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