WCSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
MakeKin.py
Go to the documentation of this file.
1 #!/usr/bin/python
2 from __future__ import print_function
3 
4 from optparse import OptionParser
5 import random
6 from math import pi,sin,cos,sqrt
7 import sys
8 
9 
10 
11 pid = {"pi0":111, "pi+":211, "k0l":130, "k0s":310, "k+":321,
12  "e+":-11, "mu+":-13, "tau+":-15,
13  "nue":12, "nuebar":-12,
14  "numu":14, "numubar":-14,
15  "nutau":16, "nutaubar":-16,
16  "p+":2212, "n0":2112}
17 
18 #holds detector [radius, height] in cm
19 detectors = {"SuperK":[3368.15/2., 3620.],
20  "Cylinder_60x74_20inchBandL_14perCent":[7400./2., 6000.],
21  "Cylinder_60x74_20inchBandL_40perCent":[7400./2., 6000.],
22  "HyperK":[7080./2., 5480.]}
23 
24 for pname, no in list(pid.items()):
25  if pname.endswith('+'):
26  pid[pname.replace('+','-')] = -1*pid[pname]
27 
28 
29 
30 
31 
32 parser = OptionParser()
33 optdefault = 1
34 parser.add_option("-N", "--nfiles", dest="nfiles",
35  help="number of files of particles to produce. Default: %s" \
36  % (optdefault),
37  metavar="#", default=optdefault)
38 optdefault = 100
39 parser.add_option("-n", "--npart", dest="npart",
40  help="number of particles to simulate per file. Default: %s" \
41  % (optdefault),
42  metavar="#", default=optdefault)
43 verticesPerEventDefault = 1
44 parser.add_option("-V","--nVerticesPerEvent",dest="verticesPerEvent",
45  help=" Average number of vertices to simulate per event. Default: %s" \
46  % (verticesPerEventDefault),
47  metavar="#", default=verticesPerEventDefault)
48 optdefault = None
49 parser.add_option("-s", "--seed", dest="seed",
50  help="Random number seed to use. Default: None.",
51  metavar="SEED", default=optdefault)
52 optchoices = list(pid.keys())
53 optdefault = "mu-"
54 parser.add_option("-t", "--type", dest="type",
55  help="Particle type to be generated. Choices: %s. Default: %s" \
56  % (optchoices, optdefault),
57  metavar="TYPE",
58  choices=optchoices, default=optdefault)
59 optdefault = 1000.0
60 parser.add_option("-e", "--energy", dest="energy",
61  help="Particle energy to be generated in MeV. Default: %s" \
62  % (optdefault),
63  metavar="ENERGY",default=optdefault)
64 optchoices = ["center", "random", "minusx", "plusx", "minusz", "plusz"]
65 optdefault = optchoices[0]
66 parser.add_option("-v", "--vertex", dest="vertname",
67  help="Type of vertex. Choices: %s. Default: %s" \
68  % (optchoices, optdefault),
69  choices=optchoices, default=optdefault)
70 optchoices = ["4pi", "towall", "tocap"]
71 optdefault = optchoices[0]
72 parser.add_option("-d", "--direction", dest="dirname",
73  help="Type of direction. Choices: %s. Default: %s" \
74  % (optchoices, optdefault),
75  choices=optchoices, default=optdefault)
76 optchoices = list(detectors.keys())
77 optdefault = "SuperK"
78 parser.add_option("-w", "--detector", dest="detector",
79  help="Detector water volume to use (for vertex positioning). Choices: %s. Default: %s" \
80  % (optchoices, optdefault),
81  choices=optchoices, default=optdefault)
82 
83 (options, args) = parser.parse_args()
84 
85 options.vertname = options.vertname.lower()
86 options.dirname = options.dirname.lower()
87 
88 random.seed(options.seed)
89 
90 nfiles = int(options.nfiles)
91 npart = int(options.npart)
92 verticesPerEvent=int(options.verticesPerEvent)
93 energy = float(options.energy)
94 
95 
96 #Define the particle
97 particle = {"vertex":(0, 0, 0),
98  "time":0,
99  "type":pid[options.type],
100  "energy":energy,
101  "direction":(1,0,0)}
102 
103 
104 randvert = False
105 if options.vertname == "center":
106  randvert = False
107 elif options.vertname == "random":
108  randvert = True
109 elif options.vertname == "wall":
110  print("Wall not implemented yet", file=sys.stderr)
111  sys.exit(3)
112 elif options.vertname == "minusx":
113  if options.detector == "SuperK":
114  particle["vertex"] = (-1000,0,0)
115  else:
116  particle["vertex"] = (-1000. * detectors[options.detector][0] / detectors["SuperK"][0], 0, 0)
117 elif options.vertname == "plusx":
118  if options.detector == "SuperK":
119  particle["vertex"] = (+1000,0,0)
120  else:
121  particle["vertex"] = (+1000. * detectors[options.detector][0] / detectors["SuperK"][0], 0, 0)
122 elif options.vertname == "minusz":
123  if options.detector == "SuperK":
124  particle["vertex"] = (0, 0, -1000)
125  else:
126  particle["vertex"] = (0, 0, -1000. * detectors[options.detector][1] / detectors["SuperK"][1])
127 elif options.vertname == "plusz":
128  if options.detector == "SuperK":
129  particle["vertex"] = (0, 0, +1000)
130  else:
131  particle["vertex"] = (0, 0, +1000. * detectors[options.detector][1] / detectors["SuperK"][1])
132 else:
133  print("Don't understand vertex", options.vertname, file=sys.stderr)
134  sys.exit(2)
135 
136 if options.dirname == "towall":
137  randdir = False
138  particle["direction"] = (1,0,0)
139 elif options.dirname == "tocap":
140  randdir = False
141  particle["direction"] = (0,0,1)
142 elif options.dirname == "4pi":
143  randdir = True
144 elif options.dirname == "wall":
145  print("Wall not implemented yet", file=sys.stderr)
146  sys.exit(3)
147 else:
148  print("Don't understand direction", options.dirname, file=sys.stderr)
149  sys.exit(2)
150 
151 
152 
153 
154 
155 nu = {"type":pid["numu"], "energy":energy+1000.0,
156  "direction":(1, 0, 0)}
157 prot = {"type":pid["p+"], "energy":935.9840,
158  "direction":(0, 0, 1)}
159 
160 def eventPrint(nv,p,f,recno) :
161  f.write("$ begin\n")
162  for v in range(nv) :
163  vertPrint(p,f,recno)
164  recno=recno+1
165  f.write("$ end\n")
166 
167 def partPrint(p, f, recno):
168  f.write("$ begin\n")
169  vertPrint(p,f,recno)
170  f.write("$ end\n")
171 
172 def vertPrint(p,f,recno) :
173  f.write("$ nuance 0\n")
174  if randvert:
175  rad = detectors[options.detector][0] - 20.
176  height = detectors[options.detector][1] - 20.
177  while True:
178  x = random.uniform(-rad,rad)
179  y = random.uniform(-rad,rad)
180  if x**2 + y**2 < rad**2: break
181  z = random.uniform(-height/2,height/2)
182  f.write("$ vertex %.5f %.5f %.5f %.5f\n" % (x, y, z, p["time"]))
183  else:
184  f.write("$ vertex %.5f %.5f %.5f %.5f\n" % (p["vertex"]+(p["time"],)) )
185  printTrack(nu, f, -1) # "Neutrino" Track
186  printTrack(prot, f, -1) # "Target" track
187  f.write("$ info 0 0 %i\n" % recno)
188  if randdir:
189  th = random.random()*2*pi
190  u = 1.-2*random.random()
191  x = sqrt(1.-u**2)*cos(th)
192  y = sqrt(1.-u**2)*sin(th)
193  z = u
194  p["direction"] = (x, y, z)
195  #th = random.random()*pi
196  #phi = random.random()*2*pi
197  #p["direction"] = (cos(phi)*cos(th), sin(phi)*cos(th), sin(th))
198 
199  printTrack(p, f) # Outgoing Particle Track
200 
201 def printTrack(p, f, code=0):
202  f.write("$ track %(type)i %(energy).5f " % p)
203  f.write("%.5f %.5f %.5f %i\n" % (p["direction"]+(code,)))
204 
205 
206 for fileno in range(nfiles):
207  typestr = options.type.replace("+","plus").replace("-","minus")
208 
209  filename="%s_%.0fMeV_%s_%s_%s_%03i.kin" % (typestr, energy, options.vertname, options.dirname, options.detector, fileno)
210 
211  outfile = open(filename, 'w')
212 
213  if(verticesPerEvent == 1 ) :
214  print("Writing", npart, "particles to", filename)
215 
216  for i in range(npart):
217  partPrint(particle, outfile, i)
218  else :
219  print("Writing", npart, "particles with an average of", verticesPerEvent, "vertices per event to", filename)
220  numberDone = 0
221  sigma = sqrt(verticesPerEvent)
222  while numberDone < npart:
223  numberToProcess = int(round(random.gauss(verticesPerEvent,sigma)))
224  eventPrint(numberToProcess,particle,outfile,numberDone)
225  numberDone = numberDone + numberToProcess
226  outfile.write("$ stop")
227  outfile.close()
def eventPrint
Definition: MakeKin.py:160
def printTrack
Definition: MakeKin.py:201
def partPrint
Definition: MakeKin.py:167
def vertPrint
Definition: MakeKin.py:172