Skill Tracer
Skills › Scientific Agent Skills › pyopenms › detect_features_centroided.py

detect_features_centroided.py

85 lines · skills/pyopenms/scripts/detect_features_centroided.py at 5f2bc03

1#!/usr/bin/env python3
2"""
3Peptide/Centroided Feature Detection
4
5Detect features in centroided (peak-picked) LC-MS data using
6FeatureFinderAlgorithmPicked -- the modern replacement for the removed
7FeatureFinderCentroided. Suited to peptide/proteomics data with defined
8isotope patterns and charge states.
9
10Outputs a featureXML and optionally a CSV table.
12Usage:
13 python detect_features_centroided.py centroided.mzML
14 python detect_features_centroided.py data.mzML --out-csv feats.csv --charge-low 2 --charge-high 5
15"""
17import argparse
18import os
19import sys
21try:
22 import pyopenms as ms
23except ImportError:
24 print("Error: pyopenms not installed. Install with: uv pip install pyopenms")
25 sys.exit(1)
28from _common import centroided_ms1
31def detect_features(exp, mz_tol_da=0.004, charge_low=1, charge_high=4, min_spectra=7, assume_centroided=False):
32 exp = centroided_ms1(exp, assume_centroided)
33 ff = ms.FeatureFinderAlgorithmPicked()
34 params = ff.getDefaults()
35 params.setValue("mass_trace:mz_tolerance", float(mz_tol_da))
36 params.setValue("mass_trace:min_spectra", int(min_spectra))
37 params.setValue("isotopic_pattern:charge_low", int(charge_low))
38 params.setValue("isotopic_pattern:charge_high", int(charge_high))
39 ff.setParameters(params)
41 features = ms.FeatureMap()
42 seeds = ms.FeatureMap()
43 ff.run(exp, features, params, seeds)
44 features.setUniqueIds()
45 return features
48def main():
49 parser = argparse.ArgumentParser(description="Centroided/peptide feature detection.")
50 parser.add_argument("input", help="Centroided mzML file")
51 parser.add_argument("--out-features", help="Output featureXML (default: <input>.featureXML)")
52 parser.add_argument("--out-csv", help="Optional CSV table of features")
53 parser.add_argument("--mz-tol-da", type=float, default=0.004, help="Absolute m/z tolerance in Th (OpenMS Da option; default 0.004)")
54 parser.add_argument("--assume-centroided", action="store_true", help="Accept unknown MS1 spectrum type after independent verification")
55 parser.add_argument("--charge-low", type=int, default=1, help="Lower charge bound (default 1)")
56 parser.add_argument("--charge-high", type=int, default=4, help="Upper charge bound (default 4)")
57 parser.add_argument("--min-spectra", type=int, default=7, help="Min scans per feature (default 7)")
58 args = parser.parse_args()
60 if not os.path.exists(args.input):
61 print(f"Error: file not found: {args.input}")
62 sys.exit(1)
64 exp = ms.MSExperiment()
65 ms.FileHandler().loadExperiment(args.input, exp)
66 print(f"Loaded {exp.getNrSpectra()} spectra from {args.input}")
68 fm = detect_features(exp, mz_tol_da=args.mz_tol_da, charge_low=args.charge_low,
69 charge_high=args.charge_high, min_spectra=args.min_spectra,
70 assume_centroided=args.assume_centroided)
71 fm.setPrimaryMSRunPath([os.path.abspath(args.input)])
72 print(f"Features detected: {fm.size()}")
74 out_features = args.out_features or os.path.splitext(args.input)[0] + ".featureXML"
75 ms.FeatureXMLFile().store(out_features, fm)
76 print(f"Wrote {out_features}")
78 if args.out_csv:
79 df = fm.get_df()
80 df.to_csv(args.out_csv, index=False)
81 print(f"Wrote {args.out_csv} ({len(df)} rows)")
84if __name__ == "__main__":
85 main()