IsoSpec  2.1.3
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* setupStochasticFixedEnvelope(void* iso,
232  size_t no_molecules,
233  double precision,
234  double beta_bias,
235  bool get_confs)
236 {
237  FixedEnvelope* ret = new FixedEnvelope( // Use copy elision to allocate on heap with named constructor
238  FixedEnvelope::FromStochastic(Iso(*reinterpret_cast<const Iso*>(iso), true),
239  no_molecules,
240  precision,
241  beta_bias,
242  get_confs));
243 
244  return reinterpret_cast<void*>(ret);
245 }
246 
247 
248 void* setupBinnedFixedEnvelope(void* iso,
249  double target_total_prob,
250  double bin_width,
251  double bin_middle)
252 {
253  FixedEnvelope* ret = new FixedEnvelope( // Use copy elision to allocate on heap with named constructor
254  FixedEnvelope::Binned(Iso(*reinterpret_cast<const Iso*>(iso), true),
255  target_total_prob,
256  bin_width,
257  bin_middle));
258 
259  return reinterpret_cast<void*>(ret);
260 }
261 
262 void* setupFixedEnvelope(double* masses, double* probs, size_t size, bool mass_sorted, bool prob_sorted, double total_prob)
263 {
264  FixedEnvelope* ret = new FixedEnvelope(masses, probs, size, mass_sorted, prob_sorted, total_prob);
265  return reinterpret_cast<void*>(ret);
266 }
267 
268 void deleteFixedEnvelope(void* t, bool release_everything)
269 {
270  FixedEnvelope* tt = reinterpret_cast<FixedEnvelope*>(t);
271  if(release_everything)
272  {
273  tt->release_masses();
274  tt->release_probs();
275  tt->release_confs();
276  }
277  delete tt;
278 }
279 
280 const double* massesFixedEnvelope(void* tabulator)
281 {
282  return reinterpret_cast<FixedEnvelope*>(tabulator)->release_masses();
283 }
284 
285 const double* probsFixedEnvelope(void* tabulator)
286 {
287  return reinterpret_cast<FixedEnvelope*>(tabulator)->release_probs();
288 }
289 
290 const int* confsFixedEnvelope(void* tabulator)
291 {
292  return reinterpret_cast<FixedEnvelope*>(tabulator)->release_confs();
293 }
294 
295 size_t confs_noFixedEnvelope(void* tabulator)
296 {
297  return reinterpret_cast<FixedEnvelope*>(tabulator)->confs_no();
298 }
299 
300 double empiricAverageMass(void* tabulator)
301 {
302  return reinterpret_cast<FixedEnvelope*>(tabulator)->empiric_average_mass();
303 }
304 
305 double empiricVariance(void* tabulator)
306 {
307  return reinterpret_cast<FixedEnvelope*>(tabulator)->empiric_variance();
308 }
309 
310 double empiricStddev(void* tabulator)
311 {
312  return reinterpret_cast<FixedEnvelope*>(tabulator)->empiric_stddev();
313 }
314 
315 double wassersteinDistance(void* tabulator1, void* tabulator2)
316 {
317  try
318  {
319  return reinterpret_cast<FixedEnvelope*>(tabulator1)->WassersteinDistance(*reinterpret_cast<FixedEnvelope*>(tabulator2));
320  }
321  catch(std::logic_error&)
322  {
323  return NAN;
324  }
325 }
326 
327 double orientedWassersteinDistance(void* tabulator1, void* tabulator2)
328 {
329  try
330  {
331  return reinterpret_cast<FixedEnvelope*>(tabulator1)->OrientedWassersteinDistance(*reinterpret_cast<FixedEnvelope*>(tabulator2));
332  }
333  catch(std::logic_error&)
334  {
335  return NAN;
336  }
337 }
338 
339 
340 void* addEnvelopes(void* tabulator1, void* tabulator2)
341 {
342  // Hopefully the compiler will do the copy elision...
343  return reinterpret_cast<void*>(new FixedEnvelope((*reinterpret_cast<FixedEnvelope*>(tabulator1))+(*reinterpret_cast<FixedEnvelope*>(tabulator2))));
344 }
345 
346 void* convolveEnvelopes(void* tabulator1, void* tabulator2)
347 {
348  // Hopefully the compiler will do the copy elision...
349  return reinterpret_cast<void*>(new FixedEnvelope((*reinterpret_cast<FixedEnvelope*>(tabulator1))*(*reinterpret_cast<FixedEnvelope*>(tabulator2))));
350 }
351 
352 double getTotalProbOfEnvelope(void* envelope)
353 {
354  return reinterpret_cast<FixedEnvelope*>(envelope)->get_total_prob();
355 }
356 
357 void scaleEnvelope(void* envelope, double factor)
358 {
359  reinterpret_cast<FixedEnvelope*>(envelope)->scale(factor);
360 }
361 
362 void normalizeEnvelope(void* envelope)
363 {
364  reinterpret_cast<FixedEnvelope*>(envelope)->normalize();
365 }
366 
367 void* binnedEnvelope(void* envelope, double width, double middle)
368 {
369  // Again, counting on copy elision...
370  return reinterpret_cast<void*>(new FixedEnvelope(reinterpret_cast<FixedEnvelope*>(envelope)->bin(width, middle)));
371 }
372 
373 void* linearCombination(void* const * const envelopes, const double* intensities, size_t count)
374 {
375  // Same...
376  return reinterpret_cast<void*>(new FixedEnvelope(FixedEnvelope::LinearCombination(reinterpret_cast<const FixedEnvelope* const *>(envelopes), intensities, count)));
377 }
378 
379 void sortEnvelopeByMass(void* envelope)
380 {
381  reinterpret_cast<FixedEnvelope*>(envelope)->sort_by_mass();
382 }
383 
384 void sortEnvelopeByProb(void* envelope)
385 {
386  reinterpret_cast<FixedEnvelope*>(envelope)->sort_by_prob();
387 }
388 
389 void freeReleasedArray(void* array)
390 {
391  free(array);
392 }
393 
394 void parse_fasta_c(const char* fasta, int atomCounts[6])
395 {
396  // Same thing, only this time with C linkage
397  parse_fasta(fasta, atomCounts);
398 }
399 } // extern "C" ends here
IsoSpec::IsoOrderedGenerator
The generator of isotopologues sorted by their probability of occurrence.
Definition: isoSpec++.h:237
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:21
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:296
IsoSpec::FixedEnvelope
Definition: fixedEnvelopes.h:35
IsoSpec::IsoStochasticGenerator
Definition: isoSpec++.h:543
IsoSpec::IsoLayeredGenerator
Definition: isoSpec++.h:440