libpappsomspp
Library for mass spectrometry
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"
29 #include "../../exception/exceptionnotfound.h"
30 #include "../../exception/exceptioninterrupted.h"
31 #include "../../processing/combiners/tracepluscombiner.h"
32 #include "../../processing/filters/filtertriangle.h"
33 #include "../../processing/filters/filtersuitestring.h"
34 #include <QDebug>
35 #include <solvers.h>
36 #include <QSqlError>
37 #include <QSqlQuery>
38 #include <QSqlRecord>
39 #include <QMutexLocker>
40 #include <QThread>
41 #include <set>
42 #include <QtConcurrent>
43 
44 namespace pappso
45 {
46 
47 TimsData::TimsData(QDir timsDataDirectory)
48  : m_timsDataDirectory(timsDataDirectory)
49 {
50 
51  qDebug() << "Start of construction of TimsData";
53  if(!m_timsDataDirectory.exists())
54  {
55  throw PappsoException(
56  QObject::tr("ERROR TIMS data directory %1 not found")
57  .arg(m_timsDataDirectory.absolutePath()));
58  }
59 
60  if(!QFileInfo(m_timsDataDirectory.absoluteFilePath("analysis.tdf")).exists())
61  {
62 
63  throw PappsoException(
64  QObject::tr("ERROR TIMS data directory, %1 sqlite file not found")
65  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf")));
66  }
67 
68  // Open the database
69  QSqlDatabase qdb = openDatabaseConnection();
70 
71 
72  QSqlQuery q(qdb);
73  if(!q.exec("select Key, Value from GlobalMetadata where "
74  "Key='TimsCompressionType';"))
75  {
76 
77  qDebug();
78  throw PappsoException(
79  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
80  "command %2:\n%3\n%4\n%5")
81  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
82  .arg(q.lastQuery())
83  .arg(q.lastError().databaseText())
84  .arg(q.lastError().driverText())
85  .arg(q.lastError().nativeErrorCode()));
86  }
87 
88 
89  int compression_type = 0;
90  if(q.next())
91  {
92  compression_type = q.value(1).toInt();
93  }
94  qDebug() << " compression_type=" << compression_type;
96  QFileInfo(m_timsDataDirectory.absoluteFilePath("analysis.tdf_bin")),
97  compression_type);
98 
99  qDebug();
100 
101  // get number of precursors
103  if(!q.exec("SELECT COUNT( DISTINCT Id) FROM Precursors;"))
104  {
105  m_hasPrecursorTable = false;
106  }
107  else
108  {
109  m_hasPrecursorTable = true;
110  if(q.next())
111  {
112  m_totalNumberOfPrecursors = q.value(0).toLongLong();
113  }
114  }
115 
116 
118 
119  // get number of scans
120  if(!q.exec("SELECT SUM(NumScans),COUNT(Id) FROM Frames"))
121  {
122  qDebug();
123  throw PappsoException(
124  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
125  "command %2:\n%3\n%4\n%5")
126  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
127  .arg(q.lastQuery())
128  .arg(qdb.lastError().databaseText())
129  .arg(qdb.lastError().driverText())
130  .arg(qdb.lastError().nativeErrorCode()));
131  }
132  if(q.next())
133  {
134  m_totalNumberOfScans = q.value(0).toLongLong();
135  m_totalNumberOfFrames = q.value(1).toLongLong();
136  }
137 
138  if(!q.exec("select * from MzCalibration;"))
139  {
140  qDebug();
141  throw PappsoException(
142  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
143  "command %2:\n%3\n%4\n%5")
144  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
145  .arg(q.lastQuery())
146  .arg(q.lastError().databaseText())
147  .arg(q.lastError().driverText())
148  .arg(q.lastError().nativeErrorCode()));
149  }
150 
151  while(q.next())
152  {
153  QSqlRecord record = q.record();
155  std::pair<int, QSqlRecord>(record.value(0).toInt(), record));
156  }
157 
158  // m_mapTimsCalibrationRecord
159 
160  if(!q.exec("select * from TimsCalibration;"))
161  {
162  qDebug();
163  throw PappsoException(
164  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
165  "command %2:\n%3\n%4\n%5")
166  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
167  .arg(q.lastQuery())
168  .arg(q.lastError().databaseText())
169  .arg(q.lastError().driverText())
170  .arg(q.lastError().nativeErrorCode()));
171  }
172  while(q.next())
173  {
174  QSqlRecord record = q.record();
176  std::pair<int, QSqlRecord>(record.value(0).toInt(), record));
177  }
178 
179 
180  // store frames
181  if(!q.exec("select Frames.TimsId, Frames.AccumulationTime, " // 1
182  "Frames.MzCalibration, " // 2
183  "Frames.T1, Frames.T2, " // 4
184  "Frames.Time, Frames.MsMsType, Frames.TimsCalibration, " // 7
185  "Frames.Id " // 8
186  " FROM Frames;"))
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(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
193  .arg(q.lastQuery())
194  .arg(q.lastError().databaseText())
195  .arg(q.lastError().driverText())
196  .arg(q.lastError().nativeErrorCode()));
197  }
198 
200  while(q.next())
201  {
202  QSqlRecord record = q.record();
203  TimsFrameRecord &frame_record =
204  m_mapFramesRecord[record.value(8).toULongLong()];
205 
206  frame_record.tims_offset = record.value(0).toULongLong();
207  frame_record.accumulation_time = record.value(1).toDouble();
208  frame_record.mz_calibration_id = record.value(2).toULongLong();
209  frame_record.frame_t1 = record.value(3).toDouble();
210  frame_record.frame_t2 = record.value(4).toDouble();
211  frame_record.frame_time = record.value(5).toDouble();
212  frame_record.msms_type = record.value(6).toInt();
213  frame_record.tims_calibration_id = record.value(7).toULongLong();
214  }
215 
216  mcsp_ms2Filter = std::make_shared<pappso::FilterSuiteString>(
217  "chargeDeconvolution|0.02dalton mzExclusion|0.01dalton");
218 
219 
220  std::shared_ptr<FilterTriangle> ms1filter =
221  std::make_shared<FilterTriangle>();
222  ms1filter.get()->setTriangleSlope(50, 0.01);
223  mcsp_ms1Filter = ms1filter;
224  qDebug();
225 }
226 
227 void
228 TimsData::setMonoThread(bool is_mono_thread)
229 {
230  m_isMonoThread = is_mono_thread;
231 }
232 
233 QSqlDatabase
235 {
236  QString database_connection_name = QString("%1_%2")
237  .arg(m_timsDataDirectory.absolutePath())
238  .arg((quintptr)QThread::currentThread());
239  // Open the database
240  QSqlDatabase qdb = QSqlDatabase::database(database_connection_name);
241  if(!qdb.isValid())
242  {
243  qDebug() << database_connection_name;
244  qdb = QSqlDatabase::addDatabase("QSQLITE", database_connection_name);
245  qdb.setDatabaseName(m_timsDataDirectory.absoluteFilePath("analysis.tdf"));
246  }
247 
248 
249  if(!qdb.open())
250  {
251  qDebug();
252  throw PappsoException(
253  QObject::tr("ERROR opening TIMS sqlite database file %1, database name "
254  "%2 :\n%3\n%4\n%5")
255  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
256  .arg(database_connection_name)
257  .arg(qdb.lastError().databaseText())
258  .arg(qdb.lastError().driverText())
259  .arg(qdb.lastError().nativeErrorCode()));
260  }
261  return qdb;
262 }
263 
264 TimsData::TimsData([[maybe_unused]] const pappso::TimsData &other)
265 {
266  qDebug();
267 }
268 
270 {
271  // m_qdb.close();
272  if(mpa_timsBinDec != nullptr)
273  {
274  delete mpa_timsBinDec;
275  }
276  if(mpa_mzCalibrationStore != nullptr)
277  {
278  delete mpa_mzCalibrationStore;
279  }
280 }
281 
282 void
284 {
285  m_builtinMs2Centroid = centroid;
286 }
287 
288 bool
290 {
291  return m_builtinMs2Centroid;
292 }
293 
294 void
296 {
297  qDebug();
298  QSqlDatabase qdb = openDatabaseConnection();
299 
300  QSqlQuery q =
301  qdb.exec(QString("SELECT Id, NumScans FROM "
302  "Frames ORDER BY Id"));
303  if(q.lastError().isValid())
304  {
305 
306  throw PappsoException(
307  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
308  "command %2:\n%3\n%4\n%5")
309  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
310  .arg(q.lastQuery())
311  .arg(qdb.lastError().databaseText())
312  .arg(qdb.lastError().driverText())
313  .arg(qdb.lastError().nativeErrorCode()));
314  }
315  TimsFrameSPtr tims_frame;
316  bool index_found = false;
317  std::size_t timsId;
318  /** @brief number of scans in mobility dimension (number of TOF scans)
319  */
320  std::size_t numberScans;
321  std::size_t cumulScans = 0;
322  while(q.next() && (!index_found))
323  {
324  timsId = q.value(0).toULongLong();
325  numberScans = q.value(1).toULongLong();
326 
327  // qDebug() << timsId;
328 
330  std::pair<std::size_t, std::size_t>((cumulScans / 1000),
331  m_frameIdDescrList.size()));
332 
333  m_frameIdDescrList.push_back({timsId, numberScans, cumulScans});
334  cumulScans += numberScans;
335  }
336  qDebug();
337 }
338 
339 std::pair<std::size_t, std::size_t>
340 TimsData::getScanCoordinateFromRawIndex(std::size_t raw_index) const
341 {
342 
343  std::size_t fast_access = raw_index / 1000;
344  qDebug() << " fast_access=" << fast_access;
345  auto map_it = m_thousandIndexToFrameIdDescrListIndex.find(fast_access);
346  if(map_it == m_thousandIndexToFrameIdDescrListIndex.end())
347  {
348  throw ExceptionNotFound(
349  QObject::tr("ERROR raw index %1 not found (fast_access)")
350  .arg(raw_index));
351  }
352  std::size_t start_point_index = map_it->second;
353  while((start_point_index > 0) &&
354  (m_frameIdDescrList[start_point_index].m_cumulSize > raw_index))
355  {
356  start_point_index--;
357  }
358  for(std::size_t i = start_point_index; i < m_frameIdDescrList.size(); i++)
359  {
360 
361  if(raw_index <
362  (m_frameIdDescrList[i].m_cumulSize + m_frameIdDescrList[i].m_size))
363  {
364  return std::pair<std::size_t, std::size_t>(
365  m_frameIdDescrList[i].m_frameId,
366  raw_index - m_frameIdDescrList[i].m_cumulSize);
367  }
368  }
369 
370  throw ExceptionNotFound(
371  QObject::tr("ERROR raw index %1 not found").arg(raw_index));
372 }
373 
374 
375 std::size_t
377  std::size_t scan_num) const
378 {
379 
380  for(auto frameDescr : m_frameIdDescrList)
381  {
382  if(frameDescr.m_frameId == frame_id)
383  {
384  return frameDescr.m_cumulSize + scan_num;
385  }
386  }
387 
388  throw ExceptionNotFound(
389  QObject::tr("ERROR raw index with frame=%1 scan=%2 not found")
390  .arg(frame_id)
391  .arg(scan_num));
392 }
393 
394 /** @brief get a mass spectrum given its spectrum index
395  * @param raw_index a number begining at 0, corresponding to a Tims Scan in
396  * the order they lies in the binary data file
397  */
400 {
401 
402  qDebug() << " raw_index=" << raw_index;
403  try
404  {
405  auto coordinate = getScanCoordinateFromRawIndex(raw_index);
406  return getMassSpectrumCstSPtr(coordinate.first, coordinate.second);
407  }
408  catch(PappsoException &error)
409  {
410  throw PappsoException(
411  QObject::tr("Error TimsData::getMassSpectrumCstSPtrByRawIndex "
412  "raw_index=%1 :\n%2")
413  .arg(raw_index)
414  .arg(error.qwhat()));
415  }
416 }
417 
418 
421 {
422 
423  qDebug() << " timsId=" << timsId;
424 
425  const TimsFrameRecord &frame_record = m_mapFramesRecord[timsId];
426  if(timsId > m_totalNumberOfScans)
427  {
428  throw ExceptionNotFound(
429  QObject::tr("ERROR Frames database id %1 not found").arg(timsId));
430  }
431  TimsFrameBaseSPtr tims_frame;
432 
433 
434  tims_frame = std::make_shared<TimsFrameBase>(
435  TimsFrameBase(timsId, frame_record.tims_offset));
436 
437  auto it_map_record =
438  m_mapMzCalibrationRecord.find(frame_record.mz_calibration_id);
439  if(it_map_record != m_mapMzCalibrationRecord.end())
440  {
441 
442  double T1_frame = frame_record.frame_t1; // Frames.T1
443  double T2_frame = frame_record.frame_t2; // Frames.T2
444 
445 
446  tims_frame.get()->setMzCalibrationInterfaceSPtr(
448  T1_frame, T2_frame, it_map_record->second));
449  }
450  else
451  {
452  throw ExceptionNotFound(
453  QObject::tr("ERROR MzCalibration database id %1 not found")
454  .arg(frame_record.mz_calibration_id));
455  }
456 
457  tims_frame.get()->setAccumulationTime(frame_record.accumulation_time);
458 
459  tims_frame.get()->setTime(frame_record.frame_time);
460  tims_frame.get()->setMsMsType(frame_record.msms_type);
461 
462 
463  auto it_map_record_tims_calibration =
465  if(it_map_record_tims_calibration != m_mapTimsCalibrationRecord.end())
466  {
467 
468  tims_frame.get()->setTimsCalibration(
469  it_map_record_tims_calibration->second.value(1).toInt(),
470  it_map_record_tims_calibration->second.value(2).toDouble(),
471  it_map_record_tims_calibration->second.value(3).toDouble(),
472  it_map_record_tims_calibration->second.value(4).toDouble(),
473  it_map_record_tims_calibration->second.value(5).toDouble(),
474  it_map_record_tims_calibration->second.value(6).toDouble(),
475  it_map_record_tims_calibration->second.value(7).toDouble(),
476  it_map_record_tims_calibration->second.value(8).toDouble(),
477  it_map_record_tims_calibration->second.value(9).toDouble(),
478  it_map_record_tims_calibration->second.value(10).toDouble(),
479  it_map_record_tims_calibration->second.value(11).toDouble());
480  }
481  else
482  {
483  throw ExceptionNotFound(
484  QObject::tr("ERROR TimsCalibration database id %1 not found")
485  .arg(frame_record.tims_calibration_id));
486  }
487 
488  return tims_frame;
489 }
490 
491 std::vector<std::size_t>
492 TimsData::getTimsMS1FrameIdRange(double rt_begin, double rt_end) const
493 {
494 
495  qDebug() << " rt_begin=" << rt_begin << " rt_end=" << rt_end;
496  if(rt_begin < 0)
497  rt_begin = 0;
498  std::vector<std::size_t> tims_frameid_list;
499  QSqlDatabase qdb = openDatabaseConnection();
500  QSqlQuery q = qdb.exec(QString("SELECT Frames.Id FROM Frames WHERE "
501  "Frames.MsMsType=0 AND (Frames.Time>=%1) AND "
502  "(Frames.Time<=%2) ORDER BY Frames.Time;")
503  .arg(rt_begin)
504  .arg(rt_end));
505  if(q.lastError().isValid())
506  {
507 
508  throw PappsoException(
509  QObject::tr("ERROR in TIMS sqlite database file %1, database name %2, "
510  "executing SQL "
511  "command %3:\n%4\n%5\n%6")
512  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
513  .arg(qdb.databaseName())
514  .arg(q.lastQuery())
515  .arg(qdb.lastError().databaseText())
516  .arg(qdb.lastError().driverText())
517  .arg(qdb.lastError().nativeErrorCode()));
518  }
519  while(q.next())
520  {
521 
522  tims_frameid_list.push_back(q.value(0).toULongLong());
523  }
524  return tims_frameid_list;
525 }
526 
528 TimsData::getTimsFrameCstSPtr(std::size_t timsId)
529 {
530 
531  qDebug() << " timsId=" << timsId
532  << " m_mapFramesRecord.size()=" << m_mapFramesRecord.size();
533 
534  /*
535  for(auto pair_i : m_mapFramesRecord)
536  {
537 
538  qDebug() << " pair_i=" << pair_i.first;
539  }
540  */
541 
542  const TimsFrameRecord &frame_record = m_mapFramesRecord[timsId];
543  if(timsId > m_totalNumberOfScans)
544  {
545  throw ExceptionNotFound(
546  QObject::tr("ERROR Frames database id %1 not found").arg(timsId));
547  }
548 
549  TimsFrameSPtr tims_frame;
550 
551 
552  // QMutexLocker lock(&m_mutex);
553  tims_frame =
555  // lock.unlock();
556 
557  qDebug();
558  auto it_map_record =
559  m_mapMzCalibrationRecord.find(frame_record.mz_calibration_id);
560  if(it_map_record != m_mapMzCalibrationRecord.end())
561  {
562 
563  double T1_frame = frame_record.frame_t1; // Frames.T1
564  double T2_frame = frame_record.frame_t2; // Frames.T2
565 
566 
567  tims_frame.get()->setMzCalibrationInterfaceSPtr(
569  T1_frame, T2_frame, it_map_record->second));
570  }
571  else
572  {
573  throw ExceptionNotFound(
574  QObject::tr("ERROR MzCalibration database id %1 not found")
575  .arg(frame_record.mz_calibration_id));
576  }
577 
578  tims_frame.get()->setAccumulationTime(frame_record.accumulation_time);
579 
580  tims_frame.get()->setTime(frame_record.frame_time);
581  tims_frame.get()->setMsMsType(frame_record.msms_type);
582 
583  qDebug();
584  auto it_map_record_tims_calibration =
586  if(it_map_record_tims_calibration != m_mapTimsCalibrationRecord.end())
587  {
588 
589  tims_frame.get()->setTimsCalibration(
590  it_map_record_tims_calibration->second.value(1).toInt(),
591  it_map_record_tims_calibration->second.value(2).toDouble(),
592  it_map_record_tims_calibration->second.value(3).toDouble(),
593  it_map_record_tims_calibration->second.value(4).toDouble(),
594  it_map_record_tims_calibration->second.value(5).toDouble(),
595  it_map_record_tims_calibration->second.value(6).toDouble(),
596  it_map_record_tims_calibration->second.value(7).toDouble(),
597  it_map_record_tims_calibration->second.value(8).toDouble(),
598  it_map_record_tims_calibration->second.value(9).toDouble(),
599  it_map_record_tims_calibration->second.value(10).toDouble(),
600  it_map_record_tims_calibration->second.value(11).toDouble());
601  }
602  else
603  {
604  throw ExceptionNotFound(
605  QObject::tr("ERROR TimsCalibration database id %1 not found")
606  .arg(frame_record.tims_calibration_id));
607  }
608  qDebug();
609  return tims_frame;
610 }
611 
612 
614 TimsData::getMassSpectrumCstSPtr(std::size_t timsId, std::size_t scanNum)
615 {
616  qDebug() << " timsId=" << timsId << " scanNum=" << scanNum;
618 
619  return frame->getMassSpectrumCstSPtr(scanNum);
620 }
621 
622 
623 std::size_t
625 {
626  return m_totalNumberOfFrames;
627 }
628 
629 
630 std::size_t
632 {
633  return m_totalNumberOfScans;
634 }
635 
636 
637 std::size_t
639 {
641 }
642 
643 std::vector<std::size_t>
645  double mz_val,
646  double rt_sec,
647  double k0)
648 {
649  std::vector<std::size_t> precursor_ids;
650  std::vector<std::vector<double>> ids;
651 
652  QSqlDatabase qdb = openDatabaseConnection();
653  QSqlQuery q = qdb.exec(
654  QString(
655  "SELECT Frames.Time, Precursors.MonoisotopicMz, Precursors.Charge, "
656  "Precursors.Id, Frames.Id, PasefFrameMsMsInfo.ScanNumBegin, "
657  "PasefFrameMsMsInfo.scanNumEnd "
658  "FROM Frames "
659  "INNER JOIN PasefFrameMsMsInfo ON Frames.Id = PasefFrameMsMsInfo.Frame "
660  "INNER JOIN Precursors ON PasefFrameMsMsInfo.Precursor = Precursors.Id "
661  "WHERE Precursors.Charge == %1 "
662  "AND Precursors.MonoisotopicMz > %2 -0.01 "
663  "AND Precursors.MonoisotopicMz < %2 +0.01 "
664  "AND Frames.Time >= %3 -1 "
665  "AND Frames.Time < %3 +1; ")
666  .arg(charge)
667  .arg(mz_val)
668  .arg(rt_sec));
669  if(q.lastError().isValid())
670  {
671 
672  throw PappsoException(
673  QObject::tr("ERROR in TIMS sqlite database file %1, database name %2, "
674  "executing SQL "
675  "command %3:\n%4\n%5\n%6")
676  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
677  .arg(qdb.databaseName())
678  .arg(q.lastQuery())
679  .arg(qdb.lastError().databaseText())
680  .arg(qdb.lastError().driverText())
681  .arg(qdb.lastError().nativeErrorCode()));
682  }
683  while(q.next())
684  {
685  // qInfo() << q.value(0).toDouble() << q.value(1).toDouble()
686  // << q.value(2).toDouble() << q.value(3).toDouble();
687 
688  std::vector<double> sql_values;
689  sql_values.push_back(q.value(4).toDouble()); // frame id
690  sql_values.push_back(q.value(3).toDouble()); // precursor id
691  sql_values.push_back(q.value(5).toDouble()); // scan num begin
692  sql_values.push_back(q.value(6).toDouble()); // scan num end
693  sql_values.push_back(q.value(1).toDouble()); // mz_value
694 
695  ids.push_back(sql_values);
696 
697 
698  if(std::find(precursor_ids.begin(),
699  precursor_ids.end(),
700  q.value(3).toDouble()) == precursor_ids.end())
701  {
702  precursor_ids.push_back(q.value(3).toDouble());
703  }
704  }
705 
706  if(precursor_ids.size() > 1)
707  {
708  // std::vector<std::size_t> precursor_ids_ko =
709  // getMatchPrecursorIdByKo(ids, values[3]);
710  if(precursor_ids.size() > 1)
711  {
712  precursor_ids = getClosestPrecursorIdByMz(ids, k0);
713  }
714  return precursor_ids;
715  }
716  else
717  {
718  return precursor_ids;
719  }
720 }
721 
722 std::vector<std::size_t>
723 TimsData::getMatchPrecursorIdByKo(std::vector<std::vector<double>> ids,
724  double ko_value)
725 {
726  std::vector<std::size_t> precursor_id;
727  for(std::vector<double> index : ids)
728  {
729  auto coordinate = getScanCoordinateFromRawIndex(index[0]);
730 
731  TimsFrameBaseCstSPtr tims_frame;
732  tims_frame = getTimsFrameBaseCstSPtrCached(coordinate.first);
733 
734  double bko = tims_frame.get()->getOneOverK0Transformation(index[2]);
735  double eko = tims_frame.get()->getOneOverK0Transformation(index[3]);
736 
737  // qInfo() << "diff" << (bko + eko) / 2;
738  double mean_ko = (bko + eko) / 2;
739 
740  if(mean_ko > ko_value - 0.1 && mean_ko < ko_value + 0.1)
741  {
742  precursor_id.push_back(index[1]);
743  }
744  }
745  return precursor_id;
746 }
747 
748 std::vector<std::size_t>
749 TimsData::getClosestPrecursorIdByMz(std::vector<std::vector<double>> ids,
750  double mz_value)
751 {
752  std::vector<std::size_t> best_precursor;
753  double best_value = 1;
754  int count = 1;
755  int best_val_position = 0;
756 
757  for(std::vector<double> values : ids)
758  {
759  double new_val = abs(mz_value - values[4]);
760  if(new_val < best_value)
761  {
762  best_value = new_val;
763  best_val_position = count;
764  }
765  count++;
766  }
767  best_precursor.push_back(ids[best_val_position][1]);
768  return best_precursor;
769 }
770 
771 
772 unsigned int
773 TimsData::getMsLevelBySpectrumIndex(std::size_t spectrum_index)
774 {
775  auto coordinate = getScanCoordinateFromRawIndex(spectrum_index);
776  auto tims_frame = getTimsFrameCstSPtrCached(coordinate.first);
777  return tims_frame.get()->getMsLevel();
778 }
779 
780 
781 void
783  const MsRunIdCstSPtr &msrun_id,
784  QualifiedMassSpectrum &mass_spectrum,
785  std::size_t spectrum_index,
786  bool want_binary_data)
787 {
788  try
789  {
790  auto coordinate = getScanCoordinateFromRawIndex(spectrum_index);
791  TimsFrameBaseCstSPtr tims_frame;
792  if(want_binary_data)
793  {
794  tims_frame = getTimsFrameCstSPtrCached(coordinate.first);
795  }
796  else
797  {
798  tims_frame = getTimsFrameBaseCstSPtrCached(coordinate.first);
799  }
800  MassSpectrumId spectrum_id;
801 
802  spectrum_id.setSpectrumIndex(spectrum_index);
803  spectrum_id.setMsRunId(msrun_id);
804  spectrum_id.setNativeId(QString("frame=%1 scan=%2 index=%3")
805  .arg(coordinate.first)
806  .arg(coordinate.second)
807  .arg(spectrum_index));
808 
809  mass_spectrum.setMassSpectrumId(spectrum_id);
810 
811  mass_spectrum.setMsLevel(tims_frame.get()->getMsLevel());
812  mass_spectrum.setRtInSeconds(tims_frame.get()->getTime());
813 
814  mass_spectrum.setDtInMilliSeconds(
815  tims_frame.get()->getDriftTime(coordinate.second));
816  // 1/K0
817  mass_spectrum.setParameterValue(
819  tims_frame.get()->getOneOverK0Transformation(coordinate.second));
820 
821  mass_spectrum.setEmptyMassSpectrum(true);
822  if(want_binary_data)
823  {
824  mass_spectrum.setMassSpectrumSPtr(
825  tims_frame.get()->getMassSpectrumSPtr(coordinate.second));
826  if(mass_spectrum.size() > 0)
827  {
828  mass_spectrum.setEmptyMassSpectrum(false);
829  }
830  }
831  else
832  {
833  // if(tims_frame.get()->getNbrPeaks(coordinate.second) > 0)
834  //{
835  mass_spectrum.setEmptyMassSpectrum(false);
836  // }
837  }
838  if(tims_frame.get()->getMsLevel() > 1)
839  {
840 
841  auto spectrum_descr = getSpectrumDescrWithScanCoordinate(coordinate);
842  if(spectrum_descr.precursor_id > 0)
843  {
844 
845  mass_spectrum.appendPrecursorIonData(
846  spectrum_descr.precursor_ion_data);
847 
848 
849  MassSpectrumId spectrum_id;
850  std::size_t prec_spectrum_index = getRawIndexFromCoordinate(
851  spectrum_descr.parent_frame, coordinate.second);
852 
853  mass_spectrum.setPrecursorSpectrumIndex(prec_spectrum_index);
854  mass_spectrum.setPrecursorNativeId(
855  QString("frame=%1 scan=%2 index=%3")
856  .arg(spectrum_descr.parent_frame)
857  .arg(coordinate.second)
858  .arg(prec_spectrum_index));
859 
860  mass_spectrum.setParameterValue(
862  spectrum_descr.isolationMz);
863  mass_spectrum.setParameterValue(
865  spectrum_descr.isolationWidth);
866 
867  mass_spectrum.setParameterValue(
869  spectrum_descr.collisionEnergy);
870  mass_spectrum.setParameterValue(
872  (quint64)spectrum_descr.precursor_id);
873  }
874  }
875  }
876  catch(PappsoException &error)
877  {
879  QObject::tr("Error TimsData::getQualifiedMassSpectrumByRawIndex "
880  "spectrum_index=%1 :\n%2")
881  .arg(spectrum_index)
882  .arg(error.qwhat()));
883  }
884 }
885 
886 
887 Trace
889 {
890  // In the Frames table, each frame has a record describing the
891  // SummedIntensities for all the mobility spectra.
892 
893 
894  MapTrace rt_tic_map_trace;
895 
896  using Pair = std::pair<double, double>;
897  using Map = std::map<double, double>;
898  using Iterator = Map::iterator;
899 
900 
901  QSqlDatabase qdb = openDatabaseConnection();
902  QSqlQuery q =
903  qdb.exec(QString("SELECT Time, SummedIntensities "
904  "FROM Frames WHERE MsMsType = 0 "
905  "ORDER BY Time;"));
906 
907  if(q.lastError().isValid())
908  {
909 
910  throw PappsoException(
911  QObject::tr("ERROR in TIMS sqlite database file %1, database name %2, "
912  "executing SQL "
913  "command %3:\n%4\n%5\n%6")
914  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
915  .arg(qdb.databaseName())
916  .arg(q.lastQuery())
917  .arg(qdb.lastError().databaseText())
918  .arg(qdb.lastError().driverText())
919  .arg(qdb.lastError().nativeErrorCode()));
920  }
921 
922  while(q.next())
923  {
924 
925  bool ok = false;
926 
927  int cumulated_results = 2;
928 
929  double rt = q.value(0).toDouble(&ok);
930  cumulated_results -= ok;
931 
932  double sumY = q.value(1).toDouble(&ok);
933  cumulated_results -= ok;
934 
935  if(cumulated_results)
936  {
937  throw PappsoException(
938  QObject::tr(
939  "ERROR in TIMS sqlite database file: could not read either the "
940  "retention time or the summed intensities (%1, database name "
941  "%2, "
942  "executing SQL "
943  "command %3:\n%4\n%5\n%6")
944  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
945  .arg(qdb.databaseName())
946  .arg(q.lastQuery())
947  .arg(qdb.lastError().databaseText())
948  .arg(qdb.lastError().driverText())
949  .arg(qdb.lastError().nativeErrorCode()));
950  }
951 
952  // Try to insert value sumY at key rt.
953  std::pair<Iterator, bool> res = rt_tic_map_trace.insert(Pair(rt, sumY));
954 
955  if(!res.second)
956  {
957  // One other same rt value was seen already (like in ion mobility
958  // mass spectrometry, for example). Only increment the y value.
959 
960  res.first->second += sumY;
961  }
962  }
963 
964  // qDebug().noquote() << "The TIC chromatogram:\n"
965  //<< rt_tic_map_trace.toTrace().toString();
966 
967  return rt_tic_map_trace.toTrace();
968 }
969 
970 
971 void
973  const MsRunIdCstSPtr &msrun_id,
974  QualifiedMassSpectrum &mass_spectrum,
975  const SpectrumDescr &spectrum_descr,
976  bool want_binary_data)
977 {
978 
979  qDebug() << " ms2_index=" << spectrum_descr.ms2_index
980  << " precursor_index=" << spectrum_descr.precursor_id;
981 
982  TracePlusCombiner combiner;
983  MapTrace combiner_result;
984 
985  try
986  {
987  mass_spectrum.setMsLevel(1);
988  mass_spectrum.setPrecursorSpectrumIndex(0);
989  mass_spectrum.setEmptyMassSpectrum(true);
990 
991  MassSpectrumId spectrum_id;
992  spectrum_id.setSpectrumIndex(spectrum_descr.ms1_index);
993  spectrum_id.setNativeId(
994  QString("frame=%1 begin=%2 end=%3 precursor=%4 idxms1=%5")
995  .arg(spectrum_descr.parent_frame)
996  .arg(spectrum_descr.scan_mobility_start)
997  .arg(spectrum_descr.scan_mobility_end)
998  .arg(spectrum_descr.precursor_id)
999  .arg(spectrum_descr.ms1_index));
1000 
1001  spectrum_id.setMsRunId(msrun_id);
1002 
1003  mass_spectrum.setMassSpectrumId(spectrum_id);
1004 
1005 
1006  TimsFrameBaseCstSPtr tims_frame;
1007  if(want_binary_data)
1008  {
1009  qDebug() << "bindec";
1010  tims_frame = getTimsFrameCstSPtrCached(spectrum_descr.parent_frame);
1011  }
1012  else
1013  {
1014  tims_frame =
1016  }
1017  mass_spectrum.setRtInSeconds(tims_frame.get()->getTime());
1018 
1019  mass_spectrum.setParameterValue(
1021  tims_frame.get()->getOneOverK0Transformation(
1022  spectrum_descr.scan_mobility_start));
1023 
1024  mass_spectrum.setParameterValue(
1026  tims_frame.get()->getOneOverK0Transformation(
1027  spectrum_descr.scan_mobility_end));
1028 
1029 
1030  if(want_binary_data)
1031  {
1032  combiner.combine(combiner_result,
1033  tims_frame.get()->cumulateScanToTrace(
1034  spectrum_descr.scan_mobility_start,
1035  spectrum_descr.scan_mobility_end));
1036 
1037  pappso::Trace trace(combiner_result);
1038  qDebug();
1039 
1040  if(trace.size() > 0)
1041  {
1042  if(mcsp_ms1Filter != nullptr)
1043  {
1044  mcsp_ms1Filter->filter(trace);
1045  }
1046 
1047  qDebug();
1048  mass_spectrum.setMassSpectrumSPtr(
1049  MassSpectrum(trace).makeMassSpectrumSPtr());
1050  mass_spectrum.setEmptyMassSpectrum(false);
1051  }
1052  else
1053  {
1054  mass_spectrum.setMassSpectrumSPtr(nullptr);
1055  mass_spectrum.setEmptyMassSpectrum(true);
1056  }
1057  }
1058  qDebug();
1059  }
1060 
1061  catch(PappsoException &error)
1062  {
1063  throw error;
1064  }
1065  catch(std::exception &error)
1066  {
1067  qDebug() << QString("Failure %1 ").arg(error.what());
1068  }
1069 }
1070 
1071 
1074 {
1075  QMutexLocker locker(&m_mutex);
1076  for(auto &tims_frame : m_timsFrameBaseCache)
1077  {
1078  if(tims_frame.get()->getId() == timsId)
1079  {
1080  m_timsFrameBaseCache.push_back(tims_frame);
1081  if(m_timsFrameBaseCache.size() > m_cacheSize)
1082  m_timsFrameBaseCache.pop_front();
1083  return tims_frame;
1084  }
1085  }
1086 
1087  m_timsFrameBaseCache.push_back(getTimsFrameBaseCstSPtr(timsId));
1088  if(m_timsFrameBaseCache.size() > m_cacheSize)
1089  m_timsFrameBaseCache.pop_front();
1090  return m_timsFrameBaseCache.back();
1091 }
1092 
1095 {
1096  qDebug();
1097  QMutexLocker locker(&m_mutex);
1098  for(auto &tims_frame : m_timsFrameCache)
1099  {
1100  if(tims_frame.get()->getId() == timsId)
1101  {
1102  m_timsFrameCache.push_back(tims_frame);
1103  if(m_timsFrameCache.size() > m_cacheSize)
1104  m_timsFrameCache.pop_front();
1105  return tims_frame;
1106  }
1107  }
1108  pappso::TimsFrameCstSPtr frame_sptr = getTimsFrameCstSPtr(timsId);
1109 
1110  // locker.relock();
1111  qDebug();
1112 
1113  m_timsFrameCache.push_back(frame_sptr);
1114  if(m_timsFrameCache.size() > m_cacheSize)
1115  m_timsFrameCache.pop_front();
1116  qDebug();
1117  return m_timsFrameCache.back();
1118 
1119 
1120  /*
1121 // the frame is not in the cache
1122 if(std::find(m_someoneIsLoadingFrameId.begin(),
1123  m_someoneIsLoadingFrameId.end(),
1124  timsId) == m_someoneIsLoadingFrameId.end())
1125  {
1126  // not found, we are alone on this frame
1127  m_someoneIsLoadingFrameId.push_back(timsId);
1128  qDebug();
1129  //locker.unlock();
1130  pappso::TimsFrameCstSPtr frame_sptr = getTimsFrameCstSPtr(timsId);
1131 
1132  // locker.relock();
1133  qDebug();
1134  m_someoneIsLoadingFrameId.erase(
1135  std::find(m_someoneIsLoadingFrameId.begin(),
1136  m_someoneIsLoadingFrameId.end(),
1137  timsId));
1138 
1139  m_timsFrameCache.push_back(frame_sptr);
1140  if(m_timsFrameCache.size() > m_cacheSize)
1141  m_timsFrameCache.pop_front();
1142  qDebug();
1143  return m_timsFrameCache.back();
1144  }
1145 else
1146  {
1147  // this frame is loading by someone else, we have to wait
1148  qDebug();
1149  // locker.unlock();
1150  // std::size_t another_frame_id = timsId;
1151  while(true)
1152  {
1153  QThread::usleep(1);
1154  // locker.relock();
1155 
1156  for(auto &tims_frame : m_timsFrameCache)
1157  {
1158  if(tims_frame.get()->getId() == timsId)
1159  {
1160  m_timsFrameCache.push_back(tims_frame);
1161  return tims_frame;
1162  }
1163  }
1164  // locker.unlock();
1165 }
1166 } // namespace pappso
1167 */
1168 }
1169 
1170 void
1172 {
1173  mcsp_ms2Filter = filter;
1174 }
1175 void
1177 {
1178  mcsp_ms1Filter = filter;
1179 }
1180 
1183  PrecisionPtr precision_ptr)
1184 {
1185 
1186  qDebug();
1187  XicCoordTims xic_coord_tims_struct;
1188 
1189  try
1190  {
1191  if(m_mapXicCoordRecord.size() == 0)
1192  {
1193  QMutexLocker lock(&m_mutex);
1194  // Go get records!
1195 
1196  // We proceed in this way:
1197 
1198  // 1. For each Precursor reference to the Precursors table's ID
1199  // found in the PasefFrameMsMsInfo table, store the precursor ID for
1200  // step 2.
1201 
1202  // 2. From the Precursors table's ID from step 1, get the
1203  // MonoisotopicMz.
1204 
1205  // 3. From the PasefFrameMsMsInfo table, for the Precursors table's
1206  // ID reference, get a reference to the Frames table's ID. Thanks to
1207  // the Frames ID, look for the Time value (acquisition retention
1208  // time) for the MS/MS spectrum. The Time value in the Frames tables
1209  // always corresponds to a Frame of MsMsType 8 (that is, MS/MS),
1210  // which is expected since we are looking into MS/MS data.
1211 
1212  // 4. From the PasefFrameMsMsInfo table, associate the values
1213  // ScanNumBegin and ScanNumEnd, the mobility bins in which the
1214  // precursor was found.
1215 
1216 
1217  QSqlDatabase qdb = openDatabaseConnection();
1218  QSqlQuery q = qdb.exec(
1219  QString("SELECT Precursors.id, "
1220  "min(Frames.Time), "
1221  "min(PasefFrameMsMsInfo.ScanNumBegin), "
1222  "max(PasefFrameMsMsInfo.ScanNumEnd), "
1223  "Precursors.MonoisotopicMz "
1224  "FROM "
1225  "PasefFrameMsMsInfo INNER JOIN Precursors ON "
1226  "PasefFrameMsMsInfo.Precursor=Precursors.Id INNER JOIN "
1227  "Frames ON PasefFrameMsMsInfo.Frame=Frames.Id "
1228  "GROUP BY Precursors.id;"));
1229  if(q.lastError().isValid())
1230  {
1231  qDebug();
1232  throw PappsoException(
1233  QObject::tr(
1234  "ERROR in TIMS sqlite database file %1, executing SQL "
1235  "command %2:\n%3\n%4\n%5")
1236  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
1237  .arg(q.lastQuery())
1238  .arg(qdb.lastError().databaseText())
1239  .arg(qdb.lastError().driverText())
1240  .arg(qdb.lastError().nativeErrorCode()));
1241  }
1242 
1243  q.last(); // strange bug : get the last sql record and get back,
1244  // otherwise it will not retrieve all records.
1245  q.first();
1246  // std::size_t i = 0;
1247  do
1248  {
1249  QSqlRecord record = q.record();
1250  m_mapXicCoordRecord.insert(std::pair<std::size_t, QSqlRecord>(
1251  (std::size_t)record.value(0).toULongLong(), record));
1252  }
1253  while(q.next());
1254  }
1255 
1256 
1257  auto it_map_xiccoord = m_mapXicCoordRecord.find(precursor_id);
1258  if(it_map_xiccoord == m_mapXicCoordRecord.end())
1259  {
1260 
1261  throw ExceptionNotFound(
1262  QObject::tr("ERROR Precursors database id %1 not found")
1263  .arg(precursor_id));
1264  }
1265 
1266  auto &q = it_map_xiccoord->second;
1267  xic_coord_tims_struct.mzRange =
1268  MzRange(q.value(4).toDouble(), precision_ptr);
1269  xic_coord_tims_struct.scanNumBegin = q.value(2).toUInt();
1270  xic_coord_tims_struct.scanNumEnd = q.value(3).toUInt();
1271  xic_coord_tims_struct.rtTarget = q.value(1).toDouble();
1272  // xic_structure.charge = q.value(5).toUInt();
1273  xic_coord_tims_struct.xicSptr = std::make_shared<Xic>();
1274  }
1275  catch(PappsoException &error)
1276  {
1277  throw error;
1278  }
1279  catch(std::exception &error)
1280  {
1281  qDebug() << QString("Failure %1 ").arg(error.what());
1282  }
1283  return xic_coord_tims_struct;
1284 }
1285 
1286 
1287 std::map<quint32, quint32>
1288 TimsData::getRawMs2ByPrecursorId(std::size_t precursor_index)
1289 {
1290  qDebug();
1291  std::map<quint32, quint32> raw_spectrum;
1292  try
1293  {
1294  QSqlDatabase qdb = openDatabaseConnection();
1295 
1296  qdb = openDatabaseConnection();
1297  QSqlQuery q =
1298  qdb.exec(QString("SELECT PasefFrameMsMsInfo.*, Precursors.* FROM "
1299  "PasefFrameMsMsInfo INNER JOIN Precursors ON "
1300  "PasefFrameMsMsInfo.Precursor=Precursors.Id where "
1301  "Precursors.Id=%1;")
1302  .arg(precursor_index));
1303  if(q.lastError().isValid())
1304  {
1305  qDebug();
1306  throw PappsoException(
1307  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
1308  "command %2:\n%3\n%4\n%5")
1309  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
1310  .arg(q.lastQuery())
1311  .arg(qdb.lastError().databaseText())
1312  .arg(qdb.lastError().driverText())
1313  .arg(qdb.lastError().nativeErrorCode()));
1314  }
1315  qDebug();
1316  // m_mutex.unlock();
1317  if(q.size() == 0)
1318  {
1319 
1320  throw ExceptionNotFound(
1321  QObject::tr(
1322  "ERROR in getQualifiedMassSpectrumByPrecursorId, precursor "
1323  "id=%1 not found")
1324  .arg(precursor_index));
1325  }
1326  else
1327  {
1328  // qDebug() << " q.size()="<< q.size();
1329  qDebug();
1330  bool first = true;
1331  std::size_t scan_mobility_start = 0;
1332  std::size_t scan_mobility_end = 0;
1333  std::vector<std::size_t> tims_frame_list;
1334 
1335  while(q.next())
1336  {
1337  tims_frame_list.push_back(q.value(0).toLongLong());
1338  if(first)
1339  {
1340 
1341  scan_mobility_start = q.value(1).toLongLong();
1342  scan_mobility_end = q.value(2).toLongLong();
1343 
1344  first = false;
1345  }
1346  }
1347  // QMutexLocker locker(&m_mutex_spectrum);
1348  qDebug();
1349  pappso::TimsFrameCstSPtr tims_frame, previous_frame;
1350  // TracePlusCombiner combiner;
1351  // MapTrace combiner_result;
1352  for(std::size_t tims_id : tims_frame_list)
1353  {
1354  tims_frame = getTimsFrameCstSPtrCached(tims_id);
1355  qDebug();
1356  /*combiner.combine(combiner_result,
1357  tims_frame.get()->cumulateScanToTrace(
1358  scan_mobility_start, scan_mobility_end));*/
1359  if(previous_frame.get() != nullptr)
1360  {
1361  if(previous_frame.get()->hasSameCalibrationData(
1362  *tims_frame.get()))
1363  {
1364  }
1365  else
1366  {
1367  throw ExceptionNotFound(
1368  QObject::tr(
1369  "ERROR in %1 %2, different calibration data "
1370  "between frame id %3 and frame id %4")
1371  .arg(__FILE__)
1372  .arg(__FUNCTION__)
1373  .arg(previous_frame.get()->getId())
1374  .arg(tims_frame.get()->getId()));
1375  }
1376  }
1377  tims_frame.get()->cumulateScansInRawMap(
1378  raw_spectrum, scan_mobility_start, scan_mobility_end);
1379  qDebug();
1380 
1381  previous_frame = tims_frame;
1382  }
1383  qDebug() << " precursor_index=" << precursor_index
1384  << " num_rows=" << tims_frame_list.size()
1385  << " sql=" << q.lastQuery() << " "
1386  << (std::size_t)QThread::currentThreadId();
1387  if(first == true)
1388  {
1389  throw ExceptionNotFound(
1390  QObject::tr(
1391  "ERROR in getQualifiedMassSpectrumByPrecursorId, precursor "
1392  "id=%1 not found")
1393  .arg(precursor_index));
1394  }
1395  qDebug();
1396  }
1397  }
1398 
1399  catch(PappsoException &error)
1400  {
1401  throw PappsoException(QObject::tr("ERROR in %1 (precursor_index=%2):\n%3")
1402  .arg(__FUNCTION__)
1403  .arg(precursor_index)
1404  .arg(error.qwhat()));
1405  }
1406  catch(std::exception &error)
1407  {
1408  qDebug() << QString("Failure %1 ").arg(error.what());
1409  }
1410  return raw_spectrum;
1411  qDebug();
1412 }
1413 
1414 
1415 void
1417  const MsRunIdCstSPtr &msrun_id,
1418  QualifiedMassSpectrum &mass_spectrum,
1419  const SpectrumDescr &spectrum_descr,
1420  bool want_binary_data)
1421 {
1422  try
1423  {
1424  qDebug();
1425  MassSpectrumId spectrum_id;
1426 
1427  spectrum_id.setSpectrumIndex(spectrum_descr.ms2_index);
1428  spectrum_id.setNativeId(QString("precursor=%1 idxms2=%2")
1429  .arg(spectrum_descr.precursor_id)
1430  .arg(spectrum_descr.ms2_index));
1431  spectrum_id.setMsRunId(msrun_id);
1432 
1433  mass_spectrum.setMassSpectrumId(spectrum_id);
1434 
1435  mass_spectrum.setMsLevel(2);
1436  qDebug() << "spectrum_descr.precursor_id=" << spectrum_descr.precursor_id
1437  << " spectrum_descr.ms1_index=" << spectrum_descr.ms1_index
1438  << " spectrum_descr.ms2_index=" << spectrum_descr.ms2_index;
1439  mass_spectrum.setPrecursorSpectrumIndex(spectrum_descr.ms1_index);
1440 
1441  mass_spectrum.setEmptyMassSpectrum(true);
1442 
1443  qDebug();
1444 
1445 
1446  mass_spectrum.appendPrecursorIonData(spectrum_descr.precursor_ion_data);
1447 
1448  mass_spectrum.setPrecursorNativeId(
1449  QString("frame=%1 begin=%2 end=%3 precursor=%4 idxms1=%5")
1450  .arg(spectrum_descr.parent_frame)
1451  .arg(spectrum_descr.scan_mobility_start)
1452  .arg(spectrum_descr.scan_mobility_end)
1453  .arg(spectrum_descr.precursor_id)
1454  .arg(spectrum_descr.ms1_index));
1455 
1456  mass_spectrum.setParameterValue(
1458  spectrum_descr.isolationMz);
1459  mass_spectrum.setParameterValue(
1461  spectrum_descr.isolationWidth);
1462 
1463  mass_spectrum.setParameterValue(
1465  spectrum_descr.collisionEnergy);
1466  mass_spectrum.setParameterValue(
1468  (quint64)spectrum_descr.precursor_id);
1469 
1470  // QMutexLocker locker(&m_mutex_spectrum);
1471  qDebug();
1472  pappso::TimsFrameBaseCstSPtr tims_frame, previous_frame;
1473  // TracePlusCombiner combiner;
1474  // MapTrace combiner_result;
1475  std::map<quint32, quint32> raw_spectrum;
1476  bool first = true;
1477  for(std::size_t tims_id : spectrum_descr.tims_frame_list)
1478  {
1479  qDebug() << " precursor_index=" << spectrum_descr.precursor_id
1480  << " tims_id=" << tims_id
1481  << (std::size_t)QThread::currentThreadId();
1482  ;
1483  if(want_binary_data)
1484  {
1485  qDebug() << "bindec";
1486  tims_frame = getTimsFrameCstSPtrCached(tims_id);
1487  }
1488  else
1489  {
1490  tims_frame = getTimsFrameBaseCstSPtrCached(tims_id);
1491  }
1492  qDebug() << (std::size_t)QThread::currentThreadId();
1493  ;
1494  if(first)
1495  {
1496  mass_spectrum.setRtInSeconds(tims_frame.get()->getTime());
1497 
1498  mass_spectrum.setParameterValue(
1500  tims_frame.get()->getOneOverK0Transformation(
1501  spectrum_descr.scan_mobility_start));
1502 
1503  mass_spectrum.setParameterValue(
1505  tims_frame.get()->getOneOverK0Transformation(
1506  spectrum_descr.scan_mobility_end));
1507 
1508  first = false;
1509  }
1510 
1511 
1512  if(want_binary_data)
1513  {
1514  qDebug();
1515  /*combiner.combine(combiner_result,
1516  tims_frame.get()->cumulateScanToTrace(
1517  scan_mobility_start, scan_mobility_end));*/
1518  if(previous_frame.get() != nullptr)
1519  {
1520  if(previous_frame.get()->hasSameCalibrationData(
1521  *tims_frame.get()))
1522  {
1523  }
1524  else
1525  {
1526  throw ExceptionNotFound(
1527  QObject::tr(
1528  "ERROR in %1 %2, different calibration data "
1529  "between frame id %3 and frame id %4")
1530  .arg(__FILE__)
1531  .arg(__FUNCTION__)
1532  .arg(previous_frame.get()->getId())
1533  .arg(tims_frame.get()->getId()));
1534  }
1535  }
1536  qDebug() << (std::size_t)QThread::currentThreadId();
1537  ;
1538  tims_frame.get()->cumulateScansInRawMap(
1539  raw_spectrum,
1540  spectrum_descr.scan_mobility_start,
1541  spectrum_descr.scan_mobility_end);
1542  qDebug() << (std::size_t)QThread::currentThreadId();
1543  ;
1544  }
1545  previous_frame = tims_frame;
1546  }
1547  qDebug() << " precursor_index=" << spectrum_descr.precursor_id
1548  << " num_rows=" << spectrum_descr.tims_frame_list.size()
1549  << (std::size_t)QThread::currentThreadId();
1550  if(first == true)
1551  {
1552  throw ExceptionNotFound(
1553  QObject::tr(
1554  "ERROR in getQualifiedMassSpectrumByPrecursorId, precursor "
1555  "id=%1 not found")
1556  .arg(spectrum_descr.precursor_id));
1557  }
1558  if(want_binary_data)
1559  {
1560  qDebug() << " precursor_index=" << spectrum_descr.precursor_id;
1561  // peak_pick.filter(trace);
1562  pappso::Trace trace;
1564  {
1565  trace =
1566  tims_frame.get()->getTraceFromCumulatedScansBuiltinCentroid(
1567  raw_spectrum);
1568  }
1569  else
1570  {
1571  // no builtin centroid:
1572 
1573  trace =
1574  tims_frame.get()->getTraceFromCumulatedScans(raw_spectrum);
1575  }
1576 
1577  if(trace.size() > 0)
1578  {
1579  qDebug() << " precursor_index=" << spectrum_descr.precursor_id
1580  << " " << trace.size() << " "
1581  << (std::size_t)QThread::currentThreadId();
1582 
1583  if(mcsp_ms2Filter != nullptr)
1584  {
1585  // FilterTriangle filter;
1586  // filter.setTriangleSlope(50, 0.02);
1587  // filter.filter(trace);
1588  // trace.filter(pappso::FilterHighPass(10));
1589  mcsp_ms2Filter->filter(trace);
1590  }
1591 
1592  // FilterScaleFactorY filter_scale((double)1 /
1593  // (double)tims_frame_list.size());
1594  // filter_scale.filter(trace);
1595  qDebug() << " precursor_index=" << spectrum_descr.precursor_id;
1596  mass_spectrum.setMassSpectrumSPtr(
1597  MassSpectrum(trace).makeMassSpectrumSPtr());
1598  mass_spectrum.setEmptyMassSpectrum(false);
1599  }
1600  else
1601  {
1602  mass_spectrum.setMassSpectrumSPtr(nullptr);
1603  mass_spectrum.setEmptyMassSpectrum(true);
1604  }
1605 
1606  qDebug();
1607  }
1608  qDebug();
1609  }
1610 
1611  catch(PappsoException &error)
1612  {
1613  throw PappsoException(
1614  QObject::tr("ERROR in %1 (ms2_index=%2 precursor_index=%3):\n%4")
1615  .arg(__FUNCTION__)
1616  .arg(spectrum_descr.ms2_index)
1617  .arg(spectrum_descr.precursor_id)
1618  .arg(error.qwhat()));
1619  }
1620  catch(std::exception &error)
1621  {
1622  qDebug() << QString("Failure %1 ").arg(error.what());
1623  }
1624  qDebug();
1625 }
1626 
1627 void
1629  const MsRunIdCstSPtr &msrun_id,
1631  unsigned int ms_level)
1632 {
1633  qDebug() << " ms_level=" << ms_level;
1634  if(!m_hasPrecursorTable)
1635  {
1636  throw PappsoException(
1637  QObject::tr("unable to read spectrum list : this data file does not "
1638  "contain MS2 data, no precursor found."));
1639  }
1640 
1641  QSqlDatabase qdb = openDatabaseConnection();
1642  QSqlQuery qprecursor_list = qdb.exec(QString(
1643  "SELECT PasefFrameMsMsInfo.Frame, " // 0
1644  "PasefFrameMsMsInfo.ScanNumBegin, " // 1
1645  "PasefFrameMsMsInfo.ScanNumEnd, " // 2
1646  "PasefFrameMsMsInfo.IsolationMz, " // 3
1647  "PasefFrameMsMsInfo.IsolationWidth, " // 4
1648  "PasefFrameMsMsInfo.CollisionEnergy, " // 5
1649  "PasefFrameMsMsInfo.Precursor, " // 6
1650  "Precursors.Id, " // 7
1651  "Precursors.LargestPeakMz, " // 8
1652  "Precursors.AverageMz, " // 9
1653  "Precursors.MonoisotopicMz, " // 10
1654  "Precursors.Charge, " // 11
1655  "Precursors.ScanNumber, " // 12
1656  "Precursors.Intensity, " // 13
1657  "Precursors.Parent " // 14
1658  "FROM PasefFrameMsMsInfo "
1659  "INNER JOIN Precursors ON "
1660  "PasefFrameMsMsInfo.Precursor=Precursors.Id "
1661  "ORDER BY PasefFrameMsMsInfo.Precursor, PasefFrameMsMsInfo.Frame ;"));
1662  if(qprecursor_list.lastError().isValid())
1663  {
1664 
1665  throw PappsoException(
1666  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
1667  "command %2:\n%3\n%4\n%5")
1668  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
1669  .arg(qprecursor_list.lastQuery())
1670  .arg(qdb.lastError().databaseText())
1671  .arg(qdb.lastError().driverText())
1672  .arg(qdb.lastError().nativeErrorCode()));
1673  }
1674 
1675 
1676  qDebug() << "qprecursor_list.size()=" << qprecursor_list.size();
1677  qDebug() << QObject::tr(
1678  "TIMS sqlite database file %1, executing SQL "
1679  "command %2:\n%3\n%4\n%5")
1680  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
1681  .arg(qprecursor_list.lastQuery())
1682  .arg(qdb.lastError().databaseText())
1683  .arg(qdb.lastError().driverText())
1684  .arg(qdb.lastError().nativeErrorCode());
1685 
1686  qDebug() << "qprecursor_list.isActive()=" << qprecursor_list.isActive();
1687  qDebug() << "qprecursor_list.isSelect()=" << qprecursor_list.isSelect();
1688  bool first = true;
1689  SpectrumDescr spectrum_descr;
1690  /*
1691 std::size_t i = 0;
1692 while(qprecursor_list.next())
1693  {
1694  qDebug() << "i=" << i;
1695  i++;
1696  }*/
1697  qprecursor_list.last(); // strange bug : get the last sql record and get
1698  // back, unless it will not retrieve all records.
1699 
1700  qDebug() << "qprecursor_list.at()=" << qprecursor_list.at();
1701  qprecursor_list.first();
1702  std::vector<pappso::TimsData::SpectrumDescr> spectrum_description_list;
1703  spectrum_descr.precursor_id = 0;
1704  // std::size_t i = 0;
1705 
1706  do
1707  {
1708 
1709  if(spectrum_descr.precursor_id !=
1710  (std::size_t)qprecursor_list.value(6).toLongLong())
1711  {
1712  // new precursor
1713  if(spectrum_descr.precursor_id > 0)
1714  {
1715  spectrum_description_list.push_back(spectrum_descr);
1716  }
1717 
1718  spectrum_descr.tims_frame_list.clear();
1719  first = true;
1720  }
1721  qDebug() << " qprecursor_list.value(6).toLongLong() ="
1722  << qprecursor_list.value(6).toLongLong();
1723  spectrum_descr.precursor_id =
1724  (std::size_t)qprecursor_list.value(6).toLongLong();
1725  qDebug() << " spectrum_descr.precursor_id ="
1726  << spectrum_descr.precursor_id;
1727  qDebug() << " cumul tims frame:" << qprecursor_list.value(0).toLongLong();
1728  spectrum_descr.tims_frame_list.push_back(
1729  qprecursor_list.value(0).toLongLong());
1730  qDebug() << " first =" << first;
1731  if(first)
1732  {
1733  qDebug();
1734  // mass_spectrum.setPrecursorCharge(q.value(11).toInt());
1735  // mass_spectrum.setPrecursorMz(q.value(10).toDouble());
1736  // mass_spectrum.setPrecursorIntensity(q.value(13).toDouble());
1737  spectrum_descr.precursor_ion_data =
1738  PrecursorIonData(qprecursor_list.value(10).toDouble(),
1739  qprecursor_list.value(11).toInt(),
1740  qprecursor_list.value(13).toDouble());
1741 
1742  // spectrum_descr.precursor_id = q.value(6).toLongLong();
1743  spectrum_descr.ms2_index = (spectrum_descr.precursor_id * 2) - 1;
1744  spectrum_descr.ms1_index = (spectrum_descr.precursor_id * 2) - 2;
1745 
1746  spectrum_descr.scan_mobility_start =
1747  qprecursor_list.value(1).toLongLong();
1748  spectrum_descr.scan_mobility_end =
1749  qprecursor_list.value(2).toLongLong();
1750 
1751  spectrum_descr.isolationMz = qprecursor_list.value(3).toDouble();
1752  spectrum_descr.isolationWidth = qprecursor_list.value(4).toDouble();
1753  spectrum_descr.collisionEnergy = qprecursor_list.value(5).toFloat();
1754  spectrum_descr.parent_frame = qprecursor_list.value(14).toLongLong();
1755 
1756 
1757  first = false;
1758  }
1759  // qDebug() << "qprecursor_list.executedQuery()="
1760  // << qprecursor_list.executedQuery();
1761  // qDebug() << "qprecursor_list.last()=" << qprecursor_list.last();
1762  // i++;
1763  }
1764  while(qprecursor_list.next());
1765 
1766  // last One
1767 
1768  // new precursor
1769  if(spectrum_descr.precursor_id > 0)
1770  {
1771  spectrum_description_list.push_back(spectrum_descr);
1772  }
1773 
1774 
1775  QString local_filepath = m_timsDataDirectory.absoluteFilePath("analysis.tdf");
1776 
1777  if(m_isMonoThread)
1778  {
1779  for(SpectrumDescr &spectrum_descr : spectrum_description_list)
1780  {
1781 
1782  std::vector<QualifiedMassSpectrum> mass_spectrum_list;
1783  ms2ReaderGenerateMS1MS2Spectrum(
1784  msrun_id, mass_spectrum_list, handler, spectrum_descr, ms_level);
1785 
1786  for(auto &qualified_spectrum : mass_spectrum_list)
1787  {
1788  handler.setQualifiedMassSpectrum(qualified_spectrum);
1789  }
1790 
1791  if(handler.shouldStop())
1792  {
1793  qDebug() << "The operation was cancelled. Breaking the loop.";
1794  throw ExceptionInterrupted(
1795  QObject::tr("reading TimsTOF job cancelled by the user :\n%1")
1796  .arg(local_filepath));
1797  }
1798  }
1799  }
1800  else
1801  {
1802 
1803 
1804  TimsData *itself = this;
1805  pappso::SpectrumCollectionHandlerInterface *pointer_handler = &handler;
1806 
1807 
1808  std::function<std::vector<QualifiedMassSpectrum>(
1810  map_function_generate_spectrum =
1811  [itself, msrun_id, pointer_handler, ms_level](
1812  const pappso::TimsData::SpectrumDescr &spectrum_descr)
1813  -> std::vector<QualifiedMassSpectrum> {
1814  std::vector<QualifiedMassSpectrum> mass_spectrum_list;
1815  itself->ms2ReaderGenerateMS1MS2Spectrum(msrun_id,
1816  mass_spectrum_list,
1817  *pointer_handler,
1818  spectrum_descr,
1819  ms_level);
1820 
1821 
1822  return mass_spectrum_list;
1823  };
1824 
1825  std::function<void(
1826  std::size_t,
1827  const std::vector<QualifiedMassSpectrum> &qualified_spectrum_list)>
1828  reduce_function_spectrum_list =
1829  [pointer_handler, local_filepath](
1830  std::size_t res,
1831  const std::vector<QualifiedMassSpectrum> &qualified_spectrum_list) {
1832  for(auto &qualified_spectrum : qualified_spectrum_list)
1833  {
1834  pointer_handler->setQualifiedMassSpectrum(qualified_spectrum);
1835  }
1836 
1837  if(pointer_handler->shouldStop())
1838  {
1839  qDebug() << "The operation was cancelled. Breaking the loop.";
1840  throw ExceptionInterrupted(
1841  QObject::tr("reading TimsTOF job on %1 cancelled by the user")
1842  .arg(local_filepath));
1843  }
1844  res++;
1845  };
1846 
1847 
1848  QFuture<std::size_t> res;
1849  res = QtConcurrent::mappedReduced<std::size_t>(
1850  spectrum_description_list.begin(),
1851  spectrum_description_list.end(),
1852  map_function_generate_spectrum,
1853  reduce_function_spectrum_list,
1854  QtConcurrent::OrderedReduce);
1855  res.waitForFinished();
1856  }
1857  handler.loadingEnded();
1858  mpa_timsBinDec->closeLinearRead();
1859 }
1860 
1861 
1862 void
1864  const MsRunIdCstSPtr &msrun_id,
1865  std::vector<QualifiedMassSpectrum> &qualified_mass_spectrum_list,
1867  const pappso::TimsData::SpectrumDescr &spectrum_descr,
1868  unsigned int ms_level)
1869 {
1870 
1871  qDebug() << " ms_level=" << ms_level;
1872  // The handler will receive the index of the mass spectrum in the
1873  // current run via the mass spectrum id member datum.
1874  if((ms_level == 0) || (ms_level == 1))
1875  {
1876  qualified_mass_spectrum_list.push_back(QualifiedMassSpectrum());
1877  getQualifiedMs1MassSpectrumByPrecursorId(
1878  msrun_id,
1879  qualified_mass_spectrum_list.back(),
1880  spectrum_descr,
1881  handler.needMsLevelPeakList(1));
1882  }
1883  if((ms_level == 0) || (ms_level == 2))
1884  {
1885  qualified_mass_spectrum_list.push_back(QualifiedMassSpectrum());
1886  getQualifiedMs2MassSpectrumByPrecursorId(
1887  msrun_id,
1888  qualified_mass_spectrum_list.back(),
1889  spectrum_descr,
1890  handler.needMsLevelPeakList(2));
1891  }
1892  qDebug();
1893 }
1894 
1895 
1898 {
1899 
1900  SpectrumDescr spectrum_descr;
1901  QSqlDatabase qdb = openDatabaseConnection();
1902  QSqlQuery q = qdb.exec(QString("SELECT PasefFrameMsMsInfo.Frame, " // 0
1903  "PasefFrameMsMsInfo.ScanNumBegin, " // 1
1904  "PasefFrameMsMsInfo.ScanNumEnd, " // 2
1905  "PasefFrameMsMsInfo.IsolationMz, " // 3
1906  "PasefFrameMsMsInfo.IsolationWidth, " // 4
1907  "PasefFrameMsMsInfo.CollisionEnergy, " // 5
1908  "PasefFrameMsMsInfo.Precursor, " // 6
1909  "Precursors.Id, " // 7
1910  "Precursors.LargestPeakMz, " // 8
1911  "Precursors.AverageMz, " // 9
1912  "Precursors.MonoisotopicMz, " // 10
1913  "Precursors.Charge, " // 11
1914  "Precursors.ScanNumber, " // 12
1915  "Precursors.Intensity, " // 13
1916  "Precursors.Parent " // 14
1917  "FROM PasefFrameMsMsInfo "
1918  "INNER JOIN Precursors ON "
1919  "PasefFrameMsMsInfo.Precursor=Precursors.Id "
1920  "WHERE Precursors.Id=%1;")
1921  .arg(precursor_id));
1922  if(q.lastError().isValid())
1923  {
1924 
1925  throw PappsoException(
1926  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
1927  "command %2:\n%3\n%4\n%5")
1928  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
1929  .arg(q.lastQuery())
1930  .arg(qdb.lastError().databaseText())
1931  .arg(qdb.lastError().driverText())
1932  .arg(qdb.lastError().nativeErrorCode()));
1933  }
1934 
1935 
1936  bool first = true;
1937  while(q.next())
1938  {
1939 
1940  qDebug() << " cumul tims frame:" << q.value(0).toLongLong();
1941  spectrum_descr.tims_frame_list.push_back(q.value(0).toLongLong());
1942  if(first)
1943  {
1944  // mass_spectrum.setPrecursorCharge(q.value(11).toInt());
1945  // mass_spectrum.setPrecursorMz(q.value(10).toDouble());
1946  // mass_spectrum.setPrecursorIntensity(q.value(13).toDouble());
1947  spectrum_descr.precursor_ion_data =
1948  PrecursorIonData(q.value(10).toDouble(),
1949  q.value(11).toInt(),
1950  q.value(13).toDouble());
1951 
1952  spectrum_descr.precursor_id = q.value(6).toLongLong();
1953  spectrum_descr.ms2_index = (spectrum_descr.precursor_id * 2) - 1;
1954  spectrum_descr.ms1_index = (spectrum_descr.precursor_id * 2) - 2;
1955 
1956  spectrum_descr.scan_mobility_start = q.value(1).toLongLong();
1957  spectrum_descr.scan_mobility_end = q.value(2).toLongLong();
1958 
1959  spectrum_descr.isolationMz = q.value(3).toDouble();
1960  spectrum_descr.isolationWidth = q.value(4).toDouble();
1961  spectrum_descr.collisionEnergy = q.value(5).toFloat();
1962  spectrum_descr.parent_frame = q.value(14).toLongLong();
1963 
1964 
1965  first = false;
1966  }
1967  }
1968  if(spectrum_descr.precursor_id == 0)
1969  {
1970  throw ExceptionNotFound(
1971  QObject::tr("ERROR in %1 %2 : precursor id (%3) NOT FOUND ")
1972  .arg(__FILE__)
1973  .arg(__FUNCTION__)
1974  .arg(precursor_id));
1975  }
1976  return spectrum_descr;
1977 }
1978 
1979 std::vector<double>
1981 {
1982  std::vector<double> timeline;
1983  timeline.reserve(m_mapFramesRecord.size());
1984  for(const TimsFrameRecord &frame_record : m_mapFramesRecord)
1985  {
1986  if(frame_record.mz_calibration_id != 0)
1987  {
1988  timeline.push_back(frame_record.frame_time);
1989  }
1990  }
1991  return timeline;
1992 }
1993 
1996  const std::pair<std::size_t, std::size_t> &scan_coordinate)
1997 {
1998 
1999  SpectrumDescr spectrum_descr;
2000  QSqlDatabase qdb = openDatabaseConnection();
2001  QSqlQuery q =
2002  qdb.exec(QString("SELECT PasefFrameMsMsInfo.Frame, " // 0
2003  "PasefFrameMsMsInfo.ScanNumBegin, " // 1
2004  "PasefFrameMsMsInfo.ScanNumEnd, " // 2
2005  "PasefFrameMsMsInfo.IsolationMz, " // 3
2006  "PasefFrameMsMsInfo.IsolationWidth, " // 4
2007  "PasefFrameMsMsInfo.CollisionEnergy, " // 5
2008  "PasefFrameMsMsInfo.Precursor, " // 6
2009  "Precursors.Id, " // 7
2010  "Precursors.LargestPeakMz, " // 8
2011  "Precursors.AverageMz, " // 9
2012  "Precursors.MonoisotopicMz, " // 10
2013  "Precursors.Charge, " // 11
2014  "Precursors.ScanNumber, " // 12
2015  "Precursors.Intensity, " // 13
2016  "Precursors.Parent " // 14
2017  "FROM PasefFrameMsMsInfo "
2018  "INNER JOIN Precursors ON "
2019  "PasefFrameMsMsInfo.Precursor=Precursors.Id "
2020  "WHERE "
2021  "PasefFrameMsMsInfo.Frame=%1 and "
2022  "(PasefFrameMsMsInfo.ScanNumBegin "
2023  "<= %2 and PasefFrameMsMsInfo.ScanNumEnd >= %2);")
2024  .arg(scan_coordinate.first)
2025  .arg(scan_coordinate.second));
2026  if(q.lastError().isValid())
2027  {
2028 
2029  throw PappsoException(
2030  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
2031  "command %2:\n%3\n%4\n%5")
2032  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
2033  .arg(q.lastQuery())
2034  .arg(qdb.lastError().databaseText())
2035  .arg(qdb.lastError().driverText())
2036  .arg(qdb.lastError().nativeErrorCode()));
2037  }
2038 
2039  if(q.next())
2040  {
2041 
2042  qDebug() << " cumul tims frame:" << q.value(0).toLongLong();
2043  spectrum_descr.tims_frame_list.push_back(q.value(0).toLongLong());
2044  // mass_spectrum.setPrecursorCharge(q.value(11).toInt());
2045  // mass_spectrum.setPrecursorMz(q.value(10).toDouble());
2046  // mass_spectrum.setPrecursorIntensity(q.value(13).toDouble());
2047  spectrum_descr.precursor_ion_data = PrecursorIonData(
2048  q.value(10).toDouble(), q.value(11).toInt(), q.value(13).toDouble());
2049 
2050  spectrum_descr.precursor_id = q.value(6).toLongLong();
2051  spectrum_descr.ms2_index = (spectrum_descr.precursor_id * 2) - 1;
2052  spectrum_descr.ms1_index = (spectrum_descr.precursor_id * 2) - 2;
2053 
2054  spectrum_descr.scan_mobility_start = q.value(1).toLongLong();
2055  spectrum_descr.scan_mobility_end = q.value(2).toLongLong();
2056 
2057  spectrum_descr.isolationMz = q.value(3).toDouble();
2058  spectrum_descr.isolationWidth = q.value(4).toDouble();
2059  spectrum_descr.collisionEnergy = q.value(5).toFloat();
2060  spectrum_descr.parent_frame = q.value(14).toLongLong();
2061  }
2062  return spectrum_descr;
2063 }
2064 
2065 
2066 void
2068  pappso::TimsData::SpectrumDescr &spectrum_descr, QSqlQuery &qprecursor_list)
2069 {
2070 
2071  spectrum_descr.tims_frame_list.clear();
2072  spectrum_descr.tims_frame_list.push_back(
2073  qprecursor_list.value(0).toLongLong());
2074  // mass_spectrum.setPrecursorCharge(q.value(11).toInt());
2075  // mass_spectrum.setPrecursorMz(q.value(10).toDouble());
2076  // mass_spectrum.setPrecursorIntensity(q.value(13).toDouble());
2077  spectrum_descr.precursor_ion_data =
2078  PrecursorIonData(qprecursor_list.value(10).toDouble(),
2079  qprecursor_list.value(11).toInt(),
2080  qprecursor_list.value(13).toDouble());
2081 
2082  spectrum_descr.precursor_id = qprecursor_list.value(6).toLongLong();
2083  spectrum_descr.ms2_index = (spectrum_descr.precursor_id * 2) - 1;
2084  spectrum_descr.ms1_index = (spectrum_descr.precursor_id * 2) - 2;
2085 
2086  spectrum_descr.scan_mobility_start = qprecursor_list.value(1).toLongLong();
2087  spectrum_descr.scan_mobility_end = qprecursor_list.value(2).toLongLong();
2088 
2089  spectrum_descr.isolationMz = qprecursor_list.value(3).toDouble();
2090  spectrum_descr.isolationWidth = qprecursor_list.value(4).toDouble();
2091  spectrum_descr.collisionEnergy = qprecursor_list.value(5).toFloat();
2092  spectrum_descr.parent_frame = qprecursor_list.value(14).toLongLong();
2093 }
2094 
2095 
2096 void
2098  const pappso::MsRunIdCstSPtr &msrun_id,
2100  unsigned int ms_level)
2101 {
2102 
2103  if(!m_hasPrecursorTable)
2104  {
2105  throw PappsoException(
2106  QObject::tr("unable to read spectrum list : this data file does not "
2107  "contain MS2 data, no precursor found."));
2108  }
2109 
2110  // We'll need it to perform the looping in the spectrum list.
2111  std::size_t spectrum_list_size = getTotalNumberOfScans();
2112 
2113  // qDebug() << "The spectrum list has size:" << spectrum_list_size;
2114 
2115  // Inform the handler of the spectrum list so that it can handle feedback to
2116  // the user.
2117  handler.spectrumListHasSize(spectrum_list_size);
2118 
2119  QSqlDatabase qdb = openDatabaseConnection();
2120  QSqlQuery qprecursor_list = qdb.exec(QString(
2121  "SELECT DISTINCT "
2122  "PasefFrameMsMsInfo.Frame, " // 0
2123  "PasefFrameMsMsInfo.ScanNumBegin, " // 1
2124  "PasefFrameMsMsInfo.ScanNumEnd, " // 2
2125  "PasefFrameMsMsInfo.IsolationMz, " // 3
2126  "PasefFrameMsMsInfo.IsolationWidth, " // 4
2127  "PasefFrameMsMsInfo.CollisionEnergy, " // 5
2128  "PasefFrameMsMsInfo.Precursor, " // 6
2129  "Precursors.Id, " // 7
2130  "Precursors.LargestPeakMz, " // 8
2131  "Precursors.AverageMz, " // 9
2132  "Precursors.MonoisotopicMz, " // 10
2133  "Precursors.Charge, " // 11
2134  "Precursors.ScanNumber, " // 12
2135  "Precursors.Intensity, " // 13
2136  "Precursors.Parent " // 14
2137  "FROM PasefFrameMsMsInfo "
2138  "INNER JOIN Precursors ON "
2139  "PasefFrameMsMsInfo.Precursor=Precursors.Id "
2140  "ORDER BY PasefFrameMsMsInfo.Frame, PasefFrameMsMsInfo.ScanNumBegin ;"));
2141  if(qprecursor_list.lastError().isValid())
2142  {
2143  throw PappsoException(
2144  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
2145  "command %2:\n%3\n%4\n%5")
2146  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
2147  .arg(qprecursor_list.lastQuery())
2148  .arg(qdb.lastError().databaseText())
2149  .arg(qdb.lastError().driverText())
2150  .arg(qdb.lastError().nativeErrorCode()));
2151  }
2152 
2153 
2154  std::size_t i = 0; // iterate on each Spectrum
2155 
2156  qprecursor_list.last(); // strange bug : get the last sql record and get
2157  // back, unless it will not retrieve all records.
2158 
2159  qDebug() << "qprecursor_list.at()=" << qprecursor_list.at();
2160  qprecursor_list.first();
2161 
2162  TimsFrameBaseCstSPtr tims_frame;
2163  SpectrumDescr spectrum_descr;
2164 
2165  for(FrameIdDescr &current_frame : m_frameIdDescrList)
2166  {
2167 
2168  // If the user of this reader instance wants to stop reading the
2169  // spectra, then break this loop.
2170  if(handler.shouldStop())
2171  {
2172  qDebug() << "The operation was cancelled. Breaking the loop.";
2173  throw ExceptionInterrupted(
2174  QObject::tr("reading TimsTOF job cancelled by the user :\n%1")
2175  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf")));
2176  }
2177 
2178  tims_frame = getTimsFrameBaseCstSPtrCached(current_frame.m_frameId);
2179  unsigned int tims_ms_level = tims_frame.get()->getMsLevel();
2180 
2181  if((ms_level != 0) && (ms_level != tims_ms_level))
2182  { // bypass
2183  i += current_frame.m_size;
2184  }
2185  else
2186  {
2187  bool want_binary_data = handler.needMsLevelPeakList(tims_ms_level);
2188  qDebug() << "want_binary_data=" << want_binary_data;
2189  if(want_binary_data)
2190  {
2191  qDebug() << "bindec";
2192  tims_frame = getTimsFrameCstSPtrCached(current_frame.m_frameId);
2193  }
2194 
2195  bool possible_precursor = false;
2196  if(tims_ms_level == 2)
2197  {
2198  // seek the precursor record:
2199  while(qprecursor_list.value(0).toULongLong() <
2200  current_frame.m_frameId)
2201  {
2202  qprecursor_list.next();
2203 
2204  if(qprecursor_list.value(0).toULongLong() ==
2205  current_frame.m_frameId)
2206  {
2207  possible_precursor = true;
2208  }
2209  fillSpectrumDescriptionWithSqlRecord(spectrum_descr,
2210  qprecursor_list);
2211  }
2212  }
2213 
2214  for(std::size_t scan_num = 0; scan_num < current_frame.m_size;
2215  scan_num++)
2216  {
2217  bool has_a_precursor = false;
2218  if(possible_precursor)
2219  {
2220  if(spectrum_descr.scan_mobility_end < scan_num)
2221  {
2222  // seek the precursor record:
2223  while(qprecursor_list.value(0).toULongLong() <
2224  current_frame.m_frameId)
2225  {
2226  qprecursor_list.next();
2227 
2228  if(qprecursor_list.value(0).toULongLong() !=
2229  current_frame.m_frameId)
2230  {
2231  possible_precursor = false;
2232  }
2233  fillSpectrumDescriptionWithSqlRecord(spectrum_descr,
2234  qprecursor_list);
2235  }
2236  }
2237 
2238  if(possible_precursor &&
2239  (spectrum_descr.scan_mobility_start < scan_num))
2240  {
2241  // we are in
2242  has_a_precursor = true;
2243  }
2244  } // end to determine if we are in a precursor for this
2245  // spectrum
2246 
2247  QualifiedMassSpectrum mass_spectrum;
2248 
2249 
2250  MassSpectrumId spectrum_id;
2251 
2252  spectrum_id.setSpectrumIndex(i);
2253  spectrum_id.setMsRunId(msrun_id);
2254  spectrum_id.setNativeId(QString("frame=%1 scan=%2 index=%3")
2255  .arg(current_frame.m_frameId)
2256  .arg(scan_num)
2257  .arg(i));
2258 
2259  mass_spectrum.setMassSpectrumId(spectrum_id);
2260 
2261  mass_spectrum.setMsLevel(tims_frame.get()->getMsLevel());
2262  mass_spectrum.setRtInSeconds(tims_frame.get()->getTime());
2263 
2264  mass_spectrum.setDtInMilliSeconds(
2265  tims_frame.get()->getDriftTime(scan_num));
2266  // 1/K0
2267  mass_spectrum.setParameterValue(
2269  tims_frame.get()->getOneOverK0Transformation(scan_num));
2270 
2271  mass_spectrum.setEmptyMassSpectrum(true);
2272  if(want_binary_data)
2273  {
2274  try
2275  {
2276  mass_spectrum.setMassSpectrumSPtr(
2277  tims_frame.get()->getMassSpectrumSPtr(scan_num));
2278  }
2279  catch(PappsoException &error)
2280  {
2281  throw PappsoException(
2282  QObject::tr(
2283  "ERROR in %1 (scan_num=%2 spectrum_index=%3):\n%4")
2284  .arg(__FUNCTION__)
2285  .arg(scan_num)
2286  .arg(spectrum_id.getSpectrumIndex())
2287  .arg(error.qwhat()));
2288  }
2289  if(mass_spectrum.size() > 0)
2290  {
2291  mass_spectrum.setEmptyMassSpectrum(false);
2292  }
2293  }
2294  else
2295  {
2296  // if(tims_frame.get()->getNbrPeaks(coordinate.second) > 0)
2297  //{
2298  mass_spectrum.setEmptyMassSpectrum(false);
2299  // }
2300  }
2301  if(has_a_precursor)
2302  {
2303  if(spectrum_descr.precursor_id > 0)
2304  {
2305 
2306  mass_spectrum.appendPrecursorIonData(
2307  spectrum_descr.precursor_ion_data);
2308 
2309  std::size_t prec_spectrum_index =
2310  getRawIndexFromCoordinate(spectrum_descr.parent_frame,
2311  scan_num);
2312 
2313  mass_spectrum.setPrecursorSpectrumIndex(
2314  prec_spectrum_index);
2315  mass_spectrum.setPrecursorNativeId(
2316  QString("frame=%1 scan=%2 index=%3")
2317  .arg(spectrum_descr.parent_frame)
2318  .arg(scan_num)
2319  .arg(prec_spectrum_index));
2320 
2321  mass_spectrum.setParameterValue(
2323  spectrum_descr.isolationMz);
2324  mass_spectrum.setParameterValue(
2326  spectrum_descr.isolationWidth);
2327 
2328  mass_spectrum.setParameterValue(
2330  spectrum_descr.collisionEnergy);
2331  mass_spectrum.setParameterValue(
2333  (quint64)spectrum_descr.precursor_id);
2334  }
2335  }
2336 
2337  handler.setQualifiedMassSpectrum(mass_spectrum);
2338  i++;
2339  }
2340  }
2341  }
2342 }
2343 
2344 std::map<quint32, quint32>
2345 TimsData::getRawMsBySpectrumIndex(std::size_t spectrum_index)
2346 {
2347 
2348  qDebug() << " spectrum_index=" << spectrum_index;
2349  auto coordinate = getScanCoordinateFromRawIndex(spectrum_index);
2350  TimsFrameBaseCstSPtr tims_frame;
2351  tims_frame = getTimsFrameCstSPtrCached(coordinate.first);
2352 
2353  std::map<quint32, quint32> raw_spectrum;
2354  tims_frame.get()->cumulateScansInRawMap(
2355  raw_spectrum, coordinate.second, coordinate.second);
2356  return raw_spectrum;
2357 }
2358 
2359 
2360 const std::vector<FrameIdDescr> &
2362 {
2363  return m_frameIdDescrList;
2364 }
2365 
2366 
2367 } // namespace pappso
Trace toTrace() const
Definition: maptrace.cpp:219
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.
Definition: massspectrum.h:71
MzCalibrationInterfaceSPtr getInstance(double T1_frame, double T2_frame, const QSqlRecord &mzcalibration_record)
virtual const QString & qwhat() const
const char * what() const noexcept override
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
Definition: msrunreader.h:56
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
Definition: msrunreader.cpp:70
virtual void spectrumListHasSize(std::size_t size)
Definition: msrunreader.cpp:53
virtual void setQualifiedMassSpectrum(const QualifiedMassSpectrum &spectrum)=0
TimsFrameSPtr getTimsFrameSPtrByOffset(std::size_t frameId, const std::vector< pappso::TimsFrameRecord > &frame_record_list)
Definition: timsbindec.cpp:147
QSqlDatabase openDatabaseConnection() const
Definition: timsdata.cpp:234
TimsFrameCstSPtr getTimsFrameCstSPtr(std::size_t timsId)
get a Tims frame with his database ID
Definition: timsdata.cpp:528
std::vector< FrameIdDescr > m_frameIdDescrList
store every frame id and corresponding sizes
Definition: timsdata.h:332
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
Definition: timsdata.cpp:1628
TimsFrameCstSPtr getTimsFrameCstSPtrCached(std::size_t timsId)
get a Tims frame with his database ID but look in the cache first
Definition: timsdata.cpp:1094
pappso::MassSpectrumCstSPtr getMassSpectrumCstSPtrByRawIndex(std::size_t raw_index)
get a mass spectrum given its spectrum index
Definition: timsdata.cpp:399
void getQualifiedMs1MassSpectrumByPrecursorId(const MsRunIdCstSPtr &msrun_id, QualifiedMassSpectrum &mass_spectrum, const SpectrumDescr &spectrum_descr, bool want_binary_data)
Definition: timsdata.cpp:972
virtual ~TimsData()
Definition: timsdata.cpp:269
SpectrumDescr getSpectrumDescrWithPrecursorId(std::size_t precursor_id)
get an intermediate structure describing a spectrum
Definition: timsdata.cpp:1897
const std::vector< FrameIdDescr > & getFrameIdDescrList() const
Definition: timsdata.cpp:2361
std::size_t getTotalNumberOfFrames() const
Get total number of frames.
Definition: timsdata.cpp:624
void getQualifiedMs2MassSpectrumByPrecursorId(const MsRunIdCstSPtr &msrun_id, QualifiedMassSpectrum &mass_spectrum, const SpectrumDescr &spectrum_descr, bool want_binary_data)
Definition: timsdata.cpp:1416
TimsData(QDir timsDataDirectory)
build using the tims data directory
Definition: timsdata.cpp:47
std::map< quint32, quint32 > getRawMs2ByPrecursorId(std::size_t precursor_index)
get cumulated raw signal for a given precursor only to use to see the raw signal
Definition: timsdata.cpp:1288
std::size_t m_totalNumberOfFrames
Definition: timsdata.h:309
Trace getTicChromatogram() const
Definition: timsdata.cpp:888
TimsFrameBaseCstSPtr getTimsFrameBaseCstSPtrCached(std::size_t timsId)
Definition: timsdata.cpp:1073
std::size_t m_totalNumberOfScans
Definition: timsdata.h:307
std::deque< TimsFrameCstSPtr > m_timsFrameCache
Definition: timsdata.h:311
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:614
std::size_t m_cacheSize
Definition: timsdata.h:310
std::pair< std::size_t, std::size_t > getScanCoordinateFromRawIndex(std::size_t spectrum_index) const
Definition: timsdata.cpp:340
std::vector< TimsFrameRecord > m_mapFramesRecord
Definition: timsdata.h:324
std::vector< std::size_t > getClosestPrecursorIdByMz(std::vector< std::vector< double >> ids, double mz_value)
Definition: timsdata.cpp:749
std::map< int, QSqlRecord > m_mapMzCalibrationRecord
Definition: timsdata.h:322
std::vector< std::size_t > getPrecursorsFromMzRtCharge(int charge, double mz_val, double rt_sec, double k0)
guess possible precursor ids given a charge, m/z, retention time and k0
Definition: timsdata.cpp:644
void fillSpectrumDescriptionWithSqlRecord(SpectrumDescr &spectrum_descr, QSqlQuery &qprecursor_list)
Definition: timsdata.cpp:2067
std::map< int, QSqlRecord > m_mapTimsCalibrationRecord
Definition: timsdata.h:323
QMutex m_mutex
Definition: timsdata.h:350
bool m_builtinMs2Centroid
enable builtin centroid on raw tims integers by default
Definition: timsdata.h:319
void setMs2BuiltinCentroid(bool centroid)
enable or disable simple centroid filter on raw tims data for MS2
Definition: timsdata.cpp:283
void fillFrameIdDescrList()
private function to fill m_frameIdDescrList
Definition: timsdata.cpp:295
TimsFrameBaseCstSPtr getTimsFrameBaseCstSPtr(std::size_t timsId)
get a Tims frame base (no binary data file access) with his database ID
Definition: timsdata.cpp:420
bool m_hasPrecursorTable
Definition: timsdata.h:348
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...
Definition: timsdata.cpp:2097
QDir m_timsDataDirectory
Definition: timsdata.h:304
std::size_t getTotalNumberOfPrecursors() const
get the number of precursors analyzes by PASEF
Definition: timsdata.cpp:638
MzCalibrationStore * mpa_mzCalibrationStore
Definition: timsdata.h:327
std::vector< std::size_t > getTimsMS1FrameIdRange(double rt_begin, double rt_end) const
Definition: timsdata.cpp:492
virtual std::vector< double > getRetentionTimeLine() const
retention timeline get retention times along the MSrun in seconds
Definition: timsdata.cpp:1980
unsigned int getMsLevelBySpectrumIndex(std::size_t spectrum_index)
Definition: timsdata.cpp:773
bool getMs2BuiltinCentroid() const
tells if simple centroid filter on raw tims data for MS2 is enabled or not
Definition: timsdata.cpp:289
SpectrumDescr getSpectrumDescrWithScanCoordinate(const std::pair< std::size_t, std::size_t > &scan_coordinate)
Definition: timsdata.cpp:1995
std::map< quint32, quint32 > getRawMsBySpectrumIndex(std::size_t spectrum_index)
get raw signal for a spectrum index only to use to see the raw signal
Definition: timsdata.cpp:2345
std::deque< TimsFrameBaseCstSPtr > m_timsFrameBaseCache
Definition: timsdata.h:312
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:339
void ms2ReaderGenerateMS1MS2Spectrum(const MsRunIdCstSPtr &msrun_id, std::vector< QualifiedMassSpectrum > &qualified_mass_spectrum_list, SpectrumCollectionHandlerInterface &handler, const SpectrumDescr &spectrum_descr, unsigned int ms_level)
Definition: timsdata.cpp:1863
TimsBinDec * mpa_timsBinDec
Definition: timsdata.h:305
void getQualifiedMassSpectrumByRawIndex(const MsRunIdCstSPtr &msrun_id, QualifiedMassSpectrum &mass_spectrum, std::size_t spectrum_index, bool want_binary_data)
Definition: timsdata.cpp:782
void setMs1FilterCstSPtr(pappso::FilterInterfaceCstSPtr &filter)
filter interface to apply just after raw MS1 specturm extraction the filter can be a list of filters ...
Definition: timsdata.cpp:1176
void setMs2FilterCstSPtr(pappso::FilterInterfaceCstSPtr &filter)
filter interface to apply just after raw MS2 specturm extraction the filter can be a list of filters ...
Definition: timsdata.cpp:1171
pappso::FilterInterfaceCstSPtr mcsp_ms1Filter
Definition: timsdata.h:315
bool m_isMonoThread
Definition: timsdata.h:346
std::size_t getTotalNumberOfScans() const
get the total number of scans
Definition: timsdata.cpp:631
std::vector< std::size_t > getMatchPrecursorIdByKo(std::vector< std::vector< double >> ids, double ko_value)
Definition: timsdata.cpp:723
std::size_t getRawIndexFromCoordinate(std::size_t frame_id, std::size_t scan_num) const
Definition: timsdata.cpp:376
pappso::FilterInterfaceCstSPtr mcsp_ms2Filter
Definition: timsdata.h:314
void setMonoThread(bool is_mono_thread)
set only one is_mono_thread to true
Definition: timsdata.cpp:228
XicCoordTims getXicCoordTimsFromPrecursorId(std::size_t precursor_id, PrecisionPtr precision_ptr)
Definition: timsdata.cpp:1182
std::size_t m_totalNumberOfPrecursors
Definition: timsdata.h:308
virtual MapTrace & combine(MapTrace &map_trace, const Trace &trace) const override
A simple container of DataPoint instances.
Definition: trace.h:148
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition: aa.cpp:39
std::shared_ptr< const TimsFrameBase > TimsFrameBaseCstSPtr
Definition: timsframebase.h:41
std::shared_ptr< TimsFrame > TimsFrameSPtr
Definition: timsframe.h:40
std::shared_ptr< TimsFrameBase > TimsFrameBaseSPtr
Definition: timsframebase.h:39
std::shared_ptr< const MsRunId > MsRunIdCstSPtr
Definition: msrunid.h:44
std::shared_ptr< const MassSpectrum > MassSpectrumCstSPtr
Definition: massspectrum.h:55
@ CollisionEnergy
Bruker's Tims tof collision energy.
@ OneOverK0end
1/k0 of last acquisition for composite pasef MS/MS spectrum
@ IsolationWidth
isolation window width
@ BrukerPrecursorIndex
Bruker's Tims tof precursor index.
@ rt
Retention time.
std::shared_ptr< const FilterInterface > FilterInterfaceCstSPtr
std::shared_ptr< const TimsFrame > TimsFrameCstSPtr
Definition: timsframe.h:42
std::vector< std::size_t > tims_frame_list
Definition: timsdata.h:137
PrecursorIonData precursor_ion_data
Definition: timsdata.h:138
std::size_t tims_calibration_id
coordinates of the XIC to extract and the resulting XIC after extraction
Definition: xiccoordtims.h:51
std::size_t scanNumEnd
mobility index end
Definition: xiccoordtims.h:91
std::size_t scanNumBegin
mobility index begin
Definition: xiccoordtims.h:87
XicSPtr xicSptr
extracted xic
Definition: xiccoord.h:113
double rtTarget
the targeted retention time to extract around intended in seconds, and related to one msrun....
Definition: xiccoord.h:109
MzRange mzRange
the mass to extract
Definition: xiccoord.h:103
main Tims data handler