Advertisement
Guest User

Untitled

a guest
Oct 22nd, 2019
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.41 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. #
  4. # Python verion of NP03 detector simulation program.
  5. #
  6. # The files contain a series of events generated by the GEANT4 simulation program.
  7. # The simulation is an infinite block of either Silicon or Germanium. Photons
  8. # are generated at the origin pointing along the positive x axis. The simulation
  9. # generates the interactions in the following particle cascade. We are going to
  10. # make two simplifying assumptions to avoid the computing becoming too complicted.
  11. # (1) The electron and positrons deposit their energy all in one location as soon
  12. # as they are generated. This is almost true, they usually travel a few
  13. # tens of microns to deposit their energy.
  14. # (2) We neglect tertiary bremstrahlung - i.e. the process where electrons emit
  15. # photons (which move a large distance) before making electrons again. This
  16. # is not bad either - in reality <1% of events have a bremstrahlung. In the
  17. # files, the energy of the bremstrahlung photon is added in to the electron
  18. # which made it.
  19. # This means that the events in the files almost always contain a single chain of
  20. # electrons which have been knocked off by the primary photon. The exception to
  21. # this is pair production.
  22. #
  23. # There are four versions of the input files simulated with different parameters
  24. # the variations in their file names are given here in brackets.
  25. # Two of the files are simulated with Silicon (Si), and two with Germanium (Ge).
  26. # Two start with monoenergetic 'Cesium' photons E=0.6617MeV (Cs) and the other
  27. # two have photons with random energies uniformly from 0.030MeV to 3.030MeV (All)
  28. #
  29. # The next clump of comments document the input file format in too much detail
  30. # to begin with. You don't need to know all the detail to start, probably. The
  31. # program loops over the events and reads them in. Better start by looking at the
  32. # comments in the loop which gives the meaning of the variables which have been read.
  33. #
  34. # Here is an example of an event. It contains a series of 'E' lines followed by
  35. # one 'M' line which indicates the end of the event. The 'E' lines represent a
  36. # particle within one interaction. The 3 numbers in the 1st bracket are (x,y,z)
  37. # of the end of the first step the particle made (we think it is where it first
  38. # interacts?). The next 4 numbers are also in brackets and are not used (except
  39. # that the first 3 are a repeat of the x,y,z of the parent particle). The final six
  40. # bits of information are partice-type particle-energy ignore-next partID parentID
  41. # interact-code. The one to ignore is the energy loss inside the GEANT step. This
  42. # is not useful without more info from GEANT because it can step the particle
  43. # more than once.
  44. # Energies are in MeV. Distances are in mm (must check the mm).
  45. # The interact-code is compt=compton scatter, conv=pair production (aka conversion)
  46. # phot=photoelectric. For the photon, it gives the first interaction which happened.
  47. # The interact-code of the electron is usually eIoni=Electron ionisation.
  48. #
  49. #E (103.595025,0.000000,0.000000) (0.000000,0.000000,0.000000,0.000000) gamma 0.661700 0.000000 1 0 compt
  50. #E (110.054005,129.214988,-29.651278) (103.595025,0.000000,0.000000,103.595025) e- 0.052832 0.052832 11 1 eIoni
  51. #E (104.175232,126.425472,-27.431369) (103.595025,0.000000,0.000000,103.595025) e- 0.002926 0.002926 10 1 eIoni
  52. #E (104.103995,123.438379,-24.163798) (103.595025,0.000000,0.000000,103.595025) e- 0.014981 0.014981 9 1 eIoni
  53. #E (104.992130,124.195952,-25.239895) (103.595025,0.000000,0.000000,103.595025) e- 0.028011 0.028011 8 1 eIoni
  54. #E (100.363148,119.641707,-21.950251) (103.595025,0.000000,0.000000,103.595025) e- 0.058091 0.058091 7 1 eIoni
  55. #E (104.220751,127.052374,-33.705091) (103.595025,0.000000,0.000000,103.595025) e- 0.140492 0.140492 6 1 eIoni
  56. #E (114.121669,96.487046,-29.259889) (103.595025,0.000000,0.000000,103.595025) e- 0.018915 0.018915 5 1 eIoni
  57. #E (143.836794,59.362828,-7.262470) (103.595025,0.000000,0.000000,103.595025) e- 0.054741 0.054741 4 1 eIoni
  58. #E (143.944857,31.562242,-3.126021) (103.595025,0.000000,0.000000,103.595025) e- 0.145172 0.145172 3 1 eIoni
  59. #E (103.624575,-0.036994,0.003667) (103.595025,0.000000,0.000000,103.595025) e- 0.143694 0.143694 2 1 eIoni
  60. #M 0 0.661700 gamma compt 0.659855 0.997212 -0.001845
  61.  
  62. # The numbers on the 'M' line are: event-number first-particle-energy first-particle-type
  63. # first-interaction-of-first-particle sum-of-all-secondary-energy. The last two give the
  64. # discrepancy between the first-particle-energy and the sum-of-all-secondary-energy,
  65. # the first as a fraction, the second as a difference. The difference seems to be
  66. # the more consistent, perhaps there is some atomic binding energy or something.
  67. # If there was a pair production, the rest mass energy of the e+e- is not included in
  68. # the total.
  69.  
  70. import sys
  71. import math
  72.  
  73. def main():
  74. # Check correct arguments
  75. if len(sys.argv) != 3:
  76. print "usage: %s <in-text-file> <out-text-file>" % sys.argv[0]
  77. sys.exit(1)
  78.  
  79. infile = sys.argv[1]
  80. outfile = sys.argv[2]
  81.  
  82. # Open input text file (this is printout from the MC with 'vent:' lines added
  83. if infile == "-": inf = sys.stdin
  84. else: inf = open(infile,'rU')
  85. if not inf:
  86. print "Input file %d cannot be opened" % outfile
  87. sys.exit(1)
  88.  
  89. # Open output file
  90. if outfile == "-": ouf = sys.stdout
  91. else: ouf = open(outfile,'wU')
  92. if not ouf:
  93. print "Output file %d cannot be opened" % outfile
  94. sys.exit(1)
  95.  
  96. # ***Place to modify*** Reserve space for histogramming
  97. NBINS = 300
  98. henerall = [0]*NBINS # Makes an array with 100 elements and puts zero in each
  99. henerpeak = [0]*NBINS
  100. htener = [0]*NBINS
  101.  
  102. # Main loop
  103. tener = 0. # Variable for total energy detected
  104. while (1): # Infinite loop, exit with break statement below
  105. line = inf.readline() # read one line from file
  106. if line == "": break # readline only returns empty at end of file
  107. line = line.rstrip('\n') # get rid of the carriage return character
  108.  
  109. # An E line. Unpack and add energy to total if wanted
  110. if line[0] == 'E':
  111. (text, Sxyz, Spxyzr, Spart, Sener, Sdener, Sid, Spid, Sinter) = line.split()
  112. (Sx,Sy,Sz) = Sxyz.lstrip('(').rstrip(')').split(',') # Splits the first xyz bracket
  113. (Spx,Spy,Spz,Spr) = Spxyzr.lstrip('(').rstrip(')').split(',') # Splits the second xyzr bracket
  114.  
  115. # The above variables are all still character strings (start with capital S)
  116. # Convert them to floats and integers (use lowercase s)
  117. sx = float(Sx) # x position of step (mm)
  118. sy = float(Sy) # y position of step (mm)
  119. sz = float(Sz) # z position of step (mm)
  120. spx = float(Spx) # x position of photon in it's step (mm)
  121. spy = float(Spy) # y position of photon in it's step (mm)
  122. spz = float(Spz) # z position of photon in it's step (mm)
  123. spart = Spart # Particle name 'gamma', 'e-' or 'e+'
  124. sener = float(Sener) # Particle energy (MeV)
  125. sid = int(Sid) # Particle ID (1=primary photon)
  126. spid = int(Spid) # Particle ID of parent
  127. sinter = Sinter # Inteaction-code (see above)
  128.  
  129. # ***Place to modify*** Decide whether to add in the energy
  130. if (Spart == "e-" or Spart == "e+"): # Only e+ and e-, not photons
  131. if math.sqrt(sy*sy+sz*sz) < 30.: # radius 3cm
  132. if sx > 0. and sx < 100.: # 10cm long
  133. tener = tener + sener
  134.  
  135. # End of 'E' line processing (python just ends indent to end if or loop!)
  136.  
  137. # An 'M' line. Process the event, and reset total for next
  138. if line[0] == 'M':
  139. (text,Mevno,Mener,Mpart,Minter,Menert,Mratio,Mdifference) = line.split()
  140. mevno = int(Mevno) # Event number
  141. mener = float(Mener) # Energy of photon
  142. mpart = Mpart # Particle type of primary (should be 'photon')
  143. minter = Minter # First interaction of primary usually 'conv', 'compt' or 'phot'
  144. menert = Menert # Total energy of secondaries
  145.  
  146. # ***Place to modify*** Histogram filling
  147. # Make an integer which is the bin number from 0 to 99 for E=0 to 3
  148. # Put events above 3MeV in bin 99
  149. ib = int(mener/3.0*float(NBINS))
  150. if ib < 0: ib = 0
  151. if ib >= NBINS: ib = NBINS-1
  152.  
  153. henerall[ib] = henerall[ib]+1
  154. d = tener - mener # Difference in energy (nearly 0 if on peak)
  155. if d > -0.02 and d < 0.02: henerpeak[ib] = henerpeak[ib]+1
  156.  
  157. # Similar bin calculation to above for tener
  158. ibt = int(tener/3.0*float(NBINS))
  159. if ibt < 0: ibt = 0
  160. if ibt >= NBINS: ibt = NBINS-1
  161. htener[ibt] = htener[ibt] + 1
  162.  
  163. # Reset variables which are accumulted in the E lines for next event
  164. tener = 0.
  165.  
  166. # Print occasionally so we know it is running
  167. if mevno%10000 == 0: print "Just done event ",mevno
  168.  
  169. # End of 'M' line processing (python just ends indent to end if or loops)
  170.  
  171. # End of loop.
  172.  
  173. # Now write a table from histograms to output file
  174. for ib in range(NBINS):
  175. e = ib*3.0/float(NBINS) # Invert the ib calculation above to get energy at bottom edge of bin
  176. print >>ouf,e,henerall[ib],henerpeak[ib],htener[ib]
  177.  
  178. inf.close()
  179. ouf.close()
  180.  
  181. if __name__=='__main__':main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement