Skip to content

Commit 8c7d3c2

Browse files
include target snr
1 parent d02e55c commit 8c7d3c2

File tree

6 files changed

+160
-15
lines changed

6 files changed

+160
-15
lines changed

R/segment.R

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,19 @@
1717
#' @param redshift Numeric, the redshift to apply for wavelength correction. Defaults to 0 (no correction).
1818
#' @param scale_fn A function used to scale each row of the 2D representation of the data cube.
1919
#' Defaults to \code{\link[base]{scale}}. If you have a custom scaling function, pass it here.
20+
#' @param target_snr Optional minimum accepted SNR per cluster. When supplied,
21+
#' Capivara chooses the largest number of clusters whose minimum cluster SNR
22+
#' remains above this threshold.
23+
#' @param var_cube Optional variance cube matching the input cube. Used only
24+
#' when \code{target_snr} is supplied.
25+
#' @param k_values Optional candidate cluster counts tested when
26+
#' \code{target_snr} is supplied.
27+
#' @param wavelength_range Optional wavelength interval used to compute SNR when
28+
#' \code{target_snr} is supplied.
29+
#' @param snr_stat Either integrated SNR or median per-wavelength SNR when
30+
#' \code{target_snr} is supplied.
31+
#' @param variance_inflation Multiplicative factor applied to propagated
32+
#' variances when \code{target_snr} is supplied.
2033
#'
2134
#' @details
2235
#' Steps performed by the function:
@@ -26,7 +39,9 @@
2639
#' \item Scales the data row-wise using \code{scale_fn}.
2740
#' \item Computes pairwise distances between rows using \code{\link{torch_dist}}.
2841
#' \item Performs hierarchical clustering using Ward's D2 method via \code{\link[fastcluster]{hclust}}.
29-
#' \item Cuts the dendrogram into \code{Ncomp} clusters and reshapes the results into a 2D cluster map.
42+
#' \item Cuts the dendrogram into \code{Ncomp} clusters and reshapes the results into a 2D cluster map,
43+
#' or, when \code{target_snr} is supplied, chooses the largest cut whose minimum cluster SNR
44+
#' remains above the requested threshold.
3045
#' \item Calculates the signal-to-noise ratio (SNR) for each cluster.
3146
#' }
3247
#'
@@ -56,8 +71,35 @@
5671
#' }
5772
#'
5873
#' @export
59-
# Cluster the IFU cube data
60-
segment <- function(input, Ncomp = 5, redshift = 0, scale_fn = median_scale) {
74+
segment <- function(input,
75+
Ncomp = 5,
76+
redshift = 0,
77+
scale_fn = median_scale,
78+
target_snr = NULL,
79+
var_cube = NULL,
80+
k_values = NULL,
81+
wavelength_range = NULL,
82+
snr_stat = c("integrated", "median_per_wavelength"),
83+
variance_inflation = 1) {
84+
if (!is.null(target_snr)) {
85+
if (!missing(Ncomp)) {
86+
stop("Specify either `Ncomp` or `target_snr`, not both.")
87+
}
88+
89+
return(choose_ncomp_by_snr(
90+
input = input,
91+
target_snr = target_snr,
92+
var_cube = var_cube,
93+
k_values = k_values,
94+
wavelength_range = wavelength_range,
95+
redshift = redshift,
96+
scale_fn = scale_fn,
97+
snr_stat = snr_stat,
98+
variance_inflation = variance_inflation,
99+
na_safe = TRUE
100+
))
101+
}
102+
61103
.segment_core(
62104
input = input,
63105
Ncomp = Ncomp,

R/segment_big_cube.R

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@
183183
#' @param refine_max_pixels Maximum number of boundary pixels to refine.
184184
#' @param verbose Logical.
185185
#' @return A list containing the full-resolution \code{cluster_map}, block
186-
#' metadata, medoid centers, axis/header data, the original cube, and
187-
#' \code{backend = "medoid"}.
186+
#' metadata, medoid centers, a per-cluster SNR summary, axis/header data, the
187+
#' original cube, and \code{backend = "medoid"}.
188188
#' @seealso \code{\link{segment}}, \code{\link{segment_starlet}}
189189
#' @export
190190
segment_big_cube <- function(input,
@@ -391,8 +391,16 @@ segment_big_cube <- function(input,
391391
}
392392
}
393393

394+
sn <- .compute_signal_noise(IFU2D)
395+
cluster_snr <- .compute_cluster_snr(
396+
clusters = cluster_map[valid_pix],
397+
signal_valid = sn$signal[valid_pix],
398+
noise_valid = sn$noise[valid_pix]
399+
)
400+
394401
list(
395402
cluster_map = cluster_map,
403+
cluster_snr = cluster_snr,
396404
block_map = block_map,
397405
block_size = block_size,
398406
n_blocks = n_blocks,

R/segment_starlet.R

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@
1414
#' @param engine Segmentation backend after masking: \code{"standard"} uses
1515
#' \code{\link{segment}}, while \code{"big_cube"} uses
1616
#' \code{\link{segment_big_cube}}.
17+
#' @param target_snr Optional minimum accepted SNR per cluster for the exact
18+
#' backend. When supplied, the masked cube is cut at the largest
19+
#' \code{Ncomp} whose minimum cluster SNR remains above this threshold.
20+
#' @param var_cube Optional variance cube used only when \code{target_snr} is
21+
#' supplied with \code{engine = "standard"}.
22+
#' @param k_values Optional candidate cluster counts tested only when
23+
#' \code{target_snr} is supplied with \code{engine = "standard"}.
24+
#' @param wavelength_range Optional wavelength interval used to compute SNR only
25+
#' when \code{target_snr} is supplied with \code{engine = "standard"}.
26+
#' @param snr_stat Either integrated SNR or median per-wavelength SNR when
27+
#' \code{target_snr} is supplied with \code{engine = "standard"}.
28+
#' @param variance_inflation Multiplicative factor applied to propagated
29+
#' variances when \code{target_snr} is supplied with \code{engine = "standard"}.
1730
#' @param collapse_fn Function used to build the white-light image.
1831
#' @param starlet_J Number of starlet scales.
1932
#' @param starlet_scales Integer vector of scales kept in the reconstruction.
@@ -33,6 +46,12 @@ segment_starlet <- function(input,
3346
redshift = 0,
3447
scale_fn = median_scale,
3548
engine = c("standard", "big_cube"),
49+
target_snr = NULL,
50+
var_cube = NULL,
51+
k_values = NULL,
52+
wavelength_range = NULL,
53+
snr_stat = c("integrated", "median_per_wavelength"),
54+
variance_inflation = 1,
3655
collapse_fn = collapse_white_light,
3756
starlet_J = 5,
3857
starlet_scales = 2:5,
@@ -45,6 +64,11 @@ segment_starlet <- function(input,
4564
engine <- match.arg(engine)
4665
mode <- match.arg(mode)
4766
mask_mode <- match.arg(mask_mode)
67+
snr_stat <- match.arg(snr_stat)
68+
69+
if (engine == "big_cube" && !is.null(target_snr)) {
70+
stop("`target_snr` is currently supported only with `engine = \"standard\"`.")
71+
}
4872

4973
cubedat <- .as_cubedat(input)
5074
mask_info <- build_starlet_mask(
@@ -74,12 +98,26 @@ segment_starlet <- function(input,
7498
...
7599
)
76100
} else {
77-
segment(
78-
input = masked_input,
79-
Ncomp = Ncomp,
80-
redshift = redshift,
81-
scale_fn = scale_fn
82-
)
101+
if (is.null(target_snr)) {
102+
segment(
103+
input = masked_input,
104+
Ncomp = Ncomp,
105+
redshift = redshift,
106+
scale_fn = scale_fn
107+
)
108+
} else {
109+
segment(
110+
input = masked_input,
111+
redshift = redshift,
112+
scale_fn = scale_fn,
113+
target_snr = target_snr,
114+
var_cube = var_cube,
115+
k_values = k_values,
116+
wavelength_range = wavelength_range,
117+
snr_stat = snr_stat,
118+
variance_inflation = variance_inflation
119+
)
120+
}
83121
}
84122

85123
c(out, list(

man/segment.Rd

Lines changed: 34 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/segment_big_cube.Rd

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/segment_starlet.Rd

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)