This repository contains downstream analysis scripts for studying feature missingness in untargeted LCβMS metabolomics data. We used repeated technical injections to estimate how consistently each feature is detected after data processing and to calculate peak-level attributes that may explain stochastic detection.
Raw vendor files were converted to .mzML using ProteoWizard/MSConvert, then processed using MassCube (v1.2.13). We also tested this workflow on MZmine (4.10.6) and MS-DIAL (v5.5.260323). The scripts in this repository start from the raw aligned feature tables exported by each processing software and apply the downstream filtering, detection probability calculation, raw signal extraction, and peak attribute calculation.
The sample data included in this repository contains a small subset of files for testing the workflow. Each software folder currently includes 3 analytical sample files plus 1 method blank (MB) file. A small sample mzML.zip is also included. The full dataset will be available on Zenodo.
The main metric used in this project is the probability of detection,
where
In this project, a feature is considered detected in a processed feature table when its intensity is greater than the configured detection threshold:
INT_THRESHOLD = 1000With 25 technical replicates,
The extraction scripts also calculate peak attributes for each replicate, including intensity, area, peak width, scan count, signal to noise ratio (S/N), smoothness, sharpness, symmetry, local peak density, local rank, and RT shift. These attributes are used to examine how chromatographic behavior, local chemical environment, and signal variability relate to stochastic feature detection.
The overall workflow is:
Raw vendor files
β
mzML conversion using ProteoWizard/MSConvert
β
Feature detection and alignment using MassCube, MZmine, or MS-DIAL
β
Software-specific aligned feature tables
β
Filtering, detection probability, and peak attribute extraction
β
Feature detection and peak attribute summaries
Users do NOT need to pre-calculate
The included filters are:
m/z >= 65
RT <= 23 min
max sample intensity >= 3 Γ max blank intensity
The m/z filter is included because the MS method was set to acquire ions above 65 m/z, but lower m/z features can still appear in software outputs.
You can edit these values near the top of each analysis script:
MIN_MZ = 65
MAX_RT = 23
BLANK_MULTIPLIER = 3
INT_THRESHOLD = 1000For example, to use a stricter blank filter:
BLANK_MULTIPLIER = 5missingness/
β
βββ README.md
β
βββ scripts/
β βββ masscube_analysis.py
β βββ mzmine_analysis.py
β βββ msdial_analysis.py
β βββ peak_attributes.py
β βββ run_masscube.sh
β βββ run_msdial.sh
β βββ run_mzmine.sh
β
βββ sample_data/
βββ masscube_sample/
β βββ aligned_feature_table.csv
β βββ single_files/
β βββ 100-1_P1-C-C-1_01_13558.txt
β βββ 100-2_P1-C-C-1_01_13559.txt
β βββ 100-3_P1-C-C-1_01_13560.txt
β βββ MB_P1-A-4_01_13240.txt
β
βββ mzmine_sample/
β βββ aligned_feature_table.csv
β
βββ msdial_sample/
β βββ feature_table_mb.csv
β βββ feature_table_no_mb.csv
β βββ single_files/
β βββ 100-1_P1-C-C-1_01_13558.txt
β βββ 100-2_P1-C-C-1_01_13559.txt
β βββ 100-3_P1-C-C-1_01_13560.txt
β βββ MB_P1-A-4_01_13240.txt
β
βββ mzML/
βββ mzML.zip
The sample data are intentionally small so users can test whether the scripts run correctly. For full-scale analysis, replace the sample files with complete aligned feature tables, single-file outputs, and .mzML files.
The scripts use relative paths by default. If you run them from the repository root, they will look for input files inside sample_data/.
Install the main dependencies with:
pip install pandas numpy pyteomics tqdm scipy matplotlibEach software workflow has a small shell script in scripts/. The easiest way to run the analysis is to edit the paths at the top of the shell script, then run it from the VS Code terminal.
scripts/
βββ masscube_analysis.py
βββ msdial_analysis.py
βββ mzmine_analysis.py
βββ peak_attributes.py
βββ run_masscube.sh
βββ run_msdial.sh
βββ run_mzmine.sh
On Windows, use Git Bash or WSL in the VS Code terminal. Paths should use forward slashes (/).
For Git Bash on Windows:
PROJECT_DIR="E:/Code/Python/MassCube"For WSL:
PROJECT_DIR="/mnt/e/Code/Python/MassCube"Avoid Windows backslash paths inside .sh files:
PROJECT_DIR="E:\Nhi\Python\MassCube"Each .sh file automatically finds the repository root, so it can be launched from VS Code without manually changing directories.
Run the workflows with:
bash scripts/run_masscube.sh
bash scripts/run_msdial.sh
bash scripts/run_mzmine.shOr, on macOS/Linux, make the scripts executable once:
chmod +x scripts/run_masscube.sh scripts/run_msdial.sh scripts/run_mzmine.shThen run:
./scripts/run_masscube.sh
./scripts/run_msdial.sh
./scripts/run_mzmine.shInside each shell script, leave any variable empty to use the default path defined in the Python script. For example:
BLANK_MZML=""means that --blank-mzml will not be passed, and the Python script will use its default blank mzML path.
Run:
bash scripts/run_masscube.shDefault input:
sample_data/masscube_sample/aligned_feature_table.csv
sample_data/masscube_sample/single_files/
sample_data/mzML/
MassCube single_files/*.txt are converted automatically to single_files_csv/*.csv. Existing CSV files are reused unless reconversion is requested.
Default output:
sample_data/masscube_sample/masscube_pdet/
Users can specify new paths by editing scripts/run_masscube.sh:
PROJECT_DIR="sample_data/masscube_sample"
INPUT_CSV=""
SINGLE_TXT_DIR=""
SINGLE_CSV_DIR=""
MZML_ROOT="sample_data/mzML"
BLANK_MZML=""
OUTPUT_ROOT=""Run:
bash scripts/run_msdial.shMS-DIAL analysis in this project uses two aligned tables because it gap fills automatically and the Fill % from a blank-included table also includes the blank in the denominator. Since we calculate Fill %, this would be inaccurate. Users would need to manually export individual traces into single_files/.
Inputs:
feature_table_mb.csv used for m/z, RT, and blank filtering
feature_table_no_mb.csv used for Fill % and P_detection
single_files/ individual MS-DIAL peak lists
sample_data/mzML/ mzML files
Default output:
sample_data/msdial_sample/msdial_pdet/
The feature table with MB analyzed is used for blank filtering, after which it's matched to the no-blank table to generate a list of filtered features with correct
sample_data/msdial_sample/aligned_feature_table.csv
Users can edit these variables in scripts/run_msdial.sh:
PROJECT_DIR="sample_data/msdial_sample"
BLANK_INCLUDED_CSV=""
NOBLANK_CSV=""
INPUT_CSV=""
SINGLE_FILES_DIR=""
SINGLE_FILES_CSV_DIR=""
MZML_DIR="sample_data/mzML/100"
BLANK_MZML=""
OUTPUT_ROOT=""Run:
bash scripts/run_mzmine.shDefault input:
sample_data/mzmine_sample/aligned_feature_table.csv
sample_data/mzML/
MZmine stores sample-specific RT ranges directly in the aligned feature table, so no individual trace files are needed.
Expected columns include:
rt
mz
id
datafile:<sample>.d:height
datafile:<sample>.d:area
datafile:<sample>.d:rt_range:min
datafile:<sample>.d:rt_range:max
Default output:
sample_data/mzmine_sample/mzmine_pdet/
Users can edit these variables in scripts/run_mzmine.sh:
PROJECT_DIR="sample_data/mzmine_sample"
INPUT_CSV=""
MZML_DIR="sample_data/mzML/100"
BLANK_MZML=""
OUTPUT_ROOT=""The shell scripts are wrappers around the Python scripts. Advanced users can still pass command line flags directly if they prefer. A list of MassCube flags is below (see software-specific scripts for details):
--project-dir project folder
--input-csv aligned feature table
--single-txt-dir MassCube single-file TXT folder
--single-csv-dir converted single-file CSV folder
--mzml-root mzML root folder
--blank-mzml blank mzML file for S/N
--output-root output folder
--skip-txt-conversion skip TXT to CSV conversion
--overwrite-converted-csv force TXT to CSV reconversion
For example:
python scripts/masscube_analysis.py --project-dir path/to/project --mzml-root path/to/mzMLEach analysis script creates a software-specific output folder inside sample_data/*_sample with similar structure. The example below expands on the MassCube output only:
masscube_pdet/
βββ masscube_pdet_full.csv
βββ masscube_extraction_analysis.csv
βββ masscube_pdet_summary.csv
βββ feature_filter_report.csv
βββ original_table.csv
βββ attributes/
β βββ area.csv
β βββ density.csv
β βββ int.csv
β βββ ...
β βββ symmetry.csv
β βββ width.csv
βββ 0/
βββ 4/
βββ ...
βββ 100/
msdial_pdet/
βββ same structure with msdial file prefixes
mzmine_pdet/
βββ same structure with mzmine file prefixes
The main table, *_pdet_full.csv, contains only the analysis-ready attributes: area, density, int, rank, rtshift, scancount, sharpness, smoothness, snr, symmetry, and width. Each attribute is reported across replicates using columns such as int_1, int_2, and so on.
The *_extraction_analysis.csv file contains diagnostic information such as RT windows, scan IDs, scanlists, raw fallback values, intensity sources, excluded scans, and blank noise estimates.
The attributes/ folder contains one file per attribute.
The numbered folders contain features grouped by (P_{\mathrm{detection}}), from 0/ to 100/.
After running one of the extraction workflows, summarize replicate-level attributes using:
python scripts/peak_attributes.pyChoose a software output:
python scripts/peak_attributes.py --model masscube
python scripts/peak_attributes.py --model msdial
python scripts/peak_attributes.py --model mzmineOr provide a table directly:
python scripts/peak_attributes.py --input-csv path/to/masscube_pdet_full.csvThe output is written to peak_analysis/ inside the software folder *_sample/:
peak_analysis/
βββ int_summary.csv
βββ area_summary.csv
βββ width_summary.csv
βββ scancount_summary.csv
βββ snr_summary.csv
βββ smoothness_summary.csv
βββ sharpness_summary.csv
βββ symmetry_summary.csv
βββ density_summary.csv
βββ rank_summary.csv
βββ rtshift_summary.csv
Each summary file contains feature metadata, the value for that attribute across replicates, and summary statistics: max, min, mean, median, 75_perc, 25_perc, sd, and rsd.
Citation information will be added after manuscript submission or publication.
This project is licensed under the Apache License 2.0. See the LICENSE file for details.