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.
- IsoSpecPy/Advanced.py +32 -0
- IsoSpecPy/Distributions.py +93 -0
- IsoSpecPy/Formulas.py +71 -0
- IsoSpecPy/IsoSpec++/aligned_ptr.h +638 -0
- IsoSpecPy/IsoSpec++/allocator.h +69 -0
- IsoSpecPy/IsoSpec++/btrd.h +206 -0
- IsoSpecPy/IsoSpec++/composition.h +126 -0
- IsoSpecPy/IsoSpec++/conf.h +38 -0
- IsoSpecPy/IsoSpec++/cwrapper.h +271 -0
- IsoSpecPy/IsoSpec++/dirtyAllocator.h +58 -0
- IsoSpecPy/IsoSpec++/element_lookup.h +36 -0
- IsoSpecPy/IsoSpec++/element_tables.h +50 -0
- IsoSpecPy/IsoSpec++/fasta.h +70 -0
- IsoSpecPy/IsoSpec++/fasta_mods.h +70 -0
- IsoSpecPy/IsoSpec++/fixedEnvelopes.h +418 -0
- IsoSpecPy/IsoSpec++/isa_kernel_impl.h +192 -0
- IsoSpecPy/IsoSpec++/isa_kernels.h +172 -0
- IsoSpecPy/IsoSpec++/isoMath.h +121 -0
- IsoSpecPy/IsoSpec++/isoSpec++.h +801 -0
- IsoSpecPy/IsoSpec++/iso_simd.h +48 -0
- IsoSpecPy/IsoSpec++/marginalTrek++.h +614 -0
- IsoSpecPy/IsoSpec++/misc.h +229 -0
- IsoSpecPy/IsoSpec++/mman.h +67 -0
- IsoSpecPy/IsoSpec++/operators.h +150 -0
- IsoSpecPy/IsoSpec++/platform.h +180 -0
- IsoSpecPy/IsoSpec++/platform_incl.h +33 -0
- IsoSpecPy/IsoSpec++/pod_vector.h +400 -0
- IsoSpecPy/IsoSpec++/summator.h +118 -0
- IsoSpecPy/IsoSpec++/unimod.h +80 -0
- IsoSpecPy/IsoSpec++/unimod_support.h +2169 -0
- IsoSpecPy/IsoSpec++/unimod_table_data.h +1027 -0
- IsoSpecPy/IsoSpecPy.py +1088 -0
- IsoSpecPy/IsoSpecPyOld.py +290 -0
- IsoSpecPy/PeriodicTbl.py +51 -0
- IsoSpecPy/__init__.py +19 -0
- IsoSpecPy/__main__.py +25 -0
- IsoSpecPy/approximations.py +122 -0
- IsoSpecPy/confs_passthrough.py +16 -0
- IsoSpecPy/isoFFI.py +290 -0
- bin/IsoSpecCppPy.dll +0 -0
- isospecpy-2.5.0.dist-info/METADATA +220 -0
- isospecpy-2.5.0.dist-info/RECORD +45 -0
- isospecpy-2.5.0.dist-info/WHEEL +5 -0
- isospecpy-2.5.0.dist-info/licenses/LICENCE +35 -0
- 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
|