libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
timsddaprecursors.cpp
Go to the documentation of this file.
1/**
2 * \file pappsomspp/vendors/tims/timsddaprecursors.h
3 * \date 30/06/2024
4 * \brief handle specific data for DDA MS runs
5 */
6
7/*******************************************************************************
8 * Copyright (c) 2024 Olivier Langella <Olivier.Langella@u-psud.fr>.
9 *
10 * This file is part of the PAPPSOms++ library.
11 *
12 * PAPPSOms++ is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * PAPPSOms++ is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with PAPPSOms++. If not, see <http://www.gnu.org/licenses/>.
24 *
25 ******************************************************************************/
26
27#include "timsddaprecursors.h"
30#include <QSqlError>
34#include <QtConcurrent>
35namespace pappso
36{
37
38TimsDdaPrecursors::TimsDdaPrecursors(QSqlQuery &query, TimsData *tims_data_origin)
39 : mp_timsDataOrigin(tims_data_origin)
40{
41
42 // get number of precursors
43 qDebug();
45 if(!query.exec("SELECT COUNT( DISTINCT Id) FROM Precursors;"))
46 {
47 qDebug();
48 throw pappso::ExceptionNotFound(QObject::tr("ERROR : no Precursors in SqlLite database"));
49 }
50 else
51 {
52 if(query.next())
53 {
54 m_totalPrecursorCount = query.value(0).toLongLong();
55 }
56 }
57
58 qDebug();
59
61 std::make_shared<FilterSuiteString>("chargeDeconvolution|0.02dalton mzExclusion|0.01dalton");
62
63
64 std::shared_ptr<FilterTriangle> ms1filter = std::make_shared<FilterTriangle>();
65 ms1filter.get()->setTriangleSlope(50, 0.01);
66 mcsp_ms1Filter = ms1filter;
67}
68
72
73std::vector<TimsDdaPrecursors::SpectrumDescr>
75{
76 std::vector<TimsDdaPrecursors::SpectrumDescr> spectrum_descr_list;
77
78 try
79 {
80 // QMutexLocker lock(&m_mutex);
81 // Go get records!
82
83
84 QSqlDatabase qdb = mp_timsDataOrigin->openDatabaseConnection();
85
86 QSqlQuery q = qdb.exec(QString("SELECT PasefFrameMsMsInfo.Frame, " // 0
87 "PasefFrameMsMsInfo.ScanNumBegin, " // 1
88 "PasefFrameMsMsInfo.ScanNumEnd, " // 2
89 "PasefFrameMsMsInfo.IsolationMz, " // 3
90 "PasefFrameMsMsInfo.IsolationWidth, " // 4
91 "PasefFrameMsMsInfo.CollisionEnergy, " // 5
92 "PasefFrameMsMsInfo.Precursor, " // 6
93 "Precursors.Id, " // 7
94 "Precursors.LargestPeakMz, " // 8
95 "Precursors.AverageMz, " // 9
96 "Precursors.MonoisotopicMz, " // 10
97 "Precursors.Charge, " // 11
98 "Precursors.ScanNumber, " // 12
99 "Precursors.Intensity, " // 13
100 "Precursors.Parent " // 14
101 "FROM PasefFrameMsMsInfo "
102 "INNER JOIN Precursors ON "
103
104
105 "PasefFrameMsMsInfo.Precursor=Precursors.Id "
106 "WHERE PasefFrameMsMsInfo.Frame=%1;")
107 .arg(frame_id));
108 if(q.lastError().isValid())
109 {
110 qDebug();
111 throw PappsoException(
112 QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
113 "command %2:\n%3\n%4\n%5")
114 .arg(mp_timsDataOrigin->m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
115 .arg(q.lastQuery())
116 .arg(qdb.lastError().databaseText())
117 .arg(qdb.lastError().driverText())
118 .arg(qdb.lastError().nativeErrorCode()));
119 }
120
121 q.last(); // strange bug : get the last sql record and get back,
122 // otherwise it will not retrieve all records.
123 q.first();
124 // std::size_t i = 0;
125 do
126 {
128 spectrum_descr.tims_frame_list.clear();
129 // mass_spectrum.setPrecursorCharge(q.value(11).toInt());
130 // mass_spectrum.setPrecursorMz(q.value(10).toDouble());
131 // mass_spectrum.setPrecursorIntensity(q.value(13).toDouble());
132 spectrum_descr.precursor_ion_data =
133 PrecursorIonData(q.value(10).toDouble(), q.value(11).toInt(), q.value(13).toDouble());
134
135 spectrum_descr.precursor_id = q.value(6).toLongLong();
136 spectrum_descr.ms2_index = (spectrum_descr.precursor_id * 2) - 1;
137 spectrum_descr.ms1_index = (spectrum_descr.precursor_id * 2) - 2;
138
139 spectrum_descr.scan_mobility_start = q.value(1).toLongLong();
140 spectrum_descr.scan_mobility_end = q.value(2).toLongLong();
141
142 spectrum_descr.isolationMz = q.value(3).toDouble();
143 spectrum_descr.isolationWidth = q.value(4).toDouble();
144 spectrum_descr.collisionEnergy = q.value(5).toFloat();
145 spectrum_descr.parent_frame = q.value(14).toLongLong();
146
147 spectrum_descr_list.push_back(spectrum_descr);
148 }
149 while(q.next());
150 }
151 catch(PappsoException &error)
152 {
153 throw error;
154 }
155 catch(std::exception &error)
156 {
157 qDebug() << QString("Failure %1 ").arg(error.what());
158 }
159 return spectrum_descr_list;
160}
161
164{
165
166 qDebug();
168 raw_spectrum.clear();
169 try
170 {
171 QSqlDatabase qdb = mp_timsDataOrigin->openDatabaseConnection();
172
173 QSqlQuery q = qdb.exec(QString("SELECT PasefFrameMsMsInfo.*, Precursors.* FROM "
174 "PasefFrameMsMsInfo INNER JOIN Precursors ON "
175 "PasefFrameMsMsInfo.Precursor=Precursors.Id where "
176 "Precursors.Id=%1;")
177 .arg(precursor_id));
178 if(q.lastError().isValid())
179 {
180 qDebug();
181 throw PappsoException(
182 QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
183 "command %2:\n%3\n%4\n%5")
184 .arg(mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf"))
185 .arg(q.lastQuery())
186 .arg(qdb.lastError().databaseText())
187 .arg(qdb.lastError().driverText())
188 .arg(qdb.lastError().nativeErrorCode()));
189 }
190 qDebug();
191 // m_mutex.unlock();
192 if(q.size() == 0)
193 {
194
195 throw ExceptionNotFound(
196 QObject::tr("ERROR in getQualifiedMassSpectrumByPrecursorId, precursor "
197 "id=%1 not found")
198 .arg(precursor_id));
199 }
200 else
201 {
202 // qDebug() << " q.size()="<< q.size();
203 qDebug();
204 bool first = true;
205 std::size_t scan_mobility_start = 0;
206 std::size_t scan_mobility_end = 0;
207 std::vector<std::size_t> tims_frame_list;
208
209 while(q.next())
210 {
211 tims_frame_list.push_back(q.value(0).toLongLong());
212 if(first)
213 {
214
215 scan_mobility_start = q.value(1).toLongLong();
216 scan_mobility_end = q.value(2).toLongLong();
217
218 first = false;
219 }
220 }
221 // QMutexLocker locker(&m_mutex_spectrum);
222 qDebug();
223 TimsFrameCstSPtr tims_frame, previous_frame;
224 // TracePlusCombiner combiner;
225 // MapTrace combiner_result;
226 for(std::size_t tims_id : tims_frame_list)
227 {
228 tims_frame = mp_timsDataOrigin->getTimsFrameCstSPtrCached(tims_id);
229 qDebug();
230 /*combiner.combine(combiner_result,
231 tims_frame.get()->cumulateScanToTrace(
232 scan_mobility_start, scan_mobility_end));*/
233 if(previous_frame.get() != nullptr)
234 {
235 if(previous_frame.get()->hasSameCalibrationData(*tims_frame.get()))
236 {
237 }
238 else
239 {
240 throw ExceptionNotFound(
241 QObject::tr("ERROR in %1 %2, different calibration data "
242 "between frame id %3 and frame id %4")
243 .arg(__FILE__)
244 .arg(__FUNCTION__)
245 .arg(previous_frame.get()->getId())
246 .arg(tims_frame.get()->getId()));
247 }
248 }
249 tims_frame.get()->combineScansInTofIndexIntensityMap(
250 raw_spectrum, scan_mobility_start, scan_mobility_end);
251 qDebug();
252
253 previous_frame = tims_frame;
254 }
255 qDebug() << " precursor_index=" << precursor_id << " num_rows=" << tims_frame_list.size()
256 << " sql=" << q.lastQuery() << " " << (std::size_t)QThread::currentThreadId();
257 if(first == true)
258 {
259 throw ExceptionNotFound(
260 QObject::tr("ERROR in getQualifiedMassSpectrumByPrecursorId, precursor "
261 "id=%1 not found")
262 .arg(precursor_id));
263 }
264 qDebug();
265 }
266 }
267
268 catch(PappsoException &error)
269 {
270 throw PappsoException(QObject::tr("ERROR in %1 (precursor_index=%2):\n%3")
271 .arg(__FUNCTION__)
272 .arg(precursor_id)
273 .arg(error.qwhat()));
274 }
275 catch(std::exception &error)
276 {
277 qDebug() << QString("Failure %1 ").arg(error.what());
278 }
279 return raw_spectrum;
280 qDebug();
281}
282
283std::size_t
288
291 PrecisionPtr precision_ptr)
292{
293
294 qDebug();
295 XicCoordTims xic_coord_tims_struct;
296
297 try
298 {
299 if(m_mapXicCoordRecord.size() == 0)
300 {
301 QMutexLocker lock(&m_mutex);
302 // Go get records!
303
304 // We proceed in this way:
305
306 // 1. For each Precursor reference to the Precursors table's ID
307 // found in the PasefFrameMsMsInfo table, store the precursor ID for
308 // step 2.
309
310 // 2. From the Precursors table's ID from step 1, get the
311 // MonoisotopicMz.
312
313 // 3. From the PasefFrameMsMsInfo table, for the Precursors table's
314 // ID reference, get a reference to the Frames table's ID. Thanks to
315 // the Frames ID, look for the Time value (acquisition retention
316 // time) for the MS/MS spectrum. The Time value in the Frames tables
317 // always corresponds to a Frame of MsMsType 8 (that is, MS/MS),
318 // which is expected since we are looking into MS/MS data.
319
320 // 4. From the PasefFrameMsMsInfo table, associate the values
321 // ScanNumBegin and ScanNumEnd, the mobility bins in which the
322 // precursor was found.
323
324
325 QSqlDatabase qdb = mp_timsDataOrigin->openDatabaseConnection();
326 QSqlQuery q =
327 qdb.exec(QString("SELECT Precursors.id, "
328 "min(Frames.Time), "
329 "min(PasefFrameMsMsInfo.ScanNumBegin), "
330 "max(PasefFrameMsMsInfo.ScanNumEnd), "
331 "Precursors.MonoisotopicMz "
332 "FROM "
333 "PasefFrameMsMsInfo INNER JOIN Precursors ON "
334 "PasefFrameMsMsInfo.Precursor=Precursors.Id "
335 "INNER JOIN Frames ON "
336 "PasefFrameMsMsInfo.Frame=Frames.Id "
337 "GROUP BY Precursors.id;"));
338 if(q.lastError().isValid())
339 {
340 qDebug();
341 throw PappsoException(
342 QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
343 "command %2:\n%3\n%4\n%5")
344 .arg(mp_timsDataOrigin->m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
345 .arg(q.lastQuery())
346 .arg(qdb.lastError().databaseText())
347 .arg(qdb.lastError().driverText())
348 .arg(qdb.lastError().nativeErrorCode()));
349 }
350
351 q.last(); // strange bug : get the last sql record and get back,
352 // otherwise it will not retrieve all records.
353 q.first();
354 // std::size_t i = 0;
355 do
356 {
357 QSqlRecord record = q.record();
358 m_mapXicCoordRecord.insert(std::pair<std::size_t, QSqlRecord>(
359 (std::size_t)record.value(0).toULongLong(), record));
360 }
361 while(q.next());
362 }
363
364
365 auto it_map_xiccoord = m_mapXicCoordRecord.find(precursor_id);
366 if(it_map_xiccoord == m_mapXicCoordRecord.end())
367 {
368
369 throw ExceptionNotFound(
370 QObject::tr("ERROR Precursors database id %1 not found").arg(precursor_id));
371 }
372
373 auto &q = it_map_xiccoord->second;
374 xic_coord_tims_struct.mzRange = MzRange(q.value(4).toDouble(), precision_ptr);
375 xic_coord_tims_struct.scanNumBegin = q.value(2).toUInt();
376 xic_coord_tims_struct.scanNumEnd = q.value(3).toUInt();
377 xic_coord_tims_struct.rtTarget = q.value(1).toDouble();
378 // xic_structure.charge = q.value(5).toUInt();
379 xic_coord_tims_struct.xicSptr = std::make_shared<Xic>();
380 }
381 catch(PappsoException &error)
382 {
383 throw error;
384 }
385 catch(std::exception &error)
386 {
387 qDebug() << QString("Failure %1 ").arg(error.what());
388 }
389 return xic_coord_tims_struct;
390}
391
392
395{
396
397 SpectrumDescr spectrum_descr;
398 QSqlDatabase qdb = mp_timsDataOrigin->openDatabaseConnection();
399 QSqlQuery q = qdb.exec(QString("SELECT PasefFrameMsMsInfo.Frame, " // 0
400 "PasefFrameMsMsInfo.ScanNumBegin, " // 1
401 "PasefFrameMsMsInfo.ScanNumEnd, " // 2
402 "PasefFrameMsMsInfo.IsolationMz, " // 3
403 "PasefFrameMsMsInfo.IsolationWidth, " // 4
404 "PasefFrameMsMsInfo.CollisionEnergy, " // 5
405 "PasefFrameMsMsInfo.Precursor, " // 6
406 "Precursors.Id, " // 7
407 "Precursors.LargestPeakMz, " // 8
408 "Precursors.AverageMz, " // 9
409 "Precursors.MonoisotopicMz, " // 10
410 "Precursors.Charge, " // 11
411 "Precursors.ScanNumber, " // 12
412 "Precursors.Intensity, " // 13
413 "Precursors.Parent " // 14
414 "FROM PasefFrameMsMsInfo "
415 "INNER JOIN Precursors ON "
416
417
418 "PasefFrameMsMsInfo.Precursor=Precursors.Id "
419 "WHERE Precursors.Id=%1;")
420 .arg(precursor_id));
421 if(q.lastError().isValid())
422 {
423
424 throw PappsoException(
425 QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
426 "command %2:\n%3\n%4\n%5")
427 .arg(mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf"))
428 .arg(q.lastQuery())
429 .arg(qdb.lastError().databaseText())
430 .arg(qdb.lastError().driverText())
431 .arg(qdb.lastError().nativeErrorCode()));
432 }
433
434
435 bool first = true;
436 while(q.next())
437 {
438
439 qDebug() << " cumul tims frame:" << q.value(0).toLongLong();
440 spectrum_descr.tims_frame_list.push_back(q.value(0).toLongLong());
441 if(first)
442 {
443 // mass_spectrum.setPrecursorCharge(q.value(11).toInt());
444 // mass_spectrum.setPrecursorMz(q.value(10).toDouble());
445 // mass_spectrum.setPrecursorIntensity(q.value(13).toDouble());
446 spectrum_descr.precursor_ion_data =
447 PrecursorIonData(q.value(10).toDouble(), q.value(11).toInt(), q.value(13).toDouble());
448
449 spectrum_descr.precursor_id = q.value(6).toLongLong();
450 spectrum_descr.ms2_index = (spectrum_descr.precursor_id * 2) - 1;
451 spectrum_descr.ms1_index = (spectrum_descr.precursor_id * 2) - 2;
452
453 spectrum_descr.scan_mobility_start = q.value(1).toLongLong();
454 spectrum_descr.scan_mobility_end = q.value(2).toLongLong();
455
456 spectrum_descr.isolationMz = q.value(3).toDouble();
457 spectrum_descr.isolationWidth = q.value(4).toDouble();
458 spectrum_descr.collisionEnergy = q.value(5).toFloat();
459 spectrum_descr.parent_frame = q.value(14).toLongLong();
460
461
462 first = false;
463 }
464 }
465 if(spectrum_descr.precursor_id == 0)
466 {
467 throw ExceptionNotFound(QObject::tr("ERROR in %1 %2 : precursor id (%3) NOT FOUND ")
468 .arg(__FILE__)
469 .arg(__FUNCTION__)
470 .arg(precursor_id));
471 }
472 return spectrum_descr;
473}
474
477 const std::pair<std::size_t, std::size_t> &scan_coordinates)
478{
479
480 SpectrumDescr spectrum_descr;
481 QSqlDatabase qdb = mp_timsDataOrigin->openDatabaseConnection();
482 QSqlQuery q = qdb.exec(QString("SELECT PasefFrameMsMsInfo.Frame, " // 0
483 "PasefFrameMsMsInfo.ScanNumBegin, " // 1
484 "PasefFrameMsMsInfo.ScanNumEnd, " // 2
485 "PasefFrameMsMsInfo.IsolationMz, " // 3
486 "PasefFrameMsMsInfo.IsolationWidth, " // 4
487 "PasefFrameMsMsInfo.CollisionEnergy, " // 5
488 "PasefFrameMsMsInfo.Precursor, " // 6
489 "Precursors.Id, " // 7
490 "Precursors.LargestPeakMz, " // 8
491 "Precursors.AverageMz, " // 9
492 "Precursors.MonoisotopicMz, " // 10
493 "Precursors.Charge, " // 11
494 "Precursors.ScanNumber, " // 12
495 "Precursors.Intensity, " // 13
496 "Precursors.Parent " // 14
497 "FROM PasefFrameMsMsInfo "
498 "INNER JOIN Precursors ON "
499 "PasefFrameMsMsInfo.Precursor=Precursors.Id "
500 "WHERE "
501 "PasefFrameMsMsInfo.Frame=%1 and "
502 "(PasefFrameMsMsInfo.ScanNumBegin "
503 "<= %2 and PasefFrameMsMsInfo.ScanNumEnd >= %2);")
504 .arg(scan_coordinates.first)
505 .arg(scan_coordinates.second));
506 if(q.lastError().isValid())
507 {
508
509 throw PappsoException(
510 QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
511 "command %2:\n%3\n%4\n%5")
512 .arg(mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf"))
513 .arg(q.lastQuery())
514 .arg(qdb.lastError().databaseText())
515 .arg(qdb.lastError().driverText())
516 .arg(qdb.lastError().nativeErrorCode()));
517 }
518
519 if(q.next())
520 {
521
522 qDebug() << " cumul tims frame:" << q.value(0).toLongLong();
523 spectrum_descr.tims_frame_list.push_back(q.value(0).toLongLong());
524 // mass_spectrum.setPrecursorCharge(q.value(11).toInt());
525 // mass_spectrum.setPrecursorMz(q.value(10).toDouble());
526 // mass_spectrum.setPrecursorIntensity(q.value(13).toDouble());
527 spectrum_descr.precursor_ion_data =
528 PrecursorIonData(q.value(10).toDouble(), q.value(11).toInt(), q.value(13).toDouble());
529
530 spectrum_descr.precursor_id = q.value(6).toLongLong();
531 spectrum_descr.ms2_index = (spectrum_descr.precursor_id * 2) - 1;
532 spectrum_descr.ms1_index = (spectrum_descr.precursor_id * 2) - 2;
533
534 spectrum_descr.scan_mobility_start = q.value(1).toLongLong();
535 spectrum_descr.scan_mobility_end = q.value(2).toLongLong();
536
537 spectrum_descr.isolationMz = q.value(3).toDouble();
538 spectrum_descr.isolationWidth = q.value(4).toDouble();
539 spectrum_descr.collisionEnergy = q.value(5).toFloat();
540 spectrum_descr.parent_frame = q.value(14).toLongLong();
541 }
542 return spectrum_descr;
543}
544
545
546void
548 TimsDdaPrecursors::SpectrumDescr &spectrum_descr, QSqlQuery &qprecursor_list)
549{
550
551 spectrum_descr.tims_frame_list.clear();
552 spectrum_descr.tims_frame_list.push_back(qprecursor_list.value(0).toLongLong());
553 // mass_spectrum.setPrecursorCharge(q.value(11).toInt());
554 // mass_spectrum.setPrecursorMz(q.value(10).toDouble());
555 // mass_spectrum.setPrecursorIntensity(q.value(13).toDouble());
556 spectrum_descr.precursor_ion_data = PrecursorIonData(qprecursor_list.value(10).toDouble(),
557 qprecursor_list.value(11).toInt(),
558 qprecursor_list.value(13).toDouble());
559
560 spectrum_descr.precursor_id = qprecursor_list.value(6).toLongLong();
561 spectrum_descr.ms2_index = (spectrum_descr.precursor_id * 2) - 1;
562 spectrum_descr.ms1_index = (spectrum_descr.precursor_id * 2) - 2;
563
564 spectrum_descr.scan_mobility_start = qprecursor_list.value(1).toLongLong();
565 spectrum_descr.scan_mobility_end = qprecursor_list.value(2).toLongLong();
566
567 spectrum_descr.isolationMz = qprecursor_list.value(3).toDouble();
568 spectrum_descr.isolationWidth = qprecursor_list.value(4).toDouble();
569 spectrum_descr.collisionEnergy = qprecursor_list.value(5).toFloat();
570 spectrum_descr.parent_frame = qprecursor_list.value(14).toLongLong();
571}
572
573void
575 QualifiedMassSpectrum &mass_spectrum,
576 const SpectrumDescr &spectrum_descr,
577 bool want_binary_data)
578{
579
580
581 qDebug() << " ms2_index=" << spectrum_descr.ms2_index
582 << " precursor_index=" << spectrum_descr.precursor_id;
583
584 TracePlusCombiner combiner;
585 MapTrace combiner_result;
586
587 try
588 {
589 mass_spectrum.setMsLevel(1);
590 mass_spectrum.setPrecursorSpectrumIndex(0);
591 mass_spectrum.setEmptyMassSpectrum(true);
592
593 MassSpectrumId spectrum_id;
594 spectrum_id.setSpectrumIndex(spectrum_descr.ms1_index);
595 spectrum_id.setNativeId(QString("frame_id=%1 begin=%2 end=%3 precursor=%4 idxms1=%5")
596 .arg(spectrum_descr.parent_frame)
597 .arg(spectrum_descr.scan_mobility_start)
598 .arg(spectrum_descr.scan_mobility_end)
599 .arg(spectrum_descr.precursor_id)
600 .arg(spectrum_descr.ms1_index));
601
602 spectrum_id.setMsRunId(msrun_id);
603
604 mass_spectrum.setMassSpectrumId(spectrum_id);
605
606
607 TimsFrameBaseCstSPtr tims_frame;
608 if(want_binary_data)
609 {
610 qDebug() << "bindec";
611 tims_frame = mp_timsDataOrigin->getTimsFrameCstSPtrCached(spectrum_descr.parent_frame);
612 }
613 else
614 {
615 tims_frame =
616 mp_timsDataOrigin->getTimsFrameBaseCstSPtrCached(spectrum_descr.parent_frame);
617 }
618 mass_spectrum.setRtInSeconds(tims_frame.get()->getRtInSeconds());
619
620 mass_spectrum.setParameterValue(
622 tims_frame.get()->getOneOverK0Transformation(spectrum_descr.scan_mobility_start));
623
624 mass_spectrum.setParameterValue(
626 tims_frame.get()->getOneOverK0Transformation(spectrum_descr.scan_mobility_end));
627
628
629 if(want_binary_data)
630 {
631 combiner.combine(combiner_result,
632 tims_frame.get()->cumulateScansToTrace(
633 spectrum_descr.scan_mobility_start, spectrum_descr.scan_mobility_end));
634
635 Trace trace(combiner_result);
636 qDebug();
637
638 if(trace.size() > 0)
639 {
640 if(mcsp_ms1Filter != nullptr)
641 {
642 mcsp_ms1Filter->filter(trace);
643 }
644
645 qDebug();
646 mass_spectrum.setMassSpectrumSPtr(MassSpectrum(trace).makeMassSpectrumSPtr());
647 mass_spectrum.setEmptyMassSpectrum(false);
648 }
649 else
650 {
651 mass_spectrum.setMassSpectrumSPtr(nullptr);
652 mass_spectrum.setEmptyMassSpectrum(true);
653 }
654 }
655 qDebug();
656 }
657
658 catch(PappsoException &error)
659 {
660 throw error;
661 }
662 catch(std::exception &error)
663 {
664 qDebug() << QString("Failure %1 ").arg(error.what());
665 }
666}
667
668
669void
674void
679
680void
682 QualifiedMassSpectrum &mass_spectrum,
683 const SpectrumDescr &spectrum_descr,
684 bool want_binary_data)
685{
686
687
688 try
689 {
690 qDebug();
691 MassSpectrumId spectrum_id;
692
693 spectrum_id.setSpectrumIndex(spectrum_descr.ms2_index);
694 spectrum_id.setNativeId(QString("precursor=%1 idxms2=%2")
695 .arg(spectrum_descr.precursor_id)
696 .arg(spectrum_descr.ms2_index));
697 spectrum_id.setMsRunId(msrun_id);
698
699 mass_spectrum.setMassSpectrumId(spectrum_id);
700
701 mass_spectrum.setMsLevel(2);
702 qDebug() << "spectrum_descr.precursor_id=" << spectrum_descr.precursor_id
703 << " spectrum_descr.ms1_index=" << spectrum_descr.ms1_index
704 << " spectrum_descr.ms2_index=" << spectrum_descr.ms2_index;
705 mass_spectrum.setPrecursorSpectrumIndex(spectrum_descr.ms1_index);
706
707 mass_spectrum.setEmptyMassSpectrum(true);
708
709 qDebug();
710
711
712 mass_spectrum.appendPrecursorIonData(spectrum_descr.precursor_ion_data);
713
714 mass_spectrum.setPrecursorNativeId(
715 QString("frame_id=%1 begin=%2 end=%3 precursor=%4 idxms1=%5")
716 .arg(spectrum_descr.parent_frame)
717 .arg(spectrum_descr.scan_mobility_start)
718 .arg(spectrum_descr.scan_mobility_end)
719 .arg(spectrum_descr.precursor_id)
720 .arg(spectrum_descr.ms1_index));
721
723 spectrum_descr.isolationMz);
725 spectrum_descr.isolationWidth);
726
728 spectrum_descr.collisionEnergy);
730 (quint64)spectrum_descr.precursor_id);
731
732 // QMutexLocker locker(&m_mutex_spectrum);
733 qDebug();
734 TimsFrameBaseCstSPtr tims_frame, previous_frame;
735 // TracePlusCombiner combiner;
736 // MapTrace combiner_result;
738 raw_spectrum.clear();
739 bool first = true;
740 for(std::size_t tims_id : spectrum_descr.tims_frame_list)
741 {
742 qDebug() << " precursor_index=" << spectrum_descr.precursor_id << " tims_id=" << tims_id
743 << (std::size_t)QThread::currentThreadId();
744
745 if(want_binary_data)
746 {
747 qDebug() << "bindec";
748 tims_frame = mp_timsDataOrigin->getTimsFrameCstSPtrCached(tims_id);
749 }
750 else
751 {
752 tims_frame = mp_timsDataOrigin->getTimsFrameBaseCstSPtrCached(tims_id);
753 }
754 qDebug() << (std::size_t)QThread::currentThreadId();
755
756 if(first)
757 {
758 mass_spectrum.setRtInSeconds(tims_frame.get()->getRtInSeconds());
759
760 mass_spectrum.setParameterValue(
762 tims_frame.get()->getOneOverK0Transformation(spectrum_descr.scan_mobility_start));
763
764 mass_spectrum.setParameterValue(
766 tims_frame.get()->getOneOverK0Transformation(spectrum_descr.scan_mobility_end));
767
768 first = false;
769 }
770
771
772 if(want_binary_data)
773 {
774 qDebug();
775 /*combiner.combine(combiner_result,
776 tims_frame.get()->cumulateScanToTrace(
777 scan_mobility_start, scan_mobility_end));*/
778 if(previous_frame.get() != nullptr)
779 {
780 if(previous_frame.get()->hasSameCalibrationData(*tims_frame.get()))
781 {
782 }
783 else
784 {
785 throw ExceptionNotFound(
786 QObject::tr("ERROR in %1 %2, different calibration data "
787 "between frame id %3 and frame id %4")
788 .arg(__FILE__)
789 .arg(__FUNCTION__)
790 .arg(previous_frame.get()->getId())
791 .arg(tims_frame.get()->getId()));
792 }
793 }
794 qDebug() << (std::size_t)QThread::currentThreadId();
795
796 tims_frame.get()->combineScansInTofIndexIntensityMap(
797 raw_spectrum, spectrum_descr.scan_mobility_start, spectrum_descr.scan_mobility_end);
798 qDebug() << (std::size_t)QThread::currentThreadId();
799 }
800 previous_frame = tims_frame;
801 }
802 qDebug() << " precursor_index=" << spectrum_descr.precursor_id
803 << " num_rows=" << spectrum_descr.tims_frame_list.size()
804 << (std::size_t)QThread::currentThreadId();
805 if(first == true)
806 {
807 throw ExceptionNotFound(
808 QObject::tr("ERROR in getQualifiedMassSpectrumByPrecursorId, precursor "
809 "id=%1 not found")
810 .arg(spectrum_descr.precursor_id));
811 }
812 if(want_binary_data)
813 {
814 qDebug() << " precursor_index=" << spectrum_descr.precursor_id;
815 // peak_pick.filter(trace);
816 Trace trace;
818 {
819 // raw_spectrum.removeArtefactualSpike();
820 raw_spectrum.builtInCentroid();
821 }
822
823 trace = tims_frame.get()->getTraceFromTofIndexIntensityMap(raw_spectrum);
824
825 if(trace.size() > 0)
826 {
827 qDebug() << " precursor_index=" << spectrum_descr.precursor_id << " " << trace.size()
828 << " " << (std::size_t)QThread::currentThreadId();
829
830 if(mcsp_ms2Filter != nullptr)
831 {
832 // FilterTriangle filter;
833 // filter.setTriangleSlope(50, 0.02);
834 // filter.filter(trace);
835 // trace.filter(FilterHighPass(10));
836 mcsp_ms2Filter->filter(trace);
837 }
838
839 // FilterScaleFactorY filter_scale((double)1 /
840 // (double)tims_frame_list.size());
841 // filter_scale.filter(trace);
842 qDebug() << " precursor_index=" << spectrum_descr.precursor_id;
843 mass_spectrum.setMassSpectrumSPtr(MassSpectrum(trace).makeMassSpectrumSPtr());
844 mass_spectrum.setEmptyMassSpectrum(false);
845 }
846 else
847 {
848 mass_spectrum.setMassSpectrumSPtr(nullptr);
849 mass_spectrum.setEmptyMassSpectrum(true);
850 }
851
852 qDebug();
853 }
854 qDebug();
855 }
856
857 catch(PappsoException &error)
858 {
859 throw PappsoException(QObject::tr("ERROR in %1 (ms2_index=%2 precursor_index=%3):\n%4")
860 .arg(__FUNCTION__)
861 .arg(spectrum_descr.ms2_index)
862 .arg(spectrum_descr.precursor_id)
863 .arg(error.qwhat()));
864 }
865 catch(std::exception &error)
866 {
867 qDebug() << QString("Failure %1 ").arg(error.what());
868 }
869 qDebug();
870}
871
872void
874{
875 m_builtinMs2Centroid = centroid;
876}
877
878bool
883
884void
887 unsigned int ms_level)
888{
889 qDebug() << " ms_level=" << ms_level;
890
891 QSqlDatabase qdb = mp_timsDataOrigin->openDatabaseConnection();
892 QSqlQuery qprecursor_list =
893 qdb.exec(QString("SELECT PasefFrameMsMsInfo.Frame, " // 0
894 "PasefFrameMsMsInfo.ScanNumBegin, " // 1
895 "PasefFrameMsMsInfo.ScanNumEnd, " // 2
896 "PasefFrameMsMsInfo.IsolationMz, " // 3
897 "PasefFrameMsMsInfo.IsolationWidth, " // 4
898 "PasefFrameMsMsInfo.CollisionEnergy, " // 5
899 "PasefFrameMsMsInfo.Precursor, " // 6
900 "Precursors.Id, " // 7
901 "Precursors.LargestPeakMz, " // 8
902 "Precursors.AverageMz, " // 9
903 "Precursors.MonoisotopicMz, " // 10
904 "Precursors.Charge, " // 11
905 "Precursors.ScanNumber, " // 12
906 "Precursors.Intensity, " // 13
907 "Precursors.Parent " // 14
908 "FROM PasefFrameMsMsInfo "
909 "INNER JOIN Precursors ON "
910 "PasefFrameMsMsInfo.Precursor=Precursors.Id "
911 "ORDER BY PasefFrameMsMsInfo.Precursor, PasefFrameMsMsInfo.Frame ;"));
912 if(qprecursor_list.lastError().isValid())
913 {
914
915 throw PappsoException(
916 QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
917 "command %2:\n%3\n%4\n%5")
918 .arg(mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf"))
919 .arg(qprecursor_list.lastQuery())
920 .arg(qdb.lastError().databaseText())
921 .arg(qdb.lastError().driverText())
922 .arg(qdb.lastError().nativeErrorCode()));
923 }
924
925
926 qDebug() << "qprecursor_list.size()=" << qprecursor_list.size();
927 qDebug() << QObject::tr(
928 "TIMS sqlite database file %1, executing SQL "
929 "command %2:\n%3\n%4\n%5")
930 .arg(mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf"))
931 .arg(qprecursor_list.lastQuery())
932 .arg(qdb.lastError().databaseText())
933 .arg(qdb.lastError().driverText())
934 .arg(qdb.lastError().nativeErrorCode());
935
936 qDebug() << "qprecursor_list.isActive()=" << qprecursor_list.isActive();
937 qDebug() << "qprecursor_list.isSelect()=" << qprecursor_list.isSelect();
938 bool first = true;
939 SpectrumDescr spectrum_descr;
940
941 /*
942std::size_t i = 0;
943while(qprecursor_list.next())
944 {
945 qDebug() << "i=" << i;
946 i++;
947 }*/
948
949 qprecursor_list.last(); // strange bug : get the last sql record and get
950 // back, otherwise it will not retrieve all records.
951
952 qDebug() << "qprecursor_list.at()=" << qprecursor_list.at();
953 qprecursor_list.first();
954 std::vector<TimsDdaPrecursors::SpectrumDescr> spectrum_description_list;
955 spectrum_descr.precursor_id = 0;
956 // std::size_t i = 0;
957
958 do
959 {
960
961 if(spectrum_descr.precursor_id != (std::size_t)qprecursor_list.value(6).toLongLong())
962 {
963 // new precursor
964 if(spectrum_descr.precursor_id > 0)
965 {
966 spectrum_description_list.push_back(spectrum_descr);
967 }
968
969 spectrum_descr.tims_frame_list.clear();
970 first = true;
971 }
972 qDebug() << " qprecursor_list.value(6).toLongLong() ="
973 << qprecursor_list.value(6).toLongLong();
974 spectrum_descr.precursor_id = (std::size_t)qprecursor_list.value(6).toLongLong();
975 qDebug() << " spectrum_descr.precursor_id =" << spectrum_descr.precursor_id;
976 qDebug() << " cumul tims frame:" << qprecursor_list.value(0).toLongLong();
977 spectrum_descr.tims_frame_list.push_back(qprecursor_list.value(0).toLongLong());
978 qDebug() << " first =" << first;
979 if(first)
980 {
981 qDebug();
982 // mass_spectrum.setPrecursorCharge(q.value(11).toInt());
983 // mass_spectrum.setPrecursorMz(q.value(10).toDouble());
984 // mass_spectrum.setPrecursorIntensity(q.value(13).toDouble());
985 spectrum_descr.precursor_ion_data =
986 PrecursorIonData(qprecursor_list.value(10).toDouble(),
987 qprecursor_list.value(11).toInt(),
988 qprecursor_list.value(13).toDouble());
989
990 // spectrum_descr.precursor_id = q.value(6).toLongLong();
991 spectrum_descr.ms2_index = (spectrum_descr.precursor_id * 2) - 1;
992 spectrum_descr.ms1_index = (spectrum_descr.precursor_id * 2) - 2;
993
994 spectrum_descr.scan_mobility_start = qprecursor_list.value(1).toLongLong();
995 spectrum_descr.scan_mobility_end = qprecursor_list.value(2).toLongLong();
996
997 spectrum_descr.isolationMz = qprecursor_list.value(3).toDouble();
998 spectrum_descr.isolationWidth = qprecursor_list.value(4).toDouble();
999 spectrum_descr.collisionEnergy = qprecursor_list.value(5).toFloat();
1000 spectrum_descr.parent_frame = qprecursor_list.value(14).toLongLong();
1001
1002
1003 first = false;
1004 }
1005 // qDebug() << "qprecursor_list.executedQuery()="
1006 // << qprecursor_list.executedQuery();
1007 // qDebug() << "qprecursor_list.last()=" << qprecursor_list.last();
1008 // i++;
1009 }
1010 while(qprecursor_list.next());
1011
1012 // last One
1013
1014 // new precursor
1015 if(spectrum_descr.precursor_id > 0)
1016 {
1017 spectrum_description_list.push_back(spectrum_descr);
1018 }
1019
1020
1021 QString local_filepath =
1022 mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf");
1023
1024 if(m_isMonoThread)
1025 {
1026 for(SpectrumDescr &spectrum_descr : spectrum_description_list)
1027 {
1028
1029 std::vector<QualifiedMassSpectrum> mass_spectrum_list;
1031 msrun_id, mass_spectrum_list, handler, spectrum_descr, ms_level);
1032
1033 for(auto &qualified_spectrum : mass_spectrum_list)
1034 {
1035 handler.setQualifiedMassSpectrum(qualified_spectrum);
1036 }
1037
1038 if(handler.shouldStop())
1039 {
1040 qDebug() << "The operation was cancelled. Breaking the loop.";
1042 QObject::tr("reading TimsTOF job cancelled by the user :\n%1").arg(local_filepath));
1043 }
1044 }
1045 }
1046 else
1047 {
1048
1049
1050 TimsDdaPrecursors *itself = this;
1051 SpectrumCollectionHandlerInterface *pointer_handler = &handler;
1052
1053
1054 std::function<std::vector<QualifiedMassSpectrum>(const TimsDdaPrecursors::SpectrumDescr &)>
1055 map_function_generate_spectrum = [itself, msrun_id, pointer_handler, ms_level](
1056 const TimsDdaPrecursors::SpectrumDescr &spectrum_descr)
1057 -> std::vector<QualifiedMassSpectrum> {
1058 std::vector<QualifiedMassSpectrum> mass_spectrum_list;
1060 msrun_id, mass_spectrum_list, *pointer_handler, spectrum_descr, ms_level);
1061
1062
1063 return mass_spectrum_list;
1064 };
1065
1066 std::function<void(std::size_t,
1067 const std::vector<QualifiedMassSpectrum> &qualified_spectrum_list)>
1068 reduce_function_spectrum_list =
1069 [pointer_handler, local_filepath](
1070 std::size_t res, const std::vector<QualifiedMassSpectrum> &qualified_spectrum_list) {
1071 for(auto &qualified_spectrum : qualified_spectrum_list)
1072 {
1073 pointer_handler->setQualifiedMassSpectrum(qualified_spectrum);
1074 }
1075
1076 if(pointer_handler->shouldStop())
1077 {
1078 qDebug() << "The operation was cancelled. Breaking the loop.";
1080 QObject::tr("reading TimsTOF job on %1 cancelled by the user")
1081 .arg(local_filepath));
1082 }
1083 res++;
1084 };
1085
1086
1087 QFuture<std::size_t> res;
1088 res = QtConcurrent::mappedReduced<std::size_t>(spectrum_description_list.begin(),
1089 spectrum_description_list.end(),
1090 map_function_generate_spectrum,
1091 reduce_function_spectrum_list,
1092 QtConcurrent::OrderedReduce);
1093 res.waitForFinished();
1094 }
1095 handler.loadingEnded();
1096 mp_timsDataOrigin->getTimsBinDecPtr()->closeLinearRead();
1097}
1098
1099void
1101{
1102 m_isMonoThread = is_mono_thread;
1103}
1104
1105void
1107 const MsRunIdCstSPtr &msrun_id,
1108 std::vector<QualifiedMassSpectrum> &qualified_mass_spectrum_list,
1110 const TimsDdaPrecursors::SpectrumDescr &spectrum_descr,
1111 unsigned int ms_level)
1112{
1113
1114 qDebug() << " ms_level=" << ms_level;
1115 // The handler will receive the index of the mass spectrum in the
1116 // current run via the mass spectrum id member datum.
1117 if((ms_level == 0) || (ms_level == 1))
1118 {
1119 qualified_mass_spectrum_list.push_back(QualifiedMassSpectrum());
1121 qualified_mass_spectrum_list.back(),
1122 spectrum_descr,
1123 handler.needMsLevelPeakList(1));
1124 }
1125 if((ms_level == 0) || (ms_level == 2))
1126 {
1127 qualified_mass_spectrum_list.push_back(QualifiedMassSpectrum());
1129 qualified_mass_spectrum_list.back(),
1130 spectrum_descr,
1131 handler.needMsLevelPeakList(2));
1132 }
1133 qDebug();
1134}
1135
1136void
1139 unsigned int ms_level)
1140{
1141
1142
1143 // We'll need it to perform the looping in the spectrum list.
1144 std::size_t spectrum_list_size = mp_timsDataOrigin->getTotalScanCount();
1145
1146 // qDebug() << "The spectrum list has size:" << spectrum_list_size;
1147
1148 // Inform the handler of the spectrum list so that it can handle feedback to
1149 // the user.
1150 handler.spectrumListHasSize(spectrum_list_size);
1151
1152 QSqlDatabase qdb = mp_timsDataOrigin->openDatabaseConnection();
1153 QSqlQuery qprecursor_list =
1154 qdb.exec(QString("SELECT DISTINCT "
1155 "PasefFrameMsMsInfo.Frame, " // 0
1156 "PasefFrameMsMsInfo.ScanNumBegin, " // 1
1157 "PasefFrameMsMsInfo.ScanNumEnd, " // 2
1158 "PasefFrameMsMsInfo.IsolationMz, " // 3
1159 "PasefFrameMsMsInfo.IsolationWidth, " // 4
1160 "PasefFrameMsMsInfo.CollisionEnergy, " // 5
1161 "PasefFrameMsMsInfo.Precursor, " // 6
1162 "Precursors.Id, " // 7
1163 "Precursors.LargestPeakMz, " // 8
1164 "Precursors.AverageMz, " // 9
1165 "Precursors.MonoisotopicMz, " // 10
1166 "Precursors.Charge, " // 11
1167 "Precursors.ScanNumber, " // 12
1168 "Precursors.Intensity, " // 13
1169 "Precursors.Parent " // 14
1170 "FROM PasefFrameMsMsInfo "
1171 "INNER JOIN Precursors ON "
1172 "PasefFrameMsMsInfo.Precursor=Precursors.Id "
1173 "ORDER BY PasefFrameMsMsInfo.Frame, PasefFrameMsMsInfo.ScanNumBegin ;"));
1174 if(qprecursor_list.lastError().isValid())
1175 {
1176 throw PappsoException(
1177 QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
1178 "command %2:\n%3\n%4\n%5")
1179 .arg(mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf"))
1180 .arg(qprecursor_list.lastQuery())
1181 .arg(qdb.lastError().databaseText())
1182 .arg(qdb.lastError().driverText())
1183 .arg(qdb.lastError().nativeErrorCode()));
1184 }
1185
1186
1187 std::size_t i = 0; // iterate on each Spectrum
1188
1189 qprecursor_list.last(); // strange bug : get the last sql record and get
1190 // back, unless it will not retrieve all records.
1191
1192 qDebug() << "qprecursor_list.at()=" << qprecursor_list.at();
1193 qprecursor_list.first();
1194
1195 TimsFrameBaseCstSPtr tims_frame;
1196 SpectrumDescr spectrum_descr;
1197
1198 for(const FrameIdDescr &current_frame : mp_timsDataOrigin->getFrameIdDescrList())
1199 {
1200
1201 // If the user of this reader instance wants to stop reading the
1202 // spectra, then break this loop.
1203 if(handler.shouldStop())
1204 {
1205 qDebug() << "The operation was cancelled. Breaking the loop.";
1207 QObject::tr("reading TimsTOF job cancelled by the user :\n%1")
1208 .arg(mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf")));
1209 }
1210
1211 tims_frame = mp_timsDataOrigin->getTimsFrameBaseCstSPtrCached(current_frame.m_frameId);
1212 unsigned int tims_ms_level = tims_frame.get()->getMsLevel();
1213
1214 if((ms_level != 0) && (ms_level != tims_ms_level))
1215 { // bypass
1216 i += current_frame.m_scanCount;
1217 }
1218 else
1219 {
1220 bool want_binary_data = handler.needMsLevelPeakList(tims_ms_level);
1221 qDebug() << "want_binary_data=" << want_binary_data;
1222 if(want_binary_data)
1223 {
1224 qDebug() << "bindec";
1225 tims_frame = mp_timsDataOrigin->getTimsFrameCstSPtrCached(current_frame.m_frameId);
1226 }
1227
1228 bool possible_precursor = false;
1229 if(tims_ms_level == 2)
1230 {
1231 // seek the precursor record:
1232 while(qprecursor_list.value(0).toULongLong() < current_frame.m_frameId)
1233 {
1234 qprecursor_list.next();
1235
1236 if(qprecursor_list.value(0).toULongLong() == current_frame.m_frameId)
1237 {
1238 possible_precursor = true;
1239 }
1240 fillSpectrumDescriptionWithSqlRecord(spectrum_descr, qprecursor_list);
1241 }
1242 }
1243
1244 for(std::size_t scan_num = 0; scan_num < current_frame.m_scanCount; scan_num++)
1245 {
1246 bool has_a_precursor = false;
1247 if(possible_precursor)
1248 {
1249 if(spectrum_descr.scan_mobility_end < scan_num)
1250 {
1251 // seek the precursor record:
1252 while(qprecursor_list.value(0).toULongLong() < current_frame.m_frameId)
1253 {
1254 qprecursor_list.next();
1255
1256 if(qprecursor_list.value(0).toULongLong() != current_frame.m_frameId)
1257 {
1258 possible_precursor = false;
1259 }
1260 fillSpectrumDescriptionWithSqlRecord(spectrum_descr, qprecursor_list);
1261 }
1262 }
1263
1264 if(possible_precursor && (spectrum_descr.scan_mobility_start < scan_num))
1265 {
1266 // we are in
1267 has_a_precursor = true;
1268 }
1269 } // end to determine if we are in a precursor for this
1270 // spectrum
1271
1272 QualifiedMassSpectrum mass_spectrum;
1273
1274
1275 MassSpectrumId spectrum_id;
1276
1277 spectrum_id.setSpectrumIndex(i);
1278 spectrum_id.setMsRunId(msrun_id);
1279 spectrum_id.setNativeId(QString("frame_id=%1 scan_index=%2 global_scan_index=%3")
1280 .arg(current_frame.m_frameId)
1281 .arg(scan_num)
1282 .arg(i));
1283
1284 mass_spectrum.setMassSpectrumId(spectrum_id);
1285
1286 mass_spectrum.setMsLevel(tims_frame.get()->getMsLevel());
1287 mass_spectrum.setRtInSeconds(tims_frame.get()->getRtInSeconds());
1288
1289 mass_spectrum.setDtInMilliSeconds(
1290 tims_frame.get()->getDriftTimeInMilliseconds(scan_num));
1291 // 1/K0
1292 mass_spectrum.setParameterValue(
1294 tims_frame.get()->getOneOverK0Transformation(scan_num));
1295
1296 mass_spectrum.setEmptyMassSpectrum(true);
1297 if(want_binary_data)
1298 {
1299 try
1300 {
1301 mass_spectrum.setMassSpectrumSPtr(
1302 tims_frame.get()->getMassSpectrumSPtr(scan_num));
1303 }
1304 catch(PappsoException &error)
1305 {
1306 throw PappsoException(
1307 QObject::tr("ERROR in %1 (scan_num=%2 spectrum_index=%3):\n%4")
1308 .arg(__FUNCTION__)
1309 .arg(scan_num)
1310 .arg(spectrum_id.getSpectrumIndex())
1311 .arg(error.qwhat()));
1312 }
1313 if(mass_spectrum.size() > 0)
1314 {
1315 mass_spectrum.setEmptyMassSpectrum(false);
1316 }
1317 }
1318 else
1319 {
1320 // if(tims_frame.get()->getNbrPeaks(coordinate.second) > 0)
1321 //{
1322 mass_spectrum.setEmptyMassSpectrum(false);
1323 // }
1324 }
1325 if(has_a_precursor)
1326 {
1327 if(spectrum_descr.precursor_id > 0)
1328 {
1329
1330 mass_spectrum.appendPrecursorIonData(spectrum_descr.precursor_ion_data);
1331
1332 std::size_t prec_spectrum_index =
1333 mp_timsDataOrigin->getGlobalScanIndexByScanCoordinates(
1334 spectrum_descr.parent_frame, scan_num);
1335
1336 mass_spectrum.setPrecursorSpectrumIndex(prec_spectrum_index);
1337 mass_spectrum.setPrecursorNativeId(
1338 QString("frame_id=%1 scan_index=%2 global_scan_index=%3")
1339 .arg(spectrum_descr.parent_frame)
1340 .arg(scan_num)
1341 .arg(prec_spectrum_index));
1342
1344 spectrum_descr.isolationMz);
1345 mass_spectrum.setParameterValue(
1347 spectrum_descr.isolationWidth);
1348
1349 mass_spectrum.setParameterValue(
1351 spectrum_descr.collisionEnergy);
1352 mass_spectrum.setParameterValue(
1354 (quint64)spectrum_descr.precursor_id);
1355 }
1356 }
1357
1358 handler.setQualifiedMassSpectrum(mass_spectrum);
1359 i++;
1360 }
1361 }
1362 }
1363}
1364
1365
1366std::vector<std::size_t>
1367TimsDdaPrecursors::getPrecursorsByMzRtCharge(int charge, double mz_val, double rt_sec, double k0)
1368{
1369
1370 std::vector<std::size_t> precursor_ids;
1371 std::vector<std::vector<double>> ids;
1372
1373 QSqlDatabase qdb = mp_timsDataOrigin->openDatabaseConnection();
1374 QSqlQuery q(QString("SELECT Frames.Time, Precursors.MonoisotopicMz, Precursors.Charge, "
1375 "Precursors.Id, Frames.Id, PasefFrameMsMsInfo.ScanNumBegin, "
1376 "PasefFrameMsMsInfo.scanNumEnd "
1377 "FROM Frames "
1378 "INNER JOIN PasefFrameMsMsInfo ON Frames.Id = "
1379 "PasefFrameMsMsInfo.Frame "
1380 "INNER JOIN Precursors ON "
1381 "PasefFrameMsMsInfo.Precursor= Precursors.Id "
1382 "WHERE Precursors.Charge == %1 "
1383 "AND Precursors.MonoisotopicMz > %2 -0.01 "
1384 "AND Precursors.MonoisotopicMz < %2 +0.01 "
1385 "AND Frames.Time >= %3 -1 "
1386 "AND Frames.Time < %3 +1; ")
1387 .arg(charge)
1388 .arg(mz_val)
1389 .arg(rt_sec));
1390 q.exec();
1391 if(q.lastError().isValid())
1392 {
1393
1394 throw PappsoException(
1395 QObject::tr("ERROR in TIMS sqlite database file %1, database name %2, "
1396 "executing SQL "
1397 "command %3:\n%4\n%5\n%6")
1398 .arg(mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf"))
1399 .arg(qdb.databaseName())
1400 .arg(q.lastQuery())
1401 .arg(qdb.lastError().databaseText())
1402 .arg(qdb.lastError().driverText())
1403 .arg(qdb.lastError().nativeErrorCode()));
1404 }
1405 while(q.next())
1406 {
1407 // qInfo() << q.value(0).toDouble() << q.value(1).toDouble()
1408 // << q.value(2).toDouble() << q.value(3).toDouble();
1409
1410 std::vector<double> sql_values;
1411 sql_values.push_back(q.value(4).toDouble()); // frame id
1412 sql_values.push_back(q.value(3).toDouble()); // precursor id
1413 sql_values.push_back(q.value(5).toDouble()); // scan num begin
1414 sql_values.push_back(q.value(6).toDouble()); // scan num end
1415 sql_values.push_back(q.value(1).toDouble()); // mz_value
1416
1417 ids.push_back(sql_values);
1418
1419
1420 if(std::find(precursor_ids.begin(), precursor_ids.end(), q.value(3).toDouble()) ==
1421 precursor_ids.end())
1422 {
1423 precursor_ids.push_back(q.value(3).toDouble());
1424 }
1425 }
1426
1427 if(precursor_ids.size() > 1)
1428 {
1429 // std::vector<std::size_t> precursor_ids_ko =
1430 // getMatchPrecursorIdByKo(ids, values[3]);
1431 if(precursor_ids.size() > 1)
1432 {
1433 precursor_ids = getClosestPrecursorIdByMz(ids, k0);
1434 }
1435 return precursor_ids;
1436 }
1437 else
1438 {
1439 return precursor_ids;
1440 }
1441}
1442
1443std::vector<std::size_t>
1444TimsDdaPrecursors::getMatchPrecursorIdByKo(std::vector<std::vector<double>> ids, double ko_value)
1445{
1446 std::vector<std::size_t> precursor_id;
1447 for(std::vector<double> index : ids)
1448 {
1449 auto coordinate = mp_timsDataOrigin->getScanCoordinatesByGlobalScanIndex(index[0]);
1450
1451 TimsFrameBaseCstSPtr tims_frame;
1452 tims_frame = mp_timsDataOrigin->getTimsFrameBaseCstSPtrCached(coordinate.first);
1453
1454 double bko = tims_frame.get()->getOneOverK0Transformation(index[2]);
1455 double eko = tims_frame.get()->getOneOverK0Transformation(index[3]);
1456
1457 // qInfo() << "diff" << (bko + eko) / 2;
1458 double mean_ko = (bko + eko) / 2;
1459
1460 if(mean_ko > ko_value - 0.1 && mean_ko < ko_value + 0.1)
1461 {
1462 precursor_id.push_back(index[1]);
1463 }
1464 }
1465 return precursor_id;
1466}
1467
1468std::vector<std::size_t>
1469TimsDdaPrecursors::getClosestPrecursorIdByMz(std::vector<std::vector<double>> ids, double mz_value)
1470{
1471 std::vector<std::size_t> best_precursor;
1472 double best_value = 1;
1473 int count = 1;
1474 int best_val_position = 0;
1475
1476 for(std::vector<double> values : ids)
1477 {
1478 double new_val = abs(mz_value - values[4]);
1479 if(new_val < best_value)
1480 {
1481 best_value = new_val;
1482 best_val_position = count;
1483 }
1484 count++;
1485 }
1486 best_precursor.push_back(ids[best_val_position][1]);
1487 return best_precursor;
1488}
1489
1490
1491} // namespace pappso
void setNativeId(const QString &native_id)
void setMsRunId(MsRunIdCstSPtr other)
std::size_t getSpectrumIndex() const
void setSpectrumIndex(std::size_t index)
Class to represent a mass spectrum.
const char * what() const noexcept override
virtual const QString & qwhat() const
Class representing a fully specified mass spectrum.
void setPrecursorNativeId(const QString &native_id)
Set the scan native id of the precursor ion.
void setDtInMilliSeconds(pappso_double rt)
Set the drift time in milliseconds.
void appendPrecursorIonData(const PrecursorIonData &precursor_ion_data)
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 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 bool needMsLevelPeakList(unsigned int ms_level) const final
tells if we need the peak list (if we want the binary data) for each spectrum, given an MS level
virtual void setQualifiedMassSpectrum(const QualifiedMassSpectrum &spectrum)=0
replacement for std::map
void builtInCentroid()
simple filter to agregate counts on neigbhor mobility slots (+1)
static TimsDataFastMap & getTimsDataFastMapInstance()
void fillSpectrumDescriptionWithSqlRecord(SpectrumDescr &spectrum_descr, QSqlQuery &qprecursor_list)
void ms2ReaderGenerateMS1MS2Spectrum(const MsRunIdCstSPtr &msrun_id, std::vector< QualifiedMassSpectrum > &qualified_mass_spectrum_list, SpectrumCollectionHandlerInterface &handler, const SpectrumDescr &spectrum_descr, unsigned int ms_level)
std::vector< std::size_t > getPrecursorsByMzRtCharge(int charge, double mz_val, double rt_sec, double k0)
guess possible precursor ids given a charge, m/z, retention time and k0
void getQualifiedMs1MassSpectrumBySpectrumDescr(const MsRunIdCstSPtr &msrun_id, QualifiedMassSpectrum &mass_spectrum, const SpectrumDescr &spectrum_descr, bool want_binary_data)
std::vector< TimsDdaPrecursors::SpectrumDescr > getSpectrumDescrListByFrameId(std::size_t frame_id) const
get a list of TimsDdaPrecursors::SpectrumDescr for a frame
pappso::FilterInterfaceCstSPtr mcsp_ms1Filter
std::vector< std::size_t > getClosestPrecursorIdByMz(std::vector< std::vector< double > > ids, double mz_value)
std::map< std::size_t, QSqlRecord > m_mapXicCoordRecord
SpectrumDescr getSpectrumDescrWithScanCoordinates(const std::pair< std::size_t, std::size_t > &scan_coordinates)
void setMs2BuiltinCentroid(bool centroid)
enable or disable simple centroid filter on raw tims data for MS2
void getQualifiedMs2MassSpectrumBySpectrumDescr(const MsRunIdCstSPtr &msrun_id, QualifiedMassSpectrum &mass_spectrum, const SpectrumDescr &spectrum_descr, bool want_binary_data)
bool getMs2BuiltinCentroid() const
tells if simple centroid filter on raw tims data for MS2 is enabled or not
XicCoordTims getXicCoordTimsFromPrecursorId(std::size_t precursor_id, PrecisionPtr precision_ptr)
void rawReaderSpectrumCollectionByMsLevel(const MsRunIdCstSPtr &msrun_id, SpectrumCollectionHandlerInterface &handler, unsigned int ms_level)
function to visit an MsRunReader and get each raw Spectrum in a spectrum collection handler by Ms Lev...
TimsDdaPrecursors(QSqlQuery &query, TimsData *tims_data_origin)
void setMs2FilterCstSPtr(pappso::FilterInterfaceCstSPtr &filter)
filter interface to apply just after raw MS2 specturm extraction the filter can be a list of filters ...
pappso::FilterInterfaceCstSPtr mcsp_ms2Filter
void ms2ReaderSpectrumCollectionByMsLevel(const MsRunIdCstSPtr &msrun_id, SpectrumCollectionHandlerInterface &handler, unsigned int ms_level)
function to visit an MsRunReader and get each Spectrum in a spectrum collection handler by Ms Levels
std::vector< std::size_t > getMatchPrecursorIdByKo(std::vector< std::vector< double > > ids, double ko_value)
void setMs1FilterCstSPtr(pappso::FilterInterfaceCstSPtr &filter)
filter interface to apply just after raw MS1 specturm extraction the filter can be a list of filters ...
TimsDdaPrecursors::SpectrumDescr getSpectrumDescrWithPrecursorId(std::size_t precursor_id) const
get an intermediate structure describing a spectrum
void setMonoThread(bool is_mono_thread)
set only one is_mono_thread to true
std::size_t getTotalPrecursorCount() const
get the number of precursors analyzed by PASEF
bool m_builtinMs2Centroid
enable builtin centroid on raw tims integers by default
TimsDataFastMap & getCombinedMs2ScansByPrecursorId(std::size_t precursor_id)
get cumulated raw signal for a given precursorCMakeLists.txt.userCMakeLists.txt.userCMakeLists....
virtual MapTrace & combine(MapTrace &map_trace, const Trace &trace) const override
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 TimsFrameBase > TimsFrameBaseCstSPtr
@ filter
concerning filters (psm, peptide, protein validation)
std::shared_ptr< const MsRunId > MsRunIdCstSPtr
Definition msrunid.h:46
@ IsolationMzWidth
m/z isolation window width (left + right)
@ CollisionEnergy
Bruker's timsTOF collision energy.
@ BrukerPrecursorIndex
Bruker's timsTOF precursor index.
std::shared_ptr< const FilterInterface > FilterInterfaceCstSPtr
const PrecisionBase * PrecisionPtr
Definition precision.h:122
std::shared_ptr< const TimsFrame > TimsFrameCstSPtr
Definition timsframe.h:44
std::vector< std::size_t > tims_frame_list
coordinates of the XIC to extract and the resulting XIC after extraction
std::size_t scanNumEnd
mobility index end
std::size_t scanNumBegin
mobility index begin
XicSPtr xicSptr
extracted xic
Definition xiccoord.h:135
double rtTarget
the targeted retention time to extract around intended in seconds, and related to one msrun....
Definition xiccoord.h:131
MzRange mzRange
the mass to extract
Definition xiccoord.h:125