libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
timsframe.cpp
Go to the documentation of this file.
1/**
2 * \file pappsomspp/vendors/tims/timsframe.cpp
3 * \date 23/08/2019
4 * \author Olivier Langella
5 * \brief handle a single Bruker's TimsTof frame
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 "timsframe.h"
30#include <QDebug>
31#include <QObject>
32#include <QtEndian>
33#include <memory>
34
35namespace pappso
36{
37
39 const XicCoordTims &xic_struct)
40{
41 xic_ptr = xic_struct.xicSptr.get();
42
44 mobilityIndexEnd = xic_struct.scanNumEnd;
45 mzIndexLowerBound = fram_p->getMzCalibrationInterfaceSPtr().get()->getTofIndexFromMz(
46 xic_struct.mzRange.lower()); // convert mz to raw digitizer value
48 fram_p->getMzCalibrationInterfaceSPtr().get()->getTofIndexFromMz(xic_struct.mzRange.upper());
49 tmpIntensity = 0;
50}
51
52TimsFrame::TimsFrame(std::size_t timsId, quint32 scanNum) : TimsFrameBase(timsId, scanNum)
53{
54 // m_timsDataFrame.resize(10);
55}
56
57TimsFrame::TimsFrame(std::size_t timsId, quint32 scanNum, char *p_bytes, std::size_t len)
58 : TimsFrameBase(timsId, scanNum)
59{
60 // langella@themis:~/developpement/git/bruker/cbuild$
61 // ./src/sample/timsdataSamplePappso
62 // /gorgone/pappso/fichiers_fabricants/Bruker/Demo_TimsTOF_juin2019/Samples/1922001/1922001-1_S-415_Pep_Pur-1ul_Slot1-10_1_2088.d/
63 // qDebug() << timsId;
64
65 m_binaryData.resize(len);
66
67 if(p_bytes != nullptr)
68 {
69 unshufflePacket(p_bytes);
70 }
71 else
72 {
73 if(m_scanCount == 0)
74 {
75
76 throw pappso::PappsoException(QObject::tr("TimsFrame::TimsFrame(%1,%2,nullptr,%3) FAILED")
77 .arg(m_frameId)
78 .arg(m_scanCount)
79 .arg(len));
80 }
81 }
82}
83
85{
86}
87
91
92
93void
95{
96 // qDebug();
97 quint64 len = m_binaryData.size();
98 if(len % 4 != 0)
99 {
100 throw pappso::PappsoException(QObject::tr("TimsFrame::unshufflePacket error: len % 4 != 0"));
101 }
102
103 quint64 nb_uint4 = len / 4;
104
105 char *dest = m_binaryData.data();
106 quint64 src_offset = 0;
107
108 for(quint64 j = 0; j < 4; j++)
109 {
110 for(quint64 i = 0; i < nb_uint4; i++)
111 {
112 dest[(i * 4) + j] = src[src_offset];
113 src_offset++;
114 }
115 }
116 // qDebug();
117}
118
119std::size_t
120TimsFrame::getScanPeakCount(std::size_t scanNum) const
121{
122 if(m_binaryData.size() == 0)
123 return 0;
124 /*
125 if(scanNum == 0)
126 {
127 quint32 res = (*(quint32 *)(m_timsDataFrame.constData() + 4)) -
128 (*(quint32 *)(m_timsDataFrame.constData()-4));
129 return res / 2;
130 }*/
131 if(scanNum == (m_scanCount - 1))
132 {
133 auto nb_uint4 = m_binaryData.size() / 4;
134
135 std::size_t cumul = 0;
136 for(quint32 i = 0; i < m_scanCount; i++)
137 {
138 cumul += (*(quint32 *)(m_binaryData.constData() + (i * 4)));
139 }
140 return (nb_uint4 - cumul) / 2;
141 }
142 checkScanNum(scanNum);
143
144 // quint32 *res = (quint32 *)(m_timsDataFrame.constData() + (scanNum * 4));
145 // qDebug() << " res=" << *res;
146 return (*(quint32 *)(m_binaryData.constData() + ((scanNum + 1) * 4))) / 2;
147}
148
149std::size_t
150TimsFrame::getScanOffset(std::size_t scanNum) const
151{
152 std::size_t offset = 0;
153 for(std::size_t i = 0; i < (scanNum + 1); i++)
154 {
155 offset += (*(quint32 *)(m_binaryData.constData() + (i * 4)));
156 }
157 return offset;
158}
159
160
161std::vector<quint32>
162TimsFrame::getScanTofIndexList(std::size_t scanNum) const
163{
164 // qDebug();
165 checkScanNum(scanNum);
166 std::vector<quint32> scan_tof;
167
168 if(m_binaryData.size() == 0)
169 return scan_tof;
170 scan_tof.resize(getScanPeakCount(scanNum));
171
172 std::size_t offset = getScanOffset(scanNum);
173
174 qint32 previous = -1;
175 for(std::size_t i = 0; i < scan_tof.size(); i++)
176 {
177 scan_tof[i] = (*(quint32 *)(m_binaryData.constData() + (offset * 4) + (i * 8))) + previous;
178 previous = scan_tof[i];
179 }
180 // qDebug();
181 return scan_tof;
182}
183
184std::vector<quint32>
185TimsFrame::getScanIntensityList(std::size_t scanNum) const
186{
187 // qDebug();
188 checkScanNum(scanNum);
189 std::vector<quint32> scan_intensities;
190
191 if(m_binaryData.size() == 0)
192 return scan_intensities;
193
194 scan_intensities.resize(getScanPeakCount(scanNum));
195
196 std::size_t offset = getScanOffset(scanNum);
197
198 for(std::size_t i = 0; i < scan_intensities.size(); i++)
199 {
200 scan_intensities[i] = (*(quint32 *)(m_binaryData.constData() + (offset * 4) + (i * 8) + 4));
201 }
202 // qDebug();
203 return scan_intensities;
204}
205
206
207quint64
208TimsFrame::cumulateScanIntensities(std::size_t scanNum) const
209{
210 // qDebug();
211
212 quint64 summed_intensities = 0;
213
214 if(m_binaryData.size() == 0)
215 return summed_intensities;
216 // checkScanNum(scanNum);
217
218 std::size_t size = getScanPeakCount(scanNum);
219
220 std::size_t offset = getScanOffset(scanNum);
221
222 qint32 previous = -1;
223
224 for(std::size_t i = 0; i < size; i++)
225 {
226 quint32 x = (*(quint32 *)((m_binaryData.constData() + (offset * 4) + (i * 8))) + previous);
227
228 quint32 y = (*(quint32 *)(m_binaryData.constData() + (offset * 4) + (i * 8) + 4));
229
230 previous = x;
231
232 summed_intensities += y;
233 }
234
235 // Normalization over the accumulation time for this frame.
236 summed_intensities *= ((double)100.0 / m_acqDurationInMilliseconds);
237
238 // qDebug();
239
240 return summed_intensities;
241}
242
243
244/**
245 * @brief ...
246 *
247 * @param mobility_scan_begin p_mobility_scan_begin:...
248 * @param mobility_scan_end p_mobility_scan_end:...
249 * @return quint64
250 */
251quint64
252TimsFrame::cumulateScanRangeIntensities(std::size_t mobility_scan_begin,
253 std::size_t mobility_scan_end) const
254{
255 quint64 summed_intensities = 0;
256
257 // qDebug() << "begin mobility_scan_begin =" << mobility_scan_begin
258 //<< "mobility_scan_end =" << mobility_scan_end;
259
260 if(m_binaryData.size() == 0)
261 return summed_intensities;
262
263 try
264 {
265 std::size_t mobility_scan_max = mobility_scan_end + 1;
266
267 for(std::size_t i = mobility_scan_begin; i < mobility_scan_max; i++)
268 {
269 // qDebug() << i;
270 summed_intensities += cumulateScanIntensities(i);
271 // qDebug() << i;
272 }
273 }
274 catch(std::exception &error)
275 {
276 qDebug() << QString("Failure in %1 %2 to %3 :\n %4")
277 .arg(__FUNCTION__)
278 .arg(mobility_scan_begin)
279 .arg(mobility_scan_end)
280 .arg(error.what());
281 }
282
283 // qDebug() << "end";
284
285 return summed_intensities;
286}
287
288
289void
290TimsFrame::cumulateScan(std::size_t scanNum, TimsDataFastMap &accumulate_into) const
291{
292 // qDebug();
293
294 if(m_binaryData.size() == 0)
295 return;
296 // qDebug();
297
298 // checkScanNum(scanNum);
299
300 std::size_t scan_size = getScanPeakCount(scanNum);
301
302 std::size_t scan_offset = getScanOffset(scanNum);
303
304 qint32 previous = -1;
305 for(std::size_t i = 0; i < scan_size; i++)
306 {
307 quint32 x =
308 (*(quint32 *)((m_binaryData.constData() + (scan_offset * 4) + (i * 8))) + previous);
309 quint32 y = (*(quint32 *)(m_binaryData.constData() + (scan_offset * 4) + (i * 8) + 4));
310
311 previous = x;
312 // qDebug() << "x=" << x << " y=" << y;
313 accumulate_into.accumulateIntensity(x, y);
314 }
315
316 qDebug();
317}
318
319// Proof of concept m/z range-conditions for accumulations
320void
321TimsFrame::cumulateScan2(std::size_t scanNum,
322 TimsDataFastMap &accumulate_into,
323 quint32 accepted_tof_index_range_begin,
324 quint32 accepted_tof_index_range_end) const
325{
326 // qDebug();
327
328 if(m_binaryData.size() == 0)
329 return;
330
331 // checkScanNum(scanNum);
332
333 std::size_t scan_size = getScanPeakCount(scanNum);
334 std::size_t scan_offset = getScanOffset(scanNum);
335 qint32 previous = -1;
336
337 for(std::size_t i = 0; i < scan_size; i++)
338 {
339 quint32 x =
340 (*(quint32 *)((m_binaryData.constData() + (scan_offset * 4) + (i * 8))) + previous);
341
342 previous = x;
343
344 if(x < accepted_tof_index_range_begin)
345 {
346
347 // qDebug() << "TOF index still not in range, x:" << x;
348 continue;
349 }
350 if(x > accepted_tof_index_range_end)
351 {
352 // qDebug() << "TOF index already out of range, x:" << x;
353 break;
354 }
355
356 // qDebug() << "TOF index in range, x:" << x;
357
358 quint32 y = (*(quint32 *)(m_binaryData.constData() + (scan_offset * 4) + (i * 8) + 4));
359
360 accumulate_into.accumulateIntensity(x, y);
361 }
362
363 // qDebug();
364}
365
366
367Trace
368TimsFrame::cumulateScansToTrace(std::size_t mobility_scan_begin,
369 std::size_t mobility_scan_end) const
370{
371 // qDebug();
372
373 Trace new_trace;
374
375 try
376 {
377 if(m_binaryData.size() == 0)
378 return new_trace;
380 raw_spectrum.clear();
381 // double local_accumulationTime = 0;
382
383 std::size_t mobility_scan_max = mobility_scan_end + 1;
384 qDebug();
385 for(std::size_t i = mobility_scan_begin; i < mobility_scan_max; i++)
386 {
387 // qDebug() << i;
388 cumulateScan(i, raw_spectrum);
389 // qDebug() << i;
390
391 // local_accumulationTime += m_accumulationTime;
392 }
393
394 // qDebug();
395
396 pappso::DataPoint data_point_cumul;
397
398
399 MzCalibrationInterface *mz_calibration_p = getMzCalibrationInterfaceSPtr().get();
400
401
402 for(quint32 tof_index : raw_spectrum.getTofIndexList())
403 {
404 data_point_cumul.x = mz_calibration_p->getMzFromTofIndex(tof_index);
405 // normalization
406 data_point_cumul.y =
407 raw_spectrum.readIntensity(tof_index) * ((double)100.0 / m_acqDurationInMilliseconds);
408 new_trace.push_back(data_point_cumul);
409 }
410 new_trace.sortX();
411
412 // qDebug();
413 }
414
415 catch(std::exception &error)
416 {
417 qDebug() << QString("Failure in TimsFrame::cumulateScanToTrace %1 to %2 :\n %3")
418 .arg(mobility_scan_begin, mobility_scan_end)
419 .arg(error.what());
420 }
421 return new_trace;
422}
423
424Trace
426 std::size_t mobility_scan_begin,
427 std::size_t mobility_scan_end,
428 quint32 &mz_minimum_index_out,
429 quint32 &mz_maximum_index_out) const
430{
431 // qDebug();
432
433 Trace new_trace;
434
435 try
436 {
437 if(m_binaryData.size() == 0)
438 {
439 qDebug() << "The frame is empty, returning empty trace.";
440 return new_trace;
441 }
442
443 // Allocate a map for (TOF,intensity) pairs to
444 // accumulate ion mobility scans.
445
447 raw_spectrum.clear();
448 // double local_accumulationTime = 0;
449
450 std::size_t mobility_scan_max = mobility_scan_end + 1;
451
452 for(std::size_t i = mobility_scan_begin; i < mobility_scan_max; i++)
453 {
454 // qDebug() << "Going to cumulate currently iterated mobility scan:"
455 // << i;
456 cumulateScan(i, raw_spectrum);
457 // qDebug() << "Done cumulating currently iterated mobility scan:" <<
458 // i;
459
460 // local_accumulationTime += m_accumulationTime;
461 }
462
463 // qDebug();
464
465 pappso::DataPoint data_point_cumul;
466
467 MzCalibrationInterface *mz_calibration_p = getMzCalibrationInterfaceSPtr().get();
468
469 // If the caller asks that m/z values be binned larger than they are,
470 // ask that the m/z raw map be reduced in resolution.
471 if(mz_index_merge_window > 0)
472 {
473 raw_spectrum.downsizeMzRawMap(mz_index_merge_window);
474 }
475
476 // Store the first mz index and the last mz index of the current spectrum.
477 // The values are set to the out parameters.
478 mz_minimum_index_out = std::numeric_limits<quint32>::max();
479 mz_maximum_index_out = 0;
480
481 // FIXME: donc je comprends que les index sont contigus
482 // puisqu'on utilise at(key) ?
483 for(quint32 tof_index : raw_spectrum.getTofIndexList())
484 {
485 if(tof_index > mz_maximum_index_out)
486 mz_maximum_index_out = tof_index;
487 if(tof_index < mz_minimum_index_out)
488 mz_minimum_index_out = tof_index;
489
490 // Convert the TOF index to m/z
491 data_point_cumul.x = mz_calibration_p->getMzFromTofIndex(tof_index);
492
493 // Normalization
494 data_point_cumul.y =
495 raw_spectrum.readIntensity(tof_index) * ((double)100.0 / m_acqDurationInMilliseconds);
496
497 // Finally make the data point a new Trace point.
498 new_trace.push_back(data_point_cumul);
499 }
500
501 // qDebug() << "At this point we have mz_minimum_index_out:"
502 // << mz_minimum_index_out
503 // << "and mz_maximum_index_out:" << mz_maximum_index_out;
504
505 // FIXME: this does not seem to be necessary since raw_spectrum is a map
506 // with auto-sorting on the keys which are quint32.
507 // new_trace.sortX();
508
509 // qDebug();
510 }
511 catch(std::exception &error)
512 {
513 qDebug() << QString("Failure in TimsFrame::cumulateScanToTrace %1 to %2 :\n %3")
514 .arg(mobility_scan_begin, mobility_scan_end)
515 .arg(error.what());
516 }
517
518 // qDebug() << "Returning new trace of size:" << new_trace.size();
519
520 return new_trace;
521}
522
523
524Trace
526 double mz_range_begin,
527 double mz_range_end,
528 std::size_t mobility_scan_begin,
529 std::size_t mobility_scan_end,
530 quint32 &mz_minimum_index_out,
531 quint32 &mz_maximum_index_out) const
532{
533 // qDebug() << "Calling cumulateScansToTraceMzDownResolution2 for both mz and "
534 // "im ranges accounting.";
535
536 Trace new_trace;
537
538 try
539 {
540 if(m_binaryData.size() == 0)
541 {
542 qDebug() << "The frame is empty, returning empty trace.";
543 return new_trace;
544 }
545
546 // Allocate a map for (TOF index,intensity) pairs to
547 // accumulate ion mobility scans.
548
550 raw_spectrum.clear();
551 // double local_accumulationTime = 0;
552
553 std::size_t mobility_scan_max = mobility_scan_end + 1;
554
555 quint32 tof_index_for_mz_range_begin =
556 getMzCalibrationInterfaceSPtr().get()->getTofIndexFromMz(mz_range_begin);
557 quint32 tof_index_for_mz_range_end =
558 getMzCalibrationInterfaceSPtr().get()->getTofIndexFromMz(mz_range_end);
559
560 // qDebug() << "TOF index for mz range begin:"
561 // << tof_index_for_mz_range_begin;
562 // qDebug() << "TOF index for mz range end:"
563 // << tof_index_for_mz_range_end;
564
565 for(std::size_t iter = mobility_scan_begin; iter < mobility_scan_max; iter++)
566 {
567 // qDebug() << "Going to cumulate currently iterated mobility scan:"
568 // << iter;
570 iter, raw_spectrum, tof_index_for_mz_range_begin, tof_index_for_mz_range_end);
571 // qDebug() << "Done cumulating currently iterated mobility scan:" <<
572 // i;
573
574 // local_accumulationTime += m_accumulationTime;
575 }
576
577 // qDebug();
578
579 pappso::DataPoint data_point_cumul;
580
581 MzCalibrationInterface *mz_calibration_p = getMzCalibrationInterfaceSPtr().get();
582
583 // If the caller asks that m/z values be binned larger than they are,
584 // ask that the m/z raw map be reduced in resolution.
585 if(mz_index_merge_window > 0)
586 {
587 raw_spectrum.downsizeMzRawMap(mz_index_merge_window);
588 }
589
590 // Store the first mz index and the last mz index of the current spectrum.
591 // The values are set to the out parameters.
592 mz_minimum_index_out = std::numeric_limits<quint32>::max();
593 mz_maximum_index_out = 0;
594
595 // for(std::pair<quint32, quint32> pair_tof_intensity : raw_spectrum)
596 for(quint32 tof_index : raw_spectrum.getTofIndexList())
597 {
598 std::size_t intensity = raw_spectrum.readIntensity(tof_index);
599 if(tof_index > mz_maximum_index_out)
600 mz_maximum_index_out = tof_index;
601 if(tof_index < mz_minimum_index_out)
602 mz_minimum_index_out = tof_index;
603
604 // Convert the TOF index to m/z
605 data_point_cumul.x = mz_calibration_p->getMzFromTofIndex(tof_index);
606
607 // Normalization
608 data_point_cumul.y = intensity * ((double)100.0 / m_acqDurationInMilliseconds);
609
610 // Finally make the data point a new Trace point.
611 new_trace.push_back(data_point_cumul);
612 }
613
614 // qDebug() << "At this point we have mz_minimum_index_out:"
615 // << mz_minimum_index_out
616 // << "and mz_maximum_index_out:" << mz_maximum_index_out;
617
618 // FIXME: this does not seem to be necessary since raw_spectrum is a map
619 // with auto-sorting on the keys which are quint32.
620 // new_trace.sortX();
621
622 // qDebug();
623 }
624 catch(std::exception &error)
625 {
626 qDebug() << QString("Failure in TimsFrame::cumulateScanToTrace %1 to %2 :\n %3")
627 .arg(mobility_scan_begin, mobility_scan_end)
628 .arg(error.what());
629 }
630
631 // qDebug() << "Returning new trace of size:" << new_trace.size();
632
633 return new_trace;
634}
635
636
637void
639 std::size_t scan_index_begin,
640 std::size_t scan_index_end) const
641{
642 // qDebug() << "begin mobility_scan_begin=" << mobility_scan_begin
643 //<< " mobility_scan_end=" << mobility_scan_end;
644
645 if(m_binaryData.size() == 0)
646 return;
647 try
648 {
649
650 std::size_t mobility_scan_max = scan_index_end + 1;
651 // if (mobility_scan_max > m_scanCount) mobility_scan_max = m_scanCount;
652 // qDebug();
653 for(std::size_t i = scan_index_begin; i < mobility_scan_max; i++)
654 {
655 // qDebug() << i;
656 cumulateScan(i, rawSpectrum);
657 // qDebug() << i;
658
659 // local_accumulationTime += m_accumulationTime;
660 }
661 }
662
663 catch(std::exception &error)
664 {
665 qDebug() << QString("Failure in %1 %2 to %3 :\n %4")
666 .arg(__FUNCTION__)
667 .arg(scan_index_begin)
668 .arg(scan_index_end)
669 .arg(error.what());
670 }
671
672 // qDebug() << "end";
673}
674
675
676void
678 std::size_t scan_index_begin,
679 std::size_t scan_index_end,
680 quint32 tof_index_begin,
681 quint32 tof_index_end) const
682{
683 // qDebug() << "tof_index_begin=" << tof_index_begin
684 // << " tof_index_end=" << tof_index_end;
685
686 //<< " mobility_scan_end=" << mobility_scan_end;
687
688 if(m_binaryData.size() == 0)
689 return;
690 try
691 {
692
693 std::size_t mobility_scan_max = scan_index_end + 1;
694 // if (mobility_scan_max > m_scanCount) mobility_scan_max = m_scanCount;
695 // qDebug();
696 for(std::size_t i = scan_index_begin; i < mobility_scan_max; i++)
697 {
698 // qDebug() << i;
699 cumulateScan2(i, rawSpectrum, tof_index_begin, tof_index_end);
700 // qDebug() << i << rawSpectrum.getTofIndexList().size();
701 // local_accumulationTime += m_accumulationTime;
702 }
703 }
704
705 catch(std::exception &error)
706 {
707 qDebug() << QString("Failure in %1 %2 to %3 :\n %4")
708 .arg(__FUNCTION__)
709 .arg(scan_index_begin)
710 .arg(scan_index_end)
711 .arg(error.what());
712 }
713
714 // qDebug() << "end";
715}
716
718TimsFrame::getMassSpectrumSPtr(std::size_t scanNum) const
719{
720
721 // qDebug() << " scanNum=" << scanNum;
722
723 checkScanNum(scanNum);
724
725 // qDebug();
726
727 pappso::MassSpectrumSPtr mass_spectrum_sptr = std::make_shared<pappso::MassSpectrum>();
728 // std::vector<DataPoint>
729
730 if(m_binaryData.size() == 0)
731 return mass_spectrum_sptr;
732
733 // qDebug();
734
735 std::size_t size = getScanPeakCount(scanNum);
736
737 std::size_t offset = getScanOffset(scanNum);
738
739 MzCalibrationInterface *mz_calibration_p = getMzCalibrationInterfaceSPtr().get();
740
741
742 qint32 previous = -1;
743 qint32 tof_index;
744 // std::vector<quint32> index_list;
745 DataPoint data_point;
746 for(std::size_t i = 0; i < size; i++)
747 {
748 tof_index = (*(quint32 *)((m_binaryData.constData() + (offset * 4) + (i * 8))) + previous);
749 data_point.y = (*(quint32 *)(m_binaryData.constData() + (offset * 4) + (i * 8) + 4));
750
751 // intensity normalization
752 data_point.y *= 100.0 / m_acqDurationInMilliseconds;
753
754 previous = tof_index;
755
756
757 // mz calibration
758 data_point.x = mz_calibration_p->getMzFromTofIndex(tof_index);
759 mass_spectrum_sptr.get()->push_back(data_point);
760 }
761
762 // qDebug();
763
764 return mass_spectrum_sptr;
765}
766
767
768Trace
769TimsFrame::getMobilityScan(std::size_t scanNum,
770 std::size_t mz_index_merge_window,
771 double mz_range_begin,
772 double mz_range_end,
773 quint32 &mz_minimum_index_out,
774 quint32 &mz_maximum_index_out) const
775{
776 // qDebug() << "mz_range_begin:" << mz_range_begin
777 // << "mz_range_end:" << mz_range_end
778 // << "mz_index_merge_window:" << mz_index_merge_window;
779
780 Trace spectrum;
781
782 quint32 mz_index_begin = 0;
783 quint32 mz_index_end = std::numeric_limits<quint32>::max();
784
785 if(mz_range_end > 0)
786 {
787 // qDebug() << "m/z range is requested.";
788
789 mz_index_begin = msp_mzCalibration.get()->getTofIndexFromMz(mz_range_begin);
790 mz_index_end = msp_mzCalibration.get()->getTofIndexFromMz(mz_range_end);
791 }
792
793 // qDebug() << "After conversion of mz indices, mz_index_begin:"
794 // << mz_index_begin << "mz_index_end;" << mz_index_end;
795
796 auto raw_spectrum = getRawValuePairList(scanNum, mz_index_begin, mz_index_end);
797
798 // qDebug() << " raw_spectrum.size();" << raw_spectrum.size();
799
800 if(mz_index_merge_window > 0)
801 {
802 // qDebug() << "mz_index_merge_window;=" << mz_index_merge_window
803 // << " raw_spectrum.size()=" << raw_spectrum.size();
804 raw_spectrum =
805 downgradeResolutionOfTofIndexIntensityPairList(mz_index_merge_window, raw_spectrum);
806 }
807
808 if(raw_spectrum.size() > 0)
809 {
810 mz_minimum_index_out = raw_spectrum.front().tof_index;
811 mz_maximum_index_out = raw_spectrum.back().tof_index;
812
813 for(auto &&element : raw_spectrum)
814 {
815 spectrum.push_back(
816 DataPoint(msp_mzCalibration.get()->getMzFromTofIndex(element.tof_index),
817 static_cast<double>(element.intensity_index)));
818
819 // intensity normalization
820 spectrum.back().y *= 100.0 / m_acqDurationInMilliseconds;
821 }
822 }
823
824 return spectrum;
825}
826
827void
828TimsFrame::extractTimsXicListInRtRange(std::vector<XicCoordTims *>::iterator &itXicListbegin,
829 std::vector<XicCoordTims *>::iterator &itXicListend,
830 Enums::XicExtractMethod method) const
831{
832 // qDebug() << std::distance(itXicListbegin, itXicListend);
833
834 std::vector<TimsFrame::XicComputeStructure> tmp_xic_list;
835
836 for(auto it = itXicListbegin; it != itXicListend; it++)
837 {
838 tmp_xic_list.push_back(TimsFrame::XicComputeStructure(this, **it));
839
840 // qDebug() << " tmp_xic_struct.mobilityIndexBegin="
841 // << tmp_xic_list.back().mobilityIndexBegin
842 // << " tmp_xic_struct.mobilityIndexEnd="
843 // << tmp_xic_list.back().mobilityIndexEnd;
844
845 // qDebug() << " tmp_xic_struct.mzIndexLowerBound="
846 // << tmp_xic_list.back().mzIndexLowerBound
847 // << " tmp_xic_struct.mzIndexUpperBound="
848 // << tmp_xic_list.back().mzIndexUpperBound;
849 }
850 if(tmp_xic_list.size() == 0)
851 return;
852 /*
853 std::sort(tmp_xic_list.begin(), tmp_xic_list.end(), [](const
854 TimsXicStructure &a, const TimsXicStructure &b) { return
855 a.mobilityIndexBegin < b.mobilityIndexBegin;
856 });
857 */
858 std::vector<std::size_t> unique_scan_num_list;
859 for(auto &&struct_xic : tmp_xic_list)
860 {
861 for(std::size_t scan = struct_xic.mobilityIndexBegin;
862 (scan <= struct_xic.mobilityIndexEnd) && (scan < m_scanCount);
863 scan++)
864 {
865 unique_scan_num_list.push_back(scan);
866 }
867 }
868 std::sort(unique_scan_num_list.begin(), unique_scan_num_list.end());
869 auto it_scan_num_end = std::unique(unique_scan_num_list.begin(), unique_scan_num_list.end());
870 auto it_scan_num = unique_scan_num_list.begin();
871
872 while(it_scan_num != it_scan_num_end)
873 {
874 TraceSPtr ms_spectrum = getRawTraceSPtr(*it_scan_num);
875 // qDebug() << ms_spectrum.get()->toString();
876 for(auto &&tmp_xic_struct : tmp_xic_list)
877 {
878 if(((*it_scan_num) >= tmp_xic_struct.mobilityIndexBegin) &&
879 ((*it_scan_num) <= tmp_xic_struct.mobilityIndexEnd))
880 {
881 if(method == Enums::XicExtractMethod::max)
882 {
883 tmp_xic_struct.tmpIntensity += ms_spectrum.get()->maxY(
884 tmp_xic_struct.mzIndexLowerBound, tmp_xic_struct.mzIndexUpperBound);
885
886 // qDebug() << "tmp_xic_struct.tmpIntensity="
887 // << tmp_xic_struct.tmpIntensity;
888 }
889 else
890 {
891 // sum
892 tmp_xic_struct.tmpIntensity += ms_spectrum.get()->sumY(
893 tmp_xic_struct.mzIndexLowerBound, tmp_xic_struct.mzIndexUpperBound);
894
895 // qDebug() << "tmp_xic_struct.tmpIntensity="
896 // << tmp_xic_struct.tmpIntensity;
897 }
898 }
899 }
900 it_scan_num++;
901 }
902
903 for(auto &&tmp_xic_struct : tmp_xic_list)
904 {
905 if(tmp_xic_struct.tmpIntensity != 0)
906 {
907 // qDebug() << tmp_xic_struct.xic_ptr;
908
909 tmp_xic_struct.xic_ptr->push_back({m_rtInSeconds, tmp_xic_struct.tmpIntensity});
910 }
911 }
912
913 // qDebug();
914}
915
916
918TimsFrame::getRawTraceSPtr(std::size_t scanNum) const
919{
920
921 // qDebug();
922
923 pappso::TraceSPtr trace_sptr = std::make_shared<pappso::Trace>();
924 // std::vector<DataPoint>
925
926 if(m_binaryData.size() == 0)
927 return trace_sptr;
928 // qDebug();
929
930 std::size_t size = getScanPeakCount(scanNum);
931
932 std::size_t offset = getScanOffset(scanNum);
933
934 qint32 previous = -1;
935 std::vector<quint32> index_list;
936 for(std::size_t i = 0; i < size; i++)
937 {
938 DataPoint data_point(
939 (*(quint32 *)((m_binaryData.constData() + (offset * 4) + (i * 8))) + previous),
940 (*(quint32 *)(m_binaryData.constData() + (offset * 4) + (i * 8) + 4)));
941
942 // intensity normalization
943 data_point.y *= 100.0 / m_acqDurationInMilliseconds;
944
945 previous = data_point.x;
946 trace_sptr.get()->push_back(data_point);
947 }
948 // qDebug();
949 return trace_sptr;
950}
951
952
953std::vector<TimsFrame::TofIndexIntensityPair>
955 quint32 accepted_tof_index_range_begin,
956 quint32 accepted_tof_index_range_end) const
957{
958 // qDebug() << accepted_tof_index_range_begin;
959
960 std::vector<TimsFrame::TofIndexIntensityPair> raw_value_pairs;
961 // std::vector<DataPoint>
962
963 if(m_binaryData.size() == 0)
964 return raw_value_pairs;
965 // qDebug();
966
967 std::size_t size = getScanPeakCount(scanNum);
968
969 std::size_t offset = getScanOffset(scanNum);
970
971 // qDebug() << size;
972 qint32 previous = -1;
973 std::vector<quint32> index_list;
974 for(std::size_t i = 0; i < size; i++)
975 {
976
977 // qDebug() << i;
979 {(*(quint32 *)((m_binaryData.constData() + (offset * 4) + (i * 8))) + previous),
980 (*(quint32 *)(m_binaryData.constData() + (offset * 4) + (i * 8) + 4))});
981
982 previous = raw_value_pair.tof_index;
983 if(raw_value_pair.tof_index < accepted_tof_index_range_begin)
984 {
985 // qDebug() << "TOF index still not in range, x:" << x;
986 continue;
987 }
988 if(raw_value_pair.tof_index > accepted_tof_index_range_end)
989 {
990 // qDebug() << "TOF index already out of range, x:" << x;
991 break;
992 }
993
994 raw_value_pairs.push_back(raw_value_pair);
995 }
996 // qDebug() << raw_value_pairs.size();
997 return raw_value_pairs;
998}
999
1000} // namespace pappso
virtual double getMzFromTofIndex(quint32 tof_index)=0
get m/z from time of flight raw index
pappso_double lower() const
Definition mzrange.h:71
pappso_double upper() const
Definition mzrange.h:77
replacement for std::map
std::size_t accumulateIntensity(quint32 tofIndex, std::size_t intensity)
accumulates intesity for the given tof index
const std::vector< quint32 > & getTofIndexList() const
std::size_t readIntensity(quint32)
reads intensity for a tof_index
void downsizeMzRawMap(std::size_t mzindex_merge_window)
downsize mz resolution to lower the number of real mz computations
static TimsDataFastMap & getTimsDataFastMapInstance()
double m_rtInSeconds
retention time
MzCalibrationInterfaceSPtr msp_mzCalibration
virtual std::vector< TofIndexIntensityPair > & downgradeResolutionOfTofIndexIntensityPairList(std::size_t tof_index_merge_window, std::vector< TofIndexIntensityPair > &spectrum) const
Downgrade the TOF index resolution to lower the number of real m/z computations.
double m_acqDurationInMilliseconds
acquisition duration in milliseconds
TimsFrameBase(std::size_t frameId, quint32 scanCount)
constructor for binary independant tims frame
virtual const MzCalibrationInterfaceSPtr & getMzCalibrationInterfaceSPtr() const final
get the MzCalibration model to compute mz and TOF for this frame
quint32 m_scanCount
total number of scans contained in this frame
std::size_t m_frameId
Tims frame database id (the SQL identifier of this frame).
bool checkScanNum(std::size_t scanNum) const
check that this scan number exists
virtual Trace combineScansToTraceWithDowngradedMzResolution(std::size_t mzindex_merge_window, std::size_t scanNumBegin, std::size_t scanNumEnd, quint32 &mz_minimum_index, quint32 &mz_maximum_index) const override
cumulate spectrum given a scan number range need the binary file The intensities are normalized with ...
virtual quint64 cumulateScanRangeIntensities(std::size_t scanNumBegin, std::size_t scanNumEnd) const override
...
virtual quint64 cumulateScanIntensities(std::size_t scanNum) const override
virtual ~TimsFrame()
Definition timsframe.cpp:88
TimsFrame(std::size_t timsId, quint32 scanNum, char *p_bytes, std::size_t len)
Definition timsframe.cpp:57
QByteArray m_binaryData
Definition timsframe.h:288
virtual pappso::MassSpectrumSPtr getMassSpectrumSPtr(std::size_t scanNum) const override
get Mass spectrum with peaks for this scan index need the binary file
virtual Trace combineScansToTraceWithDowngradedMzResolution2(std::size_t mz_index_merge_window, double mz_range_begin, double mz_range_end, std::size_t mobility_scan_begin, std::size_t mobility_scan_end, quint32 &mz_minimum_index_out, quint32 &mz_maximum_index_out) const override
cumulate spectrum given a scan number range need the binary file The intensities are normalized with ...
virtual Trace cumulateScansToTrace(std::size_t scanIndexBegin, std::size_t scanIndexEnd) const override
cumulate scan list into a trace
virtual std::vector< quint32 > getScanIntensityList(std::size_t scanNum) const override
get raw intensities without transformation from one scan it needs intensity normalization
void unshufflePacket(const char *src)
unshuffle data packet of tims compression type 2
Definition timsframe.cpp:94
virtual std::vector< TofIndexIntensityPair > getRawValuePairList(std::size_t scanNum, quint32 accepted_tof_index_range_begin, quint32 accepted_tof_index_range_end) const
get the raw index tof_index and intensities (normalized)
virtual Trace getMobilityScan(std::size_t scanNum, std::size_t mz_index_merge_window, double mz_range_begin, double mz_range_end, quint32 &mz_minimum_index_out, quint32 &mz_maximum_index_out) const override
get a single mobility scan m/z + intensities
virtual void cumulateScan(std::size_t scanNum, TimsDataFastMap &accumulate_into) const
cumulate a scan into a map
virtual void cumulateScan2(std::size_t scanNum, TimsDataFastMap &accumulate_into, quint32 accepted_tof_index_range_begin, quint32 accepted_tof_index_range_end) const
virtual std::size_t getScanPeakCount(std::size_t scanIndex) const override
get the number of peaks in this spectrum need the binary file
std::size_t getScanOffset(std::size_t scanNum) const
get offset for this spectrum in the binary file
virtual std::vector< quint32 > getScanTofIndexList(std::size_t scanNum) const override
get raw index list for one given scan index are not TOF nor m/z, just index on digitizer
void extractTimsXicListInRtRange(std::vector< XicCoordTims * >::iterator &itXicListbegin, std::vector< XicCoordTims * >::iterator &itXicListend, Enums::XicExtractMethod method) const
void combineScansInTofIndexIntensityMap(TimsDataFastMap &rawSpectrum, std::size_t scan_index_begin, std::size_t scan_index_end) const override
cumulate scan list into a trace into a raw spectrum map
virtual pappso::TraceSPtr getRawTraceSPtr(std::size_t scanNum) const
get the raw index tof_index and intensities (normalized)
A simple container of DataPoint instances.
Definition trace.h:152
void sortX(Enums::SortOrder sort_order=Enums::SortOrder::ascending)
Definition trace.cpp:1071
@ max
maximum of intensities
Definition types.h:280
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition aa.cpp:39
std::shared_ptr< Trace > TraceSPtr
Definition trace.h:139
std::shared_ptr< MassSpectrum > MassSpectrumSPtr
pappso_double x
Definition datapoint.h:24
pappso_double y
Definition datapoint.h:25
XicComputeStructure(const TimsFrame *fram_p, const XicCoordTims &xic_struct)
Definition timsframe.cpp:38
coordinates of the XIC to extract and the resulting XIC after extraction
std::size_t scanNumEnd
mobility index end
std::size_t scanNumBegin
mobility index begin
XicSPtr xicSptr
extracted xic
Definition xiccoord.h:135
MzRange mzRange
the mass to extract
Definition xiccoord.h:125