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