Loading...
Searching...
No Matches
bafasciifilereader.cpp
Go to the documentation of this file.
/////////////////////// StdLib includes
#include <iostream>
#include <iomanip>
/////////////////////// Qt includes
#include <QDebug>
#include <QFile>
#include <QFileInfo>
/////////////////////// libpwiz includes
#include <pwiz/data/msdata/DefaultReaderList.hpp>
/////////////////////// Local includes
#include "bafasciifilereader.h"
#include "pappsomspp/core/exception/exceptionnotfound.h"
#include "pappsomspp/core/utils.h"
#include "pappsomspp/core/types.h"
#include "pappsomspp/core/msrun/msrunid.h"
namespace pappso
{
static const std::size_t CHECKED_LINES_COUNT = 10;
BafAsciiFileReader::BafAsciiFileReader(const QString &file_name) : MsFileReader{file_name}
{
// To avoid initializing multiple times (costly process), we
// only initialize when needed, that is, upon getMsRunIds().
// initialize();
}
BafAsciiFileReader::~BafAsciiFileReader()
{
}
bool
BafAsciiFileReader::initialize(std::size_t &line_count)
{
// Here we just test some the lines of the file to check that they comply with
// the brukerBafAscii format.
line_count = 0;
QFile file(m_fileName);
if(!file.open(QFile::ReadOnly | QFile::Text))
{
qDebug() << "Failed to open file" << m_fileName;
return false;
}
// Construct the regular expression pattern, piecemeal...
// The retention time as the very first value in the line.
QString regexp_pattern =
QString("^(%1)").arg(Utils::unsignedDoubleNumberNoExponentialRegExp.pattern());
// The ionization mode (positive or negative)
regexp_pattern += QString(",([+-])");
regexp_pattern += QString(",(ESI|MALDI)");
// The MS level (ms1 for full scan mass spectrum)
regexp_pattern += QString(",ms(\\d)");
// Do no know what this is for.
regexp_pattern += QString(",(-)");
// The type of peak (profile or centroid).
regexp_pattern += QString(",(profile|line)");
// The m/z range of the mass spectrum.
regexp_pattern += QString(",(%1-%2)")
.arg(Utils::unsignedDoubleNumberNoExponentialRegExp.pattern())
.arg(Utils::unsignedDoubleNumberNoExponentialRegExp.pattern());
// The count of peaks following this element in the remaining of the line.
regexp_pattern += QString(",(\\d+)");
regexp_pattern += QString("(.*$)");
// qDebug() << "The full regexp_pattern:" << regexp_pattern;
QRegularExpression line_regexp(regexp_pattern);
QRegularExpressionMatch regexp_match;
QString line;
bool file_reading_failed = false;
bool ok = false;
// Reading, parsing and checking lines is extremely time consuming.
// What we want here is reduce the time all the file's lines are
// read. We could say that we want to parse and check the first
// CHECKED_LINES_COUNT lines and then avoid parsing and checking, just go
// through the lines. At the end of the file, the number of lines that have
// been read is stored in the out parameter line_count.
std::size_t iter = 0;
while(!file.atEnd())
{
line = file.readLine().trimmed();
++iter;
// qDebug() << "Read one line more: (not yet checked)" << iter;
if(iter > CHECKED_LINES_COUNT)
continue;
if(line.startsWith('#') || line.isEmpty() || Utils::endOfLineRegExp.match(line).hasMatch())
continue;
// qDebug() << "Current brukerBafAscii format line " << line_count << ": "
// << line.left(30) << " ... " << line.right(30);
regexp_match = line_regexp.match(line);
if(regexp_match.hasMatch())
{
// qDebug() << "The match succeeded.";
regexp_match.captured(1).toDouble(&ok);
if(!ok)
{
qDebug() << "Failed to extract the retention time of the mass spectrum.";
file_reading_failed = true;
break;
}
QString ionization_mode = regexp_match.captured(2);
QString source_type = regexp_match.captured(3);
regexp_match.captured(4).toInt(&ok);
if(!ok)
{
qDebug() << "Failed to extract the MS level of the mass spectrum.";
file_reading_failed = true;
break;
}
QString peak_shape_type = regexp_match.captured(6);
QString mz_range = regexp_match.captured(7);
mz_range.left(mz_range.indexOf("-")).toDouble(&ok);
if(!ok)
{
qDebug() << "Failed to extract the start of the m/z range.";
file_reading_failed = true;
break;
}
mz_range.right(mz_range.indexOf("-") + 1).toDouble(&ok);
if(!ok)
{
qDebug() << "Failed to extract the end of the m/z range.";
file_reading_failed = true;
break;
}
// qDebug() << qSetRealNumberPrecision(10)
// << "mz_range_start: " << mz_range_start
// << "mz_range_end: " << mz_range_end;
int peak_count = regexp_match.captured(8).toInt(&ok);
if(!ok)
{
qDebug() << "Failed to extract the number of peaks in the mass "
"spectrum.";
file_reading_failed = true;
break;
}
QString peaks = regexp_match.captured(9);
QStringList peaks_stringlist = peaks.split(",", Qt::SkipEmptyParts);
// qDebug() << "The number of peaks:" << peaks_stringlist.size();
// Sanity check:
if(peaks_stringlist.size() != peak_count)
{
// qDebug() << "The number of peaks in the mass spectrum does not
// "
// "match the advertised one.";
file_reading_failed = true;
break;
}
// qDebug() << "The retention time:" << retention_time
// << "the ionization mode: " << ionization_mode
// << "the source type: " << source_type
// << "MS level is:" << ms_level
// << "peak shape type: " << peak_shape_type
// << "m/z range: " << mz_range << "peak count: " <<
// peak_count
// << "and peaks: " << peaks.left(100) << " ... "
// << peaks.right(100) << "";
// If we are here, that means that the read line has conformed
// to the format expected.
++line_count;
// qDebug() << "Checked one line more:" << line_count;
}
// End end of
// if(regexp_match.hasMatch())
else
{
qDebug() << "The match failed.";
file_reading_failed = true;
break;
}
}
// End of
// while(!file.atEnd())
file.close();
if(!file_reading_failed && line_count >= 1)
{
m_fileFormat = Enums::MsDataFormat::brukerBafAscii;
return true;
}
m_fileFormat = Enums::MsDataFormat::unknown;
// qDebug() << "The number of parsed mass spectra: " << line_count;
// qDebug() << "Detected file format:"
// << Utils::msDataFormatAsString(m_fileFormat)
// << "with number of spectra: " << line_count;
return false;
}
Enums::MsDataFormat
BafAsciiFileReader::getFileFormat()
{
return m_fileFormat;
}
std::vector<MsRunIdCstSPtr>
BafAsciiFileReader::getMsRunIds(const QString &run_prefix)
{
std::vector<MsRunIdCstSPtr> ms_run_ids;
std::size_t ms_data_line_count = 0;
if(!initialize(ms_data_line_count))
return ms_run_ids;
// Finally create the MsRunId with the file name.
MsRunId ms_run_id(m_fileName);
ms_run_id.setMsDataFormat(m_fileFormat);
// We need to set the unambiguous xmlId string.
ms_run_id.setXmlId(QString("%1%2").arg(run_prefix).arg(Utils::getLexicalOrderedString(0)));
// Craft a meaningful sample name because otherwise all the files loaded from
// text files will have the same sample name and it will be difficult to
// differentiate them.
// Orig version:
// ms_run_id.setRunId("Single spectrum");
// Now the sample name is nothing but the file name without the path.
QFileInfo file_info(m_fileName);
// qDebug() << "file name:" << m_fileName;
QString sample_name = file_info.fileName();
// qDebug() << "sample name:" << sample_name;
ms_run_id.setRunId(sample_name);
// Now set the sample name to the run id:
ms_run_id.setSampleName(ms_run_id.getRunId());
// qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << "()"
//<< "Current ms_run_id:" << ms_run_id.toString();
// Finally make a shared pointer out of it and append it to the vector.
ms_run_ids.push_back(std::make_shared<MsRunId>(ms_run_id));
return ms_run_ids;
}
} // namespace pappso
bafasciifilereader.h
CardanoResultCase::line
@ line
Definition cardano.h:42
pappso::BafAsciiFileReader::~BafAsciiFileReader
virtual ~BafAsciiFileReader()
Definition bafasciifilereader.cpp:37
pappso::BafAsciiFileReader::getFileFormat
virtual Enums::MsDataFormat getFileFormat() override
Definition bafasciifilereader.cpp:258
pappso::BafAsciiFileReader::initialize
virtual bool initialize(std::size_t &line_count)
Definition bafasciifilereader.cpp:42
pappso::BafAsciiFileReader::getMsRunIds
virtual std::vector< MsRunIdCstSPtr > getMsRunIds(const QString &run_prefix) override
Definition bafasciifilereader.cpp:265
pappso::BafAsciiFileReader::BafAsciiFileReader
BafAsciiFileReader(const QString &file_name)
Definition bafasciifilereader.cpp:29
pappso::MsFileReader::MsFileReader
MsFileReader(const QString &file_name)
Definition msfilereader.cpp:19
pappso::MsFileReader::m_fileFormat
Enums::MsDataFormat m_fileFormat
Definition msfilereader.h:17
pappso::MsFileReader::m_fileName
QString m_fileName
Definition msfilereader.h:16
pappso::MsRunId
MS run identity MsRunId identifies an MS run with a unique ID (XmlId) and contains eventually informa...
Definition msrunid.h:54
pappso::MsRunId::setMsDataFormat
void setMsDataFormat(Enums::MsDataFormat format)
Definition msrunid.cpp:168
pappso::MsRunId::getRunId
const QString & getRunId() const
Definition msrunid.cpp:140
pappso::MsRunId::setRunId
void setRunId(const QString &run_id)
Definition msrunid.cpp:133
pappso::MsRunId::setXmlId
void setXmlId(const QString &xml_id)
set an XML unique identifier for this MsRunId
Definition msrunid.cpp:147
pappso::MsRunId::setSampleName
void setSampleName(const QString &name)
set a sample name for this MsRunId
Definition msrunid.cpp:77
pappso::Utils::unsignedDoubleNumberNoExponentialRegExp
static QRegularExpression unsignedDoubleNumberNoExponentialRegExp
Definition utils.h:54
pappso::Utils::getLexicalOrderedString
static const QString getLexicalOrderedString(unsigned int num)
Definition utils.cpp:72
pappso::Utils::endOfLineRegExp
static QRegularExpression endOfLineRegExp
Regular expression that tracks the end of line in text files.
Definition utils.h:69
exceptionnotfound.h
msrunid.h
pappso::Enums::MsDataFormat
MsDataFormat
Definition types.h:148
pappso::Enums::MsDataFormat::brukerBafAscii
@ brukerBafAscii
Definition types.h:166
pappso::Enums::MsDataFormat::unknown
@ unknown
unknown format
Definition types.h:149
pappso
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition aa.cpp:39
pappso::CHECKED_LINES_COUNT
static const std::size_t CHECKED_LINES_COUNT
Definition bafasciifilereader.cpp:27
types.h
utils.h