Loading...
Searching...
No Matches
spectrum.cpp
Go to the documentation of this file.
/**
* \file pappsomspp/core/processing/cbor/mzcbor/spectrum.h
* \date 24/11/2025
* \author Olivier Langella
* \brief PSI spectrum object for mzML/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 "spectrum.h"
#include "pappsomspp/core/exception/exceptionnotfound.h"
#include "pappsomspp/core/processing/cbor/mzcbor/cvparammap.h"
#include "pappsomspp/core/processing/cbor/mzcbor/scan.h"
#include "pappsomspp/core/trace/datapoint.h"
#include <qdebug.h>
#include <qjsonarray.h>
#include <qjsonobject.h>
#include <qlogging.h>
#include <qtypes.h>
#include <unistd.h>
void
pappso::cbor::mzcbor::Spectrum::fromCbor(CborStreamReader &reader, bool want_binary_data)
{
QString txt_value;
// cborBinaryDataArray.clear();
precursorList.clear();
defaultArrayLength = 0;
index = 0;
cvParamMap.clear();
scanListCvParamMap.clear();
scanList.clear();
id.clear();
qDebug();
if(reader.isInvalid())
{
throw pappso::PappsoException(
QObject::tr("ERROR in Spectrum::fromCbor :\ncbor is not valid"));
}
if(reader.enterContainer())
{
while(reader.hasNext() && (!reader.isInvalid()))
{
if(reader.isString())
{
reader.decodeString(txt_value);
qDebug() << txt_value;
if(txt_value == "id")
{
reader.decodeString(txt_value);
qDebug() << txt_value;
id = txt_value;
}
else if(txt_value == "index")
{
index = reader.toUnsignedInteger();
reader.next();
}
else if(txt_value == "defaultArrayLength")
{
defaultArrayLength = reader.toUnsignedInteger();
reader.next();
}
else if(txt_value == "cvParam")
{
cvParamMap.fromCbor(reader);
}
else if(txt_value == "scanList")
{
// mpa_cborReader->next();
reader.enterContainer();
while(reader.hasNext() && (!reader.isInvalid()))
{
if(reader.isString())
{
if(reader.decodeString(txt_value))
{
qDebug() << txt_value;
if(txt_value == "cvParam")
{
scanListCvParamMap.fromCbor(reader);
}
else if(txt_value == "scan")
{
// scan array
reader.enterContainer();
while(reader.hasNext() && (!reader.isInvalid()))
{
// scan array
Scan scan;
scan.fromCbor(reader);
scanList.emplace_back(scan);
}
reader.leaveContainer();
}
}
else
{
reader.next();
}
}
else
{
reader.next();
}
}
reader.leaveContainer();
}
else if(txt_value == "precursorList")
{
reader.enterContainer();
while(reader.hasNext() && (!reader.isInvalid()))
{
if(reader.isString())
{
if(reader.decodeString(txt_value))
{
qDebug() << txt_value;
if(txt_value == "cvParam")
{
precursorListCvParamMap.fromCbor(reader);
}
else if(txt_value == "precursor")
{
reader
.enterContainer(); // array
while(reader.hasNext() && (!reader.isInvalid()))
{
// scan array
Precursor precursor;
precursor.fromCbor(reader);
precursorList.emplace_back(precursor);
}
reader
.leaveContainer(); // array
// reader.next();
}
else
{
reader.next();
}
}
else
{
reader.next();
}
}
else
{
reader.next();
}
}
reader.leaveContainer();
}
else if(txt_value == "binaryDataArray")
{
if(want_binary_data)
{
reader.enterContainer(); // start array
while(reader.hasNext())
{
BinaryDataArray data_array;
data_array.fromCbor(reader);
binaryDataArrayList.emplace_back(data_array);
}
reader.leaveContainer(); // end array
}
else
{
reader.next();
}
}
else
{
reader.next();
}
}
// reader.next();
}
reader.leaveContainer();
}
else
{
throw pappso::PappsoException(QObject::tr("ERROR in Spectrum::fromCbor : no container"));
}
if(reader.lastError() != QCborError::NoError)
{
throw pappso::PappsoException(
QObject::tr("ERROR in Spectrum::fromCbor :\n%1").arg(reader.lastError().toString()));
}
}
QJsonObject
pappso::cbor::mzcbor::Spectrum::toJsonObject() const
{
QJsonObject spectrum_json;
spectrum_json.insert("id", id);
spectrum_json.insert("index", (qint64)index);
spectrum_json.insert("defaultArrayLength", (qint64)defaultArrayLength);
spectrum_json.insert("cvParam", cvParamMap.toJsonArray());
QJsonObject scan_list;
// QJsonObject scan_list_cvparam;
scan_list.insert("cvParam", scanListCvParamMap.toJsonArray());
QJsonArray scan_array;
for(auto &scan : scanList)
{
scan_array.append(scan.toJsonObject());
}
scan_list.insert("scan", scan_array);
spectrum_json.insert("scanList", scan_list);
if(!precursorList.empty())
{
QJsonObject precursor_list;
// QJsonObject scan_list_cvparam;
precursor_list.insert("cvParam", precursorListCvParamMap.toJsonArray());
QJsonArray precursor_array;
for(auto &precursor : precursorList)
{
precursor_array.append(precursor.toJsonObject());
}
precursor_list.insert("precursor", precursor_array);
spectrum_json.insert("precursorList", precursor_list);
}
if(!binaryDataArrayList.empty())
{
Trace trace;
decodeTrace(trace);
spectrum_json.insert("spectrum", trace.toJsonObject());
}
return spectrum_json;
}
std::map<QString, pappso::cbor::mzcbor::CvParam>
pappso::cbor::mzcbor::Spectrum::readScanCvParams(CborStreamReader &reader)
{
CvParamMap cv_params;
reader.enterContainer();
QString txt_value;
while(reader.hasNext() && (!reader.isInvalid()))
{
if(reader.isString())
{
if(reader.decodeString(txt_value))
{
qDebug() << txt_value;
if(txt_value == "cvParam")
{
cv_params.fromCbor(reader);
}
else
{
reader.next();
}
}
}
else
{
reader.next();
}
}
reader.leaveContainer();
return cv_params;
}
qint64
pappso::cbor::mzcbor::Spectrum::getTotalIonCount() const
{
// <cvParam cvRef="MS" accession="MS:1000285" value="17377980" name="total ion current" />
auto it = cvParamMap.find("MS:1000285");
if(it == cvParamMap.end())
{
throw pappso::ExceptionNotFound(QObject::tr("total ion count not found in cvParam map"));
}
qDebug() << it->first << " " << it->second.valueInt;
return it->second.valueInt;
}
uint
pappso::cbor::mzcbor::Spectrum::getMsLevel() const
{
// <cvParam cvRef="MS" accession="MS:1000511" value="1" name="ms level" />
auto it = cvParamMap.find("MS:1000511");
if(it == cvParamMap.end())
{
throw pappso::ExceptionNotFound(QObject::tr("MS level not found in cvParam map"));
}
qDebug() << it->first << " " << it->second.valueInt;
return it->second.valueInt;
}
double
pappso::cbor::mzcbor::Spectrum::getRtInSeconds() const
{
if(scanList.size() == 0)
{
throw pappso::ExceptionNotFound(QObject::tr("scan list is empty in spectrum"));
}
if(scanList.size() > 1)
{
throw pappso::ExceptionNotFound(QObject::tr("too many scans in spectrum"));
}
return scanList.front().getRtInSeconds();
}
void
pappso::cbor::mzcbor::Spectrum::decodeTrace(pappso::Trace &trace) const
{
qDebug();
std::vector<pappso_double> xVector;
std::vector<pappso_double> yVector;
for(auto &binary_array : binaryDataArrayList)
{
qDebug();
if(binary_array.isIntensity())
{
qDebug();
binary_array.decodeVector(defaultArrayLength, yVector);
}
else if(binary_array.isMz())
{
qDebug();
binary_array.decodeVector(defaultArrayLength, xVector);
}
else
{
throw pappso::ExceptionNotFound(QObject::tr(
"error in pappso::cbor::mzcbor::Spectrum::decodeTrace: binary vector type not found"));
}
qDebug();
}
qDebug();
trace.initialize(xVector, yVector);
qDebug();
}
void
pappso::cbor::mzcbor::Spectrum::toMgf(QTextStream &output, MsRunIdCstSPtr msrun_id_csptr) const
{
// BEGIN IONS
// TITLE=20120906_balliau_extract_1_A01_urnb-1.2016.2016.3
// RTINSECONDS=679.467
// PEPMASS=417.210251631473 92010.6328125
// CHARGE=3+
// 88.03964233 1132.5438232422
// 91.05783844 1945.9479980469
// 93.03697968 6423.5581054688
// 93.8877182 949.33984375
output << "BEGIN IONS" << Qt::endl;
QString title;
if(msrun_id_csptr.get() != nullptr)
{
title = msrun_id_csptr.get()->getSampleName();
}
output << "TITLE=" << title << "." << index << Qt::endl;
output << "RTINSECONDS=" << QString::number(scanList.front().getRtInSeconds(), 'f', 4)
<< Qt::endl;
bool is_ok;
double intensity = precursorList.front().selectedIonList.front().getIntensity(&is_ok);
if(is_ok)
{
output << "PEPMASS="
<< QString::number(precursorList.front().selectedIonList.front().getMz(), 'f', 8)
<< " " << QString::number(intensity, 'g', 10) << Qt::endl;
}
else
{
output << "PEPMASS="
<< QString::number(precursorList.front().selectedIonList.front().getMz(), 'f', 8)
<< Qt::endl;
}
output << "CHARGE=" << precursorList.front().selectedIonList.front().getChargeState() << "+"
<< Qt::endl;
Trace trace;
decodeTrace(trace);
for(const pappso::DataPoint &one_point : trace)
{
output << QString::number(one_point.x, 'f', 8) << " " << QString::number(one_point.y, 'f', 8)
<< Qt::endl;
}
output << "END IONS" << Qt::endl;
}
pappso::ExceptionNotFound
Definition exceptionnotfound.h:32
pappso::PappsoException
Definition pappsoexception.h:41
pappso::Trace
A simple container of DataPoint instances.
Definition trace.h:152
pappso::Trace::toJsonObject
QJsonObject toJsonObject(const QString &x_label="x", const QString &y_label="y") const
serialize a PAPPSO trace object to JSON
Definition trace.cpp:1191
pappso::Trace::initialize
size_t initialize(const std::vector< pappso_double > &xVector, const std::vector< pappso_double > &yVector)
Definition trace.cpp:597
pappso::cbor::CborStreamReader
simple override of the raw QCborStreamReader This adds convenient functions to put CBOR data into C++...
Definition cborstreamreader.h:46
pappso::cbor::CborStreamReader::decodeString
bool decodeString(QString &the_str)
decode the current cbor value as a string the point to the next value the current value is decoded as...
Definition cborstreamreader.cpp:48
cvparammap.h
cvParam map
datapoint.h
exceptionnotfound.h
pappso::MsRunIdCstSPtr
std::shared_ptr< const MsRunId > MsRunIdCstSPtr
Definition msrunid.h:46
pappso::uint
unsigned int uint
Definition types.h:67
scan.h
PSI scan object for mzML/mzCBOR.
spectrum.h
PSI spectrum object for mzML/mzCBOR.
pappso::DataPoint
Definition datapoint.h:22
pappso::cbor::mzcbor::BinaryDataArray
Definition binarydataarray.h:44
pappso::cbor::mzcbor::BinaryDataArray::fromCbor
void fromCbor(CborStreamReader &reader)
Definition binarydataarray.cpp:37
pappso::cbor::mzcbor::CvParamMap
Definition cvparammap.h:46
pappso::cbor::mzcbor::CvParamMap::fromCbor
void fromCbor(CborStreamReader &reader)
fill the structure reading data from a CBOR stream
Definition cvparammap.cpp:33
pappso::cbor::mzcbor::Precursor
Definition precursor.h:83
pappso::cbor::mzcbor::Precursor::fromCbor
void fromCbor(CborStreamReader &reader)
Definition precursor.cpp:229
pappso::cbor::mzcbor::Scan
Definition scan.h:45
pappso::cbor::mzcbor::Scan::fromCbor
void fromCbor(CborStreamReader &reader)
Definition scan.cpp:57
pappso::cbor::mzcbor::Spectrum::cvParamMap
CvParamMap cvParamMap
Definition spectrum.h:84
pappso::cbor::mzcbor::Spectrum::readScanCvParams
static std::map< QString, pappso::cbor::mzcbor::CvParam > readScanCvParams(CborStreamReader &reader)
Definition spectrum.cpp:278
pappso::cbor::mzcbor::Spectrum::toMgf
void toMgf(QTextStream &output, MsRunIdCstSPtr msrun_id_csptr) const
write spectrum in MGF text format
Definition spectrum.cpp:389
pappso::cbor::mzcbor::Spectrum::getMsLevel
uint getMsLevel() const
Definition spectrum.cpp:328
pappso::cbor::mzcbor::Spectrum::precursorList
std::vector< Precursor > precursorList
Definition spectrum.h:89
pappso::cbor::mzcbor::Spectrum::scanList
std::vector< Scan > scanList
Definition spectrum.h:88
pappso::cbor::mzcbor::Spectrum::index
std::size_t index
Definition spectrum.h:81
pappso::cbor::mzcbor::Spectrum::precursorListCvParamMap
CvParamMap precursorListCvParamMap
Definition spectrum.h:86
pappso::cbor::mzcbor::Spectrum::toJsonObject
QJsonObject toJsonObject() const
write the structure to a JSON object This is a simplified representation for easy JSON data handling ...
Definition spectrum.cpp:231
pappso::cbor::mzcbor::Spectrum::fromCbor
void fromCbor(CborStreamReader &reader, bool want_binary_data)
fill the structure reading data from a CBOR stream
Definition spectrum.cpp:43
pappso::cbor::mzcbor::Spectrum::getRtInSeconds
double getRtInSeconds() const
Definition spectrum.cpp:342
pappso::cbor::mzcbor::Spectrum::scanListCvParamMap
CvParamMap scanListCvParamMap
Definition spectrum.h:85
pappso::cbor::mzcbor::Spectrum::decodeTrace
void decodeTrace(pappso::Trace &trace) const
Definition spectrum.cpp:356
pappso::cbor::mzcbor::Spectrum::getTotalIonCount
qint64 getTotalIonCount() const
Definition spectrum.cpp:313
pappso::cbor::mzcbor::Spectrum::binaryDataArrayList
std::vector< BinaryDataArray > binaryDataArrayList
Definition spectrum.h:90
pappso::cbor::mzcbor::Spectrum::defaultArrayLength
std::size_t defaultArrayLength
Definition spectrum.h:82