|
| 1 | +#!/usr/bin/python |
| 2 | + |
| 3 | +from optparse import OptionParser |
| 4 | +import random |
| 5 | +from math import pi,sin,cos,sqrt |
| 6 | +import sys |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | +pid = {"pi0":111, "pi+":211, "k0l":130, "k0s":310, "k+":321, |
| 11 | + "e+":-11, "mu+":-13, "tau+":-15, |
| 12 | + "nue":12, "nuebar":-12, |
| 13 | + "numu":14, "numubar":-14, |
| 14 | + "nutau":16, "nutaubar":-16, |
| 15 | + "p+":2212, "n0":2112} |
| 16 | + |
| 17 | +for pname, no in pid.items(): |
| 18 | + if pname.endswith('+'): |
| 19 | + pid[pname.replace('+','-')] = -1*pid[pname] |
| 20 | + |
| 21 | + |
| 22 | + |
| 23 | + |
| 24 | + |
| 25 | +parser = OptionParser() |
| 26 | +parser.add_option("-N", "--nfiles", dest="nfiles", |
| 27 | + help="number of files of particles to produce", |
| 28 | + metavar="#", default=1) |
| 29 | +parser.add_option("-n", "--npart", dest="npart", |
| 30 | + help="number of particles to simulate per file", |
| 31 | + metavar="#", default=100) |
| 32 | +parser.add_option("-t", "--type", dest="type", |
| 33 | + help="Particle type to be generated", |
| 34 | + metavar="TYPE",default="mu-") |
| 35 | +parser.add_option("-e", "--energy", dest="energy", |
| 36 | + help="Particle energy to be generated in MeV", |
| 37 | + metavar="ENERGY",default=1000.0) |
| 38 | +parser.add_option("-v", "--vertex", dest="vertname", |
| 39 | + help="Type of vertex (center*, random, minusx, plusx, minusz, plusz)", |
| 40 | + default="center") |
| 41 | +parser.add_option("-d", "--direction", dest="dirname", |
| 42 | + help="Type of direction (4pi*, towall, tocap)", |
| 43 | + default="4pi") |
| 44 | + |
| 45 | +(options, args) = parser.parse_args() |
| 46 | + |
| 47 | +options.vertname = options.vertname.lower() |
| 48 | +options.dirname = options.dirname.lower() |
| 49 | + |
| 50 | + |
| 51 | + |
| 52 | +nfiles = int(options.nfiles) |
| 53 | +npart = int(options.npart) |
| 54 | +energy = float(options.energy) |
| 55 | + |
| 56 | + |
| 57 | +#Define the particle |
| 58 | +particle = {"vertex":(0, 0, 0), |
| 59 | + "time":0, |
| 60 | + "type":pid[options.type], |
| 61 | + "energy":energy, |
| 62 | + "direction":(1,0,0)} |
| 63 | + |
| 64 | + |
| 65 | +randvert = False |
| 66 | +if options.vertname == "center": |
| 67 | + randvert = False |
| 68 | +elif options.vertname == "random": |
| 69 | + randvert = True |
| 70 | +elif options.vertname == "wall": |
| 71 | + print >>sys.stderr, "Wall not implemented yet" |
| 72 | + sys.exit(3) |
| 73 | +elif options.vertname == "minusx": |
| 74 | + particle["vertex"] = (-1000,0,0) |
| 75 | +elif options.vertname == "plusx": |
| 76 | + particle["vertex"] = (1000,0,0) |
| 77 | +elif options.vertname == "minusz": |
| 78 | + particle["vertex"] = (0,0,-1000) |
| 79 | +elif options.vertname == "plusz": |
| 80 | + particle["vertex"] = (0,0,1000) |
| 81 | +else: |
| 82 | + print >>sys.stderr, "Don't understand vertex",opttions.vertname |
| 83 | + sys.exit(2) |
| 84 | + |
| 85 | +if options.dirname == "towall": |
| 86 | + randdir = False |
| 87 | + particle["direction"] = (1,0,0) |
| 88 | +elif options.dirname == "tocap": |
| 89 | + randdir = False |
| 90 | + particle["direction"] = (0,0,1) |
| 91 | +elif options.dirname == "4pi": |
| 92 | + randdir = True |
| 93 | +elif options.dirname == "wall": |
| 94 | + print >>sys.stderr, "Wall not implemented yet" |
| 95 | + sys.exit(3) |
| 96 | +else: |
| 97 | + print >>sys.stderr, "Don't understand direction",options.dirname |
| 98 | + sys.exit(2) |
| 99 | + |
| 100 | + |
| 101 | + |
| 102 | + |
| 103 | + |
| 104 | +nue=12 |
| 105 | +nuebar=-12 |
| 106 | +numu=14 |
| 107 | +numubar=-14 |
| 108 | +nutau=16 |
| 109 | +nutaubar=-16 |
| 110 | + |
| 111 | +nu = {"type":pid["numu"], "energy":energy+1000.0, |
| 112 | + "direction":(1, 0, 0)} |
| 113 | +prot = {"type":pid["p+"], "energy":935.9840, |
| 114 | + "direction":(0, 0, 1)} |
| 115 | + |
| 116 | + |
| 117 | + |
| 118 | +def partPrint(p, f, recno): |
| 119 | + f.write("$ begin\n") |
| 120 | + f.write("$ nuance 0\n") |
| 121 | + if randvert: |
| 122 | + rad = 3368.15/2. - 20. #cm |
| 123 | + height = 3620.0 - 20. #cm |
| 124 | + while True: |
| 125 | + x = random.uniform(-rad,rad) |
| 126 | + y = random.uniform(-rad,rad) |
| 127 | + if x**2 + y**2 < rad**2: break |
| 128 | + z = random.uniform(-height/2,height/2) |
| 129 | + f.write("$ vertex %.5f %.5f %.5f %.5f\n" % (x, y, z, p["time"])) |
| 130 | + else: |
| 131 | + f.write("$ vertex %.5f %.5f %.5f %.5f\n" % (p["vertex"]+(p["time"],)) ) |
| 132 | + printTrack(nu, f, -1) # "Neutrino" Track |
| 133 | + printTrack(prot, f, -1) # "Target" track |
| 134 | + f.write("$ info 0 0 %i\n" % recno) |
| 135 | + if randdir: |
| 136 | + th = random.random()*2*pi |
| 137 | + u = 1.-2*random.random() |
| 138 | + x = sqrt(1.-u**2)*cos(th) |
| 139 | + y = sqrt(1.-u**2)*sin(th) |
| 140 | + z = u |
| 141 | + p["direction"] = (x, y, z) |
| 142 | + #th = random.random()*pi |
| 143 | + #phi = random.random()*2*pi |
| 144 | + #p["direction"] = (cos(phi)*cos(th), sin(phi)*cos(th), sin(th)) |
| 145 | + |
| 146 | + printTrack(p, f) # Outgoing Particle Track |
| 147 | + f.write("$ end\n") |
| 148 | + |
| 149 | +def printTrack(p, f, code=0): |
| 150 | + f.write("$ track %(type)i %(energy).5f " % p) |
| 151 | + f.write("%.5f %.5f %.5f %i\n" % (p["direction"]+(code,))) |
| 152 | + |
| 153 | + |
| 154 | +for fileno in range(nfiles): |
| 155 | + typestr = options.type.replace("+","plus").replace("-","minus") |
| 156 | + |
| 157 | + filename="%s_%.0fMeV_%s_%s_%03i.kin" % (typestr, energy, options.vertname, options.dirname, fileno) |
| 158 | + |
| 159 | + outfile = open(filename, 'w') |
| 160 | + |
| 161 | + print ("Writing %i particles to " % npart) + filename |
| 162 | + |
| 163 | + for i in range(npart): |
| 164 | + partPrint(particle, outfile, i) |
| 165 | + outfile.write("$ stop") |
| 166 | + outfile.close() |
0 commit comments