IsoSpec  2.1.2
fixedEnvelopes.h
1 /*
2  * Copyright (C) 2015-2020 Mateusz Łącki and Michał Startek.
3  *
4  * This file is part of IsoSpec.
5  *
6  * IsoSpec is free software: you can redistribute it and/or modify
7  * it under the terms of the Simplified ("2-clause") BSD licence.
8  *
9  * IsoSpec is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * You should have received a copy of the Simplified BSD Licence
14  * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
15  */
16 
17 #pragma once
18 
19 #include <cstdlib>
20 #include <algorithm>
21 #include <vector>
22 #include <utility>
23 
24 #include "isoSpec++.h"
25 
26 #define ISOSPEC_INIT_TABLE_SIZE 1024
27 
28 namespace IsoSpec
29 {
30 
31 class ISOSPEC_EXPORT_SYMBOL FixedEnvelope {
32  protected:
33  double* _masses;
34  double* _probs;
35  int* _confs;
36  size_t _confs_no;
37  int allDim;
38  bool sorted_by_mass;
39  bool sorted_by_prob;
40  double total_prob;
41  size_t current_size;
42  double* tmasses;
43  double* tprobs;
44  int* tconfs;
45  int allDimSizeofInt;
46 
47  public:
48  ISOSPEC_FORCE_INLINE FixedEnvelope() : _masses(nullptr),
49  _probs(nullptr),
50  _confs(nullptr),
51  _confs_no(0),
52  allDim(0),
53  sorted_by_mass(false),
54  sorted_by_prob(false),
55  total_prob(0.0),
56  current_size(0),
57  allDimSizeofInt(0)
58  // Deliberately not initializing tmasses, tprobs, tconfs
59  {};
60 
61  FixedEnvelope(const FixedEnvelope& other);
63 
64  FixedEnvelope(double* masses, double* probs, size_t confs_no, bool masses_sorted = false, bool probs_sorted = false, double _total_prob = NAN);
65 
66  virtual ~FixedEnvelope()
67  {
68  free(_masses);
69  free(_probs);
70  free(_confs);
71  };
72 
73  FixedEnvelope operator+(const FixedEnvelope& other) const;
74  FixedEnvelope operator*(const FixedEnvelope& other) const;
75 
76  inline size_t confs_no() const { return _confs_no; }
77  inline int getAllDim() const { return allDim; }
78 
79  inline const double* masses() const { return _masses; }
80  inline const double* probs() const { return _probs; }
81  inline const int* confs() const { return _confs; }
82 
83  inline double* release_masses() { double* ret = _masses; _masses = nullptr; return ret; }
84  inline double* release_probs() { double* ret = _probs; _probs = nullptr; return ret; }
85  inline int* release_confs() { int* ret = _confs; _confs = nullptr; return ret; }
86 
87 
88  inline double mass(size_t i) const { return _masses[i]; }
89  inline double prob(size_t i) const { return _probs[i]; }
90  inline const int* conf(size_t i) const { return _confs + i*allDim; }
91 
92  void sort_by_mass();
93  void sort_by_prob();
94 
95  double get_total_prob();
96  void scale(double factor);
97  void normalize();
98 
99  double empiric_average_mass();
100  double empiric_variance();
101  double empiric_stddev() { return sqrt(empiric_variance()); }
102 
103  double WassersteinDistance(FixedEnvelope& other);
104  double OrientedWassersteinDistance(FixedEnvelope& other);
105 
106  static FixedEnvelope LinearCombination(const std::vector<const FixedEnvelope*>& spectra, const std::vector<double>& intensities);
107  static FixedEnvelope LinearCombination(const FixedEnvelope* const * spectra, const double* intensities, size_t size);
108 
109 
110  FixedEnvelope bin(double bin_width = 1.0, double middle = 0.0);
111 
112  private:
113  void sort_by(double* order);
114 
115 
116  protected:
117  template<typename T, bool tgetConfs> ISOSPEC_FORCE_INLINE void store_conf(const T& generator)
118  {
119  *tmasses = generator.mass(); tmasses++;
120  *tprobs = generator.prob(); tprobs++;
121  constexpr_if(tgetConfs) { generator.get_conf_signature(tconfs); tconfs += allDim; }
122  }
123 
124  ISOSPEC_FORCE_INLINE void store_conf(double _mass, double _prob)
125  {
126  if(_confs_no == current_size)
127  {
128  current_size *= 2;
129  reallocate_memory<false>(current_size);
130  }
131 
132  *tprobs = _prob;
133  *tmasses = _mass;
134  tprobs++;
135  tmasses++;
136 
137  _confs_no++;
138  }
139 
140  template<bool tgetConfs> ISOSPEC_FORCE_INLINE void swap(size_t idx1, size_t idx2, ISOSPEC_MAYBE_UNUSED int* conf_swapspace)
141  {
142  std::swap<double>(this->_probs[idx1], this->_probs[idx2]);
143  std::swap<double>(this->_masses[idx1], this->_masses[idx2]);
144  constexpr_if(tgetConfs)
145  {
146  int* c1 = this->_confs + (idx1*this->allDim);
147  int* c2 = this->_confs + (idx2*this->allDim);
148  memcpy(conf_swapspace, c1, this->allDimSizeofInt);
149  memcpy(c1, c2, this->allDimSizeofInt);
150  memcpy(c2, conf_swapspace, this->allDimSizeofInt);
151  }
152  }
153 
154  template<bool tgetConfs> void reallocate_memory(size_t new_size);
155  void slow_reallocate_memory(size_t new_size);
156 
157  public:
158  template<bool tgetConfs> void threshold_init(Iso&& iso, double threshold, bool absolute);
159 
160  template<bool tgetConfs> void addConfILG(const IsoLayeredGenerator& generator)
161  {
162  if(this->_confs_no == this->current_size)
163  {
164  this->current_size *= 2;
165  this->template reallocate_memory<tgetConfs>(this->current_size);
166  }
167 
168  this->template store_conf<IsoLayeredGenerator, tgetConfs>(generator);
169  this->_confs_no++;
170  }
171 
172  template<bool tgetConfs> void total_prob_init(Iso&& iso, double target_prob, bool trim);
173 
174  static FixedEnvelope FromThreshold(Iso&& iso, double threshold, bool absolute, bool tgetConfs = false)
175  {
176  FixedEnvelope ret;
177 
178  if(tgetConfs)
179  ret.threshold_init<true>(std::move(iso), threshold, absolute);
180  else
181  ret.threshold_init<false>(std::move(iso), threshold, absolute);
182  return ret;
183  }
184 
185  inline static FixedEnvelope FromThreshold(const Iso& iso, double _threshold, bool _absolute, bool tgetConfs = false)
186  {
187  return FromThreshold(Iso(iso, false), _threshold, _absolute, tgetConfs);
188  }
189 
190  static FixedEnvelope FromTotalProb(Iso&& iso, double target_total_prob, bool optimize, bool tgetConfs = false)
191  {
192  FixedEnvelope ret;
193 
194  if(tgetConfs)
195  ret.total_prob_init<true>(std::move(iso), target_total_prob, optimize);
196  else
197  ret.total_prob_init<false>(std::move(iso), target_total_prob, optimize);
198 
199  return ret;
200  }
201 
202  inline static FixedEnvelope FromTotalProb(const Iso& iso, double _target_total_prob, bool _optimize, bool tgetConfs = false)
203  {
204  return FromTotalProb(Iso(iso, false), _target_total_prob, _optimize, tgetConfs);
205  }
206 };
207 
208 } // namespace IsoSpec
IsoSpec
Definition: allocator.cpp:20
IsoSpec::Iso
The Iso class for the calculation of the isotopic distribution.
Definition: isoSpec++.h:49
IsoSpec::FixedEnvelope
Definition: fixedEnvelopes.h:31
IsoSpec::IsoLayeredGenerator
Definition: isoSpec++.h:439