Codebase list isospec / 2adf65a
New upstream version 1.9.0 Filippo Rusconi 5 years ago
145 changed file(s) with 18777 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 This file lists *major* changes between releases, for a full list see git log.
1
2 1.9.1
3 ----------------------------------
4 - R bindings brought up to speed
5 - Improvements for 1.0.X backward compatibility in Python module
6 - Minor fixes and cleanups
7
8 1.9.0
9 ----------------------------------
10 - We no longer override $CXX to use clang when available - the difference in speed of
11 produced code is no longer large enough to justify it
12 - Some more minor code cleanups
13 - Python wrapper now returns probabilities of configurations instead of logprobabilities
14 by default. This is controllable through (optional) parameter.
15 - Expose LayeredTabulator in Python
16
17 ----------------------------------
18 1.9.0beta2
19
20 - API change: rename eprob() functions to prob()
21 - Added more tests
22 - Some bugfixes
23
24 ----------------------------------
25 1.9.0beta1
26
27 - Added more tests
28 - Code cleanups
29 - Some bugfixes
30
31 ----------------------------------
32 1.9.0alpha3
33
34 - Brought C++/Python examples up to the new API
35 - Small change of Python API
36 - Speed improvements in IsoThresholdGenerator
37 - Code cleanup, ripped out much of experimental stuff which will be postponed until 2.0
38
39 ----------------------------------
40 1.9.0alpha2
41
42 - Rudimentary module for backward-compatibility with IsoSpecPy 1.0.X API
43 - Bugfix (and usability improvement) for getting configurations in
44 IsoThreshold
45
46 ----------------------------------
47 1.9.0alpha1
48
49 - Almost complete rewrite of the entire codebase
50 - Improvements in the core algorithms, resulting in 10x-1000x speed increase
51 as well as lower memory consumption
52 - Reworked API to be more sensible
53 - Laying the groundwork for multithreaded operation (not complete yet)
54 - Expose generators in Python (enabling processing configurations on the fly,
55 as they are produced without the need to compute and store all of them first
56 (using up memory) and process them later)
57 - More modular Python part
58 - C/C++ and Python-only release, R will follow soon after
59 - Some features from 1.0.5 are not yet (re-)implemented: IsoLayered is only
60 exposed as a generator, not yet as a fixed table; as a consequence quicktrim
61 to get the optimal p-set is still missing
62 - THIS IS AN ALPHA RELEASE: IT'S NOT YET EXHAUSTIVELY TESTED AND MAY CRASH OR
63 PRODUCE WRONG RESULTS
64 - API is still not yet finalized.
65
66 ----------------------------------
67 1.0.7 (Python-only release)
68
69 - Bugfix in Python's getConfs()
70
71 ----------------------------------
72 1.0.6 (Python-only release)
73
74 - Compatibility fixes for Python3.6
75
76 ----------------------------------
77 1.0.5 (Python-only release)
78
79 - Only affecting IsoSpecPy: Speed improvements in IsoFromFormula
80
81 ----------------------------------
82 1.0.4
83
84 - ??? FIXME
85
86 ----------------------------------
87 1.0.3
88
89 - Only affecting IsoSpecR: improve the efficiency of R to C++ interface
90 - Add an option to skip discarding the superfluous configurations
91
92 ----------------------------------
93 1.0.2
94
95 - Some further Python+Windows compatibility improvements
96
97 ----------------------------------
98 1.0.1
99
100 - Only affecting IsoSpecPy: provide prebuilt library
101 - Only affecting IsoSpecPy: Improve Python/cygwin functionality
102
103 ----------------------------------
104 1.0.0
105
106 - Initial release
107
0 The easiest (if not the most elegant) way to compile the example is:
1
2 clang++ water.cpp ../../IsoSpec++/unity-build.cpp -std=c++11
3
4 You may replace clang++ with g++ if you do not have LLVM installed.
5
6 Run the example by:
7
8 ./a.out
9
10
11
0 #include <iostream>
1 #include <cassert>
2 #include "../../IsoSpec++/isoSpec++.h"
3
4 using namespace IsoSpec;
5
6 int main()
7 {
8 int configs[5];
9 {
10 // We shall walk through a set of configurations which covers at least 99.9% of the mass.
11 // For water we could obviously go through the entire spectrum (100%), but for larger
12 // molecules the entire spectrum has far too many configurations. Luckily, most of the
13 // likelihood is concentrated in a relatively small set of most probable isotopologues
14 // - and this method allows one to quickly calculate such a set, parametrising on the
15 // percentage of coverage of total probability space required.
16 //
17 // This is usually better than just calculating all isotopes with probabilities above a
18 // given threshold, as it allows one to directly parametrise on the accuracy of the
19 // simplified spectrum - that is, the L1 distance between the full and simplified spectrum
20 // will be less than (in this example) 0.001.
21 //
22 // If for some reason one would wish to just calculate a set of peaks with probabilities
23 // above a given threshold - it is possible using the IsoThresholdGenerator class.
24 //
25 // Note: the returned set will usually contain a bit more configurations than necessary
26 // to achieve the desired coverage. These configurations need to be computed anyway, however
27 // it is possible to discard them using the optional trim argument.
28
29 IsoLayeredGenerator iso("H2O1", 0.999);
30
31 double total_prob = 0.0;
32
33 while(iso.advanceToNextConfiguration())
34 {
35 std::cout << "Visiting configuration: " << std::endl;
36 std::cout << "Mass: " << iso.mass() << std::endl;
37 std::cout << "log-prob: " << iso.lprob() << std::endl;
38 std::cout << "probability: " << iso.prob() << std::endl;
39 total_prob += iso.prob();
40
41 iso.get_conf_signature(configs);
42
43 // Successive isotopologues are ordered by the appearance in the formula of the element, then by nucleon number, and concatenated into one array
44 std::cout << "Protium atoms: " << configs[0] << std::endl;
45 std::cout << "Deuterium atoms " << configs[1] << std::endl;
46 std::cout << "O16 atoms: " << configs[2] << std::endl;
47 std::cout << "O17 atoms: " << configs[3] << std::endl;
48 std::cout << "O18 atoms: " << configs[4] << std::endl;
49 }
50 assert(total_prob >= 0.99); // We must have covered at least 99% of the spectrum
51 }
52
53
54
55 {
56 std::cout << "Now what if both isotopes of hydrogen were equally probable, while prob. of O16 was 50%, O17 at 30% and O18 at 20%?" << std::endl;
57
58 const int elementNumber = 2;
59 const int isotopeNumbers[2] = {2,3};
60
61 const int atomCounts[2] = {2,1};
62
63
64 const double hydrogen_masses[2] = {1.00782503207, 2.0141017778};
65 const double oxygen_masses[3] = {15.99491461956, 16.99913170, 17.9991610};
66
67 const double* isotope_masses[2] = {hydrogen_masses, oxygen_masses};
68
69 const double hydrogen_probs[2] = {0.5, 0.5};
70 const double oxygen_probs[3] = {0.5, 0.3, 0.2};
71
72 const double* probs[2] = {hydrogen_probs, oxygen_probs};
73
74 IsoLayeredGenerator iso(Iso(elementNumber, isotopeNumbers, atomCounts, isotope_masses, probs), 0.99);
75
76 iso.advanceToNextConfiguration();
77
78 std::cout << "The first configuration has the following parameters: " << std::endl;
79 std::cout << "Mass: " << iso.mass() << std::endl;
80 std::cout << "log-prob: " << iso.lprob() << std::endl;
81 std::cout << "probability: " << iso.prob() << std::endl;
82
83 iso.get_conf_signature(configs);
84
85 // Successive isotopologues are ordered by the appearance in the formula of the element, then by nucleon number, and concatenated into one array
86 std::cout << "Protium atoms: " << configs[0] << std::endl;
87 std::cout << "Deuterium atoms " << configs[1] << std::endl;
88 std::cout << "O16 atoms: " << configs[2] << std::endl;
89 std::cout << "O17 atoms: " << configs[3] << std::endl;
90 std::cout << "O18 atoms: " << configs[4] << std::endl;
91
92 std::cout << "Probabilities of the remaining configurations, are: " << std::endl;
93
94 while(iso.advanceToNextConfiguration())
95 std::cout << iso.prob() << std::endl;
96 }
97
98 // TODO: demonstrate other algorithms
99 }
0 # Calculates the isotopic distribution of water in several ways
1
2 import IsoSpecPy
3 from math import exp
4
5 try:
6 if IsoSpecPy.__version__[:3] != '1.9':
7 raise AttributeError
8 except AttributeError:
9 print("This file is meant to be used with IsoSpecPy version 1.9.X. You seem to have a different version installed on your system.")
10 import sys
11 sys.exit(-1)
12
13 i = IsoSpecPy.IsoLayeredGenerator(formula="H2O1", prob_to_cover = 0.999, get_confs=True)
14
15 print("Calculating isotopic distribution of water. Here's a list of configurations necessary to cover at least 0.999 of total probability:")
16
17 for mass, log_prob, conf in i:
18 print("")
19 print("Mass: " + str(mass))
20 print("log(probability): " + str(log_prob))
21 print("probability: " + str(exp(log_prob)))
22 print("Number of Protium atoms: " + str(conf[0][0]))
23 print("Number of Deuterium atoms: " + str(conf[0][1]))
24 print("Number of O16 atoms: " + str(conf[1][0]))
25 print("Number of O17 atoms: " + str(conf[1][1]))
26 print("Number of O18 atoms: " + str(conf[1][2]))
27
28 print("")
29 print("Now what if both isotopes of hydrogen were equally probable, while prob. of O16 was 50%, O17 at 30% and O18 at 20%?")
30
31 hydrogen_probs = (0.5, 0.5)
32 oxygen_probs = (0.5, 0.3, 0.2)
33 hydrogen_masses = (1.00782503207, 2.0141017778)
34 oxygen_masses = (15.99491461956, 16.99913170, 17.9991610)
35
36 i = IsoSpecPy.IsoLayeredGenerator(atomCounts = (2, 1), isotopeMasses = (hydrogen_masses, oxygen_masses), isotopeProbabilities = (hydrogen_probs, oxygen_probs), prob_to_cover = 0.999, get_confs=True)
37
38
39 mass, log_prob, conf = next(i.__iter__())
40
41 print("The first configuration has the following parameters:")
42 print("Mass: " + str(mass))
43 print("log(probability): " + str(log_prob))
44 print("probability: " + str(exp(log_prob)))
45 print("Number of Protium atoms: " + str(conf[0][0]))
46 print("Number of Deuterium atoms: " + str(conf[0][1]))
47 print("Number of O16 atoms: " + str(conf[1][0]))
48 print("Number of O17 atoms: " + str(conf[1][1]))
49 print("Number of O18 atoms: " + str(conf[1][2]))
50
51
52
53
54
55
0 library(IsoSpecR)
1
2 water = c(H=2,O=1) # A water molecule:
3 p = .99 # joint probability of the output
4
5 # calculate one of the smallest sets of isotopologues with
6 # probability at least equal to 99%
7 WATER = IsoSpecify(molecule = water, stopCondition = p)
8 print(WATER)
9
10 # the outcome looks small, but water can only have 3*3 = 9 isotopologues.
11 # (for a general formula, see the formula in the supplement to our paper)
12 # you can see all of them by setting the probability to 1: this will include all isotopologues.
13 WATER = IsoSpecify(molecule = water, stopCondition = 1)
14 print(WATER)
15
16 # The default output consists of a matrix with two columns: mass and log-probability of the
17 # isotopologues (the natural logarithms, with base equal to 'e').
18 print(WATER[,"mass"])
19 print(WATER[,"logProb"])
20
21 # to get the probabilities, simply run
22 WATER = IsoSpecify(molecule = water, stopCondition = 1, showCounts=T)
23 print(WATER)
24
25 # Let's get a bigger example: bovine insulin
26 bovine_insulin = c(C=254, H=377, N=65, O=75, S=6)
27 BOVINE_INSULIN = IsoSpecify(bovine_insulin, .999)
28 # as you can see, there are 1301 isotopologs such that their probability summed together
29 # exceed .99. This is one of the smallest such sets.
30 print(nrow(BOVINE_INSULIN))
31
32 total_probability = sum(exp(BOVINE_INSULIN[,'logProb']))
33 print(total_probability)
34
35 # there are other ways to get this outcome, but this one is the fastest.
36 # if you want to get the isotopologues sorted by probability, you can run the
37 # priority-queue version of the algorithm.
38 BOVINE_INSULIN = IsoSpecify(bovine_insulin, .999, algo=1)
39 is.unsorted(BOVINE_INSULIN[,'logProb'][nrow(BOVINE_INSULIN):1])
40 # is.unsorted == FALSE is the same as sorted == TRUE. It's elementary :)
41 # using the priority queue has poorer time complexity, which is O(n*log(n)).
42 T0 = Sys.time()
43 BOVINE_INSULIN = IsoSpecify(bovine_insulin, .999, algo=1)
44 T1 = Sys.time()
45 BOVINE_INSULIN = IsoSpecify(bovine_insulin, .999, algo=0)
46 T2 = Sys.time()
47
48 print(T1 - T0)
49 print(T2 - T1)
50 # If, for some reason, you just want to generate peaks above certain probability threshold,
51 # you could use the third algorithm
52 BOVINE_INSULIN_peaks_more_probable_than_10_percent_each = IsoSpecify(bovine_insulin, .1, algo=3)
53 print(exp(BOVINE_INSULIN_peaks_more_probable_than_10_percent_each[,'logProb']))
54
55 # ATTENTION: it is not a good idea to do it.
56 # Remember, that we supply you with infinitely resolved peaks.
57 # your experimental peaks are most likely generated by an mass spctrometer,
58 # that does not share this quality. Hence, the smallest observed peak might
59 # be actually a sum of some smaller, unresolved peaks, giving you false impression of security.
60
61 # Anyway, if you still want to, you can also precise the limiting height of the peak w.r.t.
62 # the height of the heighest peak.
63 # You can achieve this with algorithm 3:
64 BOVINE_INSULIN_peaks_higher_than_the_one_ten_thousandth_of_the_height_of_the_heighest_peak = IsoSpecify(bovine_insulin, 1e-04, algo=3)
65 LP = BOVINE_INSULIN_peaks_higher_than_the_one_ten_thousandth_of_the_height_of_the_heighest_peak[,'logProb']
66 print(exp(LP[length(LP)] - LP[1]))
67 # so, as you can see, this is a peak very close to 1/10,000, but still above the threshold.
68 # The next most probable that was not yet calculated, would have had that ratio below this number.
69 # You are invited to test it yourself :)
70
71 # Matteo and Michał.
0 -------------------------------------------
1 Building and installing the C/C++ library
2
3 Requirements:
4 A C++11 compiler, clang++ (v3.3 or later) or g++ (v4.7 or later)
5 Make (GNU make is OK)
6
7
8 Note: clang++ is the default (and preferred) compiler as it produces
9 faster code (in our tests, the difference in speed is about 20%).
10 If you'd like to use g++ instead, please edit the first line of
11 IsoSpec++/Makefile appropriately.
12
13 Next, execute the following commands:
14
15 cd IsoSpec++
16 make
17
18 You may copy the resulting .so file to a convenient location.
19 If you wish to develop software using this library, you will also
20 have to place the header files (*.hpp/*.h) somewhere your C/C++
21 compiler can find them.
22
23 On Windows, you should turn on the MANN_LIBRARY pre-processor directive when
24 building the library.
25
26 ------------------------------------------
27 Building and installing the Python package
28
29 IMPORTANT: please note that the Python package is standalone, in the
30 sense that it does not need the C/C++ library to be installed separately.
31
32 IsoSpecPy is compatible with both CPython and PyPy, running on Unix,
33 Cygwin or in MinGW environment.
34
35 The preferred method of installation is by using the pip package manager.
36 In order to do that, simply issue the following command, replacing
37 "<python>" with your Python executable (python/python3/pypy/...)
38
39 <python> -m pip install IsoSpecPy
40
41 If, instead, you wish to install the package manually, follow these
42 instructions:
43
44 Requirements:
45 Python (obviously) (v2 and v3 are supported)
46 C++11 compiler, clang++ (v3.3 or later) or g++ (v4.7 or later)
47 setuptools
48 cffi (this, if not present, will be automatically downloaded and
49 installed by the setup script, however you may prefer to use
50 your distribution's package manager to install that)
51
52 Execute the following commands:
53 cd IsoSpecPy
54 sudo python setup.py install
55
56 Again, clang++ is the preferred compiler and will be used if found by the
57 setup script. If you want to override the behaviour (if you have clang++
58 installed, but still want to use g++) you will have to replace the last
59 command with:
60
61 ISO_USE_DEFAULT_CXX=TRUE sudo python setup.py install
62
63
64 ------------------------------------------
65 Building and installing the R package
66
67 The preferred installation method is to use the CRAN package installer.
68 To do that, simply issue the command:
69
70 install.packages('IsoSpecR')
71
72 in your R session. However it is possible to install the package manually,
73 from source, by following these instructions:
74
75 Requirements:
76 R (>= 3.2.1)
77 Rcpp package from CRAN
78 C++11 compiler, clang++ (v3.3 or later) or g++ (v4.7 or later)
79
80 Move to the folder containing the IsoSpecR folder. Then run in terminal:
81
82 R CMD build IsoSpecR
83 R CMD INSTALL IsoSpecR_*.tar.gz
84
85 All necessary packages should download automatically.
86
0 project("IsoSpec")
1 cmake_minimum_required(VERSION 2.6)
2
3 set(my_sources
4 cwrapper.cpp
5 allocator.cpp
6 dirtyAllocator.cpp
7 isoSpec++.cpp
8 isoMath.cpp
9 marginalTrek++.cpp
10 operators.cpp
11 element_tables.cpp
12 misc.cpp
13 )
14
15 ## platform dependent compiler flags:
16 include(CheckCXXCompilerFlag)
17 if (NOT WIN32) # we only want fPIC on non-windows systems (fPIC is implicitly true there)
18 CHECK_CXX_COMPILER_FLAG("-fPIC" WITH_FPIC)
19 if (WITH_FPIC)
20 add_definitions(-fPIC)
21 endif()
22
23 # Only add those definitions on non-windows systems
24 add_definitions(-std=c++11 -Wall -pedantic -Wextra)
25 else()
26 ## On MSVS we need this for mmap
27 set(my_sources ${my_sources} mman.cpp)
28 add_definitions(-DMMAN_LIBRARY)
29 endif()
30
31 add_library(IsoSpec SHARED ${my_sources})
32
33 configure_file(IsoSpecConfig.cmake.in "${PROJECT_BINARY_DIR}/IsoSpecConfig.cmake" @ONLY)
34
35 export(TARGETS IsoSpec FILE IsoSpecLibrary.cmake)
36
0 # Create imported target IsoSpec
1 # adapted from http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file#The_FooBar.2FFooBarBuildTreeSettings.cmake.in_file
2
3 # Compute paths
4 get_filename_component(ISOSPEC_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
5 if(EXISTS "${ISOSPEC_CMAKE_DIR}/CMakeCache.txt")
6 # In build tree
7 set(ISOSPEC_INCLUDE_DIRS
8 "@PROJECT_SOURCE_DIR@/")
9 else()
10 set(ISOSPEC_INCLUDE_DIRS "${ISOSPEC_CMAKE_DIR}/@CONF_REL_INCLUDE_DIR@")
11 endif()
12
13 # Our library dependencies (contains definitions for IMPORTED targets)
14 include("${ISOSPEC_CMAKE_DIR}/IsoSpecLibrary.cmake")
15
16 # These are IMPORTED targets created by IsoSpecLibrary.cmake
17 set(ISOSPEC_LIBRARIES IsoSpec)
18
19
0 OPTFLAGS=-O3 -march=native -mtune=native
1 DEBUGFLAGS=-O0 -g -Werror
2 CXXFLAGS=-std=c++11 -Wall -pedantic -Wextra
3 SRCFILES=cwrapper.cpp allocator.cpp dirtyAllocator.cpp isoSpec++.cpp isoMath.cpp marginalTrek++.cpp operators.cpp element_tables.cpp misc.cpp mman.cpp
4
5 all: unitylib
6
7 unitylib:
8 $(CXX) $(CXXFLAGS) $(OPTFLAGS) unity-build.cpp -fPIC -shared -o libIsoSpec++.so
9
10 debug:
11 $(CXX) $(CXXFLAGS) $(DEBUGFLAGS) unity-build.cpp -DDEBUG -fPIC -shared -o libIsoSpec++.so
12
13 debug-gcc:
14 g++ $(CXXFLAGS) $(DEBUGFLAGS) unity-build.cpp -DDEBUG -fPIC -shared -o libIsoSpec++.so
15
16 nonunity:
17 $(CXX) $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) -DDEBUG -fPIC -shared -o libIsoSpec++.so
18
19 clean:
20 rm -f libIsoSpec++.so
21
22 windows:
23 g++ -O3 -std=gnu++11 -O3 -shared -static -static-libstdc++ -static-libgcc unity-build.cpp -o ../IsoSpecPy/IsoSpec++.dll
24 x86_64-w64-mingw32-g++.exe -std=gnu++11 -O3 -shared -static -static-libstdc++ unity-build.cpp -o ../IsoSpecPy/IsoSpecPy/prebuilt-libIsoSpec++1.9.1-x64.dll
25 i686-w64-mingw32-g++.exe -std=gnu++11 -O3 -shared -static -static-libstdc++ unity-build.cpp -o ../IsoSpecPy/IsoSpecPy/prebuilt-libIsoSpec++1.9.1-x32.dll
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16
17 #include <iostream>
18 #include "allocator.h"
19
20 namespace IsoSpec
21 {
22
23 template <typename T>
24 Allocator<T>::Allocator(const int dim, const int tabSize): currentId(-1), dim(dim), tabSize(tabSize)
25 {
26 currentTab = new T[dim * tabSize];
27 }
28
29 template <typename T>
30 Allocator<T>::~Allocator()
31 {
32 for(unsigned int i = 0; i < prevTabs.size(); ++i)
33 {
34 delete [] prevTabs[i];
35 }
36
37 delete [] currentTab;
38 }
39
40 template <typename T>
41 void Allocator<T>::shiftTables()
42 {
43 prevTabs.push_back(currentTab);
44 currentTab = new T[dim * tabSize];
45 currentId = 0;
46 }
47
48 template class Allocator<int>;
49
50 }
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <vector>
19 #include <iostream>
20 #include <string.h>
21 #include "conf.h"
22
23 namespace IsoSpec
24 {
25
26 template <typename T> inline void copyConf(
27 const T* source, T* destination,
28 int dim
29 ){
30 memcpy(destination, source, dim*sizeof(T));
31 }
32
33 template <typename T> class Allocator{
34 private:
35 T* currentTab;
36 int currentId;
37 const int dim, tabSize;
38 std::vector<T*> prevTabs;
39 public:
40 Allocator(const int dim, const int tabSize = 10000);
41 ~Allocator();
42
43 void shiftTables();
44
45 inline T* newConf()
46 {
47 currentId++;
48
49 if (currentId >= tabSize)
50 shiftTables();
51
52 return &(currentTab[ currentId * dim ]);
53 }
54
55 inline T* makeCopy(const T* conf)
56 {
57 T* currentPlace = newConf();
58 copyConf<T>( conf, currentPlace, dim );
59
60 return currentPlace;
61 }
62
63 inline T* makeExternalCopy(const T* conf)
64 {
65 T* res = new T[dim];
66 copyConf( conf, res, dim );
67
68 return res;
69 }
70 };
71
72 }
73
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 namespace IsoSpec
19 {
20
21 typedef int* Conf;
22
23 }
24
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16
17 #include <tuple>
18 #include <string.h>
19 #include <iostream>
20 #include <algorithm>
21 #include <stdexcept>
22 #include "cwrapper.h"
23 #include "misc.h"
24 #include "marginalTrek++.h"
25 #include "isoSpec++.h"
26 #include "tabulator.h"
27
28 using namespace IsoSpec;
29
30 extern "C"
31 {
32 void * setupIso(int dimNumber,
33 const int* isotopeNumbers,
34 const int* atomCounts,
35 const double* isotopeMasses,
36 const double* isotopeProbabilities)
37 {
38 const double** IM = new const double*[dimNumber];
39 const double** IP = new const double*[dimNumber];
40 int idx = 0;
41 for(int i=0; i<dimNumber; i++)
42 {
43 IM[i] = &isotopeMasses[idx];
44 IP[i] = &isotopeProbabilities[idx];
45 idx += isotopeNumbers[i];
46 }
47 //TODO in place (maybe pass a numpy matrix??)
48
49 Iso* iso = new Iso(dimNumber, isotopeNumbers, atomCounts, IM, IP);
50
51 delete[] IM;
52 delete[] IP;
53
54 return reinterpret_cast<void*>(iso);
55 }
56
57 void deleteIso(void* iso)
58 {
59 delete reinterpret_cast<Iso*>(iso);
60 }
61
62 double getLightestPeakMassIso(void* iso)
63 {
64 return reinterpret_cast<Iso*>(iso)->getLightestPeakMass();
65 }
66
67 double getHeaviestPeakMassIso(void* iso)
68 {
69 return reinterpret_cast<Iso*>(iso)->getHeaviestPeakMass();
70 }
71
72 double getMonoisotopicPeakMassIso(void* iso)
73 {
74 return reinterpret_cast<Iso*>(iso)->getMonoisotopicPeakMass();
75 }
76
77 double getModeLProbIso(void* iso)
78 {
79 return reinterpret_cast<Iso*>(iso)->getModeLProb();
80 }
81
82 double getModeMassIso(void* iso)
83 {
84 return reinterpret_cast<Iso*>(iso)->getModeMass();
85 }
86
87 double getTheoreticalAverageMassIso(void* iso)
88 {
89 return reinterpret_cast<Iso*>(iso)->getTheoreticalAverageMass();
90 }
91
92
93
94 #define ISOSPEC_C_FN_CODE(generatorType, dataType, method)\
95 dataType method##generatorType(void* generator){ return reinterpret_cast<generatorType*>(generator)->method(); }
96
97 #define ISOSPEC_C_FN_CODE_GET_CONF_SIGNATURE(generatorType)\
98 void get_conf_signature##generatorType(void* generator, int* space)\
99 { reinterpret_cast<generatorType*>(generator)->get_conf_signature(space); }
100
101
102 #define ISOSPEC_C_FN_DELETE(generatorType) void delete##generatorType(void* generator){ delete reinterpret_cast<generatorType*>(generator); }
103
104 #define ISOSPEC_C_FN_CODES(generatorType)\
105 ISOSPEC_C_FN_CODE(generatorType, double, mass) \
106 ISOSPEC_C_FN_CODE(generatorType, double, lprob) \
107 ISOSPEC_C_FN_CODE(generatorType, double, prob) \
108 ISOSPEC_C_FN_CODE_GET_CONF_SIGNATURE(generatorType) \
109 ISOSPEC_C_FN_CODE(generatorType, bool, advanceToNextConfiguration) \
110 ISOSPEC_C_FN_DELETE(generatorType)
111
112
113
114 //______________________________________________________THRESHOLD GENERATOR
115 void* setupIsoThresholdGenerator(void* iso,
116 double threshold,
117 bool _absolute,
118 int _tabSize,
119 int _hashSize)
120 {
121 IsoThresholdGenerator* iso_tmp = new IsoThresholdGenerator(
122 std::move(*reinterpret_cast<Iso*>(iso)),
123 threshold,
124 _absolute,
125 _tabSize,
126 _hashSize);
127
128 return reinterpret_cast<void*>(iso_tmp);
129 }
130 ISOSPEC_C_FN_CODES(IsoThresholdGenerator)
131
132
133 //______________________________________________________LAYERED GENERATOR
134 void* setupIsoLayeredGenerator(void* iso,
135 double _target_coverage,
136 double _percentage_to_expand,
137 int _tabSize,
138 int _hashSize,
139 bool _do_trim)
140 {
141 IsoLayeredGenerator* iso_tmp = new IsoLayeredGenerator(
142 std::move(*reinterpret_cast<Iso*>(iso)),
143 _target_coverage,
144 _percentage_to_expand,
145 _tabSize,
146 _hashSize,
147 _do_trim);
148
149 return reinterpret_cast<void*>(iso_tmp);
150 }
151 ISOSPEC_C_FN_CODES(IsoLayeredGenerator)
152
153
154 //______________________________________________________ORDERED GENERATOR
155 void* setupIsoOrderedGenerator(void* iso,
156 int _tabSize,
157 int _hashSize)
158 {
159 IsoOrderedGenerator* iso_tmp = new IsoOrderedGenerator(
160 std::move(*reinterpret_cast<Iso*>(iso)),
161 _tabSize,
162 _hashSize);
163
164 return reinterpret_cast<void*>(iso_tmp);
165 }
166 ISOSPEC_C_FN_CODES(IsoOrderedGenerator)
167
168 //______________________________________________________ Threshold Tabulator
169
170 void* setupThresholdTabulator(void* generator,
171 bool get_masses,
172 bool get_probs,
173 bool get_lprobs,
174 bool get_confs)
175 {
176 Tabulator<IsoThresholdGenerator>* tabulator = new Tabulator<IsoThresholdGenerator>(reinterpret_cast<IsoThresholdGenerator*>(generator),
177 get_masses,
178 get_probs,
179 get_lprobs,
180 get_confs);
181
182 return reinterpret_cast<void*>(tabulator);
183 }
184
185 void deleteThresholdTabulator(void* t)
186 {
187 delete reinterpret_cast<Tabulator<IsoThresholdGenerator>*>(t);
188 }
189
190 const double* massesThresholdTabulator(void* tabulator)
191 {
192 return reinterpret_cast<Tabulator<IsoThresholdGenerator>*>(tabulator)->masses(true);
193 }
194
195 const double* lprobsThresholdTabulator(void* tabulator)
196 {
197 return reinterpret_cast<Tabulator<IsoThresholdGenerator>*>(tabulator)->lprobs(true);
198 }
199
200 const double* probsThresholdTabulator(void* tabulator)
201 {
202 return reinterpret_cast<Tabulator<IsoThresholdGenerator>*>(tabulator)->probs(true);
203 }
204
205 const int* confsThresholdTabulator(void* tabulator)
206 {
207 return reinterpret_cast<Tabulator<IsoThresholdGenerator>*>(tabulator)->confs(true);
208 }
209
210 int confs_noThresholdTabulator(void* tabulator)
211 {
212 return reinterpret_cast<Tabulator<IsoThresholdGenerator>*>(tabulator)->confs_no();
213 }
214
215
216 //______________________________________________________ Layered Tabulator
217
218 void* setupLayeredTabulator(void* generator,
219 bool get_masses,
220 bool get_probs,
221 bool get_lprobs,
222 bool get_confs)
223 {
224 Tabulator<IsoLayeredGenerator>* tabulator = new Tabulator<IsoLayeredGenerator>(reinterpret_cast<IsoLayeredGenerator*>(generator),
225 get_masses,
226 get_probs,
227 get_lprobs,
228 get_confs);
229
230 return reinterpret_cast<void*>(tabulator);
231 }
232
233 void deleteLayeredTabulator(void* t)
234 {
235 delete reinterpret_cast<Tabulator<IsoLayeredGenerator>*>(t);
236 }
237
238 const double* massesLayeredTabulator(void* tabulator)
239 {
240 return reinterpret_cast<Tabulator<IsoLayeredGenerator>*>(tabulator)->masses(true);
241 }
242
243 const double* lprobsLayeredTabulator(void* tabulator)
244 {
245 return reinterpret_cast<Tabulator<IsoLayeredGenerator>*>(tabulator)->lprobs(true);
246 }
247
248 const double* probsLayeredTabulator(void* tabulator)
249 {
250 return reinterpret_cast<Tabulator<IsoLayeredGenerator>*>(tabulator)->probs(true);
251 }
252
253 const int* confsLayeredTabulator(void* tabulator)
254 {
255 return reinterpret_cast<Tabulator<IsoLayeredGenerator>*>(tabulator)->confs(true);
256 }
257
258 int confs_noLayeredTabulator(void* tabulator)
259 {
260 return reinterpret_cast<Tabulator<IsoLayeredGenerator>*>(tabulator)->confs_no();
261 }
262
263 void freeReleasedArray(void* array)
264 {
265 free(array);
266 }
267
268 } //extern "C" ends here
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #define ISOSPEC_ALGO_LAYERED 0
19 #define ISOSPEC_ALGO_ORDERED 1
20 #define ISOSPEC_ALGO_THRESHOLD_ABSOLUTE 2
21 #define ISOSPEC_ALGO_THRESHOLD_RELATIVE 3
22 #define ISOSPEC_ALGO_LAYERED_ESTIMATE 4
23
24
25 #ifdef __cplusplus
26 extern "C" {
27 #else
28 #include <stdbool.h>
29 #endif
30
31 void * setupIso(int dimNumber,
32 const int* isotopeNumbers,
33 const int* atomCounts,
34 const double* isotopeMasses,
35 const double* isotopeProbabilities);
36
37 double getLightestPeakMassIso(void* iso);
38 double getHeaviestPeakMassIso(void* iso);
39 double getMonoisotopicPeakMassIso(void* iso);
40 double getModeLProbIso(void* iso);
41 double getModeMassIso(void* iso);
42 double getTheoreticalAverageMassIso(void* iso);
43
44
45 void deleteIso(void* iso);
46
47 #define ISOSPEC_C_FN_HEADER(generatorType, dataType, method)\
48 dataType method##generatorType(void* generator);
49
50 #define ISOSPEC_C_FN_HEADER_GET_CONF_SIGNATURE(generatorType)\
51 void method##generatorType(void* generator);
52
53 #define ISOSPEC_C_FN_HEADERS(generatorType)\
54 ISOSPEC_C_FN_HEADER(generatorType, double, mass) \
55 ISOSPEC_C_FN_HEADER(generatorType, double, lprob) \
56 ISOSPEC_C_FN_HEADER(generatorType, double, prob) \
57 ISOSPEC_C_FN_HEADER_GET_CONF_SIGNATURE(generatorType) \
58 ISOSPEC_C_FN_HEADER(generatorType, bool, advanceToNextConfiguration) \
59 ISOSPEC_C_FN_HEADER(generatorType, void, delete)
60
61
62
63
64 //______________________________________________________THRESHOLD GENERATOR
65 void* setupIsoThresholdGenerator(void* iso,
66 double threshold,
67 bool _absolute,
68 int _tabSize,
69 int _hashSize);
70 ISOSPEC_C_FN_HEADERS(IsoThresholdGenerator)
71
72
73 //______________________________________________________LAYERED GENERATOR
74 void* setupIsoLayeredGenerator(void* iso,
75 double _target_coverage,
76 double _percentage_to_expand,
77 int _tabSize,
78 int _hashSize,
79 bool _do_trim);
80 ISOSPEC_C_FN_HEADERS(IsoLayeredGenerator)
81
82 //______________________________________________________ORDERED GENERATOR
83 void* setupIsoOrderedGenerator(void* iso,
84 int _tabSize,
85 int _hashSize);
86 ISOSPEC_C_FN_HEADERS(IsoOrderedGenerator)
87
88
89
90 void* setupThresholdTabulator(void* generator,
91 bool get_masses,
92 bool get_probs,
93 bool get_lprobs,
94 bool get_confs);
95
96 void deleteThresholdTabulator(void* tabulator);
97
98 const double* massesThresholdTabulator(void* tabulator);
99 const double* lprobsThresholdTabulator(void* tabulator);
100 const double* probsThresholdTabulator(void* tabulator);
101 const int* confsThresholdTabulator(void* tabulator);
102 int confs_noThresholdTabulator(void* tabulator);
103
104
105
106 void* setupLayeredTabulator(void* generator,
107 bool get_masses,
108 bool get_probs,
109 bool get_lprobs,
110 bool get_confs);
111
112 void deleteLayeredTabulator(void* tabulator);
113
114 const double* massesLayeredTabulator(void* tabulator);
115 const double* lprobsLayeredTabulator(void* tabulator);
116 const double* probsLayeredTabulator(void* tabulator);
117 const int* confsLayeredTabulator(void* tabulator);
118 int confs_noLayeredTabulator(void* tabulator);
119
120 void freeReleasedArray(void* array);
121
122 #ifdef __cplusplus
123 }
124 #endif
125
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16
17 #include <iostream>
18 #include <stdlib.h>
19 #include "dirtyAllocator.h"
20
21 namespace IsoSpec
22 {
23
24 DirtyAllocator::DirtyAllocator(
25 const int dim, const int tabSize
26 ): tabSize(tabSize)
27 {
28 cellSize = sizeof(double) + sizeof(int) * dim;
29 // Fix memory alignment problems for SPARC
30 if(cellSize % sizeof(double) != 0)
31 cellSize += sizeof(double) - cellSize % sizeof(double);
32 currentTab = malloc( cellSize * tabSize );
33 currentConf = currentTab;
34 endOfTablePtr = reinterpret_cast<char*>(currentTab) + cellSize*tabSize;
35 }
36
37
38 DirtyAllocator::~DirtyAllocator()
39 {
40 for(unsigned int i = 0; i < prevTabs.size(); ++i) free(prevTabs[i]);
41 free(currentTab);
42 }
43
44 void DirtyAllocator::shiftTables()
45 {
46 prevTabs.push_back(currentTab);
47
48 currentTab = malloc( cellSize * tabSize );
49 currentConf = currentTab;
50 endOfTablePtr = reinterpret_cast<char*>(currentTab) + cellSize*tabSize;
51 }
52
53 } // namespace IsoSpec
54
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <vector>
19 #include <iostream>
20 #include <string.h>
21
22 namespace IsoSpec
23 {
24
25 class DirtyAllocator{
26 private:
27 void* currentTab;
28 void* currentConf;
29 void* endOfTablePtr;
30 const int tabSize;
31 int cellSize;
32 std::vector<void*> prevTabs;
33 public:
34 DirtyAllocator(const int dim, const int tabSize = 10000);
35 ~DirtyAllocator();
36
37 void shiftTables();
38
39 inline void* newConf()
40 {
41 if (currentConf >= endOfTablePtr)
42 {
43 shiftTables();
44 }
45
46 void* ret = currentConf;
47 currentConf = reinterpret_cast<char*>(currentConf) + cellSize;
48
49 return ret;
50 }
51
52 inline void* makeCopy(const void* conf)
53 {
54 void* currentPlace = newConf();
55
56 memcpy(currentPlace, conf, cellSize);
57
58 return currentPlace;
59 }
60
61 inline void* makeExternalCopy(const void* conf)
62 {
63 void* res = malloc(cellSize);
64
65 memcpy(res, conf, cellSize);
66
67 return res;
68 }
69 };
70
71 } // namespace IsoSpec
72
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #include "element_tables.h"
17
18 namespace IsoSpec
19 {
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25 const int elem_table_atomicNo [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
26 1,
27 1,
28 2,
29 2,
30 3,
31 3,
32 4,
33 5,
34 5,
35 6,
36 6,
37 7,
38 7,
39 8,
40 8,
41 8,
42 9,
43 10,
44 10,
45 10,
46 11,
47 12,
48 12,
49 12,
50 13,
51 14,
52 14,
53 14,
54 15,
55 16,
56 16,
57 16,
58 16,
59 17,
60 17,
61 18,
62 18,
63 18,
64 19,
65 19,
66 19,
67 20,
68 20,
69 20,
70 20,
71 20,
72 20,
73 21,
74 22,
75 22,
76 22,
77 22,
78 22,
79 23,
80 23,
81 24,
82 24,
83 24,
84 24,
85 25,
86 26,
87 26,
88 26,
89 26,
90 27,
91 28,
92 28,
93 28,
94 28,
95 28,
96 29,
97 29,
98 30,
99 30,
100 30,
101 30,
102 30,
103 31,
104 31,
105 32,
106 32,
107 32,
108 32,
109 32,
110 33,
111 34,
112 34,
113 34,
114 34,
115 34,
116 34,
117 35,
118 35,
119 36,
120 36,
121 36,
122 36,
123 36,
124 36,
125 37,
126 37,
127 38,
128 38,
129 38,
130 38,
131 39,
132 40,
133 40,
134 40,
135 40,
136 40,
137 41,
138 42,
139 42,
140 42,
141 42,
142 42,
143 42,
144 42,
145 44,
146 44,
147 44,
148 44,
149 44,
150 44,
151 44,
152 45,
153 46,
154 46,
155 46,
156 46,
157 46,
158 46,
159 47,
160 47,
161 48,
162 48,
163 48,
164 48,
165 48,
166 48,
167 48,
168 48,
169 49,
170 49,
171 50,
172 50,
173 50,
174 50,
175 50,
176 50,
177 50,
178 50,
179 50,
180 50,
181 51,
182 51,
183 52,
184 52,
185 52,
186 52,
187 52,
188 52,
189 52,
190 52,
191 53,
192 54,
193 54,
194 54,
195 54,
196 54,
197 54,
198 54,
199 54,
200 54,
201 55,
202 56,
203 56,
204 56,
205 56,
206 56,
207 56,
208 56,
209 57,
210 57,
211 58,
212 58,
213 58,
214 58,
215 59,
216 60,
217 60,
218 60,
219 60,
220 60,
221 60,
222 60,
223 62,
224 62,
225 62,
226 62,
227 62,
228 62,
229 62,
230 63,
231 63,
232 64,
233 64,
234 64,
235 64,
236 64,
237 64,
238 64,
239 65,
240 66,
241 66,
242 66,
243 66,
244 66,
245 66,
246 66,
247 67,
248 68,
249 68,
250 68,
251 68,
252 68,
253 68,
254 69,
255 70,
256 70,
257 70,
258 70,
259 70,
260 70,
261 70,
262 71,
263 71,
264 72,
265 72,
266 72,
267 72,
268 72,
269 72,
270 73,
271 73,
272 74,
273 74,
274 74,
275 74,
276 74,
277 75,
278 75,
279 76,
280 76,
281 76,
282 76,
283 76,
284 76,
285 76,
286 77,
287 77,
288 78,
289 78,
290 78,
291 78,
292 78,
293 78,
294 79,
295 80,
296 80,
297 80,
298 80,
299 80,
300 80,
301 80,
302 81,
303 81,
304 82,
305 82,
306 82,
307 82,
308 83,
309 92,
310 92,
311 92,
312 90,
313 91,
314 };
315
316
317 const double elem_table_mass [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
318 1.00782503227,
319 2.01410177819,
320 3.016029322,
321 4.00260325414,
322 6.0151228871,
323 7.016003443,
324 9.01218316,
325 10.0129373,
326 11.0093053,
327 12,
328 13.0033548352,
329 14.0030740042,
330 15.0001088994,
331 15.9949146202,
332 16.9991317576,
333 17.9991596137,
334 18.9984031637,
335 19.992440182,
336 20.99384673,
337 21.99138512,
338 22.989769282,
339 23.985041701,
340 24.98583703,
341 25.98259302,
342 26.98153858,
343 27.9769265353,
344 28.9764946653,
345 29.973770012,
346 30.9737619986,
347 31.9720711741,
348 32.9714589101,
349 33.96786703,
350 35.9670812,
351 34.96885273,
352 36.96590264,
353 35.96754512,
354 37.9627322,
355 39.962383122,
356 38.963706493,
357 39.96399824,
358 40.961825263,
359 39.96259092,
360 41.9586181,
361 42.9587662,
362 43.9554822,
363 45.953692,
364 47.95252289,
365 44.9559086,
366 45.9526283,
367 46.9517593,
368 47.9479423,
369 48.9478663,
370 49.9447873,
371 49.9471567,
372 50.9439577,
373 49.9460427,
374 51.9405064,
375 52.9406484,
376 53.9388794,
377 54.9380443,
378 53.9396093,
379 55.9349363,
380 56.9353933,
381 57.9332743,
382 58.9331944,
383 57.9353423,
384 59.9307863,
385 60.9310563,
386 61.9283454,
387 63.9279674,
388 62.9295984,
389 64.9277906,
390 63.9291426,
391 65.9260347,
392 66.9271287,
393 67.9248457,
394 69.925322,
395 68.9255749,
396 70.9247037,
397 69.9242497,
398 71.92207586,
399 72.92345904,
400 73.921177761,
401 75.92140272,
402 74.9215957,
403 73.92247591,
404 75.91921372,
405 76.91991426,
406 77.9173092,
407 79.9165229,
408 81.9167001,
409 78.9183381,
410 80.9162901,
411 77.9203656,
412 79.9163786,
413 81.9134837,
414 82.9141272,
415 83.911497733,
416 85.910610633,
417 84.911789743,
418 86.909180536,
419 83.9134199,
420 85.9092619,
421 86.9088789,
422 87.9056139,
423 88.905842,
424 89.904702,
425 90.905642,
426 91.905032,
427 93.906312,
428 95.908272,
429 92.906372,
430 91.9068086,
431 93.9050853,
432 94.9058393,
433 95.9046763,
434 96.9060183,
435 97.9054053,
436 99.9074728,
437 95.9075903,
438 97.905296,
439 98.9059348,
440 99.9042148,
441 100.9055779,
442 101.9043449,
443 103.905432,
444 102.905502,
445 101.905602,
446 103.9040311,
447 104.9050809,
448 105.9034809,
449 107.9038929,
450 109.9051726,
451 106.905092,
452 108.9047551,
453 105.9064609,
454 107.9041839,
455 109.9030074,
456 110.9041834,
457 111.9027634,
458 112.9044083,
459 113.9033653,
460 115.9047632,
461 112.9040627,
462 114.903878789,
463 111.9048244,
464 113.9027837,
465 114.90334471,
466 115.9017431,
467 116.9029543,
468 117.9016073,
469 118.9033116,
470 119.9022027,
471 121.903442,
472 123.9052778,
473 120.903812,
474 122.904212,
475 119.904062,
476 121.903041,
477 122.904271,
478 123.902821,
479 124.904431,
480 125.903311,
481 127.9044617,
482 129.906222759,
483 126.904473,
484 123.905892,
485 125.904303,
486 127.9035318,
487 128.904780864,
488 129.90350941,
489 130.9050842,
490 131.904155094,
491 133.9053957,
492 135.907214488,
493 132.905451967,
494 129.906322,
495 131.9050618,
496 133.9045082,
497 134.9056882,
498 135.9045762,
499 136.9058272,
500 137.9052472,
501 137.907123,
502 138.906362,
503 135.9071293,
504 137.905998,
505 139.905442,
506 141.909252,
507 140.907662,
508 141.907732,
509 142.909822,
510 143.910092,
511 144.912582,
512 145.913122,
513 147.916902,
514 149.920902,
515 143.912012,
516 146.914902,
517 147.914832,
518 148.917192,
519 149.917282,
520 151.919742,
521 153.922222,
522 150.919862,
523 152.921242,
524 151.919802,
525 153.920872,
526 154.922632,
527 155.922132,
528 156.923972,
529 157.924112,
530 159.927062,
531 158.925352,
532 155.924282,
533 157.924422,
534 159.925202,
535 160.926942,
536 161.926812,
537 162.928742,
538 163.929182,
539 164.930332,
540 161.928792,
541 163.929212,
542 165.930302,
543 166.932052,
544 167.932382,
545 169.935472,
546 168.934222,
547 167.933892,
548 169.934772,
549 170.936332,
550 171.936392,
551 172.938222,
552 173.938872,
553 175.942582,
554 174.940782,
555 175.942692,
556 173.940052,
557 175.941412,
558 176.943232,
559 177.943712,
560 178.945822,
561 179.946562,
562 179.947462,
563 180.948002,
564 179.946712,
565 181.9482047,
566 182.9502237,
567 183.9509317,
568 185.954362,
569 184.9529559,
570 186.955751,
571 183.9524891,
572 185.953841,
573 186.955751,
574 187.955841,
575 188.958142,
576 189.958442,
577 191.961482,
578 190.960592,
579 192.962922,
580 189.959934,
581 191.961042,
582 193.9626817,
583 194.9647927,
584 195.9649527,
585 197.967892,
586 196.9665696,
587 195.965832,
588 197.9667693,
589 198.9682813,
590 199.9683273,
591 200.9703036,
592 201.9706436,
593 203.9734943,
594 202.9723451,
595 204.9744281,
596 203.9730449,
597 205.9744669,
598 206.9758979,
599 207.9766539,
600 208.980401,
601 234.040952,
602 235.043932,
603 238.050792,
604 232.038062,
605 231.035882,
606 };
607
608
609 const int elem_table_massNo [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
610 1,
611 2,
612 3,
613 4,
614 6,
615 7,
616 9,
617 10,
618 11,
619 12,
620 13,
621 14,
622 15,
623 16,
624 17,
625 18,
626 19,
627 20,
628 21,
629 22,
630 23,
631 24,
632 25,
633 26,
634 27,
635 28,
636 29,
637 30,
638 31,
639 32,
640 33,
641 34,
642 36,
643 35,
644 37,
645 36,
646 38,
647 40,
648 39,
649 40,
650 41,
651 40,
652 42,
653 43,
654 44,
655 46,
656 48,
657 45,
658 46,
659 47,
660 48,
661 49,
662 50,
663 50,
664 51,
665 50,
666 52,
667 53,
668 54,
669 55,
670 54,
671 56,
672 57,
673 58,
674 59,
675 58,
676 60,
677 61,
678 62,
679 64,
680 63,
681 65,
682 64,
683 66,
684 67,
685 68,
686 70,
687 69,
688 71,
689 70,
690 72,
691 73,
692 74,
693 76,
694 75,
695 74,
696 76,
697 77,
698 78,
699 80,
700 82,
701 79,
702 81,
703 78,
704 80,
705 82,
706 83,
707 84,
708 86,
709 85,
710 87,
711 84,
712 86,
713 87,
714 88,
715 89,
716 90,
717 91,
718 92,
719 94,
720 96,
721 93,
722 92,
723 94,
724 95,
725 96,
726 97,
727 98,
728 100,
729 96,
730 98,
731 99,
732 100,
733 101,
734 102,
735 104,
736 103,
737 102,
738 104,
739 105,
740 106,
741 108,
742 110,
743 107,
744 109,
745 106,
746 108,
747 110,
748 111,
749 112,
750 113,
751 114,
752 116,
753 113,
754 115,
755 112,
756 114,
757 115,
758 116,
759 117,
760 118,
761 119,
762 120,
763 122,
764 124,
765 121,
766 123,
767 120,
768 122,
769 123,
770 124,
771 125,
772 126,
773 128,
774 130,
775 127,
776 124,
777 126,
778 128,
779 129,
780 130,
781 131,
782 132,
783 134,
784 136,
785 133,
786 130,
787 132,
788 134,
789 135,
790 136,
791 137,
792 138,
793 138,
794 139,
795 136,
796 138,
797 140,
798 142,
799 141,
800 142,
801 143,
802 144,
803 145,
804 146,
805 148,
806 150,
807 144,
808 147,
809 148,
810 149,
811 150,
812 152,
813 154,
814 151,
815 153,
816 152,
817 154,
818 155,
819 156,
820 157,
821 158,
822 160,
823 159,
824 156,
825 158,
826 160,
827 161,
828 162,
829 163,
830 164,
831 165,
832 162,
833 164,
834 166,
835 167,
836 168,
837 170,
838 169,
839 168,
840 170,
841 171,
842 172,
843 173,
844 174,
845 176,
846 175,
847 176,
848 174,
849 176,
850 177,
851 178,
852 179,
853 180,
854 180,
855 181,
856 180,
857 182,
858 183,
859 184,
860 186,
861 185,
862 187,
863 184,
864 186,
865 187,
866 188,
867 189,
868 190,
869 192,
870 191,
871 193,
872 190,
873 192,
874 194,
875 195,
876 196,
877 198,
878 197,
879 196,
880 198,
881 199,
882 200,
883 201,
884 202,
885 204,
886 203,
887 205,
888 204,
889 206,
890 207,
891 208,
892 209,
893 234,
894 235,
895 238,
896 232,
897 231,
898 };
899
900
901 const int elem_table_extraNeutrons [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
902 0,
903 1,
904 0,
905 1,
906 0,
907 1,
908 0,
909 0,
910 1,
911 0,
912 1,
913 0,
914 1,
915 0,
916 1,
917 2,
918 0,
919 0,
920 1,
921 2,
922 0,
923 0,
924 1,
925 2,
926 0,
927 0,
928 1,
929 2,
930 0,
931 0,
932 1,
933 2,
934 4,
935 0,
936 2,
937 0,
938 2,
939 4,
940 0,
941 1,
942 2,
943 0,
944 2,
945 3,
946 4,
947 6,
948 8,
949 0,
950 0,
951 1,
952 2,
953 3,
954 4,
955 0,
956 1,
957 0,
958 2,
959 3,
960 4,
961 0,
962 0,
963 2,
964 3,
965 4,
966 0,
967 0,
968 2,
969 3,
970 4,
971 6,
972 0,
973 2,
974 0,
975 2,
976 3,
977 4,
978 6,
979 0,
980 2,
981 0,
982 2,
983 3,
984 4,
985 6,
986 0,
987 0,
988 2,
989 3,
990 4,
991 6,
992 8,
993 0,
994 2,
995 0,
996 2,
997 4,
998 5,
999 6,
1000 8,
1001 0,
1002 2,
1003 0,
1004 2,
1005 3,
1006 4,
1007 0,
1008 0,
1009 1,
1010 2,
1011 4,
1012 6,
1013 0,
1014 0,
1015 2,
1016 3,
1017 4,
1018 5,
1019 6,
1020 8,
1021 0,
1022 2,
1023 3,
1024 4,
1025 5,
1026 6,
1027 8,
1028 0,
1029 0,
1030 2,
1031 3,
1032 4,
1033 6,
1034 8,
1035 0,
1036 2,
1037 0,
1038 2,
1039 4,
1040 5,
1041 6,
1042 7,
1043 8,
1044 10,
1045 0,
1046 2,
1047 0,
1048 2,
1049 3,
1050 4,
1051 5,
1052 6,
1053 7,
1054 8,
1055 10,
1056 12,
1057 0,
1058 2,
1059 0,
1060 2,
1061 3,
1062 4,
1063 5,
1064 6,
1065 8,
1066 10,
1067 0,
1068 0,
1069 2,
1070 4,
1071 5,
1072 6,
1073 7,
1074 8,
1075 10,
1076 12,
1077 0,
1078 0,
1079 2,
1080 4,
1081 5,
1082 6,
1083 7,
1084 8,
1085 0,
1086 1,
1087 0,
1088 2,
1089 4,
1090 6,
1091 0,
1092 0,
1093 1,
1094 2,
1095 3,
1096 4,
1097 6,
1098 8,
1099 0,
1100 3,
1101 4,
1102 5,
1103 6,
1104 8,
1105 10,
1106 0,
1107 2,
1108 0,
1109 2,
1110 3,
1111 4,
1112 5,
1113 6,
1114 8,
1115 0,
1116 0,
1117 2,
1118 4,
1119 5,
1120 6,
1121 7,
1122 8,
1123 0,
1124 0,
1125 2,
1126 4,
1127 5,
1128 6,
1129 8,
1130 0,
1131 0,
1132 2,
1133 3,
1134 4,
1135 5,
1136 6,
1137 8,
1138 0,
1139 1,
1140 0,
1141 2,
1142 3,
1143 4,
1144 5,
1145 6,
1146 0,
1147 1,
1148 0,
1149 2,
1150 3,
1151 4,
1152 6,
1153 0,
1154 2,
1155 0,
1156 2,
1157 3,
1158 4,
1159 5,
1160 6,
1161 8,
1162 0,
1163 2,
1164 0,
1165 2,
1166 4,
1167 5,
1168 6,
1169 8,
1170 0,
1171 0,
1172 2,
1173 3,
1174 4,
1175 5,
1176 6,
1177 8,
1178 0,
1179 2,
1180 0,
1181 2,
1182 3,
1183 4,
1184 0,
1185 1,
1186 2,
1187 5,
1188 0,
1189 0,
1190 };
1191
1192
1193 const char* elem_table_element [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
1194 "hydrogen",
1195 "hydrogen",
1196 "helium",
1197 "helium",
1198 "lithium",
1199 "lithium",
1200 "beryllium",
1201 "boron",
1202 "boron",
1203 "carbon",
1204 "carbon",
1205 "nitrogen",
1206 "nitrogen",
1207 "oxygen",
1208 "oxygen",
1209 "oxygen",
1210 "fluorine",
1211 "neon",
1212 "neon",
1213 "neon",
1214 "sodium",
1215 "magnesium",
1216 "magnesium",
1217 "magnesium",
1218 "aluminium",
1219 "silicon",
1220 "silicon",
1221 "silicon",
1222 "phosphorus",
1223 "sulfur",
1224 "sulfur",
1225 "sulfur",
1226 "sulfur",
1227 "chlorine",
1228 "chlorine",
1229 "argon",
1230 "argon",
1231 "argon",
1232 "potassium",
1233 "potassium",
1234 "potassium",
1235 "calcium",
1236 "calcium",
1237 "calcium",
1238 "calcium",
1239 "calcium",
1240 "calcium",
1241 "scandium",
1242 "titanium",
1243 "titanium",
1244 "titanium",
1245 "titanium",
1246 "titanium",
1247 "vanadium",
1248 "vanadium",
1249 "chromium",
1250 "chromium",
1251 "chromium",
1252 "chromium",
1253 "manganese",
1254 "iron",
1255 "iron",
1256 "iron",
1257 "iron",
1258 "cobalt",
1259 "nickel",
1260 "nickel",
1261 "nickel",
1262 "nickel",
1263 "nickel",
1264 "copper",
1265 "copper",
1266 "zinc",
1267 "zinc",
1268 "zinc",
1269 "zinc",
1270 "zinc",
1271 "gallium",
1272 "gallium",
1273 "germanium",
1274 "germanium",
1275 "germanium",
1276 "germanium",
1277 "germanium",
1278 "arsenic",
1279 "selenium",
1280 "selenium",
1281 "selenium",
1282 "selenium",
1283 "selenium",
1284 "selenium",
1285 "bromine",
1286 "bromine",
1287 "krypton",
1288 "krypton",
1289 "krypton",
1290 "krypton",
1291 "krypton",
1292 "krypton",
1293 "rubidium",
1294 "rubidium",
1295 "strontium",
1296 "strontium",
1297 "strontium",
1298 "strontium",
1299 "yttrium",
1300 "zirconium",
1301 "zirconium",
1302 "zirconium",
1303 "zirconium",
1304 "zirconium",
1305 "niobium",
1306 "molybdenum",
1307 "molybdenum",
1308 "molybdenum",
1309 "molybdenum",
1310 "molybdenum",
1311 "molybdenum",
1312 "molybdenum",
1313 "ruthenium",
1314 "ruthenium",
1315 "ruthenium",
1316 "ruthenium",
1317 "ruthenium",
1318 "ruthenium",
1319 "ruthenium",
1320 "rhodium",
1321 "palladium",
1322 "palladium",
1323 "palladium",
1324 "palladium",
1325 "palladium",
1326 "palladium",
1327 "silver",
1328 "silver",
1329 "cadmium",
1330 "cadmium",
1331 "cadmium",
1332 "cadmium",
1333 "cadmium",
1334 "cadmium",
1335 "cadmium",
1336 "cadmium",
1337 "indium",
1338 "indium",
1339 "tin",
1340 "tin",
1341 "tin",
1342 "tin",
1343 "tin",
1344 "tin",
1345 "tin",
1346 "tin",
1347 "tin",
1348 "tin",
1349 "antimony",
1350 "antimony",
1351 "tellurium",
1352 "tellurium",
1353 "tellurium",
1354 "tellurium",
1355 "tellurium",
1356 "tellurium",
1357 "tellurium",
1358 "tellurium",
1359 "iodine",
1360 "xenon",
1361 "xenon",
1362 "xenon",
1363 "xenon",
1364 "xenon",
1365 "xenon",
1366 "xenon",
1367 "xenon",
1368 "xenon",
1369 "caesium",
1370 "barium",
1371 "barium",
1372 "barium",
1373 "barium",
1374 "barium",
1375 "barium",
1376 "barium",
1377 "lanthanum",
1378 "lanthanum",
1379 "cerium",
1380 "cerium",
1381 "cerium",
1382 "cerium",
1383 "praseodymium",
1384 "neodymium",
1385 "neodymium",
1386 "neodymium",
1387 "neodymium",
1388 "neodymium",
1389 "neodymium",
1390 "neodymium",
1391 "samarium",
1392 "samarium",
1393 "samarium",
1394 "samarium",
1395 "samarium",
1396 "samarium",
1397 "samarium",
1398 "europium",
1399 "europium",
1400 "gadolinium",
1401 "gadolinium",
1402 "gadolinium",
1403 "gadolinium",
1404 "gadolinium",
1405 "gadolinium",
1406 "gadolinium",
1407 "terbium",
1408 "dysprosium",
1409 "dysprosium",
1410 "dysprosium",
1411 "dysprosium",
1412 "dysprosium",
1413 "dysprosium",
1414 "dysprosium",
1415 "holmium",
1416 "erbium",
1417 "erbium",
1418 "erbium",
1419 "erbium",
1420 "erbium",
1421 "erbium",
1422 "thulium",
1423 "ytterbium",
1424 "ytterbium",
1425 "ytterbium",
1426 "ytterbium",
1427 "ytterbium",
1428 "ytterbium",
1429 "ytterbium",
1430 "lutetium",
1431 "lutetium",
1432 "hafnium",
1433 "hafnium",
1434 "hafnium",
1435 "hafnium",
1436 "hafnium",
1437 "hafnium",
1438 "tantalum",
1439 "tantalum",
1440 "tungsten",
1441 "tungsten",
1442 "tungsten",
1443 "tungsten",
1444 "tungsten",
1445 "rhenium",
1446 "rhenium",
1447 "osmium",
1448 "osmium",
1449 "osmium",
1450 "osmium",
1451 "osmium",
1452 "osmium",
1453 "osmium",
1454 "iridium",
1455 "iridium",
1456 "platinum",
1457 "platinum",
1458 "platinum",
1459 "platinum",
1460 "platinum",
1461 "platinum",
1462 "gold",
1463 "mercury",
1464 "mercury",
1465 "mercury",
1466 "mercury",
1467 "mercury",
1468 "mercury",
1469 "mercury",
1470 "thallium",
1471 "thallium",
1472 "lead",
1473 "lead",
1474 "lead",
1475 "lead",
1476 "bismuth",
1477 "uranium",
1478 "uranium",
1479 "uranium",
1480 "thorium",
1481 "protactinium",
1482 };
1483
1484
1485 const char* elem_table_symbol [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
1486 "H",
1487 "H",
1488 "He",
1489 "He",
1490 "Li",
1491 "Li",
1492 "Be",
1493 "B",
1494 "B",
1495 "C",
1496 "C",
1497 "N",
1498 "N",
1499 "O",
1500 "O",
1501 "O",
1502 "F",
1503 "Ne",
1504 "Ne",
1505 "Ne",
1506 "Na",
1507 "Mg",
1508 "Mg",
1509 "Mg",
1510 "Al",
1511 "Si",
1512 "Si",
1513 "Si",
1514 "P",
1515 "S",
1516 "S",
1517 "S",
1518 "S",
1519 "Cl",
1520 "Cl",
1521 "Ar",
1522 "Ar",
1523 "Ar",
1524 "K",
1525 "K",
1526 "K",
1527 "Ca",
1528 "Ca",
1529 "Ca",
1530 "Ca",
1531 "Ca",
1532 "Ca",
1533 "Sc",
1534 "Ti",
1535 "Ti",
1536 "Ti",
1537 "Ti",
1538 "Ti",
1539 "V",
1540 "V",
1541 "Cr",
1542 "Cr",
1543 "Cr",
1544 "Cr",
1545 "Mn",
1546 "Fe",
1547 "Fe",
1548 "Fe",
1549 "Fe",
1550 "Co",
1551 "Ni",
1552 "Ni",
1553 "Ni",
1554 "Ni",
1555 "Ni",
1556 "Cu",
1557 "Cu",
1558 "Zn",
1559 "Zn",
1560 "Zn",
1561 "Zn",
1562 "Zn",
1563 "Ga",
1564 "Ga",
1565 "Ge",
1566 "Ge",
1567 "Ge",
1568 "Ge",
1569 "Ge",
1570 "As",
1571 "Se",
1572 "Se",
1573 "Se",
1574 "Se",
1575 "Se",
1576 "Se",
1577 "Br",
1578 "Br",
1579 "Kr",
1580 "Kr",
1581 "Kr",
1582 "Kr",
1583 "Kr",
1584 "Kr",
1585 "Rb",
1586 "Rb",
1587 "Sr",
1588 "Sr",
1589 "Sr",
1590 "Sr",
1591 "Y",
1592 "Zr",
1593 "Zr",
1594 "Zr",
1595 "Zr",
1596 "Zr",
1597 "Nb",
1598 "Mo",
1599 "Mo",
1600 "Mo",
1601 "Mo",
1602 "Mo",
1603 "Mo",
1604 "Mo",
1605 "Ru",
1606 "Ru",
1607 "Ru",
1608 "Ru",
1609 "Ru",
1610 "Ru",
1611 "Ru",
1612 "Rh",
1613 "Pd",
1614 "Pd",
1615 "Pd",
1616 "Pd",
1617 "Pd",
1618 "Pd",
1619 "Ag",
1620 "Ag",
1621 "Cd",
1622 "Cd",
1623 "Cd",
1624 "Cd",
1625 "Cd",
1626 "Cd",
1627 "Cd",
1628 "Cd",
1629 "In",
1630 "In",
1631 "Sn",
1632 "Sn",
1633 "Sn",
1634 "Sn",
1635 "Sn",
1636 "Sn",
1637 "Sn",
1638 "Sn",
1639 "Sn",
1640 "Sn",
1641 "Sb",
1642 "Sb",
1643 "Te",
1644 "Te",
1645 "Te",
1646 "Te",
1647 "Te",
1648 "Te",
1649 "Te",
1650 "Te",
1651 "I",
1652 "Xe",
1653 "Xe",
1654 "Xe",
1655 "Xe",
1656 "Xe",
1657 "Xe",
1658 "Xe",
1659 "Xe",
1660 "Xe",
1661 "Cs",
1662 "Ba",
1663 "Ba",
1664 "Ba",
1665 "Ba",
1666 "Ba",
1667 "Ba",
1668 "Ba",
1669 "La",
1670 "La",
1671 "Ce",
1672 "Ce",
1673 "Ce",
1674 "Ce",
1675 "Pr",
1676 "Nd",
1677 "Nd",
1678 "Nd",
1679 "Nd",
1680 "Nd",
1681 "Nd",
1682 "Nd",
1683 "Sm",
1684 "Sm",
1685 "Sm",
1686 "Sm",
1687 "Sm",
1688 "Sm",
1689 "Sm",
1690 "Eu",
1691 "Eu",
1692 "Gd",
1693 "Gd",
1694 "Gd",
1695 "Gd",
1696 "Gd",
1697 "Gd",
1698 "Gd",
1699 "Tb",
1700 "Dy",
1701 "Dy",
1702 "Dy",
1703 "Dy",
1704 "Dy",
1705 "Dy",
1706 "Dy",
1707 "Ho",
1708 "Er",
1709 "Er",
1710 "Er",
1711 "Er",
1712 "Er",
1713 "Er",
1714 "Tm",
1715 "Yb",
1716 "Yb",
1717 "Yb",
1718 "Yb",
1719 "Yb",
1720 "Yb",
1721 "Yb",
1722 "Lu",
1723 "Lu",
1724 "Hf",
1725 "Hf",
1726 "Hf",
1727 "Hf",
1728 "Hf",
1729 "Hf",
1730 "Ta",
1731 "Ta",
1732 "W",
1733 "W",
1734 "W",
1735 "W",
1736 "W",
1737 "Re",
1738 "Re",
1739 "Os",
1740 "Os",
1741 "Os",
1742 "Os",
1743 "Os",
1744 "Os",
1745 "Os",
1746 "Ir",
1747 "Ir",
1748 "Pt",
1749 "Pt",
1750 "Pt",
1751 "Pt",
1752 "Pt",
1753 "Pt",
1754 "Au",
1755 "Hg",
1756 "Hg",
1757 "Hg",
1758 "Hg",
1759 "Hg",
1760 "Hg",
1761 "Hg",
1762 "Tl",
1763 "Tl",
1764 "Pb",
1765 "Pb",
1766 "Pb",
1767 "Pb",
1768 "Bi",
1769 "U",
1770 "U",
1771 "U",
1772 "Th",
1773 "Pa",
1774 };
1775
1776
1777 const bool elem_table_Radioactive [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
1778 false,
1779 false,
1780 false,
1781 false,
1782 false,
1783 false,
1784 false,
1785 false,
1786 false,
1787 false,
1788 false,
1789 false,
1790 false,
1791 false,
1792 false,
1793 false,
1794 false,
1795 false,
1796 false,
1797 false,
1798 false,
1799 false,
1800 false,
1801 false,
1802 false,
1803 false,
1804 false,
1805 false,
1806 false,
1807 false,
1808 false,
1809 false,
1810 false,
1811 false,
1812 false,
1813 false,
1814 false,
1815 false,
1816 false,
1817 true,
1818 false,
1819 false,
1820 false,
1821 false,
1822 false,
1823 false,
1824 true,
1825 false,
1826 false,
1827 false,
1828 false,
1829 false,
1830 false,
1831 true,
1832 false,
1833 false,
1834 false,
1835 false,
1836 false,
1837 false,
1838 false,
1839 false,
1840 false,
1841 false,
1842 false,
1843 false,
1844 false,
1845 false,
1846 false,
1847 false,
1848 false,
1849 false,
1850 false,
1851 false,
1852 false,
1853 false,
1854 false,
1855 false,
1856 false,
1857 false,
1858 false,
1859 false,
1860 false,
1861 true,
1862 false,
1863 false,
1864 false,
1865 false,
1866 false,
1867 false,
1868 true,
1869 false,
1870 false,
1871 true,
1872 false,
1873 false,
1874 false,
1875 false,
1876 false,
1877 false,
1878 true,
1879 false,
1880 false,
1881 false,
1882 false,
1883 false,
1884 false,
1885 false,
1886 false,
1887 false,
1888 true,
1889 false,
1890 false,
1891 false,
1892 false,
1893 false,
1894 false,
1895 false,
1896 true,
1897 false,
1898 false,
1899 false,
1900 false,
1901 false,
1902 false,
1903 false,
1904 false,
1905 false,
1906 false,
1907 false,
1908 false,
1909 false,
1910 false,
1911 false,
1912 false,
1913 false,
1914 false,
1915 false,
1916 false,
1917 false,
1918 true,
1919 false,
1920 true,
1921 false,
1922 true,
1923 false,
1924 false,
1925 false,
1926 false,
1927 false,
1928 false,
1929 false,
1930 false,
1931 false,
1932 false,
1933 false,
1934 false,
1935 false,
1936 false,
1937 false,
1938 false,
1939 false,
1940 false,
1941 true,
1942 true,
1943 false,
1944 false,
1945 false,
1946 false,
1947 false,
1948 false,
1949 false,
1950 false,
1951 false,
1952 true,
1953 false,
1954 true,
1955 false,
1956 false,
1957 false,
1958 false,
1959 false,
1960 false,
1961 true,
1962 false,
1963 false,
1964 false,
1965 false,
1966 false,
1967 false,
1968 false,
1969 false,
1970 true,
1971 false,
1972 false,
1973 false,
1974 true,
1975 false,
1976 true,
1977 true,
1978 false,
1979 false,
1980 false,
1981 false,
1982 true,
1983 false,
1984 false,
1985 false,
1986 false,
1987 false,
1988 false,
1989 false,
1990 false,
1991 false,
1992 false,
1993 false,
1994 false,
1995 false,
1996 false,
1997 false,
1998 false,
1999 false,
2000 false,
2001 false,
2002 false,
2003 false,
2004 false,
2005 false,
2006 false,
2007 false,
2008 false,
2009 false,
2010 false,
2011 false,
2012 false,
2013 false,
2014 false,
2015 true,
2016 true,
2017 false,
2018 false,
2019 false,
2020 false,
2021 false,
2022 true,
2023 false,
2024 true,
2025 false,
2026 false,
2027 false,
2028 false,
2029 false,
2030 true,
2031 true,
2032 true,
2033 false,
2034 false,
2035 false,
2036 false,
2037 false,
2038 false,
2039 false,
2040 true,
2041 false,
2042 false,
2043 false,
2044 false,
2045 false,
2046 false,
2047 false,
2048 false,
2049 false,
2050 false,
2051 false,
2052 false,
2053 false,
2054 false,
2055 false,
2056 false,
2057 false,
2058 false,
2059 false,
2060 true,
2061 true,
2062 true,
2063 true,
2064 true,
2065 true,
2066 };
2067
2068
2069 const double elem_table_probability [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
2070 0.999884290164307909520857720053754746913909912109375000000000,
2071 0.000115709835692033314582735648023970043141162022948265075684,
2072 0.000001342999991941999914655050951672876635711872950196266174,
2073 0.999998657000008006612290500925155356526374816894531250000000,
2074 0.075933925285977116326208147256693337112665176391601562500000,
2075 0.924066074714022800407065005856566131114959716796875000000000,
2076 1.000000000000000000000000000000000000000000000000000000000000,
2077 0.199480830670926506664741850727295968681573867797851562500000,
2078 0.800519169329073410068531302385963499546051025390625000000000,
2079 0.989211941850466902614869013632414862513542175292968750000000,
2080 0.010788058149533083507343178553128382191061973571777343750000,
2081 0.996358014567941707717579902237048372626304626464843750000000,
2082 0.003641985432058271465738386041266494430601596832275390625000,
2083 0.997567609729561044495937949250219389796257019042968750000000,
2084 0.000380998476006095935803702490218825005285907536745071411133,
2085 0.002051391794432822109073288885383590240962803363800048828125,
2086 1.000000000000000000000000000000000000000000000000000000000000,
2087 0.904766666333356561757739200402284041047096252441406250000000,
2088 0.002709810313278070148523823945652111433446407318115234375000,
2089 0.092523523353365264010328417043638182803988456726074218750000,
2090 1.000000000000000000000000000000000000000000000000000000000000,
2091 0.789876809855211581279377242026384919881820678710937500000000,
2092 0.100001999840012789633192369365133345127105712890625000000000,
2093 0.110121190304775615209642580794024979695677757263183593750000,
2094 1.000000000000000000000000000000000000000000000000000000000000,
2095 0.922220833349999713490774411184247583150863647460937500000000,
2096 0.046858437698747611166449900110819726251065731048583984375000,
2097 0.030920728951252581667707985957349592354148626327514648437500,
2098 1.000000000000000000000000000000000000000000000000000000000000,
2099 0.949850011999040066967836537514813244342803955078125000000000,
2100 0.007519398448124149821059081233443066594190895557403564453125,
2101 0.042520598352131823427502155254842364229261875152587890625000,
2102 0.000109991200703943683199964587160479823069181293249130249023,
2103 0.757594848103037898923162174469325691461563110351562500000000,
2104 0.242405151896962045565686594272847287356853485107421875000000,
2105 0.003336205796380696270847510120916012965608388185501098632812,
2106 0.000629799206452999775149304007015871320618316531181335449219,
2107 0.996033994997166272078459314798237755894660949707031250000000,
2108 0.932580526071084436878777523816097527742385864257812500000000,
2109 0.000117099885242112454345267402722186034225160256028175354004,
2110 0.067302374043673424131029037198459263890981674194335937500000,
2111 0.969400838426726974006442105746828019618988037109375000000000,
2112 0.006472228417153705684605746739634923869743943214416503906250,
2113 0.001350985058105257227353823701321289263432845473289489746094,
2114 0.020860869278785776348428271376178599894046783447265625000000,
2115 0.000042999524425259849917842214228613784143817611038684844971,
2116 0.001872079294802999303859447621789513505063951015472412109375,
2117 1.000000000000000000000000000000000000000000000000000000000000,
2118 0.082520097588289403889305617667559999972581863403320312500000,
2119 0.074411070671519405350657905273692449554800987243652343750000,
2120 0.737141543014838140912559083517407998442649841308593750000000,
2121 0.054113506379234489751528514034362160600721836090087890625000,
2122 0.051813782346118462951434224805780104361474514007568359375000,
2123 0.002503979968160254584302881752932989911641925573348999023438,
2124 0.997496020031839680797247638111002743244171142578125000000000,
2125 0.043450743830478963380947732275672024115920066833496093750000,
2126 0.837881075122238416774678171350387856364250183105468750000000,
2127 0.095010483865806516501351097758742980659008026123046875000000,
2128 0.023657697181476075587447382986283628270030021667480468750000,
2129 1.000000000000000000000000000000000000000000000000000000000000,
2130 0.058452792721208068904559240763774141669273376464843750000000,
2131 0.917532497856775930422656983864726498723030090332031250000000,
2132 0.021190743592002535267138085828264593146741390228271484375000,
2133 0.002823965830013456732028309659199294401332736015319824218750,
2134 1.000000000000000000000000000000000000000000000000000000000000,
2135 0.680769095231327558970235713786678388714790344238281250000000,
2136 0.262230419610671172669924544607056304812431335449218750000000,
2137 0.011399083035777891892426083586542517878115177154541015625000,
2138 0.036346250253448952882706635136855766177177429199218750000000,
2139 0.009255151868774300419340228529563319170847535133361816406250,
2140 0.691494255172344751692037334578344598412513732910156250000000,
2141 0.308505744827655137285660202906001359224319458007812500000000,
2142 0.491645713885820234700929631799226626753807067871093750000000,
2143 0.277325508740183801492662496457342058420181274414062500000000,
2144 0.040405292597461665848879164286699960939586162567138671875000,
2145 0.184515103497573135227227680843498092144727706909179687500000,
2146 0.006108381278961075126765489784474993939511477947235107421875,
2147 0.601079797840404217446064194518839940428733825683593750000000,
2148 0.398920202159595671531633342965506017208099365234375000000000,
2149 0.205705812301332946478993335404084064066410064697265625000000,
2150 0.274503726116209989527305879164487123489379882812500000000000,
2151 0.077504017086240106770844704442424699664115905761718750000000,
2152 0.364982406812098314485837136089685373008251190185546875000000,
2153 0.077304037684118531714716482383664697408676147460937500000000,
2154 1.000000000000000000000000000000000000000000000000000000000000,
2155 0.008938426836876709608015190156038443092256784439086914062500,
2156 0.093712506598838590798905556766840163618326187133789062500000,
2157 0.076302570747548426055573145276866853237152099609375000000000,
2158 0.237686167234566703143627819372341036796569824218750000000000,
2159 0.496053694549759227605534306348999962210655212402343750000000,
2160 0.087306634032410290746639702774700708687305450439453125000000,
2161 0.506898896176611657438115798868238925933837890625000000000000,
2162 0.493101103823388231539581738616107031702995300292968750000000,
2163 0.003552948126957346328819165037771199422422796487808227539062,
2164 0.022860666234272977725971998097520554438233375549316406250000,
2165 0.115931407401451927463575941601447993889451026916503906250000,
2166 0.115000220996773441783922464765055337920784950256347656250000,
2167 0.569863179997571966950431487930472940206527709960937500000000,
2168 0.172791577242972227423933873069472610950469970703125000000000,
2169 0.721691132354705722207199869444593787193298339843750000000000,
2170 0.278308867645294166770497668039752170443534851074218750000000,
2171 0.005609775608975640752429381308274969342164695262908935546875,
2172 0.098606055757769678349333730693615507334470748901367187500000,
2173 0.070007199712011511372189431767765199765563011169433593750000,
2174 0.825776968921243081922511919401586055755615234375000000000000,
2175 1.000000000000000000000000000000000000000000000000000000000000,
2176 0.514422711621750239352479638910153880715370178222656250000000,
2177 0.112234410554393593262290096390643157064914703369140625000000,
2178 0.171550886397901253266340404479706194251775741577148437500000,
2179 0.173788376250214926521664438041625544428825378417968750000000,
2180 0.028003615175739928616627238966430013533681631088256835937500,
2181 1.000000000000000000000000000000000000000000000000000000000000,
2182 0.145308494342837241086741073559096548706293106079101562500000,
2183 0.091496458524138415957516201615362660959362983703613281250000,
2184 0.158387558641321063435114524509117472916841506958007812500000,
2185 0.166690329831184980147185115129104815423488616943359375000000,
2186 0.095999792030779435014764544575882609933614730834960937500000,
2187 0.243900902666405350327494261364336125552654266357421875000000,
2188 0.098216463963333416886669624545902479439973831176757812500000,
2189 0.055402974808013198682044020415560225956141948699951171875000,
2190 0.018726273471579152340993346115283202379941940307617187500000,
2191 0.127588609866636532030881312493875157088041305541992187500000,
2192 0.126054915071900669465421174209041055291891098022460937500000,
2193 0.170586053375378299268305681835045106709003448486328125000000,
2194 0.315451225206183960558803391904802992939949035644531250000000,
2195 0.186189948200308125203505937861336860805749893188476562500000,
2196 1.000000000000000000000000000000000000000000000000000000000000,
2197 0.010207550187954890497099569302008603699505329132080078125000,
2198 0.111463248820283120088525663504697149619460105895996093750000,
2199 0.223336399264176588275176982278935611248016357421875000000000,
2200 0.273264416540030363744762098576757125556468963623046875000000,
2201 0.264546508837878890929573572066146880388259887695312500000000,
2202 0.117181876349676070137029171291942475363612174987792968750000,
2203 0.518389668985958174118877650471404194831848144531250000000000,
2204 0.481610331014041714858819887012941762804985046386718750000000,
2205 0.012567197514954164816458614950533956289291381835937500000000,
2206 0.008928009053980960965657409644791187020018696784973144531250,
2207 0.124890149496662231087817929164884844794869422912597656250000,
2208 0.127983459688489453753845737082883715629577636718750000000000,
2209 0.241267197414976458658131264201074372977018356323242187500000,
2210 0.122184752800125570604272695618419675156474113464355468750000,
2211 0.287277937020044504823346187549759633839130401611328125000000,
2212 0.074901297010766587636254598692175932228565216064453125000000,
2213 0.042954845418549769675564675708301365375518798828125000000000,
2214 0.957045154581450119302132861776044592261314392089843750000000,
2215 0.009707379007667929146641050408561568474397063255310058593750,
2216 0.006608215781738930282018795736576066701672971248626708984375,
2217 0.003409079548521898664348306340343697229400277137756347656250,
2218 0.145370749897527656857576516813423950225114822387695312500000,
2219 0.076859248003039171148742525474517606198787689208984375000000,
2220 0.242144620952342848330118840749491937458515167236328125000000,
2221 0.085916802463334898676272644024720648303627967834472656250000,
2222 0.325722055045137792728127124064485542476177215576171875000000,
2223 0.046317494276545329023875297025369945913553237915039062500000,
2224 0.057944355024143474885978122301821713335812091827392578125000,
2225 0.572091349038115315472907695948379114270210266113281250000000,
2226 0.427908650961884573504789841535966843366622924804687500000000,
2227 0.000909764371027903685079651907585684966761618852615356445312,
2228 0.025505394102927340937991829150632838718593120574951171875000,
2229 0.008927687728878220055350745099076448241248726844787597656250,
2230 0.047401722953754971134898710261040832847356796264648437500000,
2231 0.070696689557404629455916733604681212455034255981445312500000,
2232 0.188376210561464557668998054396070074290037155151367187500000,
2233 0.317407791382032011817670991149498149752616882324218750000000,
2234 0.340774739342510235573513455165084451436996459960937500000000,
2235 1.000000000000000000000000000000000000000000000000000000000000,
2236 0.000952296533640617525774685336870106766582466661930084228516,
2237 0.000890196759683794711613680217254795934422872960567474365234,
2238 0.019102830465697103606848017420816177036613225936889648437500,
2239 0.264005869018636762923790683998959138989448547363281250000000,
2240 0.040709981815666186621971434078659513033926486968994140625000,
2241 0.212323527142361190289676642350968904793262481689453125000000,
2242 0.269085350529324029977829013660084456205368041992187500000000,
2243 0.104356830141138279266499466757522895932197570800781250000000,
2244 0.088573117593851946605099101361702196300029754638671875000000,
2245 1.000000000000000000000000000000000000000000000000000000000000,
2246 0.001060985146207953045902061539607075246749445796012878417969,
2247 0.001010985846198153050023993415607037604786455631256103515625,
2248 0.024171461599537605313692267827718751505017280578613281250000,
2249 0.065920277116120362670415033790050074458122253417968750000000,
2250 0.078541300421794094099858796198532218113541603088378906250000,
2251 0.112320827508414877726750091824214905500411987304687500000000,
2252 0.716974162361726841119491382414707913994789123535156250000000,
2253 0.000888171872103250392010975744483403104823082685470581054688,
2254 0.999111828127896672846475212281802669167518615722656250000000,
2255 0.001851973331584025024912354417949700291501358151435852050781,
2256 0.002511963827720880421123794690174690913408994674682617187500,
2257 0.884492463308528265031327464384958148002624511718750000000000,
2258 0.111143599532166723053983048430382041260600090026855468750000,
2259 1.000000000000000000000000000000000000000000000000000000000000,
2260 0.271519166958828106483991859931848011910915374755859375000000,
2261 0.121740433020292235233306143982190405949950218200683593750000,
2262 0.237977663997580829446931716120161581784486770629882812500000,
2263 0.082929723850915446070608538775559281930327415466308593750000,
2264 0.171890140355501652713599014532519504427909851074218750000000,
2265 0.057561075412857647115583148433870519511401653289794921875000,
2266 0.056381796404024006608146635244338540360331535339355468750000,
2267 0.030772522277086666181444840617587033193558454513549804687500,
2268 0.149881578776357327065227309503825381398200988769531250000000,
2269 0.112382691006085513873991033051424892619252204895019531250000,
2270 0.138246406123312015612469849656918086111545562744140625000000,
2271 0.073792068527347848272412988990254234522581100463867187500000,
2272 0.267451009404714612482933944193064235150814056396484375000000,
2273 0.227473723885095902019770619517657905817031860351562500000000,
2274 0.478103065570820051632949798658955842256546020507812500000000,
2275 0.521896934429179837344747738825390115380287170410156250000000,
2276 0.002009636255837693018938550082452820788603276014328002929688,
2277 0.021826049485043207132317633067941642366349697113037109375000,
2278 0.147985214676143617129611129712429828941822052001953125000000,
2279 0.204672954195290635048820604424690827727317810058593750000000,
2280 0.156491675006823760529783839956508018076419830322265625000000,
2281 0.248435033258980114689862261911912355571985244750976562500000,
2282 0.218579437121880937322515592313720844686031341552734375000000,
2283 1.000000000000000000000000000000000000000000000000000000000000,
2284 0.000562985756460361477619691594753703611786477267742156982422,
2285 0.000952975889709990254573812595850768047966994345188140869141,
2286 0.023291210732368467645203580218549177516251802444458007812500,
2287 0.188889421097646226233024435714469291269779205322265625000000,
2288 0.254747154896981076177553404704667627811431884765625000000000,
2289 0.248957901365095435330943018925609067082405090332031250000000,
2290 0.282598350261738351374418698469526134431362152099609375000000,
2291 1.000000000000000000000000000000000000000000000000000000000000,
2292 0.001395973476503946332158423437874716910300776362419128417969,
2293 0.016012695758780580435054474719436257146298885345458984375000,
2294 0.335027234482544788995994622382568195462226867675781250000000,
2295 0.228686654953555862368475004586798604577779769897460937500000,
2296 0.269776674243189351631855288360384292900562286376953125000000,
2297 0.149100767085425356395234075534972362220287322998046875000000,
2298 1.000000000000000000000000000000000000000000000000000000000000,
2299 0.001232929969577727796758992440118163358420133590698242187500,
2300 0.029822206098693591902470956256365752778947353363037109375000,
2301 0.140905996539396560773838018576498143374919891357421875000000,
2302 0.216800685721051017429417129278590437024831771850585937500000,
2303 0.161027253651992552363481081556528806686401367187500000000000,
2304 0.320249909805123023076589561242144554853439331054687500000000,
2305 0.129961018214165419104588750087714288383722305297851562500000,
2306 0.974008767577204226384424146090168505907058715820312500000000,
2307 0.025991232422795697287742910930319339968264102935791015625000,
2308 0.001609652315099938373749166586890169128309935331344604492188,
2309 0.052668623577307296934613134453684324398636817932128906250000,
2310 0.185969830516608397585898160286888014525175094604492187500000,
2311 0.272821070648739838482299546740250661969184875488281250000000,
2312 0.136190582834107815068946933934057597070932388305664062500000,
2313 0.350740240108136591690168870627530850470066070556640625000000,
2314 0.000120131992311552486551486096377772128107608295977115631104,
2315 0.999879868007688354936135510797612369060516357421875000000000,
2316 0.001209872963338849303702171589236513682408258318901062011719,
2317 0.264988176241494621798722164385253563523292541503906250000000,
2318 0.143124971877952811283307710255030542612075805664062500000000,
2319 0.306387829277925793913794905165559612214565277099609375000000,
2320 0.284289149639287863635672692907974123954772949218750000000000,
2321 0.374005039798408045470523575204424560070037841796875000000000,
2322 0.625994960201591843507173962279921397566795349121093750000000,
2323 0.000209947723016968765524098428087995671376120299100875854492,
2324 0.015926034417430057904541129687459033448249101638793945312500,
2325 0.019615115836156795520173190539026109036058187484741210937500,
2326 0.132457018202467580181291850749403238296508789062500000000000,
2327 0.161519781574387955025429164379602298140525817871093750000000,
2328 0.262554623898649197588639481182326562702655792236328125000000,
2329 0.407717478347891348899878494194126687943935394287109375000000,
2330 0.373050779688124722888176165724871680140495300292968750000000,
2331 0.626949220311875166089521371759474277496337890625000000000000,
2332 0.000121987349911814132899338936066868654961581341922283172607,
2333 0.007821588901230941415221309398475568741559982299804687500000,
2334 0.328605923565726210089366077227168716490268707275390625000000,
2335 0.337788971283677852408544595164130441844463348388671875000000,
2336 0.252107856415289710572125159160350449383258819580078125000000,
2337 0.073553672484163390432598816914833150804042816162109375000000,
2338 1.000000000000000000000000000000000000000000000000000000000000,
2339 0.001509815802472098391837085351596670079743489623069763183594,
2340 0.099707835644051417967048678292485419660806655883789062500000,
2341 0.168701418426951910145561441822792403399944305419921875000000,
2342 0.230990819120067331082779560347262304276227951049804687500000,
2343 0.131793921141620695713925215386552736163139343261718750000000,
2344 0.298589572072207154462830658303573727607727050781250000000000,
2345 0.068706617792629293139938795320631470531225204467773437500000,
2346 0.295204095918081610427918803907232359051704406738281250000000,
2347 0.704795904081918278549778733577113598585128784179687500000000,
2348 0.014094362255097959285565778486670751590281724929809570312500,
2349 0.241003598560575765796798464180028531700372695922851562500000,
2350 0.221011595361855245345239495691203046590089797973632812500000,
2351 0.523890443822470963652904174523428082466125488281250000000000,
2352 1.000000000000000000000000000000000000000000000000000000000000,
2353 0.000054599923560107009460132254652364736102754250168800354004,
2354 0.007204689913434121108226637630878030904568731784820556640625,
2355 0.992740710163005690702675565262325108051300048828125000000000,
2356 1.000000000000000000000000000000000000000000000000000000000000,
2357 1.000000000000000000000000000000000000000000000000000000000000,
2358 };
2359
2360
2361 const double elem_table_log_probability [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
2362 -0.000115716530591520062594239337538937206772970966994762420654,
2363 -9.064424917075021070900220365729182958602905273437500000000000,
2364 -13.520604646423175054792409355286508798599243164062500000000000,
2365 -0.000001343000893767296712052561162564767727189973811618983746,
2366 -2.577891720978651601825504258158616721630096435546875000000000,
2367 -0.078971700466369670889932308455172460526227951049804687500000,
2368 0.000000000000000000000000000000000000000000000000000000000000,
2369 -1.612037134131381055368592569720931351184844970703125000000000,
2370 -0.222494800137427506392384657374350354075431823730468750000000,
2371 -0.010846671177187771836769591971005866071209311485290527343750,
2372 -4.529315483514038120915756735485047101974487304687500000000000,
2373 -0.003648633607616148452623683340334537206217646598815917968750,
2374 -5.615226297668721500144783931318670511245727539062500000000000,
2375 -0.002435353337518350851781390176142849668394774198532104492188,
2376 -7.872715182829573166145564755424857139587402343750000000000000,
2377 -6.189236792082963845018639403861016035079956054687500000000000,
2378 0.000000000000000000000000000000000000000000000000000000000000,
2379 -0.100078195781331494296217954342864686623215675354003906250000,
2380 -5.910876641640641970809610938886180520057678222656250000000000,
2381 -2.380292360271312634978357891668565571308135986328125000000000,
2382 0.000000000000000000000000000000000000000000000000000000000000,
2383 -0.235878282572628383828572395941591821610927581787109375000000,
2384 -2.302565094793883382351395994191989302635192871093750000000000,
2385 -2.206173789605455404227996041299775242805480957031250000000000,
2386 0.000000000000000000000000000000000000000000000000000000000000,
2387 -0.080970568540825488268453113960276823490858078002929687500000,
2388 -3.060624186220378017964094397029839456081390380859375000000000,
2389 -3.476328480144544208485513081541284918785095214843750000000000,
2390 0.000000000000000000000000000000000000000000000000000000000000,
2391 -0.051451188958515865767839869704403099603950977325439453125000,
2392 -4.890269137820559386398144852137193083763122558593750000000000,
2393 -3.157766653355948971437783256988041102886199951171875000000000,
2394 -9.115110188972028737453001667745411396026611328125000000000000,
2395 -0.277606537419771426389303314863354898989200592041015625000000,
2396 -1.417144771312495832304989562544506043195724487304687500000000,
2397 -5.702921106825801444983881083317101001739501953125000000000000,
2398 -7.370109509296556282720302988309413194656372070312500000000000,
2399 -0.003973890456746663815690290277871099533513188362121582031250,
2400 -0.069799776156532433724066777358530089259147644042968750000000,
2401 -9.052483267360123875278077321127057075500488281250000000000000,
2402 -2.698559767416127019856730839819647371768951416015625000000000,
2403 -0.031077090678799931117159971449837030377238988876342773437500,
2404 -5.040234806716209270405215647770091891288757324218750000000000,
2405 -6.606921279942914004834619845496490597724914550781250000000000,
2406 -3.869880158236262079896050636307336390018463134765625000000000,
2407 -10.054321502209552008366699737962335348129272460937500000000000,
2408 -6.280705543488890540970714937429875135421752929687500000000000,
2409 0.000000000000000000000000000000000000000000000000000000000000,
2410 -2.494713408178120150893164463923312723636627197265625000000000,
2411 -2.598150548864236686341655513388104736804962158203125000000000,
2412 -0.304975352295239643396485007542651146650314331054687500000000,
2413 -2.916671468480125817279713373864069581031799316406250000000000,
2414 -2.960099096648749483762230738648213446140289306640625000000000,
2415 -5.989873825712285437816717603709548711776733398437500000000000,
2416 -0.002507120169096173530054461053850900498218834400177001953125,
2417 -3.136127308188753737283605005359277129173278808593750000000000,
2418 -0.176879103699552453488053060937090776860713958740234375000000,
2419 -2.353768036988251211028000398073345422744750976562500000000000,
2420 -3.744066754776672834026385316974483430385589599609375000000000,
2421 0.000000000000000000000000000000000000000000000000000000000000,
2422 -2.839535812544084603104010966490022838115692138671875000000000,
2423 -0.086067279673300162157190129619266372174024581909179687500000,
2424 -3.854190815670504033363386042765341699123382568359375000000000,
2425 -5.869613059277937416879922238877043128013610839843750000000000,
2426 0.000000000000000000000000000000000000000000000000000000000000,
2427 -0.384532097536943340276849312431295402348041534423828125000000,
2428 -1.338531697560186861650777245813515037298202514648437500000000,
2429 -4.474222362274872466514352709054946899414062500000000000000000,
2430 -3.314664237037550087450199498562142252922058105468750000000000,
2431 -4.682574923715371539856278104707598686218261718750000000000000,
2432 -0.368900435688631012087768112905905582010746002197265625000000,
2433 -1.176014814002444008878001113771460950374603271484375000000000,
2434 -0.709996915609857004447746930964058265089988708496093750000000,
2435 -1.282563340904273152531800405995454639196395874023437500000000,
2436 -3.208794497707758708315850526560097932815551757812500000000000,
2437 -1.690023957076583371872402494773268699645996093750000000000000,
2438 -5.098093470692335316130083811003714799880981445312500000000000,
2439 -0.509027578151938331352255318051902577280998229980468750000000,
2440 -0.918993876681337473755206701753195375204086303710937500000000,
2441 -1.581308226517597503857359697576612234115600585937500000000000,
2442 -1.292790443930836863373201595095451921224594116210937500000000,
2443 -2.557425510595298323579527277615852653980255126953125000000000,
2444 -1.007906127076126923114429700945038348436355590820312500000000,
2445 -2.560009090805706488680471011321060359477996826171875000000000,
2446 0.000000000000000000000000000000000000000000000000000000000000,
2447 -4.717395674310531639150667615467682480812072753906250000000000,
2448 -2.367523623737181281967423274181783199310302734375000000000000,
2449 -2.573048648630889889687978211441077291965484619140625000000000,
2450 -1.436804100526558380934716296906117349863052368164062500000000,
2451 -0.701071102975730831019518518587574362754821777343750000000000,
2452 -2.438328827816317101451204507611691951751708984375000000000000,
2453 -0.679443711102156733261381305055692791938781738281250000000000,
2454 -0.707041047215952844773312335746595636010169982910156250000000,
2455 -5.639977561836668762396129750413820147514343261718750000000000,
2456 -3.778337476933724126126890041632577776908874511718750000000000,
2457 -2.154756578276459499932116159470751881599426269531250000000000,
2458 -2.162821228909660220551813836209475994110107421875000000000000,
2459 -0.562358982058553724669991424889303743839263916015625000000000,
2460 -1.755669166607024767046141278115101158618927001953125000000000,
2461 -0.326158026142060741836559145667706616222858428955078125000000,
2462 -1.279023747338471794776637580071110278367996215820312500000000,
2463 -5.183244558647554178776317712618038058280944824218750000000000,
2464 -2.316622601837921013867571673472411930561065673828125000000000,
2465 -2.659157189193052328590738397906534373760223388671875000000000,
2466 -0.191430555333882340685036638205929193645715713500976562500000,
2467 0.000000000000000000000000000000000000000000000000000000000000,
2468 -0.664709955358130821778672725486103445291519165039062500000000,
2469 -2.187165643480033949686003325041383504867553710937500000000000,
2470 -1.762875342696557545707491954090073704719543457031250000000000,
2471 -1.749916948420700224531287858553696423768997192382812500000000,
2472 -3.575421663722070153568211026140488684177398681640625000000000,
2473 0.000000000000000000000000000000000000000000000000000000000000,
2474 -1.928896249393138528915869756019674241542816162109375000000000,
2475 -2.391455012103930855005273770075291395187377929687500000000000,
2476 -1.842710346617601580021528206998482346534729003906250000000000,
2477 -1.791617500319007794118419951701071113348007202148437500000000,
2478 -2.343409253862695162951013116980902850627899169921875000000000,
2479 -1.410993272797839370724659602274186909198760986328125000000000,
2480 -2.320581420206905942649200369487516582012176513671875000000000,
2481 -2.893121989774980473697496563545428216457366943359375000000000,
2482 -3.977827742728266446903262476553209125995635986328125000000000,
2483 -2.058944176423800787034679160569794476032257080078125000000000,
2484 -2.071037633074694905843671222100965678691864013671875000000000,
2485 -1.768515397703714908672623096208553761243820190429687500000000,
2486 -1.153751204177984268639534093381371349096298217773437500000000,
2487 -1.680987899482990099997437027923297137022018432617187500000000,
2488 0.000000000000000000000000000000000000000000000000000000000000,
2489 -4.584627618010170380102863418869674205780029296875000000000000,
2490 -2.194060349407264354226754221599549055099487304687500000000000,
2491 -1.499076127310911887846600620832759886980056762695312500000000,
2492 -1.297315393792867643796284937707241624593734741210937500000000,
2493 -1.329738206325086657955125701846554875373840332031250000000000,
2494 -2.144028052451655508292560625704936683177947998046875000000000,
2495 -0.657028062796280343249577526876237243413925170898437500000000,
2496 -0.730619933776488150733996462804498150944709777832031250000000,
2497 -4.376665231519177190477876138174906373023986816406250000000000,
2498 -4.718561859232925925766721775289624929428100585937500000000000,
2499 -2.080320732081178736194715384044684469699859619140625000000000,
2500 -2.055854244595972435405428768717683851718902587890625000000000,
2501 -1.421850256682005708697147383645642548799514770507812500000000,
2502 -2.102221012532442756537420791573822498321533203125000000000000,
2503 -1.247305110167633124262920318869873881340026855468750000000000,
2504 -2.591584072043251474326552852289751172065734863281250000000000,
2505 -3.147605821582104113076638896018266677856445312500000000000000,
2506 -0.043904705171597842305875047941299271769821643829345703125000,
2507 -4.634868960235463575259018398355692625045776367187500000000000,
2508 -5.019441588675102039474040793720632791519165039062500000000000,
2509 -5.681312951243271847090454684803262352943420410156250000000000,
2510 -1.928467904013302591792466955666895955801010131835937500000000,
2511 -2.565779477876660052970692049711942672729492187500000000000000,
2512 -1.418220124080461719273671405971981585025787353515625000000000,
2513 -2.454375864191848055639866288402117788791656494140625000000000,
2514 -1.121710853164690879779641363711562007665634155273437500000000,
2515 -3.072235543110140021383358543971553444862365722656250000000000,
2516 -2.848272125086215300626690805074758827686309814453125000000000,
2517 -0.558456599237618478426270485215354710817337036132812500000000,
2518 -0.848845538512307262735134827380534261465072631835937500000000,
2519 -7.002324924918669424300787795800715684890747070312500000000000,
2520 -3.668865315739671117967191094066947698593139648437500000000000,
2521 -4.718597850559019590832576795946806669235229492187500000000000,
2522 -3.049096701706386802754877862753346562385559082031250000000000,
2523 -2.649356530974964485380951373372226953506469726562500000000000,
2524 -1.669314195717893856141245123581029474735260009765625000000000,
2525 -1.147567923673684653351756423944607377052307128906250000000000,
2526 -1.076533608421685217493291020218748599290847778320312500000000,
2527 0.000000000000000000000000000000000000000000000000000000000000,
2528 -6.956634086757649271248737932182848453521728515625000000000000,
2529 -7.024068041375896243039278488140553236007690429687500000000000,
2530 -3.957918762987576943856993239023722708225250244140625000000000,
2531 -1.331783944951729026229259034153074026107788085937500000000000,
2532 -3.201281963147128539759478371706791222095489501953125000000000,
2533 -1.549644096147559713116947932576294988393783569335937500000000,
2534 -1.312726661492457758129148714942857623100280761718750000000000,
2535 -2.259939193445343441624117986066266894340515136718750000000000,
2536 -2.423926880572130126978436237550340592861175537109375000000000,
2537 0.000000000000000000000000000000000000000000000000000000000000,
2538 -6.848557419252292000066972832428291440010070800781250000000000,
2539 -6.896829338845804180380127945682033896446228027343750000000000,
2540 -3.722582614455130833874818563344888389110565185546875000000000,
2541 -2.719309189565115580933252203976735472679138183593750000000000,
2542 -2.544130672523534641982223547529429197311401367187500000000000,
2543 -2.186395971313551900294669394497759640216827392578125000000000,
2544 -0.332715474789523235621402363904053345322608947753906250000000,
2545 -7.026345284034602123313106858404353260993957519531250000000000,
2546 -0.000888566530440708531556059934786162557429634034633636474609,
2547 -6.291503542654471203832144965417683124542236328125000000000000,
2548 -5.986690430272505913933400734094902873039245605468750000000000,
2549 -0.122741286268200244791160002932883799076080322265625000000000,
2550 -2.196932224286036738902794240857474505901336669921875000000000,
2551 0.000000000000000000000000000000000000000000000000000000000000,
2552 -1.303722545566528001614869936020113527774810791015625000000000,
2553 -2.105864098995690714133388610207475721836090087890625000000000,
2554 -1.435578458464392248572494281688705086708068847656250000000000,
2555 -2.489761730430327446583760320208966732025146484375000000000000,
2556 -1.760899725099839052688821539049968123435974121093750000000000,
2557 -2.854908713800850428299327177228406071662902832031250000000000,
2558 -2.875608931369854293080834395368583500385284423828125000000000,
2559 -3.481133121051686263314195457496680319309234619140625000000000,
2560 -1.897909771509530774125096286297775804996490478515625000000000,
2561 -2.185845347988713882614320027641952037811279296875000000000000,
2562 -1.978717634408995396100294783536810427904129028320312500000000,
2563 -2.606504025680458358493751802598126232624053955078125000000000,
2564 -1.318818871830977013104302386636845767498016357421875000000000,
2565 -1.480720546667873893653677441761828958988189697265625000000000,
2566 -0.737928951383980402667361886415164917707443237304687500000000,
2567 -0.650285154216317162756411107693566009402275085449218750000000,
2568 -6.209801540532629005042508651968091726303100585937500000000000,
2569 -3.824651092041761124562526674708351492881774902343750000000000,
2570 -1.910642911045310476936265331460162997245788574218750000000000,
2571 -1.586341919151083468264573639316949993371963500976562500000000,
2572 -1.854752465261401805918239915627054870128631591796875000000000,
2573 -1.392573903203236485026650370855350047349929809570312500000000,
2574 -1.520605773895307155640921337180770933628082275390625000000000,
2575 0.000000000000000000000000000000000000000000000000000000000000,
2576 -7.482256229504544720043668348807841539382934570312500000000000,
2577 -6.955920953990032629121742502320557832717895507812500000000000,
2578 -3.759679211363279094371137034613639116287231445312500000000000,
2579 -1.666593508702244319508167791354935616254806518554687500000000,
2580 -1.367483775157640080166743246081750839948654174804687500000000,
2581 -1.390471467634422086945278351777233183383941650390625000000000,
2582 -1.263728646463758931162146836868487298488616943359375000000000,
2583 0.000000000000000000000000000000000000000000000000000000000000,
2584 -6.574163274461459316455602674977853894233703613281250000000000,
2585 -4.134373386461300370342542009893804788589477539062500000000000,
2586 -1.093543453498669215662175702163949608802795410156250000000000,
2587 -1.475402531411262208038692733680363744497299194335937500000000,
2588 -1.310160794679168905219057705835439264774322509765625000000000,
2589 -1.903132912453214142800561603507958352565765380859375000000000,
2590 0.000000000000000000000000000000000000000000000000000000000000,
2591 -6.698361853186871606169461301760748028755187988281250000000000,
2592 -3.512501991875810691823289744206704199314117431640625000000000,
2593 -1.959662302151332857746979243529494851827621459960937500000000,
2594 -1.528776846501670894085123109107371419668197631835937500000000,
2595 -1.826181650981897996999236966075841337442398071289062500000000,
2596 -1.138653619844293141127877788676414638757705688476562500000000,
2597 -2.040520733384556528733355662552639842033386230468750000000000,
2598 -0.026334973760810023724054929061821894720196723937988281250000,
2599 -3.649996012338110329409346377360634505748748779296875000000000,
2600 -6.431737076661124596910212858347222208976745605468750000000000,
2601 -2.943735378782415867959798561059869825839996337890625000000000,
2602 -1.682170819948636486529380817955825477838516235351562500000000,
2603 -1.298939117547105670524842935265041887760162353515625000000000,
2604 -1.993700029844323484695678416755981743335723876953125000000000,
2605 -1.047709386165366352017258577689062803983688354492187500000000,
2606 -9.026919483738925720217594061978161334991455078125000000000000,
2607 -0.000120139208737295727770326425609681564310449175536632537842,
2608 -6.717239913861373423742406885139644145965576171875000000000000,
2609 -1.328070071947949681856471215724013745784759521484375000000000,
2610 -1.944037101159571623298916165367700159549713134765625000000000,
2611 -1.182903563582415440436079734354279935359954833984375000000000,
2612 -1.257763426233626136152565777592826634645462036132812500000000,
2613 -0.983486006261584555510069094452774152159690856933593750000000,
2614 -0.468412958710625382252601411892101168632507324218750000000000,
2615 -8.468651996251450597696930344682186841964721679687500000000000,
2616 -4.139800124064825226355424092616885900497436523437500000000000,
2617 -3.931454793849565199082007893593981862068176269531250000000000,
2618 -2.021497077106750417385683249449357390403747558593750000000000,
2619 -1.823127657291570224984411652258131653070449829101562500000000,
2620 -1.337296127555923419549799291417002677917480468750000000000000,
2621 -0.897180799465370992784585268964292481541633605957031250000000,
2622 -0.986040730030275258677363581227837130427360534667968750000000,
2623 -0.466889729967265909582607719130464829504489898681640625000000,
2624 -9.011593207854545539703394751995801925659179687500000000000000,
2625 -4.850867560763419739089385984698310494422912597656250000000000,
2626 -1.112896046865470500719652591214980930089950561523437500000000,
2627 -1.085333923798379451852724741911515593528747558593750000000000,
2628 -1.377898281389317913792069703049492090940475463867187500000000,
2629 -2.609739901377524873282709449995309114456176757812500000000000,
2630 0.000000000000000000000000000000000000000000000000000000000000,
2631 -6.495767620713909451524159521795809268951416015625000000000000,
2632 -2.305511012885385291326656442834064364433288574218750000000000,
2633 -1.779624881481258524829058842442464083433151245117187500000000,
2634 -1.465377313319132568381064629647880792617797851562500000000000,
2635 -2.026515779816368212351562760886736214160919189453125000000000,
2636 -1.208685317218918919834891312348190695047378540039062500000000,
2637 -2.677909755533927516069070406956598162651062011718750000000000,
2638 -1.220088311290825400234894004825036972761154174804687500000000,
2639 -0.349847015838577246604756965098204091191291809082031250000000,
2640 -4.261980401619341662922124669421464204788208007812500000000000,
2641 -1.422943413816338820154783206817228347063064575195312500000000,
2642 -1.509540111140063478600836788245942443609237670898437500000000,
2643 -0.646472693195343506289418655796907842159271240234375000000000,
2644 0.000000000000000000000000000000000000000000000000000000000000,
2645 -9.815478075212435982166425674222409725189208984375000000000000,
2646 -4.933023088148108747930109529988840222358703613281250000000000,
2647 -0.007285766694735069763655399555091207730583846569061279296875,
2648 0.000000000000000000000000000000000000000000000000000000000000,
2649 0.000000000000000000000000000000000000000000000000000000000000,
2650 };
2651
2652 #ifdef __cplusplus
2653 }
2654 #endif
2655
2656 } // namespace IsoSpec
2657
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 namespace IsoSpec
19 {
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25
26 #define ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES 288
27
28 extern const int elem_table_atomicNo[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
29 extern const double elem_table_probability[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
30 extern const double elem_table_mass[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
31 extern const int elem_table_massNo[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
32 extern const int elem_table_extraNeutrons[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
33 extern const char* elem_table_element[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
34 extern const char* elem_table_symbol[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
35 extern const bool elem_table_Radioactive[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
36 extern const double elem_table_log_probability[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
37
38
39 #ifdef __cplusplus
40 }
41 #endif
42
43 } // namespace IsoSpec
44
0 /*
1 * This file has been released into public domain by John D. Cook
2 * and is used here with some slight modifications (which are hereby
3 * also released into public domain),
4 *
5 * This file is part of IsoSpec.
6 */
7
8 #include <cmath>
9 #include <cstdlib>
10 #include "isoMath.h"
11 #include "platform.h"
12
13 namespace IsoSpec
14 {
15
16 const double pi = 3.14159265358979323846264338328;
17
18 void release_g_lfact_table()
19 {
20 #if ISOSPEC_GOT_MMAN
21 munmap(g_lfact_table, ISOSPEC_G_FACT_TABLE_SIZE*sizeof(double));
22 #else
23 free(g_lfact_table);
24 #endif
25 }
26
27 double* alloc_lfact_table()
28 {
29 double* ret;
30 # if ISOSPEC_GOT_MMAN
31 ret = reinterpret_cast<double*>(mmap(nullptr, sizeof(double)*ISOSPEC_G_FACT_TABLE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
32 #else
33 ret = reinterpret_cast<double*>(calloc(ISOSPEC_G_FACT_TABLE_SIZE, sizeof(double)));
34 #endif
35 std::atexit(release_g_lfact_table);
36 return ret;
37 }
38
39 double* g_lfact_table = alloc_lfact_table();
40
41
42 double RationalApproximation(double t)
43 {
44 // Abramowitz and Stegun formula 26.2.23.
45 // The absolute value of the error should be less than 4.5 e-4.
46 double c[] = {2.515517, 0.802853, 0.010328};
47 double d[] = {1.432788, 0.189269, 0.001308};
48 return t - ((c[2]*t + c[1])*t + c[0]) /
49 (((d[2]*t + d[1])*t + d[0])*t + 1.0);
50 }
51
52 double NormalCDFInverse(double p)
53 {
54
55 if (p < 0.5)
56 return -RationalApproximation( sqrt(-2.0*log(p)) );
57 else
58 return RationalApproximation( sqrt(-2.0*log(1-p)) );
59 }
60
61 double NormalCDFInverse(double p, double mean, double stdev)
62 {
63 return mean + stdev * NormalCDFInverse(p);
64 }
65
66 double NormalCDF(double x, double mean, double stdev)
67 {
68 x = (x-mean)/stdev * 0.7071067811865476;
69
70 // constants
71 double a1 = 0.254829592;
72 double a2 = -0.284496736;
73 double a3 = 1.421413741;
74 double a4 = -1.453152027;
75 double a5 = 1.061405429;
76 double p = 0.3275911;
77
78 // Save the sign of x
79 int sign = 1;
80 if (x < 0)
81 sign = -1;
82 x = fabs(x);
83
84 // A&S formula 7.1.26
85 double t = 1.0/(1.0 + p*x);
86 double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x);
87
88 return 0.5*(1.0 + sign*y);
89 }
90
91 double NormalPDF(double x, double mean, double stdev)
92 {
93 double two_variance = stdev * stdev * 2.0;
94 double delta = x-mean;
95 return exp( -delta*delta / two_variance ) / sqrt( two_variance * pi );
96 }
97
98 } // namespace IsoSpec
99
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <cmath>
19 #include <fenv.h>
20
21 #if !defined(ISOSPEC_G_FACT_TABLE_SIZE)
22 // 10M should be enough for anyone, right?
23 // Actually, yes. If anyone tries to input a molecule that has more than 10M atoms,
24 // he deserves to get an exception thrown in his face.
25 #define ISOSPEC_G_FACT_TABLE_SIZE 1024*1024*10
26 #endif
27
28 namespace IsoSpec
29 {
30
31 extern double* g_lfact_table;
32
33 static inline double minuslogFactorial(int n)
34 {
35 if (n < 2)
36 return 0.0;
37 if (g_lfact_table[n] == 0.0)
38 g_lfact_table[n] = -lgamma(n+1);
39
40 return g_lfact_table[n];
41 }
42 double NormalCDFInverse(double p);
43 double NormalCDFInverse(double p, double mean, double stdev);
44 double NormalCDF(double x, double mean, double stdev);
45 double NormalPDF(double x, double mean = 0.0, double stdev = 1.0);
46
47 } // namespace IsoSpec
48
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16
17 #include <cmath>
18 #include <algorithm>
19 #include <vector>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <tuple>
23 #include <unordered_map>
24 #include <queue>
25 #include <utility>
26 #include <iostream>
27 #include <iomanip>
28 #include <cctype>
29 #include <stdexcept>
30 #include <string>
31 #include <limits>
32 #include <assert.h>
33 #include <ctype.h>
34 #include "platform.h"
35 #include "conf.h"
36 #include "dirtyAllocator.h"
37 #include "operators.h"
38 #include "summator.h"
39 #include "marginalTrek++.h"
40 #include "isoSpec++.h"
41 #include "misc.h"
42 #include "element_tables.h"
43
44
45 using namespace std;
46
47 namespace IsoSpec
48 {
49
50 Iso::Iso(
51 int _dimNumber,
52 const int* _isotopeNumbers,
53 const int* _atomCounts,
54 const double* const * _isotopeMasses,
55 const double* const * _isotopeProbabilities
56 ) :
57 disowned(false),
58 dimNumber(_dimNumber),
59 isotopeNumbers(array_copy<int>(_isotopeNumbers, _dimNumber)),
60 atomCounts(array_copy<int>(_atomCounts, _dimNumber)),
61 confSize(_dimNumber * sizeof(int)),
62 allDim(0),
63 marginals(nullptr),
64 modeLProb(0.0)
65 {
66 try{
67 setupMarginals(_isotopeMasses, _isotopeProbabilities);
68 }
69 catch(...)
70 {
71 delete[] isotopeNumbers;
72 delete[] atomCounts;
73 throw;
74 }
75 }
76
77 Iso::Iso(Iso&& other) :
78 disowned(other.disowned),
79 dimNumber(other.dimNumber),
80 isotopeNumbers(other.isotopeNumbers),
81 atomCounts(other.atomCounts),
82 confSize(other.confSize),
83 allDim(other.allDim),
84 marginals(other.marginals),
85 modeLProb(other.modeLProb)
86 {
87 other.disowned = true;
88 }
89
90
91 Iso::Iso(const Iso& other, bool fullcopy) :
92 disowned(fullcopy ? throw std::logic_error("Not implemented") : true),
93 dimNumber(other.dimNumber),
94 isotopeNumbers(fullcopy ? array_copy<int>(other.isotopeNumbers, dimNumber) : other.isotopeNumbers),
95 atomCounts(fullcopy ? array_copy<int>(other.atomCounts, dimNumber) : other.atomCounts),
96 confSize(other.confSize),
97 allDim(other.allDim),
98 marginals(fullcopy ? throw std::logic_error("Not implemented") : other.marginals),
99 modeLProb(other.modeLProb)
100 {}
101
102
103 inline void Iso::setupMarginals(const double* const * _isotopeMasses, const double* const * _isotopeProbabilities)
104 {
105 if (marginals == nullptr)
106 {
107 int ii = 0;
108 try
109 {
110 marginals = new Marginal*[dimNumber];
111 while(ii < dimNumber)
112 {
113 allDim += isotopeNumbers[ii];
114 marginals[ii] = new Marginal(
115 _isotopeMasses[ii],
116 _isotopeProbabilities[ii],
117 isotopeNumbers[ii],
118 atomCounts[ii]
119 );
120 modeLProb += marginals[ii]->getModeLProb();
121 ii++;
122 }
123 }
124 catch(...)
125 {
126 ii--;
127 while(ii >= 0)
128 {
129 delete marginals[ii];
130 ii--;
131 }
132 delete[] marginals;
133 marginals = nullptr;
134 throw;
135 }
136 }
137
138 }
139
140 Iso::~Iso()
141 {
142 if(!disowned)
143 {
144 if (marginals != nullptr)
145 dealloc_table(marginals, dimNumber);
146 delete[] isotopeNumbers;
147 delete[] atomCounts;
148 }
149 }
150
151
152 double Iso::getLightestPeakMass() const
153 {
154 double mass = 0.0;
155 for (int ii=0; ii<dimNumber; ii++)
156 mass += marginals[ii]->getLightestConfMass();
157 return mass;
158 }
159
160 double Iso::getHeaviestPeakMass() const
161 {
162 double mass = 0.0;
163 for (int ii=0; ii<dimNumber; ii++)
164 mass += marginals[ii]->getHeaviestConfMass();
165 return mass;
166 }
167
168 double Iso::getMonoisotopicPeakMass() const
169 {
170 double mass = 0.0;
171 for (int ii=0; ii<dimNumber; ii++)
172 mass += marginals[ii]->getMonoisotopicConfMass();
173 return mass;
174 }
175
176 double Iso::getModeMass() const
177 {
178 double mass = 0.0;
179 for (int ii=0; ii<dimNumber; ii++)
180 mass += marginals[ii]->getModeMass();
181 return mass;
182 }
183
184 double Iso::getTheoreticalAverageMass() const
185 {
186 double mass = 0.0;
187 for (int ii=0; ii<dimNumber; ii++)
188 mass += marginals[ii]->getTheoreticalAverageMass();
189 return mass;
190 }
191
192 Iso::Iso(const char* formula) :
193 disowned(false),
194 allDim(0),
195 marginals(nullptr),
196 modeLProb(0.0)
197 {
198 std::vector<const double*> isotope_masses;
199 std::vector<const double*> isotope_probabilities;
200
201 dimNumber = parse_formula(formula, isotope_masses, isotope_probabilities, &isotopeNumbers, &atomCounts, &confSize);
202
203 setupMarginals(isotope_masses.data(), isotope_probabilities.data());
204 }
205
206 unsigned int parse_formula(const char* formula, std::vector<const double*>& isotope_masses, std::vector<const double*>& isotope_probabilities, int** isotopeNumbers, int** atomCounts, unsigned int* confSize)
207 {
208 // This function is NOT guaranteed to be secure against malicious input. It should be used only for debugging.
209 size_t slen = strlen(formula);
210 // Yes, it would be more elegant to use std::string here, but it's the only promiment place where it would be used in IsoSpec, and avoiding it here
211 // means we can run the whole thing through Clang's memory sanitizer without the need for instrumented libc++/libstdc++. That's worth messing with char pointers a
212 // little bit.
213 std::vector<std::pair<const char*, size_t> > elements;
214 std::vector<int> numbers;
215
216 if(slen == 0)
217 throw invalid_argument("Invalid formula: can't be empty");
218
219 if(!isdigit(formula[slen-1]))
220 throw invalid_argument("Invalid formula: every element must be followed by a number - write H2O1 and not H2O for water");
221
222 for(size_t ii=0; ii<slen; ii++)
223 if(!isdigit(formula[ii]) && !isalpha(formula[ii]))
224 throw invalid_argument("Ivalid formula: contains invalid (non-digit, non-alpha) character");
225
226 size_t position = 0;
227 size_t elem_end = 0;
228 size_t digit_end = 0;
229
230 while(position < slen)
231 {
232 elem_end = position;
233 while(isalpha(formula[elem_end]))
234 elem_end++;
235 digit_end = elem_end;
236 while(isdigit(formula[digit_end]))
237 digit_end++;
238 elements.emplace_back(&formula[position], elem_end-position);
239 numbers.push_back(atoi(&formula[elem_end]));
240 position = digit_end;
241 }
242
243 std::vector<int> element_indexes;
244
245 for (unsigned int i=0; i<elements.size(); i++)
246 {
247 int idx = -1;
248 for(int j=0; j<ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES; j++)
249 {
250 if ((strlen(elem_table_symbol[j]) == elements[i].second) && (strncmp(elements[i].first, elem_table_symbol[j], elements[i].second) == 0))
251 {
252 idx = j;
253 break;
254 }
255 }
256 if(idx < 0)
257 throw invalid_argument("Invalid formula");
258 element_indexes.push_back(idx);
259 }
260
261 vector<int> _isotope_numbers;
262
263 for(vector<int>::iterator it = element_indexes.begin(); it != element_indexes.end(); ++it)
264 {
265 int num = 0;
266 int at_idx = *it;
267 int atomicNo = elem_table_atomicNo[at_idx];
268 while(at_idx < ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES && elem_table_atomicNo[at_idx] == atomicNo)
269 {
270 at_idx++;
271 num++;
272 }
273 _isotope_numbers.push_back(num);
274 }
275
276 for(vector<int>::iterator it = element_indexes.begin(); it != element_indexes.end(); ++it)
277 {
278 isotope_masses.push_back(&elem_table_mass[*it]);
279 isotope_probabilities.push_back(&elem_table_probability[*it]);
280 };
281
282 const unsigned int dimNumber = elements.size();
283
284 *isotopeNumbers = array_copy<int>(_isotope_numbers.data(), dimNumber);
285 *atomCounts = array_copy<int>(numbers.data(), dimNumber);
286 *confSize = dimNumber * sizeof(int);
287
288 return dimNumber;
289
290 }
291
292
293 /*
294 * ----------------------------------------------------------------------------------------------------------
295 */
296
297
298
299 IsoGenerator::IsoGenerator(Iso&& iso, bool alloc_partials) :
300 Iso(std::move(iso)),
301 partialLProbs(alloc_partials ? new double[dimNumber+1] : nullptr),
302 partialMasses(alloc_partials ? new double[dimNumber+1] : nullptr),
303 partialProbs(alloc_partials ? new double[dimNumber+1] : nullptr)
304 {
305 if(alloc_partials)
306 {
307 partialLProbs[dimNumber] = 0.0;
308 partialMasses[dimNumber] = 0.0;
309 partialProbs[dimNumber] = 1.0;
310 }
311 }
312
313
314 IsoGenerator::~IsoGenerator()
315 {
316 if(partialLProbs != nullptr)
317 delete[] partialLProbs;
318 if(partialMasses != nullptr)
319 delete[] partialMasses;
320 if(partialProbs != nullptr)
321 delete[] partialProbs;
322 }
323
324
325
326 /*
327 * ----------------------------------------------------------------------------------------------------------
328 */
329
330
331
332 IsoThresholdGenerator::IsoThresholdGenerator(Iso&& iso, double _threshold, bool _absolute, int tabSize, int hashSize, bool reorder_marginals)
333 : IsoGenerator(std::move(iso)),
334 Lcutoff(_threshold <= 0.0 ? std::numeric_limits<double>::lowest() : (_absolute ? log(_threshold) : log(_threshold) + modeLProb))
335 {
336 counter = new int[dimNumber];
337 maxConfsLPSum = new double[dimNumber-1];
338 marginalResultsUnsorted = new PrecalculatedMarginal*[dimNumber];
339
340 empty = false;
341
342 for(int ii=0; ii<dimNumber; ii++)
343 {
344 counter[ii] = 0;
345 marginalResultsUnsorted[ii] = new PrecalculatedMarginal(std::move(*(marginals[ii])),
346 Lcutoff - modeLProb + marginals[ii]->getModeLProb(),
347 true,
348 tabSize,
349 hashSize);
350
351 if(!marginalResultsUnsorted[ii]->inRange(0))
352 empty = true;
353 }
354
355 if(reorder_marginals)
356 {
357 OrderMarginalsBySizeDecresing comparator(marginalResultsUnsorted);
358 int* tmpMarginalOrder = new int[dimNumber];
359
360 for(int ii=0; ii<dimNumber; ii++)
361 tmpMarginalOrder[ii] = ii;
362
363 std::sort(tmpMarginalOrder, tmpMarginalOrder + dimNumber, comparator);
364 marginalResults = new PrecalculatedMarginal*[dimNumber];
365
366 for(int ii=0; ii<dimNumber; ii++)
367 marginalResults[ii] = marginalResultsUnsorted[tmpMarginalOrder[ii]];
368
369 marginalOrder = new int[dimNumber];
370 for(int ii = 0; ii<dimNumber; ii++)
371 marginalOrder[tmpMarginalOrder[ii]] = ii;
372
373 delete[] tmpMarginalOrder;
374
375 }
376 else
377 {
378 marginalResults = marginalResultsUnsorted;
379 marginalOrder = nullptr;
380 }
381
382 lProbs_ptr_start = marginalResults[0]->get_lProbs_ptr();
383
384 if(dimNumber > 1)
385 maxConfsLPSum[0] = marginalResults[0]->getModeLProb();
386
387 for(int ii=1; ii<dimNumber-1; ii++)
388 maxConfsLPSum[ii] = maxConfsLPSum[ii-1] + marginalResults[ii]->getModeLProb();
389
390 lProbs_ptr = lProbs_ptr_start;
391
392 partialLProbs_second = partialLProbs;
393 partialLProbs_second++;
394
395 if(!empty)
396 {
397 recalc(dimNumber-1);
398 counter[0]--;
399 lProbs_ptr--;
400 }
401 else
402 {
403 terminate_search();
404 lcfmsv = std::numeric_limits<double>::infinity();
405 }
406
407
408
409 }
410
411 void IsoThresholdGenerator::terminate_search()
412 {
413 for(int ii=0; ii<dimNumber; ii++)
414 {
415 counter[ii] = marginalResults[ii]->get_no_confs()-1;
416 partialLProbs[ii] = -std::numeric_limits<double>::infinity();
417 }
418 partialLProbs[dimNumber] = -std::numeric_limits<double>::infinity();
419 lProbs_ptr = lProbs_ptr_start + marginalResults[0]->get_no_confs()-1;
420 }
421
422 size_t IsoThresholdGenerator::count_confs()
423 {
424 // Smarter algorithm forthcoming in 2.0
425 size_t ret = 0;
426 while(advanceToNextConfiguration())
427 ret++;
428 reset();
429 return ret;
430 }
431
432 void IsoThresholdGenerator::reset()
433 {
434 if(empty)
435 {
436 terminate_search();
437 return;
438 }
439
440 partialLProbs[dimNumber] = 0.0;
441
442 memset(counter, 0, sizeof(int)*dimNumber);
443 recalc(dimNumber-1);
444 counter[0]--;
445
446 lProbs_ptr = lProbs_ptr_start - 1;
447 }
448
449 /*
450 * ------------------------------------------------------------------------------------------------------------------------
451 */
452
453 IsoOrderedGenerator::IsoOrderedGenerator(Iso&& iso, int _tabSize, int _hashSize) :
454 IsoGenerator(std::move(iso), false), allocator(dimNumber, _tabSize)
455 {
456 partialLProbs = &currentLProb;
457 partialMasses = &currentMass;
458 partialProbs = &currentProb;
459
460 marginalResults = new MarginalTrek*[dimNumber];
461
462 for(int i = 0; i<dimNumber; i++)
463 marginalResults[i] = new MarginalTrek(std::move(*(marginals[i])), _tabSize, _hashSize);
464
465 logProbs = new const vector<double>*[dimNumber];
466 masses = new const vector<double>*[dimNumber];
467 marginalConfs = new const vector<int*>*[dimNumber];
468
469 for(int i = 0; i<dimNumber; i++)
470 {
471 masses[i] = &marginalResults[i]->conf_masses();
472 logProbs[i] = &marginalResults[i]->conf_lprobs();
473 marginalConfs[i] = &marginalResults[i]->confs();
474 }
475
476 topConf = allocator.newConf();
477 memset(
478 reinterpret_cast<char*>(topConf) + sizeof(double),
479 0,
480 sizeof(int)*dimNumber
481 );
482
483 *(reinterpret_cast<double*>(topConf)) =
484 combinedSum(
485 getConf(topConf),
486 logProbs,
487 dimNumber
488 );
489
490 pq.push(topConf);
491
492 }
493
494
495 IsoOrderedGenerator::~IsoOrderedGenerator()
496 {
497 dealloc_table<MarginalTrek*>(marginalResults, dimNumber);
498 delete[] logProbs;
499 delete[] masses;
500 delete[] marginalConfs;
501 partialLProbs = nullptr;
502 partialMasses = nullptr;
503 partialProbs = nullptr;
504 }
505
506
507 bool IsoOrderedGenerator::advanceToNextConfiguration()
508 {
509 if(pq.size() < 1)
510 return false;
511
512
513 topConf = pq.top();
514 pq.pop();
515
516 int* topConfIsoCounts = getConf(topConf);
517
518 currentLProb = *(reinterpret_cast<double*>(topConf));
519 currentMass = combinedSum( topConfIsoCounts, masses, dimNumber );
520 currentProb = exp(currentLProb);
521
522 ccount = -1;
523 for(int j = 0; j < dimNumber; ++j)
524 {
525 if(marginalResults[j]->probeConfigurationIdx(topConfIsoCounts[j] + 1))
526 {
527 if(ccount == -1)
528 {
529 topConfIsoCounts[j]++;
530 *(reinterpret_cast<double*>(topConf)) = combinedSum(topConfIsoCounts, logProbs, dimNumber);
531 pq.push(topConf);
532 topConfIsoCounts[j]--;
533 ccount = j;
534 }
535 else
536 {
537 void* acceptedCandidate = allocator.newConf();
538 int* acceptedCandidateIsoCounts = getConf(acceptedCandidate);
539 memcpy(acceptedCandidateIsoCounts, topConfIsoCounts, confSize);
540
541 acceptedCandidateIsoCounts[j]++;
542
543 *(reinterpret_cast<double*>(acceptedCandidate)) = combinedSum(acceptedCandidateIsoCounts, logProbs, dimNumber);
544
545 pq.push(acceptedCandidate);
546 }
547 }
548 if(topConfIsoCounts[j] > 0)
549 break;
550 }
551 if(ccount >=0)
552 topConfIsoCounts[ccount]++;
553
554 return true;
555 }
556
557
558
559 /*
560 * ---------------------------------------------------------------------------------------------------
561 */
562
563
564
565
566 #if !ISOSPEC_BUILDING_R
567
568 void printConfigurations(
569 const std::tuple<double*,double*,int*,int>& results,
570 int dimNumber,
571 int* isotopeNumbers
572 ){
573 int m = 0;
574
575 for(int i=0; i<std::get<3>(results); i++){
576
577 std::cout << "Mass = " << std::get<0>(results)[i] <<
578 "\tand log-prob = " << std::get<1>(results)[i] <<
579 "\tand prob = " << exp(std::get<1>(results)[i]) <<
580 "\tand configuration =\t";
581
582
583 for(int j=0; j<dimNumber; j++){
584 for(int k=0; k<isotopeNumbers[j]; k++ )
585 {
586 std::cout << std::get<2>(results)[m] << " ";
587 m++;
588 }
589 std::cout << '\t';
590 }
591
592
593 std::cout << std::endl;
594 }
595 }
596
597 #endif /* !ISOSPEC_BUILDING_R */
598
599
600
601 IsoLayeredGenerator::IsoLayeredGenerator( Iso&& iso,
602 double _targetCoverage,
603 double _percentageToExpand,
604 int _tabSize,
605 int _hashSize,
606 bool trim
607 ) : IsoGenerator(std::move(iso)),
608 allocator(dimNumber, _tabSize),
609 candidate(new int[dimNumber]),
610 targetCoverage(_targetCoverage >= 1.0 ? 10000.0 : _targetCoverage), // If the user wants the entire spectrum,
611 // give it to him - and make sure we don't terminate
612 // early because of rounding errors
613 percentageToExpand(_percentageToExpand),
614 do_trim(trim),
615 layers(0),
616 generator_position(-1)
617 {
618 marginalResults = new MarginalTrek*[dimNumber];
619
620 for(int i = 0; i<dimNumber; i++)
621 marginalResults[i] = new MarginalTrek(std::move(*(marginals[i])), _tabSize, _hashSize);
622
623 logProbs = new const vector<double>*[dimNumber];
624 masses = new const vector<double>*[dimNumber];
625 marginalConfs = new const vector<int*>*[dimNumber];
626
627 for(int i = 0; i<dimNumber; i++)
628 {
629 masses[i] = &marginalResults[i]->conf_masses();
630 logProbs[i] = &marginalResults[i]->conf_lprobs();
631 marginalConfs[i] = &marginalResults[i]->confs();
632 }
633
634 void* topConf = allocator.newConf();
635 memset(reinterpret_cast<char*>(topConf) + sizeof(double), 0, sizeof(int)*dimNumber);
636 *(reinterpret_cast<double*>(topConf)) = combinedSum(getConf(topConf), logProbs, dimNumber);
637
638 current = new std::vector<void*>();
639 next = new std::vector<void*>();
640
641 current->push_back(topConf);
642
643 lprobThr = (*reinterpret_cast<double*>(topConf));
644
645 if(targetCoverage > 0.0)
646 while(advanceToNextLayer()) {};
647 }
648
649
650 IsoLayeredGenerator::~IsoLayeredGenerator()
651 {
652 if(current != nullptr)
653 delete current;
654 if(next != nullptr)
655 delete next;
656 delete[] logProbs;
657 delete[] masses;
658 delete[] marginalConfs;
659 delete[] candidate;
660 dealloc_table(marginalResults, dimNumber);
661 }
662
663 bool IsoLayeredGenerator::advanceToNextLayer()
664 {
665 layers += 1;
666 double maxFringeLprob = -std::numeric_limits<double>::infinity();
667
668 if(current == nullptr)
669 return false;
670 int accepted_in_this_layer = 0;
671 Summator prob_in_this_layer(totalProb);
672
673 void* topConf;
674
675 while(current->size() > 0)
676 {
677 topConf = current->back();
678 current->pop_back();
679
680 double top_lprob = getLProb(topConf);
681
682 if(top_lprob >= lprobThr)
683 {
684 newaccepted.push_back(topConf);
685 accepted_in_this_layer++;
686 prob_in_this_layer.add(exp(top_lprob));
687 }
688 else
689 {
690 next->push_back(topConf);
691 continue;
692 }
693
694 int* topConfIsoCounts = getConf(topConf);
695
696 for(int j = 0; j < dimNumber; ++j)
697 {
698 // candidate cannot refer to a position that is
699 // out of range of the stored marginal distribution.
700 if(marginalResults[j]->probeConfigurationIdx(topConfIsoCounts[j] + 1))
701 {
702 memcpy(candidate, topConfIsoCounts, confSize);
703 candidate[j]++;
704
705 void* acceptedCandidate = allocator.newConf();
706 int* acceptedCandidateIsoCounts = getConf(acceptedCandidate);
707 memcpy( acceptedCandidateIsoCounts, candidate, confSize);
708
709 double newConfProb = combinedSum(
710 candidate,
711 logProbs,
712 dimNumber
713 );
714
715
716
717 *(reinterpret_cast<double*>(acceptedCandidate)) = newConfProb;
718
719 if(newConfProb >= lprobThr)
720 current->push_back(acceptedCandidate);
721 else
722 {
723 next->push_back(acceptedCandidate);
724 if(newConfProb > maxFringeLprob)
725 maxFringeLprob = top_lprob;
726 }
727 }
728 if(topConfIsoCounts[j] > 0)
729 break;
730 }
731 }
732
733 if(next == nullptr || next->size() < 1)
734 return false;
735 else
736 {
737 if(prob_in_this_layer.get() < targetCoverage)
738 {
739 std::vector<void*>* nnew = current;
740 nnew->clear();
741 current = next;
742 next = nnew;
743 int howmany = floor(current->size()*percentageToExpand);
744 lprobThr = getLProb(quickselect(current->data(), howmany, 0, current->size()));
745 totalProb = prob_in_this_layer;
746 }
747 else
748 {
749 delete next;
750 next = nullptr;
751 delete current;
752 current = nullptr;
753 int start = 0;
754 int end = accepted_in_this_layer - 1;
755 void* swapspace;
756
757 if(do_trim)
758 {
759 void** lastLayer = &(newaccepted.data()[newaccepted.size()-accepted_in_this_layer]);
760
761 Summator qsprob(totalProb);
762 while(totalProb.get() < targetCoverage)
763 {
764 if(start == end)
765 break;
766
767 // Partition part
768
769 int len = end - start;
770 #if ISOSPEC_BUILDING_R
771 int pivot = len/2 + start; // We're very definitely NOT switching to R to use a RNG, and if R sees us use C RNG it complains...
772 #else
773 int pivot = rand() % len + start;
774 #endif
775 void* pval = lastLayer[pivot];
776 double pprob = getLProb(pval);
777 mswap(lastLayer[pivot], lastLayer[end-1]);
778 int loweridx = start;
779 for(int i=start; i<end-1; i++)
780 {
781 if(getLProb(lastLayer[i]) > pprob)
782 {
783 mswap(lastLayer[i], lastLayer[loweridx]);
784 loweridx++;
785 }
786 }
787 mswap(lastLayer[end-1], lastLayer[loweridx]);
788
789 // Selection part
790
791 Summator leftProb(qsprob);
792 for(int i=start; i<=loweridx; i++)
793 {
794 leftProb.add(exp(getLProb(lastLayer[i])));
795 }
796 if(leftProb.get() < targetCoverage)
797 {
798 start = loweridx+1;
799 qsprob = leftProb;
800 }
801 else
802 end = loweridx;
803 }
804 int accend = newaccepted.size()-accepted_in_this_layer+start+1;
805
806 totalProb = qsprob;
807 newaccepted.resize(accend);
808 return true;
809 }
810 else // No trimming
811 {
812 totalProb = prob_in_this_layer;
813 return true;
814 }
815 }
816 }
817 return true;
818
819 }
820
821 bool IsoLayeredGenerator::advanceToNextConfiguration()
822 {
823 generator_position++;
824 if(generator_position < newaccepted.size())
825 {
826 partialLProbs[0] = getLProb(newaccepted[generator_position]);
827 partialMasses[0] = combinedSum(getConf(newaccepted[generator_position]), masses, dimNumber);
828 partialProbs[0] = exp(partialLProbs[0]);
829 return true;
830 }
831 else
832 return false;
833 }
834
835
836
837
838 } // namespace IsoSpec
839
0 /*!
1 Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2
3 This file is part of IsoSpec.
4
5 IsoSpec is free software: you can redistribute it and/or modify
6 it under the terms of the Simplified ("2-clause") BSD licence.
7
8 IsoSpec is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
12 You should have received a copy of the Simplified BSD Licence
13 along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <tuple>
19 #include <unordered_map>
20 #include <queue>
21 #include <limits>
22 #include "platform.h"
23 #include "dirtyAllocator.h"
24 #include "summator.h"
25 #include "operators.h"
26 #include "marginalTrek++.h"
27
28
29 #if ISOSPEC_BUILDING_R
30 #include <Rcpp.h>
31 using namespace Rcpp;
32 #endif /* ISOSPEC_BUILDING_R */
33
34
35 namespace IsoSpec
36 {
37
38 // This function is NOT guaranteed to be secure against malicious input. It should be used only for debugging.
39 unsigned int parse_formula(const char* formula,
40 std::vector<const double*>& isotope_masses,
41 std::vector<const double*>& isotope_probabilities,
42 int** isotopeNumbers,
43 int** atomCounts,
44 unsigned int* confSize);
45
46
47 //! The Iso class for the calculation of the isotopic distribution.
48 /*!
49 It contains full description of the molecule for which one would like to calculate the isotopic distribution.
50 */
51 class ISOSPEC_EXPORT_SYMBOL Iso {
52 private:
53
54 //! Set up the marginal isotopic envelopes, corresponding to subisotopologues.
55 /*!
56 \param _isotopeMasses A table of masses of isotopes of the elements in the chemical formula,
57 e.g. {12.0, 13.003355, 1.007825, 2.014102} for C100H202.
58 \param _isotopeProbabilities A table of isotope frequencies of the elements in the chemical formula,
59 e.g. {.989212, .010788, .999885, .000115} for C100H202.
60 */
61 void setupMarginals(const double* const * _isotopeMasses,
62 const double* const * _isotopeProbabilities);
63 public:
64 bool disowned; /*!< A variable showing if the Iso class was specialized by its child-class. If so, then the description of the molecules has been transfered there and Iso is a carcass class, dead as a dodo, an ex-class if you will. */
65 protected:
66 int dimNumber; /*!< The number of elements in the chemical formula of the molecule. */
67 int* isotopeNumbers; /*!< A table with numbers of isotopes for each element. */
68 int* atomCounts; /*!< A table with numbers of isotopes for each element. */
69 unsigned int confSize; /*!< The number of bytes needed to represent the counts of isotopes present in the extended chemical formula. */
70 int allDim; /*!< The total number of isotopes of elements present in a chemical formula, e.g. for H20 it is 2+3=5. */
71 Marginal** marginals; /*!< The table of pointers to the distributions of individual subisotopologues. */
72 double modeLProb; /*!< The log-probability of the mode of the isotopic distribution. */
73
74 public:
75 //! General constructror.
76 /*!
77 \param _dimNumber The number of elements in the formula, e.g. for C100H202 it would be 2, as there are only carbon and hydrogen atoms.
78 \param _isotopeNumbers A table with numbers of isotopes for each element, e.g. for C100H202 it would be {2, 2}, because both C and H have two stable isotopes.
79 \param _atomCounts Number of atoms of each element in the formula, e.g. for C100H202 corresponds to {100, 202}.
80 \param _isotopeMasses A table of tables of masses of isotopes of the elements in the chemical formula, e.g. {{12.0, 13.003355}, {1.007825, 2.014102}} for C100H202.
81 \param _isotopeProbabilities A table of tables of isotope frequencies of the elements in the chemical formula, e.g. {{.989212, .010788}, {.999885, .000115}} for C100H202.
82 */
83 Iso(
84 int _dimNumber,
85 const int* _isotopeNumbers,
86 const int* _atomCounts,
87 const double* const * _isotopeMasses,
88 const double* const * _isotopeProbabilities
89 );
90
91 //! Constructor from the formula object.
92 Iso(const char* formula);
93
94 //! The move constructor.
95 Iso(Iso&& other);
96
97 //! The copy constructor.
98 /*!
99 \param other The other instance of the Iso class.
100 \param fullcopy If false, copy only the number of atoms in the formula, the size of the configuration, the total number of isotopes, and the probability of the mode isotopologue.
101 */
102 Iso(const Iso& other, bool fullcopy);
103
104 //! Destructor.
105 virtual ~Iso();
106
107 //! Get the mass of the lightest peak in the isotopic distribution.
108 double getLightestPeakMass() const;
109
110 //! Get the mass of the heaviest peak in the isotopic distribution.
111 double getHeaviestPeakMass() const;
112
113 /*!
114 Get the mass of the monoisotopic peak in the isotopic distribution. Monoisotopc molecule is defined as
115 consisting only of the most frequent isotopes of each element. These are often (but not always) the
116 lightest ones, making this often (but again, not always) equal to getLightestPeakMass()
117 */
118 double getMonoisotopicPeakMass() const;
119
120 //! Get the log-probability of the mode-configuration (if there are many modes, they share this value).
121 inline double getModeLProb() const { return modeLProb; };
122
123 //! Get the mass of the mode-configuration (if there are many modes, it is undefined which one will be selected).
124 double getModeMass() const;
125
126 //! Get the theoretical average mass of the molecule.
127 double getTheoreticalAverageMass() const;
128
129 //! Get the number of elements in the chemical formula of the molecule.
130 inline int getDimNumber() const { return dimNumber; };
131
132 //! Get the total number of isotopes of elements present in a chemical formula.
133 inline int getAllDim() const { return allDim; };
134 };
135
136
137 //! The generator of isotopologues.
138 /*!
139 This class provides the common interface for all isotopic generators.
140 */
141 class ISOSPEC_EXPORT_SYMBOL IsoGenerator : public Iso
142 {
143 protected:
144 double* partialLProbs; /*!< The prefix sum of the log-probabilities of the current isotopologue. */
145 double* partialMasses; /*!< The prefix sum of the masses of the current isotopologue. */
146 double* partialProbs;/*!< The prefix product of the probabilities of the current isotopologue. */
147
148 public:
149 //! Advance to the next, not yet visited, most probable isotopologue.
150 /*!
151 \return Return false if it is not possible to advance.
152 */
153 virtual bool advanceToNextConfiguration() = 0;
154
155 //! Get the log-probability of the current isotopologue.
156 /*!
157 \return The log-probability of the current isotopologue.
158 */
159 virtual double lprob() const { return partialLProbs[0]; };
160
161 //! Get the mass of the current isotopologue.
162 /*!
163 \return The mass of the current isotopologue.
164 */
165 virtual double mass() const { return partialMasses[0]; };
166
167 //! Get the probability of the current isotopologue.
168 /*!
169 \return The probability of the current isotopologue.
170 */
171 virtual double prob() const { return partialProbs[0]; };
172
173 //TODO: what is this???
174 virtual void get_conf_signature(int* space) const = 0;
175
176 //! Move constructor.
177 IsoGenerator(Iso&& iso, bool alloc_partials = true);
178
179 //! Destructor.
180 virtual ~IsoGenerator();
181 };
182
183
184
185 //! The generator of isotopologues sorted by their probability of occurrence.
186 /*!
187 The subsequent isotopologues are generated with diminishing probability, starting from the mode.
188 This algorithm take O(N*log(N)) to compute the N isotopologues because of using the Priority Queue data structure.
189 Obtaining the N isotopologues can be achieved in O(N) if they are not required to be spit out in the descending order.
190 */
191 class ISOSPEC_EXPORT_SYMBOL IsoOrderedGenerator: public IsoGenerator
192 {
193 private:
194 MarginalTrek** marginalResults; /*!< Table of pointers to marginal distributions of subisotopologues. */
195 std::priority_queue<void*,std::vector<void*>,ConfOrder> pq; /*!< The priority queue used to generate isotopologues ordered by descending probability. */
196 void* topConf; /*!< Most probable configuration. */
197 DirtyAllocator allocator; /*!< Structure used for alocating memory for isotopologues. */
198 const std::vector<double>** logProbs; /*!< Obtained log-probabilities. */
199 const std::vector<double>** masses; /*!< Obtained masses. */
200 const std::vector<int*>** marginalConfs; /*!< Obtained counts of isotopes. */
201 double currentLProb; /*!< The log-probability of the current isotopologue. */
202 double currentMass; /*!< The mass of the current isotopologue. */
203 double currentProb; /*!< The probability of the current isotopologue. */
204 int ccount;
205
206 public:
207 bool advanceToNextConfiguration() override final;
208
209 //! Save the counts of isotopes in the space.
210 /*!
211 \param space An array where counts of isotopes shall be written.
212 Must be as big as the overall number of isotopes.
213 */
214 inline void get_conf_signature(int* space) const override final
215 {
216 int* c = getConf(topConf);
217
218 if (ccount >= 0)
219 c[ccount]--;
220
221 for(int ii=0; ii<dimNumber; ii++)
222 {
223 memcpy(space, marginalResults[ii]->confs()[c[ii]], isotopeNumbers[ii]*sizeof(int));
224 space += isotopeNumbers[ii];
225 }
226
227 if (ccount >= 0)
228 c[ccount]++;
229 };
230
231 //! The move-contstructor.
232 IsoOrderedGenerator(Iso&& iso, int _tabSize = 1000, int _hashSize = 1000);
233
234 //! Destructor.
235 virtual ~IsoOrderedGenerator();
236 };
237
238
239
240
241 //! The generator of isotopologues above a given threshold value.
242 /*!
243 Attention: the calculated configurations are only partially ordeded and the user should not assume they will be ordered.
244 This algorithm computes N isotopologues in O(N).
245 It is a considerable advantage w.r.t. the IsoOrderedGenerator.
246 */
247 class ISOSPEC_EXPORT_SYMBOL IsoThresholdGenerator: public IsoGenerator
248 {
249 private:
250
251 int* counter; /*!< An array storing the position of an isotopologue in terms of the subisotopologues ordered by decreasing probability. */
252 double* maxConfsLPSum;
253 const double Lcutoff; /*!< The logarithm of the lower bound on the calculated probabilities. */
254 PrecalculatedMarginal** marginalResults;
255 PrecalculatedMarginal** marginalResultsUnsorted;
256 int* marginalOrder;
257
258 const double* lProbs_ptr;
259 const double* lProbs_ptr_start;
260 double* partialLProbs_second;
261 double partialLProbs_second_val, lcfmsv;
262 bool empty;
263
264 public:
265 inline void get_conf_signature(int* space) const override final
266 {
267 counter[0] = lProbs_ptr - lProbs_ptr_start;
268 if(marginalOrder != nullptr)
269 for(int ii=0; ii<dimNumber; ii++)
270 {
271 int jj = marginalOrder[ii];
272 memcpy(space, marginalResultsUnsorted[ii]->get_conf(counter[jj]), isotopeNumbers[ii]*sizeof(int));
273 space += isotopeNumbers[ii];
274 }
275 else
276 for(int ii=0; ii<dimNumber; ii++)
277 {
278 memcpy(space, marginalResultsUnsorted[ii]->get_conf(counter[ii]), isotopeNumbers[ii]*sizeof(int));
279 space += isotopeNumbers[ii];
280 }
281
282 };
283
284 //! The move-constructor.
285 /*!
286 \param iso An instance of the Iso class.
287 \param _threshold The threshold value.
288 \param _absolute If true, the _threshold is interpreted as the absolute minimal peak height for the isotopologues.
289 If false, the _threshold is the fraction of the heighest peak's probability.
290 \param tabSize The size of the extension of the table with configurations.
291 \param hashSize The size of the hash-table used to store subisotopologues and check if they have been already calculated.
292 */
293 IsoThresholdGenerator(Iso&& iso, double _threshold, bool _absolute=true, int _tabSize=1000, int _hashSize=1000, bool reorder_marginals = true);
294
295 inline ~IsoThresholdGenerator()
296 {
297 delete[] counter;
298 delete[] maxConfsLPSum;
299 if (marginalResultsUnsorted != marginalResults)
300 delete[] marginalResultsUnsorted;
301 dealloc_table(marginalResults, dimNumber);
302 if(marginalOrder != nullptr)
303 delete[] marginalOrder;
304 };
305
306 // Perform highly aggressive inling as this function is often called as while(advanceToNextConfiguration()) {}
307 // which leads to an extremely tight loop and some compilers miss this (potentially due to the length of the function).
308 ISOSPEC_FORCE_INLINE bool advanceToNextConfiguration() override final
309 {
310 lProbs_ptr++;
311
312 if(ISOSPEC_LIKELY(*lProbs_ptr >= lcfmsv))
313 {
314 return true;
315 }
316
317 // If we reached this point, a carry is needed
318
319 int idx = 0;
320 lProbs_ptr = lProbs_ptr_start;
321
322 int * cntr_ptr = counter;
323
324 while(idx<dimNumber-1)
325 {
326 // counter[idx] = 0;
327 *cntr_ptr = 0;
328 idx++;
329 cntr_ptr++;
330 // counter[idx]++;
331 (*cntr_ptr)++;
332 partialLProbs[idx] = partialLProbs[idx+1] + marginalResults[idx]->get_lProb(counter[idx]);
333 if(partialLProbs[idx] + maxConfsLPSum[idx-1] >= Lcutoff)
334 {
335 partialMasses[idx] = partialMasses[idx+1] + marginalResults[idx]->get_mass(counter[idx]);
336 partialProbs[idx] = partialProbs[idx+1] * marginalResults[idx]->get_prob(counter[idx]);
337 recalc(idx-1);
338 return true;
339 }
340 }
341
342 terminate_search();
343 return false;
344 }
345
346
347 ISOSPEC_FORCE_INLINE double lprob() const override final { return partialLProbs_second_val + (*(lProbs_ptr)); };
348 ISOSPEC_FORCE_INLINE double mass() const override final { return partialMasses[1] + marginalResults[0]->get_mass(lProbs_ptr - lProbs_ptr_start); };
349 ISOSPEC_FORCE_INLINE double prob() const override final { return partialProbs[1] * marginalResults[0]->get_prob(lProbs_ptr - lProbs_ptr_start); };
350
351 //! Block the subsequent search of isotopologues.
352 void terminate_search();
353
354 /*! Reset the generator to the beginning of the sequence. Allows it to be reused, eg. to go through the conf space once, calculate
355 the amount of space needed to store configurations, then to allocate that memory, and go through it again, this time saving
356 configurations (and *is* in fact faster than allocating a std::vector and depending on it to grow as needed. This is cheaper
357 than throwing away the generator and making a new one too: marginal distributions don't need to be recalculated. */
358 void reset();
359
360 /*! Count the number of configurations in the distribution. This can be used to pre-allocate enough memory to store it (e.g.
361 * std::vector's reserve() method - this is faster than depending on the vector's dynamic resizing, even though it means that
362 * the configuration space is walked through twice. This method has to be called before the first call to advanceToNextConfiguration
363 * and has undefined results (incl. segfaults) otherwise. */
364 size_t count_confs();
365
366 private:
367 //! Recalculate the current partial log-probabilities, masses, and probabilities.
368 ISOSPEC_FORCE_INLINE void recalc(int idx)
369 {
370 for(; idx > 0; idx--)
371 {
372 partialLProbs[idx] = partialLProbs[idx+1] + marginalResults[idx]->get_lProb(counter[idx]);
373 partialMasses[idx] = partialMasses[idx+1] + marginalResults[idx]->get_mass(counter[idx]);
374 partialProbs[idx] = partialProbs[idx+1] * marginalResults[idx]->get_prob(counter[idx]);
375 }
376 partialLProbs_second_val = *partialLProbs_second;
377 partialLProbs[0] = *partialLProbs_second + marginalResults[0]->get_lProb(counter[0]);
378 lcfmsv = Lcutoff - partialLProbs_second_val;
379 }
380 };
381
382
383
384 //! The class that represents isotopologues above a given joint probability value.
385 /*!
386 This class generates subsequent isotopologues that ARE NOT GUARANTEED TO BE ORDERED BY probability.
387 The overal set of isotopologues is guaranteed to surpass a given threshold of probability contained in the
388 isotopic distribution.
389 This calculations are performed in O(N) operations, where N is the total number of the output isotopologues.
390
391 This class is not a true generator yet - the generator methods have been implemented for compatibility, but
392 the class actually performs all computations during the initialization and stores them, and the generator methods
393 only walk through the array of precomputed values. . It will be reimplemented as a true generator in 2.0.
394 */
395 class ISOSPEC_EXPORT_SYMBOL IsoLayeredGenerator : public IsoGenerator
396 {
397 private:
398 Summator totalProb;
399 std::vector<void*> newaccepted;
400 DirtyAllocator allocator;
401 int* candidate;
402 const std::vector<double>** logProbs; /*!< Obtained log-probabilities. */
403 const std::vector<double>** masses; /*!< Obtained masses. */
404 const std::vector<int*>** marginalConfs; /*!< Obtained counts of isotopes. */
405 MarginalTrek** marginalResults;
406 std::vector<void*>* current;
407 std::vector<void*>* next;
408 double lprobThr;
409 double targetCoverage;
410 double percentageToExpand;
411 bool do_trim;
412 int layers;
413 size_t generator_position;
414
415 bool advanceToNextLayer();
416
417 public:
418 bool advanceToNextConfiguration() override final;
419
420 inline void get_conf_signature(int* space) const override final
421 {
422 int* conf = getConf(newaccepted[generator_position]);
423 for(int ii=0; ii<dimNumber; ii++)
424 {
425 memcpy(space, marginalResults[ii]->confs()[conf[ii]], isotopeNumbers[ii]*sizeof(int));
426 space += isotopeNumbers[ii];
427 }
428 };
429
430
431 IsoLayeredGenerator(Iso&& iso, double _targetCoverage, double _percentageToExpand = 0.3, int _tabSize = 1000, int _hashSize = 1000, bool trim = false);
432 virtual ~IsoLayeredGenerator();
433
434 void terminate_search();
435
436 };
437
438
439
440
441 #if !ISOSPEC_BUILDING_R
442
443 void printConfigurations(
444 const std::tuple<double*,double*,int*,int>& results,
445 int dimNumber,
446 int* isotopeNumbers
447 );
448 #endif /* !ISOSPEC_BUILDING_R */
449
450 } // namespace IsoSpec
451
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16
17 #include <cmath>
18 #include <algorithm>
19 #include <vector>
20 #include <stdlib.h>
21 #include <tuple>
22 #include <unordered_map>
23 #include <unordered_set>
24 #include <queue>
25 #include <utility>
26 #include <iostream>
27 #include <string.h>
28 #include <string>
29 #include <limits>
30 #include <cstdlib>
31 #include <fenv.h>
32 #include "platform.h"
33 #include "marginalTrek++.h"
34 #include "conf.h"
35 #include "allocator.h"
36 #include "operators.h"
37 #include "summator.h"
38 #include "element_tables.h"
39 #include "misc.h"
40
41
42 namespace IsoSpec
43 {
44
45 //! Find one of the most probable subisotopologues.
46 /*!
47 The algorithm uses the hill-climbing algorithm.
48 It starts from a subisotopologue close to the mean of the underlying multinomial distribution.
49 There might be more than one modes, in case of which this function will return only one of them, close to the mean.
50
51 \param atomCnt
52
53 */
54 Conf initialConfigure(const int atomCnt, const int isotopeNo, const double* probs, const double* lprobs)
55 {
56 /*!
57 Here we perform hill climbing to the mode of the marginal distribution (the subisotopologue distribution).
58 We start from the point close to the mean of the underlying multinomial distribution.
59 */
60 Conf res = new int[isotopeNo];
61
62 // This approximates the mode (heuristics: the mean is close to the mode).
63 for(int i = 0; i < isotopeNo; ++i )
64 res[i] = int( atomCnt * probs[i] ) + 1;
65
66 // The number of assigned atoms above.
67 int s = 0;
68
69 for(int i = 0; i < isotopeNo; ++i) s += res[i];
70
71 int diff = atomCnt - s;
72
73 // Too little: enlarging fist index.
74 if( diff > 0 ){
75 res[0] += diff;
76 }
77 // Too much: trying to redistribute the difference: hopefully the first element is the largest.
78 if( diff < 0 ){
79 diff = abs(diff);
80 int i = 0, coordDiff = 0;
81
82 while( diff > 0){
83 coordDiff = res[i] - diff;
84
85 if( coordDiff >= 0 ){
86 res[i] -= diff;
87 diff = 0;
88 } else {
89 res[i] = 0;
90 i++;
91 diff = abs(coordDiff);
92 }
93 }
94 }
95
96 // What we computed so far will be very close to the mode: hillclimb the rest of the way
97
98 bool modified = true;
99 double LP = unnormalized_logProb(res, lprobs, isotopeNo);
100 double NLP;
101
102 while(modified)
103 {
104 modified = false;
105 for(int ii = 0; ii<isotopeNo; ii++)
106 for(int jj = 0; jj<isotopeNo; jj++)
107 if(ii != jj && res[ii] > 0)
108 {
109 res[ii]--;
110 res[jj]++;
111 NLP = unnormalized_logProb(res, lprobs, isotopeNo);
112 if(NLP>LP || (NLP==LP && ii>jj))
113 {
114 modified = true;
115 LP = NLP;
116 }
117 else
118 {
119 res[ii]++;
120 res[jj]--;
121 }
122 }
123
124
125 }
126 return res;
127 }
128
129
130
131 #if !ISOSPEC_BUILDING_R
132 void printMarginal( const std::tuple<double*,double*,int*,int>& results, int dim)
133 {
134 for(int i=0; i<std::get<3>(results); i++){
135
136 std::cout << "Mass = " << std::get<0>(results)[i] <<
137 " log-prob =\t" << std::get<1>(results)[i] <<
138 " prob =\t" << exp(std::get<1>(results)[i]) <<
139 "\tand configuration =\t";
140
141 for(int j=0; j<dim; j++) std::cout << std::get<2>(results)[i*dim + j] << " ";
142
143 std::cout << std::endl;
144 }
145 }
146 #endif
147
148
149 double* getMLogProbs(const double* probs, int isoNo)
150 {
151 /*!
152 Here we order the processor to round the numbers up rather than down.
153 Rounding down could result in the algorithm falling in an infinite loop
154 because of the numerical instability of summing.
155 */
156 int curr_method = fegetround();
157 fesetround(FE_UPWARD);
158 double* ret = new double[isoNo];
159
160 // here we change the table of probabilities and log it.
161 for(int i = 0; i < isoNo; i++)
162 {
163 ret[i] = log(probs[i]);
164 for(int j=0; j<ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES; j++)
165 if(elem_table_probability[j] == probs[i])
166 {
167 ret[i] = elem_table_log_probability[j];
168 break;
169 }
170 }
171 fesetround(curr_method);
172 return ret;
173 }
174
175 double get_loggamma_nominator(int x)
176 {
177 // calculate log gamma of the nominator calculated in the binomial exression.
178 int curr_method = fegetround();
179 fesetround(FE_UPWARD);
180 double ret = lgamma(x+1);
181 fesetround(curr_method);
182 return ret;
183 }
184
185
186 Marginal::Marginal(
187 const double* _masses,
188 const double* _probs,
189 int _isotopeNo,
190 int _atomCnt
191 ) :
192 disowned(false),
193 isotopeNo(_isotopeNo),
194 atomCnt(_atomCnt),
195 atom_masses(array_copy<double>(_masses, _isotopeNo)),
196 atom_lProbs(getMLogProbs(_probs, isotopeNo)),
197 loggamma_nominator(get_loggamma_nominator(_atomCnt)),
198 mode_conf(initialConfigure(atomCnt, isotopeNo, _probs, atom_lProbs)),
199 mode_lprob(loggamma_nominator+unnormalized_logProb(mode_conf, atom_lProbs, isotopeNo)),
200 mode_mass(mass(mode_conf, atom_masses, isotopeNo)),
201 mode_prob(exp(mode_lprob)),
202 smallest_lprob(atomCnt * *std::min_element(atom_lProbs, atom_lProbs+isotopeNo))
203 {
204 try
205 {
206 if(ISOSPEC_G_FACT_TABLE_SIZE-1 <= atomCnt)
207 throw std::length_error("Subisotopologue too large, size limit (that is, the maximum number of atoms of a single element in a molecule) is: " + std::to_string(ISOSPEC_G_FACT_TABLE_SIZE-1));
208 for(size_t ii = 0; ii < isotopeNo; ii++)
209 if(_probs[ii] <= 0.0 || _probs[ii] > 1.0)
210 throw std::invalid_argument("All isotope probabilities p must fulfill: 0.0 < p <= 1.0");
211 }
212 catch(...)
213 {
214 delete[] atom_masses;
215 delete[] atom_lProbs;
216 delete[] mode_conf;
217 throw;
218 }
219 }
220
221 // the move-constructor: used in the specialization of the marginal.
222 Marginal::Marginal(Marginal&& other) :
223 disowned(other.disowned),
224 isotopeNo(other.isotopeNo),
225 atomCnt(other.atomCnt),
226 atom_masses(other.atom_masses),
227 atom_lProbs(other.atom_lProbs),
228 loggamma_nominator(other.loggamma_nominator),
229 mode_conf(other.mode_conf),
230 mode_lprob(other.mode_lprob),
231 mode_mass(other.mode_mass),
232 mode_prob(other.mode_prob),
233 smallest_lprob(other.smallest_lprob)
234 {
235 other.disowned = true;
236 }
237
238 Marginal::~Marginal()
239 {
240 if(!disowned)
241 {
242 delete[] atom_masses;
243 delete[] atom_lProbs;
244 delete[] mode_conf;
245 }
246 }
247
248
249 double Marginal::getLightestConfMass() const
250 {
251 double ret_mass = std::numeric_limits<double>::infinity();
252 for(unsigned int ii=0; ii < isotopeNo; ii++)
253 if( ret_mass > atom_masses[ii] )
254 ret_mass = atom_masses[ii];
255 return ret_mass*atomCnt;
256 }
257
258 double Marginal::getHeaviestConfMass() const
259 {
260 double ret_mass = 0.0;
261 for(unsigned int ii=0; ii < isotopeNo; ii++)
262 if( ret_mass < atom_masses[ii] )
263 ret_mass = atom_masses[ii];
264 return ret_mass*atomCnt;
265 }
266
267 double Marginal::getMonoisotopicConfMass() const
268 {
269 double found_prob = -std::numeric_limits<double>::infinity();
270 double found_mass = 0.0; // to avoid uninitialized var warning
271 for(unsigned int ii=0; ii < isotopeNo; ii++)
272 if( found_prob < atom_lProbs[ii] )
273 {
274 found_prob = atom_lProbs[ii];
275 found_mass = atom_masses[ii];
276 }
277 return found_mass*atomCnt;
278 }
279
280 double Marginal::getTheoreticalAverageMass() const
281 {
282 double ret = 0.0;
283 for(unsigned int ii = 0; ii < isotopeNo; ii++)
284 ret += exp(atom_lProbs[ii]) * atom_masses[ii];
285 return ret * atomCnt;
286 }
287
288 // this is roughly an equivalent of IsoSpec-Threshold-Generator
289 MarginalTrek::MarginalTrek(
290 Marginal&& m,
291 int tabSize,
292 int hashSize
293 ) :
294 Marginal(std::move(m)),
295 current_count(0),
296 keyHasher(isotopeNo),
297 equalizer(isotopeNo),
298 orderMarginal(atom_lProbs, isotopeNo),
299 visited(hashSize,keyHasher,equalizer),
300 pq(orderMarginal),
301 totalProb(),
302 candidate(new int[isotopeNo]),
303 allocator(isotopeNo, tabSize)
304 {
305 int* initialConf = allocator.makeCopy(mode_conf);
306
307 pq.push(initialConf);
308 visited[initialConf] = 0;
309
310 totalProb = Summator();
311
312 current_count = 0;
313
314 add_next_conf();
315 }
316
317
318 bool MarginalTrek::add_next_conf()
319 {
320 /*!
321 Add next configuration.
322 If visited all, return false.
323 */
324 if(pq.size() < 1) return false;
325
326 Conf topConf = pq.top();
327 pq.pop();
328 ++current_count;
329 visited[topConf] = current_count;
330
331 _confs.push_back(topConf);
332 _conf_masses.push_back(mass(topConf, atom_masses, isotopeNo));
333 double logprob = logProb(topConf);
334 _conf_lprobs.push_back(logprob);
335
336
337 totalProb.add( exp( logprob ) );
338
339 for( unsigned int i = 0; i < isotopeNo; ++i )
340 {
341 for( unsigned int j = 0; j < isotopeNo; ++j )
342 {
343 // Growing index different than decreasing one AND
344 // Remain on simplex condition.
345 if( i != j && topConf[j] > 0 ){
346 copyConf(topConf, candidate, isotopeNo);
347
348 ++candidate[i];
349 --candidate[j];
350
351 // candidate should not have been already visited.
352 if( visited.count( candidate ) == 0 )
353 {
354 Conf acceptedCandidate = allocator.makeCopy(candidate);
355 pq.push(acceptedCandidate);
356
357 visited[acceptedCandidate] = 0;
358 }
359 }
360 }
361 }
362
363 return true;
364 }
365
366 int MarginalTrek::processUntilCutoff(double cutoff)
367 {
368 Summator s;
369 int last_idx = -1;
370 for(unsigned int i=0; i<_conf_lprobs.size(); i++)
371 {
372 s.add(_conf_lprobs[i]);
373 if(s.get() >= cutoff)
374 {
375 last_idx = i;
376 break;
377 }
378 }
379 if(last_idx > -1)
380 return last_idx;
381
382 while(totalProb.get() < cutoff && add_next_conf()) {}
383 return _conf_lprobs.size();
384 }
385
386
387 MarginalTrek::~MarginalTrek()
388 {
389 delete[] candidate;
390 }
391
392
393
394
395 PrecalculatedMarginal::PrecalculatedMarginal(Marginal&& m,
396 double lCutOff,
397 bool sort,
398 int tabSize,
399 int hashSize
400 ) : Marginal(std::move(m)),
401 allocator(isotopeNo, tabSize)
402 {
403 const ConfEqual equalizer(isotopeNo);
404 const KeyHasher keyHasher(isotopeNo);
405 const ConfOrderMarginalDescending orderMarginal(atom_lProbs, isotopeNo);
406
407 std::unordered_set<Conf,KeyHasher,ConfEqual> visited(hashSize,keyHasher,equalizer);
408
409 Conf currentConf = allocator.makeCopy(mode_conf);
410 if(logProb(currentConf) >= lCutOff)
411 {
412 // create a copy and store a ptr to the *same* copy in both structures
413 // (save some space and time)
414 auto tmp = allocator.makeCopy(currentConf);
415 configurations.push_back(tmp);
416 visited.insert(tmp);
417 }
418
419 unsigned int idx = 0;
420
421 while(idx < configurations.size())
422 {
423 memcpy(currentConf, configurations[idx], sizeof(int)*isotopeNo);
424 idx++;
425 for(unsigned int ii = 0; ii < isotopeNo; ii++ )
426 for(unsigned int jj = 0; jj < isotopeNo; jj++ )
427 if( ii != jj && currentConf[jj] > 0)
428 {
429 currentConf[ii]++;
430 currentConf[jj]--;
431
432 if (visited.count(currentConf) == 0 && logProb(currentConf) >= lCutOff)
433 {
434 // create a copy and store a ptr to the *same* copy in
435 // both structures (save some space and time)
436 auto tmp = allocator.makeCopy(currentConf);
437 visited.insert(tmp);
438 configurations.push_back(tmp);
439 // std::cout << " V: "; for (auto it : visited) std::cout << it << " "; std::cout << std::endl;
440 }
441
442 currentConf[ii]--;
443 currentConf[jj]++;
444
445 }
446 }
447
448 // orderMarginal defines the order of configurations (compares their logprobs)
449 // akin to key in Python sort.
450 if(sort)
451 std::sort(configurations.begin(), configurations.end(), orderMarginal);
452
453
454 confs = &configurations[0];
455 no_confs = configurations.size();
456 lProbs = new double[no_confs+1];
457 probs = new double[no_confs];
458 masses = new double[no_confs];
459
460
461 for(unsigned int ii=0; ii < no_confs; ii++)
462 {
463 lProbs[ii] = logProb(confs[ii]);
464 probs[ii] = exp(lProbs[ii]);
465 masses[ii] = mass(confs[ii], atom_masses, isotopeNo);
466 }
467 lProbs[no_confs] = -std::numeric_limits<double>::infinity();
468 }
469
470
471 PrecalculatedMarginal::~PrecalculatedMarginal()
472 {
473 if(lProbs != nullptr)
474 delete[] lProbs;
475 if(masses != nullptr)
476 delete[] masses;
477 if(probs != nullptr)
478 delete[] probs;
479 }
480
481
482
483
484 } // namespace IsoSpec
485
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <tuple>
19 #include <unordered_map>
20 #include <queue>
21 #include <atomic>
22 #include "conf.h"
23 #include "allocator.h"
24 #include "operators.h"
25 #include "summator.h"
26
27
28 namespace IsoSpec
29 {
30
31 Conf initialConfigure(int atomCnt, int isotopeNo, const double* probs);
32
33
34 void printMarginal(const std::tuple<double*,double*,int*,int>& results, int dim);
35
36 //! The marginal distribution class (a subisotopologue).
37 /*!
38 This class mostly provides some basic common API for subclasses, but itself is not abstract.
39 This class represents the probability distribution generated by one element only -- a subisotopologue.
40 For instance, it might be the distribution of C200, that might be part of, say, C200H402.
41 It corresponds to the multinomial distribution, where each configuration can also be attributed a precise mass.
42 The constructor method perform initial hill-climbing to find the most probable sub-isotopologue (the mode).
43 */
44 class Marginal
45 {
46 private:
47 bool disowned;
48 protected:
49 const unsigned int isotopeNo; /*!< The number of isotopes of the given element. */
50 const unsigned int atomCnt; /*!< The number of atoms of the given element. */
51 const double* const atom_masses; /*!< Table of atomic masses of all the isotopeNo isotopes. */
52 const double* const atom_lProbs; /*!< Table of log-probabilities of all the isotopeNo isotopes. */
53 const double loggamma_nominator; /*!< The constant nominator that appears in the expressions for the multinomial probabilities. */
54 const Conf mode_conf; /*!< A subisotopologue with most probability. If not unique, one of the representatives of that class of subisotopologues. */
55 const double mode_lprob; /*!< The log-probability of the mode subisotopologue.*/
56 const double mode_mass; /*!< The mass of the mode subisotopologue.*/
57 const double mode_prob; /*!< The probability of the mode subisotopologue.*/
58 const double smallest_lprob; /*!< The smallest-achievable log-probability in the distribution of subisotopologues. */
59
60
61 public:
62 //! Class constructor.
63 /*!
64 \param _masses A table of masses of the stable isotopes of the investigated element, e.g. for C10 it is 2: C12 and C13.
65 \param _probs A table of natural frequencies of the stable isotopes of the investigated element, see IUPAC at https://iupac.org/isotopesmatter/
66 \param _isotopeNo Number of isotopes of a given element.
67 \param _atomCnt The number of atoms of the given element, e.g. 10 for C10.
68 \return An instance of the Marginal class.
69 */
70 Marginal(
71 const double* _masses, // masses size = logProbs size = isotopeNo
72 const double* _probs,
73 int _isotopeNo,
74 int _atomCnt
75 );
76
77 // Get rid of the C++ generated copy and assignment constructors.
78 Marginal(Marginal& other) = delete;
79 Marginal& operator= (const Marginal& other) = delete;
80
81 //! Move constructor.
82 Marginal(Marginal&& other);
83
84 //! Destructor.
85 virtual ~Marginal();
86
87 //! Get the number of isotopes of the investigated element.
88 /*!
89 \return The integer number of isotopes of the investigated element.
90 */
91 inline int get_isotopeNo() const { return isotopeNo; };
92
93 //! Get the mass of the lightest subisotopologue.
94 /*! This is trivially obtained by considering all atomNo atoms to be the lightest isotope possible.
95 \return The mass of the lightiest subisotopologue.
96 */
97 double getLightestConfMass() const;
98
99 //! Get the mass of the heaviest subisotopologue.
100 /*! This is trivially obtained by considering all atomNo atoms to be the heaviest isotope possible.
101 \return The mass of the heaviest subisotopologue.
102 */
103 double getHeaviestConfMass() const;
104
105 //! Get the mass of the monoisotopic subisotopologue.
106 /*! The monoisotopic subisotopologue is defined as the molecule consiting only
107 of the most likely isotope. This is frequently the lightest subisotopologue,
108 making this frequently (but not always) eqial to getLightestconfMass()
109 */
110 double getMonoisotopicConfMass() const;
111
112 //! Get the log-probability of the mode subisotopologue.
113 /*!
114 \return The log-probability of a/the most probable subisotopologue.
115 */
116 inline double getModeLProb() const { return mode_lprob; };
117
118 //! The the mass of the mode subisotopologue.
119 /*!
120 \return The mass of one of the most probable subisotopologues.
121 */
122 inline double getModeMass() const { return mode_mass; };
123
124 //! The the probability of the mode subisotopologue.
125 /*!
126 \return The probability of a/the most probable subisotopologue.
127 */
128 inline double getModeProb() const { return mode_prob; };
129
130 //! The the log-probability of the lightest subisotopologue.
131 /*!
132 \return The logarithm of the smallest non-zero probability of a subisotopologue.
133 */
134 inline double getSmallestLProb() const { return smallest_lprob; };
135
136 //! The theoretical average mass of the molecule.
137 /*!
138 \return The theoretical average mass of the molecule.
139 */
140 double getTheoreticalAverageMass() const;
141
142 //! Calculate the log-probability of a given subisotopologue.
143 /*!
144 \param conf A subisotopologue (a table of integers describing subsequent isotope-counts).
145 \return The log-probability of the input subisotopologue.
146 */
147 inline double logProb(Conf conf) const { return loggamma_nominator + unnormalized_logProb(conf, atom_lProbs, isotopeNo); };
148 };
149
150
151 //! The marginal distribution class (a subisotopologue).
152 class MarginalTrek : public Marginal
153 {
154 private:
155 int current_count;
156 const KeyHasher keyHasher;
157 const ConfEqual equalizer;
158 const ConfOrderMarginal orderMarginal;
159 std::unordered_map<Conf,int,KeyHasher,ConfEqual> visited;
160 std::priority_queue<Conf,std::vector<Conf>,ConfOrderMarginal> pq;
161 Summator totalProb;
162 Conf candidate;
163 Allocator<int> allocator;
164 std::vector<double> _conf_lprobs;
165 std::vector<double> _conf_masses;
166 std::vector<int*> _confs;
167
168 //! Proceed to the next configuration and memoize it (as it will be surely needed).
169 bool add_next_conf();
170
171 public:
172 //! Move constructor: specializes the Marginal class.
173 /*!
174 \param tabSize The size of the table used to store configurations in the allocator.
175 \param hashSize The size of the hash table used to store visited subisotopologues.
176 */
177 MarginalTrek(
178 Marginal&& m,
179 int tabSize = 1000,
180 int hashSize = 1000
181 );
182
183 //! Check if the table of computed subisotopologues does not have to be extended.
184 /*!
185 This function checks if the idx-th most probable subisotopologue was memoized and if not, computes it and memoizes it.
186
187 \param idx The number of the idx-th most probable subisotopologue.
188 \return Returns false if it the provided idx exceeds the total number of subisotopologues.
189 */
190 inline bool probeConfigurationIdx(int idx)
191 {
192 while(current_count <= idx)
193 if(!add_next_conf())
194 return false;
195 return true;
196 }
197
198
199 //! Calculate subisotopologues with probability above or equal to the cut-off.
200 /*!
201 \param cutoff The probability cut-off
202 \return The number of the last subisotopologue above the cut-off.
203 */
204 int processUntilCutoff(double cutoff);
205
206 inline const std::vector<double>& conf_lprobs() const { return _conf_lprobs; };
207 inline const std::vector<double>& conf_masses() const { return _conf_masses; };
208 inline const std::vector<int*>& confs() const { return _confs; };
209
210
211 virtual ~MarginalTrek();
212 };
213
214
215 //! Precalculated Marginal class
216 /*!
217 This class serves to calculate a set of isotopologues that
218 is defined by the minimal probability threshold.
219
220 This works faster than if you did not know the threshold.
221 If you have no idea about the threshold, you would need to call us,
222 to change encode the layered version of the marginal.
223 */
224 class PrecalculatedMarginal : public Marginal
225 {
226 protected:
227 std::vector<Conf> configurations;
228 Conf* confs;
229 unsigned int no_confs;
230 double* masses;
231 double* lProbs;
232 double* probs;
233 Allocator<int> allocator;
234 public:
235 //! The move constructor (disowns the Marginal).
236 /*!
237 This constructor memoizes all subisotopologues with log-probability above the provided threshold lCutOff
238 \param Marginal An instance of the Marginal class this class is about to disown.
239 \param lCutOff The lower limit on the log-probability of the precomputed subisotopologues.
240 \param sort Should the subisotopologues be stored with descending probability ?
241 \return An instance of the PrecalculatedMarginal class.
242 */
243 PrecalculatedMarginal(
244 Marginal&& m,
245 double lCutOff,
246 bool sort = true,
247 int tabSize = 1000,
248 int hashSize = 1000
249 );
250
251 //! Destructor.
252 virtual ~PrecalculatedMarginal();
253
254 //! Is there a subisotopologue with a given number?
255 /*!
256 \return Returns true if idx does not exceed the number of pre-computed configurations.
257 */
258 inline bool inRange(unsigned int idx) const { return idx < no_confs; };
259
260 //! Get the log-probability of the idx-th subisotopologue.
261 /*!
262 \param idx The number of the considered subisotopologue.
263 \return The log-probability of the idx-th subisotopologue.
264 */
265 inline const double& get_lProb(int idx) const { return lProbs[idx]; };
266
267 //! Get the probability of the idx-th subisotopologue.
268 /*!
269 \param idx The number of the considered subisotopologue.
270 \return The probability of the idx-th subisotopologue.
271 */
272 inline const double& get_prob(int idx) const { return probs[idx]; };
273
274 //! Get the mass of the idx-th subisotopologue.
275 /*!
276 \param idx The number of the considered subisotopologue.
277 \return The mass of the idx-th subisotopologue.
278 */
279 inline const double& get_mass(int idx) const { return masses[idx]; };
280
281 //! Get the table of the log-probabilities of subisotopologues.
282 /*!
283 \return Pointer to the first element in the table storing log-probabilities of subisotopologues.
284 */
285 inline const double* get_lProbs_ptr() const { return lProbs; };
286
287 //! Get the table of the masses of subisotopologues.
288 /*!
289 \return Pointer to the first element in the table storing masses of subisotopologues.
290 */
291 inline const double* get_masses_ptr() const { return masses; };
292
293
294 //! Get the counts of isotopes that define the subisotopologue.
295 /*!
296 \param idx The number of the considered subisotopologue.
297 \return The counts of isotopes that define the subisotopologue.
298 */
299 inline const Conf& get_conf(int idx) const { return confs[idx]; };
300
301 //! Get the number of precomputed subisotopologues.
302 /*!
303 \return The number of precomputed subisotopologues.
304 */
305 inline unsigned int get_no_confs() const { return no_confs; };
306 };
307
308 } // namespace IsoSpec
309
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16
17 #include "misc.h"
18 #include "platform.h"
19 #include <stdlib.h>
20
21 #define mswap(x, y) swapspace = x; x = y; y=swapspace;
22
23
24 namespace IsoSpec
25 {
26
27 void* quickselect(void** array, int n, int start, int end)
28 {
29 void* swapspace;
30
31 if(start == end)
32 return array[start];
33
34 while(true)
35 {
36 // Partition part
37 int len = end - start;
38 #if ISOSPEC_BUILDING_R
39 int pivot = len/2 + start;
40 #else
41 int pivot = rand() % len + start;
42 #endif
43 void* pval = array[pivot];
44 double pprob = getLProb(pval);
45 mswap(array[pivot], array[end-1]);
46 int loweridx = start;
47 for(int i=start; i<end-1; i++)
48 {
49 if(getLProb(array[i]) < pprob)
50 {
51 mswap(array[i], array[loweridx]);
52 loweridx++;
53 }
54 }
55 mswap(array[end-1], array[loweridx]);
56
57 // Selection part
58 if(n==loweridx)
59 return array[n];
60 if(n<loweridx)
61 end = loweridx;
62 else
63 start = loweridx+1;
64 };
65 }
66
67 } // namespace IsoSpec
68
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <iostream>
19 #include <tuple>
20 #include <vector>
21 #include <fenv.h>
22 #include "isoMath.h"
23
24 namespace IsoSpec
25 {
26
27 inline double combinedSum(
28 const int* conf, const std::vector<double>** valuesContainer, int dimNumber
29 ){
30 double res = 0.0;
31 for(int i=0; i<dimNumber;i++)
32 res += (*(valuesContainer[i]))[conf[i]];
33 return res;
34 }
35
36 inline int* getConf(void* conf)
37 {
38 return reinterpret_cast<int*>(
39 reinterpret_cast<char*>(conf) + sizeof(double)
40 );
41 }
42
43 inline double getLProb(void* conf)
44 {
45 double ret = *reinterpret_cast<double*>(conf);
46 return ret;
47 }
48
49
50 inline double unnormalized_logProb(const int* conf, const double* logProbs, int dim)
51 {
52 double res = 0.0;
53
54 int curr_method = fegetround();
55
56 fesetround(FE_TOWARDZERO);
57
58 for(int i=0; i < dim; i++)
59 res += minuslogFactorial(conf[i]);
60
61 fesetround(FE_UPWARD);
62
63 for(int i=0; i < dim; i++)
64 res += conf[i] * logProbs[i];
65
66 fesetround(curr_method);
67
68 return res;
69 }
70
71 inline double mass(const int* conf, const double* masses, int dim)
72 {
73 double res = 0.0;
74
75 for(int i=0; i < dim; i++)
76 {
77 res += conf[i] * masses[i];
78 }
79
80 return res;
81 }
82
83
84 inline bool tupleCmp(
85 std::tuple<double,double,int*> t1,
86 std::tuple<double,double,int*> t2
87 ){
88 return std::get<1>(t1) > std::get<1>(t2);
89 }
90
91 template<typename T> void printArray(const T* array, int size)
92 {
93 for (int i=0; i<size; i++)
94 std::cout << array[i] << " ";
95 std::cout << std::endl;
96 }
97
98 template<typename T> void printVector(const std::vector<T>& vec)
99 {
100 printArray<T>(vec.data(), vec.size());
101 }
102
103
104 template<typename T> void printNestedArray(const T** array, const int* shape, int size)
105 {
106 for (int i=0; i<size; i++)
107 printArray(array[i], shape[i]);
108 std::cout << std::endl;
109 }
110
111 #define mswap(x, y) swapspace = x; x = y; y=swapspace;
112
113
114 //! Quickly select the n'th positional statistic, including the weights.
115 void* quickselect(void** array, int n, int start, int end);
116
117
118 template <typename T> inline static T* array_copy(const T* A, int size)
119 {
120 T* ret = new T[size];
121 memcpy(ret, A, size*sizeof(T));
122 return ret;
123 }
124
125 template<typename T> void dealloc_table(T* tbl, int dim)
126 {
127 for(int i=0; i<dim; i++)
128 {
129 delete tbl[i];
130 }
131 delete[] tbl;
132 }
133
134 } // namespace IsoSpec
135
0 /*
1 * This file has been included as a part of IsoSpec project, under a MIT licence. It
2 * comes from the repository:
3 *
4 * https://github.com/witwall/mman-win32
5 *
6 * which itself is a mirror of:
7 *
8 * https://code.google.com/archive/p/mman-win32/
9 */
10
11 #include "platform.h"
12 #if ISOSPEC_GOT_MMAN && !ISOSPEC_GOT_SYSTEM_MMAN
13
14 #include <windows.h>
15 #include <errno.h>
16 #include <io.h>
17
18 #include "mman.h"
19
20 #ifndef FILE_MAP_EXECUTE
21 #define FILE_MAP_EXECUTE 0x0020
22 #endif /* FILE_MAP_EXECUTE */
23
24
25 static int __map_mman_error(const DWORD err, const int deferr)
26 {
27 if (err == 0)
28 return 0;
29 //TODO: implement
30 return err;
31 }
32
33 static DWORD __map_mmap_prot_page(const int prot)
34 {
35 DWORD protect = 0;
36
37 if (prot == PROT_NONE)
38 return protect;
39
40 if ((prot & PROT_EXEC) != 0)
41 {
42 protect = ((prot & PROT_WRITE) != 0) ?
43 PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
44 }
45 else
46 {
47 protect = ((prot & PROT_WRITE) != 0) ?
48 PAGE_READWRITE : PAGE_READONLY;
49 }
50
51 return protect;
52 }
53
54 static DWORD __map_mmap_prot_file(const int prot)
55 {
56 DWORD desiredAccess = 0;
57
58 if (prot == PROT_NONE)
59 return desiredAccess;
60
61 if ((prot & PROT_READ) != 0)
62 desiredAccess |= FILE_MAP_READ;
63 if ((prot & PROT_WRITE) != 0)
64 desiredAccess |= FILE_MAP_WRITE;
65 if ((prot & PROT_EXEC) != 0)
66 desiredAccess |= FILE_MAP_EXECUTE;
67
68 return desiredAccess;
69 }
70
71 void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off)
72 {
73 HANDLE fm, h;
74
75 void * map = MAP_FAILED;
76
77 #ifdef _MSC_VER
78 #pragma warning(push)
79 #pragma warning(disable: 4293)
80 #endif
81
82 const DWORD dwFileOffsetLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
83 (DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
84 const DWORD dwFileOffsetHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
85 (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
86 const DWORD protect = __map_mmap_prot_page(prot);
87 const DWORD desiredAccess = __map_mmap_prot_file(prot);
88
89 const OffsetType maxSize = off + (OffsetType)len;
90
91 const DWORD dwMaxSizeLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
92 (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
93 const DWORD dwMaxSizeHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
94 (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
95
96 #ifdef _MSC_VER
97 #pragma warning(pop)
98 #endif
99
100 errno = 0;
101
102 if (len == 0
103 /* Unsupported flag combinations */
104 || (flags & MAP_FIXED) != 0
105 /* Usupported protection combinations */
106 || prot == PROT_EXEC)
107 {
108 errno = EINVAL;
109 return MAP_FAILED;
110 }
111
112 h = ((flags & MAP_ANONYMOUS) == 0) ?
113 (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;
114
115 if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
116 {
117 errno = EBADF;
118 return MAP_FAILED;
119 }
120
121 fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
122
123 if (fm == NULL)
124 {
125 errno = __map_mman_error(GetLastError(), EPERM);
126 return MAP_FAILED;
127 }
128
129 map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
130
131 CloseHandle(fm);
132
133 if (map == NULL)
134 {
135 errno = __map_mman_error(GetLastError(), EPERM);
136 return MAP_FAILED;
137 }
138
139 return map;
140 }
141
142 int munmap(void *addr, size_t len)
143 {
144 if (UnmapViewOfFile(addr))
145 return 0;
146
147 errno = __map_mman_error(GetLastError(), EPERM);
148
149 return -1;
150 }
151
152 int _mprotect(void *addr, size_t len, int prot)
153 {
154 DWORD newProtect = __map_mmap_prot_page(prot);
155 DWORD oldProtect = 0;
156
157 if (VirtualProtect(addr, len, newProtect, &oldProtect))
158 return 0;
159
160 errno = __map_mman_error(GetLastError(), EPERM);
161
162 return -1;
163 }
164
165 int msync(void *addr, size_t len, int flags)
166 {
167 if (FlushViewOfFile(addr, len))
168 return 0;
169
170 errno = __map_mman_error(GetLastError(), EPERM);
171
172 return -1;
173 }
174
175 int mlock(const void *addr, size_t len)
176 {
177 if (VirtualLock((LPVOID)addr, len))
178 return 0;
179
180 errno = __map_mman_error(GetLastError(), EPERM);
181
182 return -1;
183 }
184
185 int munlock(const void *addr, size_t len)
186 {
187 if (VirtualUnlock((LPVOID)addr, len))
188 return 0;
189
190 errno = __map_mman_error(GetLastError(), EPERM);
191
192 return -1;
193 }
194
195
196 #endif
0 /*
1 * sys/mman.h
2 * mman-win32
3 *
4 * This file has been included as a part of IsoSpec project, under a MIT licence. It
5 * comes from the repository:
6 *
7 * https://github.com/witwall/mman-win32
8 *
9 * which itself is a mirror of:
10 *
11 * https://code.google.com/archive/p/mman-win32/
12 */
13
14 #pragma once
15
16 #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
17 #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
18 #endif
19
20 /* All the headers include this file. */
21 #ifndef _MSC_VER
22 #include <_mingw.h>
23 #endif
24
25 /* Determine offset type */
26 #include <stdint.h>
27 #if defined(_WIN64)
28 typedef int64_t OffsetType;
29 #else
30 typedef uint32_t OffsetType;
31 #endif
32
33 #include <sys/types.h>
34
35
36 #define PROT_NONE 0
37 #define PROT_READ 1
38 #define PROT_WRITE 2
39 #define PROT_EXEC 4
40
41 #define MAP_FILE 0
42 #define MAP_SHARED 1
43 #define MAP_PRIVATE 2
44 #define MAP_TYPE 0xf
45 #define MAP_FIXED 0x10
46 #define MAP_ANONYMOUS 0x20
47 #define MAP_ANON MAP_ANONYMOUS
48
49 #define MAP_FAILED ((void *)-1)
50
51 /* Flags for msync. */
52 #define MS_ASYNC 1
53 #define MS_SYNC 2
54 #define MS_INVALIDATE 4
55
56 void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off);
57 int munmap(void *addr, size_t len);
58 int _mprotect(void *addr, size_t len, int prot);
59 int msync(void *addr, size_t len, int flags);
60 int mlock(const void *addr, size_t len);
61 int munlock(const void *addr, size_t len);
62
63
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #include "operators.h"
17 #include "marginalTrek++.h"
18
19 namespace IsoSpec
20 {
21
22 KeyHasher::KeyHasher(int _dim)
23 : dim(_dim)
24 {}
25
26 ConfEqual::ConfEqual(int dim)
27 : size( dim*sizeof(int) )
28 {}
29
30 ConfOrderMarginal::ConfOrderMarginal(const double* _logProbs, int _dim)
31 : logProbs(_logProbs), dim(_dim)
32 {}
33
34 ConfOrderMarginalDescending::ConfOrderMarginalDescending(const double* _logProbs, int _dim)
35 : logProbs(_logProbs), dim(_dim)
36 {}
37
38
39 OrderMarginalsBySizeDecresing::OrderMarginalsBySizeDecresing(PrecalculatedMarginal const* const * const _T) : T(_T) {}
40
41 bool OrderMarginalsBySizeDecresing::operator()(int m1, int m2)
42 {
43 return T[m1]->get_no_confs() > T[m2]->get_no_confs();
44 }
45
46
47 } // namespace IsoSpec
48
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <string.h>
19 #include "conf.h"
20 #include "isoMath.h"
21 #include "misc.h"
22
23 namespace IsoSpec
24 {
25
26 class KeyHasher
27 {
28 private:
29 int dim;
30 public:
31 KeyHasher(int dim);
32
33 inline std::size_t operator()(const int* conf) const
34 {
35 // Following Boost...
36 std::size_t seed = 0;
37 for(int i = 0; i < dim; ++i )
38 seed ^= conf[i] + 0x9e3779b9 + (seed << 6) + (seed >> 2);
39 return seed;
40 };
41 };
42
43
44 class ConfEqual
45 {
46 private:
47 int size;
48 public:
49 ConfEqual(int dim);
50
51 inline bool operator()(const int* conf1, const int* conf2) const
52 {
53 // The memcmp() function returns zero if the two strings are identical, oth-
54 // erwise returns the difference between the first two differing bytes
55 // (treated as unsigned char values, so that `\200' is greater than `\0',
56 // for example). Zero-length strings are always identical. This behavior
57 // is not required by C and portable code should only depend on the sign of
58 // the returned value.
59 // sacred man of memcmp.
60 return memcmp(conf1, conf2, size) == 0;
61 }
62 };
63
64
65 class ConfOrder
66 {
67 //configurations comparator
68 public:
69 inline bool operator()(void* conf1,void* conf2) const
70 {
71 return *reinterpret_cast<double*>(conf1) < *reinterpret_cast<double*>(conf2);
72 };
73 };
74
75
76
77 class ConfOrderMarginal
78 {
79 //configurations comparator
80 const double* logProbs;
81 int dim;
82 public:
83 ConfOrderMarginal(const double* logProbs, int dim);
84
85 inline bool operator()(const Conf conf1, const Conf conf2)
86 {// Return true if conf1 is less probable than conf2.
87 return unnormalized_logProb(conf1,logProbs,dim) < unnormalized_logProb(conf2,logProbs,dim);
88 };
89 };
90
91 class ConfOrderMarginalDescending
92 {
93 //configurations comparator
94 const double* logProbs;
95 int dim;
96 public:
97 ConfOrderMarginalDescending(const double* logProbs, int dim);
98
99 inline bool operator()(const Conf conf1, const Conf conf2)
100 {// Return true if conf1 is less probable than conf2.
101 return unnormalized_logProb(conf1,logProbs,dim) > unnormalized_logProb(conf2,logProbs,dim);
102 };
103 };
104
105 template<typename T> class ReverseOrder
106 {
107 public:
108 inline ReverseOrder() {};
109 inline bool operator()(const T a,const T b) const { return a > b; };
110 };
111
112 template<typename T> class TableOrder
113 {
114 const T* tbl;
115 public:
116 inline TableOrder(const T* _tbl) : tbl(_tbl) {};
117 inline bool operator()(unsigned int i, unsigned int j) { return tbl[i] < tbl[j]; };
118 };
119
120 } // namespace IsoSpec
121
122 #include "marginalTrek++.h"
123
124 class PrecalculatedMarginal; // In case marginalTrek++.h us including us, and can't be included again...
125
126 namespace IsoSpec
127 {
128
129 class OrderMarginalsBySizeDecresing
130 {
131 PrecalculatedMarginal const* const* const T;
132 public:
133 OrderMarginalsBySizeDecresing(PrecalculatedMarginal const* const * const _T);
134 bool operator()(int m1, int m2);
135 };
136
137
138 } // namespace IsoSpec
139
140
141
0
1 #pragma once
2
3 #if !defined(ISOSPEC_BUILDING_R)
4 #define ISOSPEC_BUILDING_R false
5 #endif
6
7 #if !defined(ISOSPEC_BUILDING_CPP)
8 #define ISOSPEC_BUILDING_CPP true
9 #endif
10
11 #if !defined(ISOSPEC_BUILDING_PYTHON)
12 #define ISOSPEC_BUILDING_PYTHON false
13 #endif
14
15 #if !defined(ISOSPEC_BUILDING_OPENMS)
16 #define ISOSPEC_BUILDING_OPENMS false
17 #endif
18
19 #if defined(__unix__) || defined(__unix) || \
20 (defined(__APPLE__) && defined(__MACH__))
21 #define ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY true
22 #define ISOSPEC_TEST_WE_ARE_ON_WINDOWS false /* CYGWIN doesn't really count as Windows for our purposes, we'll be using UNIX API anyway */
23 #define ISOSPEC_TEST_GOT_SYSTEM_MMAN true
24 #define ISOSPEC_TEST_GOT_MMAN true
25 #elif defined(__MINGW32__) || defined(_WIN32)
26 #define ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY false
27 #define ISOSPEC_TEST_WE_ARE_ON_WINDOWS true
28 #define ISOSPEC_TEST_GOT_SYSTEM_MMAN false
29 #define ISOSPEC_TEST_GOT_MMAN true
30 #else
31 #define ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY false /* Well, probably... */
32 #define ISOSPEC_TEST_WE_ARE_ON_WINDOWS false
33 #define ISOSPEC_TEST_GOT_SYSTEM_MMAN false
34 #define ISOSPEC_TEST_GOT_MMAN false
35 #endif
36
37 #if !defined(ISOSPEC_USE_PTHREADS)
38 #define ISOSPEC_USE_PTHREADS false /* TODO: possibly put a macro here to detect whether we */
39 #endif /* can/should use pthreads - or rip them out altogether.
40 * Investigate whether the performance advantage of pthreads on
41 * some platforms (*cough* CYGWIN *cough*) is still large
42 * enough to justify keeping both implementations around */
43
44 #if !defined(ISOSPEC_WE_ARE_ON_UNIX_YAY)
45 #define ISOSPEC_WE_ARE_ON_UNIX_YAY ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY
46 #endif
47
48 #if !defined(ISOSPEC_WE_ARE_ON_WINDOWS)
49 #define ISOSPEC_WE_ARE_ON_WINDOWS ISOSPEC_TEST_WE_ARE_ON_WINDOWS
50 #endif
51
52 #if !defined(ISOSPEC_GOT_SYSTEM_MMAN)
53 #define ISOSPEC_GOT_SYSTEM_MMAN ISOSPEC_TEST_GOT_SYSTEM_MMAN
54 #endif
55
56 #if !defined(ISOSPEC_GOT_MMAN)
57 #define ISOSPEC_GOT_MMAN ISOSPEC_TEST_GOT_MMAN
58 #endif
59
60
61 // Note: __GNUC__ is defined by clang and gcc
62 #ifdef __GNUC__
63 #define ISOSPEC_LIKELY(condition) __builtin_expect(static_cast<bool>(condition), 1)
64 #define ISOSPEC_UNLIKELY(condition) __builtin_expect(static_cast<bool>(condition), 0)
65 // For aggressive inlining
66 #define ISOSPEC_FORCE_INLINE __attribute__ ((always_inline)) inline
67 #elif defined _MSC_VER
68 #define ISOSPEC_LIKELY(condition) condition
69 #define ISOSPEC_UNLIKELY(condition) condition
70 #define ISOSPEC_FORCE_INLINE __forceinline inline
71 #else
72 #define ISOSPEC_LIKELY(condition) condition
73 #define ISOSPEC_UNLIKELY(condition) condition
74 #define ISOSPEC_FORCE_INLINE inline
75 #endif
76
77
78 #if ISOSPEC_GOT_MMAN
79 #if ISOSPEC_GOT_SYSTEM_MMAN
80 #include <sys/mman.h>
81 #else
82 #include "mman.h"
83 #endif
84 #else
85 #include <stdlib.h> /* malloc, free, rand */
86 #endif
87
88
89 #if defined(OPENMS_DLLAPI) /* IsoSpec is being built as a part of OpenMS: use their visibility macros */
90 #define ISOSPEC_EXPORT_SYMBOL OPENMS_DLLAPI
91 #else /* it's a can of worms we don't yet want to open ourselves though... */
92 #define ISOSPEC_EXPORT_SYMBOL
93 #endif
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <cmath>
19 #include <atomic>
20
21 namespace IsoSpec
22 {
23
24 class SSummator
25 {
26 // Shewchuk algorithm
27 std::vector<double> partials;
28 int maxpart;
29 public:
30 inline SSummator()
31 { maxpart = 0; }
32
33 inline SSummator(SSummator& other)
34 {
35 this->partials = other.partials;
36 this->maxpart = other.maxpart;
37 }
38 inline void add(double x)
39 {
40 unsigned int i=0;
41 for(int pidx=0; pidx<maxpart; pidx++)
42 {
43 double y = partials[pidx];
44 if(std::abs(x) < std::abs(y))
45 std::swap(x, y);
46 double hi = x+y;
47 double lo = y-(hi-x);
48 if(lo != 0.0)
49 {
50 partials[i] = lo;
51 i += 1;
52 }
53 x = hi;
54 }
55 while(partials.size() <= i)
56 partials.push_back(0.0);
57 partials[i] = x;
58 maxpart = i+1;
59 }
60 inline double get()
61 {
62 double ret = 0.0;
63 for(int i=0; i<maxpart; i++)
64 ret += partials[i];
65 return ret;
66 }
67 };
68
69
70
71
72
73
74
75 class Summator{
76 // Kahan algorithm
77 double sum;
78 double c;
79
80 public:
81 inline Summator()
82 { sum = 0.0; c = 0.0;}
83
84 inline void add(double what)
85 {
86 double y = what - c;
87 double t = sum + y;
88 c = (t - sum) - y;
89 sum = t;
90 }
91
92 inline double get()
93 {
94 return sum;
95 }
96 };
97
98 class TSummator
99 {
100 // Trivial algorithm, for testing only
101 double sum;
102 public:
103 inline TSummator()
104 { sum = 0.0; }
105
106 inline void add(double what)
107 {
108 sum += what;
109 }
110 inline double get()
111 {
112 return sum;
113 }
114 };
115
116
117 } // namespace IsoSpec
118
0 #include "tabulator.h"
1
2
3 namespace IsoSpec
4 {
5 template class Tabulator<IsoThresholdGenerator>;
6 template class Tabulator<IsoLayeredGenerator>;
7 } // namespace IsoSpec
0 #pragma once
1
2 #include <stdlib.h>
3
4 #include "isoSpec++.h"
5
6 #define ISOSPEC_INIT_TABLE_SIZE 1024
7
8 namespace IsoSpec
9 {
10
11 template <typename T> class Tabulator
12 {
13 private:
14 double* _masses;
15 double* _lprobs;
16 double* _probs;
17 int* _confs;
18 size_t _confs_no;
19 public:
20 Tabulator(T* generator,
21 bool get_masses, bool get_probs,
22 bool get_lprobs, bool get_confs);
23
24 ~Tabulator();
25
26 inline double* masses(bool release = false) { double* ret = _masses; if(release) _masses = nullptr; return ret; };
27 inline double* lprobs(bool release = false) { double* ret = _lprobs; if(release) _lprobs = nullptr; return ret; };
28 inline double* probs(bool release = false) { double* ret = _probs; if(release) _probs = nullptr; return ret; };
29 inline int* confs(bool release = false) { int* ret = _confs; if(release) _confs = nullptr; return ret; };
30 inline size_t confs_no() { return _confs_no; };
31 };
32
33 inline void reallocate(double **array, int new_size){
34 if( *array != nullptr ){
35 *array = (double *) realloc(*array, new_size);
36 }
37 }
38
39 template <typename T> Tabulator<T>::Tabulator(T* generator,
40 bool get_masses, bool get_probs,
41 bool get_lprobs, bool get_confs )
42 {
43 size_t current_size = ISOSPEC_INIT_TABLE_SIZE;
44 int confs_tbl_idx = 0;
45 _confs_no = 0;
46
47 const int allDimSizeOfInt = sizeof(int)*generator->getAllDim();
48
49 _masses = get_masses ? (double *) malloc(ISOSPEC_INIT_TABLE_SIZE * sizeof(double)) : nullptr;
50 _lprobs = get_lprobs ? (double *) malloc(ISOSPEC_INIT_TABLE_SIZE * sizeof(double)) : nullptr;
51 _probs = get_probs ? (double *) malloc(ISOSPEC_INIT_TABLE_SIZE * sizeof(double)) : nullptr;
52 _confs = get_confs ? (int *) malloc(ISOSPEC_INIT_TABLE_SIZE * allDimSizeOfInt): nullptr;
53
54
55 while(generator->advanceToNextConfiguration()){
56 if( _confs_no == current_size )
57 {
58 current_size *= 2;
59
60 // FIXME: Handle overflow gracefully here. It definitely could happen for people still stuck on 32 bits...
61
62 reallocate(&_masses, current_size * sizeof(double));
63 reallocate(&_lprobs, current_size * sizeof(double));
64 reallocate(&_probs, current_size * sizeof(double));
65
66 if( _confs != nullptr ){
67 _confs = (int *) realloc(_confs, current_size * allDimSizeOfInt);
68 }
69 }
70
71 if(_masses != nullptr) _masses[_confs_no] = generator->mass();
72
73 if(_lprobs != nullptr) _lprobs[_confs_no] = generator->lprob();
74
75 if(_probs != nullptr) _probs[_confs_no] = generator->prob();
76
77 if(_confs != nullptr){
78 generator->get_conf_signature(_confs + confs_tbl_idx);
79 confs_tbl_idx += generator->getAllDim();
80 }
81
82 _confs_no++;
83 }
84
85 _masses = (double *) realloc(_masses, _confs_no * sizeof(double));
86 _lprobs = (double *) realloc(_lprobs, _confs_no * sizeof(double));
87 _probs = (double *) realloc(_probs, _confs_no * sizeof(double));
88 _confs = (int *) realloc(_confs, confs_tbl_idx * sizeof(int));
89 }
90
91 template <typename T> Tabulator<T>::~Tabulator()
92 {
93 if( _masses != nullptr ) free(_masses);
94 if( _lprobs != nullptr ) free(_lprobs);
95 if( _probs != nullptr ) free(_probs);
96 if( _confs != nullptr ) free(_confs);
97 }
98
99 } // namespace IsoSpec
100
0 #include "platform.h"
1
2 #if !ISOSPEC_BUILDING_R
3
4 #if !ISOSPEC_GOT_SYSTEM_MMAN && ISOSPEC_GOT_MMAN
5 #include "mman.cpp"
6 #endif
7
8 #include "allocator.cpp"
9 #include "dirtyAllocator.cpp"
10 #include "isoSpec++.cpp"
11 #include "isoMath.cpp"
12 #include "marginalTrek++.cpp"
13 #include "operators.cpp"
14 #include "element_tables.cpp"
15 #include "cwrapper.cpp"
16 #include "tabulator.cpp"
17 #include "misc.cpp"
18
19 #endif
0 # -*- coding: utf-8 -*-
1 #
2 # Copyright (C) 2015-2018 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 '''
19 Bunch of deprecated functions for 1.0.X compatibility.
20 Avoid using them: there is a considerable overhead associated
21 with using the old interface... The backward compatibility module
22 is also very rudimentary, somewhat incomplete and not very well
23 tested too...
24
25 The current API is implemented in __init__.py, use that instead
26 '''
27
28 try:
29 xrange
30 except NameError:
31 xrange = range
32
33 import re
34
35 class IsoSpec():
36 def __init__(
37 self,
38 _atomCounts,
39 _isotopeMasses,
40 _isotopeProbabilities,
41 _stopCondition,
42 tabSize = 1000, # ignored
43 hashSize = 1000, # ignored
44 step = 0.3, # ignored
45 trim = True, # True not supported yet, treated as False anyway
46 method = 'layered'
47 ):
48
49 isoargs = {
50 "formula" : None,
51 "get_confs" : True,
52 "atomCounts" : _atomCounts,
53 "isotopeMasses" : _isotopeMasses,
54 "isotopeProbabilities" : _isotopeProbabilities,
55 }
56
57 self.dimNumber = len(_atomCounts)
58 self._isotopeNumbers = [len(x) for x in _isotopeMasses]
59 self.allIsotopeNumber = sum(self._isotopeNumbers)
60 self._atomCounts = _atomCounts
61 self._isotopeMasses = _isotopeMasses
62 self._isotopeProbabilities = _isotopeProbabilities
63 self._stopCondition = _stopCondition
64
65 from .__init__ import IsoThreshold
66
67 try:
68 algo = { 'layered' : lambda total_prob: IsoLayered(total_prob, **isoargs),
69 'ordered' : lambda total_prob: IsoLayered(total_prob, **isoargs),
70 'threshold_absolute' : lambda threshold: IsoThreshold(threshold, True, **isoargs),
71 'threshold_relative' : lambda threshold: IsoThreshold(threshold, False, **isoargs),
72 'layered_estimating' : lambda total_prob: IsoLayered(total_prob, **isoargs)
73 }[method]
74 except KeyError:
75 raise Exception("Invalid ISO method")
76
77 # Reference to iso needs to be held in this object: it will deallocate masses/lprobs/etc arrays on C++ side if we
78 # allow GC to collect it prematurely
79 self.iso = algo(_stopCondition)
80
81 self.masses = self.iso.masses
82 self.lprobs = self.iso.lprobs
83 self.probs = self.iso.probs
84 self.confs = self.iso.confs
85 self.size = self.iso.size
86
87 if method == 'ordered':
88 L = sorted(zip(self.masses, self.lprobs, self.probs, self.confs), key = lambda x: -x[1])
89 self.masses, self.lprobs, self.probs, self.confs = zip(*L)
90
91 @staticmethod
92 def IsoFromFormula(formula, cutoff, tabSize = 1000, hashSize = 1000, classId = None, method = 'threshold_relative', step = 0.25, trim = True):
93 # It's much easier to just parse it in python than to use the C parsing function
94 # and retrieve back into Python the relevant object sizes
95 symbols = re.findall("\D+", formula)
96 atom_counts = [int(x) for x in re.findall("\d+", formula)]
97
98 if not len(symbols) == len(atom_counts):
99 raise ValueError("Invalid formula")
100
101 from .PeriodicTbl import symbol_to_masses, symbol_to_probs
102 try:
103 masses = tuple(symbol_to_masses[symbol] for symbol in symbols)
104 probs = tuple(symbol_to_probs[symbol] for symbol in symbols)
105 except KeyError:
106 raise ValueError("Invalid formula")
107
108 return IsoSpec(atom_counts, masses, probs, cutoff, tabSize, hashSize, step, trim, method)
109
110
111
112 def __len__(self):
113 return self.size
114
115 def getConfsRaw(self):
116 return (self.masses, self.lprobs, self.confs)
117
118 # def get_conf_by_no(self, clist, idx):
119 # idx *= self.allIsotopeNumber
120 # ret = []
121 # for ison in self._isotopeNumbers:
122 # ret.append(tuple(clist[idx:idx+ison]))
123 # idx += ison
124 # return tuple(ret)
125
126
127 def getConfs(self):
128 masses, logProbs, isoCounts = self.getConfsRaw()
129 rows_no = len(masses)
130 cols_no = len(isoCounts) // len(masses)
131 masses = list(masses)
132 logProbs= list(logProbs)
133 confs = []
134 for i in xrange(rows_no):
135 confs.append([x for sublist in isoCounts[i] for x in sublist])
136 return masses, logProbs, confs
137
138 def splitConf(self, l, offset = 0):
139 conf = []
140 idx = self.allIsotopeNumber * offset
141 for i in xrange(self.dimNumber):
142 conf.append(tuple(l[idx:idx+self._isotopeNumbers[i]]))
143 idx += self._isotopeNumbers[i]
144 return tuple(conf)
145
146 def confStr(self, conf):
147 return '\t'.join([' '.join([str(x) for x in y]) for y in conf])
148
149 def printConfs(self):
150 masses, logProbs, isoCounts = self.getConfsRaw()
151 confs = []
152 step = sum(self._isotopeNumbers)
153 for i in xrange(len(masses)):
154 confs.append((masses[i], logProbs[i], self.splitConf(isoCounts, i)))
155
156 for conf in confs:
157 print(("Mass = {0}\t and log-prob = {1} and prob = {2}\t and configuration"\
158 "=\t{3}").format(conf[0], conf[1], math.exp(conf[1]), self.confStr(conf[2])))
159
160
161
162 class IsoPlot(dict):
163 def __init__(self, iso, bin_w):
164 self.iso = iso
165 self.bin_w = bin_w
166 masses, logProbs, _isoCounts = iso.getConfsRaw()
167 dd = defaultdict(Summator)
168 for i in xrange(len(masses)):
169 dd[float(int(masses[i]/bin_w))*bin_w].add(math.exp(logProbs[i]))
170 for key, val in dd.items():
171 self[key] = val.get()
172
173
174 def IsoSpecify( formula,
175 cutoff,
176 method= 'layered',
177 output_format = 'numpy_arrays',
178 trim = True,
179 _step = 0.25,
180 _trim = True,
181 _tabSize = 1000,
182 _hashSize = 1000 ):
183 """
184 Call IsoSpec on a formula with a given cutoff.
185
186 This function wraps around the IsoSpec class.
187
188 Parameters
189 ----------
190 formula : char
191 a string of a form '< Element Tag 1 >< Count 1 > ... ',
192 e.g. 'C100H202'. Using IUPAC conventions to name elements.
193
194 cutoff : float
195 The cutoff value. See description of the method argument.
196
197 method : char
198 Can take one of the following values: 'layered',
199 'layered_estimating', 'threshold_absolute',
200 'threshold_relative', 'ordered'.
201
202 The threshold versions of the algorithm rely on user
203 providing a precise lower bound on the reported peak heights.
204 This can be specified in absolute terms ('threshold_absolute'),
205 i.e. in terms of the limiting probability of the isotopologue,
206 or as a percentage of the heighest peak ('threshold_relative').
207
208 The layered versions of the algorithm rely on calculating
209 consecutive values of peak thresholds on flight.
210 The ultimate goal is to reach a peak probability that assures
211 that the sum of probabilities of the more probable isotopologues
212 exceeds the provided cutoff value.
213 The sequence of consecutive thresholds can be generated in
214 two ways. The default way, 'layered_estimating', estimates
215 the threshold to joint probability function by a progressive
216 linear spline, check Anal Chem. 2017 Mar 21;89(6):3272-3277.
217 doi: 10.1021/acs.analchem.6b01459. Epub 2017 Mar 8.
218 The other way, 'layered', estimates a threshold as a 30%%
219 quantile of the probabilities gathered in the fringe set, i.e.
220 isotopologues that are direct neighbours of the previously
221 accepted layer. Finally, choosing the 'ordered' version will
222 provide a loglinear version of the algorithm that relies on
223 the priority queue. This version automatically sorts
224 the configurations by their probability.
225
226 trim
227 while using a layered method, should one discard superfluously
228 obtained isotopologues, i.e. such that without them the set of
229 reported isotopologues already is an optimal p-set.
230
231 output_format
232 Should the output be presented as lists ('lists'),
233 or as numpy arrays ('numpy_arrays').
234
235 Returns
236 -------
237 masses
238 masses of isotopologues, either a list or a numpy array.
239
240 logProbs
241 logarithms of probabilities (theoretical heights) of isotopologues,
242 either a list or a numpy array.
243
244 confs
245 counts of isotopologues (extended chemical formulas that
246 include counts of isotopes of elements)
247 """
248
249
250 assert output_format in ('lists', 'numpy_arrays'), "Wrong value of output_format. Should be either 'lists' or 'numpy_arrays'."
251
252 assert method in ('layered', 'ordered', 'threshold_absolute', 'threshold_relative', 'layered_estimating'), "Wrong value of method. Should be among 'layered', 'ordered', 'threshold_absolute', 'threshold_relative', or 'layered_estimating'."
253
254 assert isinstance(cutoff, float), "Provided cut off ain't a float."
255
256 assert isinstance(formula, str), "Provided formula off ain't a string."
257
258 iso = IsoSpec.IsoFromFormula( formula,
259 cutoff,
260 tabSize = 1000,
261 hashSize = 1000,
262 classId = None,
263 method = method,
264 step = 0.25,
265 trim = trim )
266
267 if output_format == 'lists':
268 masses, logProbs, confs = iso.getConfs()
269 else:
270 masses, logProbs, confs = iso.getConfsNumpy()
271
272 # print 'Rev Startek is a silly old chump and his mother dresses up silly.'
273 return masses, logProbs, confs
274
275
0 from .isoFFI import isoFFI
1 from collections import defaultdict
2
3 try:
4 xrange
5 except NameError:
6 xrange = range
7
8 number_of_isotopic_entries = isoFFI.clib.NUMBER_OF_ISOTOPIC_ENTRIES
9
10 symbol_to_masses = defaultdict(tuple)
11 symbol_to_probs = defaultdict(tuple)
12 symbol_to_atomic_number = {}
13
14 for i in xrange(number_of_isotopic_entries):
15 symbol = isoFFI.ffi.string(isoFFI.clib.elem_table_symbol[i]).decode("ascii")
16 symbol_to_masses[symbol] += (isoFFI.clib.elem_table_mass[i],)
17 symbol_to_probs[symbol] += (isoFFI.clib.elem_table_probability[i],)
18 symbol_to_atomic_number[symbol] = isoFFI.clib.elem_table_atomicNo[i]
19
20 symbol_to_masses = dict(symbol_to_masses)
21 symbol_to_probs = dict(symbol_to_probs)
22
23 # Several derivative convenience dicts...
24 symbol_to_massprob = dict((key, [zip(symbol_to_masses[key], symbol_to_probs[key])]) for key in symbol_to_probs.keys())
25
26 def crossprod(l1, l2):
27 return sum(x1*x2 for x1, x2 in zip(l1, l2))
28
29 symbol_to_avg_mass = dict((key, crossprod(symbol_to_masses[key], symbol_to_probs[key])) for key in symbol_to_probs.keys())
30
31 def maxprod(l1, l2):
32 return max(zip(l1, l2), key = lambda x: x[1])[0]
33
34 symbol_to_monoisotopic_mass = dict((key, maxprod(symbol_to_masses[key], symbol_to_probs[key])) for key in symbol_to_probs.keys())
35
0 # -*- coding: utf-8 -*-
1 #
2 # Copyright (C) 2015-2018 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 from .isoFFI import isoFFI
18 import re
19 import types
20 from . import PeriodicTbl
21 from .confs_passthrough import ConfsPassthrough
22
23
24 try:
25 xrange
26 except NameError:
27 xrange = range
28
29 regex_pattern = re.compile('([A-Z][a-z]?)([0-9]*)')
30
31 def IsoParamsFromFormula(formula):
32 global regex_pattern
33
34 symbols = []
35 atomCounts = []
36 for elem, cnt in re.findall(regex_pattern, formula):
37 symbols.append(elem)
38 atomCounts.append(int(cnt) if cnt is not '' else 1)
39 try:
40 masses = tuple(PeriodicTbl.symbol_to_masses[s] for s in symbols)
41 probs = tuple(PeriodicTbl.symbol_to_probs[s] for s in symbols)
42 except KeyError:
43 raise ValueError("Invalid formula")
44
45 return (atomCounts, masses, probs)
46
47
48
49 class Iso(object):
50 def __init__(self, formula=None,
51 get_confs=False,
52 atomCounts=None,
53 isotopeMasses=None,
54 isotopeProbabilities=None):
55 """Initialize Iso."""
56
57 self.iso = None
58
59 if formula is None and not all([atomCounts, isotopeMasses, isotopeProbabilities]):
60 raise Exception("Either formula or ALL of: atomCounts, isotopeMasses, isotopeProbabilities must not be None")
61
62 if formula is not None:
63 if isinstance(formula, dict):
64 formula = ''.join(key + str(val) for key, val in formula.items() if val > 0)
65 self.atomCounts, self.isotopeMasses, self.isotopeProbabilities = IsoParamsFromFormula(formula)
66
67 if atomCounts is not None:
68 self.atomCounts = atomCounts
69
70
71 if isotopeMasses is not None:
72 self.isotopeMasses = isotopeMasses
73
74 if isotopeProbabilities is not None:
75 self.isotopeProbabilities = isotopeProbabilities
76
77 for sublist in self.isotopeProbabilities:
78 for prob in sublist:
79 if not (0.0 < prob <= 1.0):
80 raise ValueError("All isotope probabilities p must fulfill: 0.0 < p <= 1.0")
81
82 self.isotopeNumbers = tuple(map(len, self.isotopeMasses))
83 assert self.isotopeNumbers == tuple(map(len, self.isotopeProbabilities))
84
85 self.dimNumber = len(self.isotopeNumbers)
86
87 self.get_confs = get_confs
88 self.ffi = isoFFI.clib
89
90 offsets = []
91
92 if get_confs:
93 i = 0
94 for j in xrange(self.dimNumber):
95 newl = []
96 for k in xrange(self.isotopeNumbers[j]):
97 newl.append(i)
98 i += 1
99 offsets.append(tuple(newl))
100 self.offsets = tuple(offsets)
101
102 self.iso = self.ffi.setupIso(self.dimNumber, self.isotopeNumbers,
103 self.atomCounts,
104 [i for s in self.isotopeMasses for i in s],
105 [i for s in self.isotopeProbabilities for i in s])
106
107 def __iter__(self):
108 if self.get_confs:
109 for i in xrange(self.size):
110 yield(self.masses[i], self.probs[i], self.confs[i])
111 else:
112 for i in xrange(self.size):
113 yield (self.masses[i], self.probs[i])
114
115 def __del__(self):
116 try:
117 if self.iso is not None:
118 self.ffi.deleteIso(self.iso)
119 except AttributeError:
120 pass
121
122 def getLightestPeakMass(self):
123 return self.ffi.getLightestPeakMassIso(self.iso)
124
125 def getHeaviestPeakMass(self):
126 return self.ffi.getHeaviestPeakMassIso(self.iso)
127
128 def getMonoisotopicPeakMass(self):
129 return self.ffi.getMonoisotopicPeakMassIso(self.iso)
130
131 def getModeLProb(self):
132 return self.ffi.getModeLProbIso(self.iso)
133
134 def getModeMass(self):
135 return self.ffi.getModeMassIso(self.iso)
136
137 def getTheoreticalAverageMass(self):
138 return self.ffi.getTheoreticalAverageMassIso(self.iso)
139
140 def parse_conf(self, cptr, starting_with = 0):
141 return tuple(tuple(cptr[i+starting_with] for i in o) for o in self.offsets)
142
143
144
145 class IsoThreshold(Iso):
146 def __init__(self, threshold, absolute=False, get_confs = False, **kwargs):
147 super(IsoThreshold, self).__init__(get_confs = get_confs, **kwargs)
148 self.threshold = threshold
149 self.absolute = absolute
150
151 self.generator = self.ffi.setupIsoThresholdGenerator(self.iso, threshold, absolute, 1000, 1000)
152 tabulator = self.ffi.setupThresholdTabulator(self.generator, True, True, True, get_confs)
153
154 self.size = self.ffi.confs_noThresholdTabulator(tabulator)
155
156 def c(typename, what, mult = 1):
157 return isoFFI.ffi.gc(isoFFI.ffi.cast(typename + '[' + str(self.size*mult) + ']', what), self.ffi.freeReleasedArray)
158
159 self.masses = c("double", self.ffi.massesThresholdTabulator(tabulator))
160 self.lprobs = c("double", self.ffi.lprobsThresholdTabulator(tabulator))
161 self.probs = c("double", self.ffi.probsThresholdTabulator(tabulator))
162
163 if get_confs:
164 self.sum_isotope_numbers = sum(self.isotopeNumbers)
165 self.raw_confs = c("int", self.ffi.confsThresholdTabulator(tabulator), mult = self.sum_isotope_numbers)
166 self.confs = ConfsPassthrough(lambda idx: self._get_conf(idx), self.size)
167
168 self.ffi.deleteThresholdTabulator(tabulator)
169
170 def __del__(self):
171 self.ffi.deleteIsoThresholdGenerator(self.generator)
172
173 def _get_conf(self, idx):
174 return self.parse_conf(self.raw_confs, starting_with = self.sum_isotope_numbers * idx)
175
176 def __len__(self):
177 return self.size
178
179
180
181
182 class IsoLayered(Iso):
183 def __init__(self, prob_to_cover, get_confs = False, **kwargs):
184 super(IsoLayered, self).__init__(get_confs = get_confs, **kwargs)
185 self.prob_to_cover = prob_to_cover
186
187 self.generator = self.ffi.setupIsoLayeredGenerator(self.iso, prob_to_cover, 0.3, 1000, 1000, True)
188 tabulator = self.ffi.setupLayeredTabulator(self.generator, True, True, True, get_confs)
189
190 self.size = self.ffi.confs_noLayeredTabulator(tabulator)
191
192 def c(typename, what, mult = 1):
193 return isoFFI.ffi.gc(isoFFI.ffi.cast(typename + '[' + str(self.size*mult) + ']', what), self.ffi.freeReleasedArray)
194
195 self.masses = c("double", self.ffi.massesLayeredTabulator(tabulator))
196 self.lprobs = c("double", self.ffi.lprobsLayeredTabulator(tabulator))
197 self.probs = c("double", self.ffi.probsLayeredTabulator(tabulator))
198
199 if get_confs:
200 self.sum_isotope_numbers = sum(self.isotopeNumbers)
201 self.raw_confs = c("int", self.ffi.confsLayeredTabulator(tabulator), mult = self.sum_isotope_numbers)
202 self.confs = ConfsPassthrough(lambda idx: self._get_conf(idx), self.size)
203
204 self.ffi.deleteLayeredTabulator(tabulator)
205
206 def __del__(self):
207 self.ffi.deleteIsoLayeredGenerator(self.generator)
208
209 def _get_conf(self, idx):
210 return self.parse_conf(self.raw_confs, starting_with = self.sum_isotope_numbers * idx)
211
212 def __len__(self):
213 return self.size
214
215
216
217 class IsoGenerator(Iso):
218 def __init__(self, get_confs=False, **kwargs):
219 self.cgen = None
220 super(IsoGenerator, self).__init__(get_confs = get_confs, **kwargs)
221 self.conf_space = isoFFI.ffi.new("int[" + str(sum(self.isotopeNumbers)) + "]")
222 self.firstuse = True
223
224 def __iter__(self):
225 if not self.firstuse:
226 raise NotImplementedError("Multiple iterations through the same IsoGenerator object are not supported. Either create a new (identical) generator for a second loop-through, or use one of the non-generator classes, which do support being re-used.")
227 self.firstuse = False
228 cgen = self.cgen
229 if self.get_confs:
230 while self.advancer(cgen):
231 self.conf_getter(cgen, self.conf_space)
232 yield (self.mass_getter(cgen), self.xprob_getter(cgen), self.parse_conf(self.conf_space))
233 else:
234 while self.advancer(cgen):
235 yield (self.mass_getter(cgen), self.xprob_getter(cgen))
236
237
238
239 class IsoThresholdGenerator(IsoGenerator):
240 def __init__(self, threshold, absolute=False, get_confs=False, use_lprobs=False, **kwargs):
241 super(IsoThresholdGenerator, self).__init__(get_confs, **kwargs)
242 self.threshold = threshold
243 self.absolute = absolute
244 self.cgen = self.ffi.setupIsoThresholdGenerator(self.iso,
245 threshold,
246 absolute,
247 1000,
248 1000)
249 self.advancer = self.ffi.advanceToNextConfigurationIsoThresholdGenerator
250 self.xprob_getter = self.ffi.lprobIsoThresholdGenerator if use_lprobs else self.ffi.probIsoThresholdGenerator
251 self.mass_getter = self.ffi.massIsoThresholdGenerator
252 self.conf_getter = self.ffi.get_conf_signatureIsoThresholdGenerator
253
254 def __del__(self):
255 try:
256 if self.cgen is not None:
257 self.ffi.deleteIsoThresholdGenerator(self.cgen)
258 except AttributeError:
259 pass
260
261
262 class IsoLayeredGenerator(IsoGenerator):
263 def __init__(self, prob_to_cover = 0.99, get_confs=False, do_trim = False, use_lprobs=False, **kwargs):
264 super(IsoLayeredGenerator, self).__init__(get_confs, **kwargs)
265 self.delta = prob_to_cover
266 self.cgen = self.ffi.setupIsoLayeredGenerator(self.iso,
267 self.delta,
268 0.3,
269 1000,
270 1000,
271 do_trim)
272 self.advancer = self.ffi.advanceToNextConfigurationIsoLayeredGenerator
273 self.xprob_getter = self.ffi.lprobIsoLayeredGenerator if use_lprobs else self.ffi.probIsoLayeredGenerator
274 self.mass_getter = self.ffi.massIsoLayeredGenerator
275 self.conf_getter = self.ffi.get_conf_signatureIsoLayeredGenerator
276
277 def __del__(self):
278 try:
279 if self.cgen is not None:
280 self.ffi.deleteIsoLayeredGenerator(self.cgen)
281 except AttributeError:
282 pass
283
284 class IsoOrderedGenerator(IsoGenerator):
285 def __init__(self, get_confs=False, use_lprobs=False, **kwargs):
286 super(IsoOrderedGenerator, self).__init__(get_confs, **kwargs)
287 self.cgen = self.ffi.setupIsoOrderedGenerator(self.iso,
288 1000,
289 1000)
290 self.advancer = self.ffi.advanceToNextConfigurationIsoOrderedGenerator
291 self.xprob_getter = self.ffi.lprobIsoOrderedGenerator if use_lprobs else self.ffi.probIsoOrderedGenerator
292 self.mass_getter = self.ffi.massIsoOrderedGenerator
293 self.conf_getter = self.ffi.get_conf_signatureIsoOrderedGenerator
294
295 def __del__(self):
296 try:
297 if self.cgen is not None:
298 self.ffi.deleteIsoLayeredGenerator(self.cgen)
299 except AttributeError:
300 pass
301
302
303
304
305 __version__ = "1.9.1"
306
307
308 # For compatibility with 1.0.X
309
310 class CompatIsoWrapper(object):
311 def __init__(self):
312 from .IsoSpecPy import IsoSpec, IsoSpecify, IsoPlot
313 self.IsoSpec = IsoSpec
314 self.IsoSpecify = IsoSpecify
315 self.IsoPlot = IsoPlot
316
317
318 IsoSpecPy = CompatIsoWrapper()
319
0
1
2
3
4 class ConfsPassthrough(object):
5 def __init__(self, confs_parser, size):
6 self.confs_parser = confs_parser
7 self.size = size
8
9 def __len__(self):
10 return self.size
11
12 def __getitem__(self, idx):
13 return self.confs_parser(idx)
14
15
0 import cffi
1 import os
2 import platform
3 import sys
4 import glob
5
6
7 class IsoFFI:
8 def __init__(self):
9 self.ffi = cffi.FFI()
10 self.ffi.cdef('''
11 void * setupIso(int dimNumber,
12 const int* isotopeNumbers,
13 const int* atomCounts,
14 const double* isotopeMasses,
15 const double* isotopeProbabilities);
16
17 double getLightestPeakMassIso(void* iso);
18 double getHeaviestPeakMassIso(void* iso);
19 double getMonoisotopicPeakMassIso(void* iso);
20 double getModeLProbIso(void* iso);
21 double getModeMassIso(void* iso);
22 double getTheoreticalAverageMassIso(void* iso);
23
24 void deleteIso(void* iso);
25
26 void* setupIsoThresholdGenerator(void* iso,
27 double threshold,
28 bool _absolute,
29 int _tabSize,
30 int _hashSize);
31 double massIsoThresholdGenerator(void* generator); double lprobIsoThresholdGenerator(void* generator); double probIsoThresholdGenerator(void* generator); void methodIsoThresholdGenerator(void* generator); bool advanceToNextConfigurationIsoThresholdGenerator(void* generator); void deleteIsoThresholdGenerator(void* generator); void get_conf_signatureIsoThresholdGenerator(void* generator, int* space);
32
33
34
35 void* setupIsoLayeredGenerator(void* iso,
36 double _target_coverage,
37 double _percentage_to_expand,
38 int _tabSize,
39 int _hashSize,
40 bool _do_trim);
41 double massIsoLayeredGenerator(void* generator); double lprobIsoLayeredGenerator(void* generator); double probIsoLayeredGenerator(void* generator); void methodIsoLayeredGenerator(void* generator); bool advanceToNextConfigurationIsoLayeredGenerator(void* generator); void deleteIsoLayeredGenerator(void* generator); void get_conf_signatureIsoLayeredGenerator(void* generator, int* space);
42
43
44 void* setupIsoOrderedGenerator(void* iso,
45 int _tabSize,
46 int _hashSize);
47 double massIsoOrderedGenerator(void* generator); double lprobIsoOrderedGenerator(void* generator); double probIsoOrderedGenerator(void* generator); void methodIsoOrderedGenerator(void* generator); bool advanceToNextConfigurationIsoOrderedGenerator(void* generator); void deleteIsoOrderedGenerator(void* generator); void get_conf_signatureIsoOrderedGenerator(void* generator, int* space);
48
49 void* setupThresholdTabulator(void* generator,
50 bool get_masses,
51 bool get_probs,
52 bool get_lprobs,
53 bool get_confs);
54
55 void deleteThresholdTabulator(void* tabulator);
56
57 const double* massesThresholdTabulator(void* tabulator);
58 const double* lprobsThresholdTabulator(void* tabulator);
59 const double* probsThresholdTabulator(void* tabulator);
60 const int* confsThresholdTabulator(void* tabulator);
61 int confs_noThresholdTabulator(void* tabulator);
62
63
64 void* setupLayeredTabulator(void* generator,
65 bool get_masses,
66 bool get_probs,
67 bool get_lprobs,
68 bool get_confs);
69
70 void deleteLayeredTabulator(void* tabulator);
71
72 const double* massesLayeredTabulator(void* tabulator);
73 const double* lprobsLayeredTabulator(void* tabulator);
74 const double* probsLayeredTabulator(void* tabulator);
75 const int* confsLayeredTabulator(void* tabulator);
76 int confs_noLayeredTabulator(void* tabulator);
77
78 void freeReleasedArray(void* array);
79
80 #define NUMBER_OF_ISOTOPIC_ENTRIES 287
81 extern const int elem_table_atomicNo[NUMBER_OF_ISOTOPIC_ENTRIES];
82 extern const double elem_table_probability[NUMBER_OF_ISOTOPIC_ENTRIES];
83 extern const double elem_table_mass[NUMBER_OF_ISOTOPIC_ENTRIES];
84 extern const int elem_table_massNo[NUMBER_OF_ISOTOPIC_ENTRIES];
85 extern const int elem_table_extraNeutrons[NUMBER_OF_ISOTOPIC_ENTRIES];
86 extern const char* elem_table_element[NUMBER_OF_ISOTOPIC_ENTRIES];
87 extern const char* elem_table_symbol[NUMBER_OF_ISOTOPIC_ENTRIES];
88 extern const bool elem_table_Radioactive[NUMBER_OF_ISOTOPIC_ENTRIES];
89 ''');
90
91 mod_dir = os.path.dirname(os.path.abspath(__file__))
92
93 if os.path.exists(os.path.join(mod_dir, '..', 'setup.py')):
94 raise Exception('''Attempted to load IsoSpecPy module from its build directory. This usually
95 won't work and is generally a Bad Idea. Please cd somewhere else, or, if you're really
96 sure you want to do that, edit the source and disable this check.''')
97
98 libnames = ['IsoSpecCppPy*', 'IsoSpec++*']
99 libprefix = ['', 'lib', 'Lib']
100 extension = ['.so', '.dylib', '.dll']
101 try:
102 if platform.system() == 'Linux':
103 extension = ['.so']
104 elif platform.system() == 'Windows':
105 extension = ['.dll']
106 except:
107 pass
108
109 prebuilt = ['', 'prebuilt-']
110
111 def cprod(ll1, ll2):
112 res = []
113 for l1 in ll1:
114 for l2 in ll2:
115 res.append(l1+l2)
116 return res
117
118 paths_to_check = cprod(prebuilt, cprod(libprefix, cprod(libnames, extension)))
119
120 dpc = []
121
122 for dirpath in [mod_dir, mod_dir + '/..']:
123 dpc.extend([os.path.join(dirpath, p) for p in paths_to_check])
124
125 paths_to_check = dpc
126
127 paths_to_check = sum(map(glob.glob, paths_to_check), [])
128
129 self.clib = None
130 for libpath in set(paths_to_check):
131 try:
132 self.clib = self.ffi.dlopen(libpath)
133 break
134 except (IndexError, OSError) as e:
135 pass
136
137 if self.clib == None:
138 raise Exception("Cannot find or load the C++ part of the library")
139
140
141 isoFFI = IsoFFI() # This is done while including the module
0 # -*- coding: utf-8 -*-
1 #
2 # Copyright (C) 2015-2018 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
19 class SSummator:
20 def __init__(self):
21 self.partials = [] # sorted, non-overlapping partial sums
22
23 def add(self, x):
24 i = 0
25 for y in self.partials:
26 if abs(x) < abs(y):
27 x, y = y, x
28 hi = x + y
29 lo = y - (hi - x)
30 if lo:
31 self.partials[i] = lo
32 i += 1
33 x = hi
34 self.partials[i:] = [x]
35 def get(self):
36 return sum(self.partials)
37
38
39 class Summator:
40 def __init__(self, keep_partials = False):
41 self.sum = 0.0
42 self.c = 0.0
43 self.keep_partials = keep_partials
44 self.partials = []
45
46 def add(self, what):
47 y = what - self.c
48 t = self.sum + y
49 c = (t - self.sum) - y
50 self.sum = t
51 if self.keep_partials:
52 self.partials.append(self.sum)
53
54 def get(self):
55 return self.sum
56
57 def get_partials(self):
58 return self.partials
59
60 class PosNegSummator:
61 def __init__(self):
62 self.pos = Summator()
63 self.neg = Summator()
64 def add(self, what):
65 if what >= 0:
66 self.pos.add(what)
67 else:
68 self.neg.add(-what)
69 def get(self):
70 return self.pos.get() - self.neg.get()
71
72
73
0 include IsoSpecPy/*.dll
1 include IsoSpec++/*.cpp
2 include IsoSpec++/*.h
0 reinstall:
1 rm -rf IsoSpecPy.egg-info build dist
2 pip uninstall -y IsoSpecPy
3 python setup.py install
0
1 """A setuptools based setup module.
2
3 See:
4 https://packaging.python.org/en/latest/distributing.html
5 https://github.com/pypa/sampleproject
6 """
7
8 # Always prefer setuptools over distutils
9 from setuptools import setup, find_packages, Extension
10 from distutils import spawn
11 # To use a consistent encoding
12 from codecs import open
13 import os
14 import glob
15 import shutil
16
17 if not os.path.exists("IsoSpec++"):
18 try:
19 os.symlink("../IsoSpec++", "IsoSpec++")
20 except: # OS doesn't support symlinks
21 shutil.copytree("../IsoSpec++", "IsoSpec++", symlinks=True)
22
23
24
25 here = os.path.abspath(os.path.dirname(__file__))
26
27 # Get the long description from the relevant file
28 #with open(path.join(here, 'DESCRIPTION.rst'), encoding='utf-8') as f:
29 # long_description = f.read()
30
31 cmodule = Extension('IsoSpecCppPy',
32 sources = ['IsoSpec++/unity-build.cpp'],
33 extra_compile_args = '-mtune=native -march=native -O3 -std=c++11'.split() #+ ['-DDEBUG']
34 )
35
36 setup_args = {
37 #setup(
38 'name': 'IsoSpecPy',
39
40 # Versions should comply with PEP440. For a discussion on single-sourcing
41 # the version across setup.py and the project code, see
42 # https://packaging.python.org/en/latest/single_source_version.html
43 'version': '1.9.1',
44
45 'description': 'Python interface to IsoSpec++ isotopic envelope calculator library',
46 'long_description': 'Python interface to IsoSpec++ isotopic envelope calculator library',
47
48 # The project's main homepage.
49 'url': 'http://matteolacki.github.io/IsoSpec/',
50
51 # Author details
52 'author': 'Mateusz Lacki & Michal Startek',
53 'author_email': 'matteo.lacki@gmail.com',
54
55 # Choose your license
56 'license': '2-clause BSD',
57
58 # See https://pypi.python.org/pypi?%3Aaction=list_classifiers
59 'classifiers' : [
60 # How mature is this project? Common values are
61 # 3 - Alpha
62 # 4 - Beta
63 # 5 - Production/Stable
64 'Development Status :: 5 - Production/Stable',
65
66 # Indicate who your project is intended for
67 'Intended Audience :: Science/Research',
68 'Topic :: Scientific/Engineering :: Chemistry',
69
70 # Pick your license as you wish (should match "license" above)
71 'License :: OSI Approved :: BSD License',
72
73 # Specify the Python versions you support here. In particular, ensure
74 # that you indicate whether you support Python 2, Python 3 or both.
75 'Programming Language :: Python :: 2',
76 'Programming Language :: Python :: 2.6',
77 'Programming Language :: Python :: 2.7',
78 'Programming Language :: Python :: 3',
79 'Programming Language :: Python :: 3.2',
80 'Programming Language :: Python :: 3.3',
81 'Programming Language :: Python :: 3.4',
82 ],
83
84 # What does your project relate to?
85 'keywords' : 'isotopic envelope',
86
87 # You can just specify the packages manually here if your project is
88 # simple. Or you can use find_packages().
89 'packages' : ['IsoSpecPy'],#find_packages(),
90
91 # List run-time dependencies here. These will be installed by pip when
92 # your project is installed. For an analysis of "install_requires" vs pip's
93 # requirements files see:
94 # https://packaging.python.org/en/latest/requirements.html
95 'install_requires' : ['cffi'],
96
97 'zip_safe' : False,
98
99 # List additional groups of dependencies here (e.g. development
100 # dependencies). You can install these using the following syntax,
101 # for example:
102 # $ pip install -e .[dev,test]
103 'extras_require' : {
104 # 'dev': ['check-manifest'],
105 # 'test': ['coverage'],
106 },
107
108 # If there are data files included in your packages that need to be
109 # installed, specify them here. If using Python 2.6 or less, then these
110 # have to be included in MANIFEST.in as well.
111 'package_data' : {
112 # 'sample': ['package_data.dat'],
113 },
114
115 # Although 'package_data' is the preferred approach, in some case you may
116 # need to place data files outside of your packages. See:
117 # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa
118 # In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
119 'data_files' : [], #[('my_data', ['data/data_file'])],
120
121 # To provide executable scripts, use entry points in preference to the
122 # "scripts" keyword. Entry points provide cross-platform support and allow
123 # pip to create the appropriate form of executable for the target platform.
124 # entry_points={
125 # 'console_scripts': [
126 # 'sample=sample:main',
127 # ],
128 # },
129 'ext_modules' : [cmodule],
130 }
131
132 import platform
133 import sys
134
135
136 if platform.system() == 'Windows':
137 # Probably Anaconda distribution.
138 # Of course Windows can't even compile stuff. Install prebuilt C++ lib.
139 import copy
140 win_setup_args = copy.deepcopy(setup_args)
141 win_setup_args['ext_modules'] = []
142 win_setup_args['include_package_data'] = True
143 setup(**win_setup_args)
144 elif 'CYGWIN' in platform.system():
145 try:
146 import cffi
147 except ImportError:
148 print("You appear to be using CYGWIN, and CFFI was not found. Please use the Cygwin installer to install the cffi-python package for the appropriate Python version.")
149 print("Installing CFFI using pip will most likely NOT work. This is *NOT* a bug in IsoSpecPy.")
150 sys.exit(1)
151 if spawn.find_executable('clang++') == None:
152 print("You appear to be using CYGWIN and clang++ executable was not found. Please install the clang++ package using Cygwin installer.")
153 sys.exit(1)
154 import distutils
155 import distutils.sysconfig
156 distutils.sysconfig.get_config_vars() # Precalculate the dict so we can...
157 distutils.sysconfig._config_vars['CFLAGS'] = "" # Nuke CFLAGS: they contain gcc stuff not supported by clang
158 setup(**setup_args)
159 else:
160 # Assuming UNIX with a working compiler.
161 setup(**setup_args)
0 Encoding: UTF-8
1 Package: IsoSpecR
2 Type: Package
3 Title: The IsoSpec Algorithm
4 Version: 1.9.1
5 Date: 2018-11-14
6 Author: Mateusz Krzysztof Lacki and Michal Startek
7 Maintainer: Matteo Lacki <matteo.lacki@gmail.com>
8 Description: IsoSpec is a fine structure calculator used for obtaining the most
9 probable masses of a chemical compound given the frequencies of the composing
10 isotopes and their masses. It finds the smallest set of isotopologues with
11 a given probability. The probability is assumed to be that of the product of
12 multinomial distributions, each corresponding to one particular element and
13 parametrized by the frequencies of finding these elements in nature. These
14 numbers are supplied by IUPAC - the International Union of Pure and Applied
15 Chemistry.
16 License: BSD_2_clause + file LICENCE
17 URL: http://matteolacki.github.io/IsoSpec/
18 Depends:
19 R (>= 3.0.0)
20 Imports:
21 Rcpp (>= 0.12.0)
22 Suggests:
23 testthat
24 LazyData: no
25 LinkingTo: Rcpp
26 NeedsCompilation: yes
27 SystemRequirements: C++11
28 RoxygenNote: 5.0.1
0 YEAR: 2015-2018
1 COPYRIGHT HOLDER: Michał Startek, Mateusz Łącki
2
0 # Generated by roxygen2: do not edit by hand
1
2 export(IsoSpecify)
3 importFrom(Rcpp,sourceCpp)
4 useDynLib(IsoSpecR, .registration = TRUE)
0 #
1 # Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 #
3 # This file is part of IsoSpec.
4 #
5 # IsoSpec is free software: you can redistribute it and/or modify
6 # it under the terms of the Simplified ("2-clause") BSD licence.
7 #
8 # IsoSpec is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 #
12 # You should have received a copy of the Simplified BSD Licence
13 # along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 #
15
16
17 #' @useDynLib IsoSpecR
18 #' @importFrom Rcpp sourceCpp
19 NULL
20
21 .onUnload <- function (libpath) {
22 library.dynam.unload("IsoSpecR", libpath)
23 }
24
25 #' Calculate the isotopic fine structure peaks.
26 #'
27 #' \code{IsoSpecify} is a wrapper around \code{Rinterface} that calls the C++ implementation of the IsoSpec algorithm. Given a molecular formula, it will calculate the smallest set of infinitely resolved peaks (isotopologues) that jointly is \code{p} probable, where \code{p} is provided by the user.
28 #'
29 #' @param molecule A named integer vector, e.g. \code{c(C=2,H=6,O=1)}, containing the chemical formula of the substance of interest.
30 #' @param stopCondition A numeric value between 0 and 1.
31 #' @param showCounts Logical. If \code{TRUE}, then we output matrix contains additionally counts of isotopes for each isotopologue.
32 #' @param trim Logical. If \code{FALSE}, then we output matrix contains additionally isotopologues that otherwise would get trimmed in order to find the smalles possible p-set. Therefore, switching to \code{FALSE} results in a slightly larger set then the optimal p-set.
33 #' @param algo An integer: 0 - use standard IsoSpec algoritm,
34 #' where \code{stopCondition} specifies the probability of the optimal p-set,
35 #' 1 - use a version of algorithm that uses priority queue. Slower than 0, but does not require sorting.
36 #' 2 - use a threshold version of the algorithm, where \code{stopCondition} specifies the height of the pruned peaks.
37 #' 3 - for the threshold version of IsoSpec with \code{stopCondition} being
38 #' the percentage of the highest peak below which isotopologues get pruned.
39 #' @param isotopes A named list of isotopic information required for IsoSpec. The names must be valid element symbols, see \code{isotopicData} for examples. Each enlisted object should be a \code{data.frame} containing columns \code{element} (specifying the symbol of the element), \code{mass} (specifying the mass of the isotope), \code{abundance} (specyfying the assumed frequency of finding that isotope).
40 #' @param step The percent of the the percentile of isotopologues in the current isolayer, specyfying the cutoff for the next isolayer. It has been optimised and better not change the default value.
41 #' @return A numeric matrix containing the masses, the logarithms of probability, and, optionally, counts of isotopologues. Attention: this matrix does not have to be sorted. Sorting it would also compromise the linear complexity of our algorithm.
42 #' @examples
43 #' res <- IsoSpecify( molecule = c(C=10,H=22,O=1), stopCondition = .9999 )
44 #' print(res)
45 #' @export
46 IsoSpecify <- function(
47 molecule,
48 stopCondition,
49 isotopes= NULL,
50 showCounts = FALSE,
51 trim = TRUE,
52 algo = 0,
53 step = .25
54 ){
55 if(is.null(isotopes)){
56 isotopes <- isotopicData$IsoSpec
57 }
58
59 Rinterface(
60 molecule = molecule[ molecule > 0 ],
61 isotopes = isotopes,
62 stopCondition = stopCondition,
63 algo = as.integer(algo),
64 tabSize = 1000,
65 hashSize = 1000,
66 step = step,
67 showCounts = showCounts,
68 trim = trim
69 )
70 }
0 # Generated by using Rcpp::compileAttributes() -> do not edit by hand
1 # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
2
3 Rinterface <- function(molecule, isotopes, stopCondition, algo = 0L, tabSize = 1000L, hashSize = 1000L, step = .3, showCounts = FALSE, trim = TRUE) {
4 .Call(`_IsoSpecR_Rinterface`, molecule, isotopes, stopCondition, algo, tabSize, hashSize, step, showCounts, trim)
5 }
6
0 #
1 # Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 #
3 # This file is part of IsoSpec.
4 #
5 # IsoSpec is free software: you can redistribute it and/or modify
6 # it under the terms of the Simplified ("2-clause") BSD licence.
7 #
8 # IsoSpec is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 #
12 # You should have received a copy of the Simplified BSD Licence
13 # along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 #
15
16
17 #' Data on isotope masses, abundances and other.
18 #'
19 #' A list of data frames or table data frames (dplyr like), containing different information on isotopes.
20 #' @format A list of 6 tbl_df's or data frames, each constaining:
21 #' \describe{
22 #' \item{element}{The symbol of an element from Mendeleev's periodic table.}
23 #' \item{isotope}{String composed of the nucleon number and the symbol of element.}
24 #' \item{mass}{Isotope's Mass in Daltons.}
25 #' \item{abundance}{The abundance of the isotopes. In case of enviPat data abundances do not sum to one. In case of all other, they do.}
26 #' \item{ratioC}{As in enviPat reference manual: "Maximum number of atoms of an element for one C-atom in a molecule, based on 99.99 \% of case molecules".}
27 #' }
28 #' @source R Package enviPat and Commission on Isotopic Abundances and Atomic Weights, CIAAW, \url{http://www.ciaaw.org/index.htm}.
29 "isotopicData"
Binary diff not shown
0 citHeader("To cite IsoSpecR in publications use:")
1
2 citEntry(entry = "Article",
3 title = "{IsoSpec}: Hyperfast Fine Structure Calculator",
4 author = personList(as.person("Mateusz K. Łącki"),
5 as.person("Michał Startek"),
6 as.person("Dirk Valkenborg"),
7 as.person("Anna Gambin")),
8 journal = "Analytical Chemistry",
9 year = "2017",
10 volume = "89",
11 number = "6",
12 pages = "3272-3277",
13 url = "https://doi.org/10.1021/acs.analchem.6b01459",
14
15 textVersion =
16 paste("Mateusz K. Łącki, Michał Startek, Dirk Valkenborg, Anna Gambin (2017).",
17 "IsoSpec: Hyperfast Fine Structure Calculator.",
18 "Analytical Chemistry 89(6), 3272-3277.",
19 "URL https://doi.org/10.1021/acs.analchem.6b01459")
20 )
0 % Generated by roxygen2: do not edit by hand
1 % Please edit documentation in R/IsoSpecR.R
2 \name{IsoSpecify}
3 \alias{IsoSpecify}
4 \title{Calculate the isotopic fine structure peaks.}
5 \usage{
6 IsoSpecify(molecule, stopCondition, isotopes = NULL, showCounts = FALSE,
7 trim = TRUE, algo = 0, step = 0.25)
8 }
9 \arguments{
10 \item{molecule}{A named integer vector, e.g. \code{c(C=2,H=6,O=1)}, containing the chemical formula of the substance of interest.}
11
12 \item{stopCondition}{A numeric value between 0 and 1.}
13
14 \item{isotopes}{A named list of isotopic information required for IsoSpec. The names must be valid element symbols, see \code{isotopicData} for examples. Each enlisted object should be a \code{data.frame} containing columns \code{element} (specifying the symbol of the element), \code{mass} (specifying the mass of the isotope), \code{abundance} (specyfying the assumed frequency of finding that isotope).}
15
16 \item{showCounts}{Logical. If \code{TRUE}, then we output matrix contains additionally counts of isotopes for each isotopologue.}
17
18 \item{trim}{Logical. If \code{FALSE}, then we output matrix contains additionally isotopologues that otherwise would get trimmed in order to find the smalles possible p-set. Therefore, switching to \code{FALSE} results in a slightly larger set then the optimal p-set.}
19
20 \item{algo}{An integer: 0 - use standard IsoSpec algoritm,
21 where \code{stopCondition} specifies the probability of the optimal p-set,
22 1 - use a version of algorithm that uses priority queue. Slower than 0, but does not require sorting.
23 2 - use a threshold version of the algorithm, where \code{stopCondition} specifies the height of the pruned peaks.
24 3 - for the threshold version of IsoSpec with \code{stopCondition} being
25 the percentage of the highest peak below which isotopologues get pruned.}
26
27 \item{step}{The percent of the the percentile of isotopologues in the current isolayer, specyfying the cutoff for the next isolayer. It has been optimised and better not change the default value.}
28 }
29 \value{
30 A numeric matrix containing the masses, the logarithms of probability, and, optionally, counts of isotopologues. Attention: this matrix does not have to be sorted. Sorting it would also compromise the linear complexity of our algorithm.
31 }
32 \description{
33 \code{IsoSpecify} is a wrapper around \code{Rinterface} that calls the C++ implementation of the IsoSpec algorithm. Given a molecular formula, it will calculate the smallest set of infinitely resolved peaks (isotopologues) that jointly is \code{p} probable, where \code{p} is provided by the user.
34 }
35 \examples{
36 res <- IsoSpecify( molecule = c(C=10,H=22,O=1), stopCondition = .9999 )
37 print(res)
38 }
39
0 % Generated by roxygen2: do not edit by hand
1 % Please edit documentation in R/data_description.R
2 \docType{data}
3 \name{isotopicData}
4 \alias{isotopicData}
5 \title{Data on isotope masses, abundances and other.}
6 \format{A list of 6 tbl_df's or data frames, each constaining:
7 \describe{
8 \item{element}{The symbol of an element from Mendeleev's periodic table.}
9 \item{isotope}{String composed of the nucleon number and the symbol of element.}
10 \item{mass}{Isotope's Mass in Daltons.}
11 \item{abundance}{The abundance of the isotopes. In case of enviPat data abundances do not sum to one. In case of all other, they do.}
12 \item{ratioC}{As in enviPat reference manual: "Maximum number of atoms of an element for one C-atom in a molecule, based on 99.99 \% of case molecules".}
13 }}
14 \source{
15 R Package enviPat and Commission on Isotopic Abundances and Atomic Weights, CIAAW, \url{http://www.ciaaw.org/index.htm}.
16 }
17 \usage{
18 isotopicData
19 }
20 \description{
21 A list of data frames or table data frames (dplyr like), containing different information on isotopes.
22 }
23 \keyword{datasets}
24
0 #include <R.h>
1 #include <Rinternals.h>
2 #include <stdlib.h> // for NULL
3 #include <R_ext/Rdynload.h>
4
5
6 /* .Call calls */
7 extern SEXP _IsoSpecR_Rinterface(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
8
9 static const R_CallMethodDef CallEntries[] = {
10 {"_IsoSpecR_Rinterface", (DL_FUNC) &_IsoSpecR_Rinterface, 9},
11 {NULL, NULL, 0}
12 };
13
14 void R_init_IsoSpecR(DllInfo *dll)
15 {
16 R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
17 R_useDynamicSymbols(dll, FALSE);
18 }
19
0 // Generated by using Rcpp::compileAttributes() -> do not edit by hand
1 // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
2
3 #include <Rcpp.h>
4
5 using namespace Rcpp;
6
7 // Rinterface
8 NumericMatrix Rinterface(const IntegerVector& molecule, const DataFrame& isotopes, double stopCondition, int algo, int tabSize, int hashSize, double step, bool showCounts, bool trim);
9 RcppExport SEXP _IsoSpecR_Rinterface(SEXP moleculeSEXP, SEXP isotopesSEXP, SEXP stopConditionSEXP, SEXP algoSEXP, SEXP tabSizeSEXP, SEXP hashSizeSEXP, SEXP stepSEXP, SEXP showCountsSEXP, SEXP trimSEXP) {
10 BEGIN_RCPP
11 Rcpp::RObject rcpp_result_gen;
12 Rcpp::RNGScope rcpp_rngScope_gen;
13 Rcpp::traits::input_parameter< const IntegerVector& >::type molecule(moleculeSEXP);
14 Rcpp::traits::input_parameter< const DataFrame& >::type isotopes(isotopesSEXP);
15 Rcpp::traits::input_parameter< double >::type stopCondition(stopConditionSEXP);
16 Rcpp::traits::input_parameter< int >::type algo(algoSEXP);
17 Rcpp::traits::input_parameter< int >::type tabSize(tabSizeSEXP);
18 Rcpp::traits::input_parameter< int >::type hashSize(hashSizeSEXP);
19 Rcpp::traits::input_parameter< double >::type step(stepSEXP);
20 Rcpp::traits::input_parameter< bool >::type showCounts(showCountsSEXP);
21 Rcpp::traits::input_parameter< bool >::type trim(trimSEXP);
22 rcpp_result_gen = Rcpp::wrap(Rinterface(molecule, isotopes, stopCondition, algo, tabSize, hashSize, step, showCounts, trim));
23 return rcpp_result_gen;
24 END_RCPP
25 }
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16
17 #include <Rcpp.h>
18 #include "cwrapper.h"
19 #include "misc.h"
20 #include "isoSpec++.h"
21 #include <vector>
22 #include <iostream>
23
24 using namespace Rcpp;
25 using namespace IsoSpec;
26
27 IsoGenerator* mkIsoG(Iso& iso, int algo, double stopCondition, int tabSize, int hashSize, int step, int trim)
28 {
29 switch(algo)
30 {
31 case ISOSPEC_ALGO_LAYERED_ESTIMATE: // Not used anymore, just fall through to the next case
32 case ISOSPEC_ALGO_LAYERED: return new IsoLayeredGenerator(std::move(iso), stopCondition, step, tabSize, hashSize, trim);
33 case ISOSPEC_ALGO_ORDERED: return new IsoLayeredGenerator(std::move(iso), stopCondition, step, tabSize, hashSize, true); // Using the ordered algo in R is *completely* pointless today
34 // The only point of ordered algo is when one is using the generator
35 // interface, which we are not expising in R
36 // We'll just do layered, trim and sort it afterwards - it's equivalent
37 // and much faster
38 case ISOSPEC_ALGO_THRESHOLD_ABSOLUTE: return new IsoThresholdGenerator(std::move(iso), stopCondition, true, tabSize, hashSize, true);
39 case ISOSPEC_ALGO_THRESHOLD_RELATIVE: return new IsoThresholdGenerator(std::move(iso), stopCondition, true, tabSize, hashSize, true);
40 }
41 throw std::logic_error("Invalid algorithm selected");
42 }
43
44 // [[Rcpp::export]]
45 NumericMatrix Rinterface(
46 const IntegerVector& molecule,
47 const DataFrame& isotopes,
48 double stopCondition,
49 int algo = 0,
50 int tabSize = 1000,
51 int hashSize = 1000,
52 double step = .3,
53 bool showCounts = false,
54 bool trim = true
55 ){
56
57 unsigned int dimNumber = molecule.size();
58 std::vector<int> stdIsotopeNumbers;
59 std::vector<double> stdIsotopeMasses;
60 std::vector<double> stdIsotopeProbabilities;
61
62 const CharacterVector& element = isotopes["element"];
63 const CharacterVector& isotope = isotopes["isotope"];
64 const NumericVector& mass = isotopes["mass"];
65 const NumericVector& abundance = isotopes["abundance"];
66 const CharacterVector& molecule_names = molecule.names();
67
68 CharacterVector stdIsotopeTags = CharacterVector::create("mass", "logProb");
69
70 for (unsigned int i=0; i<dimNumber; i++)
71 {
72 unsigned int counter = 0;
73 for (int j=0; j<element.size(); j++)
74 if( element[j] == molecule_names[i] )
75 {
76 counter++;
77 stdIsotopeMasses.push_back( mass[j] );
78 stdIsotopeProbabilities.push_back( abundance[j] );
79 if( showCounts )
80 stdIsotopeTags.push_back( isotope[j] );
81 }
82 stdIsotopeNumbers.push_back(counter);
83 }
84
85 std::vector<double*> IM;
86 std::vector<double*> IP;
87 size_t tot = 0;
88 for(size_t ii = 0; ii<stdIsotopeNumbers.size(); ii++)
89 {
90 IM.push_back(&(stdIsotopeMasses.data()[tot]));
91 IP.push_back(&(stdIsotopeProbabilities.data()[tot]));
92 tot += stdIsotopeNumbers[ii];
93 }
94 Iso iso(dimNumber, stdIsotopeNumbers.data(), Rcpp::as<std::vector<int> >( molecule).data(), IM.data(), IP.data());
95 IsoGenerator* IG = mkIsoG(iso, algo, stopCondition, tabSize, hashSize, step, trim);
96
97 unsigned int columnsNo = stdIsotopeTags.size(); // standard
98
99 unsigned int isotopesNo = iso.getAllDim();
100
101 // Code doing useless copying around of memory follows, as NumericMatrix apparently can't resize dynamically like std::vector does, so we can't directly
102 // write into it, as we don't know how many configurations we're going to get upfront and we can't preallocate size.
103 std::vector<double> logProbs;
104 std::vector<double> masses;
105 std::vector<int> confs;
106 std::vector<size_t> ordering;
107 size_t data_offset = 0;
108
109 while(IG->advanceToNextConfiguration())
110 {
111 logProbs.push_back(IG->lprob());
112 masses.push_back(IG->mass());
113 if(showCounts)
114 {
115 confs.resize(confs.size()+isotopesNo);
116 IG->get_conf_signature(&(confs.data()[data_offset]));
117 data_offset += isotopesNo;
118 }
119 }
120
121 delete IG;
122 IG = nullptr;
123
124 const bool needs_sorting = (ISOSPEC_ALGO_ORDERED == algo);
125
126 if(needs_sorting)
127 {
128 // We need to sort the confs for backward compatibility
129 ordering.reserve(logProbs.size());
130 for(size_t i = 0; i < logProbs.size(); i++)
131 ordering.push_back(i);
132 std::sort(ordering.begin(), ordering.end(), [&logProbs](size_t idx1, size_t idx2) -> bool { return logProbs[idx1] > logProbs[idx2]; });
133 }
134
135 NumericMatrix res(logProbs.size(), columnsNo);
136
137
138 size_t idx, confs_idx;
139
140 for(size_t i = 0; i < logProbs.size(); i++)
141 {
142 idx = needs_sorting ? ordering[i] : i;
143 res(i,0) = masses[idx];
144 res(i,1) = logProbs[idx];
145
146 if(showCounts)
147 {
148 confs_idx = idx*isotopesNo;
149 for(size_t j = 0; j < isotopesNo; j++)
150 res(i,2+j) = confs[confs_idx+j];
151 }
152 }
153
154 colnames(res) = stdIsotopeTags; //This is RCPP sugar. It sucks.
155
156 return(res);
157 }
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16
17 #include <iostream>
18 #include "allocator.h"
19
20 namespace IsoSpec
21 {
22
23 template <typename T>
24 Allocator<T>::Allocator(const int dim, const int tabSize): currentId(-1), dim(dim), tabSize(tabSize)
25 {
26 currentTab = new T[dim * tabSize];
27 }
28
29 template <typename T>
30 Allocator<T>::~Allocator()
31 {
32 for(unsigned int i = 0; i < prevTabs.size(); ++i)
33 {
34 delete [] prevTabs[i];
35 }
36
37 delete [] currentTab;
38 }
39
40 template <typename T>
41 void Allocator<T>::shiftTables()
42 {
43 prevTabs.push_back(currentTab);
44 currentTab = new T[dim * tabSize];
45 currentId = 0;
46 }
47
48 template class Allocator<int>;
49
50 }
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <vector>
19 #include <iostream>
20 #include <string.h>
21 #include "conf.h"
22
23 namespace IsoSpec
24 {
25
26 template <typename T> inline void copyConf(
27 const T* source, T* destination,
28 int dim
29 ){
30 memcpy(destination, source, dim*sizeof(T));
31 }
32
33 template <typename T> class Allocator{
34 private:
35 T* currentTab;
36 int currentId;
37 const int dim, tabSize;
38 std::vector<T*> prevTabs;
39 public:
40 Allocator(const int dim, const int tabSize = 10000);
41 ~Allocator();
42
43 void shiftTables();
44
45 inline T* newConf()
46 {
47 currentId++;
48
49 if (currentId >= tabSize)
50 shiftTables();
51
52 return &(currentTab[ currentId * dim ]);
53 }
54
55 inline T* makeCopy(const T* conf)
56 {
57 T* currentPlace = newConf();
58 copyConf<T>( conf, currentPlace, dim );
59
60 return currentPlace;
61 }
62
63 inline T* makeExternalCopy(const T* conf)
64 {
65 T* res = new T[dim];
66 copyConf( conf, res, dim );
67
68 return res;
69 }
70 };
71
72 }
73
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 namespace IsoSpec
19 {
20
21 typedef int* Conf;
22
23 }
24
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16
17 #include <tuple>
18 #include <string.h>
19 #include <iostream>
20 #include <algorithm>
21 #include <stdexcept>
22 #include "cwrapper.h"
23 #include "misc.h"
24 #include "marginalTrek++.h"
25 #include "isoSpec++.h"
26 #include "tabulator.h"
27
28 using namespace IsoSpec;
29
30 extern "C"
31 {
32 void * setupIso(int dimNumber,
33 const int* isotopeNumbers,
34 const int* atomCounts,
35 const double* isotopeMasses,
36 const double* isotopeProbabilities)
37 {
38 const double** IM = new const double*[dimNumber];
39 const double** IP = new const double*[dimNumber];
40 int idx = 0;
41 for(int i=0; i<dimNumber; i++)
42 {
43 IM[i] = &isotopeMasses[idx];
44 IP[i] = &isotopeProbabilities[idx];
45 idx += isotopeNumbers[i];
46 }
47 //TODO in place (maybe pass a numpy matrix??)
48
49 Iso* iso = new Iso(dimNumber, isotopeNumbers, atomCounts, IM, IP);
50
51 delete[] IM;
52 delete[] IP;
53
54 return reinterpret_cast<void*>(iso);
55 }
56
57 void deleteIso(void* iso)
58 {
59 delete reinterpret_cast<Iso*>(iso);
60 }
61
62
63 #define ISOSPEC_C_FN_CODE(generatorType, dataType, method)\
64 dataType method##generatorType(void* generator){ return reinterpret_cast<generatorType*>(generator)->method(); }
65
66 #define ISOSPEC_C_FN_CODE_GET_CONF_SIGNATURE(generatorType)\
67 void get_conf_signature##generatorType(void* generator, int* space)\
68 { reinterpret_cast<generatorType*>(generator)->get_conf_signature(space); }
69
70
71 #define ISOSPEC_C_FN_DELETE(generatorType) void delete##generatorType(void* generator){ delete reinterpret_cast<generatorType*>(generator); }
72
73 #define ISOSPEC_C_FN_CODES(generatorType)\
74 ISOSPEC_C_FN_CODE(generatorType, double, mass) \
75 ISOSPEC_C_FN_CODE(generatorType, double, lprob) \
76 ISOSPEC_C_FN_CODE(generatorType, double, prob) \
77 ISOSPEC_C_FN_CODE_GET_CONF_SIGNATURE(generatorType) \
78 ISOSPEC_C_FN_CODE(generatorType, bool, advanceToNextConfiguration) \
79 ISOSPEC_C_FN_DELETE(generatorType)
80
81
82
83 //______________________________________________________THRESHOLD GENERATOR
84 void* setupIsoThresholdGenerator(void* iso,
85 double threshold,
86 bool _absolute,
87 int _tabSize,
88 int _hashSize)
89 {
90 IsoThresholdGenerator* iso_tmp = new IsoThresholdGenerator(
91 std::move(*reinterpret_cast<Iso*>(iso)),
92 threshold,
93 _absolute,
94 _tabSize,
95 _hashSize);
96
97 return reinterpret_cast<void*>(iso_tmp);
98 }
99 ISOSPEC_C_FN_CODES(IsoThresholdGenerator)
100
101
102 //______________________________________________________LAYERED GENERATOR
103 void* setupIsoLayeredGenerator(void* iso,
104 double _target_coverage,
105 double _percentage_to_expand,
106 int _tabSize,
107 int _hashSize,
108 bool _do_trim)
109 {
110 IsoLayeredGenerator* iso_tmp = new IsoLayeredGenerator(
111 std::move(*reinterpret_cast<Iso*>(iso)),
112 _target_coverage,
113 _percentage_to_expand,
114 _tabSize,
115 _hashSize,
116 _do_trim);
117
118 return reinterpret_cast<void*>(iso_tmp);
119 }
120 ISOSPEC_C_FN_CODES(IsoLayeredGenerator)
121
122
123 //______________________________________________________ORDERED GENERATOR
124 void* setupIsoOrderedGenerator(void* iso,
125 int _tabSize,
126 int _hashSize)
127 {
128 IsoOrderedGenerator* iso_tmp = new IsoOrderedGenerator(
129 std::move(*reinterpret_cast<Iso*>(iso)),
130 _tabSize,
131 _hashSize);
132
133 return reinterpret_cast<void*>(iso_tmp);
134 }
135 ISOSPEC_C_FN_CODES(IsoOrderedGenerator)
136
137 //______________________________________________________ Threshold Tabulator
138
139 void* setupThresholdTabulator(void* generator,
140 bool get_masses,
141 bool get_probs,
142 bool get_lprobs,
143 bool get_confs)
144 {
145 Tabulator<IsoThresholdGenerator>* tabulator = new Tabulator<IsoThresholdGenerator>(reinterpret_cast<IsoThresholdGenerator*>(generator),
146 get_masses,
147 get_probs,
148 get_lprobs,
149 get_confs);
150
151 return reinterpret_cast<void*>(tabulator);
152 }
153
154 void deleteThresholdTabulator(void* t)
155 {
156 delete reinterpret_cast<Tabulator<IsoThresholdGenerator>*>(t);
157 }
158
159 const double* massesThresholdTabulator(void* tabulator)
160 {
161 return reinterpret_cast<Tabulator<IsoThresholdGenerator>*>(tabulator)->masses();
162 }
163
164 const double* lprobsThresholdTabulator(void* tabulator)
165 {
166 return reinterpret_cast<Tabulator<IsoThresholdGenerator>*>(tabulator)->lprobs();
167 }
168
169 const double* probsThresholdTabulator(void* tabulator)
170 {
171 return reinterpret_cast<Tabulator<IsoThresholdGenerator>*>(tabulator)->probs();
172 }
173
174 const int* confsThresholdTabulator(void* tabulator)
175 {
176 return reinterpret_cast<Tabulator<IsoThresholdGenerator>*>(tabulator)->confs();
177 }
178
179 int confs_noThresholdTabulator(void* tabulator)
180 {
181 return reinterpret_cast<Tabulator<IsoThresholdGenerator>*>(tabulator)->confs_no();
182 }
183
184
185 //______________________________________________________ Layered Tabulator
186
187 void* setupLayeredTabulator(void* generator,
188 bool get_masses,
189 bool get_probs,
190 bool get_lprobs,
191 bool get_confs)
192 {
193 Tabulator<IsoLayeredGenerator>* tabulator = new Tabulator<IsoLayeredGenerator>(reinterpret_cast<IsoLayeredGenerator*>(generator),
194 get_masses,
195 get_probs,
196 get_lprobs,
197 get_confs);
198
199 return reinterpret_cast<void*>(tabulator);
200 }
201
202 void deleteLayeredTabulator(void* t)
203 {
204 delete reinterpret_cast<Tabulator<IsoLayeredGenerator>*>(t);
205 }
206
207 const double* massesLayeredTabulator(void* tabulator)
208 {
209 return reinterpret_cast<Tabulator<IsoLayeredGenerator>*>(tabulator)->masses();
210 }
211
212 const double* lprobsLayeredTabulator(void* tabulator)
213 {
214 return reinterpret_cast<Tabulator<IsoLayeredGenerator>*>(tabulator)->lprobs();
215 }
216
217 const double* probsLayeredTabulator(void* tabulator)
218 {
219 return reinterpret_cast<Tabulator<IsoLayeredGenerator>*>(tabulator)->probs();
220 }
221
222 const int* confsLayeredTabulator(void* tabulator)
223 {
224 return reinterpret_cast<Tabulator<IsoLayeredGenerator>*>(tabulator)->confs();
225 }
226
227 int confs_noLayeredTabulator(void* tabulator)
228 {
229 return reinterpret_cast<Tabulator<IsoLayeredGenerator>*>(tabulator)->confs_no();
230 }
231
232
233
234 } //extern "C" ends here
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #define ISOSPEC_ALGO_LAYERED 0
19 #define ISOSPEC_ALGO_ORDERED 1
20 #define ISOSPEC_ALGO_THRESHOLD_ABSOLUTE 2
21 #define ISOSPEC_ALGO_THRESHOLD_RELATIVE 3
22 #define ISOSPEC_ALGO_LAYERED_ESTIMATE 4
23
24
25 #ifdef __cplusplus
26 extern "C" {
27 #else
28 #include <stdbool.h>
29 #endif
30
31 void * setupIso(int dimNumber,
32 const int* isotopeNumbers,
33 const int* atomCounts,
34 const double* isotopeMasses,
35 const double* isotopeProbabilities);
36
37 void deleteIso(void* iso);
38
39 #define ISOSPEC_C_FN_HEADER(generatorType, dataType, method)\
40 dataType method##generatorType(void* generator);
41
42 #define ISOSPEC_C_FN_HEADER_GET_CONF_SIGNATURE(generatorType)\
43 void method##generatorType(void* generator);
44
45 #define ISOSPEC_C_FN_HEADERS(generatorType)\
46 ISOSPEC_C_FN_HEADER(generatorType, double, mass) \
47 ISOSPEC_C_FN_HEADER(generatorType, double, lprob) \
48 ISOSPEC_C_FN_HEADER(generatorType, double, prob) \
49 ISOSPEC_C_FN_HEADER_GET_CONF_SIGNATURE(generatorType) \
50 ISOSPEC_C_FN_HEADER(generatorType, bool, advanceToNextConfiguration) \
51 ISOSPEC_C_FN_HEADER(generatorType, void, delete)
52
53
54
55
56 //______________________________________________________THRESHOLD GENERATOR
57 void* setupIsoThresholdGenerator(void* iso,
58 double threshold,
59 bool _absolute,
60 int _tabSize,
61 int _hashSize);
62 ISOSPEC_C_FN_HEADERS(IsoThresholdGenerator)
63
64
65 //______________________________________________________LAYERED GENERATOR
66 void* setupIsoLayeredGenerator(void* iso,
67 double _target_coverage,
68 double _percentage_to_expand,
69 int _tabSize,
70 int _hashSize,
71 bool _do_trim);
72 ISOSPEC_C_FN_HEADERS(IsoLayeredGenerator)
73
74 //______________________________________________________ORDERED GENERATOR
75 void* setupIsoOrderedGenerator(void* iso,
76 int _tabSize,
77 int _hashSize);
78 ISOSPEC_C_FN_HEADERS(IsoOrderedGenerator)
79
80
81
82 void* setupThresholdTabulator(void* generator,
83 bool get_masses,
84 bool get_probs,
85 bool get_lprobs,
86 bool get_confs);
87
88 void deleteThresholdTabulator(void* tabulator);
89
90 const double* massesThresholdTabulator(void* tabulator);
91 const double* lprobsThresholdTabulator(void* tabulator);
92 const double* probsThresholdTabulator(void* tabulator);
93 const int* confsThresholdTabulator(void* tabulator);
94 int confs_noThresholdTabulator(void* tabulator);
95
96
97
98 void* setupLayeredTabulator(void* generator,
99 bool get_masses,
100 bool get_probs,
101 bool get_lprobs,
102 bool get_confs);
103
104 void deleteLayeredTabulator(void* tabulator);
105
106 const double* massesLayeredTabulator(void* tabulator);
107 const double* lprobsLayeredTabulator(void* tabulator);
108 const double* probsLayeredTabulator(void* tabulator);
109 const int* confsLayeredTabulator(void* tabulator);
110 int confs_noLayeredTabulator(void* tabulator);
111
112 #ifdef __cplusplus
113 }
114 #endif
115
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16
17 #include <iostream>
18 #include <stdlib.h>
19 #include "dirtyAllocator.h"
20
21 namespace IsoSpec
22 {
23
24 DirtyAllocator::DirtyAllocator(
25 const int dim, const int tabSize
26 ): tabSize(tabSize)
27 {
28 cellSize = sizeof(double) + sizeof(int) * dim;
29 // Fix memory alignment problems for SPARC
30 if(cellSize % sizeof(double) != 0)
31 cellSize += sizeof(double) - cellSize % sizeof(double);
32 currentTab = malloc( cellSize * tabSize );
33 currentConf = currentTab;
34 endOfTablePtr = reinterpret_cast<char*>(currentTab) + cellSize*tabSize;
35 }
36
37
38 DirtyAllocator::~DirtyAllocator()
39 {
40 for(unsigned int i = 0; i < prevTabs.size(); ++i) free(prevTabs[i]);
41 free(currentTab);
42 }
43
44 void DirtyAllocator::shiftTables()
45 {
46 prevTabs.push_back(currentTab);
47
48 currentTab = malloc( cellSize * tabSize );
49 currentConf = currentTab;
50 endOfTablePtr = reinterpret_cast<char*>(currentTab) + cellSize*tabSize;
51 }
52
53 } // namespace IsoSpec
54
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <vector>
19 #include <iostream>
20 #include <string.h>
21
22 namespace IsoSpec
23 {
24
25 class DirtyAllocator{
26 private:
27 void* currentTab;
28 void* currentConf;
29 void* endOfTablePtr;
30 const int tabSize;
31 int cellSize;
32 std::vector<void*> prevTabs;
33 public:
34 DirtyAllocator(const int dim, const int tabSize = 10000);
35 ~DirtyAllocator();
36
37 void shiftTables();
38
39 inline void* newConf()
40 {
41 if (currentConf >= endOfTablePtr)
42 {
43 shiftTables();
44 }
45
46 void* ret = currentConf;
47 currentConf = reinterpret_cast<char*>(currentConf) + cellSize;
48
49 return ret;
50 }
51
52 inline void* makeCopy(const void* conf)
53 {
54 void* currentPlace = newConf();
55
56 memcpy(currentPlace, conf, cellSize);
57
58 return currentPlace;
59 }
60
61 inline void* makeExternalCopy(const void* conf)
62 {
63 void* res = malloc(cellSize);
64
65 memcpy(res, conf, cellSize);
66
67 return res;
68 }
69 };
70
71 } // namespace IsoSpec
72
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #include "element_tables.h"
17
18 namespace IsoSpec
19 {
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25 const int elem_table_atomicNo [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
26 1,
27 1,
28 2,
29 2,
30 3,
31 3,
32 4,
33 5,
34 5,
35 6,
36 6,
37 7,
38 7,
39 8,
40 8,
41 8,
42 9,
43 10,
44 10,
45 10,
46 11,
47 12,
48 12,
49 12,
50 13,
51 14,
52 14,
53 14,
54 15,
55 16,
56 16,
57 16,
58 16,
59 17,
60 17,
61 18,
62 18,
63 18,
64 19,
65 19,
66 19,
67 20,
68 20,
69 20,
70 20,
71 20,
72 20,
73 21,
74 22,
75 22,
76 22,
77 22,
78 22,
79 23,
80 23,
81 24,
82 24,
83 24,
84 24,
85 25,
86 26,
87 26,
88 26,
89 26,
90 27,
91 28,
92 28,
93 28,
94 28,
95 28,
96 29,
97 29,
98 30,
99 30,
100 30,
101 30,
102 30,
103 31,
104 31,
105 32,
106 32,
107 32,
108 32,
109 32,
110 33,
111 34,
112 34,
113 34,
114 34,
115 34,
116 34,
117 35,
118 35,
119 36,
120 36,
121 36,
122 36,
123 36,
124 36,
125 37,
126 37,
127 38,
128 38,
129 38,
130 38,
131 39,
132 40,
133 40,
134 40,
135 40,
136 40,
137 41,
138 42,
139 42,
140 42,
141 42,
142 42,
143 42,
144 42,
145 44,
146 44,
147 44,
148 44,
149 44,
150 44,
151 44,
152 45,
153 46,
154 46,
155 46,
156 46,
157 46,
158 46,
159 47,
160 47,
161 48,
162 48,
163 48,
164 48,
165 48,
166 48,
167 48,
168 48,
169 49,
170 49,
171 50,
172 50,
173 50,
174 50,
175 50,
176 50,
177 50,
178 50,
179 50,
180 50,
181 51,
182 51,
183 52,
184 52,
185 52,
186 52,
187 52,
188 52,
189 52,
190 52,
191 53,
192 54,
193 54,
194 54,
195 54,
196 54,
197 54,
198 54,
199 54,
200 54,
201 55,
202 56,
203 56,
204 56,
205 56,
206 56,
207 56,
208 56,
209 57,
210 57,
211 58,
212 58,
213 58,
214 58,
215 59,
216 60,
217 60,
218 60,
219 60,
220 60,
221 60,
222 60,
223 62,
224 62,
225 62,
226 62,
227 62,
228 62,
229 62,
230 63,
231 63,
232 64,
233 64,
234 64,
235 64,
236 64,
237 64,
238 64,
239 65,
240 66,
241 66,
242 66,
243 66,
244 66,
245 66,
246 66,
247 67,
248 68,
249 68,
250 68,
251 68,
252 68,
253 68,
254 69,
255 70,
256 70,
257 70,
258 70,
259 70,
260 70,
261 70,
262 71,
263 71,
264 72,
265 72,
266 72,
267 72,
268 72,
269 72,
270 73,
271 73,
272 74,
273 74,
274 74,
275 74,
276 74,
277 75,
278 75,
279 76,
280 76,
281 76,
282 76,
283 76,
284 76,
285 76,
286 77,
287 77,
288 78,
289 78,
290 78,
291 78,
292 78,
293 78,
294 79,
295 80,
296 80,
297 80,
298 80,
299 80,
300 80,
301 80,
302 81,
303 81,
304 82,
305 82,
306 82,
307 82,
308 83,
309 92,
310 92,
311 92,
312 90,
313 91,
314 };
315
316
317 const double elem_table_mass [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
318 1.00782503227,
319 2.01410177819,
320 3.016029322,
321 4.00260325414,
322 6.0151228871,
323 7.016003443,
324 9.01218316,
325 10.0129373,
326 11.0093053,
327 12,
328 13.0033548352,
329 14.0030740042,
330 15.0001088994,
331 15.9949146202,
332 16.9991317576,
333 17.9991596137,
334 18.9984031637,
335 19.992440182,
336 20.99384673,
337 21.99138512,
338 22.989769282,
339 23.985041701,
340 24.98583703,
341 25.98259302,
342 26.98153858,
343 27.9769265353,
344 28.9764946653,
345 29.973770012,
346 30.9737619986,
347 31.9720711741,
348 32.9714589101,
349 33.96786703,
350 35.9670812,
351 34.96885273,
352 36.96590264,
353 35.96754512,
354 37.9627322,
355 39.962383122,
356 38.963706493,
357 39.96399824,
358 40.961825263,
359 39.96259092,
360 41.9586181,
361 42.9587662,
362 43.9554822,
363 45.953692,
364 47.95252289,
365 44.9559086,
366 45.9526283,
367 46.9517593,
368 47.9479423,
369 48.9478663,
370 49.9447873,
371 49.9471567,
372 50.9439577,
373 49.9460427,
374 51.9405064,
375 52.9406484,
376 53.9388794,
377 54.9380443,
378 53.9396093,
379 55.9349363,
380 56.9353933,
381 57.9332743,
382 58.9331944,
383 57.9353423,
384 59.9307863,
385 60.9310563,
386 61.9283454,
387 63.9279674,
388 62.9295984,
389 64.9277906,
390 63.9291426,
391 65.9260347,
392 66.9271287,
393 67.9248457,
394 69.925322,
395 68.9255749,
396 70.9247037,
397 69.9242497,
398 71.92207586,
399 72.92345904,
400 73.921177761,
401 75.92140272,
402 74.9215957,
403 73.92247591,
404 75.91921372,
405 76.91991426,
406 77.9173092,
407 79.9165229,
408 81.9167001,
409 78.9183381,
410 80.9162901,
411 77.9203656,
412 79.9163786,
413 81.9134837,
414 82.9141272,
415 83.911497733,
416 85.910610633,
417 84.911789743,
418 86.909180536,
419 83.9134199,
420 85.9092619,
421 86.9088789,
422 87.9056139,
423 88.905842,
424 89.904702,
425 90.905642,
426 91.905032,
427 93.906312,
428 95.908272,
429 92.906372,
430 91.9068086,
431 93.9050853,
432 94.9058393,
433 95.9046763,
434 96.9060183,
435 97.9054053,
436 99.9074728,
437 95.9075903,
438 97.905296,
439 98.9059348,
440 99.9042148,
441 100.9055779,
442 101.9043449,
443 103.905432,
444 102.905502,
445 101.905602,
446 103.9040311,
447 104.9050809,
448 105.9034809,
449 107.9038929,
450 109.9051726,
451 106.905092,
452 108.9047551,
453 105.9064609,
454 107.9041839,
455 109.9030074,
456 110.9041834,
457 111.9027634,
458 112.9044083,
459 113.9033653,
460 115.9047632,
461 112.9040627,
462 114.903878789,
463 111.9048244,
464 113.9027837,
465 114.90334471,
466 115.9017431,
467 116.9029543,
468 117.9016073,
469 118.9033116,
470 119.9022027,
471 121.903442,
472 123.9052778,
473 120.903812,
474 122.904212,
475 119.904062,
476 121.903041,
477 122.904271,
478 123.902821,
479 124.904431,
480 125.903311,
481 127.9044617,
482 129.906222759,
483 126.904473,
484 123.905892,
485 125.904303,
486 127.9035318,
487 128.904780864,
488 129.90350941,
489 130.9050842,
490 131.904155094,
491 133.9053957,
492 135.907214488,
493 132.905451967,
494 129.906322,
495 131.9050618,
496 133.9045082,
497 134.9056882,
498 135.9045762,
499 136.9058272,
500 137.9052472,
501 137.907123,
502 138.906362,
503 135.9071293,
504 137.905998,
505 139.905442,
506 141.909252,
507 140.907662,
508 141.907732,
509 142.909822,
510 143.910092,
511 144.912582,
512 145.913122,
513 147.916902,
514 149.920902,
515 143.912012,
516 146.914902,
517 147.914832,
518 148.917192,
519 149.917282,
520 151.919742,
521 153.922222,
522 150.919862,
523 152.921242,
524 151.919802,
525 153.920872,
526 154.922632,
527 155.922132,
528 156.923972,
529 157.924112,
530 159.927062,
531 158.925352,
532 155.924282,
533 157.924422,
534 159.925202,
535 160.926942,
536 161.926812,
537 162.928742,
538 163.929182,
539 164.930332,
540 161.928792,
541 163.929212,
542 165.930302,
543 166.932052,
544 167.932382,
545 169.935472,
546 168.934222,
547 167.933892,
548 169.934772,
549 170.936332,
550 171.936392,
551 172.938222,
552 173.938872,
553 175.942582,
554 174.940782,
555 175.942692,
556 173.940052,
557 175.941412,
558 176.943232,
559 177.943712,
560 178.945822,
561 179.946562,
562 179.947462,
563 180.948002,
564 179.946712,
565 181.9482047,
566 182.9502237,
567 183.9509317,
568 185.954362,
569 184.9529559,
570 186.955751,
571 183.9524891,
572 185.953841,
573 186.955751,
574 187.955841,
575 188.958142,
576 189.958442,
577 191.961482,
578 190.960592,
579 192.962922,
580 189.959934,
581 191.961042,
582 193.9626817,
583 194.9647927,
584 195.9649527,
585 197.967892,
586 196.9665696,
587 195.965832,
588 197.9667693,
589 198.9682813,
590 199.9683273,
591 200.9703036,
592 201.9706436,
593 203.9734943,
594 202.9723451,
595 204.9744281,
596 203.9730449,
597 205.9744669,
598 206.9758979,
599 207.9766539,
600 208.980401,
601 234.040952,
602 235.043932,
603 238.050792,
604 232.038062,
605 231.035882,
606 };
607
608
609 const int elem_table_massNo [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
610 1,
611 2,
612 3,
613 4,
614 6,
615 7,
616 9,
617 10,
618 11,
619 12,
620 13,
621 14,
622 15,
623 16,
624 17,
625 18,
626 19,
627 20,
628 21,
629 22,
630 23,
631 24,
632 25,
633 26,
634 27,
635 28,
636 29,
637 30,
638 31,
639 32,
640 33,
641 34,
642 36,
643 35,
644 37,
645 36,
646 38,
647 40,
648 39,
649 40,
650 41,
651 40,
652 42,
653 43,
654 44,
655 46,
656 48,
657 45,
658 46,
659 47,
660 48,
661 49,
662 50,
663 50,
664 51,
665 50,
666 52,
667 53,
668 54,
669 55,
670 54,
671 56,
672 57,
673 58,
674 59,
675 58,
676 60,
677 61,
678 62,
679 64,
680 63,
681 65,
682 64,
683 66,
684 67,
685 68,
686 70,
687 69,
688 71,
689 70,
690 72,
691 73,
692 74,
693 76,
694 75,
695 74,
696 76,
697 77,
698 78,
699 80,
700 82,
701 79,
702 81,
703 78,
704 80,
705 82,
706 83,
707 84,
708 86,
709 85,
710 87,
711 84,
712 86,
713 87,
714 88,
715 89,
716 90,
717 91,
718 92,
719 94,
720 96,
721 93,
722 92,
723 94,
724 95,
725 96,
726 97,
727 98,
728 100,
729 96,
730 98,
731 99,
732 100,
733 101,
734 102,
735 104,
736 103,
737 102,
738 104,
739 105,
740 106,
741 108,
742 110,
743 107,
744 109,
745 106,
746 108,
747 110,
748 111,
749 112,
750 113,
751 114,
752 116,
753 113,
754 115,
755 112,
756 114,
757 115,
758 116,
759 117,
760 118,
761 119,
762 120,
763 122,
764 124,
765 121,
766 123,
767 120,
768 122,
769 123,
770 124,
771 125,
772 126,
773 128,
774 130,
775 127,
776 124,
777 126,
778 128,
779 129,
780 130,
781 131,
782 132,
783 134,
784 136,
785 133,
786 130,
787 132,
788 134,
789 135,
790 136,
791 137,
792 138,
793 138,
794 139,
795 136,
796 138,
797 140,
798 142,
799 141,
800 142,
801 143,
802 144,
803 145,
804 146,
805 148,
806 150,
807 144,
808 147,
809 148,
810 149,
811 150,
812 152,
813 154,
814 151,
815 153,
816 152,
817 154,
818 155,
819 156,
820 157,
821 158,
822 160,
823 159,
824 156,
825 158,
826 160,
827 161,
828 162,
829 163,
830 164,
831 165,
832 162,
833 164,
834 166,
835 167,
836 168,
837 170,
838 169,
839 168,
840 170,
841 171,
842 172,
843 173,
844 174,
845 176,
846 175,
847 176,
848 174,
849 176,
850 177,
851 178,
852 179,
853 180,
854 180,
855 181,
856 180,
857 182,
858 183,
859 184,
860 186,
861 185,
862 187,
863 184,
864 186,
865 187,
866 188,
867 189,
868 190,
869 192,
870 191,
871 193,
872 190,
873 192,
874 194,
875 195,
876 196,
877 198,
878 197,
879 196,
880 198,
881 199,
882 200,
883 201,
884 202,
885 204,
886 203,
887 205,
888 204,
889 206,
890 207,
891 208,
892 209,
893 234,
894 235,
895 238,
896 232,
897 231,
898 };
899
900
901 const int elem_table_extraNeutrons [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
902 0,
903 1,
904 0,
905 1,
906 0,
907 1,
908 0,
909 0,
910 1,
911 0,
912 1,
913 0,
914 1,
915 0,
916 1,
917 2,
918 0,
919 0,
920 1,
921 2,
922 0,
923 0,
924 1,
925 2,
926 0,
927 0,
928 1,
929 2,
930 0,
931 0,
932 1,
933 2,
934 4,
935 0,
936 2,
937 0,
938 2,
939 4,
940 0,
941 1,
942 2,
943 0,
944 2,
945 3,
946 4,
947 6,
948 8,
949 0,
950 0,
951 1,
952 2,
953 3,
954 4,
955 0,
956 1,
957 0,
958 2,
959 3,
960 4,
961 0,
962 0,
963 2,
964 3,
965 4,
966 0,
967 0,
968 2,
969 3,
970 4,
971 6,
972 0,
973 2,
974 0,
975 2,
976 3,
977 4,
978 6,
979 0,
980 2,
981 0,
982 2,
983 3,
984 4,
985 6,
986 0,
987 0,
988 2,
989 3,
990 4,
991 6,
992 8,
993 0,
994 2,
995 0,
996 2,
997 4,
998 5,
999 6,
1000 8,
1001 0,
1002 2,
1003 0,
1004 2,
1005 3,
1006 4,
1007 0,
1008 0,
1009 1,
1010 2,
1011 4,
1012 6,
1013 0,
1014 0,
1015 2,
1016 3,
1017 4,
1018 5,
1019 6,
1020 8,
1021 0,
1022 2,
1023 3,
1024 4,
1025 5,
1026 6,
1027 8,
1028 0,
1029 0,
1030 2,
1031 3,
1032 4,
1033 6,
1034 8,
1035 0,
1036 2,
1037 0,
1038 2,
1039 4,
1040 5,
1041 6,
1042 7,
1043 8,
1044 10,
1045 0,
1046 2,
1047 0,
1048 2,
1049 3,
1050 4,
1051 5,
1052 6,
1053 7,
1054 8,
1055 10,
1056 12,
1057 0,
1058 2,
1059 0,
1060 2,
1061 3,
1062 4,
1063 5,
1064 6,
1065 8,
1066 10,
1067 0,
1068 0,
1069 2,
1070 4,
1071 5,
1072 6,
1073 7,
1074 8,
1075 10,
1076 12,
1077 0,
1078 0,
1079 2,
1080 4,
1081 5,
1082 6,
1083 7,
1084 8,
1085 0,
1086 1,
1087 0,
1088 2,
1089 4,
1090 6,
1091 0,
1092 0,
1093 1,
1094 2,
1095 3,
1096 4,
1097 6,
1098 8,
1099 0,
1100 3,
1101 4,
1102 5,
1103 6,
1104 8,
1105 10,
1106 0,
1107 2,
1108 0,
1109 2,
1110 3,
1111 4,
1112 5,
1113 6,
1114 8,
1115 0,
1116 0,
1117 2,
1118 4,
1119 5,
1120 6,
1121 7,
1122 8,
1123 0,
1124 0,
1125 2,
1126 4,
1127 5,
1128 6,
1129 8,
1130 0,
1131 0,
1132 2,
1133 3,
1134 4,
1135 5,
1136 6,
1137 8,
1138 0,
1139 1,
1140 0,
1141 2,
1142 3,
1143 4,
1144 5,
1145 6,
1146 0,
1147 1,
1148 0,
1149 2,
1150 3,
1151 4,
1152 6,
1153 0,
1154 2,
1155 0,
1156 2,
1157 3,
1158 4,
1159 5,
1160 6,
1161 8,
1162 0,
1163 2,
1164 0,
1165 2,
1166 4,
1167 5,
1168 6,
1169 8,
1170 0,
1171 0,
1172 2,
1173 3,
1174 4,
1175 5,
1176 6,
1177 8,
1178 0,
1179 2,
1180 0,
1181 2,
1182 3,
1183 4,
1184 0,
1185 1,
1186 2,
1187 5,
1188 0,
1189 0,
1190 };
1191
1192
1193 const char* elem_table_element [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
1194 "hydrogen",
1195 "hydrogen",
1196 "helium",
1197 "helium",
1198 "lithium",
1199 "lithium",
1200 "beryllium",
1201 "boron",
1202 "boron",
1203 "carbon",
1204 "carbon",
1205 "nitrogen",
1206 "nitrogen",
1207 "oxygen",
1208 "oxygen",
1209 "oxygen",
1210 "fluorine",
1211 "neon",
1212 "neon",
1213 "neon",
1214 "sodium",
1215 "magnesium",
1216 "magnesium",
1217 "magnesium",
1218 "aluminium",
1219 "silicon",
1220 "silicon",
1221 "silicon",
1222 "phosphorus",
1223 "sulfur",
1224 "sulfur",
1225 "sulfur",
1226 "sulfur",
1227 "chlorine",
1228 "chlorine",
1229 "argon",
1230 "argon",
1231 "argon",
1232 "potassium",
1233 "potassium",
1234 "potassium",
1235 "calcium",
1236 "calcium",
1237 "calcium",
1238 "calcium",
1239 "calcium",
1240 "calcium",
1241 "scandium",
1242 "titanium",
1243 "titanium",
1244 "titanium",
1245 "titanium",
1246 "titanium",
1247 "vanadium",
1248 "vanadium",
1249 "chromium",
1250 "chromium",
1251 "chromium",
1252 "chromium",
1253 "manganese",
1254 "iron",
1255 "iron",
1256 "iron",
1257 "iron",
1258 "cobalt",
1259 "nickel",
1260 "nickel",
1261 "nickel",
1262 "nickel",
1263 "nickel",
1264 "copper",
1265 "copper",
1266 "zinc",
1267 "zinc",
1268 "zinc",
1269 "zinc",
1270 "zinc",
1271 "gallium",
1272 "gallium",
1273 "germanium",
1274 "germanium",
1275 "germanium",
1276 "germanium",
1277 "germanium",
1278 "arsenic",
1279 "selenium",
1280 "selenium",
1281 "selenium",
1282 "selenium",
1283 "selenium",
1284 "selenium",
1285 "bromine",
1286 "bromine",
1287 "krypton",
1288 "krypton",
1289 "krypton",
1290 "krypton",
1291 "krypton",
1292 "krypton",
1293 "rubidium",
1294 "rubidium",
1295 "strontium",
1296 "strontium",
1297 "strontium",
1298 "strontium",
1299 "yttrium",
1300 "zirconium",
1301 "zirconium",
1302 "zirconium",
1303 "zirconium",
1304 "zirconium",
1305 "niobium",
1306 "molybdenum",
1307 "molybdenum",
1308 "molybdenum",
1309 "molybdenum",
1310 "molybdenum",
1311 "molybdenum",
1312 "molybdenum",
1313 "ruthenium",
1314 "ruthenium",
1315 "ruthenium",
1316 "ruthenium",
1317 "ruthenium",
1318 "ruthenium",
1319 "ruthenium",
1320 "rhodium",
1321 "palladium",
1322 "palladium",
1323 "palladium",
1324 "palladium",
1325 "palladium",
1326 "palladium",
1327 "silver",
1328 "silver",
1329 "cadmium",
1330 "cadmium",
1331 "cadmium",
1332 "cadmium",
1333 "cadmium",
1334 "cadmium",
1335 "cadmium",
1336 "cadmium",
1337 "indium",
1338 "indium",
1339 "tin",
1340 "tin",
1341 "tin",
1342 "tin",
1343 "tin",
1344 "tin",
1345 "tin",
1346 "tin",
1347 "tin",
1348 "tin",
1349 "antimony",
1350 "antimony",
1351 "tellurium",
1352 "tellurium",
1353 "tellurium",
1354 "tellurium",
1355 "tellurium",
1356 "tellurium",
1357 "tellurium",
1358 "tellurium",
1359 "iodine",
1360 "xenon",
1361 "xenon",
1362 "xenon",
1363 "xenon",
1364 "xenon",
1365 "xenon",
1366 "xenon",
1367 "xenon",
1368 "xenon",
1369 "caesium",
1370 "barium",
1371 "barium",
1372 "barium",
1373 "barium",
1374 "barium",
1375 "barium",
1376 "barium",
1377 "lanthanum",
1378 "lanthanum",
1379 "cerium",
1380 "cerium",
1381 "cerium",
1382 "cerium",
1383 "praseodymium",
1384 "neodymium",
1385 "neodymium",
1386 "neodymium",
1387 "neodymium",
1388 "neodymium",
1389 "neodymium",
1390 "neodymium",
1391 "samarium",
1392 "samarium",
1393 "samarium",
1394 "samarium",
1395 "samarium",
1396 "samarium",
1397 "samarium",
1398 "europium",
1399 "europium",
1400 "gadolinium",
1401 "gadolinium",
1402 "gadolinium",
1403 "gadolinium",
1404 "gadolinium",
1405 "gadolinium",
1406 "gadolinium",
1407 "terbium",
1408 "dysprosium",
1409 "dysprosium",
1410 "dysprosium",
1411 "dysprosium",
1412 "dysprosium",
1413 "dysprosium",
1414 "dysprosium",
1415 "holmium",
1416 "erbium",
1417 "erbium",
1418 "erbium",
1419 "erbium",
1420 "erbium",
1421 "erbium",
1422 "thulium",
1423 "ytterbium",
1424 "ytterbium",
1425 "ytterbium",
1426 "ytterbium",
1427 "ytterbium",
1428 "ytterbium",
1429 "ytterbium",
1430 "lutetium",
1431 "lutetium",
1432 "hafnium",
1433 "hafnium",
1434 "hafnium",
1435 "hafnium",
1436 "hafnium",
1437 "hafnium",
1438 "tantalum",
1439 "tantalum",
1440 "tungsten",
1441 "tungsten",
1442 "tungsten",
1443 "tungsten",
1444 "tungsten",
1445 "rhenium",
1446 "rhenium",
1447 "osmium",
1448 "osmium",
1449 "osmium",
1450 "osmium",
1451 "osmium",
1452 "osmium",
1453 "osmium",
1454 "iridium",
1455 "iridium",
1456 "platinum",
1457 "platinum",
1458 "platinum",
1459 "platinum",
1460 "platinum",
1461 "platinum",
1462 "gold",
1463 "mercury",
1464 "mercury",
1465 "mercury",
1466 "mercury",
1467 "mercury",
1468 "mercury",
1469 "mercury",
1470 "thallium",
1471 "thallium",
1472 "lead",
1473 "lead",
1474 "lead",
1475 "lead",
1476 "bismuth",
1477 "uranium",
1478 "uranium",
1479 "uranium",
1480 "thorium",
1481 "protactinium",
1482 };
1483
1484
1485 const char* elem_table_symbol [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
1486 "H",
1487 "H",
1488 "He",
1489 "He",
1490 "Li",
1491 "Li",
1492 "Be",
1493 "B",
1494 "B",
1495 "C",
1496 "C",
1497 "N",
1498 "N",
1499 "O",
1500 "O",
1501 "O",
1502 "F",
1503 "Ne",
1504 "Ne",
1505 "Ne",
1506 "Na",
1507 "Mg",
1508 "Mg",
1509 "Mg",
1510 "Al",
1511 "Si",
1512 "Si",
1513 "Si",
1514 "P",
1515 "S",
1516 "S",
1517 "S",
1518 "S",
1519 "Cl",
1520 "Cl",
1521 "Ar",
1522 "Ar",
1523 "Ar",
1524 "K",
1525 "K",
1526 "K",
1527 "Ca",
1528 "Ca",
1529 "Ca",
1530 "Ca",
1531 "Ca",
1532 "Ca",
1533 "Sc",
1534 "Ti",
1535 "Ti",
1536 "Ti",
1537 "Ti",
1538 "Ti",
1539 "V",
1540 "V",
1541 "Cr",
1542 "Cr",
1543 "Cr",
1544 "Cr",
1545 "Mn",
1546 "Fe",
1547 "Fe",
1548 "Fe",
1549 "Fe",
1550 "Co",
1551 "Ni",
1552 "Ni",
1553 "Ni",
1554 "Ni",
1555 "Ni",
1556 "Cu",
1557 "Cu",
1558 "Zn",
1559 "Zn",
1560 "Zn",
1561 "Zn",
1562 "Zn",
1563 "Ga",
1564 "Ga",
1565 "Ge",
1566 "Ge",
1567 "Ge",
1568 "Ge",
1569 "Ge",
1570 "As",
1571 "Se",
1572 "Se",
1573 "Se",
1574 "Se",
1575 "Se",
1576 "Se",
1577 "Br",
1578 "Br",
1579 "Kr",
1580 "Kr",
1581 "Kr",
1582 "Kr",
1583 "Kr",
1584 "Kr",
1585 "Rb",
1586 "Rb",
1587 "Sr",
1588 "Sr",
1589 "Sr",
1590 "Sr",
1591 "Y",
1592 "Zr",
1593 "Zr",
1594 "Zr",
1595 "Zr",
1596 "Zr",
1597 "Nb",
1598 "Mo",
1599 "Mo",
1600 "Mo",
1601 "Mo",
1602 "Mo",
1603 "Mo",
1604 "Mo",
1605 "Ru",
1606 "Ru",
1607 "Ru",
1608 "Ru",
1609 "Ru",
1610 "Ru",
1611 "Ru",
1612 "Rh",
1613 "Pd",
1614 "Pd",
1615 "Pd",
1616 "Pd",
1617 "Pd",
1618 "Pd",
1619 "Ag",
1620 "Ag",
1621 "Cd",
1622 "Cd",
1623 "Cd",
1624 "Cd",
1625 "Cd",
1626 "Cd",
1627 "Cd",
1628 "Cd",
1629 "In",
1630 "In",
1631 "Sn",
1632 "Sn",
1633 "Sn",
1634 "Sn",
1635 "Sn",
1636 "Sn",
1637 "Sn",
1638 "Sn",
1639 "Sn",
1640 "Sn",
1641 "Sb",
1642 "Sb",
1643 "Te",
1644 "Te",
1645 "Te",
1646 "Te",
1647 "Te",
1648 "Te",
1649 "Te",
1650 "Te",
1651 "I",
1652 "Xe",
1653 "Xe",
1654 "Xe",
1655 "Xe",
1656 "Xe",
1657 "Xe",
1658 "Xe",
1659 "Xe",
1660 "Xe",
1661 "Cs",
1662 "Ba",
1663 "Ba",
1664 "Ba",
1665 "Ba",
1666 "Ba",
1667 "Ba",
1668 "Ba",
1669 "La",
1670 "La",
1671 "Ce",
1672 "Ce",
1673 "Ce",
1674 "Ce",
1675 "Pr",
1676 "Nd",
1677 "Nd",
1678 "Nd",
1679 "Nd",
1680 "Nd",
1681 "Nd",
1682 "Nd",
1683 "Sm",
1684 "Sm",
1685 "Sm",
1686 "Sm",
1687 "Sm",
1688 "Sm",
1689 "Sm",
1690 "Eu",
1691 "Eu",
1692 "Gd",
1693 "Gd",
1694 "Gd",
1695 "Gd",
1696 "Gd",
1697 "Gd",
1698 "Gd",
1699 "Tb",
1700 "Dy",
1701 "Dy",
1702 "Dy",
1703 "Dy",
1704 "Dy",
1705 "Dy",
1706 "Dy",
1707 "Ho",
1708 "Er",
1709 "Er",
1710 "Er",
1711 "Er",
1712 "Er",
1713 "Er",
1714 "Tm",
1715 "Yb",
1716 "Yb",
1717 "Yb",
1718 "Yb",
1719 "Yb",
1720 "Yb",
1721 "Yb",
1722 "Lu",
1723 "Lu",
1724 "Hf",
1725 "Hf",
1726 "Hf",
1727 "Hf",
1728 "Hf",
1729 "Hf",
1730 "Ta",
1731 "Ta",
1732 "W",
1733 "W",
1734 "W",
1735 "W",
1736 "W",
1737 "Re",
1738 "Re",
1739 "Os",
1740 "Os",
1741 "Os",
1742 "Os",
1743 "Os",
1744 "Os",
1745 "Os",
1746 "Ir",
1747 "Ir",
1748 "Pt",
1749 "Pt",
1750 "Pt",
1751 "Pt",
1752 "Pt",
1753 "Pt",
1754 "Au",
1755 "Hg",
1756 "Hg",
1757 "Hg",
1758 "Hg",
1759 "Hg",
1760 "Hg",
1761 "Hg",
1762 "Tl",
1763 "Tl",
1764 "Pb",
1765 "Pb",
1766 "Pb",
1767 "Pb",
1768 "Bi",
1769 "U",
1770 "U",
1771 "U",
1772 "Th",
1773 "Pa",
1774 };
1775
1776
1777 const bool elem_table_Radioactive [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
1778 false,
1779 false,
1780 false,
1781 false,
1782 false,
1783 false,
1784 false,
1785 false,
1786 false,
1787 false,
1788 false,
1789 false,
1790 false,
1791 false,
1792 false,
1793 false,
1794 false,
1795 false,
1796 false,
1797 false,
1798 false,
1799 false,
1800 false,
1801 false,
1802 false,
1803 false,
1804 false,
1805 false,
1806 false,
1807 false,
1808 false,
1809 false,
1810 false,
1811 false,
1812 false,
1813 false,
1814 false,
1815 false,
1816 false,
1817 true,
1818 false,
1819 false,
1820 false,
1821 false,
1822 false,
1823 false,
1824 true,
1825 false,
1826 false,
1827 false,
1828 false,
1829 false,
1830 false,
1831 true,
1832 false,
1833 false,
1834 false,
1835 false,
1836 false,
1837 false,
1838 false,
1839 false,
1840 false,
1841 false,
1842 false,
1843 false,
1844 false,
1845 false,
1846 false,
1847 false,
1848 false,
1849 false,
1850 false,
1851 false,
1852 false,
1853 false,
1854 false,
1855 false,
1856 false,
1857 false,
1858 false,
1859 false,
1860 false,
1861 true,
1862 false,
1863 false,
1864 false,
1865 false,
1866 false,
1867 false,
1868 true,
1869 false,
1870 false,
1871 true,
1872 false,
1873 false,
1874 false,
1875 false,
1876 false,
1877 false,
1878 true,
1879 false,
1880 false,
1881 false,
1882 false,
1883 false,
1884 false,
1885 false,
1886 false,
1887 false,
1888 true,
1889 false,
1890 false,
1891 false,
1892 false,
1893 false,
1894 false,
1895 false,
1896 true,
1897 false,
1898 false,
1899 false,
1900 false,
1901 false,
1902 false,
1903 false,
1904 false,
1905 false,
1906 false,
1907 false,
1908 false,
1909 false,
1910 false,
1911 false,
1912 false,
1913 false,
1914 false,
1915 false,
1916 false,
1917 false,
1918 true,
1919 false,
1920 true,
1921 false,
1922 true,
1923 false,
1924 false,
1925 false,
1926 false,
1927 false,
1928 false,
1929 false,
1930 false,
1931 false,
1932 false,
1933 false,
1934 false,
1935 false,
1936 false,
1937 false,
1938 false,
1939 false,
1940 false,
1941 true,
1942 true,
1943 false,
1944 false,
1945 false,
1946 false,
1947 false,
1948 false,
1949 false,
1950 false,
1951 false,
1952 true,
1953 false,
1954 true,
1955 false,
1956 false,
1957 false,
1958 false,
1959 false,
1960 false,
1961 true,
1962 false,
1963 false,
1964 false,
1965 false,
1966 false,
1967 false,
1968 false,
1969 false,
1970 true,
1971 false,
1972 false,
1973 false,
1974 true,
1975 false,
1976 true,
1977 true,
1978 false,
1979 false,
1980 false,
1981 false,
1982 true,
1983 false,
1984 false,
1985 false,
1986 false,
1987 false,
1988 false,
1989 false,
1990 false,
1991 false,
1992 false,
1993 false,
1994 false,
1995 false,
1996 false,
1997 false,
1998 false,
1999 false,
2000 false,
2001 false,
2002 false,
2003 false,
2004 false,
2005 false,
2006 false,
2007 false,
2008 false,
2009 false,
2010 false,
2011 false,
2012 false,
2013 false,
2014 false,
2015 true,
2016 true,
2017 false,
2018 false,
2019 false,
2020 false,
2021 false,
2022 true,
2023 false,
2024 true,
2025 false,
2026 false,
2027 false,
2028 false,
2029 false,
2030 true,
2031 true,
2032 true,
2033 false,
2034 false,
2035 false,
2036 false,
2037 false,
2038 false,
2039 false,
2040 true,
2041 false,
2042 false,
2043 false,
2044 false,
2045 false,
2046 false,
2047 false,
2048 false,
2049 false,
2050 false,
2051 false,
2052 false,
2053 false,
2054 false,
2055 false,
2056 false,
2057 false,
2058 false,
2059 false,
2060 true,
2061 true,
2062 true,
2063 true,
2064 true,
2065 true,
2066 };
2067
2068
2069 const double elem_table_probability [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
2070 0.999884290164307909520857720053754746913909912109375000000000,
2071 0.000115709835692033314582735648023970043141162022948265075684,
2072 0.000001342999991941999914655050951672876635711872950196266174,
2073 0.999998657000008006612290500925155356526374816894531250000000,
2074 0.075933925285977116326208147256693337112665176391601562500000,
2075 0.924066074714022800407065005856566131114959716796875000000000,
2076 1.000000000000000000000000000000000000000000000000000000000000,
2077 0.199480830670926506664741850727295968681573867797851562500000,
2078 0.800519169329073410068531302385963499546051025390625000000000,
2079 0.989211941850466902614869013632414862513542175292968750000000,
2080 0.010788058149533083507343178553128382191061973571777343750000,
2081 0.996358014567941707717579902237048372626304626464843750000000,
2082 0.003641985432058271465738386041266494430601596832275390625000,
2083 0.997567609729561044495937949250219389796257019042968750000000,
2084 0.000380998476006095935803702490218825005285907536745071411133,
2085 0.002051391794432822109073288885383590240962803363800048828125,
2086 1.000000000000000000000000000000000000000000000000000000000000,
2087 0.904766666333356561757739200402284041047096252441406250000000,
2088 0.002709810313278070148523823945652111433446407318115234375000,
2089 0.092523523353365264010328417043638182803988456726074218750000,
2090 1.000000000000000000000000000000000000000000000000000000000000,
2091 0.789876809855211581279377242026384919881820678710937500000000,
2092 0.100001999840012789633192369365133345127105712890625000000000,
2093 0.110121190304775615209642580794024979695677757263183593750000,
2094 1.000000000000000000000000000000000000000000000000000000000000,
2095 0.922220833349999713490774411184247583150863647460937500000000,
2096 0.046858437698747611166449900110819726251065731048583984375000,
2097 0.030920728951252581667707985957349592354148626327514648437500,
2098 1.000000000000000000000000000000000000000000000000000000000000,
2099 0.949850011999040066967836537514813244342803955078125000000000,
2100 0.007519398448124149821059081233443066594190895557403564453125,
2101 0.042520598352131823427502155254842364229261875152587890625000,
2102 0.000109991200703943683199964587160479823069181293249130249023,
2103 0.757594848103037898923162174469325691461563110351562500000000,
2104 0.242405151896962045565686594272847287356853485107421875000000,
2105 0.003336205796380696270847510120916012965608388185501098632812,
2106 0.000629799206452999775149304007015871320618316531181335449219,
2107 0.996033994997166272078459314798237755894660949707031250000000,
2108 0.932580526071084436878777523816097527742385864257812500000000,
2109 0.000117099885242112454345267402722186034225160256028175354004,
2110 0.067302374043673424131029037198459263890981674194335937500000,
2111 0.969400838426726974006442105746828019618988037109375000000000,
2112 0.006472228417153705684605746739634923869743943214416503906250,
2113 0.001350985058105257227353823701321289263432845473289489746094,
2114 0.020860869278785776348428271376178599894046783447265625000000,
2115 0.000042999524425259849917842214228613784143817611038684844971,
2116 0.001872079294802999303859447621789513505063951015472412109375,
2117 1.000000000000000000000000000000000000000000000000000000000000,
2118 0.082520097588289403889305617667559999972581863403320312500000,
2119 0.074411070671519405350657905273692449554800987243652343750000,
2120 0.737141543014838140912559083517407998442649841308593750000000,
2121 0.054113506379234489751528514034362160600721836090087890625000,
2122 0.051813782346118462951434224805780104361474514007568359375000,
2123 0.002503979968160254584302881752932989911641925573348999023438,
2124 0.997496020031839680797247638111002743244171142578125000000000,
2125 0.043450743830478963380947732275672024115920066833496093750000,
2126 0.837881075122238416774678171350387856364250183105468750000000,
2127 0.095010483865806516501351097758742980659008026123046875000000,
2128 0.023657697181476075587447382986283628270030021667480468750000,
2129 1.000000000000000000000000000000000000000000000000000000000000,
2130 0.058452792721208068904559240763774141669273376464843750000000,
2131 0.917532497856775930422656983864726498723030090332031250000000,
2132 0.021190743592002535267138085828264593146741390228271484375000,
2133 0.002823965830013456732028309659199294401332736015319824218750,
2134 1.000000000000000000000000000000000000000000000000000000000000,
2135 0.680769095231327558970235713786678388714790344238281250000000,
2136 0.262230419610671172669924544607056304812431335449218750000000,
2137 0.011399083035777891892426083586542517878115177154541015625000,
2138 0.036346250253448952882706635136855766177177429199218750000000,
2139 0.009255151868774300419340228529563319170847535133361816406250,
2140 0.691494255172344751692037334578344598412513732910156250000000,
2141 0.308505744827655137285660202906001359224319458007812500000000,
2142 0.491645713885820234700929631799226626753807067871093750000000,
2143 0.277325508740183801492662496457342058420181274414062500000000,
2144 0.040405292597461665848879164286699960939586162567138671875000,
2145 0.184515103497573135227227680843498092144727706909179687500000,
2146 0.006108381278961075126765489784474993939511477947235107421875,
2147 0.601079797840404217446064194518839940428733825683593750000000,
2148 0.398920202159595671531633342965506017208099365234375000000000,
2149 0.205705812301332946478993335404084064066410064697265625000000,
2150 0.274503726116209989527305879164487123489379882812500000000000,
2151 0.077504017086240106770844704442424699664115905761718750000000,
2152 0.364982406812098314485837136089685373008251190185546875000000,
2153 0.077304037684118531714716482383664697408676147460937500000000,
2154 1.000000000000000000000000000000000000000000000000000000000000,
2155 0.008938426836876709608015190156038443092256784439086914062500,
2156 0.093712506598838590798905556766840163618326187133789062500000,
2157 0.076302570747548426055573145276866853237152099609375000000000,
2158 0.237686167234566703143627819372341036796569824218750000000000,
2159 0.496053694549759227605534306348999962210655212402343750000000,
2160 0.087306634032410290746639702774700708687305450439453125000000,
2161 0.506898896176611657438115798868238925933837890625000000000000,
2162 0.493101103823388231539581738616107031702995300292968750000000,
2163 0.003552948126957346328819165037771199422422796487808227539062,
2164 0.022860666234272977725971998097520554438233375549316406250000,
2165 0.115931407401451927463575941601447993889451026916503906250000,
2166 0.115000220996773441783922464765055337920784950256347656250000,
2167 0.569863179997571966950431487930472940206527709960937500000000,
2168 0.172791577242972227423933873069472610950469970703125000000000,
2169 0.721691132354705722207199869444593787193298339843750000000000,
2170 0.278308867645294166770497668039752170443534851074218750000000,
2171 0.005609775608975640752429381308274969342164695262908935546875,
2172 0.098606055757769678349333730693615507334470748901367187500000,
2173 0.070007199712011511372189431767765199765563011169433593750000,
2174 0.825776968921243081922511919401586055755615234375000000000000,
2175 1.000000000000000000000000000000000000000000000000000000000000,
2176 0.514422711621750239352479638910153880715370178222656250000000,
2177 0.112234410554393593262290096390643157064914703369140625000000,
2178 0.171550886397901253266340404479706194251775741577148437500000,
2179 0.173788376250214926521664438041625544428825378417968750000000,
2180 0.028003615175739928616627238966430013533681631088256835937500,
2181 1.000000000000000000000000000000000000000000000000000000000000,
2182 0.145308494342837241086741073559096548706293106079101562500000,
2183 0.091496458524138415957516201615362660959362983703613281250000,
2184 0.158387558641321063435114524509117472916841506958007812500000,
2185 0.166690329831184980147185115129104815423488616943359375000000,
2186 0.095999792030779435014764544575882609933614730834960937500000,
2187 0.243900902666405350327494261364336125552654266357421875000000,
2188 0.098216463963333416886669624545902479439973831176757812500000,
2189 0.055402974808013198682044020415560225956141948699951171875000,
2190 0.018726273471579152340993346115283202379941940307617187500000,
2191 0.127588609866636532030881312493875157088041305541992187500000,
2192 0.126054915071900669465421174209041055291891098022460937500000,
2193 0.170586053375378299268305681835045106709003448486328125000000,
2194 0.315451225206183960558803391904802992939949035644531250000000,
2195 0.186189948200308125203505937861336860805749893188476562500000,
2196 1.000000000000000000000000000000000000000000000000000000000000,
2197 0.010207550187954890497099569302008603699505329132080078125000,
2198 0.111463248820283120088525663504697149619460105895996093750000,
2199 0.223336399264176588275176982278935611248016357421875000000000,
2200 0.273264416540030363744762098576757125556468963623046875000000,
2201 0.264546508837878890929573572066146880388259887695312500000000,
2202 0.117181876349676070137029171291942475363612174987792968750000,
2203 0.518389668985958174118877650471404194831848144531250000000000,
2204 0.481610331014041714858819887012941762804985046386718750000000,
2205 0.012567197514954164816458614950533956289291381835937500000000,
2206 0.008928009053980960965657409644791187020018696784973144531250,
2207 0.124890149496662231087817929164884844794869422912597656250000,
2208 0.127983459688489453753845737082883715629577636718750000000000,
2209 0.241267197414976458658131264201074372977018356323242187500000,
2210 0.122184752800125570604272695618419675156474113464355468750000,
2211 0.287277937020044504823346187549759633839130401611328125000000,
2212 0.074901297010766587636254598692175932228565216064453125000000,
2213 0.042954845418549769675564675708301365375518798828125000000000,
2214 0.957045154581450119302132861776044592261314392089843750000000,
2215 0.009707379007667929146641050408561568474397063255310058593750,
2216 0.006608215781738930282018795736576066701672971248626708984375,
2217 0.003409079548521898664348306340343697229400277137756347656250,
2218 0.145370749897527656857576516813423950225114822387695312500000,
2219 0.076859248003039171148742525474517606198787689208984375000000,
2220 0.242144620952342848330118840749491937458515167236328125000000,
2221 0.085916802463334898676272644024720648303627967834472656250000,
2222 0.325722055045137792728127124064485542476177215576171875000000,
2223 0.046317494276545329023875297025369945913553237915039062500000,
2224 0.057944355024143474885978122301821713335812091827392578125000,
2225 0.572091349038115315472907695948379114270210266113281250000000,
2226 0.427908650961884573504789841535966843366622924804687500000000,
2227 0.000909764371027903685079651907585684966761618852615356445312,
2228 0.025505394102927340937991829150632838718593120574951171875000,
2229 0.008927687728878220055350745099076448241248726844787597656250,
2230 0.047401722953754971134898710261040832847356796264648437500000,
2231 0.070696689557404629455916733604681212455034255981445312500000,
2232 0.188376210561464557668998054396070074290037155151367187500000,
2233 0.317407791382032011817670991149498149752616882324218750000000,
2234 0.340774739342510235573513455165084451436996459960937500000000,
2235 1.000000000000000000000000000000000000000000000000000000000000,
2236 0.000952296533640617525774685336870106766582466661930084228516,
2237 0.000890196759683794711613680217254795934422872960567474365234,
2238 0.019102830465697103606848017420816177036613225936889648437500,
2239 0.264005869018636762923790683998959138989448547363281250000000,
2240 0.040709981815666186621971434078659513033926486968994140625000,
2241 0.212323527142361190289676642350968904793262481689453125000000,
2242 0.269085350529324029977829013660084456205368041992187500000000,
2243 0.104356830141138279266499466757522895932197570800781250000000,
2244 0.088573117593851946605099101361702196300029754638671875000000,
2245 1.000000000000000000000000000000000000000000000000000000000000,
2246 0.001060985146207953045902061539607075246749445796012878417969,
2247 0.001010985846198153050023993415607037604786455631256103515625,
2248 0.024171461599537605313692267827718751505017280578613281250000,
2249 0.065920277116120362670415033790050074458122253417968750000000,
2250 0.078541300421794094099858796198532218113541603088378906250000,
2251 0.112320827508414877726750091824214905500411987304687500000000,
2252 0.716974162361726841119491382414707913994789123535156250000000,
2253 0.000888171872103250392010975744483403104823082685470581054688,
2254 0.999111828127896672846475212281802669167518615722656250000000,
2255 0.001851973331584025024912354417949700291501358151435852050781,
2256 0.002511963827720880421123794690174690913408994674682617187500,
2257 0.884492463308528265031327464384958148002624511718750000000000,
2258 0.111143599532166723053983048430382041260600090026855468750000,
2259 1.000000000000000000000000000000000000000000000000000000000000,
2260 0.271519166958828106483991859931848011910915374755859375000000,
2261 0.121740433020292235233306143982190405949950218200683593750000,
2262 0.237977663997580829446931716120161581784486770629882812500000,
2263 0.082929723850915446070608538775559281930327415466308593750000,
2264 0.171890140355501652713599014532519504427909851074218750000000,
2265 0.057561075412857647115583148433870519511401653289794921875000,
2266 0.056381796404024006608146635244338540360331535339355468750000,
2267 0.030772522277086666181444840617587033193558454513549804687500,
2268 0.149881578776357327065227309503825381398200988769531250000000,
2269 0.112382691006085513873991033051424892619252204895019531250000,
2270 0.138246406123312015612469849656918086111545562744140625000000,
2271 0.073792068527347848272412988990254234522581100463867187500000,
2272 0.267451009404714612482933944193064235150814056396484375000000,
2273 0.227473723885095902019770619517657905817031860351562500000000,
2274 0.478103065570820051632949798658955842256546020507812500000000,
2275 0.521896934429179837344747738825390115380287170410156250000000,
2276 0.002009636255837693018938550082452820788603276014328002929688,
2277 0.021826049485043207132317633067941642366349697113037109375000,
2278 0.147985214676143617129611129712429828941822052001953125000000,
2279 0.204672954195290635048820604424690827727317810058593750000000,
2280 0.156491675006823760529783839956508018076419830322265625000000,
2281 0.248435033258980114689862261911912355571985244750976562500000,
2282 0.218579437121880937322515592313720844686031341552734375000000,
2283 1.000000000000000000000000000000000000000000000000000000000000,
2284 0.000562985756460361477619691594753703611786477267742156982422,
2285 0.000952975889709990254573812595850768047966994345188140869141,
2286 0.023291210732368467645203580218549177516251802444458007812500,
2287 0.188889421097646226233024435714469291269779205322265625000000,
2288 0.254747154896981076177553404704667627811431884765625000000000,
2289 0.248957901365095435330943018925609067082405090332031250000000,
2290 0.282598350261738351374418698469526134431362152099609375000000,
2291 1.000000000000000000000000000000000000000000000000000000000000,
2292 0.001395973476503946332158423437874716910300776362419128417969,
2293 0.016012695758780580435054474719436257146298885345458984375000,
2294 0.335027234482544788995994622382568195462226867675781250000000,
2295 0.228686654953555862368475004586798604577779769897460937500000,
2296 0.269776674243189351631855288360384292900562286376953125000000,
2297 0.149100767085425356395234075534972362220287322998046875000000,
2298 1.000000000000000000000000000000000000000000000000000000000000,
2299 0.001232929969577727796758992440118163358420133590698242187500,
2300 0.029822206098693591902470956256365752778947353363037109375000,
2301 0.140905996539396560773838018576498143374919891357421875000000,
2302 0.216800685721051017429417129278590437024831771850585937500000,
2303 0.161027253651992552363481081556528806686401367187500000000000,
2304 0.320249909805123023076589561242144554853439331054687500000000,
2305 0.129961018214165419104588750087714288383722305297851562500000,
2306 0.974008767577204226384424146090168505907058715820312500000000,
2307 0.025991232422795697287742910930319339968264102935791015625000,
2308 0.001609652315099938373749166586890169128309935331344604492188,
2309 0.052668623577307296934613134453684324398636817932128906250000,
2310 0.185969830516608397585898160286888014525175094604492187500000,
2311 0.272821070648739838482299546740250661969184875488281250000000,
2312 0.136190582834107815068946933934057597070932388305664062500000,
2313 0.350740240108136591690168870627530850470066070556640625000000,
2314 0.000120131992311552486551486096377772128107608295977115631104,
2315 0.999879868007688354936135510797612369060516357421875000000000,
2316 0.001209872963338849303702171589236513682408258318901062011719,
2317 0.264988176241494621798722164385253563523292541503906250000000,
2318 0.143124971877952811283307710255030542612075805664062500000000,
2319 0.306387829277925793913794905165559612214565277099609375000000,
2320 0.284289149639287863635672692907974123954772949218750000000000,
2321 0.374005039798408045470523575204424560070037841796875000000000,
2322 0.625994960201591843507173962279921397566795349121093750000000,
2323 0.000209947723016968765524098428087995671376120299100875854492,
2324 0.015926034417430057904541129687459033448249101638793945312500,
2325 0.019615115836156795520173190539026109036058187484741210937500,
2326 0.132457018202467580181291850749403238296508789062500000000000,
2327 0.161519781574387955025429164379602298140525817871093750000000,
2328 0.262554623898649197588639481182326562702655792236328125000000,
2329 0.407717478347891348899878494194126687943935394287109375000000,
2330 0.373050779688124722888176165724871680140495300292968750000000,
2331 0.626949220311875166089521371759474277496337890625000000000000,
2332 0.000121987349911814132899338936066868654961581341922283172607,
2333 0.007821588901230941415221309398475568741559982299804687500000,
2334 0.328605923565726210089366077227168716490268707275390625000000,
2335 0.337788971283677852408544595164130441844463348388671875000000,
2336 0.252107856415289710572125159160350449383258819580078125000000,
2337 0.073553672484163390432598816914833150804042816162109375000000,
2338 1.000000000000000000000000000000000000000000000000000000000000,
2339 0.001509815802472098391837085351596670079743489623069763183594,
2340 0.099707835644051417967048678292485419660806655883789062500000,
2341 0.168701418426951910145561441822792403399944305419921875000000,
2342 0.230990819120067331082779560347262304276227951049804687500000,
2343 0.131793921141620695713925215386552736163139343261718750000000,
2344 0.298589572072207154462830658303573727607727050781250000000000,
2345 0.068706617792629293139938795320631470531225204467773437500000,
2346 0.295204095918081610427918803907232359051704406738281250000000,
2347 0.704795904081918278549778733577113598585128784179687500000000,
2348 0.014094362255097959285565778486670751590281724929809570312500,
2349 0.241003598560575765796798464180028531700372695922851562500000,
2350 0.221011595361855245345239495691203046590089797973632812500000,
2351 0.523890443822470963652904174523428082466125488281250000000000,
2352 1.000000000000000000000000000000000000000000000000000000000000,
2353 0.000054599923560107009460132254652364736102754250168800354004,
2354 0.007204689913434121108226637630878030904568731784820556640625,
2355 0.992740710163005690702675565262325108051300048828125000000000,
2356 1.000000000000000000000000000000000000000000000000000000000000,
2357 1.000000000000000000000000000000000000000000000000000000000000,
2358 };
2359
2360
2361 const double elem_table_log_probability [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES] = {
2362 -0.000115716530591520062594239337538937206772970966994762420654,
2363 -9.064424917075021070900220365729182958602905273437500000000000,
2364 -13.520604646423175054792409355286508798599243164062500000000000,
2365 -0.000001343000893767296712052561162564767727189973811618983746,
2366 -2.577891720978651601825504258158616721630096435546875000000000,
2367 -0.078971700466369670889932308455172460526227951049804687500000,
2368 0.000000000000000000000000000000000000000000000000000000000000,
2369 -1.612037134131381055368592569720931351184844970703125000000000,
2370 -0.222494800137427506392384657374350354075431823730468750000000,
2371 -0.010846671177187771836769591971005866071209311485290527343750,
2372 -4.529315483514038120915756735485047101974487304687500000000000,
2373 -0.003648633607616148452623683340334537206217646598815917968750,
2374 -5.615226297668721500144783931318670511245727539062500000000000,
2375 -0.002435353337518350851781390176142849668394774198532104492188,
2376 -7.872715182829573166145564755424857139587402343750000000000000,
2377 -6.189236792082963845018639403861016035079956054687500000000000,
2378 0.000000000000000000000000000000000000000000000000000000000000,
2379 -0.100078195781331494296217954342864686623215675354003906250000,
2380 -5.910876641640641970809610938886180520057678222656250000000000,
2381 -2.380292360271312634978357891668565571308135986328125000000000,
2382 0.000000000000000000000000000000000000000000000000000000000000,
2383 -0.235878282572628383828572395941591821610927581787109375000000,
2384 -2.302565094793883382351395994191989302635192871093750000000000,
2385 -2.206173789605455404227996041299775242805480957031250000000000,
2386 0.000000000000000000000000000000000000000000000000000000000000,
2387 -0.080970568540825488268453113960276823490858078002929687500000,
2388 -3.060624186220378017964094397029839456081390380859375000000000,
2389 -3.476328480144544208485513081541284918785095214843750000000000,
2390 0.000000000000000000000000000000000000000000000000000000000000,
2391 -0.051451188958515865767839869704403099603950977325439453125000,
2392 -4.890269137820559386398144852137193083763122558593750000000000,
2393 -3.157766653355948971437783256988041102886199951171875000000000,
2394 -9.115110188972028737453001667745411396026611328125000000000000,
2395 -0.277606537419771426389303314863354898989200592041015625000000,
2396 -1.417144771312495832304989562544506043195724487304687500000000,
2397 -5.702921106825801444983881083317101001739501953125000000000000,
2398 -7.370109509296556282720302988309413194656372070312500000000000,
2399 -0.003973890456746663815690290277871099533513188362121582031250,
2400 -0.069799776156532433724066777358530089259147644042968750000000,
2401 -9.052483267360123875278077321127057075500488281250000000000000,
2402 -2.698559767416127019856730839819647371768951416015625000000000,
2403 -0.031077090678799931117159971449837030377238988876342773437500,
2404 -5.040234806716209270405215647770091891288757324218750000000000,
2405 -6.606921279942914004834619845496490597724914550781250000000000,
2406 -3.869880158236262079896050636307336390018463134765625000000000,
2407 -10.054321502209552008366699737962335348129272460937500000000000,
2408 -6.280705543488890540970714937429875135421752929687500000000000,
2409 0.000000000000000000000000000000000000000000000000000000000000,
2410 -2.494713408178120150893164463923312723636627197265625000000000,
2411 -2.598150548864236686341655513388104736804962158203125000000000,
2412 -0.304975352295239643396485007542651146650314331054687500000000,
2413 -2.916671468480125817279713373864069581031799316406250000000000,
2414 -2.960099096648749483762230738648213446140289306640625000000000,
2415 -5.989873825712285437816717603709548711776733398437500000000000,
2416 -0.002507120169096173530054461053850900498218834400177001953125,
2417 -3.136127308188753737283605005359277129173278808593750000000000,
2418 -0.176879103699552453488053060937090776860713958740234375000000,
2419 -2.353768036988251211028000398073345422744750976562500000000000,
2420 -3.744066754776672834026385316974483430385589599609375000000000,
2421 0.000000000000000000000000000000000000000000000000000000000000,
2422 -2.839535812544084603104010966490022838115692138671875000000000,
2423 -0.086067279673300162157190129619266372174024581909179687500000,
2424 -3.854190815670504033363386042765341699123382568359375000000000,
2425 -5.869613059277937416879922238877043128013610839843750000000000,
2426 0.000000000000000000000000000000000000000000000000000000000000,
2427 -0.384532097536943340276849312431295402348041534423828125000000,
2428 -1.338531697560186861650777245813515037298202514648437500000000,
2429 -4.474222362274872466514352709054946899414062500000000000000000,
2430 -3.314664237037550087450199498562142252922058105468750000000000,
2431 -4.682574923715371539856278104707598686218261718750000000000000,
2432 -0.368900435688631012087768112905905582010746002197265625000000,
2433 -1.176014814002444008878001113771460950374603271484375000000000,
2434 -0.709996915609857004447746930964058265089988708496093750000000,
2435 -1.282563340904273152531800405995454639196395874023437500000000,
2436 -3.208794497707758708315850526560097932815551757812500000000000,
2437 -1.690023957076583371872402494773268699645996093750000000000000,
2438 -5.098093470692335316130083811003714799880981445312500000000000,
2439 -0.509027578151938331352255318051902577280998229980468750000000,
2440 -0.918993876681337473755206701753195375204086303710937500000000,
2441 -1.581308226517597503857359697576612234115600585937500000000000,
2442 -1.292790443930836863373201595095451921224594116210937500000000,
2443 -2.557425510595298323579527277615852653980255126953125000000000,
2444 -1.007906127076126923114429700945038348436355590820312500000000,
2445 -2.560009090805706488680471011321060359477996826171875000000000,
2446 0.000000000000000000000000000000000000000000000000000000000000,
2447 -4.717395674310531639150667615467682480812072753906250000000000,
2448 -2.367523623737181281967423274181783199310302734375000000000000,
2449 -2.573048648630889889687978211441077291965484619140625000000000,
2450 -1.436804100526558380934716296906117349863052368164062500000000,
2451 -0.701071102975730831019518518587574362754821777343750000000000,
2452 -2.438328827816317101451204507611691951751708984375000000000000,
2453 -0.679443711102156733261381305055692791938781738281250000000000,
2454 -0.707041047215952844773312335746595636010169982910156250000000,
2455 -5.639977561836668762396129750413820147514343261718750000000000,
2456 -3.778337476933724126126890041632577776908874511718750000000000,
2457 -2.154756578276459499932116159470751881599426269531250000000000,
2458 -2.162821228909660220551813836209475994110107421875000000000000,
2459 -0.562358982058553724669991424889303743839263916015625000000000,
2460 -1.755669166607024767046141278115101158618927001953125000000000,
2461 -0.326158026142060741836559145667706616222858428955078125000000,
2462 -1.279023747338471794776637580071110278367996215820312500000000,
2463 -5.183244558647554178776317712618038058280944824218750000000000,
2464 -2.316622601837921013867571673472411930561065673828125000000000,
2465 -2.659157189193052328590738397906534373760223388671875000000000,
2466 -0.191430555333882340685036638205929193645715713500976562500000,
2467 0.000000000000000000000000000000000000000000000000000000000000,
2468 -0.664709955358130821778672725486103445291519165039062500000000,
2469 -2.187165643480033949686003325041383504867553710937500000000000,
2470 -1.762875342696557545707491954090073704719543457031250000000000,
2471 -1.749916948420700224531287858553696423768997192382812500000000,
2472 -3.575421663722070153568211026140488684177398681640625000000000,
2473 0.000000000000000000000000000000000000000000000000000000000000,
2474 -1.928896249393138528915869756019674241542816162109375000000000,
2475 -2.391455012103930855005273770075291395187377929687500000000000,
2476 -1.842710346617601580021528206998482346534729003906250000000000,
2477 -1.791617500319007794118419951701071113348007202148437500000000,
2478 -2.343409253862695162951013116980902850627899169921875000000000,
2479 -1.410993272797839370724659602274186909198760986328125000000000,
2480 -2.320581420206905942649200369487516582012176513671875000000000,
2481 -2.893121989774980473697496563545428216457366943359375000000000,
2482 -3.977827742728266446903262476553209125995635986328125000000000,
2483 -2.058944176423800787034679160569794476032257080078125000000000,
2484 -2.071037633074694905843671222100965678691864013671875000000000,
2485 -1.768515397703714908672623096208553761243820190429687500000000,
2486 -1.153751204177984268639534093381371349096298217773437500000000,
2487 -1.680987899482990099997437027923297137022018432617187500000000,
2488 0.000000000000000000000000000000000000000000000000000000000000,
2489 -4.584627618010170380102863418869674205780029296875000000000000,
2490 -2.194060349407264354226754221599549055099487304687500000000000,
2491 -1.499076127310911887846600620832759886980056762695312500000000,
2492 -1.297315393792867643796284937707241624593734741210937500000000,
2493 -1.329738206325086657955125701846554875373840332031250000000000,
2494 -2.144028052451655508292560625704936683177947998046875000000000,
2495 -0.657028062796280343249577526876237243413925170898437500000000,
2496 -0.730619933776488150733996462804498150944709777832031250000000,
2497 -4.376665231519177190477876138174906373023986816406250000000000,
2498 -4.718561859232925925766721775289624929428100585937500000000000,
2499 -2.080320732081178736194715384044684469699859619140625000000000,
2500 -2.055854244595972435405428768717683851718902587890625000000000,
2501 -1.421850256682005708697147383645642548799514770507812500000000,
2502 -2.102221012532442756537420791573822498321533203125000000000000,
2503 -1.247305110167633124262920318869873881340026855468750000000000,
2504 -2.591584072043251474326552852289751172065734863281250000000000,
2505 -3.147605821582104113076638896018266677856445312500000000000000,
2506 -0.043904705171597842305875047941299271769821643829345703125000,
2507 -4.634868960235463575259018398355692625045776367187500000000000,
2508 -5.019441588675102039474040793720632791519165039062500000000000,
2509 -5.681312951243271847090454684803262352943420410156250000000000,
2510 -1.928467904013302591792466955666895955801010131835937500000000,
2511 -2.565779477876660052970692049711942672729492187500000000000000,
2512 -1.418220124080461719273671405971981585025787353515625000000000,
2513 -2.454375864191848055639866288402117788791656494140625000000000,
2514 -1.121710853164690879779641363711562007665634155273437500000000,
2515 -3.072235543110140021383358543971553444862365722656250000000000,
2516 -2.848272125086215300626690805074758827686309814453125000000000,
2517 -0.558456599237618478426270485215354710817337036132812500000000,
2518 -0.848845538512307262735134827380534261465072631835937500000000,
2519 -7.002324924918669424300787795800715684890747070312500000000000,
2520 -3.668865315739671117967191094066947698593139648437500000000000,
2521 -4.718597850559019590832576795946806669235229492187500000000000,
2522 -3.049096701706386802754877862753346562385559082031250000000000,
2523 -2.649356530974964485380951373372226953506469726562500000000000,
2524 -1.669314195717893856141245123581029474735260009765625000000000,
2525 -1.147567923673684653351756423944607377052307128906250000000000,
2526 -1.076533608421685217493291020218748599290847778320312500000000,
2527 0.000000000000000000000000000000000000000000000000000000000000,
2528 -6.956634086757649271248737932182848453521728515625000000000000,
2529 -7.024068041375896243039278488140553236007690429687500000000000,
2530 -3.957918762987576943856993239023722708225250244140625000000000,
2531 -1.331783944951729026229259034153074026107788085937500000000000,
2532 -3.201281963147128539759478371706791222095489501953125000000000,
2533 -1.549644096147559713116947932576294988393783569335937500000000,
2534 -1.312726661492457758129148714942857623100280761718750000000000,
2535 -2.259939193445343441624117986066266894340515136718750000000000,
2536 -2.423926880572130126978436237550340592861175537109375000000000,
2537 0.000000000000000000000000000000000000000000000000000000000000,
2538 -6.848557419252292000066972832428291440010070800781250000000000,
2539 -6.896829338845804180380127945682033896446228027343750000000000,
2540 -3.722582614455130833874818563344888389110565185546875000000000,
2541 -2.719309189565115580933252203976735472679138183593750000000000,
2542 -2.544130672523534641982223547529429197311401367187500000000000,
2543 -2.186395971313551900294669394497759640216827392578125000000000,
2544 -0.332715474789523235621402363904053345322608947753906250000000,
2545 -7.026345284034602123313106858404353260993957519531250000000000,
2546 -0.000888566530440708531556059934786162557429634034633636474609,
2547 -6.291503542654471203832144965417683124542236328125000000000000,
2548 -5.986690430272505913933400734094902873039245605468750000000000,
2549 -0.122741286268200244791160002932883799076080322265625000000000,
2550 -2.196932224286036738902794240857474505901336669921875000000000,
2551 0.000000000000000000000000000000000000000000000000000000000000,
2552 -1.303722545566528001614869936020113527774810791015625000000000,
2553 -2.105864098995690714133388610207475721836090087890625000000000,
2554 -1.435578458464392248572494281688705086708068847656250000000000,
2555 -2.489761730430327446583760320208966732025146484375000000000000,
2556 -1.760899725099839052688821539049968123435974121093750000000000,
2557 -2.854908713800850428299327177228406071662902832031250000000000,
2558 -2.875608931369854293080834395368583500385284423828125000000000,
2559 -3.481133121051686263314195457496680319309234619140625000000000,
2560 -1.897909771509530774125096286297775804996490478515625000000000,
2561 -2.185845347988713882614320027641952037811279296875000000000000,
2562 -1.978717634408995396100294783536810427904129028320312500000000,
2563 -2.606504025680458358493751802598126232624053955078125000000000,
2564 -1.318818871830977013104302386636845767498016357421875000000000,
2565 -1.480720546667873893653677441761828958988189697265625000000000,
2566 -0.737928951383980402667361886415164917707443237304687500000000,
2567 -0.650285154216317162756411107693566009402275085449218750000000,
2568 -6.209801540532629005042508651968091726303100585937500000000000,
2569 -3.824651092041761124562526674708351492881774902343750000000000,
2570 -1.910642911045310476936265331460162997245788574218750000000000,
2571 -1.586341919151083468264573639316949993371963500976562500000000,
2572 -1.854752465261401805918239915627054870128631591796875000000000,
2573 -1.392573903203236485026650370855350047349929809570312500000000,
2574 -1.520605773895307155640921337180770933628082275390625000000000,
2575 0.000000000000000000000000000000000000000000000000000000000000,
2576 -7.482256229504544720043668348807841539382934570312500000000000,
2577 -6.955920953990032629121742502320557832717895507812500000000000,
2578 -3.759679211363279094371137034613639116287231445312500000000000,
2579 -1.666593508702244319508167791354935616254806518554687500000000,
2580 -1.367483775157640080166743246081750839948654174804687500000000,
2581 -1.390471467634422086945278351777233183383941650390625000000000,
2582 -1.263728646463758931162146836868487298488616943359375000000000,
2583 0.000000000000000000000000000000000000000000000000000000000000,
2584 -6.574163274461459316455602674977853894233703613281250000000000,
2585 -4.134373386461300370342542009893804788589477539062500000000000,
2586 -1.093543453498669215662175702163949608802795410156250000000000,
2587 -1.475402531411262208038692733680363744497299194335937500000000,
2588 -1.310160794679168905219057705835439264774322509765625000000000,
2589 -1.903132912453214142800561603507958352565765380859375000000000,
2590 0.000000000000000000000000000000000000000000000000000000000000,
2591 -6.698361853186871606169461301760748028755187988281250000000000,
2592 -3.512501991875810691823289744206704199314117431640625000000000,
2593 -1.959662302151332857746979243529494851827621459960937500000000,
2594 -1.528776846501670894085123109107371419668197631835937500000000,
2595 -1.826181650981897996999236966075841337442398071289062500000000,
2596 -1.138653619844293141127877788676414638757705688476562500000000,
2597 -2.040520733384556528733355662552639842033386230468750000000000,
2598 -0.026334973760810023724054929061821894720196723937988281250000,
2599 -3.649996012338110329409346377360634505748748779296875000000000,
2600 -6.431737076661124596910212858347222208976745605468750000000000,
2601 -2.943735378782415867959798561059869825839996337890625000000000,
2602 -1.682170819948636486529380817955825477838516235351562500000000,
2603 -1.298939117547105670524842935265041887760162353515625000000000,
2604 -1.993700029844323484695678416755981743335723876953125000000000,
2605 -1.047709386165366352017258577689062803983688354492187500000000,
2606 -9.026919483738925720217594061978161334991455078125000000000000,
2607 -0.000120139208737295727770326425609681564310449175536632537842,
2608 -6.717239913861373423742406885139644145965576171875000000000000,
2609 -1.328070071947949681856471215724013745784759521484375000000000,
2610 -1.944037101159571623298916165367700159549713134765625000000000,
2611 -1.182903563582415440436079734354279935359954833984375000000000,
2612 -1.257763426233626136152565777592826634645462036132812500000000,
2613 -0.983486006261584555510069094452774152159690856933593750000000,
2614 -0.468412958710625382252601411892101168632507324218750000000000,
2615 -8.468651996251450597696930344682186841964721679687500000000000,
2616 -4.139800124064825226355424092616885900497436523437500000000000,
2617 -3.931454793849565199082007893593981862068176269531250000000000,
2618 -2.021497077106750417385683249449357390403747558593750000000000,
2619 -1.823127657291570224984411652258131653070449829101562500000000,
2620 -1.337296127555923419549799291417002677917480468750000000000000,
2621 -0.897180799465370992784585268964292481541633605957031250000000,
2622 -0.986040730030275258677363581227837130427360534667968750000000,
2623 -0.466889729967265909582607719130464829504489898681640625000000,
2624 -9.011593207854545539703394751995801925659179687500000000000000,
2625 -4.850867560763419739089385984698310494422912597656250000000000,
2626 -1.112896046865470500719652591214980930089950561523437500000000,
2627 -1.085333923798379451852724741911515593528747558593750000000000,
2628 -1.377898281389317913792069703049492090940475463867187500000000,
2629 -2.609739901377524873282709449995309114456176757812500000000000,
2630 0.000000000000000000000000000000000000000000000000000000000000,
2631 -6.495767620713909451524159521795809268951416015625000000000000,
2632 -2.305511012885385291326656442834064364433288574218750000000000,
2633 -1.779624881481258524829058842442464083433151245117187500000000,
2634 -1.465377313319132568381064629647880792617797851562500000000000,
2635 -2.026515779816368212351562760886736214160919189453125000000000,
2636 -1.208685317218918919834891312348190695047378540039062500000000,
2637 -2.677909755533927516069070406956598162651062011718750000000000,
2638 -1.220088311290825400234894004825036972761154174804687500000000,
2639 -0.349847015838577246604756965098204091191291809082031250000000,
2640 -4.261980401619341662922124669421464204788208007812500000000000,
2641 -1.422943413816338820154783206817228347063064575195312500000000,
2642 -1.509540111140063478600836788245942443609237670898437500000000,
2643 -0.646472693195343506289418655796907842159271240234375000000000,
2644 0.000000000000000000000000000000000000000000000000000000000000,
2645 -9.815478075212435982166425674222409725189208984375000000000000,
2646 -4.933023088148108747930109529988840222358703613281250000000000,
2647 -0.007285766694735069763655399555091207730583846569061279296875,
2648 0.000000000000000000000000000000000000000000000000000000000000,
2649 0.000000000000000000000000000000000000000000000000000000000000,
2650 };
2651
2652 #ifdef __cplusplus
2653 }
2654 #endif
2655
2656 } // namespace IsoSpec
2657
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 namespace IsoSpec
19 {
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25
26 #define ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES 288
27
28 extern const int elem_table_atomicNo[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
29 extern const double elem_table_probability[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
30 extern const double elem_table_mass[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
31 extern const int elem_table_massNo[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
32 extern const int elem_table_extraNeutrons[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
33 extern const char* elem_table_element[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
34 extern const char* elem_table_symbol[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
35 extern const bool elem_table_Radioactive[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
36 extern const double elem_table_log_probability[ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES];
37
38
39 #ifdef __cplusplus
40 }
41 #endif
42
43 } // namespace IsoSpec
44
0 /*
1 * This file has been released into public domain by John D. Cook
2 * and is used here with some slight modifications (which are hereby
3 * also released into public domain),
4 *
5 * This file is part of IsoSpec.
6 */
7
8 #include <cmath>
9 #include <cstdlib>
10 #include "isoMath.h"
11 #include "platform.h"
12
13 namespace IsoSpec
14 {
15
16 const double pi = 3.14159265358979323846264338328;
17
18 void release_g_lfact_table()
19 {
20 #if ISOSPEC_GOT_MMAN
21 munmap(g_lfact_table, ISOSPEC_G_FACT_TABLE_SIZE*sizeof(double));
22 #else
23 free(g_lfact_table);
24 #endif
25 }
26
27 double* alloc_lfact_table()
28 {
29 double* ret;
30 # if ISOSPEC_GOT_MMAN
31 ret = reinterpret_cast<double*>(mmap(nullptr, sizeof(double)*ISOSPEC_G_FACT_TABLE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
32 #else
33 ret = reinterpret_cast<double*>(calloc(ISOSPEC_G_FACT_TABLE_SIZE, sizeof(double)));
34 #endif
35 std::atexit(release_g_lfact_table);
36 return ret;
37 }
38
39 double* g_lfact_table = alloc_lfact_table();
40
41
42 double RationalApproximation(double t)
43 {
44 // Abramowitz and Stegun formula 26.2.23.
45 // The absolute value of the error should be less than 4.5 e-4.
46 double c[] = {2.515517, 0.802853, 0.010328};
47 double d[] = {1.432788, 0.189269, 0.001308};
48 return t - ((c[2]*t + c[1])*t + c[0]) /
49 (((d[2]*t + d[1])*t + d[0])*t + 1.0);
50 }
51
52 double NormalCDFInverse(double p)
53 {
54
55 if (p < 0.5)
56 return -RationalApproximation( sqrt(-2.0*log(p)) );
57 else
58 return RationalApproximation( sqrt(-2.0*log(1-p)) );
59 }
60
61 double NormalCDFInverse(double p, double mean, double stdev)
62 {
63 return mean + stdev * NormalCDFInverse(p);
64 }
65
66 double NormalCDF(double x, double mean, double stdev)
67 {
68 x = (x-mean)/stdev * 0.7071067811865476;
69
70 // constants
71 double a1 = 0.254829592;
72 double a2 = -0.284496736;
73 double a3 = 1.421413741;
74 double a4 = -1.453152027;
75 double a5 = 1.061405429;
76 double p = 0.3275911;
77
78 // Save the sign of x
79 int sign = 1;
80 if (x < 0)
81 sign = -1;
82 x = fabs(x);
83
84 // A&S formula 7.1.26
85 double t = 1.0/(1.0 + p*x);
86 double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x);
87
88 return 0.5*(1.0 + sign*y);
89 }
90
91 double NormalPDF(double x, double mean, double stdev)
92 {
93 double two_variance = stdev * stdev * 2.0;
94 double delta = x-mean;
95 return exp( -delta*delta / two_variance ) / sqrt( two_variance * pi );
96 }
97
98 } // namespace IsoSpec
99
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <cmath>
19 #include <fenv.h>
20
21 #if !defined(ISOSPEC_G_FACT_TABLE_SIZE)
22 // 10M should be enough for anyone, right?
23 // Actually, yes. If anyone tries to input a molecule that has more than 10M atoms,
24 // he deserves to get an exception thrown in his face.
25 #define ISOSPEC_G_FACT_TABLE_SIZE 1024*1024*10
26 #endif
27
28 namespace IsoSpec
29 {
30
31 extern double* g_lfact_table;
32
33 static inline double minuslogFactorial(int n)
34 {
35 if (n < 2)
36 return 0.0;
37 if (g_lfact_table[n] == 0.0)
38 g_lfact_table[n] = -lgamma(n+1);
39
40 return g_lfact_table[n];
41 }
42 double NormalCDFInverse(double p);
43 double NormalCDFInverse(double p, double mean, double stdev);
44 double NormalCDF(double x, double mean, double stdev);
45 double NormalPDF(double x, double mean = 0.0, double stdev = 1.0);
46
47 } // namespace IsoSpec
48
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16
17 #include <cmath>
18 #include <algorithm>
19 #include <vector>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <tuple>
23 #include <unordered_map>
24 #include <queue>
25 #include <utility>
26 #include <iostream>
27 #include <iomanip>
28 #include <cctype>
29 #include <stdexcept>
30 #include <string>
31 #include <limits>
32 #include <assert.h>
33 #include <ctype.h>
34 #include "platform.h"
35 #include "conf.h"
36 #include "dirtyAllocator.h"
37 #include "operators.h"
38 #include "summator.h"
39 #include "marginalTrek++.h"
40 #include "isoSpec++.h"
41 #include "misc.h"
42 #include "element_tables.h"
43
44
45 using namespace std;
46
47 namespace IsoSpec
48 {
49
50 Iso::Iso(
51 int _dimNumber,
52 const int* _isotopeNumbers,
53 const int* _atomCounts,
54 const double* const * _isotopeMasses,
55 const double* const * _isotopeProbabilities
56 ) :
57 disowned(false),
58 dimNumber(_dimNumber),
59 isotopeNumbers(array_copy<int>(_isotopeNumbers, _dimNumber)),
60 atomCounts(array_copy<int>(_atomCounts, _dimNumber)),
61 confSize(_dimNumber * sizeof(int)),
62 allDim(0),
63 marginals(nullptr),
64 modeLProb(0.0)
65 {
66 try{
67 setupMarginals(_isotopeMasses, _isotopeProbabilities);
68 }
69 catch(...)
70 {
71 delete[] isotopeNumbers;
72 delete[] atomCounts;
73 throw;
74 }
75 }
76
77 Iso::Iso(Iso&& other) :
78 disowned(other.disowned),
79 dimNumber(other.dimNumber),
80 isotopeNumbers(other.isotopeNumbers),
81 atomCounts(other.atomCounts),
82 confSize(other.confSize),
83 allDim(other.allDim),
84 marginals(other.marginals),
85 modeLProb(other.modeLProb)
86 {
87 other.disowned = true;
88 }
89
90
91 Iso::Iso(const Iso& other, bool fullcopy) :
92 disowned(fullcopy ? throw std::logic_error("Not implemented") : true),
93 dimNumber(other.dimNumber),
94 isotopeNumbers(fullcopy ? array_copy<int>(other.isotopeNumbers, dimNumber) : other.isotopeNumbers),
95 atomCounts(fullcopy ? array_copy<int>(other.atomCounts, dimNumber) : other.atomCounts),
96 confSize(other.confSize),
97 allDim(other.allDim),
98 marginals(fullcopy ? throw std::logic_error("Not implemented") : other.marginals),
99 modeLProb(other.modeLProb)
100 {}
101
102
103 inline void Iso::setupMarginals(const double* const * _isotopeMasses, const double* const * _isotopeProbabilities)
104 {
105 if (marginals == nullptr)
106 {
107 int ii = 0;
108 try
109 {
110 marginals = new Marginal*[dimNumber];
111 while(ii < dimNumber)
112 {
113 allDim += isotopeNumbers[ii];
114 marginals[ii] = new Marginal(
115 _isotopeMasses[ii],
116 _isotopeProbabilities[ii],
117 isotopeNumbers[ii],
118 atomCounts[ii]
119 );
120 modeLProb += marginals[ii]->getModeLProb();
121 ii++;
122 }
123 }
124 catch(...)
125 {
126 ii--;
127 while(ii >= 0)
128 {
129 delete marginals[ii];
130 ii--;
131 }
132 delete[] marginals;
133 marginals = nullptr;
134 throw;
135 }
136 }
137
138 }
139
140 Iso::~Iso()
141 {
142 if(!disowned)
143 {
144 if (marginals != nullptr)
145 dealloc_table(marginals, dimNumber);
146 delete[] isotopeNumbers;
147 delete[] atomCounts;
148 }
149 }
150
151
152 double Iso::getLightestPeakMass() const
153 {
154 double mass = 0.0;
155 for (int ii=0; ii<dimNumber; ii++)
156 mass += marginals[ii]->getLightestConfMass();
157 return mass;
158 }
159
160 double Iso::getHeaviestPeakMass() const
161 {
162 double mass = 0.0;
163 for (int ii=0; ii<dimNumber; ii++)
164 mass += marginals[ii]->getHeaviestConfMass();
165 return mass;
166 }
167
168
169
170 Iso::Iso(const char* formula) :
171 disowned(false),
172 allDim(0),
173 marginals(nullptr),
174 modeLProb(0.0)
175 {
176 std::vector<const double*> isotope_masses;
177 std::vector<const double*> isotope_probabilities;
178
179 dimNumber = parse_formula(formula, isotope_masses, isotope_probabilities, &isotopeNumbers, &atomCounts, &confSize);
180
181 setupMarginals(isotope_masses.data(), isotope_probabilities.data());
182 }
183
184 unsigned int parse_formula(const char* formula, std::vector<const double*>& isotope_masses, std::vector<const double*>& isotope_probabilities, int** isotopeNumbers, int** atomCounts, unsigned int* confSize)
185 {
186 // This function is NOT guaranteed to be secure against malicious input. It should be used only for debugging.
187 size_t slen = strlen(formula);
188 // Yes, it would be more elegant to use std::string here, but it's the only promiment place where it would be used in IsoSpec, and avoiding it here
189 // means we can run the whole thing through Clang's memory sanitizer without the need for instrumented libc++/libstdc++. That's worth messing with char pointers a
190 // little bit.
191 std::vector<std::pair<const char*, size_t> > elements;
192 std::vector<int> numbers;
193
194 if(slen == 0)
195 throw invalid_argument("Invalid formula: can't be empty");
196
197 if(!isdigit(formula[slen-1]))
198 throw invalid_argument("Invalid formula: every element must be followed by a number - write H2O1 and not H2O for water");
199
200 for(size_t ii=0; ii<slen; ii++)
201 if(!isdigit(formula[ii]) && !isalpha(formula[ii]))
202 throw invalid_argument("Ivalid formula: contains invalid (non-digit, non-alpha) character");
203
204 size_t position = 0;
205 size_t elem_end = 0;
206 size_t digit_end = 0;
207
208 while(position < slen)
209 {
210 elem_end = position;
211 while(isalpha(formula[elem_end]))
212 elem_end++;
213 digit_end = elem_end;
214 while(isdigit(formula[digit_end]))
215 digit_end++;
216 elements.emplace_back(&formula[position], elem_end-position);
217 numbers.push_back(atoi(&formula[elem_end]));
218 position = digit_end;
219 }
220
221 std::vector<int> element_indexes;
222
223 for (unsigned int i=0; i<elements.size(); i++)
224 {
225 int idx = -1;
226 for(int j=0; j<ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES; j++)
227 {
228 if ((strlen(elem_table_symbol[j]) == elements[i].second) && (strncmp(elements[i].first, elem_table_symbol[j], elements[i].second) == 0))
229 {
230 idx = j;
231 break;
232 }
233 }
234 if(idx < 0)
235 throw invalid_argument("Invalid formula");
236 element_indexes.push_back(idx);
237 }
238
239 vector<int> _isotope_numbers;
240
241 for(vector<int>::iterator it = element_indexes.begin(); it != element_indexes.end(); ++it)
242 {
243 int num = 0;
244 int at_idx = *it;
245 int atomicNo = elem_table_atomicNo[at_idx];
246 while(at_idx < ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES && elem_table_atomicNo[at_idx] == atomicNo)
247 {
248 at_idx++;
249 num++;
250 }
251 _isotope_numbers.push_back(num);
252 }
253
254 for(vector<int>::iterator it = element_indexes.begin(); it != element_indexes.end(); ++it)
255 {
256 isotope_masses.push_back(&elem_table_mass[*it]);
257 isotope_probabilities.push_back(&elem_table_probability[*it]);
258 };
259
260 const unsigned int dimNumber = elements.size();
261
262 *isotopeNumbers = array_copy<int>(_isotope_numbers.data(), dimNumber);
263 *atomCounts = array_copy<int>(numbers.data(), dimNumber);
264 *confSize = dimNumber * sizeof(int);
265
266 return dimNumber;
267
268 }
269
270
271 /*
272 * ----------------------------------------------------------------------------------------------------------
273 */
274
275
276
277 IsoGenerator::IsoGenerator(Iso&& iso, bool alloc_partials) :
278 Iso(std::move(iso)),
279 partialLProbs(alloc_partials ? new double[dimNumber+1] : nullptr),
280 partialMasses(alloc_partials ? new double[dimNumber+1] : nullptr),
281 partialProbs(alloc_partials ? new double[dimNumber+1] : nullptr)
282 {
283 if(alloc_partials)
284 {
285 partialLProbs[dimNumber] = 0.0;
286 partialMasses[dimNumber] = 0.0;
287 partialProbs[dimNumber] = 1.0;
288 }
289 }
290
291
292 IsoGenerator::~IsoGenerator()
293 {
294 if(partialLProbs != nullptr)
295 delete[] partialLProbs;
296 if(partialMasses != nullptr)
297 delete[] partialMasses;
298 if(partialProbs != nullptr)
299 delete[] partialProbs;
300 }
301
302
303
304 /*
305 * ----------------------------------------------------------------------------------------------------------
306 */
307
308
309
310 IsoThresholdGenerator::IsoThresholdGenerator(Iso&& iso, double _threshold, bool _absolute, int tabSize, int hashSize, bool reorder_marginals)
311 : IsoGenerator(std::move(iso)),
312 Lcutoff(_threshold <= 0.0 ? std::numeric_limits<double>::lowest() : (_absolute ? log(_threshold) : log(_threshold) + modeLProb))
313 {
314 counter = new int[dimNumber];
315 maxConfsLPSum = new double[dimNumber-1];
316 marginalResultsUnsorted = new PrecalculatedMarginal*[dimNumber];
317
318 empty = false;
319
320 for(int ii=0; ii<dimNumber; ii++)
321 {
322 counter[ii] = 0;
323 marginalResultsUnsorted[ii] = new PrecalculatedMarginal(std::move(*(marginals[ii])),
324 Lcutoff - modeLProb + marginals[ii]->getModeLProb(),
325 true,
326 tabSize,
327 hashSize);
328
329 if(!marginalResultsUnsorted[ii]->inRange(0))
330 empty = true;
331 }
332
333 if(reorder_marginals)
334 {
335 OrderMarginalsBySizeDecresing comparator(marginalResultsUnsorted);
336 int* tmpMarginalOrder = new int[dimNumber];
337
338 for(int ii=0; ii<dimNumber; ii++)
339 tmpMarginalOrder[ii] = ii;
340
341 std::sort(tmpMarginalOrder, tmpMarginalOrder + dimNumber, comparator);
342 marginalResults = new PrecalculatedMarginal*[dimNumber];
343
344 for(int ii=0; ii<dimNumber; ii++)
345 marginalResults[ii] = marginalResultsUnsorted[tmpMarginalOrder[ii]];
346
347 marginalOrder = new int[dimNumber];
348 for(int ii = 0; ii<dimNumber; ii++)
349 marginalOrder[tmpMarginalOrder[ii]] = ii;
350
351 delete[] tmpMarginalOrder;
352
353 }
354 else
355 {
356 marginalResults = marginalResultsUnsorted;
357 marginalOrder = nullptr;
358 }
359
360 lProbs_ptr_start = marginalResults[0]->get_lProbs_ptr();
361
362 if(dimNumber > 1)
363 maxConfsLPSum[0] = marginalResults[0]->getModeLProb();
364
365 for(int ii=1; ii<dimNumber-1; ii++)
366 maxConfsLPSum[ii] = maxConfsLPSum[ii-1] + marginalResults[ii]->getModeLProb();
367
368 lProbs_ptr = lProbs_ptr_start;
369
370 partialLProbs_second = partialLProbs;
371 partialLProbs_second++;
372
373 if(!empty)
374 {
375 recalc(dimNumber-1);
376 counter[0]--;
377 lProbs_ptr--;
378 }
379 else
380 {
381 terminate_search();
382 lcfmsv = std::numeric_limits<double>::infinity();
383 }
384
385
386
387 }
388
389 void IsoThresholdGenerator::terminate_search()
390 {
391 for(int ii=0; ii<dimNumber; ii++)
392 {
393 counter[ii] = marginalResults[ii]->get_no_confs()-1;
394 partialLProbs[ii] = -std::numeric_limits<double>::infinity();
395 }
396 partialLProbs[dimNumber] = -std::numeric_limits<double>::infinity();
397 lProbs_ptr = lProbs_ptr_start + marginalResults[0]->get_no_confs()-1;
398 }
399
400 size_t IsoThresholdGenerator::count_confs()
401 {
402 // Smarter algorithm forthcoming in 2.0
403 size_t ret = 0;
404 while(advanceToNextConfiguration())
405 ret++;
406 reset();
407 return ret;
408 }
409
410 void IsoThresholdGenerator::reset()
411 {
412 if(empty)
413 {
414 terminate_search();
415 return;
416 }
417
418 partialLProbs[dimNumber] = 0.0;
419
420 memset(counter, 0, sizeof(int)*dimNumber);
421 recalc(dimNumber-1);
422 counter[0]--;
423
424 lProbs_ptr = lProbs_ptr_start - 1;
425 }
426
427 /*
428 * ------------------------------------------------------------------------------------------------------------------------
429 */
430
431 IsoOrderedGenerator::IsoOrderedGenerator(Iso&& iso, int _tabSize, int _hashSize) :
432 IsoGenerator(std::move(iso), false), allocator(dimNumber, _tabSize)
433 {
434 partialLProbs = &currentLProb;
435 partialMasses = &currentMass;
436 partialProbs = &currentProb;
437
438 marginalResults = new MarginalTrek*[dimNumber];
439
440 for(int i = 0; i<dimNumber; i++)
441 marginalResults[i] = new MarginalTrek(std::move(*(marginals[i])), _tabSize, _hashSize);
442
443 logProbs = new const vector<double>*[dimNumber];
444 masses = new const vector<double>*[dimNumber];
445 marginalConfs = new const vector<int*>*[dimNumber];
446
447 for(int i = 0; i<dimNumber; i++)
448 {
449 masses[i] = &marginalResults[i]->conf_masses();
450 logProbs[i] = &marginalResults[i]->conf_lprobs();
451 marginalConfs[i] = &marginalResults[i]->confs();
452 }
453
454 topConf = allocator.newConf();
455 memset(
456 reinterpret_cast<char*>(topConf) + sizeof(double),
457 0,
458 sizeof(int)*dimNumber
459 );
460
461 *(reinterpret_cast<double*>(topConf)) =
462 combinedSum(
463 getConf(topConf),
464 logProbs,
465 dimNumber
466 );
467
468 pq.push(topConf);
469
470 }
471
472
473 IsoOrderedGenerator::~IsoOrderedGenerator()
474 {
475 dealloc_table<MarginalTrek*>(marginalResults, dimNumber);
476 delete[] logProbs;
477 delete[] masses;
478 delete[] marginalConfs;
479 partialLProbs = nullptr;
480 partialMasses = nullptr;
481 partialProbs = nullptr;
482 }
483
484
485 bool IsoOrderedGenerator::advanceToNextConfiguration()
486 {
487 if(pq.size() < 1)
488 return false;
489
490
491 topConf = pq.top();
492 pq.pop();
493
494 int* topConfIsoCounts = getConf(topConf);
495
496 currentLProb = *(reinterpret_cast<double*>(topConf));
497 currentMass = combinedSum( topConfIsoCounts, masses, dimNumber );
498 currentProb = exp(currentLProb);
499
500 ccount = -1;
501 for(int j = 0; j < dimNumber; ++j)
502 {
503 if(marginalResults[j]->probeConfigurationIdx(topConfIsoCounts[j] + 1))
504 {
505 if(ccount == -1)
506 {
507 topConfIsoCounts[j]++;
508 *(reinterpret_cast<double*>(topConf)) = combinedSum(topConfIsoCounts, logProbs, dimNumber);
509 pq.push(topConf);
510 topConfIsoCounts[j]--;
511 ccount = j;
512 }
513 else
514 {
515 void* acceptedCandidate = allocator.newConf();
516 int* acceptedCandidateIsoCounts = getConf(acceptedCandidate);
517 memcpy(acceptedCandidateIsoCounts, topConfIsoCounts, confSize);
518
519 acceptedCandidateIsoCounts[j]++;
520
521 *(reinterpret_cast<double*>(acceptedCandidate)) = combinedSum(acceptedCandidateIsoCounts, logProbs, dimNumber);
522
523 pq.push(acceptedCandidate);
524 }
525 }
526 if(topConfIsoCounts[j] > 0)
527 break;
528 }
529 if(ccount >=0)
530 topConfIsoCounts[ccount]++;
531
532 return true;
533 }
534
535
536
537 /*
538 * ---------------------------------------------------------------------------------------------------
539 */
540
541
542
543
544 #if !ISOSPEC_BUILDING_R
545
546 void printConfigurations(
547 const std::tuple<double*,double*,int*,int>& results,
548 int dimNumber,
549 int* isotopeNumbers
550 ){
551 int m = 0;
552
553 for(int i=0; i<std::get<3>(results); i++){
554
555 std::cout << "Mass = " << std::get<0>(results)[i] <<
556 "\tand log-prob = " << std::get<1>(results)[i] <<
557 "\tand prob = " << exp(std::get<1>(results)[i]) <<
558 "\tand configuration =\t";
559
560
561 for(int j=0; j<dimNumber; j++){
562 for(int k=0; k<isotopeNumbers[j]; k++ )
563 {
564 std::cout << std::get<2>(results)[m] << " ";
565 m++;
566 }
567 std::cout << '\t';
568 }
569
570
571 std::cout << std::endl;
572 }
573 }
574
575 #endif /* !ISOSPEC_BUILDING_R */
576
577
578
579 IsoLayeredGenerator::IsoLayeredGenerator( Iso&& iso,
580 double _targetCoverage,
581 double _percentageToExpand,
582 int _tabSize,
583 int _hashSize,
584 bool trim
585 ) : IsoGenerator(std::move(iso)),
586 allocator(dimNumber, _tabSize),
587 candidate(new int[dimNumber]),
588 targetCoverage(_targetCoverage >= 1.0 ? 10000.0 : _targetCoverage), // If the user wants the entire spectrum,
589 // give it to him - and make sure we don't terminate
590 // early because of rounding errors
591 percentageToExpand(_percentageToExpand),
592 do_trim(trim),
593 layers(0),
594 generator_position(-1)
595 {
596 marginalResults = new MarginalTrek*[dimNumber];
597
598 for(int i = 0; i<dimNumber; i++)
599 marginalResults[i] = new MarginalTrek(std::move(*(marginals[i])), _tabSize, _hashSize);
600
601 logProbs = new const vector<double>*[dimNumber];
602 masses = new const vector<double>*[dimNumber];
603 marginalConfs = new const vector<int*>*[dimNumber];
604
605 for(int i = 0; i<dimNumber; i++)
606 {
607 masses[i] = &marginalResults[i]->conf_masses();
608 logProbs[i] = &marginalResults[i]->conf_lprobs();
609 marginalConfs[i] = &marginalResults[i]->confs();
610 }
611
612 void* topConf = allocator.newConf();
613 memset(reinterpret_cast<char*>(topConf) + sizeof(double), 0, sizeof(int)*dimNumber);
614 *(reinterpret_cast<double*>(topConf)) = combinedSum(getConf(topConf), logProbs, dimNumber);
615
616 current = new std::vector<void*>();
617 next = new std::vector<void*>();
618
619 current->push_back(topConf);
620
621 lprobThr = (*reinterpret_cast<double*>(topConf));
622
623 if(targetCoverage > 0.0)
624 while(advanceToNextLayer()) {};
625 }
626
627
628 IsoLayeredGenerator::~IsoLayeredGenerator()
629 {
630 if(current != nullptr)
631 delete current;
632 if(next != nullptr)
633 delete next;
634 delete[] logProbs;
635 delete[] masses;
636 delete[] marginalConfs;
637 delete[] candidate;
638 dealloc_table(marginalResults, dimNumber);
639 }
640
641 bool IsoLayeredGenerator::advanceToNextLayer()
642 {
643 layers += 1;
644 double maxFringeLprob = -std::numeric_limits<double>::infinity();
645
646 if(current == nullptr)
647 return false;
648 int accepted_in_this_layer = 0;
649 Summator prob_in_this_layer(totalProb);
650
651 void* topConf;
652
653 while(current->size() > 0)
654 {
655 topConf = current->back();
656 current->pop_back();
657
658 double top_lprob = getLProb(topConf);
659
660 if(top_lprob >= lprobThr)
661 {
662 newaccepted.push_back(topConf);
663 accepted_in_this_layer++;
664 prob_in_this_layer.add(exp(top_lprob));
665 }
666 else
667 {
668 next->push_back(topConf);
669 continue;
670 }
671
672 int* topConfIsoCounts = getConf(topConf);
673
674 for(int j = 0; j < dimNumber; ++j)
675 {
676 // candidate cannot refer to a position that is
677 // out of range of the stored marginal distribution.
678 if(marginalResults[j]->probeConfigurationIdx(topConfIsoCounts[j] + 1))
679 {
680 memcpy(candidate, topConfIsoCounts, confSize);
681 candidate[j]++;
682
683 void* acceptedCandidate = allocator.newConf();
684 int* acceptedCandidateIsoCounts = getConf(acceptedCandidate);
685 memcpy( acceptedCandidateIsoCounts, candidate, confSize);
686
687 double newConfProb = combinedSum(
688 candidate,
689 logProbs,
690 dimNumber
691 );
692
693
694
695 *(reinterpret_cast<double*>(acceptedCandidate)) = newConfProb;
696
697 if(newConfProb >= lprobThr)
698 current->push_back(acceptedCandidate);
699 else
700 {
701 next->push_back(acceptedCandidate);
702 if(newConfProb > maxFringeLprob)
703 maxFringeLprob = top_lprob;
704 }
705 }
706 if(topConfIsoCounts[j] > 0)
707 break;
708 }
709 }
710
711 if(next == nullptr || next->size() < 1)
712 return false;
713 else
714 {
715 if(prob_in_this_layer.get() < targetCoverage)
716 {
717 std::vector<void*>* nnew = current;
718 nnew->clear();
719 current = next;
720 next = nnew;
721 int howmany = floor(current->size()*percentageToExpand);
722 lprobThr = getLProb(quickselect(current->data(), howmany, 0, current->size()));
723 totalProb = prob_in_this_layer;
724 }
725 else
726 {
727 delete next;
728 next = nullptr;
729 delete current;
730 current = nullptr;
731 int start = 0;
732 int end = accepted_in_this_layer - 1;
733 void* swapspace;
734
735 if(do_trim)
736 {
737 void** lastLayer = &(newaccepted.data()[newaccepted.size()-accepted_in_this_layer]);
738
739 Summator qsprob(totalProb);
740 while(totalProb.get() < targetCoverage)
741 {
742 if(start == end)
743 break;
744
745 // Partition part
746
747 int len = end - start;
748 #if ISOSPEC_BUILDING_R
749 int pivot = len/2 + start; // We're very definitely NOT switching to R to use a RNG, and if R sees us use C RNG it complains...
750 #else
751 int pivot = rand() % len + start;
752 #endif
753 void* pval = lastLayer[pivot];
754 double pprob = getLProb(pval);
755 mswap(lastLayer[pivot], lastLayer[end-1]);
756 int loweridx = start;
757 for(int i=start; i<end-1; i++)
758 {
759 if(getLProb(lastLayer[i]) > pprob)
760 {
761 mswap(lastLayer[i], lastLayer[loweridx]);
762 loweridx++;
763 }
764 }
765 mswap(lastLayer[end-1], lastLayer[loweridx]);
766
767 // Selection part
768
769 Summator leftProb(qsprob);
770 for(int i=start; i<=loweridx; i++)
771 {
772 leftProb.add(exp(getLProb(lastLayer[i])));
773 }
774 if(leftProb.get() < targetCoverage)
775 {
776 start = loweridx+1;
777 qsprob = leftProb;
778 }
779 else
780 end = loweridx;
781 }
782 int accend = newaccepted.size()-accepted_in_this_layer+start+1;
783
784 totalProb = qsprob;
785 newaccepted.resize(accend);
786 return true;
787 }
788 else // No trimming
789 {
790 totalProb = prob_in_this_layer;
791 return true;
792 }
793 }
794 }
795 return true;
796
797 }
798
799 bool IsoLayeredGenerator::advanceToNextConfiguration()
800 {
801 generator_position++;
802 if(generator_position < newaccepted.size())
803 {
804 partialLProbs[0] = getLProb(newaccepted[generator_position]);
805 partialMasses[0] = combinedSum(getConf(newaccepted[generator_position]), masses, dimNumber);
806 partialProbs[0] = exp(partialLProbs[0]);
807 return true;
808 }
809 else
810 return false;
811 }
812
813
814
815
816 } // namespace IsoSpec
817
0 /*!
1 Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2
3 This file is part of IsoSpec.
4
5 IsoSpec is free software: you can redistribute it and/or modify
6 it under the terms of the Simplified ("2-clause") BSD licence.
7
8 IsoSpec is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
12 You should have received a copy of the Simplified BSD Licence
13 along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <tuple>
19 #include <unordered_map>
20 #include <queue>
21 #include <limits>
22 #include "platform.h"
23 #include "dirtyAllocator.h"
24 #include "summator.h"
25 #include "operators.h"
26 #include "marginalTrek++.h"
27
28
29 #if ISOSPEC_BUILDING_R
30 #include <Rcpp.h>
31 using namespace Rcpp;
32 #endif /* ISOSPEC_BUILDING_R */
33
34
35 namespace IsoSpec
36 {
37
38 // This function is NOT guaranteed to be secure against malicious input. It should be used only for debugging.
39 unsigned int parse_formula(const char* formula,
40 std::vector<const double*>& isotope_masses,
41 std::vector<const double*>& isotope_probabilities,
42 int** isotopeNumbers,
43 int** atomCounts,
44 unsigned int* confSize);
45
46
47 //! The Iso class for the calculation of the isotopic distribution.
48 /*!
49 It contains full description of the molecule for which one would like to calculate the isotopic distribution.
50 */
51 class ISOSPEC_EXPORT_SYMBOL Iso {
52 private:
53
54 //! Set up the marginal isotopic envelopes, corresponding to subisotopologues.
55 /*!
56 \param _isotopeMasses A table of masses of isotopes of the elements in the chemical formula,
57 e.g. {12.0, 13.003355, 1.007825, 2.014102} for C100H202.
58 \param _isotopeProbabilities A table of isotope frequencies of the elements in the chemical formula,
59 e.g. {.989212, .010788, .999885, .000115} for C100H202.
60 */
61 void setupMarginals(const double* const * _isotopeMasses,
62 const double* const * _isotopeProbabilities);
63 public:
64 bool disowned; /*!< A variable showing if the Iso class was specialized by its child-class. If so, then the description of the molecules has been transfered there and Iso is a carcass class, dead as a dodo, an ex-class if you will. */
65 protected:
66 int dimNumber; /*!< The number of elements in the chemical formula of the molecule. */
67 int* isotopeNumbers; /*!< A table with numbers of isotopes for each element. */
68 int* atomCounts; /*!< A table with numbers of isotopes for each element. */
69 unsigned int confSize; /*!< The number of bytes needed to represent the counts of isotopes present in the extended chemical formula. */
70 int allDim; /*!< The total number of isotopes of elements present in a chemical formula, e.g. for H20 it is 2+3=5. */
71 Marginal** marginals; /*!< The table of pointers to the distributions of individual subisotopologues. */
72 double modeLProb; /*!< The log-probability of the mode of the isotopic distribution. */
73
74 public:
75 //! General constructror.
76 /*!
77 \param _dimNumber The number of elements in the formula, e.g. for C100H202 it would be 2, as there are only carbon and hydrogen atoms.
78 \param _isotopeNumbers A table with numbers of isotopes for each element, e.g. for C100H202 it would be {2, 2}, because both C and H have two stable isotopes.
79 \param _atomCounts Number of atoms of each element in the formula, e.g. for C100H202 corresponds to {100, 202}.
80 \param _isotopeMasses A table of masses of isotopes of the elements in the chemical formula, e.g. {12.0, 13.003355, 1.007825, 2.014102} for C100H202.
81 \param _isotopeProbabilities A table of isotope frequencies of the elements in the chemical formula, e.g. {.989212, .010788, .999885, .000115} for C100H202.
82 */
83 Iso(
84 int _dimNumber,
85 const int* _isotopeNumbers,
86 const int* _atomCounts,
87 const double* const * _isotopeMasses,
88 const double* const * _isotopeProbabilities
89 );
90
91 //! Constructor from the formula object.
92 Iso(const char* formula);
93
94 //! The move constructor.
95 Iso(Iso&& other);
96
97 //! The copy constructor.
98 /*!
99 \param other The other instance of the Iso class.
100 \param fullcopy If false, copy only the number of atoms in the formula, the size of the configuration, the total number of isotopes, and the probability of the mode isotopologue.
101 */
102 Iso(const Iso& other, bool fullcopy);
103
104 //! Destructor.
105 virtual ~Iso();
106
107 //! Get the mass of the lightest peak in the isotopic distribution.
108 double getLightestPeakMass() const;
109
110 //! Get the mass of the heaviest peak in the isotopic distribution.
111 double getHeaviestPeakMass() const;
112
113 //! Get the log-probability of the mode-configuration (if there are many modes, they share this value).
114 inline double getModeLProb() const { return modeLProb; };
115
116 //! Get the number of elements in the chemical formula of the molecule.
117 inline int getDimNumber() const { return dimNumber; };
118
119 //! Get the total number of isotopes of elements present in a chemical formula.
120 inline int getAllDim() const { return allDim; };
121 };
122
123
124 //! The generator of isotopologues.
125 /*!
126 This class provides the common interface for all isotopic generators.
127 */
128 class ISOSPEC_EXPORT_SYMBOL IsoGenerator : public Iso
129 {
130 protected:
131 double* partialLProbs; /*!< The prefix sum of the log-probabilities of the current isotopologue. */
132 double* partialMasses; /*!< The prefix sum of the masses of the current isotopologue. */
133 double* partialProbs;/*!< The prefix product of the probabilities of the current isotopologue. */
134
135 public:
136 //! Advance to the next, not yet visited, most probable isotopologue.
137 /*!
138 \return Return false if it is not possible to advance.
139 */
140 virtual bool advanceToNextConfiguration() = 0;
141
142 //! Get the log-probability of the current isotopologue.
143 /*!
144 \return The log-probability of the current isotopologue.
145 */
146 virtual double lprob() const { return partialLProbs[0]; };
147
148 //! Get the mass of the current isotopologue.
149 /*!
150 \return The mass of the current isotopologue.
151 */
152 virtual double mass() const { return partialMasses[0]; };
153
154 //! Get the probability of the current isotopologue.
155 /*!
156 \return The probability of the current isotopologue.
157 */
158 virtual double prob() const { return partialProbs[0]; };
159
160 //TODO: what is this???
161 virtual void get_conf_signature(int* space) const = 0;
162
163 //! Move constructor.
164 IsoGenerator(Iso&& iso, bool alloc_partials = true);
165
166 //! Destructor.
167 virtual ~IsoGenerator();
168 };
169
170
171
172 //! The generator of isotopologues sorted by their probability of occurrence.
173 /*!
174 The subsequent isotopologues are generated with diminishing probability, starting from the mode.
175 This algorithm take O(N*log(N)) to compute the N isotopologues because of using the Priority Queue data structure.
176 Obtaining the N isotopologues can be achieved in O(N) if they are not required to be spit out in the descending order.
177 */
178 class ISOSPEC_EXPORT_SYMBOL IsoOrderedGenerator: public IsoGenerator
179 {
180 private:
181 MarginalTrek** marginalResults; /*!< Table of pointers to marginal distributions of subisotopologues. */
182 std::priority_queue<void*,std::vector<void*>,ConfOrder> pq; /*!< The priority queue used to generate isotopologues ordered by descending probability. */
183 void* topConf; /*!< Most probable configuration. */
184 DirtyAllocator allocator; /*!< Structure used for alocating memory for isotopologues. */
185 const std::vector<double>** logProbs; /*!< Obtained log-probabilities. */
186 const std::vector<double>** masses; /*!< Obtained masses. */
187 const std::vector<int*>** marginalConfs; /*!< Obtained counts of isotopes. */
188 double currentLProb; /*!< The log-probability of the current isotopologue. */
189 double currentMass; /*!< The mass of the current isotopologue. */
190 double currentProb; /*!< The probability of the current isotopologue. */
191 int ccount;
192
193 public:
194 bool advanceToNextConfiguration() override final;
195
196 //! Save the counts of isotopes in the space.
197 /*!
198 \param space An array where counts of isotopes shall be written.
199 Must be as big as the overall number of isotopes.
200 */
201 inline void get_conf_signature(int* space) const override final
202 {
203 int* c = getConf(topConf);
204
205 if (ccount >= 0)
206 c[ccount]--;
207
208 for(int ii=0; ii<dimNumber; ii++)
209 {
210 memcpy(space, marginalResults[ii]->confs()[c[ii]], isotopeNumbers[ii]*sizeof(int));
211 space += isotopeNumbers[ii];
212 }
213
214 if (ccount >= 0)
215 c[ccount]++;
216 };
217
218 //! The move-contstructor.
219 IsoOrderedGenerator(Iso&& iso, int _tabSize = 1000, int _hashSize = 1000);
220
221 //! Destructor.
222 virtual ~IsoOrderedGenerator();
223 };
224
225
226
227
228 //! The generator of isotopologues above a given threshold value.
229 /*!
230 Attention: the calculated configurations are only partially ordeded and the user should not assume they will be ordered.
231 This algorithm computes N isotopologues in O(N).
232 It is a considerable advantage w.r.t. the IsoOrderedGenerator.
233 */
234 class ISOSPEC_EXPORT_SYMBOL IsoThresholdGenerator: public IsoGenerator
235 {
236 private:
237
238 int* counter; /*!< An array storing the position of an isotopologue in terms of the subisotopologues ordered by decreasing probability. */
239 double* maxConfsLPSum;
240 const double Lcutoff; /*!< The logarithm of the lower bound on the calculated probabilities. */
241 PrecalculatedMarginal** marginalResults;
242 PrecalculatedMarginal** marginalResultsUnsorted;
243 int* marginalOrder;
244
245 const double* lProbs_ptr;
246 const double* lProbs_ptr_start;
247 double* partialLProbs_second;
248 double partialLProbs_second_val, lcfmsv;
249 bool empty;
250
251 public:
252 inline void get_conf_signature(int* space) const override final
253 {
254 counter[0] = lProbs_ptr - lProbs_ptr_start;
255 if(marginalOrder != nullptr)
256 for(int ii=0; ii<dimNumber; ii++)
257 {
258 int jj = marginalOrder[ii];
259 memcpy(space, marginalResultsUnsorted[ii]->get_conf(counter[jj]), isotopeNumbers[ii]*sizeof(int));
260 space += isotopeNumbers[ii];
261 }
262 else
263 for(int ii=0; ii<dimNumber; ii++)
264 {
265 memcpy(space, marginalResultsUnsorted[ii]->get_conf(counter[ii]), isotopeNumbers[ii]*sizeof(int));
266 space += isotopeNumbers[ii];
267 }
268
269 };
270
271 //! The move-constructor.
272 /*!
273 \param iso An instance of the Iso class.
274 \param _threshold The threshold value.
275 \param _absolute If true, the _threshold is interpreted as the absolute minimal peak height for the isotopologues.
276 If false, the _threshold is the fraction of the heighest peak's probability.
277 \param tabSize The size of the extension of the table with configurations.
278 \param hashSize The size of the hash-table used to store subisotopologues and check if they have been already calculated.
279 */
280 IsoThresholdGenerator(Iso&& iso, double _threshold, bool _absolute=true, int _tabSize=1000, int _hashSize=1000, bool reorder_marginals = true);
281
282 inline ~IsoThresholdGenerator()
283 {
284 delete[] counter;
285 delete[] maxConfsLPSum;
286 if (marginalResultsUnsorted != marginalResults)
287 delete[] marginalResultsUnsorted;
288 dealloc_table(marginalResults, dimNumber);
289 if(marginalOrder != nullptr)
290 delete[] marginalOrder;
291 };
292
293 // Perform highly aggressive inling as this function is often called as while(advanceToNextConfiguration()) {}
294 // which leads to an extremely tight loop and some compilers miss this (potentially due to the length of the function).
295 ISOSPEC_FORCE_INLINE bool advanceToNextConfiguration() override final
296 {
297 lProbs_ptr++;
298
299 if(ISOSPEC_LIKELY(*lProbs_ptr >= lcfmsv))
300 {
301 return true;
302 }
303
304 // If we reached this point, a carry is needed
305
306 int idx = 0;
307 lProbs_ptr = lProbs_ptr_start;
308
309 int * cntr_ptr = counter;
310
311 while(idx<dimNumber-1)
312 {
313 // counter[idx] = 0;
314 *cntr_ptr = 0;
315 idx++;
316 cntr_ptr++;
317 // counter[idx]++;
318 (*cntr_ptr)++;
319 partialLProbs[idx] = partialLProbs[idx+1] + marginalResults[idx]->get_lProb(counter[idx]);
320 if(partialLProbs[idx] + maxConfsLPSum[idx-1] >= Lcutoff)
321 {
322 partialMasses[idx] = partialMasses[idx+1] + marginalResults[idx]->get_mass(counter[idx]);
323 partialProbs[idx] = partialProbs[idx+1] * marginalResults[idx]->get_prob(counter[idx]);
324 recalc(idx-1);
325 return true;
326 }
327 }
328
329 terminate_search();
330 return false;
331 }
332
333
334 ISOSPEC_FORCE_INLINE double lprob() const override final { return partialLProbs_second_val + (*(lProbs_ptr)); };
335 ISOSPEC_FORCE_INLINE double mass() const override final { return partialMasses[1] + marginalResults[0]->get_mass(lProbs_ptr - lProbs_ptr_start); };
336 ISOSPEC_FORCE_INLINE double prob() const override final { return partialProbs[1] * marginalResults[0]->get_prob(lProbs_ptr - lProbs_ptr_start); };
337
338 //! Block the subsequent search of isotopologues.
339 void terminate_search();
340
341 /*! Reset the generator to the beginning of the sequence. Allows it to be reused, eg. to go through the conf space once, calculate
342 the amount of space needed to store configurations, then to allocate that memory, and go through it again, this time saving
343 configurations (and *is* in fact faster than allocating a std::vector and depending on it to grow as needed. This is cheaper
344 than throwing away the generator and making a new one too: marginal distributions don't need to be recalculated. */
345 void reset();
346
347 /*! Count the number of configurations in the distribution. This can be used to pre-allocate enough memory to store it (e.g.
348 * std::vector's reserve() method - this is faster than depending on the vector's dynamic resizing, even though it means that
349 * the configuration space is walked through twice. This method has to be called before the first call to advanceToNextConfiguration
350 * and has undefined results (incl. segfaults) otherwise. */
351 size_t count_confs();
352
353 private:
354 //! Recalculate the current partial log-probabilities, masses, and probabilities.
355 ISOSPEC_FORCE_INLINE void recalc(int idx)
356 {
357 for(; idx > 0; idx--)
358 {
359 partialLProbs[idx] = partialLProbs[idx+1] + marginalResults[idx]->get_lProb(counter[idx]);
360 partialMasses[idx] = partialMasses[idx+1] + marginalResults[idx]->get_mass(counter[idx]);
361 partialProbs[idx] = partialProbs[idx+1] * marginalResults[idx]->get_prob(counter[idx]);
362 }
363 partialLProbs_second_val = *partialLProbs_second;
364 partialLProbs[0] = *partialLProbs_second + marginalResults[0]->get_lProb(counter[0]);
365 lcfmsv = Lcutoff - partialLProbs_second_val;
366 }
367 };
368
369
370
371 //! The class that represents isotopologues above a given joint probability value.
372 /*!
373 This class generates subsequent isotopologues that ARE NOT GUARANTEED TO BE ORDERED BY probability.
374 The overal set of isotopologues is guaranteed to surpass a given threshold of probability contained in the
375 isotopic distribution.
376 This calculations are performed in O(N) operations, where N is the total number of the output isotopologues.
377
378 This class is not a true generator yet - the generator methods have been implemented for compatibility, but
379 the class actually performs all computations during the initialization and stores them, and the generator methods
380 only walk through the array of precomputed values. . It will be reimplemented as a true generator in 2.0.
381 */
382 class ISOSPEC_EXPORT_SYMBOL IsoLayeredGenerator : public IsoGenerator
383 {
384 private:
385 Summator totalProb;
386 std::vector<void*> newaccepted;
387 DirtyAllocator allocator;
388 int* candidate;
389 const std::vector<double>** logProbs; /*!< Obtained log-probabilities. */
390 const std::vector<double>** masses; /*!< Obtained masses. */
391 const std::vector<int*>** marginalConfs; /*!< Obtained counts of isotopes. */
392 MarginalTrek** marginalResults;
393 std::vector<void*>* current;
394 std::vector<void*>* next;
395 double lprobThr;
396 double targetCoverage;
397 double percentageToExpand;
398 bool do_trim;
399 int layers;
400 size_t generator_position;
401
402 bool advanceToNextLayer();
403
404 public:
405 bool advanceToNextConfiguration() override final;
406
407 inline void get_conf_signature(int* space) const override final
408 {
409 int* conf = getConf(newaccepted[generator_position]);
410 for(int ii=0; ii<dimNumber; ii++)
411 {
412 memcpy(space, marginalResults[ii]->confs()[conf[ii]], isotopeNumbers[ii]*sizeof(int));
413 space += isotopeNumbers[ii];
414 }
415 };
416
417
418 IsoLayeredGenerator(Iso&& iso, double _targetCoverage, double _percentageToExpand = 0.3, int _tabSize = 1000, int _hashSize = 1000, bool trim = false);
419 virtual ~IsoLayeredGenerator();
420
421 void terminate_search();
422
423 };
424
425
426
427
428 #if !ISOSPEC_BUILDING_R
429
430 void printConfigurations(
431 const std::tuple<double*,double*,int*,int>& results,
432 int dimNumber,
433 int* isotopeNumbers
434 );
435 #endif /* !ISOSPEC_BUILDING_R */
436
437 } // namespace IsoSpec
438
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16
17 #include <cmath>
18 #include <algorithm>
19 #include <vector>
20 #include <stdlib.h>
21 #include <tuple>
22 #include <unordered_map>
23 #include <unordered_set>
24 #include <queue>
25 #include <utility>
26 #include <iostream>
27 #include <string.h>
28 #include <string>
29 #include <limits>
30 #include <cstdlib>
31 #include <fenv.h>
32 #include "platform.h"
33 #include "marginalTrek++.h"
34 #include "conf.h"
35 #include "allocator.h"
36 #include "operators.h"
37 #include "summator.h"
38 #include "element_tables.h"
39 #include "misc.h"
40
41
42 namespace IsoSpec
43 {
44
45 //! Find one of the most probable subisotopologues.
46 /*!
47 The algorithm uses the hill-climbing algorithm.
48 It starts from a subisotopologue close to the mean of the underlying multinomial distribution.
49 There might be more than one modes, in case of which this function will return only one of them, close to the mean.
50
51 \param atomCnt
52
53 */
54 Conf initialConfigure(const int atomCnt, const int isotopeNo, const double* probs, const double* lprobs)
55 {
56 /*!
57 Here we perform hill climbing to the mode of the marginal distribution (the subisotopologue distribution).
58 We start from the point close to the mean of the underlying multinomial distribution.
59 */
60 Conf res = new int[isotopeNo];
61
62 // This approximates the mode (heuristics: the mean is close to the mode).
63 for(int i = 0; i < isotopeNo; ++i )
64 res[i] = int( atomCnt * probs[i] ) + 1;
65
66 // The number of assigned atoms above.
67 int s = 0;
68
69 for(int i = 0; i < isotopeNo; ++i) s += res[i];
70
71 int diff = atomCnt - s;
72
73 // Too little: enlarging fist index.
74 if( diff > 0 ){
75 res[0] += diff;
76 }
77 // Too much: trying to redistribute the difference: hopefully the first element is the largest.
78 if( diff < 0 ){
79 diff = abs(diff);
80 int i = 0, coordDiff = 0;
81
82 while( diff > 0){
83 coordDiff = res[i] - diff;
84
85 if( coordDiff >= 0 ){
86 res[i] -= diff;
87 diff = 0;
88 } else {
89 res[i] = 0;
90 i++;
91 diff = abs(coordDiff);
92 }
93 }
94 }
95
96 // What we computed so far will be very close to the mode: hillclimb the rest of the way
97
98 bool modified = true;
99 double LP = unnormalized_logProb(res, lprobs, isotopeNo);
100 double NLP;
101
102 while(modified)
103 {
104 modified = false;
105 for(int ii = 0; ii<isotopeNo; ii++)
106 for(int jj = 0; jj<isotopeNo; jj++)
107 if(ii != jj && res[ii] > 0)
108 {
109 res[ii]--;
110 res[jj]++;
111 NLP = unnormalized_logProb(res, lprobs, isotopeNo);
112 if(NLP>LP || (NLP==LP && ii>jj))
113 {
114 modified = true;
115 LP = NLP;
116 }
117 else
118 {
119 res[ii]++;
120 res[jj]--;
121 }
122 }
123
124
125 }
126 return res;
127 }
128
129
130
131 #if !ISOSPEC_BUILDING_R
132 void printMarginal( const std::tuple<double*,double*,int*,int>& results, int dim)
133 {
134 for(int i=0; i<std::get<3>(results); i++){
135
136 std::cout << "Mass = " << std::get<0>(results)[i] <<
137 " log-prob =\t" << std::get<1>(results)[i] <<
138 " prob =\t" << exp(std::get<1>(results)[i]) <<
139 "\tand configuration =\t";
140
141 for(int j=0; j<dim; j++) std::cout << std::get<2>(results)[i*dim + j] << " ";
142
143 std::cout << std::endl;
144 }
145 }
146 #endif
147
148
149 double* getMLogProbs(const double* probs, int isoNo)
150 {
151 /*!
152 Here we order the processor to round the numbers up rather than down.
153 Rounding down could result in the algorithm falling in an infinite loop
154 because of the numerical instability of summing.
155 */
156 int curr_method = fegetround();
157 fesetround(FE_UPWARD);
158 double* ret = new double[isoNo];
159
160 // here we change the table of probabilities and log it.
161 for(int i = 0; i < isoNo; i++)
162 {
163 ret[i] = log(probs[i]);
164 for(int j=0; j<ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES; j++)
165 if(elem_table_probability[j] == probs[i])
166 {
167 ret[i] = elem_table_log_probability[j];
168 break;
169 }
170 }
171 fesetround(curr_method);
172 return ret;
173 }
174
175 double get_loggamma_nominator(int x)
176 {
177 // calculate log gamma of the nominator calculated in the binomial exression.
178 int curr_method = fegetround();
179 fesetround(FE_UPWARD);
180 double ret = lgamma(x+1);
181 fesetround(curr_method);
182 return ret;
183 }
184
185
186 Marginal::Marginal(
187 const double* _masses,
188 const double* _probs,
189 int _isotopeNo,
190 int _atomCnt
191 ) :
192 disowned(false),
193 isotopeNo(_isotopeNo),
194 atomCnt(_atomCnt),
195 atom_masses(array_copy<double>(_masses, _isotopeNo)),
196 atom_lProbs(getMLogProbs(_probs, isotopeNo)),
197 loggamma_nominator(get_loggamma_nominator(_atomCnt)),
198 mode_conf(initialConfigure(atomCnt, isotopeNo, _probs, atom_lProbs)),
199 mode_lprob(loggamma_nominator+unnormalized_logProb(mode_conf, atom_lProbs, isotopeNo)),
200 mode_mass(mass(mode_conf, atom_masses, isotopeNo)),
201 mode_prob(exp(mode_lprob)),
202 smallest_lprob(atomCnt * *std::min_element(atom_lProbs, atom_lProbs+isotopeNo))
203 {
204 try
205 {
206 if(ISOSPEC_G_FACT_TABLE_SIZE-1 <= atomCnt)
207 throw std::length_error("Subisotopologue too large, size limit (that is, the maximum number of atoms of a single element in a molecule) is: " + std::to_string(ISOSPEC_G_FACT_TABLE_SIZE-1));
208 for(size_t ii = 0; ii < isotopeNo; ii++)
209 if(_probs[ii] <= 0.0 || _probs[ii] > 1.0)
210 throw std::invalid_argument("All isotope probabilities p must fulfill: 0.0 < p <= 1.0");
211 }
212 catch(...)
213 {
214 delete[] atom_masses;
215 delete[] atom_lProbs;
216 delete[] mode_conf;
217 throw;
218 }
219 }
220
221 // the move-constructor: used in the specialization of the marginal.
222 Marginal::Marginal(Marginal&& other) :
223 disowned(other.disowned),
224 isotopeNo(other.isotopeNo),
225 atomCnt(other.atomCnt),
226 atom_masses(other.atom_masses),
227 atom_lProbs(other.atom_lProbs),
228 loggamma_nominator(other.loggamma_nominator),
229 mode_conf(other.mode_conf),
230 mode_lprob(other.mode_lprob),
231 mode_mass(other.mode_mass),
232 mode_prob(other.mode_prob),
233 smallest_lprob(other.smallest_lprob)
234 {
235 other.disowned = true;
236 }
237
238 Marginal::~Marginal()
239 {
240 if(!disowned)
241 {
242 delete[] atom_masses;
243 delete[] atom_lProbs;
244 delete[] mode_conf;
245 }
246 }
247
248
249 double Marginal::getLightestConfMass() const
250 {
251 double ret_mass = std::numeric_limits<double>::infinity();
252 for(unsigned int ii=0; ii < isotopeNo; ii++)
253 if( ret_mass > atom_masses[ii] )
254 ret_mass = atom_masses[ii];
255 return ret_mass*atomCnt;
256 }
257
258 double Marginal::getHeaviestConfMass() const
259 {
260 double ret_mass = 0.0;
261 for(unsigned int ii=0; ii < isotopeNo; ii++)
262 if( ret_mass < atom_masses[ii] )
263 ret_mass = atom_masses[ii];
264 return ret_mass*atomCnt;
265 }
266
267 // this is roughly an equivalent of IsoSpec-Threshold-Generator
268 MarginalTrek::MarginalTrek(
269 Marginal&& m,
270 int tabSize,
271 int hashSize
272 ) :
273 Marginal(std::move(m)),
274 current_count(0),
275 keyHasher(isotopeNo),
276 equalizer(isotopeNo),
277 orderMarginal(atom_lProbs, isotopeNo),
278 visited(hashSize,keyHasher,equalizer),
279 pq(orderMarginal),
280 totalProb(),
281 candidate(new int[isotopeNo]),
282 allocator(isotopeNo, tabSize)
283 {
284 int* initialConf = allocator.makeCopy(mode_conf);
285
286 pq.push(initialConf);
287 visited[initialConf] = 0;
288
289 totalProb = Summator();
290
291 current_count = 0;
292
293 add_next_conf();
294 }
295
296
297 bool MarginalTrek::add_next_conf()
298 {
299 /*!
300 Add next configuration.
301 If visited all, return false.
302 */
303 if(pq.size() < 1) return false;
304
305 Conf topConf = pq.top();
306 pq.pop();
307 ++current_count;
308 visited[topConf] = current_count;
309
310 _confs.push_back(topConf);
311 _conf_masses.push_back(mass(topConf, atom_masses, isotopeNo));
312 double logprob = logProb(topConf);
313 _conf_lprobs.push_back(logprob);
314
315
316 totalProb.add( exp( logprob ) );
317
318 for( unsigned int i = 0; i < isotopeNo; ++i )
319 {
320 for( unsigned int j = 0; j < isotopeNo; ++j )
321 {
322 // Growing index different than decreasing one AND
323 // Remain on simplex condition.
324 if( i != j && topConf[j] > 0 ){
325 copyConf(topConf, candidate, isotopeNo);
326
327 ++candidate[i];
328 --candidate[j];
329
330 // candidate should not have been already visited.
331 if( visited.count( candidate ) == 0 )
332 {
333 Conf acceptedCandidate = allocator.makeCopy(candidate);
334 pq.push(acceptedCandidate);
335
336 visited[acceptedCandidate] = 0;
337 }
338 }
339 }
340 }
341
342 return true;
343 }
344
345 int MarginalTrek::processUntilCutoff(double cutoff)
346 {
347 Summator s;
348 int last_idx = -1;
349 for(unsigned int i=0; i<_conf_lprobs.size(); i++)
350 {
351 s.add(_conf_lprobs[i]);
352 if(s.get() >= cutoff)
353 {
354 last_idx = i;
355 break;
356 }
357 }
358 if(last_idx > -1)
359 return last_idx;
360
361 while(totalProb.get() < cutoff && add_next_conf()) {}
362 return _conf_lprobs.size();
363 }
364
365
366 MarginalTrek::~MarginalTrek()
367 {
368 delete[] candidate;
369 }
370
371
372
373
374 PrecalculatedMarginal::PrecalculatedMarginal(Marginal&& m,
375 double lCutOff,
376 bool sort,
377 int tabSize,
378 int hashSize
379 ) : Marginal(std::move(m)),
380 allocator(isotopeNo, tabSize)
381 {
382 const ConfEqual equalizer(isotopeNo);
383 const KeyHasher keyHasher(isotopeNo);
384 const ConfOrderMarginalDescending orderMarginal(atom_lProbs, isotopeNo);
385
386 std::unordered_set<Conf,KeyHasher,ConfEqual> visited(hashSize,keyHasher,equalizer);
387
388 Conf currentConf = allocator.makeCopy(mode_conf);
389 if(logProb(currentConf) >= lCutOff)
390 {
391 // create a copy and store a ptr to the *same* copy in both structures
392 // (save some space and time)
393 auto tmp = allocator.makeCopy(currentConf);
394 configurations.push_back(tmp);
395 visited.insert(tmp);
396 }
397
398 unsigned int idx = 0;
399
400 while(idx < configurations.size())
401 {
402 memcpy(currentConf, configurations[idx], sizeof(int)*isotopeNo);
403 idx++;
404 for(unsigned int ii = 0; ii < isotopeNo; ii++ )
405 for(unsigned int jj = 0; jj < isotopeNo; jj++ )
406 if( ii != jj && currentConf[jj] > 0)
407 {
408 currentConf[ii]++;
409 currentConf[jj]--;
410
411 if (visited.count(currentConf) == 0 && logProb(currentConf) >= lCutOff)
412 {
413 // create a copy and store a ptr to the *same* copy in
414 // both structures (save some space and time)
415 auto tmp = allocator.makeCopy(currentConf);
416 visited.insert(tmp);
417 configurations.push_back(tmp);
418 // std::cout << " V: "; for (auto it : visited) std::cout << it << " "; std::cout << std::endl;
419 }
420
421 currentConf[ii]--;
422 currentConf[jj]++;
423
424 }
425 }
426
427 // orderMarginal defines the order of configurations (compares their logprobs)
428 // akin to key in Python sort.
429 if(sort)
430 std::sort(configurations.begin(), configurations.end(), orderMarginal);
431
432
433 confs = &configurations[0];
434 no_confs = configurations.size();
435 lProbs = new double[no_confs+1];
436 probs = new double[no_confs];
437 masses = new double[no_confs];
438
439
440 for(unsigned int ii=0; ii < no_confs; ii++)
441 {
442 lProbs[ii] = logProb(confs[ii]);
443 probs[ii] = exp(lProbs[ii]);
444 masses[ii] = mass(confs[ii], atom_masses, isotopeNo);
445 }
446 lProbs[no_confs] = -std::numeric_limits<double>::infinity();
447 }
448
449
450 PrecalculatedMarginal::~PrecalculatedMarginal()
451 {
452 if(lProbs != nullptr)
453 delete[] lProbs;
454 if(masses != nullptr)
455 delete[] masses;
456 if(probs != nullptr)
457 delete[] probs;
458 }
459
460
461
462
463 } // namespace IsoSpec
464
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <tuple>
19 #include <unordered_map>
20 #include <queue>
21 #include <atomic>
22 #include "conf.h"
23 #include "allocator.h"
24 #include "operators.h"
25 #include "summator.h"
26
27
28 namespace IsoSpec
29 {
30
31 Conf initialConfigure(int atomCnt, int isotopeNo, const double* probs);
32
33
34 void printMarginal(const std::tuple<double*,double*,int*,int>& results, int dim);
35
36 //! The marginal distribution class (a subisotopologue).
37 /*!
38 This class mostly provides some basic common API for subclasses, but itself is not abstract.
39 This class represents the probability distribution generated by one element only -- a subisotopologue.
40 For instance, it might be the distribution of C200, that might be part of, say, C200H402.
41 It corresponds to the multinomial distribution, where each configuration can also be attributed a precise mass.
42 The constructor method perform initial hill-climbing to find the most probable sub-isotopologue (the mode).
43 */
44 class Marginal
45 {
46 private:
47 bool disowned;
48 protected:
49 const unsigned int isotopeNo; /*!< The number of isotopes of the given element. */
50 const unsigned int atomCnt; /*!< The number of atoms of the given element. */
51 const double* const atom_masses; /*!< Table of atomic masses of all the isotopeNo isotopes. */
52 const double* const atom_lProbs; /*!< Table of log-probabilities of all the isotopeNo isotopes. */
53 const double loggamma_nominator; /*!< The constant nominator that appears in the expressions for the multinomial probabilities. */
54 const Conf mode_conf; /*!< A subisotopologue with most probability. If not unique, one of the representatives of that class of subisotopologues. */
55 const double mode_lprob; /*!< The log-probability of the mode subisotopologue.*/
56 const double mode_mass; /*!< The mass of the mode subisotopologue.*/
57 const double mode_prob; /*!< The probability of the mode subisotopologue.*/
58 const double smallest_lprob; /*!< The smallest-achievable log-probability in the distribution of subisotopologues. */
59
60
61 public:
62 //! Class constructor.
63 /*!
64 \param _masses A table of masses of the stable isotopes of the investigated element, e.g. for C10 it is 2: C12 and C13.
65 \param _probs A table of natural frequencies of the stable isotopes of the investigated element, see IUPAC at https://iupac.org/isotopesmatter/
66 \param _isotopeNo Number of isotopes of a given element.
67 \param _atomCnt The number of atoms of the given element, e.g. 10 for C10.
68 \return An instance of the Marginal class.
69 */
70 Marginal(
71 const double* _masses, // masses size = logProbs size = isotopeNo
72 const double* _probs,
73 int _isotopeNo,
74 int _atomCnt
75 );
76
77 // Get rid of the C++ generated copy and assignment constructors.
78 Marginal(Marginal& other) = delete;
79 Marginal& operator= (const Marginal& other) = delete;
80
81 //! Move constructor.
82 Marginal(Marginal&& other);
83
84 //! Destructor.
85 virtual ~Marginal();
86
87 //! Get the number of isotopes of the investigated element.
88 /*!
89 \return The integer number of isotopes of the investigated element.
90 */
91 inline int get_isotopeNo() const { return isotopeNo; };
92
93 //! Get the mass of the lightest subisotopologue.
94 /*! This is trivially obtained by considering all atomNo atoms to be the lightest isotope possible.
95 \return The mass of the lightiest subisotopologue.
96 */
97 double getLightestConfMass() const;
98
99 //! Get the mass of the heaviest subisotopologue.
100 /*! This is trivially obtained by considering all atomNo atoms to be the heaviest isotope possible.
101 \return The mass of the heaviest subisotopologue.
102 */
103 double getHeaviestConfMass() const;
104
105 //! Get the log-probability of the mode subisotopologue.
106 /*!
107 \return The log-probability of a/the most probable subisotopologue.
108 */
109 inline double getModeLProb() const { return mode_lprob; };
110
111 //! The the mass of the mode subisotopologue.
112 /*!
113 \return The mass of one of the most probable subisotopologues.
114 */
115 inline double getModeMass() const { return mode_mass; };
116
117 //! The the probability of the mode subisotopologue.
118 /*!
119 \return The probability of a/the most probable subisotopologue.
120 */
121 inline double getModeProb() const { return mode_prob; };
122
123 //! The the log-probability of the lightest subisotopologue.
124 /*!
125 \return The logarithm of the smallest non-zero probability of a subisotopologue.
126 */
127
128 inline double getSmallestLProb() const { return smallest_lprob; };
129
130 //! Calculate the log-probability of a given subisotopologue.
131 /*!
132 \param conf A subisotopologue (a table of integers describing subsequent isotope-counts).
133 \return The log-probability of the input subisotopologue.
134 */
135 inline double logProb(Conf conf) const { return loggamma_nominator + unnormalized_logProb(conf, atom_lProbs, isotopeNo); };
136 };
137
138
139 //! The marginal distribution class (a subisotopologue).
140 class MarginalTrek : public Marginal
141 {
142 private:
143 int current_count;
144 const KeyHasher keyHasher;
145 const ConfEqual equalizer;
146 const ConfOrderMarginal orderMarginal;
147 std::unordered_map<Conf,int,KeyHasher,ConfEqual> visited;
148 std::priority_queue<Conf,std::vector<Conf>,ConfOrderMarginal> pq;
149 Summator totalProb;
150 Conf candidate;
151 Allocator<int> allocator;
152 std::vector<double> _conf_lprobs;
153 std::vector<double> _conf_masses;
154 std::vector<int*> _confs;
155
156 //! Proceed to the next configuration and memoize it (as it will be surely needed).
157 bool add_next_conf();
158
159 public:
160 //! Move constructor: specializes the Marginal class.
161 /*!
162 \param tabSize The size of the table used to store configurations in the allocator.
163 \param hashSize The size of the hash table used to store visited subisotopologues.
164 */
165 MarginalTrek(
166 Marginal&& m,
167 int tabSize = 1000,
168 int hashSize = 1000
169 );
170
171 //! Check if the table of computed subisotopologues does not have to be extended.
172 /*!
173 This function checks if the idx-th most probable subisotopologue was memoized and if not, computes it and memoizes it.
174
175 \param idx The number of the idx-th most probable subisotopologue.
176 \return Returns false if it the provided idx exceeds the total number of subisotopologues.
177 */
178 inline bool probeConfigurationIdx(int idx)
179 {
180 while(current_count <= idx)
181 if(!add_next_conf())
182 return false;
183 return true;
184 }
185
186
187 //! Calculate subisotopologues with probability above or equal to the cut-off.
188 /*!
189 \param cutoff The probability cut-off
190 \return The number of the last subisotopologue above the cut-off.
191 */
192 int processUntilCutoff(double cutoff);
193
194 inline const std::vector<double>& conf_lprobs() const { return _conf_lprobs; };
195 inline const std::vector<double>& conf_masses() const { return _conf_masses; };
196 inline const std::vector<int*>& confs() const { return _confs; };
197
198
199 virtual ~MarginalTrek();
200 };
201
202
203 //! Precalculated Marginal class
204 /*!
205 This class serves to calculate a set of isotopologues that
206 is defined by the minimal probability threshold.
207
208 This works faster than if you did not know the threshold.
209 If you have no idea about the threshold, you would need to call us,
210 to change encode the layered version of the marginal.
211 */
212 class PrecalculatedMarginal : public Marginal
213 {
214 protected:
215 std::vector<Conf> configurations;
216 Conf* confs;
217 unsigned int no_confs;
218 double* masses;
219 double* lProbs;
220 double* probs;
221 Allocator<int> allocator;
222 public:
223 //! The move constructor (disowns the Marginal).
224 /*!
225 This constructor memoizes all subisotopologues with log-probability above the provided threshold lCutOff
226 \param Marginal An instance of the Marginal class this class is about to disown.
227 \param lCutOff The lower limit on the log-probability of the precomputed subisotopologues.
228 \param sort Should the subisotopologues be stored with descending probability ?
229 \return An instance of the PrecalculatedMarginal class.
230 */
231 PrecalculatedMarginal(
232 Marginal&& m,
233 double lCutOff,
234 bool sort = true,
235 int tabSize = 1000,
236 int hashSize = 1000
237 );
238
239 //! Destructor.
240 virtual ~PrecalculatedMarginal();
241
242 //! Is there a subisotopologue with a given number?
243 /*!
244 \return Returns true if idx does not exceed the number of pre-computed configurations.
245 */
246 inline bool inRange(unsigned int idx) const { return idx < no_confs; };
247
248 //! Get the log-probability of the idx-th subisotopologue.
249 /*!
250 \param idx The number of the considered subisotopologue.
251 \return The log-probability of the idx-th subisotopologue.
252 */
253 inline const double& get_lProb(int idx) const { return lProbs[idx]; };
254
255 //! Get the probability of the idx-th subisotopologue.
256 /*!
257 \param idx The number of the considered subisotopologue.
258 \return The probability of the idx-th subisotopologue.
259 */
260 inline const double& get_prob(int idx) const { return probs[idx]; };
261
262 //! Get the mass of the idx-th subisotopologue.
263 /*!
264 \param idx The number of the considered subisotopologue.
265 \return The mass of the idx-th subisotopologue.
266 */
267 inline const double& get_mass(int idx) const { return masses[idx]; };
268
269 //! Get the table of the log-probabilities of subisotopologues.
270 /*!
271 \return Pointer to the first element in the table storing log-probabilities of subisotopologues.
272 */
273 inline const double* get_lProbs_ptr() const { return lProbs; };
274
275 //! Get the table of the masses of subisotopologues.
276 /*!
277 \return Pointer to the first element in the table storing masses of subisotopologues.
278 */
279 inline const double* get_masses_ptr() const { return masses; };
280
281
282 //! Get the counts of isotopes that define the subisotopologue.
283 /*!
284 \param idx The number of the considered subisotopologue.
285 \return The counts of isotopes that define the subisotopologue.
286 */
287 inline const Conf& get_conf(int idx) const { return confs[idx]; };
288
289 //! Get the number of precomputed subisotopologues.
290 /*!
291 \return The number of precomputed subisotopologues.
292 */
293 inline unsigned int get_no_confs() const { return no_confs; };
294 };
295
296 } // namespace IsoSpec
297
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16
17 #include "misc.h"
18 #include "platform.h"
19 #include <stdlib.h>
20
21 #define mswap(x, y) swapspace = x; x = y; y=swapspace;
22
23
24 namespace IsoSpec
25 {
26
27 void* quickselect(void** array, int n, int start, int end)
28 {
29 void* swapspace;
30
31 if(start == end)
32 return array[start];
33
34 while(true)
35 {
36 // Partition part
37 int len = end - start;
38 #if ISOSPEC_BUILDING_R
39 int pivot = len/2 + start;
40 #else
41 int pivot = rand() % len + start;
42 #endif
43 void* pval = array[pivot];
44 double pprob = getLProb(pval);
45 mswap(array[pivot], array[end-1]);
46 int loweridx = start;
47 for(int i=start; i<end-1; i++)
48 {
49 if(getLProb(array[i]) < pprob)
50 {
51 mswap(array[i], array[loweridx]);
52 loweridx++;
53 }
54 }
55 mswap(array[end-1], array[loweridx]);
56
57 // Selection part
58 if(n==loweridx)
59 return array[n];
60 if(n<loweridx)
61 end = loweridx;
62 else
63 start = loweridx+1;
64 };
65 }
66
67 } // namespace IsoSpec
68
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <iostream>
19 #include <tuple>
20 #include <vector>
21 #include <fenv.h>
22 #include "isoMath.h"
23
24 namespace IsoSpec
25 {
26
27 inline double combinedSum(
28 const int* conf, const std::vector<double>** valuesContainer, int dimNumber
29 ){
30 double res = 0.0;
31 for(int i=0; i<dimNumber;i++)
32 res += (*(valuesContainer[i]))[conf[i]];
33 return res;
34 }
35
36 inline int* getConf(void* conf)
37 {
38 return reinterpret_cast<int*>(
39 reinterpret_cast<char*>(conf) + sizeof(double)
40 );
41 }
42
43 inline double getLProb(void* conf)
44 {
45 double ret = *reinterpret_cast<double*>(conf);
46 return ret;
47 }
48
49
50 inline double unnormalized_logProb(const int* conf, const double* logProbs, int dim)
51 {
52 double res = 0.0;
53
54 int curr_method = fegetround();
55
56 fesetround(FE_TOWARDZERO);
57
58 for(int i=0; i < dim; i++)
59 res += minuslogFactorial(conf[i]);
60
61 fesetround(FE_UPWARD);
62
63 for(int i=0; i < dim; i++)
64 res += conf[i] * logProbs[i];
65
66 fesetround(curr_method);
67
68 return res;
69 }
70
71 inline double mass(const int* conf, const double* masses, int dim)
72 {
73 double res = 0.0;
74
75 for(int i=0; i < dim; i++)
76 {
77 res += conf[i] * masses[i];
78 }
79
80 return res;
81 }
82
83
84 inline bool tupleCmp(
85 std::tuple<double,double,int*> t1,
86 std::tuple<double,double,int*> t2
87 ){
88 return std::get<1>(t1) > std::get<1>(t2);
89 }
90
91 template<typename T> void printArray(const T* array, int size)
92 {
93 for (int i=0; i<size; i++)
94 std::cout << array[i] << " ";
95 std::cout << std::endl;
96 }
97
98 template<typename T> void printVector(const std::vector<T>& vec)
99 {
100 printArray<T>(vec.data(), vec.size());
101 }
102
103
104 template<typename T> void printNestedArray(const T** array, const int* shape, int size)
105 {
106 for (int i=0; i<size; i++)
107 printArray(array[i], shape[i]);
108 std::cout << std::endl;
109 }
110
111 #define mswap(x, y) swapspace = x; x = y; y=swapspace;
112
113
114 //! Quickly select the n'th positional statistic, including the weights.
115 void* quickselect(void** array, int n, int start, int end);
116
117
118 template <typename T> inline static T* array_copy(const T* A, int size)
119 {
120 T* ret = new T[size];
121 memcpy(ret, A, size*sizeof(T));
122 return ret;
123 }
124
125 template<typename T> void dealloc_table(T* tbl, int dim)
126 {
127 for(int i=0; i<dim; i++)
128 {
129 delete tbl[i];
130 }
131 delete[] tbl;
132 }
133
134 } // namespace IsoSpec
135
0 /*
1 * This file has been included as a part of IsoSpec project, under a MIT licence. It
2 * comes from the repository:
3 *
4 * https://github.com/witwall/mman-win32
5 *
6 * which itself is a mirror of:
7 *
8 * https://code.google.com/archive/p/mman-win32/
9 */
10
11 #include "platform.h"
12 #if ISOSPEC_GOT_MMAN && !ISOSPEC_GOT_SYSTEM_MMAN
13
14 #include <windows.h>
15 #include <errno.h>
16 #include <io.h>
17
18 #include "mman.h"
19
20 #ifndef FILE_MAP_EXECUTE
21 #define FILE_MAP_EXECUTE 0x0020
22 #endif /* FILE_MAP_EXECUTE */
23
24
25 static int __map_mman_error(const DWORD err, const int deferr)
26 {
27 if (err == 0)
28 return 0;
29 //TODO: implement
30 return err;
31 }
32
33 static DWORD __map_mmap_prot_page(const int prot)
34 {
35 DWORD protect = 0;
36
37 if (prot == PROT_NONE)
38 return protect;
39
40 if ((prot & PROT_EXEC) != 0)
41 {
42 protect = ((prot & PROT_WRITE) != 0) ?
43 PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
44 }
45 else
46 {
47 protect = ((prot & PROT_WRITE) != 0) ?
48 PAGE_READWRITE : PAGE_READONLY;
49 }
50
51 return protect;
52 }
53
54 static DWORD __map_mmap_prot_file(const int prot)
55 {
56 DWORD desiredAccess = 0;
57
58 if (prot == PROT_NONE)
59 return desiredAccess;
60
61 if ((prot & PROT_READ) != 0)
62 desiredAccess |= FILE_MAP_READ;
63 if ((prot & PROT_WRITE) != 0)
64 desiredAccess |= FILE_MAP_WRITE;
65 if ((prot & PROT_EXEC) != 0)
66 desiredAccess |= FILE_MAP_EXECUTE;
67
68 return desiredAccess;
69 }
70
71 void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off)
72 {
73 HANDLE fm, h;
74
75 void * map = MAP_FAILED;
76
77 #ifdef _MSC_VER
78 #pragma warning(push)
79 #pragma warning(disable: 4293)
80 #endif
81
82 const DWORD dwFileOffsetLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
83 (DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
84 const DWORD dwFileOffsetHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
85 (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
86 const DWORD protect = __map_mmap_prot_page(prot);
87 const DWORD desiredAccess = __map_mmap_prot_file(prot);
88
89 const OffsetType maxSize = off + (OffsetType)len;
90
91 const DWORD dwMaxSizeLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
92 (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
93 const DWORD dwMaxSizeHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
94 (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
95
96 #ifdef _MSC_VER
97 #pragma warning(pop)
98 #endif
99
100 errno = 0;
101
102 if (len == 0
103 /* Unsupported flag combinations */
104 || (flags & MAP_FIXED) != 0
105 /* Usupported protection combinations */
106 || prot == PROT_EXEC)
107 {
108 errno = EINVAL;
109 return MAP_FAILED;
110 }
111
112 h = ((flags & MAP_ANONYMOUS) == 0) ?
113 (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;
114
115 if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
116 {
117 errno = EBADF;
118 return MAP_FAILED;
119 }
120
121 fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
122
123 if (fm == NULL)
124 {
125 errno = __map_mman_error(GetLastError(), EPERM);
126 return MAP_FAILED;
127 }
128
129 map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
130
131 CloseHandle(fm);
132
133 if (map == NULL)
134 {
135 errno = __map_mman_error(GetLastError(), EPERM);
136 return MAP_FAILED;
137 }
138
139 return map;
140 }
141
142 int munmap(void *addr, size_t len)
143 {
144 if (UnmapViewOfFile(addr))
145 return 0;
146
147 errno = __map_mman_error(GetLastError(), EPERM);
148
149 return -1;
150 }
151
152 int _mprotect(void *addr, size_t len, int prot)
153 {
154 DWORD newProtect = __map_mmap_prot_page(prot);
155 DWORD oldProtect = 0;
156
157 if (VirtualProtect(addr, len, newProtect, &oldProtect))
158 return 0;
159
160 errno = __map_mman_error(GetLastError(), EPERM);
161
162 return -1;
163 }
164
165 int msync(void *addr, size_t len, int flags)
166 {
167 if (FlushViewOfFile(addr, len))
168 return 0;
169
170 errno = __map_mman_error(GetLastError(), EPERM);
171
172 return -1;
173 }
174
175 int mlock(const void *addr, size_t len)
176 {
177 if (VirtualLock((LPVOID)addr, len))
178 return 0;
179
180 errno = __map_mman_error(GetLastError(), EPERM);
181
182 return -1;
183 }
184
185 int munlock(const void *addr, size_t len)
186 {
187 if (VirtualUnlock((LPVOID)addr, len))
188 return 0;
189
190 errno = __map_mman_error(GetLastError(), EPERM);
191
192 return -1;
193 }
194
195
196 #endif
0 /*
1 * sys/mman.h
2 * mman-win32
3 *
4 * This file has been included as a part of IsoSpec project, under a MIT licence. It
5 * comes from the repository:
6 *
7 * https://github.com/witwall/mman-win32
8 *
9 * which itself is a mirror of:
10 *
11 * https://code.google.com/archive/p/mman-win32/
12 */
13
14 #pragma once
15
16 #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
17 #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
18 #endif
19
20 /* All the headers include this file. */
21 #ifndef _MSC_VER
22 #include <_mingw.h>
23 #endif
24
25 /* Determine offset type */
26 #include <stdint.h>
27 #if defined(_WIN64)
28 typedef int64_t OffsetType;
29 #else
30 typedef uint32_t OffsetType;
31 #endif
32
33 #include <sys/types.h>
34
35
36 #define PROT_NONE 0
37 #define PROT_READ 1
38 #define PROT_WRITE 2
39 #define PROT_EXEC 4
40
41 #define MAP_FILE 0
42 #define MAP_SHARED 1
43 #define MAP_PRIVATE 2
44 #define MAP_TYPE 0xf
45 #define MAP_FIXED 0x10
46 #define MAP_ANONYMOUS 0x20
47 #define MAP_ANON MAP_ANONYMOUS
48
49 #define MAP_FAILED ((void *)-1)
50
51 /* Flags for msync. */
52 #define MS_ASYNC 1
53 #define MS_SYNC 2
54 #define MS_INVALIDATE 4
55
56 void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off);
57 int munmap(void *addr, size_t len);
58 int _mprotect(void *addr, size_t len, int prot);
59 int msync(void *addr, size_t len, int flags);
60 int mlock(const void *addr, size_t len);
61 int munlock(const void *addr, size_t len);
62
63
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #include "operators.h"
17 #include "marginalTrek++.h"
18
19 namespace IsoSpec
20 {
21
22 KeyHasher::KeyHasher(int _dim)
23 : dim(_dim)
24 {}
25
26 ConfEqual::ConfEqual(int dim)
27 : size( dim*sizeof(int) )
28 {}
29
30 ConfOrderMarginal::ConfOrderMarginal(const double* _logProbs, int _dim)
31 : logProbs(_logProbs), dim(_dim)
32 {}
33
34 ConfOrderMarginalDescending::ConfOrderMarginalDescending(const double* _logProbs, int _dim)
35 : logProbs(_logProbs), dim(_dim)
36 {}
37
38
39 OrderMarginalsBySizeDecresing::OrderMarginalsBySizeDecresing(PrecalculatedMarginal const* const * const _T) : T(_T) {}
40
41 bool OrderMarginalsBySizeDecresing::operator()(int m1, int m2)
42 {
43 return T[m1]->get_no_confs() > T[m2]->get_no_confs();
44 }
45
46
47 } // namespace IsoSpec
48
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <string.h>
19 #include "conf.h"
20 #include "isoMath.h"
21 #include "misc.h"
22
23 namespace IsoSpec
24 {
25
26 class KeyHasher
27 {
28 private:
29 int dim;
30 public:
31 KeyHasher(int dim);
32
33 inline std::size_t operator()(const int* conf) const
34 {
35 // Following Boost...
36 std::size_t seed = 0;
37 for(int i = 0; i < dim; ++i )
38 seed ^= conf[i] + 0x9e3779b9 + (seed << 6) + (seed >> 2);
39 return seed;
40 };
41 };
42
43
44 class ConfEqual
45 {
46 private:
47 int size;
48 public:
49 ConfEqual(int dim);
50
51 inline bool operator()(const int* conf1, const int* conf2) const
52 {
53 // The memcmp() function returns zero if the two strings are identical, oth-
54 // erwise returns the difference between the first two differing bytes
55 // (treated as unsigned char values, so that `\200' is greater than `\0',
56 // for example). Zero-length strings are always identical. This behavior
57 // is not required by C and portable code should only depend on the sign of
58 // the returned value.
59 // sacred man of memcmp.
60 return memcmp(conf1, conf2, size) == 0;
61 }
62 };
63
64
65 class ConfOrder
66 {
67 //configurations comparator
68 public:
69 inline bool operator()(void* conf1,void* conf2) const
70 {
71 return *reinterpret_cast<double*>(conf1) < *reinterpret_cast<double*>(conf2);
72 };
73 };
74
75
76
77 class ConfOrderMarginal
78 {
79 //configurations comparator
80 const double* logProbs;
81 int dim;
82 public:
83 ConfOrderMarginal(const double* logProbs, int dim);
84
85 inline bool operator()(const Conf conf1, const Conf conf2)
86 {// Return true if conf1 is less probable than conf2.
87 return unnormalized_logProb(conf1,logProbs,dim) < unnormalized_logProb(conf2,logProbs,dim);
88 };
89 };
90
91 class ConfOrderMarginalDescending
92 {
93 //configurations comparator
94 const double* logProbs;
95 int dim;
96 public:
97 ConfOrderMarginalDescending(const double* logProbs, int dim);
98
99 inline bool operator()(const Conf conf1, const Conf conf2)
100 {// Return true if conf1 is less probable than conf2.
101 return unnormalized_logProb(conf1,logProbs,dim) > unnormalized_logProb(conf2,logProbs,dim);
102 };
103 };
104
105 template<typename T> class ReverseOrder
106 {
107 public:
108 inline ReverseOrder() {};
109 inline bool operator()(const T a,const T b) const { return a > b; };
110 };
111
112 template<typename T> class TableOrder
113 {
114 const T* tbl;
115 public:
116 inline TableOrder(const T* _tbl) : tbl(_tbl) {};
117 inline bool operator()(unsigned int i, unsigned int j) { return tbl[i] < tbl[j]; };
118 };
119
120 } // namespace IsoSpec
121
122 #include "marginalTrek++.h"
123
124 class PrecalculatedMarginal; // In case marginalTrek++.h us including us, and can't be included again...
125
126 namespace IsoSpec
127 {
128
129 class OrderMarginalsBySizeDecresing
130 {
131 PrecalculatedMarginal const* const* const T;
132 public:
133 OrderMarginalsBySizeDecresing(PrecalculatedMarginal const* const * const _T);
134 bool operator()(int m1, int m2);
135 };
136
137
138 } // namespace IsoSpec
139
140
141
0
1 #pragma once
2
3 #if !defined(ISOSPEC_BUILDING_R)
4 #define ISOSPEC_BUILDING_R true
5 #endif
6
7 #if !defined(ISOSPEC_BUILDING_CPP)
8 #define ISOSPEC_BUILDING_CPP true
9 #endif
10
11 #if !defined(ISOSPEC_BUILDING_PYTHON)
12 #define ISOSPEC_BUILDING_PYTHON false
13 #endif
14
15 #if !defined(ISOSPEC_BUILDING_OPENMS)
16 #define ISOSPEC_BUILDING_OPENMS false
17 #endif
18
19 #if defined(__unix__) || defined(__unix) || \
20 (defined(__APPLE__) && defined(__MACH__))
21 #define ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY true
22 #define ISOSPEC_TEST_WE_ARE_ON_WINDOWS false /* CYGWIN doesn't really count as Windows for our purposes, we'll be using UNIX API anyway */
23 #define ISOSPEC_TEST_GOT_SYSTEM_MMAN true
24 #define ISOSPEC_TEST_GOT_MMAN true
25 #elif defined(__MINGW32__) || defined(_WIN32)
26 #define ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY false
27 #define ISOSPEC_TEST_WE_ARE_ON_WINDOWS true
28 #define ISOSPEC_TEST_GOT_SYSTEM_MMAN false
29 #define ISOSPEC_TEST_GOT_MMAN true
30 #else
31 #define ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY false /* Well, probably... */
32 #define ISOSPEC_TEST_WE_ARE_ON_WINDOWS false
33 #define ISOSPEC_TEST_GOT_SYSTEM_MMAN false
34 #define ISOSPEC_TEST_GOT_MMAN false
35 #endif
36
37 #if !defined(ISOSPEC_USE_PTHREADS)
38 #define ISOSPEC_USE_PTHREADS false /* TODO: possibly put a macro here to detect whether we */
39 #endif /* can/should use pthreads - or rip them out altogether.
40 * Investigate whether the performance advantage of pthreads on
41 * some platforms (*cough* CYGWIN *cough*) is still large
42 * enough to justify keeping both implementations around */
43
44 #if !defined(ISOSPEC_WE_ARE_ON_UNIX_YAY)
45 #define ISOSPEC_WE_ARE_ON_UNIX_YAY ISOSPEC_TEST_WE_ARE_ON_UNIX_YAY
46 #endif
47
48 #if !defined(ISOSPEC_WE_ARE_ON_WINDOWS)
49 #define ISOSPEC_WE_ARE_ON_WINDOWS ISOSPEC_TEST_WE_ARE_ON_WINDOWS
50 #endif
51
52 #if !defined(ISOSPEC_GOT_SYSTEM_MMAN)
53 #define ISOSPEC_GOT_SYSTEM_MMAN ISOSPEC_TEST_GOT_SYSTEM_MMAN
54 #endif
55
56 #if !defined(ISOSPEC_GOT_MMAN)
57 #define ISOSPEC_GOT_MMAN ISOSPEC_TEST_GOT_MMAN
58 #endif
59
60
61 // Note: __GNUC__ is defined by clang and gcc
62 #ifdef __GNUC__
63 #define ISOSPEC_LIKELY(condition) __builtin_expect(static_cast<bool>(condition), 1)
64 #define ISOSPEC_UNLIKELY(condition) __builtin_expect(static_cast<bool>(condition), 0)
65 // For aggressive inlining
66 #define ISOSPEC_FORCE_INLINE __attribute__ ((always_inline)) inline
67 #elif defined _MSC_VER
68 #define ISOSPEC_LIKELY(condition) condition
69 #define ISOSPEC_UNLIKELY(condition) condition
70 #define ISOSPEC_FORCE_INLINE __forceinline inline
71 #else
72 #define ISOSPEC_LIKELY(condition) condition
73 #define ISOSPEC_UNLIKELY(condition) condition
74 #define ISOSPEC_FORCE_INLINE inline
75 #endif
76
77
78 #if ISOSPEC_GOT_MMAN
79 #if ISOSPEC_GOT_SYSTEM_MMAN
80 #include <sys/mman.h>
81 #else
82 #include "mman.h"
83 #endif
84 #else
85 #include <stdlib.h> /* malloc, free, rand */
86 #endif
87
88
89 #if defined(OPENMS_DLLAPI) /* IsoSpec is being built as a part of OpenMS: use their visibility macros */
90 #define ISOSPEC_EXPORT_SYMBOL OPENMS_DLLAPI
91 #else /* it's a can of worms we don't yet want to open ourselves though... */
92 #define ISOSPEC_EXPORT_SYMBOL
93 #endif
0 /*
1 * Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek.
2 *
3 * This file is part of IsoSpec.
4 *
5 * IsoSpec is free software: you can redistribute it and/or modify
6 * it under the terms of the Simplified ("2-clause") BSD licence.
7 *
8 * IsoSpec is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * You should have received a copy of the Simplified BSD Licence
13 * along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
14 */
15
16 #pragma once
17
18 #include <cmath>
19 #include <atomic>
20
21 namespace IsoSpec
22 {
23
24 class SSummator
25 {
26 // Shewchuk algorithm
27 std::vector<double> partials;
28 int maxpart;
29 public:
30 inline SSummator()
31 { maxpart = 0; }
32
33 inline SSummator(SSummator& other)
34 {
35 this->partials = other.partials;
36 this->maxpart = other.maxpart;
37 }
38 inline void add(double x)
39 {
40 unsigned int i=0;
41 for(int pidx=0; pidx<maxpart; pidx++)
42 {
43 double y = partials[pidx];
44 if(std::abs(x) < std::abs(y))
45 std::swap(x, y);
46 double hi = x+y;
47 double lo = y-(hi-x);
48 if(lo != 0.0)
49 {
50 partials[i] = lo;
51 i += 1;
52 }
53 x = hi;
54 }
55 while(partials.size() <= i)
56 partials.push_back(0.0);
57 partials[i] = x;
58 maxpart = i+1;
59 }
60 inline double get()
61 {
62 double ret = 0.0;
63 for(int i=0; i<maxpart; i++)
64 ret += partials[i];
65 return ret;
66 }
67 };
68
69
70
71
72
73
74
75 class Summator{
76 // Kahan algorithm
77 double sum;
78 double c;
79
80 public:
81 inline Summator()
82 { sum = 0.0; c = 0.0;}
83
84 inline void add(double what)
85 {
86 double y = what - c;
87 double t = sum + y;
88 c = (t - sum) - y;
89 sum = t;
90 }
91
92 inline double get()
93 {
94 return sum;
95 }
96 };
97
98 class TSummator
99 {
100 // Trivial algorithm, for testing only
101 double sum;
102 public:
103 inline TSummator()
104 { sum = 0.0; }
105
106 inline void add(double what)
107 {
108 sum += what;
109 }
110 inline double get()
111 {
112 return sum;
113 }
114 };
115
116
117 } // namespace IsoSpec
118
0 #include "tabulator.h"
1
2
3 namespace IsoSpec
4 {
5 template class Tabulator<IsoThresholdGenerator>;
6 template class Tabulator<IsoLayeredGenerator>;
7 } // namespace IsoSpec
0 #pragma once
1
2 #include <stdlib.h>
3
4 #include "isoSpec++.h"
5
6 #define ISOSPEC_INIT_TABLE_SIZE 1024
7
8 namespace IsoSpec
9 {
10
11 template <typename T> class Tabulator
12 {
13 private:
14 double* _masses;
15 double* _lprobs;
16 double* _probs;
17 int* _confs;
18 size_t _confs_no;
19 public:
20 Tabulator(T* generator,
21 bool get_masses, bool get_probs,
22 bool get_lprobs, bool get_confs);
23
24 ~Tabulator();
25
26 inline double* masses() { return _masses; };
27 inline double* lprobs() { return _lprobs; };
28 inline double* probs() { return _probs; };
29 inline int* confs() { return _confs; };
30 inline size_t confs_no() { return _confs_no; };
31 };
32
33 inline void reallocate(double **array, int new_size){
34 if( *array != nullptr ){
35 *array = (double *) realloc(*array, new_size);
36 }
37 }
38
39 template <typename T> Tabulator<T>::Tabulator(T* generator,
40 bool get_masses, bool get_probs,
41 bool get_lprobs, bool get_confs )
42 {
43 size_t current_size = ISOSPEC_INIT_TABLE_SIZE;
44 int confs_tbl_idx = 0;
45 _confs_no = 0;
46
47 const int allDimSizeOfInt = sizeof(int)*generator->getAllDim();
48
49 _masses = get_masses ? (double *) malloc(ISOSPEC_INIT_TABLE_SIZE * sizeof(double)) : nullptr;
50 _lprobs = get_lprobs ? (double *) malloc(ISOSPEC_INIT_TABLE_SIZE * sizeof(double)) : nullptr;
51 _probs = get_probs ? (double *) malloc(ISOSPEC_INIT_TABLE_SIZE * sizeof(double)) : nullptr;
52 _confs = get_confs ? (int *) malloc(ISOSPEC_INIT_TABLE_SIZE * allDimSizeOfInt): nullptr;
53
54
55 while(generator->advanceToNextConfiguration()){
56 if( _confs_no == current_size )
57 {
58 current_size *= 2;
59
60 // FIXME: Handle overflow gracefully here. It definitely could happen for people still stuck on 32 bits...
61
62 reallocate(&_masses, current_size * sizeof(double));
63 reallocate(&_lprobs, current_size * sizeof(double));
64 reallocate(&_probs, current_size * sizeof(double));
65
66 if( _confs != nullptr ){
67 _confs = (int *) realloc(_confs, current_size * allDimSizeOfInt);
68 }
69 }
70
71 if(_masses != nullptr) _masses[_confs_no] = generator->mass();
72
73 if(_lprobs != nullptr) _lprobs[_confs_no] = generator->lprob();
74
75 if(_probs != nullptr) _probs[_confs_no] = generator->prob();
76
77 if(_confs != nullptr){
78 generator->get_conf_signature(_confs + confs_tbl_idx);
79 confs_tbl_idx += generator->getAllDim();
80 }
81
82 _confs_no++;
83 }
84
85 _masses = (double *) realloc(_masses, _confs_no * sizeof(double));
86 _lprobs = (double *) realloc(_lprobs, _confs_no * sizeof(double));
87 _probs = (double *) realloc(_probs, _confs_no * sizeof(double));
88 _confs = (int *) realloc(_confs, confs_tbl_idx * sizeof(int));
89 }
90
91 template <typename T> Tabulator<T>::~Tabulator()
92 {
93 if( _masses != nullptr ) free(_masses);
94 if( _lprobs != nullptr ) free(_lprobs);
95 if( _probs != nullptr ) free(_probs);
96 if( _confs != nullptr ) free(_confs);
97 }
98
99 } // namespace IsoSpec
100
0 #include "platform.h"
1
2 #if !ISOSPEC_BUILDING_R
3
4 #if !ISOSPEC_GOT_SYSTEM_MMAN && ISOSPEC_GOT_MMAN
5 #include "mman.c"
6 #endif
7
8 #include "allocator.cpp"
9 #include "dirtyAllocator.cpp"
10 #include "isoSpec++.cpp"
11 #include "isoMath.cpp"
12 #include "marginalTrek++.cpp"
13 #include "operators.cpp"
14 #include "element_tables.cpp"
15 #include "cwrapper.cpp"
16 #include "tabulator.cpp"
17 #include "misc.cpp"
18
19 #endif
0 context("Numerical stability")
1
2 test_that("IsoSpecR calculates correctly full isotopic distributions.", {
3 expect_equal(nrow(IsoSpecify(c(C=100, H=202), 1)), 101*203)
4 expect_equal(nrow(IsoSpecify(c(C=100, H=202, S=5), 1)), 101*203*choose(4+5-1, 5))
5 expect_equal(nrow(IsoSpecify(c(O=100, N=10, S=6), 1)), choose(100+3-1,100)*11*choose(4+6-1, 6))
6 })
7
8 test_that("IsoSpecR provides results similar to envipat.", {
9 load("envipat.Rd")
10 isospec = lapply(mols, IsoSpecify, stopCondition=1)
11 expect_equal(sapply(isospec, nrow), sapply(envipat, nrow))
12 isospec = lapply(mols, IsoSpecify, stopCondition=1)
13
14 for(i in 1:3){
15 envi_1_probs = envipat[[i]][,"abundance"] / sum(envipat[[i]][,"abundance"])
16 envi_1_probs = sort(envi_1_probs)
17 isos_1_probs = sort(exp(isospec[[i]][,2]))
18 expect_that(max(abs(isos_1_probs - envi_1_probs)) < 1.0e-10, is_true())
19 }
20 })
0 library(testthat)
1 library(IsoSpecR)
2
3 test_check("IsoSpecR")
0 IsoSpec is provided under the terms of 2-clause BSD licence.
1 If you require other licensing terms, please contact the authors.
2
3 We would appreciate if you let us know if you use this library in
4 your own software, but you are under no legal obligation to do so.
5
6
7 -------------------------------------------------------------------------
8
9
10 Copyright (c) 2015-2018, Micha³ Startek and Mateusz £±cki
11
12 All rights reserved.
13
14 Redistribution and use in source and binary forms, with or without
15 modification, are permitted provided that the following conditions are met:
16
17 1. Redistributions of source code must retain the above copyright notice, this
18 list of conditions and the following disclaimer.
19 2. Redistributions in binary form must reproduce the above copyright notice,
20 this list of conditions and the following disclaimer in the documentation
21 and/or other materials provided with the distribution.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
27 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34
0 IsoSpec, the isotopic fine structure calculator
1 ===============================================
2
3 The main purpose of this software package is to be used as a library,
4 mostly in mass spectrometry software. We do not provide any standalone
5 programs, except for those in Examples directory which are intended to
6 showcase the usage of the library.
7
8 Please see the code in Examples directory for example usage.
9
10 The software is publically available under a 2-clause BSD licence. If
11 you require other licensing terms, please contact the authors. See
12 LICENCE file for more details.
13
14 More details about the program may be found in the Analytical Chemistry
15 publication:
16
17 http://pubs.acs.org/doi/abs/10.1021/acs.analchem.6b01459
18
19 See especially the Supporting Information for details about the algorithm.
20
21
22
0 * Properly name the classes:
1 * conf -> subisotopologue
2 * iso -> molecule
3 * partialExpProbs -> partialProbs
4 * L... -> log_...
5
6 * Types:
7 * why get_isotopeNo is an int and not a signed int?
8 * the same with the subisotopologue configurations.
9
10
11 * general WTF:
12 * get_conf_signature ???
13 * IsoOrderedGenerator::candidate ???
14 * IsoOrderedGenerator::terminate_search ???
15 * IsoLayeredGenerator::advanceToNextConfiguration
16 * why does it print out things to the console???
17 * why is advanceToNextConfiguration_internal public, if it's called internal?
18 * it ain't used anywhere else beyond that class anyway.
19
Binary diff not shown
0 .TH "IsoSpec" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Classes"
9
10 .in +1c
11 .ti -1c
12 .RI "class \fBAllocator\fP"
13 .br
14 .ti -1c
15 .RI "class \fBConfEqual\fP"
16 .br
17 .ti -1c
18 .RI "class \fBConfOrder\fP"
19 .br
20 .ti -1c
21 .RI "class \fBConfOrderMarginal\fP"
22 .br
23 .ti -1c
24 .RI "class \fBConfOrderMarginalDescending\fP"
25 .br
26 .ti -1c
27 .RI "class \fBDirtyAllocator\fP"
28 .br
29 .ti -1c
30 .RI "class \fBIso\fP"
31 .br
32 .RI "The \fBIso\fP class for the calculation of the isotopic distribution\&. "
33 .ti -1c
34 .RI "class \fBIsoGenerator\fP"
35 .br
36 .RI "The generator of isotopologues\&. "
37 .ti -1c
38 .RI "class \fBIsoLayeredGenerator\fP"
39 .br
40 .RI "The class that represents isotopologues above a given joint probability value\&. "
41 .ti -1c
42 .RI "class \fBIsoOrderedGenerator\fP"
43 .br
44 .RI "The generator of isotopologues sorted by their probability of occurrence\&. "
45 .ti -1c
46 .RI "class \fBIsoThresholdGenerator\fP"
47 .br
48 .RI "The generator of isotopologues above a given threshold value\&. "
49 .ti -1c
50 .RI "class \fBKeyHasher\fP"
51 .br
52 .ti -1c
53 .RI "class \fBMarginal\fP"
54 .br
55 .RI "The marginal distribution class (a subisotopologue)\&. "
56 .ti -1c
57 .RI "class \fBMarginalTrek\fP"
58 .br
59 .RI "The marginal distribution class (a subisotopologue)\&. "
60 .ti -1c
61 .RI "class \fBOrderMarginalsBySizeDecresing\fP"
62 .br
63 .ti -1c
64 .RI "class \fBPrecalculatedMarginal\fP"
65 .br
66 .RI "Precalculated \fBMarginal\fP class\&. "
67 .ti -1c
68 .RI "class \fBReverseOrder\fP"
69 .br
70 .ti -1c
71 .RI "class \fBSSummator\fP"
72 .br
73 .ti -1c
74 .RI "class \fBSummator\fP"
75 .br
76 .ti -1c
77 .RI "class \fBTableOrder\fP"
78 .br
79 .ti -1c
80 .RI "class \fBTabulator\fP"
81 .br
82 .ti -1c
83 .RI "class \fBTSummator\fP"
84 .br
85 .in -1c
86 .SS "Typedefs"
87
88 .in +1c
89 .ti -1c
90 .RI "typedef int * \fBConf\fP"
91 .br
92 .in -1c
93 .SS "Functions"
94
95 .in +1c
96 .ti -1c
97 .RI "template<typename T > void \fBcopyConf\fP (const T *source, T *destination, int dim)"
98 .br
99 .ti -1c
100 .RI "void \fBrelease_g_lfact_table\fP ()"
101 .br
102 .ti -1c
103 .RI "double * \fBalloc_lfact_table\fP ()"
104 .br
105 .ti -1c
106 .RI "double \fBRationalApproximation\fP (double t)"
107 .br
108 .ti -1c
109 .RI "double \fBNormalCDFInverse\fP (double p)"
110 .br
111 .ti -1c
112 .RI "double \fBNormalCDFInverse\fP (double p, double mean, double stdev)"
113 .br
114 .ti -1c
115 .RI "double \fBNormalCDF\fP (double x, double mean, double stdev)"
116 .br
117 .ti -1c
118 .RI "double \fBNormalPDF\fP (double x, double mean, double stdev)"
119 .br
120 .ti -1c
121 .RI "unsigned int \fBparse_formula\fP (const char *formula, std::vector< const double *> &isotope_masses, std::vector< const double *> &isotope_probabilities, int **isotopeNumbers, int **atomCounts, unsigned int *confSize)"
122 .br
123 .ti -1c
124 .RI "void \fBprintConfigurations\fP (const std::tuple< double *, double *, int *, int > &results, int dimNumber, int *isotopeNumbers)"
125 .br
126 .ti -1c
127 .RI "Conf \fBinitialConfigure\fP (const int atomCnt, const int isotopeNo, const double *probs, const double *lprobs)"
128 .br
129 .RI "Find one of the most probable subisotopologues\&. "
130 .ti -1c
131 .RI "void \fBprintMarginal\fP (const std::tuple< double *, double *, int *, int > &results, int dim)"
132 .br
133 .ti -1c
134 .RI "double * \fBgetMLogProbs\fP (const double *probs, int isoNo)"
135 .br
136 .ti -1c
137 .RI "double \fBget_loggamma_nominator\fP (int x)"
138 .br
139 .ti -1c
140 .RI "Conf \fBinitialConfigure\fP (int atomCnt, int isotopeNo, const double *probs)"
141 .br
142 .ti -1c
143 .RI "void * \fBquickselect\fP (void **array, int n, int start, int end)"
144 .br
145 .RI "Quickly select the n'th positional statistic, including the weights\&. "
146 .ti -1c
147 .RI "double \fBcombinedSum\fP (const int *conf, const std::vector< double > **valuesContainer, int dimNumber)"
148 .br
149 .ti -1c
150 .RI "int * \fBgetConf\fP (void *conf)"
151 .br
152 .ti -1c
153 .RI "double \fBgetLProb\fP (void *conf)"
154 .br
155 .ti -1c
156 .RI "double \fBunnormalized_logProb\fP (const int *conf, const double *logProbs, int dim)"
157 .br
158 .ti -1c
159 .RI "double \fBmass\fP (const int *conf, const double *masses, int dim)"
160 .br
161 .ti -1c
162 .RI "bool \fBtupleCmp\fP (std::tuple< double, double, int *> t1, std::tuple< double, double, int *> t2)"
163 .br
164 .ti -1c
165 .RI "template<typename T > void \fBprintArray\fP (const T *array, int size)"
166 .br
167 .ti -1c
168 .RI "template<typename T > void \fBprintVector\fP (const std::vector< T > &vec)"
169 .br
170 .ti -1c
171 .RI "template<typename T > void \fBprintNestedArray\fP (const T **array, const int *shape, int size)"
172 .br
173 .ti -1c
174 .RI "template<typename T > void \fBdealloc_table\fP (T *tbl, int dim)"
175 .br
176 .ti -1c
177 .RI "void \fBreallocate\fP (double **array, int new_size)"
178 .br
179 .in -1c
180 .SS "Variables"
181
182 .in +1c
183 .ti -1c
184 .RI "const int \fBelem_table_atomicNo\fP [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]"
185 .br
186 .ti -1c
187 .RI "const double \fBelem_table_mass\fP [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]"
188 .br
189 .ti -1c
190 .RI "const int \fBelem_table_massNo\fP [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]"
191 .br
192 .ti -1c
193 .RI "const int \fBelem_table_extraNeutrons\fP [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]"
194 .br
195 .ti -1c
196 .RI "const char * \fBelem_table_element\fP [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]"
197 .br
198 .ti -1c
199 .RI "const char * \fBelem_table_symbol\fP [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]"
200 .br
201 .ti -1c
202 .RI "const bool \fBelem_table_Radioactive\fP [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]"
203 .br
204 .ti -1c
205 .RI "const double \fBelem_table_probability\fP [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]"
206 .br
207 .ti -1c
208 .RI "const double \fBelem_table_log_probability\fP [ISOSPEC_NUMBER_OF_ISOTOPIC_ENTRIES]"
209 .br
210 .ti -1c
211 .RI "const double \fBpi\fP = 3\&.14159265358979323846264338328"
212 .br
213 .ti -1c
214 .RI "double * \fBg_lfact_table\fP = alloc_lfact_table()"
215 .br
216 .in -1c
217 .SH "Detailed Description"
218 .PP
219 Copyright (C) 2015-2018 Mateusz Łącki and Michał Startek\&.
220 .PP
221 This file is part of \fBIsoSpec\fP\&.
222 .PP
223 \fBIsoSpec\fP is free software: you can redistribute it and/or modify it under the terms of the Simplified ('2-clause') BSD licence\&.
224 .PP
225 \fBIsoSpec\fP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE\&.
226 .PP
227 You should have received a copy of the Simplified BSD Licence along with \fBIsoSpec\fP\&. If not, see https://opensource.org/licenses/BSD-2-Clause\&.
228 .SH "Function Documentation"
229 .PP
230 .SS "double* IsoSpec::getMLogProbs (const double * probs, int isoNo)"
231
232 .br
233 Here we order the processor to round the numbers up rather than down\&. Rounding down could result in the algorithm falling in an infinite loop because of the numerical instability of summing\&.
234 .PP
235 Definition at line 150 of file marginalTrek++\&.cpp\&.
236 .SS "Conf IsoSpec::initialConfigure (const int atomCnt, const int isotopeNo, const double * probs, const double * lprobs)"
237
238 .PP
239 Find one of the most probable subisotopologues\&. The algorithm uses the hill-climbing algorithm\&. It starts from a subisotopologue close to the mean of the underlying multinomial distribution\&. There might be more than one modes, in case of which this function will return only one of them, close to the mean\&.
240 .PP
241 \fBParameters:\fP
242 .RS 4
243 \fIatomCnt\fP
244 .RE
245 .PP
246
247 .br
248 Here we perform hill climbing to the mode of the marginal distribution (the subisotopologue distribution)\&. We start from the point close to the mean of the underlying multinomial distribution\&.
249 .PP
250 Definition at line 55 of file marginalTrek++\&.cpp\&.
251 .SH "Author"
252 .PP
253 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::Allocator< T >" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::Allocator< T >
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "\fBAllocator\fP (const int dim, const int tabSize=10000)"
13 .br
14 .ti -1c
15 .RI "void \fBshiftTables\fP ()"
16 .br
17 .ti -1c
18 .RI "T * \fBnewConf\fP ()"
19 .br
20 .ti -1c
21 .RI "T * \fBmakeCopy\fP (const T *conf)"
22 .br
23 .ti -1c
24 .RI "T * \fBmakeExternalCopy\fP (const T *conf)"
25 .br
26 .in -1c
27 .SH "Detailed Description"
28 .PP
29
30 .SS "template<typename T>
31 .br
32 class IsoSpec::Allocator< T >"
33
34 .PP
35 Definition at line 34 of file allocator\&.h\&.
36
37 .SH "Author"
38 .PP
39 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::ConfEqual" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::ConfEqual
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "\fBConfEqual\fP (int dim)"
13 .br
14 .ti -1c
15 .RI "bool \fBoperator()\fP (const int *conf1, const int *conf2) const"
16 .br
17 .in -1c
18 .SH "Detailed Description"
19 .PP
20 Definition at line 45 of file operators\&.h\&.
21
22 .SH "Author"
23 .PP
24 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::ConfOrder" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::ConfOrder
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "bool \fBoperator()\fP (void *conf1, void *conf2) const"
13 .br
14 .in -1c
15 .SH "Detailed Description"
16 .PP
17 Definition at line 66 of file operators\&.h\&.
18
19 .SH "Author"
20 .PP
21 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::ConfOrderMarginal" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::ConfOrderMarginal
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "\fBConfOrderMarginal\fP (const double *logProbs, int dim)"
13 .br
14 .ti -1c
15 .RI "bool \fBoperator()\fP (const Conf conf1, const Conf conf2)"
16 .br
17 .in -1c
18 .SH "Detailed Description"
19 .PP
20 Definition at line 78 of file operators\&.h\&.
21
22 .SH "Author"
23 .PP
24 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::ConfOrderMarginalDescending" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::ConfOrderMarginalDescending
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "\fBConfOrderMarginalDescending\fP (const double *logProbs, int dim)"
13 .br
14 .ti -1c
15 .RI "bool \fBoperator()\fP (const Conf conf1, const Conf conf2)"
16 .br
17 .in -1c
18 .SH "Detailed Description"
19 .PP
20 Definition at line 92 of file operators\&.h\&.
21
22 .SH "Author"
23 .PP
24 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::DirtyAllocator" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::DirtyAllocator
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "\fBDirtyAllocator\fP (const int dim, const int tabSize=10000)"
13 .br
14 .ti -1c
15 .RI "void \fBshiftTables\fP ()"
16 .br
17 .ti -1c
18 .RI "void * \fBnewConf\fP ()"
19 .br
20 .ti -1c
21 .RI "void * \fBmakeCopy\fP (const void *conf)"
22 .br
23 .ti -1c
24 .RI "void * \fBmakeExternalCopy\fP (const void *conf)"
25 .br
26 .in -1c
27 .SH "Detailed Description"
28 .PP
29 Definition at line 26 of file dirtyAllocator\&.h\&.
30
31 .SH "Author"
32 .PP
33 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::Iso" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::Iso \- The \fBIso\fP class for the calculation of the isotopic distribution\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .PP
10 \fC#include <isoSpec++\&.h>\fP
11 .PP
12 Inherited by \fBIsoSpec::IsoGenerator\fP\&.
13 .SS "Public Member Functions"
14
15 .in +1c
16 .ti -1c
17 .RI "\fBIso\fP (int _dimNumber, const int *_isotopeNumbers, const int *_atomCounts, const double *const *_isotopeMasses, const double *const *_isotopeProbabilities)"
18 .br
19 .RI "General constructror\&. "
20 .ti -1c
21 .RI "\fBIso\fP (const char *formula)"
22 .br
23 .RI "Constructor from the formula object\&. "
24 .ti -1c
25 .RI "\fBIso\fP (\fBIso\fP &&other)"
26 .br
27 .RI "The move constructor\&. "
28 .ti -1c
29 .RI "\fBIso\fP (const \fBIso\fP &other, bool fullcopy)"
30 .br
31 .RI "The copy constructor\&. "
32 .ti -1c
33 .RI "virtual \fB~Iso\fP ()"
34 .br
35 .RI "Destructor\&. "
36 .ti -1c
37 .RI "double \fBgetLightestPeakMass\fP () const"
38 .br
39 .RI "Get the mass of the lightest peak in the isotopic distribution\&. "
40 .ti -1c
41 .RI "double \fBgetHeaviestPeakMass\fP () const"
42 .br
43 .RI "Get the mass of the heaviest peak in the isotopic distribution\&. "
44 .ti -1c
45 .RI "double \fBgetModeLProb\fP () const"
46 .br
47 .RI "Get the log-probability of the mode-configuration (if there are many modes, they share this value)\&. "
48 .ti -1c
49 .RI "int \fBgetDimNumber\fP () const"
50 .br
51 .RI "Get the number of elements in the chemical formula of the molecule\&. "
52 .ti -1c
53 .RI "int \fBgetAllDim\fP () const"
54 .br
55 .RI "Get the total number of isotopes of elements present in a chemical formula\&. "
56 .in -1c
57 .SS "Public Attributes"
58
59 .in +1c
60 .ti -1c
61 .RI "bool \fBdisowned\fP"
62 .br
63 .in -1c
64 .SS "Protected Attributes"
65
66 .in +1c
67 .ti -1c
68 .RI "int \fBdimNumber\fP"
69 .br
70 .ti -1c
71 .RI "int * \fBisotopeNumbers\fP"
72 .br
73 .ti -1c
74 .RI "int * \fBatomCounts\fP"
75 .br
76 .ti -1c
77 .RI "unsigned int \fBconfSize\fP"
78 .br
79 .ti -1c
80 .RI "int \fBallDim\fP"
81 .br
82 .ti -1c
83 .RI "\fBMarginal\fP ** \fBmarginals\fP"
84 .br
85 .ti -1c
86 .RI "double \fBmodeLProb\fP"
87 .br
88 .in -1c
89 .SH "Detailed Description"
90 .PP
91 The \fBIso\fP class for the calculation of the isotopic distribution\&.
92
93 It contains full description of the molecule for which one would like to calculate the isotopic distribution\&.
94 .PP
95 Definition at line 52 of file isoSpec++\&.h\&.
96 .SH "Constructor & Destructor Documentation"
97 .PP
98 .SS "IsoSpec::Iso::Iso (int _dimNumber, const int * _isotopeNumbers, const int * _atomCounts, const double *const * _isotopeMasses, const double *const * _isotopeProbabilities)"
99
100 .PP
101 General constructror\&.
102 .PP
103 \fBParameters:\fP
104 .RS 4
105 \fI_dimNumber\fP The number of elements in the formula, e\&.g\&. for C100H202 it would be 2, as there are only carbon and hydrogen atoms\&.
106 .br
107 \fI_isotopeNumbers\fP A table with numbers of isotopes for each element, e\&.g\&. for C100H202 it would be {2, 2}, because both C and H have two stable isotopes\&.
108 .br
109 \fI_atomCounts\fP Number of atoms of each element in the formula, e\&.g\&. for C100H202 corresponds to {100, 202}\&.
110 .br
111 \fI_isotopeMasses\fP A table of masses of isotopes of the elements in the chemical formula, e\&.g\&. {12\&.0, 13\&.003355, 1\&.007825, 2\&.014102} for C100H202\&.
112 .br
113 \fI_isotopeProbabilities\fP A table of isotope frequencies of the elements in the chemical formula, e\&.g\&. {\&.989212, \&.010788, \&.999885, \&.000115} for C100H202\&.
114 .RE
115 .PP
116
117 .PP
118 Definition at line 51 of file isoSpec++\&.cpp\&.
119 .SS "IsoSpec::Iso::Iso (const \fBIso\fP & other, bool fullcopy)"
120
121 .PP
122 The copy constructor\&.
123 .PP
124 \fBParameters:\fP
125 .RS 4
126 \fIother\fP The other instance of the \fBIso\fP class\&.
127 .br
128 \fIfullcopy\fP If false, copy only the number of atoms in the formula, the size of the configuration, the total number of isotopes, and the probability of the mode isotopologue\&.
129 .RE
130 .PP
131
132 .PP
133 Definition at line 84 of file isoSpec++\&.cpp\&.
134 .SH "Member Data Documentation"
135 .PP
136 .SS "int IsoSpec::Iso::allDim\fC [protected]\fP"
137 The total number of isotopes of elements present in a chemical formula, e\&.g\&. for H20 it is 2+3=5\&.
138 .PP
139 Definition at line 71 of file isoSpec++\&.h\&.
140 .SS "int* IsoSpec::Iso::atomCounts\fC [protected]\fP"
141 A table with numbers of isotopes for each element\&.
142 .PP
143 Definition at line 69 of file isoSpec++\&.h\&.
144 .SS "unsigned int IsoSpec::Iso::confSize\fC [protected]\fP"
145 The number of bytes needed to represent the counts of isotopes present in the extended chemical formula\&.
146 .PP
147 Definition at line 70 of file isoSpec++\&.h\&.
148 .SS "int IsoSpec::Iso::dimNumber\fC [protected]\fP"
149 The number of elements in the chemical formula of the molecule\&.
150 .PP
151 Definition at line 67 of file isoSpec++\&.h\&.
152 .SS "bool IsoSpec::Iso::disowned"
153 A variable showing if the \fBIso\fP class was specialized by its child-class\&. If so, then the description of the molecules has been transfered there and \fBIso\fP is a carcass class, dead as a dodo, an ex-class if you will\&.
154 .PP
155 Definition at line 65 of file isoSpec++\&.h\&.
156 .SS "int* IsoSpec::Iso::isotopeNumbers\fC [protected]\fP"
157 A table with numbers of isotopes for each element\&.
158 .PP
159 Definition at line 68 of file isoSpec++\&.h\&.
160 .SS "\fBMarginal\fP** IsoSpec::Iso::marginals\fC [protected]\fP"
161 The table of pointers to the distributions of individual subisotopologues\&.
162 .PP
163 Definition at line 72 of file isoSpec++\&.h\&.
164 .SS "double IsoSpec::Iso::modeLProb\fC [protected]\fP"
165 The log-probability of the mode of the isotopic distribution\&.
166 .PP
167 Definition at line 73 of file isoSpec++\&.h\&.
168
169 .SH "Author"
170 .PP
171 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::IsoGenerator" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::IsoGenerator \- The generator of isotopologues\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .PP
10 \fC#include <isoSpec++\&.h>\fP
11 .PP
12 Inherits \fBIsoSpec::Iso\fP\&.
13 .PP
14 Inherited by \fBIsoSpec::IsoLayeredGenerator\fP, \fBIsoSpec::IsoOrderedGenerator\fP, and \fBIsoSpec::IsoThresholdGenerator\fP\&.
15 .SS "Public Member Functions"
16
17 .in +1c
18 .ti -1c
19 .RI "virtual bool \fBadvanceToNextConfiguration\fP ()=0"
20 .br
21 .RI "Advance to the next, not yet visited, most probable isotopologue\&. "
22 .ti -1c
23 .RI "virtual double \fBlprob\fP () const"
24 .br
25 .RI "Get the log-probability of the current isotopologue\&. "
26 .ti -1c
27 .RI "virtual double \fBmass\fP () const"
28 .br
29 .RI "Get the mass of the current isotopologue\&. "
30 .ti -1c
31 .RI "virtual double \fBprob\fP () const"
32 .br
33 .RI "Get the probability of the current isotopologue\&. "
34 .ti -1c
35 .RI "virtual void \fBget_conf_signature\fP (int *space) const =0"
36 .br
37 .ti -1c
38 .RI "\fBIsoGenerator\fP (\fBIso\fP &&iso, bool alloc_partials=true)"
39 .br
40 .RI "Move constructor\&. "
41 .ti -1c
42 .RI "virtual \fB~IsoGenerator\fP ()"
43 .br
44 .RI "Destructor\&. "
45 .in -1c
46 .SS "Protected Attributes"
47
48 .in +1c
49 .ti -1c
50 .RI "double * \fBpartialLProbs\fP"
51 .br
52 .ti -1c
53 .RI "double * \fBpartialMasses\fP"
54 .br
55 .ti -1c
56 .RI "double * \fBpartialProbs\fP"
57 .br
58 .in -1c
59 .SS "Additional Inherited Members"
60 .SH "Detailed Description"
61 .PP
62 The generator of isotopologues\&.
63
64 This class provides the common interface for all isotopic generators\&.
65 .PP
66 Definition at line 129 of file isoSpec++\&.h\&.
67 .SH "Member Function Documentation"
68 .PP
69 .SS "virtual bool IsoSpec::IsoGenerator::advanceToNextConfiguration ()\fC [pure virtual]\fP"
70
71 .PP
72 Advance to the next, not yet visited, most probable isotopologue\&.
73 .PP
74 \fBReturns:\fP
75 .RS 4
76 Return false if it is not possible to advance\&.
77 .RE
78 .PP
79
80 .PP
81 Implemented in \fBIsoSpec::IsoLayeredGenerator\fP, \fBIsoSpec::IsoThresholdGenerator\fP, and \fBIsoSpec::IsoOrderedGenerator\fP\&.
82 .SS "virtual double IsoSpec::IsoGenerator::lprob () const\fC [inline]\fP, \fC [virtual]\fP"
83
84 .PP
85 Get the log-probability of the current isotopologue\&.
86 .PP
87 \fBReturns:\fP
88 .RS 4
89 The log-probability of the current isotopologue\&.
90 .RE
91 .PP
92
93 .PP
94 Reimplemented in \fBIsoSpec::IsoThresholdGenerator\fP\&.
95 .PP
96 Definition at line 147 of file isoSpec++\&.h\&.
97 .SS "virtual double IsoSpec::IsoGenerator::mass () const\fC [inline]\fP, \fC [virtual]\fP"
98
99 .PP
100 Get the mass of the current isotopologue\&.
101 .PP
102 \fBReturns:\fP
103 .RS 4
104 The mass of the current isotopologue\&.
105 .RE
106 .PP
107
108 .PP
109 Reimplemented in \fBIsoSpec::IsoThresholdGenerator\fP\&.
110 .PP
111 Definition at line 153 of file isoSpec++\&.h\&.
112 .SS "virtual double IsoSpec::IsoGenerator::prob () const\fC [inline]\fP, \fC [virtual]\fP"
113
114 .PP
115 Get the probability of the current isotopologue\&.
116 .PP
117 \fBReturns:\fP
118 .RS 4
119 The probability of the current isotopologue\&.
120 .RE
121 .PP
122
123 .PP
124 Reimplemented in \fBIsoSpec::IsoThresholdGenerator\fP\&.
125 .PP
126 Definition at line 159 of file isoSpec++\&.h\&.
127 .SH "Member Data Documentation"
128 .PP
129 .SS "double* IsoSpec::IsoGenerator::partialLProbs\fC [protected]\fP"
130 The prefix sum of the log-probabilities of the current isotopologue\&.
131 .PP
132 Definition at line 132 of file isoSpec++\&.h\&.
133 .SS "double* IsoSpec::IsoGenerator::partialMasses\fC [protected]\fP"
134 The prefix sum of the masses of the current isotopologue\&.
135 .PP
136 Definition at line 133 of file isoSpec++\&.h\&.
137 .SS "double* IsoSpec::IsoGenerator::partialProbs\fC [protected]\fP"
138 The prefix product of the probabilities of the current isotopologue\&.
139 .PP
140 Definition at line 134 of file isoSpec++\&.h\&.
141
142 .SH "Author"
143 .PP
144 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::IsoLayeredGenerator" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::IsoLayeredGenerator \- The class that represents isotopologues above a given joint probability value\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .PP
10 \fC#include <isoSpec++\&.h>\fP
11 .PP
12 Inherits \fBIsoSpec::IsoGenerator\fP\&.
13 .SS "Public Member Functions"
14
15 .in +1c
16 .ti -1c
17 .RI "bool \fBadvanceToNextConfiguration\fP () override final"
18 .br
19 .RI "Advance to the next, not yet visited, most probable isotopologue\&. "
20 .ti -1c
21 .RI "void \fBget_conf_signature\fP (int *space) const override final"
22 .br
23 .ti -1c
24 .RI "\fBIsoLayeredGenerator\fP (\fBIso\fP &&iso, double _targetCoverage, double _percentageToExpand, int _tabSize=1000, int _hashSize=1000, bool trim=false)"
25 .br
26 .ti -1c
27 .RI "void \fBterminate_search\fP ()"
28 .br
29 .in -1c
30 .SS "Additional Inherited Members"
31 .SH "Detailed Description"
32 .PP
33 The class that represents isotopologues above a given joint probability value\&.
34
35 This class generates subsequent isotopologues that ARE NOT GUARANTEED TO BE ORDERED BY probability\&. The overal set of isotopologues is guaranteed to surpass a given threshold of probability contained in the isotopic distribution\&. This calculations are performed in O(N) operations, where N is the total number of the output isotopologues\&.
36 .PP
37 This class is not a true generator yet - the generator methods have been implemented for compatibility, but the class actually performs all computations during the initialization and stores them, and the generator methods only walk through the array of precomputed values\&. \&. It will be reimplemented as a true generator in 2\&.0\&.
38 .PP
39 Definition at line 383 of file isoSpec++\&.h\&.
40 .SH "Member Function Documentation"
41 .PP
42 .SS "bool IsoSpec::IsoLayeredGenerator::advanceToNextConfiguration ()\fC [final]\fP, \fC [override]\fP, \fC [virtual]\fP"
43
44 .PP
45 Advance to the next, not yet visited, most probable isotopologue\&.
46 .PP
47 \fBReturns:\fP
48 .RS 4
49 Return false if it is not possible to advance\&.
50 .RE
51 .PP
52
53 .PP
54 Implements \fBIsoSpec::IsoGenerator\fP\&.
55 .PP
56 Definition at line 773 of file isoSpec++\&.cpp\&.
57
58 .SH "Author"
59 .PP
60 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::IsoOrderedGenerator" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::IsoOrderedGenerator \- The generator of isotopologues sorted by their probability of occurrence\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .PP
10 \fC#include <isoSpec++\&.h>\fP
11 .PP
12 Inherits \fBIsoSpec::IsoGenerator\fP\&.
13 .SS "Public Member Functions"
14
15 .in +1c
16 .ti -1c
17 .RI "bool \fBadvanceToNextConfiguration\fP () override final"
18 .br
19 .RI "Advance to the next, not yet visited, most probable isotopologue\&. "
20 .ti -1c
21 .RI "void \fBget_conf_signature\fP (int *space) const override final"
22 .br
23 .RI "Save the counts of isotopes in the space\&. "
24 .ti -1c
25 .RI "\fBIsoOrderedGenerator\fP (\fBIso\fP &&iso, int _tabSize=1000, int _hashSize=1000)"
26 .br
27 .RI "The move-contstructor\&. "
28 .ti -1c
29 .RI "virtual \fB~IsoOrderedGenerator\fP ()"
30 .br
31 .RI "Destructor\&. "
32 .in -1c
33 .SS "Additional Inherited Members"
34 .SH "Detailed Description"
35 .PP
36 The generator of isotopologues sorted by their probability of occurrence\&.
37
38 The subsequent isotopologues are generated with diminishing probability, starting from the mode\&. This algorithm take O(N*log(N)) to compute the N isotopologues because of using the Priority Queue data structure\&. Obtaining the N isotopologues can be achieved in O(N) if they are not required to be spit out in the descending order\&.
39 .PP
40 Definition at line 179 of file isoSpec++\&.h\&.
41 .SH "Member Function Documentation"
42 .PP
43 .SS "bool IsoSpec::IsoOrderedGenerator::advanceToNextConfiguration ()\fC [final]\fP, \fC [override]\fP, \fC [virtual]\fP"
44
45 .PP
46 Advance to the next, not yet visited, most probable isotopologue\&.
47 .PP
48 \fBReturns:\fP
49 .RS 4
50 Return false if it is not possible to advance\&.
51 .RE
52 .PP
53
54 .PP
55 Implements \fBIsoSpec::IsoGenerator\fP\&.
56 .PP
57 Definition at line 461 of file isoSpec++\&.cpp\&.
58 .SS "void IsoSpec::IsoOrderedGenerator::get_conf_signature (int * space) const\fC [inline]\fP, \fC [final]\fP, \fC [override]\fP, \fC [virtual]\fP"
59
60 .PP
61 Save the counts of isotopes in the space\&.
62 .PP
63 \fBParameters:\fP
64 .RS 4
65 \fIspace\fP An array where counts of isotopes shall be written\&. Must be as big as the overall number of isotopes\&.
66 .RE
67 .PP
68
69 .PP
70 Implements \fBIsoSpec::IsoGenerator\fP\&.
71 .PP
72 Definition at line 202 of file isoSpec++\&.h\&.
73
74 .SH "Author"
75 .PP
76 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::IsoSpec::ConfEqual" 3 "Thu Oct 11 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::IsoSpec::ConfEqual \- The equality of configurations operator\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .SS "Public Member Functions"
10
11 .in +1c
12 .ti -1c
13 .RI "\fBConfEqual\fP (int dim)"
14 .br
15 .RI "Constructor\&. "
16 .ti -1c
17 .RI "bool \fBoperator()\fP (const int *conf1, const int *conf2) const"
18 .br
19 .RI "The \fBcall\fP operator\&. "
20 .in -1c
21 .SH "Detailed Description"
22 .PP
23 The equality of configurations operator\&.
24
25 Needed for the unordered-map\&.
26 .PP
27 Definition at line 62 of file operators\&.cpp\&.
28 .SH "Constructor & Destructor Documentation"
29 .PP
30 .SS "IsoSpec::ConfEqual::ConfEqual (int dim)"
31
32 .PP
33 Constructor\&.
34 .PP
35 \fBParameters:\fP
36 .RS 4
37 \fIdim\fP the number of the ints that make up a configuration\&.
38 .RE
39 .PP
40
41 .PP
42 Definition at line 26 of file operators\&.cpp\&.
43 .SH "Member Function Documentation"
44 .PP
45 .SS "bool IsoSpec::IsoSpec::ConfEqual::operator() (const int * conf1, const int * conf2) const\fC [inline]\fP"
46
47 .PP
48 The \fBcall\fP operator\&. Let us quote the sacred MAN of memcmp: "The memcmp() function returns zero if the two strings are identical, otherwise returns the difference between the first two differing bytes (treated as unsigned char values, so that `\\200' is greater than `\\0', for example)\&. Zero-length strings are always identical\&. This behavior is not required by C and portable code should only depend on the sign of the returned value\&."
49 .PP
50 \fBParameters:\fP
51 .RS 4
52 \fIconf1\fP An array of integer counts\&.
53 .br
54 \fIconf2\fP An array of integer counts\&.
55 .RE
56 .PP
57 \fBReturns:\fP
58 .RS 4
59 Are conf1 and conf2 the same configuration?
60 .RE
61 .PP
62
63 .PP
64 Definition at line 87 of file operators\&.cpp\&.
65
66 .SH "Author"
67 .PP
68 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::IsoSpec::ConfOrder" 3 "Thu Oct 11 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::IsoSpec::ConfOrder \- The class used for comparing the position of configurations in the order of descending probabilities\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .SS "Public Member Functions"
10
11 .in +1c
12 .ti -1c
13 .RI "bool \fBoperator()\fP (void *conf1, void *conf2) const"
14 .br
15 .in -1c
16 .SH "Detailed Description"
17 .PP
18 The class used for comparing the position of configurations in the order of descending probabilities\&.
19
20 Needed for the priority queue\&.
21 .PP
22 Definition at line 98 of file operators\&.cpp\&.
23
24 .SH "Author"
25 .PP
26 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::IsoSpec::ConfOrderMarginal" 3 "Thu Oct 11 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::IsoSpec::ConfOrderMarginal \- The class used for comparing the position of subisotopologues in the order of descending probabilities\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .SS "Public Member Functions"
10
11 .in +1c
12 .ti -1c
13 .RI "\fBConfOrderMarginal\fP (const double *logProbs, int dim)"
14 .br
15 .RI "Constructor\&. "
16 .ti -1c
17 .RI "bool \fBoperator()\fP (const Conf conf1, const Conf conf2)"
18 .br
19 .RI "Constructor\&. "
20 .in -1c
21 .SH "Detailed Description"
22 .PP
23 The class used for comparing the position of subisotopologues in the order of descending probabilities\&.
24
25 Needed for the priority queue\&.
26 .PP
27 Definition at line 112 of file operators\&.cpp\&.
28 .SH "Constructor & Destructor Documentation"
29 .PP
30 .SS "IsoSpec::ConfOrderMarginal::ConfOrderMarginal (const double * logProbs, int dim)"
31
32 .PP
33 Constructor\&.
34 .PP
35 \fBParameters:\fP
36 .RS 4
37 \fIlogProbs\fP
38 .br
39 \fIdim\fP The number of isotopes\&.
40 .RE
41 .PP
42
43 .PP
44 Definition at line 30 of file operators\&.cpp\&.
45 .SH "Member Function Documentation"
46 .PP
47 .SS "bool IsoSpec::IsoSpec::ConfOrderMarginal::operator() (const Conf conf1, const Conf conf2)\fC [inline]\fP"
48
49 .PP
50 Constructor\&.
51 .PP
52 \fBParameters:\fP
53 .RS 4
54 \fIconf1\fP An array of integer counts\&.
55 .br
56 \fIconf2\fP An array of integer counts\&.
57 .RE
58 .PP
59 \fBReturns:\fP
60 .RS 4
61 True if conf1 is less probable than conf2\&.
62 .RE
63 .PP
64
65 .PP
66 Definition at line 130 of file operators\&.cpp\&.
67
68 .SH "Author"
69 .PP
70 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::IsoSpec::ConfOrderMarginalDescending" 3 "Thu Oct 11 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::IsoSpec::ConfOrderMarginalDescending \- The class used for comparing the position of subisotopologues in the order of descending probabilities\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .SS "Public Member Functions"
10
11 .in +1c
12 .ti -1c
13 .RI "\fBConfOrderMarginalDescending\fP (const double *logProbs, int dim)"
14 .br
15 .RI "Contstructor\&. "
16 .ti -1c
17 .RI "bool \fBoperator()\fP (const Conf conf1, const Conf conf2)"
18 .br
19 .RI "Constructor\&. "
20 .in -1c
21 .SH "Detailed Description"
22 .PP
23 The class used for comparing the position of subisotopologues in the order of descending probabilities\&.
24
25 Needed for the priority queue\&.
26 .PP
27 Definition at line 141 of file operators\&.cpp\&.
28 .SH "Constructor & Destructor Documentation"
29 .PP
30 .SS "IsoSpec::ConfOrderMarginalDescending::ConfOrderMarginalDescending (const double * logProbs, int dim)"
31
32 .PP
33 Contstructor\&.
34 .PP
35 \fBParameters:\fP
36 .RS 4
37 \fIlogProbs\fP
38 .br
39 \fIdim\fP The number of isotopes\&.
40 .RE
41 .PP
42
43 .PP
44 Definition at line 34 of file operators\&.cpp\&.
45 .SH "Member Function Documentation"
46 .PP
47 .SS "bool IsoSpec::IsoSpec::ConfOrderMarginalDescending::operator() (const Conf conf1, const Conf conf2)\fC [inline]\fP"
48
49 .PP
50 Constructor\&.
51 .PP
52 \fBParameters:\fP
53 .RS 4
54 \fIconf1\fP An array of integer counts\&.
55 .br
56 \fIconf2\fP An array of integer counts\&.
57 .RE
58 .PP
59 \fBReturns:\fP
60 .RS 4
61 True if conf1 is more probable than conf2\&.
62 .RE
63 .PP
64
65 .PP
66 Definition at line 160 of file operators\&.cpp\&.
67
68 .SH "Author"
69 .PP
70 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::IsoSpec::KeyHasher" 3 "Thu Oct 11 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::IsoSpec::KeyHasher \- The hash function class\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .SS "Public Member Functions"
10
11 .in +1c
12 .ti -1c
13 .RI "\fBKeyHasher\fP (int dim)"
14 .br
15 .RI "Constructor\&. "
16 .ti -1c
17 .RI "std::size_t \fBoperator()\fP (const int *conf) const"
18 .br
19 .RI "The \fBcall\fP operator\&. "
20 .in -1c
21 .SH "Detailed Description"
22 .PP
23 The hash function class\&.
24
25 Needed for the unordered-map\&.
26 .PP
27 Definition at line 31 of file operators\&.cpp\&.
28 .SH "Constructor & Destructor Documentation"
29 .PP
30 .SS "IsoSpec::KeyHasher::KeyHasher (int dim)"
31
32 .PP
33 Constructor\&.
34 .PP
35 \fBParameters:\fP
36 .RS 4
37 \fIdim\fP the number of the ints that make up a configuration\&.
38 .RE
39 .PP
40
41 .PP
42 Definition at line 22 of file operators\&.cpp\&.
43 .SH "Member Function Documentation"
44 .PP
45 .SS "std::size_t IsoSpec::IsoSpec::KeyHasher::operator() (const int * conf) const\fC [inline]\fP"
46
47 .PP
48 The \fBcall\fP operator\&.
49 .PP
50 \fBParameters:\fP
51 .RS 4
52 \fIconf\fP An array of integer counts\&.
53 .RE
54 .PP
55 \fBReturns:\fP
56 .RS 4
57 The hash for counts\&.
58 .RE
59 .PP
60
61 .PP
62 Definition at line 47 of file operators\&.cpp\&.
63
64 .SH "Author"
65 .PP
66 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::IsoSpec::ReverseOrder< T >" 3 "Thu Oct 11 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::IsoSpec::ReverseOrder< T >
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "bool \fBoperator()\fP (const T a, const T b) const"
13 .br
14 .in -1c
15 .SH "Detailed Description"
16 .PP
17
18 .SS "template<typename T>
19 .br
20 class IsoSpec::IsoSpec::ReverseOrder< T >"
21
22 .PP
23 Definition at line 167 of file operators\&.cpp\&.
24
25 .SH "Author"
26 .PP
27 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::IsoSpec::TableOrder< T >" 3 "Thu Oct 11 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::IsoSpec::TableOrder< T >
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "\fBTableOrder\fP (const T *_tbl)"
13 .br
14 .ti -1c
15 .RI "bool \fBoperator()\fP (unsigned int i, unsigned int j)"
16 .br
17 .in -1c
18 .SH "Detailed Description"
19 .PP
20
21 .SS "template<typename T>
22 .br
23 class IsoSpec::IsoSpec::TableOrder< T >"
24
25 .PP
26 Definition at line 174 of file operators\&.cpp\&.
27
28 .SH "Author"
29 .PP
30 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::IsoThresholdGenerator" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::IsoThresholdGenerator \- The generator of isotopologues above a given threshold value\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .PP
10 \fC#include <isoSpec++\&.h>\fP
11 .PP
12 Inherits \fBIsoSpec::IsoGenerator\fP\&.
13 .SS "Public Member Functions"
14
15 .in +1c
16 .ti -1c
17 .RI "void \fBget_conf_signature\fP (int *space) const override final"
18 .br
19 .ti -1c
20 .RI "\fBIsoThresholdGenerator\fP (\fBIso\fP &&iso, double _threshold, bool _absolute=true, int _tabSize=1000, int _hashSize=1000, bool reorder_marginals=true)"
21 .br
22 .RI "The move-constructor\&. "
23 .ti -1c
24 .RI "ISOSPEC_FORCE_INLINE bool \fBadvanceToNextConfiguration\fP () override final"
25 .br
26 .RI "Advance to the next, not yet visited, most probable isotopologue\&. "
27 .ti -1c
28 .RI "ISOSPEC_FORCE_INLINE double \fBlprob\fP () const override final"
29 .br
30 .RI "Get the log-probability of the current isotopologue\&. "
31 .ti -1c
32 .RI "ISOSPEC_FORCE_INLINE double \fBmass\fP () const override final"
33 .br
34 .RI "Get the mass of the current isotopologue\&. "
35 .ti -1c
36 .RI "ISOSPEC_FORCE_INLINE double \fBprob\fP () const override final"
37 .br
38 .RI "Get the probability of the current isotopologue\&. "
39 .ti -1c
40 .RI "void \fBterminate_search\fP ()"
41 .br
42 .RI "Block the subsequent search of isotopologues\&. "
43 .ti -1c
44 .RI "void \fBreset\fP ()"
45 .br
46 .ti -1c
47 .RI "size_t \fBcount_confs\fP ()"
48 .br
49 .in -1c
50 .SS "Additional Inherited Members"
51 .SH "Detailed Description"
52 .PP
53 The generator of isotopologues above a given threshold value\&.
54
55 Attention: the calculated configurations are only partially ordeded and the user should not assume they will be ordered\&. This algorithm computes N isotopologues in O(N)\&. It is a considerable advantage w\&.r\&.t\&. the \fBIsoOrderedGenerator\fP\&.
56 .PP
57 Definition at line 235 of file isoSpec++\&.h\&.
58 .SH "Constructor & Destructor Documentation"
59 .PP
60 .SS "IsoSpec::IsoThresholdGenerator::IsoThresholdGenerator (\fBIso\fP && iso, double _threshold, bool _absolute = \fCtrue\fP, int _tabSize = \fC1000\fP, int _hashSize = \fC1000\fP, bool reorder_marginals = \fCtrue\fP)"
61
62 .PP
63 The move-constructor\&.
64 .PP
65 \fBParameters:\fP
66 .RS 4
67 \fIiso\fP An instance of the \fBIso\fP class\&.
68 .br
69 \fI_threshold\fP The threshold value\&.
70 .br
71 \fI_absolute\fP If true, the _threshold is interpreted as the absolute minimal peak height for the isotopologues\&. If false, the _threshold is the fraction of the heighest peak's probability\&.
72 .br
73 \fItabSize\fP The size of the extension of the table with configurations\&.
74 .br
75 \fIhashSize\fP The size of the hash-table used to store subisotopologues and check if they have been already calculated\&.
76 .RE
77 .PP
78
79 .PP
80 Definition at line 286 of file isoSpec++\&.cpp\&.
81 .SH "Member Function Documentation"
82 .PP
83 .SS "ISOSPEC_FORCE_INLINE bool IsoSpec::IsoThresholdGenerator::advanceToNextConfiguration ()\fC [inline]\fP, \fC [final]\fP, \fC [override]\fP, \fC [virtual]\fP"
84
85 .PP
86 Advance to the next, not yet visited, most probable isotopologue\&.
87 .PP
88 \fBReturns:\fP
89 .RS 4
90 Return false if it is not possible to advance\&.
91 .RE
92 .PP
93
94 .PP
95 Implements \fBIsoSpec::IsoGenerator\fP\&.
96 .PP
97 Definition at line 296 of file isoSpec++\&.h\&.
98 .SS "size_t IsoSpec::IsoThresholdGenerator::count_confs ()"
99 Count the number of configurations in the distribution\&. This can be used to pre-allocate enough memory to store it (e\&.g\&. std::vector's reserve() method - this is faster than depending on the vector's dynamic resizing, even though it means that the configuration space is walked through twice\&. This method has to be called before the first call to advanceToNextConfiguration and has undefined results (incl\&. segfaults) otherwise\&.
100 .PP
101 Definition at line 376 of file isoSpec++\&.cpp\&.
102 .SS "ISOSPEC_FORCE_INLINE double IsoSpec::IsoThresholdGenerator::lprob () const\fC [inline]\fP, \fC [final]\fP, \fC [override]\fP, \fC [virtual]\fP"
103
104 .PP
105 Get the log-probability of the current isotopologue\&.
106 .PP
107 \fBReturns:\fP
108 .RS 4
109 The log-probability of the current isotopologue\&.
110 .RE
111 .PP
112
113 .PP
114 Reimplemented from \fBIsoSpec::IsoGenerator\fP\&.
115 .PP
116 Definition at line 335 of file isoSpec++\&.h\&.
117 .SS "ISOSPEC_FORCE_INLINE double IsoSpec::IsoThresholdGenerator::mass () const\fC [inline]\fP, \fC [final]\fP, \fC [override]\fP, \fC [virtual]\fP"
118
119 .PP
120 Get the mass of the current isotopologue\&.
121 .PP
122 \fBReturns:\fP
123 .RS 4
124 The mass of the current isotopologue\&.
125 .RE
126 .PP
127
128 .PP
129 Reimplemented from \fBIsoSpec::IsoGenerator\fP\&.
130 .PP
131 Definition at line 336 of file isoSpec++\&.h\&.
132 .SS "ISOSPEC_FORCE_INLINE double IsoSpec::IsoThresholdGenerator::prob () const\fC [inline]\fP, \fC [final]\fP, \fC [override]\fP, \fC [virtual]\fP"
133
134 .PP
135 Get the probability of the current isotopologue\&.
136 .PP
137 \fBReturns:\fP
138 .RS 4
139 The probability of the current isotopologue\&.
140 .RE
141 .PP
142
143 .PP
144 Reimplemented from \fBIsoSpec::IsoGenerator\fP\&.
145 .PP
146 Definition at line 337 of file isoSpec++\&.h\&.
147 .SS "void IsoSpec::IsoThresholdGenerator::reset ()"
148 Reset the generator to the beginning of the sequence\&. Allows it to be reused, eg\&. to go through the conf space once, calculate the amount of space needed to store configurations, then to allocate that memory, and go through it again, this time saving configurations (and \fIis\fP in fact faster than allocating a std::vector and depending on it to grow as needed\&. This is cheaper than throwing away the generator and making a new one too: marginal distributions don't need to be recalculated\&.
149 .PP
150 Definition at line 386 of file isoSpec++\&.cpp\&.
151
152 .SH "Author"
153 .PP
154 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::IsoThresholdGeneratorMT" 3 "Thu Oct 11 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::IsoThresholdGeneratorMT \- The multi-threaded version of the generator of isotopologues\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .PP
10 \fC#include <isoSpec++\&.h>\fP
11 .PP
12 Inherits \fBIsoSpec::IsoGenerator\fP\&.
13 .SS "Public Member Functions"
14
15 .in +1c
16 .ti -1c
17 .RI "bool \fBadvanceToNextConfiguration\fP () override final"
18 .br
19 .RI "Advance to the next, not yet visited, most probable isotopologue\&. "
20 .ti -1c
21 .RI "void \fBget_conf_signature\fP (int *space) const override final"
22 .br
23 .RI "Save the counts of isotopes in the space\&. "
24 .ti -1c
25 .RI "\fBIsoThresholdGeneratorMT\fP (\fBIso\fP &&iso, double _threshold, \fBPrecalculatedMarginal\fP **\fBmarginals\fP, bool _absolute=true)"
26 .br
27 .RI "Move constructor\&. "
28 .ti -1c
29 .RI "virtual \fB~IsoThresholdGeneratorMT\fP ()"
30 .br
31 .RI "Destructor\&. "
32 .ti -1c
33 .RI "void \fBterminate_search\fP ()"
34 .br
35 .RI "Block the subsequent search of isotopologues\&. "
36 .in -1c
37 .SS "Additional Inherited Members"
38 .SH "Detailed Description"
39 .PP
40 The multi-threaded version of the generator of isotopologues\&.
41
42 Attention: this code is experimental\&.
43 .PP
44 Definition at line 305 of file isoSpec++\&.h\&.
45 .SH "Member Function Documentation"
46 .PP
47 .SS "bool IsoSpec::IsoThresholdGeneratorMT::advanceToNextConfiguration ()\fC [final]\fP, \fC [override]\fP, \fC [virtual]\fP"
48
49 .PP
50 Advance to the next, not yet visited, most probable isotopologue\&.
51 .PP
52 \fBReturns:\fP
53 .RS 4
54 Return false if it is not possible to advance\&.
55 .RE
56 .PP
57
58 .PP
59 Implements \fBIsoSpec::IsoGenerator\fP\&.
60 .PP
61 Definition at line 354 of file isoSpec++\&.cpp\&.
62 .SS "void IsoSpec::IsoThresholdGeneratorMT::get_conf_signature (int * space) const\fC [inline]\fP, \fC [final]\fP, \fC [override]\fP, \fC [virtual]\fP"
63
64 .PP
65 Save the counts of isotopes in the space\&.
66 .PP
67 \fBParameters:\fP
68 .RS 4
69 \fIspace\fP An array where counts of isotopes shall be written\&. Must be as big as the overall number of isotopes\&.
70 .RE
71 .PP
72
73 .PP
74 Implements \fBIsoSpec::IsoGenerator\fP\&.
75 .PP
76 Definition at line 316 of file isoSpec++\&.h\&.
77
78 .SH "Author"
79 .PP
80 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::KeyHasher" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::KeyHasher
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "\fBKeyHasher\fP (int dim)"
13 .br
14 .ti -1c
15 .RI "std::size_t \fBoperator()\fP (const int *conf) const"
16 .br
17 .in -1c
18 .SH "Detailed Description"
19 .PP
20 Definition at line 27 of file operators\&.h\&.
21
22 .SH "Author"
23 .PP
24 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::LayeredMarginal" 3 "Thu Oct 11 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::LayeredMarginal \- \fBLayeredMarginal\fP class\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .PP
10 \fC#include <marginalTrek++\&.h>\fP
11 .PP
12 Inherits \fBIsoSpec::Marginal\fP\&.
13 .SS "Public Member Functions"
14
15 .in +1c
16 .ti -1c
17 .RI "\fBLayeredMarginal\fP (\fBMarginal\fP &&m, int tabSize=1000, int hashSize=1000)"
18 .br
19 .RI "Move constructor: specializes the \fBMarginal\fP class\&. "
20 .ti -1c
21 .RI "bool \fBextend\fP (double new_threshold)"
22 .br
23 .RI "Extend the set of computed subisotopologues to those above the new threshold\&. "
24 .ti -1c
25 .RI "double \fBget_lProb\fP (int idx) const"
26 .br
27 .RI "get the log-probability of the idx-th subisotopologue, see details in \fBPrecalculatedMarginal::get_lProb\fP\&. "
28 .ti -1c
29 .RI "double \fBget_eProb\fP (int idx) const"
30 .br
31 .RI "get the probability of the idx-th subisotopologue, see details in \fBPrecalculatedMarginal::get_eProb\fP\&. "
32 .ti -1c
33 .RI "double \fBget_mass\fP (int idx) const"
34 .br
35 .RI "get the mass of the idx-th subisotopologue, see details in \fBPrecalculatedMarginal::get_mass\fP\&. "
36 .ti -1c
37 .RI "const Conf & \fBget_conf\fP (int idx) const"
38 .br
39 .RI "get the counts of isotopes that define the subisotopologue, see details in \fBPrecalculatedMarginal::get_conf\fP\&. "
40 .ti -1c
41 .RI "unsigned int \fBget_no_confs\fP () const"
42 .br
43 .RI "Get the number of precomputed subisotopologues, see details in \fBPrecalculatedMarginal::get_no_confs\fP\&. "
44 .in -1c
45 .SS "Additional Inherited Members"
46 .SH "Detailed Description"
47 .PP
48 \fBLayeredMarginal\fP class\&.
49
50 An extendable version of the \fBPrecalculatedMarginal\fP, where you can extend the threshold at will\&.
51 .PP
52 Definition at line 337 of file marginalTrek++\&.h\&.
53 .SH "Constructor & Destructor Documentation"
54 .PP
55 .SS "IsoSpec::LayeredMarginal::LayeredMarginal (\fBMarginal\fP && m, int tabSize = \fC1000\fP, int hashSize = \fC1000\fP)"
56
57 .PP
58 Move constructor: specializes the \fBMarginal\fP class\&.
59 .PP
60 \fBParameters:\fP
61 .RS 4
62 \fItabSize\fP The size of the table used to store configurations in the allocator\&.
63 .br
64 \fIhashSize\fP The size of the hash table used to store visited subisotopologues\&.
65 .RE
66 .PP
67
68 .PP
69 Definition at line 445 of file marginalTrek++\&.cpp\&.
70 .SH "Member Function Documentation"
71 .PP
72 .SS "bool IsoSpec::LayeredMarginal::extend (double new_threshold)"
73
74 .PP
75 Extend the set of computed subisotopologues to those above the new threshold\&.
76 .PP
77 \fBParameters:\fP
78 .RS 4
79 \fInew_threshold\fP The new log-probability limiting the subisotopologues from below\&.
80 .RE
81 .PP
82 \fBReturns:\fP
83 .RS 4
84 Returns false, if there are no fringe-subisotopologues (subisotopologues that were neighbours of the previously calculated subisotopologues, with log-probability below the previous threshold)\&.
85 .RE
86 .PP
87
88 .PP
89 Definition at line 455 of file marginalTrek++\&.cpp\&.
90
91 .SH "Author"
92 .PP
93 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::Marginal" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::Marginal \- The marginal distribution class (a subisotopologue)\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .PP
10 \fC#include <marginalTrek++\&.h>\fP
11 .PP
12 Inherited by \fBIsoSpec::MarginalTrek\fP, and \fBIsoSpec::PrecalculatedMarginal\fP\&.
13 .SS "Public Member Functions"
14
15 .in +1c
16 .ti -1c
17 .RI "\fBMarginal\fP (const double *_masses, const double *_probs, int _isotopeNo, int _atomCnt)"
18 .br
19 .RI "Class constructor\&. "
20 .ti -1c
21 .RI "\fBMarginal\fP (\fBMarginal\fP &other)=delete"
22 .br
23 .ti -1c
24 .RI "\fBMarginal\fP & \fBoperator=\fP (const \fBMarginal\fP &other)=delete"
25 .br
26 .ti -1c
27 .RI "\fBMarginal\fP (\fBMarginal\fP &&other)"
28 .br
29 .RI "Move constructor\&. "
30 .ti -1c
31 .RI "virtual \fB~Marginal\fP ()"
32 .br
33 .RI "Destructor\&. "
34 .ti -1c
35 .RI "int \fBget_isotopeNo\fP () const"
36 .br
37 .RI "Get the number of isotopes of the investigated element\&. "
38 .ti -1c
39 .RI "double \fBgetLightestConfMass\fP () const"
40 .br
41 .RI "Get the mass of the lightest subisotopologue\&. "
42 .ti -1c
43 .RI "double \fBgetHeaviestConfMass\fP () const"
44 .br
45 .RI "Get the mass of the heaviest subisotopologue\&. "
46 .ti -1c
47 .RI "double \fBgetModeLProb\fP () const"
48 .br
49 .RI "Get the log-probability of the mode subisotopologue\&. "
50 .ti -1c
51 .RI "double \fBgetModeMass\fP () const"
52 .br
53 .RI "The the mass of the mode subisotopologue\&. "
54 .ti -1c
55 .RI "double \fBgetModeProb\fP () const"
56 .br
57 .RI "The the probability of the mode subisotopologue\&. "
58 .ti -1c
59 .RI "double \fBgetSmallestLProb\fP () const"
60 .br
61 .RI "The the log-probability of the lightest subisotopologue\&. "
62 .ti -1c
63 .RI "double \fBlogProb\fP (Conf conf) const"
64 .br
65 .RI "Calculate the log-probability of a given subisotopologue\&. "
66 .in -1c
67 .SS "Protected Attributes"
68
69 .in +1c
70 .ti -1c
71 .RI "const unsigned int \fBisotopeNo\fP"
72 .br
73 .ti -1c
74 .RI "const unsigned int \fBatomCnt\fP"
75 .br
76 .ti -1c
77 .RI "const double *const \fBatom_masses\fP"
78 .br
79 .ti -1c
80 .RI "const double *const \fBatom_lProbs\fP"
81 .br
82 .ti -1c
83 .RI "const double \fBloggamma_nominator\fP"
84 .br
85 .ti -1c
86 .RI "const Conf \fBmode_conf\fP"
87 .br
88 .ti -1c
89 .RI "const double \fBmode_lprob\fP"
90 .br
91 .ti -1c
92 .RI "const double \fBmode_mass\fP"
93 .br
94 .ti -1c
95 .RI "const double \fBmode_prob\fP"
96 .br
97 .ti -1c
98 .RI "const double \fBsmallest_lprob\fP"
99 .br
100 .in -1c
101 .SH "Detailed Description"
102 .PP
103 The marginal distribution class (a subisotopologue)\&.
104
105 This class mostly provides some basic common API for subclasses, but itself is not abstract\&. This class represents the probability distribution generated by one element only -- a subisotopologue\&. For instance, it might be the distribution of C200, that might be part of, say, C200H402\&. It corresponds to the multinomial distribution, where each configuration can also be attributed a precise mass\&. The constructor method perform initial hill-climbing to find the most probable sub-isotopologue (the mode)\&.
106 .PP
107 Definition at line 45 of file marginalTrek++\&.h\&.
108 .SH "Constructor & Destructor Documentation"
109 .PP
110 .SS "IsoSpec::Marginal::Marginal (const double * _masses, const double * _probs, int _isotopeNo, int _atomCnt)"
111
112 .PP
113 Class constructor\&.
114 .PP
115 \fBParameters:\fP
116 .RS 4
117 \fI_masses\fP A table of masses of the stable isotopes of the investigated element, e\&.g\&. for C10 it is 2: C12 and C13\&.
118 .br
119 \fI_probs\fP A table of natural frequencies of the stable isotopes of the investigated element, see IUPAC at https://iupac.org/isotopesmatter/
120 .br
121 \fI_isotopeNo\fP Number of isotopes of a given element\&.
122 .br
123 \fI_atomCnt\fP The number of atoms of the given element, e\&.g\&. 10 for C10\&.
124 .RE
125 .PP
126 \fBReturns:\fP
127 .RS 4
128 An instance of the \fBMarginal\fP class\&.
129 .RE
130 .PP
131
132 .PP
133 Definition at line 187 of file marginalTrek++\&.cpp\&.
134 .SH "Member Function Documentation"
135 .PP
136 .SS "int IsoSpec::Marginal::get_isotopeNo () const\fC [inline]\fP"
137
138 .PP
139 Get the number of isotopes of the investigated element\&.
140 .PP
141 \fBReturns:\fP
142 .RS 4
143 The integer number of isotopes of the investigated element\&.
144 .RE
145 .PP
146
147 .PP
148 Definition at line 92 of file marginalTrek++\&.h\&.
149 .SS "double IsoSpec::Marginal::getHeaviestConfMass () const"
150
151 .PP
152 Get the mass of the heaviest subisotopologue\&. This is trivially obtained by considering all atomNo atoms to be the heaviest isotope possible\&.
153 .PP
154 \fBReturns:\fP
155 .RS 4
156 The mass of the heaviest subisotopologue\&.
157 .RE
158 .PP
159
160 .PP
161 Definition at line 246 of file marginalTrek++\&.cpp\&.
162 .SS "double IsoSpec::Marginal::getLightestConfMass () const"
163
164 .PP
165 Get the mass of the lightest subisotopologue\&. This is trivially obtained by considering all atomNo atoms to be the lightest isotope possible\&.
166 .PP
167 \fBReturns:\fP
168 .RS 4
169 The mass of the lightiest subisotopologue\&.
170 .RE
171 .PP
172
173 .PP
174 Definition at line 237 of file marginalTrek++\&.cpp\&.
175 .SS "double IsoSpec::Marginal::getModeLProb () const\fC [inline]\fP"
176
177 .PP
178 Get the log-probability of the mode subisotopologue\&.
179 .PP
180 \fBReturns:\fP
181 .RS 4
182 The log-probability of a/the most probable subisotopologue\&.
183 .RE
184 .PP
185
186 .PP
187 Definition at line 110 of file marginalTrek++\&.h\&.
188 .SS "double IsoSpec::Marginal::getModeMass () const\fC [inline]\fP"
189
190 .PP
191 The the mass of the mode subisotopologue\&.
192 .PP
193 \fBReturns:\fP
194 .RS 4
195 The mass of one of the most probable subisotopologues\&.
196 .RE
197 .PP
198
199 .PP
200 Definition at line 116 of file marginalTrek++\&.h\&.
201 .SS "double IsoSpec::Marginal::getModeProb () const\fC [inline]\fP"
202
203 .PP
204 The the probability of the mode subisotopologue\&.
205 .PP
206 \fBReturns:\fP
207 .RS 4
208 The probability of a/the most probable subisotopologue\&.
209 .RE
210 .PP
211
212 .PP
213 Definition at line 122 of file marginalTrek++\&.h\&.
214 .SS "double IsoSpec::Marginal::getSmallestLProb () const\fC [inline]\fP"
215
216 .PP
217 The the log-probability of the lightest subisotopologue\&.
218 .PP
219 \fBReturns:\fP
220 .RS 4
221 The logarithm of the smallest non-zero probability of a subisotopologue\&.
222 .RE
223 .PP
224
225 .PP
226 Definition at line 129 of file marginalTrek++\&.h\&.
227 .SS "double IsoSpec::Marginal::logProb (Conf conf) const\fC [inline]\fP"
228
229 .PP
230 Calculate the log-probability of a given subisotopologue\&.
231 .PP
232 \fBParameters:\fP
233 .RS 4
234 \fIconf\fP A subisotopologue (a table of integers describing subsequent isotope-counts)\&.
235 .RE
236 .PP
237 \fBReturns:\fP
238 .RS 4
239 The log-probability of the input subisotopologue\&.
240 .RE
241 .PP
242
243 .PP
244 Definition at line 136 of file marginalTrek++\&.h\&.
245 .SH "Member Data Documentation"
246 .PP
247 .SS "const double* const IsoSpec::Marginal::atom_lProbs\fC [protected]\fP"
248 Table of log-probabilities of all the isotopeNo isotopes\&.
249 .PP
250 Definition at line 53 of file marginalTrek++\&.h\&.
251 .SS "const double* const IsoSpec::Marginal::atom_masses\fC [protected]\fP"
252 Table of atomic masses of all the isotopeNo isotopes\&.
253 .PP
254 Definition at line 52 of file marginalTrek++\&.h\&.
255 .SS "const unsigned int IsoSpec::Marginal::atomCnt\fC [protected]\fP"
256 The number of atoms of the given element\&.
257 .PP
258 Definition at line 51 of file marginalTrek++\&.h\&.
259 .SS "const unsigned int IsoSpec::Marginal::isotopeNo\fC [protected]\fP"
260 The number of isotopes of the given element\&.
261 .PP
262 Definition at line 50 of file marginalTrek++\&.h\&.
263 .SS "const double IsoSpec::Marginal::loggamma_nominator\fC [protected]\fP"
264 The constant nominator that appears in the expressions for the multinomial probabilities\&.
265 .PP
266 Definition at line 54 of file marginalTrek++\&.h\&.
267 .SS "const Conf IsoSpec::Marginal::mode_conf\fC [protected]\fP"
268 A subisotopologue with most probability\&. If not unique, one of the representatives of that class of subisotopologues\&.
269 .PP
270 Definition at line 55 of file marginalTrek++\&.h\&.
271 .SS "const double IsoSpec::Marginal::mode_lprob\fC [protected]\fP"
272 The log-probability of the mode subisotopologue\&.
273 .PP
274 Definition at line 56 of file marginalTrek++\&.h\&.
275 .SS "const double IsoSpec::Marginal::mode_mass\fC [protected]\fP"
276 The mass of the mode subisotopologue\&.
277 .PP
278 Definition at line 57 of file marginalTrek++\&.h\&.
279 .SS "const double IsoSpec::Marginal::mode_prob\fC [protected]\fP"
280 The probability of the mode subisotopologue\&.
281 .PP
282 Definition at line 58 of file marginalTrek++\&.h\&.
283 .SS "const double IsoSpec::Marginal::smallest_lprob\fC [protected]\fP"
284 The smallest-achievable log-probability in the distribution of subisotopologues\&.
285 .PP
286 Definition at line 59 of file marginalTrek++\&.h\&.
287
288 .SH "Author"
289 .PP
290 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::MarginalTrek" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::MarginalTrek \- The marginal distribution class (a subisotopologue)\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .PP
10 \fC#include <marginalTrek++\&.h>\fP
11 .PP
12 Inherits \fBIsoSpec::Marginal\fP\&.
13 .SS "Public Member Functions"
14
15 .in +1c
16 .ti -1c
17 .RI "\fBMarginalTrek\fP (\fBMarginal\fP &&m, int tabSize=1000, int hashSize=1000)"
18 .br
19 .RI "Move constructor: specializes the \fBMarginal\fP class\&. "
20 .ti -1c
21 .RI "bool \fBprobeConfigurationIdx\fP (int idx)"
22 .br
23 .RI "Check if the table of computed subisotopologues does not have to be extended\&. "
24 .ti -1c
25 .RI "int \fBprocessUntilCutoff\fP (double cutoff)"
26 .br
27 .RI "Calculate subisotopologues with probability above or equal to the cut-off\&. "
28 .ti -1c
29 .RI "const std::vector< double > & \fBconf_lprobs\fP () const"
30 .br
31 .ti -1c
32 .RI "const std::vector< double > & \fBconf_masses\fP () const"
33 .br
34 .ti -1c
35 .RI "const std::vector< int * > & \fBconfs\fP () const"
36 .br
37 .in -1c
38 .SS "Additional Inherited Members"
39 .SH "Detailed Description"
40 .PP
41 The marginal distribution class (a subisotopologue)\&.
42 .PP
43 Definition at line 141 of file marginalTrek++\&.h\&.
44 .SH "Constructor & Destructor Documentation"
45 .PP
46 .SS "IsoSpec::MarginalTrek::MarginalTrek (\fBMarginal\fP && m, int tabSize = \fC1000\fP, int hashSize = \fC1000\fP)"
47
48 .PP
49 Move constructor: specializes the \fBMarginal\fP class\&.
50 .PP
51 \fBParameters:\fP
52 .RS 4
53 \fItabSize\fP The size of the table used to store configurations in the allocator\&.
54 .br
55 \fIhashSize\fP The size of the hash table used to store visited subisotopologues\&.
56 .RE
57 .PP
58
59 .PP
60 Definition at line 256 of file marginalTrek++\&.cpp\&.
61 .SH "Member Function Documentation"
62 .PP
63 .SS "bool IsoSpec::MarginalTrek::probeConfigurationIdx (int idx)\fC [inline]\fP"
64
65 .PP
66 Check if the table of computed subisotopologues does not have to be extended\&. This function checks if the idx-th most probable subisotopologue was memoized and if not, computes it and memoizes it\&.
67 .PP
68 \fBParameters:\fP
69 .RS 4
70 \fIidx\fP The number of the idx-th most probable subisotopologue\&.
71 .RE
72 .PP
73 \fBReturns:\fP
74 .RS 4
75 Returns false if it the provided idx exceeds the total number of subisotopologues\&.
76 .RE
77 .PP
78
79 .PP
80 Definition at line 179 of file marginalTrek++\&.h\&.
81 .SS "int IsoSpec::MarginalTrek::processUntilCutoff (double cutoff)"
82
83 .PP
84 Calculate subisotopologues with probability above or equal to the cut-off\&.
85 .PP
86 \fBParameters:\fP
87 .RS 4
88 \fIcutoff\fP The probability cut-off
89 .RE
90 .PP
91 \fBReturns:\fP
92 .RS 4
93 The number of the last subisotopologue above the cut-off\&.
94 .RE
95 .PP
96
97 .PP
98 Definition at line 333 of file marginalTrek++\&.cpp\&.
99
100 .SH "Author"
101 .PP
102 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::OrderMarginalsBySizeDecresing" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::OrderMarginalsBySizeDecresing
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "\fBOrderMarginalsBySizeDecresing\fP (\fBPrecalculatedMarginal\fP const *const *_T)"
13 .br
14 .ti -1c
15 .RI "bool \fBoperator()\fP (int m1, int m2)"
16 .br
17 .in -1c
18 .SH "Detailed Description"
19 .PP
20 Definition at line 128 of file operators\&.h\&.
21
22 .SH "Author"
23 .PP
24 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::PrecalculatedMarginal" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::PrecalculatedMarginal \- Precalculated \fBMarginal\fP class\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .PP
10 \fC#include <marginalTrek++\&.h>\fP
11 .PP
12 Inherits \fBIsoSpec::Marginal\fP\&.
13 .SS "Public Member Functions"
14
15 .in +1c
16 .ti -1c
17 .RI "\fBPrecalculatedMarginal\fP (\fBMarginal\fP &&m, double lCutOff, bool sort=true, int tabSize=1000, int hashSize=1000)"
18 .br
19 .RI "The move constructor (disowns the \fBMarginal\fP)\&. "
20 .ti -1c
21 .RI "virtual \fB~PrecalculatedMarginal\fP ()"
22 .br
23 .RI "Destructor\&. "
24 .ti -1c
25 .RI "bool \fBinRange\fP (unsigned int idx) const"
26 .br
27 .RI "Is there a subisotopologue with a given number? "
28 .ti -1c
29 .RI "const double & \fBget_lProb\fP (int idx) const"
30 .br
31 .RI "Get the log-probability of the idx-th subisotopologue\&. "
32 .ti -1c
33 .RI "const double & \fBget_eProb\fP (int idx) const"
34 .br
35 .RI "Get the probability of the idx-th subisotopologue\&. "
36 .ti -1c
37 .RI "const double & \fBget_mass\fP (int idx) const"
38 .br
39 .RI "Get the mass of the idx-th subisotopologue\&. "
40 .ti -1c
41 .RI "const double * \fBget_lProbs_ptr\fP () const"
42 .br
43 .RI "Get the table of the log-probabilities of subisotopologues\&. "
44 .ti -1c
45 .RI "const double * \fBget_masses_ptr\fP () const"
46 .br
47 .RI "Get the table of the masses of subisotopologues\&. "
48 .ti -1c
49 .RI "const Conf & \fBget_conf\fP (int idx) const"
50 .br
51 .RI "Get the counts of isotopes that define the subisotopologue\&. "
52 .ti -1c
53 .RI "unsigned int \fBget_no_confs\fP () const"
54 .br
55 .RI "Get the number of precomputed subisotopologues\&. "
56 .in -1c
57 .SS "Protected Attributes"
58
59 .in +1c
60 .ti -1c
61 .RI "std::vector< Conf > \fBconfigurations\fP"
62 .br
63 .ti -1c
64 .RI "Conf * \fBconfs\fP"
65 .br
66 .ti -1c
67 .RI "unsigned int \fBno_confs\fP"
68 .br
69 .ti -1c
70 .RI "double * \fBmasses\fP"
71 .br
72 .ti -1c
73 .RI "double * \fBlProbs\fP"
74 .br
75 .ti -1c
76 .RI "double * \fBeProbs\fP"
77 .br
78 .ti -1c
79 .RI "\fBAllocator\fP< int > \fBallocator\fP"
80 .br
81 .in -1c
82 .SH "Detailed Description"
83 .PP
84 Precalculated \fBMarginal\fP class\&.
85
86 This class serves to calculate a set of isotopologues that is defined by the minimal probability threshold\&.
87 .PP
88 This works faster than if you did not know the threshold\&. If you have no idea about the threshold, you would need to call us, to change encode the layered version of the marginal\&.
89 .PP
90 Definition at line 213 of file marginalTrek++\&.h\&.
91 .SH "Constructor & Destructor Documentation"
92 .PP
93 .SS "IsoSpec::PrecalculatedMarginal::PrecalculatedMarginal (\fBMarginal\fP && m, double lCutOff, bool sort = \fCtrue\fP, int tabSize = \fC1000\fP, int hashSize = \fC1000\fP)"
94
95 .PP
96 The move constructor (disowns the \fBMarginal\fP)\&. This constructor memoizes all subisotopologues with log-probability above the provided threshold lCutOff
97 .PP
98 \fBParameters:\fP
99 .RS 4
100 \fI\fBMarginal\fP\fP An instance of the \fBMarginal\fP class this class is about to disown\&.
101 .br
102 \fIlCutOff\fP The lower limit on the log-probability of the precomputed subisotopologues\&.
103 .br
104 \fIsort\fP Should the subisotopologues be stored with descending probability ?
105 .RE
106 .PP
107 \fBReturns:\fP
108 .RS 4
109 An instance of the \fBPrecalculatedMarginal\fP class\&.
110 .RE
111 .PP
112
113 .PP
114 Definition at line 362 of file marginalTrek++\&.cpp\&.
115 .SH "Member Function Documentation"
116 .PP
117 .SS "const Conf& IsoSpec::PrecalculatedMarginal::get_conf (int idx) const\fC [inline]\fP"
118
119 .PP
120 Get the counts of isotopes that define the subisotopologue\&.
121 .PP
122 \fBParameters:\fP
123 .RS 4
124 \fIidx\fP The number of the considered subisotopologue\&.
125 .RE
126 .PP
127 \fBReturns:\fP
128 .RS 4
129 The counts of isotopes that define the subisotopologue\&.
130 .RE
131 .PP
132
133 .PP
134 Definition at line 288 of file marginalTrek++\&.h\&.
135 .SS "const double& IsoSpec::PrecalculatedMarginal::get_eProb (int idx) const\fC [inline]\fP"
136
137 .PP
138 Get the probability of the idx-th subisotopologue\&.
139 .PP
140 \fBParameters:\fP
141 .RS 4
142 \fIidx\fP The number of the considered subisotopologue\&.
143 .RE
144 .PP
145 \fBReturns:\fP
146 .RS 4
147 The probability of the idx-th subisotopologue\&.
148 .RE
149 .PP
150
151 .PP
152 Definition at line 261 of file marginalTrek++\&.h\&.
153 .SS "const double& IsoSpec::PrecalculatedMarginal::get_lProb (int idx) const\fC [inline]\fP"
154
155 .PP
156 Get the log-probability of the idx-th subisotopologue\&.
157 .PP
158 \fBParameters:\fP
159 .RS 4
160 \fIidx\fP The number of the considered subisotopologue\&.
161 .RE
162 .PP
163 \fBReturns:\fP
164 .RS 4
165 The log-probability of the idx-th subisotopologue\&.
166 .RE
167 .PP
168
169 .PP
170 Definition at line 254 of file marginalTrek++\&.h\&.
171 .SS "const double* IsoSpec::PrecalculatedMarginal::get_lProbs_ptr () const\fC [inline]\fP"
172
173 .PP
174 Get the table of the log-probabilities of subisotopologues\&.
175 .PP
176 \fBReturns:\fP
177 .RS 4
178 Pointer to the first element in the table storing log-probabilities of subisotopologues\&.
179 .RE
180 .PP
181
182 .PP
183 Definition at line 274 of file marginalTrek++\&.h\&.
184 .SS "const double& IsoSpec::PrecalculatedMarginal::get_mass (int idx) const\fC [inline]\fP"
185
186 .PP
187 Get the mass of the idx-th subisotopologue\&.
188 .PP
189 \fBParameters:\fP
190 .RS 4
191 \fIidx\fP The number of the considered subisotopologue\&.
192 .RE
193 .PP
194 \fBReturns:\fP
195 .RS 4
196 The mass of the idx-th subisotopologue\&.
197 .RE
198 .PP
199
200 .PP
201 Definition at line 268 of file marginalTrek++\&.h\&.
202 .SS "const double* IsoSpec::PrecalculatedMarginal::get_masses_ptr () const\fC [inline]\fP"
203
204 .PP
205 Get the table of the masses of subisotopologues\&.
206 .PP
207 \fBReturns:\fP
208 .RS 4
209 Pointer to the first element in the table storing masses of subisotopologues\&.
210 .RE
211 .PP
212
213 .PP
214 Definition at line 280 of file marginalTrek++\&.h\&.
215 .SS "unsigned int IsoSpec::PrecalculatedMarginal::get_no_confs () const\fC [inline]\fP"
216
217 .PP
218 Get the number of precomputed subisotopologues\&.
219 .PP
220 \fBReturns:\fP
221 .RS 4
222 The number of precomputed subisotopologues\&.
223 .RE
224 .PP
225
226 .PP
227 Definition at line 294 of file marginalTrek++\&.h\&.
228 .SS "bool IsoSpec::PrecalculatedMarginal::inRange (unsigned int idx) const\fC [inline]\fP"
229
230 .PP
231 Is there a subisotopologue with a given number?
232 .PP
233 \fBReturns:\fP
234 .RS 4
235 Returns true if idx does not exceed the number of pre-computed configurations\&.
236 .RE
237 .PP
238
239 .PP
240 Definition at line 247 of file marginalTrek++\&.h\&.
241
242 .SH "Author"
243 .PP
244 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::ReverseOrder< T >" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::ReverseOrder< T >
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "bool \fBoperator()\fP (const T a, const T b) const"
13 .br
14 .in -1c
15 .SH "Detailed Description"
16 .PP
17
18 .SS "template<typename T>
19 .br
20 class IsoSpec::ReverseOrder< T >"
21
22 .PP
23 Definition at line 106 of file operators\&.h\&.
24
25 .SH "Author"
26 .PP
27 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::SSummator" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::SSummator
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "\fBSSummator\fP (\fBSSummator\fP &other)"
13 .br
14 .ti -1c
15 .RI "void \fBadd\fP (double x)"
16 .br
17 .ti -1c
18 .RI "double \fBget\fP ()"
19 .br
20 .in -1c
21 .SH "Detailed Description"
22 .PP
23 Definition at line 25 of file summator\&.h\&.
24
25 .SH "Author"
26 .PP
27 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::Summator" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::Summator
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "void \fBadd\fP (double what)"
13 .br
14 .ti -1c
15 .RI "double \fBget\fP ()"
16 .br
17 .in -1c
18 .SH "Detailed Description"
19 .PP
20 Definition at line 76 of file summator\&.h\&.
21
22 .SH "Author"
23 .PP
24 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::SyncMarginal" 3 "Thu Oct 11 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::SyncMarginal \- Big experiment for multi-threaded version of the algorithm, do not touch\&.
5
6 .SH SYNOPSIS
7 .br
8 .PP
9 .PP
10 \fC#include <marginalTrek++\&.h>\fP
11 .PP
12 Inherits \fBIsoSpec::PrecalculatedMarginal\fP\&.
13 .SS "Public Member Functions"
14
15 .in +1c
16 .ti -1c
17 .RI "\fBSyncMarginal\fP (\fBMarginal\fP &&m, double lCutOff, int tabSize=1000, int hashSize=1000)"
18 .br
19 .RI "likewise\&.\&.\&. "
20 .ti -1c
21 .RI "unsigned int \fBgetNextConfIdx\fP ()"
22 .br
23 .ti -1c
24 .RI "unsigned int \fBgetNextConfIdxwMass\fP (double mmin, double mmax)"
25 .br
26 .in -1c
27 .SS "Protected Attributes"
28
29 .in +1c
30 .ti -1c
31 .RI "char \fBpadding\fP [64]"
32 .br
33 .ti -1c
34 .RI "std::atomic< unsigned int > \fBcounter\fP"
35 .br
36 .ti -1c
37 .RI "char \fBpadding2\fP [64]"
38 .br
39 .in -1c
40 .SH "Detailed Description"
41 .PP
42 Big experiment for multi-threaded version of the algorithm, do not touch\&.
43 .PP
44 Definition at line 298 of file marginalTrek++\&.h\&.
45
46 .SH "Author"
47 .PP
48 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::TSummator" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::TSummator
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "void \fBadd\fP (double what)"
13 .br
14 .ti -1c
15 .RI "double \fBget\fP ()"
16 .br
17 .in -1c
18 .SH "Detailed Description"
19 .PP
20 Definition at line 99 of file summator\&.h\&.
21
22 .SH "Author"
23 .PP
24 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::TableOrder< T >" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::TableOrder< T >
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "\fBTableOrder\fP (const T *_tbl)"
13 .br
14 .ti -1c
15 .RI "bool \fBoperator()\fP (unsigned int i, unsigned int j)"
16 .br
17 .in -1c
18 .SH "Detailed Description"
19 .PP
20
21 .SS "template<typename T>
22 .br
23 class IsoSpec::TableOrder< T >"
24
25 .PP
26 Definition at line 113 of file operators\&.h\&.
27
28 .SH "Author"
29 .PP
30 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::Tabulator< T >" 3 "Tue Oct 30 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::Tabulator< T >
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "\fBTabulator\fP (T *generator, bool get_masses, bool get_probs, bool get_lprobs, bool get_confs)"
13 .br
14 .ti -1c
15 .RI "double * \fBmasses\fP ()"
16 .br
17 .ti -1c
18 .RI "double * \fBlprobs\fP ()"
19 .br
20 .ti -1c
21 .RI "double * \fBprobs\fP ()"
22 .br
23 .ti -1c
24 .RI "int * \fBconfs\fP ()"
25 .br
26 .ti -1c
27 .RI "size_t \fBconfs_no\fP ()"
28 .br
29 .in -1c
30 .SH "Detailed Description"
31 .PP
32
33 .SS "template<typename T>
34 .br
35 class IsoSpec::Tabulator< T >"
36
37 .PP
38 Definition at line 12 of file tabulator\&.h\&.
39
40 .SH "Author"
41 .PP
42 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 .TH "IsoSpec::ThreadSummator" 3 "Thu Oct 11 2018" "Version 1.95" "IsoSpec" \" -*- nroff -*-
1 .ad l
2 .nh
3 .SH NAME
4 IsoSpec::ThreadSummator
5 .SH SYNOPSIS
6 .br
7 .PP
8 .SS "Public Member Functions"
9
10 .in +1c
11 .ti -1c
12 .RI "\fBThreadSummator\fP ()"
13 .br
14 .RI "Constructor (sum defaults to zero)\&. "
15 .ti -1c
16 .RI "void \fBadd\fP (double what)"
17 .br
18 .RI "Add a number to the existing sum\&. "
19 .ti -1c
20 .RI "double \fBget\fP ()"
21 .br
22 .RI "Get the current value of the sum of the added floating point numbers\&. "
23 .in -1c
24 .SH "Detailed Description"
25 .PP
26 Definition at line 139 of file summator\&.h\&.
27 .SH "Member Function Documentation"
28 .PP
29 .SS "void IsoSpec::ThreadSummator::add (double what)\fC [inline]\fP"
30
31 .PP
32 Add a number to the existing sum\&.
33 .PP
34 \fBParameters:\fP
35 .RS 4
36 \fIx\fP A double floating point number to add\&.
37 .RE
38 .PP
39
40 .PP
41 Definition at line 151 of file summator\&.h\&.
42
43 .SH "Author"
44 .PP
45 Generated automatically by Doxygen for IsoSpec from the source code\&.
0 all: test_IsoThresholdGenerator test_IsoOrderedGenerator
1
2 test_IsoThresholdGenerator:
3 clang++ -std=c++11 -x c++ test_IsoThresholdGenerator.c -o isoThreshold -lpthread
4
5 test_IsoOrderedGenerator:
6 clang++ -std=c++11 -x c++ test_IsoOrderedGenerator.c -o isoOrdered -lpthread
0 #include <iostream>
1 #include "../../IsoSpec++/unity-build.cpp"
2
3 using std::cout;
4
5 int main()
6 {
7 int isotopeNumbers[] = {2, 3};
8 int atomCounts[] = {10, 10};
9 double isotopeMasses[] = {1.0, 2.0, 3.0, 4.0, 5.0};
10 double isotopeProbabilities[] = {0.5, 0.5, 0.5, 0.3, 0.2};
11
12 void* iso = setupIso(2, isotopeNumbers, atomCounts, isotopeMasses, isotopeProbabilities);
13
14 void* p = setupIsoOrderedGenerator(
15 iso,
16 1000,
17 1000);
18
19 while(advanceToNextConfigurationIsoOrderedGenerator(p))
20 {
21 cout << "mass="<< massIsoOrderedGenerator(p) << " lprob=" <<
22 lprobIsoOrderedGenerator(p) << std::endl;
23 }
24
25 deleteIsoOrderedGenerator(p);
26 deleteIso(iso);
27
28 return 0;
29 }
0 #include <iostream>
1 #include "../../IsoSpec++/unity-build.cpp"
2
3 using std::cout;
4
5 int main()
6 {
7 int isotopeNumbers[] = {2, 3};
8 int atomCounts[] = {10, 10};
9 double isotopeMasses[] = {1.0, 2.0, 3.0, 4.0, 5.0};
10 double isotopeProbabilities[] = {0.5, 0.5, 0.5, 0.3, 0.2};
11
12 void* iso = setupIso(2, isotopeNumbers, atomCounts, isotopeMasses, isotopeProbabilities);
13
14 void* p = setupIsoThresholdGenerator(
15 iso,
16 .001,
17 true,
18 1000,
19 1000);
20
21 while(advanceToNextConfigurationIsoThresholdGenerator(p))
22 {
23 cout << "mass="<< massIsoThresholdGenerator(p) << " lprob=" <<
24 lprobIsoThresholdGenerator(p) << std::endl;
25 }
26
27 deleteIsoThresholdGenerator(p);
28 deleteIso(iso);
29
30 return 0;
31 }
0 #include <iostream>
1 #include "../../IsoSpec++/unity-build.cpp"
2
3 using std::cout;
4 using std::endl;
5
6 int main()
7 {
8 cout << "Welcome to the test!" << endl;
9 int isotopeNumbers[] = {2, 3};
10 int atomCounts[] = {10, 10};
11 double isotopeMasses[] = {1.0, 2.0, 3.0, 4.0, 5.0};
12 double isotopeProbabilities[] = {0.5, 0.5, 0.5, 0.3, 0.2};
13
14 void* iso = setupIso(2, isotopeNumbers, atomCounts, isotopeMasses, isotopeProbabilities);
15
16 void* p = setupIsoOrderedGenerator(iso, 1000, 1000);
17
18 MassSpectrum MS = set_tablesIsoOrderedGenerator(p, 100);
19
20 double *masses = MS.masses, *lprobs = MS.logprobs;
21 int confs_no = MS.confs_no;
22
23 for(int i = 0; i < confs_no; i++ )
24 {
25 cout << masses[i] << " " << lprobs[i] << endl;
26 }
27
28 deleteIsoOrderedGenerator(p);
29 deleteIso(iso)
30
31 return 0;
32 }
0 #include <iostream>
1 #include "../../IsoSpec++/unity-build.cpp"
2
3 using std::cout;
4 using std::endl;
5
6 using namespace IsoSpec;
7
8 int main()
9 {
10 int isotopeNumbers[] = {2, 3};
11 int config_size = isotopeNumbers[0] + isotopeNumbers[1];
12 int atomCounts[] = {10, 10};
13 double isotopeMasses[] = {1.0, 2.0, 3.0, 4.0, 5.0};
14 double isotopeProbabilities[] = {0.5, 0.5, 0.5, 0.3, 0.2};
15
16 void* iso = setupIso(
17 2,
18 isotopeNumbers,
19 atomCounts,
20 isotopeMasses,
21 isotopeProbabilities);
22
23 void* p = setupIsoThresholdGenerator(
24 iso,
25 .001,
26 true,
27 1000,
28 1000);
29
30 int conf_no(0);
31 int *space = new int[config_size];
32 while(advanceToNextConfigurationIsoThresholdGenerator(p))
33 {
34 cout << "mass="<< massIsoThresholdGenerator(p) << " lprob=" <<
35 lprobIsoThresholdGenerator(p) << endl;
36
37 get_conf_signatureIsoThresholdGenerator(p, space);
38 for(conf_no = 0; conf_no < config_size; conf_no++)
39 {
40 cout << space[conf_no] << " ";
41 }
42
43 cout << endl;
44
45 }
46
47 deleteIsoThresholdGenerator(p);
48 delete[] space;
49 deleteIso(iso);
50
51 return 0;
52 }
0 CXX=clang++
1 OPTFLAGS=-O3 -march=native -mtune=native
2 DEBUGFLAGS=-O0 -g
3 TESTFLAGS=-fsanitize=leak,undefined
4 TESTMEMFLAGS= $(TESTFLAGS) -fsanitize=memory
5 TESTADDRFLAGS= $(TESTFLAGS) -fsanitize=address
6 LLVMTESTFLAGS= -fsanitize=dataflow,cfi,safe-stack
7 CXXFLAGS=-std=c++11 -Wall -I../../IsoSpec++ -Wextra -pedantic
8 SRCFILES=../../IsoSpec++/unity-build.cpp
9
10 all: main_test cmdlines
11
12 main_test:
13 clang++ $(CXXFLAGS) $(OPTFLAGS) main_test.cpp -o main_test_clang
14 g++ $(CXXFLAGS) $(OPTFLAGS) main_test.cpp -o main_test_gcc
15 g++ $(CXXFLAGS) $(DEBUGFLAGS) main_test.cpp -o main_test_dbg
16 g++ $(CXXFLAGS) $(DEBUGFLAGS) main_test.cpp -DISOSPEC_SKIP_SLOW_TESTS -o main_test_dbg_fast
17 clang++ $(CXXFLAGS) $(DEBUGFLAGS) main_test.cpp -DISOSPEC_SKIP_SLOW_TESTS -fsanitize=address,undefined -o main_test_asan
18 clang++ $(CXXFLAGS) $(DEBUGFLAGS) main_test.cpp -fsanitize=cfi -flto -fvisibility=hidden -o main_test_cfi
19 clang++ $(CXXFLAGS) $(DEBUGFLAGS) main_test.cpp -fsanitize=safe-stack -o main_test_ss
20 clang++ $(CXXFLAGS) $(DEBUGFLAGS) main_test.cpp -DISOSPEC_TESTS_MEMSAN -fsanitize=memory,undefined -o main_test_memsan
21
22 cmdlines: formula_layered formula_ordered formula_threshold formula_threshold_simple
23
24 formula_ordered:
25 clang++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_ordered.cpp -o ./from_formula_ordered_clang
26 g++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_ordered.cpp -o ./from_formula_ordered_gcc
27 g++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_ordered.cpp -o ./from_formula_ordered_dbg
28 clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_ordered.cpp -fsanitize=address,undefined -o ./from_formula_ordered_asan
29 clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_ordered.cpp -DISOSPEC_TESTS_MEMSAN -fsanitize=memory,undefined -o ./from_formula_ordered_memsan
30
31 formula_threshold_simple:
32 clang++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_threshold_simple.cpp -o ./from_formula_threshold_simple_clang
33 g++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_threshold_simple.cpp -o ./from_formula_threshold_simple_gcc
34 g++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_threshold_simple.cpp -o ./from_formula_threshold_simple_dbg
35 clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_threshold_simple.cpp -fsanitize=address,undefined -o ./from_formula_threshold_simple_asan
36 clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_threshold_simple.cpp -DISOSPEC_TESTS_MEMSAN -fsanitize=memory,undefined -o ./from_formula_threshold_simple_memsan
37
38 formula_threshold:
39 clang++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_threshold.cpp -o ./from_formula_threshold_clang
40 g++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_threshold.cpp -o ./from_formula_threshold_gcc
41 g++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_threshold.cpp -o ./from_formula_threshold_dbg
42 clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_threshold.cpp -fsanitize=address,undefined -o ./from_formula_threshold_asan
43 clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_threshold.cpp -DISOSPEC_TESTS_MEMSAN -fsanitize=memory,undefined -o ./from_formula_threshold_memsan
44
45 formula_layered:
46 clang++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_layered.cpp -o ./from_formula_layered_clang
47 g++ $(CXXFLAGS) $(OPTFLAGS) $(SRCFILES) from_formula_layered.cpp -o ./from_formula_layered_gcc
48 g++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_layered.cpp -o ./from_formula_layered_dbg
49 clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_layered.cpp -fsanitize=address,undefined -o ./from_formula_layered_asan
50 clang++ $(CXXFLAGS) $(DEBUGFLAGS) $(SRCFILES) from_formula_layered.cpp -DISOSPEC_TESTS_MEMSAN -fsanitize=memory,undefined -o ./from_formula_layered_memsan
51
52 ti:
53 $(CXX) $(CXXFLAGS) $(OPTFLAGS) ../../IsoSpec++/unity-build.cpp titin-test.cpp -o ./titin
54
55 mr:
56 $(CXX) $(CXXFLAGS) $(DEBUGFLAGS) marginal-test.cpp -o marginal -g
57
58 tabulator:
59 clang++ -std=c++11 tabulator_test.cpp -o tabulator
60
61 la:
62 $(CXX) $(CXXFLAGS) $(DEBUGFLAGS) ../../IsoSpec++/unity-build.cpp layered-test.cpp -o layered
63
64 IsoThresholdGenerator:
65 clang++ -std=c++11 IsoThresholdGenerator.cpp -o IsoThresholdGenerator -lpthread
66
67 nr_conf:
68 clang++ -std=c++11 nr_conf.cpp -o nr_conf -lpthread
69
70 clean:
71 rm -f *_gcc *_clang *_dbg *_memsan *_asan IsoThresholdGenerator layered main_test_cfi main_test_ss marginal nr_conf tabulator titin
0 #include <iostream>
1 #include "isoSpec++.h"
2 #include <cassert>
3
4 using namespace IsoSpec;
5
6 #ifndef ISOSPEC_TESTS_SKIP_MAIN
7
8 size_t test_zero(double, bool);
9
10 int main(int argc, char** argv)
11 {
12 if(argc < 1) // yeah... never.
13 {
14 std::cout << "Proper usage (for example): " << argv[1] << std::endl;
15 std::cout << "...will hopefully throw an exception instead of segfaulting." << std::endl;
16 return -1;
17 }
18 size_t nc = test_zero(0.1, true);
19 std::cout << "No confs visited: " << nc << std::endl;
20
21
22 }
23 #endif /* ISOSPEC_TESTS_SKIP_MAIN */
24
25
26 size_t test_zero(double threshold, bool print_confs)
27 {
28 int dimNumber = 1;
29 int isoNumbers[] = { 3 };
30 int atomCounts[] = { 100 };
31 double isoMasses[] = { 1.0, 2.0, 3.0 };
32 double isoProbs[] = { 0.0, 0.4, 0.6 };
33
34 double* IM = { isoMasses };
35 double* IP = { isoProbs };
36
37 Iso ii(dimNumber, isoNumbers, atomCounts, &IM, &IP);
38 IsoThresholdGenerator i(std::move(ii), false, threshold);
39 size_t confs_no = i.count_confs();
40 if(print_confs)
41 std::cout << "No. confs is: " << confs_no << std::endl;
42 i.reset();
43 int* confspace = new int[i.getAllDim()];
44 int no_visited = 0;
45 double total_prob = 0.0;
46 while(i.advanceToNextConfiguration())
47 {
48 i.get_conf_signature(confspace);
49 if(print_confs)
50 std::cout << "lprob: " << i.lprob() << " prob: " << i.prob() << " log(prob): " << log(i.prob()) << " mass: " << i.mass() << " conf: ";
51 if(print_confs)
52 printArray<int>(confspace, i.getAllDim());
53 no_visited += 1;
54 total_prob += i.prob();
55 }
56 delete[] confspace;
57 return no_visited;
58
59 }
0 #include <iostream>
1 #include "isoSpec++.h"
2
3 using namespace IsoSpec;
4
5 size_t test_layered(const char* formula, double total_prob, bool print_confs = false);
6
7 #ifndef ISOSPEC_TESTS_SKIP_MAIN
8 int main(int argc, char** argv)
9 {
10 if(argc < 3)
11 {
12 std::cout << "Proper usage (for example): ./from_formula_layered C10000H1000O1000N1000 0.9999" << std::endl;
13 std::cout << "...will print the minimal number of configurations necessary to cover 0.9999 probability of the above molecule" << std::endl;
14 return -1;
15 }
16
17 size_t no_confs = test_layered(argv[1], atof(argv[2]), true);
18
19 std::cout << "The number of visited configurations is:" << no_confs << std::endl;
20 }
21 #endif /* #ifndef ISOSPEC_TESTS_SKIP_MAIN */
22
23 size_t test_layered(const char* formula, double total_prob, bool print_confs)
24 {
25 IsoLayeredGenerator i(formula, total_prob, 0.3, 1000, 1000, true);
26 size_t no_visited = 0;
27 int* space = new int[i.getAllDim()];
28 while(i.advanceToNextConfiguration())
29 {
30 no_visited += 1;
31 if(print_confs)
32 {
33 std::cout << "PROB: " << i.prob() << " \tMASS: " << i.mass() << "\tCONF: ";
34 i.get_conf_signature(space);
35 for(int ii=0; ii<i.getAllDim(); ii++)
36 std::cout << space[ii] << " ";
37 std::cout << std::endl;
38 }
39
40 }
41 delete[] space;
42
43 return no_visited;
44 }
0 #include <iostream>
1 #include "isoSpec++.h"
2
3 using namespace IsoSpec;
4
5 #ifndef ISOSPEC_TESTS_SKIP_MAIN
6 size_t test_ordered(const char* formula, double total_prob, bool print_confs = false);
7
8 int main(int argc, char** argv)
9 {
10 if(argc < 3)
11 {
12 std::cout << "Proper usage (for example): " << argv[0] << " C10000H1000O1000N1000 0.9999" << std::endl;
13 std::cout << "...will print the minimal number of configurations necessary to cover 0.9999 probability of the above molecule" << std::endl;
14 return -1;
15 }
16
17 #ifndef ISOSPEC_TESTS_MEMSAN
18 size_t no_confs =
19 #endif
20 test_ordered(argv[1], atof(argv[2]), true);
21
22 #ifndef ISOSPEC_TESTS_MEMSAN
23 std::cout << "The number of visited configurations is: " << no_confs << std::endl;
24 #endif
25 }
26
27 #endif /* ISOSPEC_TESTS_SKIP_MAIN */
28
29
30 size_t test_ordered(const char* formula, double total_prob, bool print_confs)
31 {
32 IsoOrderedGenerator i(formula);
33 double target_prob = total_prob;
34
35 size_t no_visited = 0;
36 int* space = new int[i.getAllDim()];
37 while(target_prob > 0.0 && i.advanceToNextConfiguration())
38 {
39 target_prob -= i.prob();
40 no_visited += 1;
41 if(print_confs)
42 {
43 std::cout << "PROB: " << i.prob() << " \tMASS: " << i.mass() << "\tCONF: ";
44 i.get_conf_signature(space);
45 for(int ii=0; ii<i.getAllDim(); ii++)
46 std::cout << space[ii] << " ";
47 std::cout << std::endl;
48 }
49
50 }
51 delete[] space;
52 return no_visited;
53
54 }
0 #include <iostream>
1 #include "isoSpec++.h"
2 #include <cassert>
3
4 using namespace IsoSpec;
5
6 #ifndef ISOSPEC_TESTS_SKIP_MAIN
7
8 size_t test_threshold(const char* formula, double threshold, bool print_confs);
9
10 int main(int argc, char** argv)
11 {
12 if(argc < 3)
13 {
14 std::cout << "Proper usage (for example): ./from_formula_threshold C10000H1000O1000N1000 0.01" << std::endl;
15 std::cout << "...will the configurations with probability above 0.01 for the above molecule" << std::endl;
16 return -1;
17 }
18 size_t no_visited = test_threshold(argv[1], atof(argv[2]), true);
19
20 std::cout << "The number of visited configurations is:" << no_visited << std::endl;
21
22 }
23 #endif /* ISOSPEC_TESTS_SKIP_MAIN */
24
25
26 size_t test_threshold(const char* formula, double threshold, bool print_confs)
27 {
28
29 IsoThresholdGenerator i(formula, threshold, true, 100, 100, true);
30 size_t confs_no = i.count_confs();
31 if(print_confs)
32 std::cout << "No. confs is: " << confs_no << std::endl;
33 i.reset();
34 IsoThresholdGenerator i2(formula, threshold, true, 100, 100, true);
35 IsoThresholdGenerator i3(formula, threshold, true, 100, 100, false);
36 int* confspace = new int[i.getAllDim()];
37 int* confspace2 = new int[i2.getAllDim()];
38 //int* confspace3 = new int[i3.getAllDim()]; // these will be in different order...
39 int no_visited = 0;
40 double total_prob = 0.0;
41 while(i.advanceToNextConfiguration())
42 {
43 assert(i2.advanceToNextConfiguration());
44 assert(i3.advanceToNextConfiguration());
45 if(print_confs)
46 std::cout << "lprob: " << i.lprob() << " prob: " << i.prob() << " log(prob): " << log(i.prob()) << " mass: " << i.mass() << " conf: ";
47 assert(i.lprob() == i2.lprob());
48 assert(i.mass() == i2.mass());
49 assert(i.prob() == i2.prob());
50 i.get_conf_signature(confspace);
51 i2.get_conf_signature(confspace2);
52 assert(memcmp(confspace, confspace2, i.getAllDim()*sizeof(int)) == 0);
53 if(print_confs)
54 printArray<int>(confspace, i.getAllDim());
55 no_visited += 1;
56 total_prob += i.prob();
57 }
58 delete[] confspace;
59 delete[] confspace2;
60 assert(!i2.advanceToNextConfiguration());
61 assert(!i3.advanceToNextConfiguration());
62 assert(!i.advanceToNextConfiguration());
63 assert(!i2.advanceToNextConfiguration());
64 assert(!i3.advanceToNextConfiguration());
65 return no_visited;
66
67 }
0 #include <iostream>
1 #include "isoSpec++.h"
2 #include <cassert>
3
4 using namespace IsoSpec;
5
6 #ifndef ISOSPEC_TESTS_SKIP_MAIN
7
8 size_t test_threshold_simple(const char* formula, double threshold, bool print_confs);
9
10 int main(int argc, char** argv)
11 {
12 if(argc < 3)
13 {
14 std::cout << "Proper usage (for example): ./from_formula_threshold C10000H1000O1000N1000 0.01" << std::endl;
15 std::cout << "...will the configurations with probability above 0.01 for the above molecule" << std::endl;
16 return -1;
17 }
18 size_t no_visited = test_threshold_simple(argv[1], atof(argv[2]), true);
19
20 std::cout << "The number of visited configurations is:" << no_visited << std::endl;
21
22 }
23 #endif /* ISOSPEC_TESTS_SKIP_MAIN */
24
25
26 size_t test_threshold_simple(const char* formula, double threshold, bool print_confs)
27 {
28
29 IsoThresholdGenerator i(formula, threshold, true, 100, 100, true);
30 #ifdef TEST_SIZE
31 size_t confs_no = i.count_confs();
32 if(print_confs)
33 std::cout << "No. confs is: " << confs_no << std::endl;
34 i.reset();
35 #endif
36 int* confspace = new int[i.getAllDim()];
37 int no_visited = 0;
38 double total_prob = 0.0;
39 while(i.advanceToNextConfiguration())
40 {
41 i.get_conf_signature(confspace);
42 if(print_confs)
43 {
44 std::cout << "lprob: " << i.lprob() << " prob: " << i.prob() << " log(prob): " << log(i.prob()) << " mass: " << i.mass() << " conf: ";
45 printArray<int>(confspace, i.getAllDim());
46 }
47 no_visited += 1;
48 total_prob += i.prob();
49 }
50 delete[] confspace;
51 return no_visited;
52
53 }
0 #include <iostream>
1 #include "isoSpec++.h"
2 #include "summator.h"
3
4 using namespace IsoSpec;
5
6
7 int main()
8 {
9
10 SSummator s;
11 // unsigned int cnt_tot = 0;
12 // int total_t = 10;
13 double threshold = 0.999;
14 // double mmin = 3815900.0;
15 // double mmax = 3816000.0;
16 double mmin = -100000000000.0;
17 double mmax = 100000000000.0;
18
19 IsoLayeredGenerator* iso = new IsoLayeredGenerator("C1600H2700N1000", threshold, 0.3);
20 // IsoLayeredGenerator* iso = new IsoLayeredGenerator("H2C2", 0.5, 0.3);
21 unsigned int cnt = 0;
22 int cntr[10];
23 while(iso->advanceToNextConfiguration())
24 {
25 if(iso->mass() >= mmin and mmax >= iso->mass())
26 cnt++;
27 iso->get_conf_signature(cntr);
28
29 // std::cout << cntr[0] << " " << cntr[1] << " " << cntr[2] << " " << " " << cntr[3] << " " << cntr[4] << " " << cntr[5] << " " << iso->lprob() << std::endl;
30 if(cnt%10000 == 0)
31 std::cout << cnt << " " << s.get() << std::endl;
32
33 s.add(exp(iso->lprob()));
34 }
35 delete iso;
36
37 std::cout << "The isotopologue set containing at least " << threshold << " probability has " << cnt << " element(s)" << std::endl;
38 std::cout << "prob: " << s.get() << std::endl;
39 }
0 #define ISOSPEC_TESTS_SKIP_MAIN true
1 #include "from_formula_layered.cpp"
2 #include "from_formula_ordered.cpp"
3 #include "from_formula_threshold.cpp"
4 #include "from_formula_threshold_simple.cpp"
5 #include "element_zero.cpp"
6 #include "unity-build.cpp"
7 #include <vector>
8
9 #if !defined(ISOSPEC_TESTS_MEMSAN)
10 #define TEST(formula, prob, function) \
11 std::cout << "Testing " << formula << " prob: " << prob << " function: " << #function << "..." << std::flush; \
12 tmp = function(formula, prob, false); \
13 std::cout << " " << tmp << " confs." << std::endl; \
14 total += tmp;
15 #else
16 #define TEST(formula, prob, function) \
17 tmp = function(formula, prob, false); \
18 total += tmp;
19 #endif
20
21 int main()
22 {
23 bool zero_ok = false;
24 try{
25 test_zero(0.1, false);
26 }
27 catch(std::invalid_argument&)
28 {
29 zero_ok = true;
30 }
31 assert(zero_ok);
32 #if !defined(ISOSPEC_SKIP_SLOW_TESTS)
33 char test_formulas[] = "P1 P2 H1 H2 O1 O2 H2O1 C0 P0 C100O0P100 C100 P100 C1 H10C10O10N10S5 Se1 Se10 Sn1 Sn4 Sn4C1 C2H6O1 C1000 C1H1O2N2Se1Sn1P1 P1C1Sn1 Se5 Sn5 Se2Sn2C2O2N2S2B2He2U2Na2Cl2";
34 #else
35 char test_formulas[] = "P1 P2 H1 H2 O1 O2 H2O1 C0 P0 C100O0P100 C100 P100 C1 H3C3O3N3S3 Se1 Se3 Sn1 Sn3C1 C2H6O1 C1000 C1H1O2N2Se1Sn1P1 P1C1Sn1 Se5";
36 #endif
37 size_t tf_len = strlen(test_formulas);
38 std::vector<const char*> formulas;
39 formulas.push_back(test_formulas);
40 std::vector<float> probs = {0.0, 0.1, 0.5, 0.01, 0.9, 0.99, 0.01, 0.0001, 0.999, 0.362, 0.852348};
41
42 for(size_t ii=0; ii<tf_len; ii++)
43 {
44 if(test_formulas[ii] == ' ')
45 {
46 test_formulas[ii] = '\0';
47 formulas.push_back(&test_formulas[ii+1]);
48 }
49 }
50
51 size_t total = 0;
52 size_t tmp;
53 for(auto it_formula = formulas.begin(); it_formula != formulas.end(); it_formula++)
54 for(auto it_prob = probs.begin(); it_prob != probs.end(); it_prob++)
55 {
56 TEST(*it_formula, *it_prob, test_threshold_simple);
57 TEST(*it_formula, *it_prob, test_threshold);
58 TEST(*it_formula, *it_prob, test_layered);
59 TEST(*it_formula, *it_prob, test_ordered);
60 }
61
62 std::cout << "Total confs considered: " << total << std::endl;
63 }
0 #include <iostream>
1 #include "unity-build.cpp"
2 #include "marginalTrek++.h"
3 #include "summator.h"
4
5 using namespace IsoSpec;
6
7
8 int main()
9 {
10
11 SSummator s;
12 unsigned int cnt_tot = 0;
13 int total_t = 10;
14 double threshold = 0.1;
15 double masses[] = {1.0, 1000.0};
16 double probs[] = {0.9, 0.1};
17 Marginal m(masses, probs, 2, 100);
18 MarginalTrek mr(std::move(m));
19
20 int ii = 0;
21 while(mr.probeConfigurationIdx(ii))
22 {
23 std::cout << ii << " " << mr.conf_lprobs()[ii] << "\n";
24 ii++;
25 }
26
27 #if 0
28 IsoThresholdGeneratorBoundMass* isob = new IsoThresholdGeneratorBoundMass("C169719H270464N45688O52237S911", threshold, mmin, mmax, false);
29 std::cout << isob->getModeLProb() << std::endl;
30
31 unsigned int confsig[5];
32 double cnt = 1.0;
33 cnt_tot = 0;
34 double lc = isob->getModeLProb() + log(threshold);
35 while(isob->advanceToNextConfiguration())
36 {
37 cnt_tot++;
38 }
39 delete isob;
40
41 std::cout << "The isotopologue set containing at least 0.9 probability has " << cnt_tot << " element(s)" << std::endl;
42 #endif
43 }
0 #include <iostream>
1 #include <string>
2 #include <cassert>
3
4 #include "../../IsoSpec++/unity-build.cpp"
5
6 int main()
7 {
8 std::string formula = "C100";
9
10 int tabSize = 1000;
11 int hashSize = 1000;
12 double threshold = 0.01;
13 bool absolute = false;
14
15 threshold = 1e-2;
16 {
17 Iso* iso = new Iso(formula.c_str());
18 IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize);
19 Tabulator<IsoThresholdGenerator>* tabulator = new Tabulator<IsoThresholdGenerator>(generator, true, true, false, true);
20 int64_t size = tabulator->confs_no();
21 std::cout << size << std::endl;
22
23 delete iso;
24 delete generator;
25 delete tabulator;
26 }
27
28
29 threshold = 1e-200;
30 {
31 Iso* iso = new Iso(formula.c_str());
32 IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize);
33 Tabulator<IsoThresholdGenerator>* tabulator = new Tabulator<IsoThresholdGenerator>(generator, true, true, false, true);
34 int64_t size = tabulator->confs_no();
35 std::cout << size << std::endl;
36
37 delete iso;
38 delete generator;
39 delete tabulator;
40 }
41
42 formula = "C520H817N139O147S8";
43
44 threshold = 1e-10;
45 {
46 Iso* iso = new Iso(formula.c_str());
47 IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize);
48 Tabulator<IsoThresholdGenerator>* tabulator = new Tabulator<IsoThresholdGenerator>(generator, true, true, false, true);
49 int64_t size = tabulator->confs_no();
50 std::cout << size << std::endl;
51
52 delete iso;
53 delete generator;
54 delete tabulator;
55 }
56
57 threshold = 1e-50;
58 {
59 Iso* iso = new Iso(formula.c_str());
60 IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize);
61 Tabulator<IsoThresholdGenerator>* tabulator = new Tabulator<IsoThresholdGenerator>(generator, true, true, false, true);
62 int64_t size = tabulator->confs_no();
63 std::cout << size << std::endl;
64
65 delete iso;
66 delete generator;
67 delete tabulator;
68 }
69
70 threshold = 1e-100;
71 {
72 Iso* iso = new Iso(formula.c_str());
73 IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize);
74 Tabulator<IsoThresholdGenerator>* tabulator = new Tabulator<IsoThresholdGenerator>(generator, true, true, false, true);
75 int64_t size = tabulator->confs_no();
76 std::cout << size << std::endl;
77
78 delete iso;
79 delete generator;
80 delete tabulator;
81 }
82
83 #if 0
84 threshold = 1e-200;
85 {
86 Iso* iso = new Iso(formula.c_str());
87 IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize);
88 Tabulator<IsoThresholdGenerator>* tabulator = new Tabulator<IsoThresholdGenerator>(generator, true, true, false, true);
89 int64_t size = tabulator->confs_no();
90 std::cout << size << std::endl;
91
92 delete iso;
93 delete generator;
94 delete tabulator;
95 }
96
97 threshold = 1e-300;
98 {
99 Iso* iso = new Iso(formula.c_str());
100 IsoThresholdGenerator* generator = new IsoThresholdGenerator(std::move(*iso), threshold, absolute, tabSize, hashSize);
101 Tabulator<IsoThresholdGenerator>* tabulator = new Tabulator<IsoThresholdGenerator>(generator, true, true, false, true);
102 int64_t size = tabulator->confs_no();
103 std::cout << size << std::endl;
104
105 delete iso;
106 delete generator;
107 delete tabulator;
108 }
109 #endif
110 }
0 #include <iostream>
1 #include "../../IsoSpec++/unity-build.cpp"
2
3 using std::cout;
4 using std::endl;
5
6 using namespace IsoSpec;
7
8 int main(void){
9 // int isotopeNumbers[] = {2, 3};
10 // int config_size = isotopeNumbers[0] + isotopeNumbers[1];
11 // int atomCounts[] = {10, 10};
12 // double isotopeMasses[] = {1.0, 2.0, 3.0, 4.0, 5.0};
13 // double isotopeProbabilities[] = {0.5, 0.5, 0.5, 0.3, 0.2};
14
15 // IsoThresholdGenerator* generator = new IsoThresholdGenerator(
16 // 2,
17 // isotopeNumbers,
18 // atomCounts,
19 // isotopeMasses,
20 // isotopeProbabilities,
21 // .001,
22 // true,
23 // 1000,
24 // 1000);
25
26 // cout << reinterpret_cast<IsoThresholdGenerator*>(generator)->getAllDim() << endl;
27 // void* tabulator = setupThresholdTabulator(generator, true, true, true, true);
28
29 return 0;
30 }
0 #include <iostream>
1 #include "isoSpec++.h"
2 #include "summator.h"
3
4 using namespace IsoSpec;
5
6 int main()
7 {
8
9 SSummator s;
10 // unsigned int cnt_tot = 0;
11 // int total_t = 10;
12 double threshold = 0.01;
13 // double mmin = 3815900.0;
14 // double mmax = 3816000.0;
15 double mmin = -100000000000.0;
16 double mmax = 100000000000.0;
17 const char formula[] = "C169719H270464N45688O52237S911";
18 // const char formula[] = "H2O1";
19 // const char formula[] = "C63H98N18O13S1"; // substance P
20 // const char formula[] = "C520H817N139O147S8"; // Human insulin
21 IsoThresholdGenerator* iso = new IsoThresholdGenerator(formula, threshold, false);
22 unsigned int cnt = 0;
23 while(iso->advanceToNextConfiguration())
24 {
25 if(iso->mass() >= mmin and mmax >= iso->mass())
26 cnt++;
27 s.add(iso->prob());
28 }
29 delete iso;
30
31 std::cout << "The isotopologue set containing at least 0.9 probability has " << cnt << " element(s)" << std::endl;
32 std::cout << "prob: " << s.get() << std::endl;
33 }
0 import sys
1 import IsoSpecPy
2 from math import exp, log
3
4 def sprint(s):
5 sys.stdout.write(str(s))
6 sys.stdout.flush()
7
8 try:
9 import OldIsoSpecPy
10 except ImportError:
11 print("This test compares the results of installed IsoSpec with IsoSpec version 1.0.7, installed as OldIsoSpecPy")
12 print("You must install it, using:")
13 print("pip install OldIsoSpecPy --index-url https://test.pypi.org/simple/")
14 sys.exit(1)
15
16
17 # Correctness tests comparing IsoSpecPy 1.0.7 and HEAD. The trouble here is that due to slightly different way things are calculated
18 # we get different rounding errors, and therefore slightly different results - and that's OK. The function kinda_like reflects that
19 # - but is still WAAAY too strict. Often we can justifiably get different configurations, or different counts of configurations...
20
21 molecules = "H2O1 C100 P1 P100 C1 H10C10O10N10S5 Se1 Se10 Sn1 Sn4 Sn4C1 C2H6O1 C1000 C520H817N139O147S8 C1H1O2N2Se1Sn1P1 P1C1Sn1 Se5 Sn5 Se2Sn2C2O2N2S2B2He2U2Na2Cl2".split()
22
23 parameters = list(map(float, "0.0 0.1 0.5 0.01 0.9 0.99 0.01 0.0001 0.999 0.362 0.852348".split()))
24
25 def kinda_like(o1, o2):
26 if type(o1) in (list, tuple) and type(o2) in (list, tuple) :
27 assert len(o1) == len(o2)
28 assert all(kinda_like(oo1, oo2) for oo1, oo2 in zip(o1, o2))
29 if type(o1) == type(o2) == float:
30 assert o1*o2 >= 0.0 # same sign check
31 assert abs(o1*0.99)-0.000001 <= abs(o2) <= abs(o1*1.01)+0.000001
32 return True
33
34 def sort_confs(confs):
35 if len(confs[0]) == 0:
36 return confs
37 l = list(zip(*confs))
38 l.sort(key = lambda x: -x[1])
39
40 return ([x[0] for x in l], [x[1] for x in l], [x[2] for x in l])
41
42 def confs_from_ordered_generator(formula, target_prob):
43 ret = ([], [], [])
44 prob = 0.0
45 for conf in IsoSpecPy.IsoOrderedGenerator(formula=formula, get_confs=True):
46 conf = (conf[0], log(conf[1]), conf[2])
47 if prob >= target_prob and target_prob < 1.0:
48 return ret
49 ret[0].append(conf[0])
50 prob += exp(conf[1])
51 ret[1].append(conf[1])
52 ret[2].append([item for sublist in conf[2] for item in sublist])
53 return ret
54
55 def confs_from_layered_generator(formula, target_prob):
56 ret = ([], [], [])
57 for conf in IsoSpecPy.IsoLayeredGenerator(formula=formula, prob_to_cover = target_prob, get_confs=True, do_trim=True):
58 conf = (conf[0], log(conf[1]), conf[2])
59 ret[0].append(conf[0])
60 ret[1].append(conf[1])
61 ret[2].append([item for sublist in conf[2] for item in sublist])
62
63 return sort_confs(ret)
64
65 def confs_from_threshold_generator(formula, target_prob):
66 ret = ([], [], [])
67 for conf in IsoSpecPy.IsoThresholdGenerator(formula=formula, threshold = target_prob, absolute = True, get_confs=True):
68 conf = (conf[0], log(conf[1]), conf[2])
69 ret[0].append(conf[0])
70 ret[1].append(conf[1])
71 ret[2].append([item for sublist in conf[2] for item in sublist])
72
73 return sort_confs(ret)
74
75
76 is_ok = False
77 try:
78 i = IsoSpecPy.IsoThreshold(0.1, False, atomCounts = [100], isotopeMasses = [[1.0, 2.0, 3.0]], isotopeProbabilities = [[0.0, 0.6, 0.4]])
79 for x in i:
80 print(x)
81 except ValueError:
82 is_ok = True
83 assert is_ok
84
85 for molecule in molecules:
86 for parameter in parameters:
87 sprint("{} {}... ".format(molecule, parameter))
88 old_ordered = OldIsoSpecPy.IsoSpecPy.IsoSpec.IsoFromFormula(molecule, parameter, method="ordered").getConfs()
89 sprint(len(old_ordered[0]))
90 new_ordered = confs_from_ordered_generator(molecule, parameter)
91 assert kinda_like(new_ordered, old_ordered)
92 new_layered = confs_from_layered_generator(molecule, parameter)
93 assert kinda_like(new_layered, new_ordered)
94 if len(new_ordered[1]) > 0:
95 new_threshold = exp(new_ordered[1][-1]-0.00000001)
96 else:
97 new_threshold = 1.1
98 new_threshold_res = confs_from_threshold_generator(molecule, new_threshold)
99 assert kinda_like(new_ordered, new_threshold_res)
100
101 if parameter > 0:
102 sprint(" thresholded: ")
103 new_thr_r = confs_from_threshold_generator(molecule, parameter)
104 sprint(len(new_thr_r[0]))
105 old_thr_r = sort_confs(OldIsoSpecPy.IsoSpecPy.IsoSpec.IsoFromFormula(molecule, parameter, method="threshold_absolute").getConfs())
106
107 assert kinda_like(new_thr_r, old_thr_r)
108
109 print("... OK!")
110
111
112
0 # add this file to the tests
1
2 library(enviPat)
3 library(stringr)
4 library(IsoSpecR)
5 library(tidyverse)
6 library(microbenchmark)
7 library(jsonlite)
8
9 data(isotopicData)
10 # store args in function env for multiple calls without the passing of args
11 envipat_call_factory = function(...) function() isopattern(...)
12 is.error = function(x) inherits(x, "try-error")
13
14 # test the call for results and their timing
15 test_envipat = function(..., times = 100, timing = T){
16 envipat_call = envipat_call_factory(...)
17 out = list()
18 call_result = try(envipat_call())
19 if(is.error(call_result)){
20 return(call_result)
21 } else{
22 call_result = call_result[[1]]
23 if(timing) out$timing = microbenchmark(envipat_call(), times = times, unit = 'us')
24 call_result = tbl_df(call_result)
25 call_result = call_result[,1:2]
26 colnames(call_result) = c('mass', 'prob')
27 call_result = arrange(tbl_df(call_result), desc(prob))
28 out$call_result = call_result
29 return(out)
30 }
31 }
32
33
34 run_test = function(molecule, threshold, out_path, timing=T){
35 res = test_envipat(isotopes = isotopicData$IsoSpec,
36 chemforms = molecule,
37 threshold = threshold,
38 verbose = F,
39 rel_to = 2,
40 timing = timing)
41 if(is.error(res)){
42 return(res)
43 } else {
44 file_name = file.path(out_path, paste0(molecule, "_", threshold, ".tsv"))
45 readr::write_tsv(res$call_result, file_name, col_names = F)
46 return(res$timing)
47 }
48 }
49
50 out_path = "/Users/matteo/Projects/isospec/IsoSpec/tests/envipat_results"
51 thresholds = seq(10^{-5}, .05, by=.01)
52
53 data(chemforms)
54 atoms = c("C", "H", "N", "O", "S")
55 envipat_mols = chemforms[!str_detect(chemforms, "\\[")]
56 envipat_path= file.path(out_path, "envipat_mols")
57 mist_mols = c("P1", "P2", "H1", "H2", "O1", "O2", "H2O1", "C0", "P0", "C100O0P100", "C100", "P100", "C1", "H10C10O10N10S5", "Se1", "Se10", "Sn1", "Sn4", "Sn4C1", "C2H6O1", "C1000", "C1H1O2N2Se1Sn1P1", "P1C1Sn1", "Se5", "Sn5", "Se2Sn2C2O2N2S2B2He2U2Na2Cl2")
58 mist_path = file.path(out_path, "mist_mols")
59 human = fromJSON("/Users/matteo/Projects/furious_fastas/py_data/human_fastas_small.json")
60 human_path= file.path(out_path, "human_uniprot_mols")
61 human = human[,atoms]
62 human = sapply(
63 split(human, 1:nrow(human)),
64 function(x){
65 a = atoms[x > 0]
66 x = x[x > 0]
67 paste(a, x, sep='', collapse='')
68 },
69 USE.NAMES = F)
70
71 timeout = R.utils::withTimeout
72 run_no_timing = function(..., secs) try(timeout(run_test(...),
73 timeout = secs),
74 silent = T)
75
76 run_tests = function(molecules, out_path, thresholds, secs = 10, mc.cores = 5)
77 parallel::mclapply(thresholds,
78 function(thr) sapply(molecules, run_no_timing,
79 threshold = thr,
80 out_path = out_path,
81 secs = secs),
82 mc.cores = 5)
83
84 mist_timings = run_tests(mist_mols, mist_path, thresholds)
85 envipat_timings = run_tests(envipat_mols, envipat_path, thresholds)
86 human_timings = run_tests(human[1:2000], human_path, thresholds[1])
87
88 save(mist_timings,
89 envipat_timings,
90 human_timings,
91 file = paste0(out_path,"timings_envipat.Rda"))