GCC Code Coverage Report


source/XpertMassCore/src/
File: source/XpertMassCore/src/OligomerCollection.cpp
Date: 2025-11-20 01:41:33
Lines:
47/138
34.1%
Functions:
10/26
38.5%
Branches:
19/98
19.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 /////////////////////// libmass includes
35
36
37 /////////////////////// Local includes
38 #include "MsXpS/libXpertMassCore/OligomerCollection.hpp"
39
40
41 namespace MsXpS
42 {
43 namespace libXpertMassCore
44 {
45
46
47 /*!
48 \class MsXpS::libXpertMassCore::OligomerCollection
49 \inmodule libXpertMassCore
50 \ingroup PolChemDefBuildingdBlocks
51 \inheaderfile OligomerCollection.hpp
52
53 \brief The OligomerCollection class provides abstractions to work with Oligomer
54 instances that have been produced in specific contexts, like Polymer cleavages
55 or Oligomer fragmentations.
56 */
57
58 /*!
59 \variable MsXpS::libXpertMassCore::OligomerCollection::mcsp_polymer
60
61 \brief The \l Polymer instance about which this OligomerCollection is about.
62 */
63
64 /*!
65 \variable MsXpS::libXpertMassCore::OligomerCollection::m_name
66
67 \brief The name of the OligomerCollection.
68 */
69
70 /*!
71 \variable MsXpS::libXpertMassCore::OligomerCollection::m_comment
72
73 \brief A comment associated to the OligomerCollection.
74 */
75
76 /*!
77 \variable MsXpS::libXpertMassCore::OligomerCollection::m_massType
78
79 \brief The type of mass that is dealt with in a number of calculations.
80 */
81
82 /*!
83 \variable MsXpS::libXpertMassCore::OligomerCollection::m_oligomers
84
85 \brief The container of Oligomer instances in this OligomerCollection.
86 */
87
88 /*!
89 \typedef MsXpS::libXpertMassCore::OligomerCollectionSPtr
90 \relates OligomerCollection
91
92 Synonym for std::shared_ptr<OligomerCollection>.
93 */
94
95 /*!
96 \typedef MsXpS::libXpertMassCore::OligomerCollectionCstSPtr
97 \relates OligomerCollection
98
99 Synonym for std::shared_ptr<const OligomerCollection>.
100 */
101
102 /*!
103 \brief Constructs an OligomerCollection instance with a number of parameters.
104
105 \list
106 \li \a name The name of the OligomerCollection
107
108 \li \a polymer_cqsp The Polymer about which this OligomerCollection is about
109
110 \li \a mass_type The type of mass that is dealt with in a number of calculations
111
112 \endlist
113
114 */
115 660 OligomerCollection::OligomerCollection(const QString &name,
116 PolymerCstQSPtr polymer_cqsp,
117 660 Enums::MassType mass_type)
118
4/4
✓ Branch 1 taken 566 times.
✓ Branch 2 taken 94 times.
✓ Branch 3 taken 566 times.
✓ Branch 4 taken 94 times.
1226 : m_name(name), mcsp_polymer(polymer_cqsp), m_massType(mass_type)
119 {
120 660 }
121
122
123 /*!
124 \brief Constructs an OligomerCollection instance as a copy of \a other.
125
126 The Oligomer instances in the member container are instantiated anew (deep
127 copy).
128 */
129 OligomerCollection::OligomerCollection(const OligomerCollection &other)
130 : QObject(),
131 m_name(other.m_name),
132 m_comment(other.m_comment),
133 mcsp_polymer(other.mcsp_polymer),
134 m_massType(other.m_massType)
135 {
136 for(const OligomerSPtr &oligomer_sp : other.m_oligomers)
137 m_oligomers.emplace_back(std::make_shared<Oligomer>(*oligomer_sp.get()));
138 }
139
140
141 /*!
142 \brief Destructs the OligomerCollection.
143 */
144 1320 OligomerCollection::~OligomerCollection()
145 {
146 1320 m_oligomers.clear();
147 1320 }
148
149 /*!
150 \brief Sets the the polymer to \a polymer_cqsp.
151 */
152 void
153 OligomerCollection::setPolymer(PolymerCstQSPtr polymer_cqsp)
154 {
155 mcsp_polymer = polymer_cqsp;
156 }
157
158
159 /*!
160 \brief Returns the polymer.
161 */
162 const PolymerCstQSPtr
163 OligomerCollection::getPolymer() const
164 {
165 return mcsp_polymer;
166 }
167
168
169 /*!
170 \brief Sets the \a name.
171 */
172 void
173 OligomerCollection::setName(const QString &name)
174 {
175 if(!name.isEmpty())
176 m_name = name;
177 }
178
179
180 /*!
181 \brief Returns the name.
182 */
183 const QString &
184 OligomerCollection::getName() const
185 {
186 return m_name;
187 }
188
189
190 /*!
191 \brief Sets the \a comment.
192 */
193 void
194 OligomerCollection::setComment(const QString &comment)
195 {
196 if(!comment.isEmpty())
197 m_comment = comment;
198 }
199
200
201 /*!
202 \brief Returns the comment.
203 */
204 const QString &
205 OligomerCollection::getComment() const
206 {
207 return m_comment;
208 }
209
210 /*!
211 \brief Returns a const reference to the Oligomer container.
212 */
213 const std::vector<OligomerSPtr> &
214 43 OligomerCollection::getOligomersCstRef() const
215 {
216 43 return m_oligomers;
217 }
218
219 /*!
220 \brief Returns a reference to the Oligomer container.
221 */
222 std::vector<OligomerSPtr> &
223 6372 OligomerCollection::getOligomersRef()
224 {
225 6372 return m_oligomers;
226 }
227
228
229 /*!
230 \brief Sets the type of mass \a mass_type to be dealt with by default.
231 */
232 void
233 OligomerCollection::setMassType(Enums::MassType mass_type)
234 {
235 m_massType = mass_type;
236 if(m_massType == Enums::MassType::BOTH)
237 qFatalStream() << "Programming error. The mass type cannot be Enums::MassType::BOTH.";
238 }
239
240
241 /*!
242 \brief Returns the type of mass to be dealt with by default.
243 */
244 Enums::MassType
245 OligomerCollection::getMassType() const
246 {
247 return m_massType;
248 }
249
250 /*!
251 \brief Returns the Oligomer instance that encompasses a Monomer at \a
252 monomer_index.
253
254 This function starts searching for Oligomer instances in the member Oligomer
255 container at \a oligomer_index.
256
257 If \a oligomer_index is out of bounds, nullptr is returned.
258
259 When an Oligomer is found, its index in the member Oligomer container is set to
260 \a oligomer_index and its pointer is returned.
261
262 If no Oligomer is found, returns nullptr;
263 */
264 OligomerSPtr
265 OligomerCollection::findOligomerEncompassing(std::size_t monomer_index,
266 std::size_t &oligomer_index)
267 {
268 // Is there any oligomer that emcompasses the index ? If so return
269 // its pointer. Start searching in the list at index oligomer_index.
270
271 if(oligomer_index >= m_oligomers.size())
272 return nullptr;
273
274 std::vector<OligomerSPtr>::const_iterator the_begin_iterator_cst =
275 m_oligomers.cbegin() + oligomer_index;
276 std::vector<OligomerSPtr>::const_iterator the_end_iterator_cst =
277 m_oligomers.cend();
278 std::vector<OligomerSPtr>::const_iterator the_iterator_cst =
279 m_oligomers.cbegin() + oligomer_index;
280
281 while(the_iterator_cst != the_end_iterator_cst)
282 {
283 if((*the_iterator_cst)->encompasses(monomer_index))
284 {
285 oligomer_index =
286 std::distance(the_begin_iterator_cst, the_iterator_cst);
287 return *the_iterator_cst;
288 }
289
290 ++the_iterator_cst;
291 }
292
293 return nullptr;
294 }
295
296
297 /*!
298 \brief Returns the Oligomer instance that encompasses Monomer \a
299 monomer_csp.
300
301 This function starts searching for Oligomer instances in the member Oligomer
302 container at \a oligomer_index.
303
304 If \a oligomer_index is out of bounds, nullptr is returned.
305
306 When an Oligomer is found, its index in the member Oligomer container is set to
307 \a oligomer_index and its pointer is returned.
308
309 If no Oligomer is found, returns nullptr;
310 */
311 OligomerSPtr
312 116 OligomerCollection::findOligomerEncompassing(MonomerCstSPtr monomer_csp,
313 std::size_t &oligomer_index)
314 {
315 // Is there any oligomer that emcompasses the monomer_csp ? If so return
316 // its pointer. Start searching in the list at index oligomer_index.
317
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 116 times.
116 if(monomer_csp == nullptr || monomer_csp.get() == nullptr)
319 qFatalStream() << "Programming error. Pointer cannot be nullptr.";
320
321
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 116 times.
116 if(oligomer_index >= m_oligomers.size())
322 return nullptr;
323
324 116 std::vector<OligomerSPtr>::const_iterator the_begin_iterator_cst =
325 116 m_oligomers.cbegin() + oligomer_index;
326 116 std::vector<OligomerSPtr>::const_iterator the_end_iterator_cst =
327 116 m_oligomers.cend();
328 116 std::vector<OligomerSPtr>::const_iterator the_iterator_cst =
329 116 m_oligomers.cbegin() + oligomer_index;
330
331
2/2
✓ Branch 0 taken 3344 times.
✓ Branch 1 taken 84 times.
3428 while(the_iterator_cst != the_end_iterator_cst)
332 {
333
2/2
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 3312 times.
3344 if((*the_iterator_cst)->encompasses(monomer_csp.get()))
334 {
335 32 oligomer_index =
336 32 std::distance(the_begin_iterator_cst, the_iterator_cst);
337 32 return *the_iterator_cst;
338 }
339
340 3312 ++the_iterator_cst;
341 }
342
343 84 return nullptr;
344 }
345
346 /*!
347 \brief Returns the Oligomer instance that encompasses Monomer \a
348 monomer_sp.
349
350 This function starts searching for Oligomer instances in the member Oligomer
351 container at \a oligomer_index.
352
353 If \a oligomer_index is out of bounds, nullptr is returned.
354
355 When an Oligomer is found, its index in the member Oligomer container is set to
356 \a oligomer_index and its pointer is returned.
357
358 If no Oligomer is found, returns nullptr;
359 */
360 OligomerSPtr
361 OligomerCollection::findOligomerEncompassing(MonomerSPtr monomer_sp,
362 std::size_t &oligomer_index)
363 {
364 // Is there any oligomer that emcompasses the monomer_sp ? If so return
365 // its pointer. Start searching in the list at index oligomer_index.
366
367 if(monomer_sp == nullptr || monomer_sp.get() == nullptr)
368 qFatalStream() << "Programming error. Pointer cannot be nullptr.";
369
370 if(oligomer_index >= m_oligomers.size())
371 return nullptr;
372
373 std::vector<OligomerSPtr>::const_iterator the_begin_iterator_cst =
374 m_oligomers.cbegin() + oligomer_index;
375 std::vector<OligomerSPtr>::const_iterator the_end_iterator_cst =
376 m_oligomers.cend();
377 std::vector<OligomerSPtr>::const_iterator the_iterator_cst =
378 m_oligomers.cbegin() + oligomer_index;
379
380 while(the_iterator_cst != the_end_iterator_cst)
381 {
382 if((*the_iterator_cst)->encompasses(monomer_sp))
383 {
384 oligomer_index =
385 std::distance(the_begin_iterator_cst, the_iterator_cst);
386 return *the_iterator_cst;
387 }
388
389 ++the_iterator_cst;
390 }
391
392 return nullptr;
393 }
394
395 /*!
396 \brief Returns a string in which all the Oligomer instances present in the
397 member container are represented as text.
398
399 The masses of the Oligomer instances are reported for the \a mass_type. If \a
400 mass_type is Enums::MassType::BOTH, the the member mass type is used.
401 */
402 QString
403 OligomerCollection::allOligomerMassesToString(Enums::MassType mass_type)
404 {
405 QString text;
406
407 if(mass_type == Enums::MassType::BOTH && m_massType == Enums::MassType::BOTH)
408 return text;
409
410 Enums::MassType local_mass_type;
411
412 if(mass_type == Enums::MassType::BOTH)
413 local_mass_type = m_massType;
414 else
415 local_mass_type = mass_type;
416
417 for(const OligomerSPtr &oligomer_sp : m_oligomers)
418 {
419 text += QString("%1\n").arg(
420 oligomer_sp->getMass(local_mass_type), 0, 'f', OLIGOMER_DEC_PLACES);
421 }
422
423 return text;
424 }
425
426 /*!
427 \brief Returns true if the monoisotopic mass of \a o1_sp is smaller than that of
428 \a o2_sp, else returns false.
429 */
430 bool
431 OligomerCollection::monoMassCompare(const OligomerSPtr o1_sp,
432 const OligomerSPtr o2_sp)
433 {
434 // qDebug() << "o1_sp is:" << o1_sp.get() << "o2_sp is:" << o2_sp.get();
435
436 // std:sort compare function:
437 // Binary function that accepts two elements in the range as arguments, and
438 // returns a value convertible to bool. The value returned indicates whether
439 // the element passed as first argument is considered to go before the second
440 // in the specific strict weak ordering it defines.
441
442 return o1_sp->getMass(Enums::MassType::MONO) < o2_sp->getMass(Enums::MassType::MONO);
443 }
444
445
446 /*!
447 \brief Returns true if the average mass of \a o1_sp is smaller than that of \a
448 o2_sp, else returns false.
449 */
450 bool
451 OligomerCollection::avgMassCompare(const OligomerSPtr o1_sp,
452 const OligomerSPtr o2_sp)
453 {
454 qDebug() << "o1_sp is:" << o1_sp.get() << "o2_sp is:" << o2_sp.get();
455
456 return o1_sp->getMass(Enums::MassType::AVG) < o2_sp->getMass(Enums::MassType::AVG);
457 }
458
459
460 /*!
461 \brief Sorts the Oligomer instances in the member container according to
462 ascending masses of the default member Enums::MassType.
463 */
464 void
465 OligomerCollection::sortAscending()
466 {
467 // We only can sort if this instance knows which mass type it should
468 // handle, and that cannot be anything other than Enums::MassType::MASS_MONO
469 // or MASS_AVG.
470
471 if(m_massType == Enums::MassType::BOTH)
472 {
473 qDebug() << "Could not sort the oligomer list: "
474 "m_massType cannot be Enums::MassType::BOTH.";
475
476 return;
477 }
478
479 if(m_massType == Enums::MassType::MONO)
480 std::sort(m_oligomers.begin(),
481 m_oligomers.end(),
482 OligomerCollection::monoMassCompare);
483 else
484 std::sort(m_oligomers.begin(),
485 m_oligomers.end(),
486 OligomerCollection::avgMassCompare);
487 }
488
489 /*!
490 \brief Returns the size of this OligomerCollection as the count of Oligomer
491 instances in the member container.
492 */
493 std::size_t
494 409 OligomerCollection::size() const
495 {
496 409 return m_oligomers.size();
497 }
498
499 /*!
500 \brief Returns a text string representing this OligomerCollection's Oligomer instances.
501
502 \sa Oligomer::toString
503 */
504 QString
505 OligomerCollection::toString() const
506 {
507 QString text;
508
509 for(OligomerSPtr oligomer_sp : m_oligomers)
510 text += oligomer_sp->toString();
511
512 return text;
513 }
514
515 /*!
516 \brief Clears the member Oligomer container.
517 */
518 void
519 287 OligomerCollection::clear()
520 {
521 287 m_oligomers.clear();
522 287 }
523
524 /*!
525 Assigns \a other to this instance.
526 */
527 OligomerCollection &
528 1 OligomerCollection::operator=(const OligomerCollection &other)
529 {
530
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(this == &other)
531 return *this;
532
533 1 m_name = other.m_name;
534 1 m_comment = other.m_comment;
535 1 mcsp_polymer = other.mcsp_polymer;
536 1 m_massType = other.m_massType;
537
538 1 m_oligomers.assign(other.m_oligomers.begin(), other.m_oligomers.end());
539
540 1 return *this;
541 }
542
543 /*!
544 \brief Returns true if this OligomerCollection instance and \a other are identical, false otherwise.
545 */
546 bool
547 1 OligomerCollection::operator==(const OligomerCollection &other) const
548 {
549
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(this == &other)
550 return true;
551
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 if(m_name != other.m_name || m_comment != other.m_comment ||
552
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 mcsp_polymer != other.mcsp_polymer || m_massType != other.m_massType ||
553
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 m_oligomers != other.m_oligomers)
554 return false;
555
556 return true;
557 }
558
559 /*!
560 \brief Returns true if this OligomerCollection instance and \a other differ, false otherwise.
561
562 Returns the negated value returned from \l{operator==()}.
563 */
564 bool
565 1 OligomerCollection::operator!=(const OligomerCollection &other) const
566 {
567 1 return !operator==(other);
568 }
569
570 } // namespace libXpertMassCore
571 } // namespace MsXpS
572