libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
timsmsrunreader.cpp
Go to the documentation of this file.
1/**
2 * \file pappsomspp/msrun/private/timsmsrunreader.h
3 * \date 05/09/2019
4 * \author Olivier Langella
5 * \brief MSrun file reader for native Bruker TimsTOF raw data
6 */
7
8/*******************************************************************************
9 * Copyright (c) 2019 Olivier Langella <Olivier.Langella@u-psud.fr>.
10 *
11 * This file is part of the PAPPSOms++ library.
12 *
13 * PAPPSOms++ 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++ 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++. If not, see <http://www.gnu.org/licenses/>.
25 *
26 ******************************************************************************/
27
28#include "timsmsrunreader.h"
29#include "../../exception/exceptionnotimplemented.h"
30#include "../../exception/exceptioninterrupted.h"
31#include <QDebug>
32
33using namespace pappso;
34
36 : MsRunReader(msrun_id_csp)
37{
38 initialize();
39}
40
45
46void
48{
49 msp_timsData = std::make_shared<TimsData>(mcsp_msRunId.get()->getFileName());
50
51 if(msp_timsData == nullptr)
52 {
53 throw PappsoException(QObject::tr("ERROR in TimsMsRunReader::initialize "
54 "msp_timsData is null for MsRunId %1")
55 .arg(mcsp_msRunId.get()->toString()));
56 }
57}
58
59
60bool
61TimsMsRunReader::accept(const QString &file_name) const
62{
63 qDebug() << file_name;
64 return true;
65}
66
67
69TimsMsRunReader::massSpectrumSPtr([[maybe_unused]] std::size_t spectrum_index)
70{
72 QObject::tr("Not yet implemented in TimsMsRunReader %1.\n").arg(__LINE__));
74}
75
76
78TimsMsRunReader::massSpectrumCstSPtr(std::size_t spectrum_index)
79{
80 return msp_timsData->getMassSpectrumCstSPtrByRawIndex(spectrum_index);
81}
82
83
85TimsMsRunReader::qualifiedMassSpectrum(std::size_t spectrum_index,
86 bool want_binary_data) const
87{
88
89 QualifiedMassSpectrum mass_spectrum;
90
91 msp_timsData->getQualifiedMassSpectrumByRawIndex(
92 getMsRunId(), mass_spectrum, spectrum_index, want_binary_data);
93 return mass_spectrum;
94}
95
96
97void
103
104void
107{
108
109 qDebug().noquote() << "Reading the spectrum collection with this "
110 "specific configuration:"
111 << config.toString();
112
113 // We want to restrict the data reading process to the configuration provided
114 // as parameter.
115 // The frame record subset will include all frames fulfiling the config
116 // requirements (retention time and ms levels)
117
118 std::vector<std::size_t> subset_of_tims_frame_ids;
119
120 // Check for ion mobility range :
121 bool asked_ion_mobility_range = false;
122 quint32 mobility_scan_num_begin = 0;
123 quint32 mobility_scan_num_end = 0;
124
125 if(!config
126 .getParameterValue(
128 .isNull())
129 {
130 asked_ion_mobility_range = true;
131
132 mobility_scan_num_begin =
133 config
136 .toUInt();
137 mobility_scan_num_end =
138 config
141 .toUInt();
142 }
143
144
145 // Now that we have gathered all the configuration bits from the user,
146 // iterate in the vector of frames records and for each frame ask that
147 // all its scans be combined into a single mass spectrum, by taking into
148 // account the configuration bits provided by the user.
149
150 const std::vector<FrameIdDescr> &frame_id_descr_list =
151 msp_timsData->getFrameIdDescrList();
152
153 // The very first sorting of frames is perfomed on the basis of the
154 // retention time range that the user might have defined. Otherwise, all the
155 // frames are deemed suitable for next processing steps.
156
157 // Then, the MS level is checked against the config provided by the user.
158 std::size_t scan_count = 0;
159 for(auto const &frame_record : msp_timsData->getTimsFrameRecordList())
160 {
161 if(frame_record.frame_id == 0)
162 continue;
163
164 if(config.acceptRetentionTimeInSeconds(frame_record.frame_time))
165 {
166 std::size_t ms_level = 2;
167 if(frame_record.msms_type == 0)
168 ms_level = 1;
169 if(config.acceptMsLevel(ms_level))
170 {
171 subset_of_tims_frame_ids.push_back(frame_record.frame_id);
172
173 if(mobility_scan_num_end == 0)
174 {
175 scan_count +=
176 frame_id_descr_list[frame_record.frame_id].m_size;
177 }
178 else
179 {
180 scan_count +=
181 mobility_scan_num_end + 1 - mobility_scan_num_begin;
182 }
183 }
184 }
185 }
186
187
188 // Inform the handler of the spectrum list so that it can handle feedback to
189 // the user.
190 handler.spectrumListHasSize(scan_count);
191
192 // Check for m/z resolution downgrading
193 std::size_t mz_index_merge_window = 0;
194 if(!config
195 .getParameterValue(
197 .isNull())
198 {
199 mz_index_merge_window =
200 config
203 .toUInt();
204
205 qDebug() << "mz_index_merge_window=" << mz_index_merge_window;
206 }
207
208 // Check for m/z range selection
209 bool asked_mz_range = false;
210 double mz_range_begin = -1;
211 double mz_range_end = -1;
212
213 if(!config
214 .getParameterValue(
216 .isNull())
217 {
218 asked_mz_range = true;
219
220 mz_range_begin =
221 config
224 .toDouble();
225
226 mz_range_end = config
229 .toDouble();
230
231 qDebug() << "The m/z range asked is: " << mz_range_begin << "--"
232 << mz_range_end;
233 }
234
235
236 // The scan index is the index of the scan in the *whole* mass data file, it
237 // is a sequential number of scans over all the frames.
238 std::size_t scan_index = 0; // iterate in each spectrum
239
240 for(std::size_t tims_frame_id : subset_of_tims_frame_ids)
241 {
242 qDebug() << "tims_frame_id=" << tims_frame_id;
243 const FrameIdDescr &current_frame_record =
244 frame_id_descr_list[tims_frame_id];
245 qDebug() << "tims_frame_id=" << tims_frame_id;
246
247 TimsFrameCstSPtr tims_frame_csp =
248 msp_timsData->getTimsFrameCstSPtrCached(tims_frame_id);
249 qDebug() << "tims_frame_id=" << tims_frame_id;
250
251 // If the user wants to select specific 1/Ko values, we need to
252 // compute the ion mobility scan value starting from that 1/Ko value in
253 // each frame.
254
255 if(!config
256 .getParameterValue(
259 .isNull())
260 {
261 asked_ion_mobility_range = true;
262
263 mobility_scan_num_begin =
264 tims_frame_csp.get()->getScanNumFromOneOverK0(
265 config
266 .getParameterValue(
269 .toDouble());
270
271 mobility_scan_num_end = tims_frame_csp.get()->getScanNumFromOneOverK0(
272 config
273 .getParameterValue(
276 .toDouble());
277 }
278 else if(!config
279 .getParameterValue(
282 .isNull() &&
283 !config
286 .isNull())
287 {
288 asked_ion_mobility_range = true;
289
290 mobility_scan_num_begin =
291 config
294 .toDouble();
295
296 mobility_scan_num_end =
297 config
300 .toDouble();
301 }
302
303 qDebug() << "tims_frame_id=" << tims_frame_id;
304
305 // Get to know the size of the frame, that is,
306 // the number of mobility scans in it.
307
308 quint32 mobility_scans_count = tims_frame_csp->getTotalNumberOfScans();
309
310 // Provide these two variables for the function below to fill in the
311 // values.
312 quint32 min_mz_index_out = 0;
313 quint32 max_mz_index_out = 0;
314
315 qDebug() << "tims_frame_id=" << tims_frame_id;
316 if(asked_ion_mobility_range)
317 {
318 if(mobility_scan_num_end > (mobility_scans_count - 1))
319 {
320 mobility_scan_num_end = mobility_scans_count - 1;
321 }
322 }
323 else
324 {
325 mobility_scan_num_begin = 0;
326 mobility_scan_num_end = mobility_scans_count - 1;
327 }
328
329 qDebug() << "tims_frame_id=" << tims_frame_id;
330 // qDebug() << "Got min_mz_index_out:" << min_mz_index_out;
331 // qDebug() << "Got max_mz_index_out:" << max_mz_index_out;
332
333 // Now, with or without the peak list, we have to craft a qualified mass
334 // spectrum that will hold all the data about the data in it.
335 QualifiedMassSpectrum mass_spectrum;
336
337 MassSpectrumId spectrum_id;
338
339 spectrum_id.setSpectrumIndex(tims_frame_id);
340 spectrum_id.setMsRunId(getMsRunId());
341
342 mass_spectrum.setMassSpectrumId(spectrum_id);
343
344 // We want to document the retention time!
345 mass_spectrum.setRtInSeconds(tims_frame_csp.get()->getTime());
346
347 // We do want to document the ms level of the spectrum and possibly
348 // the precursor's m/z and charge.
349 unsigned int frame_ms_level = tims_frame_csp.get()->getMsLevel();
350 mass_spectrum.setMsLevel(frame_ms_level);
351
352
353 // qDebug() << "Setting mass spectrum parameter value mz index begin to:"
354 // << min_mz_index_out;
355 mass_spectrum.setParameterValue(
357 min_mz_index_out);
358
359 // qDebug() << "Setting mass spectrum parameter value mz index end to:"
360 // << max_mz_index_out;
361
362 scan_index = current_frame_record.m_cumulSize -
363 current_frame_record.m_size + mobility_scan_num_begin;
364 for(quint32 i = mobility_scan_num_begin; i <= mobility_scan_num_end; i++)
365 {
366 mass_spectrum.getMassSpectrumId().setSpectrumIndex(scan_index);
367
368 mass_spectrum.getMassSpectrumId().setNativeId(
369 QString("frame=%1 scan=%2 index=%3")
370 .arg(tims_frame_id)
371 .arg(i)
372 .arg(scan_index));
373
374 qDebug() << "i=" << i;
375
376 if(config.needPeakList())
377 {
378 quint32 mz_minimum_index_out =
379 std::numeric_limits<quint32>::max();
380 quint32 mz_maximum_index_out = 0;
381 auto raw =
382 tims_frame_csp.get()->getMobilityScan(i,
383 mz_index_merge_window,
384 mz_range_begin,
385 mz_range_end,
386 mz_minimum_index_out,
387 mz_maximum_index_out);
388 qDebug() << raw.size();
389 mass_spectrum.setEmptyMassSpectrum(false);
390
391
392 mass_spectrum.setDtInMilliSeconds(
393 tims_frame_csp.get()->getDriftTime(i));
394 // 1/K0
395 mass_spectrum.setParameterValue(
397 tims_frame_csp.get()->getOneOverK0Transformation(i));
398
399 /*
400 mass_spectrum.setParameterValue(
401 QualifiedMassSpectrumParameter::TimsFrameMzIndexEnd,
402 max_mz_index_out);
403 */
404 qDebug();
405 mass_spectrum.setMassSpectrumSPtr(
406 std::make_shared<MassSpectrum>(raw));
407
408 qDebug();
409 }
410 else
411 {
412 mass_spectrum.setEmptyMassSpectrum(true);
413 }
414
415 qDebug() << "mz_index_merge_window=" << mz_index_merge_window;
416 handler.setQualifiedMassSpectrum(mass_spectrum);
417 scan_index++;
418 }
419 }
420}
421
422void
424 SpectrumCollectionHandlerInterface &handler, unsigned int ms_level)
425{
426
427 qDebug();
428
429 try
430 {
431
432 msp_timsData.get()->rawReaderSpectrumCollectionByMsLevel(
433 getMsRunId(), handler, ms_level);
434 }
435
436 catch(ExceptionInterrupted &)
437 {
438 qDebug() << "Reading of MS data interrupted by the user.";
439 }
440
441 // Now let the loading handler know that the loading of the data has ended.
442 // The handler might need this "signal" to perform additional tasks or to
443 // cleanup cruft.
444
445 // qDebug() << "Loading ended";
446 handler.loadingEnded();
447}
448
449
450std::size_t
452{
453 return msp_timsData->getTotalNumberOfScans();
454}
455
456
457bool
459{
460 return false;
461}
462
463
464bool
466{
467 msp_timsData = nullptr;
468 return true;
469}
470
471bool
473{
474 if(msp_timsData == nullptr)
475 {
476 initialize();
477 }
478 return true;
479}
480
481
484 [[maybe_unused]],
485 pappso::PrecisionPtr precision
486 [[maybe_unused]]) const
487{
488 throw ExceptionNotImplemented(QObject::tr("Not implemented %1 %2 %3")
489 .arg(__FILE__)
490 .arg(__FUNCTION__)
491 .arg(__LINE__));
492}
493
496 const pappso::QualifiedMassSpectrum &mass_spectrum [[maybe_unused]],
497 pappso::PrecisionPtr precision [[maybe_unused]]) const
498{
499 throw ExceptionNotImplemented(QObject::tr("Not implemented %1 %2 %3")
500 .arg(__FILE__)
501 .arg(__FUNCTION__)
502 .arg(__LINE__));
503}
504
511
512
513Trace
515{
516 // Use the Sqlite database to fetch the total ion current chromatogram (TIC
517 // chromatogram).
518
520
521 // The time unit here is seconds, not minutes!!!
522 return msp_timsData->getTicChromatogram();
523}
void setNativeId(const QString &native_id)
void setMsRunId(MsRunIdCstSPtr other)
void setSpectrumIndex(std::size_t index)
const QVariant getParameterValue(MsRunReadConfigParameter parameter) const
bool acceptMsLevel(std::size_t ms_level) const
bool acceptRetentionTimeInSeconds(double retention_time_in_seconds) const
base class to read MSrun the only way to build a MsRunReader object is to use the MsRunReaderFactory
Definition msrunreader.h:63
MsRunIdCstSPtr mcsp_msRunId
const MsRunIdCstSPtr & getMsRunId() const
Class representing a fully specified mass spectrum.
void setDtInMilliSeconds(pappso_double rt)
Set the drift time in milliseconds.
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 setParameterValue(QualifiedMassSpectrumParameter parameter, const QVariant &value)
void setMassSpectrumSPtr(MassSpectrumSPtr massSpectrum)
Set the MassSpectrumSPtr.
void setRtInSeconds(pappso_double rt)
Set the retention time in seconds.
void setEmptyMassSpectrum(bool is_empty_mass_spectrum)
interface to collect spectrums from the MsRunReader class
virtual void setQualifiedMassSpectrum(const QualifiedMassSpectrum &spectrum)=0
TimsMsRunReader(MsRunIdCstSPtr &msrun_id_csp)
virtual void readSpectrumCollection2(const MsRunReadConfig &config, SpectrumCollectionHandlerInterface &handler) override
virtual void readSpectrumCollection(SpectrumCollectionHandlerInterface &handler) override
function to visit an MsRunReader and get each Spectrum in a spectrum collection handler
virtual void readSpectrumCollectionByMsLevel(SpectrumCollectionHandlerInterface &handler, unsigned int ms_level) override
function to visit an MsRunReader and get each Spectrum in a spectrum collection handler by Ms Levels
virtual MassSpectrumCstSPtr massSpectrumCstSPtr(std::size_t spectrum_index) override
virtual MassSpectrumSPtr massSpectrumSPtr(std::size_t spectrum_index) override
get a MassSpectrumSPtr class given its spectrum index
virtual bool hasScanNumbers() const override
tells if spectra can be accessed using scan numbers by default, it returns false. Only overrided func...
virtual pappso::XicCoordSPtr newXicCoordSPtrFromSpectrumIndex(std::size_t spectrum_index, pappso::PrecisionPtr precision) const override
get a xic coordinate object from a given spectrum index
virtual QualifiedMassSpectrum qualifiedMassSpectrum(std::size_t spectrum_index, bool want_binary_data=true) const override
get a QualifiedMassSpectrum class given its scan number
virtual bool releaseDevice() override
release data back end device if a the data back end is released, the developper has to use acquireDev...
virtual bool acquireDevice() override
acquire data back end device
virtual bool accept(const QString &file_name) const override
tells if the reader is able to handle this file must be implemented by private MS run reader,...
virtual TimsDataSp getTimsDataSPtr()
give an access to the underlying raw data pointer
virtual void initialize() override
virtual std::size_t spectrumListSize() const override
get the totat number of spectrum conained in the MSrun data file
virtual pappso::XicCoordSPtr newXicCoordSPtrFromQualifiedMassSpectrum(const pappso::QualifiedMassSpectrum &mass_spectrum, pappso::PrecisionPtr precision) const override
get a xic coordinate object from a given spectrum
virtual Trace getTicChromatogram() override
get a TIC chromatogram
A simple container of DataPoint instances.
Definition trace.h:148
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition aa.cpp:39
std::shared_ptr< const MsRunId > MsRunIdCstSPtr
Definition msrunid.h:46
std::shared_ptr< TimsData > TimsDataSp
shared pointer on a TimsData object
Definition timsdata.h:50
std::shared_ptr< const MassSpectrum > MassSpectrumCstSPtr
@ TimsFrameMzIndexBegin
Bruker's Tims tof mz index frame start range.
std::shared_ptr< MassSpectrum > MassSpectrumSPtr
std::shared_ptr< const TimsFrame > TimsFrameCstSPtr
Definition timsframe.h:42
MsRunReadConfigParameter
std::shared_ptr< XicCoord > XicCoordSPtr
Definition xiccoord.h:43
std::size_t m_cumulSize
Definition timsdata.h:57
std::size_t m_size
Definition timsdata.h:56
MSrun file reader for native Bruker TimsTOF raw data.