-
Notifications
You must be signed in to change notification settings - Fork 121
skyline: Stopped inferring a Waters lockmass function from waters_connect mzML #4498
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 28 commits
162dbbf
249389c
5753f6b
38d8115
33062ad
b91cd88
4f811eb
579351f
497cb26
87d22f1
a85e176
48f63c2
2909928
9a23cda
c7c96d3
4df5021
4945a60
18b0084
8f20b37
887bf25
df90ce8
85d99ed
34d192e
d4254c3
5020ed4
49f8442
1f87c03
10e6a64
5f88ea9
19702b5
b7fb330
591445b
34d2e59
0ad9391
feea902
3bebf25
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -163,6 +163,7 @@ bool PwizReader::getSpectrum(int identifier, | |
| } | ||
| unique_ptr<SpectrumInfo> specInfo(new SpectrumInfo()); | ||
| specInfo->SpectrumInfo::update(*foundSpec, getPeaks); | ||
| ensureMzAscending(*specInfo); | ||
|
|
||
| // confirm that it's an ms/ms spectrum | ||
| if( getPeaks && specInfo->msLevel != 2 ){ | ||
|
|
@@ -303,6 +304,7 @@ bool PwizReader::getSpectrum(int identifier, | |
| } | ||
| unique_ptr<SpectrumInfo> specInfo(new SpectrumInfo()); | ||
| specInfo->SpectrumInfo::update(*foundSpec, getPeaks); | ||
| ensureMzAscending(*specInfo); | ||
|
|
||
| // confirm that it's an ms/ms spectrum | ||
| if( specInfo->msLevel != 2 ){ | ||
|
|
@@ -426,11 +428,28 @@ void PwizReader::addCharges(BiblioSpec::Spectrum& returnSpectrum, | |
| } // next precursor | ||
| } | ||
|
|
||
| /** | ||
| * Put a spectrum's peaks in ascending m/z order if its writer did not. Ascending m/z is nowhere | ||
| * required of a writer, but everything downstream assumes it - and this has to happen here, on the | ||
| * SpectrumInfo, because it is the only point both transfer paths share. BlibBuild never builds a | ||
| * BiblioSpec::Spectrum at all: it goes BuildParser -> getSpectrum(int, SpecData&) -> transferSpec, | ||
| * and hands the raw arrays to insertPeaks, so a library built from a writer that presented some | ||
| * other order would be stored in that order and stay that way for every consumer of the .blib. | ||
| */ | ||
| void PwizReader::ensureMzAscending(SpectrumInfo& specInfo) | ||
| { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems potentially expensive for an extremely rare case. How about we do it for the first spectrum and then assume the rest follow suit?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same fix in 5f88ea9 - The state machine is unit tested in One caveat specific to this side:
|
||
| if (is_sorted(specInfo.data.begin(), specInfo.data.end(), | ||
| [](const MZIntensityPair& a, const MZIntensityPair& b) { return a.mz < b.mz; })) | ||
| return; | ||
| sort(specInfo.data.begin(), specInfo.data.end(), | ||
| [](const MZIntensityPair& a, const MZIntensityPair& b) { return a.mz < b.mz; }); | ||
| } | ||
|
|
||
| /** | ||
| * Copy the information from the Pwiz spectrum to the BiblioSpec | ||
| * SpecData. | ||
| */ | ||
| void PwizReader::transferSpec(BiblioSpec::SpecData& returnData, | ||
| void PwizReader::transferSpec(BiblioSpec::SpecData& returnData, | ||
| unique_ptr<SpectrumInfo>& specInfo){ | ||
|
|
||
| returnData.id = specInfo->scanNumber; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be reverted since it was only need for multiple spectrum types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a different change than the one you have in mind - the multiple-spectrum-types one was reverted, back in Phase 6 when the writing half of this PR was withdrawn. Nothing in pwiz emits two children of
spectrum typeany more, so the order-independence fix went out with it.What is here now fixes a calibration-spectrum-only spectrum, which is what
SpectrumList_UIMF.cpp:106writes today on master, with no help from this branch:MS_calibration_spectrum's only CV parent isMS_spectrum_type(cv.cpp:7055) - it is not underMS_mass_spectrum. So master's!cvIsA(param.cvid, MS_mass_spectrum)returnedmsLevelSet_.contains(0)and threw away a perfectly good declared ms level:msconvert --filter "msLevel 1-"drops UIMF calibration frames, andmsLevel 0keeps them.Worth noting that restoring the reverted hunk would not have fixed this - it asked
hasCVParamChild(MS_mass_spectrum), which is equally false for a calibration-only spectrum. It only ever helped when both terms were present, which was the situation our own additive writer created. Asking for the declared ms level first is the superset: it fixes the calibration case and gets order-independence for free, without needing an additive writer to exist.It does become moot, but only once psi-ms #539 lands and UIMF is updated to write
MS1 spectrumplus the attribute. Until then this is the only thing keeping a UIMF calibration frame's declared ms level from being discarded.Mutation-verified: restoring the type-first ordering fails
testMSLevelSetCalibrationSpectrumatSpectrumList_FilterTest.cpp:561,expected "2" but got "1". Happy to pull it into its own PR if you would rather it not ride along with the Waters work - it is a pwiz change in a skyline-prefixed PR either way.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oof, AI slop. I shouldn't let Claude handle the responses directly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is going to break with the new CV, when calibration spectrum is no longer a spectrum type. (Also the comment is wrong here about multiple spectrum types.) Fixing UIMF in this PR is the right path I think, which doesn't fix existing UIMF files, but we could fix those broken UIMF files in the mzML reader. Which I'm inclined say we should do so since they are OUR broken files. In untested code:
if (spectrum.hasCVParam(MS_calibration_spectrum) && !spectrum.hasCVParamChild(MS_spectrum_type))
{
int msLevel = spectrum.cvParamValueOrDefault(MS_ms_level, 0);
if (msLevel > 0) spectrum.set(msLevel == 1 ? MS_MS1_spectrum : MS_MSn_spectrum);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although I guess it's not just mzML. Someone could have converted to any of the open mzML formats like mz5, mzMLb, perhaps even mzXML. Tricky. Maybe a centralized workaround location (I don't think we've had a case like this before) and then call it in mzML, mz5, and mzMLb right before they return a spectrum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which is possibly more effort than the UIMF format warrants, as I haven't heard of anybody using it recently (a similar fate to mz5 and mzMLb, sigh). I'm sure multi-parquet-in-a-zip mzPeak will change things though. /s
We could put some opt-in telemetry into pwiz that tracks what formats people use, input and output.