@@ -242,8 +242,9 @@ impl MzMLReader {
242242 precursor. charge = Some ( extract_value ! ( ev) ) ;
243243 }
244244 SELECTED_ION_MZ => {
245- if precursor. mz == 0.0 {
246- precursor. mz = extract_value ! ( ev)
245+ let val = extract_value ! ( ev) ;
246+ if val != 0.0 {
247+ precursor. mz = val;
247248 }
248249 }
249250 SELECTED_ION_INT => {
@@ -606,4 +607,103 @@ mod test {
606607 assert_eq ! ( s. intensity. len( ) , s. mz. len( ) ) ;
607608 Ok ( ( ) )
608609 }
610+
611+ #[ tokio:: test]
612+ async fn parse_spectrum_issue_210 ( ) -> Result < ( ) , MzMLError > {
613+ // Handle cases where both isolation window target m/z is set and different than selected ion m/z
614+ let s = r#"
615+ <spectrum id="spectrum=8678309" index="8678309" defaultArrayLength="102" dataProcessingRef="dp_sp_1">
616+ <cvParam cvRef="MS" accession="MS:1000127" name="centroid spectrum" />
617+ <cvParam cvRef="MS" accession="MS:1000511" name="ms level" value="2" />
618+ <precursorList count="1">
619+ <precursor>
620+ <isolationWindow>
621+ <cvParam cvRef="MS" accession="MS:1000827" name="isolation window target m/z" value="457.75" unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" />
622+ <cvParam cvRef="MS" accession="MS:1000828" name="isolation window lower offset" value="1.5" unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" />
623+ <cvParam cvRef="MS" accession="MS:1000829" name="isolation window upper offset" value="0.75" unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" />
624+ </isolationWindow>
625+ <selectedIonList count="1">
626+ <selectedIon>
627+ <cvParam cvRef="MS" accession="MS:1000744" name="selected ion m/z" value="457.723968505859" unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" />
628+ <cvParam cvRef="MS" accession="MS:1000041" name="charge state" value="2" />
629+ </selectedIon>
630+ </selectedIonList>
631+ </precursor>
632+ </precursorList>
633+ </spectrum>
634+ "# ;
635+ let mut spectra = MzMLReader :: with_file_id ( 0 ) . parse ( s. as_bytes ( ) ) . await ?;
636+
637+ assert_eq ! ( spectra. len( ) , 1 ) ;
638+ let s = spectra. pop ( ) . unwrap ( ) ;
639+ assert ! ( ( s. precursors[ 0 ] . mz - 457.723968 ) < 0.0001 ) ;
640+ assert_eq ! (
641+ s. precursors[ 0 ] . isolation_window,
642+ Some ( Tolerance :: Da ( -1.5 , 0.75 ) )
643+ ) ;
644+
645+ // Check different ordering of fields in mzML
646+ let s = r#"
647+ <spectrum id="spectrum=8678309" index="8678309" defaultArrayLength="102" dataProcessingRef="dp_sp_1">
648+ <cvParam cvRef="MS" accession="MS:1000127" name="centroid spectrum" />
649+ <cvParam cvRef="MS" accession="MS:1000511" name="ms level" value="2" />
650+ <precursorList count="1">
651+ <precursor>
652+ <selectedIonList count="1">
653+ <selectedIon>
654+ <cvParam cvRef="MS" accession="MS:1000744" name="selected ion m/z" value="457.723968505859" unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" />
655+ <cvParam cvRef="MS" accession="MS:1000041" name="charge state" value="2" />
656+ </selectedIon>
657+ </selectedIonList>
658+ <isolationWindow>
659+ <cvParam cvRef="MS" accession="MS:1000827" name="isolation window target m/z" value="457.75" unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" />
660+ <cvParam cvRef="MS" accession="MS:1000828" name="isolation window lower offset" value="1.5" unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" />
661+ <cvParam cvRef="MS" accession="MS:1000829" name="isolation window upper offset" value="0.75" unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" />
662+ </isolationWindow>
663+ </precursor>
664+ </precursorList>
665+ </spectrum>
666+ "# ;
667+ let mut spectra = MzMLReader :: with_file_id ( 0 ) . parse ( s. as_bytes ( ) ) . await ?;
668+
669+ assert_eq ! ( spectra. len( ) , 1 ) ;
670+ let s = spectra. pop ( ) . unwrap ( ) ;
671+ assert ! ( ( s. precursors[ 0 ] . mz - 457.723968 ) < 0.0001 ) ;
672+ assert_eq ! (
673+ s. precursors[ 0 ] . isolation_window,
674+ Some ( Tolerance :: Da ( -1.5 , 0.75 ) )
675+ ) ;
676+
677+ // Check fallback keeping iso window m/z of fields in mzML
678+ let s = r#"
679+ <spectrum id="spectrum=8678309" index="8678309" defaultArrayLength="102" dataProcessingRef="dp_sp_1">
680+ <cvParam cvRef="MS" accession="MS:1000127" name="centroid spectrum" />
681+ <cvParam cvRef="MS" accession="MS:1000511" name="ms level" value="2" />
682+ <precursorList count="1">
683+ <precursor>
684+ <isolationWindow>
685+ <cvParam cvRef="MS" accession="MS:1000827" name="isolation window target m/z" value="457.75" unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" />
686+ <cvParam cvRef="MS" accession="MS:1000828" name="isolation window lower offset" value="1.5" unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" />
687+ <cvParam cvRef="MS" accession="MS:1000829" name="isolation window upper offset" value="0.75" unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" />
688+ </isolationWindow>
689+ <selectedIonList count="1">
690+ <selectedIon>
691+ <cvParam cvRef="MS" accession="MS:1000041" name="charge state" value="2" />
692+ </selectedIon>
693+ </selectedIonList>
694+ </precursor>
695+ </precursorList>
696+ </spectrum>
697+ "# ;
698+ let mut spectra = MzMLReader :: with_file_id ( 0 ) . parse ( s. as_bytes ( ) ) . await ?;
699+
700+ assert_eq ! ( spectra. len( ) , 1 ) ;
701+ let s = spectra. pop ( ) . unwrap ( ) ;
702+ assert ! ( ( s. precursors[ 0 ] . mz - 457.75 ) < 0.0001 ) ;
703+ assert_eq ! (
704+ s. precursors[ 0 ] . isolation_window,
705+ Some ( Tolerance :: Da ( -1.5 , 0.75 ) )
706+ ) ;
707+ Ok ( ( ) )
708+ }
609709}
0 commit comments