GCC Code Coverage Report


source/XpertMassCore/src/
File: source/XpertMassCore/src/CalcOptions.cpp
Date: 2025-11-20 01:41:33
Lines:
118/131
90.1%
Functions:
27/29
93.1%
Branches:
52/114
45.6%

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 /////////////////////// Qt includes
35 #include <QChar>
36 #include <QDebug>
37 #include <QString>
38
39
40 /////////////////////// Local includes
41 #include "MsXpS/libXpertMassCore/CalcOptions.hpp"
42
43
44 int calcOptionsMetaTypeId =
45 qRegisterMetaType<MsXpS::libXpertMassCore::CalcOptions>(
46 "MsXpS::libXpertMassCore::CalcOptions");
47
48 namespace MsXpS
49 {
50 namespace libXpertMassCore
51 {
52
53
54 /*!
55 \class MsXpS::libXpertMassCore::CalcOptions
56 \inmodule libXpertMassCore
57 \ingroup XpertMassMassCoreCalculations
58 \inheaderfile CalcOptions.hpp
59
60 \brief The CalcOptions class provides the specifications that
61 configure the way masses are calculated for \l{Oligomer}s, \l{Polymer}s and
62 product ions.
63 */
64
65 /*!
66 \variable MsXpS::libXpertMassCore::CalcOptions::m_deepCalculation
67
68 \brief Tells if the calculations must involve the recalculation of all
69 the masses of the \l{Monomer}s in the sequence. This is typically needed when
70 calculating masses involving modified Monomer instances, whereby each Monomer
71 needs to recompute its mass taking into account the Modif instances attached to
72 it.
73 */
74
75 /*!
76 \variable MsXpS::libXpertMassCore::CalcOptions::m_massType
77
78 \brief The mass type to compute, monoisotopic or average.
79
80 \sa Enums::MassType
81 */
82
83 /*!
84 \variable MsXpS::libXpertMassCore::CalcOptions::m_capType
85
86 \brief The cap type, left or right (or both), to account for in the
87 calculations.
88
89 \sa Enums::CapType
90 */
91
92 /*!
93 \variable MsXpS::libXpertMassCore::CalcOptions::m_monomerEntities
94
95 \brief The \l Monomer entities to account for in the calculations.
96
97 \sa Enums::ChemicalEntity
98 */
99
100 /*!
101 \variable MsXpS::libXpertMassCore::CalcOptions::m_polymerEntities
102
103 \brief The \l Polymer entities to account for in the calculations.
104
105 \sa Enums::ChemicalEntity
106 */
107
108 /*!
109 \variable MsXpS::libXpertMassCore::CalcOptions::m_selectionType
110
111 \brief The manner the monomers need to be accounted for: as residual chains
112 or as finished-polymerization state sequences.
113
114 The calculations might consider only the residual chain. In that case, only
115 the mass of the monomers is considered and then the polymer is not in its
116 finished polymerization state. If that latter state is required, then, the
117 residual chain must be capped with both the left and the right end caps.
118
119 \sa MsXpS::libXpertMassCore::Enums::SelectionType
120 */
121
122 /*!
123 \variable MsXpS::libXpertMassCore::CalcOptions::mp_indexRangeCollection
124
125 \brief The IndexRangeCollection container that contains all the IndexRange
126 instances that describes what regions of the \l Polymer need to be accounted for
127 in the calculation. Most generally, there will be only one IndexRange, but there
128 might be situations in which multiple regions might be selected.
129 */
130
131
132 /*!
133 \brief Constructs an empty CalcOptions instance.
134 */
135 152 CalcOptions::CalcOptions(QObject *parent)
136
2/4
✓ Branch 2 taken 152 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 152 times.
✗ Branch 6 not taken.
152 : QObject(parent), mp_indexRangeCollection(new IndexRangeCollection(this))
137 {
138 152 }
139
140 /*!
141 \brief Constructs a CalcOptions instance.
142
143 All the members are initialized using the parameters:
144
145 \list
146 \li \a deepCalculation: m_deepCalculation (defaults to false)
147
148 \li \a mass_type: m_massType (defaults to Enums::MassType::BOTH)
149
150 \li \a capping: m_capType (defaults to Enums::CapType::BOTH)
151
152 \li \a monomer_entities The monomer entities to be accounted for in the
153 calculations (defaults to Enums::ChemicalEntity::NONE)
154
155 \li \a polymer_entities: The polymer entities to be accounted for in the
156 calculations (defaults to Enums::ChemicalEntity::NONE)
157 \endlist
158
159 The selection type is set by default to Oligomer (not residual chain).
160 */
161 64 CalcOptions::CalcOptions(bool deepCalculation,
162 Enums::MassType mass_type,
163 Enums::CapType capping,
164 Enums::ChemicalEntity monomer_entities,
165 Enums::ChemicalEntity polymer_entities,
166 64 QObject *parent)
167 : QObject(parent),
168 64 m_deepCalculation(deepCalculation),
169 64 m_massType(mass_type),
170 64 m_capType(capping),
171 64 m_monomerEntities(monomer_entities),
172 64 m_polymerEntities(polymer_entities),
173
2/4
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 64 times.
✗ Branch 6 not taken.
64 mp_indexRangeCollection(new IndexRangeCollection(this))
174 {
175 64 }
176
177 /*!
178 \brief Construct a CalcOptions instance as a copy of \a other.
179 */
180 3485 CalcOptions::CalcOptions(const CalcOptions &other, QObject *parent)
181 : QObject(parent),
182 3485 m_deepCalculation(other.m_deepCalculation),
183 3485 m_massType(other.m_massType),
184 3485 m_capType(other.m_capType),
185 3485 m_monomerEntities(other.m_monomerEntities),
186 3485 m_polymerEntities(other.m_polymerEntities),
187 3485 m_selectionType(other.m_selectionType),
188 3485 mp_indexRangeCollection(
189
2/4
✓ Branch 2 taken 3485 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3485 times.
✗ Branch 6 not taken.
3485 new IndexRangeCollection(*other.mp_indexRangeCollection, this))
190 {
191 3485 qDebug()
192 << "In pseudo copy constructor, other IndexRangeCollection indices as text:"
193 << other.getIndexRangeCollectionCstRef().indicesAsText();
194
195 // mp_indexRangeCollection = new IndexRangeCollection(this);
196 //
197 // foreach(const IndexRange *item,
198 // other.getIndexRangeCollectionCstRef().getRangesCstRef())
199 // mp_indexRangeCollection->appendIndexRange(*item);
200
201 3485 qDebug().noquote()
202 << "After pseudo copy constructor, with other calc options:"
203 << other.toString() << "\n this calc options:" << this->toString();
204 3485 }
205
206 /*!
207 \brief Returns a reference to this CalcOptions after having initialized it using
208 \a other.
209 */
210 CalcOptions &
211 22 CalcOptions::initialize(const CalcOptions &other)
212 {
213
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 if(this == &other)
214 return *this;
215
216 22 m_deepCalculation = other.m_deepCalculation;
217 22 m_massType = other.m_massType;
218 22 m_capType = other.m_capType;
219 22 m_monomerEntities = other.m_monomerEntities;
220 22 m_polymerEntities = other.m_polymerEntities;
221 22 m_selectionType = other.m_selectionType;
222
223 44 mp_indexRangeCollection->setIndexRanges(
224 22 other.mp_indexRangeCollection->getRangesCstRef());
225
226 22 return *this;
227 }
228
229 /*!
230 \brief Returns an newly allocated CalcOptions instance with parent set to \a
231 parent.
232 */
233 CalcOptions *
234 1 CalcOptions::clone(QObject *parent)
235 {
236
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 CalcOptions *copy_p = new CalcOptions(parent);
237 1 copy_p->initialize(*this);
238 1 return copy_p;
239 }
240
241 /*!
242 \ b*rief Returns an newly allocated CalcOptions instance initialized using \a
243 other and with parent set to \a parent.
244 */
245 CalcOptions *
246 1 CalcOptions::clone(const CalcOptions &other, QObject *parent)
247 {
248
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 CalcOptions *copy_p = new CalcOptions(parent);
249 1 copy_p->initialize(other);
250 1 return copy_p;
251 }
252
253 /*!
254 \brief Destructs this CalcOptions object.
255
256 Clear the member coordinateList.
257 */
258 7516 CalcOptions::~CalcOptions()
259 {
260 7516 }
261
262 /*!
263 \brief Sets to \a deep the configuration defining if the mass calculations must
264 involve the recalculation of the masses of all the monomers.
265
266 The deep calculation is typically requested when computing masses involving
267 Monomer instance that might be modified with Modif instances.
268
269 \sa m_deepCalculation
270 */
271 void
272 19 CalcOptions::setDeepCalculation(bool deep)
273 {
274 19 m_deepCalculation = deep;
275 19 }
276
277 /*!
278 \brief Returns if the calculation should be deep.
279
280 \sa m_deepCalculation
281 */
282 bool
283 18774 CalcOptions::isDeepCalculation() const
284 {
285 18774 return m_deepCalculation;
286 }
287
288 /*!
289 \brief Copies \a index_range to the member IndexRangeCollection instance.
290
291 \note The IndexRangeCollection instance is first emptied, making index_range
292 essentially replacing its contents with a copy of \a index_range.
293 */
294 void
295 799 CalcOptions::setIndexRange(const IndexRange &index_range)
296 {
297
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
799 mp_indexRangeCollection->setIndexRange(index_range);
298 799 }
299
300 /*!
301 \brief Creates an IndexRange instance with \a index_start and \a index_end and
302 sets it as the sole member of the member IndexRangeCollection instance.
303 */
304 void
305 743 CalcOptions::setIndexRange(qsizetype index_start, qsizetype index_end)
306 {
307
1/2
✓ Branch 2 taken 743 times.
✗ Branch 3 not taken.
743 setIndexRange(IndexRange(index_start, index_end));
308 743 }
309
310 /*!
311 \brief Allocates a copy of each IndexRange instance in the \a index_ranges
312 container and adds it to the member IndexRangeCollection instance.
313
314 \note The IndexRangeCollection instance is first emptied, essentially replacing
315 its contents with a copy of those in \a index_ranges.
316 */
317 void
318 8 CalcOptions::setIndexRanges(const IndexRangeCollection &index_ranges)
319 {
320 8 mp_indexRangeCollection->setIndexRanges(index_ranges);
321 8 }
322
323 /*!
324 \brief Returns a const reference to the member IndexRangeCollection instance.
325 */
326 const IndexRangeCollection &
327 5204 CalcOptions::getIndexRangeCollectionCstRef() const
328 {
329 5204 return *mp_indexRangeCollection;
330 }
331
332 /*!
333 \brief Returns a reference to the member IndexRangeCollection instance.
334 */
335 IndexRangeCollection &
336 80 CalcOptions::getIndexRangeCollectionRef()
337 {
338 80 return *mp_indexRangeCollection;
339 }
340
341 /*!
342 \brief Returns a reference to the member IndexRangeCollection instance.
343 */
344 IndexRangeCollection *
345 CalcOptions::getIndexRangeCollection()
346 {
347 return mp_indexRangeCollection;
348 }
349
350 /*!
351 \brief Sets the mass type to \a mass_type.
352
353 \sa m_massType
354 */
355 void
356 7 CalcOptions::setMassType(Enums::MassType mass_type)
357 {
358 7 m_massType = mass_type;
359 7 }
360
361 /*!
362 \brief Returns the mass type.
363
364 \sa m_massType
365 */
366 Enums::MassType
367 6 CalcOptions::getMassType() const
368 {
369 6 return m_massType;
370 }
371
372 /*!
373 \brief Set the selection type to \a selection_type.
374
375 \sa m_selectionType
376 */
377 void
378 7 CalcOptions::setSelectionType(Enums::SelectionType selection_type)
379 {
380 7 m_selectionType = selection_type;
381 7 }
382
383 /*!
384 \brief Returns the selection type.
385
386 \sa m_selectionType
387 */
388 Enums::SelectionType
389 1835 CalcOptions::getSelectionType() const
390 {
391 1835 return m_selectionType;
392 }
393
394 /*!
395 \brief Sets the cap type to \a cap_type.
396
397 \sa m_capType
398 */
399 void
400 218 CalcOptions::setCapType(Enums::CapType cap_type)
401 {
402 218 m_capType = cap_type;
403 218 }
404
405 /*!
406 \brief Returns the cap type.
407
408 \sa m_capType
409 */
410 Enums::CapType
411 1952 CalcOptions::getCapType() const
412 {
413 1952 return m_capType;
414 }
415
416 /*!
417 \brief Sets the monomer entities to \a monomer_chem_ent.
418
419 \sa m_monomerEntities
420 */
421 void
422 527 CalcOptions::setMonomerEntities(Enums::ChemicalEntity monomer_chem_ent)
423 {
424 527 m_monomerEntities = monomer_chem_ent;
425 527 }
426
427 /*!
428 \brief Returns the monomer entities.
429
430 \sa m_monomerEntities
431 */
432 Enums::ChemicalEntity
433 12134 CalcOptions::getMonomerEntities() const
434 {
435 12134 return m_monomerEntities;
436 }
437
438 /*!
439 \brief Sets the polymer entities to \a polymer_chem_ent.
440
441 \sa m_polymerEntities
442 */
443 void
444 10 CalcOptions::setPolymerEntities(Enums::ChemicalEntity polymer_chem_ent)
445 {
446 10 m_polymerEntities = polymer_chem_ent;
447 10 }
448
449 /*!
450 \brief Returns the polymer entities.
451
452 \sa m_polymerEntities
453 */
454 Enums::ChemicalEntity
455 2160 CalcOptions::getPolymerEntities() const
456 {
457 2160 return m_polymerEntities;
458 }
459
460 /*!
461 \brief Returns true if this instance is identical to \a other, false otherwise.
462 */
463 bool
464 5 CalcOptions::operator==(const CalcOptions &other) const
465 {
466
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if(m_deepCalculation != other.m_deepCalculation ||
467
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 m_massType != other.m_massType || m_capType != other.m_capType ||
468 m_monomerEntities != other.m_monomerEntities ||
469
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 m_polymerEntities != other.m_polymerEntities ||
470 m_selectionType != other.m_selectionType)
471 return false;
472
473
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
5 if(mp_indexRangeCollection->size() != other.mp_indexRangeCollection->size())
474 return false;
475
476
2/2
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 5 times.
14 for(qsizetype iter = 0; iter < mp_indexRangeCollection->size(); ++iter)
477
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
9 if(mp_indexRangeCollection->getRangeCstRefAt(iter) !=
478 9 other.mp_indexRangeCollection->getRangeCstRefAt(iter))
479 return false;
480
481 return true;
482 }
483
484 /*!
485 \brief Returns true if this instance is different than \a other, false
486 otherwise.
487 */
488 bool
489 2 CalcOptions::operator!=(const CalcOptions &other) const
490 {
491 2 return !operator==(other);
492 }
493
494 /*!
495 \brief Returns a string describing this CalcOptions instance.
496 */
497 QString
498 1 CalcOptions::toString() const
499 {
500 // qDebug() << "\n~~~~~~~~~~~~~~ CalcOptions instance ~~~~~~~~~~~~~\n"
501 // << this << "\n"
502 // << "m_deepCalculation:" << m_deepCalculation
503 // << "\n m_massType:" << massTypeMap[m_massType]
504 // << "\n m_capType:" << capTypeMap[m_capType] << "\n ";
505
506 1 QString text;
507
508
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 text += QString("m_deepCalculation: %1\n").arg(m_deepCalculation);
509
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 text += QString("m_massType: %1\n").arg(massTypeMap[m_massType]);
510
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 text += QString("m_capType: %1\n").arg(capTypeMap[m_capType]);
511
512
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 if(!mp_indexRangeCollection->getRangesCstRef().size())
513 text += "No IndexRange instances\n";
514 else
515
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 text += QString("IndexRange instances (%1 instance(s)):\n")
516
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 .arg(mp_indexRangeCollection->getRangesCstRef().size());
517
518
3/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
4 foreach(const IndexRange *item, mp_indexRangeCollection->getRangesCstRef())
519 {
520
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
6 text += QString("[%1 - %2]\n").arg(item->m_start).arg(item->m_stop);
521 }
522
523
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 text += QString("%1: %2\n")
524
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 .arg("Monomer chemical entities")
525
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 .arg(chemicalEntityMap[m_monomerEntities]);
526
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 text += QString("%1: %2\n")
527
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 .arg("Polymer chemical entities")
528
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 .arg(chemicalEntityMap[m_polymerEntities]);
529
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 text += QString("%1: %2\n")
530
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 .arg("Selection type")
531
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 .arg(selectionTypeMap[m_selectionType]);
532
533 1 return text;
534 }
535
536 void
537 CalcOptions::registerJsConstructor(QJSEngine *engine)
538 {
539 if(!engine)
540 {
541 qWarning() << "Cannot register CalcOptions class: engine is null";
542 return;
543 }
544
545 // Register the meta object as a constructor
546
547 QJSValue jsMetaObject =
548 engine->newQMetaObject(&CalcOptions::staticMetaObject);
549 engine->globalObject().setProperty("CalcOptions", jsMetaObject);
550 }
551
552
553 } // namespace libXpertMassCore
554 } // namespace MsXpS
555