| Title: | Governed Near-Infrared Spectroscopy Data and SNIRF Input/Output |
|---|---|
| Description: | Provides strict input, output, measurement identity, probe geometry, optical-density, modified Beer-Lambert, motion-correction, and short-separation nuisance, signal-quality, channel-pruning, and live neurofeedback contracts for continuous-wave functional near-infrared spectroscopy data stored in 'PhysioExperiment' objects. Shared Near Infrared Spectroscopy Format ('SNIRF') files are read and written through structured 'HDF5' APIs while preserving time bases, measurement order, probe coordinates, metadata tags, stimulus tables, and processing provenance. |
| Authors: | Yusuke Matsui [aut, cre] |
| Maintainer: | Yusuke Matsui <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.6.1 |
| Built: | 2026-10-03 14:13:44 UTC |
| Source: | https://github.com/x-biosignal/PhysioNIRS |
PhysioNIRS maps continuous-wave SNIRF data into the
PhysioExperiment::PhysioExperiment() contract without changing measurement
order, probe geometry, stimulus tables, or the exact time base. Governed
optical-density, modified Beer-Lambert, motion-correction,
short-separation nuisance, quality/pruning, and live-neurofeedback
operations retain their log, distance, pathlength, geometry, filter,
identity, and reference conventions.
SNIRF metadata may contain identifying subject and acquisition fields. Callers are responsible for de-identification before sharing a file.
Maintainer: Yusuke Matsui [email protected]
Shared Near Infrared Spectroscopy Format specification: https://fnirs.github.io/snirf/
Useful links:
Report bugs at https://github.com/x-biosignal/PhysioNIRS/issues
Implements published population equations. These values are population estimates, not subject-specific pathlength measurements.
dpf( wavelength_nm, age_years, model = c("scholkmann2013", "duncan1996"), extrapolate = FALSE )dpf( wavelength_nm, age_years, model = c("scholkmann2013", "duncan1996"), extrapolate = FALSE )
wavelength_nm |
Positive wavelength values in nanometres. |
age_years |
Non-negative age values in years. |
model |
Exactly |
extrapolate |
Whether to allow age/wavelength extrapolation where the selected model defines an unambiguous equation. |
A positive numeric vector with model and extrapolation attributes.
# Age-dependent differential pathlength factors for a 30-year-old adult dpf(c(760, 850), age_years = 30)# Age-dependent differential pathlength factors for a 30-year-old adult dpf(c(760, 850), age_years = 30)
Coefficients are linearly interpolated from the package-owned table. Stored
coefficients use the base-10 molar convention in cm^-1 M^-1; natural-log
coefficients in m^-1 M^-1 include the explicit 100 * log(10) conversion.
extinctionCoefficients( wavelength_nm, unit = c("m-1 M-1", "cm-1 M-1"), extrapolate = FALSE )extinctionCoefficients( wavelength_nm, unit = c("m-1 M-1", "cm-1 M-1"), extrapolate = FALSE )
wavelength_nm |
Positive wavelengths in nanometres. |
unit |
Exactly |
extrapolate |
Whether to permit terminal-slope linear extrapolation. |
A numeric matrix with exact columns HbO and HbR.
# Molar extinction (m^-1 M^-1) at two typical fNIRS wavelengths extinctionCoefficients(c(760, 850)) # The same coefficients expressed per centimetre extinctionCoefficients(c(690, 830), unit = "cm-1 M-1")# Molar extinction (m^-1 M^-1) at two typical fNIRS wavelengths extinctionCoefficients(c(760, 850)) # The same coefficients expressed per centimetre extinctionCoefficients(c(690, 830), unit = "cm-1 M-1")
Calculates governed source-detector distances and midpoints in metres.
Channels strictly below threshold_m are classified as short. A returned
map is fingerprint-bound to the complete source object.
identifyShortChannels(x, threshold_m = 0.01)identifyShortChannels(x, threshold_m = 0.01)
x |
A governed measurement-level or MBLL pair-level
|
threshold_m |
Positive short-separation threshold in metres. |
A source-bound nirs_short_channels data frame.
od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) identifyShortChannels(od, threshold_m = 0.015)od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) identifyShortChannels(od, threshold_m = 0.015)
Optical density is calculated with the natural-log convention
-log(I / I0). The reference intensity and any replacement of non-positive
cells are explicit and recorded in provenance.
intensityToOD( x, assay_name = NULL, baseline = c("mean", "median"), baseline_interval = NULL, reference = NULL, nonpositive = c("error", "replace"), replacement = NULL, output_assay = "OD" )intensityToOD( x, assay_name = NULL, baseline = c("mean", "median"), baseline_interval = NULL, reference = NULL, nonpositive = c("error", "replace"), replacement = NULL, output_assay = "OD" )
x |
A governed continuous-wave |
assay_name |
Exact input assay name. |
baseline |
Exactly |
baseline_interval |
Optional closed interval in seconds. |
reference |
Optional positive scalar or vector with one value per measurement. |
nonpositive |
Exactly |
replacement |
Explicit positive scalar used only with
|
output_assay |
Exact name for the new optical-density assay. |
x with a unitless optical-density assay appended.
pe <- PhysioNIRS:::.nirs_demo_object() od <- intensityToOD(pe) SummarizedExperiment::assayNames(od)pe <- PhysioNIRS:::.nirs_demo_object() od <- intensityToOD(pe) SummarizedExperiment::assayNames(od)
Solves the modified Beer-Lambert system independently for each exact
source-detector pair. The returned PhysioExperiment has one column per
pair and assays HbO, HbR, and HbT in micromolar.
mbll( x, assay_name = "OD", pathlength_factor = 6, age_years = NULL, dpf_model = "scholkmann2013", distance_m = NULL, output_unit = "uM" )mbll( x, assay_name = "OD", pathlength_factor = 6, age_years = NULL, dpf_model = "scholkmann2013", distance_m = NULL, output_unit = "uM" )
x |
A governed |
assay_name |
Exact optical-density assay name. |
pathlength_factor |
Positive scalar/vector, or |
age_years |
Age used only when |
dpf_model |
Exact DPF model name passed to |
distance_m |
Optional positive scalar, per-measurement vector, or per-pair vector overriding probe geometry. |
output_unit |
Exactly |
A pair-collapsed PhysioExperiment with concentration assays.
od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) hb <- mbll(od) SummarizedExperiment::assayNames(hb)od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) hb <- mbll(od) SummarizedExperiment::assayNames(hb)
Return the governed SNIRF measurement list
measurementList(x)measurementList(x)
x |
A |
A defensive copy of the normalized measurement DataFrame.
pe <- PhysioNIRS:::.nirs_demo_object() measurementList(pe)[, c("channel_label", "wavelength_nm")]pe <- PhysioNIRS:::.nirs_demo_object() measurementList(pe)[, c("channel_label", "wavelength_nm")]
Uses strict amplitude and derivative-SD thresholds over a finite lag window. Detections are expanded in time and can be unioned across wavelengths from the same source-detector pair.
motionArtifactDetect( x, assay_name = "OD", t_motion = 0.5, t_mask = 1, sd_threshold = 20, amplitude_threshold = 0.5, group_wavelengths = TRUE )motionArtifactDetect( x, assay_name = "OD", t_motion = 0.5, t_mask = 1, sd_threshold = 20, amplitude_threshold = 0.5, group_wavelengths = TRUE )
x |
A governed |
assay_name |
Exact source assay name. |
t_motion |
Positive lag window in seconds. |
t_mask |
Non-negative expansion on each side in seconds. |
sd_threshold |
Positive multiple of channel derivative SD. |
amplitude_threshold |
Positive absolute-change threshold. |
group_wavelengths |
Whether to union measurements sharing an exact source-detector pair. |
A typed nirs_motion_mask aligned to assay rows and columns.
od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) mask <- motionArtifactDetect(od) class(mask)od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) mask <- motionArtifactDetect(od) class(mask)
Applies a linear contrast over the condition betas of a
nirsActivationGLM() fit, per channel: the estimate c' beta, its standard
error sqrt(sigma^2 * c' (X'X)^-1 c), t-statistic, degrees of freedom and
p-value.
nirsActivationContrast(fit, contrast)nirsActivationContrast(fit, contrast)
fit |
A |
contrast |
A numeric contrast over conditions: named by condition, or an
unnamed vector with one weight per condition (e.g. |
A per-channel data.frame: channel, estimate, se, t, df,
p.
hb <- mbll(intensityToOD(PhysioNIRS:::.nirs_demo_object())) fit <- nirsActivationGLM(hb, assay_name = "HbO") nirsActivationContrast(fit, c(task = 1))hb <- mbll(intensityToOD(PhysioNIRS:::.nirs_demo_object())) fit <- nirsActivationGLM(hb, assay_name = "HbO") nirsActivationContrast(fit, c(task = 1))
Fits a general linear model of every haemoglobin channel against
HRF-convolved task regressors: for each condition, a boxcar over its stimulus
blocks convolved with a canonical double-gamma HRF, plus a discrete-cosine
drift basis and optional short-separation nuisance regressors. Returns the
per-channel activation amplitude (beta), standard error and t-statistic for
each condition. Run it separately on the HbO and HbR assays.
nirsActivationGLM( x, events = NULL, assay_name = "HbO", conditions = NULL, basis = c("canonical", "derivative"), drift = 6, nuisance = NULL, hrf = list(peak = 6, undershoot = 16, ratio = 6), prewhiten = c("none", "ar1") )nirsActivationGLM( x, events = NULL, assay_name = "HbO", conditions = NULL, basis = c("canonical", "derivative"), drift = 6, nuisance = NULL, hrf = list(peak = 6, undershoot = 16, ratio = 6), prewhiten = c("none", "ar1") )
x |
A |
events |
A |
assay_name |
Assay to model (default |
conditions |
Optional character vector selecting/ordering conditions. |
basis |
|
drift |
Number of discrete-cosine drift terms (default 6). |
nuisance |
Optional numeric matrix of extra nuisance regressors (e.g.
|
hrf |
List of HRF parameters ( |
prewhiten |
|
An S3 nirs_activation_glm with coefficients (a channel x
condition data.frame of beta, se, t, df, p), the beta/se
matrices, per-channel sigma2/rho, and the design (for
nirsActivationContrast()).
Friston KJ et al. (1994) Statistical parametric maps. Hum Brain Mapp 2:189-210. Huppert TJ et al. (2009) HomER. Appl Opt 48:D280.
nirsActivationContrast(), shortSeparationDesign(), mbll()
hb <- mbll(intensityToOD(PhysioNIRS:::.nirs_demo_object())) fit <- nirsActivationGLM(hb, assay_name = "HbO") fit$coefficientshb <- mbll(intensityToOD(PhysioNIRS:::.nirs_demo_object())) fit <- nirsActivationGLM(hb, assay_name = "HbO") fit$coefficients
The controller builds a public PhysioStream pipeline and
BiofeedbackScope. It computes frozen-baseline regional HbO contrasts in a
committed pipeline operation and publishes each eligible multi-target value
through one atomic biofeedbackUpdate() call. Construction is
side-effect-free.
nirsNeurofeedback( stream, regions, contrast, assay_name = "HbO", baseline_seconds = 20, update_seconds = 0.1, smoothing_seconds = 2 )nirsNeurofeedback( stream, regions, contrast, assay_name = "HbO", baseline_seconds = 20, update_seconds = 0.1, smoothing_seconds = 2 )
stream |
A created or open regular-rate numeric |
regions |
A named list of non-overlapping exact HbO channel IDs. |
contrast |
A region-named numeric vector or region-by-target matrix. |
assay_name |
Exact live assay name, currently |
baseline_seconds |
Positive frozen-baseline duration. |
update_seconds |
Positive scheduled update interval. |
smoothing_seconds |
Positive trailing time-weighted mean duration. |
The stream must declare metadata$nirs fields assay_name,
assay_kind = "haemoglobin_concentration", identity_kind = "pair",
channel_id, source_index, and detector_index; ordered channel names
and units must be the exact HbO identities and "uM".
A side-effect-free NIRSNeurofeedback runtime.
Kober et al. (2017), DOI: 10.3389/fnhum.2017.00081.
# Offline demonstration on a deterministic loopback stream. In practice # `stream` is a live regular-rate HbO inlet (e.g. an LSL inlet from a device). info <- PhysioStream::streamInfo( "nirs-demo", type = "NIRS", channel_names = c("S1_D1", "S2_D2"), nominal_srate = 10, dtype = "float64", source_id = "nirs-demo", clock_domain = "demo-clock", channel_units = c("uM", "uM"), metadata = list(nirs = list( assay_name = "HbO", assay_kind = "haemoglobin_concentration", identity_kind = "pair", channel_id = c("S1_D1", "S2_D2"), source_index = 1:2, detector_index = 1:2))) stream <- PhysioStream::streamOpen(PhysioStream::loopbackSource(info, 8192L)) controller <- nirsNeurofeedback( stream, regions = list(motor = "S1_D1", control = "S2_D2"), contrast = c(motor = 1, control = -1), baseline_seconds = 1, update_seconds = 0.1, smoothing_seconds = 0.5) nirsNeurofeedbackStart(controller) time <- (0:19) / 10 PhysioStream::loopbackFeed(stream, cbind( S1_D1 = 1 + 0.2 * sin(2 * pi * 0.5 * time), S2_D2 = 1 + 0.1 * cos(time)), time) while (nirsNeurofeedbackStep(controller, 4L)$updated) {} nirsNeurofeedbackState(controller)$lifecycle nirsNeurofeedbackStop(controller)# Offline demonstration on a deterministic loopback stream. In practice # `stream` is a live regular-rate HbO inlet (e.g. an LSL inlet from a device). info <- PhysioStream::streamInfo( "nirs-demo", type = "NIRS", channel_names = c("S1_D1", "S2_D2"), nominal_srate = 10, dtype = "float64", source_id = "nirs-demo", clock_domain = "demo-clock", channel_units = c("uM", "uM"), metadata = list(nirs = list( assay_name = "HbO", assay_kind = "haemoglobin_concentration", identity_kind = "pair", channel_id = c("S1_D1", "S2_D2"), source_index = 1:2, detector_index = 1:2))) stream <- PhysioStream::streamOpen(PhysioStream::loopbackSource(info, 8192L)) controller <- nirsNeurofeedback( stream, regions = list(motor = "S1_D1", control = "S2_D2"), contrast = c(motor = 1, control = -1), baseline_seconds = 1, update_seconds = 0.1, smoothing_seconds = 0.5) nirsNeurofeedbackStart(controller) time <- (0:19) / 10 PhysioStream::loopbackFeed(stream, cbind( S1_D1 = 1 + 0.2 * sin(2 * pi * 0.5 * time), S2_D2 = 1 + 0.1 * cos(time)), time) while (nirsNeurofeedbackStep(controller, 4L)$updated) {} nirsNeurofeedbackState(controller)$lifecycle nirsNeurofeedbackStop(controller)
nirsNeurofeedbackStep() processes at most max_chunks synchronously,
flushing committed target values after each chunk so the external update
timestamp remains the latest scope signal time.
nirsNeurofeedbackStart(controller) nirsNeurofeedbackStep(controller, max_chunks = 16L) nirsNeurofeedbackState(controller) nirsNeurofeedbackStop(controller) nirsNeurofeedbackScope(controller)nirsNeurofeedbackStart(controller) nirsNeurofeedbackStep(controller, max_chunks = 16L) nirsNeurofeedbackState(controller) nirsNeurofeedbackStop(controller) nirsNeurofeedbackScope(controller)
controller |
A |
max_chunks |
Positive exact per-call work bound. |
Lifecycle functions return controller invisibly. Step and state
functions return portable plain lists. nirsNeurofeedbackScope() returns
the governed BiofeedbackScope for a viewer.
# A controller is driven by an open regular-rate HbO stream; here a loopback # stream stands in for a live device inlet. info <- PhysioStream::streamInfo( "nirs-demo", type = "NIRS", channel_names = c("S1_D1", "S2_D2"), nominal_srate = 10, dtype = "float64", source_id = "nirs-demo", clock_domain = "demo-clock", channel_units = c("uM", "uM"), metadata = list(nirs = list( assay_name = "HbO", assay_kind = "haemoglobin_concentration", identity_kind = "pair", channel_id = c("S1_D1", "S2_D2"), source_index = 1:2, detector_index = 1:2))) stream <- PhysioStream::streamOpen(PhysioStream::loopbackSource(info, 8192L)) controller <- nirsNeurofeedback( stream, regions = list(motor = "S1_D1", control = "S2_D2"), contrast = c(motor = 1, control = -1), baseline_seconds = 1) nirsNeurofeedbackStart(controller) time <- (0:19) / 10 PhysioStream::loopbackFeed(stream, cbind( S1_D1 = 1 + 0.2 * sin(2 * pi * 0.5 * time), S2_D2 = 1), time) while (nirsNeurofeedbackStep(controller, 4L)$updated) {} nirsNeurofeedbackScope(controller) nirsNeurofeedbackState(controller)$lifecycle nirsNeurofeedbackStop(controller)# A controller is driven by an open regular-rate HbO stream; here a loopback # stream stands in for a live device inlet. info <- PhysioStream::streamInfo( "nirs-demo", type = "NIRS", channel_names = c("S1_D1", "S2_D2"), nominal_srate = 10, dtype = "float64", source_id = "nirs-demo", clock_domain = "demo-clock", channel_units = c("uM", "uM"), metadata = list(nirs = list( assay_name = "HbO", assay_kind = "haemoglobin_concentration", identity_kind = "pair", channel_id = c("S1_D1", "S2_D2"), source_index = 1:2, detector_index = 1:2))) stream <- PhysioStream::streamOpen(PhysioStream::loopbackSource(info, 8192L)) controller <- nirsNeurofeedback( stream, regions = list(motor = "S1_D1", control = "S2_D2"), contrast = c(motor = 1, control = -1), baseline_seconds = 1) nirsNeurofeedbackStart(controller) time <- (0:19) / 10 PhysioStream::loopbackFeed(stream, cbind( S1_D1 = 1 + 0.2 * sin(2 * pi * 0.5 * time), S2_D2 = 1), time) while (nirsNeurofeedbackStep(controller, 4L)$updated) {} nirsNeurofeedbackScope(controller) nirsNeurofeedbackState(controller)$lifecycle nirsNeurofeedbackStop(controller)
Applies a zero-phase Butterworth band-pass independently to every source assay column. Band names identify common nuisance ranges; they are not physiological diagnoses.
physiologyBandpass( x, assay_name = "OD", band = c("mayer", "respiration", "cardiac"), range_hz = NULL, output_assay = paste0(assay_name, "_", band[[1L]]), order = 3L )physiologyBandpass( x, assay_name = "OD", band = c("mayer", "respiration", "cardiac"), range_hz = NULL, output_assay = paste0(assay_name, "_", band[[1L]]), order = 3L )
x |
A governed |
assay_name |
Exact source assay name. |
band |
Exactly |
range_hz |
Optional explicit positive passband below Nyquist. |
output_assay |
Exact name for the added filtered assay. |
order |
Positive integer Butterworth order. |
Default passbands in Hz are Mayer 0.07--0.13, respiration
0.15--0.40, and cardiac 0.70--2.00. Filtering uses an order-order
Butterworth band-pass through signal::filtfilt(). Explicit ranges must
remain strictly below the governed Nyquist frequency.
A clone of x with one zero-phase filtered assay.
od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) # Pass an explicit band; defaults warn that adult ranges may not transfer filt <- physiologyBandpass(od, band = "cardiac", range_hz = c(0.8, 2)) SummarizedExperiment::assayNames(filt)od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) # Pass an explicit band; defaults warn that adult ranges may not transfer filt <- physiologyBandpass(od, band = "cardiac", range_hz = c(0.8, 2)) SummarizedExperiment::assayNames(filt)
Display a governed NIRS quality result
## S3 method for class 'nirs_quality' print(x, ...)## S3 method for class 'nirs_quality' print(x, ...)
x |
A |
... |
Unused. |
od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) print(signalQualityIndex(od))od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) print(signalQualityIndex(od))
Display a governed NIRS neurofeedback runtime
## S3 method for class 'NIRSNeurofeedback' print(x, ...)## S3 method for class 'NIRSNeurofeedback' print(x, ...)
x |
A |
... |
Unused. |
info <- PhysioStream::streamInfo( "nirs-demo", type = "NIRS", channel_names = c("S1_D1", "S2_D2"), nominal_srate = 10, dtype = "float64", source_id = "nirs-demo", clock_domain = "demo-clock", channel_units = c("uM", "uM"), metadata = list(nirs = list( assay_name = "HbO", assay_kind = "haemoglobin_concentration", identity_kind = "pair", channel_id = c("S1_D1", "S2_D2"), source_index = 1:2, detector_index = 1:2))) stream <- PhysioStream::streamOpen(PhysioStream::loopbackSource(info, 8192L)) controller <- nirsNeurofeedback( stream, regions = list(motor = "S1_D1", control = "S2_D2"), contrast = c(motor = 1, control = -1), baseline_seconds = 1) print(controller)info <- PhysioStream::streamInfo( "nirs-demo", type = "NIRS", channel_names = c("S1_D1", "S2_D2"), nominal_srate = 10, dtype = "float64", source_id = "nirs-demo", clock_domain = "demo-clock", channel_units = c("uM", "uM"), metadata = list(nirs = list( assay_name = "HbO", assay_kind = "haemoglobin_concentration", identity_kind = "pair", channel_id = c("S1_D1", "S2_D2"), source_index = 1:2, detector_index = 1:2))) stream <- PhysioStream::streamOpen(PhysioStream::loopbackSource(info, 8192L)) controller <- nirsNeurofeedback( stream, regions = list(motor = "S1_D1", control = "S2_D2"), contrast = c(motor = 1, control = -1), baseline_seconds = 1) print(controller)
Window decisions are collapsed conservatively per metric. Measurement-level optical-density drops propagate to the complete source-detector pair. Inputs and quality results are fingerprint-bound and are never modified.
pruneChannels(x, quality, action = c("mark", "drop"), require_all = TRUE)pruneChannels(x, quality, action = c("mark", "drop"), require_all = TRUE)
x |
The exact governed source |
quality |
One |
action |
Exactly |
require_all |
Whether all metrics, rather than any metric, must pass. |
A cloned marked or consistently subset PhysioExperiment.
od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) q <- signalQualityIndex(od) pruneChannels(od, q, action = "mark")od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) q <- signalQualityIndex(od) pruneChannels(od, q, action = "mark")
Read a Shared Near Infrared Spectroscopy Format file
readSNIRF(path, nirs_index = 1L, data_index = 1L)readSNIRF(path, nirs_index = 1L, data_index = 1L)
path |
Path to one readable |
nirs_index |
Positive index of the NIRS root. |
data_index |
Positive index of the data block. |
A PhysioExperiment::PhysioExperiment() with a time-by-measurement
raw assay.
# Round-trip through a temporary SNIRF/HDF5 file (needs a .snirf on disk) pe <- PhysioNIRS:::.nirs_demo_object() pe <- PhysioExperiment::setEvents(pe, PhysioExperiment::PhysioEvents( onset = 6, duration = 4, type = "task", value = "1")) path <- tempfile(fileext = ".snirf") writeSNIRF(pe, path) back <- readSNIRF(path) dim(back) unlink(path)# Round-trip through a temporary SNIRF/HDF5 file (needs a .snirf on disk) pe <- PhysioNIRS:::.nirs_demo_object() pe <- PhysioExperiment::setEvents(pe, PhysioExperiment::PhysioEvents( onset = 6, duration = 4, type = "task", value = "1")) path <- tempfile(fileext = ".snirf") writeSNIRF(pe, path) back <- readSNIRF(path) dim(back) unlink(path)
Optical-density measurements are grouped by exact source-detector identity, zero-phase filtered in the cardiac band, and scored by the minimum pairwise wavelength correlation. Scores are copied to every wavelength in the group. The default threshold is a project default, not a clinical cutoff.
scalpCouplingIndex( x, assay_name = "OD", l_freq = 0.7, h_freq = 1.5, window_seconds = NULL, step_seconds = NULL, threshold = 0.8, order = 3L )scalpCouplingIndex( x, assay_name = "OD", l_freq = 0.7, h_freq = 1.5, window_seconds = NULL, step_seconds = NULL, threshold = 0.8, order = 3L )
x |
A governed measurement-level optical-density
|
assay_name |
Exact optical-density assay name. |
l_freq, h_freq
|
Cardiac-band limits in Hz. |
window_seconds |
Optional positive complete-window duration. |
step_seconds |
Optional positive window step. |
threshold |
Finite pass threshold in |
order |
Positive Butterworth filter order. |
A source-bound nirs_quality result.
Pollonini et al. (2014), DOI: 10.1117/1.JBO.19.8.086007.
od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) scalpCouplingIndex(od)od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) scalpCouplingIndex(od)
Returns short-channel signals, optionally aggregated by compatibility class, with requested physiology-band copies. No intercept, task, or drift regressor is added.
shortSeparationDesign( x, assay_name = "OD", short = NULL, aggregation = c("all", "mean"), physiology_bands = character(), band_ranges = NULL, standardize = TRUE )shortSeparationDesign( x, assay_name = "OD", short = NULL, aggregation = c("all", "mean"), physiology_bands = character(), band_ranges = NULL, standardize = TRUE )
x |
A governed OD or pair-collapsed haemoglobin
|
assay_name |
Exact source assay. |
short |
A compatible |
aggregation |
Exactly |
physiology_bands |
Unique exact band names to append. |
band_ranges |
Optional named list providing one explicit range per requested band. |
standardize |
Whether to centre and sample-SD standardize every column. |
A time-aligned nirs_nuisance_design numeric matrix.
od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) short <- identifyShortChannels(od, threshold_m = 0.015) design <- shortSeparationDesign(od, short = short) dim(design)od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) short <- identifyShortChannels(od, threshold_m = 0.015) design <- shortSeparationDesign(od, short = short) dim(design)
Fits a centred short-channel regression separately for each long channel.
Short channels are copied unchanged. Positive lag means that the short
signal at t - lag_seconds predicts the long signal at t.
shortSeparationRegress( x, assay_name = "OD", short = NULL, method = c("nearest", "all"), lag_seconds = 0, output_assay = paste0(assay_name, "_ssr"), condition_limit = 1e+10 )shortSeparationRegress( x, assay_name = "OD", short = NULL, method = c("nearest", "all"), lag_seconds = 0, output_assay = paste0(assay_name, "_ssr"), condition_limit = 1e+10 )
x |
A governed OD or pair-collapsed haemoglobin
|
assay_name |
Exact source assay name. |
short |
A compatible |
method |
Exactly |
lag_seconds |
A finite lag that corresponds to an exact sample count. |
output_assay |
Exact name for the added corrected assay. |
condition_limit |
Finite regression condition-number limit greater than one. |
For a target y and selected short signals X, the fitted
intercept is retained and only (X - colMeans(X)) beta is subtracted.
Regression uses a deterministic SVD solve and rejects rank-deficient or
over-limit designs. Short columns and lag-edge rows remain unchanged.
A clone of x with one short-separation-corrected assay.
Saager and Berger (2005), DOI: 10.1364/JOSAA.22.001874.
od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) short <- identifyShortChannels(od, threshold_m = 0.015) corrected <- shortSeparationRegress(od, short = short) SummarizedExperiment::assayNames(corrected)od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) short <- identifyShortChannels(od, threshold_m = 0.015) corrected <- shortSeparationRegress(od, short = short) SummarizedExperiment::assayNames(corrected)
method = "peak_power" implements the pinned MNE-NIRS PHOEBE-style
cross-correlation peak-power metric. It is not the original PHOEBE
equation. method = "snr" returns a channel-specific cardiac-to-noise
spectral power ratio in decibels.
signalQualityIndex( x, assay_name = "OD", method = c("peak_power", "snr"), window_seconds = 10, step_seconds = NULL, cardiac_range_hz = c(0.7, 1.5), noise_range_hz = NULL, threshold = NULL, order = 3L )signalQualityIndex( x, assay_name = "OD", method = c("peak_power", "snr"), window_seconds = 10, step_seconds = NULL, cardiac_range_hz = c(0.7, 1.5), noise_range_hz = NULL, threshold = NULL, order = 3L )
x |
A governed measurement-level optical-density
|
assay_name |
Exact optical-density assay name. |
method |
Exactly |
window_seconds |
Positive complete-window duration. |
step_seconds |
Optional positive window step. |
cardiac_range_hz |
Finite increasing cardiac band below Nyquist. |
noise_range_hz |
For SNR, |
threshold |
Optional finite threshold. Defaults to |
order |
Positive Butterworth filter order. |
A source-bound nirs_quality result.
Pollonini et al. (2016), DOI: 10.1364/BOE.7.005104.
od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) signalQualityIndex(od)od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) signalQualityIndex(od)
Calculate source-detector distances for each SNIRF measurement
sourceDetectorDistances( x, dimension = c("auto", "3d", "2d"), unit = c("m", "native") )sourceDetectorDistances( x, dimension = c("auto", "3d", "2d"), unit = c("m", "native") )
x |
A governed |
dimension |
Geometry selection: exactly |
unit |
Output unit: exactly |
A DataFrame with one row per measurement and distance identity.
pe <- PhysioNIRS:::.nirs_demo_object() sourceDetectorDistances(pe)pe <- PhysioNIRS:::.nirs_demo_object() sourceDetectorDistances(pe)
Uses the MATLAB csaps smoothing-parameter definition and stitches
corrected artifact and clean segments with short local means.
splineMotionCorrect( x, mask = NULL, assay_name = "OD", output_assay = paste0(assay_name, "_spline"), p = 0.99, t_motion = 0.5, t_mask = 1, sd_threshold = 20, amplitude_threshold = 0.5, group_wavelengths = TRUE )splineMotionCorrect( x, mask = NULL, assay_name = "OD", output_assay = paste0(assay_name, "_spline"), p = 0.99, t_motion = 0.5, t_mask = 1, sd_threshold = 20, amplitude_threshold = 0.5, group_wavelengths = TRUE )
x |
A governed |
mask |
A compatible |
assay_name |
Exact source assay name. |
output_assay |
Exact new assay name. |
p |
Cubic smoothing parameter in |
t_motion |
Positive detection lag window in seconds, used only when
|
t_mask |
Non-negative detection-mask expansion in seconds, used only
when |
sd_threshold |
Positive derivative-SD detection multiplier, used only
when |
amplitude_threshold |
Positive absolute-change detection threshold,
used only when |
group_wavelengths |
Whether detection unions wavelengths from each
source-detector pair, used only when |
A clone of x with one motion-corrected assay.
od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) corrected <- splineMotionCorrect(od) SummarizedExperiment::assayNames(corrected)od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) corrected <- splineMotionCorrect(od) SummarizedExperiment::assayNames(corrected)
Implements temporal derivative distribution repair with a third-order Butterworth low-pass and Tukey bisquare derivative weights.
tddr( x, assay_name = "OD", output_assay = paste0(assay_name, "_tddr"), cutoff_hz = 0.5, tune = 4.685, max_iter = 50L )tddr( x, assay_name = "OD", output_assay = paste0(assay_name, "_tddr"), cutoff_hz = 0.5, tune = 4.685, max_iter = 50L )
x |
A governed |
assay_name |
Exact source assay name. |
output_assay |
Exact new assay name. |
cutoff_hz |
Positive low-pass cutoff below Nyquist. |
tune |
Positive Tukey bisquare tuning constant. |
max_iter |
Positive integer maximum robust iterations. |
A clone of x with one motion-corrected assay.
od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) corrected <- tddr(od) SummarizedExperiment::assayNames(corrected)od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) corrected <- tddr(od) SummarizedExperiment::assayNames(corrected)
Outlying detail coefficients are removed using a per-block IQR rule and the signal is reconstructed at its original length.
waveletMotionCorrect( x, assay_name = "OD", output_assay = paste0(assay_name, "_wavelet"), iqr = 1.5, wavelet = "db2", min_level = 4L )waveletMotionCorrect( x, assay_name = "OD", output_assay = paste0(assay_name, "_wavelet"), iqr = 1.5, wavelet = "db2", min_level = 4L )
x |
A governed |
assay_name |
Exact source assay name. |
output_assay |
Exact new assay name. |
iqr |
Positive IQR multiplier. |
wavelet |
Exact wavelet name; currently only |
min_level |
Positive integer lowest analysis scale. |
A clone of x with one motion-corrected assay.
od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) corrected <- waveletMotionCorrect(od) SummarizedExperiment::assayNames(corrected)od <- intensityToOD(PhysioNIRS:::.nirs_demo_object()) corrected <- waveletMotionCorrect(od) SummarizedExperiment::assayNames(corrected)
Write a Shared Near Infrared Spectroscopy Format file
writeSNIRF(x, path, assay_name = NULL, overwrite = FALSE, compact_time = FALSE)writeSNIRF(x, path, assay_name = NULL, overwrite = FALSE, compact_time = FALSE)
x |
A governed |
path |
Destination ending exactly in |
assay_name |
Assay to write. |
overwrite |
Whether to replace an existing destination. |
compact_time |
Whether to use |
path, invisibly.
# Write a governed object to a temporary SNIRF/HDF5 file pe <- PhysioNIRS:::.nirs_demo_object() pe <- PhysioExperiment::setEvents(pe, PhysioExperiment::PhysioEvents( onset = 6, duration = 4, type = "task", value = "1")) path <- tempfile(fileext = ".snirf") writeSNIRF(pe, path) file.exists(path) unlink(path)# Write a governed object to a temporary SNIRF/HDF5 file pe <- PhysioNIRS:::.nirs_demo_object() pe <- PhysioExperiment::setEvents(pe, PhysioExperiment::PhysioEvents( onset = 6, duration = 4, type = "task", value = "1")) path <- tempfile(fileext = ".snirf") writeSNIRF(pe, path) file.exists(path) unlink(path)