GCC Code Coverage Report


./
File: src/XpertMass/PkaPhPiDataParser.cpp
Date: 2024-08-24 11:26:06
Lines:
0/90
0.0%
Functions:
0/5
0.0%
Branches:
0/242
0.0%

Line Branch Exec Source
1 /* BEGIN software license
2 *
3 * MsXpertSuite - mass spectrometry software suite
4 * -----------------------------------------------
5 * Copyright(C) 2009,...,2018 Filippo Rusconi
6 *
7 * http://www.msxpertsuite.org
8 *
9 * This file is part of the MsXpertSuite project.
10 *
11 * The MsXpertSuite project is the successor of the massXpert project. This
12 * project now includes various independent modules:
13 *
14 * - massXpert, model polymer chemistries and simulate mass spectrometric data;
15 * - mineXpert, a powerful TIC chromatogram/mass spectrum viewer/miner;
16 *
17 * This program is free software: you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation, either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 *
30 * END software license
31 */
32
33 #include <QFile>
34 #include <QIODevice>
35
36
37 /////////////////////// Local includes
38 #include "PkaPhPiDataParser.hpp"
39 #include "ChemicalGroup.hpp"
40 #include "PolChemDefEntity.hpp"
41
42
43 namespace MsXpS
44 {
45
46 namespace libXpertMass
47 {
48
49
50 /*!
51 \class MsXpS::libXpertMass::PkaPhPiDataParser
52 \inmodule libXpertMass
53 \ingroup PolChemDefBuildingdBlocks
54 \inheaderfile PkaPhPiDataParser.hpp
55
56 \brief The PkaPhPiDataParser class provides a file reader for the pKa, pH,
57 pI data XML file..
58
59 The format is the following:
60
61 \code
62 <pkaphpidata>
63 <monomers>
64 <monomer>
65 <code>A</code>
66 <mnmchemgroup>
67 <name>N-term NH2</name>
68 <pka>9.6</pka>
69 <acidcharged>TRUE</acidcharged>
70 <polrule>left_trapped</polrule>
71 <chemgrouprule>
72 <entity>LE_PLM_MODIF</entity>
73 <name>Acetylation</name>
74 <outcome>LOST</outcome>
75 </chemgrouprule>
76 </mnmchemgroup>
77 <mnmchemgroup>
78 <name>C-term COOH</name>
79 <pka>2.35</pka>
80 <acidcharged>FALSE</acidcharged>
81 <polrule>right_trapped</polrule>
82 </mnmchemgroup>
83 </monomer>
84 [...]
85 <monomer>
86 <code>C</code>
87 <mnmchemgroup>
88 <name>N-term NH2</name>
89 <pka>9.6</pka>
90 <acidcharged>TRUE</acidcharged>
91 <polrule>left_trapped</polrule>
92 <chemgrouprule>
93 <entity>LE_PLM_MODIF</entity>
94 <name>Acetylation</name>
95 <outcome>LOST</outcome>
96 </chemgrouprule>
97 </mnmchemgroup>
98 <mnmchemgroup>
99 <name>C-term COOH</name>
100 <pka>2.35</pka>
101 <acidcharged>FALSE</acidcharged>
102 <polrule>right_trapped</polrule>
103 </mnmchemgroup>
104 <mnmchemgroup>
105 <name>Lateral SH2</name>
106 <pka>8.3</pka>
107 <acidcharged>FALSE</acidcharged>
108 <polrule>never_trapped</polrule>
109 </mnmchemgroup>
110 </monomer>
111 </monomers>
112 <modifs>
113 <modif>
114 <name>Phosphorylation</name>
115 <mdfchemgroup>
116 <name>none_set</name>
117 <pka>1.2</pka>
118 <acidcharged>FALSE</acidcharged>
119 </mdfchemgroup>
120 <mdfchemgroup>
121 <name>none_set</name>
122 <pka>6.5</pka>
123 <acidcharged>FALSE</acidcharged>
124 </mdfchemgroup>
125 </modif>
126 </modifs>
127 </pkaphpidata>
128 \endcode
129 */
130
131
132 /*!
133 \variable MsXpS::libXpertMass::PkaPhPiDataParser::mcsp_polChemDef
134
135 \brief The polymer chemistry definition.
136 */
137
138 /*!
139 \variable MsXpS::libXpertMass::PkaPhPiDataParser::m_filePath
140
141 \brief The path the file that contains all the specifications for chemical
142 groups and chemical rules.
143 */
144
145 /*!
146 \brief Constructs a PkaPhPiDataParser instance.
147
148 \list
149 \li \a pol_chem_def_csp: The polymer chemistry definition (cannot be nullptr).
150 \li \a file_path: the specification file path.
151 \endlist
152 */
153 PkaPhPiDataParser::PkaPhPiDataParser(
154 const libXpertMass::PolChemDefCstSPtr pol_chem_def_csp, QString file_path)
155 : mcsp_polChemDef(pol_chem_def_csp), m_filePath(file_path)
156 {
157 Q_ASSERT(mcsp_polChemDef);
158 }
159
160 /*!
161 \brief Destructs this PkaPhPiDataParser instance
162 */
163 PkaPhPiDataParser::~PkaPhPiDataParser()
164 {
165 }
166
167 /*!
168 \brief Sets the \a file_path.
169 */
170 void
171 PkaPhPiDataParser::setFilePath(const QString &file_path)
172 {
173 m_filePath = file_path;
174 }
175
176 /*!
177 \brief Returns the file path.
178 */
179 const QString &
180 PkaPhPiDataParser::filePath()
181 {
182 return m_filePath;
183 }
184
185 /*!
186 \brief Parses the file and fills-in the
187
188 \a monomer_list_p: the list of \l Monomer instances documented in the file.
189 \a modif_list_p: the list of \l Modif instances documented in the file.
190
191 Returns true upon success, false otherwise.
192 */
193 bool
194 PkaPhPiDataParser::renderXmlFile(QList<libXpertMass::Monomer *> *monomer_list_p,
195 QList<libXpertMass::Modif *> *modif_list_p)
196 {
197 Q_ASSERT(monomer_list_p);
198 Q_ASSERT(modif_list_p);
199
200 // <pkaphpidata>
201 // <monomers>
202 // <monomer>
203 // <code>A</code>
204 // <mnmchemgroup>
205 // <name>N-term NH2</name>
206 // <pka>9.6</pka>
207 // <acidcharged>TRUE</acidcharged>
208 // <polrule>left_trapped</polrule>
209 // <chemgrouprule>
210 // <entity>LE_PLM_MODIF</entity>
211 // <name>Acetylation</name>
212 // <outcome>LOST</outcome>
213 // </chemgrouprule>
214 // </mnmchemgroup>
215 // <mnmchemgroup>
216 // <name>C-term COOH</name>
217 // <pka>2.35</pka>
218 // <acidcharged>FALSE</acidcharged>
219 // <polrule>right_trapped</polrule>
220 // </mnmchemgroup>
221 // </monomer>
222 // [...]
223 // <monomer>
224 // <code>C</code>
225 // <mnmchemgroup>
226 // <name>N-term NH2</name>
227 // <pka>9.6</pka>
228 // <acidcharged>TRUE</acidcharged>
229 // <polrule>left_trapped</polrule>
230 // <chemgrouprule>
231 // <entity>LE_PLM_MODIF</entity>
232 // <name>Acetylation</name>
233 // <outcome>LOST</outcome>
234 // </chemgrouprule>
235 // </mnmchemgroup>
236 // <mnmchemgroup>
237 // <name>C-term COOH</name>
238 // <pka>2.35</pka>
239 // <acidcharged>FALSE</acidcharged>
240 // <polrule>right_trapped</polrule>
241 // </mnmchemgroup>
242 // <mnmchemgroup>
243 // <name>Lateral SH2</name>
244 // <pka>8.3</pka>
245 // <acidcharged>FALSE</acidcharged>
246 // <polrule>never_trapped</polrule>
247 // </mnmchemgroup>
248 // </monomer>
249 // </monomers>
250 // <modifs>
251 // <modif>
252 // <name>Phosphorylation</name>
253 // <mdfchemgroup>
254 // <name>none_set</name>
255 // <pka>1.2</pka>
256 // <acidcharged>FALSE</acidcharged>
257 // </mdfchemgroup>
258 // <mdfchemgroup>
259 // <name>none_set</name>
260 // <pka>6.5</pka>
261 // <acidcharged>FALSE</acidcharged>
262 // </mdfchemgroup>
263 // </modif>
264 // </modifs>
265 // </pkaphpidata>
266 //
267 // The DTD stipulates that:
268 //
269 // <!ELEMENT pkaphpidata(monomers,modifs*)>
270 // <!ELEMENT monomers(monomer*)>
271 // <!ELEMENT modifs(modif*)>
272 // <!ELEMENT monomer(code,mnmchemgroup*)>
273 // <!ELEMENT modif(name,mdfchemgroup*)>
274
275 QDomDocument doc("pkaPhPiData");
276 QDomElement element;
277 QDomElement child;
278 QDomElement indentedChild;
279
280 QFile file(m_filePath);
281
282 if(!file.open(QIODevice::ReadOnly))
283 return false;
284
285 if(!doc.setContent(&file))
286 {
287 file.close();
288 return false;
289 }
290
291 file.close();
292
293 element = doc.documentElement();
294
295 if(element.tagName() != "pkaphpidata")
296 {
297 qDebug() << __FILE__ << __LINE__ << "pKa-pH-pI data file is erroneous\n";
298 return false;
299 }
300
301 // The first child element must be <monomers>.
302
303 child = element.firstChildElement();
304 if(child.tagName() != "monomers")
305 {
306 qDebug() << __FILE__ << __LINE__ << "pKa-pH-pI data file is erroneous\n";
307 return false;
308 }
309
310 // Parse the <monomer> elements.
311
312 indentedChild = child.firstChildElement();
313 while(!indentedChild.isNull())
314 {
315 if(indentedChild.tagName() != "monomer")
316 return false;
317
318 QDomElement superIndentedElement = indentedChild.firstChildElement();
319
320 if(superIndentedElement.tagName() != "code")
321 return false;
322
323 libXpertMass::Monomer *monomer = new libXpertMass::Monomer(
324 mcsp_polChemDef, "NOT_SET", superIndentedElement.text());
325
326 // All the <mnmchemgroup> elements, if any.
327
328 superIndentedElement = superIndentedElement.nextSiblingElement();
329 while(!superIndentedElement.isNull())
330 {
331 if(superIndentedElement.tagName() != "mnmchemgroup")
332 {
333 delete monomer;
334 return false;
335 }
336
337 libXpertMass::ChemicalGroup *chemGroup =
338 new libXpertMass::ChemicalGroup("NOT_SET");
339
340 if(!chemGroup->renderXmlMnmElement(superIndentedElement))
341 {
342 delete monomer;
343 delete chemGroup;
344 return false;
345 }
346
347 libXpertMass::ChemicalGroupProp *prop =
348 new libXpertMass::ChemicalGroupProp("CHEMICAL_GROUP", chemGroup);
349
350 monomer->appendProp(prop);
351
352 superIndentedElement = superIndentedElement.nextSiblingElement();
353 }
354
355 monomer_list_p->append(monomer);
356
357 indentedChild = indentedChild.nextSiblingElement();
358 }
359
360 #if 0
361
362 qDebug() << __FILE__ << __LINE__
363 << "Debug output of all the monomers parsed:";
364
365 for (int iter = 0; iter < monomerList->size(); ++iter)
366 {
367 Monomer *monomer = monomerList->at(iter);
368 qDebug() << __FILE__ << __LINE__
369 << "Monomer:" << monomer->name();
370
371 for(int jter = 0; jter < monomer->propList()->size(); ++jter)
372 {
373 libXpertMass::Prop *prop = monomer->propList()->at(jter);
374
375 if (prop->name() == "CHEMICAL_GROUP")
376 {
377 const libXpertMass::ChemicalGroup *chemGroup =
378 static_cast<const libXpertMass::ChemicalGroup *>(prop->data());
379
380 qDebug() << __FILE__ << __LINE__
381 << "Chemical group:"
382 << chemGroup->name() << chemGroup->pka();
383 }
384 }
385 }
386
387 #endif
388
389 // And now parse the <modifs> elements, if any, this time, as
390 // this element is not compulsory.
391
392 child = child.nextSiblingElement();
393 if(child.isNull())
394 return true;
395
396 if(child.tagName() != "modifs")
397 {
398 qDebug() << __FILE__ << __LINE__ << "pKa-pH-pI data file is erroneous\n";
399 return false;
400 }
401
402 // Parse the <modif> elements.
403
404 indentedChild = child.firstChildElement();
405 while(!indentedChild.isNull())
406 {
407 if(indentedChild.tagName() != "modif")
408 return false;
409
410 QDomElement superIndentedElement = indentedChild.firstChildElement();
411
412 if(superIndentedElement.tagName() != "name")
413 return false;
414
415 libXpertMass::Modif *modif =
416 new libXpertMass::Modif(mcsp_polChemDef, superIndentedElement.text(), "H0");
417
418 // All the <mdfchemgroup> elements, if any.
419
420 superIndentedElement = superIndentedElement.nextSiblingElement();
421 while(!superIndentedElement.isNull())
422 {
423 if(superIndentedElement.tagName() != "mdfchemgroup")
424 {
425 delete modif;
426 return false;
427 }
428
429 libXpertMass::ChemicalGroup *chemGroup =
430 new libXpertMass::ChemicalGroup("NOT_SET");
431
432 if(!chemGroup->renderXmlMdfElement(superIndentedElement))
433 {
434 delete modif;
435 delete chemGroup;
436 return false;
437 }
438
439 libXpertMass::ChemicalGroupProp *prop =
440 new libXpertMass::ChemicalGroupProp("CHEMICAL_GROUP", chemGroup);
441
442 modif->appendProp(prop);
443
444 superIndentedElement = superIndentedElement.nextSiblingElement();
445 }
446
447 modif_list_p->append(modif);
448
449 indentedChild = indentedChild.nextSiblingElement();
450 }
451
452 #if 0
453
454 qDebug() << __FILE__ << __LINE__
455 << "Debug output of all the modifs parsed:";
456
457 for (int iter = 0; iter < modifList->size(); ++iter)
458 {
459 Modif *modif = modifList->at(iter);
460
461 // qDebug() << __FILE__ << __LINE__
462 // << "Modif:" << modif->name();
463
464 for(int jter = 0; jter < modif->propList()->size(); ++jter)
465 {
466 libXpertMass::Prop *prop = modif->propList()->at(jter);
467
468 if (prop->name() == "CHEMICAL_GROUP")
469 {
470 const libXpertMass::ChemicalGroup *chemGroup =
471 static_cast<const libXpertMass::ChemicalGroup *>(prop->data());
472
473 qDebug() << __FILE__ << __LINE__
474 << "Chemical group:"
475 << chemGroup->name() << chemGroup->pka();
476 }
477 }
478 }
479
480 #endif
481
482 return true;
483 }
484
485 } // namespace libXpertMass
486
487 } // namespace MsXpS
488