libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
jsoninput.cpp
Go to the documentation of this file.
1
2/**
3 * \file pappsomspp/masschroq/input/jsoninput.cpp
4 * \date 02/01/2025
5 * \author Olivier Langella
6 * \brief process json document input
7 */
8
9/*******************************************************************************
10 * Copyright (c) 2025 Olivier Langella
11 *<Olivier.Langella@universite-paris-saclay.fr>.
12 *
13 * This file is part of MassChroQ.
14 *
15 * MassChroQ is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation, either version 3 of the License, or
18 * (at your option) any later version.
19 *
20 * MassChroQ is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with MassChroQ. If not, see <http://www.gnu.org/licenses/>.
27 *
28 ******************************************************************************/
29
30
37#include <QtConcurrent>
38#include <QStringList>
39
41 const QString &tmp_dir_name,
42 const QJsonDocument &json_doc)
43 : m_jsonDocument(json_doc), m_tmpDirName(tmp_dir_name), m_uiMonitor(ui_monitor)
44{
45}
46
50
51void
53{
58 cbor_output.writeActionBegin("quantification");
59
60
62
63 // QJsonDocument doc;
64 // doc.setObject(params);
65 // qDebug() << doc.toJson();
66 m_isMatchBetweenRun = msp_quantificationMethod.get()->getMatchBetweenRun();
67
69
70
71 param.name = "mcq_version";
73 m_projectParameters.setProjectParam(param);
74
75 m_projectParameters.merge(msp_alignmentMethod.get()->getProjectParameters());
76 m_projectParameters.merge(msp_quantificationMethod.get()->getProjectParameters());
77
79
80 qDebug();
81
82 QJsonObject methods = m_jsonDocument.object().value("masschroq_methods").toObject();
83 cbor_output.writeJsonObject("masschroq_methods", methods);
84
85 cbor_output.getCborStreamWriter().append("identification_data");
86 cbor_output.getCborStreamWriter().startMap();
87 QJsonObject msrun_list = documentFind("identification_data", "msrun_list").toObject();
88 cbor_output.writeJsonObject("msrun_list", msrun_list);
89 QJsonObject protein_list = documentFind("identification_data", "protein_list").toObject();
90 cbor_output.writeJsonObject("protein_list", protein_list);
91 QJsonObject peptide_list = documentFind("identification_data", "peptide_list").toObject();
92 cbor_output.writeJsonObject("peptide_list", peptide_list);
93 QJsonObject msrunpeptide_list =
94 documentFind("identification_data", "msrunpeptide_list").toObject();
95 cbor_output.writeJsonObject("msrunpeptide_list", msrunpeptide_list);
96 cbor_output.getCborStreamWriter().endMap();
97
98 qDebug();
101
102 QJsonObject actions = m_jsonDocument.object().value("actions").toObject();
103 cbor_output.writeJsonObject("actions", actions);
104
105 readAction(cbor_output);
106}
107
108const QJsonValue
109pappso::masschroq::JsonInput::documentFind(const QString &key1, const QString &key2) const
110{
111 QJsonObject obj1 = m_jsonDocument.object();
112 auto it1 = obj1.find(key1);
113 if(it1 != obj1.end())
114 {
115 QJsonObject obj2 = it1.value().toObject();
116 auto it2 = obj2.find(key2);
117 if(it2 != obj2.end())
118 {
119 return it2.value();
120 }
121 else
122 {
124 QObject::tr("key2 %1 not found in json document element %2").arg(key2).arg(key1));
125 }
126 }
127 else
128 {
129 throw pappso::ExceptionNotFound(QObject::tr("key1 %1 not found in json document").arg(key1));
130 }
131}
132
133
134void
136{
137 qDebug();
138 std::map<QString, QString> msfilepathlist;
139 const QJsonObject msrun_list(documentFind("identification_data", "msrun_list").toObject());
140 auto it = msrun_list.begin();
141 while(it != msrun_list.end())
142 {
143 qDebug() << it.key();
144 qDebug() << it.value().toObject().value("file");
145 //<data_file id="samp0" format="mzxml" path="bsa1.mzXML"
146 // type="profile" />
147 msfilepathlist.insert({it.key(), it.value().toObject().value("file").toString()});
148 it++;
149 }
150
151
152 qDebug();
153 std::function<pappso::masschroq::MsRunPeptideListSp(const std::pair<QString, QString> &)>
154 mapFilenameList = [](const std::pair<QString, QString> &mapit) {
155 pappso::MsFileAccessor file_access(mapit.second, mapit.first);
158
159 std::vector<pappso::MsRunIdCstSPtr> msrunid_list = file_access.getMsRunIds();
160
161
163 {
164 throw pappso::ExceptionNotRecognized("MS data file format not recognized");
165 }
166 if(msrunid_list.size() == 0)
167 {
168 throw pappso::PappsoException("msrunid_list.size() == 0");
169 }
170
171
172 pappso::MsRunReaderSPtr run_reader = file_access.getMsRunReaderSPtrByRunId("", mapit.first);
173 run_reader.get()->setMonoThread(true);
174 pappso::masschroq::MsRunSp msrun = std::make_shared<pappso::masschroq::MsRun>(run_reader);
175 run_reader.get()->releaseDevice();
176 run_reader.get()->setMonoThread(false);
177 return std::make_shared<pappso::masschroq::MsRunPeptideList>(msrun);
178 };
179
180 qDebug();
181
182 m_uiMonitor.appendText(QObject::tr("reading %1 msruns").arg(msfilepathlist.size()));
183
184
185 pappso::UiMonitorInterface *local_monitor = &m_uiMonitor;
186 std::map<QString, pappso::masschroq::MsRunPeptideListSp> *p_localPtrOnmsrunpeptidelist =
188
189 std::function<void(std::size_t, const pappso::masschroq::MsRunPeptideListSp)> reduce_function =
190 [local_monitor, p_localPtrOnmsrunpeptidelist](
191 std::size_t result, const pappso::masschroq::MsRunPeptideListSp msrun) {
192 local_monitor->setStatus(QObject::tr("MS run '%1' from file %2: added ")
193 .arg(msrun.get()
194 ->getMsRunSp()
195 .get()
196 ->getMsRunReaderSPtr()
197 .get()
198 ->getMsRunId()
199 .get()
200 ->getXmlId())
201 .arg(msrun.get()
202 ->getMsRunSp()
203 .get()
204 ->getMsRunReaderSPtr()
205 .get()
206 ->getMsRunId()
207 .get()
208 ->getFileName()));
209
210 p_localPtrOnmsrunpeptidelist->insert({msrun.get()
211 ->getMsRunSp()
212 .get()
213 ->getMsRunReaderSPtr()
214 .get()
215 ->getMsRunId()
216 .get()
217 ->getXmlId(),
218 msrun});
219 result++;
220 };
221
222 QFuture<std::size_t> res = QtConcurrent::mappedReduced<std::size_t>(msfilepathlist.begin(),
223 msfilepathlist.end(),
224 mapFilenameList,
225 reduce_function,
226 QtConcurrent::OrderedReduce);
227 res.waitForFinished();
228
229 m_uiMonitor.appendText("reading msruns finished");
230 if(m_msfileList.begin()->second.get()->getMsRunSp().get()->hasTimsTofMobilityIndex())
231 {
232 m_uiMonitor.appendText("ion mobility grid enabled");
233 msp_ionMobilityGrid = std::make_shared<pappso::IonMobilityGrid>();
234 }
235}
236
237void
239{
240 msp_alignmentMethod = std::make_shared<pappso::masschroq::AlignmentMethod>("align1");
241
242 msp_alignmentMethod.get()->setJsonObject(
243 documentFind("masschroq_methods", "alignment_method").toObject());
244}
245
246void
248{
249 msp_quantificationMethod = std::make_shared<pappso::masschroq::QuantificationMethod>("qm1");
250
251
252 msp_quantificationMethod.get()->setJsonObject(
253 documentFind("masschroq_methods", "quantification_method").toObject());
254
255 /*
256 "quantification_method": {
257 "detection": {
258 "type": "zivy",
259 "meanfilter": 1,
260 "minmax": 3,
261 "maxmin": 2,
262 "threshold_on_max": 5000,
263 "threshold_on_min": 3000,
264 }
265 }
266 */
267}
268
269
270void
272{
273
274
275 const QJsonObject protein_list(documentFind("identification_data", "protein_list").toObject());
276 //<protein desc="conta|P02769|ALBU_BOVIN SERUM ALBUMIN PRECURSOR."
277 // id="P1.1" />
278
279 auto it = protein_list.begin();
280 while(it != protein_list.end())
281 {
282 qDebug() << it.key();
283 qDebug() << it.value().toObject().value("description");
284
285 /// create a new Protein object and set its description
287 try
288 {
289 p_protein = std::make_shared<pappso::masschroq::Protein>(
290 it.key(), it.value().toObject().value("description").toString());
291 }
292 catch(pappso::PappsoException &error)
293 {
295 QObject::tr("problem creating protein :\n%1").arg(it.key()));
296 }
297 /// add this protein to _p_proteins (: map<id, Protein *>)
298 m_proteinMap.insert({p_protein.get()->getId(), p_protein});
299 it++;
300 }
301}
302
303void
305{
306
307
308 const QJsonObject peptide_list(documentFind("identification_data", "peptide_list").toObject());
309 //<protein desc="conta|P02769|ALBU_BOVIN SERUM ALBUMIN PRECURSOR."
310 // id="P1.1" />
311
312 auto it = peptide_list.begin();
313 while(it != peptide_list.end())
314 {
315 qDebug() << it.key();
316 qDebug() << it.value().toObject().value("proforma");
317
318 /// create a new peptide object and set its description
320 try
321 {
322
323 std::vector<pappso::masschroq::ProteinSp> protein_list;
324 for(auto prot_id : it.value().toObject().value("proteins").toArray())
325 {
326 auto it = m_proteinMap.find(prot_id.toString());
327 if(it != m_proteinMap.end())
328 {
329 protein_list.push_back(it->second);
330 }
331 else
332 {
334 QObject::tr("protein id %1 not found").arg(prot_id.toString()));
335 }
336 }
337
338
339 peptide_sp = std::make_shared<pappso::masschroq::Peptide>(
340 it.key(),
342 it.value().toObject().value("proforma").toString()),
343 protein_list);
344 m_peptideStore.push_back(peptide_sp);
345 peptide_sp.get()->setMods(it.value().toObject().value("mods").toString());
346 m_peptideMap.insert({peptide_sp.get()->getId(), peptide_sp});
347
348 qDebug();
349 QJsonObject json_label_list = it.value().toObject().value("label_list").toObject();
350
351 qDebug();
352 if(!json_label_list.isEmpty())
353 {
354 qDebug();
355 peptide_sp.get()->setJsonLabelList(json_label_list);
356 qDebug();
357 }
358 }
359 catch(pappso::PappsoException &error)
360 {
362 QObject::tr("problem creating protein :\n%1").arg(it.key()));
363 }
364 it++;
365 }
366
367 qDebug();
368}
369
370void
372{
373 qDebug();
374 const QJsonObject msrunpeptide_list(
375 documentFind("identification_data", "msrunpeptide_list").toObject());
376 auto it = msrunpeptide_list.begin();
377 while(it != msrunpeptide_list.end())
378 {
379 qDebug() << it.key();
380 QJsonObject jmsrun_peptidelist_object = it.value().toObject();
381 auto it_peptide_obs = jmsrun_peptidelist_object.find("peptide_obs");
382 if(it_peptide_obs == jmsrun_peptidelist_object.end())
383 {
385 QObject::tr("peptide_obs not found in msrunpeptide_list %1").arg(it.key()));
386 }
387 QJsonObject json_msrunobs = it_peptide_obs->toObject();
388 auto it_msrun = m_msfileList.find(it.key());
389 if(it_msrun == m_msfileList.end())
390 {
391 throw pappso::ExceptionNotFound(QObject::tr("msrun %1 not found").arg(it.key()));
392 }
393 pappso::masschroq::MsRunPeptideListSp msrunpep_sp = it_msrun->second;
394
395 auto itpep = json_msrunobs.begin();
396 while(itpep != json_msrunobs.end())
397 {
398 qDebug() << itpep.key();
399 QJsonArray json_obs_list = itpep.value().toArray();
400 auto it_pepmap = m_peptideMap.find(itpep.key());
401 if(it_pepmap == m_peptideMap.end())
402 {
403 throw pappso::ExceptionNotFound(QObject::tr("peptide %1 not found").arg(itpep.key()));
404 }
405 pappso::masschroq::PeptideSp peptide_sp = it_pepmap->second;
406 qDebug() << "json_obs_list.size()=" << json_obs_list.size();
407 for(auto json_obs_value : json_obs_list)
408 {
409 QJsonObject observation = json_obs_value.toObject();
410 qint64 scan = observation.value("scan").toInteger();
411 qint64 index = observation.value("index").toInteger();
412 QString label = observation.value("label").toString();
413 std::uint8_t charge =
414 observation.value("precursor").toObject().value("charge").toInt();
415 try
416 {
417 pappso::masschroq::PeptideLabel *p_label = nullptr;
418 if(!label.isEmpty())
419 {
420 p_label = peptide_sp.get()->getPeptideLabelPtr(label);
421 }
422 if(scan == 0)
423 {
424 msrunpep_sp.get()->addPeptideSpectrumIndexObservation(
425 peptide_sp, p_label, index, charge);
426 }
427 else
428 {
429
430 msrunpep_sp.get()->addPeptideScanNumberObservation(
431 peptide_sp, p_label, scan, charge);
432 }
433
434 peptide_sp.get()->addObservedChargeState(charge);
435 peptide_sp.get()->addObservedInMsRunSp(msrunpep_sp.get()->getMsRunSp());
436 }
437 catch(pappso::PappsoException &err)
438 {
440 QObject::tr("error reading peptide %1 observation scan %2 "
441 "index %3 : %4")
442 .arg(itpep.key())
443 .arg(scan)
444 .arg(index)
445 .arg(err.qwhat()));
446 }
447 }
448
449
450 if(msp_ionMobilityGrid.get() != nullptr)
451 {
452 if(peptide_sp.get() != nullptr)
453 {
454 peptide_sp.get()->populateIonMobilityGrid(msp_ionMobilityGrid.get());
455 }
456 }
457
458
459 itpep++;
460 }
461
462 it++;
463 }
464 qDebug();
465}
466
467void
469{
470 if(ni_min_abundance > 0)
471 { /*
472 for(auto &peptide_sp : m_peptideStore)
473 {
474 peptide_sp.get()->computeIsotopologues(ni_min_abundance);
475 }*/
476 std::function<void(const pappso::masschroq::PeptideSp &)> mapComputeIsotopologues =
477 [ni_min_abundance](const pappso::masschroq::PeptideSp &peptide_sp) {
478 peptide_sp.get()->computeIsotopologues(ni_min_abundance);
479 };
480
481
482 QFuture<void> res = QtConcurrent::map<std::vector<pappso::masschroq::PeptideSp>::iterator>(
483 m_peptideStore.begin(), m_peptideStore.end(), mapComputeIsotopologues);
484 m_uiMonitor.appendText(QObject::tr("Computing isotopologues %1").arg(ni_min_abundance));
485 res.waitForFinished();
486
487 m_uiMonitor.appendText("Computing isotopologues OK");
488 }
489}
490
491
492void
494{
495 const QJsonObject group_list(documentFind("actions", "group_list").toObject());
496
497 auto it_group = group_list.begin();
498 while(it_group != group_list.end())
499 {
500 QString id = it_group.key();
501 QJsonArray json_msrun_list = it_group.value().toArray();
502 std::vector<pappso::masschroq::MsRunPeptideListSp> msrun_list;
503 for(auto json_msrun : json_msrun_list)
504 {
505
506 auto it_msrun = m_msfileList.find(json_msrun.toString());
507 if(it_msrun == m_msfileList.end())
508 {
510 QObject::tr("msrun %1 not found").arg(json_msrun.toString()));
511 }
512 msrun_list.push_back(it_msrun->second);
513 }
514
515 m_msRunGroupSpList.insert({id, std::make_shared<MsRunGroup>(id, msrun_list)});
516 it_group++;
517 }
518
519
520 QJsonObject align_list;
521 try
522 {
523 align_list = documentFind("actions", "align_group").toObject();
524 }
525 catch(const pappso::ExceptionNotFound &notfound)
526 {
527 }
528 if(!align_list.isEmpty())
529 {
530 cbor_output.getCborStreamWriter().append("alignment_data");
531 cbor_output.getCborStreamWriter().startArray();
532
533 std::size_t count_q = 1;
534 QStringList group_keys = align_list.keys();
535 for(auto group_id : group_keys)
536 {
537 auto itgroup = m_msRunGroupSpList.find(group_id);
538 if(itgroup == m_msRunGroupSpList.end())
539 {
540 throw pappso::ExceptionNotFound(QObject::tr("group id %1 not found").arg(group_id));
541 }
542 else
543 {
544 QString ref_id =
545 align_list.value(group_id).toObject().value("alignment_reference").toString();
546 if(!ref_id.isEmpty())
547 {
548 itgroup->second.get()->setAlignmentMethodSp(msp_alignmentMethod, ref_id);
549 }
550 itgroup->second.get()->setIonMobilityGridSp(msp_ionMobilityGrid);
551 itgroup->second.get()->align(cbor_output, QString("a%1").arg(count_q), m_uiMonitor);
552 }
553 count_q++;
554 }
555 cbor_output.getCborStreamWriter().endArray();
556 }
557
558 QVariant quantify_all;
559 try
560 {
561 quantify_all = documentFind("actions", "quantify_all").toVariant();
562 }
563 catch(const pappso::ExceptionNotFound &notfound)
564 {
565 }
566 if(!quantify_all.isNull())
567 {
568 if(quantify_all.toBool())
569 {
570 double ni_ratio = msp_quantificationMethod.get()->getIsotopeMinimumRatio();
571 computeIsotopologues(ni_ratio);
572 std::size_t count_q = 1;
573 cbor_output.getCborStreamWriter().append("quantification_data");
574 cbor_output.getCborStreamWriter().startArray();
575 for(auto &pair_group : m_msRunGroupSpList)
576 {
577 pair_group.second.get()->setIonMobilityGridSp(msp_ionMobilityGrid);
578 pair_group.second.get()->quantify(cbor_output,
579 QString("q%1").arg(count_q),
584 }
585
586 cbor_output.getCborStreamWriter().endArray();
587 count_q++;
588 }
589 }
590}
591
592void
594{
595
596 QJsonObject params = m_jsonDocument.object().value("project_parameters").toObject();
597
598 pappso::ProjectParameters parameters(params);
599 m_projectParameters.merge(parameters);
600}
excetion to use when an item type is not recognized
void setPreferredFileReaderType(Enums::MsDataFormat format, Enums::FileReaderType reader_type)
given an mz format, explicitly set the preferred reader
Enums::MsDataFormat getFileFormat() const
get the raw format of mz data
std::vector< MsRunIdCstSPtr > getMsRunIds()
MsRunReaderSPtr getMsRunReaderSPtrByRunId(const QString &run_id, const QString &xml_id)
get an msrun reader by finding the run_id in file
virtual const QString & qwhat() const
static PeptideSp parseString(const QString &pepstr)
virtual void setStatus(const QString &status)=0
current status of the process
void writeJsonObject(const QString &name, const QJsonObject &json_object)
void writeProjectParameters(const pappso::ProjectParameters &project_parameters)
void writeActionBegin(const QString &operation)
const QJsonDocument & m_jsonDocument
Definition jsoninput.h:77
std::vector< PeptideSp > m_peptideStore
Definition jsoninput.h:86
std::map< QString, MsRunGroupSp > m_msRunGroupSpList
Definition jsoninput.h:88
const QString & m_tmpDirName
Definition jsoninput.h:78
pappso::UiMonitorInterface & m_uiMonitor
Definition jsoninput.h:79
void computeIsotopologues(double ni_ratio)
std::map< QString, PeptideSp > m_peptideMap
Definition jsoninput.h:87
void readAction(CborOutputStream &cbor_output)
std::map< QString, ProteinSp > m_proteinMap
Definition jsoninput.h:85
pappso::ProjectParameters m_projectParameters
Definition jsoninput.h:92
JsonInput(pappso::UiMonitorInterface &ui_monitor, const QString &tmp_dir_name, const QJsonDocument &json_doc)
Definition jsoninput.cpp:40
AlignmentMethodSp msp_alignmentMethod
Definition jsoninput.h:83
QuantificationMethodSp msp_quantificationMethod
Definition jsoninput.h:84
void action(CborOutputStream &cbor_output)
Definition jsoninput.cpp:52
std::map< QString, MsRunPeptideListSp > m_msfileList
Definition jsoninput.h:82
const QJsonValue documentFind(const QString &key1, const QString &key2) const
std::shared_ptr< pappso::IonMobilityGrid > msp_ionMobilityGrid
Definition jsoninput.h:90
void addPeptideScanNumberObservation(PeptideSp peptide_sp, PeptideLabel *p_label, std::size_t spectrum_index, std::uint8_t charge)
void addPeptideSpectrumIndexObservation(PeptideSp peptide_sp, PeptideLabel *p_label, std::size_t spectrum_index, std::uint8_t charge)
void addObservedChargeState(std::uint8_t charge)
Definition peptide.cpp:106
void populateIonMobilityGrid(pappso::IonMobilityGrid *ion_mobility_grid_p) const
Populate ion mobility grid with observed XIC coordinates for this peptide on all MSruns The ion mobil...
Definition peptide.cpp:308
void setJsonLabelList(const QJsonObject &json_label_list)
build peptide label map from JSON label_list object
Definition peptide.cpp:405
void setMods(const QString &mods)
set optional information as text to this peptide
Definition peptide.cpp:88
PeptideLabel * getPeptideLabelPtr(const QString &label) const
get a peptide label pointer with the corresponding label identifier
Definition peptide.cpp:433
const QString & getId() const
get peptide unique identifier
Definition peptide.cpp:82
void addObservedInMsRunSp(const MsRunSp &msrun_sp)
Definition peptide.cpp:123
const QString & getId() const
Definition protein.cpp:46
static QString getVersion()
Definition utils.cpp:37
@ unknown
unknown format
Definition types.h:149
std::shared_ptr< Protein > ProteinSp
Definition protein.h:39
std::shared_ptr< MsRunPeptideList > MsRunPeptideListSp
std::shared_ptr< Peptide > PeptideSp
Definition peptide.h:46
std::shared_ptr< MsRun > MsRunSp
Definition msrun.h:44
std::shared_ptr< MsRunReader > MsRunReaderSPtr
Definition msrunreader.h:57