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 "../../processing/combiners/tracepluscombiner.h"
31 #include "../../processing/filters/filtertriangle.h"
32 #include "../../processing/filters/filterpseudocentroid.h"
33 #include "../../processing/filters/filterpass.h"
35 #include <QDebug>
36 #include <solvers.h>
37 #include <QSqlError>
38 #include <QSqlQuery>
39 #include <QSqlRecord>
40 #include <QMutexLocker>
41 #include <QThread>
42 #include <set>
43 
44 using namespace pappso;
45 
46 TimsData::TimsData(QDir timsDataDirectory)
47  : m_timsDataDirectory(timsDataDirectory)
48 {
49 
50  qDebug();
52  if(!m_timsDataDirectory.exists())
53  {
54  throw PappsoException(
55  QObject::tr("ERROR TIMS data directory %1 not found")
56  .arg(m_timsDataDirectory.absolutePath()));
57  }
58 
59  if(!QFileInfo(m_timsDataDirectory.absoluteFilePath("analysis.tdf")).exists())
60  {
61 
62  throw PappsoException(
63  QObject::tr("ERROR TIMS data directory, %1 sqlite file not found")
64  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf")));
65  }
66 
67  // Open the database
68  QSqlDatabase qdb = openDatabaseConnection();
69 
70 
71  QSqlQuery q(qdb);
72  if(!q.exec("select Key, Value from GlobalMetadata where "
73  "Key='TimsCompressionType';"))
74  {
75 
76  qDebug();
77  throw PappsoException(
78  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
79  "command %2:\n%3\n%4\n%5")
80  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
81  .arg(q.lastQuery())
82  .arg(q.lastError().databaseText())
83  .arg(q.lastError().driverText())
84  .arg(q.lastError().nativeErrorCode()));
85  }
86 
87 
88  int compression_type = 0;
89  if(q.next())
90  {
91  compression_type = q.value(1).toInt();
92  }
93  qDebug() << " compression_type=" << compression_type;
95  QFileInfo(m_timsDataDirectory.absoluteFilePath("analysis.tdf_bin")),
96  compression_type);
97 
98 
99  // get number of precursors
100  if(!q.exec("SELECT COUNT( DISTINCT Id) FROM Precursors;"))
101  {
102  qDebug();
103  throw PappsoException(
104  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
105  "command %2:\n%3\n%4\n%5")
106  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
107  .arg(q.lastQuery())
108  .arg(qdb.lastError().databaseText())
109  .arg(qdb.lastError().driverText())
110  .arg(qdb.lastError().nativeErrorCode()));
111  }
112  if(q.next())
113  {
114  m_totalNumberOfPrecursors = q.value(0).toLongLong();
115  }
116 
117 
119 
120  // get number of scans
121  if(!q.exec("SELECT SUM(NumScans) FROM Frames"))
122  {
123  qDebug();
124  throw PappsoException(
125  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
126  "command %2:\n%3\n%4\n%5")
127  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
128  .arg(q.lastQuery())
129  .arg(qdb.lastError().databaseText())
130  .arg(qdb.lastError().driverText())
131  .arg(qdb.lastError().nativeErrorCode()));
132  }
133  if(q.next())
134  {
135  m_totalNumberOfScans = q.value(0).toLongLong();
136  }
137 
138  if(!q.exec("select * from MzCalibration;"))
139  {
140  qDebug();
141  throw PappsoException(
142  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
143  "command %2:\n%3\n%4\n%5")
144  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
145  .arg(q.lastQuery())
146  .arg(q.lastError().databaseText())
147  .arg(q.lastError().driverText())
148  .arg(q.lastError().nativeErrorCode()));
149  }
150 
151  while(q.next())
152  {
153  QSqlRecord record = q.record();
155  std::pair<int, QSqlRecord>(record.value(0).toInt(), record));
156  }
157 
158  // m_mapTimsCalibrationRecord
159 
160  if(!q.exec("select * from TimsCalibration;"))
161  {
162  qDebug();
163  throw PappsoException(
164  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
165  "command %2:\n%3\n%4\n%5")
166  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
167  .arg(q.lastQuery())
168  .arg(q.lastError().databaseText())
169  .arg(q.lastError().driverText())
170  .arg(q.lastError().nativeErrorCode()));
171  }
172  while(q.next())
173  {
174  QSqlRecord record = q.record();
176  std::pair<int, QSqlRecord>(record.value(0).toInt(), record));
177  }
178 
179 
180  // store frames
181  if(!q.exec("select Frames.TimsId, Frames.AccumulationTime, " // 1
182  "Frames.MzCalibration, " // 2
183  "Frames.T1, Frames.T2, " // 4
184  "Frames.Time, Frames.MsMsType, Frames.TimsCalibration, " // 7
185  "Frames.Id " // 8
186  " FROM Frames;"))
187  {
188  qDebug();
189  throw PappsoException(
190  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
191  "command %2:\n%3\n%4\n%5")
192  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
193  .arg(q.lastQuery())
194  .arg(q.lastError().databaseText())
195  .arg(q.lastError().driverText())
196  .arg(q.lastError().nativeErrorCode()));
197  }
198  while(q.next())
199  {
200  QSqlRecord record = q.record();
201  m_mapFramesRecord.insert(
202  std::pair<std::size_t, QSqlRecord>(record.value(8).toUInt(), record));
203  }
204 
205 
206  std::shared_ptr<pappso::FilterPseudoCentroid> ms2filter =
207  std::make_shared<pappso::FilterPseudoCentroid>(35000, 5, 0.5, 0.1);
208  mcsp_ms2Filter = ms2filter;
209 
210 
211  std::shared_ptr<FilterTriangle> ms1filter =
212  std::make_shared<FilterTriangle>();
213  ms1filter.get()->setTriangleSlope(50, 0.01);
214  mcsp_ms1Filter = ms1filter;
215 }
216 
217 QSqlDatabase
219 {
220  QString database_connection_name = QString("%1_%2")
221  .arg(m_timsDataDirectory.absolutePath())
222  .arg((quintptr)QThread::currentThread());
223  // Open the database
224  QSqlDatabase qdb = QSqlDatabase::database(database_connection_name);
225  if(!qdb.isValid())
226  {
227  qDebug() << database_connection_name;
228  qdb = QSqlDatabase::addDatabase("QSQLITE", database_connection_name);
229  qdb.setDatabaseName(m_timsDataDirectory.absoluteFilePath("analysis.tdf"));
230  }
231 
232 
233  if(!qdb.open())
234  {
235  qDebug();
236  throw PappsoException(
237  QObject::tr("ERROR opening TIMS sqlite database file %1, database name "
238  "%2 :\n%3\n%4\n%5")
239  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
240  .arg(database_connection_name)
241  .arg(qdb.lastError().databaseText())
242  .arg(qdb.lastError().driverText())
243  .arg(qdb.lastError().nativeErrorCode()));
244  }
245  return qdb;
246 }
247 
248 TimsData::TimsData([[maybe_unused]] const pappso::TimsData &other)
249 {
250  qDebug();
251 }
252 
254 {
255  // m_qdb.close();
256  if(mpa_timsBinDec != nullptr)
257  {
258  delete mpa_timsBinDec;
259  }
260  if(mpa_mzCalibrationStore != nullptr)
261  {
262  delete mpa_mzCalibrationStore;
263  }
264 }
265 
266 void
268 {
269  m_builtinMs2Centroid = centroid;
270 }
271 
272 bool
274 {
275  return m_builtinMs2Centroid;
276 }
277 
278 void
280 {
281 
282  QSqlDatabase qdb = openDatabaseConnection();
283 
284  QSqlQuery q =
285  qdb.exec(QString("SELECT Id, NumScans FROM "
286  "Frames ORDER BY Id"));
287  if(q.lastError().isValid())
288  {
289 
290  throw PappsoException(
291  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
292  "command %2:\n%3\n%4\n%5")
293  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
294  .arg(q.lastQuery())
295  .arg(qdb.lastError().databaseText())
296  .arg(qdb.lastError().driverText())
297  .arg(qdb.lastError().nativeErrorCode()));
298  }
299  pappso::TimsFrameSPtr tims_frame;
300  bool index_found = false;
301  std::size_t timsId;
302  std::size_t numberScans;
303  std::size_t cumulScans = 0;
304  while(q.next() && (!index_found))
305  {
306  timsId = q.value(0).toUInt();
307  numberScans = q.value(1).toUInt();
308 
310  std::pair<std::size_t, std::size_t>((cumulScans % 1000),
311  m_frameIdDescrList.size()));
312 
313  m_frameIdDescrList.push_back({timsId, numberScans, cumulScans});
314  cumulScans += numberScans;
315  }
316 }
317 
318 std::pair<std::size_t, std::size_t>
319 TimsData::getScanCoordinateFromRawIndex(std::size_t raw_index) const
320 {
321 
322  std::size_t modulo = raw_index % 1000;
323  auto map_it = m_thousandIndexToFrameIdDescrListIndex.find(modulo);
324  if(map_it == m_thousandIndexToFrameIdDescrListIndex.end())
325  {
326  throw ExceptionNotFound(
327  QObject::tr("ERROR raw index %1 not found (modulo)").arg(raw_index));
328  }
329  std::size_t start_point_index = map_it->second;
330  while((start_point_index > 0) &&
331  (m_frameIdDescrList[start_point_index].m_cumulSize > raw_index))
332  {
333  start_point_index--;
334  }
335  for(std::size_t i = start_point_index; i < m_frameIdDescrList.size(); i++)
336  {
337 
338  if(raw_index <
339  (m_frameIdDescrList[i].m_cumulSize + m_frameIdDescrList[i].m_size))
340  {
341  return std::pair<std::size_t, std::size_t>(
342  m_frameIdDescrList[i].m_frameId,
343  raw_index - m_frameIdDescrList[i].m_cumulSize);
344  }
345  }
346 
347  throw ExceptionNotFound(
348  QObject::tr("ERROR raw index %1 not found").arg(raw_index));
349 }
350 
351 
352 std::size_t
354  std::size_t scan_num) const
355 {
356 
357  for(auto frameDescr : m_frameIdDescrList)
358  {
359  if(frameDescr.m_frameId == frame_id)
360  {
361  return frameDescr.m_cumulSize + scan_num;
362  }
363  }
364 
365  throw ExceptionNotFound(
366  QObject::tr("ERROR raw index with frame=%1 scan=%2 not found")
367  .arg(frame_id)
368  .arg(scan_num));
369 }
370 
371 /** @brief get a mass spectrum given its spectrum index
372  * @param raw_index a number begining at 0, corresponding to a Tims Scan in
373  * the order they lies in the binary data file
374  */
377 {
378 
379  auto coordinate = getScanCoordinateFromRawIndex(raw_index);
380  return getMassSpectrumCstSPtr(coordinate.first, coordinate.second);
381 }
382 
383 
385 TimsData::getTimsFrameBaseCstSPtr(std::size_t timsId) const
386 {
387 
388  qDebug() << " timsId=" << timsId;
389 
390  auto it_map_record_frames = m_mapFramesRecord.find(timsId);
391  if(it_map_record_frames == m_mapFramesRecord.end())
392  {
393  throw ExceptionNotFound(
394  QObject::tr("ERROR Frames database id %1 not found").arg(timsId));
395  }
396  pappso::TimsFrameBaseSPtr tims_frame;
397 
398 
399  tims_frame = std::make_shared<TimsFrameBase>(
400  TimsFrameBase(timsId, it_map_record_frames->second.value(0).toUInt()));
401 
402  auto it_map_record = m_mapMzCalibrationRecord.find(
403  it_map_record_frames->second.value(2).toInt());
404  if(it_map_record != m_mapMzCalibrationRecord.end())
405  {
406 
407  double T1_frame =
408  it_map_record_frames->second.value(3).toDouble(); // Frames.T1
409  double T2_frame =
410  it_map_record_frames->second.value(4).toDouble(); // Frames.T2
411 
412 
413  tims_frame.get()->setMzCalibrationInterfaceSPtr(
415  T1_frame, T2_frame, it_map_record->second));
416  }
417  else
418  {
419  throw ExceptionNotFound(
420  QObject::tr("ERROR MzCalibration database id %1 not found")
421  .arg(it_map_record_frames->second.value(2).toInt()));
422  }
423 
424  tims_frame.get()->setAccumulationTime(
425  it_map_record_frames->second.value(1).toDouble());
426 
427  tims_frame.get()->setTime(it_map_record_frames->second.value(5).toDouble());
428  tims_frame.get()->setMsMsType(it_map_record_frames->second.value(6).toUInt());
429 
430 
431  auto it_map_record_tims_calibration = m_mapTimsCalibrationRecord.find(
432  it_map_record_frames->second.value(7).toInt());
433  if(it_map_record_tims_calibration != m_mapTimsCalibrationRecord.end())
434  {
435 
436  tims_frame.get()->setTimsCalibration(
437  it_map_record_tims_calibration->second.value(1).toInt(),
438  it_map_record_tims_calibration->second.value(2).toDouble(),
439  it_map_record_tims_calibration->second.value(3).toDouble(),
440  it_map_record_tims_calibration->second.value(4).toDouble(),
441  it_map_record_tims_calibration->second.value(5).toDouble(),
442  it_map_record_tims_calibration->second.value(6).toDouble(),
443  it_map_record_tims_calibration->second.value(7).toDouble(),
444  it_map_record_tims_calibration->second.value(8).toDouble(),
445  it_map_record_tims_calibration->second.value(9).toDouble(),
446  it_map_record_tims_calibration->second.value(10).toDouble(),
447  it_map_record_tims_calibration->second.value(11).toDouble());
448  }
449  else
450  {
451  throw ExceptionNotFound(
452  QObject::tr("ERROR TimsCalibration database id %1 not found")
453  .arg(it_map_record_frames->second.value(7).toInt()));
454  }
455 
456  return tims_frame;
457 }
458 
459 std::vector<std::size_t>
460 TimsData::getTimsMS1FrameIdRange(double rt_begin, double rt_end) const
461 {
462 
463  qDebug() << " rt_begin=" << rt_begin << " rt_end=" << rt_end;
464  std::vector<std::size_t> tims_frameid_list;
465  QSqlDatabase qdb = openDatabaseConnection();
466  QSqlQuery q = qdb.exec(QString("SELECT Frames.Id FROM Frames WHERE "
467  "Frames.MsMsType=0 AND (Frames.Time>=%1) AND "
468  "(Frames.Time<=%2) ORDER BY Frames.Time;")
469  .arg(rt_begin)
470  .arg(rt_end));
471  if(q.lastError().isValid())
472  {
473 
474  throw PappsoException(
475  QObject::tr("ERROR in TIMS sqlite database file %1, database name %2, "
476  "executing SQL "
477  "command %3:\n%4\n%5\n%6")
478  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
479  .arg(qdb.databaseName())
480  .arg(q.lastQuery())
481  .arg(qdb.lastError().databaseText())
482  .arg(qdb.lastError().driverText())
483  .arg(qdb.lastError().nativeErrorCode()));
484  }
485  while(q.next())
486  {
487 
488  tims_frameid_list.push_back(q.value(0).toUInt());
489  }
490  return tims_frameid_list;
491 }
492 
494 TimsData::getTimsFrameCstSPtr(std::size_t timsId) const
495 {
496 
497  qDebug() << " timsId=" << timsId
498  << " m_mapFramesRecord.size()=" << m_mapFramesRecord.size();
499  /*
500  for(auto pair_i : m_mapFramesRecord)
501  {
502 
503  qDebug() << " pair_i=" << pair_i.first;
504  }
505  */
506 
507  auto it_map_record_frames = m_mapFramesRecord.find(timsId);
508  if(it_map_record_frames == m_mapFramesRecord.end())
509  {
510 
511  throw ExceptionNotFound(
512  QObject::tr("ERROR Frames database id %1 not found").arg(timsId));
513  }
514 
515 
516  pappso::TimsFrameSPtr tims_frame;
517 
518 
520  timsId, it_map_record_frames->second.value(0).toUInt());
521 
522  qDebug();
523  auto it_map_record = m_mapMzCalibrationRecord.find(
524  it_map_record_frames->second.value(2).toInt());
525  if(it_map_record != m_mapMzCalibrationRecord.end())
526  {
527 
528  double T1_frame =
529  it_map_record_frames->second.value(3).toDouble(); // Frames.T1
530  double T2_frame =
531  it_map_record_frames->second.value(4).toDouble(); // Frames.T2
532 
533 
534  tims_frame.get()->setMzCalibrationInterfaceSPtr(
536  T1_frame, T2_frame, it_map_record->second));
537  }
538  else
539  {
540  throw ExceptionNotFound(
541  QObject::tr("ERROR MzCalibration database id %1 not found")
542  .arg(it_map_record_frames->second.value(2).toInt()));
543  }
544 
545  tims_frame.get()->setAccumulationTime(
546  it_map_record_frames->second.value(1).toDouble());
547 
548  tims_frame.get()->setTime(it_map_record_frames->second.value(5).toDouble());
549  tims_frame.get()->setMsMsType(it_map_record_frames->second.value(6).toUInt());
550 
551  qDebug();
552  auto it_map_record_tims_calibration = m_mapTimsCalibrationRecord.find(
553  it_map_record_frames->second.value(7).toInt());
554  if(it_map_record_tims_calibration != m_mapTimsCalibrationRecord.end())
555  {
556 
557  tims_frame.get()->setTimsCalibration(
558  it_map_record_tims_calibration->second.value(1).toInt(),
559  it_map_record_tims_calibration->second.value(2).toDouble(),
560  it_map_record_tims_calibration->second.value(3).toDouble(),
561  it_map_record_tims_calibration->second.value(4).toDouble(),
562  it_map_record_tims_calibration->second.value(5).toDouble(),
563  it_map_record_tims_calibration->second.value(6).toDouble(),
564  it_map_record_tims_calibration->second.value(7).toDouble(),
565  it_map_record_tims_calibration->second.value(8).toDouble(),
566  it_map_record_tims_calibration->second.value(9).toDouble(),
567  it_map_record_tims_calibration->second.value(10).toDouble(),
568  it_map_record_tims_calibration->second.value(11).toDouble());
569  }
570  else
571  {
572  throw ExceptionNotFound(
573  QObject::tr("ERROR TimsCalibration database id %1 not found")
574  .arg(it_map_record_frames->second.value(7).toInt()));
575  }
576  qDebug();
577  return tims_frame;
578 }
579 
580 
582 TimsData::getMassSpectrumCstSPtr(std::size_t timsId, std::size_t scanNum)
583 {
585 
586  return frame->getMassSpectrumCstSPtr(scanNum);
587 }
588 
589 std::size_t
591 {
592  return m_totalNumberOfScans;
593 }
594 
595 
596 std::size_t
598 {
600 }
601 
602 std::vector<std::size_t>
604  double mz_val,
605  double rt_sec,
606  double k0)
607 {
608  std::vector<std::size_t> precursor_ids;
609  std::vector<std::vector<double>> ids;
610 
611  QSqlDatabase qdb = openDatabaseConnection();
612  QSqlQuery q = qdb.exec(
613  QString(
614  "SELECT Frames.time, Precursors.MonoisotopicMz, Precursors.Charge, "
615  "Precursors.Id, Frames.Id, PasefFrameMsMsInfo.ScanNumBegin, "
616  "PasefFrameMsMsInfo.scanNumEnd "
617  "FROM Frames "
618  "INNER JOIN PasefFrameMsMsInfo ON Frames.Id = PasefFrameMsMsInfo.Frame "
619  "INNER JOIN Precursors ON PasefFrameMsMsInfo.Precursor = Precursors.Id "
620  "WHERE Precursors.Charge == %1 "
621  "AND Precursors.MonoisotopicMz > %2 -0.01 "
622  "AND Precursors.MonoisotopicMz < %2 +0.01 "
623  "AND Frames.Time >= %3 "
624  "AND Frames.Time < %3 +1; ")
625  .arg(charge)
626  .arg(mz_val)
627  .arg(rt_sec));
628  if(q.lastError().isValid())
629  {
630 
631  throw PappsoException(
632  QObject::tr("ERROR in TIMS sqlite database file %1, database name %2, "
633  "executing SQL "
634  "command %3:\n%4\n%5\n%6")
635  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
636  .arg(qdb.databaseName())
637  .arg(q.lastQuery())
638  .arg(qdb.lastError().databaseText())
639  .arg(qdb.lastError().driverText())
640  .arg(qdb.lastError().nativeErrorCode()));
641  }
642  while(q.next())
643  {
644  // qInfo() << q.value(0).toDouble() << q.value(1).toDouble()
645  // << q.value(2).toDouble() << q.value(3).toDouble();
646 
647  std::vector<double> sql_values;
648  sql_values.push_back(q.value(4).toDouble()); // frame id
649  sql_values.push_back(q.value(3).toDouble()); // precursor id
650  sql_values.push_back(q.value(5).toDouble()); // scan num begin
651  sql_values.push_back(q.value(6).toDouble()); // scan num end
652  sql_values.push_back(q.value(1).toDouble()); // mz_value
653 
654  ids.push_back(sql_values);
655 
656 
657  if(std::find(precursor_ids.begin(),
658  precursor_ids.end(),
659  q.value(3).toDouble()) == precursor_ids.end())
660  {
661  precursor_ids.push_back(q.value(3).toDouble());
662  }
663  }
664 
665  if(precursor_ids.size() > 1)
666  {
667  // std::vector<std::size_t> precursor_ids_ko =
668  // getMatchPrecursorIdByKo(ids, values[3]);
669  if(precursor_ids.size() > 1)
670  {
671  precursor_ids = getClosestPrecursorIdByMz(ids, k0);
672  }
673  return precursor_ids;
674  }
675  else
676  {
677  return precursor_ids;
678  }
679 }
680 
681 std::vector<std::size_t>
682 TimsData::getMatchPrecursorIdByKo(std::vector<std::vector<double>> ids,
683  double ko_value)
684 {
685  std::vector<std::size_t> precursor_id;
686  for(std::vector<double> index : ids)
687  {
688  auto coordinate = getScanCoordinateFromRawIndex(index[0]);
689 
690  TimsFrameBaseCstSPtr tims_frame;
691  tims_frame = getTimsFrameBaseCstSPtrCached(coordinate.first);
692 
693  double bko = tims_frame.get()->getOneOverK0Transformation(index[2]);
694  double eko = tims_frame.get()->getOneOverK0Transformation(index[3]);
695 
696  // qInfo() << "diff" << (bko + eko) / 2;
697  double mean_ko = (bko + eko) / 2;
698 
699  if(mean_ko > ko_value - 0.1 && mean_ko < ko_value + 0.1)
700  {
701  precursor_id.push_back(index[1]);
702  }
703  }
704  return precursor_id;
705 }
706 
707 std::vector<std::size_t>
708 TimsData::getClosestPrecursorIdByMz(std::vector<std::vector<double>> ids,
709  double mz_value)
710 {
711  std::vector<std::size_t> best_precursor;
712  double best_value = 1;
713  int count = 1;
714  int best_val_position = 0;
715 
716  for(std::vector<double> values : ids)
717  {
718  double new_val = abs(mz_value - values[4]);
719  if(new_val < best_value)
720  {
721  best_value = new_val;
722  best_val_position = count;
723  }
724  count++;
725  }
726  best_precursor.push_back(ids[best_val_position][1]);
727  return best_precursor;
728 }
729 
730 
731 unsigned int
732 TimsData::getMsLevelBySpectrumIndex(std::size_t spectrum_index)
733 {
734  auto coordinate = getScanCoordinateFromRawIndex(spectrum_index);
735  auto tims_frame = getTimsFrameCstSPtrCached(coordinate.first);
736  return tims_frame.get()->getMsLevel();
737 }
738 
739 
742  bool want_binary_data)
743 {
744  auto coordinate = getScanCoordinateFromRawIndex(spectrum_index);
745  TimsFrameBaseCstSPtr tims_frame;
746  if(want_binary_data)
747  {
748  tims_frame = getTimsFrameCstSPtrCached(coordinate.first);
749  }
750  else
751  {
752  tims_frame = getTimsFrameBaseCstSPtrCached(coordinate.first);
753  }
754  QualifiedMassSpectrum mass_spectrum;
755  MassSpectrumId spectrum_id;
756 
757  spectrum_id.setSpectrumIndex(spectrum_index);
758  spectrum_id.setNativeId(QString("frame=%1 scan=%2 index=%3")
759  .arg(coordinate.first)
760  .arg(coordinate.second)
761  .arg(spectrum_index));
762 
763  mass_spectrum.setMassSpectrumId(spectrum_id);
764 
765  mass_spectrum.setMsLevel(tims_frame.get()->getMsLevel());
766  mass_spectrum.setRtInSeconds(tims_frame.get()->getTime());
767 
768  mass_spectrum.setDtInMilliSeconds(
769  tims_frame.get()->getDriftTime(coordinate.second));
770  // 1/K0
771  mass_spectrum.setParameterValue(
773  tims_frame.get()->getOneOverK0Transformation(coordinate.second));
774 
775  mass_spectrum.setEmptyMassSpectrum(true);
776  if(want_binary_data)
777  {
778  mass_spectrum.setMassSpectrumSPtr(
779  tims_frame.get()->getMassSpectrumSPtr(coordinate.second));
780  if(mass_spectrum.size() > 0)
781  {
782  mass_spectrum.setEmptyMassSpectrum(false);
783  }
784  }
785  else
786  {
787  // if(tims_frame.get()->getNbrPeaks(coordinate.second) > 0)
788  //{
789  mass_spectrum.setEmptyMassSpectrum(false);
790  // }
791  }
792  if(tims_frame.get()->getMsLevel() > 1)
793  {
794 
795  QSqlDatabase qdb = openDatabaseConnection();
796  QSqlQuery q = qdb.exec(
797  QString(
798  "SELECT PasefFrameMsMsInfo.*, Precursors.* FROM "
799  "PasefFrameMsMsInfo INNER JOIN Precursors ON "
800  "PasefFrameMsMsInfo.Precursor=Precursors.Id where "
801  "PasefFrameMsMsInfo.Frame=%1 and (PasefFrameMsMsInfo.ScanNumBegin "
802  "<= %2 and PasefFrameMsMsInfo.ScanNumEnd >= %2);")
803  .arg(coordinate.first)
804  .arg(coordinate.second));
805  if(q.lastError().isValid())
806  {
807  throw PappsoException(
808  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
809  "command %2:\n%3\n%4\n%5")
810  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
811  .arg(q.lastQuery())
812  .arg(qdb.lastError().databaseText())
813  .arg(qdb.lastError().driverText())
814  .arg(qdb.lastError().nativeErrorCode()));
815  }
816  if(q.next())
817  {
818  // mass_spectrum.setPrecursorCharge(q.value(11).toInt());
819  // mass_spectrum.setPrecursorMz(q.value(10).toDouble());
820  // mass_spectrum.setPrecursorIntensity(q.value(13).toDouble());
821  // mass_spectrum.setPrecursorSpectrumIndex();
822 
823  mass_spectrum.appendPrecursorIonData(
824  PrecursorIonData(q.value(10).toDouble(),
825  q.value(11).toInt(),
826  q.value(13).toDouble()));
827 
828 
829  MassSpectrumId spectrum_id;
830  std::size_t prec_spectrum_index = getRawIndexFromCoordinate(
831  q.value(14).toDouble(), coordinate.second);
832 
833  mass_spectrum.setPrecursorSpectrumIndex(prec_spectrum_index);
834  mass_spectrum.setPrecursorNativeId(
835  QString("frame=%1 scan=%2 index=%3")
836  .arg(q.value(14).toDouble())
837  .arg(coordinate.second)
838  .arg(prec_spectrum_index));
839 
840  mass_spectrum.setParameterValue(
841  QualifiedMassSpectrumParameter::IsolationMz, q.value(3).toDouble());
842  mass_spectrum.setParameterValue(
844  q.value(4).toDouble());
845 
846  mass_spectrum.setParameterValue(
848  q.value(5).toFloat());
849  mass_spectrum.setParameterValue(
851  q.value(6).toInt());
852  }
853  }
854 
855  return mass_spectrum;
856 }
857 
858 
861  std::size_t precursor_index,
862  bool want_binary_data)
863 {
864  QualifiedMassSpectrum mass_spectrum;
865 
866  try
867  {
868  QSqlDatabase qdb = openDatabaseConnection();
869  mass_spectrum.setMsLevel(1);
870  mass_spectrum.setPrecursorSpectrumIndex(0);
871  mass_spectrum.setEmptyMassSpectrum(true);
872  QSqlQuery q =
873  qdb.exec(QString("SELECT PasefFrameMsMsInfo.*, Precursors.* FROM "
874  "PasefFrameMsMsInfo INNER JOIN Precursors ON "
875  "PasefFrameMsMsInfo.Precursor=Precursors.Id where "
876  "Precursors.Id=%1;")
877  .arg(precursor_index));
878  if(q.lastError().isValid())
879  {
880 
881  throw PappsoException(
882  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
883  "command %2:\n%3\n%4\n%5")
884  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
885  .arg(q.lastQuery())
886  .arg(qdb.lastError().databaseText())
887  .arg(qdb.lastError().driverText())
888  .arg(qdb.lastError().nativeErrorCode()));
889  }
890  if(q.size() == 0)
891  {
892 
893  throw ExceptionNotFound(
894  QObject::tr(
895  "ERROR in getQualifiedMassSpectrumByPrecursorId, precursor "
896  "id=%1 not found")
897  .arg(precursor_index));
898  }
899  else
900  {
901  TracePlusCombiner combiner;
902  MapTrace combiner_result;
903 
904 
905  bool first = true;
906  std::size_t scan_mobility_start = 0;
907  std::size_t scan_mobility_end = 0;
908  std::set<std::size_t> tims_frame_list;
909  while(q.next())
910  {
911  // get MS1 frame
912  tims_frame_list.insert(q.value(14).toLongLong());
913  if(first)
914  {
915 
916 
917  MassSpectrumId spectrum_id;
918 
919  spectrum_id.setSpectrumIndex(precursor_index);
920  spectrum_id.setNativeId(
921  QString("frame=%1 begin=%2 end=%3 precursor=%4 idxms2=%5")
922  .arg(q.value(0).toLongLong())
923  .arg(q.value(1).toLongLong())
924  .arg(q.value(2).toLongLong())
925  .arg(precursor_index)
926  .arg(ms2_index));
927 
928 
929  mass_spectrum.setMassSpectrumId(spectrum_id);
930 
931 
932  scan_mobility_start = q.value(1).toLongLong();
933  scan_mobility_end = q.value(2).toLongLong();
934 
935  first = false;
936  }
937  }
938 
939  first = true;
940  for(std::size_t tims_id : tims_frame_list)
941  {
942  TimsFrameBaseCstSPtr tims_frame =
943  getTimsFrameCstSPtrCached(tims_id);
944  if(first)
945  {
946  mass_spectrum.setRtInSeconds(tims_frame.get()->getTime());
947 
948  mass_spectrum.setParameterValue(
950  tims_frame.get()->getOneOverK0Transformation(
951  scan_mobility_start));
952 
953  mass_spectrum.setParameterValue(
955  tims_frame.get()->getOneOverK0Transformation(
956  scan_mobility_end));
957 
958  first = false;
959  }
960 
961 
962  if(want_binary_data)
963  {
964  combiner.combine(combiner_result,
965  tims_frame.get()->cumulateScanToTrace(
966  scan_mobility_start, scan_mobility_end));
967  }
968  else
969  {
970  break;
971  }
972  }
973 
974 
975  if(first == true)
976  {
977  throw ExceptionNotFound(
978  QObject::tr(
979  "ERROR in getQualifiedMassSpectrumByPrecursorId, precursor "
980  "id=%1 not found")
981  .arg(precursor_index));
982  }
983 
984 
985  if(want_binary_data)
986  {
987 
988  pappso::Trace trace(combiner_result);
989  qDebug();
990 
991  if(trace.size() > 0)
992  {
993  if(mcsp_ms1Filter != nullptr)
994  {
995  mcsp_ms1Filter->filter(trace);
996  }
997 
998  qDebug();
999  mass_spectrum.setMassSpectrumSPtr(
1000  MassSpectrum(trace).makeMassSpectrumSPtr());
1001  mass_spectrum.setEmptyMassSpectrum(false);
1002  }
1003  else
1004  {
1005  mass_spectrum.setMassSpectrumSPtr(nullptr);
1006  mass_spectrum.setEmptyMassSpectrum(true);
1007  }
1008  }
1009  }
1010  }
1011 
1012  catch(PappsoException &error)
1013  {
1014  throw error;
1015  }
1016  catch(std::exception &error)
1017  {
1018  qDebug() << QString("Failure %1 ").arg(error.what());
1019  }
1020  return mass_spectrum;
1021 }
1022 
1023 
1024 void
1026  QualifiedMassSpectrum &mass_spectrum,
1027  std::size_t ms2_index,
1028  std::size_t precursor_index,
1029  bool want_binary_data)
1030 {
1031  qDebug();
1032  try
1033  {
1034  QSqlDatabase qdb = openDatabaseConnection();
1035  MassSpectrumId spectrum_id;
1036 
1037  spectrum_id.setSpectrumIndex(precursor_index);
1038  spectrum_id.setNativeId(
1039  QString("precursor=%1 idxms2=%2").arg(precursor_index).arg(ms2_index));
1040 
1041  mass_spectrum.setMassSpectrumId(spectrum_id);
1042 
1043  mass_spectrum.setMsLevel(2);
1044  mass_spectrum.setPrecursorSpectrumIndex(ms2_index - 1);
1045 
1046  mass_spectrum.setEmptyMassSpectrum(true);
1047 
1048  qdb = openDatabaseConnection();
1049  // m_mutex.lock();
1050  // if(m_query != nullptr)
1051  // {
1052  // *m_query =
1053  // qdb.exec(QString("SELECT PasefFrameMsMsInfo.*, Precursors.*
1054  // FROM "
1055  // "PasefFrameMsMsInfo INNER JOIN Precursors ON "
1056  // "PasefFrameMsMsInfo.Precursor=Precursors.Id
1057  // where " "Precursors.Id=%1;")
1058  // .arg(precursor_index));
1059  // }
1060  QSqlQuery q =
1061  qdb.exec(QString("SELECT PasefFrameMsMsInfo.*, Precursors.* FROM "
1062  "PasefFrameMsMsInfo INNER JOIN Precursors ON "
1063  "PasefFrameMsMsInfo.Precursor=Precursors.Id where "
1064  "Precursors.Id=%1;")
1065  .arg(precursor_index));
1066  if(q.lastError().isValid())
1067  {
1068  qDebug();
1069  throw PappsoException(
1070  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
1071  "command %2:\n%3\n%4\n%5")
1072  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
1073  .arg(q.lastQuery())
1074  .arg(qdb.lastError().databaseText())
1075  .arg(qdb.lastError().driverText())
1076  .arg(qdb.lastError().nativeErrorCode()));
1077  }
1078  qDebug();
1079  // m_mutex.unlock();
1080  if(q.size() == 0)
1081  {
1082 
1083  throw ExceptionNotFound(
1084  QObject::tr(
1085  "ERROR in getQualifiedMassSpectrumByPrecursorId, precursor "
1086  "id=%1 not found")
1087  .arg(precursor_index));
1088  }
1089  else
1090  {
1091  // qDebug() << " q.size()="<< q.size();
1092  qDebug();
1093  bool first = true;
1094  std::size_t scan_mobility_start = 0;
1095  std::size_t scan_mobility_end = 0;
1096  std::vector<std::size_t> tims_frame_list;
1097 
1098  while(q.next())
1099  {
1100  tims_frame_list.push_back(q.value(0).toLongLong());
1101  if(first)
1102  {
1103  // mass_spectrum.setPrecursorCharge(q.value(11).toInt());
1104  // mass_spectrum.setPrecursorMz(q.value(10).toDouble());
1105  // mass_spectrum.setPrecursorIntensity(q.value(13).toDouble());
1106 
1107  mass_spectrum.appendPrecursorIonData(
1108  PrecursorIonData(q.value(10).toDouble(),
1109  q.value(11).toInt(),
1110  q.value(13).toDouble()));
1111 
1112  mass_spectrum.setPrecursorNativeId(
1113  QString("frame=%1 begin=%2 end=%3 precursor=%4 idxms2=%5")
1114  .arg(q.value(14).toLongLong())
1115  .arg(q.value(1).toLongLong())
1116  .arg(q.value(2).toLongLong())
1117  .arg(precursor_index)
1118  .arg(ms2_index - 1));
1119  // mass_spectrum.setPrecursorSpectrumIndex();
1120 
1121  scan_mobility_start = q.value(1).toLongLong();
1122  scan_mobility_end = q.value(2).toLongLong();
1123 
1124  mass_spectrum.setParameterValue(
1126  q.value(3).toDouble());
1127  mass_spectrum.setParameterValue(
1129  q.value(4).toDouble());
1130 
1131  mass_spectrum.setParameterValue(
1133  q.value(5).toFloat());
1134  mass_spectrum.setParameterValue(
1136  q.value(6).toInt());
1137 
1138  first = false;
1139  }
1140  }
1141  // QMutexLocker locker(&m_mutex_spectrum);
1142  qDebug();
1143  pappso::TimsFrameCstSPtr tims_frame, previous_frame;
1144  // TracePlusCombiner combiner;
1145  // MapTrace combiner_result;
1146  std::map<quint32, quint32> raw_spectrum;
1147  first = true;
1148  for(std::size_t tims_id : tims_frame_list)
1149  {
1150 
1151  tims_frame = getTimsFrameCstSPtrCached(tims_id);
1152  if(first)
1153  {
1154  mass_spectrum.setRtInSeconds(tims_frame.get()->getTime());
1155 
1156  mass_spectrum.setParameterValue(
1158  tims_frame.get()->getOneOverK0Transformation(
1159  scan_mobility_start));
1160 
1161  mass_spectrum.setParameterValue(
1163  tims_frame.get()->getOneOverK0Transformation(
1164  scan_mobility_end));
1165 
1166  first = false;
1167  }
1168 
1169 
1170  if(want_binary_data)
1171  {
1172  qDebug();
1173  /*combiner.combine(combiner_result,
1174  tims_frame.get()->cumulateScanToTrace(
1175  scan_mobility_start, scan_mobility_end));*/
1176  if(previous_frame.get() != nullptr)
1177  {
1178  if(previous_frame.get()->hasSameCalibrationData(
1179  *tims_frame.get()))
1180  {
1181  }
1182  else
1183  {
1184  throw ExceptionNotFound(
1185  QObject::tr(
1186  "ERROR in %1 %2, different calibration data "
1187  "between frame id %3 and frame id %4")
1188  .arg(__FILE__)
1189  .arg(__FUNCTION__)
1190  .arg(previous_frame.get()->getId())
1191  .arg(tims_frame.get()->getId()));
1192  }
1193  }
1194  tims_frame.get()->cumulateScansInRawMap(
1195  raw_spectrum, scan_mobility_start, scan_mobility_end);
1196  qDebug();
1197  }
1198  previous_frame = tims_frame;
1199  }
1200  qDebug() << " precursor_index=" << precursor_index
1201  << " num_rows=" << tims_frame_list.size()
1202  << " sql=" << q.lastQuery() << " "
1203  << (std::size_t)QThread::currentThreadId();
1204  if(first == true)
1205  {
1206  throw ExceptionNotFound(
1207  QObject::tr(
1208  "ERROR in getQualifiedMassSpectrumByPrecursorId, precursor "
1209  "id=%1 not found")
1210  .arg(precursor_index));
1211  }
1212  if(want_binary_data)
1213  {
1214  qDebug();
1215  // peak_pick.filter(trace);
1216  pappso::Trace trace;
1218  {
1219  trace =
1220  tims_frame.get()->getTraceFromCumulatedScansBuiltinCentroid(
1221  raw_spectrum);
1222  }
1223  else
1224  {
1225  // no builtin centroid:
1226 
1227  trace =
1228  tims_frame.get()->getTraceFromCumulatedScans(raw_spectrum);
1229  }
1230 
1231  if(trace.size() > 0)
1232  {
1233  qDebug() << trace.size() << " "
1234  << (std::size_t)QThread::currentThreadId();
1235 
1236  if(mcsp_ms2Filter != nullptr)
1237  {
1238  // FilterTriangle filter;
1239  // filter.setTriangleSlope(50, 0.02);
1240  // filter.filter(trace);
1241  // trace.filter(pappso::FilterHighPass(10));
1242  mcsp_ms2Filter->filter(trace);
1243  }
1244 
1245  // FilterScaleFactorY filter_scale((double)1 /
1246  // (double)tims_frame_list.size());
1247  // filter_scale.filter(trace);
1248  qDebug();
1249  mass_spectrum.setMassSpectrumSPtr(
1250  MassSpectrum(trace).makeMassSpectrumSPtr());
1251  mass_spectrum.setEmptyMassSpectrum(false);
1252  }
1253  else
1254  {
1255  mass_spectrum.setMassSpectrumSPtr(nullptr);
1256  mass_spectrum.setEmptyMassSpectrum(true);
1257  }
1258 
1259  qDebug();
1260  }
1261  qDebug();
1262  }
1263  }
1264 
1265  catch(PappsoException &error)
1266  {
1267  throw error;
1268  }
1269  catch(std::exception &error)
1270  {
1271  qDebug() << QString("Failure %1 ").arg(error.what());
1272  }
1273  qDebug();
1274 }
1275 
1276 
1279 {
1280  QMutexLocker locker(&m_mutex);
1281  for(auto &tims_frame : m_timsFrameBaseCache)
1282  {
1283  if(tims_frame.get()->getId() == timsId)
1284  {
1285  m_timsFrameBaseCache.push_back(tims_frame);
1286  return tims_frame;
1287  }
1288  }
1289 
1290  m_timsFrameBaseCache.push_back(getTimsFrameBaseCstSPtr(timsId));
1291  if(m_timsFrameBaseCache.size() > m_cacheSize)
1292  m_timsFrameBaseCache.pop_front();
1293  return m_timsFrameBaseCache.back();
1294 }
1295 
1298 {
1299  QMutexLocker locker(&m_mutex);
1300  for(auto &tims_frame : m_timsFrameCache)
1301  {
1302  if(tims_frame.get()->getId() == timsId)
1303  {
1304  m_timsFrameCache.push_back(tims_frame);
1305  return tims_frame;
1306  }
1307  }
1308 
1309  m_timsFrameCache.push_back(getTimsFrameCstSPtr(timsId));
1310  if(m_timsFrameCache.size() > m_cacheSize)
1311  m_timsFrameCache.pop_front();
1312  return m_timsFrameCache.back();
1313 }
1314 
1315 void
1317 {
1318  mcsp_ms2Filter = filter;
1319 }
1320 void
1322 {
1323  mcsp_ms1Filter = filter;
1324 }
1325 
1326 std::vector<TimsXicStructure>
1328  const std::vector<std::size_t> &precursor_id_list,
1329  PrecisionPtr precision_ptr,
1330  XicExtractMethod xicExtractMethod,
1331  double rtRange) const
1332 {
1333 
1334  qDebug();
1335  std::vector<TimsXicStructure> xic_list;
1336 
1337  try
1338  {
1339  QSqlDatabase qdb = openDatabaseConnection();
1340 
1341  for(auto precursor_id : precursor_id_list)
1342  {
1343  QSqlQuery q = qdb.exec(
1344  QString("SELECT Frames.Time, "
1345  "PasefFrameMsMsInfo.Frame,PasefFrameMsMsInfo.ScanNumBegin,"
1346  "PasefFrameMsMsInfo.ScanNumEnd, Precursors.MonoisotopicMz, "
1347  "Precursors.Charge FROM "
1348  "PasefFrameMsMsInfo INNER JOIN Precursors ON "
1349  "PasefFrameMsMsInfo.Precursor=Precursors.Id INNER JOIN "
1350  "Frames ON PasefFrameMsMsInfo.Frame=Frames.Id where "
1351  "Precursors.Id=%1;")
1352  .arg(precursor_id));
1353  if(q.lastError().isValid())
1354  {
1355  qDebug();
1356  throw PappsoException(
1357  QObject::tr(
1358  "ERROR in TIMS sqlite database file %1, executing SQL "
1359  "command %2:\n%3\n%4\n%5")
1360  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
1361  .arg(q.lastQuery())
1362  .arg(qdb.lastError().databaseText())
1363  .arg(qdb.lastError().driverText())
1364  .arg(qdb.lastError().nativeErrorCode()));
1365  }
1366 
1367  while(q.next())
1368  {
1369  // Frame, ScanNumBegin, ScanNumEnd, IsolationMz, ColliqionEnergy,
1370  // Precursor
1371  // Id, LargestPeakMz, AverageMz, MonoisotopicMz, Charge,
1372  // ScanNumber, Intensity, Parent
1373  TimsXicStructure xic_structure;
1374 
1375  xic_structure.precursorId = precursor_id;
1376  xic_structure.mzRange =
1377  MzRange(q.value(4).toDouble(), precision_ptr);
1378  xic_structure.scanNumBegin = q.value(2).toUInt();
1379  xic_structure.scanNumEnd = q.value(3).toUInt();
1380  xic_structure.rtTarget = q.value(0).toDouble();
1381  // xic_structure.charge = q.value(5).toUInt();
1382  xic_structure.xicSptr = std::make_shared<Xic>();
1383 
1384  xic_list.push_back(xic_structure);
1385  }
1386  }
1387  qDebug();
1388 
1389  TimsXicExtractorInterface *extractor_p = new TimsDirectXicExtractor(this);
1390  extractor_p->setXicExtractMethod(xicExtractMethod);
1391  extractor_p->extractTimsXicList(xic_list, rtRange);
1392  }
1393  catch(PappsoException &error)
1394  {
1395  throw error;
1396  }
1397  catch(std::exception &error)
1398  {
1399  qDebug() << QString("Failure %1 ").arg(error.what());
1400  }
1401 
1402  qDebug();
1403  return xic_list;
1404 }
1405 
1406 void
1408  std::vector<TimsXicStructure> &tims_xic_structure_list,
1409  pappso::XicExtractMethod xicExtractMethod,
1410  double rtRange) const
1411 {
1412  try
1413  {
1414 
1415  TimsXicExtractorInterface *extractor_p = new TimsDirectXicExtractor(this);
1416  extractor_p->setXicExtractMethod(xicExtractMethod);
1417  extractor_p->extractTimsXicList(tims_xic_structure_list, rtRange);
1418  }
1419  catch(PappsoException &error)
1420  {
1421  throw error;
1422  }
1423  catch(std::exception &error)
1424  {
1425  qDebug() << QString("Failure %1 ").arg(error.what());
1426  }
1427 
1428  qDebug();
1429 }
1430 
1431 
1434  std::size_t precursor_id, PrecisionPtr precision_ptr) const
1435 {
1436 
1437  qDebug();
1438  TimsXicStructure tims_xic_structure;
1439 
1440  try
1441  {
1442  QSqlDatabase qdb = openDatabaseConnection();
1443  QSqlQuery q = qdb.exec(
1444  QString("SELECT Frames.Time, "
1445  "PasefFrameMsMsInfo.Frame,PasefFrameMsMsInfo.ScanNumBegin,"
1446  "PasefFrameMsMsInfo.ScanNumEnd, Precursors.MonoisotopicMz, "
1447  "Precursors.Charge FROM "
1448  "PasefFrameMsMsInfo INNER JOIN Precursors ON "
1449  "PasefFrameMsMsInfo.Precursor=Precursors.Id INNER JOIN "
1450  "Frames ON PasefFrameMsMsInfo.Frame=Frames.Id where "
1451  "Precursors.Id=%1;")
1452  .arg(precursor_id));
1453  if(q.lastError().isValid())
1454  {
1455  qDebug();
1456  throw PappsoException(
1457  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
1458  "command %2:\n%3\n%4\n%5")
1459  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
1460  .arg(q.lastQuery())
1461  .arg(qdb.lastError().databaseText())
1462  .arg(qdb.lastError().driverText())
1463  .arg(qdb.lastError().nativeErrorCode()));
1464  }
1465 
1466  while(q.next())
1467  {
1468  // Frame, ScanNumBegin, ScanNumEnd, IsolationMz, ColliqionEnergy,
1469  // Precursor
1470  // Id, LargestPeakMz, AverageMz, MonoisotopicMz, Charge,
1471  // ScanNumber, Intensity, Parent
1472 
1473  tims_xic_structure.precursorId = precursor_id;
1474  tims_xic_structure.mzRange =
1475  MzRange(q.value(4).toDouble(), precision_ptr);
1476  tims_xic_structure.scanNumBegin = q.value(2).toUInt();
1477  tims_xic_structure.scanNumEnd = q.value(3).toUInt();
1478  tims_xic_structure.rtTarget = q.value(0).toDouble();
1479  // xic_structure.charge = q.value(5).toUInt();
1480  tims_xic_structure.xicSptr = std::make_shared<Xic>();
1481  }
1482  }
1483  catch(PappsoException &error)
1484  {
1485  throw error;
1486  }
1487  catch(std::exception &error)
1488  {
1489  qDebug() << QString("Failure %1 ").arg(error.what());
1490  }
1491  return tims_xic_structure;
1492 }
1493 
1494 
1495 std::map<quint32, quint32>
1496 TimsData::getRawMs2ByPrecursorId(std::size_t precursor_index)
1497 {
1498  qDebug();
1499  try
1500  {
1501  QSqlDatabase qdb = openDatabaseConnection();
1502 
1503  qdb = openDatabaseConnection();
1504  QSqlQuery q =
1505  qdb.exec(QString("SELECT PasefFrameMsMsInfo.*, Precursors.* FROM "
1506  "PasefFrameMsMsInfo INNER JOIN Precursors ON "
1507  "PasefFrameMsMsInfo.Precursor=Precursors.Id where "
1508  "Precursors.Id=%1;")
1509  .arg(precursor_index));
1510  if(q.lastError().isValid())
1511  {
1512  qDebug();
1513  throw PappsoException(
1514  QObject::tr("ERROR in TIMS sqlite database file %1, executing SQL "
1515  "command %2:\n%3\n%4\n%5")
1516  .arg(m_timsDataDirectory.absoluteFilePath("analysis.tdf"))
1517  .arg(q.lastQuery())
1518  .arg(qdb.lastError().databaseText())
1519  .arg(qdb.lastError().driverText())
1520  .arg(qdb.lastError().nativeErrorCode()));
1521  }
1522  qDebug();
1523  // m_mutex.unlock();
1524  if(q.size() == 0)
1525  {
1526 
1527  throw ExceptionNotFound(
1528  QObject::tr(
1529  "ERROR in getQualifiedMassSpectrumByPrecursorId, precursor "
1530  "id=%1 not found")
1531  .arg(precursor_index));
1532  }
1533  else
1534  {
1535  // qDebug() << " q.size()="<< q.size();
1536  qDebug();
1537  bool first = true;
1538  std::size_t scan_mobility_start = 0;
1539  std::size_t scan_mobility_end = 0;
1540  std::vector<std::size_t> tims_frame_list;
1541 
1542  while(q.next())
1543  {
1544  tims_frame_list.push_back(q.value(0).toLongLong());
1545  if(first)
1546  {
1547 
1548  scan_mobility_start = q.value(1).toLongLong();
1549  scan_mobility_end = q.value(2).toLongLong();
1550 
1551  first = false;
1552  }
1553  }
1554  // QMutexLocker locker(&m_mutex_spectrum);
1555  qDebug();
1556  pappso::TimsFrameCstSPtr tims_frame, previous_frame;
1557  // TracePlusCombiner combiner;
1558  // MapTrace combiner_result;
1559  std::map<quint32, quint32> raw_spectrum;
1560  for(std::size_t tims_id : tims_frame_list)
1561  {
1562  tims_frame = getTimsFrameCstSPtrCached(tims_id);
1563  qDebug();
1564  /*combiner.combine(combiner_result,
1565  tims_frame.get()->cumulateScanToTrace(
1566  scan_mobility_start, scan_mobility_end));*/
1567  if(previous_frame.get() != nullptr)
1568  {
1569  if(previous_frame.get()->hasSameCalibrationData(
1570  *tims_frame.get()))
1571  {
1572  }
1573  else
1574  {
1575  throw ExceptionNotFound(
1576  QObject::tr(
1577  "ERROR in %1 %2, different calibration data "
1578  "between frame id %3 and frame id %4")
1579  .arg(__FILE__)
1580  .arg(__FUNCTION__)
1581  .arg(previous_frame.get()->getId())
1582  .arg(tims_frame.get()->getId()));
1583  }
1584  }
1585  tims_frame.get()->cumulateScansInRawMap(
1586  raw_spectrum, scan_mobility_start, scan_mobility_end);
1587  qDebug();
1588 
1589  previous_frame = tims_frame;
1590  }
1591  qDebug() << " precursor_index=" << precursor_index
1592  << " num_rows=" << tims_frame_list.size()
1593  << " sql=" << q.lastQuery() << " "
1594  << (std::size_t)QThread::currentThreadId();
1595  if(first == true)
1596  {
1597  throw ExceptionNotFound(
1598  QObject::tr(
1599  "ERROR in getQualifiedMassSpectrumByPrecursorId, precursor "
1600  "id=%1 not found")
1601  .arg(precursor_index));
1602  }
1603  qDebug();
1604  }
1605  }
1606 
1607  catch(PappsoException &error)
1608  {
1609  throw error;
1610  }
1611  catch(std::exception &error)
1612  {
1613  qDebug() << QString("Failure %1 ").arg(error.what());
1614  }
1615  qDebug();
1616 }
void setNativeId(const QString &native_id)
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)
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)
TimsFrameSPtr getTimsFrameSPtrByOffset(std::size_t timsId, std::size_t timsOffset) const
Definition: timsbindec.cpp:142
QualifiedMassSpectrum getQualifiedMs1MassSpectrumByPrecursorId(std::size_t ms2_index, std::size_t precursor_index, bool want_binary_data)
Definition: timsdata.cpp:860
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:1321
void fillFrameIdDescrList()
private function to fill m_frameIdDescrList
Definition: timsdata.cpp:279
TimsFrameBaseCstSPtr getTimsFrameBaseCstSPtr(std::size_t timsId) const
get a Tims frame base (no binary data file access) with his database ID
Definition: timsdata.cpp:385
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:582
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:1316
std::vector< FrameIdDescr > m_frameIdDescrList
store every frame id and corresponding sizes
Definition: timsdata.h:302
std::map< std::size_t, QSqlRecord > m_mapFramesRecord
Definition: timsdata.h:288
TimsFrameCstSPtr getTimsFrameCstSPtrCached(std::size_t timsId)
get a Tims frame with his database ID but look in the cache first
Definition: timsdata.cpp:1297
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:603
TimsData(QDir timsDataDirectory)
build using the tims data directory
Definition: timsdata.cpp:46
void extractXicListByTimsXicStructureList(std::vector< TimsXicStructure > &tims_xic_structure_list, XicExtractMethod xicExtractMethod, double rtRange) const
extract a list of XICs from Tims data
Definition: timsdata.cpp:1407
QualifiedMassSpectrum getQualifiedMassSpectrumByRawIndex(std::size_t spectrum_index, bool want_binary_data)
Definition: timsdata.cpp:741
QSqlDatabase openDatabaseConnection() const
Definition: timsdata.cpp:218
TimsFrameCstSPtr getTimsFrameCstSPtr(std::size_t timsId) const
get a Tims frame with his database ID
Definition: timsdata.cpp:494
std::size_t getRawIndexFromCoordinate(std::size_t frame_id, std::size_t scan_num) const
Definition: timsdata.cpp:353
TimsXicStructure getTimsXicStructureFromPrecursorId(std::size_t precursor_id, PrecisionPtr precision_ptr) const
Definition: timsdata.cpp:1433
std::size_t m_totalNumberOfScans
Definition: timsdata.h:272
std::deque< TimsFrameCstSPtr > m_timsFrameCache
Definition: timsdata.h:275
std::size_t m_cacheSize
Definition: timsdata.h:274
unsigned int getMsLevelBySpectrumIndex(std::size_t spectrum_index)
Definition: timsdata.cpp:732
std::map< int, QSqlRecord > m_mapMzCalibrationRecord
Definition: timsdata.h:286
std::map< int, QSqlRecord > m_mapTimsCalibrationRecord
Definition: timsdata.h:287
QMutex m_mutex
Definition: timsdata.h:309
bool m_builtinMs2Centroid
enable builtin centroid on raw tims integers by default
Definition: timsdata.h:283
std::vector< std::size_t > getTimsMS1FrameIdRange(double rt_begin, double rt_end) const
Definition: timsdata.cpp:460
QDir m_timsDataDirectory
Definition: timsdata.h:269
std::vector< std::size_t > getClosestPrecursorIdByMz(std::vector< std::vector< double >> ids, double mz_value)
Definition: timsdata.cpp:708
MzCalibrationStore * mpa_mzCalibrationStore
Definition: timsdata.h:290
TimsFrameBaseCstSPtr getTimsFrameBaseCstSPtrCached(std::size_t timsId)
Definition: timsdata.cpp:1278
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:1496
std::vector< TimsXicStructure > extractXicListByPrecursorIds(const std::vector< std::size_t > &precursor_id_list, PrecisionPtr precision_ptr, XicExtractMethod xicExtractMethod, double rtRange) const
extract a list of XICs from Tims data
Definition: timsdata.cpp:1327
std::size_t getTotalNumberOfScans() const
get the total number of scans
Definition: timsdata.cpp:590
std::deque< TimsFrameBaseCstSPtr > m_timsFrameBaseCache
Definition: timsdata.h:276
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:307
TimsBinDec * mpa_timsBinDec
Definition: timsdata.h:270
void setMs2BuiltinCentroid(bool centroid)
enable or disable simple centroid filter on raw tims data for MS2
Definition: timsdata.cpp:267
std::vector< std::size_t > getMatchPrecursorIdByKo(std::vector< std::vector< double >> ids, double ko_value)
Definition: timsdata.cpp:682
pappso::FilterInterfaceCstSPtr mcsp_ms1Filter
Definition: timsdata.h:279
void getQualifiedMs2MassSpectrumByPrecursorId(QualifiedMassSpectrum &mass_spectrum, std::size_t ms2_index, std::size_t precursor_index, bool want_binary_data)
Definition: timsdata.cpp:1025
bool getMs2BuiltinCentroid() const
tells if simple centroid filter on raw tims data for MS2 is enabled or not
Definition: timsdata.cpp:273
std::pair< std::size_t, std::size_t > getScanCoordinateFromRawIndex(std::size_t spectrum_index) const
Definition: timsdata.cpp:319
pappso::FilterInterfaceCstSPtr mcsp_ms2Filter
Definition: timsdata.h:278
pappso::MassSpectrumCstSPtr getMassSpectrumCstSPtrByRawIndex(std::size_t raw_index)
get a mass spectrum given its spectrum index
Definition: timsdata.cpp:376
std::size_t getTotalNumberOfPrecursors() const
get the number of precursors analyzes by PASEF
Definition: timsdata.cpp:597
std::size_t m_totalNumberOfPrecursors
Definition: timsdata.h:273
void setXicExtractMethod(XicExtractMethod method)
set the XIC extraction method
virtual void extractTimsXicList(std::vector< TimsXicStructure > &timsXicList, double rtRange) const =0
extract XICs for given coordinates XICs are extracted given their coordinates : retention time target...
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:40
std::shared_ptr< TimsFrameBase > TimsFrameBaseSPtr
Definition: timsframebase.h:39
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
XicExtractMethod
Definition: types.h:200
std::shared_ptr< const TimsFrame > TimsFrameCstSPtr
Definition: timsframe.h:42
structure needed to extract XIC from Tims data
Definition: timsdata.h:49
pappso::pappso_double rtTarget
targeted retention time for this precursor
Definition: timsdata.h:69
std::size_t scanNumEnd
mobility index end
Definition: timsdata.h:65
MzRange mzRange
mass range to extract
Definition: timsdata.h:58
XicSPtr xicSptr
extracted xic
Definition: timsdata.h:73
std::size_t scanNumBegin
mobility index begin
Definition: timsdata.h:61
std::size_t precursorId
the corresponding precursor id
Definition: timsdata.h:51
main Tims data handler
minimum functions to extract XICs from Tims Data