libpappsomspp
Library for mass spectrometry
msrundatasettreenode.cpp
Go to the documentation of this file.
1 // GPL 3+
2 // Filippo Rusconi
3 
4 /////////////////////// StdLib includes
5 #include <string>
6 #include <vector>
7 #include <iostream>
8 #include <iomanip>
9 
10 
11 /////////////////////// Qt includes
12 #include <QDebug>
13 
14 
15 /////////////////////// pwiz includes
16 
17 
18 /////////////////////// Local includes
19 #include "../exception/exceptionnotpossible.h"
20 #include "msrundatasettreenode.h"
21 #include "../utils.h"
22 
23 
24 namespace pappso
25 {
26 
27 
29 {
30 }
31 
32 
34  QualifiedMassSpectrumCstSPtr mass_spectrum_csp,
35  MsRunDataSetTreeNode *parent_p)
36  : mcsp_massSpectrum(mass_spectrum_csp), mp_parent(parent_p)
37 {
38 }
39 
40 
42  : mcsp_massSpectrum(other.mcsp_massSpectrum), mp_parent(other.mp_parent)
43 {
44  for(auto &&node : other.m_children)
45  m_children.push_back(new MsRunDataSetTreeNode(*node));
46 }
47 
48 
50 {
51  for(auto &&node : m_children)
52  delete node;
53 
54  m_children.clear();
55 }
56 
57 
60 {
61  if(this == &other)
62  return *this;
63 
65  mp_parent = other.mp_parent;
66 
67  for(auto &&node : other.m_children)
68  m_children.push_back(new MsRunDataSetTreeNode(*node));
69 
70  return *this;
71 }
72 
73 void
75  QualifiedMassSpectrumCstSPtr qualified_mass_spectrum_csp)
76 {
77  mcsp_massSpectrum = qualified_mass_spectrum_csp;
78 }
79 
80 
83 {
84  return mcsp_massSpectrum;
85 }
86 
87 
88 void
90 {
91  mp_parent = parent;
92 }
93 
94 
97 {
98  // qDebug();
99 
100  return mp_parent;
101 }
102 
103 
104 bool
106 {
107  // qDebug();
108 
109  if(mp_parent != nullptr)
110  return true;
111  else
112  return false;
113 }
114 
115 
116 void
117 MsRunDataSetTreeNode::size(std::size_t &cumulative_node_count) const
118 {
119 
120  // First account for this node.
121  ++cumulative_node_count;
122 
123  // Then ask for each child to recursively account for themselves and their
124  // children.
125 
126  for(auto &&node : m_children)
127  {
128  node->size(cumulative_node_count);
129  }
130 }
131 
132 
134 MsRunDataSetTreeNode::findNode(std::size_t spectrum_index)
135 {
136  // qDebug();
137 
138  // Finding a node that contains a qualified mass spectrum that has been
139  // acquired at spectrum_index, requires checking if that node is not *this and
140  // if not if it is not one of the children. By essence, this work is
141  // recursive.
142 
143  if(mcsp_massSpectrum->getMassSpectrumId().getSpectrumIndex() ==
144  spectrum_index)
145  {
146  // qDebug() << "The mass spectrum's node is this node.";
147 
148  return this;
149  }
150 
151  // qDebug() << "Need to go searching in the children.";
152 
153  for(auto &node : m_children)
154  {
155  MsRunDataSetTreeNode *iterNode = node->findNode(spectrum_index);
156 
157  if(iterNode != nullptr)
158  {
159  // qDebug() << "Found the mass spectrum's node.";
160 
161  return iterNode;
162  }
163  }
164 
165  return nullptr;
166 }
167 
168 
171 {
172  // qDebug();
173 
174  // Finding a node that contains a qualified mass spectrum requires checking if
175  // that node is not *this and if not if it is not one of the children. By
176  // essence, this work is recursive.
177 
178  if(mass_spectrum_csp == mcsp_massSpectrum)
179  {
180  // qDebug() << "The mass spectrum's node is this node.";
181 
182  return this;
183  }
184 
185  // qDebug() << "Need to go searching in the children.";
186 
187  for(auto &node : m_children)
188  {
189  MsRunDataSetTreeNode *iterNode = node->findNode(mass_spectrum_csp);
190 
191  if(iterNode != nullptr)
192  {
193  // qDebug() << "Found the mass spectrum's node.";
194 
195  return iterNode;
196  }
197  }
198 
199  return nullptr;
200 }
201 
202 
203 void
204 MsRunDataSetTreeNode::flattenedView(std::vector<MsRunDataSetTreeNode *> &nodes,
205  bool with_descendants)
206 {
207 
208  // Do store this.
209 
210  nodes.push_back(this);
211 
212  // And now the descendants.
213 
214  if(with_descendants)
215  {
216  for(auto &&node : m_children)
217  {
218  node->flattenedView(nodes, with_descendants);
219  }
220  }
221  else
222  {
223  }
224 }
225 
226 
227 void
229  std::vector<MsRunDataSetTreeNode *> &nodes, bool with_descendants)
230 {
231 
232  // Do not store this, only this->m_children !
233 
234  for(auto &&node : m_children)
235  node->flattenedView(nodes, with_descendants);
236 }
237 
238 
239 void
241  std::size_t ms_level,
242  std::size_t depth,
243  std::vector<MsRunDataSetTreeNode *> &nodes,
244  bool with_descendants)
245 {
246 
247  if(ms_level == (depth + 1))
248  {
249 
250  // There we are. The ms_level that is asked matches the current depth of
251  // the node we are in.
252 
253  flattenedView(nodes, with_descendants);
254  }
255  else if(ms_level > (depth + 1))
256  {
257  // We still do not have to store the nodes, because what we are
258  // searching is down the tree...
259 
260  for(auto &&node : m_children)
261  {
262  node->flattenedViewMsLevelNodes(
263  ms_level, depth + 1, nodes, with_descendants);
264  }
265  }
266 }
267 
268 
269 std::vector<MsRunDataSetTreeNode *>
271  pappso_double precursor_mz,
272  PrecisionPtr precision_ptr,
273  std::vector<MsRunDataSetTreeNode *> &nodes)
274 {
275  if(precision_ptr == nullptr)
276  throw ExceptionNotPossible(
277  QObject::tr("Fatal error at msrundatasettreenode.cpp "
278  "-- ERROR precision_ptr cannot be nullptr. "
279  "Program aborted."));
280 
281  // Check if this node matches the requirements.
282 
283  pappso_double mz = mcsp_massSpectrum->getPrecursorMz();
284 
285  if(mz != std::numeric_limits<double>::max())
286  {
287 
288  // Calculate the mz range using the tolerance.
289 
290  pappso_double lower_mz =
291  precursor_mz - (precision_ptr->delta(precursor_mz) / 2);
292  pappso_double upper_mz =
293  precursor_mz + (precision_ptr->delta(precursor_mz) / 2);
294 
295  if(mz >= lower_mz && mz <= upper_mz)
296  {
297  // We are iterating in a node that holds a mass spectrum that was
298  // acquired by fragmenting an ion that matches the searched mz value.
299 
300  nodes.push_back(this);
301  }
302  }
303 
304  // Now handle in the same way, but recursively, all the children of this node.
305 
306  for(auto &&node : m_children)
307  {
308  node->productNodesByPrecursorMz(precursor_mz, precision_ptr, nodes);
309  }
310 
311  return nodes;
312 }
313 
314 
315 std::vector<MsRunDataSetTreeNode *>
317  pappso_double precursor_mz,
318  PrecisionPtr precision_ptr,
319  std::vector<MsRunDataSetTreeNode *> &nodes)
320 {
321  if(precision_ptr == nullptr)
322  throw ExceptionNotPossible(
323  QObject::tr("Fatal error at msrundatasettreenode.cpp "
324  "-- ERROR precision_ptr cannot be nullptr. "
325  "Program aborted."));
326 
327  // Calculate the mz range using the tolerance.
328  pappso_double lower_mz =
329  precursor_mz - (precision_ptr->delta(precursor_mz) / 2);
330  pappso_double upper_mz =
331  precursor_mz + (precision_ptr->delta(precursor_mz) / 2);
332 
333  // Check if this node matches the requirements.
334 
335  pappso_double mz = mcsp_massSpectrum->getPrecursorMz();
336 
337  if(mz != std::numeric_limits<double>::max())
338  {
339  if(mz >= lower_mz && mz <= upper_mz)
340  {
341  // We are iterating in a node that hold a mass spectrum that was
342  // acquired by fragmenting an ion matching the searched mz value. We
343  // can extract the spectrum index of that precursor mass spectrum and
344  // then get its corresponding node, that we'll store.
345 
346  std::size_t precursor_spectrum_index =
347  mcsp_massSpectrum->getPrecursorSpectrumIndex();
348 
349  MsRunDataSetTreeNode *found_node = findNode(precursor_spectrum_index);
350 
351  if(precursor_spectrum_index !=
352  found_node->mcsp_massSpectrum->getMassSpectrumId()
353  .getSpectrumIndex())
354  throw ExceptionNotPossible(
355  QObject::tr("Fatal error at msrundatasettreenode.cpp "
356  "-- ERROR precursor_spectrum_index bad value. "
357  "Program aborted."));
358 
359  nodes.push_back(found_node);
360  }
361  }
362 
363  // Now handle in the same way, but recursively, all the children of this node.
364 
365  for(auto &&node : m_children)
366  {
367  node->precursorIonNodesByPrecursorMz(precursor_mz, precision_ptr, nodes);
368  }
369 
370  return nodes;
371 }
372 
373 
374 void
376 {
377  // qDebug() << "now calling visitor.visit(*this);";
378 
379  visitor.visit(*this);
380 
381  // qDebug() << "and now calling node->accept(visitor) for each child node.";
382 
383  visitor.setNodesToProcessCount(m_children.size());
384 
385  for(auto &&node : m_children)
386  node->accept(visitor);
387 }
388 
389 
390 std::size_t
391 MsRunDataSetTreeNode::depth(std::size_t depth) const
392 {
393 
394  // qDebug() << "Got depth:" << depth;
395 
396  // If there are no children in this node, that is the end of the tree.
397  // Do not change anything an return.
398 
399  if(!m_children.size())
400  {
401  // qDebug() << "No children, returning" << depth;
402 
403  return depth;
404  }
405 
406  // qDebug() << "There are" << m_children.size() << "children nodes";
407 
408 
409  // At this point we know we can already increment depth by one because
410  // we go down one level by iterating in the m_children vector of nodes.
411 
412  // qDebug() << "Children found, incrementing depth to" << depth + 1;
413 
414  std::size_t local_depth = depth + 1;
415 
416  std::size_t tmp_depth = 0;
417  std::size_t greatest_depth = 0;
418 
419  for(auto &node : m_children)
420  {
421  // qDebug() << "In the children for loop";
422 
423  tmp_depth = node->depth(local_depth);
424 
425  // qDebug() << "Got depth from iterated node:" << tmp_depth;
426 
427  if(tmp_depth > greatest_depth)
428  greatest_depth = tmp_depth;
429  }
430 
431  // qDebug() << "Returning:" << greatest_depth;
432 
433  return greatest_depth;
434 }
435 
436 
437 QString
439 {
440  return QString("mcsp_massSpectrum: %1 ; to string: %2 ; children: %3\n")
442  const_cast<QualifiedMassSpectrum *>(mcsp_massSpectrum.get())))
443  .arg(mcsp_massSpectrum->toString())
444  .arg(m_children.size());
445 }
446 
447 } // namespace pappso
virtual void setNodesToProcessCount(std::size_t)=0
virtual bool visit(const MsRunDataSetTreeNode &node)=0
std::vector< MsRunDataSetTreeNode * > precursorIonNodesByPrecursorMz(pappso_double precursor_mz, PrecisionPtr precision_ptr, std::vector< MsRunDataSetTreeNode * > &nodes)
void flattenedView(std::vector< MsRunDataSetTreeNode * > &nodes, bool with_descendants=false)
void flattenedViewChildrenOnly(std::vector< MsRunDataSetTreeNode * > &nodes, bool with_descendants=false)
QualifiedMassSpectrumCstSPtr mcsp_massSpectrum
QualifiedMassSpectrumCstSPtr getQualifiedMassSpectrum() const
void flattenedViewMsLevelNodes(std::size_t ms_level, std::size_t depth, std::vector< MsRunDataSetTreeNode * > &nodes, bool with_descendants=false)
std::size_t depth(std::size_t depth) const
void setParent(MsRunDataSetTreeNode *parent)
void size(std::size_t &cumulative_node_count) const
MsRunDataSetTreeNode * getParent() const
MsRunDataSetTreeNode * mp_parent
void accept(MsRunDataSetTreeNodeVisitorInterface &visitor)
void setQualifiedMassSpectrum(QualifiedMassSpectrumCstSPtr qualified_mass_spectrum_csp)
MsRunDataSetTreeNode * findNode(std::size_t spectrum_index)
std::vector< MsRunDataSetTreeNode * > m_children
std::vector< MsRunDataSetTreeNode * > productNodesByPrecursorMz(pappso_double precursor_mz, PrecisionPtr precision_ptr, std::vector< MsRunDataSetTreeNode * > &nodes)
MsRunDataSetTreeNode & operator=(const MsRunDataSetTreeNode &other)
virtual pappso_double delta(pappso_double value) const =0
Class representing a fully specified mass spectrum.
static QString pointerToString(const void *const pointer)
Definition: utils.cpp:251
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition: aa.cpp:39
double pappso_double
A type definition for doubles.
Definition: types.h:49
std::shared_ptr< const QualifiedMassSpectrum > QualifiedMassSpectrumCstSPtr