libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
timsframesmsrunreader.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
29#include "../../exception/exceptionnotimplemented.h"
30#include <QDebug>
31
32using namespace pappso;
33
35 : MsRunReader(msrun_id_csp)
36{
37 qDebug() << "Now initializing the TimsFramesMsRunReader.";
38
39 initialize();
40}
41
46
47void
49{
50 msp_timsData = std::make_shared<TimsData>(mcsp_msRunId.get()->getFileName());
51 if(msp_timsData == nullptr)
52 {
53 throw PappsoException(
54 QObject::tr("ERROR in TimsFramesMsRunReader::initialize "
55 "msp_timsData is null for MsRunId %1")
56 .arg(mcsp_msRunId.get()->toString()));
57 }
58}
59
60
61bool
62TimsFramesMsRunReader::accept(const QString &file_name) const
63{
64 qDebug() << file_name;
65 return true;
66}
67
68
71 [[maybe_unused]] std::size_t spectrum_index)
72{
74 QObject::tr("Not yet implemented in TimsFramesMsRunReader %1.\n")
75 .arg(__LINE__));
76
78}
79
80
83{
84 return msp_timsData->getMassSpectrumCstSPtrByRawIndex(spectrum_index);
85}
86
87
90 bool want_binary_data) const
91{
92
93 QualifiedMassSpectrum mass_spectrum;
94
95 msp_timsData->getQualifiedMassSpectrumByRawIndex(
96 getMsRunId(), mass_spectrum, spectrum_index, want_binary_data);
97 return mass_spectrum;
98}
99
100
101void
104{
105 qDebug() << "Reading the spectrum collection with no specific configuration.";
106 MsRunReadConfig config;
107 readSpectrumCollection2(config, handler);
108}
109
110
111void
114{
115 qDebug().noquote() << "Reading the spectrum collection with this "
116 "specific configuration:"
117 << config.toString();
118
119 // We want to restrict the data reading process to the configuration provided
120 // as parameter.
121 // The frame record subset will include all frames fulfiling the config
122 // requirements (retention time and ms levels)
123
124 std::vector<std::size_t> subset_of_tims_frame_ids;
125
126 // The very first sorting of frames is perfomed on the basis of the
127 // retention time range that the user might have defined. Otherwise, all the
128 // frames are deemed suitable for next processing steps.
129
130 // Then, the MS level is checked against the config provided by the user.
131 for(auto const &frame_record : msp_timsData->getTimsFrameRecordList())
132 {
133 if(frame_record.frame_id == 0)
134 continue;
135
136 if(config.acceptRetentionTimeInSeconds(frame_record.frame_time))
137 {
138 std::size_t ms_level = 2;
139 if(frame_record.msms_type == 0)
140 ms_level = 1;
141 if(config.acceptMsLevel(ms_level))
142 {
143 subset_of_tims_frame_ids.push_back(frame_record.frame_id);
144 }
145 }
146 }
147
148 // At this point, we have a subset of frame records.
149 std::size_t frames_count = subset_of_tims_frame_ids.size();
150 qDebug() << "The number of retained RT range-matching frames:"
151 << frames_count;
152
153 // Inform the handler of the spectrum list so that it can handle feedback to
154 // the user.
155 handler.spectrumListHasSize(frames_count);
156
157 // Check for ion mobility range :
158 bool asked_ion_mobility_range = false;
159 quint32 mobility_scan_num_begin = 0;
160 quint32 mobility_scan_num_end = 0;
161
162 if(!config
163 .getParameterValue(
165 .isNull())
166 {
167 asked_ion_mobility_range = true;
168
169 mobility_scan_num_begin =
170 config
173 .toUInt();
174 mobility_scan_num_end =
175 config
178 .toUInt();
179 }
180
181 // Check for m/z resolution downgrading
182 std::size_t mz_index_merge_window = 0;
183 if(!config
184 .getParameterValue(
186 .isNull())
187 {
188 mz_index_merge_window =
189 config
192 .toUInt();
193 }
194
195 // Check for m/z range selection
196 bool asked_mz_range = false;
197 double mz_range_begin = -1;
198 double mz_range_end = -1;
199
200 if(!config
201 .getParameterValue(
203 .isNull())
204 {
205 asked_mz_range = true;
206
207 mz_range_begin =
208 config
211 .toDouble();
212 mz_range_end = config
215 .toDouble();
216 }
217
218 // Now that we have gathered all the configuration bits from the user,
219 // iterate in the vector of frames records and for each frame ask that
220 // all its scans be combined into a single mass spectrum, by taking into
221 // account the configuration bits provided by the user.
222
223 const std::vector<FrameIdDescr> &frame_id_descr_list =
224 msp_timsData->getFrameIdDescrList();
225
226 // The scan index is the index of the scan in the *whole* mass data file, it
227 // is a sequential number of scans over all the frames.
228 std::size_t scan_index = 0; // iterate in each spectrum
229
230 for(std::size_t tims_frame_id : subset_of_tims_frame_ids)
231 {
232 const FrameIdDescr &current_frame_record =
233 frame_id_descr_list[tims_frame_id];
234
235 scan_index = current_frame_record.m_cumulSize;
236 TimsFrameCstSPtr tims_frame_csp =
237 msp_timsData->getTimsFrameCstSPtrCached(tims_frame_id);
238
239 // If the user wants to select specific 1/Ko values, we need to
240 // compute the ion mobility scan value starting from that 1/Ko value in
241 // each frame.
242
243 if(!config
244 .getParameterValue(
247 .isNull())
248 {
249 asked_ion_mobility_range = true;
250
251 mobility_scan_num_begin =
252 tims_frame_csp.get()->getScanNumFromOneOverK0(
253 config
254 .getParameterValue(
257 .toDouble());
258
259 mobility_scan_num_end = tims_frame_csp.get()->getScanNumFromOneOverK0(
260 config
261 .getParameterValue(
264 .toDouble());
265 }
266
267 // Get to know the size of the frame, that is,
268 // the number of mobility scans in it.
269 quint32 mobility_scans_count = tims_frame_csp->getTotalNumberOfScans();
270
271 // Provide these two variables for the function below to fill in the
272 // values.
273 quint32 min_mz_index_out = 0;
274 quint32 max_mz_index_out = 0;
275
276 Trace spectrum;
277
278 if(config.needPeakList())
279 {
280 if(asked_ion_mobility_range)
281 {
282 if(mobility_scan_num_end > (mobility_scans_count - 1))
283 mobility_scan_num_end = mobility_scans_count - 1;
284
285 if(asked_mz_range)
286 spectrum = tims_frame_csp->cumulateScanToTraceMzDownResolution2(
287 mz_index_merge_window,
288 mz_range_begin,
289 mz_range_end,
290 mobility_scan_num_begin,
291 mobility_scan_num_end,
292 min_mz_index_out,
293 max_mz_index_out);
294 else
295 spectrum = tims_frame_csp->cumulateScanToTraceMzDownResolution(
296 mz_index_merge_window,
297 mobility_scan_num_begin,
298 mobility_scan_num_end,
299 min_mz_index_out,
300 max_mz_index_out);
301 }
302 else
303 {
304 mobility_scan_num_end = mobility_scans_count - 1;
305
306 spectrum = tims_frame_csp->cumulateScanToTraceMzDownResolution(
307 mz_index_merge_window,
308 0,
309 mobility_scan_num_end,
310 min_mz_index_out,
311 max_mz_index_out);
312 }
313 }
314
315 // qDebug() << "Got min_mz_index_out:" << min_mz_index_out;
316 // qDebug() << "Got max_mz_index_out:" << max_mz_index_out;
317
318 // Now, with or without the peak list, we have to craft a qualified mass
319 // spectrum that will hold all the data about the data in it.
320 QualifiedMassSpectrum mass_spectrum;
321
322 MassSpectrumId spectrum_id;
323
324 spectrum_id.setSpectrumIndex(tims_frame_id);
325 spectrum_id.setMsRunId(getMsRunId());
326
327 // Can be modified to add bits that might help our case
328 spectrum_id.setNativeId(
329 QString("frame id=%1 scan index=%2 im_begin=%3 im_end=%4")
330 .arg(tims_frame_id)
331 .arg(scan_index)
332 .arg(mobility_scan_num_begin)
333 .arg(mobility_scan_num_end));
334
335 mass_spectrum.setMassSpectrumId(spectrum_id);
336
337 // We want to document the retention time!
338 mass_spectrum.setRtInSeconds(tims_frame_csp.get()->getTime());
339
340 // We do want to document the ms level of the spectrum and possibly
341 // the precursor's m/z and charge.
342 unsigned int frame_ms_level = tims_frame_csp.get()->getMsLevel();
343 mass_spectrum.setMsLevel(frame_ms_level);
344
345 // We cannot set this value because the inverse mobility (1/Ko) measured
346 // by Bruker does not correspond formally to a drift time.
347 mass_spectrum.setDtInMilliSeconds(-1);
348
349 mass_spectrum.setParameterValue(
351 (qlonglong)tims_frame_csp->getTotalNumberOfScans());
352 mass_spectrum.setParameterValue(
354 tims_frame_csp->getOneOverK0Transformation(0));
355 mass_spectrum.setParameterValue(
357 tims_frame_csp->getOneOverK0Transformation(
358 tims_frame_csp->getTotalNumberOfScans() - 1));
359
360 // qDebug() << "Setting mass spectrum parameter value mz index begin to:"
361 // << min_mz_index_out;
362 mass_spectrum.setParameterValue(
364 min_mz_index_out);
365
366 // qDebug() << "Setting mass spectrum parameter value mz index end to:"
367 // << max_mz_index_out;
368 mass_spectrum.setParameterValue(
370
371 if(config.needPeakList())
372 {
373 mass_spectrum.setEmptyMassSpectrum(false);
374
375 mass_spectrum.setMassSpectrumSPtr(
376 std::make_shared<MassSpectrum>(spectrum));
377 }
378 else
379 {
380 mass_spectrum.setEmptyMassSpectrum(true);
381 }
382
383 handler.setQualifiedMassSpectrum(mass_spectrum);
384 }
385}
386
387
388void
390 [[maybe_unused]] SpectrumCollectionHandlerInterface &handler,
391 [[maybe_unused]] unsigned int ms_level)
392{
393 qDebug();
394}
395
396
397std::size_t
399{
400 return msp_timsData->getTotalNumberOfScans();
401}
402
403
404bool
406{
407 return false;
408}
409
410
411bool
413{
414 msp_timsData = nullptr;
415 return true;
416}
417
418bool
420{
421 if(msp_timsData == nullptr)
422 {
423 initialize();
424 }
425 return true;
426}
427
428
431 std::size_t spectrum_index [[maybe_unused]],
432 pappso::PrecisionPtr precision [[maybe_unused]]) const
433{
434 throw ExceptionNotImplemented(QObject::tr("Not implemented %1 %2 %3")
435 .arg(__FILE__)
436 .arg(__FUNCTION__)
437 .arg(__LINE__));
438}
439
442 const pappso::QualifiedMassSpectrum &mass_spectrum [[maybe_unused]],
443 pappso::PrecisionPtr precision [[maybe_unused]]) const
444{
445 throw ExceptionNotImplemented(QObject::tr("Not implemented %1 %2 %3")
446 .arg(__FILE__)
447 .arg(__FUNCTION__)
448 .arg(__LINE__));
449}
450
457
458
459Trace
461{
462 // Use the Sqlite database to fetch the total ion current chromatogram (TIC
463 // chromatogram).
464
466
467 return msp_timsData->getTicChromatogram();
468}
469
470
471Trace
473{
474
475 // We want to compute the TIC chromatogram, not load the chromatogram that
476 // is located in the SQL database.
477 //
478 // For this, we need to iterated into the frames and ask for MS1 spectra
479 // only. msp_timsData has that information:
480 //
481 // std::vector<FrameIdDescr> m_frameIdDescrList;
482 //
483 // and
484
485 // struct FrameIdDescr
486 // {
487 // std::size_t m_frameId; // frame id
488 // std::size_t m_size; // frame size (number of TOF scans in frame)
489 // std::size_t m_cumulSize; // cumulative size
490 // };
491
492 Trace tic_chromatogram;
493
494 const std::vector<FrameIdDescr> frame_descr_list =
495 msp_timsData->getFrameIdDescrList();
496
497 for(FrameIdDescr frame_id_descr : frame_descr_list)
498 {
499 TimsFrameCstSPtr tims_frame_csp =
500 msp_timsData->getTimsFrameCstSPtrCached(frame_id_descr.m_frameId);
501 std::size_t scan_begin = 0;
502 std::size_t scan_end = tims_frame_csp->getTotalNumberOfScans() - 1;
503
504 // By convention, a TIC chromatogram is only performed using MS1
505 // spectra.
506 if(tims_frame_csp->getMsLevel() == 1)
507 {
508
509 // Retention times are in seconds in the Bruker world.
510 double rt = tims_frame_csp->getTime();
511
512 tic_chromatogram.append(DataPoint(
513 rt,
514 tims_frame_csp->cumulateScansIntensities(scan_begin, scan_end)));
515 }
516 else
517 continue;
518 }
519
520 return tic_chromatogram;
521}
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.
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
virtual std::size_t spectrumListSize() const override
get the totat number of spectrum conained in the MSrun data file
virtual void readSpectrumCollection(SpectrumCollectionHandlerInterface &handler) override
function to visit an MsRunReader and get each Spectrum in a spectrum collection handler
virtual MassSpectrumCstSPtr massSpectrumCstSPtr(std::size_t spectrum_index) override
virtual pappso::XicCoordSPtr newXicCoordSPtrFromQualifiedMassSpectrum(const pappso::QualifiedMassSpectrum &mass_spectrum, pappso::PrecisionPtr precision) const override
get a xic coordinate object from a given spectrum
virtual QualifiedMassSpectrum qualifiedMassSpectrum(std::size_t spectrum_index, bool want_binary_data=true) const override
get a QualifiedMassSpectrum class given its scan number
virtual MassSpectrumSPtr massSpectrumSPtr(std::size_t spectrum_index) override
get a MassSpectrumSPtr class given its spectrum index
virtual Trace getTicChromatogram() override
get a TIC chromatogram
virtual bool releaseDevice() override
release data back end device if a the data back end is released, the developper has to use acquireDev...
virtual void readSpectrumCollection2(const MsRunReadConfig &config, SpectrumCollectionHandlerInterface &handler) override
virtual TimsDataSp getTimsDataSPtr()
give an access to the underlying raw data pointer
virtual bool hasScanNumbers() const override
tells if spectra can be accessed using scan numbers by default, it returns false. Only overrided func...
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,...
TimsFramesMsRunReader(MsRunIdCstSPtr &msrun_id_csp)
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 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
A simple container of DataPoint instances.
Definition trace.h:148
size_t append(const DataPoint &data_point)
appends a datapoint and return new size
Definition trace.cpp:648
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
@ TimsFrameInvKoBegin
Bruker's Tims tof 1/K0 frame start range.
@ TimsFrameMzIndexBegin
Bruker's Tims tof mz index frame start range.
@ TimsFrameMzIndexEnd
Bruker's Tims tof mz index frame end range.
@ TimsFrameInvKoEnd
Bruker's Tims tof 1/K0 frame end range.
@ rt
Retention time.
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