Skip to content

Commit 1d4d57c

Browse files
committed
Implement retrieval of special confs
1 parent 24ddee6 commit 1d4d57c

File tree

9 files changed

+144
-23
lines changed

9 files changed

+144
-23
lines changed

src/IsoSpec++/cwrapper.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ double getLightestPeakLProbIso(void* iso)
6464
return reinterpret_cast<Iso*>(iso)->getLightestPeakLProb();
6565
}
6666

67+
void getLightestPeakSignature(void* iso, int* space)
68+
{
69+
reinterpret_cast<Iso*>(iso)->getLightestPeakSignature(space);
70+
}
71+
6772
double getHeaviestPeakMassIso(void* iso)
6873
{
6974
return reinterpret_cast<Iso*>(iso)->getHeaviestPeakMass();
@@ -74,6 +79,11 @@ double getHeaviestPeakLProbIso(void* iso)
7479
return reinterpret_cast<Iso*>(iso)->getHeaviestPeakLProb();
7580
}
7681

82+
void getHeaviestPeakSignature(void* iso, int* space)
83+
{
84+
reinterpret_cast<Iso*>(iso)->getHeaviestPeakSignature(space);
85+
}
86+
7787
double getMonoisotopicPeakMassIso(void* iso)
7888
{
7989
return reinterpret_cast<Iso*>(iso)->getMonoisotopicPeakMass();
@@ -84,6 +94,11 @@ double getMonoisotopicPeakLProbIso(void* iso)
8494
return reinterpret_cast<Iso*>(iso)->getMonoisotopicPeakLProb();
8595
}
8696

