| name | bio-metabolomics-msdial-preprocessing |
| description | Process metabolomics data with MS-DIAL for peak detection, alignment, annotation, and export to feature tables. Use when: user has MS-DIAL output files, wants to import MS-DIAL results into R/Python, needs peak alignment from MS-DIAL, or prefers GUI-based LC-MS preprocessing. Triggers: MS-DIAL, MS-DIAL output, MSDIAL, peak alignment, MS-DIAL export, GUI preprocessing, alternative to XCMS, MS-DIAL console mode, metabolomics feature table from MS-DIAL. |
| tool_type | mixed |
| primary_tool | msdial |
| upstream | {"repo":"https://github.com/GPTomics/bioSkills","license":"MIT","original_author":"GPTomics"} |
Version Compatibility
Reference examples tested with: numpy 1.26+, pandas 2.2+, scanpy 1.10+, xcms 4.0+
Before using code patterns, verify installed versions match. If versions differ:
- Python:
pip show <package> then help(module.function) to check signatures
- R:
packageVersion('<pkg>') then ?function_name to verify parameters
- CLI:
<tool> --version then <tool> --help to confirm flags
If code throws ImportError, AttributeError, or TypeError, introspect the installed
package and adapt the example to match the actual API rather than retrying.
MS-DIAL Preprocessing
"Process my LC-MS data with MS-DIAL" → Detect chromatographic peaks, align across samples, annotate metabolites, and export a feature table for statistical analysis.
- CLI: MS-DIAL GUI or console mode for peak picking and alignment
MS-DIAL GUI Workflow
MS-DIAL provides a user-friendly GUI for complete metabolomics preprocessing:
- Project Setup - Create new project, select data type
- Data Import - Load mzML/ABF files
- Peak Detection - Automatic peak picking
- Alignment - Cross-sample alignment
- Gap Filling - Fill missing values
- Annotation - Database matching
- Export - Export for downstream analysis
Export MS-DIAL Results to R
library(tidyverse)
msdial_data <- read.csv('msdial_alignment_result.csv', check.names = FALSE)
sample_cols <- grep('Area$|^Sample', colnames(msdial_data), value = TRUE)
meta_cols <- setdiff(colnames(msdial_data), sample_cols)
feature_info <- msdial_data[, meta_cols]
intensity_matrix <- as.matrix(msdial_data[, sample_cols])
rownames(intensity_matrix) <- msdial_data$`Alignment ID`
cat('Loaded', nrow(intensity_matrix), 'features from', ncol(intensity_matrix), 'samples\n')
Filter MS-DIAL Results
annotated <- feature_info$`Annotation tag` != 'Unknown'
fill_threshold <- 50
good_fill <- feature_info$`Fill %` >= fill_threshold
has_msms <- feature_info$`MS/MS assigned` == TRUE
filtered_idx <- which(good_fill)
filtered_matrix <- intensity_matrix[filtered_idx, ]
filtered_info <- feature_info[filtered_idx, ]
cat('After filtering:', nrow(filtered_matrix), 'features\n')
MS-DIAL Data to XCMS-Like Format
library(SummarizedExperiment)
se <- SummarizedExperiment(
assays = list(raw = filtered_matrix),
rowData = filtered_info,
colData = data.frame(
sample = colnames(filtered_matrix),
row.names = colnames(filtered_matrix)
)
)
sample_metadata <- read.csv('sample_metadata.csv')
colData(se) <- merge(colData(se), sample_metadata, by.x = 'sample', by.y = 'sample_id')
MS-DIAL Batch Processing (Console Mode)
MsdialConsoleApp.exe lcmsdda -i input_folder -o output_folder -m msdial_param.txt
Parameter File Example
# MS-DIAL Parameter File for LC-MS DDA
# Data collection
Data type=Centroid
Ion mode=Positive
MS1 data type=Centroid
MS2 data type=Centroid
# Peak detection
Smoothing method=LinearWeightedMovingAverage
Smoothing level=3
Minimum peak width=5
Minimum peak height=1000
Mass slice width=0.1
# Alignment
Retention time tolerance=0.1
MS1 tolerance=0.01
Retention time factor=0.5
MS1 factor=0.5
# Identification
MSP file path=MassBank-GNPS.msp
Retention time tolerance for identification=0.5
Accurate mass tolerance (MS1)=0.01
Accurate mass tolerance (MS2)=0.05
Identification score cut off=80
Python Processing of MS-DIAL Output
Goal: Convert MS-DIAL alignment results into a clean, filtered, log-transformed feature matrix for downstream statistical analysis.
Approach: Parse MS-DIAL CSV export to separate feature metadata from intensity values, filter by fill percentage, log2-transform, and export as a tidy matrix.
import pandas as pd
import numpy as np
df = pd.read_csv('msdial_alignment_result.csv')
sample_cols = [c for c in df.columns if 'Area' in c or c.startswith('Sample')]
meta_cols = [c for c in df.columns if c not in sample_cols]
feature_info = df[meta_cols].copy()
intensities = df[sample_cols].values
sample_names = [c.replace(' Area', '').strip() for c in sample_cols]
fill_pct = df['Fill %'].values
good_features = fill_pct >= 50
intensities_filtered = intensities[good_features]
feature_info_filtered = feature_info[good_features].reset_index(drop=True)
print(f'Filtered: {sum(good_features)} / {len(good_features)} features')
intensities_log = np.log2(intensities_filtered + 1)
result_df = pd.DataFrame(
intensities_log,
columns=sample_names,
index=feature_info_filtered['Alignment ID']
)
result_df.to_csv('msdial_processed.csv')
MS-DIAL Annotation Levels
annotation_levels <- data.frame(
level = c('Lipid', 'Metabolite', 'SuggestedLipid', 'SuggestedMetabolite', 'Unknown'),
confidence = c('High', 'High', 'Medium', 'Medium', 'None'),
description = c(
'MS/MS match to lipid database',
'MS/MS match to metabolite database',
'Mass match to lipid (no MS/MS)',
'Mass match to metabolite (no MS/MS)',
'No database match'
)
)
table(feature_info$`Annotation tag`)
Compare MS-DIAL vs XCMS Results
msdial_features <- read.csv('msdial_alignment_result.csv')
xcms_features <- read.csv('xcms_features.csv')
cat('MS-DIAL features:', nrow(msdial_features), '\n')
cat('XCMS features:', nrow(xcms_features), '\n')
match_features <- function(mz1, rt1, mz2, rt2, mz_tol = 0.01, rt_tol = 0.5) {
matches <- data.frame()
for (i in 1:length(mz1)) {
mz_match <- abs(mz2 - mz1[i]) < mz_tol
rt_match <- abs(rt2 - rt1[i]) < rt_tol
both_match <- which(mz_match & rt_match)
if (length(both_match) > 0) {
matches <- rbind(matches, data.frame(idx1 = i, idx2 = both_match[1]))
}
}
return(matches)
}
matched <- match_features(
msdial_features$`Average Mz`, msdial_features$`Average Rt(min)`,
xcms_features$mzmed, xcms_features$rtmed / 60
)
cat('Matched features:', nrow(matched), '\n')
Export for MetaboAnalyst
metaboanalyst_format <- t(filtered_matrix)
sample_info <- colData(se)
metaboanalyst_df <- cbind(
Sample = rownames(metaboanalyst_format),
Group = sample_info$condition,
as.data.frame(metaboanalyst_format)
)
write.csv(metaboanalyst_df, 'for_metaboanalyst.csv', row.names = FALSE)
Normalization Options
normalize_istd <- function(data, istd_idx) {
istd_values <- data[istd_idx, ]
sweep(data[-istd_idx, ], 2, istd_values, '/')
}
normalize_loess <- function(data, qc_idx, span = 0.75) {
qc_data <- data[, qc_idx]
qc_median <- apply(qc_data, 1, median)
normalized <- data
for (i in 1:ncol(data)) {
loess_fit <- loess(data[, i] ~ qc_median, span = span)
normalized[, i] <- data[, i] / predict(loess_fit)
}
return(normalized)
}
normalize_pqn <- function(data) {
reference <- apply(data, 1, median)
quotients <- sweep(data, 1, reference, '/')
sample_medians <- apply(quotients, 2, median, na.rm = TRUE)
sweep(data, 2, sample_medians, '/')
}
Related Skills
- xcms-preprocessing - Alternative preprocessing with XCMS
- metabolite-annotation - Additional annotation methods
- normalization-qc - Detailed normalization approaches
- lipidomics - Lipid-specific MS-DIAL workflows