GCC Code Coverage Report


source/XpertMassCore/src/
File: source/XpertMassCore/src/CleavageMotif.cpp
Date: 2025-11-20 01:41:33
Lines:
166/205
81.0%
Functions:
19/21
90.5%
Branches:
115/270
42.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 /////////////////////// Local includes
35 #include "MsXpS/libXpertMassCore/CleavageMotif.hpp"
36 #include "MsXpS/libXpertMassCore/Polymer.hpp"
37 #include "MsXpS/libXpertMassCore/PolChemDef.hpp"
38
39 namespace MsXpS
40 {
41
42 namespace libXpertMassCore
43 {
44
45
46 /*!
47 \class MsXpS::libXpertMassCore::CleavageMotif
48 \inmodule libXpertMassCore
49 \ingroup PolChemDefAqueousChemicalReactions
50 \inheaderfile CleavageMotif.hpp
51
52 \brief The CleavageMotif class provides a model for specifying aqueous cleavage
53 motfis of \l{Polymer} \l{Sequence}s.
54
55 When a polymer sequence cleavage occurs, using, for example, the Trypsin
56 cleavage agent, that cleavage agent specifies that cleavage should occur at the
57 following sites "Lys/;Arg/;-Lys/Pro".
58
59 The "Lys/;Arg/;-Lys/Pro" string of sites gets parsed and \e{cleavage motifs} are
60 generated from it. In this specific case, we'll have three \e{CleavageMotif}
61 instances with the following data:
62
63 - First motif (or cleavage site):
64 - "Lys"
65 - monomer container: [0] = "Lys"
66 - offset = 1 ('/' indicates that the cut is right of monomer)
67 - is for cleavage ? = Enums::CleavageAction::CLEAVE
68
69 - Second motif (or cleavage site):
70 - "Arg"
71 - monomer container: [0] = "Arg"
72 - offset = 1 ('/' indicates that the cut is right of monomer)
73 - is for cleavage ? = Enums::CleavageAction::CLEAVE
74
75 - Third motif (or non-cleavage site):
76 - "-LysPro"
77 - monomer container: [0] = "Lys", [1] = "Pro"
78 - offset = 1 ('/' indicates that the cut is right of monomer)
79 - is for cleavage ? = Enums::CleavageAction::NO_CLEAVE
80
81 Thanks to this deconstruction (from "Lys/;Arg/;-Lys/Pro" to the 3 cleavage
82 motifs above) is the polymer sequence cleaved according to the
83 cleavage agent specification.
84
85 \sa CleavageAgent, CleavageRule
86 */
87
88
89 /*!
90 \variable MsXpS::libXpertMassCore::CleavageMotif::mcsp_polChemDef
91
92 \brief The \l PolChemDef (polymer chemistry definition) that is needed.
93 */
94
95 /*!
96 \variable MsXpS::libXpertMassCore::CleavageMotif::m_monomers
97
98 \brief The container of Monomer instances. The Monomer instances
99 are in the form of const shared pointers to Monomer in the
100 polymer chemistry definition.
101
102 A "Lys/Pro" motif will translate into two Monomer instances (actually pointers)
103 having codes Lys and Pro, in the right order.
104 */
105
106 /*!
107 \variable MsXpS::libXpertMassCore::CleavageMotif::m_offset
108
109 \brief The offset between the actual cleavage site and the first monomer of the
110 motif.
111
112 In the The "Lys/", "Arg/" and "-Lys/Pro" examples, the offset would be 1 for
113 each motif, because each time the cleavage occurs after the first monomer
114 code: Lys/, or Arg/ or Lys/Pro. In the /Asp cleavage site the offset would be 0,
115 because the cleavage occurs before the first monomer in the motif (Asp). In the
116 ATGC/GCAT cleavage motif, the offset would be 4.
117 */
118
119 /*!
120 \variable MsXpS::libXpertMassCore::CleavageMotif::m_cleavageAction
121
122 \brief Tells if the motif is for cleavage or not for cleavage.
123
124 In the "Lys/" and "Arg/" motif, that would be true; for "-Lys/Pro", that would
125 be false, because Trypsin does not cleave after a Lysyl residue if it is
126 followed by a Prolyl residue.
127 */
128
129 /*!
130 \variable MsXpS::libXpertMassCore::CleavageMotif::m_isValid
131 \brief Tell the validity status of the CleavageMotif instance.
132 */
133
134 /*!
135 \brief Constructs a cleavage motif with \a pol_chem_def_csp as the polymer chemistry definition.
136
137 The instance will be invalid (m_isValid set to false).
138 */
139 1140 CleavageMotif::CleavageMotif(PolChemDefCstSPtr pol_chem_def_csp)
140 1140 : mcsp_polChemDef(pol_chem_def_csp)
141 {
142 1140 }
143
144 /*!
145 \brief Constructs a cleavage motif with a number of parameters.
146
147 \list
148 \li \a pol_chem_def_csp Polymer chemistry definition. Cannot be nullptr.
149
150 \li \a motif Motif in the form of "Lys/" or "Lys/Pro" or "/Asp".
151
152 \li \a offset Offset position of the cleavage to the first monomer code in
153 the motif.
154
155 \li \a cleavage_action Tells if motif is for cleavage (for example, "Lys/") or
156 not for cleavage (for example, "-Lys/Pro").
157 \endlist
158
159 After setting the member data, the CleavageMotif instance is validated and
160 m_isValid is set to the result of this validation.
161 */
162 4 CleavageMotif::CleavageMotif(PolChemDefCstSPtr pol_chem_def_csp,
163 const QString &motif,
164 int offset,
165 4 Enums::CleavageAction cleavage_action)
166 4 : mcsp_polChemDef(pol_chem_def_csp),
167 4 m_offset(offset),
168
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 m_cleavageAction(cleavage_action)
169 {
170
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
4 if(!parseMotif(motif))
171 qCritical()
172 << "Upon construction of CleavageMotif, the motif could not be parsed.";
173
174 // Let's see the other members.
175 4 ErrorList error_list;
176
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 m_isValid = validate(&error_list);
177
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!m_isValid)
179 qCritical() << "Upon construction of CleavageMotif, the instance failed to "
180 "validate with errors:"
181 << Utils::joinErrorList(error_list, ", ");
182
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
4 }
183
184 /*!
185 \brief Constructs a CleavageMotif instance as a copy of \a other.
186
187 After setting the member data, the CleavageMotif instance is validated and
188 m_isValid is set to the result of this validation.
189 */
190 1 CleavageMotif::CleavageMotif(const CleavageMotif &other)
191 1 : mcsp_polChemDef(other.mcsp_polChemDef),
192 1 m_offset(other.m_offset),
193
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 m_cleavageAction(other.m_cleavageAction)
194 {
195
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 m_monomers = other.m_monomers;
196
197 // Let's see the other members.
198 1 ErrorList error_list;
199
200
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 m_isValid = validate(&error_list);
201
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(!m_isValid)
203 qCritical() << "Upon copy-construction of CleavageMotif, the instance "
204 "failed to validate with errors:"
205 << Utils::joinErrorList(error_list, ", ");
206
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
1 }
207
208 /*!
209 \brief Destructs this CleavageMotif instance.
210 */
211 125 CleavageMotif::~CleavageMotif()
212 {
213 125 m_monomers.clear();
214
2/2
✓ Branch 1 taken 124 times.
✓ Branch 2 taken 1 times.
125 }
215
216 /*!
217 \brief Sets the PolChemDef member to \a pol_chem_def_csp.
218
219 This instance then undergoes validation and m_isValid is set to the result of
220 it.
221 */
222 void
223 4 CleavageMotif::setPolChemDefCstSPtr(PolChemDefCstSPtr pol_chem_def_csp)
224 {
225 4 mcsp_polChemDef = pol_chem_def_csp;
226
227 4 ErrorList error_list;
228
229
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 m_isValid = validate(&error_list);
230
231
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(!m_isValid)
232
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 qCritical() << "Upon setting PolChemDef of CleavageMotif, the instance "
233
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 "failed to validate with errors:"
234
3/6
✓ 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.
8 << Utils::joinErrorList(error_list, ", ");
235 4 }
236
237 /*!
238 \brief Returns the \l PolChemDef.
239 */
240 PolChemDefCstSPtr
241 CleavageMotif::getPolChemDefCstSPtr() const
242 {
243 return mcsp_polChemDef;
244 }
245
246 /*!
247 \brief Parses the \a motif and fills-in the member container of Monomers as a
248 result of the parsing.
249
250 \sa parseMotif()
251 */
252 void
253 4 CleavageMotif::setMotif(const QString &motif)
254 {
255
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if(!parseMotif(motif))
256 {
257 qCritical()
258 << "Upon setting motif string of CleavageMotif, the motif could "
259 "not be parsed.";
260 m_isValid = false;
261 }
262
263 // Let's see the other members.
264 4 ErrorList error_list;
265
266
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 m_isValid = validate(&error_list);
267
268
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if(!m_isValid)
269
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 qCritical() << "Upon setting motif of CleavageMotif, the instance "
270
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 "failed to validate with errors:"
271
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 << Utils::joinErrorList(error_list, ", ");
272 4 }
273
274 /*!
275 \brief Returns the motif as a concatenation of the codes of the Monomer
276 instances found in the member container of Monomers.
277 */
278 QString
279 13 CleavageMotif::getMotif() const
280 {
281 13 QString text;
282
283
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 13 times.
31 for(const MonomerSPtr &monomer_csp : m_monomers)
284
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
36 text += monomer_csp->getCode();
285
286 13 return text;
287 }
288
289 /*!
290 \brief Returns a const reference to the container of Monomers.
291 */
292 const std::vector<MonomerSPtr> &
293 298 CleavageMotif::getMonomersCstRef() const
294 {
295 298 return m_monomers;
296 }
297
298 /*!
299 \brief Returns a reference to the container of Monomers.
300 */
301 std::vector<MonomerSPtr> &
302 CleavageMotif::getMonomersRef()
303 {
304 return m_monomers;
305 }
306
307 /*!
308 \brief Sets the \a offset.
309
310 The offset is the position of the cleavage inside the motif, with reset to the
311 first monomer code in that motif. For example, for a cleavage site "Lys/Pro",
312 the cleavage motif becomes {"Lys", "Pro"} and the offset is 1, while for a site
313 "/Asp", the cleavage motif becomes {"Asp"} and the offset is 0.
314
315 An offset value can thus not be greater than the number of Monomer codes in the
316 motif.
317
318 This instance then undergoes validation and m_isValid is set to the result of
319 it.
320 */
321 void
322 2 CleavageMotif::setOffset(int offset)
323 {
324 2 m_offset = offset;
325
326 2 ErrorList error_list;
327
328
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 m_isValid = validate(&error_list);
329
330
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if(!m_isValid)
331
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 qCritical() << "Upon setting offset of CleavageMotif, the instance "
332
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 "failed to validate with errors:"
333
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 << Utils::joinErrorList(error_list, ", ");
334 2 }
335
336 /*!
337 \brief Returns the offset.
338 */
339 int
340 245 CleavageMotif::getOffset() const
341 {
342 245 return m_offset;
343 }
344
345 /*!
346 \brief Sets the member Enums::CleavageAction to \a cleavage_action.
347
348 This instance then undergoes validation and m_isValid is set to the result of
349 it.
350 */
351 void
352 1131 CleavageMotif::setCleavageAction(Enums::CleavageAction cleavage_action)
353 {
354 1131 m_cleavageAction = cleavage_action;
355
356 1131 ErrorList error_list;
357
358
1/2
✓ Branch 1 taken 1131 times.
✗ Branch 2 not taken.
1131 m_isValid = validate(&error_list);
359
360
2/2
✓ Branch 0 taken 1126 times.
✓ Branch 1 taken 5 times.
1131 if(!m_isValid)
361
1/2
✓ Branch 1 taken 1126 times.
✗ Branch 2 not taken.
2252 qCritical()
362 << "Upon setting cleave operation of CleavageMotif, the instance "
363
1/2
✓ Branch 1 taken 1126 times.
✗ Branch 2 not taken.
1126 "failed to validate with errors:"
364
3/6
✓ Branch 1 taken 1126 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1126 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1126 times.
✗ Branch 8 not taken.
2252 << Utils::joinErrorList(error_list, ", ");
365 1131 }
366
367 /*!
368 \brief Returns if motif is for cleavage or not.
369 */
370 Enums::CleavageAction
371 245 CleavageMotif::getCleavageAction() const
372 {
373 245 return m_cleavageAction;
374 }
375
376 /*!
377 \brief Assigns \a other to this CleavageMotif instance.
378
379 This instance then undergoes validation and m_isValid is set to the result of
380 it.
381
382 Returns a reference to this CleavageMotif instance.
383 */
384 CleavageMotif &
385 1 CleavageMotif::operator=(const CleavageMotif &other)
386 {
387
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(&other == this)
388 return *this;
389
390 1 mcsp_polChemDef = other.mcsp_polChemDef;
391 1 m_offset = other.m_offset;
392 1 m_cleavageAction = other.m_cleavageAction;
393
394 1 m_monomers = other.m_monomers;
395
396 1 ErrorList error_list;
397
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 m_isValid = validate(&error_list);
398
399
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(!m_isValid)
400 qCritical() << "Upon assignment of CleavageMotif, the instance "
401 "failed to validate with errors:"
402 << Utils::joinErrorList(error_list, ", ");
403
404 1 return *this;
405 1 }
406
407 /*!
408 \brief Returns true if \c this and \a other are identical.
409
410 The comparison of the Monomer instances in the member container is deep (that is
411 the Monomer instances are compared and not the shared pointers).
412 */
413 bool
414 25 CleavageMotif::operator==(const CleavageMotif &other) const
415 {
416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if(&other == this)
417 return true;
418
419 // Remember that the motif is actually a vector of MonomerSPtr, so when one
420 // does a copy either via the operator ==() or the copy constructor, the
421 // Motifs are going to be the same.
422
423 // If, then one of the MonomerSPtr is changed, the other is changed also.
424
425 // qDebug() << "Now == comparing cleavage motifs:" << this->getMotif()
426 // << "versus" << other.getMotif();
427
428 // We cannot compare the PolChemDef, because that would cause
429 // an infinite loop: (each instance of this class in the PolChemDef would
430 // try to compare the PolChemDef...).
431
432
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if(m_offset != other.m_offset ||
433
2/4
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
25 m_monomers.size() != other.m_monomers.size() ||
434
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 m_cleavageAction != other.m_cleavageAction)
435 {
436 // qDebug() << "Either or both offset or/and cleavage operation differ.";
437 return false;
438 }
439
440
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 49 times.
74 for(std::size_t iter = 0; iter < m_monomers.size(); ++iter)
441 {
442
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49 times.
49 if(*m_monomers.at(iter).get() != *other.m_monomers.at(iter).get())
443 {
444 // qDebug() << "At least one Monomer instance differ in both
445 // CleavageMotif instances.";
446 return false;
447 }
448 }
449
450 return true;
451 }
452
453 /*!
454 \brief Returns true if \c this and \a other are different.
455
456 Returns the negated result of operator==().
457 */
458 bool
459 65 CleavageMotif::operator!=(const CleavageMotif &other) const
460 {
461
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 42 times.
65 if(&other == this)
462 return false;
463
464 23 return !operator==(other);
465 }
466
467 /*!
468 \brief Parses the cleavage \a site and returns the count of Monomer
469 instances stored in the member container as a result of parsing the \a site.
470
471 A cleavage site is a string in the form "Lys/Pro" or "/Asp". The member
472 container of Monomer pointers is filled-in with pointers to the PolChemDef's
473 Monomer instances having codes {Lys, Pro} or {Asp}. The offset is the position
474 of the
475 '/' cleavage symbol (that is, the actual cleavage position in the motif). For
476 "Lys/Pro", the offset is 1 while for "/Asp", the offset is 0.
477
478 After setting the member data, the CleavageMotif instance is validated and
479 m_isValid is set to the result of this validation.
480 */
481 std::size_t
482 1134 CleavageMotif::parseSite(const QString &site)
483 {
484 1134 m_monomers.clear();
485
486
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1134 times.
1134 if(mcsp_polChemDef == nullptr || mcsp_polChemDef.get() == nullptr)
487 {
488 qCritical()
489 << "Cannot parse cleavage site without any available PolChemDef.";
490 m_isValid = false;
491 return 0;
492 }
493
494
2/4
✓ Branch 1 taken 1134 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1134 times.
✗ Branch 5 not taken.
1134 if(site.count('/') == 0 || site.count('/') > 1)
495 {
496 qCritical() << "Cannot parse cleavage site: either missing '/' cleavage "
497 "indicator or more than one.";
498 m_isValid = false;
499 return 0;
500 }
501
502 1134 std::size_t code_length = mcsp_polChemDef->getCodeLength();
503
504 1134 std::size_t monomer_count = 0;
505
506 1134 QRegularExpression single_monomer_code_regexp(
507
2/4
✓ Branch 2 taken 1134 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1134 times.
✗ Branch 6 not taken.
2268 QString("([/]?)([A-Z][a-z]{0,%1})([/]?)").arg(code_length - 1));
508
509
1/2
✓ Branch 1 taken 1134 times.
✗ Branch 2 not taken.
1134 for(const QRegularExpressionMatch &match :
510
4/6
✓ Branch 1 taken 1134 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1134 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1326 times.
✓ Branch 7 taken 1134 times.
2460 single_monomer_code_regexp.globalMatch(site))
511 {
512
1/2
✓ Branch 1 taken 1326 times.
✗ Branch 2 not taken.
1326 QString sub_match = match.captured(0);
513 // qDebug() << "Entering single_monomer_code_regexp sub-match:" <<
514 // sub_match;
515
516
1/2
✓ Branch 1 taken 1326 times.
✗ Branch 2 not taken.
1326 QString ant_cleave = match.captured(1);
517 // qDebug() << "ant_cleave:" << ant_cleave;
518
519
1/2
✓ Branch 1 taken 1326 times.
✗ Branch 2 not taken.
1326 QString code = match.captured(2);
520 // qDebug() << "Parsed code:" << code;
521
522
1/2
✓ Branch 1 taken 1326 times.
✗ Branch 2 not taken.
1326 QString post_cleave = match.captured(3);
523 // qDebug() << "post_cleave:" << post_cleave;
524
525
2/2
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 1052 times.
1326 if(!ant_cleave.isEmpty())
526 274 m_offset = monomer_count;
527
528
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1326 times.
1326 if(code.isEmpty())
529 qFatalStream() << "Programming error: code cannot be empty.";
530
531 1326 const MonomerSPtr monomer_csp =
532
1/2
✓ Branch 1 taken 1326 times.
✗ Branch 2 not taken.
1326 mcsp_polChemDef->getMonomerCstSPtrByCode(code);
533
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1326 times.
1326 if(monomer_csp == nullptr)
534 qFatalStream()
535 << "Programming error. The monomer code must be known to the "
536 "PolChemDef.";
537
538
1/2
✓ Branch 1 taken 1326 times.
✗ Branch 2 not taken.
1326 m_monomers.push_back(monomer_csp);
539 1326 ++monomer_count;
540
541
2/2
✓ Branch 0 taken 860 times.
✓ Branch 1 taken 466 times.
1326 if(!post_cleave.isEmpty())
542 860 m_offset = monomer_count;
543
1/2
✓ Branch 5 taken 1326 times.
✗ Branch 6 not taken.
2460 }
544
545 1134 ErrorList error_list;
546
547
1/2
✓ Branch 1 taken 1134 times.
✗ Branch 2 not taken.
1134 m_isValid = validate(&error_list);
548
549
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1126 times.
1134 if(!m_isValid)
550
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 qCritical() << "Upon parsing cleavage site in CleavageMotif, the instance "
551
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 "failed to validate with errors:"
552
3/6
✓ 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.
16 << Utils::joinErrorList(error_list, ", ");
553
554 1134 return m_monomers.size();
555 1134 }
556
557 /*!
558 \brief Parses the cleavage \a motif and returns the count of Monomer
559 instances stored in m_monomers as a result of parsing the \a motif.
560
561 A cleavage motif is a string in the form "LysPro" or "Asp" (in fact that is
562 the string representation of a \l{Sequence}).
563 */
564 std::size_t
565 8 CleavageMotif::parseMotif(const QString &motif)
566 {
567 8 m_monomers.clear();
568
569
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if(mcsp_polChemDef == nullptr || mcsp_polChemDef.get() == nullptr)
570 {
571 qCritical() << "Cannot parse motif without any available PolChemDef;";
572 m_isValid = false;
573 return 0;
574 }
575
576
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 Sequence motif_sequence(mcsp_polChemDef, motif);
577
578 8 ErrorList error_list;
579
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
8 if(!motif_sequence.validate(&error_list))
580 {
581 qCritical()
582 << "The motif" << motif
583 << "failed to convert to a valid Sequence object, with errors:"
584 << Utils::joinErrorList(error_list, ", ");
585 m_isValid = false;
586 return 0;
587 }
588
589
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 motif_sequence.cleanupMonomers();
590
3/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
✓ Branch 4 taken 8 times.
35 for(const MonomerSPtr &monomer_sp : motif_sequence.getMonomersCstRef())
591 {
592
1/2
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
27 m_monomers.push_back(monomer_sp);
593 // qDebug() << "Pushed back monomer:" << monomer_csp->toString();
594 }
595
596 8 return m_monomers.size();
597 8 }
598
599 /*!
600 \brief Returns true if validation of this CleavageMotif instance was successful,
601 false otherwise.
602
603 If errors are encountered and \a error_list_p is not nullptr, then these error are stored in that ErrorList.
604 */
605 bool
606 3582 CleavageMotif::validate(ErrorList *error_list_p) const
607 {
608 3582 m_isValid = true;
609
610
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3581 times.
3582 if(mcsp_polChemDef == nullptr || mcsp_polChemDef.get() == nullptr)
611 {
612 2 qCritical() << "A CleavageMotif with no PolChemDef available cannot "
613
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 "validate successfully.";
614
615 1 m_isValid = false;
616
617
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(error_list_p != nullptr)
618 2 error_list_p->push_back(
619 "A CleavageMotif with no PolChemDef available cannot validate "
620 "successfully");
621 }
622
623
2/2
✓ Branch 0 taken 1132 times.
✓ Branch 1 taken 2450 times.
3582 if(m_monomers.size() == 0)
624 {
625 2264 qCritical() << "A CleavageMotif with no Monomer motif cannot validate "
626
1/2
✓ Branch 1 taken 1132 times.
✗ Branch 2 not taken.
1132 "successfully.";
627
628 1132 m_isValid = false;
629
630
1/2
✓ Branch 0 taken 1132 times.
✗ Branch 1 not taken.
1132 if(error_list_p != nullptr)
631 2264 error_list_p->push_back(
632 "A CleavageMotif with no Monomer motif cannot validate successfully");
633 }
634
635
2/2
✓ Branch 0 taken 1135 times.
✓ Branch 1 taken 2447 times.
3582 if(m_offset > m_monomers.size())
636 {
637 2270 qCritical()
638 << "A CleavageMotif with an offset greater than the number of "
639
1/2
✓ Branch 1 taken 1135 times.
✗ Branch 2 not taken.
1135 "Monomer codes in the motif cannot validate successfully.";
640
641 1135 m_isValid = false;
642
643
1/2
✓ Branch 0 taken 1135 times.
✗ Branch 1 not taken.
1135 if(error_list_p != nullptr)
644 2270 error_list_p->push_back(
645 "A CleavageMotif with an offset greater than the number of "
646 "Monomer codes in the motif cannot validate successfully");
647 }
648
649
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 3557 times.
3582 if(m_cleavageAction == Enums::CleavageAction::NOT_SET)
650 {
651 50 qCritical() << "A CleavageMotif with no set Enums::CleavageAction cannot "
652
1/2
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
25 "validate successfully.";
653
654 25 m_isValid = false;
655
656
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if(error_list_p != nullptr)
657 50 error_list_p->push_back(
658 "A CleavageMotif with no set Enums::CleavageAction cannot validate "
659 "successfully");
660 }
661
662 3582 return m_isValid;
663 }
664
665 /*
666 \brief Returns the validity status of this CleavageMotif instance.
667 */
668 bool
669 1154 CleavageMotif::isValid() const
670 {
671 1154 return m_isValid;
672 }
673
674
675 } // namespace libXpertMassCore
676 } // namespace MsXpS
677