def get_info_from_file(start, stop, filename, num_entries, radius_cut): """ :param start: number of first file :param stop: number of last file :param filename: path and name of the file :param num_entries: number of entries per file :param radius_cut: radius, that define the volume cut, in mm :return: """ """ preallocate arrays: """ # number of PE of each event: number_pe = np.array([]) # initial total momentum of each event in MeV: momentum_init = np.array([]) # deposit energy in each event in MeV: edep = np.array([]) # quenched deposit energy in each event in MeV: qedep = np.array([]) # loop over files of proton = 10 MeV: for num in range(start, stop + 1, 1): # path to file: input_file = filename + "_{0:d}.root".format(num) # get number of PE per event (array of int), hit-times of the last event in ns (array of float), # initial momentum per event in MeV (array of float), deposit energy per event in MeV and quenched deposit # energy per event in MeV: num_pe, momentum, e, qe = NC_background_functions.conversion_npe_mev( input_file, num_entries, radius_cut) # append arrays to array: number_pe = np.append(number_pe, num_pe) momentum_init = np.append(momentum_init, momentum) edep = np.append(edep, e) qedep = np.append(qedep, qe) return number_pe, momentum_init, edep, qedep
min_time = -50 max_time = 10000 # Set bin-width of hittime histogram in ns: binwidth = 5.0 """ thresholds for delayed signal: """ # Set threshold of number of PE per bin for possible delayed signal (bin-width = 5 ns): threshold1 = 50 # set threshold2 of number of PEs per bin (signal peak is summed as long as nPE is above threshold2): threshold2 = 0 # set the radius for the volume cut in mm: r_cut = 16000 """ load position of the PMTs and corresponding PMT ID from file PMT_position.root: """ file_PMT_position = "/home/astro/blum/juno/atmoNC/PMT_information/PMT_position.root" # array with PMT ID and corresponding x, y, z position in mm: pmtID_pos_file, x_pos_pmt, y_pos_pmt, z_pos_pmt = NC_background_functions.get_pmt_position( file_PMT_position) """ load 'time resolution' in ns of the 20 inch PMTs and corresponding PMT ID from file PmtData.root: """ file_PMT_time = "/home/astro/blum/juno/atmoNC/PMT_information/PmtData.root" # array with PMT ID and corresponding sigma in ns: pmtID_time_file, sigma_time_20inch = NC_background_functions.get_20inchpmt_tts( file_PMT_time) # set TTS (FWHM) of the 3inch PMTs in ns: tts_3inch = 5.0 # calculate time resolution (sigma) for the 3inch PMTs in ns: sigma_time_3inch = tts_3inch / (2 * np.sqrt(2 * np.log(2))) # set effective speed of light in the liquid scintillator in mm/ns (see page 7 of c_effective_JUNO-doc-3144-v2.pdf in # folder /home/astro/blum/PhD/paper/Pulse_Shape_Discrimination/). Effective refraction index in LS n_eff = 1.54. # c/n_eff = 299792458 m / 1.54 s ~ 194670427 m/s = 194670427 * 10**(-6) mm/ns ~ 194.67 mm/ns: c_effective = 194.67
number_pe_file = np.loadtxt(input_file) # file name, where evtID of preselected events are saved: input_file_evtID = input_path_evtID + "evtID_preselected_{0:d}.txt".format( index) # read this file: evtID_preselected, x_reco, y_reco, z_reco = np.loadtxt(input_file_evtID, unpack=True) # number of preselected events: number_preselected = number_preselected + len(number_pe_file) # loop over all entries in number_pe_file: for index1 in range(len(number_pe_file)): # convert number_pe to E_vis: e_vis = NC_background_functions.conversion_npe_to_evis( number_pe_file[index1]) # check, if energy is in the correct time window: if min_energy <= e_vis <= max_energy: # add e_vis to default evis histogram: e_vis_array += np.histogram(e_vis, bins_evis)[0] else: # event is rejected by prompt energy cut: number_rejected_prompt_cut += 1 if e_vis < min_energy: # nPE below min_energy: number_rejected_prompt_cut_min += 1 elif e_vis > max_energy: # nPE above max_energy:
# first file of neutron simulation: first_file_neutron = 0 # last file of neutron simulation (100 corresponds to user_neutron_300_MeV_0.root, 200 corresponds to # user_neutron_500_MeV_0.root and 299 corresponds to user_neutron_500_MeV_99.root): last_file_neutron = 1099 # number of events per file: number_evts_per_file = 10 # total number of neutron events (factor 2 for 10 MeV and 100 MeV): number_evts_total = (last_file_neutron - first_file_neutron + 1) * number_evts_per_file # preallocate number of events that are analyzed (pass volume cut): number_analyzed = 0 """ load position of the PMTs and corresponding PMT ID from file PMT_position.root: """ file_PMT_position = "/home/astro/blum/juno/atmoNC/PMT_information/PMT_position.root" # array with PMT ID and corresponding x, y, z position in mm: pmtID_pos_file, x_pos_pmt, y_pos_pmt, z_pos_pmt = NC_background_functions.get_pmt_position( file_PMT_position) """ load 'time resolution' in ns of the 20 inch PMTs and corresponding PMT ID from file PmtData.root: """ file_PMT_time = "/home/astro/blum/juno/atmoNC/PMT_information/PmtData.root" # array with PMT ID and corresponding sigma in ns: pmtID_time_file, sigma_time_20inch = NC_background_functions.get_20inchpmt_tts( file_PMT_time) # set TTS (FWHM) of the 3inch PMTs in ns: tts_3inch = 5.0 # calculate time resolution (sigma) for the 3inch PMTs in ns: sigma_time_3inch = tts_3inch / (2 * np.sqrt(2 * np.log(2))) # set effective speed of light in the liquid scintillator in mm/ns (see page 7 of c_effective_JUNO-doc-3144-v2.pdf in # folder /home/astro/blum/PhD/paper/Pulse_Shape_Discrimination/). Effective refraction index in LS n_eff = 1.54. # c/n_eff = 299792458 m / 1.54 s ~ 194670427 m/s = 194670427 * 10**(-6) mm/ns ~ 194.67 mm/ns: c_effective = 194.67 # loop over root files with neutron simulation:
""" Script to read the 'original' ROOT file from Julia's GENIE simulation and convert it to a ROOT-file, which can be read from the DSNB-NC.exe generator of the JUNO offline software. The ROOT-file, which is generated with this script can be used as input for the DSNB-NC.exe generator. """ # import ROOT import datetime # import glob import NC_background_functions import numpy as np from matplotlib import pyplot as plt # set the path of the inputs: input_path = "/home/astro/blum/juno/atmoNC/data_Julia/" # file name of the input file: input_name = input_path + "gntp.101.gst.root" # set the path, where the outputs are saved: output_path = "/home/astro/blum/juno/atmoNC/data_NC/" NC_background_functions.convert_genie_file_for_generator( input_name, output_path)
def check_volume_cut(input_path, number_entries_input, radius_cut): """ :param input_path: file name with path to input root files from tut_detsim.py: user_atmoNC_{}.root :param number_entries_input: number of entries, that the input files should have (integer), normally = 100 :param radius_cut: radius, which defines the fiducial volume, in mm :return: """ # load the ROOT file: rfile = ROOT.TFile(input_path) # get the "geninfo"-TTree from the TFile: rtree_geninfo = rfile.Get("geninfo") # get the "prmtrkdep"-TTree from TFile: rtree_prmtrkdep = rfile.Get("prmtrkdep") # get the number of events in the geninfo Tree: number_events = rtree_geninfo.GetEntries() # check if number_events_geninfo is equal to number_entries_input (if not, the detector simulation was incorrect!!): if number_events != number_entries_input: sys.exit( "ERROR: number of events are not equal to {0:d} -> Detector Simulation not correct!" .format(number_entries_input)) # number of events with reconstructed position inside fiducial volume (r_reco < Radius_cut): n_reco_inside = 0 # number of leak-out events (r_init < Radius_cut, but r_reco >= Radius_cut): n_leak_out = 0 # number of leak-in events (r_init >= Radius_cut, but r_reco < Radius_cut): n_leak_in = 0 # loop over every event, i.e. every entry, in the TTree: for event in range(number_events): """ read prmtrkdep tree: """ rtree_prmtrkdep.GetEntry(event) # get nInitParticles from prmtrkdep tree: n_par_prmtrkdep = int( rtree_prmtrkdep.GetBranch('nInitParticles').GetLeaf( 'nInitParticles').GetValue()) # preallocate sum of Qedep of initial particles: qedep_sum = 0 # to get total quenched deposited energy, sum over initial particles: for index1 in range(n_par_prmtrkdep): # get deposit energy of initial neutron in MeV: qedep = float( rtree_prmtrkdep.GetBranch('Qedep').GetLeaf('Qedep').GetValue( index1)) # add qedep to qedep_sum: qedep_sum += qedep """ read 'geninfo' tree: """ # get the current event in the Tree: rtree_geninfo.GetEntry(event) # get event ID: evt_id = int( rtree_geninfo.GetBranch('evtID').GetLeaf('evtID').GetValue()) if evt_id != event: sys.exit( "ERROR: event ID's are not equal in file {0}".format(rfile)) # get number of particles in the event: n_par_geninfo = int( rtree_geninfo.GetBranch('nInitParticles').GetLeaf( 'nInitParticles').GetValue()) # check if there are initial particles: if n_par_geninfo == 0: # no initial particle -> go to next event continue # preallocate array for initial position: initx = np.array([]) inity = np.array([]) initz = np.array([]) # loop over number of particles in the event: for index1 in range(n_par_geninfo): # get initial position of the particle in mm : initx = np.append( initx, float( rtree_geninfo.GetBranch('InitX').GetLeaf('InitX').GetValue( index1))) inity = np.append( inity, float( rtree_geninfo.GetBranch('InitY').GetLeaf('InitY').GetValue( index1))) initz = np.append( initz, float( rtree_geninfo.GetBranch('InitZ').GetLeaf('InitZ').GetValue( index1))) # set 0th entry of array as initial position in mm: x_init = initx[0] y_init = inity[0] z_init = initz[0] # check if all initial position are equal: for index1 in range(n_par_geninfo): if x_init != initx[index1] or y_init != inity[ index1] or z_init != initz[index1]: sys.exit( "ERROR: initial positions are not equal for all initial particles (event {0:d}, file {1})" .format(event, rfile)) # smear the initial position with vertex reconstruction: x_reco = NC_background_functions.position_smearing(x_init, qedep_sum) y_reco = NC_background_functions.position_smearing(y_init, qedep_sum) z_reco = NC_background_functions.position_smearing(z_init, qedep_sum) # calculate r_init in mm: r_init = np.sqrt(x_init**2 + y_init**2 + z_init**2) # calculate r_reco in mm: r_reco = np.sqrt(x_reco**2 + y_reco**2 + z_reco**2) if r_reco < radius_cut: # reco. position inside fiducial volume: n_reco_inside += 1 if r_init < radius_cut and r_reco >= radius_cut: n_leak_out += 1 if r_init >= radius_cut and r_reco < radius_cut: n_leak_in += 1 return number_events, n_reco_inside, n_leak_out, n_leak_in
import NC_background_functions import numpy as np from matplotlib import pyplot as plt # path, where GENIE cross-sections are saved: path_xsec = "/home/astro/blum/juno/GENIE/genie_xsec_2.12.0_eventrate/genie_xsec/v2_12_0/NULL/DefaultPlusMECWithNC/data/" # set energy interval in MeV: interval_energy = 10 # set energy range in MeV (do NOT change this, it is hardcoded in function read_xml_xsec()): energy = np.arange(0, 10000 + interval_energy, interval_energy) """ Neutral Current interaction cross-sections of neutrinos with C12 for each neutrino flavour: """ # NC interaction nu_e + C12 -> nu_e + ...: # define path, where cross-sections are saved (string): path_xsec_NC_nue_C12 = path_xsec + "gxspl-FNALsmall_nue.xml" # calculate total cross-section with function 'read_xml_xsec()' (total cross-section in cm**2, array of float): xsec_NC_nue_C12 = NC_background_functions.read_xml_xsec( path_xsec_NC_nue_C12, interval_energy) # NC interaction nu_e_bar + C12 -> nu_e_bar + ...: # define path, where cross-sections are saved (string): path_xsec_NC_nuebar_C12 = path_xsec + "gxspl-FNALsmall_nuebar.xml" # calculate total cross-section with function 'read_xml_xsec()' (total cross-section in cm**2, array of float): xsec_NC_nuebar_C12 = NC_background_functions.read_xml_xsec( path_xsec_NC_nuebar_C12, interval_energy) # NC interaction nu_mu + C12 -> nu_mu + ...: # define path, where cross-sections are saved (string): path_xsec_NC_numu_C12 = path_xsec + "gxspl-FNALsmall_numu.xml" # calculate total cross-section with function 'read_xml_xsec()' (total cross-section in cm**2, array of float): xsec_NC_numu_C12 = NC_background_functions.read_xml_xsec( path_xsec_NC_numu_C12, interval_energy)
efficiency_neutron_multiplicity_cut / 100.0 * efficiency_distance_cut / 100.0 * error_efficiency_muon_veto) # spectrum of all simulated IBD-like events (cut efficiencies are considered): Evis_histo = Evis_histo_without_eff * cut_efficiency / 100.0 # number of simulated IBD-like events (cut efficiencies are considered): number_IBDlike_events_simu = number_IBDlike_events_simu_without_eff * cut_efficiency / 100.0 print( "number of IBD-like events from simulation (with cut efficiency) = {0:.2f}" .format(number_IBDlike_events_simu)) """ Event rate calculation: """ # calculate the theoretical event rate in NC events/sec in JUNO for neutrino energies from 0 MeV to 10 GeV (float) # (event_rate = A * (flux_nue*xsec_nue + flux_nuebar*xsec_nuebar + flux_numu*xsec_numu + flux_numubar*xsec_numubar)): event_rate = NC_background_functions.event_rate(bin_width_energy, r_cut, output_path, PLOT_FLUX, SHOW_FLUXPLOT, SAVE_FLUXPLOT, PLOT_EVT_RATE, SHOW_EVT_RATE, SAVE_EVT_RATE) # number of NC events in JUNO after 10 years: number_NC_events_JUNO = event_rate * time_seconds # number of IBD-like events in JUNO after 10 years (cut efficiencies are considered): number_IBDlike_events_JUNO = int( number_NC_events_JUNO * number_IBDlike_events_simu / number_NC_events_simu) # normalize the spectrum of IBD-like events to the spectrum, JUNO will measure after 10 years (cut efficiencies are # considered): Evis_histo_JUNO = float(number_IBDlike_events_JUNO) / float( number_IBDlike_events_simu) * Evis_histo """ display simulated spectrum: """
filename_positron_100MeV = "user_positron_100_MeV_" totalPE_positron_100MeV, Redep_positron_100MeV, Qedep_positron_100MeV, Edep_positron_100MeV = \ get_npe_redep_qedep_from_file(path_positron, filename_positron_100MeV, first_file_positron, last_file_positron, E_min_window, E_max_window) # positrons of 50 MeV in detector center: path_positron_CDcenter = "/local/scratch1/pipc51/astro/blum/positron_output_CDcenter/" filename_positron_50MeV = "user_positron_50MeV_" totalPE_positron_50MeV, Redep_positron_50MeV, Qedep_positron_50MeV, Edep_positron_50MeV = \ get_npe_redep_qedep_from_file(path_positron_CDcenter, filename_positron_50MeV, first_file_positron, last_file_positron, E_min_window, E_max_window) # convert list Qedep_positron_50MeV to numpy array: Qedep_positron_50MeV = np.asarray(Qedep_positron_50MeV) # smear Qedep_positron_50MeV with the energy resolution of JUNO: sigma = NC_background_functions.energy_resolution(Qedep_positron_50MeV) Qedep_positron_50MeV_smeared = np.random.normal(Qedep_positron_50MeV, sigma) """ read IBD files: """ print("read IBD events...") path_IBD = "/local/scratch1/pipc51/astro/blum/IBD_hepevt/" first_file_IBD = 0 last_file_IBD = 199 # IBD (positron and neutron) events from 10 MeV to 100 MeV: # filename_IBD = "user_IBD_hepevt_" # totalPE_IBD, Redep_IBD, Qedep_IBD, Edep_IBD = \ # get_npe_redep_qedep_from_file(path_IBD, filename_IBD, first_file_IBD, last_file_IBD, E_min_window, E_max_window) """ plot Qedep vs. nPE and Qedep vs. Redep: """
# number of events without neutron, but with possible delayed signal (agree with time but NOT with energy cut): number_possible_delayed = 0 # number of events without neutron, but with possible second delayed signal (agree only with time cut) after one # delayed or possible delayed cut: number_possible_second_delayed = 0 # loop over files: for file_number in range(start_number, stop_number + 1, 1): # path to file: input_file = "user_atmoNC_{0:d}.root".format(file_number) print("Start reading {0} ...".format(input_file)) # analyze file with function check_neutron_cut(): num_events, num_neutron, num_no_neutron, num_no_delayed, num_delayed, num_pos_delayed, num_pos_second_delayed = \ NC_background_functions.check_neutron_cut(input_path, file_number, output_path, min_hittime, max_hittime, threshold, threshold2, binwidth, min_PE_delayed, max_PE_delayed, Number_entries_input, SAVE_HITTIME) # add variables: number_events = number_events + num_events number_neutron = number_neutron + num_neutron number_no_neutron = number_no_neutron + num_no_neutron number_no_delayed = number_no_delayed + num_no_delayed number_delayed = number_delayed + num_delayed number_possible_delayed = number_possible_delayed + num_pos_delayed number_possible_second_delayed = number_possible_second_delayed + num_pos_second_delayed print("\nnumber_events = {0}".format(number_events)) print("\nnumber_neutron = {0}".format(number_neutron)) print("\nnumber_no_neutron = {0}".format(number_no_neutron)) print("\nnumber_no_delayed = {0}".format(number_no_delayed))
""" thresholds and cuts for delayed signal: """ # Set threshold of number of PE per bin for possible delayed signal (bin-width = 5 ns): threshold1_del = 50 # set threshold2 of number of PEs per bin (signal peak is summed as long as nPE is above threshold2): threshold2_del = 0 # min and max number of PE for delayed energy cut (from check_delayed_energy.py): min_PE_delayed = 2805.53 max_PE_delayed = 3731.04 # preallocate number of events that are rejected by delayed energy cut: number_rejected_delayed_energy_cut = 0 # preallocate array, where npe of delayed signal, that wouldn't pass the delayed energy cut are saved: number_pe_delayed_rejected_array = np.array([]) """ load position of the PMTs and corresponding PMT ID from file PMT_position.root: """ file_PMT_position = "/home/astro/blum/juno/atmoNC/PMT_information/PMT_position.root" # array with PMT ID and corresponding x, y, z position in mm: pmtID_pos_file, x_pos_pmt, y_pos_pmt, z_pos_pmt = NC_background_functions.get_pmt_position( file_PMT_position) """ load 'time resolution' in ns of the 20 inch PMTs and corresponding PMT ID from file PmtData.root: """ file_PMT_time = "/home/astro/blum/juno/atmoNC/PMT_information/PmtData.root" # array with PMT ID and corresponding sigma in ns: pmtID_time_file, sigma_time_20inch = NC_background_functions.get_20inchpmt_tts( file_PMT_time) # set TTS (FWHM) of the 3inch PMTs in ns: tts_3inch = 5.0 # calculate time resolution (sigma) for the 3inch PMTs in ns: sigma_time_3inch = tts_3inch / (2 * np.sqrt(2 * np.log(2))) # set effective speed of light in the liquid scintillator in mm/ns (see page 7 of c_effective_JUNO-doc-3144-v2.pdf in # folder /home/astro/blum/PhD/paper/Pulse_Shape_Discrimination/). Effective refraction index in LS n_eff = 1.54. # c/n_eff = 299792458 m / 1.54 s ~ 194670427 m/s = 194670427 * 10**(-6) mm/ns ~ 194.67 mm/ns: c_effective = 194.67 # loop over the files:
distance_cut = 1500 """ thresholds and cuts for ncapture signal: """ # Set threshold of number of PE per bin for possible delayed signal (bin-width = 5 ns): threshold1_del = 50 # set threshold2 of number of PEs per bin (signal peak is summed as long as nPE is above threshold2): threshold2_del = 0 # min and max number of PE for delayed energy cut (delayed energy cut: 1.9 MeV / 0.0007483 = 2573 PE ~ 2500 PE, # 2.5 MeV / 0.0007384 = 3385 PE ~ 3400 PE): min_PE_delayed = 2400 max_PE_delayed = 3400 """ load position of the PMTs and corresponding PMT ID from file PMT_position.root: """ file_PMT_position = "/home/astro/blum/juno/atmoNC/PMT_information/PMT_position.root" # array with PMT ID and corresponding x, y, z position in mm: pmtID_pos_file, x_pos_pmt, y_pos_pmt, z_pos_pmt = NC_background_functions.get_pmt_position(file_PMT_position) """ load 'time resolution' in ns of the 20 inch PMTs and corresponding PMT ID from file PmtData.root: """ file_PMT_time = "/home/astro/blum/juno/atmoNC/PMT_information/PmtData.root" # array with PMT ID and corresponding sigma in ns: pmtID_time_file, sigma_time_20inch = NC_background_functions.get_20inchpmt_tts(file_PMT_time) # set TTS (FWHM) of the 3inch PMTs in ns: tts_3inch = 5.0 # calculate time resolution (sigma) for the 3inch PMTs in ns: sigma_time_3inch = tts_3inch / (2 * np.sqrt(2 * np.log(2))) # set effective speed of light in the liquid scintillator in mm/ns (see page 7 of c_effective_JUNO-doc-3144-v2.pdf in # folder /home/astro/blum/PhD/paper/Pulse_Shape_Discrimination/). Effective refraction index in LS n_eff = 1.54. # c/n_eff = 299792458 m / 1.54 s ~ 194670427 m/s = 194670427 * 10**(-6) mm/ns ~ 194.67 mm/ns: c_effective = 194.67 """ preallocate variables: """
# preallocate number of IBD-like events: number_IBDevts = 0 # loop over the files that are read: for index in range(start_number, stop_number + 1): # file name of the input file: input_name = input_path + "user_atmoNC_{0:d}.root".format(index) print( "------------------------------------------------------------------------------------" ) print(input_name) # get the visible energy of the prompt signal from events that mimic IBD signals (E_vis in MeV) (np.array): num_evts, evt_ID_IBD, E_vis = NC_background_functions.read_sample_detsim_user( input_name, R_cut, E_prompt_min, E_prompt_max, E_delayed_min, E_delayed_max, time_cut_min, time_cut_max, Distance_cut, time_resolution, Number_entries_input) # add number_evts to number_events: number_events = number_events + num_evts # calculate number of IBD-like events: num_IBD = len(E_vis) # add num_IBD to number_IBDevts: number_IBDevts = number_IBDevts + num_IBD # append E_vis to E_visible: E_visible = np.append(E_visible, E_vis) print(evt_ID_IBD) print(E_vis)
Frac_C12_Li6_4p_2n_piminus, Frac_C12_Li6_3p_3n_piminus_piplus, Frac_C12_Li8_3p_n, Frac_C12_Li8_4p_piminus, Frac_C12_Li8_4p_2piminus_piplus, Frac_C12_Li8_2p_2n_piplus, Frac_C12_Li8_3p_n_piminus_piplus, Frac_C12_Li7_2p_3n_piplus, Frac_C12_Li7_4p_n_piminus, Frac_C12_Li7_3p_2n, Frac_C12_Li7_3p_2n_piminus_piplus, Frac_C12_Li7_4p_n_2piminus_piplus, Frac_C12_Li7_2p_3n_piminus_2piplus, Frac_C12_B8_p_3n, Frac_C12_B8_p_3n_piminus_piplus, Frac_C12_B8_2p_2n_2piminus_piplus, Frac_C12_B8_2p_2n_piminus, Frac_C12_B8_4n_piplus, Frac_C12_Li9_2p_n_piplus, Frac_C12_Li9_3p, Frac_C12_Li9_3p_piminus_piplus, Frac_C12_Li9_2p_n_piminus_2piplus, Frac_C12_Li9_p_2n_piminus_3piplus, Frac_C12_C8_4n, Frac_C12_He8_4p, Frac_C12_B7_p_4n, Frac_C12_He7_4p_n, Frac_C12_H7_5p, Frac_C12_Be6_2p_4n, Frac_C12_Li5_3p_4n, Frac_C12_Li4_3p_5n, Frac_C12_He6_4p_2n, Frac_C12_He5_4p_3n, Frac_C12_He4_4p_4n, Frac_C12_He3_4p_5n, Frac_C12_H6_5p_n, Frac_C12_H5_5p_2n, Frac_C12_H4_5p_3n, Frac_C12_H3_5p_4n, Frac_C12_H2_5p_5n, Frac_C12_C12, Frac_C12_NoIso, Frac_no_C12, Frac_ES_proton_chID, Frac_ES_electron_chID, Frac_ES_O16_chID, Frac_ES_N14_chID, Frac_ES_S32_chID, Frac_C12_missing) \ = NC_background_functions.get_channels_from_original_genie_file(input_name) """ Save information from get_interaction_channel() into txt file: """ if SAVE_TXT: np.savetxt(output_path + "interaction_channels_NC_onlyC12_{0:d}evts.txt".format(Number_Events), np.array([Frac_C12_B11_p, Frac_C12_B11_n_piplus, Frac_C12_B11_n_piminus_2piplus, Frac_C12_B11_p_piminus_piplus, Frac_C12_B11_p_2piminus_2piplus, Frac_C12_B11_piplus, Frac_C12_C11_n, Frac_C12_C11_p_piminus, Frac_C12_C11_n_piminus_piplus, Frac_C12_C11_p_2piminus_piplus, Frac_C12_C11_p_3piminus_2piplus, Frac_C12_C11_n_2piminus_2piplus, Frac_C12_B10_p_n, Frac_C12_B10_2p_piminus, Frac_C12_B10_p_n_piminus_piplus, Frac_C12_B10_2n_piplus, Frac_C12_B10_2n_piminus_2piplus, Frac_C12_B10_2p_2piminus_piplus, Frac_C12_B10_2p_3piminus_2piplus, Frac_C12_B10_p_n_2piminus_2piplus, Frac_C12_C10_2n, Frac_C12_C10_p_n_piminus, Frac_C12_C10_p_n_2piminus_piplus, Frac_C12_C10_2n_piminus_piplus, Frac_C12_C10_2p_2piminus,
for index in range(start_number, stop_number + 1): # file name of the input file: input_name = input_path + "user_atmoNC_{0:d}.root".format(index) print( "------------------------------------------------------------------------------------" ) print(input_name) # get the visible energy of the prompt signal from events that mimic IBD signals (E_vis in MeV) (np.array): (num_evts, evt_ID_IBD, E_vis, number_case0, number_case0_1ibdlike, number_case1, number_case1_1posibdlike, number_case1_2posibdlike, number_case1_2posibdlike_added, number_case1_2posibdlike_notadded, number_case1_moreposibdlike, number_case2, number_case2_1posibdlike, number_case3, number_case3_noibdlike, number_case3_1ibdlike, number_case3_2ibdlike, number_check1, number_check2, number_case3_moreibdlike) \ = NC_background_functions.read_sample_detsim_user(input_name, R_cut_mm, E_prompt_min, E_prompt_max, E_delayed_min, E_delayed_max, time_cut_min, time_cut_max, Distance_cut, time_resolution, Number_entries_input) # check numbers: Number_case0 = Number_case0 + number_case0 Number_case0_1ibdlike = Number_case0_1ibdlike + number_case0_1ibdlike Number_case1 = Number_case1 + number_case1 Number_case1_1posibdlike = Number_case1_1posibdlike + number_case1_1posibdlike Number_case1_2posibdlike = Number_case1_2posibdlike + number_case1_2posibdlike Number_case1_2posibdlike_added = Number_case1_2posibdlike_added + number_case1_2posibdlike_added Number_case1_2posibdlike_notadded = Number_case1_2posibdlike_notadded + number_case1_2posibdlike_notadded Number_case1_moreposibdlike = Number_case1_moreposibdlike + number_case1_moreposibdlike Number_case2 = Number_case2 + number_case2 Number_case2_1posibdlike = Number_case2_1posibdlike + number_case2_1posibdlike Number_case3 = Number_case3 + number_case3 Number_case3_noibdlike = Number_case3_noibdlike + number_case3_noibdlike
E_neutrino = np.arange(105, 223 + E_neutrino_interval, E_neutrino_interval) E_visible = np.arange(10, 100 + 0.5 + 0.5, 0.5) # exposure time in seconds: time_seconds = 10 * 3.156 * 10**7 # fiducial volume cut in mm: radius_cut = 16000 # mass of proton in MeV (reference PDG 2016) (float constant): MASS_PROTON = 938.27203 # mass of neutron in MeV (reference PDG 2016) (float constant): MASS_NEUTRON = 939.56536 # mass of muon in MeV (reference PDG 2019): MASS_MUON = 105.658 # number of C12 in JUNO LS for specific radius cut: number_C12 = NC_background_functions.number_c12_atoms(radius_cut / 1000) # number of free protons in total JUNO LS (17.7 m and 20 ktons): N_free_protons_total = 1.45 * 10**33 # number of free protons in JUNO LS for specific radius cut: number_free_protons = N_free_protons_total * radius_cut**3 / 17700**3 """ Results of the HONDA simulation (based on the paper of Honda2015: 'Atmospheric neutrino flux calculation using the NRLMSISE-00 atmospheric model'): """ # Neutrino energy in MeV from the table from file HONDA_juno-ally-01-01-solmin.d (is equal to neutrino energy # in HONDA_juno-ally-01-01-solmax.d) (np.array of float): energy_honda = 10**3 * np.array([ 1.0000E-01, 1.1220E-01, 1.2589E-01, 1.4125E-01, 1.5849E-01, 1.7783E-01, 1.9953E-01, 2.2387E-01 ]) """ for solar minimum (HONDA_juno-ally-01-01-solmin.d): """ # all-direction averaged flux for no oscillation for electron-neutrinos for solar minimum at the site of JUNO
array_TTR_20_30 = [] array_TTR_30_40 = [] array_TTR_40_100 = [] # array, where prompt energy of neutron events is saved in MeV: array_E_prompt_neutron = [] array_E_10_20 = [] array_E_20_30 = [] array_E_30_40 = [] array_E_40_100 = [] # number of neutron events, that pass the PSD cut: number_pass_PSD_total = 0 number_pass_PSD_array = np.zeros(len(energy_range)) """ load position of the PMTs and corresponding PMT ID from file PMT_position.root: """ file_PMT_position = "/home/astro/blum/juno/atmoNC/PMT_information/PMT_position.root" # array with PMT ID and corresponding x, y, z position in mm: pmtID_pos_file, x_pos_pmt, y_pos_pmt, z_pos_pmt = NC_background_functions.get_pmt_position( file_PMT_position) """ load 'time resolution' in ns of the 20 inch PMTs and corresponding PMT ID from file PmtData.root: """ file_PMT_time = "/home/astro/blum/juno/atmoNC/PMT_information/PmtData_old.root" # array with PMT ID and corresponding sigma in ns: pmtID_time_file, sigma_time_20inch = NC_background_functions.get_20inchpmt_tts( file_PMT_time) # set TTS (FWHM) of the 3inch PMTs in ns: tts_3inch = 5.0 # calculate time resolution (sigma) for the 3inch PMTs in ns: sigma_time_3inch = tts_3inch / (2 * np.sqrt(2 * np.log(2))) # set effective speed of light in the liquid scintillator in mm/ns (see page 12 of # 20200111_zli_VertexReconstruction_page20.pdf in folder /home/astro/blum/PhD/paper/reconstruction/). # The effective refraction index in LS depends on the TTS of the PMT (Hamamatsu with TTS ~ 2.7 ns, # NNVT with TTS ~ 18 ns). # for Hamamatsu and 3inch PMTs (TTS ~ 2.7 ns and 5 ns) use n_eff = 1.544 (c/n_eff = 299792458 m / 1.544 s # = 194166100 * 10**(-6) mm/ns ~ 194.17 mm/ns):
# file name of the input file: input_name = input_path + "user_atmoNC_{0:d}.root".format(index) print( "------------------------------------------------------------------------------------" ) print(input_name) # preselection of detsim events: (num_events, evt_id_preselected, edep_total, x_reco, y_reco, z_reco, num_preselected, num_rejected, num_vol_pass, num_vol_reject, num_vol_pass_initial, num_e_pass, num_mine_reject, num_maxe_reject, num_nmult_pass, num_nmult_reject, num_without_ncap, num_time_pass, num_time_reject, num_dist_pass, num_dist_reject) = \ NC_background_functions.preselect_sample_detsim_user(input_name, R_cut_mm, dep_energy_min, dep_energy_max, time_cut_min, time_cut_max, dist_cut_mm, Number_entries_input) # add numbers to parameters: number_events += num_events number_preselected += num_preselected number_rejected += num_rejected number_vol_pass += num_vol_pass number_vol_reject += num_vol_reject number_vol_pass_initial += num_vol_pass_initial number_e_pass += num_e_pass number_mine_reject += num_mine_reject number_maxe_reject += num_maxe_reject number_nmult_pass += num_nmult_pass number_nmult_reject += num_nmult_reject number_without_ncap += num_without_ncap
# TODO: include the event rate to get "real" spectra # TODO-me: Get the Event Rate for GENIE simulations of Julia!!! # evt_rate_Genie = 3.59E-5 evt_rate_Genie = 1 # total exposure time in years (float): t_years = 10 # total time-exposure in seconds (1yr = 365.2425 * 24 * 60 * 60 sec = 3.1556952 * 10^7 sec), 10 years (float): # TODO: include the total exposure time to get "real" spectra # time = t_years * 3.156 * 10 ** 7 time = 1 # read NC generator data to arrays: (event_ID, projectile_PDG, projectile_E, target_PDG, NC_inter_ch_ID, deexcitation_ID, isotope_PDG, Nparticles, final_PDG, final_Px, final_Py, final_Pz) = NC_background_functions.read_nc_data(input_name) # get the number of events in the root file: # from the maximum of event_ID +1 (float): evtnumber_fromMax = int(np.max(event_ID) + 1) # from the length of the array: evtnumber_fromLength = len(event_ID) if evtnumber_fromMax != evtnumber_fromLength: print("WARNING: different values for max(event_ID) and len(event_ID)!!!") else: NumEvent = evtnumber_fromLength # get the number of event as function of the energy of the incoming neutrinos for each neutrino type: (Energy_nu_incoming, Event_nu_e_IN, Event_nu_e_bar_IN, Event_nu_mu_IN, Event_nu_mu_bar_IN, Event_nu_tau_IN, Event_nu_tau_bar_IN, Number_nu_e_IN, Number_nu_e_bar_IN, Number_nu_mu_IN, Number_nu_mu_bar_IN, Number_nu_tau_IN, Number_nu_tau_bar_IN,