lumnik. / scénarios Tous les scénarios · English

Spectrométrie haute résolution: le QC dérive de 3,84 ppm, les échantillons suivants le savent

Objectif Lire l'export QC d'un criblage LC-HRMS sans perdre une décimale, et signaler chaque échantillon acquis après un QC hors de sa tolérance en masse.

Un laboratoire d'environnement crible des micropolluants dans l'eau sur un Orbitrap. Les transitoires et les spectres restent sur l'instrument; lumnik lit ce que le logiciel de traitement exporte.

HRMS-26-1106-A.csv
Batch;HRMS-26-1106-A
Instrument;FTMS-01 (Orbitrap, positive ESI)
Method;Screening_pos_R70k
Mass calibration;2026-11-05 17:40 (external, positive calibration solution)
QC acceptance;|Δm| <= 3.0 ppm on caffeine, MRFA and reserpine

Inj;Type;Sample;Acquired;Compound;Ion;m/z theo;m/z meas;Δm;Intensity;R;Max |Δm|
;;;;;;(Th);(Th);(ppm);(counts);(FWHM);(ppm)
1;QC;QC-SST;06/11/2026 07:30;Caffeine;[C8H10N4O2+H]+;195.08765;195.08771;0.30;25894746;69900;0.52
;;;;MRFA;[C23H37N7O5S+H]+;524.26496;524.26524;0.52;117023040;42400;
;;;;Reserpine;[C33H40N2O9+H]+;609.28066;609.28075;0.15;69156004;40600;
2;Blank;Solvent blank;06/11/2026 07:48;Atrazine;[C8H14ClN5+H]+;216.10105;;;n.d.;;
;;;;Carbamazepine;[C15H12N2O+H]+;237.10224;;;n.d.;;
;;;;Sulfamethoxazole;[C10H11N3O3S+H]+;254.05939;;;n.d.;;
;;;;Diclofenac;[C14H11Cl2NO2+H]+;296.02396;;;n.d.;;
3;Sample;W-26-0401;06/11/2026 08:06;Atrazine;[C8H14ClN5+H]+;216.10105;216.10099;-0.28;2620037;;
;;;;Carbamazepine;[C15H12N2O+H]+;237.10224;;;n.d.;;
;;;;Sulfamethoxazole;[C10H11N3O3S+H]+;254.05939;;;n.d.;;
;;;;Diclofenac;[C14H11Cl2NO2+H]+;296.02396;296.02400;0.13;406567;;
4;Sample;W-26-0402;06/11/2026 08:24;Atrazine;[C8H14ClN5+H]+;216.10105;;;n.d.;;

… 49 lignes de plus

