00001
00002
00003 '''
00004 A job option module and algorithm to histogram kinematics from GenDecay
00005 '''
00006
00007 from DybPython.DybPythonAlg import DybPythonAlg
00008 from GaudiPython import SUCCESS, FAILURE, loaddict
00009 from ROOT import TH1F
00010 from DybPython.Util import irange
00011 import GaudiKernel.SystemOfUnits as units
00012 import math
00013
00014
00015 loaddict('libHepMCRflx')
00016
00017 class MyPythonAlg(DybPythonAlg):
00018 def __init__(self,name,default_path=""):
00019 DybPythonAlg.__init__(self,name)
00020 if default_path[-1] == '/': default_path = default_path[:-1]
00021 self.default_path = default_path
00022 self.data = {}
00023 return
00024
00025 def initialize(self):
00026 status = DybPythonAlg.initialize(self)
00027 if status.isFailure(): return status
00028 self.statsSvc = self.svc('IStatisticsSvc','StatisticsSvc')
00029 if self.statsSvc == None:
00030 self.error("Failed to initialize StatisticsSvc.")
00031 return FAILURE
00032 return SUCCESS
00033
00034 def finalize(self):
00035 return DybPythonAlg.finalize(self)
00036
00037 def _key2path(self,key):
00038 if key[0] != '/':
00039 key = self.default_path + '/' + key
00040 return key
00041
00042 def __setitem__(self,key,value):
00043
00044 key = self._key2path(key)
00045 if self.data.has_key(key):
00046 raise KeyError, 'key "%s" already set'%key
00047 self.statsSvc.put(key,value)
00048 self.data[key] = value
00049 return
00050
00051 def __getitem__(self,key):
00052 return self.data[self._key2path(key)]
00053
00054 pass
00055
00056 def pdgid2name(idn):
00057 _pdgid2name = {
00058 11: "e-",
00059 -11: "e+",
00060 22: "gamma",
00061 1000020040: "alpha",
00062 1000802060: "Hg-206",
00063 1000812060: "Tl-206",
00064 1000822060: "Pb-206",
00065 1000812080: "Tl-208",
00066 1000822080: "Pb-208",
00067 1000812100: "Tl-210",
00068 1000822100: "Pb-210",
00069 1000832100: "Bi-210",
00070 1000842100: "Po-210",
00071 1000822120: "Pb-212",
00072 1000832120: "Bi-212",
00073 1000842120: "Po-212",
00074 1000822140: "Pb-214",
00075 1000832140: "Bi-214",
00076 1000842140: "Po-214",
00077 1000842160: "Po-216",
00078 1000842180: "Po-218",
00079 1000862200: "Rn-220",
00080 1000862220: "Rn-222",
00081 1000882240: "Ra-224",
00082 1000882260: "Ra-226",
00083 1000882280: "Ra-228",
00084 1000892280: "Ac-228",
00085 1000902280: "Th-228",
00086 1000902300: "Th-230",
00087 1000902320: "Th-232",
00088 1000902340: "Th-234",
00089 1000912340: "Pa-234",
00090 1000922340: "U-234",
00091 1000922380: "U-238",
00092 }
00093 try:
00094 return _pdgid2name[idn]
00095 except KeyError:
00096 return str(idn)
00097
00098
00099
00100 class DecayEnergy(MyPythonAlg):
00101 '''
00102 Histogram radioactive decays by parent
00103 '''
00104
00105 class ParentHist:
00106 def __init__(self,particle,alg):
00107 self.particle = particle
00108 self.bin=len(alg.parentHist)
00109 self.alg=alg
00110
00111 self.name = pdgid2name(particle.pdg_id())
00112
00113
00114
00115
00116 self.Ealpha = TH1F(self.mkname('Ealpha'),"Alpha kinetic energy (MeV) [%s]"%self.mkname('Ealpha'),2000,0,10)
00117 alg[self.mkname('Ealpha')] = self.Ealpha
00118 self.Ebeta = TH1F(self.mkname('Ebeta'),"Beta kinetic energy (MeV) [%s]"%self.mkname('Ebeta'),2000,0,10)
00119 alg[self.mkname('Ebeta')] = self.Ebeta
00120 self.Egamma = TH1F(self.mkname('Egamma'),"Gamma kinetic energy (MeV) [%s]"%self.mkname('Egamma'),2000,0,10)
00121 alg[self.mkname('Egamma')] = self.Egamma
00122 self.Ecap = TH1F(self.mkname('Ecap'),"Electron capture energy (MeV) [%s]"%self.mkname('Ecap'),2000,0,10)
00123 alg[self.mkname('Ecap')] = self.Ecap
00124
00125
00126 self.Talpha = TH1F(self.mkname('Talpha'),"Parent-Alpha time (ns) [%s]"%self.mkname('Talpha'),1000,0,1e9)
00127 alg[self.mkname('Talpha')] = self.Talpha
00128 self.Tbeta = TH1F(self.mkname('Tbeta'),"Parent-Beta time (ns) [%s]"%self.mkname('Tbeta'),1000,0,1e9)
00129 alg[self.mkname('Tbeta')] = self.Tbeta
00130 self.Tgamma = TH1F(self.mkname('Tgamma'),"Parent-Gamma time (ns) [%s]"%self.mkname('Tgamma'),1000,0,1e9)
00131 alg[self.mkname('Tgamma')] = self.Tgamma
00132 self.Tecap = TH1F(self.mkname('Tecap'),"Parent-EC time (ns) [%s]"%self.mkname('Tecap'),1000,0,1e9)
00133 alg[self.mkname('Tecap')] = self.Tecap
00134
00135 self.nDecay = TH1F(self.mkname('nDecay'),"Number of decay particles [%s]"%self.mkname('nDecay'),10,0,10)
00136 alg[self.mkname('nDecay')] = self.nDecay
00137
00138 return
00139
00140 def mkname(self,label):
00141 return self.name+'_'+label
00142
00143 pass
00144
00145 def __init__(self,name,dk_type):
00146 MyPythonAlg.__init__(self,name,'/file1/%s/%s'%(name,dk_type))
00147 self.dk_type = dk_type
00148 self.parentHist = {}
00149 self.lastRefTime = 0.0
00150 return
00151
00152 def initialize(self):
00153 status = MyPythonAlg.initialize(self)
00154 if status.isFailure(): return status
00155 self.info("initializing")
00156 self['ngamma'] = TH1F("ngamma","Number of Gammas",100,0,100)
00157 self['necap'] = TH1F("necap","Number of Electron Captures",100,0,100)
00158 self['alphabeta'] = TH1F("alphabeta","Alpha(<0) or Beta(>0)",2,-1,1)
00159 self['Ealpha'] = TH1F("Ealpha","Alpha kinetic energy (MeV)",2000,0,10)
00160 self['Ebeta'] = TH1F("Ebeta","Beta kinetic energy (MeV)",2000,0,10)
00161 self['Egamma'] = TH1F("Egamma","Gamma kinetic energy (MeV)",2000,0,10)
00162 self['Ecap'] = TH1F("Ecap","Energy from electron capture (MeV)",2000,0,10)
00163 self['deltaT'] = TH1F("deltaT","Time between parents (sec)",1000,0,100)
00164 '''
00165 histograms to add:
00166
00167 * parent nuclide specie
00168 * per parent alpha, beta & gamma spectra
00169 * time between parents
00170 * per parent time from parent to alpha, beta, gamma
00171
00172 code to add:
00173
00174 * GenEvent should hold daughter nuclides, take care with
00175 corelated decays, save only last daughter.
00176
00177 '''
00178 return status
00179
00180 def execute(self):
00181 evt = self.evtSvc()
00182 path = "/Event/Gen/GenHeader"
00183 hdr = evt[path]
00184
00185 refTimestamp = hdr.timeStamp()
00186 refSeconds = refTimestamp.GetSeconds()
00187
00188 deltaRefSeconds = refSeconds - self.lastRefTime
00189 self.lastRefTime = refSeconds
00190
00191 event = hdr.event()
00192 if event is None:
00193 error('Failed to get %s'%path)
00194 return FAILURE
00195
00196
00197 sigvtx = event.signal_process_vertex()
00198 if sigvtx is None:
00199 error('No signal vertex')
00200 return FAILURE
00201
00202 if sigvtx.particles_in_size() == 0:
00203 error('No input particles in signal process vertex')
00204 return FAILURE
00205
00206 parent = sigvtx.particles_in_const_begin().__deref__()
00207 if parent is None:
00208 fatal('Unable to deref iterator')
00209 return FAILURE
00210
00211 parent_pos = sigvtx.position()
00212 thisRelSeconds = parent_pos.t()/units.second
00213
00214
00215
00216 dT = deltaRefSeconds + thisRelSeconds
00217
00218 if dT <= 0.0: logT = 0.0
00219 else: logT = math.log10(dT)
00220 self['deltaT'].Fill(logT)
00221
00222 try:
00223 parentHist = self.parentHist[parent.pdg_id()]
00224 except KeyError:
00225 parentHist = DecayEnergy.ParentHist(parent,self)
00226 self.parentHist[parent.pdg_id()] = parentHist
00227 pass
00228
00229 ndecay = 0
00230 ngamma = 0
00231 necap = 0
00232
00233 for vertex in irange(event.vertices_begin(),
00234 event.vertices_end()):
00235 pos = vertex.position()
00236
00237
00238
00239 deltaT = pos.t()/units.ns
00240
00241 for particle in irange(vertex.particles_out_const_begin(),
00242 vertex.particles_out_const_end()):
00243 id = particle.pdg_id()
00244 mom = particle.momentum()
00245 mass = particle.generated_mass()
00246
00247
00248 ndecay += 1
00249
00250 ke = (mom.e()-mass)/units.MeV
00251
00252 if id == 1000020040:
00253 self['Ealpha'].Fill(ke)
00254 parentHist.Ealpha.Fill(ke)
00255 parentHist.Talpha.Fill(deltaT)
00256 self['alphabeta'].Fill(-0.5)
00257
00258
00259 pass
00260
00261 if id == 11 or id == -11:
00262 self['Ebeta'].Fill(ke)
00263 parentHist.Ebeta.Fill(ke)
00264 parentHist.Tbeta.Fill(deltaT)
00265 self['alphabeta'].Fill(+0.5)
00266 pass
00267
00268 if id == 22:
00269 self['Egamma'].Fill(ke)
00270 parentHist.Egamma.Fill(ke)
00271 parentHist.Tgamma.Fill(deltaT)
00272 ngamma += 1
00273 pass
00274
00275 if id == 0:
00276 self['Ecap'].Fill(ke)
00277 parentHist.Ecap.Fill(ke)
00278 parentHist.Tecap.Fill(deltaT)
00279 necap += 1
00280 pass
00281 continue
00282 continue
00283
00284 self['ngamma'].Fill(ngamma)
00285 self['necap'].Fill(necap)
00286 parentHist.nDecay.Fill(ndecay)
00287
00288 return SUCCESS
00289
00290 def finalize(self):
00291 return MyPythonAlg.finalize(self)
00292
00293 pass
00294
00295 def configure(argv=[]):
00296 try:
00297 histfile = argv[0]
00298 except IndexError:
00299 histfile="gendecay.root"
00300
00301 from StatisticsSvc.StatisticsSvcConf import StatisticsSvc
00302 statsSvc = StatisticsSvc()
00303 statsSvc.Output ={"file1":histfile}
00304 return
00305
00306 def run(app):
00307 app.ExtSvc += ["StaticCableSvc", "StatisticsSvc"]
00308
00309 dke = DecayEnergy("DecayEnergy","Chain")
00310 app.addAlgorithm(dke)
00311 return