libpappsomspp
Library for mass spectrometry
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 
42 namespace pappso
43 {
44 
45 
46 QRegularExpression Utils::xyMassDataFormatRegExp =
47  QRegularExpression("^(\\d*\\.?\\d+)([^\\d^\\.^-]+)(-?\\d*\\.?\\d*[e-]?\\d*)");
48 
49 QRegularExpression Utils::endOfLineRegExp = QRegularExpression("^\\s+$");
50 
51 const QString
52 Utils::getLexicalOrderedString(unsigned int num)
53 {
54  int size = log10(num);
55  size += 97;
56  QString base(size);
57  base.append(QString().setNum(num));
58  return (base);
59 }
60 
61 
62 void
63 Utils::writeLexicalOrderedString(QTextStream *p_out, unsigned int num)
64 {
65  *p_out << (char)(log10(num) + 97) << num;
66 }
67 
68 
69 //! Determine the number of zero decimals between the decimal point and the
70 //! first non-zero decimal.
71 /*!
72  * 0.11 would return 0 (no empty decimal)
73  * 2.001 would return 2
74  * 1000.0001254 would return 3
75  *
76  * \param value the value to be analyzed
77  * \return the number of '0' decimals between the decimal separator '.' and
78  * the first non-0 decimal
79  */
80 int
82 {
83  int intPart = static_cast<int>(value);
84 
85  double decimalPart = value - intPart;
86 
87  int count = -1;
88 
89  while(1)
90  {
91  ++count;
92 
93  decimalPart *= 10;
94 
95  if(decimalPart > 1)
96  return count;
97  }
98 
99  return count;
100 }
101 
102 
104 Utils::roundToDecimals(pappso_double value, int decimal_places)
105 {
106  if(decimal_places < 0)
107  return value;
108 
109  return ceil((value * pow(10, decimal_places)) - 0.49) /
110  pow(10, decimal_places);
111 }
112 
113 
114 std::string
115 Utils::toUtf8StandardString(const QString &text)
116 {
117  std::string env_backup = setlocale(LC_ALL, "");
118 
119  // struct lconv *lc_backup = localeconv();
120  // qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << "()"
121  //<< "env_backup=" << env_backup.c_str() << "lc_backup->decimal_point"
122  //<< lc_backup->decimal_point;
123 
124  // Force locale to be "C".
125  setlocale(LC_ALL, "C");
126 
127  // Now perform the conversion.
128  QByteArray byte_array = text.toUtf8();
129  std::string stdText = "";
130 
131  for(char c : byte_array)
132  {
133  stdText += c;
134  }
135 
136  // Set back the locale to the backed-up one.
137  setlocale(LC_ALL, env_backup.c_str());
138 
139  return stdText;
140 }
141 
142 
143 bool
144 Utils::writeToFile(const QString &text, const QString &file_name)
145 {
146 
147  QFile file(file_name);
148 
149  if(file.open(QFile::WriteOnly | QFile::Truncate))
150  {
151 
152  QTextStream out(&file);
153 
154  out << text;
155 
156  out.flush();
157  file.close();
158 
159  return true;
160  }
161 
162  return false;
163 }
164 
165 
166 bool
167 Utils::appendToFile(const QString &text, const QString &file_name)
168 {
169 
170  QFile file(file_name);
171 
172  if(file.open(QFile::WriteOnly | QFile::Append))
173  {
174 
175  QTextStream out(&file);
176 
177  out << text;
178 
179  out.flush();
180  file.close();
181 
182  return true;
183  }
184 
185  return false;
186 }
187 
188 
189 std::size_t
190 Utils::extractScanNumberFromMzmlNativeId(const QString &spectrum_native_id)
191 {
192  qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << "()"
193  << " " << spectrum_native_id;
194  QStringList native_id_list = spectrum_native_id.split("=");
195  if(native_id_list.size() < 2)
196  {
197  throw ExceptionNotFound(
198  QObject::tr("scan number not found in mzML native id %1")
199  .arg(spectrum_native_id));
200  }
201  else
202  {
203  return native_id_list.back().toULong();
204  }
205  return 0;
206 }
207 
208 
209 QString
210 Utils::pointerToString(const void *const pointer)
211 {
212  return QString("%1").arg(
213  (quintptr)pointer, QT_POINTER_SIZE * 2, 16, QChar('0'));
214 }
215 
216 
217 //! Tell if both double values, are equal within the double representation
218 //! capabilities of the platform.
219 bool
220 Utils::almostEqual(double value1, double value2, int decimalPlaces)
221 {
222  // QString value1String = QString("%1").arg(value1,
223  // 0, 'f', 60);
224  // QString value2String = QString("%1").arg(value2,
225  // 0, 'f', 60);
226 
227  // qWarning() << __FILE__ << __LINE__ << __FUNCTION__
228  //<< "value1:" << value1String << "value2:" << value2String;
229 
230  // The machine epsilon has to be scaled to the magnitude of the values used
231  // and multiplied by the desired precision in ULPs (units in the last place)
232  // (decimal places).
233 
234  double valueSum = std::abs(value1 + value2);
235  // QString valueSumString = QString("%1").arg(valueSum,
236  // 0, 'f', 60);
237 
238  double valueDiff = std::abs(value1 - value2);
239  // QString valueDiffString = QString("%1").arg(valueDiff,
240  // 0, 'f', 60);
241 
242  double epsilon = std::numeric_limits<double>::epsilon();
243  // QString epsilonString = QString("%1").arg(epsilon,
244  // 0, 'f', 60);
245 
246  double scaleFactor = epsilon * valueSum * decimalPlaces;
247  // QString scaleFactorString = QString("%1").arg(scaleFactor,
248  // 0, 'f', 60);
249 
250  // qWarning() << "valueDiff:" << valueDiffString << "valueSum:" <<
251  // valueSumString <<
252  //"epsilon:" << epsilonString << "scaleFactor:" << scaleFactorString;
253 
254  bool res = valueDiff < scaleFactor
255  // unless the result is subnormal:
256  || valueDiff < std::numeric_limits<double>::min();
257 
258  // qWarning() << __FILE__ << __LINE__ << __FUNCTION__
259  //<< "returning res:" << res;
260 
261  return res;
262 }
263 
264 
265 QString
267  const QString &msg, std::chrono::system_clock::time_point chrono_time)
268 {
269 
270  time_t tt;
271 
272  tt = std::chrono::system_clock::to_time_t(chrono_time);
273 
274  QString debug_text =
275  QString("%1 - %2\n").arg(msg).arg(QString::fromLatin1(ctime(&tt)));
276 
277  return debug_text;
278 }
279 
280 
281 QString
283  const QString &msg,
284  std::chrono::system_clock::time_point chrono_start,
285  std::chrono::system_clock::time_point chrono_finish)
286 {
287  QString debug_text =
288  QString(
289  "%1 %2 min = %3 s = %4 ms = %5 "
290  "µs\n")
291  .arg(msg)
292  .arg(std::chrono::duration_cast<std::chrono::minutes>(chrono_finish -
293  chrono_start)
294  .count())
295  .arg(std::chrono::duration_cast<std::chrono::seconds>(chrono_finish -
296  chrono_start)
297  .count())
298  .arg(std::chrono::duration_cast<std::chrono::milliseconds>(chrono_finish -
299  chrono_start)
300  .count())
301  .arg(std::chrono::duration_cast<std::chrono::microseconds>(chrono_finish -
302  chrono_start)
303  .count());
304 
305  return debug_text;
306 }
307 
308 
309 std::vector<double>
311  std::size_t &error_count)
312 {
313 
314  QStringList string_list =
315  text.split(QRegularExpression("[\\s]+"), QString::SkipEmptyParts);
316 
317  // qDebug() << "string list:" << string_list;
318 
319  std::vector<double> double_vector;
320 
321  for(int iter = 0; iter < string_list.size(); ++iter)
322  {
323  QString current_string = string_list.at(iter);
324 
325  bool ok = false;
326 
327  double current_double = current_string.toDouble(&ok);
328 
329  if(!current_double && !ok)
330  {
331  ++error_count;
332  continue;
333  }
334 
335  double_vector.push_back(current_double);
336  }
337 
338  return double_vector;
339 }
340 
341 
342 std::vector<std::size_t>
344  std::size_t &error_count)
345 {
346  // qDebug() << "Parsing text:" << text;
347 
348  QStringList string_list =
349  text.split(QRegularExpression("[\\s]+"), QString::SkipEmptyParts);
350 
351  // qDebug() << "string list size:" << string_list.size()
352  //<< "values:" << string_list;
353 
354  std::vector<std::size_t> sizet_vector;
355 
356  for(int iter = 0; iter < string_list.size(); ++iter)
357  {
358  QString current_string = string_list.at(iter);
359 
360  bool ok = false;
361 
362  std::size_t current_sizet = current_string.toUInt(&ok);
363 
364  if(!current_sizet && !ok)
365  {
366  ++error_count;
367  continue;
368  }
369 
370  sizet_vector.push_back(current_sizet);
371  }
372 
373  return sizet_vector;
374 }
375 
376 
377 } // namespace pappso
pappso::Utils::almostEqual
static bool almostEqual(double value1, double value2, int decimalPlaces=10)
Definition: utils.cpp:241
pappso::Utils::splitMzStringToDoubleVectorWithSpaces
static std::vector< double > splitMzStringToDoubleVectorWithSpaces(const QString &text, std::size_t &error_count)
Definition: utils.cpp:331
pappso::pappso_double
double pappso_double
A type definition for doubles.
Definition: types.h:69
pappso::Utils::zeroDecimalsInValue
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:102
pappso::Utils::splitSizetStringToSizetVectorWithSpaces
static std::vector< std::size_t > splitSizetStringToSizetVectorWithSpaces(const QString &text, std::size_t &error_count)
Definition: utils.cpp:364
pappso::Utils::extractScanNumberFromMzmlNativeId
static std::size_t extractScanNumberFromMzmlNativeId(const QString &spectrum_native_id)
Definition: utils.cpp:211
types.h
This header contains all the type re-definitions and all the global variables definitions used in the...
pappso::Utils::chronoTimePointDebugString
static QString chronoTimePointDebugString(const QString &msg, std::chrono::system_clock::time_point chrono_time=std::chrono::system_clock::now())
Definition: utils.cpp:287
pappso
Definition: aa.cpp:38
trace.h
pappso::Utils::endOfLineRegExp
static QRegularExpression endOfLineRegExp
Regular expression that tracks the end of line in text files.
Definition: utils.h:83
pappso::Utils::writeToFile
static bool writeToFile(const QString &text, const QString &file_name)
Definition: utils.cpp:165
pappso::Utils::appendToFile
static bool appendToFile(const QString &text, const QString &file_name)
Definition: utils.cpp:188
pappso::PrecisionUnit::res
@ res
utils.h
pappso::Utils::pointerToString
static QString pointerToString(const void *const pointer)
Definition: utils.cpp:231
pappso::Utils::chronoIntervalDebugString
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:303
pappso::Utils::toUtf8StandardString
static std::string toUtf8StandardString(const QString &text)
Definition: utils.cpp:136
pappso::PeptideIonNter::c
@ c
pappso::ExceptionNotFound
Definition: exceptionnotfound.h:52
exceptionnotfound.h
pappso::Utils::roundToDecimals
static pappso_double roundToDecimals(pappso_double value, int decimal_places)
Definition: utils.cpp:125
pappso::Utils::writeLexicalOrderedString
static void writeLexicalOrderedString(QTextStream *p_out, unsigned int num)
Definition: utils.cpp:84
pappso::Utils::xyMassDataFormatRegExp
static QRegularExpression xyMassDataFormatRegExp
Definition: utils.h:74
pappso::Utils::getLexicalOrderedString
static const QString getLexicalOrderedString(unsigned int num)
Definition: utils.cpp:73