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