Skip to main content

Come analyze HEASARC, IRSA, and MAST data in the cloud! The Fornax Initiative is now welcoming all interested beta users.

Xspec Home Page

Complete list of fixes in version 13.0.0

This section lists the user-facing bug fixes in version 13.0.0, expanding the summary given in the Introduction. These are bugs present in earlier public releases; fixes internal to the features that are new in this version are described with those features in the Introduction.

Data, responses and input/output

  • Defining a model with more than one data group loaded read out of bounds, aborting XSPEC on builds compiled with array-bounds assertions.

  • An ignore or notice command whose channel range lay entirely above the spectrum's channel count could crash or mis-clamp the range.

  • Deleting several spectra in a single data command could remove the wrong spectra.

  • A data command ending in a trailing comma wrote past the end of an internal array.

  • Running fakeit on a spectrum that uses a diagonal (diagrsp) response segfaulted while generating the fake data.

  • Loading a type-II spectrum with a reversed or empty row range (for example a {n-*} range that resolves to no rows) segfaulted instead of reporting an error.

  • Channels re-noticed after a dummyrsp command were incorrectly folded to zero for the life of the response.

  • save all wrote incorrect ignore/notice ranges for spectra whose first channel is above TLMIN, so the restored session ignored the wrong channels.

  • A table-model file path containing a slash or a hyphen was corrupted when the component was added with addcomp.

  • Changing the file path of a table-model component that was not the last component in the model hung XSPEC in an infinite loop.

  • Additive table (atable) models returned zero, rather than the tabulated LOELIMIT/HIELIMIT value, for energies outside the table's parameter range.

  • XSPEC crashed at start-up when the Xspec.init settings file contained a keyword line with a blank value.

  • Parallelized commands (parallel error, steppar, leven, walkers, goodness) could hang, silently return an empty result, or terminate the whole session when a worker process died.

  • A mistyped parallel <task> name was silently applied to a different task instead of reporting an error.

  • freeze, thaw, untie and delcomp with a list containing an empty element silently dropped the later entries.

  • Variable-length QUALITY and GROUPING columns were incorrectly assumed to be scalar when their repeat count was 1.

  • Improved the warning issued when reading a background file that contains zero-count bins.

  • An ignore or notice of a large contiguous channel range on a high-resolution spectrum (for example an XRISM/Resolve spectrum of tens of thousands of channels) was very slow; it is now linear in the number of channels.

Models

  • The btapec model overwrote the (cosmic) helium abundance with the metal abundance, giving a wrong continuum whenever the abundance parameter was not 1.

  • The zvgabs absorption-line width was applied in km/s instead of the equivalent keV value.

  • The zxipab model applied the redshift twice.

  • The velocity-width parameters (Width, Sigma, Gamma) of the velocity-broadened Lorentzian and Voigt models (vlorentz, zvlorentz, vlorabs, zlorabs, zvlorabs, vvoigt, zvvoigt, voigtabs, vvoigtabs, zvoigtabs and zvvoigtabs) carried soft/hard maxima of 10/20 km/s – below their own default of 100 km/s – so the models shipped with a default outside their stated hard limit and a fit could never raise the width above 20 km/s. The maxima are now $3\times10^{5}$ km/s, matching the vgauss family. The LineE parameters of the same models were labelled km/s; they are energies and are now labelled keV (values and defaults are unchanged, so model evaluation is unaffected).

  • The rgsxsrc convolution model left its projection rotation matrices as the identity, collapsing the RGS extended-source correction.

  • The grbjet model read past the end of its parameter array, so its spectrum depended on uninitialized memory.

  • The variable-abundance NEI models (vgnei, vpshock, vsedov, vrnei, vnpshock and their b-variants) read trace abundances out of bounds when xset NEI_TRACE_ABUND named a fitted element.

  • The vvnpshock, vvsedov, bvvnpshock and bvvsedov models reused stale ionization fractions when only the electron temperature was changed, giving a wrong spectrum and derivative.

  • The olivineabs model left the transmission of the first energy bin uninitialized.

  • Convolution models built with mdefine divided embedded additive, convolution or mixing sub-components by the bin width twice.

  • The absori model built its internal ionizing continuum over the wrong energy range.

  • The xmmpsf and suzpsf PSF mixing models set the model flux to zero above the top PSF energy (6 keV).

  • The clmass mixing model used swapped rebinning grids (giving a wrong mixed spectrum and an out-of-bounds read) and crashed when the XFLT keywords used the projct-style major/minor/orient names.

  • The bwcycl model blocked waiting for keyboard input at a bad-parameter point during a fit.

  • An out-of-bounds write in the pileup model when max_ph$\,=1$.

  • A memory-corrupting write in the diskline model when a line's blue edge fell in the first energy bin.

  • The ascac, xmmpsf and suzpsf mixing models ignored their Alpha, Beta and Core parameters when thawed, so those parameters had no effect and could not be fitted.

  • Raised the soft and hard upper limits of the element-abundance parameters of the tbvarabs model to match the other variable-abundance models.

  • Removed the built-in relline, rellinelp, rellinelpext, relconv, relconvlp and relconvlpext models; they are superseded by the versions in the externally-distributed relxill local model package.

