Skip to contents

Changes in version 1.3.1 (2026-09-18)

CRAN release: 2026-09-18

See also the write-up for Luminescence v1.3.1 on the REPLAY website.

Bugfixes and changes

analyse_Al2O3C_Measurement()

  • The function now better validates the dose_points argument so that it no longer generates an incorrect data frame if the argument is provided as a list when the main input is a non-list object (#1640).

analyse_IRSAR.RF()

  • The colour of the regeneration points was changed to black to guarantee greater contrast against the natural points. This should improve readability for people with red-green colour blindness and for black-and-white printing. Moreover, point colours can now be freely customised via the new col_nat and col_reg parameters (#1654; thanks to @DirkMittelstrass for reporting).

  • The plot is no longer constrained to keep a fixed aspect ratio, so that it can occupy more of the available space (#1654; thanks to @DirkMittelstrass for reporting).

  • The default x-axis label was changed from "Time" to "Irradiation time", (#1654; thanks to @DirkMittelstrass for reporting).

  • The y-axis no longer enforces the labels to be in scientific format. The previous behaviour can be restored by setting yaxis_scientific = TRUE (#1665).

  • The cores argument no longer accepts "auto" as valid input: the same functionality (using all but two of the available cores) can now be achieved by setting cores = NULL (#1668).

  • A warning message shown in case of failure of the test parameters has been improved to avoid reporting a spurious NA (#1715).

  • The function used to crash during plotting if any the extremes of the confidence interval built around the De value was computed as NaN. This was a very old (and presumably extremely rare) crash that affected only method = "FIT" (#1744).

analyse_pIRIRSequence()

  • The function no longer crashes when presented with an empty RLum.Analysis object (#1725; thanks to Annette Kadereit for reporting).

  • The check on the window size now occurs also if plot_singlePanels = TRUE. This avoids hard failures on Linux when both plot_singlePanels and plot_onePage are set to TRUE and the window size is too small; on Windows, it seems that instead of a hard error, the function would silently stop working with those settings (#1734; thanks to Annette Kadereit for reporting).

analyse_SAR.CWOSL()

  • The ordering of columns in the $data field of the result object was different from expected when fit_DoseResponseCurve() returned NULL, which meant that merging the results from multiple aliquots would fail if any such result was present. This was a regression introduced in v1.1.1 (#1623).

  • The POS and GRAIN columns in the $data field of the result object are now correctly populated also for XSYG files, instead of being set to NA. This was a regression introduced in v1.1.2 (#1625).

  • It is now possible to set recuperation_reference = "Rmax" to select the point with highest dose as reference in the calculation of the recuperation rate (#1740; thanks to Annette Kadereit for reporting).

analyse_SAR.NCF()

  • The object argument is now better validated (#1657, 1732).

analyse_SAR.TL()

  • The function no longer crashes if the input object contains no TL curves (#1732).

calc_CentralDose()

  • The function no longer crashes when the De values are identical and log = FALSE (#1628).

  • The removal of missing values now happens only after restricting the input to the first two columns, so NA values in unrelated columns no longer affect the operation of the function (#1653; thanks to @DirkMittelstrass for reporting).

calc_FastRatio()

  • Some code that adjusted the Ch_L3 setting has been removed because it had become largely superfluous since v0.9.25. Users should see no impact, except in the unlikely case when both elements of Ch_L3 are set to the last channel. In that case, the computation will now respect the user input instead of automatically moving the start of Ch_L3 back by 5 channels. That behaviour was an undocumented leftover from when user inputs were not validated (#1682).

  • The number of background channels was counted as one fewer than the number used, causing the computed errors to be marginally larger than expected. This error has been present since 2016, and its impact on the results produced depends on the number of background channels used, with the inflation of errors decreasing as the size of the background region grows (#1684).

calc_FuchsLang2001()

  • The function now returns an error if startDeValue exceeds the number of rows in the input data set, instead of returning only NAs in the result table (#1645).

calc_Huntley2006()

  • The cores argument now can be set to NULL to use all but two of the available cores (#1668).

  • The function no longer crashes when plotting in extrapolation mode if both De.measured and De.measured.error are 0 (#1672).

calc_MaxDose()

calc_MinDose()

  • The removal of missing values now happens only after restricting the input to the first two columns, so NA values in unrelated columns no longer affect the operation of the function (#1659).

  • The multicore argument has been deprecated and is no longer functional. Its functionality has been replaced by the cores argument, which can be set to either a numeric value or to NULL to use all but two of the available cores (#1668).

  • The function now validates that the initial parameter values supplied via init.values are strictly positive, as non-positive values may cause unrecoverable crashes during fitting (#1670).

  • It is now possible to disable the second-level bootstrap entirely by setting bs.N = 0. This setting corresponds to a classic bootstrap, as opposed to the recycled bootstrap that would otherwise be run by default (#1525; thanks to @MarijnvanderMeij for reporting).

calc_SourceDoseRate()

  • Source type "Am-241" was misspelled in the documentation and in the function as "Am-214" and has now been corrected. The latter form is no longer accepted (#1630).

calc_Statistics()

  • The function incorrectly ignored the error column whenever only some error values were exactly 0, which led to miscalculated weighted statistics. This was due to a regression introduced in v1.1.2; weighted mean, weighted median and the corresponding standard error and standard deviation are now set to NA in such cases, restoring the original behaviour (#1686).

fit_DoseResponseCurve()

  • If the (optional) TnTx column contains only NAs, the column is ignored instead of causing the entire dataset to be dropped (#1632).

  • The number of parameters for fit.method = "DSE" and "QDR" has been corrected to 5 and 3, respectively. For "DSE" this was a regression introduced in v1.3.0, when a new Di parameter was added to the "DSE" method without updating its parameter count; for "QDR", the behaviour regressed in v1.0.0, when predict() was introduced to replace the manual evaluation of the model fit. In both cases, this has no user-visible effect other than changing the number of dose points under which the function switches to using the “LIN” method (#1634, #1636).

  • When the root finding step failed during the Monte Carlo simulation for fit.method = "OTORX" and mode = "extrapolation", the function incorrectly reverted to the OTOR model before attempting that iteration again. This turned out to be a simple typo, with minimal impact (#1727).

  • The Monte Carlo error estimation considered spurious contributions from iterations that failed to fit. This was caused by the result vector being initialised to 0 instead of NA, which resulted in a slight overestimation of errors when any MC model failed to fit (#1730).

fit_OSLLifeTimes()

  • The function no longer crashes when using a list containing an empty RLum.Analysis object (#1732).

merge_Risoe.BINfileData()

  • Argument objects has been renamed to object. The older name will still work, but it generates a deprecation warning (#1697).

merge_RLum()

  • Argument objects has been renamed to object. The older name will still work, but it generates a deprecation warning (#1697).

merge_RLum.Analysis()

  • Argument objects has been renamed to object (#1697).

  • The function no longer crashes when using a list containing an empty RLum.Analysis object (#1732).

merge_RLum.Results()

  • Argument objects has been renamed to object (#1697).

plot_AbanicoPlot()

  • The default background colour was incorrectly set to NA, which in some very specific cases would cause some overplotting, at least on MacOS (#1649).

  • The interactive plotting mode (interactive = TRUE) is more complete and renders a usable plot (#1664, #1696).

  • The function no longer crashes when using a list of data frames with different column names (#1705).

  • A misspecified bw argument now reverts to the default value of "SJ" recommended by base R, instead of the historical (and somewhat deprecated) setting of "nrd0" (#1708).

  • Datasets containing only one non-missing observation are no longer removed and are now plotted, but no density curve is drawn for them unless a numeric value is provided for the bw (bandwidth) argument (#1707; thanks to Annette Kadereit for reporting).

  • Plot colours are now respected when one of the input data frames is automatically removed because it contains no non-missing observations (#1707; thanks to Annette Kadereit for reporting).

  • The logic for the positioning of the boxplot has been slightly revised to avoid cases in which the boxplot was plotted over one of the axes or even completely outside of the visible area (#1713; thanks to Annette Kadereit for reporting).

plot_DetPlot()

  • The multicore argument has been deprecated and is no longer functional. Its functionality has been replaced by the cores argument, which can be set to either a numeric value or to NULL to use all but two of the available cores (#1668).

plot_DoseResponseCurve()

  • The size of the repeated point has been slightly increased to make it more distinguishable (#1722).

plot_KDE()

  • The plot title is no longer drawn in a bold font, and the spacing between words in title and x-axis label has been refined so that the words no longer look attached (#1717).

plot_RadialPlot()

  • The function no longer crashes when the error column contains NA values. This was a regression introduced in v1.2.0 (#1689).

plot_RLum()

  • The handling of mtext has been improved so that, when specified as a list, each element is dispatched (with recycling) to each object being plotted, making mtext behave like the main argument. This was a regression introduced in v1.2.0 (#1676).

plot_RLum.Data.Curve()

  • If the IRR_UNIT field is present in a BIN file (version 03 or 04), this is used as unit measure in the axis labels instead of seconds (#1721).

plot_RLum.Data.Spectrum()

  • The setting legend = FALSE did not work as advertised and did not remove the legend, e.g., in plot.type = "multiple.lines" (#1702).

  • The argument legend.text was removed from the function definition but it’s still available through the ... argument (#1702).

read_RF2R()

  • Headers generated by the upcoming 'RLumImage' package are now supported (#1655; thanks to @DirkMittelstrass for reporting).

  • Header parsing is now more robust and supports quoted strings containing spaces. Malformed header values no longer cause all headers to be lost: valid values are now stored in the info slot, while malformed entries are silently dropped and no longer produce a message (#1742; thanks to @DirkMittelstrass for reporting).

read_XSYG2R()

  • The function no longer crashes when an empty <sequence /> node is found. Such a node may be present if the reader encounters an empty position and would then automatically move on to the next.

verify_SingleGrainData()

  • The message reported when cleanup = TRUE is used is now shorter and more readable as it compresses consecutive record indices into a range (#1647).

write_R2BIN()

  • Arguments file and version are now better validated (#1680).

Other changes

  • We have expanded the family of snapshot tests by testing the function output in more cases, going from 12 to 85 output snapshots (#1638).

  • Functions plot_AbanicoPlot() and plot_RLum.Data.Curve() gained a hidden .shiny flag which can be set in combination with interactive = TRUE to return the plotly object instead of printing it. This was added to improve the interactive functionality within the RLumShiny package.


Changes in version 1.3.0 (2026-07-22)

CRAN release: 2026-07-22

See also the write-up for Luminescence v1.3.0 on the REPLAY website.

Breaking changes

fit_DoseResponseCurve()

  • In function fit_DoseReponseCurve() we modified how weights are handled. Up to v1.2.1, the default for fit.weights used a normalised inverse standard error approach, under the assumption that uncertainties scale with the dose. In hindsight, this appears to be short-sighted and not very well justified: individual relative uncertainties typically do not scale with the dose, but are independent except in exceptional cases. In consequence, we modified what values fit.weights accepts to accommodate the old and new approach. This has three immediate consequences:

    • The allowed input for fit.weights is no longer logical, but either character ("inverse_var", "inverse_std", or "norm_inverse_std"), numeric, or NULL (no weights);
    • The numerical output of fit_DoseReponseCurve() will differ, as the new default use inverse variance instead;
    • Users are now able to provide their own weights.

    These changes affect the numerical output of the following functions: fit_DoseResponseCurve(), analyse_SAR.CWOSL(), analyse_SAR.TL(), analyse_baSAR(), analyse_pIRIRSequence(), calc_Lamothe2003(), calc_Huntley2006(), plot_DRCSummary(), plot_DetPlot().

    Although the changes in the numerical output may be inconvenient, we strongly advise updating regardless. The old results can still be reproduced using option fit.weights = "norm_inverse_std" in the affected functions.

  • The fit.method parameters have undergone some renaming to make them more rigorous (#1604):

    • EXP is now called SSE (single saturating exponential); similarly, EXP+LIN and EXP OR LIN are now SSE+LIN and SSE OR LIN, respectively
    • EXP+EXP is now called DSE (double saturating exponential)

    The previous method names are still functional, but will now raise a deprecation warning.

    These changes also affect the following functions: analyse_SAR.CWOSL(), analyse_SAR.TL(), analyse_baSAR(), analyse_pIRIRSequence(), analyse_Al2O3C_CrossTalk(), analyse_Al2O3C_ITC(), calc_Huntley2006(), plot_GrowthCurve().

  • Internally, the following model parameters have been renamed so they are consistent between models when they have a physical meaning (#1604):

    • for SSE, SSE+LIN and SSE OR LIN: the a, b and c parameters are now called N, D0 and Di, respectively
    • for DSE: the a1, a2, b1, b2 parameters are now called N1,N2,D01andD02`, respectively
    • for GOK: the b parameter is now called D0
    • for OTOR: the Dint parameter is now called Di
    • for OTORX: the a parameter is now called Di
  • The output object data frame was expanded to contain columns for the D63 and D80 parameters used by OTOR and OTORX. Along with this, we modified the uncertainty calculation for Dc, R, D63, and D80: now we calculate the 25% and the 75% quantiles (in the “LOWER” and “UPPER” columns for each of those parameters) instead of returning the standard deviation, which did not make much sense. This means that the column R.ERROR is no longer available. Please note that the output table was also updated in analyse_SAR.CWOSL() and subsequent functions. As long as you access column values using their names rather than indices, these changes should not affect your existing scripts.

Other breaking changes

  • In function calc_MinDose() we changed how the sigmab argument should be expressed in the log = FALSE case. Up to v1.2.1, it was required to be specified in the same absolute units used for the De values. From now on, it must be expressed in relative units as a ratio (e.g. 0.2 for 20 %). This makes the interpretation of the argument consistent between logged and unlogged models (#1548).

  • Plotting an object generated by analyse_SAR.CWOSL() via plot_RLum() (or just plot()) will no longer produce an abanico plot, but will redraw the plots originally created by analyse_SAR.CWOSL(). This will work only for objects generated by the current package version, while the previous behaviour is maintained for objects generated by version up to 1.2.1. In any case, Abanico plots can still be created by calling plot_AbanicoPlot() directly (#1589).

  • The summary keywords accepted by the plotting functions have been uniformed throughout the package to match those used by calc_Statistics() (#1618):

    • the names sdrel, sdabs, serel and seabs that were used by plot_Histogram() and plot_RadialPlot() are no longer recognised, and will be silently ignored; they have been replaced by sd.rel, sd.abs, se.rel and se.abs, respectively.
    • the names weighted$mean and weighted$median that were used by plot_DRTResults() have been replaced by mean.weighted and median.weighted.

New functions

  • Function analyse_SAR.NCF() implements the natural sensitivity correction for the assessment of single aliquot regeneration based palaeodoses, proposed originally by Singhvi et al. (2011) and later implemented in Matlab by Kaushal et al. (2022). This is currently in beta, pending more testing on real data (#1091).

Bugfixes and changes

analyse_baSAR()

  • The function no longer crashes if a list containing multiple empty objects is provided (#1598).

analyse_IRSAR.RF()

  • The RF_nat.lim and RF_reg.lim arguments are now checked to have the expected length (1 or 2 elements) to avoid crashes that occurred when they were misspecified (#1621).

analyse_SAR.CWOSL()

  • The default value for the background_integral argument has changed from NA to NULL. In v1.2.0 NA acquired the distinct meaning “do not subtract the background integral”, so using it as the implicit default changed user-facing behaviour. Switching the default to NULL restores the behaviour present up to v1.1.2, where integrals are applied only when both signal and background integrals are provided, and specifying only the signal integral results in no integrals being applied (#1526).

  • The plot_singlePanels argument produced no plots when set to 7 or 8 (#1558).

  • The dose.points and dose.points.test arguments are now better validated, and a clearer error message will be reported if misspecified (#1583).

apply_EfficiencyCorrection()

  • The argument spectral.efficiency now directly supports a CSV-file input.

calc_Huntley2006()

  • The function now requires at least 4 dose points (the natural dose, which is removed before fitting, plus at least 3 others). With fewer points, model fitting can fail or crash, as all models have 3 parameters (#1572).

calc_MinDose()

  • If init.values is provided and log = TRUE, the sigma parameter is now initialised as sigma / mu instead of log(sigma). The previous approach failed silently when sigma < 1, as the logarithm produced out-of-bounds parameter values, with the effect of leaving all parameters at their initial values (#1527; thanks to @MarijnvanderMeij for reporting and suggesting a fix).

  • The confidence intervals stored in the RLum.Results object are now always in the natural units, independently of the log argument (#1533; thanks to @MarijnvanderMeij for reporting).

calc_OSLLxTxRatio()

  • The SN_RATIO_TnTx value was wrongly returned as Inf if use_previousBG was set to TRUE and background_integral = NA. Now the function will return NA in this case, as stated in the function documentation (#1554).

  • The computation of LxTx has been fixed to compute the contribution of the Tx background correctly when use_previousBG = TRUE. This should result in very minor differences if the background counts for the Lx and Tx curves are similar (#1565).

  • The new od_rates argument activates an alternative approach for error estimation of Lx/Tx ratios based on Bluszcz, Adamiec and Herr (2015). This argument is also supported by analyse_SAR.CWOSL(), analyse_pIRIRSequence(), and analyse_FadingMeasurement() (#1390; thanks to @andrzejbluszcz for providing the mathematical description, contributing code and checking the implementation).

calc_SourceDoseRate()

  • The predict argument has been extended to handle backwards and forward prediction.

  • The function has been corrected so that, in case multiple measurement dates, the predict argument will be applied to the last date, as specified by the manual (#1609).

  • If multiple values are provided for calib.date when predict is used, only the last calibration date specified will be applied. This ensures that the source dose rates are computed consistently, rather than depending on R’s recycling rules for vectors (#1611).

calc_Statistics()

  • The values accepted by the weight.calc argument have been changed to align to the terminology used in fit_DoseResponseCurve(). Therefore, option "square" is now called "inverse_var", and "reciprocal" is now called "inverse_std". The previous names will continue to work, but will now raise a deprecation warning (#1615).

convert_Second2Gray()

  • Input validation was strengthened to avoid two possible crashes (#1537).

fit_DoseResponseCurve()

  • Argument fit.weights now supports a numeric vector as input. This gives more control over the fitting process and enables better comparison with other software, such as Python’s SciPy. In this case, the vector must be of the same length as the number of data points to fit, which is typical the number of LxTx points (#1536).

  • The fit.weights argument was reimplemented to different approaches for the weight computation. These can be specified by the keywords "inverse_var" (the new default, corresponding to 1/sigma^2), "inverse_std" and "norm_inverse_std" (corresponding to the default up to v1.2.1). Moreover, NULL disables weights, while a numeric input enables the definition of own weights (#1539).

  • The "QDR" fit method is now less likely to fail due to an invalid choice of the starting point for the uniroot() function (#1541).

  • The starting value of one of the parameters of the SSE model has been tweaked to remove a dependency of the results from the random values used during the Monte Carlo steps. This should make the results more stable, in particular for mode = "extrapolation". This change may introduce some minor differences to the result of this function and of other functions that depend on it (#1552).

  • Vectors containing the starting values for some fitting parameters used during the Monte Carlo runs are no longer generated for fit.method = "QDR" and "GOK", as they were unused in those models. This affects the state of the random number generator, so very minor numerical differences in the results are to be expected (#1568).

  • The models used to generate sensible starting points for "SSE", "DSE", "SSE+LIN", "GOK", "OTOR" and "OTORX" models now consider the LxTx errors as weights, which may improve the fitting in cases when the data to fit is highly irregular due to very large errors (#1570).

  • From the documentation, it was not always clear that the function expects columns with values in a particular order and does not look up column names (at least not all). Now the function is a little bit more flexible and automatically orders columns in the required order if column names that would somewhat match the expectations are used. As a positive side effect, the LxTx table produced by analyse_SAR.CWOSL() can be now inserted as input without further modification. (#1591; thanks to @DirkMittelstrass for reporting).

  • Minor adjustment of the terminal feedback for better text alignment. Plus, remove reporting Dc for OTOR in favour of D63 (Dc is still accessible in the output).

  • Method “DSE” gains a Di parameter in the model for the offset (#1604).

  • Method “DSE” used to compute a starting point from 50 random points generated from the input data with the goal of finding a robust initialization point for the final fitting. However, this was not used, so those computations were effectively discarded. This has been fixed, and this should provide more robustness for this method (#1605).

fit_EmissionSpectra()

  • The function no longer crashes if a frame argument of length 0 is used (#1602).

get_RLum()

  • It is now possible to disable a potentially very long information message reported when the subset argument returns an empty list by setting verbose = FALSE. The verbose argument is also exposed in the subset() method for RLum.Analysis objects (#1587; thanks to @DirkMittelstrass for highlighting the problem).

merge_RLum.Results()

  • The function gained the flatten argument, which allows to control whether list elements should be flattened into a single list when merging (#1593).

plot_AbanicoPlot()

  • The summary text is no longer overprinted when multiple datasets are given as input and summary.pos is one of "left", "center" or "right" (#1575).

  • The function no longer crashes when z.0 is misspecified (#1579).

plot_DetPlot()

  • The function now allows passing the dose_rate_source argument to the analysis function via the analyse_function.control argument, as in analyse_function.control = list(dose_rate_source = 4.07) (#1561).

plot_DoseResponseCurve()

  • The error bars had been missing for extrapolation and alternate mode since v1.1.0. This error was introduced with commit cf299831 and remained unnoticed due to lack of graphical snapshots (a3ed7744).

  • Add ... support for arguments lwd_drc, lty_drc, and col_drc to enable further customisation of the dose-response curve.

  • The function can now print the dose-response curves from an RLum.Results object created by analyse_SAR.CWOSL() (#1592; thanks to @DirkMittelstrass for reporting).

  • The function crashed with a object of type 'closure' is not subsettable error if the fit could not be established and an object named histogram was present in the workspace or exposed in the namespace by another package.

plot_DRTResults()

  • The plotting of a list of inputs with summary.pos = "sub" was regressed in v1.2.0, resulting in the summary statistics being printed one line down from their intended position (#1613).

plot_KDE()

  • The default background colour was incorrectly set to NA, which in some cases, such as when plotting to a png file or in RStudio (at least on MacOS), corresponds to a transparent background. This could cause the KDE plot to appear to be drawn over an existing plot (#1556).

  • The summary text is no longer overprinted when multiple datasets are given as input and summary.pos is one of "left", "center" or "right" (#1575).

plot_RadialPlot()

  • The summary text is no longer overprinted when multiple datasets are given as input and summary.pos is one of "left", "center" or "right" (#1575).

  • The function no longer crashes if centrality is set to a numerical value of length shorter than the number of input datasets (#1577).

plot_RLum.Results()

plot_RLum.Data.Spectrum()

  • If the function was called with plot.type = "interactive", the error plot.new has not been called yet appeared in the terminal. This was a regression introduced in v1.1.2, and has now been fixed.

  • If the column names are replaced by the index, the default y-axis label is now preset to “Channel index”, but it can be overwritten using the ylab function argument. This should avoid cases where the user overlooks the warning and struggles to understand the axis values.

  • The plot.type = "transect" now scales the y-axis automatically (can be overwritten with zlim).

  • The plot.type = "transect" gained support for a few new arguments: add (to add additional transects to an existing plot), smooth (basic curve smoothing), transect_mode to control the integration method (sum the default, mean, median, min, max)

  • For plot.type = "multiple.lines" the number of legend entries is limited to 30 to avoid excessive overplotting; it can be overwritten by setting legend.text.

plot_ViolinPlot()

  • Numeric coordinates for summary.pos are now respected (#1596).

read_Daybreak2R()

  • Information about irradiation doses are now more easily retrievable from the info element (#1563; thanks to @andrzejbluszcz for the code contribution).

remove_RLum()

  • The function no longer accepts unnamed arguments (#1529).

Changes in version 1.2.1 (2026-03-25)

CRAN release: 2026-03-25

See also the write-up for Luminescence v1.2.1 on the REPLAY website.

Bugfixes and changes

analyse_IRSAR.RF()

  • A work array in the C++ implementation of the sliding method was not correctly initialised when n.MC = 1. This was spotted by the valgrind memory debugger run by CRAN, and triggered a request to resubmit the package (#1479).

analyse_SAR.TL()

  • The integral_input argument was not sufficiently validated when checking for deprecated arguments (#1483).

calc_OSLLxTxRatio()

  • The computation of sigmab was overaccounting the contribution of the background integral as it generated sub-intervals that overlapped by one element (the last value in an interval with the first of the next). It was also mistakenly computing abs(var(Y.i) - mean(Y.i)) when instead it should have truncated negative values to zero, as in max(var(Y.i) - mean(Y.i), 0): this means that if the data follows a Poisson distribution, sigmab will be computed to be 0, instead of a possibly large positive value. These changes affect results generated by analyse_baSAR(), analyse_FadingMeasurement(), analyse_SAR.CWOSL(), analyse_pIRIRSequence() and plot_DetPlot() as they call this function (#1491, #1495; thanks to @AndrzejBluszcz for reporting and fixing).

  • Errors are now computed also when background_integral = NA. When this feature was first introduced in v1.2.0, errors were set to NA, which in turn led to miscomputing the De.error as 0. Now, instead, the error calculation simplifies to the error component coming from the signal integral, so that downstream uses (for example, in analyse_SAR.CWOSL()) can produce a correct De.error. Note that when background_integral = NA, sigmab is returned as NA, as Galbraith’s method of computing it cannot be applied (#1504; thanks to Annette Kadereit for reporting).

calc_TLLxTxRatio()

  • The function now checks that the input data frames contain 2 columns instead of crashing if they are malformed (#1501).

calc_WodaFuchs()

  • The curvature was computed but never used. As its implementation looked fragile, the line of code that computed it was commented out (#223).

convert_CW2HMi(), convert_CW2LMi(), convert_CW2PMi()

  • The functions stop early if the input object contains duplicate times. Previously this generated a warning but produced results according to whatever approx() decided to keep. We believe that instead the user should be in charge of removing duplicated values, so that they can better assess which should be kept or why there are duplicates at all (#1485).

fit_OSLLifeTimes()

  • The function will remove any NA or NaN values from signal_range before using it (#1497).

  • The function wrongly rejected inputs such as signal_range = 1:2 due to incorrect argument validation. Note, however, that now the function will check the number of values set in signal_range, and produce an error (instead of a warning) if more than 2 values are specified (#1506).

  • The function no longer crashes if arguments of length 0 (such as NULL) are passed via ... (#1514).

fit_ThermalQuenching()

  • The function now checks that the input dataset contains at least 4 points, and stops with an error if that is not the case. This avoids possibly wrong fit results and the corresponding warnings from nlsLM() (#1512).

normalise_RLum()

plot_DRT()

  • A regression introduced in v1.2.0 caused the summary text to appear in black instead of colour for the very specific case of a dataset that contained a number of points equal to the total number of datasets in the input list (#1516).

  • When a list of datasets was provided, x-axis ticks were drawn only up to the size of the first dataset (#1518).

  • A regression introduced in v1.1.2 caused the na.rm argument to behave in the opposite way as expected. This has been corrected so that the default setting of na.rm = FALSE will not remove the NA values. Moreover, the function no longer crashes if all errors are NA and na.rm = FALSE (#1520).

  • The function no longer crashes if the input data frames don’t have names or if they contain a different number of columns (#1522).

plot_KDE()

  • A regression introduced in v1.2.0 caused the rug to have uneven tick lengths if a list of datasets of different size was provided, which could lead to very long rug lines for the smaller dataset (#1508).

use_DRAC()

  • The function has been updated to accept the DRAC v1.3 input template. This doesn’t appear to be different from the v1.2 template apart from the updated version number in the header row (#1311).

verify_SingleGrainData()

  • The function better validates all its arguments (#1487).

Changes in version 1.2.0 (2026-03-12)

CRAN release: 2026-03-12

See also the write-up for Luminescence v1.2.0 on the REPLAY website.

Breaking changes

  • All import functions will now always append the detector used to the recordType slot of the RLum.Data.Curve object generated, for consistency with what has always been done by read_XSYG2R(). The following functions have been modified to support this new behaviour:

    • read_Daybreak2R()
    • read_PSL2R()
    • read_RF2R()
    • read_SPE2()
    • Risoe.BINfileData2RLum.Data.Curve() In most cases, this is the string “(PMT)” for BIN/BINX, PSL and Daybreak files; in the remaining cases the string “(NA)” is appended. The following example files have been updated to reflect these changes:
    • ExampleData.RLum.Analysis
    • ExampleData.portableOSL As a consequence of these changes, default titles for curve plots will now also contain the detector string. This may potentially disrupt code that uses strict equality (==) when selecting curves based on their recordType (#1275, #1286).
  • Function read_XSYG2R() will now prepend an underscore to the recordType slot of the RLum.Data.Curve object generated from an XSYG file for all objects after the first curve in a record. This will allow an easier way to differentiate the curves to analyse (for example, “OSL (UVVIS”) from those that are not useful in the analysis (for example, “_OSL (NA)“) (#1276).

  • The @info slot returned by function read_XSYG2R() no longer contains a name field: this has been replaced by sequenceName, to differentiate it from the newly-added recordName (#1239, #1387).

  • Functions calc_OSLLxTxRatio(), calc_OSLLxTxDecomposed(), calc_TLLxTxRatio() and analyse_SAR.TL() return two extra columns, SN_RATIO_LnLx and SN_RATIO_TnTx, in their result object. This may disrupt code that relies on column indices instead of column names (#1281, #1330, #1436).

See this post on the REPLAY website for more information and advice on how to deal with these changes.

New functions

  • normalise_RLum(): This function enables a fast normalisation of RLum.Data.Curve-class, RLum.Data.Spectrum-class, RLum.Data.Image-class and their combination in RLum.Analysis-class objects. Normalisation was already possible for plotting (e.g., plot_RLum.Data.Curve(…, norm = TRUE)), which uses an internal function called .normalise_curves() to do the job. With normalise_RLum() we expose this functionality to RLum-class objects and enable a convenient normalisation of values that might come in handy in same cases. Normalised values are only count values. Currently implemented is normalisation via keywords, such as "max", "min", "first", "last", "huot", "intensity". Additionally, the function supports normalisation to a positive number (#1250 by @RLumSK, #1300).

  • read_BINXLOG2R(): This function enables the salvaging of log files created by a Risø reader into R as RLum.Analysis-class. It also allows for exporting these files into a BIN/BINX format. While the function has been tested on a few examples, it is important to note that log files are not a well-defined data format. This function is intended for use in cases where you have a corrupted BIN/BINX file but a complete log file is still available. Supported log formats are TL, OSL, and IRSL curves. All other formats are ignored (#1241 by @RLumSK; thanks to Michael Kenzler for bringing this to our attention).

Removed functions and deprecations

  • Functions github_branches(), github_commits(), github_issues(), is.RLum(), is.RLum.Analysis(), is.RLum.Data(), is.RLum.Data.Curve(), is.RLum.Data.Image(), is.RLum.Data.Spectrum() and is.RLum.Results() (deprecated since 1.1.2) have been removed (#1242).

  • Function install_DevelopmentVersion() has been removed as it relied on the now deprecated devtools::install_github(). Equivalent functionality is available via pak::pkg_install("R-Lum/Luminescence") (#1453).

Bugfixes and changes

analyse_Al2O3C_CrossTalk()

  • The signal_integral argument was silently ignored (#1428).

  • The function now supports the integral_input argument, which can be set to either "channel" (default) and "measurement". When the latter is used, the integrals can be specified in terms of seconds, in which case the function performs an automatic conversion to channels (#1396).

analyse_Al2O3C_ITC()

  • The function used to output a suppressed error message instead of validating the input ahead of that (#1256).

  • The signal_integral argument was silently ignored (#1428).

  • The function now supports the integral_input argument, which can be set to either "channel" (default) and "measurement". When the latter is used, the integrals can be specified in terms of seconds, in which case the function performs an automatic conversion to channels (#1396).

analyse_Al2O3C_Measurement()

  • The function now supports the integral_input argument, which can be set to either "channel" (default) and "measurement". When the latter is used, the integrals can be specified in terms of seconds, in which case the function performs an automatic conversion to channels (#1396).

analyse_baSAR()

  • The function has been updated to use fit_DoseResponseCurve() and plot_DoseResponseCurve() instead of plot_GrowthCurve(). This should not have any visible difference other than the renaming of two arguments: output.plot has been renamed to plot_drc, while output.plotExtended has been renamed to plot_extended. The older names will still work but generate a deprecation warning (#1244).

  • Arguments signal.integral, background.integral, signal.integral.Tx and background.integral.Tx have been renamed to signal_integral, background_integral, signal_integral_Tx and background_integral_Tx, respectively. The older names will still work but generate a deprecation warning (#1290).

  • The function no longer crashes if aliquot_range specifies non-positive indices or if source_doserate = 0 (#1424, #1426).

analyse_FadingMeasurement()

  • The plots were affected by a bug in plot_RLum.Analysis(), so that the output was unnecessarily split over two pages (#1247).

  • Arguments signal.integral and background.integral have been renamed to signal_integral, background_integral, respectively. The older names will still work but generate a deprecation warning (#1290).

  • The function now supports the integral_input argument, which can be set to either "channel" (default) and "measurement". When the latter is used, the integrals can be specified in terms of seconds, in which case the function performs an automatic conversion to channels (#1396).

analyse_IRSAR.RF()

  • The slide$squared_residuals field of the @data slot in the RLum.Results object returned by the function is no longer a 1-column matrix, but a plain numeric vector (#1254).

analyse_pIRIRSequence()

  • Arguments signal.integral.min, signal.integral.max, background.integral.min and background.integral.max have been replaced by signal_integral and background_integral: each of them now defines a vector of channels for the respective integrals. The older names will still work but generate a deprecation warning (#1290).

  • The function crashed if called on an empty list (#1372).

  • The function now supports the integral_input argument, which can be set to either "channel" (default) and "measurement". When the latter is used, the integrals can be specified in terms of seconds, in which case the function performs an automatic conversion to channels (#1396).

analyse_portableOSL()

  • Argument signal.integral has been renamed to signal_integral. The older name will still work but generates a deprecation warning (#1290).

  • The function now supports the integral_input argument, which can be set to either "channel" (default) and "measurement". When the latter is used, the integrals can be specified in terms of seconds, in which case the function performs an automatic conversion to channels (#1396).

analyse_SAR.CWOSL()

  • If mode = "alternate", the dose value is no longer reset automatically. If the first dose point was > 0, the function detected a dose-recovery test and automatically reset this dose point to 0. While this is likely convenient in 9 out of 10 cases, it caused trouble if the mode = "alternate" (passed on to fit_DoseResponseCurve()) because it modified the first dose point and this required additional handling afterwards. Please keep in mind that you have to redefine the recuperation reference in such a case: this is wanted and not a bug (fixed in commit 9ff29bf).

  • The order of columns in the rejection.criteria data frame that is output by the function has been changed so that the UID column appears now first. This is meant to facilitate seeing visually to what aliquot each criteria belongs to. While the UID values are random-looking alphanumeric values, they can identify univocally an aliquot also after merge operations (#1172).

  • A new argument, dose_rate_source, was added to allow users to specify a value for the source dose rate and display values in Gy, rather than seconds. Previously, this was only possible by using a factor with the dose.points argument. However, setting it manually was particularly inconvenient if the dose points were already extracted automatically, as it required users to insert dose values manually regardless of the automated extraction. This argument is also available in other functions that wrap around analyse_SAR.CWOSL() (fixed in commit 4fc985d).

  • The function warns if the most common curve type (which is the one used in the analysis) matches multiple record types, as this may be a sign that the user has forgotten to select the correct set of curves to analyze (#1269).

  • A new signal-to-noise ratio rejection criterion has been added, with default threshold of 50 (controllable by setting the sn.ratio parameter in the rejection.criteria list to a different value). By default it uses the signal-to-noise value computed for the natural curve, but a different curve can be specified via the sn_reference parameter in the rejection.criteria list (#1284).

  • Arguments signal.integral.min, signal.integral.max, background.integral.min and background.integral.max have been replaced by signal_integral, background_integral, signal_integral_Tx and background_integral_Tx: each of them now defines a vector of channels for the respective integrals. The older names will still work but generate a deprecation warning (#1290).

  • When rejection criteria are set to NA, in the plot we now only show the value calculated (say, 1.1) instead of incorrectly showing NAs for both the sign and the threshold (as in 1.1 NA NA) which would look ugly and confusing (#1318).

  • The rejection criteria for the highest dose points was not considered correctly, and in most cases validated to "FAILED" even for thresholds set to NA or Inf (fixed in commit 3562bca).

  • It is now possible to consider value uncertainties in the computation of some rejection criteria (currently only recycling.ratio, recuperation.rate and exceed.max.point) by setting consider.uncertainties = TRUE in the rejection.criteria list. This is disabled by default to preserve existing behaviour (#1325).

  • The function now supports setting background_integral = NA, in which case no background integral is subtracted (#1385; thanks to Annette Kadereit for reporting).

  • If the function processes a list of objects, as is the typical scenario, the aliquot number (not the position number) is returned. The aliquot number represents the consecutive number of objects processed.

  • Add support to control the legend size and the legend symbols via legend.cex and legend.pch (fixed in commit 9ec687d).

  • The function now supports the integral_input argument, which can be set to either "channel" (default) and "measurement". When the latter is used, the integrals can be specified in terms of seconds, in which case the function performs an automatic conversion to channels (#1396).

  • When OSL.component is specified, the function now checks that the input object was actually processed by OSLdecomposed::RLum.OSL_decomposition(), in order to return a warning message when that is not the case (#1464).

  • Curves with recordType starting with _ are automatically removed. This allows to analyse an XSYG file directly without (in many cases) any manual intervention required. This behaviour can be changed by setting argument method_control = list(auto_curve_removal = FALSE) (#1468).

analyse_SAR.TL()

  • Argument signal.integral has been renamed to signal_integral. The older name will still work but generate a deprecation warning (#1290).

  • The integral_input argument now accepts options “channel” (as before) and “measurement” (instead of “temperature”). This was done to uniform the choices accepted by the argument throughout the package. The older name will still work but generates a deprecation warning (#1396).

apply_EfficiencyCorrection()

  • The function no longer produces an invalid object when the interpolation range is outside of the wavelength range of the RLum.Data.Spectrum object (#1402).

calc_AverageDose()

  • The RLum.Results returned now contains a $data field to store the input data for consistency with similar functions, and two columns have been appended to the end of the $summary field for internal use (#1455).

calc_CobbleDoseRate()

  • Argument input has been renamed to object. The older name will still work but generates a deprecation warning (#1434).

calc_CommonDose()

  • The function incorrectly disallowed setting sigmab > 1 when log = FALSE due to excessively strict input validation (#1343).

calc_FiniteMixture()

  • The function didn’t allow inputs such as n.components = 1:3, enforcing the usage of n.components = 2:3 instead. This check, added in v1.1.0, was unnecessarily stringent and has been reverted (#1458).

calc_gSGC()

  • The function no longer crashes if n.MC is set to 0 (#1327).

calc_MaxDose()

  • The De estimates produced when bootstrap = TRUE were not transformed back to the original scale before being returned to the user (#1351).

calc_MinDose()

  • The function now set non-positive De values to NA when log = TRUE, which used to lead to a crash when combined with bootstrap = TRUE (#1313).

  • The bootstrap results stored in the @data$bootstrap$pairs$gamma matrix are now correctly converted to the normal scale for log models. This fixes a regression introduced in v1.0.0, which caused those values to be stored in the log scale (#1345).

  • The function now stores the bootstrap results in the summary slot when bootstrap = TRUE. Moreover, summary results are printed to the terminal also when using bootstrap (#1336; thanks to @feldsparlover and Arindam Biswas for reporting and to Marijn van der Meij for checking the implementation).

  • The function crashed when bootstrapping with bs.N = 1. Now the bs.N parameter is silently reset to 2 in that case, although such low values are discouraged as they may trigger a warning during loess fitting (#1355).

  • The computation of frequencies of bootstrap replicates has been fixed to be sample-wise, while before it was mistakenly computed as a cumulative sum over all samples. In our tests, the difference in results produced by the two implementations appears to be minimal (#1374).

calc_OSLLxTxDecomposed()

  • The data frame returned by the function now contains two additional columns, SN_RATIO_LnLx and SN_RATIO_TnTx (containing NA) for consistency with the output produced by calc_OSLLxTxRatio() (#1330).

calc_OSLLxTxRatio()

  • The data frame returned by the function now contains two additional columns, SN_RATIO_LnLx and SN_RATIO_TnTx. This is the signal-to-noise ratio for the respective shine-down curves for Lx and Tx (#1281).

  • Arguments signal.integral, background.integral, signal.integral.Tx and background.integral.Tx have been renamed to signal_integral, background_integral, signal_integral_Tx and background_integral_Tx, respectively. The older names will still work but generate a deprecation warning (#1290).

  • The function can now accept lists for its Lx.data and Tx.data arguments, in which case it will self-call. This can simplify using the function, as it’s no longer necessary to write a loop to process all records (#1299).

  • The function now supports setting signal_integral to a chosen set of channels while setting background_integral = NA. In this case, no background integral is subtracted and the error calculation and the signal-to-noise ratio will report NA values (#1375).

  • The function now supports the integral_input argument, which can be set to either "channel" (default) and "measurement". When the latter is used, the integrals can be specified in terms of time or temperature, in which case the function performs an automatic conversion to channels (#1396).

calc_TLLxTxRatio()

  • Argument signal.integral has been renamed to signal_integral. The older name will still work but generate a deprecation warning (#1290).

  • The function now supports the integral_input argument, which can be set to either "channel" (default) and "measurement". When the latter is used, the integrals can be specified in terms of temperature, in which case the function performs an automatic conversion to channels (#1396).

combine_De_Dr()

  • The function crashed if the Age_range argument contained missing values (#1378).

convert_CW2pHMi() and convert_CW2pPMi()

  • The function now checks if the results of the approximation step are not valid because all points lie outside of the computed interpolation range, which can happen if the input data is misspecified (#1295).

correct_PMTLinerarity()

  • The function, introduced in v1.1.2, unintentionally came with a major flaw, in that it did nothing on a single RLum.Data.Curve() object (fixed in commit 1d978cf).

  • If the channel resolution was not changing, the function produced NaN values even in cases where dead time was not corrected (fixed in commit 1d978cf).

convert_Concentration2DoseRate()

  • Argument input has been renamed to object. The older name will still work but generates a deprecation warning (#1434).

  • The interpolation of attenuation values has been corrected so that it will not unexpectedly fail if a non-integer value for the grain size is provided, as long as it’s in the valid range (#1444; thanks to Christina Neudorf for reporting).

convert_CW2p*()

  • Argument values has been renamed to object. The older name will still work but generates a deprecation warning (#1434).

convert_Second2Gray()

  • The dose_rate argument is now better validated (#1439).

convert_SG2MG()

  • The function crashed if used on an object resulting from a subset operation, as it used the rownames (which may no longer correspond to row indices) to index into the METADATA slot (#1415).

  • The function now exits cleanly instead of crashing if more than one input filenames are provided (#1446).

extract_IrradiationTimes()

  • The function no longer crashes if the input object contains no position field in its info object (#1466).

fit_CWCurve()

  • Argument values has been renamed to object. The older name will still work but generates a deprecation warning (#1434).

fit_DoseResponseCurve()

  • The C++ implementation of the GOK function has been tweaked to avoid some repeated computations in a loop. Given the different ordering of computations (although mathematically equivalent), there will be small differences in the numerical output when fit.method = "GOK" is used (#1277).

  • The fit message reported is now also stored in the @info slot of the object returned by the function (#1362).

  • The function now consistently returns the material specific parameter R for OTOR and OTORX and its uncertainty (fixed in commit 9b4d6bd).

fit_LMCurve()

  • Arguments values and values.bg have been renamed to object and object.bg, respectively. The older names will still work but generate a deprecation warning (#1434).

  • The function now checks that the number of data points provided is large enough to fit the requested number of components (#1448).

get_RLum()

  • An internal optimization increased the performance of the function by over 50% in some particular cases, such as when merging a large number of RLum.Analysis object (#1271).

merge_RLum.Risoe.BINfileData()

  • Argument input.objects has been renamed to objects. The older name will still work but generates a deprecation warning (#1434).

merge_RLum.Data.Spectrum()

  • The function no longer warns unnecessarily if the RLum.Data.Spectrum object contains no column names (#1450).

plot_AbanicoPlot()

plot_DetPlot()

  • When operating on a list with the default setting of multicore = TRUE, the function limits the size of the parallel cluster to the number of list elements to process (#1258).

  • Arguments signal.integral.min, signal.integral.max, background.integral.min and background.integral.max have been replaced by signal_integral, background_integral, signal_integral_Tx and background_integral_Tx: each of them now defines a vector of channels for the respective integrals. The older names will still work but generate a deprecation warning (#1290).

  • The function now supports the integral_input argument, which can be set to either "channel" (default) and "measurement". When the latter is used, the integrals can be specified in terms of seconds, in which case the function performs an automatic conversion to channels (#1396).

plot_DRTResults()

  • Argument values has been renamed to object. The older name will still work but generates a deprecation warning (#1434).

plot_RLum.Analysis()

  • The ability to combine multiple plots on a single page regressed in v1.1.2, causing plots intended to appear side-by-side to be rendered on separate pages (#1247).

plot_RLum.Data.Curve()

  • The scaling of the subtitle by cex didn’t account of the par.local argument, thus affecting curve plots generated by plot_RLum.Analysis() (#1347).

plot_RLum.Data.Spectrum()

  • The norm argument is no longer limited to just "min" and "max" but now supports all options provided by normalise_RLum() (#1303).

  • The function now returns NULL (instead of producing an empty plot or crashing) whenever the normalisation step replaces all values with zeroes, which can happen if the normalisation term used is 0, for example when the bg.spectrum argument is used and norm = "min" (#1305).

  • Setting log = "z" will produce a warning if the data contains non-positive values (for example after background subtraction or normalisation) before setting those values to NA. This avoids producing infinities or NaN values that would lead to crashes for some plot types (#1307).

plot_FilterCombinations()

  • The interactive mode did not accept all plotting options from the default (non-interactive) mode (fixed in commit c27a656).

  • If the function was used on a shiny server, the plot showed only after the app was closed (fixed in commit c27a656).

plot_GrowthCurve()

  • Argument sample has been renamed to object. The older name will still work but generates a deprecation warning (#1434).

plot_KDE()

  • The length of the ticks for the rugs is now scaled by the size of dataset, so that visually the rug appears identical any dataset size (#1470; thanks to @feldsparlover for reporting).

plot_RadialPlot()

  • If the error column contains zero values, they are reset to the smallest between the non-zero errors in the dataset and 10-9. This avoids a crash when using the argument centrality = "mean.weighted", which is the default for this function (#1314).

  • The weighted median used to compute the central values when centrality = "median.weighted" now uses the precision as weight (similarly to what is done for the weighted mean), while before it incorrectly used the error (#1323).

read_BIN2R()

  • The function could crash if called with do.call() and some particularly odd inputs (#1260).

  • The function now throws an error instead of returning NULL when a file with the wrong extension is read (#1393).

  • The function will now look for files recursively if the path to a directory is provided (#1393).

read_Daybreak2R()

  • The function struggled with variable header lengths (#1262; thanks to @andrzejbluszcz for reporting).

  • The function will no longer crash if the data point entries have more than four columns (thanks to @andrzejbluszcz for reporting).

  • The import of binary .DAT files has been overhauled and made more correct; moreover, the function accepts both .DAT and .dat extensions for binary inputs, and supports DataType=Command records in ASCII files (#1263, #1266; thanks to @andrzejbluszcz for contributing code and datasets).

  • Trying to import multiple files by specifying a directory name failed because the generated path missed a directory separator (#1264).

read_PSL2R()

  • The function now returns NULL instead of throwing an error if a directory is provided and no PSL files are found within it (#1393).

read_RF2R()

  • The function now throws an error instead of returning NULL if a list containing elements other than character strings is provided (#1393).

read_SPE2R()

  • The function now throws an error instead of returning NULL if the filename provided does not exist (#1393).

read_XSYG2R()

  • Attributes from the record level are now all included in the @info slot, as long as they do not duplicate the attributes from the curve level. Hence, those attributes are now available for filtering (#1239; thanks to @DirkMittelstrass for reporting).

  • The function could crash if called with do.call() and some particularly odd inputs (#1260).

remove_RLum()

  • The function used to add spurious NULL records when an invalid record.id was specified, which in turn could cause a crash when displaying the object to the terminal (#1380).

report_RLum()

  • The function could crash if called with do.call() and some particularly odd inputs (#1260).

subset_SingleGrainData()

  • The function reports an helpful error instead of crashing if the given grains and positions table produces an empty selection (#1412).

Other changes

  • The internal function .normalise_curve() received support to normalise by the minimum value ("min"), the first value ("first"), the channel length ("intensity") or a positive number (e.g, 2.2). These new settings are automatically available to plot_RLum.Analysis() and the plot_RLum.Data.*() functions (#1250, #1300).

  • All the read_*() functions now process and validate the file argument through the same internal helper function. This allows them to support single and multiple files, URLs and directory paths (#1393).

  • The package no longer depends on RcppArmadillo. This has no visible impact to the user other than a small reduction in the package size (#1254).

  • The show method for an RLum.Analysis-class object would fail if the record slot contained NULL elements (fixed in commit f1846c5c).

  • The package has now reached 100% coverage! The test-coverage workflow action has been updated so that any decrease in coverage will be marked as a failure (#548).