Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:27:05

0001 import pyhepmc as hep
0002 from pyhepmc.io import WriterAscii
0003 import random as rd
0004 from datetime import datetime
0005 import argparse
0006 
0007 # ============================================================================================
0008 # Prints a banner
0009 def banner(Signal_File,Background_Files,one_background_particle,int_window):
0010     print('\n==================================================================')
0011     print('*** EPIC HEPMC MERGER ***')
0012     print('author: Benjamen Sterwerf, UC Berkeley (bsterwerf@berkeley.edu)')
0013     print('\nRun this code as:\npython signal_background_merger.py --help\nto get more info')
0014     print('------------------------------------------------------------------')
0015     print('Signal events will be read from:')
0016     print('\t- ',Signal_File,'\n')
0017     print('Background files will be read from:')
0018     for bf in Background_Files:
0019         print('\t- ',bf)
0020     print('\none_background_particle:',one_background_particle)
0021     print('Int_Window:',int_window, 'ns')
0022     print('==================================================================\n')
0023 
0024 # ============================================================================================
0025 # opens HEPMC File in any generation and appends each event to a container which is then returned
0026 def fileProcess(fileName):
0027     container=[]
0028     with hep.open(fileName) as f:
0029         for event in f:
0030             container.append(event)
0031             pass
0032     return container
0033 
0034 # ============================================================================================
0035 def merger(one_background_particle,Int_Window,sig_cont,back_cont):
0036 
0037     c_light  = 299.792458 # speed of light = 299.792458 mm/ns to get mm
0038     combo_cont=[] # container for combo events
0039 
0040     lengths = [len(bck) for bck in back_cont]
0041     lengths.extend([len(sig_cont)])
0042 
0043     # If files are provided with variable number of events, run as many events as events are in the smallest file
0044     # i here are events
0045     for i in range(min(lengths)):
0046         combo_cont.append(hep.GenEvent(hep.Units.GEV, hep.Units.MM))
0047 
0048         # -----------------------------------------------------
0049         # SIGNALS
0050         sig_particles, sig_vertices = [], []
0051         sig_time_shift = c_light*(Int_Window*rd.random())
0052         
0053         # Stores the vertices of the event inside a vertex container. These vertices are in increasing order so we can index them with [abs(vertex_id)-1]
0054         for vertex in sig_cont[i].vertices:
0055             position=vertex.position
0056             #if we are shifting the event in time uses the random time generator and adds this time to the position four vector for the vertex
0057             if Int_Window > 0:
0058                 position=position+hep.FourVector(x=0,y=0,z=0,t=sig_time_shift)
0059             v1=hep.GenVertex(position)
0060             sig_vertices.append(v1)
0061         
0062         # copies the particles and attaches them to their corresponding vertices
0063         for particle in sig_cont[i].particles:
0064             momentum = particle.momentum
0065             status = particle.status
0066             pid = particle.pid
0067             
0068             # hep.GenParticle(momentum(px,py,pz,e), pdgid, status)
0069             p1 = hep.GenParticle(momentum, pid, status)
0070             p1.generated_mass = particle.generated_mass
0071             sig_particles.append(p1)
0072             # since the beam particles do not have a production vertex they cannot be attached to a production vertex
0073             if particle.production_vertex.id < 0:
0074                 production_vertex=particle.production_vertex.id
0075                 sig_vertices[abs(production_vertex)-1].add_particle_out(p1)
0076                 combo_cont[i].add_particle(p1)
0077             # Adds particles with an end vertex to their end vertices
0078             if particle.end_vertex:
0079                 end_vertex = particle.end_vertex.id
0080                 sig_vertices[abs(end_vertex)-1].add_particle_in(p1)
0081         # Adds the vertices with the attached particles to the event
0082         for vertex in sig_vertices:
0083             combo_cont[i].add_vertex(vertex)
0084         
0085         # -----------------------------------------------------
0086         # BACKGROUNDS
0087         # Loop over different background input files
0088         for b in range(len(back_cont)):
0089             back_particles, back_vertices = [], []
0090 
0091             # Standard use except for SR backgrounds. Will only shift the background event when this conditional is triggered.
0092             if one_background_particle:
0093                 #time to shift each background vertex
0094                 back_time_shift = c_light*(Int_Window*rd.random())
0095 
0096             for vertex in back_cont[b][i].vertices:
0097 
0098                 position=vertex.position
0099                 # When the background event has many particles separated in time, like SR backgrounds, trigger this coniditional by changing the one_background_particle to False
0100                 if one_background_particle == False:
0101                     back_time_shift = c_light*(Int_Window*rd.random())
0102                 position = position+hep.FourVector(x=0,y=0,z=0,t=back_time_shift)
0103                 v1 = hep.GenVertex(position)
0104                 back_vertices.append(v1)
0105 
0106             # copies the particles and attaches them to their corresponding vertices
0107             for particle in back_cont[b][i].particles:
0108                 momentum = particle.momentum
0109                 status = particle.status
0110                 pid = particle.pid
0111 
0112                 # hep.GenParticle(momentum(px,py,pz,e), pdgid, status)
0113                 p1 = hep.GenParticle(momentum, pid, status)
0114                 p1.generated_mass = particle.generated_mass
0115                 back_particles.append(p1)
0116                 # since the beam particles do not have a production vertex they cannot be attached to a production vertex
0117                 if particle.production_vertex.id < 0:
0118                     production_vertex = particle.production_vertex.id
0119                     back_vertices[abs(production_vertex)-1].add_particle_out(p1)
0120                     combo_cont[i].add_particle(p1)
0121                 # Adds particles with an end vertex to their end vertices
0122                 if particle.end_vertex:     
0123                     end_vertex = particle.end_vertex.id
0124                     back_vertices[abs(end_vertex)-1].add_particle_in(p1)
0125             # Adds the vertices with the attached particles to the event        
0126             for vertex in back_vertices:
0127                 combo_cont[i].add_vertex(vertex)
0128     return combo_cont
0129 
0130 # ============================================================================================
0131 def nameGen(numEvents):
0132     # datetime object containing current date and time
0133     now = datetime.now()
0134     dt_string = now.strftime("%Y_%m_%d_%H_%M_%S") # YY/mm/dd H:M:S
0135     return 'Sig_Back_Combo_{}_{}_event.hepmc'.format(dt_string,numEvents)
0136 
0137 # ============================================================================================
0138 def fileWriter(combo_cont):
0139     numEvents=len(combo_cont)
0140     name=nameGen(numEvents)
0141     Event_ind=0
0142     with WriterAscii(name) as f:
0143         for i in combo_cont:
0144             i.event_number=Event_ind
0145             Event_ind=Event_ind+1
0146             f.write_event(i)
0147     f.close()
0148 
0149 # ============================================================================================
0150 # Main function
0151 if __name__ == '__main__':
0152 
0153     parser = argparse.ArgumentParser(description='Run this code as: python signal_background_merger.py --Int_Window 2000 --one_background_particle False --Signal_File signal.hepmc --Background_Files background_1.hepmc background_2.hepmc')
0154     parser.add_argument('--one_background_particle', 
0155                         help='Set to True if all the background vertices in the file are to be connected temporally and spatially and False for backgrounds with many particles in the event like SR (synchrotron radiation)', 
0156                         action='store_true')
0157     parser.add_argument('--Int_Window', action='store', type=float, default=0.0,
0158                         help='length of the integration window in nanoseconds. Default is 0. If set to a positive value (in ns), the signal event will be moved to a random time within the integration window')
0159     parser.add_argument('--Signal_File', action='store',
0160                         help='Name of the HEPMC file with the signal events',default='dummy_signal.hepmc')
0161     parser.add_argument('--Background_Files', action='store', nargs='+',
0162                         help='Names of the HEPMC files with background events',default=['SR_out_single.hepmc.gz','dummy_background_2.hepmc'])
0163     
0164     args = parser.parse_args()    
0165 
0166     # Depending on the background type.
0167     # SR Synchrotron radiation will be set too false since there will be many individual photons
0168     one_background_particle = args.one_background_particle
0169 
0170     # opens up the signal file and extracts all individual events stores these events in sig_cont
0171     sig_cont=fileProcess(args.Signal_File)
0172 
0173     # opens up the background files and extracts all individual events. stores these events in back_cont
0174     back_cont = [ fileProcess(bck) for bck in args.Background_Files ]
0175 
0176     # integration window
0177     int_window = args.Int_Window
0178 
0179     banner(args.Signal_File,args.Background_Files,one_background_particle,int_window)
0180 
0181     # merger(one_background_particle,shift,Int_Window,sig_cont,back_cont)
0182     combo_cont= merger(args.one_background_particle,int_window,sig_cont,back_cont)
0183 
0184     fileWriter(combo_cont)