Fitting and statistics

  • A segmentation fault in the cstat statistic when all channels are ignored.

  • The default Levenberg-Marquardt (leven) method could leave parameters stuck pegged at a hard limit (exiting with a sigma of $-1$).

  • A parameter resting on one of its limits was given a numerical derivative half its true value. The derivative evaluates the model at the parameter value plus and minus its delta and divides by twice the delta, but a limit clamps one of those two points, so only half that interval was actually spanned. The curvature came back at a quarter of its true value and the Levenberg-Marquardt step for such a parameter was consequently twice as long as it should be. Additive norms met this routinely, their hard minimum being zero and renorm driving them there.

  • With xset usechainrule no, and for the recorn cornorm, which always differentiates the statistic directly, a parameter resting on one of its limits could hang fit outright. The second derivative used a three-point formula that assumes evenly spaced points; with one of them clamped onto the parameter's own value it is not a second derivative at all, and the large negative curvature it returned left Levenberg-Marquardt with no descent direction. Both the first and second derivatives now use the spacing actually achieved, stepping to the far side of the parameter when one side is pinned.

  • A parameter lying between its soft and hard limits could stall the Levenberg-Marquardt fit and be reported as converged when it was not. The derivatives are taken with respect to the parameter's stored value, but the step was applied to its adjusted value – the compressed coordinate in which the soft limits are an infinite distance from the hard ones – so between the two limits only a small fraction of each intended step was delivered. The parameter crawled while the others stepped fully, every trial was rejected, and the fit stopped silently short of the minimum. Starting a fit at newpar 9.99 for a photon index with the default limits, for example, reached a $\chi^2$ of 3981 where 527 was available from any starting value inside the soft limits. The step is now taken in the same coordinate as the derivative, so where a fit converges no longer depends on which side of a soft limit it started from. Fits in which a parameter reaches a soft limit will follow a different path than before and may reach a different, usually better, minimum.

  • The same mismatch of coordinates affected the Minuit methods (migrad, simplex), which were given a parameter's adjusted value while being handed derivatives with respect to its stored value. Minuit now works in the stored value throughout, and enforcement of the hard limits is left to Minuit's own internal transformation, which applies its Jacobian to both the gradient and the covariance matrix. A migrad fit started with a photon index between its soft and hard limits now reaches the same minimum as one started inside them, and the uncertainties reported after a short migrad fit agree with the error command's confidence ranges where before they could be less than half as wide. Hard limits are passed to Minuit only when they span a range of 100 or less, since Minuit's transformation loses resolution over a wide range; see the method section for what this means when setting up a Minuit fit.

  • A Minuit fit that gave up without minimizing anything was reported as though it had converged. Minuit returns that way when the error matrix it carries between iterations yields no direction of improvement, and its own status flags do not distinguish the case: one such fit reported itself valid with an estimated distance to the minimum of 3306 against a convergence criterion of $2\times10^{-4}$, while an ordinary converged fit reported itself invalid at $9\times10^{-7}$. The iteration loop now continues while the estimated distance to the minimum is above that criterion — as the simplex loop always intended to, though the flag it tested never fired — and a fit that ends short of the minimum now says so, with the distance it stopped at. The two ways that can happen carry different warnings, because they call for different responses: a fit that ran out of function evaluations is continued by fitting again, while one that ended with Minuit unable to improve will do the same thing if refitted from the same point.

  • fit could abort the whole session, or read out of bounds with a Minuit method, when the covariance matrix was ill-conditioned or not positive-definite; it now issues a recoverable error.

  • The empirical distribution function test statistics (Kolmogorov-Smirnov, Cramer-von Mises, Anderson-Darling and CUSUM) could crash or return NaN. With every channel ignored, statistic test cusum segfaulted where the other three returned $-\infty$. A model integrating to zero over the noticed range – which happens whenever a norm sits at its hard lower limit of 0, so routinely during a fit – made all four return NaN, and goodness then compared its simulations against that NaN. A spectrum that was folded but not fitted, for example one dropped from the fit by a mode-2 dummyrsp, was accumulated at the wrong offset, giving a wrong statistic and reading past the end of an array.

  • The post-fit covariance uncertainties (the $\pm$ values reported after a fit, and tclout sigma) were wrong for the pgstat and whittle statistics and for model-weighted or systematic chi-square; the fit statistic itself and the error command were unaffected.

  • With the cstat or pgstat statistic and a correction file, the Levenberg-Marquardt steps and errors were computed from a statistic that ignored the correction.

  • Interrupting a Goodman-Weare chain with Ctrl-C corrupted the recorded chain length, so the file was misread when reloaded.

  • The error command could report slightly wrong upper confidence bounds and fall back to bisection unnecessarily.

  • The Minuit strategy setting was silently ignored.

  • The integrated-probability contours of steppar and margin were wrong on non-uniform (for example logarithmic) grids.

  • margin dropped samples falling exactly on the upper grid edge while still counting them in the normalization, deflating the other bins.

  • The recorn cornorm parameter could not be fitted at all. The default chain-rule derivative evaluates $\partial S/\partial p$ as $(\partial S/\partial M)(\partial M/\partial p)$, which is identically zero for a parameter that rescales the data rather than the model, so cornorm was given a zero alpha-matrix diagonal, pegged as insensitive, and fit stopped with “No variable parameters for fit”. XSPEC now differentiates the statistic directly when such a parameter is free; the xset usechainrule no workaround the model documentation used to require is no longer needed.

  • untie could break the link on a mixing-model parameter belonging to a data group other than the lowest one. Only the lowest group's copy of an ordinary mixing component performs the transformation, so the result was a free parameter that show par did not display, newpar refused to change, and no fit could move: it consumed a degree of freedom and made every subsequent fit report “Zero alpha-matrix diagonal element”. Such parameters are now left tied, with an explanatory message, and are excluded from the fit however the link is broken.

