GCC Code Coverage Report


./
File: src/XpertMass/CrossLink.cpp
Date: 2024-08-24 11:26:06
Lines:
6/270
2.2%
Functions:
2/39
5.1%
Branches:
2/268
0.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 "Polymer.hpp"
36 #include "CrossLink.hpp"
37
38
39 namespace MsXpS
40 {
41
42 namespace libXpertMass
43 {
44
45 ///////////////////////////// CrossLink ////////////////////////
46 ///////////////////////////// CrossLink ////////////////////////
47 ///////////////////////////// CrossLink ////////////////////////
48
49 ///// Look down for CrossLinkList
50
51
52
53 /*!
54 \class MsXpS::libXpertMass::CrossLink
55 \inmodule libXpertMass
56 \ingroup PolChemDefAqueousChemicalReactions
57 \inheaderfile CrossLink.hpp
58
59 \brief The CrossLink class provides abstractions to work with
60 a cross-link entity between \l Monomer instances.
61
62 The notion of a cross-link is that it is a chemical reaction that involves at
63 least two monomers in a \l Polymer or in an \l Oligomer sequence.
64
65 Polymer sequences might contain more than one CrossLink and these are stored as
66 a \l CrossLinkList.
67 */
68
69 /*!
70 \enum MsXpS::libXpertMass::CrossLinkEncompassed
71
72 This enum type specifies the manner in which a sequence region in a \l
73 Polymer or in an \l Oligomer contains fully, or partially not does not contain
74 all the monomers involved in a CrossLink:
75
76 \value CROSS_LINK_ENCOMPASSED_NO
77 The region does not contain any \l Monomer involved in a CrossLink.
78 \value CROSS_LINK_ENCOMPASSED_PARTIAL
79 The region contains one or more \l{Monomer}s involved in a
80 CrossLink but not all.
81 \value CROSS_LINK_ENCOMPASSED_FULL
82 All the \l{Monomer}s involved in the CrossLink are contained in
83 the \l Polymer or \l Oligomer region.
84 */
85
86
87 /*!
88 \variable MsXpS::libXpertMass::CrossLink::mp_polymer
89
90 \brief The \l Polymer instance of which this CrossLink is part. This CrossLink
91 does not own the Polymer.
92 */
93
94 /*!
95 \variable MsXpS::libXpertMass::CrossLink::m_monomerList
96
97 \brief The list of \l Monomer instances that are involved in the formation of
98 this CrossLink.
99
100 The monomers are the \l Monomer instances found in the mp_polymer \l Polymer
101 instance. This CrossLink does not own these \l{Monomer}s.
102
103 The reason the CrossLink lists the involved \l Monomer instances as pointers to
104 these very monomers in the polymer sequence is that in this way, even if the
105 sequence is edited the cross-link does not loose the relation to the monomers.
106 The only way that the sequence editing modifies a CrossLink instance is by
107 removing a \l Monomer instance involved in the CrossLink. If that occurs, the
108 CrossLink is informed and its destructed.
109 */
110
111 /*!
112 \variable MsXpS::libXpertMass::CrossLink::m_comment
113
114 \brief The comment that might be associated to this CrossLink.
115 */
116
117 /*!
118 \brief Constructs a CrossLink instance
119
120 \list
121 \li \a pol_chem_def_csp: the polymer chemistry definition (\l PolChemDef).
122 \li \a polymer: the \l Polymer instance in which this CrossLink was formed.
123 \li \a name: the name of this CrossLink instance.
124 \li \a formula: the \l Formula that describes the reaction that is the basis of
125 the chemical reaction leading to the formation of this CrossLink.
126 \li \a comment: a comment that might be associated to this CrossLink.
127 \endlist
128 */
129 CrossLink::CrossLink(PolChemDefCstSPtr pol_chem_def_csp,
130 Polymer *polymer,
131 const QString &name,
132 const QString &formula,
133 const QString &comment)
134 : CrossLinker(pol_chem_def_csp, name, formula),
135 mp_polymer(polymer),
136 m_comment(comment)
137 {
138 }
139
140
141 /*!
142 \brief Constructs a CrossLink instance
143
144 \list
145 \li \a cross_linker: CrossLinker instance used to initialize this CrossLink.
146 \li \a polymer: the \l Polymer instance in which this CrossLink was formed
147 \li \a comment: a comment that might be associated to this CrossLink
148 \endlist
149 */
150 CrossLink::CrossLink(const CrossLinker &cross_linker,
151 Polymer *polymer,
152 const QString &comment)
153 : CrossLinker(cross_linker), mp_polymer(polymer), m_comment(comment)
154 {
155 }
156
157 /*!
158 \brief Constructs a CrossLink instance as a copy of \a other.
159 */
160 CrossLink::CrossLink(const CrossLink &other)
161 : CrossLinker(other),
162 mp_polymer(other.mp_polymer),
163 m_comment(other.m_comment)
164 {
165 }
166
167
168 /*!
169 \brief Destructs this CrossLink instance.
170
171 No entity needs to be destructed, since the \l Monomer instances in the list
172 are not owned by this CrossLinker instance.
173 */
174 CrossLink::~CrossLink()
175 {
176 }
177
178 /*!
179 \brief Sets \a monomer to this CrossLink at \a index of the member list of
180 Monomer instances, effectively replacing the \a monomer instance currently at
181 that index.
182
183 \a monomer cannot be nullptr and \a index cannot be out-of-bounds.
184
185 This CrossLinker instance does not take ownership of \a monomer.
186
187 Returns true.
188 */
189 bool
190 CrossLink::setMonomerAt(Monomer *monomer, int index)
191 {
192 Q_ASSERT(monomer);
193 Q_ASSERT(index >= 0 && index < m_monomerList.size());
194
195 m_monomerList.replace(index, monomer);
196
197 return true;
198 }
199
200 /*!
201 \brief Adds \a monomer to the member list of Monomer instances.
202
203 \a monomer cannot be nullptr.
204
205 Returns true.
206 */
207 bool
208 CrossLink::appendMonomer(const Monomer *monomer)
209 {
210 Q_ASSERT(monomer);
211
212 m_monomerList.append(monomer);
213
214 return true;
215 }
216
217 /*!
218 \brief Returns the monomer at \a index in the member list of \l Monomer
219 instances.
220
221 \a index cannot be out-of-bounds.
222 */
223 const Monomer *
224 CrossLink::monomerAt(int index)
225 {
226 Q_ASSERT(index >= 0 && index < m_monomerList.size());
227
228 return m_monomerList.at(index);
229 }
230
231 /*!
232 \brief Removes the monomer at \a index in the member list of \l Monomer
233 instances.
234
235 \a index cannot be out-of-bounds.
236
237 Returns true.
238 */
239 bool
240 CrossLink::removeMonomerAt(int index)
241 {
242 Q_ASSERT(index < m_monomerList.size());
243
244 m_monomerList.removeAt(index);
245
246 return true;
247 }
248
249 /*!
250 \brief Set \a polymer as the \l Polymer sequence in which this CrossLink has
251 been formed.
252
253 \a polymer cannot be nullptr.
254 */
255 void
256 CrossLink::setPolymer(Polymer *polymer)
257 {
258 Q_ASSERT(polymer);
259
260 mp_polymer = polymer;
261 }
262
263 /*!
264 \brief Returns the \l Polymer instance in which this CrossLink has
265 been formed.
266 */
267 Polymer *
268 CrossLink::polymer()
269 {
270 return mp_polymer;
271 }
272
273 /*!
274 \brief Set the member comment to \a comment.
275 */
276 void
277 CrossLink::setComment(const QString &comment)
278 {
279 m_comment = comment;
280 }
281
282 /*!
283 \brief Returns the member comment.
284 */
285 const QString &
286 CrossLink::comment() const
287 {
288 return m_comment;
289 }
290
291 /*!
292 \brief Returns true if this CrossLink instance and \a other are identical,
293 false otherwise.
294 */
295 bool
296 CrossLink::operator==(const CrossLink &other) const
297 {
298 int tests = 0;
299
300 tests += CrossLinker::operator==(other);
301 tests += mp_polymer == other.mp_polymer;
302
303 if(m_monomerList.size() != other.m_monomerList.size())
304 return false;
305
306 for(int iter = 0; iter < m_monomerList.size(); ++iter)
307 {
308 if(m_monomerList.at(iter) != other.m_monomerList.at(iter))
309 return false;
310 }
311
312 tests += m_comment == other.m_comment;
313
314 if(tests < 3)
315 return false;
316 else
317 return true;
318 }
319
320 /*!
321 \brief Sets to the member monomer list all the \l Monomer instances referenced
322 in \a text as indices to monomer in the \l Polymer sequence.
323
324 \a text contains a list of \l Monomer instance indices separated by ';'
325 characters. The corresponding monomers found in the member Polymer are copied
326 to the member list of \l Monomer instances, effectively documenting a CrossLink
327 in that member Polymer sequence.
328
329 This CrossLink instance does not own the \l Monomer instances pointers, as they
330 effectively point to monomer that belong to the member \l Polymer.
331 */
332 int
333 CrossLink::populateMonomerList(QString text)
334 {
335 // We do not own the monomers pointed to by the pointers in
336 // m_monomerList.
337
338 while(m_monomerList.size())
339 m_monomerList.removeFirst();
340
341 QStringList stringList =
342 text.split(';', Qt::SkipEmptyParts, Qt::CaseSensitive);
343
344 // There must be at least 2 monomers to make a crossLink !
345
346 if(stringList.size() < 2)
347 return -1;
348
349 for(int iter = 0; iter < stringList.size(); ++iter)
350 {
351 QString value = stringList.at(iter);
352
353 bool ok = false;
354
355 int index = value.toInt(&ok);
356
357 if(!index && !ok)
358 return -1;
359
360 Q_ASSERT(index >= 0 && index < mp_polymer->size());
361
362 m_monomerList.append(mp_polymer->at(index));
363 }
364
365 return m_monomerList.size();
366 }
367
368 /*!
369 \brief Returns the member list of \l Monomer instances.
370 */
371 QList<const Monomer *> *
372 CrossLink::monomerList()
373 {
374 return &m_monomerList;
375 }
376
377 /*!
378 \brief Lists in \a list the indices of all the monomers involved in this
379 CrossLink instance.
380
381 Returns the count of indices set to \a list.
382 */
383 int
384 CrossLink::monomerIndexList(QList<int> *list)
385 {
386 if(!list)
387 qFatal("Fatal error at %s@%d. Aborting.", __FILE__, __LINE__);
388
389 int count = 0;
390
391 QList<int> localIndexList;
392
393 for(int iter = 0; iter < m_monomerList.size(); ++iter)
394 {
395 const Monomer *monomer = m_monomerList.at(iter);
396 int index = mp_polymer->monomerIndex(monomer);
397
398 // qDebug() << __FILE__ << __LINE__
399 // << "Other monomer index:" << index;
400
401 localIndexList.append(index);
402
403 ++count;
404 }
405
406 std::sort(localIndexList.begin(), localIndexList.end());
407
408 // Now that we have the minIndex and the maxIndex of the region
409 // involved by the cross-link, we can fill-in the integer list
410 // with all the values contained between these two borders.i
411
412 for(int iter = localIndexList.first(); iter <= localIndexList.last(); ++iter)
413 {
414 // If we had a cross-link between monomers [4] and [10] of the
415 // polymer, then the indices appended to the list would be 4,
416 // 5, 6, 7, 8, 9 and 10.
417 list->append(iter);
418 }
419
420 return count;
421 }
422
423 /*!
424 \brief Returns a string containing a ';'-separated list of the indices of all
425 the \l Monomer instances involved in this CrossLink.
426 */
427 QString
428 CrossLink::monomerIndexText()
429 {
430 QString text = ";";
431
432 for(int iter = 0; iter < m_monomerList.size(); ++iter)
433 {
434 const Monomer *monomer = m_monomerList.at(iter);
435 int index = mp_polymer->monomerIndex(monomer);
436
437 text += QString("%1;").arg(index);
438 }
439
440 return text;
441 }
442
443 /*!
444 \brief Returns a string containing a ';'-separated list of the positions
445 of all the \l Monomer instances involved in this CrossLink.
446 */
447 QString
448 CrossLink::monomerPosText()
449 {
450 QString text = ";";
451
452 for(int iter = 0; iter < m_monomerList.size(); ++iter)
453 {
454 const Monomer *monomer = m_monomerList.at(iter);
455 int index = mp_polymer->monomerIndex(monomer);
456
457 text += QString("%1;").arg(index + 1);
458 }
459
460 return text;
461 }
462
463 /*!
464 \brief Returns the index of \a monomer found in the member \l Polymer sequence
465 that is involved in this CrossLink, or -1 if that is not found.
466 */
467 int
468 CrossLink::involvesMonomer(const Monomer *monomer) const
469 {
470 Q_ASSERT(monomer);
471
472 for(int iter = 0; iter < m_monomerList.size(); ++iter)
473 {
474 if(m_monomerList.at(iter) == monomer)
475 {
476 return iter;
477 }
478 }
479
480 return -1;
481 }
482
483 /*!
484 \brief Returns the first \l Monomer instance listed in the member list of
485 monomers. If the list is empty; returns nullptr.
486 */
487 const Monomer *
488 CrossLink::firstMonomer() const
489 {
490 if(!m_monomerList.size())
491 return nullptr;
492
493 return m_monomerList.first();
494 }
495
496 /*!
497 \brief Tells if this CrossLink instance is encompassed (partially or fully) or
498 not at all by the Polymer sequence region defined by the [\a start - \a end ]
499 \l Monomer index range.
500
501 The count of monomers involved in this cross-link that:
502
503 \list
504 \li Are contained in the range is stored in \a in.
505 \li Are not contained in the range is stored in \a out.
506 \endlist
507
508 If all the monomers are listed as \a in, then this CrossLink is fully
509 encompassed by the Polymer sequence region defined by the [\a start - \a end ]
510 \l Monomer index range and CROSS_LINK_ENCOMPASSED_FULL is returned.
511
512 If all the monomers are listed as \a out, then this CrossLink is not at all
513 encompassed by the Polymer sequence region and CROSS_LINK_ENCOMPASSED_NO is
514 returned.
515
516 If both kinds of monmers were found, then CROSS_LINK_ENCOMPASSED_PARTIAL is
517 returned.
518 */
519 int
520 CrossLink::encompassedBy(int start, int end, int *in, int *out)
521 {
522 // Iterate in the list of monomers, and for each monomer check if
523 // their index is contained in the stretch.
524
525 int countIn = 0;
526 int countOut = 0;
527
528 int localStart = std::min(start, end);
529 int localEnd = std::max(start, end);
530
531 for(int iter = 0; iter < m_monomerList.size(); ++iter)
532 {
533 const Monomer *monomer = m_monomerList.at(iter);
534
535 int index = mp_polymer->monomerIndex(monomer);
536
537 if(index >= localStart && index <= localEnd)
538 ++countIn;
539 else
540 ++countOut;
541 }
542
543 Q_ASSERT((countIn + countOut) == m_monomerList.size());
544
545 if(in)
546 *in = countIn;
547 if(out)
548 *out = countOut;
549
550 if(countOut && countIn)
551 return CROSS_LINK_ENCOMPASSED_PARTIAL;
552
553 if(countOut)
554 return CROSS_LINK_ENCOMPASSED_NO;
555
556 if(countIn)
557 return CROSS_LINK_ENCOMPASSED_FULL;
558
559 return CROSS_LINK_ENCOMPASSED_NO;
560 }
561
562
563 /*!
564 \brief Tells if this CrossLink instance is encompassed (partially or fully) or
565 not at all by various \l Coordinates instances in the \a coordinate_list \l
566 CoordinateList.
567
568 The count of monomers involved in this cross-link that:
569
570 \list
571 \li Are contained in the regions defined in \a coordinate_list is stored in \a
572 in.
573 \li Are not contained in the range is stored in \a out.
574 \endlist
575
576 If all the monomers are listed as \a in, then this CrossLink is fully
577 encompassed by the Polymer sequence regions defined in \a coordinate_list and
578 CROSS_LINK_ENCOMPASSED_FULL is returned.
579
580 If all the monomers are listed as \a out, then this CrossLink is not at all
581 encompassed by the Polymer sequence region and CROSS_LINK_ENCOMPASSED_NO is
582 returned.
583
584 If both kinds of monmers were found, then CROSS_LINK_ENCOMPASSED_PARTIAL is
585 returned.
586 */
587 int
588 CrossLink::encompassedBy(const CoordinateList &coordinate_list,
589 int *in,
590 int *out)
591 {
592 // Iterate in the list of monomers involved in *this crossLink,
593 // and for each monomer check if their index is contained in any
594 // of the Coordinates [start--end] of the coordinateList passed as
595 // parameter.
596
597 int countIn = 0;
598 int countOut = 0;
599
600 for(int iter = 0; iter < m_monomerList.size(); ++iter)
601 {
602 const Monomer *monomer = m_monomerList.at(iter);
603
604 int index = mp_polymer->monomerIndex(monomer);
605
606 // qDebug() << __FILE__ << __LINE__
607 // << " monomer at index:" << index
608 // << "tested:";
609
610 // Is the index encompassed by any of the Coordinates of the
611 // CoordinateList ?
612
613 bool countedIn = false;
614
615 for(int jter = 0; jter < coordinate_list.size(); ++jter)
616 {
617 Coordinates *coordinates = coordinate_list.at(jter);
618
619 if(index >= coordinates->start() && index <= coordinates->end())
620 {
621 ++countIn;
622 countedIn = true;
623
624 // qDebug() << __FILE__ << __LINE__
625 // << " encompassedBy YES by coordinates"
626 // << "coordinates->start()" << coordinates->start()
627 // << "coordinates->end()" << coordinates->end();
628
629 break;
630 }
631 else
632 {
633 // qDebug() << __FILE__ << __LINE__
634 // << " encompassedBy NO by coordinates"
635 // << "coordinates->start()" << coordinates->start()
636 // << "coordinates->end()" << coordinates->end();
637 }
638 }
639
640 if(!countedIn)
641 ++countOut;
642 }
643
644 Q_ASSERT((countIn + countOut) == m_monomerList.size());
645
646 if(in)
647 *in = countIn;
648 if(out)
649 *out = countOut;
650
651 if(countOut && countIn)
652 return CROSS_LINK_ENCOMPASSED_PARTIAL;
653
654 if(countOut)
655 return CROSS_LINK_ENCOMPASSED_NO;
656
657 if(countIn)
658 return CROSS_LINK_ENCOMPASSED_FULL;
659
660 return CROSS_LINK_ENCOMPASSED_NO;
661 }
662
663 /*!
664 \brief Returns true if this CrossLink instance validates successfully, false
665 otherwise.
666
667 The validation is successful if:
668
669 \list
670 \li The count of \l Monomer instances listed in the member list is > 1.
671 \li The member \l Polymer instance exists.
672 \li The count of \l Monomer instances listed in the member list is equal to
673 the number of \l Modif instance in the \l CrossLinker base class.
674 \li If the list of \l Modif
675 instances in the \l CrossLinker base class is not empty, there must be a
676 colinearity between the order in which these instances are listed and the
677 order in which the \l Monomer instances are listed in the member list. The
678 monomer instance must be a target of the modification.
679 \endlist
680 */
681 bool
682 CrossLink::validate()
683 {
684 if(m_monomerList.size() <= 1)
685 {
686 qDebug() << __FILE__ << __LINE__
687 << "A crossLink with a single monomer "
688 "cannot be created.";
689
690 return false;
691 }
692
693 if(mp_polymer == nullptr)
694 return false;
695
696 // If the crossLinker has at least one modif in its definition, then
697 // we have to make sure that the modification has as one of its
698 // targets the corresponding monomer in the list of monomer
699 // pointers.
700
701 // Indeed, there is some logic here. Either the m_modifList in the
702 // parent class CrossLinker contains no item, in which case
703 // everything is fine, or it does contain items. In the latter case,
704 // then, the number of items must match the number of monomers being
705 // crosslinked, and then we get to know which modif is attributable
706 // to which monomer, hence the possibility of a check.
707
708 if(m_modifList.size())
709 {
710 if(m_modifList.size() != m_monomerList.size())
711 {
712 qDebug() << __FILE__ << __LINE__
713 << QObject::tr(
714 "The number of modification items "
715 "does not match the number of "
716 "monomers. This is an error.");
717 return false;
718 }
719
720 // At this point, we can make the check for each modif:
721
722 for(int iter = 0; iter < m_modifList.size(); ++iter)
723 {
724 Modif *modif = m_modifList.at(iter);
725 const Monomer *monomer = m_monomerList.at(iter);
726
727 if(!monomer->isModifTarget(*modif))
728 {
729 // The monomer is not target for the modification that is
730 // implied by the crossLinking.
731
732 qDebug() << __FILE__ << __LINE__
733 << QObject::tr(
734 "The monomer '%1' is not target of "
735 "crossLinker modif '%2'")
736 .arg(monomer->name())
737 .arg(modif->name());
738
739 return false;
740 }
741 }
742 }
743
744 return true;
745 }
746
747 /*!
748 \brief Calculates the masses of this CrossLink and set them anew to the member
749 masses (\l Ponderable base class).
750
751 Returns true.
752 */
753 bool
754 CrossLink::calculateMasses()
755 {
756 return CrossLinker::calculateMasses();
757 }
758
759 /*!
760 \brief Adds the member m_mono and m_avg masses to \a mono and \a
761 avg, as compounded by the \a times factor.
762
763 Returns true.
764 */
765 bool
766 CrossLink::accountMasses(double *mono, double *avg, int times)
767 {
768 return CrossLinker::accountMasses(mono, avg, times);
769 }
770
771
772 /*!
773 \brief Adds the member m_mono and m_avg masses to \a ponderable, as compounded
774 by the \a times factor.
775
776 Returns true.
777 */
778 bool
779 CrossLink::accountMasses(Ponderable *ponderable, int times)
780 {
781 return CrossLinker::accountMasses(ponderable, times);
782 }
783
784 /*!
785 \brief Returns an allocated string describing this CrossLink instance.
786 */
787 QString *
788 CrossLink::prepareResultsTxtString()
789 {
790 QString *text = new QString();
791
792 *text += QObject::tr(
793 "\nCross-link:\n"
794 "===============\n"
795 "Cross-linker name: %1\n"
796 "Cross-link comment: %2\n")
797 .arg(m_name)
798 .arg(m_comment);
799
800 for(int iter = 0; iter < m_monomerList.size(); ++iter)
801 {
802 const Monomer *monomer = m_monomerList.at(iter);
803
804 int index = mp_polymer->monomerIndex(monomer);
805
806 *text += QObject::tr("Partner %1: %2 at position: %3\n")
807 .arg(iter + 1)
808 .arg(monomer->code())
809 .arg(index + 1);
810 }
811
812 return text;
813 }
814
815 ///////////////////////////// CrossLinkList ////////////////////////
816 ///////////////////////////// CrossLinkList ////////////////////////
817 ///////////////////////////// CrossLinkList ////////////////////////
818
819
820 /*!
821 \class MsXpS::libXpertMass::CrossLinkList
822 \inmodule libXpertMass
823 \ingroup PolChemDefAqueousChemicalReactions
824
825 \brief The CrossLinkList class provides a list of CrossLink instances.
826 */
827
828 /*!
829 \variable MsXpS::libXpertMass::CrossLinkList::m_name
830
831 \brief The name of the list of \l CrossLink instances.
832 */
833
834 /*!
835 \variable MsXpS::libXpertMass::CrossLinkList::mp_polymer
836
837 \brief The \l Polymer instance of which this CrossLinkList is part. This
838 CrossLinkList does not own the Polymer.
839 */
840
841 /*!
842 \variable MsXpS::libXpertMass::CrossLinkList::m_comment
843
844 \brief The comment that might be associated to this CrossLinkList.
845 */
846
847 /*!
848 \brief Constructs an empty CrossLinkList instance.
849 */
850
2/4
✓ Branch 3 taken 116 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 116 times.
✗ Branch 7 not taken.
116 CrossLinkList::CrossLinkList()
851 {
852 116 }
853
854 /*!
855 \brief Constructs a CrossLinkList instance.
856
857 \list
858 \li \a name: the name of this CrossLinkList instance.
859 \li \a polymer: the \l Polymer instance in which this CrossLinkList was formed.
860 \li \a comment: a comment that might be associated to this CrossLinkList.
861 \endlist
862 */
863 CrossLinkList::CrossLinkList(const QString &name,
864 Polymer *polymer,
865 const QString &comment)
866 : m_name(name), mp_polymer(polymer), m_comment(comment)
867 {
868 }
869
870
871 /*!
872 \brief Constructs a CrossLinkList instance as a copy of \a other.
873 */
874 CrossLinkList::CrossLinkList(const CrossLinkList *other)
875 : QList<CrossLink *>(*other),
876 m_name(other->m_name),
877 mp_polymer(other->mp_polymer),
878 m_comment(other->m_comment)
879 {
880 // And now copy all the items from other in here:
881 for(int iter = 0; iter < other->size(); ++iter)
882 {
883 CrossLink *crossLink = other->at(iter);
884
885 CrossLink *crossLinkNew = new CrossLink(crossLink->getPolChemDefCstSPtr(),
886 crossLink->polymer(),
887 crossLink->name(),
888 crossLink->formula(),
889 crossLink->comment());
890
891 append(crossLinkNew);
892 }
893 }
894
895 /*!
896 \brief Destructs thisCrossLinkList instance.
897
898 Deletes all the CrossLink instances in this list.
899 */
900 464 CrossLinkList::~CrossLinkList()
901 {
902 232 qDeleteAll(begin(), end());
903 232 clear();
904 464 }
905
906 /*!
907 \brief Assigns \a other to this CrossLinkList instance.
908
909 Returns a reference to this CrossLinkList instance.
910 */
911 CrossLinkList &
912 CrossLinkList::operator=(const CrossLinkList &other)
913 {
914 if(&other == this)
915 return *this;
916
917 m_name = other.m_name;
918 mp_polymer = other.mp_polymer;
919 m_comment = other.m_comment;
920
921 // Now empty and clear this list.
922 qDeleteAll(begin(), end());
923 clear();
924
925 // And now copy all the items from other in here:
926 for(int iter = 0; iter < other.size(); ++iter)
927 {
928 CrossLink *crossLink = other.at(iter);
929
930 CrossLink *crossLinkNew = new CrossLink(*crossLink);
931
932 append(crossLinkNew);
933 }
934
935 return *this;
936 }
937
938
939 /*!
940 \brief Sets the \a name.
941 */
942 void
943 CrossLinkList::setName(QString name)
944 {
945 if(!name.isEmpty())
946 m_name = name;
947 }
948
949
950 /*!
951 \brief Returns the name.
952 */
953 QString
954 CrossLinkList::name()
955 {
956 return m_name;
957 }
958
959 /*!
960 \brief Sets the \a comment.
961 */
962 void
963 CrossLinkList::setComment(QString comment)
964 {
965 if(!comment.isEmpty())
966 m_comment = comment;
967 }
968
969
970 /*!
971 \brief Returns the comment.
972 */
973 const QString &
974 CrossLinkList::comment() const
975 {
976 return m_comment;
977 }
978
979 /*!
980 \brief Sets the \a polymer.
981 */
982 void
983 CrossLinkList::setPolymer(Polymer *polymer)
984 {
985 mp_polymer = polymer;
986 }
987
988
989 /*!
990 \brief Gets the polymer.
991 */
992 const Polymer *
993 CrossLinkList::polymer() const
994 {
995 return mp_polymer;
996 }
997
998
999 int
1000 CrossLinkList::crossLinksInvolvingMonomer(const Monomer *monomer,
1001 QList<int> *list) const
1002 {
1003 int count = 0;
1004
1005 for(int iter = 0; iter < size(); ++iter)
1006 {
1007 CrossLink *crossLink = at(iter);
1008
1009 for(int jter = 0; jter < crossLink->monomerList()->size(); ++jter)
1010 {
1011 const Monomer *iterMonomer = crossLink->monomerList()->at(jter);
1012
1013 if(monomer == iterMonomer)
1014 {
1015 count++;
1016
1017 if(list)
1018 list->append(iter);
1019 }
1020 }
1021 }
1022
1023 return count;
1024 }
1025
1026
1027 } // namespace libXpertMass
1028
1029 } // namespace MsXpS
1030