libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
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
32#include <QDataStream>
33#include <QThread>
34#include <zstd.h>
37
38using namespace pappso;
39
40TimsBinDec::TimsBinDec(const QFileInfo &timsBinFile, int timsCompressionType)
41 : m_timsBinFile(timsBinFile.absoluteFilePath())
42{
43 m_timsCompressionType = timsCompressionType;
44 if((timsCompressionType != 1) && (timsCompressionType != 2))
45 {
47 QObject::tr("compression type %1 not handled by this library").arg(timsCompressionType));
48 }
49 if(m_timsBinFile.isEmpty())
50 {
51 throw pappso::PappsoException(QObject::tr("No TIMS binary file name specified"));
52 }
53 QFile file(m_timsBinFile);
54 if(!file.open(QIODevice::ReadOnly))
55 {
56 throw PappsoException(QObject::tr("ERROR opening TIMS binary file %1 for read")
57 .arg(timsBinFile.absoluteFilePath()));
58 }
59}
60
61
65
67{
68
69
70 if(mpa_decompressMemoryBuffer != nullptr)
71 {
73 }
74
75 if(mp_fileLinear != nullptr)
76 {
77 mp_fileLinear->close();
78 delete mp_fileLinear;
79 }
80 if(mp_fileRandom != nullptr)
81 {
82 mp_fileRandom->close();
83 delete mp_fileRandom;
84 }
85}
86
87void
89{
90 // qDebug();
91 if(mp_fileLinear != nullptr)
92 {
93 mp_fileLinear->close();
94 delete mp_fileLinear;
95 }
96 mp_fileLinear = nullptr;
98 m_lastFrameId = 0;
100 // qDebug();
101}
102
103
104QFile *
105TimsBinDec::getQfileLinear(std::size_t frameId,
106 const std::vector<pappso::TimsFrameRecord> &frame_record_list)
107{
108 if(mp_fileLinear == nullptr)
109 {
110 mp_fileLinear = new QFile(m_timsBinFile);
111 if(!mp_fileLinear->open(QIODevice::ReadOnly))
112 {
113 throw PappsoException(
114 QObject::tr("ERROR opening TIMS binary file %1 for read").arg(m_timsBinFile));
115 }
116
117 startLinearRead(frameId, m_linearAccessRawDataChunckDequeSize, frame_record_list);
118 }
119
120 return mp_fileLinear;
121}
122
123QFile *
125{
126 if(mp_fileRandom == nullptr)
127 {
128 mp_fileRandom = new QFile(m_timsBinFile);
129 if(!mp_fileRandom->open(QIODevice::ReadOnly))
130 {
131 throw PappsoException(
132 QObject::tr("ERROR opening TIMS binary file %1 for read").arg(m_timsBinFile));
133 }
134 }
135 return mp_fileRandom;
136}
137
140 const std::vector<pappso::TimsFrameRecord> &frame_record_list)
141{
142
143 qDebug() << "frameId:" << frameId;
144
145 // QMutexLocker locker(&m_mutex);
146 QFile *p_file = getQfileLinear(frameId, frame_record_list);
147
148 if(mp_fileLinear->pos() < (qint64)frame_record_list[m_firstFrameId].tims_offset)
149 {
150 }
151 else
152 {
153 if(frameId > m_lastFrameId)
154 {
156 {
157 // move forward
158 moveLinearReadForward(frame_record_list);
159 }
160 }
161 }
162
163 auto it = std::find_if(m_linearAccessRawDataChunckList.begin(),
165 [frameId](const TimsFrameRawDataChunck &chunck) {
166 if(chunck.getFrameId() == frameId)
167 return true;
168 return false;
169 });
170 if(it != m_linearAccessRawDataChunckList.end())
171 {
172 try
173 {
175 }
176 catch(PappsoException &error)
177 {
178
179 throw PappsoException(QObject::tr("ERROR reading TIMS binary file %1 with linear QFile: "
180 "%2")
181 .arg(m_timsBinFile)
182 .arg(error.qwhat()));
183 }
184 }
185
186 // random access file
187 // qDebug();
188 p_file = getQfileRandom();
189 bool seekpos_ok = p_file->seek(frame_record_list[frameId].tims_offset);
190 if(!seekpos_ok)
191 {
192 throw PappsoException(QObject::tr("ERROR reading TIMS frame %1 TIMS binary file %2: "
193 "m_timsBinFile.seek(%3) failed")
194 .arg(frameId)
195 .arg(m_timsBinFile)
196 .arg(frame_record_list[frameId].tims_offset));
197 }
198
199
200 try
201 {
202 m_randemAccessFrameRawDataChunck.readTimsFrame(p_file, frameId, frame_record_list);
203 }
204 catch(PappsoException &error)
205 {
206
207 throw PappsoException(QObject::tr("ERROR reading TIMS binary file %1 with random QFile: "
208 "%2")
209 .arg(m_timsBinFile)
210 .arg(error.qwhat()));
211 }
212
214}
215
216void
218 const std::vector<pappso::TimsFrameRecord> &frame_record_list)
219{
220 // qDebug();
221 for(std::size_t i = 0; i < m_linearForwardThreshold; i++)
222 {
223 auto it =
224 std::min_element(m_linearAccessRawDataChunckList.begin(),
227 return a.getFrameId() < b.getFrameId();
228 });
231 if(m_lastFrameId >= frame_record_list.size())
232 break;
233 it->readTimsFrame(mp_fileLinear, m_lastFrameId, frame_record_list);
234 }
235 // qDebug();
236}
237
238
241{
242 // qDebug();
243 TimsFrameSPtr frame_sptr;
244 if(raw_data_chunck.getCompressedSize() > 0)
245 {
246 // qDebug();
247 if(m_timsCompressionType == 2)
248 {
249 auto decompressed_size2 = ZSTD_getFrameContentSize(raw_data_chunck.getMemoryBuffer(),
250 raw_data_chunck.getCompressedSize());
251 // qDebug();
252 if(decompressed_size2 == ZSTD_CONTENTSIZE_UNKNOWN)
253 {
254 throw PappsoException(QObject::tr("ERROR TimsBinDec::getTimsFrameFromRawDataChunck "
255 "reading TIMS frame %1 TIMS binary file %2: "
256 " decompressed_size2 == ZSTD_CONTENTSIZE_UNKNOWN, "
257 "frame_length=%3")
258 .arg(raw_data_chunck.getFrameId())
259 .arg(m_timsBinFile)
260 .arg(raw_data_chunck.getFrameLength()));
261 }
262 // qDebug();
263 if(decompressed_size2 == ZSTD_CONTENTSIZE_ERROR)
264 {
265 // qDebug();
266 throw PappsoException(QObject::tr("ERROR TimsBinDec::getTimsFrameFromRawDataChunck "
267 "reading TIMS frame %1 TIMS binary file %2: "
268 " decompressed_size2 == ZSTD_CONTENTSIZE_ERROR, "
269 "frame_length=%3")
270 .arg(raw_data_chunck.getFrameId())
271 .arg(m_timsBinFile)
272 .arg(raw_data_chunck.getFrameLength()));
273 }
274 qDebug() << " decompressed_size2=" << decompressed_size2;
275
276 if(m_decompressMemoryBufferSize < (decompressed_size2 + 10))
277 {
278 if(mpa_decompressMemoryBuffer != nullptr)
279 {
281 }
282 m_decompressMemoryBufferSize = decompressed_size2 + 10;
284 }
285 std::size_t decompressed_size = ZSTD_decompress(mpa_decompressMemoryBuffer,
287 raw_data_chunck.getMemoryBuffer(),
288 raw_data_chunck.getCompressedSize());
289 // qDebug();
290
291 if(decompressed_size != decompressed_size2)
292 {
293 throw PappsoException(QObject::tr("ERROR TimsBinDec::getTimsFrameFromRawDataChunck "
294 "reading TIMS frame %1 TIMS binary file %2: "
295 "decompressed_size != decompressed_size2")
296 .arg(raw_data_chunck.getFrameId())
297 .arg(m_timsBinFile)
298 .arg(decompressed_size)
299 .arg(decompressed_size2));
300 }
301
302 // qDebug();
303
304 frame_sptr = std::make_shared<TimsFrame>(raw_data_chunck.getFrameId(),
305 raw_data_chunck.getFrameNumberOfScans(),
307 decompressed_size);
308 }
309 else
310 {
311
312 if(m_timsCompressionType == 1)
313 {
314 frame_sptr = std::make_shared<TimsFrameType1>(raw_data_chunck.getFrameId(),
315 raw_data_chunck.getFrameNumberOfScans(),
316 raw_data_chunck.getMemoryBuffer(),
317 raw_data_chunck.getCompressedSize());
318 }
319 }
320 // delete[] mpa_decompressMemoryBuffer;
321 }
322 else
323 {
324 frame_sptr = std::make_shared<TimsFrame>(
325 raw_data_chunck.getFrameId(), raw_data_chunck.getFrameNumberOfScans(), nullptr, 0);
326 }
327 return frame_sptr;
328}
329/*
330TimsFrameCstSPtr
331TimsBinDec::getTimsFrameCstSPtr(std::size_t timsId)
332{
333 return getTimsFrameCstSPtrByOffset(timsId, m_indexArray[timsId]);
334}
335*/
336
337void
338pappso::TimsBinDec::startLinearRead(std::size_t start_frame_id,
339 std::size_t chunk_deque_size,
340 const std::vector<pappso::TimsFrameRecord> &frame_record_list)
341{
342 // qDebug();
343 m_linearAccessRawDataChunckList.resize(chunk_deque_size);
344 m_firstFrameId = start_frame_id;
345 m_lastFrameId = start_frame_id;
346
347 QFile *p_file = mp_fileLinear;
348 if(p_file == nullptr)
349 {
350 throw PappsoException(QObject::tr("ERROR mp_fileLinear == nullptr"));
351 }
352
353 bool seekpos_ok = p_file->seek(frame_record_list[start_frame_id].tims_offset);
354 if(!seekpos_ok)
355 {
356 throw PappsoException(QObject::tr("ERROR reading TIMS frame %1 TIMS binary file %2: "
357 "m_timsBinFile.seek(%3) failed")
358 .arg(start_frame_id)
359 .arg(m_timsBinFile)
360 .arg(frame_record_list[start_frame_id].tims_offset));
361 }
362
363 try
364 {
366 {
367
368 chunck.readTimsFrame(p_file, start_frame_id, frame_record_list);
369 m_lastFrameId = start_frame_id;
370 start_frame_id++;
371 }
372 }
373 catch(PappsoException &error)
374 {
375
376 throw PappsoException(
377 QObject::tr("ERROR in TimsBinDec::startLinearRead reading TIMS binary file %1:\n "
378 " start_frame_id=%2 m_firstFrameId=%3 m_lastFrameId=%4 "
379 "%5")
380 .arg(m_timsBinFile)
381 .arg(start_frame_id)
382 .arg(m_firstFrameId)
383 .arg(m_lastFrameId)
384 .arg(error.qwhat()));
385 }
386
387 // qDebug();
388}
virtual const QString & qwhat() const
std::size_t m_firstFrameId
Definition timsbindec.h:113
std::size_t m_decompressMemoryBufferSize
Definition timsbindec.h:107
TimsFrameSPtr getTimsFrameSPtrByOffset(std::size_t frameId, const std::vector< pappso::TimsFrameRecord > &frame_record_list)
void startLinearRead(std::size_t start_frame_id, std::size_t chunk_deque_size, const std::vector< pappso::TimsFrameRecord > &frame_record_list)
populate a fifo buffer with TimsFrameRawDataChunck accelerates inputs from file
QFile * getQfileRandom()
open one QFile handler for random read
std::size_t m_linearForwardThreshold
Definition timsbindec.h:116
void closeLinearRead()
close file access and flush cache
std::size_t m_lastFrameId
Definition timsbindec.h:114
std::size_t m_linearAccessRawDataChunckDequeSize
Definition timsbindec.h:115
QFile * getQfileLinear(std::size_t frameId, const std::vector< pappso::TimsFrameRecord > &frame_record_list)
open one QFile handler for linear read
std::vector< TimsFrameRawDataChunck > m_linearAccessRawDataChunckList
Definition timsbindec.h:112
void moveLinearReadForward(const std::vector< pappso::TimsFrameRecord > &frame_record_list)
TimsBinDec(const QFileInfo &timsBinFile, int timsCompressionType)
virtual ~TimsBinDec()
TimsFrameSPtr getTimsFrameFromRawDataChunck(const TimsFrameRawDataChunck &raw_data_chunck)
TimsFrameRawDataChunck m_randemAccessFrameRawDataChunck
Definition timsbindec.h:109
char * mpa_decompressMemoryBuffer
Definition timsbindec.h:106
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:43