IsoSpecPy 2.5.0__py3-none-win_arm64.whl

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 (45) hide show
  1. IsoSpecPy/Advanced.py +32 -0
  2. IsoSpecPy/Distributions.py +93 -0
  3. IsoSpecPy/Formulas.py +71 -0
  4. IsoSpecPy/IsoSpec++/aligned_ptr.h +638 -0
  5. IsoSpecPy/IsoSpec++/allocator.h +69 -0
  6. IsoSpecPy/IsoSpec++/btrd.h +206 -0
  7. IsoSpecPy/IsoSpec++/composition.h +126 -0
  8. IsoSpecPy/IsoSpec++/conf.h +38 -0
  9. IsoSpecPy/IsoSpec++/cwrapper.h +271 -0
  10. IsoSpecPy/IsoSpec++/dirtyAllocator.h +58 -0
  11. IsoSpecPy/IsoSpec++/element_lookup.h +36 -0
  12. IsoSpecPy/IsoSpec++/element_tables.h +50 -0
  13. IsoSpecPy/IsoSpec++/fasta.h +70 -0
  14. IsoSpecPy/IsoSpec++/fasta_mods.h +70 -0
  15. IsoSpecPy/IsoSpec++/fixedEnvelopes.h +418 -0
  16. IsoSpecPy/IsoSpec++/isa_kernel_impl.h +192 -0
  17. IsoSpecPy/IsoSpec++/isa_kernels.h +172 -0
  18. IsoSpecPy/IsoSpec++/isoMath.h +121 -0
  19. IsoSpecPy/IsoSpec++/isoSpec++.h +801 -0
  20. IsoSpecPy/IsoSpec++/iso_simd.h +48 -0
  21. IsoSpecPy/IsoSpec++/marginalTrek++.h +614 -0
  22. IsoSpecPy/IsoSpec++/misc.h +229 -0
  23. IsoSpecPy/IsoSpec++/mman.h +67 -0
  24. IsoSpecPy/IsoSpec++/operators.h +150 -0
  25. IsoSpecPy/IsoSpec++/platform.h +180 -0
  26. IsoSpecPy/IsoSpec++/platform_incl.h +33 -0
  27. IsoSpecPy/IsoSpec++/pod_vector.h +400 -0
  28. IsoSpecPy/IsoSpec++/summator.h +118 -0
  29. IsoSpecPy/IsoSpec++/unimod.h +80 -0
  30. IsoSpecPy/IsoSpec++/unimod_support.h +2169 -0
  31. IsoSpecPy/IsoSpec++/unimod_table_data.h +1027 -0
  32. IsoSpecPy/IsoSpecPy.py +1088 -0
  33. IsoSpecPy/IsoSpecPyOld.py +290 -0
  34. IsoSpecPy/PeriodicTbl.py +51 -0
  35. IsoSpecPy/__init__.py +19 -0
  36. IsoSpecPy/__main__.py +25 -0
  37. IsoSpecPy/approximations.py +122 -0
  38. IsoSpecPy/confs_passthrough.py +16 -0
  39. IsoSpecPy/isoFFI.py +290 -0
  40. bin/IsoSpecCppPy.dll +0 -0
  41. isospecpy-2.5.0.dist-info/METADATA +220 -0
  42. isospecpy-2.5.0.dist-info/RECORD +45 -0
  43. isospecpy-2.5.0.dist-info/WHEEL +5 -0
  44. isospecpy-2.5.0.dist-info/licenses/LICENCE +35 -0
  45. lib/IsoSpecCppPy.lib +0 -0
