libpappsomspp
Library for mass spectrometry
timsbindec.cpp
Go to the documentation of this file.
1 /**
2  * \file pappsomspp/vendors/tims/timsbindec.h
3  * \date 23/08/2019
4  * \author Olivier Langella
5  * \brief binary file handler of Bruker's TimsTof raw data
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 "timsbindec.h"
29 #include "../../../pappsomspp/pappsoexception.h"
30 #include "../../../pappsomspp/exception/exceptionnotimplemented.h"
31 #include "timsframetype1.h"
32 #include <QDataStream>
33 #include <zstd.h>
34 
35 using namespace pappso;
36 
37 TimsBinDec::TimsBinDec(const QFileInfo &timsBinFile, int timsCompressionType)
38  : m_timsBinFile(timsBinFile.absoluteFilePath())
39 {
40  m_timsCompressionType = timsCompressionType;
41  if((timsCompressionType != 1) && (timsCompressionType != 2))
42  {
44  QObject::tr("compression type %1 not handled by this library")
45  .arg(timsCompressionType));
46  }
47  if(m_timsBinFile.isEmpty())
48  {
50  QObject::tr("No TIMS binary file name specified"));
51  }
52  QFile file(m_timsBinFile);
53  if(!file.open(QIODevice::ReadOnly))
54  {
55  throw PappsoException(
56  QObject::tr("ERROR opening TIMS binary file %1 for read")
57  .arg(timsBinFile.absoluteFilePath()));
58  }
59 }
60 
61 
63  : m_timsBinFile(other.m_timsBinFile)
64 {
65 }
66 
68 {
69  if(mpa_memoryBuffer != nullptr)
70  {
71  delete[] mpa_memoryBuffer;
72  mpa_memoryBuffer = nullptr;
73  }
74 
75 
76  if(mpa_decompressMemoryBuffer != nullptr)
77  {
79  }
80 }
81 
82 
83 void
85 {
86 
87  qDebug();
88  QFile file(m_timsBinFile);
89  QDataStream bin_in(&file);
90  bin_in.setByteOrder(QDataStream::ByteOrder::LittleEndian);
91  // m_indexArray.push_back(0);
92 
93  // QChar first_char;
94  // txt_in >> first_char;
95  quint32 number_in;
96  qint64 position(0);
97  qint8 trash;
98  while(!bin_in.atEnd())
99  {
100  while((!bin_in.atEnd()) && (position % 4 != 0))
101  {
102  bin_in >> trash;
103  position += 1;
104  if(trash != 0)
105  { /*
106  throw PappsoException(
107  QObject::tr("ERROR reading TIMS frame %1 TIMS binary file %2: "
108  "trash%3 != 0")
109  .arg(m_indexArray.size())
110  .arg(m_timsBinFile.fileName())
111  .arg(trash));*/
112  }
113  }
114  quint32 frame_len(0);
115  while((!bin_in.atEnd()) && (frame_len == 0))
116  {
117  bin_in >> frame_len;
118  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__
119  // << " i=" << i;
120  position += 4;
121  }
122 
123  // m_indexArray.push_back(position - 4);
124  /*
125  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__
126  << " frame_len=" << frame_len
127  << " frameid=" << m_indexArray.size() - 1
128  << " back=" << m_indexArray.back() << " position=" <<
129  position;
130 
131 
132  quint64 next_frame = m_indexArray.back() + frame_len;
133  */
134 
135  bin_in >> number_in;
136  position += 4;
137  qDebug() << " number_in(nb scans)=" << number_in
138  << " position=" << position;
139  ;
140  /*
141 
142  while((!bin_in.atEnd()) && (position < next_frame))
143  {
144  bin_in >> trash;
145  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " <<
146  __LINE__
147  // << " i=" << i;
148  position += 1;
149  }*/
150  }
151  qDebug();
152 }
153 
155 TimsBinDec::getTimsFrameSPtrByOffset(std::size_t timsId, std::size_t timsOffset)
156 {
157  qDebug() << "timsId:" << timsId << "timsOffset:" << timsOffset;
158 
159  // QMutexLocker locker(&m_mutex);
160  QFile file(m_timsBinFile);
161  if(!file.open(QIODevice::ReadOnly))
162  {
163  throw PappsoException(
164  QObject::tr("ERROR opening TIMS binary file %1 for read")
165  .arg(m_timsBinFile));
166  }
167  qDebug();
168  bool seekpos_ok = file.seek(timsOffset);
169  if(!seekpos_ok)
170  {
171  throw PappsoException(
172  QObject::tr("ERROR reading TIMS frame %1 TIMS binary file %2: "
173  "m_timsBinFile.seek(%3) failed")
174  .arg(timsId)
175  .arg(m_timsBinFile)
176  .arg(timsOffset));
177  }
178 
179  qDebug();
180  quint32 frame_length;
181  file.read((char *)&frame_length, 4);
182  // frame_length = qToBigEndian(frame_length);
183 
184  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__
185  // << " frame_length=" << frame_length;
186 
187  qDebug();
188  quint32 scan_number;
189  file.read((char *)&scan_number, 4);
190  // scan_number = qToBigEndian(scan_number);
191  frame_length -= 8;
192 
193  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__
194  // << " pos=" << m_timsBinFile.pos();
195 
196  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__
197  // << " scan_number=" << scan_number;
198  // m_timsBinFile.seek(m_indexArray.at(timsId) + 8);
199 
200 
201  qDebug();
202 
203  // if (m_memoryBufferSize
204  if(mpa_memoryBuffer == nullptr)
205  {
206  qDebug() << "mpa_memoryBuffer == nullptr";
207  m_memoryBufferSize = (qint64)frame_length + 10;
209  }
210  if((m_memoryBufferSize - 10) < frame_length)
211  {
212  if(mpa_memoryBuffer != nullptr)
213  {
214  delete[] mpa_memoryBuffer;
215  }
216  m_memoryBufferSize = (qint64)frame_length + 10;
218  }
219 
220 
221  // QByteArray frame_byte_array(mpa_memoryBuffer, m_memoryBufferSize);
222 
223  qDebug();
224  qint64 read_length = file.read(mpa_memoryBuffer, (qint64)frame_length + 2);
225  qDebug();
226  file.close();
227 
228  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__
229  // << " +frame_length-1="
230  // << (quint8) * (frame_byte_array.constData() + frame_length - 1);
231  // qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__
232  // << " +frame_length="
233  // << (quint8) * (frame_byte_array.constData() + frame_length);
234  // m_timsBinFile.seek(m_indexArray.at(timsId) + 8);
235 
236  if(read_length - 2 != (qint64)frame_length)
237  {
238  throw PappsoException(
239  QObject::tr("ERROR reading TIMS frame %1 TIMS binary file %2: "
240  "read_length=%3 != %4frame_length")
241  .arg(timsId)
242  .arg(m_timsBinFile)
243  .arg(read_length)
244  .arg(frame_length));
245  }
246  qDebug();
247  TimsFrameSPtr frame_sptr;
248  if(frame_length > 0)
249  {
250  qDebug();
251  if(m_timsCompressionType == 2)
252  {
253  auto decompressed_size2 =
254  ZSTD_getFrameContentSize(mpa_memoryBuffer, frame_length);
255  qDebug();
256  if(decompressed_size2 == ZSTD_CONTENTSIZE_UNKNOWN)
257  {
258  throw PappsoException(
259  QObject::tr("ERROR reading TIMS frame %1 TIMS binary file %2: "
260  " decompressed_size2 == ZSTD_CONTENTSIZE_UNKNOWN, "
261  "frame_length=%3")
262  .arg(timsId)
263  .arg(m_timsBinFile)
264  .arg(frame_length));
265  }
266  qDebug();
267  if(decompressed_size2 == ZSTD_CONTENTSIZE_ERROR)
268  {
269  qDebug();
270  throw PappsoException(
271  QObject::tr("ERROR reading TIMS frame %1 TIMS binary file %2: "
272  " decompressed_size2 == ZSTD_CONTENTSIZE_ERROR, "
273  "frame_length=%3")
274  .arg(timsId)
275  .arg(m_timsBinFile)
276  .arg(frame_length));
277  }
278  qDebug() << " decompressed_size2=" << decompressed_size2;
279 
280  if(m_decompressMemoryBufferSize < (decompressed_size2 + 10))
281  {
282  if(mpa_decompressMemoryBuffer != nullptr)
283  {
285  }
286  m_decompressMemoryBufferSize = decompressed_size2 + 10;
289  }
290  std::size_t decompressed_size =
291  ZSTD_decompress(mpa_decompressMemoryBuffer,
294  frame_length);
295  qDebug();
296 
297  if(decompressed_size != decompressed_size2)
298  {
299  throw PappsoException(
300  QObject::tr("ERROR reading TIMS frame %1 TIMS binary file %2: "
301  "decompressed_size != decompressed_size2")
302  .arg(timsId)
303  .arg(m_timsBinFile)
304  .arg(decompressed_size)
305  .arg(decompressed_size2));
306  }
307 
308  qDebug();
309 
310  frame_sptr = std::make_shared<TimsFrame>(
311  timsId, scan_number, mpa_decompressMemoryBuffer, decompressed_size);
312  }
313  else
314  {
315 
316  if(m_timsCompressionType == 1)
317  {
318  frame_sptr = std::make_shared<TimsFrameType1>(
319  timsId, scan_number, mpa_memoryBuffer, frame_length);
320  }
321  }
322  // delete[] mpa_decompressMemoryBuffer;
323  }
324  else
325  {
326  frame_sptr = std::make_shared<TimsFrame>(timsId, scan_number, nullptr, 0);
327  }
328  return frame_sptr;
329 }
330 /*
331 TimsFrameCstSPtr
332 TimsBinDec::getTimsFrameCstSPtr(std::size_t timsId)
333 {
334  return getTimsFrameCstSPtrByOffset(timsId, m_indexArray[timsId]);
335 }
336 */
std::size_t m_decompressMemoryBufferSize
Definition: timsbindec.h:77
char * mpa_memoryBuffer
Definition: timsbindec.h:72
TimsBinDec(const QFileInfo &timsBinFile, int timsCompressionType)
Definition: timsbindec.cpp:37
qint64 m_memoryBufferSize
Definition: timsbindec.h:73
QString m_timsBinFile
Definition: timsbindec.h:70
char * mpa_decompressMemoryBuffer
Definition: timsbindec.h:76
TimsFrameSPtr getTimsFrameSPtrByOffset(std::size_t timsId, std::size_t timsOffset)
Definition: timsbindec.cpp:155
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition: aa.cpp:39
std::shared_ptr< TimsFrame > TimsFrameSPtr
Definition: timsframe.h:41
binary file handler of Bruker's TimsTof raw data
handle a single Bruker's TimsTof frame type 1 compression