libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
timsdiaslices.cpp
Go to the documentation of this file.
1/**
2 * \file pappsomspp/vendors/tims/timsdiaslices.cpp
3 * \date 02/07/2024
4 * \brief handle specific data for DIA MS runs
5 */
6
7/*******************************************************************************
8 * Copyright (c) 2024 Olivier Langella <Olivier.Langella@u-psud.fr>.
9 *
10 * This file is part of the PAPPSOms++ library.
11 *
12 * PAPPSOms++ is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * PAPPSOms++ is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with PAPPSOms++. If not, see <http://www.gnu.org/licenses/>.
24 *
25 ******************************************************************************/
26
27#include "timsdiaslices.h"
29
30#include <iterator>
31#include <QSqlError>
32
33namespace pappso
34{
35
36bool
38{
39 double half_window = IsolationWidth / 2;
40 if(mz < (IsolationMz - half_window))
41 return false;
42 if(mz > (IsolationMz + half_window))
43 return false;
44 return true;
45}
46
48{
49 for(MsMsWindowGroup *p_group : *this)
50 {
51 delete p_group;
52 }
53}
54
55void
57{
58 std::size_t group_id = window.WindowGroup;
59 auto it_in_list = std::find_if(begin(), end(), [group_id](const MsMsWindowGroup *group) {
60 if(group->WindowGroup == group_id)
61 return true;
62 return false;
63 });
64 if(it_in_list == end())
65 {
66
67 qDebug();
68 MsMsWindowGroup *new_group = new MsMsWindowGroup();
69 new_group->WindowGroup = group_id;
70 new_group->push_back(window);
71 push_back(new_group);
72 }
73 else
74 {
75 qDebug();
76 (*it_in_list)->push_back(window);
77
78 std::sort(
79 (*it_in_list)->begin(), (*it_in_list)->end(), [](const MsMsWindow &a, const MsMsWindow &b) {
80 return (a.ScanNumBegin < b.ScanNumBegin);
81 });
82 std::size_t i = 0;
83 for(MsMsWindow &window : *(*it_in_list))
84 {
85 window.SliceIndex = i;
86 i++;
87 }
88 }
89 qDebug();
90}
91
94{
95
96 auto it_in_list = std::find_if(begin(), end(), [window_group_id](const MsMsWindowGroup *group) {
97 if(group->WindowGroup == window_group_id)
98 return true;
99 return false;
100 });
101
102 if(it_in_list == end())
103 {
105 QObject::tr("MsMsWindowGroup %1 not found").arg(window_group_id));
106 }
107 return *it_in_list;
108}
109
110TimsDiaSlices::TimsDiaSlices(QSqlQuery &query, TimsData *tims_data_origin)
111 : mp_timsDataOrigin(tims_data_origin)
112{
113
114 /*
115CREATE TABLE IF NOT EXISTS "DiaFrameMsMsWindows" (
116"WindowGroup" INTEGER NOT NULL,
117"ScanNumBegin" INTEGER NOT NULL,
118"ScanNumEnd" INTEGER NOT NULL,
119"IsolationMz" REAL NOT NULL,
120"IsolationWidth" REAL NOT NULL,
121"CollisionEnergy" REAL NOT NULL,
122FOREIGN KEY("WindowGroup") REFERENCES "FrameMsMsWindowGroups"("Id"),
123PRIMARY KEY("WindowGroup","ScanNumBegin")
124) WITHOUT ROWID;
125*/
126
127 if(!query.exec("SELECT WindowGroup, ScanNumBegin, ScanNumEnd, IsolationMz, "
128 "IsolationWidth, CollisionEnergy FROM DiaFrameMsMsWindows;"))
129 {
130 qDebug();
131 throw ExceptionNotFound(QObject::tr("ERROR : executing %1 :\n%2")
132 .arg(query.lastQuery())
133 .arg(query.lastError().text()));
134 }
135 else
136 {
137
138 qDebug() << query.size();
139 if(query.size() == 0)
140 {
141 qDebug();
142 // FIXME: this exception is thrown, but my file is DDA.
143 // That's not a nice info...
144 throw ExceptionNotFound(
145 QObject::tr("ERROR : DiaFrameMsMsWindows table is empty in SqlLite database"));
146 }
147 MsMsWindow msms_window;
148 while(query.next())
149 {
150 qDebug();
151 msms_window.WindowGroup = query.value(0).toLongLong();
152 msms_window.ScanNumBegin = query.value(1).toLongLong();
153 msms_window.ScanNumEnd = query.value(2).toLongLong();
154 msms_window.IsolationMz = query.value(3).toDouble();
155 msms_window.IsolationWidth = query.value(4).toDouble();
156 msms_window.CollisionEnergy = query.value(5).toDouble();
157
158 qDebug();
159 m_msMsWindowGroupList.addInGroup(msms_window);
160 }
161
162 if(m_msMsWindowGroupList.size() == 0)
163 {
164 qDebug();
165 // FIXME: this exception is thrown, but my file is DDA.
166 // That's not a nice info...
167 throw ExceptionNotFound(
168 QObject::tr("ERROR : no DiaFrameMsMsWindows in SqlLite database"));
169 }
170 }
171
172 qDebug();
173 std::size_t max_frame_id = 0;
174 if(!query.exec("SELECT Frame, WindowGroup FROM DiaFrameMsMsInfo;"))
175 {
176 qDebug();
178 QObject::tr("ERROR : no DiaFrameMsMsInfo in SqlLite database"));
179 }
180 else
181 {
182 qDebug() << query.size();
183 if(query.size() == 0)
184 {
185 qDebug();
187 QObject::tr("ERROR : no DiaFrameMsMsInfo in SqlLite database"));
188 }
189 while(query.next())
190 {
191 qDebug();
192 max_frame_id = query.value(0).toLongLong();
193 m_mapFrame2WindowGroupPtr[query.value(0).toLongLong()] =
194 m_msMsWindowGroupList.getWindowGroupPtrByGroupId(query.value(1).toLongLong());
195 }
196
197 if(m_mapFrame2WindowGroupPtr.size() == 0)
198 {
199 qDebug();
200 throw ExceptionNotFound(QObject::tr("ERROR : no DiaFrameMsMsInfo in SqlLite database"));
201 }
202 }
203 qDebug();
204
205 m_frameId2GlobalSliceIndexBegin.resize(max_frame_id + 1);
206
207 m_ms2frameId2Ms1FrameId.resize(max_frame_id + 1);
208 std::size_t last_ms1 = 0;
209 std::size_t previous_frame = 0;
210
211 std::size_t cumul_global_slice = 0;
212 m_ms1frameIdList.clear();
213 for(const std::pair<std::size_t, MsMsWindowGroup *> pair_frame_pgroup : m_mapFrame2WindowGroupPtr)
214 {
215 if(previous_frame != pair_frame_pgroup.first - 1)
216 {
217 last_ms1 = previous_frame + 1;
218 m_ms1frameIdList.push_back(last_ms1);
219 }
220 previous_frame = pair_frame_pgroup.first;
221 qDebug() << pair_frame_pgroup.first << " " << m_frameId2GlobalSliceIndexBegin.size();
222 FrameSliceRange slice_range;
223 qDebug() << pair_frame_pgroup.first;
224 slice_range.frame_id = pair_frame_pgroup.first;
225 slice_range.begin_global_slice_index = cumul_global_slice;
226 m_frameId2GlobalSliceIndexBegin[pair_frame_pgroup.first] = cumul_global_slice;
227 m_ms2frameId2Ms1FrameId[pair_frame_pgroup.first] = last_ms1;
228
229 cumul_global_slice += pair_frame_pgroup.second->size();
230
231 if(cumul_global_slice > 0)
232 slice_range.end_global_slice_index = cumul_global_slice - 1;
233 m_frameSliceRangeList.push_back(slice_range);
234 }
235
236 qDebug();
237 m_totalSlicesCount = cumul_global_slice;
238}
239
243
244const std::map<std::size_t, TimsDiaSlices::MsMsWindowGroup *> &
254
255std::size_t
257{
258 return (m_frameId2GlobalSliceIndexBegin[frame_id]);
259}
260std::size_t
261TimsDiaSlices::getFrameIdByGlobalSliceIndex(std::size_t global_slice_id) const
262{
263 return (getFrameSliceRangeByGlobalSliceIndex(global_slice_id).frame_id);
264}
265
267TimsDiaSlices::getFrameSliceRangeByGlobalSliceIndex(std::size_t global_slice_index) const
268{
269
270 qDebug();
271 auto it = std::find_if(m_frameSliceRangeList.cbegin(),
273 [global_slice_index](const FrameSliceRange &x) {
274 if(global_slice_index < x.begin_global_slice_index)
275 return false;
276 if(global_slice_index > x.end_global_slice_index)
277 return false;
278 return true;
279 });
280
281 if(it != m_frameSliceRangeList.cend())
282 {
283 return *it;
284 }
285 qDebug();
286 throw ExceptionNotFound(
287 QObject::tr("ERROR : GlobalSliceIndex %1 not found").arg(global_slice_index));
288}
289
290std::size_t
295
297TimsDiaSlices::getMsMsWindowByGlobalSliceIndex(std::size_t global_slice_index) const
298{
299 qDebug() << global_slice_index;
300 const TimsDiaSlices::FrameSliceRange &range =
301 getFrameSliceRangeByGlobalSliceIndex(global_slice_index);
302
303 qDebug() << "range.frame_id=" << range.frame_id
304 << " range.begin_global_slice_index=" << range.begin_global_slice_index;
305 return m_mapFrame2WindowGroupPtr.at(range.frame_id)
306 ->at(global_slice_index - range.begin_global_slice_index);
307}
308
309std::size_t
311{
312
313 return m_ms2frameId2Ms1FrameId.at(frame_id);
314}
315
316
318TimsDiaSlices::getCombinedMs2ScansByGlobalSliceIndex(std::size_t global_slice_index) const
319{
320
321 qDebug();
323 raw_spectrum.clear();
324 try
325 {
326 FrameSliceRange range = getFrameSliceRangeByGlobalSliceIndex(global_slice_index);
327
329 ->at(global_slice_index - range.begin_global_slice_index);
330 qDebug();
331 TimsFrameCstSPtr tims_frame;
332 tims_frame = mp_timsDataOrigin->getTimsFrameCstSPtrCached(range.frame_id);
333 qDebug();
334 /*combiner.combine(combiner_result,
335 tims_frame.get()->cumulateScanToTrace(
336 scan_mobility_start, scan_mobility_end));*/
337 tims_frame.get()->combineScansInTofIndexIntensityMap(
338 raw_spectrum, window.ScanNumBegin, window.ScanNumEnd);
339 qDebug();
340 }
341
342 catch(PappsoException &error)
343 {
344 throw PappsoException(QObject::tr("ERROR in %1 (global_slice_index=%2):\n%3")
345 .arg(__FUNCTION__)
346 .arg(global_slice_index)
347 .arg(error.qwhat()));
348 }
349 catch(std::exception &error)
350 {
351 qDebug() << QString("Failure %1 ").arg(error.what());
352 }
353 return raw_spectrum;
354 qDebug();
355}
356void
358 QualifiedMassSpectrum &mass_spectrum,
359 std::size_t global_slice_index,
360 bool want_binary_data) const
361{
362
363 qDebug();
364 try
365 {
366 FrameSliceRange range = getFrameSliceRangeByGlobalSliceIndex(global_slice_index);
367
369 ->at(global_slice_index - range.begin_global_slice_index);
370
371 MassSpectrumId spectrum_id;
372
373 spectrum_id.setSpectrumIndex(global_slice_index);
374 spectrum_id.setNativeId(
375 QString("global_slice_index=%1 frame=%2 begin=%3 end=%4 group=%5 slice=%6")
376 .arg(global_slice_index)
377 .arg(range.frame_id)
378 .arg(window.ScanNumBegin)
379 .arg(window.ScanNumEnd)
380 .arg(window.WindowGroup)
381 .arg(window.SliceIndex));
382
383 spectrum_id.setMsRunId(msrun_id);
384
385 mass_spectrum.setMassSpectrumId(spectrum_id);
386
387 mass_spectrum.setMsLevel(2);
388 // mass_spectrum.setPrecursorSpectrumIndex(spectrum_descr.ms1_index);
389
390 mass_spectrum.setEmptyMassSpectrum(true);
391
392 qDebug();
393
394 // get precursor ion data
395
396 // mass_spectrum.appendPrecursorIonData(spectrum_descr.precursor_ion_data);
397
398 mass_spectrum.setPrecursorNativeId(QString("frame_id=%1 begin=%2 end=%3 group=%4 slice=%5")
399 .arg(m_ms2frameId2Ms1FrameId.at(range.frame_id))
400 .arg(window.ScanNumBegin)
401 .arg(window.ScanNumEnd)
402 .arg(window.WindowGroup)
403 .arg(window.SliceIndex));
404
406 window.IsolationMz);
408 window.IsolationWidth);
409
411 window.CollisionEnergy);
412
413
414 qDebug() << window.ScanNumBegin;
416 (qulonglong)window.ScanNumBegin);
417
418
419 qDebug() << window.ScanNumEnd;
421 (qulonglong)window.ScanNumEnd);
422 qDebug();
423 TimsFrameBaseCstSPtr tims_frame;
424
425
426 if(want_binary_data)
427 {
428 qDebug() << "bindec";
429 tims_frame = mp_timsDataOrigin->getTimsFrameCstSPtrCached(range.frame_id);
430 }
431 else
432 {
433 tims_frame = mp_timsDataOrigin->getTimsFrameBaseCstSPtrCached(range.frame_id);
434 }
435
436 mass_spectrum.setRtInSeconds(tims_frame.get()->getRtInSeconds());
437
438
439 mass_spectrum.setParameterValue(
441 tims_frame.get()->getOneOverK0Transformation(window.ScanNumBegin));
442
443 mass_spectrum.setParameterValue(
445 tims_frame.get()->getOneOverK0Transformation(window.ScanNumEnd));
446
447 qDebug();
448 /*combiner.combine(combiner_result,
449 tims_frame.get()->cumulateScanToTrace(
450 scan_mobility_start, scan_mobility_end));*/
451 if(want_binary_data)
452 {
453
455 raw_spectrum.clear();
456 tims_frame.get()->combineScansInTofIndexIntensityMap(
457 raw_spectrum, window.ScanNumBegin, window.ScanNumEnd);
458
459
460 Trace trace;
462 {
463 // raw_spectrum.removeArtefactualSpike();
464 raw_spectrum.builtInCentroid();
465 }
466
467 trace = tims_frame.get()->getTraceFromTofIndexIntensityMap(raw_spectrum);
468
469 if(trace.size() > 0)
470 {
471 mass_spectrum.setMassSpectrumSPtr(MassSpectrum(trace).makeMassSpectrumSPtr());
472 mass_spectrum.setEmptyMassSpectrum(false);
473 }
474 else
475 {
476 mass_spectrum.setMassSpectrumSPtr(nullptr);
477 mass_spectrum.setEmptyMassSpectrum(true);
478 }
479 }
480 qDebug();
481 }
482
483 catch(PappsoException &error)
484 {
485 throw PappsoException(QObject::tr("ERROR in %1 (global_slice_index=%2):\n%3")
486 .arg(__FUNCTION__)
487 .arg(global_slice_index)
488 .arg(error.qwhat()));
489 }
490 catch(std::exception &error)
491 {
492 qDebug() << QString("Failure %1 ").arg(error.what());
493 }
494 qDebug();
495}
496
497void
499 QualifiedMassSpectrum &mass_spectrum,
500 std::size_t global_slice_index,
501 bool want_binary_data,
502 int rt_position) const
503{
504
505 qDebug();
506 try
507 {
508 FrameSliceRange range = getFrameSliceRangeByGlobalSliceIndex(global_slice_index);
509
511 ->at(global_slice_index - range.begin_global_slice_index);
512
513 std::size_t ms1_frame_id = getLastMs1FrameIdByMs2FrameId(range.frame_id);
514 if(rt_position != 0)
515 {
516 std::size_t i = 0;
517 for(i = 0; i < m_ms1frameIdList.size(); i++)
518 {
519 if(m_ms1frameIdList.at(i) == ms1_frame_id)
520 break;
521 }
522 long index = (long)i + rt_position;
523 if((index > -1) && (index < (long)m_ms1frameIdList.size()))
524 ms1_frame_id = m_ms1frameIdList.at(index);
525 }
526
527 MassSpectrumId spectrum_id;
528
529 spectrum_id.setSpectrumIndex(global_slice_index);
530 spectrum_id.setNativeId(
531 QString("global_slice_index=%1 frame=%2 begin=%3 end=%4 group=%5 slice=%6")
532 .arg(global_slice_index)
533 .arg(ms1_frame_id)
534 .arg(window.ScanNumBegin)
535 .arg(window.ScanNumEnd)
536 .arg(window.WindowGroup)
537 .arg(window.SliceIndex));
538
539 spectrum_id.setMsRunId(msrun_id);
540
541 mass_spectrum.setMassSpectrumId(spectrum_id);
542
543 mass_spectrum.setMsLevel(1);
544 // mass_spectrum.setPrecursorSpectrumIndex(spectrum_descr.ms1_index);
545
546 mass_spectrum.setEmptyMassSpectrum(true);
547
548 qDebug();
549
550 // get precursor ion data
551
552 // mass_spectrum.appendPrecursorIonData(spectrum_descr.precursor_ion_data);
553
554
555 qDebug() << window.ScanNumBegin;
557 (qulonglong)window.ScanNumBegin);
558
559
560 qDebug() << window.ScanNumEnd;
562 (qulonglong)window.ScanNumEnd);
563 qDebug();
564 TimsFrameBaseCstSPtr tims_frame;
565
566
567 if(want_binary_data)
568 {
569 qDebug() << "bindec";
570 tims_frame = mp_timsDataOrigin->getTimsFrameCstSPtrCached(ms1_frame_id);
571 }
572 else
573 {
574 tims_frame = mp_timsDataOrigin->getTimsFrameBaseCstSPtrCached(ms1_frame_id);
575 }
576 mass_spectrum.setRtInSeconds(tims_frame.get()->getRtInSeconds());
577
578
579 mass_spectrum.setParameterValue(
581 tims_frame.get()->getOneOverK0Transformation(window.ScanNumBegin));
582
583 mass_spectrum.setParameterValue(
585 tims_frame.get()->getOneOverK0Transformation(window.ScanNumEnd));
586
587 qDebug();
588 /*combiner.combine(combiner_result,
589 tims_frame.get()->cumulateScanToTrace(
590 scan_mobility_start, scan_mobility_end));*/
591 if(want_binary_data)
592 {
593
594 double mz = (window.IsolationMz - (window.IsolationWidth / 2));
595 qDebug() << mz;
596
597 quint32 tof_index_begin =
598 tims_frame.get()->getMzCalibrationInterfaceSPtr().get()->getTofIndexFromMz(mz);
599
600 mz = (window.IsolationMz + (window.IsolationWidth / 2));
601 qDebug() << mz;
602 quint32 tof_index_end =
603 tims_frame.get()->getMzCalibrationInterfaceSPtr().get()->getTofIndexFromMz(mz);
604
605 qDebug() << "tof_index_begin=" << tof_index_begin << " tof_index_end=" << tof_index_end;
606
608 raw_spectrum.clear();
609 tims_frame.get()->combineScansInTofIndexIntensityMap(
610 raw_spectrum, window.ScanNumBegin, window.ScanNumEnd, tof_index_begin, tof_index_end);
611
612
613 Trace trace;
615 {
616 // raw_spectrum.removeArtefactualSpike();
617 raw_spectrum.builtInCentroid();
618 }
619
620 trace = tims_frame.get()->getTraceFromTofIndexIntensityMap(raw_spectrum);
621
622 if(trace.size() > 0)
623 {
624 mass_spectrum.setMassSpectrumSPtr(MassSpectrum(trace).makeMassSpectrumSPtr());
625 mass_spectrum.setEmptyMassSpectrum(false);
626 }
627 else
628 {
629 mass_spectrum.setMassSpectrumSPtr(nullptr);
630 mass_spectrum.setEmptyMassSpectrum(true);
631 }
632 }
633 qDebug();
634 }
635
636 catch(PappsoException &error)
637 {
638 throw PappsoException(QObject::tr("ERROR in %1 (global_slice_index=%2):\n%3")
639 .arg(__FUNCTION__)
640 .arg(global_slice_index)
641 .arg(error.qwhat()));
642 }
643 catch(std::exception &error)
644 {
645 qDebug() << QString("Failure %1 ").arg(error.what());
646 }
647 qDebug();
648}
649
650} // namespace pappso
void setNativeId(const QString &native_id)
void setMsRunId(MsRunIdCstSPtr other)
void setSpectrumIndex(std::size_t index)
Class to represent a mass spectrum.
const char * what() const noexcept override
virtual const QString & qwhat() const
Class representing a fully specified mass spectrum.
void setPrecursorNativeId(const QString &native_id)
Set the scan native id of the precursor ion.
void setMassSpectrumId(const MassSpectrumId &iD)
Set the MassSpectrumId.
void setMsLevel(uint ms_level)
Set the mass spectrum level.
void setParameterValue(QualifiedMassSpectrumParameter parameter, const QVariant &value)
void setMassSpectrumSPtr(MassSpectrumSPtr massSpectrum)
Set the MassSpectrumSPtr.
void setRtInSeconds(pappso_double rt)
Set the retention time in seconds.
void setEmptyMassSpectrum(bool is_empty_mass_spectrum)
replacement for std::map
void builtInCentroid()
simple filter to agregate counts on neigbhor mobility slots (+1)
static TimsDataFastMap & getTimsDataFastMapInstance()
std::vector< std::size_t > m_ms2frameId2Ms1FrameId
TimsDataFastMap & getCombinedMs2ScansByGlobalSliceIndex(std::size_t global_slice_index) const
std::size_t getGlobalSliceIndexBeginByFrameId(std::size_t frame_id) const
std::size_t getLastMs1FrameIdByMs2FrameId(std::size_t frame_id) const
const FrameSliceRange & getFrameSliceRangeByGlobalSliceIndex(std::size_t global_slice_index) const
MsMsWindowGroupList m_msMsWindowGroupList
const MsMsWindow & getMsMsWindowByGlobalSliceIndex(std::size_t global_slice_index) const
bool m_builtinMs2Centroid
enable builtin centroid on raw tims integers by default
std::vector< std::size_t > m_ms1frameIdList
std::map< std::size_t, MsMsWindowGroup * > m_mapFrame2WindowGroupPtr
std::size_t m_totalSlicesCount
std::size_t getFrameIdByGlobalSliceIndex(std::size_t global_slice_id) const
std::vector< std::size_t > m_frameId2GlobalSliceIndexBegin
void getMs2QualifiedSpectrumByGlobalSliceIndex(const MsRunIdCstSPtr &msrun_id, QualifiedMassSpectrum &mass_spectrum, std::size_t global_slice_index, bool want_binary_data) const
const std::map< std::size_t, MsMsWindowGroup * > & getMapFrame2WindowGroupPtr() const
void getMs1QualifiedSpectrumByGlobalSliceIndex(const MsRunIdCstSPtr &msrun_id, QualifiedMassSpectrum &mass_spectrum, std::size_t global_slice_index, bool want_binary_data, int rt_position=0) const
get MS1 spectrum corresponding to the given slice extract MS1 mz range and mobility range correspondi...
TimsDiaSlices(QSqlQuery &query, TimsData *tims_data_origin)
std::vector< FrameSliceRange > m_frameSliceRangeList
std::size_t getTotalSlicesCount() const
get the number of DIA MS2 slices analyzed by PASEF
const MsMsWindowGroupList & getMsMsWindowGroupList() const
A simple container of DataPoint instances.
Definition trace.h:148
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition aa.cpp:39
std::shared_ptr< const TimsFrameBase > TimsFrameBaseCstSPtr
std::shared_ptr< const MsRunId > MsRunIdCstSPtr
Definition msrunid.h:46
@ IsolationMzWidth
m/z isolation window width (left + right)
@ CollisionEnergy
Bruker's timsTOF collision energy.
std::shared_ptr< const TimsFrame > TimsFrameCstSPtr
Definition timsframe.h:44
MsMsWindowGroup * getWindowGroupPtrByGroupId(std::size_t window_group_id) const
void addInGroup(const MsMsWindow &window)
bool isMzInRange(double mz) const
tell if given mz is in range for this window