Skip to content

Commit 85a0703

Browse files
JamesHWadeclaude
andcommitted
fix: improve error handling and add tests for advanced baseline methods
- Add warnings to tryCatch fallbacks instead of silent failures - Add NA/Inf input validation with informative warnings - Add convergence warnings for iterative algorithms (aspls, iarpls) - Move parameter validation from constructors to prep() methods - Add length checks to all parameter validation - Fix .arpls_simple by removing dead mad_val code - Update aspls documentation to accurately describe global lambda averaging - Add baseline_alpha() and baseline_window() parameter functions - Fix tunable() specifications to reference proper parameter functions - Add comprehensive test files for all four new baseline methods - Package check passes with 0 errors, 0 warnings, 0 notes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent ef6b8d5 commit 85a0703

File tree

8 files changed

+768
-56
lines changed

8 files changed

+768
-56
lines changed

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,11 +618,13 @@ export(align_segment_length)
618618
export(all_pass)
619619
export(assess_deconv_quality)
620620
export(augment)
621+
export(baseline_alpha)
621622
export(baseline_asymmetry)
622623
export(baseline_degree)
623624
export(baseline_half_window)
624625
export(baseline_lambda)
625626
export(baseline_span)
627+
export(baseline_window)
626628
export(bigaussian_peak_model)
627629
export(bin_width)
628630
export(check_axis_consistency)

R/baseline-morphological.R

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,6 @@ step_measure_baseline_morphological <- function(
6262
skip = FALSE,
6363
id = recipes::rand_id("measure_baseline_morphological")
6464
) {
65-
if (!is.numeric(window_size) || window_size < 3) {
66-
cli::cli_abort("{.arg window_size} must be a number >= 3.")
67-
}
68-
if (!is.numeric(iterations) || iterations < 1) {
69-
cli::cli_abort("{.arg iterations} must be a positive integer.")
70-
}
71-
7265
recipes::add_step(
7366
recipe,
7467
step_measure_baseline_morphological_new(
@@ -113,6 +106,24 @@ prep.step_measure_baseline_morphological <- function(
113106
) {
114107
check_for_measure(training)
115108

109+
# Validate parameters
110+
if (
111+
!is.numeric(x$window_size) ||
112+
length(x$window_size) != 1 ||
113+
x$window_size < 3
114+
) {
115+
cli::cli_abort(
116+
"{.arg window_size} must be a single integer >= 3, not {.val {x$window_size}}."
117+
)
118+
}
119+
if (
120+
!is.numeric(x$iterations) || length(x$iterations) != 1 || x$iterations < 1
121+
) {
122+
cli::cli_abort(
123+
"{.arg iterations} must be a positive integer, not {.val {x$iterations}}."
124+
)
125+
}
126+
116127
if (is.null(x$measures)) {
117128
measure_cols <- find_measure_cols(training)
118129
} else {
@@ -121,8 +132,8 @@ prep.step_measure_baseline_morphological <- function(
121132

122133
step_measure_baseline_morphological_new(
123134
measures = measure_cols,
124-
window_size = x$window_size,
125-
iterations = x$iterations,
135+
window_size = as.integer(x$window_size),
136+
iterations = as.integer(x$iterations),
126137
role = x$role,
127138
trained = TRUE,
128139
skip = x$skip,
@@ -134,10 +145,25 @@ prep.step_measure_baseline_morphological <- function(
134145
#' @noRd
135146
.morphological_baseline <- function(y, window_size, iterations) {
136147
n <- length(y)
148+
149+
# Validate input
150+
if (n < 3) {
151+
cli::cli_warn("Input vector has fewer than 3 points, returning original.")
152+
return(y)
153+
}
154+
if (anyNA(y)) {
155+
cli::cli_warn(
156+
"Input contains {sum(is.na(y))} NA value{?s}. NA values will propagate."
157+
)
158+
}
159+
if (any(!is.finite(y) & !is.na(y))) {
160+
cli::cli_abort("Input contains Inf/-Inf values. Cannot compute baseline.")
161+
}
162+
137163
baseline <- y
138164
half_window <- window_size %/% 2
139165

140-
# Multiple erosion iterations
166+
# Multiple erosion iterations (local minimum)
141167
for (iter in seq_len(iterations)) {
142168
eroded <- numeric(n)
143169
for (i in seq_len(n)) {
@@ -148,7 +174,7 @@ prep.step_measure_baseline_morphological <- function(
148174
baseline <- eroded
149175
}
150176

151-
# Single dilation to smooth
177+
# Dilation (local maximum) to recover baseline level after erosion
152178
dilated <- numeric(n)
153179
for (i in seq_len(n)) {
154180
start <- max(1, i - half_window)

0 commit comments

Comments
 (0)