Skip to content

Commit

Permalink
Parse precursor charge specified in PEPMASS (override CHARGE)
Browse files Browse the repository at this point in the history
  • Loading branch information
levitsky committed Jul 28, 2024
1 parent 67cee99 commit d581317
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 8 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
4.7.3a2
-------

- Add compatibility with NumPy 2.0.
- Fix `#153 <https://github.com/levitsky/pyteomics/issues/153>`_. MGF parser now recognizes precursor charge specified
on the PEPMASS line. If CHARGE is also specified, it is ignored.

4.7.2
-----

Expand Down
29 changes: 22 additions & 7 deletions pyteomics/mgf.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,25 @@ def __setstate__(self, state):
def parse_precursor_charge(charge_text, list_only=False):
return aux._parse_charge(charge_text, list_only=list_only)

@staticmethod
def parse_pepmass_charge(pepmass_str):
split = pepmass_str.split()
if len(split) > 3:
raise aux.PyteomicsError('MGF format error: cannot parse '
'PEPMASS = {}'.format(pepmass_str))
elif len(split) == 3:
charge = split[2]
try:
pepmass = tuple(map(float, split[:2]))
except ValueError:
raise aux.PyteomicsError('MGF format error: cannot parse '
'PEPMASS = {}'.format(pepmass_str))
else:
pepmass = tuple(map(float, split[:2]))
pepmass = pepmass + (None,) * (2-len(pepmass))
charge = None
return pepmass, charge

@staticmethod
def parse_peak_charge(charge_text, list_only=False):
return aux._parse_charge(charge_text, list_only=False)
Expand Down Expand Up @@ -203,13 +222,9 @@ def _read_spectrum_lines(self, lines):
pass
elif sline == 'END IONS':
if 'pepmass' in params:
try:
pepmass = tuple(map(float, params['pepmass'].split()))
except ValueError:
raise aux.PyteomicsError('MGF format error: cannot parse '
'PEPMASS = {}'.format(params['pepmass']))
else:
params['pepmass'] = pepmass + (None,) * (2-len(pepmass))
params['pepmass'], charge = self.parse_pepmass_charge(params['pepmass'])
if charge is not None:
params['charge'] = charge
if isinstance(params.get('charge'), aux.basestring):
params['charge'] = self.parse_precursor_charge(params['charge'], True)
if 'rtinseconds' in params:
Expand Down
2 changes: 1 addition & 1 deletion pyteomics/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"""

__version__ = '4.7.3a1'
__version__ = '4.7.3a2'

from collections import namedtuple
import re
Expand Down
6 changes: 6 additions & 0 deletions tests/test_mgf.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,12 @@ def test_charge_repr_multiple(self):
self.assertEqual(mgf._charge_repr('charge', '2+, 3+'), 'CHARGE=2+ and 3+')
self.assertEqual(mgf._charge_repr('charge', np.array([2, 3])), 'CHARGE=2+ and 3+')

def test_pepmass_parsing(self):
with mgf.MGF('test_pepmass.mgf') as f:
spectra = list(f)
self.assertEqual(len(spectra), 3)
self.assertEqual(spectra[0]['params'], spectra[1]['params'])
self.assertEqual(spectra[0]['params'], spectra[2]['params'])

if __name__ == "__main__":
unittest.main()

0 comments on commit d581317

Please sign in to comment.