IsoSpecPy 2.3.3__tar.gz → 2.3.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. {isospecpy-2.3.3 → isospecpy-2.3.5}/PKG-INFO +1 -1
  2. {isospecpy-2.3.3 → isospecpy-2.3.5}/pyproject.toml +1 -1
  3. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/cwrapper.cpp +40 -10
  4. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/cwrapper.h +7 -0
  5. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/fixedEnvelopes.cpp +102 -260
  6. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/fixedEnvelopes.h +4 -5
  7. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/isoSpec++.cpp +57 -0
  8. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/isoSpec++.h +31 -0
  9. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/marginalTrek++.cpp +53 -0
  10. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/marginalTrek++.h +21 -0
  11. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/misc.h +18 -0
  12. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpecPy/Distributions.py +0 -1
  13. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpecPy/IsoSpecPy.py +70 -47
  14. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpecPy/IsoSpecPyOld.py +6 -10
  15. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpecPy/PeriodicTbl.py +2 -6
  16. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpecPy/approximations.py +0 -9
  17. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpecPy/isoFFI.py +49 -18
  18. {isospecpy-2.3.3 → isospecpy-2.3.5}/LICENCE +0 -0
  19. {isospecpy-2.3.3 → isospecpy-2.3.5}/README.md +0 -0
  20. {isospecpy-2.3.3 → isospecpy-2.3.5}/skbuild/CMakeLists.txt +0 -0
  21. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/allocator.cpp +0 -0
  22. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/allocator.h +0 -0
  23. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/btrd.h +0 -0
  24. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/conf.h +0 -0
  25. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/dirtyAllocator.cpp +0 -0
  26. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/dirtyAllocator.h +0 -0
  27. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/element_tables.cpp +0 -0
  28. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/element_tables.h +0 -0
  29. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/fasta.cpp +0 -0
  30. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/fasta.h +0 -0
  31. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/isoMath.cpp +0 -0
  32. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/isoMath.h +0 -0
  33. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/misc.cpp +0 -0
  34. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/mman.cpp +0 -0
  35. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/mman.h +0 -0
  36. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/operators.cpp +0 -0
  37. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/operators.h +0 -0
  38. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/platform.h +0 -0
  39. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/platform_incl.h +0 -0
  40. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/pod_vector.h +0 -0
  41. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/python-build.cpp +0 -0
  42. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/summator.h +0 -0
  43. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpec++/unity-build.cpp +0 -0
  44. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpecPy/Advanced.py +0 -0
  45. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpecPy/Formulas.py +0 -0
  46. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpecPy/__init__.py +0 -0
  47. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpecPy/__main__.py +0 -0
  48. {isospecpy-2.3.3 → isospecpy-2.3.5}/src/IsoSpecPy/confs_passthrough.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: IsoSpecPy
3
- Version: 2.3.3
3
+ Version: 2.3.5
4
4
  Summary: IsoSpecPy is a Python library for computing isotopic distributions of molecules.
5
5
  Keywords: isotopic distribution,mass spectrometry,chemistry,isotopic envelope,isotopologues
6
6
  Author: Michał Startek, Mateusz Łącki
@@ -9,7 +9,7 @@ cmake.source-dir = "skbuild"
9
9
  name = "IsoSpecPy"
10
10
  dependencies = ["cffi"]
11
11
  description = "IsoSpecPy is a Python library for computing isotopic distributions of molecules."
12
- version = "2.3.3"
12
+ version = "2.3.5"
13
13
  license = "BSD-2-Clause"
14
14
  license-files = ["LICENCE"]
15
15
  authors = [{name = "Michał Startek"}, {name = "Mateusz Łącki"}]
@@ -59,16 +59,46 @@ double getLightestPeakMassIso(void* iso)
59
59
  return reinterpret_cast<Iso*>(iso)->getLightestPeakMass();
60
60
  }
61
61
 
62
+ double getLightestPeakLProbIso(void* iso)
63
+ {
64
+ return reinterpret_cast<Iso*>(iso)->getLightestPeakLProb();
65
+ }
66
+
67
+ void getLightestPeakSignature(void* iso, int* space)
68
+ {
69
+ reinterpret_cast<Iso*>(iso)->getLightestPeakSignature(space);
70
+ }
71
+
62
72
  double getHeaviestPeakMassIso(void* iso)