manifests/10-qc-export.yaml
apiVersion: connectors.lumnik.io/v1kind: Connectormetadata:  name: scenario-hrms-a  connector_type: csv-file  scopes: [qc-hrms-a]spec:  transport:    kind: local    path: /tmp/lumnik-scenario/hrms-qc-mass-accuracy/a/*.csv   # the folder the processing software exports to  parser:    delimiter: ";"    has_header: false              # the header runs over two lines, under a key;value block    columns: [inj, type, sample, acquired, compound, ion, mz_theo, mz_meas, dm_ppm, intensity, resolution, qc_max_ppm]    short_rows: skip-leading       # the key;value block before the table: skipped, never a dead letter  after_process: none  mapping:    dataset:      # the two header lines (the names, then the units) carry no theoretical m/z      - filter-where: { column: mz_theo, regex: "[0-9]+\\.[0-9]+" }    cell:      # the injection's fields are printed on its first line only; inj is left as written: one line per injection      - fill-down: { columns: [type, sample, acquired] }      # the last QC speaks for the samples after it, until the instrument is recalibrated      - fill-down: { columns: [qc_max_ppm], reset-when: { column: type, in: [Cal] } }      # n.d.: no peak in the window; < LOD: a peak below the limit of detection. Kept apart from the number.      - regex-extract: { column: intensity, pattern: "^(n\\.d\\.|< LOD)$", groups: { 1: detection } }      - regex-replace: { column: intensity, pattern: "^(n\\.d\\.|< LOD)$", replacement: "" }      - parse-number: { column: inj, integer: true }      - parse-number: { column: mz_theo, decimal-separator: "." }      - parse-number: { column: mz_meas, decimal-separator: "." }      - parse-number: { column: dm_ppm, decimal-separator: "." }      - parse-number: { column: intensity, integer: true }      - parse-number: { column: resolution, integer: true }      - parse-number: { column: qc_max_ppm, decimal-separator: "." }      - parse-date: { column: acquired, formats: ["dd/MM/yyyy HH:mm"], zone: Europe/Paris }
manifests/20-after-a-failed-qc.yaml
apiVersion: apps.lumnik.io/v1kind: Processmetadata:  name: scenario-hrms-qc-aspec:  scope: qc-hrms-a  on: { event: data.row.changed, table: connector.t_scenario_hrms_a }  when:    - type=Sample    - inj>0                          # the injection's first line: one decision per sample, not per compound    - qc_max_ppm>3                   # the QC acceptance: |Δm| <= 3.0 ppm on every calibrant ion  emit:    type: decision.after-failed-qc-a    message: "{sample} (injection {inj}): the QC before it reads {qc_max_ppm} ppm, acceptance 3.0 ppm"    key: sample
HRMS-26-1106-B.csv
Batch;HRMS-26-1106-B
Instrument;FTMS-01 (Orbitrap, positive ESI)
Method;Screening_pos_R70k
Mass calibration;2026-11-05 17:40 (external, positive calibration solution)
QC acceptance;|Δm| <= 3.0 ppm on caffeine, MRFA and reserpine

Inj;Type;Sample;Acquired;Compound;Ion;m/z theo;m/z meas;Δm;Intensity;R;Max |Δm|
;;;;;;(Th);(Th);(ppm);(counts);(FWHM);(ppm)
1;QC;QC-SST;06/11/2026 13:30;Caffeine;[C8H10N4O2+H]+;195.08765;195.08770;0.25;24385043;70900;0.35
;;;;MRFA;[C23H37N7O5S+H]+;524.26496;524.26515;0.35;117614317;43000;
;;;;Reserpine;[C33H40N2O9+H]+;609.28066;609.28082;0.27;62832434;40800;
2;Sample;W-26-0413;06/11/2026 13:48;Atrazine;[C8H14ClN5+H]+;216.10105;216.10114;0.42;123219;;
;;;;Carbamazepine;[C15H12N2O+H]+;237.10224;237.10245;0.89;1641533;;
;;;;Sulfamethoxazole;[C10H11N3O3S+H]+;254.05939;254.05960;0.83;5112642;;
;;;;Diclofenac;[C14H11Cl2NO2+H]+;296.02396;296.02395;-0.04;4000786;;
3;Sample;W-26-0414;06/11/2026 14:06;Atrazine;[C8H14ClN5+H]+;216.10105;;;n.d.;;
;;;;Carbamazepine;[C15H12N2O+H]+;237.10224;;;n.d.;;
;;;;Sulfamethoxazole;[C10H11N3O3S+H]+;254.05939;254.05949;0.40;57442;;
;;;;Diclofenac;[C14H11Cl2NO2+H]+;296.02396;296.02414;0.61;92461;;
4;Sample;W-26-0415;06/11/2026 14:24;Atrazine;[C8H14ClN5+H]+;216.10105;216.10121;0.74;55256;;

… 56 lignes de plus

Limites

  • La règle lit le QC précédent, pas l'encadrement: W-26-0417 et 0418, acquis avant le QC raté pendant que la dérive montait, atteignent 2,6 et 3,3 ppm et ne sont pas signalés.
  • Un échantillon acquis après une recalibration et avant le QC suivant n'est couvert par aucun QC; la page le montre, aucune décision ne le dit.
  • Seule l'erreur en masse est jugée. Le pouvoir de résolution et l'intensité du QC sont lus, aucune règle ne les juge ici.
  • Une perte d'identification par la dérive (un n.d. faux) n'est pas détectée: la décision dit seulement de ne pas croire l'échantillon.
  • Échantillons, intensités et dérive synthétiques; les masses théoriques sont exactes.

Laboratoire · HRMS

Un standard QC entre chaque série d'échantillons.

Caféine, MRFA, réserpine: leur erreur en masse dit si les échantillons suivants sont crédibles.

195.08765 · 524.26496 · 609.28066

Le problème

Le QC lit 3,84 ppm. Le lot continue.

  • La tolérance est de 3,0 ppm.
  • Quatre échantillons sont acquis après lui, comme si de rien n'était.

Ce qui n'est pas modifié

L'instrument et son logiciel restent tels quels.

  • L'export reste celui du logiciel de traitement.
  • Aucun spectre ne quitte l'instrument.

Ce qu'il a fallu écrire

fill-down: { columns: [qc_max_ppm],
  reset-when: { column: type, in: [Cal] } }

Le dernier QC parle pour les échantillons suivants.

  • Jusqu'à la recalibration.
  • Une règle: qc_max_ppm>3.

Ce qui a été corrigé

Le hub gardait quatre décimales (#1862).

  • 195.08765 devenait 195.0877: 0,26 ppm d'erreur ajoutée.
  • Le bloc d'en-tête n'est plus une lettre morte (#1863).

Essayer

Le scénario se rejoue en local.

Chaque étape est publiée avec sa sortie.

Ce scénario tourne sur lumnik Open, gratuit et open source.

Essayer lumnik Open →