| Title: | Processing and Quantification of Targeted Mass Spectrometry Imaging Data |
|---|---|
| Description: | Implements tools for processing and quantifying targeted DESI-MRM mass spectrometry imaging (MSI) datasets, extending the Cardinal package. Includes signal-to-noise filtering against background pixels, tissue/background separation, per-feature ion images, quantile heatmaps, quantification against on-slide or on-tissue calibration standards, and batch export of per-feature text images for external viewers. |
| Authors: | Matthew J. Smith [aut, cre] (ORCID: <https://orcid.org/0000-0002-7357-2670>) |
| Maintainer: | Matthew J. Smith <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.99.0 |
| Built: | 2026-07-23 18:56:30 UTC |
| Source: | https://github.com/BiocStaging/quantMSImageR |
Cardinal's cbind (used by combine_MSIs) requires the
mz key column to match exactly across objects. When acquisitions
come from different instrument methods or ion-library versions, features
with the same display name can carry different mz values, causing
cbind to fail with a "non-matching key columns" error.
align_features( obj1, obj2, feature_match = c("transition", "name"), mz_tolerance = 0.05 )align_features( obj1, obj2, feature_match = c("transition", "name"), mz_tolerance = 0.05 )
obj1 |
A |
obj2 |
A |
feature_match |
Character. |
mz_tolerance |
Numeric. Half-width in Da within which two precursor or
product m/z values are taken to be the same (default |
align_features resolves this by:
Subsetting both objects to the intersection of feature names.
Reordering obj2 to match obj1's feature order.
Forcing obj2's mz values to equal obj1's, which
permits Cardinal's key check to pass after features have been matched by
name. combine_MSIs then restores fData from
obj1, so all feature metadata originates from the first object.
Features are paired by display name, and by default that pairing is then
verified against the transition each name refers to: precursor and
product m/z must agree to within mz_tolerance. Two methods can reuse
a name while differing in precursor ion, product ion or transition
definition, and because this function rewrites the mz key, an
unverified pairing would silently merge different measurements into one
feature. A disagreement is therefore an error naming the features involved.
feature_match = "name" restores name-only matching for objects that
carry no precursor/product metadata. It is not the default: it cannot
detect the failure above, and this function is called automatically inside
generate_txt_images.
The function is called automatically inside
generate_txt_images before every cross-sample
combine_MSIs, so mixed-method studies (e.g. 1 Hz + 2 Hz
acquisitions) are handled transparently. It is also exported so that it
can be used directly in custom scripts or Rmd reports whenever two
quant_MSImagingExperiment objects need to be combined.
A named list with two elements:
obj1Subset of obj1 containing only common
features.
obj2Subset of obj2 reordered and mz-keyed
to match obj1, ready for combine_MSIs.
combine_MSIs, generate_txt_images
Other combining acquisitions:
bind_panels(),
combine_MSIs,MSImagingExperiment-method
p1 <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") p2 <- system.file("extdata", "example.raw", "section02.RDS", package = "quantMSImageR") al <- align_features(readRDS(p1), readRDS(p2))p1 <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") p2 <- system.file("extdata", "example.raw", "section02.RDS", package = "quantMSImageR") al <- align_features(readRDS(p1), readRDS(p2))
Sets pixels to NA in val_slot wherever the snr spectra slot is NA.
Typically called after int2snr(): pixels that did not pass the SNR threshold
(stored as NA in the snr slot) are suppressed in the intensity slot so
they are excluded from downstream analysis and visualisation.
## S4 method for signature 'quant_MSImagingExperiment' applySNR(MSIobject, val_slot = "intensity", ...)## S4 method for signature 'quant_MSImagingExperiment' applySNR(MSIobject, val_slot = "intensity", ...)
MSIobject |
A |
val_slot |
Character. Name of the intensity slot to mask (default
|
... |
Additional arguments (currently unused). |
The input object with sub-threshold pixels set to NA in val_slot.
This modifies val_slot in place rather than adding a new layer. Keep a copy
of the object if the pre-masking values are needed afterwards.
Other filtering:
back2NA,quant_MSImagingExperiment-method,
int2response,quant_MSImagingExperiment-method,
int2snr,quant_MSImagingExperiment-method,
zero2na,quant_MSImagingExperiment-method
p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- int2snr(obj, snr_thresh = 3) obj <- applySNR(obj, val_slot = "intensity")p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- int2snr(obj, snr_thresh = 3) obj <- applySNR(obj, val_slot = "intensity")
Replaces the spectral values of background pixels with NA in a chosen
spectra slot. Tissue pixels are left unchanged.
## S4 method for signature 'quant_MSImagingExperiment' back2NA( MSIobject, val_slot = "intensity", pixel_header = "sample_name", background = "background_pixels", sample_type = NULL, ... )## S4 method for signature 'quant_MSImagingExperiment' back2NA( MSIobject, val_slot = "intensity", pixel_header = "sample_name", background = "background_pixels", sample_type = NULL, ... )
MSIobject |
A |
val_slot |
Character. Name of the spectra slot to modify (default |
pixel_header |
Character. Column of |
background |
Character. Value in |
sample_type |
Deprecated alias for |
... |
Additional arguments (currently unused). |
The input quant_MSImagingExperiment with background pixels set to
NA in val_slot. Returns the object unchanged if no background pixels are
found.
This modifies val_slot in place rather than adding a new layer. Keep a copy
of the object if the original values are needed afterwards.
Other filtering:
applySNR,quant_MSImagingExperiment-method,
int2response,quant_MSImagingExperiment-method,
int2snr,quant_MSImagingExperiment-method,
zero2na,quant_MSImagingExperiment-method
p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- back2NA(obj)p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- back2NA(obj)
Combines two MSImagingExperiment objects acquired on the same physical
sample into one whose feature set spans both inputs. Pixels are matched
by (x, y) coordinates rather than by row order, so the two acquisitions
can have different pixel counts (which is the rule, not the exception:
different MRM panels or polarities almost always sample at slightly
different rates and therefore produce different grids).
bind_panels( obj1, obj2, label = NULL, feature_match = c("transition", "name"), mz_tolerance = 0.05 )bind_panels( obj1, obj2, label = NULL, feature_match = c("transition", "name"), mz_tolerance = 0.05 )
obj1, obj2
|
|
label |
Character. Optional. If supplied, written to
|
feature_match |
Character. How a feature name appearing in both inputs
is treated: |
mz_tolerance |
Numeric. Half-width in Da within which two precursor or
product m/z values count as the same (default |
Pixels present in only one input are dropped – a small percentage of edge coverage in the more densely sampled acquisition typically. Pixels present in both keep real intensities from both inputs, so cross-panel / cross-polarity colocalisation is meaningful at the combined object.
The common use is pairing a positive- and a negative-mode acquisition of the same section, but any two panels of the same physical area work.
A quant_MSImagingExperiment with:
Features = obj1's features followed by obj2's features (feature names duplicated in both are kept once, with obj1's values).
Pixels = intersection of (x, y) grids.
Each pixel carries real intensities from both inputs.
Every spectra layer both inputs carry – response, snr and
calibrated amounts as well as intensity – together with
obj1's experiment metadata and calibration/tissue slots.
Both inputs must carry the same set of spectra layers, since a layer present on only one side cannot be filled in for the other half of the features. Bind panels at the same stage of processing: either both raw, or both after the same steps.
combine_MSIs(), generate_txt_images()
Other combining acquisitions:
align_features(),
combine_MSIs,MSImagingExperiment-method
# Both inputs must be the SAME physical area measured twice, so the example # splits one section into two disjoint "panels" rather than using two # different sections -- binding unrelated sections by coordinate would # silently pair pixels that are not the same piece of tissue. p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- readRDS(p) panel_a <- obj[1:4, ] panel_b <- obj[5:nrow(fData(obj)), ] merged <- bind_panels(panel_a, panel_b, label = "SampleA_1") nrow(fData(merged)) # features from both panels# Both inputs must be the SAME physical area measured twice, so the example # splits one section into two disjoint "panels" rather than using two # different sections -- binding unrelated sections by coordinate would # silently pair pixels that are not the same piece of tissue. p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- readRDS(p) panel_a <- obj[1:4, ] panel_b <- obj[5:nrow(fData(obj)), ] merged <- bind_panels(panel_a, panel_b, label = "SampleA_1") nrow(fData(merged)) # features from both panels
Joins each row of fData(combined) to the ion library on the
(precursor_mz, product_mz) pair, within mz_tolerance. Robust to feature
renames in the YAML (features.rename) because m/z is stable across name
changes.
build_feature_meta( combined, ion_lib_meta, mz_tolerance = 0.05, ambiguity = c("error", "warn", "nearest"), verbose = TRUE )build_feature_meta( combined, ion_lib_meta, mz_tolerance = 0.05, ambiguity = c("error", "warn", "nearest"), verbose = TRUE )
combined |
An MSI object whose |
ion_lib_meta |
A |
mz_tolerance |
Numeric. Half-width in Da within which a feature's
precursor and product are taken to be the library's (default |
ambiguity |
Character. What to do when a feature matches more than one
library entry: |
verbose |
Logical. Emit a |
Matching uses the same rule as read_mrm(), so the two cannot disagree about
which library entry a feature is. They previously built their m/z keys
independently – one rounding to whole numbers, the other not – and a
feature matching several library entries silently took the first one's
annotation.
Used by run_study.R (via inst/run_study.R) and run_example() to build
a per-feature metadata frame the heatmap report can consume – e.g. for
splitting / colour-bar annotation by an ion-library column such as Met-1.
A data.frame of metadata, one row per feature in fData(combined),
with row names set to the feature name and a name column appended.
Unmatched features become a row of NAs. Returns NULL when
ion_lib_meta is NULL.
quantile_hm(), generate_txt_images()
p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- readRDS(p) lib <- read.csv(system.file("extdata", "example_ion_library.csv", package = "quantMSImageR"), check.names = FALSE) fm <- build_feature_meta(obj, lib)p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- readRDS(p) lib <- read.csv(system.file("extdata", "example_ion_library.csv", package = "quantMSImageR"), check.names = FALSE) fm <- build_feature_meta(obj, lib)
Holds everything needed to turn a measured response into an estimated amount:
the calibration design, the summarised response at each level, the fitted
per-analyte models, and their fit quality. It is carried in the
calibrationInfo slot of a quant_MSImagingExperiment.
The slots are filled in workflow order and are empty (zero-row data frames, empty list) until the corresponding step has run:
cal_metadatadata.frame. The calibration design supplied by the
user: one row per (spot, analyte), with columns identifier, analyte,
amount_pg and level. Set by summarise_cal_levels().
cal_response_datadata.frame. Summarised response per
calibration level, with columns analyte, pg_perpixel,
response_perpixel and level. Set by summarise_cal_levels().
cal_listlist. One stats::lm per analyte, of
response_perpixel ~ pg_perpixel, named by analyte so that
int2conc() can match models to features by fData(x)$name. Set by
create_cal_curve().
r2_dfdata.frame. One row per analyte, with feature and r2;
int2conc() adds an out_of_range column giving the proportion of
pixels extrapolated beyond the calibrated range. Set by
create_cal_curve().
Invariants checked by the validity method: cal_list must be named if it is
non-empty, and every name must appear in r2_df$feature when r2_df is
populated. An unnamed cal_list is accepted only when empty – matching
models to features positionally would silently apply one analyte's curve to
another.
Use the accessors (calibrationModels(), calibrationDiagnostics(),
calibrationLevels(), calibrationMetadata()) rather than @.
An object of class calibrationInfo.
cal_metadatadata.frame of the calibration design.
cal_listNamed list of fitted lm models, one per analyte.
cal_response_datadata.frame of summarised response per level.
r2_dfdata.frame of fit quality per analyte.
quant_MSImagingExperiment, create_cal_curve(),
quantMSImageR-accessors
Other calibration:
create_cal_curve,quant_MSImagingExperiment-method,
int2conc,quant_MSImagingExperiment-method,
plot_cal_coverage,quant_MSImagingExperiment-method,
summarise_cal_levels,quant_MSImagingExperiment-method
# Empty, as attached to a freshly coerced object ci <- calibrationInfo() ci # Populated by the calibration workflow cal_dir <- system.file("extdata", "cal_example.raw", package = "quantMSImageR") cal <- as(readRDS(file.path(cal_dir, "cal_MSI.RDS")), "quant_MSImagingExperiment") cal_metadata <- read.csv(file.path(cal_dir, "calibration_metadata.csv")) cal <- summarise_cal_levels(cal, cal_metadata, val_slot = "intensity", cal_label = "Cal", id = "identifier") cal <- create_cal_curve(cal, cal_type = "cal") calibrationDiagnostics(cal)# Empty, as attached to a freshly coerced object ci <- calibrationInfo() ci # Populated by the calibration workflow cal_dir <- system.file("extdata", "cal_example.raw", package = "quantMSImageR") cal <- as(readRDS(file.path(cal_dir, "cal_MSI.RDS")), "quant_MSImagingExperiment") cal_metadata <- read.csv(file.path(cal_dir, "calibration_metadata.csv")) cal <- summarise_cal_levels(cal, cal_metadata, val_slot = "intensity", cal_label = "Cal", id = "identifier") cal <- create_cal_curve(cal, cal_type = "cal") calibrationDiagnostics(cal)
Concatenates two or more acquisitions pixel-wise into a single object, so
that a whole study can be filtered, summarised and plotted together. Each
input keeps its own run, which is what downstream per-sample summaries
group on.
## S4 method for signature 'MSImagingExperiment' combine_MSIs(MSIobject, ...)## S4 method for signature 'MSImagingExperiment' combine_MSIs(MSIobject, ...)
MSIobject |
An |
... |
Further |
A single quant_MSImagingExperiment holding every input's pixels,
with the shared fData() restored and one run level per acquisition.
Other combining acquisitions:
align_features(),
bind_panels()
p1 <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") p2 <- system.file("extdata", "example.raw", "section02.RDS", package = "quantMSImageR") combined <- combine_MSIs(readRDS(p1), readRDS(p2))p1 <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") p2 <- system.file("extdata", "example.raw", "section02.RDS", package = "quantMSImageR") combined <- combine_MSIs(readRDS(p1), readRDS(p2))
Fits a linear response-versus-amount model for each standard, which
int2conc() later inverts to turn a measured response into an estimated
amount per pixel.
## S4 method for signature 'quant_MSImagingExperiment' create_cal_curve( MSIobject, cal_type, level = "level", background = "background", weighting = c("1/x", "none", "1/x2") )## S4 method for signature 'quant_MSImagingExperiment' create_cal_curve( MSIobject, cal_type, level = "level", background = "background", weighting = c("1/x", "none", "1/x2") )
MSIobject |
A |
cal_type |
Character, required. |
level |
Character. Column of |
background |
Character. Value of |
weighting |
Character. Regression weights: |
cal_type has no default and must be chosen explicitly, because the two
modes apply materially different processing.
cal_type = "cal" fits the summarised response directly against the amount
deposited, appropriate for standards spotted onto the slide beside the
tissue (on-slide / external calibration).
cal_type = "std_addition" is classical standard addition, for standards
deposited onto tissue where endogenous analyte is already present. It:
fits an unweighted response ~ deposited amount across all levels;
takes the x-intercept of that line – the amount at which predicted response is zero – as an estimate of the endogenous amount already in the tissue (this value is negative when endogenous signal is present);
subtracts it from every deposited amount, which shifts the x-axis so it expresses total amount present (endogenous + added);
drops the rows at the background level and refits on that shifted
axis.
The input object with cal_list (one lm per standard, response
versus amount in pg per pixel), r2_df (fit R-squared per standard) and
the calibration metadata populated.
Calibration response in MSI is usually heteroscedastic – absolute scatter
grows with amount – so an unweighted fit lets the top standards dominate and
the low end, where most tissue pixels sit, is fitted worst. weighting
therefore defaults to "1/x"; "1/x2" weights the low end harder still, and
"none" is ordinary least squares.
A zero (blank) level has no 1/x weight. It is given the weight of the
lowest positive level rather than a weight derived from a substituted tiny
amount, which would let a single blank determine the whole regression.
Weighting is an empirical model choice, not a property of the data. Check it
against residual structure, back-calculated accuracy at each level and
replicate precision rather than against R-squared – see
calibrationDiagnostics() and plot_cal_coverage().
Other calibration:
calibrationInfo-class,
int2conc,quant_MSImagingExperiment-method,
plot_cal_coverage,quant_MSImagingExperiment-method,
summarise_cal_levels,quant_MSImagingExperiment-method
cal_dir <- system.file("extdata", "cal_example.raw", package = "quantMSImageR") cal <- as(readRDS(file.path(cal_dir, "cal_MSI.RDS")), "quant_MSImagingExperiment") cal_metadata <- read.csv(file.path(cal_dir, "calibration_metadata.csv")) cal <- summarise_cal_levels(cal, cal_metadata, val_slot = "intensity", cal_label = "Cal", id = "identifier") cal <- create_cal_curve(cal, cal_type = "cal")cal_dir <- system.file("extdata", "cal_example.raw", package = "quantMSImageR") cal <- as(readRDS(file.path(cal_dir, "cal_MSI.RDS")), "quant_MSImagingExperiment") cal_metadata <- read.csv(file.path(cal_dir, "calibration_metadata.csv")) cal <- summarise_cal_levels(cal, cal_metadata, val_slot = "intensity", cal_label = "Cal", id = "identifier") cal <- create_cal_curve(cal, cal_type = "cal")
Flattens the pixel-level object into tabular form for downstream statistics:
one row per pixel, or one row per region of interest when roi_header names
a grouping column.
## S4 method for signature 'quant_MSImagingExperiment' createMSIDatamatrix( MSIobject, val_slot = "intensity", inputNA = TRUE, roi_header = NA )## S4 method for signature 'quant_MSImagingExperiment' createMSIDatamatrix( MSIobject, val_slot = "intensity", inputNA = TRUE, roi_header = NA )
MSIobject |
A |
val_slot |
Character. Spectra slot to tabulate (default |
inputNA |
Logical. Convert zeros in the matrix to |
roi_header |
Character. Column of |
The input object with its tissueInfo slot populated:
all_pixel_matrix (one row per pixel, one column per feature),
roi_average_matrix (one row per ROI, when roi_header is given) and the
accompanying sample/ROI metadata.
p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- createMSIDatamatrix(obj, val_slot = "intensity", roi_header = NA)p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- createMSIDatamatrix(obj, val_slot = "intensity", roi_header = NA)
Reads one or more DESI-MRM acquisitions, applies SNR filtering and
tissue/background separation, and writes per-feature text matrices that
can be imported by imaging software (e.g. MassLynx QuanOptimise overlay
tools). Setting output_txt = FALSE runs all processing but skips file
writing, which is useful when the caller only needs the processed MSI
objects (e.g. for HTML report rendering).
generate_txt_images( fns, data_path, image_dir, lib_ion_path, snr_thresh = 0, thresh = 20, perc = 97, rot_clockwise = 0, average_method = "median", output_txt = TRUE, exclude = NULL, rename = NULL, ratios = NULL, output_ratios = TRUE, snr_overrides = NULL, is_name = NULL, is_norm_header = "IS_norm", is_mode = "line", is_window = 15, remove_IS = TRUE, type_header = "Type" )generate_txt_images( fns, data_path, image_dir, lib_ion_path, snr_thresh = 0, thresh = 20, perc = 97, rot_clockwise = 0, average_method = "median", output_txt = TRUE, exclude = NULL, rename = NULL, ratios = NULL, output_ratios = TRUE, snr_overrides = NULL, is_name = NULL, is_norm_header = "IS_norm", is_mode = "line", is_window = 15, remove_IS = TRUE, type_header = "Type" )
fns |
Character vector of acquisition names (without |
data_path |
Path to the folder that contains the |
image_dir |
Root output directory. One sub-directory per acquisition is created inside it. |
lib_ion_path |
Full path to the MRM ion-library CSV. Must contain
columns: |
snr_thresh |
Numeric scalar or vector. One or more minimum
signal-to-noise thresholds; pixels below each threshold are set to |
thresh |
Numeric. Cold-spot percentile passed to |
perc |
Numeric. Hot-spot percentile passed to |
rot_clockwise |
Integer (0-3). Number of 90 deg clockwise rotations
applied via |
average_method |
Character, |
output_txt |
Logical. When |
exclude |
Character vector of feature names to drop before processing.
Names must match |
rename |
Named character vector or list mapping old feature names to new
display names, e.g. |
ratios |
Optional list of metabolite ratio pairs. Each element must be a named list with fields:
Ratio images (numerator / denominator, pixel-wise) are written to the
same SNR-filtered subdirectories as the individual ion images, immediately
after them. Pixels where the denominator is zero or either ion is |
output_ratios |
Logical. When |
snr_overrides |
Optional named map of feature name to a feature-specific
SNR threshold. Keys may be original ion-library names or post- |
is_name |
Character. Value identifying the internal standard in
|
is_norm_header |
Character. Ion-library column mapping each analyte to
the standard that normalises it, needed only when |
is_mode |
Character. Level at which the internal standard is
summarised: |
is_window |
Integer. Number of consecutive pixels averaged when
|
remove_IS |
Logical. Drop the internal-standard feature after
normalising (default |
type_header |
Character. Ion-library column holding the feature type,
passed to |
Invisibly returns a named list:
combinedRaw combined object (background pixels retained).
combined_snrSNR-filtered intensity for the first threshold
in snr_thresh; sub-threshold pixels NA. Provided for
backward compatibility.
combined_snr_listNamed list of SNR-filtered objects, one per
threshold in snr_thresh, named "snr<value>" (e.g. "snr3").
combined_NAbackgroundRaw intensity with background set to NA.
int2snr(), applySNR(), back2NA(), imageR()
Other workflow:
print.quant_validation(),
run_example(),
run_study(),
validate_config()
# Section-mode run on the bundled synthetic data (no tissue mask needed at # snr_thresh = 0), returning the processed objects without writing files. fns <- list(list(neg = "example", section = "section01", label = "A")) res <- generate_txt_images( fns = fns, data_path = system.file("extdata", package = "quantMSImageR"), image_dir = tempfile(), lib_ion_path = system.file("extdata", "example_ion_library.csv", package = "quantMSImageR"), snr_thresh = 0, output_txt = FALSE )# Section-mode run on the bundled synthetic data (no tissue mask needed at # snr_thresh = 0), returning the processed objects without writing files. fns <- list(list(neg = "example", section = "section01", label = "A")) res <- generate_txt_images( fns = fns, data_path = system.file("extdata", package = "quantMSImageR"), image_dir = tempfile(), lib_ion_path = system.file("extdata", "example_ion_library.csv", package = "quantMSImageR"), snr_thresh = 0, output_txt = FALSE )
Renders a single feature's spatial distribution as a ggplot. Because the
result is an ordinary ggplot, the layout, theme and scales can be modified
with the usual + syntax – for example + facet_wrap(~ sample, ncol = 3)
to arrange several acquisitions in a grid.
## S4 method for signature 'quant_MSImagingExperiment' imageR( MSIobject, val_slot = "intensity", value = "response %", scale = "suppress", threshold = 1, sample_lab = "sample_ID", pixels = NA, percentile = 99, feat_ind = 1, perc_scale = FALSE, blank_back = TRUE, aspect_ratio = 1, text_image = FALSE, palette = c("heatmap0", "viridis") )## S4 method for signature 'quant_MSImagingExperiment' imageR( MSIobject, val_slot = "intensity", value = "response %", scale = "suppress", threshold = 1, sample_lab = "sample_ID", pixels = NA, percentile = 99, feat_ind = 1, perc_scale = FALSE, blank_back = TRUE, aspect_ratio = 1, text_image = FALSE, palette = c("heatmap0", "viridis") )
MSIobject |
A |
val_slot |
Character. Spectra slot to image (default |
value |
Character. Legend label describing what the values represent
(e.g. |
scale |
Character. Colour-scale treatment: |
threshold |
Numeric. Lowest percentile removed from the colour scale,
to stop residual background dominating it (default |
sample_lab |
Character. Column of |
pixels |
Character. Value of |
percentile |
Numeric. Percentile at which the colour scale is capped
when |
feat_ind |
Integer. Row index of the feature in |
perc_scale |
Logical. Express the colour scale as a percentage of the
maximum ( |
blank_back |
Logical; when TRUE background/zero pixels are drawn transparent. |
aspect_ratio |
numeric plot aspect ratio (default 1). |
text_image |
Logical; when TRUE return the image as a numeric matrix (for text export) rather than a ggplot. |
palette |
Character. Colour scale for the image: |
A ggplot object, or a numeric matrix when text_image = TRUE.
Other visualisation:
quant_palettes(),
quantile_hm()
p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") gg <- imageR(obj, feat_ind = 1, sample_lab = "run", scale = "suppress")p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") gg <- imageR(obj, feat_ind = 1, sample_lab = "run", scale = "suppress")
Inverts each analyte's calibration model to turn a measured response into an estimated amount per pixel. Features without a calibration model are dropped.
## S4 method for signature 'quant_MSImagingExperiment' int2conc( MSIobject, val_slot = "intensity", pixel_header = "sample_name", pixels = "tissue_pixels", max_out_of_range = 0.1 )## S4 method for signature 'quant_MSImagingExperiment' int2conc( MSIobject, val_slot = "intensity", pixel_header = "sample_name", pixels = "tissue_pixels", max_out_of_range = 0.1 )
MSIobject |
A |
val_slot |
Character. Spectra slot holding the measured response
(default |
pixel_header |
Character. Column of |
pixels |
Character. Label(s) in |
max_out_of_range |
Numeric in |
Mass spectrometry imaging measures analyte response at each pixel rather than
analyte amount directly. The values produced here are calibrated amount
estimates (pg per pixel, and pg per mm-squared where the pixel size is
known), not volumetric concentrations. They are conditional on the
calibration design, matrix matching, acquisition conditions and the validity
of the fitted model – see plot_cal_coverage() for the coverage check that
should accompany them.
The object subset to pixels, with two spectra slots added:
pg_pixel (estimated amount per pixel) and, when
experimentData(MSIobject)$pixelSize is available, pg_mm2 (estimated
amount per unit area). Features with no calibration model are removed, and
r2_df gains an out_of_range column giving the proportion of each
feature's pixels that were extrapolated beyond the calibrated range.
pg_pixel is inverted directly from the calibration model. pg_mm2 is then
derived from the pixel size recorded in the acquisition metadata:
where s is experimentData(MSIobject)$pixelSize, expected in
micrometres, and the factor 1000 converts micrometres to millimetres. A
single scalar is assumed, i.e. square pixels of side s; rectangular pixels
are not currently supported, and supplying s in millimetres would inflate
the result by a factor of 10^6. When pixelSize is missing or not a positive
number the pg_mm2 slot is omitted and a warning is issued.
Other calibration:
calibrationInfo-class,
create_cal_curve,quant_MSImagingExperiment-method,
plot_cal_coverage,quant_MSImagingExperiment-method,
summarise_cal_levels,quant_MSImagingExperiment-method
cal_dir <- system.file("extdata", "cal_example.raw", package = "quantMSImageR") cal <- as(readRDS(file.path(cal_dir, "cal_MSI.RDS")), "quant_MSImagingExperiment") cal_metadata <- read.csv(file.path(cal_dir, "calibration_metadata.csv")) cal <- summarise_cal_levels(cal, cal_metadata, val_slot = "intensity", cal_label = "Cal", id = "identifier") cal <- create_cal_curve(cal, cal_type = "cal") # A calibration acquisition labels its pixels in `sample_type`, so the # imaging defaults are overridden here cal <- int2conc(cal, pixel_header = "sample_type", pixels = "Tissue")cal_dir <- system.file("extdata", "cal_example.raw", package = "quantMSImageR") cal <- as(readRDS(file.path(cal_dir, "cal_MSI.RDS")), "quant_MSImagingExperiment") cal_metadata <- read.csv(file.path(cal_dir, "calibration_metadata.csv")) cal <- summarise_cal_levels(cal, cal_metadata, val_slot = "intensity", cal_label = "Cal", id = "identifier") cal <- create_cal_curve(cal, cal_type = "cal") # A calibration acquisition labels its pixels in `sample_type`, so the # imaging defaults are overridden here cal <- int2conc(cal, pixel_header = "sample_type", pixels = "Tissue")
Divides each feature's intensity by an internal standard measured in the same pixel, line or sample, which suppresses drift and much of the local variation in ionisation efficiency.
## S4 method for signature 'quant_MSImagingExperiment' int2response( MSIobject, val_slot = "intensity", normalisation = c("internal_standard", "within_feature"), IS_name = NULL, is_norm_header = "IS_norm", mode = c("line", "sample", "pixel", "window"), window = 15, remove_IS = TRUE, ... )## S4 method for signature 'quant_MSImagingExperiment' int2response( MSIobject, val_slot = "intensity", normalisation = c("internal_standard", "within_feature"), IS_name = NULL, is_norm_header = "IS_norm", mode = c("line", "sample", "pixel", "window"), window = 15, remove_IS = TRUE, ... )
MSIobject |
A |
val_slot |
Character. Spectra slot to normalise (default
|
normalisation |
Character. |
IS_name |
Character. Value identifying the internal standard in the
feature-type column of |
is_norm_header |
Character. Feature-metadata column holding the
analyte-to-standard mapping (default |
mode |
Character. Level at which the standard is summarised:
|
window |
Integer. Number of consecutive pixels averaged when
|
remove_IS |
Logical. Drop the internal-standard features from the
returned object (default |
... |
Additional arguments (currently unused). |
normalisation states what is being done, so that no argument value has to
be read as an instruction:
"internal_standard"Divide by the standard named in IS_name.
This is the quantitative path.
"within_feature"Divide each feature by its own summary at the
chosen mode. This removes between-line or between-sample scale
differences within a feature, but it is not internal-standard
normalisation and does not make features comparable to one another.
To leave values untouched, do not call this function. There is deliberately
no "none" value here: skipping a step is the caller's decision, not a mode of
the step. The YAML workflow exposes normalisation: none for that, and
simply does not call this function.
The input object with a response spectra slot holding the
normalised values.
When IS_name matches exactly one feature, every analyte is normalised to
it. When it matches several – a panel carrying one class-specific standard
per lipid class, for instance – an explicit analyte-to-standard mapping is
required, because dividing by several standards at once has no defined
meaning. Supply it as an ion-library column (named by is_norm_header,
default "IS_norm") whose value on each analyte row is the transition name
of the standard that normalises it. Any analyte left unmapped is an error
rather than a silent fallback.
With a single standard the column is never read, so is_norm_header = "None"
is the right setting for a panel where every analyte shares one standard.
Other filtering:
applySNR,quant_MSImagingExperiment-method,
back2NA,quant_MSImagingExperiment-method,
int2snr,quant_MSImagingExperiment-method,
zero2na,quant_MSImagingExperiment-method
p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") # No internal standard in the example panel: normalise each feature to # itself, per acquisition line. obj <- int2response(obj, val_slot = "intensity", normalisation = "within_feature")p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") # No internal standard in the example panel: normalise each feature to # itself, per acquisition line. obj <- int2response(obj, val_slot = "intensity", normalisation = "within_feature")
Expresses each tissue pixel's response as a ratio to the same feature's response in the background pixels of the same acquisition.
## S4 method for signature 'quant_MSImagingExperiment' int2snr( MSIobject, val_slot = "intensity", pixel_header = "sample_name", background = "background_pixels", tissue = "tissue_pixels", snr_thresh = 3, average = c("median", "mean"), snr_overrides = NULL, no_background = c("error", "all_na", "copy"), noise = NULL, sample_type = NULL, ... )## S4 method for signature 'quant_MSImagingExperiment' int2snr( MSIobject, val_slot = "intensity", pixel_header = "sample_name", background = "background_pixels", tissue = "tissue_pixels", snr_thresh = 3, average = c("median", "mean"), snr_overrides = NULL, no_background = c("error", "all_na", "copy"), noise = NULL, sample_type = NULL, ... )
MSIobject |
A |
val_slot |
Character. Spectra slot holding the measured response
(default |
pixel_header |
Character. Column of |
background |
Character. Value in |
tissue |
Character. Value in |
snr_thresh |
Global minimum SNR to accept (below this value SNR = NA).
Applied to every feature unless overridden by |
average |
Character, |
snr_overrides |
Optional named numeric vector mapping feature name
(as in |
no_background |
Character. What to do when |
noise |
Deprecated alias for |
sample_type |
Deprecated alias for |
... |
Additional arguments (currently unused). |
For feature f and tissue pixel p, with background-pixel set B:
where summary is the mean or median selected by average. This is a
background-referenced signal ratio, not the classical analytical definition
based on the standard deviation of the noise.
median is the default because a background region that clips part of the
tissue, or contains a spot of carryover, shifts a mean far more than a
median. Zero background values are treated as missing and imputed at one
tenth of the smallest non-zero background value for that feature, so a
feature whose background is entirely zero or NA is skipped and its snr
stays NA.
Run this after internal-standard normalisation (int2response()) when
one is used. A threshold of 3 is a detection-level criterion; a stricter
threshold is advisable before converting a feature to calibrated amounts.
The input object with an additional snr spectra slot. Values below
the selected threshold, and values outside the pixels labelled tissue,
are stored as NA in that slot. No existing slot is modified.
Other filtering:
applySNR,quant_MSImagingExperiment-method,
back2NA,quant_MSImagingExperiment-method,
int2response,quant_MSImagingExperiment-method,
zero2na,quant_MSImagingExperiment-method
p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") # The defaults match the imaging convention used throughout the package obj <- int2snr(obj, snr_thresh = 3) names(spectraData(obj))p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") # The defaults match the imaging convention used throughout the package obj <- int2snr(obj, snr_thresh = 3) names(spectraData(obj))
Converting a response into a calibrated amount is only trustworthy where the
standards actually constrain the fit. A calibration whose levels sit above or
below the signal measured in tissue is extrapolation, not quantification.
int2conc() reports the proportion of extrapolated pixels per feature, but
without an explicit coverage check that is still easy to overlook – and the
plot shows where the mismatch is, not just how much of it there is.
## S4 method for signature 'quant_MSImagingExperiment' plot_cal_coverage( MSIobject, features = NULL, val_slot = "intensity", conc_slot = "pg_pixel", log_base = 2, bins = 40, cal_colour = "red", cal_alpha = 0.4, cal_linetype = "dotted", ... )## S4 method for signature 'quant_MSImagingExperiment' plot_cal_coverage( MSIobject, features = NULL, val_slot = "intensity", conc_slot = "pg_pixel", log_base = 2, bins = 40, cal_colour = "red", cal_alpha = 0.4, cal_linetype = "dotted", ... )
MSIobject |
A |
features |
Features to plot: a character vector of names as in
|
val_slot |
Character. Spectra slot holding the measured response
(default |
conc_slot |
Character. Spectra slot holding the calibrated amount
estimate written by |
log_base |
Numeric. Base for both axes (default |
bins |
Integer. Number of histogram bins for the pixel distribution
(default |
cal_colour |
Colour used for the standards and the level markers
(default |
cal_alpha |
Numeric. Opacity of the calibration-level marker lines
(default |
cal_linetype |
Line type for the calibration-level markers (default
|
... |
Additional arguments (currently unused). |
This function plots the two together on log axes so the overlap can be
judged directly. The lower panel is the calibration itself: the standard
spots and the fitted model that int2conc() inverts. The upper panel is the
distribution of the object's own pixels on the same x-axis, with the
calibration levels marked. When the histogram sits inside the span of those
marks, every converted pixel is interpolated between real standards.
The standards are read back from each model's own model frame
(stats::model.frame) rather than from cal_response_data. This matters for
cal_type = "std_addition", where create_cal_curve() shifts the amount
axis by the estimated endogenous amount before fitting: the stored response
data is on the unshifted axis, so plotting it against the fitted line would
put the points and the model on different scales. The model frame always
holds the points the line was actually fitted to.
The fitted model is linear in amount, so on log axes it is drawn as a curve evaluated across the plotted range rather than as a straight line. Any part of it predicting a non-positive response has no log-scale counterpart and is dropped.
A patchwork object: the pixel histogram stacked above the
calibration curve, sharing an x-axis. Printing it draws the figure; it can
also be further modified with ggplot2 layers.
Other calibration:
calibrationInfo-class,
create_cal_curve,quant_MSImagingExperiment-method,
int2conc,quant_MSImagingExperiment-method,
summarise_cal_levels,quant_MSImagingExperiment-method
cal_dir <- system.file("extdata", "cal_example.raw", package = "quantMSImageR") cal <- as(readRDS(file.path(cal_dir, "cal_MSI.RDS")), "quant_MSImagingExperiment") cal_metadata <- read.csv(file.path(cal_dir, "calibration_metadata.csv")) cal <- summarise_cal_levels(cal, cal_metadata, val_slot = "intensity", cal_label = "Cal", id = "identifier") cal <- create_cal_curve(cal, cal_type = "cal") cal <- int2conc(cal, pixel_header = "sample_type", pixels = "Tissue") plot_cal_coverage(cal, val_slot = "intensity")cal_dir <- system.file("extdata", "cal_example.raw", package = "quantMSImageR") cal <- as(readRDS(file.path(cal_dir, "cal_MSI.RDS")), "quant_MSImagingExperiment") cal_metadata <- read.csv(file.path(cal_dir, "calibration_metadata.csv")) cal <- summarise_cal_levels(cal, cal_metadata, val_slot = "intensity", cal_label = "Cal", id = "identifier") cal <- create_cal_curve(cal, cal_type = "cal") cal <- int2conc(cal, pixel_header = "sample_type", pixels = "Tissue") plot_cal_coverage(cal, val_slot = "intensity")
Print a validation result
## S3 method for class 'quant_validation' print(x, ...)## S3 method for class 'quant_validation' print(x, ...)
x |
A |
... |
Ignored. |
x, invisibly.
Other workflow:
generate_txt_images(),
run_example(),
run_study(),
validate_config()
Extends Cardinal::MSImagingExperiment with the metadata quantMSImageR
needs to filter against background pixels and to convert a measured response
into an estimated amount. Nearly every function in the package takes one of
these, so a Cardinal object is normally coerced on the way in.
The object is features x pixels: one row per MRM transition, one column
per pixel. Derived layers are added as additional spectra slots rather than
overwriting intensity, so the raw values survive the whole workflow:
intensityRaw measured response, as read from the acquisition.
responseInternal-standard-normalised, added by int2response().
snrBackground-referenced signal-to-noise, added by int2snr().
pg_pixel, pg_mm2
Calibrated amount estimates, added by
int2conc().
Inherited structure comes from Cardinal: fData() for feature metadata
(mz, name, transition m/z, ion-library columns), pData() for pixel
metadata (x, y, run, and the tissue mask in sample_name) and
experimentData() for acquisition metadata – pixelSize in particular,
without which int2conc() cannot produce pg_mm2.
Several acquisitions are held in a single object, distinguished by the run
column of pData(); this is what combine_MSIs() produces and what the
per-sample summaries group on.
An object of class quant_MSImagingExperiment, extending
Cardinal::MSImagingExperiment with calibrationInfo and tissueInfo
slots.
calibrationInfoA calibrationInfo object.
tissueInfoA tissueInfo object.
calibrationInfo, tissueInfo,
quantMSImageR-accessors, combine_MSIs()
p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") # Cardinal object in, quant_MSImagingExperiment out obj <- as(readRDS(p), "quant_MSImagingExperiment") dim(obj) # features x pixels names(spectraData(obj)) # available layers head(as.data.frame(pData(obj)), 3) # Derived layers accumulate alongside intensity obj <- int2snr(obj, snr_thresh = 3) names(spectraData(obj))p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") # Cardinal object in, quant_MSImagingExperiment out obj <- as(readRDS(p), "quant_MSImagingExperiment") dim(obj) # features x pixels names(spectraData(obj)) # available layers head(as.data.frame(pData(obj)), 3) # Derived layers accumulate alongside intensity obj <- int2snr(obj, snr_thresh = 3) names(spectraData(obj))
The palettes available to imageR(), quantile_hm() and the metadata
colour bars, returned as named character vectors of hex colours.
quant_palettes(name = NULL, n = NULL)quant_palettes(name = NULL, n = NULL)
name |
Optional palette name. When |
n |
Optional number of colours. Qualitative palettes are truncated,
continuous ones are interpolated. |
Four of these – heatmap0, heatmap2, hat and reading – are taken
from the ltc package by Loukas Theodosiou
(https://github.com/loukesio/ltc-color-palettes), which is MIT licensed.
heatmap2 and hat are re-ordered relative to ltc – see below – and
hat substitutes a grey for ltc's black; the remaining colours are
unchanged.
They are reproduced here rather than depended on: ltc brings in 34
recursive dependencies, which is a large amount of installation surface for
four colour vectors in a package that is otherwise light.
Which palette suits what:
viridisSequential, perceptually uniform and colour-blind safe. The default for ion images, where the quantity is one-directional.
heatmap0Nine-colour sequential ramp running dark blue to teal to sand to red. An alternative for ion images.
heatmap2Five-colour diverging ramp, blue to white to red. Suits z-scores, where the midpoint is meaningful.
hat, reading
Qualitative, for categorical metadata such as study
group or pathway class. hat carries 10 well-separated hues, re-sequenced
from ltc's ordering so that the first few are maximally distinct, with
ltc's black replaced by a neutral grey placed last; reading is a softer
8-colour set.
A named list of character vectors, or a single character vector of
hex colours when name is given.
Other visualisation:
imageR,quant_MSImagingExperiment-method,
quantile_hm()
names(quant_palettes()) quant_palettes("heatmap2") quant_palettes("hat", n = 3)names(quant_palettes()) quant_palettes("heatmap2") quant_palettes("hat", n = 3)
For each feature, computes the nth quantile of pixel intensities within each
acquisition run, then z-scores the resulting per-feature profile across
samples (clipped to [-1, 1]) and renders a ComplexHeatmap::Heatmap.
quantile_hm( MSIobject, quant_val, heatmap_order = NA, heatmap_labs = NA, feature_split = NULL, feature_split_name = "Pathway", group_split_name = "Group", cell_size = 8, max_aspect = 1.5, cell_border = "white", fontsize = 8, palette = c("heatmap2", "heatmap0"), group_palette = "hat", feature_palette = "reading", row_split = NULL, row_split_name = NULL, column_split_name = NULL )quantile_hm( MSIobject, quant_val, heatmap_order = NA, heatmap_labs = NA, feature_split = NULL, feature_split_name = "Pathway", group_split_name = "Group", cell_size = 8, max_aspect = 1.5, cell_border = "white", fontsize = 8, palette = c("heatmap2", "heatmap0"), group_palette = "hat", feature_palette = "reading", row_split = NULL, row_split_name = NULL, column_split_name = NULL )
MSIobject |
A |
quant_val |
Numeric in (0, 1). Quantile to summarise per feature per
sample (e.g. |
heatmap_order |
Character vector of run names in the desired column order.
Must match values in |
heatmap_labs |
Character vector of display labels, one per entry in
|
feature_split |
Optional character/factor vector of length equal to the
number of features, used to split the heatmap columns into labelled groups.
Typically derived from an ion library metadata column (e.g. |
feature_split_name |
Display name for the feature-group annotation
legend (e.g. |
group_split_name |
Display name for the sample-group annotation legend
(e.g. |
cell_size |
Numeric. Side of a heatmap cell, in millimetres (default
|
max_aspect |
Numeric >= 1. Largest cell width-to-height ratio allowed
when one dimension has many more entries than the other (default |
cell_border |
Colour for the line drawn around every cell (default
|
fontsize |
Numeric. Point size for the sample and feature labels and the
annotation names (default |
palette |
Character. Diverging colour ramp for the z-scores:
|
group_palette, feature_palette
|
Character. Qualitative palettes for the
sample-group and feature-group colour bars (defaults |
row_split, row_split_name, column_split_name
|
Deprecated aliases for
|
Rows are samples and columns are features, in the order given by
heatmap_order. Studies normally have more samples than features, so this
puts the long dimension vertically where there is room for it and keeps
sample names horizontally readable.
A ComplexHeatmap::Heatmap object (rows = samples, columns =
features), with an absolutely-sized body unless cell_size is NA.
Other visualisation:
imageR,quant_MSImagingExperiment-method,
quant_palettes()
p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") hm <- quantile_hm(obj, quant_val = 0.5, heatmap_order = "section01", heatmap_labs = "A")p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") hm <- quantile_hm(obj, quant_val = 0.5, heatmap_order = "section01", heatmap_labs = "A")
Extract and replace the contents of a quant_MSImagingExperiment's
calibrationInfo and tissueInfo slots. Prefer these to reaching into the
slots with @: the internal representation may change, but these functions
will not.
calibrationData(x) ## S4 method for signature 'quant_MSImagingExperiment' calibrationData(x) calibrationData(x) <- value ## S4 replacement method for signature 'quant_MSImagingExperiment' calibrationData(x) <- value calibrationModels(x) ## S4 method for signature 'quant_MSImagingExperiment' calibrationModels(x) calibrationModels(x) <- value ## S4 replacement method for signature 'quant_MSImagingExperiment' calibrationModels(x) <- value calibrationDiagnostics(x) ## S4 method for signature 'quant_MSImagingExperiment' calibrationDiagnostics(x) calibrationR2(x) ## S4 method for signature 'quant_MSImagingExperiment' calibrationR2(x) calibrationLevels(x) ## S4 method for signature 'quant_MSImagingExperiment' calibrationLevels(x) calibrationMetadata(x) ## S4 method for signature 'quant_MSImagingExperiment' calibrationMetadata(x) tissueData(x) ## S4 method for signature 'quant_MSImagingExperiment' tissueData(x) tissueMatrix(x, which = c("roi", "pixel")) ## S4 method for signature 'quant_MSImagingExperiment' tissueMatrix(x, which = c("roi", "pixel"))calibrationData(x) ## S4 method for signature 'quant_MSImagingExperiment' calibrationData(x) calibrationData(x) <- value ## S4 replacement method for signature 'quant_MSImagingExperiment' calibrationData(x) <- value calibrationModels(x) ## S4 method for signature 'quant_MSImagingExperiment' calibrationModels(x) calibrationModels(x) <- value ## S4 replacement method for signature 'quant_MSImagingExperiment' calibrationModels(x) <- value calibrationDiagnostics(x) ## S4 method for signature 'quant_MSImagingExperiment' calibrationDiagnostics(x) calibrationR2(x) ## S4 method for signature 'quant_MSImagingExperiment' calibrationR2(x) calibrationLevels(x) ## S4 method for signature 'quant_MSImagingExperiment' calibrationLevels(x) calibrationMetadata(x) ## S4 method for signature 'quant_MSImagingExperiment' calibrationMetadata(x) tissueData(x) ## S4 method for signature 'quant_MSImagingExperiment' tissueData(x) tissueMatrix(x, which = c("roi", "pixel")) ## S4 method for signature 'quant_MSImagingExperiment' tissueMatrix(x, which = c("roi", "pixel"))
x |
A |
value |
Replacement value. |
which |
For |
Note the naming: calibrationInfo() and tissueInfo() are the class
constructors, so the slot accessors are calibrationData() and
tissueData().
The calibration accessors follow the workflow. summarise_cal_levels()
populates calibrationLevels(), create_cal_curve() fills
calibrationModels() and calibrationR2(), and int2conc() reads the
models back out. calibrationData() moves the whole block at once, which is
what carrying fitted models from a standards acquisition to a study object
requires.
calibrationModels() a named list of lm objects, one per calibrated
analyte. calibrationDiagnostics() a data frame of fit quality, one row per
analyte: feature, r2, and an out_of_range column once int2conc() has
run. calibrationR2() the feature/r2 columns of that table only.
calibrationLevels() the summarised response per calibration level.
calibrationMetadata() the calibration design supplied by the user.
calibrationData() the whole calibrationInfo object.
tissueMatrix() a data frame of features by pixels or by ROI.
The replacement forms return the modified object.
cal_dir <- system.file("extdata", "cal_example.raw", package = "quantMSImageR") cal <- as(readRDS(file.path(cal_dir, "cal_MSI.RDS")), "quant_MSImagingExperiment") cal_metadata <- read.csv(file.path(cal_dir, "calibration_metadata.csv")) cal <- summarise_cal_levels(cal, cal_metadata, val_slot = "intensity", cal_label = "Cal", id = "identifier") cal <- create_cal_curve(cal, cal_type = "cal") names(calibrationModels(cal)) calibrationDiagnostics(cal) head(calibrationLevels(cal)) # Carry the fitted models onto a study acquisition p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") study <- as(readRDS(p), "quant_MSImagingExperiment") calibrationData(study) <- calibrationData(cal)cal_dir <- system.file("extdata", "cal_example.raw", package = "quantMSImageR") cal <- as(readRDS(file.path(cal_dir, "cal_MSI.RDS")), "quant_MSImagingExperiment") cal_metadata <- read.csv(file.path(cal_dir, "calibration_metadata.csv")) cal <- summarise_cal_levels(cal, cal_metadata, val_slot = "intensity", cal_label = "Cal", id = "identifier") cal <- create_cal_curve(cal, cal_type = "cal") names(calibrationModels(cal)) calibrationDiagnostics(cal) head(calibrationLevels(cal)) # Carry the fitted models onto a study acquisition p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") study <- as(readRDS(p), "quant_MSImagingExperiment") calibrationData(study) <- calibrationData(cal)
Reads one or more analyte text files from <.raw>/imaging/, matches
transitions to the ion library on rounded (precursor, product) m/z, and
constructs a Cardinal::MSImagingExperiment. Handles both the
single-file case (one combined Analyte 1.txt, the modern QuanOptimise
default) and the multi-file case (older exports that split transitions
across several Analyte N.txt files) transparently.
read_mrm( name, folder, lib_ion_path, overwrite = TRUE, type_header = "Type", is_norm_header = "IS_norm", mz_tolerance = 0.05, ambiguity = c("error", "warn", "nearest") )read_mrm( name, folder, lib_ion_path, overwrite = TRUE, type_header = "Type", is_norm_header = "IS_norm", mz_tolerance = 0.05, ambiguity = c("error", "warn", "nearest") )
name |
Acquisition name (without the |
folder |
Path to the directory that contains the |
lib_ion_path |
Full path to the ion-library CSV. Must contain columns
Measured transitions are matched to it on precursor and product m/z within
|
overwrite |
Logical. When |
type_header |
Character. Name of the ion-library column holding the
feature type – the values that mark internal standards versus analytes
(default |
is_norm_header |
Character. Name of the optional ion-library column that
maps each analyte to the internal standard normalising it (default
|
mz_tolerance |
Numeric. Half-width, in Da, within which a measured
precursor and product are taken to be the library's. The default |
ambiguity |
Character. What to do when a measured transition matches
more than one library entry within |
Results are cached to <.raw>/MSImagingExperiment.rds; pass
overwrite = TRUE (the default) to re-parse from the raw text files.
An MSImagingExperiment with feature metadata joined to the ion
library, ready to pass into generate_txt_images() or
select_tissue_pixels().
Other acquisition:
remove_blank_mzs,quant_MSImagingExperiment-method,
select_tissue_pixels(),
trim_MSI()
# Return a previously parsed acquisition from its cached .rds folder <- system.file("extdata", package = "quantMSImageR") lib <- system.file("extdata", "ion_library_pos04.csv", package = "quantMSImageR") obj <- read_mrm("pos04_test", folder = folder, lib_ion_path = lib, overwrite = FALSE)# Return a previously parsed acquisition from its cached .rds folder <- system.file("extdata", package = "quantMSImageR") lib <- system.file("extdata", "ion_library_pos04.csv", package = "quantMSImageR") obj <- read_mrm("pos04_test", folder = folder, lib_ion_path = lib, overwrite = FALSE)
Drops any feature whose intensities are entirely zero or NA – typically a
transition present in the acquisition method but never detected, or a panel
row padded in when acquisitions were aligned. Reporting these alongside real
measurements is how empty transitions reach a figure.
## S4 method for signature 'quant_MSImagingExperiment' remove_blank_mzs(MSIobject)## S4 method for signature 'quant_MSImagingExperiment' remove_blank_mzs(MSIobject)
MSIobject |
A |
The input object with features carrying no data removed.
Other acquisition:
read_mrm(),
select_tissue_pixels(),
trim_MSI()
p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- remove_blank_mzs(obj)p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- remove_blank_mzs(obj)
Executes the full DESI-MRM workflow on a small synthetic dataset bundled
with the package. The dataset contains two samples – SampleA (circular
tissue, sections 01-03) and SampleB (square tissue, sections 04-06) –
acquired on a panel of eight oxylipin features (seven analytes + one
internal standard, all negative-ion mode).
run_example( render_report = TRUE, output_txt = FALSE, snr_thresh = 3, shapes = NULL, calibrate = TRUE )run_example( render_report = TRUE, output_txt = FALSE, snr_thresh = 3, shapes = NULL, calibrate = TRUE )
render_report |
Logical. Render and open the HTML report in the RStudio
viewer or default browser? Requires pandoc. Default |
output_txt |
Logical. Write per-feature |
snr_thresh |
Numeric. SNR threshold passed to |
shapes |
Character vector of tissue shapes to include – any of
|
calibrate |
Logical. Also run the quantification demo on the
bundled synthetic calibration standards ( |
Distinct tissue shapes per sample make the rendered ion images visually
easy to distinguish, and the bundled ion library carries a Met-1 column
(COX, LOX, IS) that drives the row-split colour bar in the report's
main heatmap and the diagonal colour blocks in the correlation triangles.
All file paths are resolved automatically via system.file(), so the
example works on any machine without editing a YAML.
Invisibly returns the list produced by generate_txt_images(), with
an added calibrated element when calibrate = TRUE: the study sections
with their tissue pixels converted to pg_pixel and pg_mm2 layers,
restricted to the analytes that have a standard.
When render_report = TRUE a report element gives the path to the
rendered HTML.
Other workflow:
generate_txt_images(),
print.quant_validation(),
run_study(),
validate_config()
# The workflow itself, without rendering or opening the HTML report res <- run_example(render_report = FALSE, shapes = "circle") names(res) # The full demo: renders the report and opens it in the viewer/browser if (interactive()) { res <- run_example() res$report # path to the rendered HTML }# The workflow itself, without rendering or opening the HTML report res <- run_example(render_report = FALSE, shapes = "circle") names(res) # The full demo: renders the report and opens it in the viewer/browser if (interactive()) { res <- run_example() res$report # path to the rendered HTML }
Executes the whole workflow for a study described by a single YAML file:
loads every acquisition, applies the tissue masks, runs SNR filtering at each
requested threshold, optionally builds calibration models and converts tissue
pixels to estimated amounts, writes per-feature .txt images, and renders one
HTML report per SNR threshold.
run_study(config_file)run_study(config_file)
config_file |
Path to the study YAML configuration. |
The configuration format is documented by the template shipped with the package:
file.show(system.file("config_template.yaml", package = "quantMSImageR"))
A study can also be run from the command line, which uses this function internally:
Rscript -e 'quantMSImageR::run_study("config.yaml")'
Invisibly, the list produced by generate_txt_images() for the
study, with a calibrated element added when the configuration's
calibration: block is enabled. Called for its side effects: .txt
images, the calibrated .RDS and the HTML reports written under the
configured output paths.
Other workflow:
generate_txt_images(),
print.quant_validation(),
run_example(),
validate_config()
# A minimal study driven from a config, using the bundled synthetic data. # snr_thresh = 0 skips SNR filtering and the tissue-mask requirement, and # both outputs are switched off, so this runs without writing a report. out <- file.path(tempdir(), "qmsi_study") dir.create(out, showWarnings = FALSE) cfg <- list( study = "example_study", paths = list( data_path = system.file("extdata", package = "quantMSImageR"), out_path = out, image_dir = file.path(out, "images"), lib_ion_path = system.file("extdata", "example_ion_library.csv", package = "quantMSImageR") ), samples = list( list(neg = "example", sections = list("section01"), run_id = "S1", label = "A") ), parameters = list(snr_thresh = 0), output = list(render_report = FALSE, output_txt = FALSE) ) cfg_file <- file.path(out, "config.yaml") yaml::write_yaml(cfg, cfg_file) res <- run_study(cfg_file) names(res)# A minimal study driven from a config, using the bundled synthetic data. # snr_thresh = 0 skips SNR filtering and the tissue-mask requirement, and # both outputs are switched off, so this runs without writing a report. out <- file.path(tempdir(), "qmsi_study") dir.create(out, showWarnings = FALSE) cfg <- list( study = "example_study", paths = list( data_path = system.file("extdata", package = "quantMSImageR"), out_path = out, image_dir = file.path(out, "images"), lib_ion_path = system.file("extdata", "example_ion_library.csv", package = "quantMSImageR") ), samples = list( list(neg = "example", sections = list("section01"), run_id = "S1", label = "A") ), parameters = list(snr_thresh = 0), output = list(render_report = FALSE, output_txt = FALSE) ) cfg_file <- file.path(out, "config.yaml") yaml::write_yaml(cfg, cfg_file) res <- run_study(cfg_file) names(res)
Loads a DESI-MRM acquisition, displays ion images of all features so the
user can identify which best discriminates tissue from background, then
opens an interactive ROI-selection window on a chosen feature. The
resulting logical mask is saved as tissue_pixels.csv inside the
acquisition's .raw folder, where generate_txt_images() will find it
automatically.
select_tissue_pixels( name, data_path, lib_ion_path, feature = NULL, enhance = "histogram", overwrite = FALSE, preview = TRUE )select_tissue_pixels( name, data_path, lib_ion_path, feature = NULL, enhance = "histogram", overwrite = FALSE, preview = TRUE )
name |
Character. Acquisition name, without the |
data_path |
Character. Path to the folder that contains the |
lib_ion_path |
Character. Full path to the MRM ion-library CSV. |
feature |
Integer index or character name of the feature to use for
tissue selection. When |
enhance |
Character. Contrast enhancement passed to |
overwrite |
Logical. If |
preview |
Logical. Draw the saved mask (tissue versus background over
the pixel coordinates) once selection finishes, so it can be checked before
the workflow uses it. Default |
This function must be run before the YAML workflow for each acquisition
that does not yet have a tissue_pixels.csv. It requires an interactive R
session with a graphics device (i.e. not inside Rscript --no-save).
Invisibly returns a data frame with columns x, y,
tissue_pixels and background_pixels (logical), one row per pixel, in
acquisition order.
Other acquisition:
read_mrm(),
remove_blank_mzs,quant_MSImagingExperiment-method,
trim_MSI()
# Requires a graphics device and user input, so it only runs interactively. if (interactive()) { # Step 1 (once per acquisition, before running the study): select_tissue_pixels( name = "my_acquisition", data_path = "path/to/raw", lib_ion_path = "path/to/ion_library.csv" ) # Step 2: run the full workflow from the study config run_study("path/to/study.yaml") }# Requires a graphics device and user input, so it only runs interactively. if (interactive()) { # Step 1 (once per acquisition, before running the study): select_tissue_pixels( name = "my_acquisition", data_path = "path/to/raw", lib_ion_path = "path/to/ion_library.csv" ) # Step 2: run the full workflow from the study config run_study("path/to/study.yaml") }
Averages the signal across the pixels of each calibration spot, giving one
response value per standard per level. This is the input
create_cal_curve() fits its models to.
## S4 method for signature 'quant_MSImagingExperiment' summarise_cal_levels( MSIobject, cal_metadata, val_slot = "intensity", cal_header = "sample_type", cal_label = "Cal", id = "identifier" )## S4 method for signature 'quant_MSImagingExperiment' summarise_cal_levels( MSIobject, cal_metadata, val_slot = "intensity", cal_header = "sample_type", cal_label = "Cal", id = "identifier" )
MSIobject |
A |
cal_metadata |
Data frame of calibration metadata, with columns
|
val_slot |
Character. Spectra slot to summarise (default |
cal_header |
Character. Column of |
cal_label |
Character. Value of |
id |
Character. Column present in both |
Every spot is also summarised for dispersion, because a mean and a pixel
count cannot show whether a calibration level was measured reproducibly. The
returned table carries sd_response and cv_response alongside the mean, so
an imprecise level is visible rather than averaged away.
Problems in the calibration design are errors rather than quiet NAs: an
analyte that is not in the object, an identifier that matches no pixel, a
spot with no usable response, and duplicated identifiers that disagree about
amount or level all stop the function. Each of these would otherwise produce
a curve that looks fitted but is not anchored to the data it claims.
The input object with cal_response_data populated: one row per
(standard, calibration spot) pair holding response_perpixel (the mean),
median_response, sd_response, cv_response, pixels,
n_nonmissing and pg_perpixel. Amounts are expressed in pg per
pixel.
Other calibration:
calibrationInfo-class,
create_cal_curve,quant_MSImagingExperiment-method,
int2conc,quant_MSImagingExperiment-method,
plot_cal_coverage,quant_MSImagingExperiment-method
cal_dir <- system.file("extdata", "cal_example.raw", package = "quantMSImageR") cal <- as(readRDS(file.path(cal_dir, "cal_MSI.RDS")), "quant_MSImagingExperiment") cal_metadata <- read.csv(file.path(cal_dir, "calibration_metadata.csv")) cal <- summarise_cal_levels(cal, cal_metadata, val_slot = "intensity", cal_label = "Cal", id = "identifier")cal_dir <- system.file("extdata", "cal_example.raw", package = "quantMSImageR") cal <- as(readRDS(file.path(cal_dir, "cal_MSI.RDS")), "quant_MSImagingExperiment") cal_metadata <- read.csv(file.path(cal_dir, "calibration_metadata.csv")) cal <- summarise_cal_levels(cal, cal_metadata, val_slot = "intensity", cal_label = "Cal", id = "identifier")
Holds the tabular views of an imaging experiment produced by
createMSIDatamatrix(): one row per pixel, and optionally one row per region
of interest, together with the accompanying metadata. It is carried in the
tissueInfo slot of a quant_MSImagingExperiment.
all_pixel_matrixdata.frame, one row per pixel and one column
per feature.
roi_average_matrixdata.frame, one row per region of interest,
populated only when createMSIDatamatrix(roi_header=) is given.
sample_metadatadata.frame describing the rows of the matrices
above (sample, run, ROI identifier).
feature_metadatadata.frame describing their columns.
All four are zero-row data frames until createMSIDatamatrix() has run.
Access them with tissueMatrix() and tissueData() rather than @.
An object of class tissueInfo.
roi_average_matrixdata.frame of per-ROI averages.
all_pixel_matrixdata.frame of per-pixel values.
sample_metadatadata.frame describing the matrix rows.
feature_metadatadata.frame describing the matrix columns.
quant_MSImagingExperiment, createMSIDatamatrix(),
quantMSImageR-accessors
ti <- tissueInfo() p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- createMSIDatamatrix(obj, val_slot = "intensity", roi_header = NA) dim(tissueMatrix(obj, which = "pixel"))ti <- tissueInfo() p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- createMSIDatamatrix(obj, val_slot = "intensity", roi_header = NA) dim(tissueMatrix(obj, which = "pixel"))
Drops any x-column or y-row in which every pixel is labelled as
"background_pixels" (or the historical "noise_pixels") in
pData(MSI_data)$sample_name. This trims empty scan borders that arise from
the Waters acquisition geometry without affecting tissue or mixed-content
rows/columns.
trim_MSI(MSI_data)trim_MSI(MSI_data)
MSI_data |
A |
A subset quant_MSImagingExperiment with pure-background border
pixels removed.
Other acquisition:
read_mrm(),
remove_blank_mzs,quant_MSImagingExperiment-method,
select_tissue_pixels()
p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- trim_MSI(obj)p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- trim_MSI(obj)
Structural and cross-file checks on a study config before anything is processed: required blocks present, referenced files and ion-library columns actually exist, enumerated values spelled correctly, and the calibration and internal-standard settings coherent with each other.
validate_config(config, check_paths = TRUE)validate_config(config, check_paths = TRUE)
config |
A config list, or a path to a study YAML file. |
check_paths |
Logical. Also check that the referenced data directory,
ion library and calibration files exist on disk (default |
Every check runs, so one call reports every problem rather than stopping at
the first. run_study() calls this first and refuses to start if there are
errors – these are mistakes that would otherwise surface as an obscure
failure halfway through a long run, or worse, as a plausible-looking result
computed from the wrong column.
A quant_validation object with errors, warnings and a summary
data frame of every check.
Other workflow:
generate_txt_images(),
print.quant_validation(),
run_example(),
run_study()
# The shipped template is structurally valid; its placeholder paths are not # meant to exist, so the path checks are skipped here. cfg <- system.file("config_template.yaml", package = "quantMSImageR") validate_config(cfg, check_paths = FALSE)# The shipped template is structurally valid; its placeholder paths are not # meant to exist, so the path checks are skipped here. cfg <- system.file("config_template.yaml", package = "quantMSImageR") validate_config(cfg, check_paths = FALSE)
Zeros in an MRM acquisition mean "nothing recorded" rather than "measured as
zero", and left in place they bias means and compress colour scales. This
converts them to NA so they are excluded from summaries.
## S4 method for signature 'quant_MSImagingExperiment' zero2na(MSIobject, val_slot = "intensity")## S4 method for signature 'quant_MSImagingExperiment' zero2na(MSIobject, val_slot = "intensity")
MSIobject |
A |
val_slot |
Character. Spectra slot to modify (default |
The input object with zero values in val_slot replaced by NA.
This modifies val_slot in place rather than adding a new layer. Keep a copy
of the object if the original values are needed afterwards.
Other filtering:
applySNR,quant_MSImagingExperiment-method,
back2NA,quant_MSImagingExperiment-method,
int2response,quant_MSImagingExperiment-method,
int2snr,quant_MSImagingExperiment-method
p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- zero2na(obj, val_slot = "intensity")p <- system.file("extdata", "example.raw", "section01.RDS", package = "quantMSImageR") obj <- as(readRDS(p), "quant_MSImagingExperiment") obj <- zero2na(obj, val_slot = "intensity")