ATLAS Offline Software
Loading...
Searching...
No Matches
MonopoleConfig.py
Go to the documentation of this file.
1# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2
3from AthenaConfiguration.AccumulatorCache import AccumulatorCache
4import os
5from AthenaConfiguration.ComponentFactory import CompFactory
6from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
7from AthenaConfiguration.Enums import ProductionStep
8from ExtraParticles.PDGHelpers import getPDGTABLE
9
10
11@AccumulatorCache
13 if getPDGTABLE('PDGTABLE.MeV'):
14 ALINE1="M 4110000 {intmass}.E+03 +0.0E+00 -0.0E+00 Monopole 0".format(intmass=int(MASS))
15 ALINE2="W 4110000 0.E+00 +0.0E+00 -0.0E+00 Monopole 0"
16 BLINE1="4110000 {intmass}.00 0.0 {gcharge} # Monopole".format(intmass=int(MASS), gcharge=GCHARGE)
17 BLINE2="-4110000 {intmass}.00 0.0 -{gcharge} # MonopoleBar".format(intmass=int(MASS), gcharge=GCHARGE)
18
19 f=open('PDGTABLE.MeV','a')
20 f.writelines(str(ALINE1))
21 f.writelines('\n')
22 f.writelines(str(ALINE2))
23 f.writelines('\n')
24 f.close()
25 partmod = os.path.isfile('particles.txt')
26 if partmod is True:
27 os.remove('particles.txt')
28 f=open('particles.txt','w')
29 f.writelines(str(BLINE1))
30 f.writelines('\n')
31 f.writelines(str(BLINE2))
32 f.writelines('\n')
33 f.close()
34
35 del ALINE1
36 del ALINE2
37 del BLINE1
38 del BLINE2
39
40
41@AccumulatorCache
43 if getPDGTABLE('PDGTABLE.MeV'):
44 CODE=10000000+int(float(CHARGE)*100)
45
46 ALINE1="M {code} {intmass}.E+03 +0.0E+00 -0.0E+00 Qball +".format(code=CODE,intmass=int(MASS))
47 ALINE2="W {code} 0.E+00 +0.0E+00 -0.0E+00 Qball +".format(code=CODE)
48 BLINE1="{code} {intmass}.00 {charge} 0.0 # Qball".format(code=CODE,intmass=int(MASS), charge=CHARGE)
49 BLINE2="-{code} {intmass}.00 -{charge} 0.0 # QballBar".format(code=CODE,intmass=int(MASS), charge=CHARGE)
50
51 f=open('PDGTABLE.MeV','a')
52 f.writelines(str(ALINE1))
53 f.writelines('\n')
54 f.writelines(str(ALINE2))
55 f.writelines('\n')
56 f.close()
57 partmod = os.path.isfile('particles.txt')
58 if partmod is True:
59 os.remove('particles.txt')
60 f=open('particles.txt','w')
61 f.writelines(str(BLINE1))
62 f.writelines('\n')
63 f.writelines(str(BLINE2))
64 f.writelines('\n')
65 f.close()
66
67 del ALINE1
68 del ALINE2
69 del BLINE1
70 del BLINE2
71
72
73@AccumulatorCache
74def load_files_for_fcp_scenario(MASS, CHARGE, X, Y):
75 CODE=int(20000000)+int(X)*1000+int(Y)*10
76 print("Trying to load %s, %s for particle with code %s" % (X, Y, CODE))
77
78 pdgLine1="M {code} {intmass}.E+03 +0.0E+00 -0.0E+00 fcp +\n".format(code=CODE,intmass=int(MASS))
79 pdgLine2="W {code} 0.E+00 +0.0E+00 -0.0E+00 fcp +\n".format(code=CODE)
80 particleLine1="{code} {intmass}.00 {fcharge} 0.0 # fcp\n".format(code=CODE,intmass=int(MASS), fcharge=float(CHARGE))
81 particleLine2="-{code} {intmass}.00 -{fcharge} 0.0 # fcpBar\n".format(code=CODE,intmass=int(MASS), fcharge=float(CHARGE))
82
83 # retreive the PDGTABLE file
84 if getPDGTABLE('PDGTABLE.MeV'):
85 f=open('PDGTABLE.MeV','a')
86 f.writelines(str(pdgLine1))
87 f.writelines(str(pdgLine2))
88 f.close()
89 partmod = os.path.isfile('particles.txt')
90 if partmod is True:
91 os.remove('particles.txt')
92 f=open('particles.txt','w')
93 f.writelines(str(particleLine1))
94 f.writelines(str(particleLine2))
95 f.close()
96
97 del pdgLine1
98 del pdgLine2
99 del particleLine1
100 del particleLine2
101
102
103@AccumulatorCache
104def load_files_for_dyon_scenario(MASS, CHARGE, GCHARGE):
105 CODE=4110000+int(CHARGE)*10
106 CODE2=4120000+int(CHARGE)*10
107 if getPDGTABLE('PDGTABLE.MeV'):
108 ALINE1="M {code} {intmass}.E+03 +0.0E+00 -0.0E+00 DyonSS 0".format(code=CODE,intmass=int(MASS)) #Dyon magnetic and electric charges are the same sign
109 ALINE2="W {code} 0.E+00 +0.0E+00 -0.0E+00 DyonSS 0".format(code=CODE)
110 ALINE3="M {code2} {intmass}.E+03 +0.0E+00 -0.0E+00 DyonOS 0".format(code2=CODE2,intmass=int(MASS)) #Dyon magnetic and electric charges are opposite signs
111 ALINE4="W {code2} 0.E+00 +0.0E+00 -0.0E+00 DyonOS 0".format(code2=CODE2)
112
113
114 BLINE1="{code} {intmass}.00 {fcharge} {gcharge} # DyonSS".format(code=CODE, intmass=int(MASS), fcharge=float(CHARGE), gcharge=GCHARGE)
115 BLINE2="-{code} {intmass}.00 -{fcharge} -{gcharge} # DyonSSBar".format(code=CODE, intmass=int(MASS), fcharge=float(CHARGE), gcharge=GCHARGE)
116 BLINE3="{code2} {intmass}.00 -{fcharge} {gcharge} # DyonOS".format(code2=CODE2, intmass=int(MASS), fcharge=float(CHARGE), gcharge=GCHARGE)
117 BLINE4="-{code2} {intmass}.00 {fcharge} -{gcharge} # DyonOSBar".format(code2=CODE2, intmass=int(MASS), fcharge=float(CHARGE), gcharge=GCHARGE)
118
119 f=open('PDGTABLE.MeV','a')
120 f.writelines(str(ALINE1))
121 f.writelines('\n')
122 f.writelines(str(ALINE2))
123 f.writelines('\n')
124 f.writelines(str(ALINE3))
125 f.writelines('\n')
126 f.writelines(str(ALINE4))
127 f.writelines('\n')
128 f.close()
129 partmod = os.path.isfile('particles.txt')
130 if partmod is True:
131 os.remove('particles.txt')
132 f=open('particles.txt','w')
133 f.writelines(str(BLINE1))
134 f.writelines('\n')
135 f.writelines(str(BLINE2))
136 f.writelines('\n')
137 f.writelines(str(BLINE3))
138 f.writelines('\n')
139 f.writelines(str(BLINE4))
140 f.writelines('\n')
141 f.close()
142
143 del ALINE1
144 del ALINE2
145 del ALINE3
146 del ALINE4
147 del BLINE1
148 del BLINE2
149 del BLINE3
150 del BLINE4
151
152
153def MonopolePhysicsToolCfg(flags, name="MonopolePhysicsTool", **kwargs):
154 result = ComponentAccumulator()
155 result.setPrivateTools( CompFactory.MonopolePhysicsTool(name, **kwargs) )
156 return result
157
158
159def G4mplEqMagElectricFieldToolCfg(flags, name="G4mplEqMagElectricField", **kwargs):
160 result = ComponentAccumulator()
161 result.setPrivateTools( CompFactory.G4mplEqMagElectricFieldTool(name, **kwargs) )
162 return result
163
164
165def fcpPreInclude(flags):
166 simdict = flags.Input.SpecialConfiguration
167 if flags.Common.ProductionStep == ProductionStep.Simulation:
168 # add monopole-specific configuration for looper killer
169 flags.Sim.OptionalUserActionList += ['G4UserActions.G4UserActionsConfig.MonopoleLooperKillerToolCfg']
170 # add default HIP killer
171 flags.Sim.OptionalUserActionList += ['G4UserActions.G4UserActionsConfig.HIPKillerToolCfg']
172 if "InteractingPDGCodes" not in simdict: #FIXME This code would ideally update the ConfigFlag itself
173 assert "CHARGE" in simdict
174 assert "X" in simdict
175 assert "Y" in simdict
176 CODE=int(20000000)+int(simdict["X"])*1000+int(simdict["Y"])*10
177 simdict['InteractingPDGCodes'] = str([CODE,-1*CODE])
178 flags.Input.SpecialConfiguration = simdict
179
180
181def fcpCfg(flags):
182 result = ComponentAccumulator()
183 if flags.Common.ProductionStep == ProductionStep.Simulation:
184 from G4AtlasServices.G4AtlasServicesConfig import PhysicsListSvcCfg
185 result.merge(PhysicsListSvcCfg(flags))
186
187 simdict = flags.Input.SpecialConfiguration
188 load_files_for_fcp_scenario(simdict["MASS"], simdict["CHARGE"], simdict["X"], simdict["Y"])
189 pdgcodes = eval(simdict['InteractingPDGCodes']) if 'InteractingPDGCodes' in simdict else []
190 from ExtraParticles.PDGHelpers import updateExtraParticleAcceptList
191 updateExtraParticleAcceptList('G4particle_acceptlist_ExtraParticles.txt', pdgcodes)
192
193 if flags.Common.ProductionStep == ProductionStep.Simulation:
194 physicsOptions = [ result.popToolsAndMerge(MonopolePhysicsToolCfg(flags)) ]
195 result.getService("PhysicsListSvc").PhysOption += physicsOptions
196 # add monopole-specific configuration for looper killer
197 #simFlags.OptionalUserActionList.addAction('G4UA::MonopoleLooperKillerTool') #FIXME missing functionality
198 # add default HIP killer
199 #simFlags.OptionalUserActionList.addAction('G4UA::HIPKillerTool') #FIXME missing functionality
200
201 return result
202
203
205 simdict = flags.Input.SpecialConfiguration
206 if flags.Common.ProductionStep == ProductionStep.Simulation:
207 # add monopole-specific configuration for looper killer
208 flags.Sim.OptionalUserActionList += ['G4UserActions.G4UserActionsConfig.MonopoleLooperKillerToolCfg']
209 # add default HIP killer
210 flags.Sim.OptionalUserActionList += ['G4UserActions.G4UserActionsConfig.HIPKillerToolCfg']
211 if "InteractingPDGCodes" not in simdict:
212 assert "CHARGE" in simdict
213 CODE=10000000+int(float(simdict["CHARGE"])*100)
214 simdict['InteractingPDGCodes'] = str([CODE,-1*CODE])
215 flags.Input.SpecialConfiguration = simdict
216
217
218def QballCfg(flags):
219 result = ComponentAccumulator()
220 simdict = flags.Input.SpecialConfiguration
221 if flags.Common.ProductionStep == ProductionStep.Simulation:
222 from G4AtlasServices.G4AtlasServicesConfig import PhysicsListSvcCfg
223 result.merge(PhysicsListSvcCfg(flags))
224 if "InteractingPDGCodes" not in simdict:
225 assert "CHARGE" in simdict
226 CODE=10000000+int(float(simdict["CHARGE"])*100)
227 simdict['InteractingPDGCodes'] = str([CODE,-1*CODE])
228
229 assert "MASS" in simdict
230 assert "CHARGE" in simdict
231 load_files_for_qball_scenario(simdict["MASS"], simdict["CHARGE"])
232 pdgcodes = eval(simdict['InteractingPDGCodes']) if 'InteractingPDGCodes' in simdict else []
233 from ExtraParticles.PDGHelpers import updateExtraParticleAcceptList
234 updateExtraParticleAcceptList('G4particle_acceptlist_ExtraParticles.txt', pdgcodes)
235
236 if flags.Common.ProductionStep == ProductionStep.Simulation:
237 physicsOptions = [ result.popToolsAndMerge(MonopolePhysicsToolCfg(flags)) ]
238 result.getService("PhysicsListSvc").PhysOption += physicsOptions
239
240 return result
241
242
243def DyonPreInclude(flags):
244 if flags.Common.ProductionStep == ProductionStep.Simulation:
245 # add monopole-specific configuration for looper killer
246 flags.Sim.OptionalUserActionList += ['G4UserActions.G4UserActionsConfig.MonopoleLooperKillerToolCfg']
247 # add default HIP killer
248 flags.Sim.OptionalUserActionList += ['G4UserActions.G4UserActionsConfig.HIPKillerToolCfg']
249 flags.Sim.G4Stepper = 'ClassicalRK4'
250 flags.Sim.G4EquationOfMotion = "G4mplEqMagElectricField" #Monopole Equation of Motion
251 flags.Sim.TightMuonStepping = False
252 simdict = flags.Input.SpecialConfiguration
253 if "InteractingPDGCodes" not in simdict:
254 assert "CHARGE" in simdict
255 CODE=4110000+int(float(simdict["CHARGE"])*10)
256 CODE2=4120000+int(float(simdict["CHARGE"])*10)
257 simdict['InteractingPDGCodes'] = str([CODE,-1*CODE,CODE2,-1*CODE2])
258 flags.Input.SpecialConfiguration = simdict
259
260
261def DyonCfg(flags):
262 result = ComponentAccumulator()
263 if flags.Common.ProductionStep == ProductionStep.Simulation:
264 from G4AtlasServices.G4AtlasServicesConfig import PhysicsListSvcCfg
265 result.merge(PhysicsListSvcCfg(flags))
266
267 simdict = flags.Input.SpecialConfiguration
268 assert "MASS" in simdict
269 assert "CHARGE" in simdict
270 assert "GCHARGE" in simdict
271 load_files_for_dyon_scenario(simdict["MASS"], simdict["CHARGE"], simdict["GCHARGE"])
272 pdgcodes = eval(simdict['InteractingPDGCodes']) if 'InteractingPDGCodes' in simdict else []
273 from ExtraParticles.PDGHelpers import updateExtraParticleAcceptList
274 updateExtraParticleAcceptList('G4particle_acceptlist_ExtraParticles.txt', pdgcodes)
275
276 if flags.Common.ProductionStep == ProductionStep.Simulation:
277 from GaudiKernel.GaudiHandles import PrivateToolHandleArray
278 physicsOptions = PrivateToolHandleArray([ result.popToolsAndMerge(MonopolePhysicsToolCfg(flags)) ])
279 result.getService("PhysicsListSvc").PhysOption = physicsOptions + result.getService("PhysicsListSvc").PhysOption
280 return result
281
282
284 if flags.Common.ProductionStep == ProductionStep.Simulation:
285 # add monopole-specific configuration for looper killer
286 flags.Sim.OptionalUserActionList += ['G4UserActions.G4UserActionsConfig.MonopoleLooperKillerToolCfg']
287 # add default HIP killer
288 flags.Sim.OptionalUserActionList += ['G4UserActions.G4UserActionsConfig.HIPKillerToolCfg']
289 flags.Sim.G4Stepper = 'ClassicalRK4'
290 flags.Sim.G4EquationOfMotion = "G4mplEqMagElectricField" #Monopole Equation of Motion
291 flags.Sim.TightMuonStepping = False
292 simdict = flags.Input.SpecialConfiguration
293 if "InteractingPDGCodes" not in simdict:
294 simdict['InteractingPDGCodes'] = str([4110000,-4110000])
295 flags.Input.SpecialConfiguration = simdict
296
297
298def MonopoleCfg(flags):
299 result = ComponentAccumulator()
300 if flags.Common.ProductionStep == ProductionStep.Simulation:
301 from G4AtlasServices.G4AtlasServicesConfig import PhysicsListSvcCfg
302 result.merge(PhysicsListSvcCfg(flags))
303
304 simdict = flags.Input.SpecialConfiguration
305 assert "MASS" in simdict
306 assert "GCHARGE" in simdict
307 load_files_for_monopole_scenario(simdict["MASS"], simdict["GCHARGE"])
308 pdgcodes = eval(simdict['InteractingPDGCodes']) if 'InteractingPDGCodes' in simdict else []
309 from ExtraParticles.PDGHelpers import updateExtraParticleAcceptList
310 updateExtraParticleAcceptList('G4particle_acceptlist_ExtraParticles.txt', pdgcodes)
311
312 if flags.Common.ProductionStep == ProductionStep.Simulation:
313 from GaudiKernel.GaudiHandles import PrivateToolHandleArray
314 physicsOptions = PrivateToolHandleArray([ result.popToolsAndMerge(MonopolePhysicsToolCfg(flags)) ])
315 result.getService("PhysicsListSvc").PhysOption = physicsOptions + result.getService("PhysicsListSvc").PhysOption
316 return result
317
318
319def Monopole_VerboseSelectorCfg(flags, name="G4UA::VerboseSelectorTool", **kwargs):
320 kwargs.setdefault('TargetEvent',1)
321 kwargs.setdefault('VerboseLevel',1)
322 kwargs.setdefault('TargetPdgIDs',
323 [
324 -4110000,4110000 #Monopoles
325 ])
326 from G4DebuggingTools.G4DebuggingToolsConfig import VerboseSelectorToolCfg
327 return VerboseSelectorToolCfg(flags, name, **kwargs)
void print(char *figname, TCanvas *c1)
G4mplEqMagElectricFieldToolCfg(flags, name="G4mplEqMagElectricField", **kwargs)
load_files_for_fcp_scenario(MASS, CHARGE, X, Y)
MonopolePhysicsToolCfg(flags, name="MonopolePhysicsTool", **kwargs)
Monopole_VerboseSelectorCfg(flags, name="G4UA::VerboseSelectorTool", **kwargs)
load_files_for_qball_scenario(MASS, CHARGE)
MonopolePreInclude(flags)
load_files_for_dyon_scenario(MASS, CHARGE, GCHARGE)
load_files_for_monopole_scenario(MASS, GCHARGE)