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);
731
733 spectrum_descr.collisionEnergy);
735 (quint64)spectrum_descr.precursor_id);
736
737 // QMutexLocker locker(&m_mutex_spectrum);
738 qDebug();
739 TimsFrameBaseCstSPtr tims_frame, previous_frame;
740 // TracePlusCombiner combiner;
741 // MapTrace combiner_result;
743 raw_spectrum.clear();
744 bool first = true;
745 for(std::size_t tims_id : spectrum_descr.tims_frame_list)
746 {
747 qDebug() << " precursor_index=" << spectrum_descr.precursor_id << " tims_id=" << tims_id
748 << (std::size_t)QThread::currentThreadId();
749
750 if(want_binary_data)
751 {
752 qDebug() << "bindec";
753 tims_frame = mp_timsDataOrigin->getTimsFrameCstSPtrCached(tims_id);
754 }
755 else
756 {
757 tims_frame = mp_timsDataOrigin->getTimsFrameBaseCstSPtrCached(tims_id);
758 }
759 qDebug() << (std::size_t)QThread::currentThreadId();
760
761 if(first)
762 {
763 mass_spectrum.setRtInSeconds(tims_frame.get()->getRtInSeconds());
764
765 mass_spectrum.setParameterValue(
767 tims_frame.get()->getOneOverK0Transformation(spectrum_descr.scan_mobility_start));
768
769 mass_spectrum.setParameterValue(
771 tims_frame.get()->getOneOverK0Transformation(spectrum_descr.scan_mobility_end));
772
773 first = false;
774 }
775
776
777 if(want_binary_data)
778 {
779 qDebug();
780 /*combiner.combine(combiner_result,
781 tims_frame.get()->cumulateScanToTrace(
782 scan_mobility_start, scan_mobility_end));*/
783 if(previous_frame.get() != nullptr)
784 {
785 if(previous_frame.get()->hasSameCalibrationData(*tims_frame.get()))
786 {
787 }
788 else
789 {
790 throw ExceptionNotFound(
791 QObject::tr("ERROR in %1 %2, different calibration data "
792 "between frame id %3 and frame id %4")
793 .arg(__FILE__)
794 .arg(__FUNCTION__)
795 .arg(previous_frame.get()->getId())
796 .arg(tims_frame.get()->getId()));
797 }
798 }
799 qDebug() << (std::size_t)QThread::currentThreadId();
800
801 tims_frame.get()->combineScansInTofIndexIntensityMap(
802 raw_spectrum, spectrum_descr.scan_mobility_start, spectrum_descr.scan_mobility_end);
803 qDebug() << (std::size_t)QThread::currentThreadId();
804 }
805 previous_frame = tims_frame;
806 }
807 qDebug() << " precursor_index=" << spectrum_descr.precursor_id
808 << " num_rows=" << spectrum_descr.tims_frame_list.size()
809 << (std::size_t)QThread::currentThreadId();
810 if(first == true)
811 {
812 throw ExceptionNotFound(
813 QObject::tr("ERROR in getQualifiedMassSpectrumByPrecursorId, precursor "
814 "id=%1 not found")
815 .arg(spectrum_descr.precursor_id));
816 }
817 if(want_binary_data)
818 {
819 qDebug() << " precursor_index=" << spectrum_descr.precursor_id;
820 // peak_pick.filter(trace);
821 Trace trace;
823 {
824 // raw_spectrum.removeArtefactualSpike();
825 raw_spectrum.builtInCentroid();
826 }
827
828 trace = tims_frame.get()->getTraceFromTofIndexIntensityMap(raw_spectrum);
829
830 if(trace.size() > 0)
831 {
832 qDebug() << " precursor_index=" << spectrum_descr.precursor_id << " " << trace.size()
833 << " " << (std::size_t)QThread::currentThreadId();
834
835 if(mcsp_ms2Filter != nullptr)
836 {
837 // FilterTriangle filter;
838 // filter.setTriangleSlope(50, 0.02);
839 // filter.filter(trace);
840 // trace.filter(FilterHighPass(10));
841 mcsp_ms2Filter->filter(trace);
842 }
843
844 // FilterScaleFactorY filter_scale((double)1 /
845 // (double)tims_frame_list.size());
846 // filter_scale.filter(trace);
847 qDebug() << " precursor_index=" << spectrum_descr.precursor_id;
848 mass_spectrum.setMassSpectrumSPtr(MassSpectrum(trace).makeMassSpectrumSPtr());
849 mass_spectrum.setEmptyMassSpectrum(false);
850 }
851 else
852 {
853 mass_spectrum.setMassSpectrumSPtr(nullptr);
854 mass_spectrum.setEmptyMassSpectrum(true);
855 }
856
857 qDebug();
858 }
859 qDebug();
860 }
861
862 catch(PappsoException &error)
863 {
864 throw PappsoException(QObject::tr("ERROR in %1 (ms2_index=%2 precursor_index=%3):\n%4")
865 .arg(__FUNCTION__)
866 .arg(spectrum_descr.ms2_index)
867 .arg(spectrum_descr.precursor_id)
868 .arg(error.qwhat()));
869 }
870 catch(std::exception &error)
871 {
872 qDebug() << QString("Failure %1 ").arg(error.what());
873 }
874 qDebug();
875}
876
877void
879{
880 m_builtinMs2Centroid = centroid;
881}
882
883bool
888
889void
892 unsigned int ms_level)
893{
894 qDebug() << " ms_level=" << ms_level;
895
896 QSqlDatabase qdb = mp_timsDataOrigin->openDatabaseConnection();
897 QSqlQuery qprecursor_list(qdb);
898 qprecursor_list.exec(
899 QString("SELECT PasefFrameMsMsInfo.Frame, " // 0
900 "PasefFrameMsMsInfo.ScanNumBegin, " // 1
901 "PasefFrameMsMsInfo.ScanNumEnd, " // 2
902 "PasefFrameMsMsInfo.IsolationMz, " // 3
903 "PasefFrameMsMsInfo.IsolationWidth, " // 4
904 "PasefFrameMsMsInfo.CollisionEnergy, " // 5
905 "PasefFrameMsMsInfo.Precursor, " // 6
906 "Precursors.Id, " // 7
907 "Precursors.LargestPeakMz, " // 8
908 "Precursors.AverageMz, " // 9
909 "Precursors.MonoisotopicMz, " // 10
910 "Precursors.Charge, " // 11
911 "Precursors.ScanNumber, " // 12
912 "Precursors.Intensity, " // 13
913 "Precursors.Parent " // 14
914 "FROM PasefFrameMsMsInfo "
915 "INNER JOIN Precursors ON "
916 "PasefFrameMsMsInfo.Precursor=Precursors.Id "
917 "ORDER BY PasefFrameMsMsInfo.Precursor, PasefFrameMsMsInfo.Frame ;"));
918 if(qprecursor_list.lastError().isValid())
919 {
920
921 throw PappsoException(
922 QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
923 "command %2:\n%3\n%4\n%5")
924 .arg(mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf"))
925 .arg(qprecursor_list.lastQuery())
926 .arg(qdb.lastError().databaseText())
927 .arg(qdb.lastError().driverText())
928 .arg(qdb.lastError().nativeErrorCode()));
929 }
930
931
932 qDebug() << "qprecursor_list.size()=" << qprecursor_list.size();
933 qDebug() << QObject::tr(
934 "TIMS sqlite database file %1, executing SQL "
935 "command %2:\n%3\n%4\n%5")
936 .arg(mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf"))
937 .arg(qprecursor_list.lastQuery())
938 .arg(qdb.lastError().databaseText())
939 .arg(qdb.lastError().driverText())
940 .arg(qdb.lastError().nativeErrorCode());
941
942 qDebug() << "qprecursor_list.isActive()=" << qprecursor_list.isActive();
943 qDebug() << "qprecursor_list.isSelect()=" << qprecursor_list.isSelect();
944 bool first = true;
945 SpectrumDescr spectrum_descr;
946
947 /*
948std::size_t i = 0;
949while(qprecursor_list.next())
950 {
951 qDebug() << "i=" << i;
952 i++;
953 }*/
954
955 qprecursor_list.last(); // strange bug : get the last sql record and get
956 // back, otherwise it will not retrieve all records.
957
958 qDebug() << "qprecursor_list.at()=" << qprecursor_list.at();
959 qprecursor_list.first();
960 std::vector<TimsDdaPrecursors::SpectrumDescr> spectrum_description_list;
961 spectrum_descr.precursor_id = 0;
962 // std::size_t i = 0;
963
964 do
965 {
966
967 if(spectrum_descr.precursor_id != (std::size_t)qprecursor_list.value(6).toLongLong())
968 {
969 // new precursor
970 if(spectrum_descr.precursor_id > 0)
971 {
972 spectrum_description_list.push_back(spectrum_descr);
973 }
974
975 spectrum_descr.tims_frame_list.clear();
976 first = true;
977 }
978 qDebug() << " qprecursor_list.value(6).toLongLong() ="
979 << qprecursor_list.value(6).toLongLong();
980 spectrum_descr.precursor_id = (std::size_t)qprecursor_list.value(6).toLongLong();
981 qDebug() << " spectrum_descr.precursor_id =" << spectrum_descr.precursor_id;
982 qDebug() << " cumul tims frame:" << qprecursor_list.value(0).toLongLong();
983 spectrum_descr.tims_frame_list.push_back(qprecursor_list.value(0).toLongLong());
984 qDebug() << " first =" << first;
985 if(first)
986 {
987 qDebug();
988 // mass_spectrum.setPrecursorCharge(q.value(11).toInt());
989 // mass_spectrum.setPrecursorMz(q.value(10).toDouble());
990 // mass_spectrum.setPrecursorIntensity(q.value(13).toDouble());
991 spectrum_descr.precursor_ion_data =
992 PrecursorIonData(qprecursor_list.value(10).toDouble(),
993 qprecursor_list.value(11).toInt(),
994 qprecursor_list.value(13).toDouble());
995
996 // spectrum_descr.precursor_id = q.value(6).toLongLong();
997 spectrum_descr.ms2_index = (spectrum_descr.precursor_id * 2) - 1;
998 spectrum_descr.ms1_index = (spectrum_descr.precursor_id * 2) - 2;
999
1000 spectrum_descr.scan_mobility_start = qprecursor_list.value(1).toLongLong();
1001 spectrum_descr.scan_mobility_end = qprecursor_list.value(2).toLongLong();
1002
1003 spectrum_descr.isolationMz = qprecursor_list.value(3).toDouble();
1004 spectrum_descr.isolationWidth = qprecursor_list.value(4).toDouble();
1005 spectrum_descr.collisionEnergy = qprecursor_list.value(5).toFloat();
1006 spectrum_descr.parent_frame = qprecursor_list.value(14).toLongLong();
1007
1008
1009 first = false;
1010 }
1011 // qDebug() << "qprecursor_list.executedQuery()="
1012 // << qprecursor_list.executedQuery();
1013 // qDebug() << "qprecursor_list.last()=" << qprecursor_list.last();
1014 // i++;
1015 }
1016 while(qprecursor_list.next());
1017
1018 // last One
1019
1020 // new precursor
1021 if(spectrum_descr.precursor_id > 0)
1022 {
1023 spectrum_description_list.push_back(spectrum_descr);
1024 }
1025
1026
1027 QString local_filepath =
1028 mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf");
1029
1030 if(m_isMonoThread)
1031 {
1032 for(SpectrumDescr &spectrum_descr : spectrum_description_list)
1033 {
1034
1035 std::vector<QualifiedMassSpectrum> mass_spectrum_list;
1037 msrun_id, mass_spectrum_list, handler, spectrum_descr, ms_level);
1038
1039 for(auto &qualified_spectrum : mass_spectrum_list)
1040 {
1041 handler.setQualifiedMassSpectrum(qualified_spectrum);
1042 }
1043
1044 if(handler.shouldStop())
1045 {
1046 qDebug() << "The operation was cancelled. Breaking the loop.";
1048 QObject::tr("reading TimsTOF job cancelled by the user :\n%1").arg(local_filepath));
1049 }
1050 }
1051 }
1052 else
1053 {
1054
1055
1056 TimsDdaPrecursors *itself = this;
1057 SpectrumCollectionHandlerInterface *pointer_handler = &handler;
1058
1059
1060 std::function<std::vector<QualifiedMassSpectrum>(const TimsDdaPrecursors::SpectrumDescr &)>
1061 map_function_generate_spectrum = [itself, msrun_id, pointer_handler, ms_level](
1062 const TimsDdaPrecursors::SpectrumDescr &spectrum_descr)
1063 -> std::vector<QualifiedMassSpectrum> {
1064 std::vector<QualifiedMassSpectrum> mass_spectrum_list;
1066 msrun_id, mass_spectrum_list, *pointer_handler, spectrum_descr, ms_level);
1067
1068
1069 return mass_spectrum_list;
1070 };
1071
1072 std::function<void(std::size_t,
1073 const std::vector<QualifiedMassSpectrum> &qualified_spectrum_list)>
1074 reduce_function_spectrum_list =
1075 [pointer_handler, local_filepath](
1076 std::size_t res, const std::vector<QualifiedMassSpectrum> &qualified_spectrum_list) {
1077 for(auto &qualified_spectrum : qualified_spectrum_list)
1078 {
1079 pointer_handler->setQualifiedMassSpectrum(qualified_spectrum);
1080 }
1081
1082 if(pointer_handler->shouldStop())
1083 {
1084 qDebug() << "The operation was cancelled. Breaking the loop.";
1086 QObject::tr("reading TimsTOF job on %1 cancelled by the user")
1087 .arg(local_filepath));
1088 }
1089 res++;
1090 };
1091
1092
1093 QFuture<std::size_t> res;
1094 res = QtConcurrent::mappedReduced<std::size_t>(spectrum_description_list.begin(),
1095 spectrum_description_list.end(),
1096 map_function_generate_spectrum,
1097 reduce_function_spectrum_list,
1098 QtConcurrent::OrderedReduce);
1099 res.waitForFinished();
1100 }
1101 handler.loadingEnded();
1102 mp_timsDataOrigin->getTimsBinDecPtr()->closeLinearRead();
1103}
1104
1105void
1107{
1108 m_isMonoThread = is_mono_thread;
1109}
1110
1111void
1113 const MsRunIdCstSPtr &msrun_id,
1114 std::vector<QualifiedMassSpectrum> &qualified_mass_spectrum_list,
1116 const TimsDdaPrecursors::SpectrumDescr &spectrum_descr,
1117 unsigned int ms_level)
1118{
1119
1120 qDebug() << " ms_level=" << ms_level;
1121 // The handler will receive the index of the mass spectrum in the
1122 // current run via the mass spectrum id member datum.
1123 if((ms_level == 0) || (ms_level == 1))
1124 {
1125 qualified_mass_spectrum_list.push_back(QualifiedMassSpectrum());
1127 qualified_mass_spectrum_list.back(),
1128 spectrum_descr,
1129 handler.needMsLevelPeakList(1));
1130 }
1131 if((ms_level == 0) || (ms_level == 2))
1132 {
1133 qualified_mass_spectrum_list.push_back(QualifiedMassSpectrum());
1135 qualified_mass_spectrum_list.back(),
1136 spectrum_descr,
1137 handler.needMsLevelPeakList(2));
1138 }
1139 qDebug();
1140}
1141
1142void
1145 unsigned int ms_level)
1146{
1147
1148
1149 // We'll need it to perform the looping in the spectrum list.
1150 std::size_t spectrum_list_size = mp_timsDataOrigin->getTotalScanCount();
1151
1152 // qDebug() << "The spectrum list has size:" << spectrum_list_size;
1153
1154 // Inform the handler of the spectrum list so that it can handle feedback to
1155 // the user.
1156 handler.spectrumListHasSize(spectrum_list_size);
1157
1158 QSqlDatabase qdb = mp_timsDataOrigin->openDatabaseConnection();
1159 QSqlQuery qprecursor_list(qdb);
1160 qprecursor_list.exec(
1161 QString("SELECT DISTINCT "
1162 "PasefFrameMsMsInfo.Frame, " // 0
1163 "PasefFrameMsMsInfo.ScanNumBegin, " // 1
1164 "PasefFrameMsMsInfo.ScanNumEnd, " // 2
1165 "PasefFrameMsMsInfo.IsolationMz, " // 3
1166 "PasefFrameMsMsInfo.IsolationWidth, " // 4
1167 "PasefFrameMsMsInfo.CollisionEnergy, " // 5
1168 "PasefFrameMsMsInfo.Precursor, " // 6
1169 "Precursors.Id, " // 7
1170 "Precursors.LargestPeakMz, " // 8
1171 "Precursors.AverageMz, " // 9
1172 "Precursors.MonoisotopicMz, " // 10
1173 "Precursors.Charge, " // 11
1174 "Precursors.ScanNumber, " // 12
1175 "Precursors.Intensity, " // 13
1176 "Precursors.Parent " // 14
1177 "FROM PasefFrameMsMsInfo "
1178 "INNER JOIN Precursors ON "
1179 "PasefFrameMsMsInfo.Precursor=Precursors.Id "
1180 "ORDER BY PasefFrameMsMsInfo.Frame, PasefFrameMsMsInfo.ScanNumBegin ;"));
1181 if(qprecursor_list.lastError().isValid())
1182 {
1183 throw PappsoException(
1184 QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
1185 "command %2:\n%3\n%4\n%5")
1186 .arg(mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf"))
1187 .arg(qprecursor_list.lastQuery())
1188 .arg(qdb.lastError().databaseText())
1189 .arg(qdb.lastError().driverText())
1190 .arg(qdb.lastError().nativeErrorCode()));
1191 }
1192
1193
1194 std::size_t i = 0; // iterate on each Spectrum
1195
1196 qprecursor_list.last(); // strange bug : get the last sql record and get
1197 // back, unless it will not retrieve all records.
1198
1199 qDebug() << "qprecursor_list.at()=" << qprecursor_list.at();
1200 qprecursor_list.first();
1201
1202 TimsFrameBaseCstSPtr tims_frame;
1203 SpectrumDescr spectrum_descr;
1204
1205 for(const FrameIdDescr &current_frame : mp_timsDataOrigin->getFrameIdDescrList())
1206 {
1207
1208 // If the user of this reader instance wants to stop reading the
1209 // spectra, then break this loop.
1210 if(handler.shouldStop())
1211 {
1212 qDebug() << "The operation was cancelled. Breaking the loop.";
1214 QObject::tr("reading TimsTOF job cancelled by the user :\n%1")
1215 .arg(mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf")));
1216 }
1217
1218 tims_frame = mp_timsDataOrigin->getTimsFrameBaseCstSPtrCached(current_frame.m_frameId);
1219 unsigned int tims_ms_level = tims_frame.get()->getMsLevel();
1220
1221 if((ms_level != 0) && (ms_level != tims_ms_level))
1222 { // bypass
1223 i += current_frame.m_scanCount;
1224 }
1225 else
1226 {
1227 bool want_binary_data = handler.needMsLevelPeakList(tims_ms_level);
1228 qDebug() << "want_binary_data=" << want_binary_data;
1229 if(want_binary_data)
1230 {
1231 qDebug() << "bindec";
1232 tims_frame = mp_timsDataOrigin->getTimsFrameCstSPtrCached(current_frame.m_frameId);
1233 }
1234
1235 bool possible_precursor = false;
1236 if(tims_ms_level == 2)
1237 {
1238 // seek the precursor record:
1239 while(qprecursor_list.value(0).toULongLong() < current_frame.m_frameId)
1240 {
1241 qprecursor_list.next();
1242
1243 if(qprecursor_list.value(0).toULongLong() == current_frame.m_frameId)
1244 {
1245 possible_precursor = true;
1246 }
1247 fillSpectrumDescriptionWithSqlRecord(spectrum_descr, qprecursor_list);
1248 }
1249 }
1250
1251 for(std::size_t scan_num = 0; scan_num < current_frame.m_scanCount; scan_num++)
1252 {
1253 bool has_a_precursor = false;
1254 if(possible_precursor)
1255 {
1256 if(spectrum_descr.scan_mobility_end < scan_num)
1257 {
1258 // seek the precursor record:
1259 while(qprecursor_list.value(0).toULongLong() < current_frame.m_frameId)
1260 {
1261 qprecursor_list.next();
1262
1263 if(qprecursor_list.value(0).toULongLong() != current_frame.m_frameId)
1264 {
1265 possible_precursor = false;
1266 }
1267 fillSpectrumDescriptionWithSqlRecord(spectrum_descr, qprecursor_list);
1268 }
1269 }
1270
1271 if(possible_precursor && (spectrum_descr.scan_mobility_start < scan_num))
1272 {
1273 // we are in
1274 has_a_precursor = true;
1275 }
1276 } // end to determine if we are in a precursor for this
1277 // spectrum
1278
1279 QualifiedMassSpectrum mass_spectrum;
1280
1281
1282 MassSpectrumId spectrum_id;
1283
1284 spectrum_id.setSpectrumIndex(i);
1285 spectrum_id.setMsRunId(msrun_id);
1286 spectrum_id.setNativeId(QString("frame_id=%1 scan_index=%2 global_scan_index=%3")
1287 .arg(current_frame.m_frameId)
1288 .arg(scan_num)
1289 .arg(i));
1290
1291 mass_spectrum.setMassSpectrumId(spectrum_id);
1292
1293 mass_spectrum.setMsLevel(tims_frame.get()->getMsLevel());
1294 mass_spectrum.setRtInSeconds(tims_frame.get()->getRtInSeconds());
1295
1296 mass_spectrum.setDtInMilliSeconds(
1297 tims_frame.get()->getDriftTimeInMilliseconds(scan_num));
1298 // 1/K0
1299 mass_spectrum.setParameterValue(
1301 tims_frame.get()->getOneOverK0Transformation(scan_num));
1302
1303 mass_spectrum.setEmptyMassSpectrum(true);
1304 if(want_binary_data)
1305 {
1306 try
1307 {
1308 mass_spectrum.setMassSpectrumSPtr(
1309 tims_frame.get()->getMassSpectrumSPtr(scan_num));
1310 }
1311 catch(PappsoException &error)
1312 {
1313 throw PappsoException(
1314 QObject::tr("ERROR in %1 (scan_num=%2 spectrum_index=%3):\n%4")
1315 .arg(__FUNCTION__)
1316 .arg(scan_num)
1317 .arg(spectrum_id.getSpectrumIndex())
1318 .arg(error.qwhat()));
1319 }
1320 if(mass_spectrum.size() > 0)
1321 {
1322 mass_spectrum.setEmptyMassSpectrum(false);
1323 }
1324 }
1325 else
1326 {
1327 // if(tims_frame.get()->getNbrPeaks(coordinate.second) > 0)
1328 //{
1329 mass_spectrum.setEmptyMassSpectrum(false);
1330 // }
1331 }
1332 if(has_a_precursor)
1333 {
1334 if(spectrum_descr.precursor_id > 0)
1335 {
1336
1337 mass_spectrum.appendPrecursorIonData(spectrum_descr.precursor_ion_data);
1338
1339 std::size_t prec_spectrum_index =
1340 mp_timsDataOrigin->getGlobalScanIndexByScanCoordinates(
1341 spectrum_descr.parent_frame, scan_num);
1342
1343 mass_spectrum.setPrecursorSpectrumIndex(prec_spectrum_index);
1344 mass_spectrum.setPrecursorNativeId(
1345 QString("frame_id=%1 scan_index=%2 global_scan_index=%3")
1346 .arg(spectrum_descr.parent_frame)
1347 .arg(scan_num)
1348 .arg(prec_spectrum_index));
1349
1351 spectrum_descr.isolationMz);
1352 mass_spectrum.setParameterValue(
1354 spectrum_descr.isolationWidth);
1355
1356 mass_spectrum.setParameterValue(
1358 spectrum_descr.collisionEnergy);
1359 mass_spectrum.setParameterValue(
1361 (quint64)spectrum_descr.precursor_id);
1362 }
1363 }
1364
1365 handler.setQualifiedMassSpectrum(mass_spectrum);
1366 i++;
1367 }
1368 }
1369 }
1370}
1371
1372
1373std::vector<std::size_t>
1374TimsDdaPrecursors::getPrecursorsByMzRtCharge(int charge, double mz_val, double rt_sec, double k0)
1375{
1376
1377 std::vector<std::size_t> precursor_ids;
1378 std::vector<std::vector<double>> ids;
1379
1380 QSqlDatabase qdb = mp_timsDataOrigin->openDatabaseConnection();
1381 QSqlQuery q(QString("SELECT Frames.Time, Precursors.MonoisotopicMz, Precursors.Charge, "
1382 "Precursors.Id, Frames.Id, PasefFrameMsMsInfo.ScanNumBegin, "
1383 "PasefFrameMsMsInfo.scanNumEnd "
1384 "FROM Frames "
1385 "INNER JOIN PasefFrameMsMsInfo ON Frames.Id = "
1386 "PasefFrameMsMsInfo.Frame "
1387 "INNER JOIN Precursors ON "
1388 "PasefFrameMsMsInfo.Precursor= Precursors.Id "
1389 "WHERE Precursors.Charge == %1 "
1390 "AND Precursors.MonoisotopicMz > %2 -0.01 "
1391 "AND Precursors.MonoisotopicMz < %2 +0.01 "
1392 "AND Frames.Time >= %3 -1 "
1393 "AND Frames.Time < %3 +1; ")
1394 .arg(charge)
1395 .arg(mz_val)
1396 .arg(rt_sec));
1397 q.exec();
1398 if(q.lastError().isValid())
1399 {
1400
1401 throw PappsoException(
1402 QObject::tr("ERROR in TIMS sqlite database file %1, database name %2, "
1403 "executing SQL "
1404 "command %3:\n%4\n%5\n%6")
1405 .arg(mp_timsDataOrigin->getTimsDataDirectory().absoluteFilePath("analysis.tdf"))
1406 .arg(qdb.databaseName())
1407 .arg(q.lastQuery())
1408 .arg(qdb.lastError().databaseText())
1409 .arg(qdb.lastError().driverText())
1410 .arg(qdb.lastError().nativeErrorCode()));
1411 }
1412 while(q.next())
1413 {
1414 // qInfo() << q.value(0).toDouble() << q.value(1).toDouble()
1415 // << q.value(2).toDouble() << q.value(3).toDouble();
1416
1417 std::vector<double> sql_values;
1418 sql_values.push_back(q.value(4).toDouble()); // frame id
1419 sql_values.push_back(q.value(3).toDouble()); // precursor id
1420 sql_values.push_back(q.value(5).toDouble()); // scan num begin
1421 sql_values.push_back(q.value(6).toDouble()); // scan num end
1422 sql_values.push_back(q.value(1).toDouble()); // mz_value
1423
1424 ids.push_back(sql_values);
1425
1426
1427 if(std::find(precursor_ids.begin(), precursor_ids.end(), q.value(3).toDouble()) ==
1428 precursor_ids.end())
1429 {
1430 precursor_ids.push_back(q.value(3).toDouble());
1431 }
1432 }
1433
1434 if(precursor_ids.size() > 1)
1435 {
1436 // std::vector<std::size_t> precursor_ids_ko =
1437 // getMatchPrecursorIdByKo(ids, values[3]);
1438 if(precursor_ids.size() > 1)
1439 {
1440 precursor_ids = getClosestPrecursorIdByMz(ids, k0);
1441 }
1442 return precursor_ids;
1443 }
1444 else
1445 {
1446 return precursor_ids;
1447 }
1448}
1449
1450std::vector<std::size_t>
1451TimsDdaPrecursors::getMatchPrecursorIdByKo(std::vector<std::vector<double>> ids, double ko_value)
1452{
1453 std::vector<std::size_t> precursor_id;
1454 for(std::vector<double> index : ids)
1455 {
1456 auto coordinate = mp_timsDataOrigin->getScanCoordinatesByGlobalScanIndex(index[0]);
1457
1458 TimsFrameBaseCstSPtr tims_frame;
1459 tims_frame = mp_timsDataOrigin->getTimsFrameBaseCstSPtrCached(coordinate.first);
1460
1461 double bko = tims_frame.get()->getOneOverK0Transformation(index[2]);
1462 double eko = tims_frame.get()->getOneOverK0Transformation(index[3]);
1463
1464 // qInfo() << "diff" << (bko + eko) / 2;
1465 double mean_ko = (bko + eko) / 2;
1466
1467 if(mean_ko > ko_value - 0.1 && mean_ko < ko_value + 0.1)
1468 {
1469 precursor_id.push_back(index[1]);
1470 }
1471 }
1472 return precursor_id;
1473}
1474
1475std::vector<std::size_t>
1476TimsDdaPrecursors::getClosestPrecursorIdByMz(std::vector<std::vector<double>> ids, double mz_value)
1477{
1478 std::vector<std::size_t> best_precursor;
1479 double best_value = 1;
1480 int count = 1;
1481 int best_val_position = 0;
1482
1483 for(std::vector<double> values : ids)
1484 {
1485 double new_val = abs(mz_value - values[4]);
1486 if(new_val < best_value)
1487 {
1488 best_value = new_val;
1489 best_val_position = count;
1490 }
1491 count++;
1492 }
1493 best_precursor.push_back(ids[best_val_position][1]);
1494 return best_precursor;
1495}
1496
1497
1498} // 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
@ IsolationMzWidth
m/z isolation window width (left + right)
@ CollisionEnergy
Bruker's timsTOF collision energy.
@ BrukerPrecursorIndex
Bruker's timsTOF precursor index.
std::shared_ptr< const FilterInterface > FilterInterfaceCstSPtr
const PrecisionBase * PrecisionPtr
Definition precision.h:122
std::shared_ptr< const TimsFrame > TimsFrameCstSPtr
Definition timsframe.h:44
std::vector< std::size_t > tims_frame_list
coordinates of the XIC to extract and the resulting XIC after extraction
std::size_t scanNumEnd
mobility index end
std::size_t scanNumBegin
mobility index begin
XicSPtr xicSptr
extracted xic
Definition xiccoord.h:135
double rtTarget
the targeted retention time to extract around intended in seconds, and related to one msrun....
Definition xiccoord.h:131
MzRange mzRange
the mass to extract
Definition xiccoord.h:125