<!-- NEWS.md was auto-generated by NEWS.Rmd. Please DO NOT edit by hand!-->

# Changes in version 1.2.1 (2026-03-25)

See also the [write-up for Luminescence v1.2.1 on the REPLAY
website](https://replay.geog.uni-heidelberg.de/REPLAY-website/post/2026/03/luminescence-release-1.2.1/).

## 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()`

- The function crashed if `norm = NA` was used (#1489; thanks to
  @JohannesFriedrich for reporting).

### `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.1 (2026-03-12)

See also the [write-up for Luminescence v1.2.0 on the REPLAY
website](https://replay.geog.uni-heidelberg.de/REPLAY-website/post/2026/03/luminescence-release-1.2.0/).

## 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](https://replay.geog.uni-heidelberg.de/REPLAY-website/post/2026/01/upcoming-breaking-changes-in-luminescence/)
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 `NA`s
  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()`

- When the input data is an `RLum.Results` object generated by
  `calc_AverageDose()`, `calc_CentralDose()`, `calc_MaxDose()`,
  `calc_MinDose()` or `calc_FiniteMixture()`, one or more lines (and
  corresponding labels) for the relevant results will be automatically
  drawn, unless explicitly suppressed by setting `line = NA` (#1452).

### `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).

------------------------------------------------------------------------

# Changes in version 1.1.2 (2025-12-12)

See also the [write-up for Luminescence v1.1.2 on the REPLAY
website](https://replay.geog.uni-heidelberg.de/REPLAY-website/post/2025/12/luminescence-release-1.1.2/).

**This package version requires R \>= 4.4**

## Removed functions and deprecations

- The functions `CW2pHMi()`, `CW2pLM()`, `CW2pLMi()` and `CW2pPMi()`
  (deprecated since 1.0.0) have been removed, but their functionality
  remains in the corresponding `convert_CW2*()` functions (#992).

- Functions `github_commits()`, `github_branches()` and
  `github_issues()` are now deprecated and will be removed in a future
  release (#1026).

- Functions `is.RLum()`, `is.RLum.Data()`, `is.RLum.Data.Curve()`,
  `is.RLum.Data.Spectrum()`, `is.RLum.Data.Image()`,
  `is.RLum.Analysis()` and `is.RLum.Results()`, and are now deprecated
  and will be removed in a future release. The best way of testing
  whether an object is of a given type is by using the `inherits()`
  function, as in `inherits(object, "RLum.Data.Curve")` (#1034).

## Bugfixes and changes

### `analyse_Al2O3C_CrossTalk()`

- The function no longer crashes if `dose_point` is misspecified
  (#1073).

- The function no longer crashes when called on an `RLum.Analysis`
  object rather than on a list of them (#1182).

### `analyse_Al2O3C_Measurement()`

- The function no longer crashes when called on RLum.Analysis objects
  that do not contain records of type `"OSL (UVVIS)"` or `"TL (UVVIS)"`
  (#1232).

### `analyse_baSAR()`

- The function no longer crashes if all objects in the input list are
  removed because empty (#1041).

- The dose response curves are no longer overplotted when there are
  fewer than 1000 MCMC iterations (#1058).

### `analyse_FadingMeasurement()`

- The function no longer crashes when called on an object with missing
  originator (#1130, \#1154).

- When called with a list containing object with multiple classes, the
  message produced reports the correct number of objects removed from
  the analysis (#1132).

- The function no longer crashes if the normalisation term is zero,
  which should never happen in real-life analyses, but it may occur if
  the input data is somewhat malformed (#1144).

- The function no longer crashes when attempting to remove undesired
  objects from a list-like class that overloads the `[<-` S3 method
  (#1236).

### `analyse_IRSAR.RF()`

- The function no longer crashes when `n.MC = NULL` is used with the
  `FIT` method (#1055).

- The function has been optimized to be faster during the bootstrap and
  sliding phases for the `SLIDE` and `VSLIDE` methods, with speed-ups in
  the region of 45% (#1210, \#1230).

### `analyse_pIRIRSequence()`

- The names in the curves legend are no longer cut off (#1206).

- Labels and legend in the rejection criteria plot are better positioned
  and no longer cut off (#1208).

- The dashed lines in the summarised DRC plot have been extended to
  reach the outer box instead of leaving small white gaps at the
  extremes (#1215).

- The space around the plots when using `plot_singlePanels = FALSE` has
  been reduced, so that plots can be a bit more detailed (#1219).

### `analyse_portableOSL()`

- The size of the contour labels for `mode = "surface"` can now be
  controlled with the `...` argument `labcex` and scale with `cex`
  (#1075).

- The size of the interpolation grid can be controlled via the `...`
  arguments `nx` and `ny` (#1077).

- The `coord` argument is now better validated to avoid a crash in case
  of misspecification (#1097).

### `analyse_SAR.CWOSL()`

- Empty subplots are inserted when `onlyLxTxTable = TRUE` to preserve
  the usual plot ordering. This prevents a crash that would otherwise
  occur if the option was set from `analyse_pIRIRSequence()` (#1186).

- The function crashed when applied to an object generated by
  `OSLdecomposition::RLum.OSL_decomposition()` with `plot = TRUE`; this
  was a regression introduced in v1.1.0 (#1188; thanks to
  @DirkMittelstrass for reporting).

- The visualisation of the ‘Checks’ (former rejection criteria) was not
  very intuitive. To improve the situation, we now display correct
  inequality symbols, such as `<=` or `>=` instead of `<>` (which was
  meant to be understood as a comparator). Furthermore, the recycling
  ratio now shows better the threshold depending on whether the ratio is
  smaller or larger than one.

- The function crashed if the `rejection.criteria` list specified a
  `NULL` value for `recuperation_reference` (#1204).

- The space around the plots when using `plot_onePage = TRUE` has been
  reduced, so that plots can be a bit more detailed (#1219).

- The labels in the rejection criteria plot are now shortened only when
  the available horizontal space is not wide enough (#1222).

### `bin_RLum.Data()`

- Validation of the `bin_size` (for `RLum.Data.Curve`), `bin_size.row`
  and `bin_size.col` (for `RLum.Data.Spectrum`) has been made stricter,
  so that invalid values produce an error (#1104).

### `calc_AliquotSize()`

- The function no longer hangs when `grain.size` is set to a small value
  and its minimum and maximum values are the same (#1114).

- The number of MC iteration is now correctly reported in the plot
  subtitle (#1115).

- The function now validates the `MC.iter` argument to avoid an ugly
  crash if a non-positive value is provided (#1124).

- The function now better validates its `grain.size` argument (#1152).

### `calc_CentralDose()`

- The profile log-likelihood plot is now cut at a log-likelihood of
  -100, so that for profiles with log-likelihoods more negative than
  that don’t get too squashed in the region of interest (#1227; thanks
  to @DirkMittelstrass for reporting).

### `calc_CosmicDoseRate()`

- The function is now more robust against `NA` values in its input
  arguments (#1101).

### `calc_EED_Model()`

- A crash that occurred with a small number of simulation was fixed
  (#1051).

- The error message in case of failed surface interpolation is now
  clearer and more complete (#1053).

### `calc_FadingCorr()`

- The function produces an error if `g_value` is an `RLum.Results`
  object with an unsupported originator instead of returning `NULL`
  (#1136).

### `calc_FiniteMixture()`

- The function no longer crashes if the De column contains zeros or
  missing values (#1146, \#1148).

- The legend for the components is positioned consistently also at `cex`
  values other than 1 and is drawn also when `pdf.colors = "gray"`
  (#1175).

### `calc_HomogeneityTest()`

- The function ignores all columns after the first two, as they could
  lead to crashes if they contained non-numeric values (#1224).

### `calc_Huntley()`

- A warning raised in rare occasions if the number of Monte Carlo
  iterations is very small has been fixed (#1048).

### `calc_OSLLxTxRatio()`

- The `Lx.data` and `Tx.data` arguments are now better validated
  (#1178).

### `calc_SourceDoseRate()`

- The function returns a clearer error message if dates are specified in
  an unexpected or ambiguous format (#1162).

### `calc_Statistics()`

- The function could crash if an error was exactly zero. This affected
  also the plotting functions that use `calc_Statistics()` (#1160).

### `combine_De_Dr()`

- It is now possible to control the random seeds used by the JAGS MCMC
  chains via the `method_control` argument (#1038).

### `fit_CWCurve()`

- If model fitting failed but an object named `fit` was present in the
  workspace, the function tried to use that one, which would lead to a
  crash or to unexpected results (#1081).

- The `output.table` field of the `RLum.Results` object returned now
  contains only columns corresponding to the components effectively
  fitted (#1083).

### `fit_EmissionSpectra()`

- The function makes better use of the plot area, leaving smaller
  margins around the plot (#1011).

### `fit_OSLLifeTimes()`

- The function throws a warning when the fit fails (#1005).

- The function makes better use of the plot area, leaving smaller
  margins around the plot (#1011).

### `install_DevelopmentVersion()`

- The function has been refactored so that it no longer depends on the
  deprecated `github_branches()` function (#1079).

### `plot_AbanicoPlot()`

- A warning was raised if the function returned early (for example due
  to invalid inputs) and the graphical device was off (#1001).

- The function now validates the `frame` argument in order to avoid
  crashing on misspecified values (#1036).

- The function no longer crashes when a small `plot.ratio` value is
  specified (#1062).

- The function now validates the `zlim` argument to avoid a crash if
  negative values are used with `log.z = TRUE` (#1063).

- The legend text now scales better at high `cex` values (#1066).

- If `summary.pos` contains multiple valid positions, the first one is
  used rather than generating warnings and not showing the summary
  (#1093).

### `plot_DoseResponseCurve()`

- The plot symbols are now correctly assigned for
  `mode = "extrapolation"` and in the legend. If `reg_points_pch` is
  specified, it must now be a vector of 3 elements, corresponding to the
  symbols to use for normal points, point 0 and repeated points,
  respectively (#1072).

- The baseline line in the sensitivity plot has been extended to reach
  the outer box instead of leaving small white gaps at the extremes
  (#1213).

- The space around the plots has been reduced, so that plots can be a
  bit more detailed (#1219).

### `plot_DRTResponse()`

- The function now suppresses the warnings generated by
  `graphics::arrows()` when datasets having wildly different
  distributions are plotted (#1184).

### `plot_Histogram()`

- Since version 1.0.0, setting `summary.pos` to one of “left”, “center”
  or “right” and `normal_curve = TRUE` resulted in the summary table not
  being visible (#1118).

### `plot_KDE()`

- Space at the bottom of the plot is no longer added when the boxplot is
  not plotted because `values.cumulative = FALSE` (#1110).

- The plot title and subtitle now respect the `cex` option (#1112).

- The function now better validates its input arguments (#1158).

### `plot_RadialPlot()`

- The function avoids some possible overprinting at the extremes of the
  z-axis labels and draws lines at the extremes of the ellipse (#1013).

- The appearance of the y-axis ticks has been improved in the case when
  the y-axis is particularly narrow (#1060).

- If `summary.pos` contains multiple valid positions, use the first one
  rather than generating warnings and not showing the summary (#1093).

- The functionality of the `stats` argument had regressed in version
  1.1.1, and now has been restored (#1106).

- The function better validates the `zlim` argument, to avoid crashes on
  misspecified axis limits if `log.z = TRUE` (#1140).

- The function now always returns invisibly the list of plot parameters,
  independently of the value of the `output` argument. This change made
  that argument redundant, so it was removed. This should have no impact
  on users; if specified, it will be ignored (#1142).

- The function stops with an error instead of crashing if the input
  contains only 1 data point (#1150).

- The function reports a message instead of throwing a warning when
  adding a line with negative value if `log.z = TRUE` (#1164, \#1168).

- The summary text and line labels now scale better at high `cex` values
  (#1170).

- The function no lonver crashes if `central.value` is a non-positive
  value when `log.z = TRUE` (#1173).

- Some graphical artifacts related to the 2-sigma bar, which would
  appear for extreme settings of the `central.value` argument have been
  fixed (#1194).

### `plot_RLum.Analysis()`

- Setting `records_max` to a value larger than the number of curves no
  longer generates spurious legend entries (#1017).

- The function now supports plotting of `RLum.Data.Image` objects
  contained in its records (#1028).

### `plot_RLum.Data.Image()`

- The function now supports the `...` argument `mtext` (#1031).

- The positioning of axis ticks and labels in raster and contour plots
  of low-resolution images has been improved, and pixel numbering starts
  consistently from 1 (#1191).

- The function gained support for the arguments `digits` and
  `scientific`. Moreover, it is possible to specify multiple plot titles
  in `main`. Thanks to @Zink-Antoine for the contribution (#1197).

### `plot_RLum.Data.Spectrum()`

- The function doesn’t crash anymore if `bg.spectrum` is used and `ylim`
  specifies an interval that doesn’t contain any background channels
  (#1019).

- The function doesn’t crash anymore if the value of `frames` given is
  too large when `plot.type = "multiple.lines"` (#1021).

- The legend text now scales better at high `cex` values (#1068).

- The function now makes better use of the plot area by setting smaller
  margins and reducing the spacing between axis elements (#1070).

### `read_PSL2R()`

- The function gained a `pattern` argument to refine the list of files
  to read when a directory path is specified (#1099).

### `read_SPE2R()`

- The function no longer crashes if `frame.range` is misspecified
  (#1138).

### `subset.Risoe.BINfileData()`

- The function also updates the `.RESERVED` slot (if present) to keep
  only the elements selected (#1089).

### `verify_SingleGrainData()`

- The function crashed on empty `RLum.Analysis-class` objects. Now a
  warning and `NULL` is returned.

## Other changes

- The `ExampleData.portableOSL` file has been updated with surface
  coordinates (#1095).

- Documentation for all example data (including synthetic datasets) is
  now more easily findable from RStudio (#1166; thanks to
  @DirkMittelstrass for reporting).

------------------------------------------------------------------------

# Changes in version 1.1.1 (2025-09-11)

See also the [write-up for Luminescence v1.1.1 on the REPLAY
website](https://replay.geog.uni-heidelberg.de/REPLAY-website/post/2025/09/luminescence-release-1.1.1/).

## New functions

- `correct_PMTLinearity()`: A helper function to correct luminescence
  signals measured with a PMT for count linearity (#920).

## Removed functions and deprecations

- Functions `calc_Kars2008()` (defunct since 0.9.26),
  `Analyse_SAR.OSLdata()` (since 1.0.0), `PSL2Risoe.BINfileData()`
  (since 1.0.0) and `Second2Gray()` (since 1.0.0) have been removed from
  the package. Their functionality can be found in functions
  `calc_Huntley2006()`, `analyse_SAR.CWOSL()`,
  `convert_PSL2Risoe.BINfileData()` and `convert_Second2Gray()`,
  respectively.

- Function `get_Risoe.BINfileData()` has been removed as it was not used
  and provided no benefits to the user (#945).

## Bugfixes and changes

## `add_metadata<-()`

- The function throws an error if trying to assign a `NULL` value
  instead of silently ignoring it (#946).

### `analyse_Al2O3C_ITC()`

- The function returns early if the fitting of the dose response curve
  fails (#979).

### `analyse_Al2O3C_Measurement()`

- The function allows to specify the `cross_talk_argument` as a numeric
  vector of length 3, as was already documented (#930).

### `analyse_SAR.CWOSL()`

- The function crashed if any of the curves had `NA` as its `recordType`
  (#867).

### `apply_CosmicRayRemoval()`

- The `method` argument of `smooth_RLum()` was not reachable via `...`
  as the `apply_CosmicRayRemoval()` already has an argument called
  `method`. Now the `...` argument is called `method_smooth_RLum` and
  works as expected (9b27467).

- The function crashed if method = “Pych”`and`MARGIN = 1\` were
  specified. The function now better validates its inputs and no longer
  returns invisibly but normally (#987).

### `calc_AliquotSize()`

- The legend text now scales better at non-default cex settings (#849).

### `calc_Huntley2006()`

- If the user set the `n.MC` argument, this was also used in the fitting
  of the dose response curve. This was not the expected behaviour, and
  resulted in poor performance (a 2x slowdown for `n.MC = 10000`). This
  regression was introduced in version 1.0.0 (#867).

### `calc_MaxDose()`

- The function crashed if `sigmab` was set to a very small value (#898).

### `calc_MinDose()`

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

- The function crashed when all rows in the input data set contained
  `NA` values (#915).

### `calc_Statistics()`

- The computation of the weighted median is now correct, while before it
  corresponded to the simple (unweighted) median (#905).

### `fit_CWCurve()`

- The function hanged on particularly small datasets as it tried to fit
  too many components for the available data (#953).

### `fit_DoseResponseCurve()`

- The object returned now contains an additional `.De.raw` column to
  store the calculated De value computed by the fitting function “as
  is”, without setting meaningless results to `NA`. The `De` and
  `.De.raw` columns differ only for `mode = "interpolation"`, where the
  first sets the De to `NA` if negative, while the latter doesn’t. It is
  then up to the user to decide what to do with those values, bearing in
  mind that they may be arbitrary when negative (#957).

- The message reported for `fit.method = "QDR"` now states correctly
  whether the fit succeeded or failed (#961).

- The computation of De.MC, De.Error and HPDI for
  `mode = "interpolation"` has been modified to account correctly for
  possible negative De values resulting from the fit (#963).

- Previously, a single `NA` value in the Monte Carlo results prevented
  the computation of Highest Density Intervals (HPDI). This limitation
  has been removed, and now HPDIs are reported in more cases (#976).

- The columns of the `results$De` data frame are now reported in a
  different order; an additional “Mode” column reports the value of the
  `mode` argument; columns meant for internal use have been moved to the
  end and their names are now prefixed with `.` (#974).

### `fit_LMCurve()`

- The automatic correction of the x-axis limits when `log = "x"` is
  specified and the lowest value is set to `0` threw the correct warning
  but actually did nothing (38e4324).

### `fit_OSLLifeTimes()`

- The function ensures that the `signal_range` argument doesn’t contain
  negative values instead of crashing (#896).

### `get_RLum()`

- The function doesn’t crash anymore on `RLum.Analysis` objects if using
  the `record.id` argument removes all available records (#873).

- An internal optimization increased the performance of the function.
  The difference is not perceivable on single calls to `get_RLum()`, but
  the change brings a visible speed up when `merge_RLum()` is called
  over a sufficiently large number of `RLum.Analysis` objects (#875).

### `merge_Risoe.BINfileData()`

- The function gained argument `verbose` to allow disabling the output
  from `read_BIN2R()` and `write_R2BIN()` (#950).

### `plot_AbanicoPlot()`

- The positioning of the y-axis label has been improved to be centred
  around the zero line (#847). The z-axis tickmarks and labels are
  better drawn at non-default cex values (#865).

- The minor grid lines were drawn incorrectly in a rotated plot (#849).

- Some plot elements didn’t scale correctly at non-default cex values
  (#861, \#879).

- The `frame` argument is now respected also when the plot is rotated
  (#863).

- The weighted median is computed correctly when `summary = "median"`
  and `summary.method = "weighted"` are used (#905).

### `plot_DoseResponseCurve()`

- We added support for the `log` graphical parameter, which can be used
  if the fit was obtained with mode other than `"extrapolation"` (#820).

- The normal curve drawn as part of the histogram plot could appear very
  jagged or even as a straight line, as it could happen that too few
  points were actually used when drawing the curve (#843).

- The legend symbols did not match anymore the plotted regeneration/dose
  points. This also affected functions such as `analyse_SAR.CWOSL()` and
  `analyse_pIRIRSequence()` (9ba54e65).

- The legend positioning can now be controlled via the `...` argument
  `legend.pos` (#959).

### `plot_DRCSummary()`

- The dose-response curve is now plotted as expected, after a regression
  in 1.1.0 caused the function to produce an empty plot (#969).

### `plot_DRTResults()`

- Points didn’t scale correctly at non-default `cex` values (#879).

- Option `summary = "weighted$median"` is now officially supported
  (#905).

### `plot_Histogram()`

- Option `summary = "median.weighted"` is now officially supported
  (#905).

### `plot_KDE()`

- Outlier points didn’t scale correctly at non-default `cex` values
  (#879).

- The weighted median is computed correctly when `summary = "median"`
  and `summary.method = "weighted"` are used (#905).

### `plot_RadialPlot()`

- Option `summary = "median.weighted"` is now officially supported
  (#905).

### `plot_Risoe.BINfileData()`

- Input arguments are validate more strictly to avoid unexpected crashes
  in case of misspecification (#964).

- The x-axis label for TL curves now reports temperature rather than
  time, consistently with the data shown (#971).

### `plot_RLum.Analysis()`

- The legend text now scales better at non-default `cex` settings
  (#854).

### `plot_RLum.Data.Curve()`

- The function gained a new logical argument `interactive` that enables
  interactive plotting of curves using `plotly::plot_ly()`. It requires
  the suggested package `'plotly'` to be installed (e4746eaa).

### `plot_RLum.Data.Spectrum()`

- Types `image` and `contour` gained more control of the contour line
  labels through the argument `labcex`.

- For plot types `"image"` and `"multiple.lines"` the `...` logical
  argument `legend` was added.

- Plot type `"image"` further gained a legend with support through `...`
  for `legend.pos`, `legend.horiz` and `n_breaks` to control the number
  of colours in the graphic.

### `read_BIN2R()`

- The `FNAME` metadata field is no longer left empty if the BIN-file
  didn’t specify one, but it’s populated with the BIN-file name without
  extension. This is the behaviour that was present up to version
  0.9.26, but version 1.0.0 had regressed it (#928).

### `read_XSYG2R()`

- Add support for the new function `correct_PMTLinearity()` (#920).

### `smooth_RLum()`

- Add support for the Poisson smoother of Carter et al. (2018), which
  can be accessed by setting `method = "Carter_etal_2018"`. This is
  helpful to ensure that the dark-background counts signals measured by
  a photomultiplier tube follow a Poisson statistic, and smooths
  non-conforming values according to an average over four neighbours
  (#921).

### `trim_RLum.Data()`

- The function crashed if both values specified in the `trim_range`
  argument exceeded the number of channels available (#871).

### `use_DRAC()`

- Report the message produced by the DRAC server more reliably in case
  of error (#982).

------------------------------------------------------------------------

# Changes in version 1.1.0 (2025-06-11)

See also the [write-up for Luminescence v1.1.0 on the REPLAY
website](https://replay.geog.uni-heidelberg.de/REPLAY-website/post/2025/06/luminescence-release-1.1.0/).

## New functions

- `remove_SignalBackground()`: A user-friendly method to subtract
  background signals from various curves in `RLum.Analysis` objects
  without resorting to `lapply()` loops. Depending on the record type,
  the function identifies pairs of curves; for instance, if in a
  sequence, a `TL` curve is immediately followed by another `TL` curve,
  the second curve is recognised as the background signal, subtracted
  using `merge_RLum()` and subsequently removed from the object (if
  desired). Alternatively, a set of potential background curves can be
  specified.

- `remove_RLum()`: This function further completes the set of methods
  that can handle and modify `RLum-class` objects. It operates on
  `RLum.Analysis` objects or a `list` of such objects to remove unwanted
  records from datasets. Although the function calls `get_RLum()` and
  relies on its functionality, the new implementation facilitates a more
  logical workflow and analysis pipeline.

- `.as.latex.table()`: Converts `RLum.Results` objects where suitable to
  `LaTeX` ready tables, for instance, objects produced by `use_DRAC()`.
  The function has been present in the package as an internal function
  for many years; now it is exported and better linked to make it
  discoverable.

## New datasets

- `RF70Curves` is a new dataset consisting of two IR-RF curves measured
  with the RF70 protocol. This new dataset provides a more realistic
  example for `analyse_IRSAR.RF()`.

## Breaking changes

- Function `get_Quote()` is no longer exported, but remains available as
  an internal function. This is unlikely to affect any user of the
  package, as the function was only meant to report a random quote at
  startup (#644).

- In the functions `fit_DoseResponseCurve()` and `plot_GrowthCurve()`,
  the `fit.method` option `LambertW` was replaced by the more correct
  term `OTOR`.

- Argument `cex.global` has been removed from `plot_DoseResponseCurve()`
  (and consequently also from `plot_GrowthCurve()`), and if set it will
  be silently ignored. Users can set the `cex` graphical parameter via
  `...` in its place (#831).

- The `fit.method` and `fit.advanced` arguments of function
  `fit_LMCurve()` have been removed. The default fitting method has been
  changed from `port` to `LM`, and support for the `port` algorithm has
  been removed. From now on, argument `fit.method` is silently ignored,
  unless `fit.method = 'port'` is used, in which case a deprecation
  warning is thrown (#793).

- The fundamental physical constants used in the package (such as
  Boltzmann constant, Planck constant, etc.) have been uniformed to
  those reported in the [NIST Reference on Constants, Units and
  Uncertainty](https://physics.nist.gov/cuu/Constants/). This may affect
  the numerical results of the following functions: `calc_FastRatio()`,
  `calc_Huntley2006()`, `calc_SourceDoseRate()`,
  `calc_ThermalLifetime()`, `convert_Activity2Concentration()`,
  `convert_Wavelength2Energy()`, `fit_CWCurve()`, `fit_LMCurve()`,
  `fit_SurfaceExposure()`, `fit_ThermalQuenching()` (#693).

## Bugfixes and changes

### `analyse_baSAR()`

- The function crashed if only one aliquot was kept (#834).

### `analyse_FadingMeasurement()`

- The function crashed if the number of `Lx` and `Tx` curves was not
  equal when `structure = c("Lx", "Tx")`, which is the default. The
  check that the number of points within each pair of curves has also
  been improved, and the function now produces more helpful error
  messages (#616).

- The function tests are now less rigorous for different `Lx` and `Tx`
  sizes. While they should match, numerical rounding issues in the data
  returned by the measurement devices could previously result in
  rejection of records, although this had no actual meaning for the data
  analysis.

### `analyse_IRSAR.RF()`

- The legend and subtitle texts now scale better at non-default cex
  settings (#803).

- The printing of progress bars and messages to the terminal can now be
  controlled via the `...` argument `verbose`. Previously this could
  only be done via the `txtProgressBar` argument (which is still
  supported), but the new option makes the interface consistent with
  most other functions (#805).

- The `mtext` and `cex` options are respected if `method = "None"`
  (#807).

- The residual plot correctly respects the logarithmic transformation of
  the x-axis when `log = "x"` or `log = "xy"` are specified (#814,
  \#825).

- The function now deals correctly also with input objects containing
  multiple curves (#816).

- The residual indicator rectangle, which is drawn when `method` is
  either `SLIDE` or `VSLIDE`, is also drawn when `log = "x"` (#821).

- The plotting of the density is silently disabled if `n.MC = NULL`,
  which avoids a spurious warning (#823).

### `analyse_pIRIRSequence()`

- The function now respects the `cex` graphical argument, and its plot
  output has been subtly improved thanks to various fixes that have
  occurred especially in `plot_DoseResponseCurve()` (#831).

### `analyse_portableOSL()`

- The function now returns an error if `mode` is something other than
  `"profile"` or `"surface"`.

- The `mode` argument was not respected when operating over a list of
  objects (#673).

- The function crashed when using `mode = "surface"` if the plotting
  limits were too tight and left only one point (#675).

- The check on the validity of the `signal.integral` argument has been
  improved, and now it occurs only once, so at most one warning is
  raised if the argument is set to a value exceeding the valid range
  (#678, \#680).

- The function returns a clearer message when no x-coordinates were
  measured and `mode = "surface"` was used (#682).

- The `cex` and `type` graphical parameters can now configured via the
  `...` argument (#684).

- The expected sequence pattern of the input object is validated more
  thoroughly to avoid crashes in case of misspecification (#687).

- The graphical `...` argument `contour` never produced a meaningful
  contour plot due to an internal error (#686). Along, arguments
  `contour_nlevels` and `contour_col` are now supported through `...` to
  better control the number and colour of contour lines.

### `analyse_SAR.CWOSL()`

- Add support for `fit.method = 'OTORX'` following the changes in
  `fit_DoseResponseCurve()`; this change includes the new argument
  `dose.points.test` that is only of use in combination with the `OTORX`
  fit.

- Add new graphical output if the measurements were single grain
  measurements, in such case a disc with the position and grain number
  marked in shown. This plot replaces the IRSL curve check plot, but
  only for single grain data (#797).

- The rejection criteria plot was rewritten and now provides an easier
  to grasp visual feedback (#797, \#798).

- The `IRSL`/`Single Grain` panel swapped place with the rejection
  criteria panel; the plot numbers remained unchanged to avoid
  regression.

- More code optimisation for better readability (#802)

### `analyse_SAR.TL()`

- A check on the `sequence.structure` argument ensures that a “SIGNAL”
  entry has been specified (#779).

### `calc_AliquotSize()`

- The new argument `sample_carrier.diameter` allows to specify a value
  for the diameter of the sample carrier, which up to now was hardcoded
  to the very common 9.8 mm size (#623).

- Several graphical parameters can now configured via `...` arguments,
  so that the plot appearance can be fully customized (#671).

### `calc_AverageDose()`

- A bug in the implementation prevented the default plot settings from
  being modified via `...` as advertised. Now custom settings are
  respected (#658).

### `calc_FiniteMixture()`

- The function doesn’t crash anymore if the `n.components` argument
  specifies non-consecutive values (#691).

- The function sometimes failed to plot some of the densities when the
  number of components was set to a value of 8 or more (#704).

- The density plots would not always be coloured completely, but
  especially for high values of `sigmab` there would be an unfilled area
  at the base of the densities (#706).

- If the very first iteration over the components during plotting was
  skipped, then the function crashed as a quantity computed only in that
  iteration was not available. This happened for very specific
  combinations of `sigmab` and `n.components` (#708).

- Another crash occurred when height of the largest density curve could
  not be estimated due to the presence of too many `NA` values in the
  intermediate computations (#710).

- The check for significance of each component added to the model has
  been corrected to be more statistically rigorous (#703).

- Blank gaps appearing to the sides of the proportion of components plot
  for high number of components have been removed (#713), as well as
  extra slices appearing due to rounding errors (#715).

- The plot can be better configured via the new `plot.criteria` argument
  to control whether the statistical criteria curves should be drawn.
  Moreover, support for the `...` options has been added: `cex` to
  control the overall scaling, `main.densities`, `main.proportions` and
  `main.criteria` to set the subplot titles (#717).

- Plots are now generated even when results contain `NA` values, as they
  in general don’t affect the plot. However, when that happens we report
  it in the plot subtitle (#718).

### `calc_Huntley2006()`

- Support was added for multicore computations via the `cores` argument,
  and for the nls-fitting control options `maxiter` and `trace`.

- The fitting of the simulated curve with the GOK model has been made
  more robust: when an initial fit of the model fails, the fit is
  attempted again with 10 different values for `D0` and the best fit is
  used. This should reduce the number of occasions in which the error
  message “Could not fit simulated model curve, check suitability of
  model and parameters” is reported (#660).

- The function crashed if all simulated Lx/Tx values were identical and
  approximately zero, which could happen if the `rhop` argument was set
  to a large enough value (#725).

- An error message has been improved so that it doesn’t suggest setting
  the ‘fit.bounds = FALSE’ argument if it has already been set (#729).

- The computation of the x-axis limits has been improved to avoid having
  too much unused horizontal space, especially for
  `mode = "extrapolation"` (#731).

- The scaling of the plot can now be controlled via the `cex` argument
  (#735).

- The plot margins are set more precisely and avoid the summary text to
  be cut off (#737).

### `calc_MinDose()`

- The function now warns if the number of bootstrap replicates is too
  low to perform the loess fitting (#721).

### `calc_OSLLxTxRatio()`

- The function returned a warning for wrong integral settings for the
  `Tx` curve even if no `Tx` curve was provided.

- The function does not check any more of different object types for
  `Lx.data` and `Tx.data` but validate objects for allowed types (this
  should have no user-visible effects).

### `convert_Concentration2DoseRate()`

- The function validates its input values more thoroughly (#613).

### `extract_IrradiationTimes()`

- The function tries a little bit harder to extract the correct duration
  of TL steps, rendering the data output hopefully a little bit more
  intelligible (#651).

- The function gained a new argument called `return_same_as_input`, with
  default value of `FALSE`. If set to `TRUE`, the input object (usually
  an `RLum.Analysis` object or a `list` of them) is returned with
  updated info elements for `IRR_TIME` and `TIMESINCEIRR`. This makes
  the `RLum.Analysis` object compatible with functions that explicitly
  search for those two objects, such as those in the
  `'OSLdecomposition'` package (#752).

### `fit_DoseResponseCurve()`

- The function now allocates less memory for storing intermediate values
  (#610).

- Add initial support for `OTORX` fitting following Lawless and
  Timar-Gabor 2024 (#677). The code implementation follows the Python
  reference by [jll2](https://github.com/jll2/LumDRC/blob/main/otorx.py)
  with an addition for an allowed offset parameter `a` set if
  `fit.force_through_origin = FALSE`. This also enables to support
  `mode = "extrapolation"` (thanks to John Lawless for his input).

- The code of the function was optimised in several places to improve
  code readability and reduce redundant calls.

- The models for `EXP`, `EXP+LIN`, `EXP+EXP` and `GOK` are now available
  in C++. This cut the required computation times in half in benchmark
  scenarios. More importantly, this performance scales with the number
  of Monte Carlo runs.

### `fit_EmissionSpectra()`

- Fix crash when attempting to plot a frame with non-positive counts
  (#761).

### `fit_LMCurve()`

- If the user asks logarithmic scaling in the y-axis, using either
  `log = "y"` or `log = "xy"`, this is now ignored when plotting
  residuals and component contributions (#755).

- The plot has been slightly reworked to reduce the cases of “margin too
  large” errors and to work better at high settings of `cex` (#757).

- Missing values in the input data are now silently removed (#759,
  \#763).

- The plotting of residuals, component contributions and legend can now
  be disabled, and the legend position can be controlled (#785).

- The error computed when using option `fit.calcError = TRUE` is now
  returned correctly, instead of being left to `NA` (#789).

- Argument `bg.subtraction` also accepts the option `"none"` to disable
  background subtraction even if `values.bg` is provided (#795).

### `fit_SurfaceExposure()`

- It is now possible to specify different values for the light
  attenuation coefficient `mu` when a list of input data is provided
  (#667).

### `fit_ThermalQuenching()`

- The `trace` option, which can be specified via the `method_control`
  argument, is now respected.

- The model now get internally reformulated into a mathematically
  equivalent expression that is easier to fit. This should reduce the
  number of occasions when the function fails to find a valid solution
  and improve the uncertainty estimation (#696).

### `get_RLum()`

- The argument `subset` can now be provided as a character that
  represents a logical expression. Before, it always required a logical
  expression, but this may lead to odd effects due to the early
  evaluation happening in R and might not be wanted. Providing `subset`
  as a character is now a viable workaround in those situations.

### `import_Data()`

- The function uses the most common formats (BINX and XSYG) before
  trying all others.

### `merge_RLum.Data.Curve()`

- The function does no longer stops for differing channel resolutions,
  but it does issue a warning. The user is responsible for the
  consequences.

### `plot_DetPlot()`

- The logic for multicore support was incorrect, which resulted in
  always starting a parallel cluster even when `multicore = FALSE`
  (#742).

### `plot_DoseResponseCurve()`

- The response curve always tries to the get the 0 point in the mode
  `interpolation` and `alternate` (#677).

- Minor graphical polish to limit overplotting and also plot a density
  curve for the `L_n/T_n` signal.

- If `mode = "alternate"`, the message that the equivalent dose could
  not be fitted is no longer shown.

- Argument `cex.global` has been removed and will be silently ignored
  (#831).

### `plot_DRCSummary()`

- Add support for `fit.method = 'OTORX'` following the change in
  `fit_DoseResponseCurve()` (#677).

### `plot_DRTResults()`

- The summary and legend texts now scale better at non-default cex
  settings (#765).

- Argument `given.dose` is better validated against misspecifications,
  and setting it to 0 is equivalent to leaving it at its default `NULL`
  value, which corresponds to avoiding data normalization (#767, \#799).

- The function crashed when multiple inputs were used with
  `boxplot = TRUE` and all preheat values were identical (#769).

- Plot title, summary text and legend are now better positioned (#773,
  \#774, \#781).

- A bug in the way colours and symbols are assigned to plot points has
  been fixed (#777).

- The horizontal axis doesn’t include anymore a spurious extra tick that
  didn’t correspond to any aliquot (#783).

### `plot_GrowthCurve()`

- Add support for `fit.method = 'OTORX'` following the change in
  `fit_DoseResponseCurve()` (#677).

- Argument `cex.global` has been removed and will be silently ignored
  (#831).

### `plot_Histogram()`

- The function now doesn’t produce warnings when the input consists of a
  single-column data frame, as it assumes that the De error is 10^-9
  (#744).

- The right margin is now smaller when errors are not plotted, as there
  is no need to leave space for the standard error axis (#748).

- The summary text now scales better at non-default cex settings (#750).

### `plot_KDE()`

- The function validates its input values more thoroughly (#635).

- Setting `summary.pos` to one of “left”, “center” or “right” resulted
  in the summary table not being visible (#642).

- Argument `output` has been removed, and it will be ignored if set
  (#700).

### `plot_RadialPlot()`

- The function validates its input values more thoroughly (#639).

- The legend text now scales better at non-default cex settings (#746).

### `plot_RLum.Data.Curve()`

- We added comprehensive support for base R plotting arguments utilised
  by `plot.default()` and `par()`. This enhancement ensures that all
  available arguments are fully supported (#646).

- The function gained a new logical argument named `auto_scale`. When
  set in conjunction with either `xlim` or `ylim`, this argument
  automatically adjusts the plot range to align with the corresponding
  settings for `xlim` or `ylim`. For instance, if a user intends to plot
  OSL curves but initially selects the `xlim` range `c(10:30)` to
  examine the background, the initial count values may be excessively
  large, resulting in limited visibility. With the introduction of the
  `auto_scale` option, the `ylim` values are automatically adjusted to
  compensate for this scenario. The `auto_scale` argument is also
  accessible through `plot_RLum.Analysis()` and `plot_RLum()` (#646).

### `plot_RLum.Data.Spectrum()`

- The channel-wise background subtraction was essentially broken if a
  background spectrum with the same setting was provided. The function
  always calculated the arithmetic mean. This was fixed, and the manual
  updated accordingly.

- If a background spectrum was provided, the behaviour of the plot
  output was sometimes hard to understand without knowledge of the
  underlying code. This behaviour was improved and now `ylim` will also
  affect the background spectrum if `bg.channels = NULL` (the default).

- The function could crash if column names were missing and the
  1bg.spectrum\` argument was used (#726).

### `read_TIFF2R()`

- The argument `file` can now be provided as a `list` or a character
  vector.

- The function gained a new logical argument called `merge2stack` that
  can be used if `file` is either a `list` or a character vector of
  length \> 1. If set to `TRUE`, images are combined into one image
  stack.

### `read_XSYG2R()`

- A redundant computation has been removed, and the function is now
  marginally faster on files where the detector is not a spectrometer
  (#753).

- Prepare import for an updated version of LexStudio2 (\>=v2.31.1) where
  the horizontal hardware binning finally works after \>10 years, but
  the changes introduce a lot of `NaN` values that would cause a crash
  of the function.

- Minor code refactoring for a small speed boost if spectrometer
  measurements are imported.

### `scale_GammaDose()`

- Argument `plot_singlePanels` now works as documented, that is it
  produces all plots in a single page when set to `FALSE` (default), and
  one plot per page when set to `TRUE` (#698).

### `sort_RLum()`

- The sorting mechanism for `RLum.Analysis` objects has been enhanced.
  It now enables sorting based on multiple parameters, including sorting
  all available `info_elements` in a prioritised manner (#606, \#620).

- Sorting now works on a list of `RLum.Analysis` objects. If the list
  contains elements of a different type, they are passed through
  unchanged. The output is again a list (#620).

### `structure_RLum()`

- The function now returns a less messy data frame because it
  encapsulates `.pid` and `info` as lists within the data frame. The
  function is primarily used internally to facilitate a rapid
  exploration of `RLum.Analysis` object structures. However, the change
  may potentially break existing code in extremely rare circumstances.

### `template_DRAC()`

- The function now throws messages instead of warnings for wanted
  coercions; however, it will be hard on failed coercions that would
  cause `use_DRAC()` to fail.

### `use_DRAC()`

- The function now checks for DRAC specific URL parts if a custom URL is
  provided; this avoids long searches for unspecific errors.

- Due to the internal masking of submitted values, the initial row order
  got mixed up; regression from \#438. The order is maintained and the
  row index corrected; in other words, the masking should now be again
  invisible to the user.

### `verify_SingleGrainData()`

- The function crashed if an object originating from `read_XSYG2R()`
  contained positions in its `info` field (#740).

### `write_R2TIFF()`

- The function now supports the export of more than one image slice.

## Internals

- The internal function `create_UID()` has undergone further
  optimisation for speed, resulting in a significant performance
  improvement. Additionally, it now generates a hash value with a
  consistent length instead of a time stamp with a random number.
