libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
timsdata.cpp
Go to the documentation of this file.
1/**
2 * \file pappsomspp/vendors/tims/timsdata.cpp
3 * \date 27/08/2019
4 * \author Olivier Langella
5 * \brief main Tims data handler
6 */
7
8/*******************************************************************************
9 * Copyright (c) 2019 Olivier Langella <Olivier.Langella@u-psud.fr>.
10 *
11 * This file is part of the PAPPSOms++ library.
12 *
13 * PAPPSOms++ is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * PAPPSOms++ is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with PAPPSOms++. If not, see <http://www.gnu.org/licenses/>.
25 *
26 ******************************************************************************/
27
28#include "timsdata.h"
32#include <QDebug>
33#include <QSqlError>
34#include <QSqlQuery>
35#include <QSqlRecord>
36#include <QMutexLocker>
37#include <QThread>
38#include <set>
39#include <QtConcurrent>
40#include "timsddaprecursors.h"
41#include "timsdiaslices.h"
42
43namespace pappso
44{
45
46TimsData::TimsData(QDir timsDataDirectory) : m_timsDataDirectory(timsDataDirectory)
47{
48
49 qDebug() << "Start of construction of TimsData";
51 if(!m_timsDataDirectory.exists())
52 {
53 qDebug();
54 throw PappsoException(QObject::tr("ERROR TIMS data directory %1 not found")
55 .arg(m_timsDataDirectory.absolutePath()));
56 }
57
58 if(!QFileInfo(m_timsDataDirectory.absoluteFilePath("analysis.tdf")).exists())
59 {
60
61 throw PappsoException(QObject::tr("ERROR TIMS data directory, %1 sqlite file not found")
62 .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf")));
63 }
64
65 // Open the database
66 QSqlDatabase qdb = openDatabaseConnection();
67
68
69 QSqlQuery sql_query(qdb);
70 if(!sql_query.exec("select Key, Value from GlobalMetadata;"))
71 {
72
73 qDebug();
74 throw PappsoException(QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
75 "command %2:\n%3\n%4\n%5")
76 .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
77 .arg(sql_query.lastQuery())
78 .arg(sql_query.lastError().databaseText())
79 .arg(sql_query.lastError().driverText())
80 .arg(sql_query.lastError().nativeErrorCode()));
81 }
82
83 while(sql_query.next())
84 {
85 QSqlRecord record = sql_query.record();
87 std::pair<QString, QVariant>(record.value(0).toString(), record.value(1)));
88 }
89
90 int compression_type = getGlobalMetadataValue("TimsCompressionType").toInt();
91 qDebug() << " compression_type=" << compression_type;
93 QFileInfo(m_timsDataDirectory.absoluteFilePath("analysis.tdf_bin")), compression_type);
94
95 qDebug();
96
97 try
98 {
99
100 qDebug();
101 mpa_timsDdaPrecursors = new TimsDdaPrecursors(sql_query, this);
102 }
103 catch(pappso::ExceptionNotFound &not_found)
104 {
105
106 qDebug();
107 mpa_timsDdaPrecursors = nullptr;
108 }
109
110
111 qDebug();
112 try
113 {
114 qDebug();
115 mpa_timsDiaSlices = new TimsDiaSlices(sql_query, this);
116 }
117 catch(pappso::ExceptionNotFound &not_found)
118 {
119 qDebug();
120 mpa_timsDiaSlices = nullptr;
121 }
122
124
125 // get number of scans
126 if(!sql_query.exec("SELECT SUM(NumScans),COUNT(Id) FROM Frames"))
127 {
128 qDebug();
129 throw PappsoException(QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
130 "command %2:\n%3\n%4\n%5")
131 .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
132 .arg(sql_query.lastQuery())
133 .arg(qdb.lastError().databaseText())
134 .arg(qdb.lastError().driverText())
135 .arg(qdb.lastError().nativeErrorCode()));
136 }
137 if(sql_query.next())
138 {
139 qDebug();
140 m_totalScanCount = sql_query.value(0).toLongLong();
141 m_frameCount = sql_query.value(1).toLongLong();
142 }
143
144 if(!sql_query.exec("select * from MzCalibration;"))
145 {
146 qDebug();
147 throw PappsoException(QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
148 "command %2:\n%3\n%4\n%5")
149 .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
150 .arg(sql_query.lastQuery())
151 .arg(sql_query.lastError().databaseText())
152 .arg(sql_query.lastError().driverText())
153 .arg(sql_query.lastError().nativeErrorCode()));
154 }
155
156 while(sql_query.next())
157 {
158 QSqlRecord record = sql_query.record();
159 m_mapMzCalibrationRecord.insert(std::pair<int, QSqlRecord>(record.value(0).toInt(), record));
160 }
161
162 // m_mapTimsCalibrationRecord
163
164 if(!sql_query.exec("select * from TimsCalibration;"))
165 {
166 qDebug();
167 throw PappsoException(QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
168 "command %2:\n%3\n%4\n%5")
169 .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
170 .arg(sql_query.lastQuery())
171 .arg(sql_query.lastError().databaseText())
172 .arg(sql_query.lastError().driverText())
173 .arg(sql_query.lastError().nativeErrorCode()));
174 }
175 while(sql_query.next())
176 {
177 QSqlRecord record = sql_query.record();
179 std::pair<int, QSqlRecord>(record.value(0).toInt(), record));
180 }
181
182
183 // store frames
184 if(!sql_query.exec("select Frames.TimsId, Frames.AccumulationTime, " // 1
185 "Frames.MzCalibration, " // 2
186 "Frames.T1, Frames.T2, " // 4
187 "Frames.Time, Frames.MsMsType, Frames.TimsCalibration, " // 7
188 "Frames.Id " // 8
189 " FROM Frames;"))
190 {
191 qDebug();
192 throw PappsoException(QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
193 "command %2:\n%3\n%4\n%5")
194 .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
195 .arg(sql_query.lastQuery())
196 .arg(sql_query.lastError().databaseText())
197 .arg(sql_query.lastError().driverText())
198 .arg(sql_query.lastError().nativeErrorCode()));
199 }
200
202 while(sql_query.next())
203 {
204 QSqlRecord record = sql_query.record();
205 TimsFrameRecord &frame_record = m_mapFramesRecord[record.value(8).toULongLong()];
206
207 frame_record.frame_id = record.value(8).toULongLong();
208 frame_record.tims_offset = record.value(0).toULongLong();
209 frame_record.accumulation_time = record.value(1).toDouble();
210 frame_record.mz_calibration_id = record.value(2).toULongLong();
211 frame_record.frame_t1 = record.value(3).toDouble();
212 frame_record.frame_t2 = record.value(4).toDouble();
213 frame_record.frame_time = record.value(5).toDouble();
214 frame_record.msms_type = record.value(6).toInt();
215 frame_record.tims_calibration_id = record.value(7).toULongLong();
216 }
217
218 qDebug();
219}
220
221QSqlDatabase
223{
224 QString database_connection_name = QString("%1_%2")
225 .arg(m_timsDataDirectory.absolutePath())
226 .arg((quintptr)QThread::currentThread());
227 // Open the database
228 QSqlDatabase qdb = QSqlDatabase::database(database_connection_name);
229 if(!qdb.isValid())
230 {
231 qDebug() << database_connection_name;
232 qdb = QSqlDatabase::addDatabase("QSQLITE", database_connection_name);
233 qdb.setDatabaseName(m_timsDataDirectory.absoluteFilePath("analysis.tdf"));
234 }
235
236
237 if(!qdb.open())
238 {
239 qDebug();
240 throw PappsoException(QObject::tr("ERROR opening TIMS sqlite database file %1, database name "
241 "%2 :\n%3\n%4\n%5")
242 .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
243 .arg(database_connection_name)
244 .arg(qdb.lastError().databaseText())
245 .arg(qdb.lastError().driverText())
246 .arg(qdb.lastError().nativeErrorCode()));
247 }
248 return qdb;
249}
250
251TimsData::TimsData([[maybe_unused]] const TimsData &other)
252{
253 qDebug();
254}
255
257{
258 // m_qdb.close();
259 if(mpa_timsBinDec != nullptr)
260 {
261 delete mpa_timsBinDec;
262 }
263 if(mpa_mzCalibrationStore != nullptr)
264 {
266 }
267 if(mpa_timsDdaPrecursors != nullptr)
268 {
270 }
271 if(mpa_timsDiaSlices != nullptr)
272 {
273 delete mpa_timsDiaSlices;
274 }
275}
276
277void
279{
280 qDebug();
281 QSqlDatabase qdb = openDatabaseConnection();
282
283 QSqlQuery q(qdb);
284 q.prepare(
285 QString("SELECT Id, NumScans FROM "
286 "Frames ORDER BY Id"));
287 q.exec();
288 if(q.lastError().isValid())
289 {
290
291 throw PappsoException(QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
292 "command %2:\n%3\n%4\n%5")
293 .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
294 .arg(q.lastQuery())
295 .arg(qdb.lastError().databaseText())
296 .arg(qdb.lastError().driverText())
297 .arg(qdb.lastError().nativeErrorCode()));
298 }
299 TimsFrameSPtr tims_frame;
300 bool index_found = false;
301 std::size_t timsId;
302 /** @brief number of scans in mobility dimension (number of TOF scans)
303 */
304 std::size_t numberScans;
305 std::size_t cumulScans = 0;
306 while(q.next() && (!index_found))
307 {
308 timsId = q.value(0).toULongLong();
309 numberScans = q.value(1).toULongLong();
310
311 // qDebug() << timsId;
312
314 std::pair<std::size_t, std::size_t>((cumulScans / 1000), m_frameIdDescrList.size()));
315
316 m_frameIdDescrList.push_back({timsId, numberScans, cumulScans});
317 cumulScans += numberScans;
318 }
319 qDebug();
320}
321
322std::pair<std::size_t, std::size_t>
323TimsData::getScanCoordinateFromRawIndex(std::size_t raw_index) const
324{
325 return getScanCoordinatesByGlobalScanIndex(raw_index);
326}
327
328std::pair<std::size_t, std::size_t>
330{
331 std::size_t fast_access = raw_index / 1000;
332 qDebug() << " fast_access=" << fast_access;
333 auto map_it = m_thousandIndexToFrameIdDescrListIndex.find(fast_access);
335 {
336 throw ExceptionNotFound(
337 QObject::tr("ERROR raw index %1 not found (fast_access)").arg(raw_index));
338 }
339 std::size_t start_point_index = map_it->second;
340 while((start_point_index > 0) &&
341 (m_frameIdDescrList[start_point_index].m_globalScanIndex > raw_index))
342 {
343 start_point_index--;
344 }
345 for(std::size_t i = start_point_index; i < m_frameIdDescrList.size(); i++)
346 {
347
348 if(raw_index < (m_frameIdDescrList[i].m_globalScanIndex + m_frameIdDescrList[i].m_scanCount))
349 {
350 return std::pair<std::size_t, std::size_t>(
351 m_frameIdDescrList[i].m_frameId, raw_index - m_frameIdDescrList[i].m_globalScanIndex);
352 }
353 }
354
355 throw ExceptionNotFound(QObject::tr("ERROR raw index %1 not found").arg(raw_index));
356}
357
358std::size_t
359TimsData::getRawIndexFromCoordinate(std::size_t frame_id, std::size_t index) const
360{
361
362 return getGlobalScanIndexByScanCoordinates(frame_id, index);
363}
364
365std::size_t
366TimsData::getGlobalScanIndexByScanCoordinates(std::size_t frame_id, std::size_t index) const
367{
368
369 for(auto frameDescr : m_frameIdDescrList)
370 {
371 if(frameDescr.m_frameId == frame_id)
372 {
373 return frameDescr.m_globalScanIndex + index;
374 }
375 }
376
377 throw ExceptionNotFound(QObject::tr("ERROR raw index with frame_id=%1 scan_index=%2 not found")
378 .arg(frame_id)
379 .arg(index));
380}
381
382/** @brief get a mass spectrum given its spectrum index
383 * @param raw_index a number begining at 0, corresponding to a Tims Scan in
384 * the order they lies in the binary data file
385 */
388{
390}
391
394{
395
396 qDebug() << " raw_index=" << raw_index;
397 try
398 {
399 auto coordinate = getScanCoordinatesByGlobalScanIndex(raw_index);
400 return getMassSpectrumCstSPtr(coordinate.first, coordinate.second);
401 }
402 catch(PappsoException &error)
403 {
404 throw PappsoException(QObject::tr("Error TimsData::getMassSpectrumCstSPtrByRawIndex "
405 "raw_index=%1 :\n%2")
406 .arg(raw_index)
407 .arg(error.qwhat()));
408 }
409}
410
413{
414
415 qDebug() << " timsId=" << timsId;
416
417 const TimsFrameRecord &frame_record = m_mapFramesRecord[timsId];
418 if(timsId > m_totalScanCount)
419 {
420 throw ExceptionNotFound(QObject::tr("ERROR Frames database id %1 not found").arg(timsId));
421 }
422 TimsFrameBaseSPtr tims_frame;
423
424
425 tims_frame = std::make_shared<TimsFrameBase>(TimsFrameBase(timsId, frame_record.tims_offset));
426
427 auto it_map_record = m_mapMzCalibrationRecord.find(frame_record.mz_calibration_id);
428 if(it_map_record != m_mapMzCalibrationRecord.end())
429 {
430
431 double T1_frame = frame_record.frame_t1; // Frames.T1
432 double T2_frame = frame_record.frame_t2; // Frames.T2
433
434
435 tims_frame.get()->setMzCalibrationInterfaceSPtr(
436 mpa_mzCalibrationStore->getInstance(T1_frame, T2_frame, it_map_record->second));
437 }
438 else
439 {
440 throw ExceptionNotFound(QObject::tr("ERROR MzCalibration database id %1 not found")
441 .arg(frame_record.mz_calibration_id));
442 }
443
444
445 tims_frame.get()->setAcqDurationInMilliseconds(frame_record.accumulation_time);
446
447 tims_frame.get()->setRtInSeconds(frame_record.frame_time);
448 tims_frame.get()->setMsMsType(frame_record.msms_type);
449
450
451 auto it_map_record_tims_calibration =
453 if(it_map_record_tims_calibration != m_mapTimsCalibrationRecord.end())
454 {
455
456 tims_frame.get()->setTimsCalibration(
457 it_map_record_tims_calibration->second.value(1).toInt(),
458 it_map_record_tims_calibration->second.value(2).toDouble(),
459 it_map_record_tims_calibration->second.value(3).toDouble(),
460 it_map_record_tims_calibration->second.value(4).toDouble(),
461 it_map_record_tims_calibration->second.value(5).toDouble(),
462 it_map_record_tims_calibration->second.value(6).toDouble(),
463 it_map_record_tims_calibration->second.value(7).toDouble(),
464 it_map_record_tims_calibration->second.value(8).toDouble(),
465 it_map_record_tims_calibration->second.value(9).toDouble(),
466 it_map_record_tims_calibration->second.value(10).toDouble(),
467 it_map_record_tims_calibration->second.value(11).toDouble());
468 }
469 else
470 {
471 throw ExceptionNotFound(QObject::tr("ERROR TimsCalibration database id %1 not found")
472 .arg(frame_record.tims_calibration_id));
473 }
474
475 return tims_frame;
476}
477
478std::vector<std::size_t>
479TimsData::getTimsMS1FrameIdsInRtRange(double rt_begin, double rt_end) const
480{
481
482 qDebug() << " rt_begin=" << rt_begin << " rt_end=" << rt_end;
483 if(rt_begin < 0)
484 rt_begin = 0;
485 std::vector<std::size_t> tims_frameid_list;
486 QSqlDatabase qdb = openDatabaseConnection();
487 QSqlQuery q(qdb);
488 q.prepare(QString("SELECT Frames.Id FROM Frames WHERE "
489 "Frames.MsMsType=0 AND (Frames.Time>=%1) "
490 "AND (Frames.Time<=%2) ORDER BY "
491 "Frames.Time;")
492 .arg(rt_begin)
493 .arg(rt_end));
494 q.exec();
495 if(q.lastError().isValid())
496 {
497
498 throw PappsoException(QObject::tr("ERROR in TIMS sqlite database file %1, database name %2, "
499 "executing SQL "
500 "command %3:\n%4\n%5\n%6\nrtbegin=%7 rtend=%8")
501 .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
502 .arg(qdb.databaseName())
503 .arg(q.lastQuery())
504 .arg(qdb.lastError().databaseText())
505 .arg(qdb.lastError().driverText())
506 .arg(qdb.lastError().nativeErrorCode())
507 .arg(rt_begin)
508 .arg(rt_end));
509 }
510 while(q.next())
511 {
512
513 tims_frameid_list.push_back(q.value(0).toULongLong());
514 }
515 return tims_frameid_list;
516}
517
518std::vector<std::size_t>
519TimsData::getTimsMS2FrameIdsInRtRange(double rt_begin, double rt_end) const
520{
521
522 qDebug() << " rt_begin=" << rt_begin << " rt_end=" << rt_end;
523 if(rt_begin < 0)
524 rt_begin = 0;
525 std::vector<std::size_t> tims_frameid_list;
526 QSqlDatabase qdb = openDatabaseConnection();
527
528 QSqlQuery q(qdb);
529 q.prepare(QString("SELECT Frames.Id FROM Frames WHERE "
530 "Frames.MsMsType=8 AND "
531 "(Frames.Time>=%1) AND (Frames.Time<=%2) ORDER BY "
532 "Frames.Time;")
533 .arg(rt_begin)
534 .arg(rt_end));
535 q.exec();
536 if(q.lastError().isValid())
537 {
538
539 throw PappsoException(QObject::tr("ERROR in TIMS sqlite database file %1, database name %2, "
540 "executing SQL "
541 "command %3:\n%4\n%5\n%6")
542 .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
543 .arg(qdb.databaseName())
544 .arg(q.lastQuery())
545 .arg(qdb.lastError().databaseText())
546 .arg(qdb.lastError().driverText())
547 .arg(qdb.lastError().nativeErrorCode()));
548 }
549 while(q.next())
550 {
551
552 tims_frameid_list.push_back(q.value(0).toULongLong());
553 }
554 return tims_frameid_list;
555}
556
559{
560
561 qDebug() << " timsId=" << timsId << " m_mapFramesRecord.size()=" << m_mapFramesRecord.size();
562
563 /*
564 for(auto pair_i : m_mapFramesRecord)
565 {
566
567 qDebug() << " pair_i=" << pair_i.first;
568 }
569 */
570
571 const TimsFrameRecord &frame_record = m_mapFramesRecord[timsId];
572 if(timsId > m_totalScanCount)
573 {
574 throw ExceptionNotFound(QObject::tr("ERROR Frames database id %1 not found").arg(timsId));
575 }
576
577 TimsFrameSPtr tims_frame;
578
579
580 // QMutexLocker lock(&m_mutex);
582 // lock.unlock();
583
584 qDebug();
585 auto it_map_record = m_mapMzCalibrationRecord.find(frame_record.mz_calibration_id);
586 if(it_map_record != m_mapMzCalibrationRecord.end())
587 {
588
589 double T1_frame = frame_record.frame_t1; // Frames.T1
590 double T2_frame = frame_record.frame_t2; // Frames.T2
591
592
593 tims_frame.get()->setMzCalibrationInterfaceSPtr(
594 mpa_mzCalibrationStore->getInstance(T1_frame, T2_frame, it_map_record->second));
595 }
596 else
597 {
598 throw ExceptionNotFound(
599 QObject::tr("ERROR MzCalibration database id %1 not found for frame_id=%2")
600 .arg(frame_record.mz_calibration_id)
601 .arg(timsId));
602 }
603
604
605 tims_frame.get()->setAcqDurationInMilliseconds(frame_record.accumulation_time);
606
607 tims_frame.get()->setRtInSeconds(frame_record.frame_time);
608 tims_frame.get()->setMsMsType(frame_record.msms_type);
609
610 qDebug();
611 auto it_map_record_tims_calibration =
613 if(it_map_record_tims_calibration != m_mapTimsCalibrationRecord.end())
614 {
615
616 tims_frame.get()->setTimsCalibration(
617 it_map_record_tims_calibration->second.value(1).toInt(),
618 it_map_record_tims_calibration->second.value(2).toDouble(),
619 it_map_record_tims_calibration->second.value(3).toDouble(),
620 it_map_record_tims_calibration->second.value(4).toDouble(),
621 it_map_record_tims_calibration->second.value(5).toDouble(),
622 it_map_record_tims_calibration->second.value(6).toDouble(),
623 it_map_record_tims_calibration->second.value(7).toDouble(),
624 it_map_record_tims_calibration->second.value(8).toDouble(),
625 it_map_record_tims_calibration->second.value(9).toDouble(),
626 it_map_record_tims_calibration->second.value(10).toDouble(),
627 it_map_record_tims_calibration->second.value(11).toDouble());
628 }
629 else
630 {
631 throw ExceptionNotFound(QObject::tr("ERROR TimsCalibration database id %1 not found")
632 .arg(frame_record.tims_calibration_id));
633 }
634 qDebug();
635 return tims_frame;
636}
637
638
640TimsData::getMassSpectrumCstSPtr(std::size_t timsId, std::size_t scanNum)
641{
642 qDebug() << " timsId=" << timsId << " scanNum=" << scanNum;
644
645 return frame->getMassSpectrumCstSPtr(scanNum);
646}
647
648
649std::size_t
651{
652 return m_frameCount;
653}
654
655
656std::size_t
658{
659 return m_frameCount;
660}
661
662
663std::size_t
668
669
670std::size_t
672{
673 return m_totalScanCount;
674}
675
676unsigned int
678{
679 return getMsLevelByGlobalScanIndex(index);
680}
681
682
683unsigned int
685{
686 auto coordinate = getScanCoordinatesByGlobalScanIndex(index);
687 auto tims_frame = getTimsFrameCstSPtrCached(coordinate.first);
688 return tims_frame.get()->getMsLevel();
689}
690
691
692void
694 QualifiedMassSpectrum &mass_spectrum,
695 std::size_t global_scan_index,
696 bool want_binary_data)
697{
698
700 msrun_id, mass_spectrum, global_scan_index, want_binary_data);
701}
702
703void
705 QualifiedMassSpectrum &mass_spectrum,
706 std::size_t global_scan_index,
707 bool want_binary_data)
708{
709
710
711 try
712 {
713 auto coordinate = getScanCoordinatesByGlobalScanIndex(global_scan_index);
714 TimsFrameBaseCstSPtr tims_frame;
715 if(want_binary_data)
716 {
717 tims_frame = getTimsFrameCstSPtrCached(coordinate.first);
718 }
719 else
720 {
721 tims_frame = getTimsFrameBaseCstSPtrCached(coordinate.first);
722 }
723 MassSpectrumId spectrum_id;
724
725 spectrum_id.setSpectrumIndex(global_scan_index);
726 spectrum_id.setMsRunId(msrun_id);
727 spectrum_id.setNativeId(QString("frame_id=%1 scan_index=%2 global_scan_index=%3")
728 .arg(coordinate.first)
729 .arg(coordinate.second)
730 .arg(global_scan_index));
731
732 mass_spectrum.setMassSpectrumId(spectrum_id);
733
734 mass_spectrum.setMsLevel(tims_frame.get()->getMsLevel());
735 mass_spectrum.setRtInSeconds(tims_frame.get()->getRtInSeconds());
736
737 mass_spectrum.setDtInMilliSeconds(
738 tims_frame.get()->getDriftTimeInMilliseconds(coordinate.second));
739 // 1/K0
740 mass_spectrum.setParameterValue(
742 tims_frame.get()->getOneOverK0Transformation(coordinate.second));
743
744 mass_spectrum.setEmptyMassSpectrum(true);
745 if(want_binary_data)
746 {
747 mass_spectrum.setMassSpectrumSPtr(
748 tims_frame.get()->getMassSpectrumSPtr(coordinate.second));
749 if(mass_spectrum.size() > 0)
750 {
751 mass_spectrum.setEmptyMassSpectrum(false);
752 }
753 }
754 else
755 {
756 // if(tims_frame.get()->getNbrPeaks(coordinate.second) > 0)
757 //{
758 mass_spectrum.setEmptyMassSpectrum(false);
759 // }
760 }
761 if(tims_frame.get()->getMsLevel() > 1)
762 {
763
764 if(mpa_timsDdaPrecursors != nullptr)
765 {
766 auto spectrum_descr =
768 if(spectrum_descr.precursor_id > 0)
769 {
770
771 mass_spectrum.appendPrecursorIonData(spectrum_descr.precursor_ion_data);
772
773
774 MassSpectrumId spectrum_id;
775 std::size_t prec_spectrum_index = getGlobalScanIndexByScanCoordinates(
776 spectrum_descr.parent_frame, coordinate.second);
777
778 mass_spectrum.setPrecursorSpectrumIndex(prec_spectrum_index);
779 mass_spectrum.setPrecursorNativeId(
780 QString("frame_id=%1 scan_index=%2 global_scan_index=%3")
781 .arg(spectrum_descr.parent_frame)
782 .arg(coordinate.second)
783 .arg(prec_spectrum_index));
784
786 spectrum_descr.isolationMz);
788 spectrum_descr.isolationWidth);
789
791 spectrum_descr.collisionEnergy);
792 mass_spectrum.setParameterValue(
794 (quint64)spectrum_descr.precursor_id);
795 }
796 }
797 }
798 }
799 catch(PappsoException &error)
800 {
801 throw PappsoException(QObject::tr("Error TimsData::getQualifiedMassSpectrumByRawIndex "
802 "spectrum_index=%1 :\n%2")
803 .arg(global_scan_index)
804 .arg(error.qwhat()));
805 }
806}
807
808Trace
810{
811 // In the Frames table, each frame has a record describing the
812 // SummedIntensities for all the mobility spectra.
813
814
815 MapTrace rt_tic_map_trace;
816
817 using Pair = std::pair<double, double>;
818 using Map = std::map<double, double>;
819 using Iterator = Map::iterator;
820
821
822 QSqlDatabase qdb = openDatabaseConnection();
823 QSqlQuery q(qdb);
824
825 q.prepare(
826 QString("SELECT Time, SummedIntensities "
827 "FROM Frames WHERE MsMsType = 0 "
828 "ORDER BY Time;"));
829 q.exec();
830
831 if(q.lastError().isValid())
832 {
833
834 throw PappsoException(QObject::tr("ERROR in TIMS sqlite database file %1, database name %2, "
835 "executing SQL "
836 "command %3:\n%4\n%5\n%6")
837 .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
838 .arg(qdb.databaseName())
839 .arg(q.lastQuery())
840 .arg(qdb.lastError().databaseText())
841 .arg(qdb.lastError().driverText())
842 .arg(qdb.lastError().nativeErrorCode()));
843 }
844
845 while(q.next())
846 {
847
848 bool ok = false;
849
850 int cumulated_results = 2;
851
852 double rt = q.value(0).toDouble(&ok);
853 cumulated_results -= ok;
854
855 double sumY = q.value(1).toDouble(&ok);
856 cumulated_results -= ok;
857
858 if(cumulated_results)
859 {
860 throw PappsoException(
861 QObject::tr("ERROR in TIMS sqlite database file: could not read either the "
862 "retention time or the summed intensities (%1, database name "
863 "%2, "
864 "executing SQL "
865 "command %3:\n%4\n%5\n%6")
866 .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
867 .arg(qdb.databaseName())
868 .arg(q.lastQuery())
869 .arg(qdb.lastError().databaseText())
870 .arg(qdb.lastError().driverText())
871 .arg(qdb.lastError().nativeErrorCode()));
872 }
873
874 // Try to insert value sumY at key rt.
875 std::pair<Iterator, bool> res = rt_tic_map_trace.insert(Pair(rt, sumY));
876
877 if(!res.second)
878 {
879 // One other same rt value was seen already (like in ion mobility
880 // mass spectrometry, for example). Only increment the y value.
881
882 res.first->second += sumY;
883 }
884 }
885
886 // qDebug().noquote() << "The TIC chromatogram:\n"
887 //<< rt_tic_map_trace.toTrace().toString();
888
889 return rt_tic_map_trace.toTrace();
890}
891
892
895{
896 QMutexLocker locker(&m_mutex);
897 for(auto &tims_frame : m_timsFrameBaseCache)
898 {
899 if(tims_frame.get()->getId() == timsId)
900 {
901 m_timsFrameBaseCache.push_back(tims_frame);
903 m_timsFrameBaseCache.pop_front();
904 return tims_frame;
905 }
906 }
907
910 m_timsFrameBaseCache.pop_front();
911 return m_timsFrameBaseCache.back();
912}
913
916{
917 qDebug();
918 QMutexLocker locker(&m_mutex);
919 for(auto &tims_frame : m_timsFrameCache)
920 {
921 if(tims_frame.get()->getId() == timsId)
922 {
923 m_timsFrameCache.push_back(tims_frame);
924 if(m_timsFrameCache.size() > m_cacheSize)
925 m_timsFrameCache.pop_front();
926 return tims_frame;
927 }
928 }
929 TimsFrameCstSPtr frame_sptr = getTimsFrameCstSPtr(timsId);
930
931 // locker.relock();
932 qDebug();
933
934 m_timsFrameCache.push_back(frame_sptr);
935 if(m_timsFrameCache.size() > m_cacheSize)
936 m_timsFrameCache.pop_front();
937 qDebug();
938 return m_timsFrameCache.back();
939
940
941 /*
942// the frame is not in the cache
943if(std::find(m_someoneIsLoadingFrameId.begin(),
944 m_someoneIsLoadingFrameId.end(),
945 timsId) == m_someoneIsLoadingFrameId.end())
946 {
947 // not found, we are alone on this frame
948 m_someoneIsLoadingFrameId.push_back(timsId);
949 qDebug();
950 //locker.unlock();
951 TimsFrameCstSPtr frame_sptr = getTimsFrameCstSPtr(timsId);
952
953 // locker.relock();
954 qDebug();
955 m_someoneIsLoadingFrameId.erase(
956 std::find(m_someoneIsLoadingFrameId.begin(),
957 m_someoneIsLoadingFrameId.end(),
958 timsId));
959
960 m_timsFrameCache.push_back(frame_sptr);
961 if(m_timsFrameCache.size() > m_cacheSize)
962 m_timsFrameCache.pop_front();
963 qDebug();
964 return m_timsFrameCache.back();
965 }
966else
967 {
968 // this frame is loading by someone else, we have to wait
969 qDebug();
970 // locker.unlock();
971 // std::size_t another_frame_id = timsId;
972 while(true)
973 {
974 QThread::usleep(1);
975 // locker.relock();
976
977 for(auto &tims_frame : m_timsFrameCache)
978 {
979 if(tims_frame.get()->getId() == timsId)
980 {
981 m_timsFrameCache.push_back(tims_frame);
982 return tims_frame;
983 }
984 }
985 // locker.unlock();
986}
987} // namespace pappso
988*/
989}
990
991
992std::vector<double>
997
998std::vector<double>
1000{
1001
1002 std::vector<double> timeline;
1003 timeline.reserve(m_mapFramesRecord.size());
1004 for(const TimsFrameRecord &frame_record : m_mapFramesRecord)
1005 {
1006 if(frame_record.mz_calibration_id != 0)
1007 {
1008 timeline.push_back(frame_record.frame_time);
1009 }
1010 }
1011 return timeline;
1012}
1013
1016{
1017 return getScanByGlobalScanIndex(index);
1018}
1019
1022{
1023 qDebug() << " spectrum_index=" << index;
1024 auto coordinate = getScanCoordinatesByGlobalScanIndex(index);
1025 TimsFrameBaseCstSPtr tims_frame;
1026 tims_frame = getTimsFrameCstSPtrCached(coordinate.first);
1027
1029 raw_spectrum.clear();
1030 tims_frame.get()->combineScansInTofIndexIntensityMap(
1031 raw_spectrum, coordinate.second, coordinate.second);
1032 return raw_spectrum;
1033}
1034
1035const std::vector<FrameIdDescr> &
1037{
1038 return m_frameIdDescrList;
1039}
1040
1041const std::vector<TimsFrameRecord> &
1046
1047const QDir &
1052
1055{
1056 if(mpa_timsDdaPrecursors == nullptr)
1057 {
1058 throw pappso::PappsoException("TimsData does not contain DDA precursors");
1059 }
1060 return mpa_timsDdaPrecursors;
1061}
1062
1063TimsBinDec *
1065{
1066 return mpa_timsBinDec;
1067}
1068
1069bool
1071{
1072 if(mpa_timsDdaPrecursors == nullptr)
1073 return false;
1074 return true;
1075}
1076
1077bool
1079{
1080 if(mpa_timsDiaSlices == nullptr)
1081 return false;
1082 return true;
1083}
1084
1087{
1088 qDebug();
1089 if(mpa_timsDiaSlices == nullptr)
1090 {
1091 throw pappso::PappsoException("TimsData does not contain DIA slices");
1092 }
1093 return mpa_timsDiaSlices;
1094}
1095
1096} // namespace pappso
1097
1098const QVariant &
1100{
1101 auto it = m_mapGlobalMetadaTable.find(key);
1102 if(it == m_mapGlobalMetadaTable.end())
1103 {
1104 throw pappso::PappsoException(QString("TimsData GlobalMetadata key %1 not found").arg(key));
1105 }
1106 return it->second;
1107}
Trace toTrace() const
Definition maptrace.cpp:219
void setNativeId(const QString &native_id)
void setMsRunId(MsRunIdCstSPtr other)
void setSpectrumIndex(std::size_t index)
MzCalibrationInterfaceSPtr getInstance(double T1_frame, double T2_frame, const QSqlRecord &mzcalibration_record)
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)
TimsFrameSPtr getTimsFrameSPtrByOffset(std::size_t frameId, const std::vector< pappso::TimsFrameRecord > &frame_record_list)
replacement for std::map
static TimsDataFastMap & getTimsDataFastMapInstance()
std::size_t getGlobalScanIndexByScanCoordinates(std::size_t frame_id, std::size_t index) const
Definition timsdata.cpp:366
QSqlDatabase openDatabaseConnection() const
Definition timsdata.cpp:222
std::size_t getTotalScanCount() const
Definition timsdata.cpp:671
TimsDiaSlices * getTimsDiaSlicesPtr() const
TimsFrameCstSPtr getTimsFrameCstSPtr(std::size_t timsId)
get a Tims frame with his database ID
Definition timsdata.cpp:558
TimsDdaPrecursors * mpa_timsDdaPrecursors
Definition timsdata.h:242
const std::vector< TimsFrameRecord > & getTimsFrameRecordList() const
std::vector< FrameIdDescr > m_frameIdDescrList
store every frame id and corresponding sizes
Definition timsdata.h:261
TimsFrameCstSPtr getTimsFrameCstSPtrCached(std::size_t timsId)
get a Tims frame with his database ID but look in the cache first
Definition timsdata.cpp:915
pappso::MassSpectrumCstSPtr getMassSpectrumCstSPtrByRawIndex(std::size_t raw_index)
get a mass spectrum given its spectrum index
Definition timsdata.cpp:387
TimsDataFastMap & getScanByGlobalScanIndex(std::size_t index)
friend TimsDdaPrecursors
Definition timsdata.h:69
virtual ~TimsData()
Definition timsdata.cpp:256
const std::vector< FrameIdDescr > & getFrameIdDescrList() const
std::size_t getTotalNumberOfFrames() const
Get total number of frames.
Definition timsdata.cpp:650
std::vector< std::size_t > getTimsMS1FrameIdsInRtRange(double rt_begin, double rt_end) const
Definition timsdata.cpp:479
pappso::MassSpectrumCstSPtr getMassSpectrumCstSPtr(std::size_t timsId, std::size_t scanNum)
get a mass spectrum given the tims frame database id and scan number within tims frame
Definition timsdata.cpp:640
TimsBinDec * getTimsBinDecPtr() const
TimsData(QDir timsDataDirectory)
build using the tims data directory
Definition timsdata.cpp:46
void getQualifiedMassSpectrumByRawIndex(const MsRunIdCstSPtr &msrun_id, QualifiedMassSpectrum &mass_spectrum, std::size_t global_scan_index, bool want_binary_data)
Definition timsdata.cpp:693
std::vector< std::size_t > getTimsMS2FrameIdsInRtRange(double rt_begin, double rt_end) const
Definition timsdata.cpp:519
Trace getTicChromatogram() const
Definition timsdata.cpp:809
TimsFrameBaseCstSPtr getTimsFrameBaseCstSPtrCached(std::size_t timsId)
Definition timsdata.cpp:894
void getQualifiedMassSpectrumByGlobalScanIndex(const MsRunIdCstSPtr &msrun_id, QualifiedMassSpectrum &mass_spectrum, std::size_t global_scan_index, bool want_binary_data)
Definition timsdata.cpp:704
std::deque< TimsFrameCstSPtr > m_timsFrameCache
Definition timsdata.h:248
std::size_t m_cacheSize
Definition timsdata.h:247
std::pair< std::size_t, std::size_t > getScanCoordinateFromRawIndex(std::size_t spectrum_index) const
Definition timsdata.cpp:323
std::vector< TimsFrameRecord > m_mapFramesRecord
Definition timsdata.h:254
unsigned int getMsLevelBySpectrumIndex(std::size_t index)
Definition timsdata.cpp:677
std::size_t m_totalScanCount
Definition timsdata.h:245
std::map< int, QSqlRecord > m_mapMzCalibrationRecord
Definition timsdata.h:252
std::map< int, QSqlRecord > m_mapTimsCalibrationRecord
Definition timsdata.h:253
std::map< QString, QVariant > m_mapGlobalMetadaTable
Definition timsdata.h:275
void fillFrameIdDescrList()
private function to fill m_frameIdDescrList
Definition timsdata.cpp:278
TimsFrameBaseCstSPtr getTimsFrameBaseCstSPtr(std::size_t timsId)
get a Tims frame base (no binary data file access) with his database ID
Definition timsdata.cpp:412
unsigned int getMsLevelByGlobalScanIndex(std::size_t index)
Definition timsdata.cpp:684
friend TimsDiaSlices
Definition timsdata.h:70
QDir m_timsDataDirectory
Definition timsdata.h:239
MzCalibrationStore * mpa_mzCalibrationStore
Definition timsdata.h:256
pappso::MassSpectrumCstSPtr getMassSpectrumCstSPtrByGlobalScanIndex(std::size_t index)
Definition timsdata.cpp:393
virtual std::vector< double > getRetentionTimeLineInSeconds() const
Definition timsdata.cpp:999
virtual std::vector< double > getRetentionTimeLine() const
retention timeline get retention times along the MSrun in seconds
Definition timsdata.cpp:993
const QDir & getTimsDataDirectory() const
TimsDataFastMap & getRawMsBySpectrumIndex(std::size_t index)
get raw signal for a spectrum index only to use to see the raw signal
std::size_t getFrameCount() const
Definition timsdata.cpp:657
bool isDiaRun() const
tells if this MS run is a DIA run
std::deque< TimsFrameBaseCstSPtr > m_timsFrameBaseCache
Definition timsdata.h:249
std::map< std::size_t, std::size_t > m_thousandIndexToFrameIdDescrListIndex
index to find quickly a frameId in the description list with the raw index of spectrum modulo 1000 @k...
Definition timsdata.h:268
TimsBinDec * mpa_timsBinDec
Definition timsdata.h:240
bool isDdaRun() const
tells if this MS run is a DDA run
std::size_t getTotalNumberOfScans() const
get the total number of scans
Definition timsdata.cpp:664
TimsDdaPrecursors * getTimsDdaPrecursorsPtr() const
TimsDiaSlices * mpa_timsDiaSlices
Definition timsdata.h:243
std::size_t m_frameCount
Definition timsdata.h:246
std::size_t getRawIndexFromCoordinate(std::size_t frame_id, std::size_t scan_num) const
Definition timsdata.cpp:359
std::pair< std::size_t, std::size_t > getScanCoordinatesByGlobalScanIndex(std::size_t index) const
Definition timsdata.cpp:329
const QVariant & getGlobalMetadataValue(const QString &key) const
SpectrumDescr getSpectrumDescrWithScanCoordinates(const std::pair< std::size_t, std::size_t > &scan_coordinates)
A simple container of DataPoint instances.
Definition trace.h:148
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition aa.cpp:39
std::shared_ptr< const TimsFrameBase > TimsFrameBaseCstSPtr
std::shared_ptr< TimsFrame > TimsFrameSPtr
Definition timsframe.h:43
std::shared_ptr< TimsFrameBase > TimsFrameBaseSPtr
std::shared_ptr< const MsRunId > MsRunIdCstSPtr
Definition msrunid.h:46
std::shared_ptr< const MassSpectrum > MassSpectrumCstSPtr
@ IsolationMzWidth
m/z isolation window width (left + right)
@ CollisionEnergy
Bruker's timsTOF collision energy.
@ BrukerPrecursorIndex
Bruker's timsTOF precursor index.
std::shared_ptr< const TimsFrame > TimsFrameCstSPtr
Definition timsframe.h:44