Plotting

  • plot sensitivity and insensitivity drew the first detector's curve for every response of a multiple-response spectrum.

  • plot delchi, ufspec, fitstat and icounts could crash for a plot group whose spectrum has no response for an active model source.

  • The polarization plots polfrac and polangle returned NaN or zero for multiple-source models and could contain spurious or infinite bins from a zero effective area, zero modulation, or angle re-wrapping.

  • plot chain autocorr segfaulted when the number of lags reached the length of the chain series.

  • plot integprob issued before a margin run segfaulted; it now reports a clean error.

  • setplot delete 0, and reversed ranges such as setplot delete 5-2, deleted the wrong command or corrupted the command list.

  • The Gehrels and rootn error modes produced NaN error bars on very-low-count bins.

  • Blank (undefined) bins reappeared as spurious plotted points in the eufspec/eeufspec plots and in wdata output.

  • setplot id disabled all line identifications when only a low-energy limit was supplied.

  • PyXspec Plot array retrieval could throw, or drop components, when an additive component was turned off.

  • Multiple plot groups overlapped instead of being offset in channel-space plots.

Commands, scripting and PyXspec

  • autosave 0 crashed XSPEC with a divide-by-zero on the next command.

  • error/rerror from a loaded MCMC chain reported the wrong model's confidence interval (and read out of bounds in rerror) when a frozen or scale parameter preceded a free one.

  • A use-after-free or double-free when a model definition failed during evaluation (for example a model defined with no data loaded), crashing the next command.

  • margin or steppar using the delta step form on a frozen or non-variable parameter crashed.

  • energies with the log option and a low energy of 0 silently built a degenerate (NaN) energy grid for every model.

  • Running a script by a path containing a directory component (for example @../model) failed to append the default .xcm suffix.

  • An out-of-bounds read in the eqwidth calculation when a component peak lay within the range fraction of an energy-array boundary.

  • A crash when saving or showing a parameter link such as newpar 2 = p1/1.0e5, or a malformed single-token link.

  • Fixed tclout xset when called without a third argument.

  • A PyXspec segfault from an out-of-range or stale Spectrum or Response index.

  • PyXspec raised a SystemError when querying the spectra of a model defined before any data was loaded.

  • The PyXspec Jupyter inline-SVG device (plotDevice /svg) always failed with a NameError.