3 """Parser for the PDGTABLE.MeV file
5 Creates a compact object that holds configuration
6 for the ExtraParticlesPhysicsTool.
8 Gaudi cannot parse nested std::map objects, so the extra
9 particles are converted into a
11 std::map< std::string, std::vector< double > >
13 object and ordering of the values is therefore important.
22 Charge, spin, parity, and isospin3 are set to zero.
32 from AthenaCommon.PhysicalConstants
import hbar_Planck, h_Planck
33 from AthenaCommon.Logging
import logging
34 from functools
import lru_cache
39 if os.path.isfile(table):
42 os.system(
'get_files -data %s' % table)
49 if os.path.isfile(acceptlist):
52 blank =
open(
'G4particle_acceptlist_ExtraParticles.txt',
'x')
60 shutil.copy(listName, listName+
'.org')
61 existingpdgcodes = [
int(x)
for x
in open(listName).readlines()]
62 newpdgcodes =
list(
set(pdgcodes).difference(existingpdgcodes))
64 with open(listName,
'a')
as writer:
65 for pdg
in newpdgcodes:
66 writer.write(
'%s\n' % pdg)
75 lifetime = h_Planck / joule
78 self.__dict__.
update(kwargs)
82 string +=
'name: %s\n' % self.
name
83 string +=
' mass: %s\n' % self.
mass
84 string +=
' width: %s\n' % self.
width
85 string +=
' charge: %s\n' % self.
charge
86 string +=
' pdg: %s\n' % self.
pdg
87 string +=
' lifetime: %s\n' % self.
lifetime
93 antiParticle.charge *= -1
94 antiParticle.pdg *= -1
98 if self.
name[-1] ==
'0':
99 if 'anti_' in self.
name:
102 return 'anti_' + self.
name
103 elif self.
name[-1] ==
'+':
105 elif self.
name[-1] ==
'-':
112 self.
log = logging.getLogger(__name__)
119 """Function to determine which extra particles are added
121 Function checks the ranges member variable
122 and evaluates whether the particle should be accepted.
124 TODO Consider adding a Sim.ExtraParticlesRanges ConfigFlag
126 For example, '111-556,1112-9090226' matches everything from
127 111 to 555 and 1112 to 9090225.
129 ranges = [r.split(
"-")
for r
in self.
ranges.
split(
",")]
131 if int(r[0]) <= pdg <
int(r[1]):
139 if line.startswith(
'*'):
142 splitLine = line.split()
145 baseName = splitLine[-2]
148 charges = splitLine[-1].
split(
',')
152 symbol = splitLine[0]
159 'Unidentified symbol %s for particle %s' % (
162 pdgs = splitLine[1:1+len(charges)]
163 value =
float(splitLine[1+len(charges)])
165 for pdg, charge
in zip(pdgs, charges):
170 kwargs.setdefault(
'name', name)
171 kwargs.setdefault(prop, value * MeV)
172 kwargs.setdefault(
'pdg',
int(pdg))
179 "Property %s is already"
180 "set for particle %s."
181 "Current value is %s and"
182 "incoming value is %s.",
202 nameOut = nameOut.replace(
"*",
"_star").
replace(
"'",
"_prime")
209 if not (charge == len(charge) * charge[0]):
210 raise ValueError(
'Unexpected charge %s' % charge)
220 raise ValueError(
'Unexpected charge %s' % charge)
229 outDict.update({name: [