@@ -0,0 +1,206 @@
1
+ /* This file was taken from Boost, as permitted by Boost licence,
2
+ * with slight modifications. The reason is: we don't want to introduce
3
+ * dependency on the whole Boost just for this one thing.
4
+ *
5
+ * Source: boost random/binomial_distribution.hpp header file, at version 1.71
6
+ *
7
+ * Copyright Steven Watanabe 2010
8
+ * Distributed under the Boost Software License, Version 1.0. (See
9
+ * accompanying file LICENSE_1_0.txt or copy at
10
+ * http://www.boost.org/LICENSE_1_0.txt)
11
+ *
12
+ * See http://www.boost.org for most recent version including documentation.
13
+ *
14
+ */
15
+
16
+ #pragma once
17
+
18
+ #include "isoMath.h"
19
+ #include <cstdlib>
20
+ #include <cstdint>
21
+ #include <cmath>
22
+ #include <limits>
23
+
24
+
25
+ namespace IsoSpec {
26
+
27
+ typedef double RealType;
28
+ typedef int64_t IntType;
29
+
30
+
31
+ static const RealType btrd_binomial_table[10] = {
32
+ 0.08106146679532726,
33
+ 0.04134069595540929,
34
+ 0.02767792568499834,
35
+ 0.02079067210376509,
36
+ 0.01664469118982119,
37
+ 0.01387612882307075,
38
+ 0.01189670994589177,
39
+ 0.01041126526197209,
40
+ 0.009255462182712733,
41
+ 0.008330563433362871
42
+ };
43
+
44
+
45
+ /**
46
+ * The binomial distribution is an integer valued distribution with
47
+ * two parameters, @c t and @c p. The values of the distribution
48
+ * are within the range [0,t].
49
+ *
50
+ * The distribution function is
51
+ * \f$\displaystyle P(k) = {t \choose k}p^k(1-p)^{t-k}\f$.
52
+ *
53
+ * The algorithm used is the BTRD algorithm described in
54
+ *
55
+ * @blockquote
56
+ * "The generation of binomial random variates", Wolfgang Hormann,
57
+ * Journal of Statistical Computation and Simulation, Volume 46,
58
+ * Issue 1 & 2 April 1993 , pages 101 - 110
59
+ * @endblockquote
60
+ */
61
+
62
+
63
+ // computes the correction factor for the Stirling approximation
64
+ // for log(k!)
65
+ static RealType fc(IntType k)
66
+ {
67
+ if(k < 10) { return btrd_binomial_table[k]; }
68
+ else
69
+ {
70
+ RealType ikp1 = RealType(1) / (k + 1);
71
+ return (RealType(1)/12
72
+ - (RealType(1)/360
73
+ - (RealType(1)/1260)*(ikp1*ikp1))*(ikp1*ikp1))*ikp1;
74
+ }
75
+ }
76
+
77
+ IntType btrd(IntType _t, RealType p, IntType m, std::mt19937& urng = random_gen)
78
+ {
79
+ using std::floor;
80
+ using std::abs;
81
+ using std::log;
82
+
83
+ RealType btrd_r = p/(1-p);
84
+ RealType btrd_nr = (_t+1)*btrd_r;
85
+ RealType btrd_npq = _t*p*(1-p);
86
+ RealType sqrt_npq = sqrt(btrd_npq);
87
+ RealType btrd_b = 1.15 + 2.53 * sqrt_npq;
88
+ RealType btrd_a = -0.0873 + 0.0248*btrd_b + 0.01*p;
89
+ RealType btrd_c = _t*p + 0.5;
90
+ RealType btrd_alpha = (2.83 + 5.1/btrd_b) * sqrt_npq;
91
+ RealType btrd_v_r = 0.92 - 4.2/btrd_b;
92
+ RealType btrd_u_rv_r = 0.86*btrd_v_r;
93
+
94
+ while(true) {
95
+ RealType u;
96
+ RealType v = rdvariate_unif01(urng);
97
+ if(v <= btrd_u_rv_r) {
98
+ u = v/btrd_v_r - 0.43;
99
+ return static_cast<IntType>(floor(
100
+ (2*btrd_a/(0.5 - abs(u)) + btrd_b)*u + btrd_c));
101
+ }
102
+
103
+ if(v >= btrd_v_r) {
104
+ u = rdvariate_unif01(urng) - 0.5;
105
+ } else {
106
+ u = v/btrd_v_r - 0.93;
107
+ u = ((u < 0)? -0.5 : 0.5) - u;
108
+ v = rdvariate_unif01(urng) * btrd_v_r;
109
+ }
110
+
111
+ RealType us = 0.5 - abs(u);
112
+ IntType k = static_cast<IntType>(floor((2*btrd_a/us + btrd_b)*u + btrd_c));
113
+ if(k < 0 || k > _t) continue;
114
+ v = v*btrd_alpha/(btrd_a/(us*us) + btrd_b);
115
+ RealType km = abs(k - m);
116
+ if(km <= 15) {
117
+ RealType f = 1;
118
+ if(m < k) {
119
+ IntType i = m;
120
+ do {
121
+ ++i;
122
+ f = f*(btrd_nr/i - btrd_r);
123
+ } while(i != k);
124
+ } else if(m > k) {
125
+ IntType i = k;
126
+ do {
127
+ ++i;
128
+ v = v*(btrd_nr/i - btrd_r);
129
+ } while(i != m);
130
+ }
131
+ if(v <= f) return k;
132
+ else continue;
133
+ } else {
134
+ // final acceptance/rejection
135
+ v = log(v);
136
+ RealType rho =
137
+ (km/btrd_npq)*(((km/3. + 0.625)*km + 1./6)/btrd_npq + 0.5);
138
+ RealType t = -km*km/(2*btrd_npq);
139
+ if(v < t - rho) return k;
140
+ if(v > t + rho) continue;
141
+
142
+ IntType nm = _t - m + 1;
143
+ RealType h = (m + 0.5)*log((m + 1)/(btrd_r*nm))
144
+ + fc(m) + fc(_t - m);
145
+
146
+ IntType nk = _t - k + 1;
147
+ if(v <= h + (_t+1)*log(static_cast<RealType>(nm)/nk)
148
+ + (k + 0.5)*log(nk*btrd_r/(k+1))
149
+ - fc(k)
150
+ - fc(_t - k))
151
+ {
152
+ return k;
153
+ } else {
154
+ continue;
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+ IntType invert(IntType t, RealType p, std::mt19937& urng = random_gen)
161
+ {
162
+ RealType q = 1 - p;
163
+ RealType s = p / q;
164
+ RealType a = (t + 1) * s;
165
+ RealType r = pow((1 - p), static_cast<RealType>(t));
166
+ RealType u = rdvariate_unif01(urng);
167
+ IntType x = 0;
168
+ while(u > r) {
169
+ u = u - r;
170
+ ++x;
171
+ RealType r1 = ((a/x) - s) * r;
172
+ // If r gets too small then the round-off error
173
+ // becomes a problem. At this point, p(i) is
174
+ // decreasing exponentially, so if we just call
175
+ // it 0, it's close enough. Note that the
176
+ // minimum value of q_n is about 1e-7, so we
177
+ // may need to be a little careful to make sure that
178
+ // we don't terminate the first time through the loop
179
+ // for float. (Hence the test that r is decreasing)
180
+ if(r1 < std::numeric_limits<RealType>::epsilon() && r1 < r) {
181
+ break;
182
+ }
183
+ r = r1;
184
+ }
185
+ return x;
186
+ }
187
+
188
+
189
+ IntType boost_binomial_distribution_variate(IntType t_arg, RealType p_arg, std::mt19937& urng = random_gen)
190
+ {
191
+ bool other_side = p_arg > 0.5;
192
+ RealType fake_p = other_side ? 1.0 - p_arg : p_arg;
193
+ IntType m = static_cast<IntType>((t_arg+1)*fake_p);
194
+ IntType result;
195
+ if(m < 11)
196
+ result = invert(t_arg, fake_p, urng);
197
+ else
198
+ result = btrd(t_arg, fake_p, m, urng);
199
+
200
+ if(other_side)
201
+ return t_arg - result;
202
+ else
203
+ return result;
204
+ }
205
+
206
+ } // namespace IsoSpec
@@ -0,0 +1,126 @@
1
+ /*
2
+ * Copyright (C) 2015-2026 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
+ // The library's vocabulary for "a molecule as element counts", and the one
18
+ // implementation of turning that into the isotope masses and probabilities an
19
+ // Iso is built from.
20
+ //
21
+ // This lives in its own header because three unrelated things need it: the
22
+ // formula parser (isoSpec++.cpp), the peptide-sequence parsers (fasta_mods.h),
23
+ // and the C ABI (cwrapper.cpp). It used to sit inside fasta_mods.h, which
24
+ // meant the core formula path could only share the resolution by including a
25
+ // peptide-modification header -- backwards, so it didn't, and kept its own
26
+ // copy instead. See docs/ai/composition_expansion.md.
27
+
28
+ #pragma once
29
+
30
+ #include <vector>
31
+
32
+ #include "isoSpec++.h"
33
+
34
+ namespace IsoSpec {
35
+
36
+ //! A resolved elemental composition: parallel arrays of
37
+ //! (element_table_first_index, count) pairs, one per element actually
38
+ //! present (non-zero net count).
39
+ //!
40
+ //! Counts are *signed*, and parse_fasta_with_mods/_full really can return a
41
+ //! negative one: a modification's composition delta may remove more atoms of
42
+ //! some element than the bare sequence provides ("G[UNIMOD:11]" nets H-1
43
+ //! S-1). That is a legitimate intermediate -- adding a second modification
44
+ //! could bring it back up -- so the parser does not reject it. The
45
+ //! non-negativity check belongs at the point a composition becomes a
46
+ //! molecule, and lives in build_iso_from_composition; anything else
47
+ //! consuming an ElementComposition directly (the C ABI's
48
+ //! parseFastaWithModsC, R's RParsePeptideSequence) must do its own check
49
+ //! before handing the counts to an Iso.
50
+ struct ElementComposition {
51
+ std::vector<int> element_first_index;
52
+ std::vector<int> count;
53
+
54
+ //! Empties both vectors without releasing their capacity -- a caller
55
+ //! that reuses one ElementComposition across many parse_fasta_with_mods_into
56
+ //! calls (e.g. building a cache over millions of peptides) pays for the
57
+ //! underlying heap allocation at most a handful of times total (until
58
+ //! capacity reaches this feature's real ceiling, ~30 elements), not once
59
+ //! per call the way the value-returning parse_fasta_with_mods does.
60
+ void clear() {
61
+ element_first_index.clear();
62
+ count.clear();
63
+ }
64
+ };
65
+
66
+ //! A composition expanded to the flat, per-isotope form the generic
67
+ //! Iso(dimNumber, isotopeNumbers, atomCounts, masses, probs) constructor
68
+ //! takes: one isotopeNumbers/atomCounts entry per element of the
69
+ //! composition, and one isotope_masses/isotope_probabilities entry per
70
+ //! isotope, element-major, in the composition's own order. Exactly the
71
+ //! layout the C ABI's setupIso expects, since that constructor is what it
72
+ //! forwards to.
73
+ struct ExpandedComposition {
74
+ std::vector<int> isotopeNumbers;
75
+ std::vector<int> atomCounts;
76
+ std::vector<double> isotope_masses;
77
+ std::vector<double> isotope_probabilities;
78
+
79
+ //! Empties all four vectors without releasing their capacity -- same
80
+ //! reuse contract, for the same reason, as ElementComposition::clear
81
+ //! above.
82
+ void clear() {
83
+ isotopeNumbers.clear();
84
+ atomCounts.clear();
85
+ isotope_masses.clear();
86
+ isotope_probabilities.clear();
87
+ }
88
+ };
89
+
90
+ //! Resolves each element of `composition` to its isotopes' masses and
91
+ //! probabilities from element_tables.h, filling a caller-owned `out`
92
+ //! (cleared first).
93
+ //!
94
+ //! The single implementation of that resolution. Everything that turns
95
+ //! element counts into an Iso goes through here: parse_formula (the formula
96
+ //! string path), build_iso_from_composition (the peptide-sequence path), and
97
+ //! cwrapper.h's expandCompositionC -- which exists so that a binding
98
+ //! language need not carry its own copy of the periodic table either.
99
+ //! IsoSpecPy did carry one (IsoParamsFromDict, walking PeriodicTbl's
100
+ //! symbol->isotopes dicts) until that entry point existed.
101
+ //!
102
+ //! Counts are copied through unchanged, negatives included: expanding a
103
+ //! composition is not the same as making a molecule out of one, and the
104
+ //! non-negativity check belongs at the latter -- see ElementComposition's
105
+ //! note above, and build_iso_from_composition, which does check.
106
+ void expand_composition_into(const ElementComposition& composition, ExpandedComposition& out,
107
+ bool use_nominal_masses = false);
108
+
109
+ //! Throws std::invalid_argument if any of `composition`'s counts is
110
+ //! negative, naming the offending elements. The check every path from a
111
+ //! composition to an Iso has to make: a negative atom count reaching Iso's
112
+ //! constructor is not merely a wrong answer but undefined behaviour --
113
+ //! Marginal::computeModeConf() sizes its configuration buffer from the count
114
+ //! and writeInitialConfiguration then walks off the end of it (ASan catches
115
+ //! it as a heap-buffer-overflow).
116
+ void reject_negative_counts(const ElementComposition& composition);
117
+
118
+ //! Resolves a composition (as returned by parse_fasta_with_mods[_full]) into
119
+ //! an Iso via the same generic Iso(dimNumber, isotopeNumbers, atomCounts,
120
+ //! masses, probs) constructor parse_formula uses. Throws
121
+ //! std::invalid_argument if any accumulated element count is negative (a
122
+ //! modification set that removes more atoms of some element than the base
123
+ //! sequence plus other modifications provide).
124
+ Iso build_iso_from_composition(const ElementComposition& composition, bool use_nominal_masses = false);
125
+
126
+ } // namespace IsoSpec
@@ -0,0 +1,38 @@
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
+ namespace IsoSpec
20
+ {
21
+
22
+ typedef int* Conf;
23
+
24
+ struct ProbAndConfPtr
25
+ {
26
+ // For some reason std::pair isn't trivially copyable...
27
+ double first;
28
+ Conf second;
29
+
30
+ ProbAndConfPtr(double p, Conf c) : first(p), second(c) {}
31
+
32
+ bool operator<(const ProbAndConfPtr& other) const
33
+ {
34
+ return first < other.first;
35
+ }
36
+ };
37
+
38
+ } // namespace IsoSpec
@@ -0,0 +1,271 @@
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 "platform.h"
20
+
21
+ #define ISOSPEC_ALGO_LAYERED 0
22
+ #define ISOSPEC_ALGO_ORDERED 1
23
+ #define ISOSPEC_ALGO_THRESHOLD_ABSOLUTE 2
24
+ #define ISOSPEC_ALGO_THRESHOLD_RELATIVE 3
25
+ #define ISOSPEC_ALGO_LAYERED_ESTIMATE 4
26
+
27
+
28
+ // Error reporting across the C ABI: these functions never let a C++ exception
29
+ // escape (that would be undefined behaviour for a C / cffi caller). On bad input
30
+ // or out-of-memory they instead return an out-of-band error value:
31
+ // * functions returning a handle/pointer return NULL,
32
+ // * functions returning a double return NaN,
33
+ // * functions returning an integer/bool return 0 / false.
34
+ // Callers should check the returned handle for NULL before using it.
35
+
36
+ #ifdef __cplusplus
37
+ extern "C" {
38
+ #else
39
+ #include <stdbool.h>
40
+ #endif
41
+
42
+ ISOSPEC_C_API void * setupIso(int dimNumber,
43
+ const int* isotopeNumbers,
44
+ const int* atomCounts,
45
+ const double* isotopeMasses,
46
+ const double* isotopeProbabilities);
47
+
48
+ ISOSPEC_C_API void * isoFromFasta(const char* fasta, bool use_nominal_masses, bool add_water);
49
+
50
+ ISOSPEC_C_API double getLightestPeakMassIso(void* iso);
51
+ ISOSPEC_C_API double getLightestPeakLProbIso(void* iso);
52
+ ISOSPEC_C_API void getLightestPeakSignature(void* iso, int* space);
53
+ ISOSPEC_C_API double getHeaviestPeakMassIso(void* iso);
54
+ ISOSPEC_C_API double getHeaviestPeakLProbIso(void* iso);
55
+ ISOSPEC_C_API void getHeaviestPeakSignature(void* iso, int* space);
56
+ ISOSPEC_C_API double getMonoisotopicPeakMassIso(void* iso);
57
+ ISOSPEC_C_API double getMonoisotopicPeakLProbIso(void* iso);
58
+ ISOSPEC_C_API void getMonoisotopicPeakSignature(void* iso, int* space);
59
+ ISOSPEC_C_API double getModeLProbIso(void* iso);
60
+ ISOSPEC_C_API double getModeMassIso(void* iso);
61
+ ISOSPEC_C_API double getTheoreticalAverageMassIso(void* iso);
62
+ ISOSPEC_C_API double getIsoVariance(void* iso);
63
+ ISOSPEC_C_API double getIsoStddev(void* iso);
64
+ ISOSPEC_C_API double* getMarginalLogSizeEstimates(void* iso, double target_total_prob);
65
+
66
+
67
+ ISOSPEC_C_API void deleteIso(void* iso);
68
+
69
+
70
+ // ______________________________________________________THRESHOLD GENERATOR
71
+ ISOSPEC_C_API void* setupIsoThresholdGenerator(void* iso,
72
+ double threshold,
73
+ bool _absolute,
74
+ int _tabSize,
75
+ int _hashSize,
76
+ bool reorder_marginals);
77
+ ISOSPEC_C_API double massIsoThresholdGenerator(void* generator);
78
+ ISOSPEC_C_API double lprobIsoThresholdGenerator(void* generator);
79
+ ISOSPEC_C_API double probIsoThresholdGenerator(void* generator);
80
+ ISOSPEC_C_API void get_conf_signatureIsoThresholdGenerator(void* generator, int* space);
81
+ ISOSPEC_C_API bool advanceToNextConfigurationIsoThresholdGenerator(void* generator);
82
+ ISOSPEC_C_API void deleteIsoThresholdGenerator(void* generator);
83
+
84
+
85
+ // ______________________________________________________LAYERED GENERATOR
86
+ ISOSPEC_C_API void* setupIsoLayeredGenerator(void* iso,
87
+ int _tabSize,
88
+ int _hashSize,
89
+ bool reorder_marginals,
90
+ double t_prob_hint);
91
+ ISOSPEC_C_API double massIsoLayeredGenerator(void* generator);
92
+ ISOSPEC_C_API double lprobIsoLayeredGenerator(void* generator);
93
+ ISOSPEC_C_API double probIsoLayeredGenerator(void* generator);
94
+ ISOSPEC_C_API void get_conf_signatureIsoLayeredGenerator(void* generator, int* space);
95
+ ISOSPEC_C_API bool advanceToNextConfigurationIsoLayeredGenerator(void* generator);
96
+ ISOSPEC_C_API void deleteIsoLayeredGenerator(void* generator);
97
+
98
+ // ______________________________________________________ORDERED GENERATOR
99
+ ISOSPEC_C_API void* setupIsoOrderedGenerator(void* iso,
100
+ int _tabSize,
101
+ int _hashSize);
102
+ ISOSPEC_C_API double massIsoOrderedGenerator(void* generator);
103
+ ISOSPEC_C_API double lprobIsoOrderedGenerator(void* generator);
104
+ ISOSPEC_C_API double probIsoOrderedGenerator(void* generator);
105
+ ISOSPEC_C_API void get_conf_signatureIsoOrderedGenerator(void* generator, int* space);
106
+ ISOSPEC_C_API bool advanceToNextConfigurationIsoOrderedGenerator(void* generator);
107
+ ISOSPEC_C_API void deleteIsoOrderedGenerator(void* generator);
108
+
109
+ // ______________________________________________________STOCHASTIC GENERATOR
110
+ ISOSPEC_C_API void* setupIsoStochasticGenerator(void* iso,
111
+ size_t no_molecules,
112
+ double precision,
113
+ double beta_bias);
114
+ ISOSPEC_C_API double massIsoStochasticGenerator(void* generator);
115
+ ISOSPEC_C_API double lprobIsoStochasticGenerator(void* generator);
116
+ ISOSPEC_C_API double probIsoStochasticGenerator(void* generator);
117
+ ISOSPEC_C_API void get_conf_signatureIsoStochasticGenerator(void* generator, int* space);
118
+ ISOSPEC_C_API bool advanceToNextConfigurationIsoStochasticGenerator(void* generator);
119
+ ISOSPEC_C_API void deleteIsoStochasticGenerator(void* generator);
120
+
121
+ ISOSPEC_C_API void* setupThresholdFixedEnvelope(void* iso,
122
+ double threshold,
123
+ bool absolute,
124
+ bool get_confs);
125
+
126
+ ISOSPEC_C_API void* setupTotalProbFixedEnvelope(void* iso,
127
+ double taget_coverage,
128
+ bool optimize,
129
+ bool get_confs);
130
+
131
+ ISOSPEC_C_API void* setupStochasticFixedEnvelope(void* iso,
132
+ size_t no_molecules,
133
+ double precision,
134
+ double beta_bias,
135
+ bool get_confs);
136
+
137
+ ISOSPEC_C_API void* setupBinnedFixedEnvelope(void* iso,
138
+ double target_total_prob,
139
+ double bin_width,
140
+ double bin_middle);
141
+
142
+ ISOSPEC_C_API void freeReleasedArray(void* array);
143
+
144
+ ISOSPEC_C_API void array_add(double* array, size_t N, double what);
145
+ ISOSPEC_C_API void array_mul(double* array, size_t N, double what);
146
+ ISOSPEC_C_API void array_fma(double* array, size_t N, double mul, double add);
147
+
148
+ ISOSPEC_C_API void* setupFixedEnvelope(double* masses, double* probs, size_t size, bool mass_sorted, bool prob_sorted, double total_prob);
149
+ 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);
150
+ ISOSPEC_C_API void* copyFixedEnvelope(void* other);
151
+ ISOSPEC_C_API void deleteFixedEnvelope(void* tabulator, bool releaseEverything);
152
+
153
+ /* These three hand the envelope's array over to the caller, who must free() it
154
+ (with freeReleasedArray) once done. That costs a copy of the whole array
155
+ whenever the envelope did not allocate it with plain malloc() -- which is the
156
+ normal case now that everything the library produces is SIMD-aligned, and one
157
+ that grew large enough is mapped straight from the OS. Prefer the *WithDeleter
158
+ variants below, which never copy. */
159
+ ISOSPEC_C_API const double* massesFixedEnvelope(void* tabulator);
160
+ ISOSPEC_C_API const double* probsFixedEnvelope(void* tabulator);
161
+ ISOSPEC_C_API const int* confsFixedEnvelope(void* tabulator);
162
+ ISOSPEC_C_API size_t confs_noFixedEnvelope(void* tabulator);
163
+
164
+ /* How a buffer obtained from one of the *WithDeleter entry points below has to
165
+ be given back: deleter(array, size), exactly once, with the very size that
166
+ came out alongside the pointer. free() is not, in general, the right answer.
167
+ Call it through freeReleasedArrayWithDeleter() rather than directly, so
168
+ callers that cannot invoke a raw function pointer (cffi, say) need not. */
169
+ typedef void (*IsoSpecArrayDeleter)(void* array, size_t size);
170
+
171
+ /* Zero-copy counterparts of the three getters above: each yields the array's
172
+ pointer and writes out the (size, deleter) pair needed to release it. Both
173
+ out-parameters may be NULL if not wanted -- but then the array can only be
174
+ leaked. A NULL return means either an empty envelope or an error. */
175
+ ISOSPEC_C_API double* massesFixedEnvelopeWithDeleter(void* tabulator, size_t* size_out, IsoSpecArrayDeleter* deleter_out);
176
+ ISOSPEC_C_API double* probsFixedEnvelopeWithDeleter(void* tabulator, size_t* size_out, IsoSpecArrayDeleter* deleter_out);
177
+ ISOSPEC_C_API int* confsFixedEnvelopeWithDeleter(void* tabulator, size_t* size_out, IsoSpecArrayDeleter* deleter_out);
178
+
179
+ ISOSPEC_C_API void freeReleasedArrayWithDeleter(void* array, size_t size, IsoSpecArrayDeleter deleter);
180
+
181
+ ISOSPEC_C_API double empiricAverageMass(void* tabulator);
182
+ ISOSPEC_C_API double empiricVariance(void* tabulator);
183
+ ISOSPEC_C_API double empiricStddev(void* tabulator);
184
+
185
+ ISOSPEC_C_API double wassersteinDistance(void* tabulator1, void* tabulator2);
186
+ ISOSPEC_C_API double orientedWassersteinDistance(void* tabulator1, void* tabulator2);
187
+ ISOSPEC_C_API double abyssalWassersteinDistance(void* tabulator1, void* tabulator2, double abyss_depth, double other_scale);
188
+ // ISOSPEC_C_API double abyssalWassersteinDistanceGrad(void* const* envelopes, const double* scales, double* ret_gradient, size_t N, double abyss_depth_exp, double abyss_depth_the);
189
+
190
+ struct ws_match_res{
191
+ double res1;
192
+ double res2;
193
+ double flow;
194
+ };
195
+
196
+ ISOSPEC_C_API struct ws_match_res wassersteinMatch(void* tabulator1, void* tabulator2, double flow_dist, double other_scale);
197
+
198
+ ISOSPEC_C_API void* addEnvelopes(void* tabulator1, void* tabulator2);
199
+ ISOSPEC_C_API void* convolveEnvelopes(void* tabulator1, void* tabulator2);
200
+
201
+ ISOSPEC_C_API double getTotalProbOfEnvelope(void* envelope);
202
+ ISOSPEC_C_API void scaleEnvelope(void* envelope, double factor);
203
+ ISOSPEC_C_API void normalizeEnvelope(void* envelope);
204
+ ISOSPEC_C_API void shiftMassEnvelope(void* envelope, double d_mass);
205
+ ISOSPEC_C_API void resampleEnvelope(void* envelope, size_t ionic_current, double beta_bias);
206
+ ISOSPEC_C_API void* binnedEnvelope(void* envelope, double width, double middle);
207
+ ISOSPEC_C_API void* linearCombination(void* const * const envelopes, const double* intensities, size_t count);
208
+
209
+ ISOSPEC_C_API void sortEnvelopeByMass(void* envelope);
210
+ ISOSPEC_C_API void sortEnvelopeByProb(void* envelope);
211
+
212
+ ISOSPEC_C_API void parse_fasta_c(const char* fasta, int atomCounts[6]);
213
+
214
+ /* Unimod-modification-aware peptide sequence parsing (fasta_mods.h/unimod.h):
215
+ recognizes [UNIMOD:<id>] brackets in N-terminal ("[id]-SEQ"), internal
216
+ ("X[id]"), and C-terminal ("SEQ-[id]") placement -- see docs/ai/unimod.md.
217
+ unimod_db_path == NULL or "" selects the compile-time embedded default
218
+ table; any other path is loaded and cached (see unimod_table_for_path).
219
+ NULL on error (malformed bracket, unknown/excluded id) -- callers must
220
+ NULL-check like every other handle-returning function here. */
221
+ ISOSPEC_C_API void* isoFromFastaWithMods(const char* sequence, bool use_nominal_masses, bool add_water, const char* unimod_db_path);
222
+
223
+ /* Opaque parsed-composition handle: NULL_UNIMOD_db_path selects the embedded
224
+ default table, same as above. NULL return on error. */
225
+ ISOSPEC_C_API void* parseFastaWithModsC(const char* sequence, const char* unimod_db_path);
226
+ ISOSPEC_C_API size_t compositionSizeC(void* composition);
227
+ /* Element symbols, e.g. "C", "H", "Se" -- static strings (elem_table_symbol),
228
+ must NOT be freed individually; only the returned array belongs to the
229
+ handle, freed by deleteCompositionC. */
230
+ ISOSPEC_C_API const char* const* compositionSymbolsC(void* composition);
231
+ ISOSPEC_C_API const int* compositionCountsC(void* composition);
232
+ ISOSPEC_C_API void deleteCompositionC(void* composition);
233
+
234
+ /* Composition -> the flat per-isotope arrays setupIso takes, with the
235
+ isotopes resolved from the library's own element tables (see
236
+ composition.h's expand_composition_into, the single implementation).
237
+
238
+ This is the rung between setupIso -- which requires the caller to already
239
+ know every isotope mass and probability, i.e. to carry its own copy of the
240
+ periodic table -- and isoFromFasta/isoFromFastaWithMods, which accept
241
+ nothing but a sequence. A binding holding a composition (symbol, count)
242
+ has one of those, not the other, and this is what it should call.
243
+
244
+ `symbols` are element symbols spelled as in elem_table_symbol ("C", "H",
245
+ "Se"), `size` entries, paired positionally with `counts`. Element order is
246
+ preserved throughout, so a caller can match the outputs back up by index.
247
+
248
+ Counts may be negative: a composition is not yet a molecule, and rejecting
249
+ that is the caller's job at the point it builds one (see composition.h).
250
+ NULL on an unknown element symbol or OOM. */
251
+ ISOSPEC_C_API void* expandCompositionC(const char* const* symbols, const int* counts, size_t size, bool use_nominal_masses);
252
+ /* `size` entries each, in the input's element order. */
253
+ ISOSPEC_C_API const int* expandedIsotopeNumbersC(void* expanded);
254
+ ISOSPEC_C_API const int* expandedAtomCountsC(void* expanded);
255
+ /* sum(expandedIsotopeNumbersC) entries each, element-major. Exactly what
256
+ setupIso's isotopeMasses/isotopeProbabilities arguments want. */
257
+ ISOSPEC_C_API const double* expandedIsotopeMassesC(void* expanded);
258
+ ISOSPEC_C_API const double* expandedIsotopeProbabilitiesC(void* expanded);
259
+ /* All four arrays above belong to the handle and die with it. */
260
+ ISOSPEC_C_API void deleteExpandedCompositionC(void* expanded);
261
+
262
+ /* What the library's batched kernels are vectorised to on this machine, as a
263
+ stable lowercase token: "scalar", "sse2", "avx", "avx2", "avx512", "neon", or
264
+ "simd" for a vector unit with no name here. Never NULL; a static string, so
265
+ it must NOT be freed. See active_simd_level() in isa_kernels.h. */
266
+ ISOSPEC_C_API const char* activeSimdLevel(void);
267
+
268
+
269
+ #ifdef __cplusplus
270
+ }
271
+ #endif