libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
timsframetype1.cpp
Go to the documentation of this file.
1/**
2 * \file pappsomspp/vendors/tims/timsframetype1.cpp
3 * \date 3/10/2021
4 * \author Olivier Langella
5 * \brief handle a single Bruker's TimsTof frame type 1 compression
6 */
7
8/*******************************************************************************
9 * Copyright (c) 2021 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
33#include <QDebug>
34#include <QObject>
35#include <liblzf/lzf.h>
36#include <cerrno>
37
38
39namespace pappso
40{
41TimsFrameType1::TimsFrameType1(std::size_t timsId, quint32 scanNum, char *p_bytes, std::size_t len)
42 : TimsFrame(timsId, scanNum)
43{
44 qDebug() << timsId;
45 m_binaryData.resize(len * 2);
46
47 if(p_bytes != nullptr)
48 {
49 qDebug() << timsId;
50 copyAndLzfDecompress(p_bytes, len);
51 qDebug() << timsId;
52 }
53 else
54 {
55 if(m_scanCount == 0)
56 {
57
59 QObject::tr("TimsFrameType1::TimsFrameType1(%1,%2,nullptr,%3) FAILED")
60 .arg(m_frameId)
61 .arg(m_scanCount)
62 .arg(len));
63 }
64 }
65}
66
70
74
75
76void
77TimsFrameType1::copyAndLzfDecompress(const char *src, std::size_t len)
78{
79
80 qDebug() << " m_scanNumber=" << m_scanCount << " len=" << len;
81 // the start position offset for each scan and the length of the last scan
82 // copy first m_scanNumber*4 bytes in qbyte array
83 std::size_t count = (m_scanCount + 2) * 4;
84
85 qDebug() << " count=" << count;
86 if(m_binaryData.size() < (long)(count + count))
87 {
88 qDebug() << " m_timsDataFrame.size()=" << m_binaryData.size();
89 m_binaryData.resize(count + count);
90 }
91
92 /*
93 std::size_t decompressed_size =
94 lzfDecompressScan(src + 3687 - 8,
95 9,
96 m_timsDataFrame.data() + 3660,
97 m_timsDataFrame.size() - 3660);
98
99 qDebug() << "decompressed_size=" << decompressed_size;
100 */
101 // memcpy(m_timsDataFrame.data(), src, count);
102
103 qDebug() << "offset begin at last :" << count + 4;
104
105 // std::vector<std::size_t> compressed_len_list;
106 std::size_t offset;
107 std::size_t previous_offset = (*(quint32 *)(src));
108 qDebug() << "first offset= " << previous_offset;
109 std::size_t cumul_decompressed_size = 0;
110
111
112 for(quint32 i = 1; i <= m_scanCount; i++)
113 {
114 offset = (*(quint32 *)(src + (i * 4)));
115
116 std::size_t compressed_size = offset - previous_offset;
117
118 qDebug() << "scan i=" << i << " previous_offset=" << previous_offset << " offset=" << offset
119 << " length=" << compressed_size;
120 // compressed_len_list.push_back(offset - previous_offset);
121 std::size_t remaining_size = m_binaryData.size();
122
123 if(cumul_decompressed_size < remaining_size)
124 {
125 remaining_size = remaining_size - cumul_decompressed_size;
126 }
127 else
128 {
129 remaining_size = 0;
130 }
131 qDebug() << " remaining_size=" << remaining_size;
132 std::size_t decompressed_size =
133 lzfDecompressScan(src + previous_offset - 8,
134 compressed_size,
135 m_binaryData.data() + cumul_decompressed_size,
136 remaining_size);
137
138
139 m_scanOffsetList.push_back(cumul_decompressed_size);
140 m_scanSizeList.push_back(decompressed_size / 4);
141 cumul_decompressed_size += decompressed_size;
142 qDebug() << " decompressed_size=" << decompressed_size;
143
144
145 previous_offset = offset;
146 }
147 /*
148 std::size_t last_offset = (*(quint32 *)(src + (m_scanNumber * 4)));
149 qDebug() << "last scan length :" << last_offset;
150
151 qDebug() << "last scan length bonus:"
152 << (*(quint32 *)(src + (m_scanNumber + 1 * 4)));
153
154 qDebug() << " m_scanOffsetList.size()=" << m_scanOffsetList.size()
155 << " m_scanNumber=" << m_scanNumber;
156 */
157 /*
158 throw PappsoException(
159 QObject::tr("ERROR reading TimsFrameType1 ").arg(m_timsId));
160 */
161}
162
163
164unsigned int
166 unsigned int src_len,
167 char *dest,
168 unsigned int dest_len)
169{
170 qDebug() << "src=" << src << " src_len=" << src_len << " dest_len=" << dest_len;
171 if(src_len == 0)
172 return 0;
173 unsigned int decompressed_size;
174 unsigned int more_space = src_len * 2;
175 decompressed_size = lzf_decompress(src, src_len, dest, dest_len);
176 while(decompressed_size == 0)
177 {
178 qDebug() << "dest_len=" << dest_len;
179 qDebug() << "decompressed_size=" << decompressed_size;
180
181 if(errno == EINVAL)
182 {
183 throw PappsoException(QObject::tr("ERROR reading TimsFrameType1 %1 TIMS binary file %2: "
184 "LZF decompression error EINVAL")
185 .arg(m_frameId));
186 }
187 else if(errno == E2BIG)
188 {
189 qDebug() << " m_timsDataFrame.size()=" << m_binaryData.size()
190 << " more_space=" << more_space;
191 m_binaryData.resize(m_binaryData.size() + more_space);
192 dest_len += more_space;
193 qDebug();
194 decompressed_size = lzf_decompress(src, src_len, dest, dest_len);
195 }
196 else
197 {
198 break;
199 }
200 }
201 return decompressed_size;
202}
203
204std::size_t
205TimsFrameType1::getScanPeakCount(std::size_t scanNum) const
206{
207 pappso::MassSpectrumSPtr mass_spectrum_sptr = getMassSpectrumSPtr(scanNum);
208 return mass_spectrum_sptr.get()->size();
209}
210
211
212void
213TimsFrameType1::cumulateScan(std::size_t scanNum, TimsDataFastMap &accumulate_into) const
214{
215 if(m_binaryData.size() == 0)
216 return;
217 // checkScanNum(scanNum);
218
219
220 std::size_t size = m_scanSizeList[scanNum];
221
222 std::size_t offset = m_scanOffsetList[scanNum];
223
224 // qDebug() << "begin offset=" << offset << " size=" << size;
225 qint32 value = 0;
226 qint32 tof_index = 0;
227 for(std::size_t i = 0; i < size; i++)
228 {
229 value = (*(qint32 *)(m_binaryData.constData() + offset + (i * 4)));
230 // qDebug() << " i=" << i << " value=" << value;
231
232 if(value < 0)
233 {
234 tof_index += -1 * value;
235 }
236 else
237 {
238
239 quint32 x = tof_index;
240 quint32 y = value;
241
242 accumulate_into.accumulateIntensity(x, y);
243
244 tof_index++;
245 }
246 }
247 qDebug() << "end";
248}
249
250
251void
253 TimsDataFastMap &accumulate_into,
254 quint32 accepted_tof_index_range_begin,
255 quint32 accepted_tof_index_range_end) const
256{
257 if(m_binaryData.size() == 0)
258 return;
259 // checkScanNum(scanNum);
260
261
262 std::size_t size = m_scanSizeList[scanNum];
263
264 std::size_t offset = m_scanOffsetList[scanNum];
265
266 // qDebug() << "begin offset=" << offset << " size=" << size;
267 qint32 value = 0;
268 qint32 tof_index = 0;
269 for(std::size_t i = 0; i < size; i++)
270 {
271 value = (*(qint32 *)(m_binaryData.constData() + offset + (i * 4)));
272 // qDebug() << " i=" << i << " value=" << value;
273
274 if(value < 0)
275 {
276 tof_index += -1 * value;
277 }
278 else
279 {
280
281 quint32 x = tof_index;
282 quint32 y = value;
283
284
285 if(x < accepted_tof_index_range_begin)
286 {
287 tof_index++;
288 continue;
289 }
290 if(x > accepted_tof_index_range_end)
291 {
292 break;
293 }
294 accumulate_into.accumulateIntensity(x, y);
295
296 tof_index++;
297 }
298 }
299 qDebug() << "end";
300}
301
302std::vector<quint32>
303TimsFrameType1::getScanTofIndexList(std::size_t scanNum) const
304{
305 qDebug();
306 checkScanNum(scanNum);
307
308 std::vector<quint32> mzindex_values;
309
310 try
311 {
312 qDebug();
313
314
315 if(m_binaryData.size() == 0)
316 return mzindex_values;
317 qDebug();
318
319 std::size_t size = m_scanSizeList[scanNum];
320
321 std::size_t offset = m_scanOffsetList[scanNum];
322
323 qDebug() << " offset=" << offset << " size=" << size;
324 if(size == 0)
325 return mzindex_values;
326
327 qint32 value = 0;
328 qint32 tof_index = 0;
329 // std::vector<quint32> index_list;
330 for(std::size_t i = 0; i < size; i++)
331 {
332 value = (*(qint32 *)(m_binaryData.constData() + offset + (i * 4)));
333
334 if(value < 0)
335 {
336 tof_index += -1 * value;
337 }
338 else
339 {
340 mzindex_values.push_back(tof_index);
341 tof_index++;
342 }
343 }
344
345
346 qDebug();
347 return mzindex_values;
348 }
349 catch(PappsoException &error)
350 {
351 throw pappso::PappsoException(QObject::tr("Error %1 frameId=%2 "
352 "scanNum=%3 :\n%4")
353 .arg(__FUNCTION__)
354 .arg(getId())
355 .arg(scanNum)
356 .arg(error.qwhat()));
357 }
358 qDebug();
359}
360
361std::vector<quint32>
362TimsFrameType1::getScanIntensityList(std::size_t scanNum) const
363{
364
365
366 qDebug() << " scanNum=" << scanNum;
367
368 checkScanNum(scanNum);
369
370 std::vector<quint32> int_values;
371
372 try
373 {
374 qDebug();
375
376
377 if(m_binaryData.size() == 0)
378 return int_values;
379 qDebug();
380
381 std::size_t size = m_scanSizeList[scanNum];
382
383 std::size_t offset = m_scanOffsetList[scanNum];
384
385 qDebug() << " offset=" << offset << " size=" << size;
386 if(size == 0)
387 return int_values;
388
389 qint32 value = 0;
390 qint32 tof_index = 0;
391 // std::vector<quint32> index_list;
392 for(std::size_t i = 0; i < size; i++)
393 {
394 value = (*(qint32 *)(m_binaryData.constData() + offset + (i * 4)));
395
396 if(value < 0)
397 {
398 tof_index += -1 * value;
399 }
400 else
401 {
402 int_values.push_back(value);
403 tof_index++;
404 }
405 }
406
407
408 qDebug();
409 return int_values;
410 }
411 catch(PappsoException &error)
412 {
413 throw pappso::PappsoException(QObject::tr("Error %1 frameId=%2 "
414 "scanNum=%3 :\n%4")
415 .arg(__FUNCTION__)
416 .arg(getId())
417 .arg(scanNum)
418 .arg(error.qwhat()));
419 }
420}
421
423TimsFrameType1::getMassSpectrumSPtr(std::size_t scanNum) const
424{
425
426 qDebug() << " scanNum=" << scanNum;
427
428 checkScanNum(scanNum);
429
430 try
431 {
432 qDebug();
433
434 pappso::MassSpectrumSPtr mass_spectrum_sptr = std::make_shared<pappso::MassSpectrum>();
435 // std::vector<DataPoint>
436
437 if(m_binaryData.size() == 0)
438 return mass_spectrum_sptr;
439 qDebug();
440
441 std::size_t size = m_scanSizeList[scanNum];
442
443 std::size_t offset = m_scanOffsetList[scanNum];
444
445 qDebug() << " offset=" << offset << " size=" << size;
446 if(size == 0)
447 return mass_spectrum_sptr;
448
449
450 MzCalibrationInterface *mz_calibration_p = getMzCalibrationInterfaceSPtr().get();
451
452
453 qint32 value = 0;
454 qint32 tof_index = 0;
455 // std::vector<quint32> index_list;
456 DataPoint data_point;
457 for(std::size_t i = 0; i < size; i++)
458 {
459 value = (*(qint32 *)(m_binaryData.constData() + offset + (i * 4)));
460
461 if(value < 0)
462 {
463 tof_index += -1 * value;
464 }
465 else
466 {
467 data_point.y = value;
468
469 // intensity normalization
470 data_point.y *= 100.0 / m_acqDurationInMilliseconds;
471
472
473 // mz calibration
474 data_point.x = mz_calibration_p->getMzFromTofIndex(tof_index);
475 mass_spectrum_sptr.get()->push_back(data_point);
476 tof_index++;
477 }
478 }
479
480
481 qDebug() << mass_spectrum_sptr.get()->toString();
482 return mass_spectrum_sptr;
483 }
484 catch(PappsoException &error)
485 {
487 QObject::tr("Error TimsFrameType1::getMassSpectrumSPtr frameId=%1 "
488 "scanNum=%2 :\n%3")
489 .arg(getId())
490 .arg(scanNum)
491 .arg(error.qwhat()));
492 }
493}
494
495
497TimsFrameType1::getRawTraceSPtr(std::size_t scanNum) const
498{
499
500 // qDebug();
501
502 pappso::TraceSPtr trace_sptr = std::make_shared<pappso::Trace>();
503 // std::vector<DataPoint>
504
505 if(m_binaryData.size() == 0)
506 return trace_sptr;
507 qDebug();
508
509 std::size_t size = m_scanSizeList[scanNum];
510
511 std::size_t offset = m_scanOffsetList[scanNum];
512
513 qDebug() << " offset=" << offset << " size=" << size;
514 if(size == 0)
515 return trace_sptr;
516
517 // qDebug();
518 qint32 value = 0;
519 qint32 tof_index = 0;
520
521 // std::vector<quint32> index_list;
522 DataPoint data_point;
523 for(std::size_t i = 0; i < size; i++)
524 {
525 value = (*(qint32 *)(m_binaryData.constData() + offset + (i * 4)));
526
527 if(value < 0)
528 {
529 tof_index += -1 * value;
530 }
531 else
532 {
533 data_point.y = value;
534
535 // intensity normalization
536 data_point.y *= 100.0 / m_acqDurationInMilliseconds;
537
538
539 // mz calibration
540 data_point.x = tof_index;
541 trace_sptr.get()->push_back(data_point);
542 tof_index++;
543 }
544 }
545
546
547 // qDebug();
548 return trace_sptr;
549}
550
551
552std::vector<TimsFrameType1::TofIndexIntensityPair>
554 quint32 accepted_tof_index_range_begin,
555 quint32 accepted_tof_index_range_end) const
556{
557
558 // qDebug();
559
560 std::vector<TimsFrame::TofIndexIntensityPair> trace_sptr;
561 // std::vector<DataPoint>
562
563 if(m_binaryData.size() == 0)
564 return trace_sptr;
565 qDebug();
566
567 std::size_t size = m_scanSizeList[scanNum];
568
569 std::size_t offset = m_scanOffsetList[scanNum];
570
571 qDebug() << " offset=" << offset << " size=" << size;
572 if(size == 0)
573 return trace_sptr;
574
575 // qDebug();
576 qint32 value = 0;
577 qint32 tof_index = 0;
578
579 // std::vector<quint32> index_list;
581 for(std::size_t i = 0; i < size; i++)
582 {
583 value = (*(qint32 *)(m_binaryData.constData() + offset + (i * 4)));
584
585 if(value < 0)
586 {
587 tof_index += -1 * value;
588 }
589 else
590 {
591 data_point.intensity_index = value;
592
593 if(data_point.intensity_index < accepted_tof_index_range_begin)
594 {
595 tof_index++;
596 continue;
597 }
598 if(data_point.intensity_index > accepted_tof_index_range_end)
599 {
600 break;
601 }
602 // intensity normalization
603 data_point.intensity_index *= 100.0 / m_acqDurationInMilliseconds;
604
605
606 // mz calibration
607 data_point.tof_index = tof_index;
608 trace_sptr.push_back(data_point);
609 tof_index++;
610 }
611 }
612
613
614 // qDebug();
615 return trace_sptr;
616}
617
618} // namespace pappso
virtual double getMzFromTofIndex(quint32 tof_index)=0
get m/z from time of flight raw index
virtual const QString & qwhat() const
replacement for std::map
std::size_t accumulateIntensity(quint32 tofIndex, std::size_t intensity)
accumulates intesity for the given tof index
double m_acqDurationInMilliseconds
acquisition duration in milliseconds
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
std::size_t getId() const
virtual void cumulateScan2(std::size_t scanNum, TimsDataFastMap &accumulate_into, quint32 accepted_tof_index_range_begin, quint32 accepted_tof_index_range_end) const override
virtual std::size_t getScanPeakCount(std::size_t scanNum) const override
get the number of peaks in this spectrum need the binary file
virtual std::vector< quint32 > getScanIntensityList(std::size_t scanNum) const override
get raw intensities without transformation from one scan it needs intensity normalization
std::vector< std::size_t > m_scanSizeList
TimsFrameType1(std::size_t timsId, quint32 scanNum, char *p_bytes, std::size_t len)
void copyAndLzfDecompress(const char *src, std::size_t len)
copy buffer header and lzf decompress each scan for tims compression type 1
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
unsigned int lzfDecompressScan(const char *src, unsigned int src_len, char *dest, unsigned int dest_len)
decompress a single LZF compressed scan buffer
virtual std::vector< TofIndexIntensityPair > getRawValuePairList(std::size_t scanNum, quint32 accepted_tof_index_range_begin, quint32 accepted_tof_index_range_end) const override
get the raw index tof_index and intensities (normalized)
virtual pappso::MassSpectrumSPtr getMassSpectrumSPtr(std::size_t scanNum) const override
get the mass spectrum corresponding to a scan number
virtual void cumulateScan(std::size_t scanNum, TimsDataFastMap &accumulate_into) const override
cumulate a scan into a map
std::vector< std::size_t > m_scanOffsetList
virtual pappso::TraceSPtr getRawTraceSPtr(std::size_t scanNum) const override
get the raw index tof_index and intensities (normalized)
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
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