Skip to content

Commit

Permalink
add more species names patterns to be recognized
Browse files Browse the repository at this point in the history
  • Loading branch information
skuschel committed Dec 5, 2014
1 parent 3739f68 commit 9eb9f94
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 31 deletions.
76 changes: 45 additions & 31 deletions postpic/analyzer/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ class SpeciesIdentifier(PhysicalConstants):
'gold20': True}

# unit: amu
_masslistelement = {'H': 1, 'He': 4, 'C': 12, 'N': 14, 'O': 16, 'F': 19,
'Ne': 20.2, 'Al': 27, 'Si': 28, 'Ar': 40, 'Au': 197}
_masslistelement = {'H': 1, 'He': 4, 'Li': 6.9, 'C': 12, 'N': 14, 'O': 16, 'F': 19,
'Ne': 20.2, 'Al': 27, 'Si': 28, 'Ar': 40, 'Rb': 85.5, 'Au': 197}

@staticmethod
def isejected(species):
Expand All @@ -105,7 +105,8 @@ def ision(cls, species):
@classmethod
def identifyspecies(cls, species):
"""
Returns a dictionary contining particle informations.
Returns a dictionary containing particle informations deduced from
the species name.
The following keys in the dictionary will always be present:
name species name string
mass kg (SI)
Expand All @@ -125,15 +126,20 @@ def identifyspecies(cls, species):

# Regex for parsing ion species name.
# See docsting for valid examples
regex = '(?P<prae>(.*_)*)(?P<name>(ionc(?P<c1>\d+)m(?P<m2>\d+)|' \
'ionm(?P<m1>\d+)c(?P<c2>\d+))|(?P<electron>[Ee]le[ck]tron)|' \
'(?P<elem>[A-Za-z]+)(?P<elem_c>\d*))(?P<suffix>[a-z]*)'
regex = '(?P<prae>(.*_)*)' \
'((?P<elem>((?!El)[A-Z][a-z]?))(?P<elem_c>\d*)|' \
'(?P<ionmc>(ionc(?P<c1>\d+)m(?P<m2>\d+)|ionm(?P<m1>\d+)c(?P<c2>\d+)))' \
')?' \
'(?P<plus>(Plus)*)' \
'(?P<electron>[Ee]le[ck])?' \
'(?P<suffix>\w*?)$'
r = re.match(regex, s)
if r is None:
raise Exception('Species ' + str(s) +
' does not match regex name pattern: ' +
str(regex))
regexdict = r.groupdict()
# print(regexdict)

# recognize anz prae and add dictionary key
if regexdict['prae']:
Expand All @@ -142,44 +148,52 @@ def identifyspecies(cls, species):
if not key == '':
ret[key] = True

# Name Element + charge state: C1, C6, F2, F9, Au20, Pb34a
# Excluding patterns start here
# 1) Name Element + charge state: C1, C6, F2, F9, Au20, Pb34a
if regexdict['elem']:
try:
ret['mass'] = float(cls._masslistelement[regexdict['elem']]) * \
1836.2 * cls.me
ret['mass'] = float(cls._masslistelement[regexdict['elem']]) * \
1836.2 * cls.me
if regexdict['elem_c'] == '':
ret['charge'] = 0
else:
ret['charge'] = float(regexdict['elem_c']) * cls.qe
ret['ision'] = True
# 2) ionmc like
elif regexdict['ionmc']:
if regexdict['c1']:
ret['mass'] = float(regexdict['m2']) * 1836.2 * cls.me
ret['charge'] = float(regexdict['c1']) * cls.qe
ret['ision'] = True

if regexdict['c2']:
ret['mass'] = float(regexdict['m1']) * 1836.2 * cls.me
ret['charge'] = float(regexdict['c2']) * cls.qe
ret['ision'] = True
except KeyError:
# this pattern will also match, if name is defined in masslist,
# so just ignore if key is not found.
pass

# charge may be given via plus
if regexdict['plus']:
charge = len(regexdict['plus'])/4 * cls.qe
if ret['charge'] == 0:
ret['charge'] = charge

# Elektron can be appended to any ion name, so overwrite.
if regexdict['electron']:
ret['mass'] = cls.me
ret['charge'] = -1 * cls.qe
ret['ision'] = False

if regexdict['c1']:
ret['mass'] = float(regexdict['m2']) * 1836.2 * cls.me
ret['charge'] = float(regexdict['c1']) * cls.qe
ret['ision'] = True

if regexdict['c2']:
ret['mass'] = float(regexdict['m1']) * 1836.2 * cls.me
ret['charge'] = float(regexdict['c2']) * cls.qe
ret['ision'] = True

# simply added to _masslist and _chargelist
# this should not be used anymore
if regexdict['name'] in cls._masslist:
ret['mass'] = float(cls._masslist[regexdict['name']]) * cls.me
if regexdict['name'] in cls._chargelist:
ret['charge'] = float(cls._chargelist[regexdict['name']] * cls.qe)
if regexdict['name'] in cls._isionlist:
ret['ision'] = cls._isionlist[regexdict['name']]
# set only if property is not already set
if 'mass' not in ret and regexdict['suffix'] in cls._masslist:
ret['mass'] = float(cls._masslist[regexdict['suffix']]) * cls.me
if 'charge' not in ret and regexdict['suffix'] in cls._chargelist:
ret['charge'] = float(cls._chargelist[regexdict['suffix']] * cls.qe)
if 'ision' not in ret and regexdict['suffix'] in cls._isionlist:
ret['ision'] = cls._isionlist[regexdict['suffix']]

if not (('mass' in ret) and ('charge' in ret) and ('ision' in ret)):
raise Error('species ' + species + ' not recognized.')
raise Exception('species ' + species + ' not recognized.')

return ret

Expand Down
32 changes: 32 additions & 0 deletions test/test_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ def test_identifyspecies_electron(self):
self.checke(idfy('ElektronAu2'), 1, -1, False, False, False)
self.checke(idfy('ejected_ElektronAu2'), 1, -1, True, False, False)
self.checke(idfy('tracer_blahh_electronHe2b'), 1, -1, False, True, False)
self.checke(idfy('tracer_blahh_elecHe2b'), 1, -1, False, True, False)
self.checke(idfy('tracer_blahh_HeElec2b'), 1, -1, False, True, False)
self.checke(idfy('Elec'), 1, -1, False, False, False)
self.checke(idfy('Elec2x'), 1, -1, False, False, False)
self.checke(idfy('Electrons'), 1, -1, False, False, False)

def test_identifyspecies_praefix(self):
x = pa.identifyspecies('a_b_c_xxx_tracer_h_w_33_He5_O3x2')
Expand All @@ -52,5 +57,32 @@ def test_identifyspecies_praefix(self):
self.assertEqual(x['He5'], True)
self.checkion(x, 16,3, False, True, True)

def test_identifyspecies_extendedsyntax(self):
idfy = pa.identifyspecies
self.checkion(idfy('H'), 1, 0, False, False, True)
self.checkion(idfy('HPlus'), 1, 1, False, False, True)
self.checkion(idfy('H1Plus'), 1, 1, False, False, True)
#self.checkion(idfy('Hplus'), 1, 1, False, False, True)
self.checkion(idfy('HePlusPlus'), 4, 2, False, False, True)
self.checkion(idfy('He2Plus'), 4, 2, False, False, True)
self.checkion(idfy('HPlus'), 1, 1, False, False, True)
self.checke(idfy('HElectron'), 1, -1, False, False, False)
self.checke(idfy('HElectrons'), 1, -1, False, False, False)
self.checke(idfy('HElec'), 1, -1, False, False, False)
self.checke(idfy('HPlusElec'), 1, -1, False, False, False)
self.checke(idfy('HePlusPluselectrons'), 1, -1, False, False, False)

def test_falsefriends(self):
idfy = pa.identifyspecies
# careful: the last one is an uncharged ion
self.checke(idfy('HElectron'), 1, -1, False, False, False)
self.checke(idfy('HeElectron'), 1, -1, False, False, False)
self.checke(idfy('Heelectron'), 1, -1, False, False, False)
self.checkion(idfy('Helectron'), 4, 0, False, False, True)
# Tiny differences may decide about Ne or electrons
self.checke(idfy('NElectron'), 1, -1, False, False, False)
self.checkion(idfy('Nelectron'), 20.2, 0, False, False, True)
self.checke(idfy('Neelectron'), 1, -1, False, False, False)

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

0 comments on commit 9eb9f94

Please sign in to comment.