Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Load and parse mass spectrometry data formats including mzML, mzXML, and quantification tool outputs like MaxQuant proteinGroups.txt. Use when starting a proteomics analysis with raw or processed MS data. Handles contaminant filtering and missing value assessment.
.claude/skills/bio-proteomics-data-import/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-11 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✓ | ▲ Improved | — | — |
| case-16 | ✗→✓ | ▲ Improved | — | — |
| case-05 | ✗→✓ | ▲ Improved | — | — |
| case-09 | ✗→✓ | ▲ Improved | — | — |
Reference examples tested with: MSnbase 2.28+, pandas 2.2+
Before using code patterns, verify installed versions match. If versions differ:
pip show <package> then help(module.function) to check signaturespackageVersion('<pkg>') then ?function_name to verify parametersIf code throws ImportError, AttributeError, or TypeError, introspect the installed package and adapt the example to match the actual API rather than retrying.
"Load my mass spec data into Python" → Parse mzML/mzXML raw files or MaxQuant proteinGroups.txt into data structures for programmatic access and downstream analysis.
pyopenms.MzMLFile().load() for raw spectra, pandas.read_csv() for search engine outputsMSnbase::readMSData() for raw, read.delim() for MaxQuant/Proteome DiscovererGoal: Parse raw mass spectrometry data files into memory for programmatic access.
Approach: Load mzML/mzXML into an MSExperiment object, then iterate spectra by MS level to access peaks and precursor info.
pythonfrom pyopenms import MSExperiment, MzMLFile, MzXMLFile exp = MSExperiment() MzMLFile().load('sample.mzML', exp) for spectrum in exp: if spectrum.getMSLevel() == 1: mz, intensity = spectrum.get_peaks() elif spectrum.getMSLevel() == 2: precursor = spectrum.getPrecursors()[0] precursor_mz = precursor.getMZ()
Goal: Import MaxQuant proteinGroups.txt with contaminant and decoy filtering.
Approach: Read the TSV file, remove reverse hits, contaminants, and site-only identifications, then extract intensity columns.
pythonimport pandas as pd protein_groups = pd.read_csv('proteinGroups.txt', sep='\t', low_memory=False) # Filter contaminants and reverse hits contam_col = 'Potential contaminant' if 'Potential contaminant' in protein_groups.columns else 'Contaminant' protein_groups = protein_groups[ (protein_groups.get(contam_col, '') != '+') & (protein_groups.get('Reverse', '') != '+') & (protein_groups.get('Only identified by site', '') != '+') ] # Extract intensity columns (LFQ or iBAQ) intensity_cols = [c for c in protein_groups.columns if c.startswith('LFQ intensity') or c.startswith('iBAQ ')] if not intensity_cols: intensity_cols = [c for c in protein_groups.columns if c.startswith('Intensity ') and 'Intensity L' not in c] intensities = protein_groups[['Protein IDs', 'Gene names'] + intensity_cols]
Goal: Import DIA-NN long-format report and reshape into a protein-by-sample quantification matrix.
Approach: Pivot the report table on protein group and run columns, using MaxLFQ values.
pythondiann_report = pd.read_csv('report.tsv', sep='\t') # Pivot to protein-level matrix protein_matrix = diann_report.pivot_table( index='Protein.Group', columns='Run', values='PG.MaxLFQ', aggfunc='first' )
Goal: Load raw MS data in R for interactive exploration of spectra and metadata.
Approach: Use MSnbase's on-disk reading mode to access spectra and feature metadata without loading all data into memory.
rlibrary(MSnbase) raw_data <- readMSData('sample.mzML', mode = 'onDisk') spectra <- spectra(raw_data) header_info <- fData(raw_data)
Goal: Quantify missing value patterns across proteins and samples in an intensity matrix.
Approach: Count NaN values per protein and per sample, then compute overall missing percentage.
pythondef assess_missing_values(df, intensity_cols): missing_per_protein = df[intensity_cols].isna().sum(axis=1) missing_per_sample = df[intensity_cols].isna().sum(axis=0) total_missing = df[intensity_cols].isna().sum().sum() total_values = df[intensity_cols].size missing_pct = 100 * total_missing / total_values return {'per_protein': missing_per_protein, 'per_sample': missing_per_sample, 'total_pct': missing_pct}
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +23 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.