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