IsoSpec  2.1.2
cwrapper.cpp
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 
18 #include <cstring>
19 #include <algorithm>
20 #include <utility>
21 #include <stdexcept>
22 #include "cwrapper.h"
23 #include "misc.h"
24 #include "marginalTrek++.h"
25 #include "isoSpec++.h"
26 #include "fixedEnvelopes.h"
27 #include "fasta.h"
28 
29 using namespace IsoSpec; // NOLINT(build/namespaces) - all of this really should be in a namespace IsoSpec, but C doesn't have them...
30 
31 
32 extern "C"
33 {
34 void * setupIso(int dimNumber,
35  const int* isotopeNumbers,
36  const int* atomCounts,
37  const double* isotopeMasses,
38  const double* isotopeProbabilities)
39 {
40  Iso* iso = new Iso(dimNumber, isotopeNumbers, atomCounts, isotopeMasses, isotopeProbabilities);
41 
42  return reinterpret_cast<void*>(iso);
43 }
44 
45 void * isoFromFasta(const char* fasta, bool use_nominal_masses, bool add_water)
46 {
47  Iso* iso = new Iso(Iso::FromFASTA(fasta, use_nominal_masses, add_water));
48 
49  return reinterpret_cast<void*>(iso);
50 }
51 
52 void deleteIso(void* iso)
53 {
54  delete reinterpret_cast<Iso*>(iso);
55 }
56 
57 double getLightestPeakMassIso(void* iso)
58 {
59  return reinterpret_cast<Iso*>(iso)->getLightestPeakMass();
60 }
61 
62 double getHeaviestPeakMassIso(void* iso)
63 {
64  return reinterpret_cast<Iso*>(iso)->getHeaviestPeakMass();
65 }
66 
67 double getMonoisotopicPeakMassIso(void* iso)
68 {
69  return reinterpret_cast<Iso*>(iso)->getMonoisotopicPeakMass();
70 }
71 
72 double getModeLProbIso(void* iso)
73 {
74  return reinterpret_cast<Iso*>(iso)->getModeLProb();
75 }
76 
77 double getModeMassIso(void* iso)
78 {
79  return reinterpret_cast<Iso*>(iso)->getModeMass();
80 }
81 
82 double getTheoreticalAverageMassIso(void* iso)
83 {
84  return reinterpret_cast<Iso*>(iso)->getTheoreticalAverageMass();
85 }
86 
87 double getIsoVariance(void* iso)
88 {
89  return reinterpret_cast<Iso*>(iso)->variance();
90 }
91 
92 double getIsoStddev(void* iso)
93 {
94  return reinterpret_cast<Iso*>(iso)->stddev();
95 }
96 
97 
98 double* getMarginalLogSizeEstimates(void* iso, double target_total_prob)
99 {
100  Iso* i = reinterpret_cast<Iso*>(iso);
101  double* ret = reinterpret_cast<double*>(malloc(sizeof(double)*i->getDimNumber()));
102  if(ret != nullptr)
103  i->saveMarginalLogSizeEstimates(ret, target_total_prob);
104  return ret;
105 }
106 
107 
108 
109 #define ISOSPEC_C_FN_CODE(generatorType, dataType, method)\
110 dataType method##generatorType(void* generator){ return reinterpret_cast<generatorType*>(generator)->method(); }
111 
112 #define ISOSPEC_C_FN_CODE_GET_CONF_SIGNATURE(generatorType)\
113 void get_conf_signature##generatorType(void* generator, int* space)\
114 { reinterpret_cast<generatorType*>(generator)->get_conf_signature(space); }
115 
116 
117 #define ISOSPEC_C_FN_DELETE(generatorType) void delete##generatorType(void* generator){ delete reinterpret_cast<generatorType*>(generator); }
118 
119 #define ISOSPEC_C_FN_CODES(generatorType)\
120 ISOSPEC_C_FN_CODE(generatorType, double, mass) \
121 ISOSPEC_C_FN_CODE(generatorType, double, lprob) \
122 ISOSPEC_C_FN_CODE(generatorType, double, prob) \
123 ISOSPEC_C_FN_CODE_GET_CONF_SIGNATURE(generatorType) \
124 ISOSPEC_C_FN_CODE(generatorType, bool, advanceToNextConfiguration) \
125 ISOSPEC_C_FN_DELETE(generatorType)
126 
127 
128 
129 // ______________________________________________________THRESHOLD GENERATOR
130 void* setupIsoThresholdGenerator(void* iso,
131  double threshold,
132  bool _absolute,
133  int _tabSize,
134  int _hashSize,
135  bool reorder_marginals)
136 {
138  std::move(*reinterpret_cast<Iso*>(iso)),
139  threshold,
140  _absolute,
141  _tabSize,
142  _hashSize,
143  reorder_marginals);
144 
145  return reinterpret_cast<void*>(iso_tmp);
146 }
147 ISOSPEC_C_FN_CODES(IsoThresholdGenerator)
148 
149 
150 // ______________________________________________________LAYERED GENERATOR
151 void* setupIsoLayeredGenerator(void* iso,
152  int _tabSize,
153  int _hashSize,
154  bool reorder_marginals,
155  double t_prob_hint
156  )
157 {
159  std::move(*reinterpret_cast<Iso*>(iso)),
160  _tabSize,
161  _hashSize,
162  reorder_marginals,
163  t_prob_hint
164  );
165 
166  return reinterpret_cast<void*>(iso_tmp);
167 }
168 ISOSPEC_C_FN_CODES(IsoLayeredGenerator)
169 
170 
171 // ______________________________________________________ORDERED GENERATOR
172 void* setupIsoOrderedGenerator(void* iso,
173  int _tabSize,
174  int _hashSize)
175 {
177  std::move(*reinterpret_cast<Iso*>(iso)),
178  _tabSize,
179  _hashSize);
180 
181  return reinterpret_cast<void*>(iso_tmp);
182 }
183 ISOSPEC_C_FN_CODES(IsoOrderedGenerator)
184 
185 // ______________________________________________________STOCHASTIC GENERATOR
186 void* setupIsoStochasticGenerator(void* iso,
187  size_t no_molecules,
188  double precision,
189  double beta_bias)
190 {
192  std::move(*reinterpret_cast<Iso*>(iso)),
193  no_molecules,
194  precision,
195  beta_bias);
196 
197  return reinterpret_cast<void*>(iso_tmp);
198 }
199 ISOSPEC_C_FN_CODES(IsoStochasticGenerator)
200 
201 // ______________________________________________________ FixedEnvelopes
202 
203 void* setupThresholdFixedEnvelope(void* iso,
204  double threshold,
205  bool absolute,
206  bool get_confs)
207 {
208  FixedEnvelope* ret = new FixedEnvelope( // Use copy elision to allocate on heap with named constructor
209  FixedEnvelope::FromThreshold(Iso(*reinterpret_cast<const Iso*>(iso), true),
210  threshold,
211  absolute,
212  get_confs));
213 
214  return reinterpret_cast<void*>(ret);
215 }
216 
217 void* setupTotalProbFixedEnvelope(void* iso,
218  double target_coverage,
219  bool optimize,
220  bool get_confs)
221 {
222  FixedEnvelope* ret = new FixedEnvelope( // Use copy elision to allocate on heap with named constructor
223  FixedEnvelope::FromTotalProb(Iso(*reinterpret_cast<const Iso*>(iso), true),
224  target_coverage,
225  optimize,
226  get_confs));
227 
228  return reinterpret_cast<void*>(ret);
229 }
230 
231 void* setupFixedEnvelope(double* masses, double* probs, size_t size, bool mass_sorted, bool prob_sorted, double total_prob)
232 {
233  FixedEnvelope* ret = new FixedEnvelope(masses, probs, size, mass_sorted, prob_sorted, total_prob);
234  return reinterpret_cast<void*>(ret);
235 }
236 
237 void deleteFixedEnvelope(void* t, bool release_everything)
238 {
239  FixedEnvelope* tt = reinterpret_cast<FixedEnvelope*>(t);
240  if(release_everything)
241  {
242  tt->release_masses();
243  tt->release_probs();
244  tt->release_confs();
245  }
246  delete tt;
247 }
248 
249 const double* massesFixedEnvelope(void* tabulator)
250 {
251  return reinterpret_cast<FixedEnvelope*>(tabulator)->release_masses();
252 }
253 
254 const double* probsFixedEnvelope(void* tabulator)
255 {
256  return reinterpret_cast<FixedEnvelope*>(tabulator)->release_probs();
257 }
258 
259 const int* confsFixedEnvelope(void* tabulator)
260 {
261  return reinterpret_cast<FixedEnvelope*>(tabulator)->release_confs();
262 }
263 
264 int confs_noFixedEnvelope(void* tabulator)
265 {
266  return reinterpret_cast<FixedEnvelope*>(tabulator)->confs_no();
267 }
268 
269 double empiricAverageMass(void* tabulator)
270 {
271  return reinterpret_cast<FixedEnvelope*>(tabulator)->empiric_average_mass();
272 }
273 
274 double empiricVariance(void* tabulator)
275 {
276  return reinterpret_cast<FixedEnvelope*>(tabulator)->empiric_variance();
277 }
278 
279 double empiricStddev(void* tabulator)
280 {
281  return reinterpret_cast<FixedEnvelope*>(tabulator)->empiric_stddev();
282 }
283 
284 double wassersteinDistance(void* tabulator1, void* tabulator2)
285 {
286  try
287  {
288  return reinterpret_cast<FixedEnvelope*>(tabulator1)->WassersteinDistance(*reinterpret_cast<FixedEnvelope*>(tabulator2));
289  }
290  catch(std::logic_error&)
291  {
292  return NAN;
293  }
294 }
295 
296 double orientedWassersteinDistance(void* tabulator1, void* tabulator2)
297 {
298  try
299  {
300  return reinterpret_cast<FixedEnvelope*>(tabulator1)->OrientedWassersteinDistance(*reinterpret_cast<FixedEnvelope*>(tabulator2));
301  }
302  catch(std::logic_error&)
303  {
304  return NAN;
305  }
306 }
307 
308 
309 void* addEnvelopes(void* tabulator1, void* tabulator2)
310 {
311  // Hopefully the compiler will do the copy elision...
312  return reinterpret_cast<void*>(new FixedEnvelope((*reinterpret_cast<FixedEnvelope*>(tabulator1))+(*reinterpret_cast<FixedEnvelope*>(tabulator2))));
313 }
314 
315 void* convolveEnvelopes(void* tabulator1, void* tabulator2)
316 {
317  // Hopefully the compiler will do the copy elision...
318  return reinterpret_cast<void*>(new FixedEnvelope((*reinterpret_cast<FixedEnvelope*>(tabulator1))*(*reinterpret_cast<FixedEnvelope*>(tabulator2))));
319 }
320 
321 double getTotalProbOfEnvelope(void* envelope)
322 {
323  return reinterpret_cast<FixedEnvelope*>(envelope)->get_total_prob();
324 }
325 
326 void scaleEnvelope(void* envelope, double factor)
327 {
328  reinterpret_cast<FixedEnvelope*>(envelope)->scale(factor);
329 }
330 
331 void normalizeEnvelope(void* envelope)
332 {
333  reinterpret_cast<FixedEnvelope*>(envelope)->normalize();
334 }
335 
336 void* binnedEnvelope(void* envelope, double width, double middle)
337 {
338  // Again, counting on copy elision...
339  return reinterpret_cast<void*>(new FixedEnvelope(reinterpret_cast<FixedEnvelope*>(envelope)->bin(width, middle)));
340 }
341 
342 void* linearCombination(void* const * const envelopes, const double* intensities, size_t count)
343 {
344  // Same...
345  return reinterpret_cast<void*>(new FixedEnvelope(FixedEnvelope::LinearCombination(reinterpret_cast<const FixedEnvelope* const *>(envelopes), intensities, count)));
346 }
347 
348 void sortEnvelopeByMass(void* envelope)
349 {
350  reinterpret_cast<FixedEnvelope*>(envelope)->sort_by_mass();
351 }
352 
353 void sortEnvelopeByProb(void* envelope)
354 {
355  reinterpret_cast<FixedEnvelope*>(envelope)->sort_by_prob();
356 }
357 
358 void freeReleasedArray(void* array)
359 {
360  free(array);
361 }
362 
363 void parse_fasta_c(const char* fasta, int atomCounts[6])
364 {
365  // Same thing, only this time with C linkage
366  parse_fasta(fasta, atomCounts);
367 }
368 } // extern "C" ends here
IsoSpec::IsoOrderedGenerator
The generator of isotopologues sorted by their probability of occurrence.
Definition: isoSpec++.h:236
IsoSpec::Iso::getDimNumber
int getDimNumber() const
Get the number of elements in the chemical formula of the molecule.
Definition: isoSpec++.h:166
IsoSpec::Iso::FromFASTA
static Iso FromFASTA(const char *fasta, bool use_nominal_masses=false, bool add_water=true)
Constructor (named) from aminoacid FASTA sequence as C string.
Definition: isoSpec++.cpp:169
IsoSpec::Iso::saveMarginalLogSizeEstimates
void saveMarginalLogSizeEstimates(double *priorities, double target_total_prob) const
Save estimates of logarithms of target sizes of marginals using Gaussian approximation into argument ...
Definition: isoSpec++.cpp:335
IsoSpec
Definition: allocator.cpp:20
IsoSpec::Iso
The Iso class for the calculation of the isotopic distribution.
Definition: isoSpec++.h:49
IsoSpec::IsoThresholdGenerator
The generator of isotopologues above a given threshold value.
Definition: isoSpec++.h:295
IsoSpec::FixedEnvelope
Definition: fixedEnvelopes.h:31
IsoSpec::IsoStochasticGenerator
Definition: isoSpec++.h:542
IsoSpec::IsoLayeredGenerator
Definition: isoSpec++.h:439