-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfull.py
executable file
·74 lines (56 loc) · 1.9 KB
/
full.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#! /usr/bin/python3
import sys
import argparse
import signal
import itertools
import math
import tools
def candidate_pairs(spectrum, parent_mass):
pairs = []
for left, right in itertools.combinations(spectrum, 2):
if not math.isclose(left + right, parent_mass, rel_tol=1.e-6):
continue
pairs.append((left, right))
return pairs
def _check_mass(string, masses, parent_mass):
mass = tools.spectrometry.mass(string)
for left, right in itertools.combinations(masses, 2):
if math.isclose(parent_mass - mass, left + right, rel_tol=1.e-6):
return True
return False
def _infer_protein(masses, n):
for i, j in itertools.combinations(range(len(masses) - n), 2):
mass = masses[j] - masses[i]
acid = tools.spectrometry.find_amino_acid(mass)
if acid is None:
continue
elif n == 1:
yield acid
else:
for tail in _infer_protein(masses[j:], n-1):
yield acid + tail
def infer_protein(pairs, n, parent_mass):
masses = itertools.chain.from_iterable(pairs)
masses = sorted(masses)
for protein in _infer_protein(masses, n):
if _check_mass(protein, masses, parent_mass):
return protein
assert False, 'should not be reached'
def main(args):
inputs = map(float, sys.stdin.read().split())
parent_mass = next(inputs)
spectrum = list(inputs)
n = len(spectrum) // 2 - 1
pairs = candidate_pairs(spectrum, parent_mass)
protein = infer_protein(pairs, n, parent_mass)
print(protein)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='description',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
args = parser.parse_args()
try:
main(args)
except BrokenPipeError:
sys.exit(128 + signal.SIGPIPE)
except KeyboardInterrupt:
sys.exit(128 + signal.SIGINT)