97+
void getMonoisotopicPeakSignature(void* iso, int* space)
98+
{
99+
reinterpret_cast<Iso*>(iso)->getMonoisotopicPeakSignature(space);
100+
}
101+
87102
double getModeLProbIso(void* iso)
88103
{
89104
return reinterpret_cast<Iso*>(iso)->getModeLProb();

src/IsoSpec++/cwrapper.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,13 @@ ISOSPEC_C_API void * isoFromFasta(const char* fasta, bool use_nominal_masses, bo
4141

4242
ISOSPEC_C_API double getLightestPeakMassIso(void* iso);
4343
ISOSPEC_C_API double getLightestPeakLProbIso(void* iso);
44+
ISOSPEC_C_API void getLightestPeakSignature(void* iso, int* space);
4445
ISOSPEC_C_API double getHeaviestPeakMassIso(void* iso);
4546
ISOSPEC_C_API double getHeaviestPeakLProbIso(void* iso);
47+
ISOSPEC_C_API void getHeaviestPeakSignature(void* iso, int* space);
4648
ISOSPEC_C_API double getMonoisotopicPeakMassIso(void* iso);
4749
ISOSPEC_C_API double getMonoisotopicPeakLProbIso(void* iso);
50+
ISOSPEC_C_API void getMonoisotopicPeakSignature(void* iso, int* space);
4851
ISOSPEC_C_API double getModeLProbIso(void* iso);
4952
ISOSPEC_C_API double getModeMassIso(void* iso);
5053
ISOSPEC_C_API double getTheoreticalAverageMassIso(void* iso);

src/IsoSpec++/isoSpec++.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,17 @@ double Iso::getLightestPeakLProb() const
258258
return lprob;
259259
}
260260

261+
void Iso::getLightestPeakSignature(int* space) const
262+
{
263+
for (int ii = 0; ii < dimNumber; ii++)
264+
{
265+
size_t lightest_idx = marginals[ii]->getLightestAtomIndex();
266+
for(int jj = 0; jj < isotopeNumbers[ii]; jj++)
267+
space[jj] = (jj == lightest_idx ? atomCounts[ii] : 0);
268+
space += isotopeNumbers[ii];
269+
}
270+
}
271+
261272
double Iso::getHeaviestPeakMass() const
262273
{
263274
double mass = 0.0;
@@ -274,6 +285,17 @@ double Iso::getHeaviestPeakLProb() const
274285
return lprob;
275286
}
276287

288+
void Iso::getHeaviestPeakSignature(int* space) const
289+
{
290+
for (int ii = 0; ii < dimNumber; ii++)
291+
{
292+
size_t heaviest_idx = marginals[ii]->getHeaviestAtomIndex();
293+
for(int jj = 0; jj < isotopeNumbers[ii]; jj++)
294+
space[jj] = (jj == heaviest_idx ? atomCounts[ii] : 0);
295+
space += isotopeNumbers[ii];
296+
}
297+
}
298+
277299
double Iso::getMonoisotopicPeakMass() const
278300
{
279301
double mass = 0.0;
@@ -290,6 +312,17 @@ double Iso::getMonoisotopicPeakLProb() const
290312
return lprob;
291313
}
292314

315+
void Iso::getMonoisotopicPeakSignature(int* space) const
316+
{
317+
for (int ii = 0; ii < dimNumber; ii++)
318+
{
319+
size_t monoisotopic_idx = marginals[ii]->getMonoisotopicAtomIndex();
320+
for(int jj = 0; jj < isotopeNumbers[ii]; jj++)
321+
space[jj] = (jj == monoisotopic_idx ? atomCounts[ii] : 0);
322+
space += isotopeNumbers[ii];
323+
}
324+
}
325+
293326
double Iso::getUnlikeliestPeakLProb() const
294327
{
295328
double lprob = 0.0;

src/IsoSpec++/isoSpec++.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,24 @@ class ISOSPEC_EXPORT_SYMBOL Iso {
138138
//! Get the log-probability of the lightest peak in the isotopic distribution.
139139
double getLightestPeakLProb() const;
140140

141+
/*!
142+
Write the counts of isotopes in the lightest peak into target memory location. It must be large enough to accomodate it.
143+
\param space An array where counts of isotopes shall be written. Must be as big as the overall number of isotopes.
144+
*/
145+
void getLightestPeakSignature(int* space) const;
146+
141147
//! Get the mass of the heaviest peak in the isotopic distribution.
142148
double getHeaviestPeakMass() const;
143149

144150
//! Get the log-probability of the heaviest peak in the isotopic distribution.
145151
double getHeaviestPeakLProb() const;
146152

153+
/*!
154+
Write the counts of isotopes in the heaviest peak into target memory location. It must be large enough to accomodate it.
155+
\param space An array where counts of isotopes shall be written. Must be as big as the overall number of isotopes.
156+
*/
157+
void getHeaviestPeakSignature(int* space) const;
158+
147159
/*!
148160
Get the mass of the monoisotopic peak in the isotopic distribution. Monoisotopc molecule is defined as
149161
consisting only of the most frequent isotopes of each element. These are often (but not always) the
@@ -158,6 +170,12 @@ class ISOSPEC_EXPORT_SYMBOL Iso {
158170
*/
159171
double getMonoisotopicPeakLProb() const;
160172

173+
/*!
174+
Write the counts of isotopes in the monoisotopic peak into target memory location. It must be large enough to accomodate it.
175+
\param space An array where counts of isotopes shall be written. Must be as big as the overall number of isotopes.
176+
*/
177+
void getMonoisotopicPeakSignature(int* space) const;
178+
161179
//! Get the log-probability of the mode-configuration (if there are many modes, they share this value).
162180
double getModeLProb() const;
163181

src/IsoSpec++/marginalTrek++.cpp

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,7 @@ double Marginal::getLightestConfMass() const
259259
double Marginal::getLightestConfLProb() const
260260
{
261261
std::unique_ptr<int[]> lightest_conf = std::make_unique<int[]>(isotopeNo);
262-
size_t lightest_idx = 0;
263-
double min_mass = std::numeric_limits<double>::infinity();
264-
for(unsigned int ii = 0; ii < isotopeNo; ii++)
265-
if( min_mass > atom_masses[ii] )
266-
{
267-
min_mass = atom_masses[ii];
268-
lightest_idx = ii;
269-
}
262+
size_t lightest_idx = getLightestAtomIndex();
270263
for(unsigned int ii = 0; ii < isotopeNo; ii++)
271264
lightest_conf[ii] = (ii == lightest_idx ? atomCnt : 0);
272265
return logProb(lightest_conf.get());
@@ -284,14 +277,7 @@ double Marginal::getHeaviestConfMass() const
284277
double Marginal::getHeaviestConfLProb() const
285278
{
286279
std::unique_ptr<int[]> heaviest_conf = std::make_unique<int[]>(isotopeNo);
287-
size_t heaviest_idx = 0;
288-
double max_mass = -std::numeric_limits<double>::infinity();
289-
for(unsigned int ii = 0; ii < isotopeNo; ii++)
290-
if( max_mass < atom_masses[ii] )
291-
{
292-
max_mass = atom_masses[ii];
293-
heaviest_idx = ii;
294-
}
280+
size_t heaviest_idx = getHeaviestAtomIndex();
295281
for(unsigned int ii = 0; ii < isotopeNo; ii++)
296282
heaviest_conf[ii] = (ii == heaviest_idx ? atomCnt : 0);
297283
return logProb(heaviest_conf.get());
@@ -310,6 +296,32 @@ size_t Marginal::getMonoisotopicAtomIndex() const
310296
return found_idx;
311297
}
312298

299+
size_t Marginal::getLightestAtomIndex() const
300+
{
301+
double found_mass = std::numeric_limits<double>::infinity();
302+
size_t found_idx = 0;
303+
for(unsigned int ii = 0; ii < isotopeNo; ii++)
304+
if( found_mass > atom_masses[ii] )
305+
{
306+
found_mass = atom_masses[ii];
307+
found_idx = ii;
308+
}
309+
return found_idx;
310+
}
311+
312+
size_t Marginal::getHeaviestAtomIndex() const
313+
{
314+
double found_mass = -std::numeric_limits<double>::infinity();
315+
size_t found_idx = 0;
316+
for(unsigned int ii = 0; ii < isotopeNo; ii++)
317+
if( found_mass < atom_masses[ii] )
318+
{
319+
found_mass = atom_masses[ii];
320+
found_idx = ii;
321+
}
322+
return found_idx;
323+
}
324+
313325
double Marginal::getMonoisotopicConfMass() const
314326
{
315327
size_t idx = getMonoisotopicAtomIndex();

src/IsoSpec++/marginalTrek++.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,18 @@ class Marginal
124124
*/
125125
size_t getMonoisotopicAtomIndex() const;
126126

127+
//! Get the index of the lightest atom.
128+
/*!
129+
\return The index of the lightest isotope of the element.
130+
*/
131+
size_t getLightestAtomIndex() const;
132+
133+
//! Get the index of the heaviest atom.
134+
/*!
135+
\return The index of the heaviest isotope of the element.
136+
*/
137+
size_t getHeaviestAtomIndex() const;
138+
127139
//! The the mass of the mode subisotopologue.
128140
/*!
129141
\return The mass of one of the most probable subisotopologues.

src/IsoSpecPy/IsoSpecPy.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ def __init__(self, formula="",
202202
offsets.append(tuple(newl))
203203
self.offsets = tuple(offsets)
204204

205+
self.conf_space = isoFFI.ffi.new("int[" + str(sum(self.isotopeNumbers)) + "]")
206+
205207
self.iso = self.ffi.setupIso(self.dimNumber, self.isotopeNumbers,
206208
self.atomCounts,
207209
[i/charge for s in self.isotopeMasses for i in s],
@@ -223,6 +225,11 @@ def getLightestPeakLProb(self):
223225
"""Get the log probability of the lightest peak in the isotopic distribution."""
224226
return self.ffi.getLightestPeakLProbIso(self.iso)
225227

228+
def getLightestPeakConf(self):
229+
"""Get the isotopic configuration of the lightest peak in the isotopic distribution."""
230+
self.ffi.getLightestPeakSignature(self.iso, self.conf_space)
231+
return self.parse_conf(self.conf_space)
232+
226233
def getHeaviestPeakMass(self):
227234
"""Get the heaviest peak in the isotopic distribution."""
228235
return self.ffi.getHeaviestPeakMassIso(self.iso)
@@ -231,6 +238,11 @@ def getHeaviestPeakLProb(self):
231238
"""Get the log probability of the heaviest peak in the isotopic distribution."""
232239
return self.ffi.getHeaviestPeakLProbIso(self.iso)
233240

241+
def getHeaviestPeakConf(self):
242+
"""Get the isotopic configuration of the heaviest peak in the isotopic distribution."""
243+
self.ffi.getHeaviestPeakSignature(self.iso, self.conf_space)
244+
return self.parse_conf(self.conf_space)
245+
234246
def getMonoisotopicPeakMass(self):
235247
"""Get the monoisotopic mass of the peak."""
236248
return self.ffi.getMonoisotopicPeakMassIso(self.iso)
@@ -239,6 +251,11 @@ def getMonoisotopicPeakLProb(self):
239251
"""Get the log probability of the monoisotopic peak in the isotopic distribution."""
240252
return self.ffi.getMonoisotopicPeakLProbIso(self.iso)
241253

254+
def getMonoisotopicPeakConf(self):
255+
"""Get the isotopic configuration of the monoisotopic peak in the isotopic distribution."""
256+
self.ffi.getMonoisotopicPeakSignature(self.iso, self.conf_space)
257+
return self.parse_conf(self.conf_space)
258+
242259
def getModeLProb(self):
243260
"""Get the log probability of the most probable peak(s) in the isotopic distribution."""
244261
return self.ffi.getModeLProbIso(self.iso)
@@ -700,7 +717,6 @@ def __init__(self, formula="", get_confs=False, **kwargs):
700717
"""
701718
self.cgen = None
702719
super(IsoGenerator, self).__init__(formula=formula, get_confs=get_confs, **kwargs)
703-
self.conf_space = isoFFI.ffi.new("int[" + str(sum(self.isotopeNumbers)) + "]")
704720
self.firstuse = True
705721

706722
def __iter__(self):

src/IsoSpecPy/isoFFI.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ def __init__(self):
2323
2424
double getLightestPeakMassIso(void* iso);
2525
double getLightestPeakLProbIso(void* iso);
26+
void getLightestPeakSignature(void* iso, int* space);
2627
double getHeaviestPeakMassIso(void* iso);
2728
double getHeaviestPeakLProbIso(void* iso);
29+
void getHeaviestPeakSignature(void* iso, int* space);
2830
double getMonoisotopicPeakMassIso(void* iso);
2931
double getMonoisotopicPeakLProbIso(void* iso);
32+
void getMonoisotopicPeakSignature(void* iso, int* space);
3033
double getModeLProbIso(void* iso);
3134
double getModeMassIso(void* iso);
3235
double getTheoreticalAverageMassIso(void* iso);

tests/Python/test_iface.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,14 @@ def test_lightest_peak():
173173
iso = IsoSpecPy.Iso(formula=formula)
174174
lightest_mass = iso.getLightestPeakMass()
175175
lightest_lprob = iso.getLightestPeakLProb()
176-
iso_threshold = IsoSpecPy.IsoThreshold(0.0, formula=formula)
176+
lightest_conf = iso.getLightestPeakConf()
177+
iso_threshold = IsoSpecPy.IsoThreshold(0.0, formula=formula, get_confs=True)
177178
masses = list(iso_threshold.masses)
178179
probs = list(iso_threshold.probs)
180+
confs = list(iso_threshold.confs)
179181
min_index = masses.index(min(masses))
180-
print(lightest_mass, lightest_lprob, end=" ")
182+
print(lightest_conf, lightest_mass, lightest_lprob, end=" ")
183+
assert lightest_conf == confs[min_index]
181184
assert lightest_mass == masses[min_index]
182185
assert math.isclose(lightest_lprob, math.log(probs[min_index]), rel_tol=1e-9)
183186
print("OK!")
@@ -188,11 +191,14 @@ def test_heaviest_peak():
188191
iso = IsoSpecPy.Iso(formula=formula)
189192
heaviest_mass = iso.getHeaviestPeakMass()
190193
heaviest_lprob = iso.getHeaviestPeakLProb()
191-
iso_threshold = IsoSpecPy.IsoThreshold(0.0, formula=formula)
194+
heaviest_conf = iso.getHeaviestPeakConf()
195+
iso_threshold = IsoSpecPy.IsoThreshold(0.0, formula=formula, get_confs=True)
192196
masses = list(iso_threshold.masses)
193197
probs = list(iso_threshold.probs)
198+
confs = list(iso_threshold.confs)
194199
max_index = masses.index(max(masses))
195-
print(heaviest_mass, heaviest_lprob, end=" ")
200+
print(heaviest_conf, heaviest_mass, heaviest_lprob, end=" ")
201+
assert heaviest_conf == confs[max_index]
196202
assert heaviest_mass == masses[max_index]
197203
assert math.isclose(heaviest_lprob, math.log(probs[max_index]), rel_tol=1e-9)
198204
print("OK!")
@@ -203,13 +209,16 @@ def test_monoisotopic_peak():
203209
iso = IsoSpecPy.Iso(formula=formula)
204210
monoisotopic_mass = iso.getMonoisotopicPeakMass()
205211
monoisotopic_lprob = iso.getMonoisotopicPeakLProb()
212+
monoisotopic_conf = iso.getMonoisotopicPeakConf()
206213
iso_threshold = IsoSpecPy.IsoThreshold(0.0, formula=formula, get_confs=True)
207214
masses = list(iso_threshold.masses)
208215
probs = list(iso_threshold.probs)
209216
confs = list(iso_threshold.confs)
210-
monoisotopic_conf = ((10, 0), (0, 1000), (10, 0), (0,0,0,0,0,0,0,1,0,0))
217+
monoisotopic_conf2 = ((10, 0), (0, 1000), (10, 0), (0,0,0,0,0,0,0,1,0,0))
211218
monoisotopic_peak_idx = confs.index(monoisotopic_conf)
212-
print(monoisotopic_mass, monoisotopic_lprob, end=" ")
219+
print(monoisotopic_conf, monoisotopic_mass, monoisotopic_lprob, end=" ")
220+
assert monoisotopic_conf == confs[monoisotopic_peak_idx]
221+
assert monoisotopic_conf == monoisotopic_conf2
213222
assert monoisotopic_mass == masses[monoisotopic_peak_idx]
214223
assert math.isclose(monoisotopic_lprob, math.log(probs[monoisotopic_peak_idx]), rel_tol=1e-9)
215224
print("OK!")

0 commit comments

Comments
 (0)