GCC Code Coverage Report


source/XpertMassCore/src/
File: source/XpertMassCore/src/FragmentationConfig.cpp
Date: 2025-11-20 01:41:33
Lines:
97/113
85.8%
Functions:
20/21
95.2%
Branches:
41/106
38.7%

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
34 /////////////////////// Local includes
35 #include "MsXpS/libXpertMassCore/FragmentationConfig.hpp"
36 #include "MsXpS/libXpertMassCore/PolChemDef.hpp"
37
38
39 namespace MsXpS
40 {
41 namespace libXpertMassCore
42 {
43
44
45 /*!
46 \class MsXpS::libXpertMassCore::FragmentationConfig
47 \inmodule libXpertMassCore
48 \ingroup PolChemDefGasPhaseChemicalReactions
49 \inheaderfile FragmentationConfig.hpp
50
51 \brief The FragmentationConfig class derives from FragmentationPathway and adds
52 functionality to configure the way the fragmentation occurs in the \l{Oligomer}
53 \l{Sequence}.
54
55 Since an Oligomer is actually defined to merely be a monomer range in a given
56 \l{Polymer} \l{Sequence}, the configuration handles the definition of the
57 Polymer sequence region that needs to undergo fragmentation.
58
59 Because the user might need to apply specific gas phase chemical reactions upon
60 fragmentation of the Oligomer that are not defined per se in the
61 FragmentationPathway, a container of formulas enables the application of any
62 number of such chemical reactions for each fragmentation event. This is useful
63 in any polymer chemistry definition, because most often the Oligomer undergoing
64 fragmentation has loss of neutral ions decompositions like \e{NH\sub{3}} or
65 \e{H\sub{2}O}.
66
67 The user might need to generate fragmentation ions that are of different
68 ionization levels. This class provides settings for this eventuality.
69
70 \sa FragmentationPathway
71 */
72
73
74 /*!
75 \variable MsXpS::libXpertMassCore::FragmentationConfig::m_startIndex
76
77 \brief The index that delimits the start position (index) of the Polymer
78 Sequence that defines the Oligomer undergoing fragmentation.
79 */
80
81 /*!
82 \variable MsXpS::libXpertMassCore::FragmentationConfig::m_stopIndex
83
84 \brief The index that delimits the stop position (index) of the Polymer Sequence
85 that defines the Oligomer undergoing fragmentation.
86 */
87
88 /*!
89 \variable MsXpS::libXpertMassCore::FragmentationConfig::m_startIonizeLevel
90
91 \brief The first value of the ionization level range.
92 */
93
94 /*!
95 \variable MsXpS::libXpertMassCore::FragmentationConfig::m_stopIonizeLevel
96
97 \brief The last value of the ionization level range.
98 */
99
100 /*!
101 \variable MsXpS::libXpertMassCore::FragmentationConfig::m_sequenceEmbedded
102
103 \brief Specifies if the sequence of the fragments needs to be stored or not in
104 the Oligomer fragments.
105 */
106
107 /*!
108 \variable MsXpS::libXpertMassCore::FragmentationConfig::m_formulas
109
110 \brief Container for Formula instances that describe additional decomposition
111 reactions like those often observed in protein gas phase chemistry (loss of
112 ammonia and/or of water).
113 */
114
115 /*!
116 \brief Constructs a fragmentation configuration with a number of parameters.
117
118 \list
119 \li \a pol_chem_def_csp Polymer chemistry definition that is passed to the FragmentationPathway base class. Cannot be nullptr (fatal error if so).
120
121 \li \a name Name that is passed to the FragmentationPathway base class. Cannot be empty.
122
123 \li \a formula Formula that is passed to the FragmentationPathway base class.
124
125 \li \a frag_end The end of the Oligomer undergoing fragmentation that is found in the product ions. Used to initialize the FragmentationPathway base class.
126
127 \li \a comment Comment that is passed to the FragmentationPathway base class. Defaults to the null string.
128
129 \li \a sequence_embedded Indicates if the product ion sequence needs to be stored in the fragment Oligomer.
130 \endlist
131
132 \sa FragmentationPathway
133 */
134 5 FragmentationConfig::FragmentationConfig(PolChemDefCstSPtr pol_chem_def_csp,
135 const QString &name,
136 const QString &formula,
137 Enums::FragEnd frag_end,
138 const QString &comment,
139 5 bool sequence_embedded)
140 : FragmentationPathway(pol_chem_def_csp, name, formula, frag_end, comment),
141
2/4
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5 times.
10 m_sequenceEmbedded(sequence_embedded)
142 {
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if(mcsp_polChemDef == nullptr || mcsp_polChemDef.get() == nullptr)
144 qFatalStream() << "Programming error. Pointer cannot be nullptr;";
145 5 }
146
147
148 /*!
149 \brief Constructs a fragmentation configuration with a number of parameters.
150
151 \list
152 \li \a fragmentation_pathway Fragmentation pathway that will become the base class instance of this instance.
153
154 \li \a start_index Start position (index) in the Polymer Sequence that delimits the Oligomer undergoing fragmentation.
155
156 \li \a stop_index Stop position (index) in the Polymer Sequence that delimits the Oligomer undergoing fragmentation.
157
158 \li \a sequence_embedded Indicates if the product ion sequence needs to be stored in the fragment Oligomer.
159 \endlist
160
161 The PolChemDef member of the FragmentationPathway base class is tested. If it is nullptr, that is a fatal error.
162
163 \sa FragmentationPathway
164 */
165 13 FragmentationConfig::FragmentationConfig(
166 const FragmentationPathway &fragmentation_pathway,
167 int start_index,
168 int stop_index,
169 13 bool sequence_embedded)
170 : FragmentationPathway(fragmentation_pathway),
171 13 m_startIndex(start_index),
172 13 m_stopIndex(stop_index),
173
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 m_sequenceEmbedded(sequence_embedded)
174 {
175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if(mcsp_polChemDef == nullptr || mcsp_polChemDef.get() == nullptr)
176 qFatalStream() << "Programming error. Pointer cannot be nullptr;";
177 13 }
178
179
180 /*!
181 \brief Constructs a fragmentation configuration as a copy of \a other.
182
183 The PolChemDef member of the FragmentationPathway base class is tested. If it is nullptr, that is a fatal error.
184
185 \sa FragmentationPathway
186 */
187 46 FragmentationConfig::FragmentationConfig(const FragmentationConfig &other)
188 : FragmentationPathway(other),
189 46 m_startIndex(other.m_startIndex),
190 46 m_stopIndex(other.m_stopIndex),
191 46 m_startIonizeLevel(other.m_startIonizeLevel),
192 46 m_stopIonizeLevel(other.m_stopIonizeLevel),
193 46 m_sequenceEmbedded(other.m_sequenceEmbedded),
194
1/2
✓ Branch 2 taken 46 times.
✗ Branch 3 not taken.
46 m_formulas(other.m_formulas)
195 {
196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if(mcsp_polChemDef == nullptr || mcsp_polChemDef.get() == nullptr)
197 qFatalStream() << "Programming error. Pointer cannot be nullptr;";
198 46 }
199
200
201 /*!
202 \brief Constructs this fragmentation configuration.
203 */
204 128 FragmentationConfig::~FragmentationConfig()
205 {
206
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 56 times.
128 m_formulas.clear();
207 128 }
208
209 /*!
210 \brief Assigns \a other to this FragmentationConfig instance.
211 */
212 FragmentationConfig &
213 1 FragmentationConfig::operator=(const FragmentationConfig &other)
214 {
215
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(&other == this)
216 return *this;
217
218 1 FragmentationPathway::operator=(other);
219
220 1 m_startIndex = other.m_startIndex;
221 1 m_stopIndex = other.m_stopIndex;
222
223 1 m_startIonizeLevel = other.m_startIonizeLevel;
224 1 m_stopIonizeLevel = other.m_stopIonizeLevel;
225
226 1 m_sequenceEmbedded = other.m_sequenceEmbedded;
227
228
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 for(const Formula &formula : other.m_formulas)
229 2 m_formulas.push_back(formula);
230
231 return *this;
232 }
233
234 /*!
235 \brief Sets the Oligomer start \a index in the Polymer Sequence.
236 */
237 void
238 2 FragmentationConfig::setStartIndex(std::size_t index)
239 {
240 2 m_startIndex = index;
241 2 }
242
243
244 /*!
245 \brief Returns the Oligomer start index in the Polymer Sequence.
246 */
247 std::size_t
248 400 FragmentationConfig::getStartIndex() const
249 {
250 400 return m_startIndex;
251 }
252
253
254 /*!
255 \brief Sets the Oligomer stop \a index in the Polymer Sequence.
256 */
257 void
258 2 FragmentationConfig::setStopIndex(std::size_t index)
259 {
260 2 m_stopIndex = index;
261 2 }
262
263
264 /*!
265 \brief Returns the Oligomer stop index in the Polymer Sequence.
266 */
267 std::size_t
268 411 FragmentationConfig::getStopIndex() const
269 {
270 411 return m_stopIndex;
271 }
272
273 /*!
274 \brief Sets the start \a value of the ionization range.
275 */
276 void
277 1 FragmentationConfig::setStartIonizeLevel(std::size_t value)
278 {
279
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(value <= m_stopIonizeLevel)
280 {
281 1 m_startIonizeLevel = value;
282 }
283 else
284 {
285 m_startIonizeLevel = m_stopIonizeLevel;
286 m_stopIonizeLevel = value;
287 }
288 1 }
289
290
291 /*!
292 \brief Returns the start value of the ionization range.
293 */
294 std::size_t
295 617 FragmentationConfig::getStartIonizeLevel() const
296 {
297 617 return m_startIonizeLevel;
298 }
299
300
301 /*!
302 \brief Sets the stop \a value of the ionization range.
303 */
304 void
305 1 FragmentationConfig::setStopIonizeLevel(std::size_t value)
306 {
307
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(value > m_startIonizeLevel)
308 {
309 1 m_stopIonizeLevel = value;
310 }
311 else
312 {
313 m_startIonizeLevel = m_stopIonizeLevel;
314 m_stopIonizeLevel = value;
315 }
316 1 }
317
318
319 /*!
320 \brief Returns the stop value of the ionization range.
321 */
322 std::size_t
323 286 FragmentationConfig::getStopIonizeLevel() const
324 {
325 286 return m_stopIonizeLevel;
326 }
327
328 /*!
329 \brief Sets the \a start and \a stop values of the ionization range.
330 */
331 void
332 13 FragmentationConfig::setIonizeLevels(std::size_t start, std::size_t stop)
333 {
334 13 m_startIonizeLevel = start;
335 13 m_stopIonizeLevel = stop;
336 13 }
337
338 /*!
339 \brief Adds a \a formula to the container of Formula instances.
340
341 Returns true if the formula validated successfully, false otherwise.
342 */
343 bool
344 6 FragmentationConfig::addFormula(const Formula &formula)
345 {
346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(mcsp_polChemDef == nullptr || mcsp_polChemDef.get() == nullptr)
347 qFatalStream() << "Programming error. Pointer cannot be nullptr;";
348
349 6 IsotopicDataCstSPtr isotopic_data_csp =
350 6 mcsp_polChemDef->getIsotopicDataCstSPtr();
351
352 6 ErrorList error_list;
353
354
3/6
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
12 if(!formula.validate(isotopic_data_csp, &error_list))
355 {
356 qCritical() << "Formula" << formula.getActionFormula()
357 << "failed to validate with errors:"
358 << Utils::joinErrorList(error_list);
359
360 return false;
361 }
362
363 // Check that the formula is not already in the list.
364
365 6 std::vector<Formula>::const_iterator the_iterator_cst =
366
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 std::find_if(m_formulas.cbegin(),
367 m_formulas.cend(),
368 3 [&formula](const Formula &iter_formula) {
369 3 return iter_formula == formula;
370 });
371
372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(the_iterator_cst != m_formulas.cend())
373 return false;
374
375 // At this point we can say that the formula is OK and can be
376 // added.
377
378
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 m_formulas.push_back(formula);
379
380 return true;
381
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 }
382
383 /*!
384 \brief Adds a Formula to the container of Formula instances using \a formula_string.
385 */
386 bool
387 2 FragmentationConfig::addFormula(const QString &formula_string)
388 {
389 // With the string make a true Formula instance.
390
391 2 Formula formula = Formula(formula_string);
392
393
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 return addFormula(formula);
394 2 }
395
396 /*!
397 \brief Returns a const reference to the container of Formula instances.
398 */
399 const std::vector<Formula> &
400 292 FragmentationConfig::getFormulasCstRef() const
401 {
402 292 return m_formulas;
403 }
404
405 /*!
406 \brief Returns a reference to the container of Formula instances.
407 */
408 std::vector<Formula> &
409 3 FragmentationConfig::getFormulasRef()
410 {
411 3 return m_formulas;
412 }
413
414 /*!
415 \brief Sets if the product ion Oligomer's sequence needs to be stored to \a value.
416 */
417 void
418 FragmentationConfig::setSequenceEmbedded(bool value)
419 {
420 m_sequenceEmbedded = value;
421 }
422
423
424 /*!
425 \brief Returns if the product ion Oligomer's sequence needs to be stored.
426 */
427 bool
428 3 FragmentationConfig::isSequenceEmbedded() const
429 {
430 3 return m_sequenceEmbedded;
431 }
432
433 /*!
434 \brief Returns a string describing this FragmentationConfig instance.
435 */
436 QString
437 1 FragmentationConfig::toString() const
438 {
439 1 QString text = "FragmentationConfig: \n";
440
441
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 text += FragmentationPathway::toString();
442
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 text += "\n";
443
444
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 text += QString("Indices [%1-%2] -- ionization levels [%3-%4].\n")
445
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 .arg(m_startIndex)
446
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 .arg(m_stopIndex)
447
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 .arg(m_startIonizeLevel)
448
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 .arg(m_stopIonizeLevel);
449
450
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(m_formulas.size())
451 {
452
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 text += "Formulas:\n";
453
454
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 for(const Formula &formula : m_formulas)
455
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
4 text += QString("%1 - \n").arg(formula.getActionFormula());
456 }
457
458 1 return text;
459 }
460
461
462 } // namespace libXpertMassCore
463 } // namespace MsXpS
464