libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
mzcborspectrumcollectionreader.cpp
Go to the documentation of this file.
1/**
2 * \file pappsomspp/core/processing/cbor/mzcbor/mzcborspectrumcollectionreader.cpp
3 * \date 22/11/2025
4 * \author Olivier Langella
5 * \brief read mzcbor for spectrum collection m_SpectrumCollectionHandlerInterface
6 */
7
8/*******************************************************************************
9 * Copyright (c) 2025 Olivier Langella <Olivier.Langella@universite-paris-saclay.fr>.
10 *
11 * This file is part of PAPPSOms-tools.
12 *
13 * PAPPSOms-tools is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * PAPPSOms-tools is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with PAPPSOms-tools. If not, see <http://www.gnu.org/licenses/>.
25 *
26 ******************************************************************************/
27
28
30#include "spectrum.h"
32
33
41
45
46void
52
53void
55 const std::map<QString, std::size_t> *nativeId2SpectrumIndexMap)
56{
57 mp_nativeId2SpectrumIndexMap = nativeId2SpectrumIndexMap;
58}
59
60
61void
63{
64 // qDebug();
65
66 mpa_cborReader->enterContainer();
67 bool ms_run_to_read = false;
68
69 while(getExpectedString())
70 {
71 if(m_expectedString == "id")
72 {
74
75 if((m_expectedString == m_xmlMzMlRunId) || (m_xmlMzMlRunId.isEmpty()))
76 {
77 ms_run_to_read = true;
78 }
79 }
80 else if(m_expectedString == "spectrumList")
81 {
82 if(ms_run_to_read)
83 {
85 }
86 else
87 {
88 mpa_cborReader->next();
89 }
90 }
91 else
92 {
93 mpa_cborReader->next();
94 }
95 }
96
97 mpa_cborReader->leaveContainer();
98}
99
100void
102{
103 mpa_cborReader->enterContainer();
104 // We want to iterate in the pwiz-spectrum-list and for each pwiz-spectrum
105 // create a pappso-spectrum (QualifiedMassSpectrum). Once the pappso mass
106 // spectrum has been fully qualified (that is, the member data have been
107 // set), it is transferred to the m_SpectrumCollectionHandlerInterface passed as parameter to this
108 // function for the consumer to do what it wants with it.
109
110 // Does the m_SpectrumCollectionHandlerInterface consuming the mass spectra read from file want
111 // these mass spectra to hold the binary data arrays (mz/i vectors)?
112
113 const bool want_binary_data = m_msRunReadConfig.needPeakList();
114
115
116 // qDebug();
117
118 // We'll need it to perform the looping in the spectrum list.
119 std::size_t spectrum_list_size = 0;
120
121 // qDebug() << "The spectrum list has size:" << spectrum_list_size;
122
123 while(getExpectedString())
124 {
125
126 qDebug() << m_expectedString;
127 if(m_expectedString == "count")
128 {
129 if(mpa_cborReader->isUnsignedInteger())
130 {
131 spectrum_list_size = mpa_cborReader->toUnsignedInteger();
132 mpa_cborReader->next();
133 qDebug() << "spectrum count=" << spectrum_list_size;
134 }
135
136 // Inform the m_SpectrumCollectionHandlerInterface of the spectrum list so that it can
137 // handle feedback to the user.
138 m_SpectrumCollectionHandlerInterface.spectrumListHasSize(spectrum_list_size);
139 }
140 else if(m_expectedString == "spectrum")
141 {
142
143 mpa_cborReader->enterContainer(); // start array
144
145 std::size_t index_count = 0;
146 while(mpa_cborReader->hasNext())
147 {
148 // If the user of this reader instance wants to stop reading the
149 // spectra, then break this loop.
151 {
152 qDebug() << "The operation was cancelled. Breaking the loop.";
153 m_stopParsing = true;
154 return;
155 }
156
157 readSpectrum(index_count, want_binary_data);
158 index_count++;
159 }
160
161 mpa_cborReader->leaveContainer(); // stop array
162 }
163 else
164 {
165 mpa_cborReader->next();
166 }
167 }
168
169
170 qDebug() << "Loading ended";
172
173 mpa_cborReader->leaveContainer();
174 m_stopParsing = true;
175}
176
177
178void
180 bool want_binary_data)
181{
182
183 qDebug() << index_count << " " << want_binary_data;
184 Spectrum cbor_spectrum;
185 cbor_spectrum.fromCbor(*mpa_cborReader, want_binary_data);
186 //<spectrum id="controllerType=0 controllerNumber=1 scan=1" index="0" defaultArrayLength="1552">
187
188
189 // Now, with or without the peak list, we have to craft a qualified mass
190 // spectrum that will hold all the metadata about the data potentially
191 // found in it.
192 QualifiedMassSpectrum qualified_mass_spectrum;
193
194 MassSpectrumId spectrum_id(mcsp_msRunId, cbor_spectrum.index);
195 spectrum_id.setNativeId(cbor_spectrum.id);
196
197 spectrum_id.setSpectrumIndex(cbor_spectrum.index);
198
199 qualified_mass_spectrum.setMassSpectrumId(spectrum_id);
200 qualified_mass_spectrum.setRtInSeconds(cbor_spectrum.getRtInSeconds());
201
202 if(cbor_spectrum.precursorList.size() > 0)
203 {
204 qualified_mass_spectrum.setPrecursorNativeId(cbor_spectrum.precursorList.at(0).spectrumRef);
205 if(mp_nativeId2SpectrumIndexMap != nullptr)
206 {
207 auto it =
208 mp_nativeId2SpectrumIndexMap->find(cbor_spectrum.precursorList.at(0).spectrumRef);
209 if(it != mp_nativeId2SpectrumIndexMap->end())
210 {
211 qualified_mass_spectrum.setPrecursorSpectrumIndex(it->second);
212 }
213 }
214 }
215
216
217 qualified_mass_spectrum.setMsLevel(cbor_spectrum.getMsLevel());
218 qualified_mass_spectrum.setEmptyMassSpectrum(!cbor_spectrum.defaultArrayLength);
219
220 if(cbor_spectrum.binaryDataArrayList.size() == 2)
221 {
222 MassSpectrumSPtr mass_spectrum_sp = std::make_shared<MassSpectrum>();
223 cbor_spectrum.decodeTrace(*(mass_spectrum_sp.get()));
224 qualified_mass_spectrum.setMassSpectrumSPtr(mass_spectrum_sp);
225 }
226
227 qDebug() << "spectrum_id.getNativeId()=" << spectrum_id.getNativeId();
228 qDebug() << "rt=" << qualified_mass_spectrum.getRtInSeconds();
229 qDebug() << "mslevel=" << qualified_mass_spectrum.getMsLevel();
230
231 if(m_msRunReadConfig.acceptMsLevel(qualified_mass_spectrum.getMsLevel()))
232 {
233 if(m_msRunReadConfig.acceptRetentionTimeInSeconds(qualified_mass_spectrum.getRtInSeconds()))
234 {
235
236 if(qualified_mass_spectrum.getMassSpectrumId().getSpectrumIndex() ==
237 std::numeric_limits<std::size_t>::max())
238 {
240 QObject::tr("ERROR in %1 spectrum index not initialised").arg(__FUNCTION__));
241 }
242 m_SpectrumCollectionHandlerInterface.setQualifiedMassSpectrum(qualified_mass_spectrum);
243 }
244 }
245
246 /*
247 *
248 <cvParam cvRef="MS" accession="MS:1000579" value="" name="MS1 spectrum" />
249 <cvParam cvRef="MS" accession="MS:1000130" value="" name="positive scan" />
250 <cvParam cvRef="MS" accession="MS:1000285" value="17377980" name="total ion current" />
251 <cvParam cvRef="MS" accession="MS:1000127" value="" name="centroid spectrum" />
252 <cvParam cvRef="MS" accession="MS:1000504" value="519.138854980469" name="base peak m/z"
253 unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" />
254 <cvParam cvRef="MS"
255 accession="MS:1000505" value="1702482.375" name="base peak intensity" unitAccession="MS:1000131"
256 unitName="number of detector counts" unitCvRef="MS" />
257 <cvParam cvRef="MS" accession="MS:1000528"
258 value="400.153411865234" name="lowest observed m/z" unitAccession="MS:1000040" unitName="m/z"
259 unitCvRef="MS" />
260 <cvParam cvRef="MS" accession="MS:1000527" value="1013.12335205078"
261 name="highest observed m/z" unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" /> <scanList
262 count="1">
263 <cvParam cvRef="MS" accession="MS:1000795" value="" name="no combination" />
264 <scan
265 instrumentConfigurationRef="IC1"> <cvParam cvRef="MS" accession="MS:1000016" value="0.0048758833"
266 name="scan start time" unitAccession="UO:0000031" unitName="minute" unitCvRef="UO" /> <cvParam
267 cvRef="MS" accession="MS:1000512" value="FTMS + p NSI Full lock ms [400.00-1400.00]" name="filter
268 string" /> <cvParam cvRef="MS" accession="MS:1000927" value="250" name="ion injection time"
269 unitAccession="UO:0000028" unitName="millisecond" unitCvRef="UO" /> <scanWindowList count="1">
270 <scanWindow>
271 <cvParam cvRef="MS" accession="MS:1000501" value="400" name="scan window lower
272 limit" unitAccession="MS:1000040" unitName="m/z" unitCvRef="MS" /> <cvParam cvRef="MS"
273 accession="MS:1000500" value="1400" name="scan window upper limit" unitAccession="MS:1000040"
274 unitName="m/z" unitCvRef="MS" />
275 </scanWindow>
276 </scanWindowList>
277 </scan>
278 </scanList>
279 <binaryDataArrayList count="2">
280 */
281
282 // qDebug();
283 // Get the native pwiz-spectrum from the spectrum list.
284 // Note that this pointer is a shared pointer from pwiz.
285 /*
286 pwiz::msdata::SpectrumPtr native_pwiz_spectrum_sp =
287 getPwizSpectrumPtr(spectrum_list_p.get(), iter, want_binary_data);
288 // qDebug();
289
290 // Instantiate the mass spectrum id that will hold critical information
291 // like the the native id string and the spectrum index.
292
293 MassSpectrumId massSpectrumId(mcsp_msRunId, iter);
294
295 // qDebug();
296 // Get the spectrum native id as a QString to store it in the mass
297 // spectrum id class. This is will allow later to refer to the same
298 // spectrum starting back from the file.
299
300 QString native_id = QString::fromStdString(native_pwiz_spectrum_sp->id);
301 massSpectrumId.setNativeId(native_id);
302
303 // Finally, instantiate the qualified mass spectrum with its id. This
304 // function will continue performing pappso-spectrum detailed
305 // qualification.
306
307 bool ok = false;
308
309 QualifiedMassSpectrum qualified_mass_spectrum = qualifiedMassSpectrumFromPwizSpectrumPtr(
310 massSpectrumId, native_pwiz_spectrum_sp.get(), want_binary_data, ok);
311
312 if(!ok)
313 {
314 // qDebug() << "Encountered a mass spectrum for which the returned "
315 //"status is bad.";
316 continue;
317 }
318
319 // qDebug();
320 // Before handing the mass spectrum out to the m_SpectrumCollectionHandlerInterface, see if
321 // the native mass spectrum was empty or not.
322
323 // if(!native_pwiz_spectrum_sp->defaultArrayLength)
324 // qDebug() << "The mass spectrum has not defaultArrayLength";
325
326 qualified_mass_spectrum.setEmptyMassSpectrum(!native_pwiz_spectrum_sp->defaultArrayLength);
327
328 // The m_SpectrumCollectionHandlerInterface will receive the index of the mass spectrum in the
329 // current run via the mass spectrum id member datum.
330
331 // qDebug();
332 */
333}
334
335std::map<QString, pappso::cbor::mzcbor::CvParam>
337{
338 std::map<QString, CvParam> cv_params;
339 mpa_cborReader->enterContainer();
340 while(getExpectedString())
341 {
342 qDebug() << m_expectedString;
343 if(m_expectedString == "cvParam")
344 {
345 cv_params = getCvParamsMap();
346 }
347 else
348 {
349 mpa_cborReader->next();
350 }
351 }
352 mpa_cborReader->leaveContainer();
353 return cv_params;
354}
void setNativeId(const QString &native_id)
std::size_t getSpectrumIndex() const
void setSpectrumIndex(std::size_t index)
const QString & getNativeId() const
Class representing a fully specified mass spectrum.
uint getMsLevel() const
Get the mass spectrum level.
void setPrecursorNativeId(const QString &native_id)
Set the scan native id of the precursor ion.
const MassSpectrumId & getMassSpectrumId() const
Get the MassSpectrumId.
void setMassSpectrumId(const MassSpectrumId &iD)
Set the MassSpectrumId.
void setMsLevel(uint ms_level)
Set the mass spectrum level.
void setPrecursorSpectrumIndex(std::size_t precursor_scan_num)
Set the scan number of the precursor ion.
void setMassSpectrumSPtr(MassSpectrumSPtr massSpectrum)
Set the MassSpectrumSPtr.
void setRtInSeconds(pappso_double rt)
Set the retention time in seconds.
pappso_double getRtInSeconds() const
Get the retention time in seconds.
void setEmptyMassSpectrum(bool is_empty_mass_spectrum)
interface to collect spectrums from the MsRunReader class
std::map< QString, CvParam > getCvParamsMap()
read the array containing cvParams to give accessions and values
SpectrumCollectionHandlerInterface & m_SpectrumCollectionHandlerInterface
void readSpectrum(std::size_t index_count, bool want_binary_data)
read each spectrum in the targeted msrun (msrunId)
MzcborSpectrumCollectionReader(const MsRunReadConfig &config, SpectrumCollectionHandlerInterface &handler)
void setNativeId2SpectrumIndexMapPtr(const std::map< QString, std::size_t > *nativeId2SpectrumIndexMap)
void readSpectrumListAndLeave()
only the spectrum list of targeted msrun, then stop parsing
const std::map< QString, std::size_t > * mp_nativeId2SpectrumIndexMap
virtual void readMsrun() override
read only the targeted msrun
read mzcbor for spectrum collection handler
std::shared_ptr< const MsRunId > MsRunIdCstSPtr
Definition msrunid.h:46
std::shared_ptr< MassSpectrum > MassSpectrumSPtr
PSI spectrum object for mzML/mzCBOR.
std::vector< Precursor > precursorList
Definition spectrum.h:81
void fromCbor(CborStreamReader &reader, bool want_binary_data)
fill the structure reading data from a CBOR stream
Definition spectrum.cpp:40
void decodeTrace(pappso::Trace &trace) const
Definition spectrum.cpp:353
std::vector< BinaryDataArray > binaryDataArrayList
Definition spectrum.h:82