Loading...
Searching...
No Matches
mzmlconvert.cpp
Go to the documentation of this file.
/**
* \file pappsomspp/processing/cbor/mzcbor/mzmlconvert.cpp
* \date 19/11/2025
* \author Olivier Langella
* \brief convert mzML to mzcbor
*/
/*******************************************************************************
* Copyright (c) 2025 Olivier Langella <Olivier.Langella@universite-paris-saclay.fr>.
*
* This file is part of PAPPSOms-tools.
*
* PAPPSOms-tools 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-tools 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-tools. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#include "mzmlconvert.h"
#include <QDebug>
#include <qlogging.h>
#include <QObject>
#include <zlib.h>
#include "pappsomspp/core/pappsoexception.h"
#include "pappsomspp/config.h"
#include "binarydataarray.h"
#include "cvparam.h"
pappso::cbor::mzcbor::MzmlConvert::MzmlConvert(pappso::UiMonitorInterface *p_monitor,
pappso::cbor::CborStreamWriter *p_output)
: mp_monitor(p_monitor), mp_cborWriter(p_output)
{
m_elementToStoreInArray.clear();
m_elementToStoreInArray << "cv" << "userParam" << "cvParam" << "binaryDataArray" << "spectrum"
<< "sourceFile"
<< "referenceableParamGroup" << "software" << "instrumentConfiguration"
<< "processingMethod" << "dataProcessing" << "scan" << "scanWindow"
<< "precursor" << "selectedIon";
m_elementStash.clear();
m_currentSpectrumSize = 0;
m_doubleArray.clear();
m_runIdList.clear();
m_runAndSpectrumOffsetList.clear();
m_runAndSpectrumIdList.clear();
}
pappso::cbor::mzcbor::MzmlConvert::~MzmlConvert()
{
}
void
pappso::cbor::mzcbor::MzmlConvert::writeMzcborIndex(pappso::cbor::CborStreamWriter *writer) const
{
writer->startMap();
writer->writeInformations(PAPPSOMSPP_NAME, PAPPSOMSPP_VERSION, "mzCBORindex", "mzMLconvert");
writer->append("from");
writer->append(m_uuid);
writer->append("runIdList");
writer->writeArray(m_runIdList);
std::vector<std::size_t> msrun_size;
writer->append("runSpectrumIndexList");
writer->startArray(m_runAndSpectrumOffsetList.size());
for(auto &spectrum_offset_list : m_runAndSpectrumOffsetList)
{
msrun_size.push_back(spectrum_offset_list.size());
writer->writeArray(spectrum_offset_list);
}
writer->endArray();
writer->append("runSpectrumNativeIdList");
writer->startArray(m_runAndSpectrumIdList.size());
for(auto &spectrum_id_list : m_runAndSpectrumIdList)
{
writer->writeArray(spectrum_id_list);
}
writer->endArray();
// TIC
bool size_ok = true;
for(std::size_t i = 0; i < msrun_size.size(); i++)
{
if(m_runAndSpectrumTotalIonCountList.at(i).size() != msrun_size.at(i))
{
size_ok = false;
}
}
if(size_ok)
{
writer->append("runSpectrumTotalIonCountList");
writer->startArray(m_runAndSpectrumIdList.size());
for(auto &spectrum_tic_list : m_runAndSpectrumTotalIonCountList)
{
writer->writeArray(spectrum_tic_list);
}
writer->endArray();
}
// retention time
size_ok = true;
for(std::size_t i = 0; i < msrun_size.size(); i++)
{
if(m_runAndSpectrumRtList.at(i).size() != msrun_size.at(i))
{
size_ok = false;
}
}
if(size_ok)
{
writer->append("runSpectrumRtList");
writer->startArray(m_runAndSpectrumRtList.size());
for(auto &spectrum_rt_list : m_runAndSpectrumRtList)
{
writer->writeArray(spectrum_rt_list);
}
writer->endArray();
}
else
{
// qFatal() << "wrong size";
}
// MS Level
size_ok = true;
for(std::size_t i = 0; i < msrun_size.size(); i++)
{
if(m_runAndSpectrumMsLevelList.at(i).size() != msrun_size.at(i))
{
size_ok = false;
}
}
if(size_ok)
{
writer->append("runSpectrumMsLevelList");
writer->startArray(m_runAndSpectrumMsLevelList.size());
for(auto &spectrum_mslevel_list : m_runAndSpectrumMsLevelList)
{
writer->writeArray(spectrum_mslevel_list);
}
writer->endArray();
}
writer->endMap();
}
void
pappso::cbor::mzcbor::MzmlConvert::readStream()
{
mp_cborWriter->startMap();
if(m_qxmlStreamReader.readNextStartElement())
{
qDebug() << m_qxmlStreamReader.name().toString();
if(m_qxmlStreamReader.name().toString() == "indexedmzML")
{
m_qxmlStreamReader.readNextStartElement();
}
if(m_qxmlStreamReader.name().toString() == "mzML")
{
// write mzCBOR header
mp_cborWriter->append("mzCBOR");
mp_cborWriter->startMap();
mp_cborWriter->append("mode");
mp_cborWriter->append(0);
mp_cborWriter->writeInformations(
PAPPSOMSPP_NAME, PAPPSOMSPP_VERSION, "mzCBOR", "mzMLconvert");
m_uuid = mp_cborWriter->getUuid();
mp_cborWriter->endMap();
mp_cborWriter->append(m_qxmlStreamReader.name().toString());
mp_cborWriter->startMap();
mp_cborWriter->append("xmlns");
mp_cborWriter->append(m_qxmlStreamReader.namespaceUri());
attributeListToCbor(m_qxmlStreamReader.attributes());
mp_cborWriter->endMap();
bool array_started = false;
QString last_element;
while(m_qxmlStreamReader.readNextStartElement())
{
qDebug();
insideElement(last_element, array_started);
last_element = m_qxmlStreamReader.name().toString();
qDebug();
}
}
else
{
m_qxmlStreamReader.raiseError(QObject::tr("Not an mzML input file"));
m_qxmlStreamReader.skipCurrentElement();
}
}
mp_cborWriter->endMap();
}
void
pappso::cbor::mzcbor::MzmlConvert::getCurrentSpectrumSize()
{
// defaultArrayLength 1552
m_currentSpectrumSize = m_qxmlStreamReader.attributes().value("defaultArrayLength").toULongLong();
}
void
pappso::cbor::mzcbor::MzmlConvert::readBinaryDataArrayList()
{
qDebug() << m_qxmlStreamReader.name();
// m_qxmlStreamReader.skipCurrentElement();
/*
*
<binaryDataArray encodedLength="9092">
<cvParam cvRef="MS" accession="MS:1000515" value="" name="intensity array"
unitAccession="MS:1000131" unitName="number of counts" unitCvRef="MS" /> <cvParam cvRef="MS"
accession="MS:1000523" value="" name="64-bit float" /> <cvParam cvRef="MS" accession="MS:1000574"
value="" name="zlib compression" /> <binary>*/
std::size_t count = m_qxmlStreamReader.attributes().value("count").toULongLong();
mp_cborWriter->append("binaryDataArray");
mp_cborWriter->startArray(count);
while(m_qxmlStreamReader.readNext() && !m_qxmlStreamReader.isEndElement())
{
if(m_qxmlStreamReader.isStartElement())
{
BinaryDataArray binary_data_array;
binary_data_array.fromMzml(m_qxmlStreamReader);
binary_data_array.toCbor(*mp_cborWriter);
// writeZlibDataArray();
}
}
mp_cborWriter->endArray();
qDebug() << m_qxmlStreamReader.name();
}
void
pappso::cbor::mzcbor::MzmlConvert::insideElement(QString &last_element_in, bool &array_started_in)
{
m_elementStash.push_back(m_qxmlStreamReader.name().toString());
qDebug() << m_qxmlStreamReader.name();
if(m_elementStash.back() == "spectrum")
{
// qDebug() << m_qxmlStreamReader.attributes().value("id").toString();
m_runAndSpectrumIdList.back().push_back(
m_qxmlStreamReader.attributes().value("id").toString());
getCurrentSpectrumSize();
// qFatal();
}
// stop an array ?
qDebug() << "current element=" << m_elementStash.back();
qDebug() << "last_element=" << last_element_in;
if(array_started_in && (last_element_in != m_qxmlStreamReader.name().toString()))
{
mp_cborWriter->endArray();
qDebug() << "mp_cborWriter->endArray()";
array_started_in = false;
}
if(m_elementStash.back() == "binaryDataArrayList")
{
qDebug() << "readBinaryDataArrayList()";
readBinaryDataArrayList();
}
else
{
// start an array ?
if(m_elementToStoreInArray.contains(m_elementStash.back()))
{
// start an array ?
if((!array_started_in) && (last_element_in != m_elementStash.back()))
{
mp_cborWriter->append(m_elementStash.back());
mp_cborWriter->startArray();
qDebug() << "mp_cborWriter->startArray()";
array_started_in = true;
}
}
if(m_elementStash.back() == "spectrum")
{
if(mp_cborWriter->device() != nullptr)
m_runAndSpectrumOffsetList.back().push_back(mp_cborWriter->device()->pos());
}
if(!array_started_in)
mp_cborWriter->append(m_elementStash.back());
bool array_started = false;
if(m_elementStash.back() == "cvParam")
{
// *********** special treatment for cvParam **********
if(!array_started_in)
{
throw pappso::PappsoException(
QObject::tr("unable to write cvParam outside CBOR array"));
}
// array_started = true;
qDebug() << m_qxmlStreamReader.name() << " "
<< m_elementStash.at(m_elementStash.size() - 2);
CvParam cv_param;
cv_param.fromMzml(m_qxmlStreamReader);
cv_param.toCbor(*mp_cborWriter);
qDebug() << cv_param.name;
if(m_elementStash.at(m_elementStash.size() - 2) == "spectrum")
{
qDebug() << "cvparam in spectrum";
if(cv_param.accession == "MS:1000511")
{
m_runAndSpectrumMsLevelList.back().push_back(cv_param.getExpectedUint8());
qDebug() << m_runAndSpectrumMsLevelList.back().back();
}
else if(cv_param.accession == "MS:1000285")
{ // TIC
m_runAndSpectrumTotalIonCountList.back().push_back(cv_param.getExpectedDouble());
}
}
else if(m_elementStash.at(m_elementStash.size() - 2) == "scan")
{
if(cv_param.accession == "MS:1000016")
{ // rt
double rt = cv_param.getExpectedDouble();
if(cv_param.unitAccession == "UO:0000031")
{
// // minutes
rt = rt * 60;
}
m_runAndSpectrumRtList.back().push_back(rt);
}
}
qDebug();
// *********** special treatment for cvParam **********
//
qDebug() << "finish cvParam " << cv_param.accession;
}
else
{
mp_cborWriter->startMap();
attributeListToCbor(m_qxmlStreamReader.attributes());
QString last_element;
while(m_qxmlStreamReader.readNext() && !m_qxmlStreamReader.isEndElement())
{
qDebug() << m_qxmlStreamReader.name();
if(m_qxmlStreamReader.isCharacters())
{
// clean content:
QStringView content = m_qxmlStreamReader.text().trimmed();
if((m_qxmlStreamReader.text().toString() == "\n") ||
(m_qxmlStreamReader.text().toString() == "\n\t"))
{
}
else
{
// text node
if(!content.isEmpty())
{
qDebug() << "text isCharacters" << content.mid(0, 10);
mp_cborWriter->append("@text@");
mp_cborWriter->append(content);
}
}
}
else if(m_qxmlStreamReader.isStartElement())
{
QString tmp_element = m_qxmlStreamReader.name().toString();
qDebug() << tmp_element;
insideElement(last_element, array_started);
last_element = tmp_element;
}
}
if(array_started)
{
mp_cborWriter->endArray();
}
mp_cborWriter->endMap();
qDebug() << m_qxmlStreamReader.name();
}
}
qDebug() << m_elementStash.back();
m_elementStash.pop_back();
}
void
pappso::cbor::mzcbor::MzmlConvert::attributeValueToCbor(const QStringView &value_str)
{
bool ok(false);
double d = value_str.toDouble(&ok);
if(ok)
{
if(value_str.contains('.'))
{
mp_cborWriter->append(d);
}
else
{
qint64 bigint = value_str.toLongLong(&ok);
if(ok)
{
mp_cborWriter->append(bigint);
}
}
}
else
{
mp_cborWriter->append(value_str);
}
}
void
pappso::cbor::mzcbor::MzmlConvert::attributeListToCbor(const QXmlStreamAttributes &xml_attributes)
{
for(auto &xml_attribute : xml_attributes)
{
qDebug() << xml_attribute.name() << " " << xml_attribute.value();
mp_cborWriter->append(xml_attribute.name());
attributeValueToCbor(xml_attribute.value());
if((m_elementStash.size() > 0) && (m_elementStash.back() == "run") &&
(xml_attribute.name() == "id"))
{
m_runAndSpectrumOffsetList.push_back(std::vector<qint64>());
m_runAndSpectrumIdList.push_back(std::vector<QString>());
m_runAndSpectrumMsLevelList.push_back(std::vector<std::uint8_t>());
m_runAndSpectrumRtList.push_back(std::vector<double>());
m_runAndSpectrumTotalIonCountList.push_back(std::vector<qint64>());
m_runIdList.push_back(xml_attribute.value().toString());
}
}
}
const std::vector<QString> &
pappso::cbor::mzcbor::MzmlConvert::getRunIdList() const
{
return m_runIdList;
}
const std::vector<std::vector<qint64>> &
pappso::cbor::mzcbor::MzmlConvert::getRunAndSpectrumOffsetList() const
{
return m_runAndSpectrumOffsetList;
}
const std::vector<std::vector<QString>> &
pappso::cbor::mzcbor::MzmlConvert::getRunAndSpectrumIdList() const
{
return m_runAndSpectrumIdList;
}
binarydataarray.h
PSI BinaryDataArray object for mzML/mzCBOR.
pappso::PappsoException
Definition pappsoexception.h:41
pappso::UiMonitorInterface
Definition uimonitorinterface.h:50
pappso::XmlStreamReaderInterface::m_qxmlStreamReader
QXmlStreamReader m_qxmlStreamReader
Definition xmlstreamreaderinterface.h:71
pappso::cbor::CborStreamWriter
overrides QCborStreamWriter base class to provide convenient functions
Definition cborstreamwriter.h:45
pappso::cbor::CborStreamWriter::writeInformations
void writeInformations(const QString &software_name, const QString &software_version, const QString &type, const QString &operation)
automatically produces an informations CBOR map the "informations" map contains default parameters : ...
Definition cborstreamwriter.cpp:59
pappso::cbor::CborStreamWriter::writeArray
void writeArray(const std::vector< std::size_t > &int_list)
Definition cborstreamwriter.cpp:93
pappso::cbor::mzcbor::MzmlConvert::readStream
virtual void readStream() override
Definition mzmlconvert.cpp:169
pappso::cbor::mzcbor::MzmlConvert::m_elementStash
std::vector< QString > m_elementStash
Definition mzmlconvert.h:84
pappso::cbor::mzcbor::MzmlConvert::m_runAndSpectrumIdList
std::vector< std::vector< QString > > m_runAndSpectrumIdList
Definition mzmlconvert.h:93
pappso::cbor::mzcbor::MzmlConvert::getCurrentSpectrumSize
void getCurrentSpectrumSize()
Definition mzmlconvert.cpp:224
pappso::cbor::mzcbor::MzmlConvert::m_elementToStoreInArray
QStringList m_elementToStoreInArray
Definition mzmlconvert.h:85
pappso::cbor::mzcbor::MzmlConvert::m_runAndSpectrumTotalIonCountList
std::vector< std::vector< qint64 > > m_runAndSpectrumTotalIonCountList
Definition mzmlconvert.h:94
pappso::cbor::mzcbor::MzmlConvert::writeMzcborIndex
void writeMzcborIndex(pappso::cbor::CborStreamWriter *writer) const
Definition mzmlconvert.cpp:65
pappso::cbor::mzcbor::MzmlConvert::m_runAndSpectrumMsLevelList
std::vector< std::vector< std::uint8_t > > m_runAndSpectrumMsLevelList
Definition mzmlconvert.h:95
pappso::cbor::mzcbor::MzmlConvert::getRunAndSpectrumOffsetList
const std::vector< std::vector< qint64 > > & getRunAndSpectrumOffsetList() const
Definition mzmlconvert.cpp:489
pappso::cbor::mzcbor::MzmlConvert::insideElement
void insideElement(QString &last_element, bool &array_started)
Definition mzmlconvert.cpp:265
pappso::cbor::mzcbor::MzmlConvert::getRunIdList
const std::vector< QString > & getRunIdList() const
Definition mzmlconvert.cpp:482
pappso::cbor::mzcbor::MzmlConvert::m_runAndSpectrumRtList
std::vector< std::vector< double > > m_runAndSpectrumRtList
Definition mzmlconvert.h:96
pappso::cbor::mzcbor::MzmlConvert::m_uuid
QString m_uuid
Definition mzmlconvert.h:97
pappso::cbor::mzcbor::MzmlConvert::attributeListToCbor
void attributeListToCbor(const QXmlStreamAttributes &xml_attributes)
Definition mzmlconvert.cpp:460
pappso::cbor::mzcbor::MzmlConvert::getRunAndSpectrumIdList
const std::vector< std::vector< QString > > & getRunAndSpectrumIdList() const
Definition mzmlconvert.cpp:495
pappso::cbor::mzcbor::MzmlConvert::m_runIdList
std::vector< QString > m_runIdList
Definition mzmlconvert.h:91
pappso::cbor::mzcbor::MzmlConvert::mp_monitor
pappso::UiMonitorInterface * mp_monitor
Definition mzmlconvert.h:81
pappso::cbor::mzcbor::MzmlConvert::attributeValueToCbor
void attributeValueToCbor(const QStringView &value_str)
Definition mzmlconvert.cpp:433
pappso::cbor::mzcbor::MzmlConvert::readBinaryDataArrayList
void readBinaryDataArrayList()
Definition mzmlconvert.cpp:233
pappso::cbor::mzcbor::MzmlConvert::MzmlConvert
MzmlConvert(pappso::UiMonitorInterface *p_monitor, pappso::cbor::CborStreamWriter *p_output)
Definition mzmlconvert.cpp:39
pappso::cbor::mzcbor::MzmlConvert::~MzmlConvert
virtual ~MzmlConvert()
Definition mzmlconvert.cpp:59
pappso::cbor::mzcbor::MzmlConvert::m_doubleArray
QVector< double > m_doubleArray
Definition mzmlconvert.h:89
pappso::cbor::mzcbor::MzmlConvert::m_runAndSpectrumOffsetList
std::vector< std::vector< qint64 > > m_runAndSpectrumOffsetList
Definition mzmlconvert.h:92
pappso::cbor::mzcbor::MzmlConvert::m_currentSpectrumSize
std::size_t m_currentSpectrumSize
Definition mzmlconvert.h:87
pappso::cbor::mzcbor::MzmlConvert::mp_cborWriter
pappso::cbor::CborStreamWriter * mp_cborWriter
Definition mzmlconvert.h:82
config.h
PAPPSOMSPP_VERSION
#define PAPPSOMSPP_VERSION
Definition config.h:6
PAPPSOMSPP_NAME
#define PAPPSOMSPP_NAME
Definition config.h:5
cvparam.h
PSI cvParam object for mzML/mzCBOR.
mzmlconvert.h
pappsoexception.h
pappso::cbor::mzcbor::BinaryDataArray
Definition binarydataarray.h:44
pappso::cbor::mzcbor::BinaryDataArray::fromMzml
void fromMzml(QXmlStreamReader &reader)
Definition binarydataarray.cpp:132
pappso::cbor::mzcbor::BinaryDataArray::toCbor
void toCbor(CborStreamWriter &writer)
Definition binarydataarray.cpp:111
pappso::cbor::mzcbor::CvParam
Definition cvparam.h:47
pappso::cbor::mzcbor::CvParam::accession
QString accession
Definition cvparam.h:74
pappso::cbor::mzcbor::CvParam::fromMzml
void fromMzml(QXmlStreamReader &reader)
reads the XML attributes of the cvParam element Inside the cvParam XML element, reads the attributes ...
Definition cvparam.cpp:121
pappso::cbor::mzcbor::CvParam::toCbor
void toCbor(CborStreamWriter &writer)
Definition cvparam.cpp:161
pappso::cbor::mzcbor::CvParam::unitAccession
QString unitAccession
Definition cvparam.h:79
pappso::cbor::mzcbor::CvParam::getExpectedUint8
std::uint8_t getExpectedUint8() const
Definition cvparam.cpp:271
pappso::cbor::mzcbor::CvParam::name
QString name
Definition cvparam.h:78
pappso::cbor::mzcbor::CvParam::getExpectedDouble
double getExpectedDouble() const
Definition cvparam.cpp:303