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.1

This section lists the bug fixes in versions 13.0.0 and 13.0.1, expanding the summary given 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.

  • 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 luminosity distance for a non-zero cosmological constant was evaluated with the Pen (1999) fitting formula, which forms the comoving distance as the difference $\eta(1)-\eta(1/(1+z))$. At low redshift those two terms agree to within about 1% of themselves, so the formula's small residual was amplified roughly a hundredfold. The reported luminosity was a few tenths of a percent low at the default $\Lambda_0 = 0.73$ and 3–5% low at $\Lambda_0 = 0.9$, where it stopped increasing with $\Lambda_0$ altogether – the luminosity distance rises monotonically with $\Lambda_0$, so those values were unphysical, not merely imprecise. XSPEC now integrates the flat $\Lambda$CDM comoving distance exactly, to a relative accuracy better than $10^{-13}$ over the usable range of $\Omega_{matter}$ and redshift. lumin, clumin, the cooling-flow models (cflow, mkcflow, coolflow, cph and their variants), zkerrbb and smaug all move accordingly. Results with $\Lambda_0 = 0$ are unchanged: that case uses the Mattig formula in $q_0$, which was correct and is untouched.

  • A negative $\Lambda_0$ is now accepted by cosmo.

  • clumin failed with a negative <Redshift> parameter, which was allowed by the hard limit. This was fixed by changing the hard limit to zero.

  • 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.

  • The nteea model could abort or crash for some parameter combinations. An internal break-frequency index was clamped at neither end, so a low maximum Lorentz factor drove it out of range; and the Compton temperature could evaluate to a NaN through a single-precision underflow, which then produced a zero array index rather than a diagnostic. Both are fixed at source, and no model output changes for parameter sets that previously worked.

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. 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. 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. A fit that ends short of the minimum now says so.

  • 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. If every channel was 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 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 error command could restart itself without end. On finding a new minimum it re-fits with all parameters free but never checks whether fit actually improved the statistic. A new minimum is declared when a trial, taken with the parameter of interest frozen at a displaced value, beats the best fit by more than the critical delta set by the method command, which is also the convergence tolerance of the fit itself. So a fit that stopped because its statistic moved by less than the critical delta could be restarted repeatedly without any progress being made. The restart now requires the re-fit to lower the statistic by more than the critical delta; if it does not, error reports both statistics and stops. Seeing that message means the fit is not properly converged: try refitting with a smaller critical delta.

  • 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.

  • With query on and no input left to read – the end of a piped script, or a redirected input file that has run out – the prompt asking whether to continue past the trial limit was answered with its default of yes. Each unanswered prompt re-armed the trial counter, so the fit ran without bound. End of input is now distinguished from an empty reply: the fit stops at its trial limit and reports that it has not converged.

  • Two reads in the MCMC code were performed without checking the length of the array being read.

  • Independent processes started within the same second shared an identical random number stream, because the generator was seeded from the clock at one-second resolution. Simulations run in parallel from a script – fakeit, goodness, and the parallel workers used by chain – could therefore repeat one another exactly. The seed is now drawn from system entropy, and the parallel workers derive distinct streams from it. Reproducibility on demand is still guaranteed by using xset seed.

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.

  • tclout chain stat crashed when no chain stat had been run, and tclout chain dic returned uninitialized values in the same situation. Both now report that the quantity has not been calculated. The two results are also discarded when the chains they describe are unloaded or replaced, instead of being reported for a different set of chains.

  • Several xset keyword names given in the documentation and in error messages did not match the names the code actually recognizes.