GCC Code Coverage Report


./
File: src/XpertMass/FragSpec.cpp
Date: 2024-08-24 11:26:06
Lines:
101/213
47.4%
Functions:
8/22
36.4%
Branches:
126/346
36.4%

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 "FragSpec.hpp"
36 #include "PolChemDef.hpp"
37
38
39 namespace MsXpS
40 {
41
42 namespace libXpertMass
43 {
44
45
46 /*!
47 \class MsXpS::libXpertMass::FragSpec
48 \inmodule libXpertMass
49 \ingroup PolChemDefGasPhaseChemicalReactions
50 \inheaderfile FragSpec.hpp
51
52 \brief The FragSpec class provides a model for specifying gas phase
53 fragmentations of \l{Oligomer} \l{Sequence}s.
54
55 The FragSpec class provides a fragmentation specification. Fragmentation
56 specifications determine the chemical reaction that governs the fragmentation
57 of the polymer in the gas-phase. The chemical reaction is embodied by a
58 formula. The side of the polymer (left or right) that makes the fragment after
59 the fragmentation has occurred is described by a fragmentation-end enumeration.
60
61 A fragmentation specification might not be enough information to determine the
62 manner in which a polymer fragments in the gas-phase. Fragmentation rules
63 (\l{FragRule}s) might be required to refine the specification. A fragmentation
64 specification might hold as many \l{FragRule}s as required.
65 */
66
67 /*!
68 \enum MsXpS::libXpertMass::FragEnd
69
70 This enum specifies the end of the \l Oligomer that will be contained in the
71 fragment resulting from its fragmentation. In protein chemistry, for example,
72 a,b and x fragments are N-terminal fragments, that is, they contain the left
73 end of the framgented Oligomer's sequence.
74
75 \value FRAG_END_NONE
76 The value is not set.
77 \value FRAG_END_LEFT
78 The generated fragment contains the left end of the oligomer
79 \value FRAG_END_RIGHT
80 The generated fragment contains the right end of the oligomer
81 \value FRAG_END_BOTH
82 The generated fragment contains both the left and the right end of the
83 oligomer (that is, is all the oligomer)
84 */
85
86
87 /*!
88 \brief Constructs a FragSpec instance.
89
90 \a pol_chem_def_csp Polymer chemistry definition. Cannot be nullptr.
91
92 \a name Name. Cannot be empty.
93
94 \a formula Formula. Defaults to the null string.
95
96 \a frag_end Fragmentation end. Defaults to FRAG_END_NONE.
97
98 \a comment Comment. Defaults to the null string.
99 */
100 2744 FragSpec::FragSpec(PolChemDefCstSPtr pol_chem_def_csp,
101 QString name,
102 QString formula,
103 FragEnd frag_end,
104 2744 const QString &comment)
105 : PolChemDefEntity(pol_chem_def_csp, name),
106 Formula(formula),
107 2744 m_fragEnd(frag_end),
108
2/4
✓ Branch 2 taken 2744 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2744 times.
✗ Branch 7 not taken.
2744 m_comment(comment)
109 {
110 2744 m_fragEnd = FRAG_END_NONE;
111
112 2744 m_monomerContribution = 0;
113 2744 }
114
115
116 /*!
117 \brief Constructs a fragmentation specification.
118
119 \a pol_chem_def_csp Polymer chemistry definition. Cannot be nullptr.
120
121 \a name Name. Cannot be empty.
122
123 \a formula Formula.
124 */
125 FragSpec::FragSpec(PolChemDefCstSPtr pol_chem_def_csp,
126 QString name,
127 QString formula)
128 : PolChemDefEntity(pol_chem_def_csp, name), Formula(formula)
129 {
130 m_fragEnd = FRAG_END_NONE;
131
132 m_monomerContribution = 0;
133 }
134
135
136 /*!
137 \brief Constructs a FragSpec instance as a copy of \a other.
138 */
139 FragSpec::FragSpec(const FragSpec &other)
140 : PolChemDefEntity(other),
141 Formula(other),
142 m_fragEnd(other.m_fragEnd),
143 m_monomerContribution(other.m_monomerContribution),
144 m_comment(other.m_comment)
145 {
146 for(int iter = 0; iter < other.m_ruleList.size(); ++iter)
147 {
148 FragRule *fragRule = new FragRule(*other.m_ruleList.at(iter));
149 m_ruleList.append(fragRule);
150 }
151 }
152
153
154 /*!
155 \brief Destroys this FragSpec instance.
156 */
157 FragSpec::~FragSpec()
158 {
159 while(!m_ruleList.isEmpty())
160 delete m_ruleList.takeFirst();
161 }
162
163
164 /*!
165 \brief Assigns \a other to this FragSpec instance.
166
167 Returns a reference to this FragSpec.
168 */
169 FragSpec &
170 FragSpec::operator=(const FragSpec &other)
171 {
172 if(&other == this)
173 return *this;
174
175 PolChemDefEntity::operator=(other);
176 Formula::operator=(other);
177
178 m_fragEnd = other.m_fragEnd;
179 m_monomerContribution = other.m_monomerContribution;
180 m_comment = other.m_comment;
181
182 while(!m_ruleList.isEmpty())
183 delete m_ruleList.takeFirst();
184
185 for(int iter = 0; iter < other.m_ruleList.size(); ++iter)
186 {
187 FragRule *fragRule = new FragRule(*other.m_ruleList.at(iter));
188 m_ruleList.append(fragRule);
189 }
190
191 return *this;
192 }
193
194
195 /*!
196 \brief Returns true if \c this and \a other are identical.
197 */
198 bool
199 FragSpec::operator==(const FragSpec &other) const
200 {
201 if(&other == this)
202 return true;
203
204 if(m_fragEnd != other.m_fragEnd)
205 return false;
206 if(m_monomerContribution != other.m_monomerContribution)
207 return false;
208 if(m_comment != other.m_comment)
209 return false;
210
211 if(m_ruleList.size() != other.m_ruleList.size())
212 return false;
213
214 for(int iter = 0; iter < m_ruleList.size(); ++iter)
215 {
216 if(m_ruleList.at(iter) != other.m_ruleList.at(iter))
217 return false;
218 }
219
220 return true;
221 }
222
223 /*!
224 \brief Returns true if \c this and \a other are different.
225 */
226 bool
227 FragSpec::operator!=(const FragSpec &other) const
228 {
229 if(&other == this)
230 return false;
231
232 return !operator==(other);
233 }
234
235 /*!
236 \brief Returns the list of FragRule instances.
237 */
238 QList<FragRule *> &
239 FragSpec::ruleList()
240 {
241 return m_ruleList;
242 }
243
244
245 /*!
246 \brief Adds the \a frag_rule FragRule instance to the member list of FragRule
247 instances.
248 */
249 void
250 FragSpec::appendRule(FragRule *frag_rule)
251 {
252 Q_ASSERT(frag_rule);
253
254 m_ruleList.append(frag_rule);
255 }
256
257
258 /*!
259 \brief Inserts in the member list of FragRule instances at \a index the \a
260 frag_rule FragRule instance.
261 */
262 void
263 FragSpec::insertRuleAt(int index, FragRule *frag_rule)
264 {
265 Q_ASSERT(frag_rule);
266
267 m_ruleList.insert(index, frag_rule);
268 }
269
270
271 /*!
272 \brief Removes from the member list of FragRule instances the item at index \a
273 index.
274 */
275 void
276 FragSpec::removeRuleAt(int index)
277 {
278 m_ruleList.removeAt(index);
279 }
280
281
282 /*!
283 \brief Sets the fragmentation end to \a frag_end.
284 */
285 void
286 FragSpec::setFragEnd(FragEnd frag_end)
287 {
288 m_fragEnd = frag_end;
289 }
290
291
292 /*!
293 \brief Returns the fragmentation end.
294 */
295 FragEnd
296 8 FragSpec::fragEnd() const
297 {
298 8 return m_fragEnd;
299 }
300
301
302 void
303 FragSpec::setMonomerContribution(int value)
304 {
305 m_monomerContribution = value;
306 }
307
308
309 int
310 8 FragSpec::monomerContribution()
311 {
312 8 return m_monomerContribution;
313 }
314
315
316 /*!
317 \brief Returns the \l Formula as a string.
318 */
319 QString
320 8 FragSpec::formula() const
321 {
322 8 return Formula::toString();
323 }
324
325
326 /*!
327 \brief Sets the \a comment.
328 */
329 void
330 FragSpec::setComment(const QString &comment)
331 {
332 m_comment = comment;
333 }
334
335
336 /*!
337 \brief Returns the comment.
338 */
339 QString
340 8 FragSpec::comment() const
341 {
342 8 return m_comment;
343 }
344
345
346 /*!
347 \brief Searches by \a name for a FragSpec in the \a frag_spec_list.
348
349 If such fragmentation specification is found, and if \a other is non-0, the
350 found fragmentation specification's data are copied into \a other.
351
352 Returns the index of the found FragSpec instance or -1 if none is found or if
353 \a name is empty.
354 */
355 int
356 FragSpec::isNameInList(const QString &name,
357 const QList<FragSpec *> &frag_spec_list,
358 FragSpec *other)
359 {
360 FragSpec *fragSpec = 0;
361
362 if(name.isEmpty())
363 return -1;
364
365 for(int iter = 0; iter < frag_spec_list.size(); ++iter)
366 {
367 fragSpec = frag_spec_list.at(iter);
368 Q_ASSERT(fragSpec);
369
370 if(fragSpec->m_name == name)
371 {
372 if(other)
373 *other = *fragSpec;
374
375 return iter;
376 }
377 }
378
379 return -1;
380 }
381
382
383 /*!
384 \brief Validates the FragSpec.
385
386 The validation involves checking that:
387
388 \list
389 \li The name is not empty.
390 \li The fragmentation end must have been set.
391 \li The FragRule instances (if any) are valid.
392 \li The Formula is valid.
393 \endlist
394
395 Returns true upon success, false otherwise.
396 */
397 bool
398 2744 FragSpec::validate()
399 {
400 IsotopicDataCstSPtr isotopic_data_csp =
401
1/2
✓ Branch 2 taken 2744 times.
✗ Branch 3 not taken.
2744 mcsp_polChemDef->getIsotopicDataCstSPtr();
402
403
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2744 times.
2744 if(m_name.isEmpty())
404 return false;
405
406
4/4
✓ Branch 0 taken 2352 times.
✓ Branch 1 taken 392 times.
✓ Branch 2 taken 1176 times.
✓ Branch 3 taken 1176 times.
2744 if(m_fragEnd != FRAG_END_NONE && m_fragEnd != FRAG_END_LEFT &&
407
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1176 times.
1176 m_fragEnd != FRAG_END_RIGHT)
408 return false;
409
410
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2744 times.
2744 for(int iter = 0; iter < m_ruleList.size(); ++iter)
411 {
412 if(!m_ruleList.at(iter)->validate())
413 return false;
414 }
415
416
1/2
✓ Branch 2 taken 2744 times.
✗ Branch 3 not taken.
2744 return Formula::validate(isotopic_data_csp);
417 2744 }
418
419
420 /*!
421 \brief Parses a fragmentation specification XML \a element using a
422 \a{version}ed function.
423
424 Upon parsing and validation of the parsed data, the member data are updated,
425 thus essentially initializing this FragSpec instance.
426
427 Returns true if parsing and formula validation were successful, false otherwise.
428 */
429 bool
430 2744 FragSpec::renderXmlFgsElement(const QDomElement &element, int version)
431 {
432
1/2
✓ Branch 0 taken 2744 times.
✗ Branch 1 not taken.
2744 if(version == 1)
433 {
434 // no-op
435
436 2744 version = 1;
437 }
438
439
1/2
✓ Branch 1 taken 2744 times.
✗ Branch 2 not taken.
2744 QDomElement child;
440
1/2
✓ Branch 1 taken 2744 times.
✗ Branch 2 not taken.
2744 QDomElement childRule;
441
442 2744 FragRule *fragRule = 0;
443
444 2744 bool commentParsed = false;
445
446 /* The xml node we are in is structured this way:
447 *
448 * <fgs>
449 * <name>a</name>
450 * <end>LE</end>
451 * <formula>-C1O1</formula>
452 * <comment>opt_comment</comment>
453 * <fgr>
454 * <name>one_rule</name>
455 * <formula>+H2O</formula>
456 * <prev-mnm-code>M</prev-mnm-code>
457 * <this-mnm-code>Y</this-mnm-code>
458 * <next-mnm-code>T</next-mnm-code>
459 * <comment>opt_comment</comment>
460 * </fgr>
461 * other fgr allowed, none possible also
462 * </fgs>
463 *
464 * And the element parameter points to the
465 *
466 * <fgs> element tag:
467 * ^
468 * |
469 * +----- here we are right now.
470 *
471 * Which means that element.tagName() == "fgs" and that
472 * we'll have to go one step down to the first child of the
473 * current node in order to get to the <name> element.
474 *
475 * The DTD says this:
476 * <!ELEMENT fgs(name,end,formula,comment?,fgr*)>
477 */
478
479
2/4
✓ Branch 1 taken 2744 times.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2744 times.
2744 if(element.tagName() != "fgs")
480 return false;
481
482
3/6
✓ Branch 2 taken 2744 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2744 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2744 times.
✗ Branch 9 not taken.
2744 child = element.firstChildElement("name");
483
484
2/4
✓ Branch 1 taken 2744 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2744 times.
2744 if(child.isNull())
485 return false;
486
487
1/2
✓ Branch 1 taken 2744 times.
✗ Branch 2 not taken.
2744 m_name = child.text();
488
489
2/4
✓ Branch 3 taken 2744 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2744 times.
✗ Branch 7 not taken.
2744 child = child.nextSiblingElement();
490
491
6/14
✓ Branch 1 taken 2744 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2744 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2744 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 2744 times.
✓ Branch 11 taken 2744 times.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 2744 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2744 if(child.isNull() || child.tagName() != "end")
492 return false;
493
494
3/4
✓ Branch 1 taken 2744 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 392 times.
✓ Branch 6 taken 2352 times.
2744 if(child.text() == "NE")
495 392 m_fragEnd = FRAG_END_NONE;
496
3/4
✓ Branch 1 taken 2352 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1176 times.
✓ Branch 6 taken 1176 times.
2352 else if(child.text() == "LE")
497 1176 m_fragEnd = FRAG_END_LEFT;
498
2/4
✓ Branch 1 taken 1176 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1176 times.
✗ Branch 6 not taken.
1176 else if(child.text() == "RE")
499 1176 m_fragEnd = FRAG_END_RIGHT;
500 else if(child.text() == "BE")
501 m_fragEnd = FRAG_END_BOTH;
502 else
503 return false;
504
505
2/4
✓ Branch 3 taken 2744 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2744 times.
✗ Branch 7 not taken.
2744 child = child.nextSiblingElement();
506
507
6/14
✓ Branch 1 taken 2744 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2744 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2744 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 2744 times.
✓ Branch 11 taken 2744 times.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 2744 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2744 if(child.isNull() || child.tagName() != "formula")
508 return false;
509
510
2/4
✓ Branch 1 taken 2744 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2744 times.
2744 if(!Formula::renderXmlFormulaElement(child))
511 return false;
512
513 // The next element must be <sidechaincontrib>
514
2/4
✓ Branch 3 taken 2744 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2744 times.
✗ Branch 7 not taken.
2744 child = child.nextSiblingElement();
515
516
2/4
✓ Branch 1 taken 2744 times.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2744 times.
2744 if(child.tagName() != "sidechaincontrib")
517 return false;
518
519
1/2
✓ Branch 1 taken 2744 times.
✗ Branch 2 not taken.
2744 QString text = child.text();
520
521 2744 bool ok = false;
522
523
1/2
✓ Branch 1 taken 2744 times.
✗ Branch 2 not taken.
2744 m_monomerContribution = text.toInt(&ok);
524
525
2/4
✓ Branch 0 taken 2744 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2744 times.
2744 if(!m_monomerContribution && !ok)
526 return false;
527
528 // The next element might be either comment or(none, one or more)
529 // fgr.
530
2/4
✓ Branch 3 taken 2744 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2744 times.
✗ Branch 7 not taken.
2744 child = child.nextSiblingElement();
531
532
3/4
✓ Branch 1 taken 3528 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 784 times.
✓ Branch 4 taken 2744 times.
3528 while(!child.isNull())
533 {
534 // Is it a comment or the first of one|more <fgr> elements ?
535 // Remember: <!ELEMENT fgs(name,end,formula,comment?,fgr*)>
536
537
2/4
✓ Branch 1 taken 784 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 784 times.
✗ Branch 6 not taken.
784 if(child.tagName() == "comment")
538 {
539
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 784 times.
784 if(commentParsed)
540 return false;
541
542
1/2
✓ Branch 1 taken 784 times.
✗ Branch 2 not taken.
784 m_comment = child.text();
543 784 commentParsed = true;
544
545
2/4
✓ Branch 3 taken 784 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 784 times.
✗ Branch 7 not taken.
784 child = child.nextSiblingElement();
546 784 continue;
547 }
548
549 // At this point, yes, if there is still a sibling, then it
550 // has to be one <fgr>, either alone or the first of multiple.
551
552 while(!child.isNull())
553 {
554 fragRule = new FragRule(mcsp_polChemDef, "NOT_SET");
555
556 if(!fragRule->renderXmlFgrElement(child))
557 {
558 delete fragRule;
559 return false;
560 }
561 else
562 m_ruleList.append(fragRule);
563
564 child = child.nextSiblingElement();
565 }
566 }
567
568
2/4
✓ Branch 1 taken 2744 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2744 times.
2744 if(!validate())
569 return false;
570
571 2744 return true;
572 2744 }
573
574
575 /*!
576 \brief Formats a string representing this FragSpec instance suitable to use as
577 an XML element.
578
579 The typical fragmentation
580 specification element that is generated in this function looks like
581 this:
582
583 \code
584 <fgs>
585 <name>a</name>
586 <end>LE</end>
587 <formula>-C1O1</formula>
588 <fgr>
589 <name>a-fgr-1</name>
590 <formula>+H200</formula>
591 <prev-mnm-code>E</prev-mnm-code>
592 <curr-mnm-code>D</curr-mnm-code>
593 <next-mnm-code>F</next-mnm-code>
594 <comment>comment here!</comment>
595 </fgr>
596 <fgr>
597 <name>a-fgr-2</name>
598 <formula>+H100</formula>
599 <prev-mnm-code>F</prev-mnm-code>
600 <curr-mnm-code>D</curr-mnm-code>
601 <next-mnm-code>E</next-mnm-code>
602 <comment>comment here!</comment>
603 </fgr>
604 </fgs>
605 \endcode
606
607 The formatting of the XML element takes into account \a offset and \a
608 indent by prepending the string with \a offset * \a indent character substring.
609
610 \a indent defaults to two spaces.
611
612 Returns a dynamically allocated string that needs to be freed after use.
613 */
614 QString *
615 28 FragSpec::formatXmlFgsElement(int offset, const QString &indent)
616 {
617
618 int newOffset;
619 28 int iter = 0;
620
621
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 QString lead("");
622
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 QString *string = new QString();
623
624
625 // Prepare the lead.
626 28 newOffset = offset;
627
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 28 times.
112 while(iter < newOffset)
628 {
629
1/2
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
84 lead += indent;
630 84 ++iter;
631 }
632
633
3/6
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 28 times.
✗ Branch 8 not taken.
56 *string += QString("%1<fgs>\n").arg(lead);
634
635 // Prepare the lead.
636 28 ++newOffset;
637 28 lead.clear();
638 28 iter = 0;
639
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 28 times.
140 while(iter < newOffset)
640 {
641
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 lead += indent;
642 112 ++iter;
643 }
644
645 // Continue with indented elements.
646
647
4/8
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 28 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 28 times.
✗ Branch 11 not taken.
84 *string += QString("%1<name>%2</name>\n").arg(lead).arg(m_name);
648
649
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 24 times.
28 if(m_fragEnd == FRAG_END_NONE)
650
5/10
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
12 *string += QString("%1<end>%2</end>\n").arg(lead).arg("NE");
651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 else if(m_fragEnd == FRAG_END_BOTH)
652 *string += QString("%1<end>%2</end>\n").arg(lead).arg("BE");
653
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 else if(m_fragEnd == FRAG_END_LEFT)
654
5/10
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
36 *string += QString("%1<end>%2</end>\n").arg(lead).arg("LE");
655
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 else if(m_fragEnd == FRAG_END_RIGHT)
656
5/10
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
36 *string += QString("%1<end>%2</end>\n").arg(lead).arg("RE");
657
658
4/8
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 28 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 28 times.
✗ Branch 11 not taken.
84 *string += QString("%1<formula>%2</formula>\n").arg(lead).arg(m_formula);
659
660
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 *string += QString("%1<sidechaincontrib>%2</sidechaincontrib>\n")
661
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
56 .arg(lead)
662
2/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
28 .arg(m_monomerContribution);
663
664
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 20 times.
28 if(!m_comment.isEmpty())
665
4/8
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
24 *string += QString("%1<comment>%2</comment>\n").arg(lead).arg(m_comment);
666
667
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 for(int iter = 0; iter < m_ruleList.size(); ++iter)
668 {
669 QString *ruleString = m_ruleList.at(iter)->formatXmlFgrElement(newOffset);
670
671 *string += *ruleString;
672
673 delete ruleString;
674 }
675
676 // Prepare the lead.
677 28 --newOffset;
678 28 lead.clear();
679 28 iter = 0;
680
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 28 times.
112 while(iter < newOffset)
681 {
682
1/2
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
84 lead += indent;
683 84 ++iter;
684 }
685
686
3/6
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 28 times.
✗ Branch 8 not taken.
56 *string += QString("%1</fgs>\n").arg(lead);
687
688 28 return string;
689 28 }
690
691 } // namespace libXpertMass
692
693 } // namespace MsXpS
694