63
73
  {
64
74
  return reinterpret_cast<Iso*>(iso)->getHeaviestPeakMass();
65
75
  }
66
76
 
77
+ double getHeaviestPeakLProbIso(void* iso)
78
+ {
79
+ return reinterpret_cast<Iso*>(iso)->getHeaviestPeakLProb();
80
+ }
81
+
82
+ void getHeaviestPeakSignature(void* iso, int* space)
83
+ {
84
+ reinterpret_cast<Iso*>(iso)->getHeaviestPeakSignature(space);
85
+ }
86
+
67
87
  double getMonoisotopicPeakMassIso(void* iso)
68
88
  {
69
89
  return reinterpret_cast<Iso*>(iso)->getMonoisotopicPeakMass();
70
90
  }
71
91
 
92
+ double getMonoisotopicPeakLProbIso(void* iso)
93
+ {
94
+ return reinterpret_cast<Iso*>(iso)->getMonoisotopicPeakLProb();
95
+ }
96
+
97
+ void getMonoisotopicPeakSignature(void* iso, int* space)
98
+ {
99
+ reinterpret_cast<Iso*>(iso)->getMonoisotopicPeakSignature(space);
100
+ }
101
+
72
102
  double getModeLProbIso(void* iso)
73
103
  {
74
104
  return reinterpret_cast<Iso*>(iso)->getModeLProb();
@@ -99,8 +129,9 @@ double* getMarginalLogSizeEstimates(void* iso, double target_total_prob)
99
129
  {
100
130
  Iso* i = reinterpret_cast<Iso*>(iso);
101
131
  double* ret = reinterpret_cast<double*>(malloc(sizeof(double)*i->getDimNumber()));
102
- if(ret != nullptr)
103
- i->saveMarginalLogSizeEstimates(ret, target_total_prob);
132
+ if(ret == nullptr)
133
+ throw std::bad_alloc();
134
+ i->saveMarginalLogSizeEstimates(ret, target_total_prob);
104
135
  return ret;
105
136
  }
106
137
 
@@ -265,6 +296,12 @@ void* setupFixedEnvelope(double* masses, double* probs, size_t size, bool mass_s
265
296
  return reinterpret_cast<void*>(ret);
266
297
  }
267
298
 
299
+ void* setupFixedEnvelopeWithConfs(double* masses, double* probs, int* confs, size_t size, int allDim, bool mass_sorted, bool prob_sorted, double total_prob)
300
+ {
301
+ FixedEnvelope* ret = new FixedEnvelope(masses, probs, confs, size, allDim, mass_sorted, prob_sorted, total_prob);
302
+ return reinterpret_cast<void*>(ret);
303
+ }
304
+
268
305
  void deleteFixedEnvelope(void* t, bool release_everything)
269
306
  {
270
307
  FixedEnvelope* tt = reinterpret_cast<FixedEnvelope*>(t);
@@ -347,13 +384,6 @@ double abyssalWassersteinDistance(void* tabulator1, void* tabulator2, double aby
347
384
  return reinterpret_cast<FixedEnvelope*>(tabulator1)->AbyssalWassersteinDistance(*reinterpret_cast<FixedEnvelope*>(tabulator2), abyss_depth, other_scale);
348
385
  }
349
386
 
350
- #if 0
351
- double abyssalWassersteinDistanceGrad(void* const* envelopes, const double* scales, double* ret_gradient, size_t N, double abyss_depth_exp, double abyss_depth_the)
352
- {
353
- return AbyssalWassersteinDistanceGrad(reinterpret_cast<FixedEnvelope* const*>(envelopes), scales, ret_gradient, N, abyss_depth_exp, abyss_depth_the);
354
- }
355
- #endif
356
-
357
387
  struct ws_match_res wassersteinMatch(void* tabulator1, void* tabulator2, double flow_dist, double other_scale)
358
388
  {
359
389
  struct ws_match_res res;
@@ -447,7 +477,7 @@ void array_fma(double* array, size_t N, double mul, double add)
447
477
  #if defined(FP_FAST_FMA)
448
478
  array[ii] = std::fma(array[ii], mul, add);
449
479
  #else
450
- array[ii] += (array[ii] * mul) + add;
480
+ array[ii] = (array[ii] * mul) + add;
451
481
  #endif
452
482
  }
453
483
 
@@ -40,8 +40,14 @@ ISOSPEC_C_API void * setupIso(int dimNumber,
40
40
  ISOSPEC_C_API void * isoFromFasta(const char* fasta, bool use_nominal_masses, bool add_water);
41
41
 
42
42
  ISOSPEC_C_API double getLightestPeakMassIso(void* iso);
43
+ ISOSPEC_C_API double getLightestPeakLProbIso(void* iso);
44
+ ISOSPEC_C_API void getLightestPeakSignature(void* iso, int* space);
43
45
  ISOSPEC_C_API double getHeaviestPeakMassIso(void* iso);
46
+ ISOSPEC_C_API double getHeaviestPeakLProbIso(void* iso);
47
+ ISOSPEC_C_API void getHeaviestPeakSignature(void* iso, int* space);
44
48
  ISOSPEC_C_API double getMonoisotopicPeakMassIso(void* iso);
49
+ ISOSPEC_C_API double getMonoisotopicPeakLProbIso(void* iso);
50
+ ISOSPEC_C_API void getMonoisotopicPeakSignature(void* iso, int* space);
45
51
  ISOSPEC_C_API double getModeLProbIso(void* iso);
46
52
  ISOSPEC_C_API double getModeMassIso(void* iso);
47
53
  ISOSPEC_C_API double getTheoreticalAverageMassIso(void* iso);
@@ -132,6 +138,7 @@ ISOSPEC_C_API void array_mul(double* array, size_t N, double what);
132
138
  ISOSPEC_C_API void array_fma(double* array, size_t N, double mul, double add);
133
139
 
134
140
  ISOSPEC_C_API void* setupFixedEnvelope(double* masses, double* probs, size_t size, bool mass_sorted, bool prob_sorted, double total_prob);
141
+ ISOSPEC_C_API void* setupFixedEnvelopeWithConfs(double* masses, double* probs, int* confs, size_t size, int allDim, bool mass_sorted, bool prob_sorted, double total_prob);
135
142
  ISOSPEC_C_API void* copyFixedEnvelope(void* other);
136
143
  ISOSPEC_C_API void deleteFixedEnvelope(void* tabulator, bool releaseEverything);
137
144
 
@@ -23,14 +23,16 @@ namespace IsoSpec
23
23
  {
24
24
 
25
25
  FixedEnvelope::FixedEnvelope(const FixedEnvelope& other) :
26
- _masses(array_copy<double>(other._masses, other._confs_no)),
27
- _probs(array_copy<double>(other._probs, other._confs_no)),
28
- _confs(array_copy_nptr<int>(other._confs, other._confs_no*other.allDim)),
26
+ _masses(array_copy_malloc<double>(other._masses, other._confs_no)),
27
+ _probs(array_copy_malloc<double>(other._probs, other._confs_no)),
28
+ _confs(array_copy_nptr_malloc<int>(other._confs, other._confs_no*other.allDim)),
29
29
  _confs_no(other._confs_no),
30
30
  allDim(other.allDim),
31
+ allDimSizeofInt(other.allDimSizeofInt),
31
32
  sorted_by_mass(other.sorted_by_mass),
32
33
  sorted_by_prob(other.sorted_by_prob),
33
- total_prob(other.total_prob)
34
+ total_prob(other.total_prob),
35
+ current_size(other._confs_no)
34
36
  {}
35
37
 
36
38
  FixedEnvelope::FixedEnvelope(FixedEnvelope&& other) :
@@ -39,15 +41,60 @@ _probs(other._probs),
39
41
  _confs(other._confs),
40
42
  _confs_no(other._confs_no),
41
43
  allDim(other.allDim),
44
+ allDimSizeofInt(other.allDimSizeofInt),
42
45
  sorted_by_mass(other.sorted_by_mass),
43
46
  sorted_by_prob(other.sorted_by_prob),
44
- total_prob(other.total_prob)
47
+ total_prob(other.total_prob),
48
+ current_size(other.current_size)
45
49
  {
46
50
  other._masses = nullptr;
47
51
  other._probs = nullptr;
48
52
  other._confs = nullptr;
49
53
  other._confs_no = 0;
50
54
  other.total_prob = 0.0;
55
+ other.current_size = 0;
56
+ }
57
+
58
+ FixedEnvelope& FixedEnvelope::operator=(const FixedEnvelope& other)
59
+ {
60
+ if(this == &other)
61
+ return *this;
62
+ // Copy-and-swap: construct the copy first so that if any allocation inside
63
+ // the copy constructor throws, *this is left untouched. Only after tmp is
64
+ // fully built do we pilfer its pointers; tmp then destructs holding the old
65
+ // ones, which frees them without any possibility of failure.
66
+ FixedEnvelope tmp(other);
67
+ std::swap(_masses, tmp._masses);
68
+ std::swap(_probs, tmp._probs);
69
+ std::swap(_confs, tmp._confs);
70
+ _confs_no = tmp._confs_no;
71
+ allDim = tmp.allDim;
72
+ allDimSizeofInt = tmp.allDimSizeofInt;
73
+ sorted_by_mass = tmp.sorted_by_mass;
74
+ sorted_by_prob = tmp.sorted_by_prob;
75
+ total_prob = tmp.total_prob;
76
+ current_size = tmp.current_size;
77
+ return *this;
78
+ }
79
+
80
+ FixedEnvelope& FixedEnvelope::operator=(FixedEnvelope&& other)
81
+ {
82
+ if(this == &other)
83
+ return *this;
84
+ free(_masses);
85
+ free(_probs);
86
+ free(_confs);
87
+ _masses = other._masses; other._masses = nullptr;
88
+ _probs = other._probs; other._probs = nullptr;
89
+ _confs = other._confs; other._confs = nullptr;
90
+ _confs_no = other._confs_no; other._confs_no = 0;
91
+ allDim = other.allDim;
92
+ allDimSizeofInt = other.allDimSizeofInt;
93
+ sorted_by_mass = other.sorted_by_mass;
94
+ sorted_by_prob = other.sorted_by_prob;
95
+ total_prob = other.total_prob; other.total_prob = 0.0;
96
+ current_size = other.current_size; other.current_size = 0;
97
+ return *this;
51
98
  }
52
99
 
53
100
  FixedEnvelope::FixedEnvelope(double* in_masses, double* in_probs, size_t in_confs_no, bool masses_sorted, bool probs_sorted, double _total_prob) :
@@ -56,6 +103,19 @@ _probs(in_probs),
56
103
  _confs(nullptr),
57
104
  _confs_no(in_confs_no),
58
105
  allDim(0),
106
+ allDimSizeofInt(0),
107
+ sorted_by_mass(masses_sorted),
108
+ sorted_by_prob(probs_sorted),
109
+ total_prob(_total_prob)
110
+ {}
111
+
112
+ FixedEnvelope::FixedEnvelope(double* in_masses, double* in_probs, int* in_confs, size_t in_confs_no, int _allDim, bool masses_sorted, bool probs_sorted, double _total_prob) :
113
+ _masses(in_masses),
114
+ _probs(in_probs),
115
+ _confs(in_confs),
116
+ _confs_no(in_confs_no),
117
+ allDim(_allDim),
118
+ allDimSizeofInt(_allDim * sizeof(int)),
59
119
  sorted_by_mass(masses_sorted),
60
120
  sorted_by_prob(probs_sorted),
61
121
  total_prob(_total_prob)
@@ -233,6 +293,12 @@ void FixedEnvelope::resample(size_t samples, double beta_bias)
233
293
  double cprob = 0.0;
234
294
  size_t pidx = -1; // Overflows - but it doesn't matter.
235
295
 
296
+ // Sentinel: prevents the inner while(pprob < cprob) from walking off the end
297
+ // if floating-point rounding leaves the accumulated probability sum slightly
298
+ // below 1.0. Safe to overwrite in-place: rdvariate_binom guards succ_prob>=1.0
299
+ // so infinity is handled correctly, and the sentinel is always cleaned up before
300
+ // return — either by the loop zeroing the slot when it advances pidx to here,
301
+ // or by the memset below when the loop terminates earlier.
236
302
  _probs[_confs_no-1] = (std::numeric_limits<double>::max)();
237
303
 
238
304
  while(samples > 0)
@@ -489,244 +555,6 @@ double FixedEnvelope::AbyssalWassersteinDistance(FixedEnvelope& other, double ab
489
555
  return accd + condemned * abyss_depth * 0.5;
490
556
  }
491
557
 
492
- #if 0
493
- double FixedEnvelope::ScaledAbyssalWassersteinDistance(FixedEnvelope * const * others, double abyss_depth, const double* other_scales, const size_t N)
494
- {
495
- sort_by_mass();
496
-
497
- std::priority_queue<std::pair<double, size_t>> PQ;
498
- std::unique_ptr<size_t[]> indices = std::make_unique<size_t[]>(N);
499
- memset(indices.get(), 0, sizeof(size_t)*N);
500
-
501
- for(size_t ii=0; ii<N; ii++)
502
- {
503
- others[ii]->sort_by_mass();
504
- if(others[ii]->_confs_no > 0)
505
- PQ.emplace_back({others._probs[0], ii});
506
- }
507
-
508
-
509
-
510
-
511
- std::vector<std::pair<double, double>> carried;
512
-
513
- size_t idx_this = 0;
514
- size_t idx_other = 0;
515
-
516
- //std::cout << "AAA" << std::endl;
517
-
518
- auto finished = [&]() -> bool { return idx_this >= _confs_no && PQ.empty(); };
519
- auto next = [&]() -> std::tuple<double, double, size_t> {
520
- if(idx_this >= _confs_no || (idx_other < other._confs_no && _masses[idx_this] > other._masses[idx_other]))
521
- {
522
- std::pair<double, double> res = std::pair<double, double>(other._masses[idx_other], other._probs[idx_other]*other_scale);
523
- idx_other++;
524
- return res;
525
- }
526
- else
527
- {
528
- std::pair<double, double> res = std::pair<double, double>(_masses[idx_this], -_probs[idx_this]);
529
- idx_this++;
530
- return res;
531
- }
532
- };
533
- double accd = 0.0;
534
- double condemned = 0.0;
535
-
536
- while(!finished())
537
- {
538
- auto [m, p] = next();
539
- if(!carried.empty() && carried[0].second * p > 0.0)
540
- {
541
- carried.emplace_back(m, p);
542
- continue;
543
- }
544
-
545
- while(!carried.empty())
546
- {
547
- auto& [cm, cp] = carried.back();
548
- if(m - cm >= abyss_depth)
549
- {
550
- for(auto it = carried.cbegin(); it != carried.cend(); it++)
551
- condemned += fabs(it->second);
552
- carried.clear();
553
- break;
554
- }
555
- if((cp+p)*p > 0.0)
556
- {
557
- accd += fabs((m-cm)*cp);
558
- p += cp;
559
- carried.pop_back();
560
- }
561
- else
562
- {
563
- accd += fabs((m-cm)*p);
564
- cp += p;
565
- p = 0.0;
566
- break;
567
- }
568
- }
569
- if(p != 0.0)
570
- carried.emplace_back(m, p);
571
- //std::cout << m << " " << p << std::endl;
572
- }
573
-
574
- for(auto it = carried.cbegin(); it != carried.cend(); it++)
575
- condemned += fabs(it->second);
576
-
577
- return accd + condemned * abyss_depth * 0.5;
578
- }
579
-
580
- #endif
581
-
582
- #if 0
583
- double AbyssalWassersteinDistanceGrad(FixedEnvelope* const* envelopes, const double* scales, double* ret_gradient, size_t N, double abyss_depth_exp, double abyss_depth_the)
584
- {
585
- return 0.0;
586
- std::unique_ptr<size_t[]> env_idx = std::make_unique<size_t[]>(N+1);
587
- memset(env_idx.get(), 0, (N+1)*sizeof(size_t));
588
- memset(ret_gradient, 0, (N+1)*sizeof(double));
589
-
590
- auto pq_cmp = [](std::pair<double, size_t>& p1, std::pair<double, size_t>& p2) { return p1.first > p2.first; };
591
- std::priority_queue<std::pair<double, size_t>, std::vector<std::pair<double, size_t>>, decltype(pq_cmp)> PQ(pq_cmp);
592
-
593
- for(size_t ii=0; ii<=N; ii++)
594
- {
595
- envelopes[ii]->sort_by_mass();
596
- if(envelopes[ii]->_confs_no > 0)
597
- {
598
- std::cout << "Initial push: " << envelopes[ii]->_masses[0] << " " << ii << '\n';
599
- PQ.push({envelopes[ii]->_masses[0], ii});
600
- }
601
- }
602
-
603
- std::vector<std::tuple<double, double, size_t>> carried;
604
-
605
- auto next = [&]() -> std::tuple<double, double, size_t> {
606
- auto [mass, eidx] = PQ.top();
607
- double prob = envelopes[eidx]->_probs[env_idx[eidx]];
608
- PQ.pop();
609
- if(eidx == 0)
610
- prob = -prob;
611
- else
612
- prob = prob * scales[eidx];
613
- std::cout << "Next: " << mass << " " << prob << " " << eidx << '\n';
614
- env_idx[eidx]++;
615
- if(env_idx[eidx] < envelopes[eidx]->_confs_no)
616
- PQ.push({envelopes[eidx]->_masses[env_idx[eidx]], eidx});
617
-
618
- return {mass, prob, eidx};
619
- };
620
- double accd = 0.0;
621
- double condemned = 0.0;
622
- //double flow;
623
- const double max_flow_dist = abyss_depth_exp + abyss_depth_the;
624
- max_flow_dist *= 2.0;
625
-
626
- while(!PQ.empty())
627
- {
628
- auto [m, p, eidx] = next();
629
- if(!carried.empty() && std::get<1>(carried[0]) * p > 0.0)
630
- {
631
- carried.emplace_back(m, p, eidx);
632
- continue;
633
- }
634
-
635
- while(!carried.empty())
636
- {
637
- auto& [cm, cp, ceidx] = carried.back();
638
- if(m - cm >= max_flow_dist)
639
- {
640
- for(auto it = carried.cbegin(); it != carried.cend(); it++)
641
- condemned += fabs(std::get<1>(*it));
642
- carried.clear();
643
- break;
644
- }
645
- std::cout << "accing\n";
646
- if((cp+p)*p > 0.0)
647
- {
648
- accd += fabs((m-cm)*cp);
649
- p += cp;
650
- carried.pop_back();
651
- std::cout << "cprob:" << cp << '\n';
652
- }
653
- else
654
- {
655
- accd += fabs((m-cm)*p);
656
- cp += p;
657
- std::cout << "prob:" << p << '\n';
658
- p = 0.0;
659
- break;
660
- }
661
- }
662
- if(p != 0.0)
663
- carried.emplace_back(m, p, eidx);
664
- //std::cout << m << " " << p << std::endl;
665
- }
666
-
667
- for(auto it = carried.cbegin(); it != carried.cend(); it++)
668
- condemned += fabs(std::get<1>(*it));
669
-
670
- std::cout << "ISO:" << accd << " " << condemned << '\n';
671
- return accd + condemned * max_flow_dist * 0.5;
672
- while(!PQ.empty())
673
- {
674
- auto [m, p, eidx] = next();
675
- if(!carried.empty() && (std::get<1>(carried[0]) * p > 0.0))
676
- {
677
- carried.emplace_back(m, p, eidx);
678
- continue;
679
- }
680
-
681
- while(!carried.empty())
682
- {
683
- auto& [cm, cp, ceidx] = carried.back();
684
- if(m - cm >= max_flow_dist)
685
- {
686
- for(auto it = carried.cbegin(); it != carried.cend(); it++)
687
- {
688
- flow = fabs(std::get<1>(*it));
689
- const size_t target_idx = std::get<2>(*it);
690
- flow *= target_idx == 0 ? abyss_depth_exp : abyss_depth_the;
691
- ret_gradient[target_idx] += flow;
692
- condemned += flow;
693
- std::cout << "condemnin': " << m << " " << p << " " << eidx << " | " << cm << " " << cp << " " << ceidx << '\n';
694
- }
695
- carried.clear();
696
- break;
697
- }
698
- if((cp+p)*p > 0.0)
699
- {
700
- flow = fabs((m-cm)*cp);
701
- accd += flow;
702
- p += cp;
703
- ret_gradient[ceidx] += flow;
704
- carried.pop_back();
705
- }
706
- else
707
- {
708
- flow = fabs((m-cm)*p);
709
- accd += flow;
710
- cp += p;
711
- ret_gradient[eidx] += flow;
712
- p = 0.0;
713
- break;
714
- }
715
- }
716
- if(p != 0.0)
717
- carried.emplace_back(m, p, eidx);
718
- //std::cout << m << " " << p << std::endl;
719
- }
720
-
721
- for(auto it = carried.cbegin(); it != carried.cend(); it++)
722
- condemned += fabs(std::get<1>(*it));
723
-
724
-
725
- return accd + condemned * (abyss_depth_exp + abyss_depth_the) * 0.5;
726
- }
727
- #endif
728
-
729
-
730
558
  std::tuple<double, double, double> FixedEnvelope::WassersteinMatch(FixedEnvelope& other, double flow_distance, double other_scale)
731
559
  {
732
560
  if(_confs_no == 0)
@@ -854,48 +682,60 @@ FixedEnvelope FixedEnvelope::bin(double bin_width, double middle)
854
682
 
855
683
  template<bool tgetConfs> void FixedEnvelope::reallocate_memory(size_t new_size)
856
684
  {
857
- current_size = new_size;
858
- // FIXME: Handle overflow gracefully here. It definitely could happen for people still stuck on 32 bits...
859
- _masses = reinterpret_cast<double*>(realloc(_masses, new_size * sizeof(double)));
860
- if(_masses == nullptr)
685
+ if(new_size > SIZE_MAX / sizeof(double))
686
+ throw std::bad_alloc();
687
+ double* tmp_masses = reinterpret_cast<double*>(realloc(_masses, new_size * sizeof(double)));
688
+ if(tmp_masses == nullptr)
861
689
  throw std::bad_alloc();
690
+ _masses = tmp_masses;
862
691
  tmasses = _masses + _confs_no;
863
692
 
864
- _probs = reinterpret_cast<double*>(realloc(_probs, new_size * sizeof(double)));
865
- if(_probs == nullptr)
693
+ double* tmp_probs = reinterpret_cast<double*>(realloc(_probs, new_size * sizeof(double)));
694
+ if(tmp_probs == nullptr)
866
695
  throw std::bad_alloc();
696
+ _probs = tmp_probs;
867
697
  tprobs = _probs + _confs_no;
868
698
 
869
699
  constexpr_if(tgetConfs)
870
700
  {
871
- _confs = reinterpret_cast<int*>(realloc(_confs, new_size * allDimSizeofInt));
872
- if(_confs == nullptr)
701
+ if(allDimSizeofInt > 0 && new_size > SIZE_MAX / static_cast<size_t>(allDimSizeofInt))
702
+ throw std::bad_alloc();
703
+ int* tmp_confs = reinterpret_cast<int*>(realloc(_confs, new_size * allDimSizeofInt));
704
+ if(tmp_confs == nullptr)
873
705
  throw std::bad_alloc();
706
+ _confs = tmp_confs;
874
707
  tconfs = _confs + (allDim * _confs_no);
875
708
  }
709
+ current_size = new_size;
876
710
  }
877
711
 
878
712
  void FixedEnvelope::slow_reallocate_memory(size_t new_size)
879
713
  {
880
- current_size = new_size;
881
- // FIXME: Handle overflow gracefully here. It definitely could happen for people still stuck on 32 bits...
882
- _masses = reinterpret_cast<double*>(realloc(_masses, new_size * sizeof(double)));
883
- if(_masses == nullptr)
714
+ if(new_size > SIZE_MAX / sizeof(double))
715
+ throw std::bad_alloc();
716
+ double* tmp_masses = reinterpret_cast<double*>(realloc(_masses, new_size * sizeof(double)));
717
+ if(tmp_masses == nullptr)
884
718
  throw std::bad_alloc();
719
+ _masses = tmp_masses;
885
720
  tmasses = _masses + _confs_no;
886
721
 
887
- _probs = reinterpret_cast<double*>(realloc(_probs, new_size * sizeof(double)));
888
- if(_probs == nullptr)
722
+ double* tmp_probs = reinterpret_cast<double*>(realloc(_probs, new_size * sizeof(double)));
723
+ if(tmp_probs == nullptr)
889
724
  throw std::bad_alloc();
725
+ _probs = tmp_probs;
890
726
  tprobs = _probs + _confs_no;
891
727
 
892
728
  if(_confs != nullptr)
893
729
  {
894
- _confs = reinterpret_cast<int*>(realloc(_confs, new_size * allDimSizeofInt));
895
- if(_confs == nullptr)
730
+ if(allDimSizeofInt > 0 && new_size > SIZE_MAX / static_cast<size_t>(allDimSizeofInt))
896
731
  throw std::bad_alloc();
732
+ int* tmp_confs = reinterpret_cast<int*>(realloc(_confs, new_size * allDimSizeofInt));
733
+ if(tmp_confs == nullptr)
734
+ throw std::bad_alloc();
735
+ _confs = tmp_confs;
897
736
  tconfs = _confs + (allDim * _confs_no);
898
737
  }
738
+ current_size = new_size;
899
739
  }
900
740
 
901
741
  template<bool tgetConfs> void FixedEnvelope::threshold_init(Iso&& iso, double threshold, bool absolute)
@@ -1142,7 +982,7 @@ FixedEnvelope FixedEnvelope::Binned(Iso&& iso, double target_total_prob, double
1142
982
 
1143
983
  ret.reallocate_memory<false>(ISOSPEC_INIT_TABLE_SIZE);
1144
984
 
1145
- for(size_t ii = nonzero_idx; ii >= idx_min && empty_steps < distance_10da; ii--)
985
+ for(size_t ii = nonzero_idx; empty_steps < distance_10da; )
1146
986
  {
1147
987
  if(acc[ii] > 0.0)
1148
988
  {
@@ -1151,6 +991,8 @@ FixedEnvelope FixedEnvelope::Binned(Iso&& iso, double target_total_prob, double
1151
991
  }
1152
992
  else
1153
993
  empty_steps++;
994
+ if(ii == idx_min) break;
995
+ ii--;
1154
996
  }
1155
997
 
1156
998
  empty_steps = 0;
@@ -34,9 +34,6 @@ namespace IsoSpec
34
34
 
35
35
  class FixedEnvelope;
36
36
 
37
- double AbyssalWassersteinDistanceGrad(FixedEnvelope* const* envelopes, const double* scales, double* ret_gradient, size_t N, double abyss_depth_exp, double abyss_depth_the);
38
-
39
-
40
37
  class ISOSPEC_EXPORT_SYMBOL FixedEnvelope {
41
38
  protected:
42
39
  double* _masses;
@@ -61,7 +58,7 @@ class ISOSPEC_EXPORT_SYMBOL FixedEnvelope {
61
58
  allDim(0),
62
59
  sorted_by_mass(false),
63
60
  sorted_by_prob(false),
64
- total_prob(0.0),
61
+ total_prob(NAN),
65
62
  current_size(0),
66
63
  allDimSizeofInt(0)
67
64
  // Deliberately not initializing tmasses, tprobs, tconfs
@@ -69,8 +66,11 @@ class ISOSPEC_EXPORT_SYMBOL FixedEnvelope {
69
66
 
70
67
  FixedEnvelope(const FixedEnvelope& other);
71
68
  FixedEnvelope(FixedEnvelope&& other);
69
+ FixedEnvelope& operator=(const FixedEnvelope& other);
70
+ FixedEnvelope& operator=(FixedEnvelope&& other);
72
71
 
73
72
  FixedEnvelope(double* masses, double* probs, size_t confs_no, bool masses_sorted = false, bool probs_sorted = false, double _total_prob = NAN);
73
+ FixedEnvelope(double* masses, double* probs, int* confs, size_t confs_no, int _allDim, bool masses_sorted = false, bool probs_sorted = false, double _total_prob = NAN);
74
74
 
75
75
  virtual ~FixedEnvelope()
76
76
  {
@@ -238,7 +238,6 @@ class ISOSPEC_EXPORT_SYMBOL FixedEnvelope {
238
238
  return Binned(Iso(iso, false), target_total_prob, bin_width, bin_middle);
239
239
  }
240
240
 
241
- friend double AbyssalWassersteinDistanceGrad(FixedEnvelope* const* envelopes, const double* scales, double* ret_gradient, size_t N, double abyss_depth_exp, double abyss_depth_the);
242
241
  };
243
242
 
244
243
  } // namespace IsoSpec