Come analyze HEASARC, IRSA, and MAST data in the cloud! The Fornax Initiative is now welcoming all interested beta users.
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
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
.
- 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
).
- 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
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
, while an ordinary converged fit reported itself invalid at
. 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
. 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
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
as
, 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.