def compute(opt_input, path, effective, zenith_sim, azimuth_sim, energy, injection_height, primary, json_file=None): #=========================================================================================================== if opt_input == 'json': # shower you are interested in showerID = str(path.split('/')[-1]) if not showerID: showerID = str(path.split('/')[-2]) # Find that shower in the json file event = [ evt for evt in EventIterator(json_file) if evt["tag"] == showerID ][0] ### json file containing additional data for analysis filename = str(showerID) + ".voltage.json" path2 = join(path_json, filename) print path2 log_event = EventLogger(path=path2) voltage = [] time_peaks = [] print "Zenith, azimuth=", zenith_sim, azimuth_sim ########################################################################################## ###Handing over one antenna or a whole array if opt_input == 'txt': if len(sys.argv) >= 7: # just one specif antenna handed over start = int(sys.argv[6]) # antenna ID end = start + 1 # print "single antenna with ID: ", str(start)," handed over" if len(sys.argv) < 7: # grep all antennas from the antenna file positions = np.genfromtxt(path + '/antpos.dat') start = 0 end = len(positions) # print "Array with ", end, " antennas handed over" elif opt_input == 'json': if len(sys.argv) >= 7: # just one specif antenna handed over start = int(sys.argv[6]) # antenna ID end = start + 1 # print "single antenna with ID: ", str(start)," handed over" if len(sys.argv) < 7: # grep all antennas from the antenna file positions = np.array(event["antennas"], dtype=float) decay_pos = event["tau_at_decay"][1] positions = positions - [decay_pos[0], decay_pos[1], 0.] #positions=np.genfromtxt(path+'/antpos.dat') start = 0 end = len(positions) #print "Array with ", end, " antennas handed over" elif opt_input == 'manual': if len(sys.argv) >= 11: # just one specif antenna handed over start = int(sys.argv[10]) # antenna ID end = start + 1 # print "single antenna with ID: ", str(start)," handed over" if len(sys.argv) < 11: # grep all antennas from the antenna file positions = np.genfromtxt(path + '/antpos.dat') start = 0 end = len(positions) # print "Array with ", end, " antennas handed over" if effective == 1: # effective zenith caclculation needs Xmax position as input # print "effective zenith calculated - Xmax position approximated ..." # Then compute Xmax caz = np.cos(np.deg2rad(azimuth_sim)) saz = np.sin(np.deg2rad(azimuth_sim)) czen = np.cos(np.deg2rad(zenith_sim)) szen = np.sin(np.deg2rad(zenith_sim)) Xmax_primary = modules._getXmax( primary, energy, np.deg2rad(zenith_sim) ) # approximation based on values from plots for gamma (=e) and protons (=pi) # g/cm2 Xmax_height, Xmax_distance = modules._dist_decay_Xmax( np.deg2rad(zenith_sim), injection_height, Xmax_primary) # d_prime: distance from decay point to Xmax Xmax = Xmax_distance * np.array([caz * szen, saz * szen, czen ]) + np.array( [0, 0, injection_height]) # print 'Xmax=',Xmax_primary,' Xmax height=',Xmax_height,' Xmax distance =',Xmax_distance,'Xmax position= ',Xmax # print 'Now computing Xmax position from injection height=',injection_height,'m and (zen,azim) values.' ###### loop over l --- LOOP OVER ANTENNA ARRAY for l in range(start, end): efieldtxt = path + '/a' + str(l) + '.trace' # print 'Wave direction: zenith = ', zenith_sim, ' deg, azimuth = ', azimuth_sim, 'deg. (GRAND conventions), mountain slope: ', alpha_sim, 'deg.' # print 'Efield file: ', efieldtxt # Model the input signal. try: time1_sim, Ex_sim, Ey_sim, Ez_sim = np.loadtxt(efieldtxt, delimiter=' ', usecols=(0, 1, 2, 3), unpack=True) except IOError: continue #jlzhang if the file and the path is not exist, if will go to next antenna, so I think it should be break; # NOTE: adapt to your time from whatever to s time1_sim = time1_sim * 1e-9 # time has to be handed in s #print 'Now computing antenna response...' if effective == 1: # Compute effective zenith # First get antenna position #print 'Reading antenna position from parameter input.' if (opt_input == 'json' or opt_input == 'txt') and (len(sys.argv) == 12): x_sim = float(sys.argv[7]) y_sim = float(sys.argv[8]) z_sim = float(sys.argv[9]) # include a mountain slope - correction of zenith angle alpha_sim = float(sys.argv[10]) beta_sim = float(sys.argv[11]) elif (opt_input == 'manual') and (len(sys.argv) == 16): x_sim = float(sys.argv[11]) y_sim = float(sys.argv[12]) z_sim = float(sys.argv[13]) # include a mountain slope - correction of zenith angle alpha_sim = float(sys.argv[14]) beta_sim = float(sys.argv[15]) else: try: if opt_input == 'json': x_sim, y_sim, z_sim = positions[ l] #,alpha_sim,beta_sim alpha_sim = 0. beta_sim = 0. else: #print 'Trying to read antenna position from antpos.dat file...' numberline = int(l) + 1 line = linecache.getline(path + '/antpos.dat', numberline) #[x_sim, y_sim, z_sim] = map(float, line.split()) [x_sim, y_sim, z_sim, alpha_sim, beta_sim] = map(float, line.split()) #print 'Read antenna position from antpos.dat file... Antenna',l,' at position [', x_sim, y_sim, z_sim,'].' except: print 'No antenna position file found, please put antpos.dat in', path, 'or enter check antenna informations in json file or enter antenna positions as arguments.' sys.exit() Xant = [x_sim, y_sim, z_sim] # Hack OMH 24/01 alpha_sim = 10 beta_sim = 0 Xant = [400000, 0, 0] ush = Xmax - Xant ush = ush / np.linalg.norm( ush) # Unitary vector pointing to Xmax from antenna pos voltage_NS, timeNS = get_voltage(time1=time1_sim, Ex=Ex_sim, Ey=Ey_sim, Ez=Ez_sim, ush=ush, alpha=alpha_sim, beta=beta_sim, typ="X") voltage_EW, timeEW = get_voltage(time1=time1_sim, Ex=Ex_sim, Ey=Ey_sim, Ez=Ez_sim, ush=ush, alpha=alpha_sim, beta=beta_sim, typ="Y") voltage_vert, timevert = get_voltage(time1=time1_sim, Ex=Ex_sim, Ey=Ey_sim, Ez=Ez_sim, ush=ush, alpha=alpha_sim, beta=beta_sim, typ="Z") #pl.savetxt(path+'out_'+str(l)+'.txt', (timeEW, voltage_EW, voltage_NS), newline='\r\n')#, voltage_NS)) # is not working correctly if np.size(timeEW) > 0: # Dat was computed f = file(pathout + '/out_' + str(l) + '.txt', "w") #print "OUTFILE : ", pathout+'/out_'+str(l)+'.txt' for i in np.arange(len(timeEW)): print >> f, "%1.5e %1.2e %1.2e %1.2e" % ( timeNS[i], voltage_NS[i], voltage_EW[i], voltage_vert[i] ) # same number of digits as input f.close() ###plots DISPLAY = 1 if DISPLAY == 1: import pylab as pl import matplotlib.pyplot as plt plt.figure(1, facecolor='w', edgecolor='k') plt.subplot(211) plt.plot(time1_sim * 1e9, Ey_sim, label="Ey = EW") plt.plot(time1_sim * 1e9, Ex_sim, label="Ex = NS") plt.plot(time1_sim * 1e9, Ez_sim, label="Ez = UP") plt.xlabel('Time (nsec)') plt.ylabel('Electric field (muV/m)') plt.legend(loc='best') plt.subplot(212) plt.plot(timeEW * 1e9, voltage_EW, label="EW") plt.plot(timeEW * 1e9, voltage_NS, label="NS") plt.plot(timeEW * 1e9, voltage_vert, label="Vertical") plt.xlabel('Time (nsec)') plt.ylabel('Voltage (muV)') plt.legend(loc='best') plt.show() ################################################################## ################################################################## if opt_input == 'json': #### additional output needed for later study, added in the json file # p2p voltage: antenna ID, p2p EW, NS, UP, EW+NS voltage_com = np.copy(voltage_EW) for i in range(0, len(voltage_EW)): voltage_com[i] += voltage_NS[i] v_list = ( str(l), max(voltage_EW) - min(voltage_EW), max(voltage_NS) - min(voltage_NS), max(voltage_vert) - min(voltage_vert), max(voltage_com) - min(voltage_com) ) #jlzhang zen>90, so there is no voltage, the max() will be empty voltage.append(v_list) # time of peaks and value: t_EW_max, v_EW_max, t_EW_min, v_EW_min,.... EW, NS, vert, EW+NS import operator EW_ind_max, value = max(enumerate(voltage_EW), key=operator.itemgetter(1)) EW_ind_min, value = min(enumerate(voltage_EW), key=operator.itemgetter(1)) NS_ind_max, value = max(enumerate(voltage_NS), key=operator.itemgetter(1)) NS_ind_min, value = min(enumerate(voltage_NS), key=operator.itemgetter(1)) vert_ind_max, value = max(enumerate(voltage_vert), key=operator.itemgetter(1)) vert_ind_min, value = min(enumerate(voltage_vert), key=operator.itemgetter(1)) com_ind_max, value = max(enumerate(voltage_com), key=operator.itemgetter(1)) com_ind_min, value = min(enumerate(voltage_com), key=operator.itemgetter(1)) time_peaks.append( (round(timeEW[EW_ind_max], 11), voltage_EW[EW_ind_max], round(timeEW[EW_ind_min], 11), voltage_EW[EW_ind_min], round(timeNS[NS_ind_max], 11), voltage_NS[NS_ind_max], round(timeNS[NS_ind_min], 11), voltage_NS[NS_ind_min], round(timevert[vert_ind_max], 11), voltage_vert[vert_ind_max], round(timevert[vert_ind_min], 11), voltage_vert[vert_ind_min], round(timeEW[com_ind_max], 11), voltage_com[com_ind_max], round(timeEW[com_ind_min], 11), voltage_com[com_ind_min])) ############### end of loop over antennas if opt_input == 'json': if len(voltage) == 0: print "- effective zenith not fulfilled - NO VOLTAGE COMPUTED" log_event(**event) else: # add the additional informations to the shower event event['voltage'] = voltage # muV event['time_peaks'] = time_peaks # s, muV log_event(**event)
def main(): """ Main script allowing to produce the ZHAireS input files for each one of the showers from a DANTON library """ ################################################################## # Test arguments if (len(sys.argv) < 2 or len(sys.argv) > 3): print """\ This script will allow to produce the ZHAireS input files for cosmic-rays (hence down-going). It reads the antenna positions defined for GRANDproto300 (x,y,altitude). The energy is hardcoded. AZIMUTH [0,360[, ZENITH [90, 140[, core position (chosen between -draw_area_size and +draw_area_size around the origin both in x and y directions) are randomized. Then a selection of the antenna falling into the Cherenkov ring is done and the process is iterated until more than MIN_ANTENNAS antennas are contained in the Cherenkov ring. The number of tries needed to meet the criterion to get one event is recorded together with a bunch of informations about the shower and the array. Inputs : work_dir = directory where all ZHAireS input files and the simulation results will be stored. Ouput: The script will produce as many ZHAireS input files as there are combinations between the requested energies, zeniths and azimuths (respectively in tables pwr_EE, ZENITH and AZIMUTH). They will located in the work_dir+"/inp/" directory. Usage: python PrepCR_zhaires_GP300.py work_dir Notes: The global variable DISPLAY allows you to turn on/off the display of the 3D map of the radio array and the print-out of the processed showers The "compute_antenna_pos" function can easily be modified/replaced to build a different antenna array configuration (star-shape pattern, circularly distributed, ...) """ #in RASPASS North <=> azim=180 because azim and zenith reversed to trick Aires and then indicate dir of propag instead of dir of origin sys.exit(1) print('******************************') ################################################################## # Retrieve the input parameters # ROOT = "/home/renault/CRs_GP300/" output_folder = str(sys.argv[1]) DISPLAY = False ################################################################## #Showers parameters pwr_EE = np.array([16.5, 17., 17.5, 18., 18.5, 19., 19.5], dtype=str) #in eV injh = 100e3 #above sea level in m draw_area_size = 50e3 #m ################################################################## # Compute an antenna array #ANTENNAS = np.loadtxt('/Users/nrenault/Downloads/GP300/5_good/GP300_antpos.txt') #antcoord = np.loadtxt('/Users/nrenault/Downloads/GP300/5_good/GP300_antcoord.txt') antcoord = np.loadtxt( '/home/renault/CRs_GP300/GP300_layout/5_good/GP300_antcoord.txt') ANTENNAS = np.loadtxt( '/home/renault/CRs_GP300/GP300_layout/5_good/GP300_antpos.txt') ANTENNAS[:, 2] = antcoord[:, 2] ### Reduce the radio array to the shower geometrical footprint (we account for a footprint twice larger than the Cherenkov angle) dx = draw_area_size #+ (np.amax(ANTENNAS[:,0])-np.amin(ANTENNAS[:,0]))/2 dy = draw_area_size #+ (np.amax(ANTENNAS[:,1])-np.amin(ANTENNAS[:,1]))/2 shower_infos = [] Nwish = 500 ievt = 0 for eny in pwr_EE: #[:1]: Nevents = 0 while Nevents < Nwish: ievt += 1 azim = random.uniform(0., 1.) * 360. #GRAND convention zen = random.uniform( 0., 1. ) * 50. + 90. #GRAND convention #zenith between 90 and 140 deg # Compute informations on Xmax Xmax_primary, zen_inj = modules._getXmax('proton', 10**float(eny) / 1e9, np.deg2rad(zen), GdAlt, injh) # approximation based on values from plots for gamma (=e) and protons (=pi) # g/cm2 Xmax_height, Xmax_distance = modules._dist_decay_Xmax( zen_inj, injh, Xmax_primary) # d_prime: distance from decay point to Xmax # Sample the shower core position. b = np.mean(ANTENNAS[:, 0:], axis=0) ANTENNAS1 = np.copy(ANTENNAS) x = random.uniform(b[0] - dx, b[0] + dx) y = random.uniform(b[1] - dy, b[1] + dy) try: altcore = topo.ground_altitude(x, y) except: altcore = 2000. ANTENNAS2 = reduce_antenna_array(Xmax_height, zen, azim, ANTENNAS1, x, y, altcore, 10**float(eny) / 1e9, DISPLAY) #Xmax_height if len(ANTENNAS2) >= MIN_ANTENNAS: Nevents += 1 task = 'EE1E' + eny + '_evt' + str(Nevents) print Nevents, ievt, azim, zen, x, y, len(ANTENNAS2) totito = generate_input(task, 10**float(eny), azim, zen, ANTENNAS2 - [x, y, 0.]) #Write file fileZha = output_folder + 'inp/' + task + '.inp' dir = os.path.dirname(fileZha) if not os.path.exists(dir): os.makedirs(dir) os.makedirs(dir + '/fig/') inpfile = open(fileZha, "w+") inpfile.write(totito) inpfile.close() plot_drawn_pos(ANTENNAS1, ANTENNAS2, [x, y, altcore], output_folder, task, DISPLAY) shower_infos.append([ ievt, Nevents, 10**float(eny) / 1e18, azim, zen, len(ANTENNAS2), b[0], b[1], x, y, altcore, dx, dy, GdAlt, MIN_ANTENNAS ]) else: shower_infos.append([ ievt, 0, 10**float(eny) / 1e18, azim, zen, len(ANTENNAS2), b[0], b[1], x, y, altcore, dx, dy, GdAlt, MIN_ANTENNAS ]) shower_info_file = output_folder + '/inp/summary_table.txt' shower_infos = np.array(shower_infos) hdr = '\n'.join([ "NumEvt Nevents_selected[0 if not selected] Energy[EeV] Azimuth_GRAND[deg] Zenith_GRAND[deg] NAntennas Xmean_array[m] Ymean_array[m] Xcore[m] Ycore[m] AltCore[m] dx[m] dy[m] GroundAltitudeAboveSeaLevel[m] MinAntennas" ]) np.savetxt( shower_info_file, shower_infos, fmt= '%d %d %0.2f %0.2f %0.2f %d %0.2f %0.2f %0.2f %0.2f %0.2f %0.1f %0.1f %0.2f %d', header=hdr)
def fresnel(event): """Extract the relevant tau info from an event""" global origin, topo, flat #50MHz: lam=6m #100MHz: lam=3m c0 = 299792458 freq = np.arange(20,300)*1e6 # 100MHz lam = c0/freq if flat==False and event["origin"] != origin: # Update the topography handle if required print "Loading new topo tile..." latitude, longitude = origin = event["origin"] print "(lat, lont)",latitude, longitude topo = Topography(latitude=latitude, longitude=longitude,path=MAPDIR, stack_size=121) print 'Done.' # Get decay parameters _, _, r0, u, _, _ = event["tau_at_decay"] r0, u = map(np.array, (r0, u)) tagall = event["tag"] tag = int(tagall.split(".")[-1]) # Compute the shower energy shower_energy = 0. for (pid_, momentum) in event["decay"]: aid = abs(pid_) if aid in (12, 13, 14, 16): continue shower_energy += sum(m**2 for m in momentum)**0.5 zenith = np.arccos(-u[2]) # Zenith angle @ injection point (Zhaires convention, Radians) # Get Xmax location Xmax_primary = modules._getXmax("pion", shower_energy,_) # Slant Xmax #decayHeight = r0[2]-getGroundAltitudeFlat(r0) decayHeight = np.linalg.norm([r0[0],r0[1],r0[2]+Rt])-Rt Xmax_height, Xmax_distance = modules._dist_decay_Xmax(zenith, decayHeight, Xmax_primary) # d_prime: distance from decay point to Xmax r1 = r0 + u * Xmax_distance # Xmax position print 'Shower vector:',u print 'Injection point:',r0 print 'Xmax:',r1 print 'Xmax distance (km) =',Xmax_distance/1e3 #raw_input() # Get antenna data ra = np.array(event["antennas"])[:, :3] attfile=tagall+".att" if os.path.isfile(attfile): os.remove(attfile) # Delete old file fid=open(attfile,'a') ## Loop on antennas in the shower for i in range(len(ra[:, 1])): #print '*** Antenna ',i,ra[i, :] dBAtt = np.ones((1,len(lam))) # Loop n all frequencies for j in range(len(lam)): # Determine Fresnel range r, f, a, m, s= compute_ray(r1,ra[i, :],lam[j]) # Ray is along line of sigth from Xmax to antenna if r is None: # Antenna is to far break if r<0: # Non continuous LoS ==> skip this frequency continue if r>0: # Compute attenuation in Fresnel range v = np.array(r1-ra[i,:]) vn = v/np.linalg.norm(v) rx = ra[i,:]+vn*r #Ray location at position of Fresnel range hx = rx[2]-f #print 'Source distance, height:',r,hx dbAtt2, ind2 = diffLossFlat(r,hx,lam[j]) if r==0: dbAtt2, ind2 = 0, 0 dBAtt[0,j] = dbAtt2 dBAtt = np.insert(dBAtt,0,int(i)) if DISPLAY == 1: print 'Range,Att:',r,dBAtt np.savetxt(fid, dBAtt[np.newaxis],fmt="%s",delimiter=' ',newline='\n')
def compute(opt_input,path, effective,zenith_sim, azimuth_sim, energy, injection_height, primary,json_file=None): #=========================================================================================================== if opt_input=='json': # shower you are interested in showerID = str(path.split('/')[-1]) if not showerID: showerID = str(path.split('/')[-2]) # Find that shower in the json file event = [evt for evt in EventIterator(json_file) if evt["tag"]==showerID][0] log_event = EventLogger(path=json_file) voltage=[] time_peaks=[] ########################################################################################## ###Handing over one antenna or a whole array if opt_input=='txt': if len(sys.argv)>=6: # just one specif antenna handed over start=int(sys.argv[5]) # antenna ID end=start+1 # print "single antenna with ID: ", str(start)," handed over" if len(sys.argv)<6: # grep all antennas from the antenna file positions=np.genfromtxt(path+'/antpos.dat') start=0 end=len(positions) # print "Array with ", end, " antennas handed over" elif opt_input=='json': if len(sys.argv)>=6: # just one specif antenna handed over start=int(sys.argv[5]) # antenna ID end=start+1 # print "single antenna with ID: ", str(start)," handed over" if len(sys.argv)<6: # grep all antennas from the antenna file positions=np.array(event["antennas"],dtype=float) decay_pos=event["tau_at_decay"][1] positions = positions - [decay_pos[0],decay_pos[1],0.] #positions=np.genfromtxt(path+'/antpos.dat') start=0 end=len(positions) #print "Array with ", end, " antennas handed over" elif opt_input=='manual': if len(sys.argv)>=10: # just one specif antenna handed over start=int(sys.argv[9]) # antenna ID end=start+1 # print "single antenna with ID: ", str(start)," handed over" if len(sys.argv)<10: # grep all antennas from the antenna file positions=np.genfromtxt(path+'/antpos.dat') start=0 end=len(positions) # print "Array with ", end, " antennas handed over" if effective==1: # effective zenith caclculation needs Xmax position as input # print "effective zenith calculated - Xmax position approximated ..." # Then compute Xmax caz = np.cos(np.deg2rad(azimuth_sim)) saz = np.sin(np.deg2rad(azimuth_sim)) czen = np.cos(np.deg2rad(zenith_sim)) szen = np.sin(np.deg2rad(zenith_sim)) Xmax_primary = modules._getXmax(primary, energy, np.deg2rad(zenith_sim)) # approximation based on values from plots for gamma (=e) and protons (=pi) # g/cm2 Xmax_height, Xmax_distance = modules._dist_decay_Xmax(np.deg2rad(zenith_sim), injection_height, Xmax_primary) # d_prime: distance from decay point to Xmax Xmax = Xmax_distance*np.array([caz*szen, saz*szen, czen])+np.array([0,0,injection_height]) # print 'Xmax=',Xmax_primary,' Xmax height=',Xmax_height,' Xmax distance =',Xmax_distance,'Xmax position= ',Xmax # print 'Now computing Xmax position from injection height=',injection_height,'m and (zen,azim) values.' ###### loop over l --- LOOP OVER ANTENNA ARRAY for l in range(start,end): efieldtxt=path+'/a'+str(l)+'.trace' # print 'Wave direction: zenith = ', zenith_sim, ' deg, azimuth = ', azimuth_sim, 'deg. (GRAND conventions), mountain slope: ', alpha_sim, 'deg.' # print 'Efield file: ', efieldtxt # Model the input signal. try: time1_sim, Ex_sim, Ey_sim,Ez_sim = np.loadtxt(efieldtxt,delimiter=' ',usecols=(0,1,2,3),unpack=True) except IOError: continue # NOTE: adapt to your time from whatever to s time1_sim= time1_sim*1e-9 # time has to be handed in s #print 'Now computing antenna response...' if effective==1: # Compute effective zenith # First get antenna position #print 'Reading antenna position from parameter input.' if (opt_input=='json' or opt_input=='txt') and (len(sys.argv)==11) : x_sim = float(sys.argv[6]) y_sim = float(sys.argv[7]) z_sim = float(sys.argv[8]) # include a mountain slope - correction of zenith angle alpha_sim=float(sys.argv[9]) beta_sim=float(sys.argv[10]) elif (opt_input=='manual') and (len(sys.argv)==15) : x_sim = float(sys.argv[10]) y_sim = float(sys.argv[11]) z_sim = float(sys.argv[12]) # include a mountain slope - correction of zenith angle alpha_sim=float(sys.argv[13]) beta_sim=float(sys.argv[14]) else : try : if opt_input=='json': x_sim,y_sim,z_sim = positions[l] #,alpha_sim,beta_sim alpha_sim = 0. beta_sim = 0. else: #print 'Trying to read antenna position from antpos.dat file...' numberline = int(l) + 1 line = linecache.getline(path+'/antpos.dat', numberline) #[x_sim, y_sim, z_sim] = map(float, line.split()) [x_sim, y_sim, z_sim, alpha_sim, beta_sim] = map(float, line.split()) #print 'Read antenna position from antpos.dat file... Antenna',l,' at position [', x_sim, y_sim, z_sim,'].' except : print 'No antenna position file found, please put antpos.dat in', path, 'or enter check antenna informations in json file or enter antenna positions as arguments.' sys.exit() # Finally compute effective zenith #alpha_sim = 0. # Hack OMH 24/01 alpha_sim=10 beta_sim=0 x_sim = 400000 y_sim = 0 z_sim = 0 print "input zen, azim, alpha,beta : ", zenith_sim, azimuth_sim, alpha_sim,beta_sim #zenith_eff = effective_zenith(zenith_sim, azimuth_sim, alpha_sim, x_sim, y_sim, z_sim, Xmax[0], Xmax[1], Xmax[2]) #print 'zenith_eff = ',zenith_eff zen_inant,azim_inant = effective_angles(alpha_sim, beta_sim, x_sim, y_sim, z_sim, Xmax[0], Xmax[1], Xmax[2]) print "effective zenith and azimuth in GRAND convention: ", zen_inant,azim_inant,' deg' else: # in case effective zenith not wanted, one still has to account for mountain slope # zenith: correct for mountain slope #zenith_eff= 180.-(zenith_sim+alpha_sim) # in antenna convention #zenith_eff= 180.- zenith_eff # back to GRAND conventions print('Not supported') #if zenith_eff < 90 : if zen_inant < 90 : #>90 if in NEC convention pass print ' --- Wave coming from ground (GRAND zenith smaller than 90deg), antenna response not computed for that angle. Abort --- ' #exit() else: # Compute the output voltage for EW component # print '*** Computing EW voltage...' #voltage_EW, timeEW = get_voltage( time1=time1_sim,Ex=Ex_sim, Ey=Ey_sim, Ez=Ez_sim, zenith=zenith_eff, azimuth=azimuth_sim, EW=1) voltage_EW, timeEW = get_voltage( time1=time1_sim,Ex=Ex_sim, Ey=Ey_sim, Ez=Ez_sim, zenith=zen_inant, azimuth=azim_inant, EW=1) # Compute the output voltage for NS component -- TODO add here the correct antenna file at some point # print '*** Computing SN voltage...' #voltage_NS, timeNS = get_voltage( time1=time1_sim,Ex=Ex_sim, Ey=Ey_sim, Ez=Ez_sim, zenith=zenith_eff, azimuth=azimuth_sim, EW=0) voltage_NS, timeNS = get_voltage( time1=time1_sim,Ex=Ex_sim, Ey=Ey_sim, Ez=Ez_sim, zenith=zen_inant, azimuth=azim_inant, EW=0) # Compute the output voltage for vertical component -- TODO add here the correct antenna file at some point, at the moment equivalent to EW arm # print '*** Computing Vertical voltage...' #voltage_vert, timevert = get_voltage( time1=time1_sim,Ex=Ex_sim, Ey=Ey_sim, Ez=Ez_sim, zenith=zenith_eff, azimuth=azimuth_sim, EW=2) voltage_vert, timevert = get_voltage( time1=time1_sim,Ex=Ex_sim, Ey=Ey_sim, Ez=Ez_sim, zenith=zen_inant, azimuth=azim_inant, EW=2) #pl.savetxt(path+'out_'+str(l)+'.txt', (timeEW, voltage_EW, voltage_NS), newline='\r\n')#, voltage_NS)) # is not working correctly f = file(path+'/out_'+str(l)+'.txt',"w") print "OUTFILE : ", path+'/out_'+str(l)+'.txt' for i in np.arange(len(timeEW)): print >>f,"%1.5e %1.2e %1.2e %1.2e" % (timeEW[i], voltage_EW[i], voltage_NS[i], voltage_vert[i] ) # same number of digits as input f.close() ###plots DISPLAY=1 if DISPLAY==1: import pylab as pl import matplotlib.pyplot as plt plt.figure(1, facecolor='w', edgecolor='k') plt.subplot(211) plt.plot(time1_sim*1e9,Ey_sim, label="Ey = EW") plt.plot(time1_sim*1e9,Ex_sim, label="Ex = NS") plt.plot(time1_sim*1e9,Ez_sim, label="Ez = UP") plt.xlabel('Time (nsec)') plt.ylabel('Electric field (muV/m)') plt.legend(loc='best') plt.subplot(212) plt.plot(timeEW*1e9,voltage_EW, label="EW") plt.plot(timeNS*1e9,voltage_NS, label="NS") plt.plot(timeNS*1e9,voltage_vert, label="Vertical") plt.xlabel('Time (nsec)') plt.ylabel('Voltage (muV)') plt.legend(loc='best') plt.show() ################################################################## ################################################################## if opt_input=='json': #### additional output needed for later study, added in the json file # p2p voltage: antenna ID, p2p EW, NS, UP, EW+NS voltage_com=np.copy(voltage_EW) for i in range (0, len(voltage_EW)): voltage_com[i]+=voltage_NS[i] v_list =( str(l), max(voltage_EW) - min(voltage_EW), max(voltage_NS) - min(voltage_NS), max(voltage_vert) - min(voltage_vert), max(voltage_com) - min(voltage_com) ) voltage.append( v_list ) # time of peaks and value: t_EW_max, v_EW_max, t_EW_min, v_EW_min,.... EW, NS, vert, EW+NS import operator EW_ind_max, value = max(enumerate(voltage_EW), key=operator.itemgetter(1)) EW_ind_min, value = min(enumerate(voltage_EW), key=operator.itemgetter(1)) NS_ind_max, value = max(enumerate(voltage_NS), key=operator.itemgetter(1)) NS_ind_min, value = min(enumerate(voltage_NS), key=operator.itemgetter(1)) vert_ind_max, value = max(enumerate(voltage_vert), key=operator.itemgetter(1)) vert_ind_min, value = min(enumerate(voltage_vert), key=operator.itemgetter(1)) com_ind_max, value = max(enumerate(voltage_com), key=operator.itemgetter(1)) com_ind_min, value = min(enumerate(voltage_com), key=operator.itemgetter(1)) time_peaks.append( (round(timeEW[EW_ind_max],11), voltage_EW[EW_ind_max], round(timeEW[EW_ind_min],11), voltage_EW[EW_ind_min], round(timeNS[NS_ind_max],11), voltage_NS[NS_ind_max], round(timeNS[NS_ind_min],11), voltage_NS[NS_ind_min], round(timevert[vert_ind_max],11), voltage_vert[vert_ind_max], round(timevert[vert_ind_min],11), voltage_vert[vert_ind_min], round(timeEW[com_ind_max],11), voltage_com[com_ind_max], round(timeEW[com_ind_min],11), voltage_com[com_ind_min] ) ) ############### end of loop over antennas if opt_input=='json': if len(voltage)==0: print "- effective zenith not fulfilled - NO VOLTAGE COMPUTED" log_event(**event) else: # add the additional informations to the shower event event['voltage'] = voltage # muV event['time_peaks'] = time_peaks # s, muV log_event(**event)
def main(): """ Main script allowing to produce the ZHAireS input files for each one of the showers from a DANTON library """ ################################################################## # Test arguments if (len(sys.argv)<7 or len(sys.argv)>8): print """\ This script will allow to produce the ZHAireS input files for cosmic-rays (hence down-going). It creates a regular rectangular array centered on the intersection point of the shower axis with the ground. The seed of each shower is uniformly randomized between 0 and 1. At the beginning of the script, you can set the altitude of the bottom of the array. By default GdAlt=1500 m The tables (pwr_EE, ZENITH and AZIMUTH) setting the energy, zenith and azimuth are, for now, hard coded and meant to be modified in the script. If the direction and energy are set, the intersection point between the shower axis and ground is randomly chosen between -draw_area_size and +draw_area_size around the array edges both in x and y directions. Then a selection of the antenna falling into the Cherenkov ring is done, and the process is iterated until more than MIN_ANTENNAS antennas are contained in the Cherenkov ring. The number of tries needed to meet the criterion to get one event is recorded together with a bunch of informations about the shower and the array. Inputs : work_dir = directory where all ZHAireS input files and the simulation results will be stored. slope = angle between horizontal and the slope along which the radio array is distributed [in degrees] height = maximum height that antennas distributed along the slope can reach [in m] step = separation between antennas [in m] Nx = number of antennas in the X direction Ny = number of antennas in the Y direction Ouput: The script will produce as many ZHAireS input files as there are combinations between the requested energies, zeniths and azimuths (respectively in tables pwr_EE, ZENITH and AZIMUTH). They will located in the work_dir+"/inp/" directory. Usage: python PrepCR_zhaires_RandomCore.py work_dir slope height step Nx Ny Notes: The global variable DISPLAY allows you to turn on/off the display of the 3D map of the radio array and the print-out of the processed showers The "compute_antenna_pos" function can easily be modified/replaced to build a different antenna array configuration (star-shape pattern, circularly distributed, ...) """ #in RASPASS North <=> azim=180 because azim and zenith reversed to trick Aires and then indicate dir of propag instead of dir of origin sys.exit(1) ################################################################## ################################################################## # Retrieve the input parameters ROOT = "/home/renault/CRs/" output_folder=str(sys.argv[1]) DISPLAY = False #True # ################################################################## # Array configuration parameters slope=float(sys.argv[2]) #slope [deg] hz=float(sys.argv[3]) #Array maximum height [m] sep=float(sys.argv[4]) #separation between antennas [m] nx = int(sys.argv[5]) #number of lines along x axis ny = int(sys.argv[6]) #number of lines along y axis ################################################################## #Showers parameters pwr_EE = np.array([17.5,18.,18.5,19.,19.5],dtype=str) #in eV AZIMUTH = np.array([0.,45.,90.,135.,180.],dtype=float) #in degrees in GRAND convention ZENITH = 180.-np.array([85.,80.,75.,70.,65.,60.],dtype=float) #in degrees in GRAND convention injh = 100e3 #above sea level in m draw_area_size = 50e3 ################################################################## print('******************************') print os.getcwd() # Compute an antenna array ANTENNAS=[] ANTENNAS=compute_antenna_pos(sep,nx,ny,GdAlt,slope) print ANTENNAS print np.amax(ANTENNAS[:,0]),np.amin(ANTENNAS[:,0]) print np.amax(ANTENNAS[:,1]),np.amin(ANTENNAS[:,1]) exit() ### Reduce the radio array to the shower geometrical footprint (we account for a footprint twice larger than the Cherenkov angle) CORE = random_array_pos(slope,sep) #[0.,0.,0.] # ANTENNAS[:,0] = ANTENNAS[:,0]+CORE[0] ANTENNAS[:,1] = ANTENNAS[:,1]+CORE[1] ANTENNAS[:,2] = ANTENNAS[:,2]+CORE[2] dx = draw_area_size + (np.amax(ANTENNAS[:,0])-np.amin(ANTENNAS[:,0]))/2 dy = draw_area_size + (np.amax(ANTENNAS[:,1])-np.amin(ANTENNAS[:,1]))/2 shower_infos = [] Nwish = 20 for ievt in range(0,Nwish): for azim in AZIMUTH: for zen in ZENITH: for eny in pwr_EE: task = 'EE1E'+eny+'-az'+str(int(azim))+'-zen'+str(int(zen))+'_evt'+str(ievt) # Compute informations on Xmax Xmax_primary,zen_inj = modules._getXmax('proton', 10**float(eny)/1e18, np.deg2rad(zen)) # approximation based on values from plots for gamma (=e) and protons (=pi) # g/cm2 Xmax_height, Xmax_distance = modules._dist_decay_Xmax(zen_inj, injh, Xmax_primary) # d_prime: distance from decay point to Xmax # Sample the shower core position. b = np.mean(ANTENNAS[:,0:], axis=0) pos_tab= [] Nevents = 0 while True: Nevents += 1 ANTENNAS2 = np.copy(ANTENNAS) x = random.uniform(b[0] - dx, b[0] + dx) y = random.uniform(b[1] - dy, b[1] + dy) ANTENNAS2 = ANTENNAS2-[x,y,0] pos_tab.append([x,y]) if Nevents %1e5==0: random.seed() print Nevents ANTENNAS3 = reduce_antenna_array(Xmax_height,zen,azim,ANTENNAS2,DISPLAY) if len(ANTENNAS3) >= MIN_ANTENNAS: break pos_tab = np.array(pos_tab) totito = generate_input(task, 10**float(eny), azim, zen, ANTENNAS3) #Write file fileZha = output_folder+'inp/'+task+'.inp' dir=os.path.dirname(fileZha) if not os.path.exists(dir): os.makedirs(dir) os.makedirs(dir+'/fig/') inpfile = open(fileZha,"w+") inpfile.write(totito) inpfile.close() plot_drawn_pos(ANTENNAS2,ANTENNAS3,pos_tab,output_folder,task,DISPLAY) print 'Nevents =',Nevents shower_infos.append([ievt,10**float(eny)/1e18,azim,zen,Nevents,len(ANTENNAS3),x,y,dx,dy,sep,nx,ny,slope,hz,GdAlt,MIN_ANTENNAS]) shower_info_file = output_folder+'/inp/summary_table.txt' shower_infos = np.array(shower_infos) hdr='\n'.join(["NumEvt Energy[EeV] Azimuth_GRAND[deg] Zenith_GRAND[deg] Ntry NAntennas x[m] y[m] dx[m] dy[m] step[m] Nx Ny Slope[deg] MountainHeight[m] GroundAltitudeAboveSeaLevel[m] MinAntennas", "xmin= "+str(np.amin(ANTENNAS[:,0]))+" xmax= "+str(np.amax(ANTENNAS[:,0]))+" ymin= "+str(np.amin(ANTENNAS[:,1]))+" ymax= "+str(np.amax(ANTENNAS[:,1]))]) np.savetxt(shower_info_file,shower_infos,fmt='%d %0.2f %0.1f %0.1f %d %d %0.2f %0.2f %0.2f %0.2f %0.1f %d %d %0.1f %0.1f %0.1f %d' ,header=hdr)