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