libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
utils.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 * Copyright (c) 2015 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
3 *
4 * This file is part of the PAPPSOms++ library.
5 *
6 * PAPPSOms++ is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * PAPPSOms++ is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with PAPPSOms++. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Contributors:
20 * Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and
21 *implementation
22 ******************************************************************************/
23
24/////////////////////// StdLib includes
25#include <cmath>
26#include <iomanip>
27
28
29/////////////////////// Qt includes
30#include <QDebug>
31#include <QFile>
32#include <QTextStream>
33
34
35/////////////////////// Local includes
36#include "utils.h"
37#include "types.h"
39#include "trace/trace.h"
40
41
42namespace pappso
43{
44
45// Matches a double (decimal value, that is, m/z
46// value)
48 QRegularExpression("\\d*\\.?\\d+");
49
50// Matches anything that is not digit, '.', or '-'
51// (that is, matches a separator
52QRegularExpression Utils::anythingButDigitDotDash =
53 QRegularExpression("[^\\d^\\.^-]+");
54
55// Matches a double (with exp notation
56// possibly) and also potentially a '-' sign. This is the intensity.
58 QRegularExpression("-?\\d*\\.?\\d*[e-]?\\d*");
59
60// Matches <number><separator><number>, that is: m/z<separator>intensity.
61QRegularExpression Utils::xyMassDataFormatRegExp =
62 // QRegularExpression("^(\\d*\\.?\\d+)([^\\d^\\.^-]+)(-?\\d*\\.?\\d*[e-]?\\d*)");
63 QRegularExpression(
64 QString("^(%1)(%2)(%3)")
66 .arg(Utils::anythingButDigitDotDash.pattern())
68
69
70QRegularExpression Utils::endOfLineRegExp = QRegularExpression("^\\s+$");
71
72const QString
74{
75 int size = log10(num);
76 size += 97;
77 QLatin1Char latin1_char(size);
78 QString base(latin1_char);
79 base.append(QString().setNum(num));
80 return (base);
81}
82
83
84void
85Utils::writeLexicalOrderedString(QTextStream *p_out, unsigned int num)
86{
87 *p_out << (char)(log10(num) + 97) << num;
88}
89
90
91//! Determine the number of zero decimals between the decimal point and the
92//! first non-zero decimal.
93/*!
94 * 0.11 would return 0 (no empty decimal)
95 * 2.001 would return 2
96 * 1000.0001254 would return 3
97 *
98 * \param value the value to be analyzed
99 * \return the number of '0' decimals between the decimal separator '.' and
100 * the first non-0 decimal
101 */
102int
104{
105 // qDebug() << qSetRealNumberPrecision(10) << "Double value: " << value;
106
107 int intPart = static_cast<int>(value);
108
109 // qDebug() << "int part:" << intPart;
110
111 double decimalPart = value - intPart;
112
113 // qDebug() << qSetRealNumberPrecision(10) << "decimal part: " << decimalPart;
114
115 int count = 0;
116
117 while(decimalPart > 0)
118 {
119 ++count;
120
121 decimalPart *= 10;
122
123 // qDebug() << "Iteration " << count << "decimal part:" << decimalPart;
124
125 if(decimalPart >= 1)
126 {
127 // qDebug() << "Because decimal part " << decimalPart
128 //<< "is >= 1, breaking loop while count is " << count << ".";
129
130 break;
131 }
132 }
133
134 // qDebug() << "Returning count:" << count - 1;
135
136 return count - 1;
137}
138
139
141Utils::roundToDecimals(pappso_double value, int decimal_places)
142{
143 if(decimal_places < 0)
144 return value;
145
146 return ceil((value * pow(10, decimal_places)) - 0.49) /
147 pow(10, decimal_places);
148}
149
150
151long long int
153{
154 pappso::pappso_double test_decimal = 100000000000;
155 if(sizeof(int *) == 4)
156 { // 32bits
157 test_decimal = 100000000;
158 }
159 return (floor(input * test_decimal));
160}
161
162
163std::string
164Utils::toUtf8StandardString(const QString &text)
165{
166 std::string env_backup = setlocale(LC_ALL, "");
167
168 // struct lconv *lc_backup = localeconv();
169 // qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << "()"
170 //<< "env_backup=" << env_backup.c_str() << "lc_backup->decimal_point"
171 //<< lc_backup->decimal_point;
172
173 // Force locale to be "C".
174 setlocale(LC_ALL, "C");
175
176 // Now perform the conversion.
177 QByteArray byte_array = text.toUtf8();
178 std::string stdText = "";
179
180 for(char c : byte_array)
181 {
182 stdText += c;
183 }
184
185 // Set back the locale to the backed-up one.
186 setlocale(LC_ALL, env_backup.c_str());
187
188 return stdText;
189}
190
191
192bool
193Utils::writeToFile(const QString &text, const QString &file_name)
194{
195
196 QFile file(file_name);
197
198 if(file.open(QFile::WriteOnly | QFile::Truncate))
199 {
200
201 QTextStream out(&file);
202
203 out << text;
204
205 out.flush();
206 file.close();
207
208 return true;
209 }
210
211 return false;
212}
213
214
215bool
216Utils::appendToFile(const QString &text, const QString &file_name)
217{
218
219 QFile file(file_name);
220
221 if(file.open(QFile::WriteOnly | QFile::Append))
222 {
223
224 QTextStream out(&file);
225
226 out << text;
227
228 out.flush();
229 file.close();
230
231 return true;
232 }
233
234 return false;
235}
236
237
238std::size_t
239Utils::extractScanNumberFromMzmlNativeId(const QString &spectrum_native_id)
240{
241 qDebug() << " " << spectrum_native_id;
242 QStringList native_id_list = spectrum_native_id.split("=");
243 if(native_id_list.size() < 2)
244 {
245 throw ExceptionNotFound(
246 QObject::tr("scan number not found in mzML native id %1")
247 .arg(spectrum_native_id));
248 }
249 else
250 {
251 /** TODO activate this in a future release to ensure scan number
252 for(auto i = 0; i < native_id_list.size(); i += 2)
253 {
254 if(native_id_list[i] == "scan")
255 {
256 return native_id_list[i + 1].toULong();
257 }
258 }
259
260 throw ExceptionNotFound(
261 QObject::tr("scan number not found in mzML native id %1")
262 .arg(spectrum_native_id));
263
264*/
265 return native_id_list.back().toULong();
266 }
267 return 0;
268}
269
270
271QString
272Utils::pointerToString(const void *const pointer)
273{
274 return QString("%1").arg(
275 (quintptr)pointer, QT_POINTER_SIZE * 2, 16, QChar('0'));
276}
277
278
279//! Tell if both double values, are equal within the double representation
280//! capabilities of the platform.
281bool
282Utils::almostEqual(double value1, double value2, int decimalPlaces)
283{
284 // QString value1String = QString("%1").arg(value1,
285 // 0, 'f', 60);
286 // QString value2String = QString("%1").arg(value2,
287 // 0, 'f', 60);
288
289 // qWarning() << __FILE__ << __LINE__ << __FUNCTION__
290 //<< "value1:" << value1String << "value2:" << value2String;
291
292 // The machine epsilon has to be scaled to the magnitude of the values used
293 // and multiplied by the desired precision in ULPs (units in the last place)
294 // (decimal places).
295
296 double valueSum = std::abs(value1 + value2);
297 // QString valueSumString = QString("%1").arg(valueSum,
298 // 0, 'f', 60);
299
300 double valueDiff = std::abs(value1 - value2);
301 // QString valueDiffString = QString("%1").arg(valueDiff,
302 // 0, 'f', 60);
303
304 double epsilon = std::numeric_limits<double>::epsilon();
305 // QString epsilonString = QString("%1").arg(epsilon,
306 // 0, 'f', 60);
307
308 double scaleFactor = epsilon * valueSum * decimalPlaces;
309 // QString scaleFactorString = QString("%1").arg(scaleFactor,
310 // 0, 'f', 60);
311
312 // qWarning() << "valueDiff:" << valueDiffString << "valueSum:" <<
313 // valueSumString <<
314 //"epsilon:" << epsilonString << "scaleFactor:" << scaleFactorString;
315
316 bool res = valueDiff < scaleFactor
317 // unless the result is subnormal:
318 || valueDiff < std::numeric_limits<double>::min();
319
320 // qWarning() << __FILE__ << __LINE__ << __FUNCTION__
321 //<< "returning res:" << res;
322
323 return res;
324}
325
326
327double
329{
330 return std::nextafter(value, value + 1);
331}
332
333
334QString
336 const QString &msg, std::chrono::system_clock::time_point chrono_time)
337{
338
339 time_t tt;
340
341 tt = std::chrono::system_clock::to_time_t(chrono_time);
342
343 QString debug_text =
344 QString("%1 - %2\n").arg(msg).arg(QString::fromLatin1(ctime(&tt)));
345
346 return debug_text;
347}
348
349
350QString
352 const QString &msg,
353 std::chrono::system_clock::time_point chrono_start,
354 std::chrono::system_clock::time_point chrono_finish)
355{
356 QString debug_text =
357 QString(
358 "%1 %2 min = %3 s = %4 ms = %5 "
359 "µs\n")
360 .arg(msg)
361 .arg(std::chrono::duration_cast<std::chrono::minutes>(chrono_finish -
362 chrono_start)
363 .count())
364 .arg(std::chrono::duration_cast<std::chrono::seconds>(chrono_finish -
365 chrono_start)
366 .count())
367 .arg(std::chrono::duration_cast<std::chrono::milliseconds>(chrono_finish -
368 chrono_start)
369 .count())
370 .arg(std::chrono::duration_cast<std::chrono::microseconds>(chrono_finish -
371 chrono_start)
372 .count());
373
374 return debug_text;
375}
376
377
378std::vector<double>
380 std::size_t &error_count)
381{
382
383 QStringList string_list =
384 text.split(QRegularExpression("[\\s]+"), Qt::SkipEmptyParts);
385
386 // qDebug() << "string list:" << string_list;
387
388 std::vector<double> double_vector;
389
390 for(int iter = 0; iter < string_list.size(); ++iter)
391 {
392 QString current_string = string_list.at(iter);
393
394 bool ok = false;
395
396 double current_double = current_string.toDouble(&ok);
397
398 if(!current_double && !ok)
399 {
400 ++error_count;
401 continue;
402 }
403
404 double_vector.push_back(current_double);
405 }
406
407 return double_vector;
408}
409
410
411std::vector<std::size_t>
413 std::size_t &error_count)
414{
415 // qDebug() << "Parsing text:" << text;
416
417 QStringList string_list =
418 text.split(QRegularExpression("[\\s]+"), Qt::SkipEmptyParts);
419
420 // qDebug() << "string list size:" << string_list.size()
421 //<< "values:" << string_list;
422
423 std::vector<std::size_t> sizet_vector;
424
425 for(int iter = 0; iter < string_list.size(); ++iter)
426 {
427 QString current_string = string_list.at(iter);
428
429 bool ok = false;
430
431 std::size_t current_sizet = current_string.toUInt(&ok);
432
433 if(!current_sizet && !ok)
434 {
435 ++error_count;
436 continue;
437 }
438
439 sizet_vector.push_back(current_sizet);
440 }
441
442 return sizet_vector;
443}
444QString
446{
447 if(value)
448 return "TRUE";
449 return "FALSE";
450}
451
452QString
454{
455
456 if(mz_format == MsDataFormat::mzML)
457 return "mzML";
458 else if(mz_format == MsDataFormat::mzXML)
459 return "mzXML";
460 else if(mz_format == MsDataFormat::MGF)
461 return "MGF";
462 else if(mz_format == MsDataFormat::SQLite3)
463 return "SQLite3";
464 else if(mz_format == MsDataFormat::xy)
465 return "xy";
466 else if(mz_format == MsDataFormat::mz5)
467 return "mz5";
468 else if(mz_format == MsDataFormat::msn)
469 return "msn";
470 else if(mz_format == MsDataFormat::abSciexWiff)
471 return "abSciexWiff";
472 else if(mz_format == MsDataFormat::abSciexT2D)
473 return "abSciexT2D";
474 else if(mz_format == MsDataFormat::agilentMassHunter)
475 return "agilentMassHunter";
476 else if(mz_format == MsDataFormat::thermoRaw)
477 return "thermoRaw";
478 else if(mz_format == MsDataFormat::watersRaw)
479 return "watersRaw";
480 else if(mz_format == MsDataFormat::brukerFid)
481 return "brukerFid";
482 else if(mz_format == MsDataFormat::brukerYep)
483 return "brukerYep";
484 else if(mz_format == MsDataFormat::brukerBaf)
485 return "brukerBaf";
486 else if(mz_format == MsDataFormat::brukerTims)
487 return "brukerTims";
488 else if(mz_format == MsDataFormat::brukerBafAscii)
489 return "brukerBafAscii";
490 else
491 return "unknown";
492}
493
494
495QString
497{
498
499 if(file_reader_type == FileReaderType::pwiz)
500 return "pwiz";
501 else if(file_reader_type == FileReaderType::xy)
502 return "xy";
503 else if(file_reader_type == FileReaderType::tims)
504 return "tims";
505 else if(file_reader_type == FileReaderType::tims_frames)
506 return "tims_frames";
507 else
508 return "unknown";
509}
510
511QString
513{
514 switch(type)
515 {
517 return "AL";
518 break;
520 return "NA";
521 break;
523 return "RA";
524 break;
525 default:
526 return "ER";
527 }
528}
529
530QString
532{
533 switch(type)
534 {
536 return "both";
537 break;
539 return "native";
540 break;
542 return "symmetric";
543 break;
544 default:
545 return "synthetic";
546 }
547}
548
549} // namespace pappso
static std::size_t extractScanNumberFromMzmlNativeId(const QString &spectrum_native_id)
Definition utils.cpp:239
static QString chronoTimePointDebugString(const QString &msg, std::chrono::system_clock::time_point chrono_time=std::chrono::system_clock::now())
Definition utils.cpp:335
static QString toString(specglob::SpectralAlignmentType type)
Convenience function to return a string describing the specglob alingment type.
Definition utils.cpp:512
static QString pointerToString(const void *const pointer)
Definition utils.cpp:272
static pappso_double roundToDecimals(pappso_double value, int decimal_places)
Definition utils.cpp:141
static QRegularExpression anythingButDigitDotDash
Definition utils.h:53
static bool almostEqual(double value1, double value2, int decimalPlaces=10)
Definition utils.cpp:282
static QString msDataFormatAsString(MsDataFormat mz_format)
Convenience function to return a string describing the MzFormat of a file.
Definition utils.cpp:453
static std::vector< double > splitMzStringToDoubleVectorWithSpaces(const QString &text, std::size_t &error_count)
Definition utils.cpp:379
static double nearestGreater(double value)
Definition utils.cpp:328
static std::string toUtf8StandardString(const QString &text)
Definition utils.cpp:164
static bool appendToFile(const QString &text, const QString &file_name)
Definition utils.cpp:216
static QString booleanToString(bool value)
convenient function to transform a boolean to QString "TRUE" or "FALSE" QString returned is readable ...
Definition utils.cpp:445
static QString chronoIntervalDebugString(const QString &msg, std::chrono::system_clock::time_point chrono_start, std::chrono::system_clock::time_point chrono_finish=std::chrono::system_clock::now())
Definition utils.cpp:351
static bool writeToFile(const QString &text, const QString &file_name)
Definition utils.cpp:193
static std::vector< std::size_t > splitSizetStringToSizetVectorWithSpaces(const QString &text, std::size_t &error_count)
Definition utils.cpp:412
static QRegularExpression signedDoubleNumberExponentialRegExp
Definition utils.h:54
static QRegularExpression xyMassDataFormatRegExp
Definition utils.h:58
static QRegularExpression unsignedDoubleNumberNoExponentialRegExp
Definition utils.h:52
static const QString getLexicalOrderedString(unsigned int num)
Definition utils.cpp:73
static void writeLexicalOrderedString(QTextStream *p_out, unsigned int num)
Definition utils.cpp:85
static int zeroDecimalsInValue(pappso_double value)
0.11 would return 0 (no empty decimal) 2.001 would return 2 1000.0001254 would return 3
Definition utils.cpp:103
static QString fileReaderTypeAsString(FileReaderType file_reader_type)
Definition utils.cpp:496
static QRegularExpression endOfLineRegExp
Regular expression that tracks the end of line in text files.
Definition utils.h:67
static long long int roundToDecimal32bitsAsLongLongInt(pappso::pappso_double input)
Definition utils.cpp:152
@ nonAlign
the type of alignment to put in origin matrix NON Alignment (0 - NA)
ExperimentalSpectrumDataPointType
Definition types.h:78
@ both
both, the ion and the complement exists in the original spectrum
@ symmetric
new peak : computed symmetric mass from a corresponding native peak
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition aa.cpp:39
MsDataFormat
Definition types.h:120
@ xy
(x,y) format
@ SQLite3
SQLite3 format.
@ MGF
Mascot format.
double pappso_double
A type definition for doubles.
Definition types.h:50
FileReaderType
Definition types.h:147
This header contains all the type re-definitions and all the global variables definitions used in the...