Loading...
Searching...
No Matches
utils.cpp
Go to the documentation of this file.
/*******************************************************************************
* Copyright (c) 2015 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
*
* This file is part of the PAPPSOms++ library.
*
* PAPPSOms++ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PAPPSOms++ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PAPPSOms++. If not, see <http://www.gnu.org/licenses/>.
*
* Contributors:
* Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and
*implementation
******************************************************************************/
/////////////////////// StdLib includes
#include <cmath>
#include <iomanip>
/////////////////////// Qt includes
#include <QDebug>
#include <QFile>
#include <QTextStream>
/////////////////////// Local includes
#include "config.h"
#include "utils.h"
#include "types.h"
#include "exception/exceptionnotfound.h"
#include "trace/trace.h"
namespace pappso
{
// Matches a double (decimal value, that is, m/z
// value)
QRegularExpression Utils::unsignedDoubleNumberNoExponentialRegExp =
QRegularExpression("\\d*\\.?\\d+");
// Matches anything that is not digit, '.', or '-'
// (that is, matches a separator
QRegularExpression Utils::anythingButDigitDotDash =
QRegularExpression("[^\\d^\\.^-]+");
// Matches a double (with exp notation
// possibly) and also potentially a '-' sign. This is the intensity.
QRegularExpression Utils::signedDoubleNumberExponentialRegExp =
QRegularExpression("-?\\d*\\.?\\d*[e-]?\\d*");
// Matches <number><separator><number>, that is: m/z<separator>intensity.
QRegularExpression Utils::xyMassDataFormatRegExp =
// QRegularExpression("^(\\d*\\.?\\d+)([^\\d^\\.^-]+)(-?\\d*\\.?\\d*[e-]?\\d*)");
QRegularExpression(
QString("^(%1)(%2)(%3)")
.arg(Utils::unsignedDoubleNumberNoExponentialRegExp.pattern())
.arg(Utils::anythingButDigitDotDash.pattern())
.arg(Utils::signedDoubleNumberExponentialRegExp.pattern()));
QRegularExpression Utils::endOfLineRegExp = QRegularExpression("^\\s+$");
const QString
Utils::getLexicalOrderedString(unsigned int num)
{
int size = log10(num);
size += 97;
QLatin1Char latin1_char(size);
QString base(latin1_char);
base.append(QString().setNum(num));
return (base);
}
void
Utils::writeLexicalOrderedString(QTextStream *p_out, unsigned int num)
{
*p_out << (char)(log10(num) + 97) << num;
}
//! Determine the number of zero decimals between the decimal point and the
//! first non-zero decimal.
/*!
* 0.11 would return 0 (no empty decimal)
* 2.001 would return 2
* 1000.0001254 would return 3
*
* \param value the value to be analyzed
* \return the number of '0' decimals between the decimal separator '.' and
* the first non-0 decimal
*/
int
Utils::zeroDecimalsInValue(pappso_double value)
{
// qDebug() << qSetRealNumberPrecision(10) << "Double value: " << value;
int intPart = static_cast<int>(value);
// qDebug() << "int part:" << intPart;
double decimalPart = value - intPart;
// qDebug() << qSetRealNumberPrecision(10) << "decimal part: " << decimalPart;
int count = 0;
while(decimalPart > 0)
{
++count;
decimalPart *= 10;
// qDebug() << "Iteration " << count << "decimal part:" << decimalPart;
if(decimalPart >= 1)
{
// qDebug() << "Because decimal part " << decimalPart
//<< "is >= 1, breaking loop while count is " << count << ".";
break;
}
}
// qDebug() << "Returning count:" << count - 1;
return count - 1;
}
pappso_double
Utils::roundToDecimals(pappso_double value, int decimal_places)
{
if(decimal_places < 0)
return value;
return ceil((value * pow(10, decimal_places)) - 0.49) /
pow(10, decimal_places);
}
long long int
Utils::roundToDecimal32bitsAsLongLongInt(pappso::pappso_double input)
{
pappso::pappso_double test_decimal = 100000000000;
if(sizeof(int *) == 4)
{ // 32bits
test_decimal = 100000000;
}
return (floor(input * test_decimal));
}
std::string
Utils::toUtf8StandardString(const QString &text)
{
std::string env_backup;
try
{
#ifdef MXE
// std::locale::global(std::locale("C")); // set locale to default locale
env_backup = std::setlocale(LC_ALL, nullptr);
std::setlocale(LC_ALL, "C");
#else
std::locale::global(std::locale("C")); // set locale to default locale
#endif
}
catch(std::exception &error)
{
throw pappso::PappsoException(
QObject::tr("Error trying to set local to C : %1").arg(error.what()));
}
// Now perform the conversion.
QByteArray byte_array = text.toUtf8();
std::string stdText = "";
for(char c : byte_array)
{
stdText += c;
}
try
{
#ifdef MXE
// std::locale::global(std::locale("C")); // set locale to default locale
std::setlocale(LC_ALL, env_backup.c_str());
#else // Set back the locale to the backed-up one.
std::locale::global(
std::locale("")); // sets locale according to OS environment
#endif
}
catch(std::exception &error)
{
throw pappso::PappsoException(
QObject::tr("Error trying to set local to original system one %1 : %2")
.arg(env_backup.c_str())
.arg(error.what()));
}
return stdText;
}
bool
Utils::writeToFile(const QString &text, const QString &file_name)
{
QFile file(file_name);
if(file.open(QFile::WriteOnly | QFile::Truncate))
{
QTextStream out(&file);
out << text;
out.flush();
file.close();
return true;
}
return false;
}
bool
Utils::appendToFile(const QString &text, const QString &file_name)
{
QFile file(file_name);
if(file.open(QFile::WriteOnly | QFile::Append))
{
QTextStream out(&file);
out << text;
out.flush();
file.close();
return true;
}
return false;
}
std::size_t
Utils::extractScanNumberFromMzmlNativeId(const QString &spectrum_native_id)
{
qDebug() << " " << spectrum_native_id;
QStringList native_id_list = spectrum_native_id.split("=");
if(native_id_list.size() < 2)
{
throw ExceptionNotFound(
QObject::tr("scan number not found in mzML native id %1")
.arg(spectrum_native_id));
}
else
{
/** TODO activate this in a future release to ensure scan number
for(auto i = 0; i < native_id_list.size(); i += 2)
{
if(native_id_list[i] == "scan")
{
return native_id_list[i + 1].toULong();
}
}
throw ExceptionNotFound(
QObject::tr("scan number not found in mzML native id %1")
.arg(spectrum_native_id));
*/
return native_id_list.back().toULong();
}
return 0;
}
QString
Utils::pointerToString(const void *const pointer)
{
return QString("%1").arg(
(quintptr)pointer, QT_POINTER_SIZE * 2, 16, QChar('0'));
}
//! Tell if both double values, are equal within the double representation
//! capabilities of the platform.
bool
Utils::almostEqual(double value1, double value2, int decimalPlaces)
{
// QString value1String = QString("%1").arg(value1,
// 0, 'f', 60);
// QString value2String = QString("%1").arg(value2,
// 0, 'f', 60);
// qWarning() << __FILE__ << __LINE__ << __FUNCTION__
//<< "value1:" << value1String << "value2:" << value2String;
// The machine epsilon has to be scaled to the magnitude of the values used
// and multiplied by the desired precision in ULPs (units in the last place)
// (decimal places).
double valueSum = std::abs(value1 + value2);
// QString valueSumString = QString("%1").arg(valueSum,
// 0, 'f', 60);
double valueDiff = std::abs(value1 - value2);
// QString valueDiffString = QString("%1").arg(valueDiff,
// 0, 'f', 60);
double epsilon = std::numeric_limits<double>::epsilon();
// QString epsilonString = QString("%1").arg(epsilon,
// 0, 'f', 60);
double scaleFactor = epsilon * valueSum * decimalPlaces;
// QString scaleFactorString = QString("%1").arg(scaleFactor,
// 0, 'f', 60);
// qWarning() << "valueDiff:" << valueDiffString << "valueSum:" <<
// valueSumString <<
//"epsilon:" << epsilonString << "scaleFactor:" << scaleFactorString;
bool res = valueDiff < scaleFactor
// unless the result is subnormal:
|| valueDiff < std::numeric_limits<double>::min();
// qWarning() << __FILE__ << __LINE__ << __FUNCTION__
//<< "returning res:" << res;
return res;
}
double
Utils::nearestGreater(double value)
{
return std::nextafter(value, value + 1);
}
QString
Utils::chronoTimePointDebugString(
const QString &msg, std::chrono::system_clock::time_point chrono_time)
{
time_t tt;
tt = std::chrono::system_clock::to_time_t(chrono_time);
QString debug_text =
QString("%1 - %2\n").arg(msg).arg(QString::fromLatin1(ctime(&tt)));
return debug_text;
}
QString
Utils::chronoIntervalDebugString(
const QString &msg,
std::chrono::system_clock::time_point chrono_start,
std::chrono::system_clock::time_point chrono_finish)
{
QString debug_text =
QString(
"%1 %2 min = %3 s = %4 ms = %5 "
"µs\n")
.arg(msg)
.arg(std::chrono::duration_cast<std::chrono::minutes>(chrono_finish -
chrono_start)
.count())
.arg(std::chrono::duration_cast<std::chrono::seconds>(chrono_finish -
chrono_start)
.count())
.arg(std::chrono::duration_cast<std::chrono::milliseconds>(chrono_finish -
chrono_start)
.count())
.arg(std::chrono::duration_cast<std::chrono::microseconds>(chrono_finish -
chrono_start)
.count());
return debug_text;
}
std::vector<double>
Utils::splitMzStringToDoubleVectorWithSpaces(const QString &text,
std::size_t &error_count)
{
QStringList string_list =
text.split(QRegularExpression("[\\s]+"), Qt::SkipEmptyParts);
// qDebug() << "string list:" << string_list;
std::vector<double> double_vector;
for(int iter = 0; iter < string_list.size(); ++iter)
{
QString current_string = string_list.at(iter);
bool ok = false;
double current_double = current_string.toDouble(&ok);
if(!current_double && !ok)
{
++error_count;
continue;
}
double_vector.push_back(current_double);
}
return double_vector;
}
std::vector<std::size_t>
Utils::splitSizetStringToSizetVectorWithSpaces(const QString &text,
std::size_t &error_count)
{
// qDebug() << "Parsing text:" << text;
QStringList string_list =
text.split(QRegularExpression("[\\s]+"), Qt::SkipEmptyParts);
// qDebug() << "string list size:" << string_list.size()
//<< "values:" << string_list;
std::vector<std::size_t> sizet_vector;
for(int iter = 0; iter < string_list.size(); ++iter)
{
QString current_string = string_list.at(iter);
bool ok = false;
std::size_t current_sizet = current_string.toUInt(&ok);
if(!current_sizet && !ok)
{
++error_count;
continue;
}
sizet_vector.push_back(current_sizet);
}
return sizet_vector;
}
QString
Utils::booleanToString(bool value)
{
if(value)
return "TRUE";
return "FALSE";
}
QString
Utils::msDataFormatAsString(MsDataFormat mz_format)
{
if(mz_format == MsDataFormat::mzML)
return "mzML";
else if(mz_format == MsDataFormat::mzXML)
return "mzXML";
else if(mz_format == MsDataFormat::MGF)
return "MGF";
else if(mz_format == MsDataFormat::SQLite3)
return "SQLite3";
else if(mz_format == MsDataFormat::xy)
return "xy";
else if(mz_format == MsDataFormat::mz5)
return "mz5";
else if(mz_format == MsDataFormat::msn)
return "msn";
else if(mz_format == MsDataFormat::abSciexWiff)
return "abSciexWiff";
else if(mz_format == MsDataFormat::abSciexT2D)
return "abSciexT2D";
else if(mz_format == MsDataFormat::agilentMassHunter)
return "agilentMassHunter";
else if(mz_format == MsDataFormat::thermoRaw)
return "thermoRaw";
else if(mz_format == MsDataFormat::watersRaw)
return "watersRaw";
else if(mz_format == MsDataFormat::brukerFid)
return "brukerFid";
else if(mz_format == MsDataFormat::brukerYep)
return "brukerYep";
else if(mz_format == MsDataFormat::brukerBaf)
return "brukerBaf";
else if(mz_format == MsDataFormat::brukerTims)
return "brukerTims";
else if(mz_format == MsDataFormat::brukerBafAscii)
return "brukerBafAscii";
else
return "unknown";
}
QString
Utils::fileReaderTypeAsString(FileReaderType file_reader_type)
{
if(file_reader_type == FileReaderType::pwiz)
return "pwiz";
else if(file_reader_type == FileReaderType::xy)
return "xy";
else if(file_reader_type == FileReaderType::tims)
return "tims";
else if(file_reader_type == FileReaderType::tims_frames)
return "tims_frames";
else
return "unknown";
}
QString
Utils::toString(specglob::SpectralAlignmentType type)
{
switch(type)
{
case specglob::SpectralAlignmentType::align:
return "AL";
break;
case specglob::SpectralAlignmentType::nonAlign:
return "NA";
break;
case specglob::SpectralAlignmentType::reAlign:
return "RA";
break;
default:
return "ER";
}
}
QString
Utils::toString(specglob::ExperimentalSpectrumDataPointType type)
{
switch(type)
{
case specglob::ExperimentalSpectrumDataPointType::both:
return "both";
break;
case specglob::ExperimentalSpectrumDataPointType::native:
return "native";
break;
case specglob::ExperimentalSpectrumDataPointType::symmetric:
return "symmetric";
break;
default:
return "synthetic";
}
}
QString
Utils::getVersion()
{
QString version(PAPPSOMSPP_VERSION);
return version;
}
} // namespace pappso
pappso::ExceptionNotFound
Definition exceptionnotfound.h:32
pappso::PappsoException
Definition pappsoexception.h:42
pappso::Utils::extractScanNumberFromMzmlNativeId
static std::size_t extractScanNumberFromMzmlNativeId(const QString &spectrum_native_id)
Definition utils.cpp:262
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:358
pappso::Utils::toString
static QString toString(specglob::SpectralAlignmentType type)
Convenience function to return a string describing the specglob alingment type.
Definition utils.cpp:535
pappso::Utils::pointerToString
static QString pointerToString(const void *const pointer)
Definition utils.cpp:295
pappso::Utils::roundToDecimals
static pappso_double roundToDecimals(pappso_double value, int decimal_places)
Definition utils.cpp:142
pappso::Utils::anythingButDigitDotDash
static QRegularExpression anythingButDigitDotDash
Definition utils.h:54
pappso::Utils::almostEqual
static bool almostEqual(double value1, double value2, int decimalPlaces=10)
Definition utils.cpp:305
pappso::Utils::msDataFormatAsString
static QString msDataFormatAsString(MsDataFormat mz_format)
Convenience function to return a string describing the MzFormat of a file.
Definition utils.cpp:476
pappso::Utils::splitMzStringToDoubleVectorWithSpaces
static std::vector< double > splitMzStringToDoubleVectorWithSpaces(const QString &text, std::size_t &error_count)
Definition utils.cpp:402
pappso::Utils::nearestGreater
static double nearestGreater(double value)
Definition utils.cpp:351
pappso::Utils::toUtf8StandardString
static std::string toUtf8StandardString(const QString &text)
Definition utils.cpp:165
pappso::Utils::appendToFile
static bool appendToFile(const QString &text, const QString &file_name)
Definition utils.cpp:239
pappso::Utils::booleanToString
static QString booleanToString(bool value)
convenient function to transform a boolean to QString "TRUE" or "FALSE" QString returned is readable ...
Definition utils.cpp:468
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:374
pappso::Utils::writeToFile
static bool writeToFile(const QString &text, const QString &file_name)
Definition utils.cpp:216
pappso::Utils::splitSizetStringToSizetVectorWithSpaces
static std::vector< std::size_t > splitSizetStringToSizetVectorWithSpaces(const QString &text, std::size_t &error_count)
Definition utils.cpp:435
pappso::Utils::signedDoubleNumberExponentialRegExp
static QRegularExpression signedDoubleNumberExponentialRegExp
Definition utils.h:55
pappso::Utils::xyMassDataFormatRegExp
static QRegularExpression xyMassDataFormatRegExp
Definition utils.h:59
pappso::Utils::unsignedDoubleNumberNoExponentialRegExp
static QRegularExpression unsignedDoubleNumberNoExponentialRegExp
Definition utils.h:53
pappso::Utils::getLexicalOrderedString
static const QString getLexicalOrderedString(unsigned int num)
Definition utils.cpp:74
pappso::Utils::writeLexicalOrderedString
static void writeLexicalOrderedString(QTextStream *p_out, unsigned int num)
Definition utils.cpp:86
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:104
pappso::Utils::fileReaderTypeAsString
static QString fileReaderTypeAsString(FileReaderType file_reader_type)
Definition utils.cpp:519
pappso::Utils::endOfLineRegExp
static QRegularExpression endOfLineRegExp
Regular expression that tracks the end of line in text files.
Definition utils.h:68
pappso::Utils::roundToDecimal32bitsAsLongLongInt
static long long int roundToDecimal32bitsAsLongLongInt(pappso::pappso_double input)
Definition utils.cpp:153
pappso::Utils::getVersion
static QString getVersion()
Definition utils.cpp:573
exceptionnotfound.h
pappso::specglob::SpectralAlignmentType
SpectralAlignmentType
Definition types.h:48
pappso::specglob::SpectralAlignmentType::nonAlign
@ nonAlign
the type of alignment to put in origin matrix NON Alignment (0 - NA)
pappso::specglob::SpectralAlignmentType::reAlign
@ reAlign
Re Alignment (1 - RE)
pappso::specglob::SpectralAlignmentType::align
@ align
Alignment (2 - AL)
pappso::specglob::ExperimentalSpectrumDataPointType
ExperimentalSpectrumDataPointType
Definition types.h:78
pappso::specglob::ExperimentalSpectrumDataPointType::native
@ native
pappso::specglob::ExperimentalSpectrumDataPointType::both
@ both
both, the ion and the complement exists in the original spectrum
pappso::specglob::ExperimentalSpectrumDataPointType::symmetric
@ symmetric
new peak : computed symmetric mass from a corresponding native peak
pappso
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition aa.cpp:39
pappso::MsDataFormat
MsDataFormat
Definition types.h:120
pappso::MsDataFormat::brukerTims
@ brukerTims
pappso::MsDataFormat::msn
@ msn
pappso::MsDataFormat::xy
@ xy
(x,y) format
pappso::MsDataFormat::agilentMassHunter
@ agilentMassHunter
pappso::MsDataFormat::abSciexT2D
@ abSciexT2D
pappso::MsDataFormat::mzXML
@ mzXML
mzXML
pappso::MsDataFormat::watersRaw
@ watersRaw
pappso::MsDataFormat::mz5
@ mz5
pappso::MsDataFormat::brukerBaf
@ brukerBaf
pappso::MsDataFormat::mzML
@ mzML
mzML
pappso::MsDataFormat::abSciexWiff
@ abSciexWiff
pappso::MsDataFormat::brukerBafAscii
@ brukerBafAscii
pappso::MsDataFormat::brukerFid
@ brukerFid
pappso::MsDataFormat::SQLite3
@ SQLite3
SQLite3 format.
pappso::MsDataFormat::MGF
@ MGF
Mascot format.
pappso::MsDataFormat::thermoRaw
@ thermoRaw
pappso::MsDataFormat::brukerYep
@ brukerYep
pappso::PrecisionUnit::res
@ res
pappso::PeptideIonNter::c
@ c
pappso::pappso_double
double pappso_double
A type definition for doubles.
Definition types.h:50
pappso::AxisScale::log10
@ log10
pappso::FileReaderType
FileReaderType
Definition types.h:147
pappso::FileReaderType::pwiz
@ pwiz
using libpwizlite
pappso::FileReaderType::xy
@ xy
pappso::FileReaderType::tims_frames
@ tims_frames
pappso::FileReaderType::tims
@ tims
TimsMsRunReader : each scan is returned as a mass spectrum.
trace.h
types.h
This header contains all the type re-definitions and all the global variables definitions used in the...
utils.h