IsoSpecPy 2.5.0__py3-none-win_amd64.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,400 @@
|
|
|
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 <type_traits>
|
|
20
|
+
#include <cstdlib>
|
|
21
|
+
#include <cstddef>
|
|
22
|
+
#include <utility>
|
|
23
|
+
#include <new>
|
|
24
|
+
#include <algorithm>
|
|
25
|
+
#include "platform.h"
|
|
26
|
+
#include "conf.h"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
template<typename T> class unsafe_pod_vector;
|
|
31
|
+
|
|
32
|
+
template<typename T> class pod_vector
|
|
33
|
+
{
|
|
34
|
+
T* backend_past_end;
|
|
35
|
+
T* first_free;
|
|
36
|
+
T* store;
|
|
37
|
+
|
|
38
|
+
public:
|
|
39
|
+
explicit pod_vector(size_t initial_size = 16)
|
|
40
|
+
{
|
|
41
|
+
#if !ISOSPEC_BUILDING_R
|
|
42
|
+
static_assert(std::is_trivially_copyable<T>::value, "Cannot use a pod_vector with a non-Plain Old Data type.");
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
store = reinterpret_cast<T*>(malloc(sizeof(T) * initial_size));
|
|
46
|
+
if(store == NULL)
|
|
47
|
+
throw std::bad_alloc();
|
|
48
|
+
first_free = store;
|
|
49
|
+
backend_past_end = store + initial_size;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
pod_vector(const pod_vector<T>& other) = delete;
|
|
53
|
+
pod_vector& operator=(const pod_vector<T>& other) = delete;
|
|
54
|
+
pod_vector& operator=(pod_vector<T>&& other)
|
|
55
|
+
{
|
|
56
|
+
free(store);
|
|
57
|
+
backend_past_end = other.backend_past_end;
|
|
58
|
+
first_free = other.first_free;
|
|
59
|
+
store = other.store;
|
|
60
|
+
other.backend_past_end = other.first_free = other.store = NULL;
|
|
61
|
+
return *this;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
pod_vector(pod_vector<T>&& other)
|
|
65
|
+
{
|
|
66
|
+
backend_past_end = other.backend_past_end;
|
|
67
|
+
first_free = other.first_free;
|
|
68
|
+
store = other.store;
|
|
69
|
+
other.backend_past_end = other.first_free = other.store = NULL;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
~pod_vector() { free(store); backend_past_end = first_free = store = NULL; }
|
|
73
|
+
|
|
74
|
+
explicit pod_vector(unsafe_pod_vector<T>&& other)
|
|
75
|
+
{
|
|
76
|
+
backend_past_end = other.backend_past_end;
|
|
77
|
+
first_free = other.first_free;
|
|
78
|
+
store = other.store;
|
|
79
|
+
other.backend_past_end = other.first_free = other.store = NULL;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
void fast_reserve(size_t n)
|
|
83
|
+
{
|
|
84
|
+
ISOSPEC_IMPOSSIBLE(n < static_cast<size_t>(backend_past_end - store));
|
|
85
|
+
const std::ptrdiff_t store_used_size = first_free - store;
|
|
86
|
+
T* new_store = reinterpret_cast<T*>(realloc(store, n * sizeof(T)));
|
|
87
|
+
if(new_store == NULL)
|
|
88
|
+
throw std::bad_alloc();
|
|
89
|
+
first_free = new_store + store_used_size;
|
|
90
|
+
backend_past_end = new_store + n;
|
|
91
|
+
store = new_store;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
void reserve(size_t n)
|
|
95
|
+
{
|
|
96
|
+
if (n > static_cast<size_t>(backend_past_end - store))
|
|
97
|
+
fast_reserve(n);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
void resize(size_t new_size)
|
|
101
|
+
{
|
|
102
|
+
ISOSPEC_IMPOSSIBLE(static_cast<std::ptrdiff_t>(new_size) < first_free - store);
|
|
103
|
+
size_t cap = capacity();
|
|
104
|
+
if(cap < new_size)
|
|
105
|
+
{
|
|
106
|
+
cap = (std::max<size_t>)(4, cap);
|
|
107
|
+
do {
|
|
108
|
+
cap = cap * 2;
|
|
109
|
+
} while(cap < new_size);
|
|
110
|
+
fast_reserve(cap);
|
|
111
|
+
}
|
|
112
|
+
first_free = store + new_size;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
void resize_and_wipe(size_t new_size)
|
|
116
|
+
{
|
|
117
|
+
size_t old_size = size();
|
|
118
|
+
ISOSPEC_IMPOSSIBLE(new_size <= old_size);
|
|
119
|
+
resize(new_size);
|
|
120
|
+
memset(store+old_size, 0, (new_size-old_size) * sizeof(T));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
ISOSPEC_FORCE_INLINE void nocheck_push_back(const T& val) noexcept
|
|
124
|
+
{
|
|
125
|
+
ISOSPEC_IMPOSSIBLE(first_free >= backend_past_end);
|
|
126
|
+
*first_free = val;
|
|
127
|
+
first_free++;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
ISOSPEC_FORCE_INLINE void push_back(const T& val)
|
|
131
|
+
{
|
|
132
|
+
if(first_free >= backend_past_end)
|
|
133
|
+
fast_reserve((std::max<std::ptrdiff_t>)(4, (backend_past_end-store)) * 2);
|
|
134
|
+
*first_free = val;
|
|
135
|
+
first_free++;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
ISOSPEC_FORCE_INLINE T& operator[](size_t n) noexcept
|
|
139
|
+
{
|
|
140
|
+
ISOSPEC_IMPOSSIBLE(store + n >= first_free);
|
|
141
|
+
return store[n];
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
ISOSPEC_FORCE_INLINE const T& operator[](size_t n) const noexcept
|
|
145
|
+
{
|
|
146
|
+
ISOSPEC_IMPOSSIBLE(store + n >= first_free);
|
|
147
|
+
return store[n];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
ISOSPEC_FORCE_INLINE size_t size() const noexcept
|
|
151
|
+
{
|
|
152
|
+
return first_free - store;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
ISOSPEC_FORCE_INLINE size_t capacity() const noexcept
|
|
156
|
+
{
|
|
157
|
+
return backend_past_end - store;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
ISOSPEC_FORCE_INLINE T* data() noexcept
|
|
161
|
+
{
|
|
162
|
+
return store;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
ISOSPEC_FORCE_INLINE const T* data() const noexcept
|
|
166
|
+
{
|
|
167
|
+
return store;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
ISOSPEC_FORCE_INLINE bool empty() const noexcept
|
|
171
|
+
{
|
|
172
|
+
return first_free == store;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
ISOSPEC_FORCE_INLINE const T& back() const noexcept
|
|
176
|
+
{
|
|
177
|
+
ISOSPEC_IMPOSSIBLE(first_free == store);
|
|
178
|
+
return *(first_free-1);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
ISOSPEC_FORCE_INLINE void pop_back() noexcept
|
|
182
|
+
{
|
|
183
|
+
// Unlike std::vector we do not ever shrink backend storage unless explicitly requested.
|
|
184
|
+
ISOSPEC_IMPOSSIBLE(first_free == store);
|
|
185
|
+
first_free--;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
void swap(pod_vector<T>& other) noexcept
|
|
189
|
+
{
|
|
190
|
+
std::swap(backend_past_end, other.backend_past_end);
|
|
191
|
+
std::swap(first_free, other.first_free);
|
|
192
|
+
std::swap(store, other.store);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
typedef T* iterator;
|
|
196
|
+
typedef const T* const_iterator;
|
|
197
|
+
typedef T value_type;
|
|
198
|
+
typedef size_t size_type;
|
|
199
|
+
typedef T& reference;
|
|
200
|
+
typedef const T& const_reference;
|
|
201
|
+
|
|
202
|
+
iterator begin() noexcept { return store; };
|
|
203
|
+
const_iterator begin() const noexcept { return store; }
|
|
204
|
+
const_iterator cbegin() const noexcept { return store; }
|
|
205
|
+
iterator end() noexcept { return first_free; }
|
|
206
|
+
const_iterator end() const noexcept { return first_free; }
|
|
207
|
+
const_iterator cend() const noexcept { return first_free; }
|
|
208
|
+
|
|
209
|
+
ISOSPEC_FORCE_INLINE const T& front() const noexcept
|
|
210
|
+
{
|
|
211
|
+
ISOSPEC_IMPOSSIBLE(store == first_free);
|
|
212
|
+
return *store;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
void clear()
|
|
216
|
+
{
|
|
217
|
+
free(store);
|
|
218
|
+
first_free = store = backend_past_end = NULL;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
friend class unsafe_pod_vector<T>;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
template<typename T> class unsafe_pod_vector
|
|
226
|
+
{
|
|
227
|
+
T* backend_past_end;
|
|
228
|
+
T* first_free;
|
|
229
|
+
T* store;
|
|
230
|
+
|
|
231
|
+
public:
|
|
232
|
+
unsafe_pod_vector() = default;
|
|
233
|
+
|
|
234
|
+
void init() {
|
|
235
|
+
#if !ISOSPEC_BUILDING_R
|
|
236
|
+
static_assert(std::is_trivially_copyable<T>::value, "Cannot use a pod_vector with a non-Plain Old Data type.");
|
|
237
|
+
static_assert(std::is_trivially_copyable<unsafe_pod_vector<T> >::value, "Cannot use a pod_vector with a non-Plain Old Data type.");
|
|
238
|
+
#endif
|
|
239
|
+
memset(this, 0, sizeof(*this));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
void init(size_t initial_size)
|
|
243
|
+
{
|
|
244
|
+
#if !ISOSPEC_BUILDING_R
|
|
245
|
+
static_assert(std::is_trivially_copyable<T>::value, "Cannot use a pod_vector with a non-Plain Old Data type.");
|
|
246
|
+
static_assert(std::is_trivially_copyable<unsafe_pod_vector<T> >::value, "Cannot use a pod_vector with a non-Plain Old Data type.");
|
|
247
|
+
#endif
|
|
248
|
+
store = reinterpret_cast<T*>(malloc(sizeof(T) * initial_size));
|
|
249
|
+
if(store == NULL)
|
|
250
|
+
throw std::bad_alloc();
|
|
251
|
+
first_free = store;
|
|
252
|
+
backend_past_end = store + initial_size;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
unsafe_pod_vector(const pod_vector<T>& other) = delete; // NOLINT(runtime/explicit) - seriously? Deleted constructors have to be marked explicit?
|
|
256
|
+
unsafe_pod_vector& operator=(const pod_vector<T>& other) = delete;
|
|
257
|
+
// unsafe_pod_vector(unsafe_pod_vector<T>&& other) = default;
|
|
258
|
+
|
|
259
|
+
~unsafe_pod_vector() = default;
|
|
260
|
+
|
|
261
|
+
void fast_reserve(size_t n)
|
|
262
|
+
{
|
|
263
|
+
ISOSPEC_IMPOSSIBLE(n < static_cast<size_t>(backend_past_end - store));
|
|
264
|
+
T* new_store = reinterpret_cast<T*>(realloc(store, n * sizeof(T)));
|
|
265
|
+
if(new_store == NULL)
|
|
266
|
+
throw std::bad_alloc();
|
|
267
|
+
first_free = new_store + (first_free - store);
|
|
268
|
+
backend_past_end = new_store + n;
|
|
269
|
+
store = new_store;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
void reserve(size_t n)
|
|
273
|
+
{
|
|
274
|
+
if (n > static_cast<size_t>(backend_past_end - store))
|
|
275
|
+
fast_reserve(n);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
void resize(size_t new_size)
|
|
279
|
+
{
|
|
280
|
+
ISOSPEC_IMPOSSIBLE(static_cast<std::ptrdiff_t>(new_size) < first_free - store);
|
|
281
|
+
size_t cap = capacity();
|
|
282
|
+
if(cap < new_size)
|
|
283
|
+
{
|
|
284
|
+
cap = (std::max<size_t>)(4, cap);
|
|
285
|
+
do {
|
|
286
|
+
cap = cap * 2;
|
|
287
|
+
} while(cap < new_size);
|
|
288
|
+
fast_reserve(cap);
|
|
289
|
+
}
|
|
290
|
+
first_free = store + new_size;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
void resize_and_wipe(size_t new_size)
|
|
294
|
+
{
|
|
295
|
+
size_t old_size = size();
|
|
296
|
+
ISOSPEC_IMPOSSIBLE(new_size <= old_size);
|
|
297
|
+
resize(new_size);
|
|
298
|
+
memset(store+old_size, 0, (new_size-old_size) * sizeof(T));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
ISOSPEC_FORCE_INLINE void nocheck_push_back(const T& val) noexcept
|
|
302
|
+
{
|
|
303
|
+
ISOSPEC_IMPOSSIBLE(first_free >= backend_past_end);
|
|
304
|
+
*first_free = val;
|
|
305
|
+
first_free++;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
ISOSPEC_FORCE_INLINE void push_back(const T& val)
|
|
309
|
+
{
|
|
310
|
+
if(first_free >= backend_past_end)
|
|
311
|
+
fast_reserve((std::max<std::ptrdiff_t>)(4, (backend_past_end-store)) * 2);
|
|
312
|
+
*first_free = val;
|
|
313
|
+
first_free++;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
ISOSPEC_FORCE_INLINE T& operator[](size_t n) noexcept
|
|
317
|
+
{
|
|
318
|
+
ISOSPEC_IMPOSSIBLE(store + n >= first_free);
|
|
319
|
+
return store[n];
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
ISOSPEC_FORCE_INLINE const T& operator[](size_t n) const noexcept
|
|
323
|
+
{
|
|
324
|
+
ISOSPEC_IMPOSSIBLE(store + n >= first_free);
|
|
325
|
+
return store[n];
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
ISOSPEC_FORCE_INLINE size_t size() const noexcept
|
|
329
|
+
{
|
|
330
|
+
return first_free - store;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
ISOSPEC_FORCE_INLINE size_t capacity() const noexcept
|
|
334
|
+
{
|
|
335
|
+
return backend_past_end - store;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
ISOSPEC_FORCE_INLINE T* data() noexcept
|
|
339
|
+
{
|
|
340
|
+
return store;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
ISOSPEC_FORCE_INLINE const T* data() const noexcept
|
|
344
|
+
{
|
|
345
|
+
return store;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
ISOSPEC_FORCE_INLINE bool empty() const noexcept
|
|
349
|
+
{
|
|
350
|
+
return first_free == store;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
ISOSPEC_FORCE_INLINE const T& back() const noexcept
|
|
354
|
+
{
|
|
355
|
+
ISOSPEC_IMPOSSIBLE(first_free == store);
|
|
356
|
+
return *(first_free-1);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
ISOSPEC_FORCE_INLINE void pop_back() noexcept
|
|
360
|
+
{
|
|
361
|
+
// Unlike std::vector we do not ever shrink backend storage unless explicitly requested.
|
|
362
|
+
ISOSPEC_IMPOSSIBLE(first_free == store);
|
|
363
|
+
first_free--;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
void swap(unsafe_pod_vector<T>& other) noexcept
|
|
367
|
+
{
|
|
368
|
+
std::swap(backend_past_end, other.backend_past_end);
|
|
369
|
+
std::swap(first_free, other.first_free);
|
|
370
|
+
std::swap(store, other.store);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
typedef T* iterator;
|
|
374
|
+
typedef const T* const_iterator;
|
|
375
|
+
typedef T value_type;
|
|
376
|
+
typedef size_t size_type;
|
|
377
|
+
typedef T& reference;
|
|
378
|
+
typedef const T& const_reference;
|
|
379
|
+
|
|
380
|
+
iterator begin() noexcept { return store; };
|
|
381
|
+
const_iterator begin() const noexcept { return store; }
|
|
382
|
+
const_iterator cbegin() const noexcept { return store; }
|
|
383
|
+
iterator end() noexcept { return first_free; }
|
|
384
|
+
const_iterator end() const noexcept { return first_free; }
|
|
385
|
+
const_iterator cend() const noexcept { return first_free; }
|
|
386
|
+
|
|
387
|
+
ISOSPEC_FORCE_INLINE const T& front() const noexcept
|
|
388
|
+
{
|
|
389
|
+
ISOSPEC_IMPOSSIBLE(store == first_free);
|
|
390
|
+
return *store;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
void clear()
|
|
394
|
+
{
|
|
395
|
+
free(store);
|
|
396
|
+
first_free = store = backend_past_end = NULL;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
friend class pod_vector<T>;
|
|
400
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
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 <cmath>
|
|
20
|
+
#include <vector>
|
|
21
|
+
#include <utility>
|
|
22
|
+
|
|
23
|
+
namespace IsoSpec
|
|
24
|
+
{
|
|
25
|
+
|
|
26
|
+
class SSummator
|
|
27
|
+
{
|
|
28
|
+
// Shewchuk algorithm
|
|
29
|
+
std::vector<double> partials;
|
|
30
|
+
int maxpart;
|
|
31
|
+
public:
|
|
32
|
+
inline SSummator()
|
|
33
|
+
{ maxpart = 0; }
|
|
34
|
+
|
|
35
|
+
inline SSummator(const SSummator& other) :
|
|
36
|
+
partials(other.partials),
|
|
37
|
+
maxpart(other.maxpart) {}
|
|
38
|
+
|
|
39
|
+
inline void add(double x)
|
|
40
|
+
{
|
|
41
|
+
unsigned int i = 0;
|
|
42
|
+
for(int pidx = 0; pidx < maxpart; pidx++)
|
|
43
|
+
{
|
|
44
|
+
double y = partials[pidx];
|
|
45
|
+
if(std::abs(x) < std::abs(y))
|
|
46
|
+
std::swap(x, y);
|
|
47
|
+
double hi = x+y;
|
|
48
|
+
double lo = y-(hi-x);
|
|
49
|
+
if(lo != 0.0)
|
|
50
|
+
{
|
|
51
|
+
partials[i] = lo;
|
|
52
|
+
i += 1;
|
|
53
|
+
}
|
|
54
|
+
x = hi;
|
|
55
|
+
}
|
|
56
|
+
while(partials.size() <= i)
|
|
57
|
+
partials.push_back(0.0);
|
|
58
|
+
partials[i] = x;
|
|
59
|
+
maxpart = i+1;
|
|
60
|
+
}
|
|
61
|
+
inline double get()
|
|
62
|
+
{
|
|
63
|
+
double ret = 0.0;
|
|
64
|
+
for(int i = 0; i < maxpart; i++)
|
|
65
|
+
ret += partials[i];
|
|
66
|
+
return ret;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class Summator{
|
|
77
|
+
// Kahan algorithm
|
|
78
|
+
double sum;
|
|
79
|
+
double c;
|
|
80
|
+
|
|
81
|
+
public:
|
|
82
|
+
inline Summator()
|
|
83
|
+
{ sum = 0.0; c = 0.0;}
|
|
84
|
+
|
|
85
|
+
inline void add(double what)
|
|
86
|
+
{
|
|
87
|
+
double y = what - c;
|
|
88
|
+
double t = sum + y;
|
|
89
|
+
c = (t - sum) - y;
|
|
90
|
+
sum = t;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
inline double get()
|
|
94
|
+
{
|
|
95
|
+
return sum;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
class TSummator
|
|
100
|
+
{
|
|
101
|
+
// Trivial algorithm, for testing only
|
|
102
|
+
double sum;
|
|
103
|
+
public:
|
|
104
|
+
inline TSummator()
|
|
105
|
+
{ sum = 0.0; }
|
|
106
|
+
|
|
107
|
+
inline void add(double what)
|
|
108
|
+
{
|
|
109
|
+
sum += what;
|
|
110
|
+
}
|
|
111
|
+
inline double get()
|
|
112
|
+
{
|
|
113
|
+
return sum;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
} // namespace IsoSpec
|
|
@@ -0,0 +1,80 @@
|
|
|
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
|
+
#pragma once
|
|
18
|
+
|
|
19
|
+
#include <string>
|
|
20
|
+
#include <vector>
|
|
21
|
+
|
|
22
|
+
namespace IsoSpec {
|
|
23
|
+
|
|
24
|
+
//! One Unimod modification's resolved, ready-to-merge atomic composition
|
|
25
|
+
//! delta: parallel arrays over each element it touches, `element_first_index`
|
|
26
|
+
//! being that element's row in element_tables.h's flat arrays (see
|
|
27
|
+
//! element_lookup.h) and `element_delta_count` its signed atom-count change.
|
|
28
|
+
struct UnimodEntry {
|
|
29
|
+
bool present = false;
|
|
30
|
+
std::string name;
|
|
31
|
+
double mono_mass = 0.0;
|
|
32
|
+
std::vector<int> element_first_index;
|
|
33
|
+
std::vector<int> element_delta_count;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
//! Unimod ids -> resolved compositions, dense: a plain `vector<UnimodEntry>`
|
|
37
|
+
//! indexed directly by id (sized one past the largest shipped id), not a
|
|
38
|
+
//! map -- `lookup(id)` is a bounds check plus a `present` flag, matching
|
|
39
|
+
//! Unimod's own id space (ids are assigned once and never reused).
|
|
40
|
+
class UnimodTable {
|
|
41
|
+
public:
|
|
42
|
+
size_t size() const { return entries_.size(); }
|
|
43
|
+
|
|
44
|
+
//! nullptr for an id that is out of range, or in range but not shipped
|
|
45
|
+
//! (deliberately excluded -- isotope-labeled or glycan/derivatization
|
|
46
|
+
//! "brick" entries, see scripts/build_unimod_table.py) -- both cases are
|
|
47
|
+
//! the same "unknown to this table" outcome, no need to distinguish them.
|
|
48
|
+
const UnimodEntry* lookup(unsigned int id) const {
|
|
49
|
+
if (id >= entries_.size() || !entries_[id].present)
|
|
50
|
+
return nullptr;
|
|
51
|
+
return &entries_[id];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private:
|
|
55
|
+
std::vector<UnimodEntry> entries_;
|
|
56
|
+
|
|
57
|
+
friend UnimodTable parse_unimod_csv(const std::string& csv_text);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
//! Parses a `data/unimod.csv`-shaped CSV (`id,name,mono_mass,composition`,
|
|
61
|
+
//! composition in IsoSpec's own native formula-string grammar -- see
|
|
62
|
+
//! scripts/build_unimod_table.py) into a UnimodTable. Throws
|
|
63
|
+
//! std::invalid_argument on a malformed row or composition.
|
|
64
|
+
UnimodTable parse_unimod_csv(const std::string& csv_text);
|
|
65
|
+
|
|
66
|
+
//! The default table, embedded at compile time (src/IsoSpec++/
|
|
67
|
+
//! unimod_table_data.h) and parsed once, lazily.
|
|
68
|
+
const UnimodTable& embedded_unimod_table();
|
|
69
|
+
|
|
70
|
+
//! Loads and parses `path` (same CSV shape as the embedded default),
|
|
71
|
+
//! overriding it. `unimod_db_path == nullptr` or `""` should use
|
|
72
|
+
//! `embedded_unimod_table()` instead -- callers check that, not this
|
|
73
|
+
//! function. Caches a single (path, table) pair -- not a map: a process
|
|
74
|
+
//! realistically uses 0 or 1 distinct override paths, so a full path-keyed
|
|
75
|
+
//! map buys nothing over remembering just the last one. IsoSpec is
|
|
76
|
+
//! single-threaded by design (see this repo's CLAUDE.md), so this cache is
|
|
77
|
+
//! not synchronized; do not call it from more than one thread.
|
|
78
|
+
const UnimodTable& unimod_table_for_path(const std::string& path);
|
|
79
|
+
|
|
80
|
+
} // namespace IsoSpec
|