def genBands( nSim=1e5, maxS1=50, f_drift=700, g1=0.075, SPE_res=0.5, eff_extract=0.95, SE_size=50, SE_res=10, e_lifetime=1000, dt0=500, minSpikePE=0.25, min_NS1_coin=3, min_Ne_ext=5, Det="LZ", S2raw_min=250, xe_density=2.888, ): # Setup the LUX or LZ detector: pt = 0 # start with NR NEST = libNEST.NEST(pt, 10, f_drift, xe_density) # 0 is NR, 1 is ER ... Energy, EField(V/cm), density if Det == "LZ": myDet = libNEST.Detector() myDet.LZSettings() NEST.SetDetectorParameters(myDet) elif Det == "LUX": myDet = libNEST.Detector() myDet.LUXSettings() NEST.SetDetectorParameters(myDet) else: print("Invalid detector, defulting to LZ") myDet = libNEST.Detector() myDet.LZSettings() NEST.SetDetectorParameters(myDet) # Calculate the NR band, and count below that for acceptance ######## maxEr = 100 # keVnr, for flat spectrum... DD Flat_Er = maxEr * st.uniform.rvs(size=nSim) # 0-100 keVnr ## Generate Signal in the detector ## Nph = [] Ne = [] S1 = [] S2 = [] S1c = [] S2c = [] for en in Flat_Er: NEST.SetEnergy(en) NEST.DetectorResponse() Nph.append(NEST.GetNumPhotons()) Ne.append(NEST.GetNumElectrons()) S1.append(NEST.GetS1()) S2.append(NEST.GetS2()) S1c.append(NEST.GetS1c()) S2c.append(NEST.GetS2c()) Nph = np.array(Nph) Ne = np.array(Ne) S1 = np.array(S1) S2 = np.array(S2) S1c = np.array(S1c) S2c = np.array(S2c) S1_bins = linspace(1, maxS1, maxS1) S1_bin_cen_n = empty_like(S1_bins) mean_S2oS1_n = empty_like(S1_bins) std_S2oS1_n = empty_like(S1_bins) # Find the NR S2/S1 band at each S1 det_cuts = (S1c > 0) & (S2c >= S2raw_min) for index, S1s in enumerate(S1_bins): cut = det_cuts & inrange(S1c, [S1s - 0.5, S1s + 0.5]) S1_bin_cen_n[index] = mean(S1c[cut]) mean_S2oS1_n[index] = mean(log10(S2c[cut] / S1c[cut])) std_S2oS1_n[index] = std(log10(S2c[cut] / S1c[cut])) # Calc Nr Efficiency vs E E_bins = linspace(1, maxEr, maxEr) E_bin_cen_n = empty_like(E_bins) Eff_n = empty_like(E_bins) det_cuts = (S1c > 0) & (S2c >= S2raw_min) for index, Es in enumerate(E_bins): cut = det_cuts & inrange(Flat_Er, [Es - 0.5, Es + 0.5]) E_bin_cen_n[index] = mean(Flat_Er[cut]) Eff_n[index] = sum(cut) / sum(inrange(Flat_Er, [Es - 0.5, Es + 0.5])) # cut/total_in_bin # Calculate the ER band #################################################### maxEe = 100 # keVee, for flat ER spectrum Flat_Ee = maxEe * st.uniform.rvs(size=nSim) # 0-100 keVee ## Generate Signal in the detector ## Nph = [] Ne = [] S1 = [] S2 = [] S1c = [] S2c = [] NEST.SetParticleType(1) # set to ER events for en in Flat_Er: NEST.SetEnergy(en) NEST.DetectorResponse() Nph.append(NEST.GetNumPhotons()) Ne.append(NEST.GetNumElectrons()) S1.append(NEST.GetS1()) S2.append(NEST.GetS2()) S1c.append(NEST.GetS1c()) S2c.append(NEST.GetS2c()) Nph = np.array(Nph) Ne = np.array(Ne) S1 = np.array(S1) S2 = np.array(S2) S1c = np.array(S1c) S2c = np.array(S2c) S1_bins = linspace(1, maxS1, maxS1) S1_bins = linspace(1, maxS1, maxS1) S1_bin_cen_e = empty_like(S1_bins) mean_S2oS1_e = empty_like(S1_bins) stdev_S2oS1_e = empty_like(S1_bins) # Find the ER S2/S1 band at each S1 det_cuts = (S1c > 0) & (S2c >= S2raw_min) for index, S1s in enumerate(S1_bins): cut = det_cuts & inrange(S1c, [S1s - 0.5, S1s + 0.5]) S1_bin_cen_e[index] = mean(S1c[cut]) mean_S2oS1_e[index] = mean(log10(S2c[cut] / S1c[cut])) stdev_S2oS1_e[index] = std(log10(S2c[cut] / S1c[cut])) # Calc Nr Efficiency vs E E_bins = linspace(1, maxEe, maxEe) E_bin_cen_e = empty_like(E_bins) Eff_e = empty_like(E_bins) det_cuts = (S1c > 0) & (S2c >= S2raw_min) for index, Es in enumerate(E_bins): cut = det_cuts & inrange(Flat_Ee, [Es - 0.5, Es + 0.5]) E_bin_cen_e[index] = mean(Flat_Ee[cut]) Eff_e[index] = sum(cut) / sum(inrange(Flat_Ee, [Es - 0.5, Es + 0.5])) # cut/total_in_bin return ( S1_bin_cen_n, mean_S2oS1_n, std_S2oS1_n, S1_bin_cen_e, mean_S2oS1_e, stdev_S2oS1_e, E_bin_cen_e, Eff_e, E_bin_cen_n, Eff_n, )
def genBands(NEST=NEST_setup(),nSim=2e5, maxS1=50, S2raw_min=450, Ermin=0, mWmp=50): '''input: NEST obj, nSim, maxS1, S2raw_min, Ermin, mWmp. output: S1_bin_cen_n, mean_S2oS1_n, std_S2oS1_n, S1_bin_cen_e, mean_S2oS1_e, std_S2oS1_e, E_bin_cen_e, Eff_e, E_S1_e(average E for a given S1), E_bin_cen_n, Eff_n, E_S1_n(average E for a given S1), num_leak_e(vs S1 bin), num_total_e(vs S1 bin), leak_gauss_e(vs S1 bin), sNR(spline NR band) ''' #start with NR NEST.SetParticleType(0) maxEr=100 #keVnr, for flat spectrum #Default, use a 50 GeV WIMP for discrimnation if mWmp==-1: Er = maxEr*st.uniform.rvs(size=nSim); #0-100 keVnr else: Er = rates.WIMP.genRandEnergies(nSim, mW=mWmp) ## Generate Signal in the detector ## Nph=[] Ne=[] S1=[] S2=[] S1c=[] S2c=[] for en in Er: NEST.SetEnergy(en) NEST.DetectorResponse() Nph.append(NEST.GetNumPhotons()) Ne.append(NEST.GetNumElectrons()) S1.append(NEST.GetS1()) S2.append(NEST.GetS2()) S1c.append(NEST.GetS1c()) S2c.append(NEST.GetS2c()) Nph=np.array(Nph) Ne=np.array(Ne) S1=np.array(S1) S2=np.array(S2) S1c=np.array(S1c) S2c=np.array(S2c) S1_bins=linspace(1,maxS1,maxS1) S1_bin_cen_n=empty_like(S1_bins) mean_S2oS1_n=empty_like(S1_bins) std_S2oS1_n=empty_like(S1_bins) E_S1_n=empty_like(S1_bins) coeff_n=[] var_matrix_n=[] #Find the NR S2/S1 band at each S1 det_cuts= (S1c>0) & (S2c>0) & (S2>=S2raw_min) & (Er>=Ermin) for index, S1s in enumerate(S1_bins): cut=det_cuts & inrange(S1c,[S1s-1/2,S1s+1/2]) S1_bin_cen_n[index]=mean(S1c[cut]) mean_S2oS1_n[index]=mean(log10(S2c[cut]/S1c[cut])) std_S2oS1_n[index]=std(log10(S2c[cut]/S1c[cut])) E_S1_n[index]=mean(Er[cut]) #average E for a given S1 #fit Gauss to distibution # p0 is the initial guess for the fitting coefficients (A, mu and sigma above) #hist, bin_edges = np.histogram(log10(S2c[cut]/S1c[cut]), 20, density=True) #bin_centres = (bin_edges[:-1] + bin_edges[1:])/2 #p0 = [max(hist), mean_S2oS1_n[index], std_S2oS1_n[index]] #coeff, var_matrix = curve_fit(gauss, bin_centres, hist, p0=p0) #coeff_n.append(coeff) #var_matrix_n.append(var_matrix) #convert to numpy array. 3xN matrix #coeff_n=np.array(coeff_n) #indexed as: amp, mean, sigma #var_matrix_n=np.array(var_matrix_n) #get NR mean, with a smooth spline(need this for discrimination calculation) if nSim>=5e5: sNR = ip.UnivariateSpline(S1_bin_cen_n, mean_S2oS1_n,s=.0001) #essentially linear interp else: sNR = ip.UnivariateSpline(S1_bin_cen_n, mean_S2oS1_n,s=.01) #essentially linear interp #Use gaussian fit #sNR = ip.UnivariateSpline(S1_bin_cen_n, coeff_n[:,1],s=0.005) #Calc Nr Efficiency vs E E_bins=linspace(0,maxEr,maxEr) E_bin_cen_n=empty_like(E_bins) Eff_n=empty_like(E_bins) det_cuts= (S1c>0) & (S2>=S2raw_min) for index, Es in enumerate(E_bins): cut=det_cuts & inrange(Er,[Es-0.5,Es+0.5]) E_bin_cen_n[index]=mean(Er[cut]) Eff_n[index]=sum(cut)/sum(inrange(Er,[Es-0.5,Es+0.5])) #cut/total_in_bin #Calculate the ER band and discrimination #################################################### maxEe=30 #keVee, for flat ER spectrum Flat_Ee = maxEe*st.uniform.rvs(size=nSim); #0-50 keVee ## Generate Signal in the detector ## Nph=[] Ne=[] S1=[] S2=[] S1c=[] S2c=[] NEST.SetParticleType(1) #set to ER events for en in Flat_Ee: NEST.SetEnergy(en) NEST.DetectorResponse() Nph.append(NEST.GetNumPhotons()) Ne.append(NEST.GetNumElectrons()) S1.append(NEST.GetS1()) S2.append(NEST.GetS2()) S1c.append(NEST.GetS1c()) S2c.append(NEST.GetS2c()) Nph=np.array(Nph) Ne=np.array(Ne) S1=np.array(S1) S2=np.array(S2) S1c=np.array(S1c) S2c=np.array(S2c) S1_bins=linspace(1,maxS1,maxS1) S1_bin_cen_e=empty_like(S1_bins) mean_S2oS1_e=empty_like(S1_bins) std_S2oS1_e=empty_like(S1_bins) num_leak_e=empty_like(S1_bins) num_total_e=empty_like(S1_bins) leak_gauss_e=empty_like(S1_bins) E_S1_e=empty_like(S1_bins) #Find the ER S2/S1 band at each S1 det_cuts= (S1c>0) & (S2c>0) & (S2>=S2raw_min) for index, S1s in enumerate(S1_bins): cut=det_cuts & inrange(S1c,[S1s-1/2,S1s+1/2]) S1_bin_cen_e[index]=mean(S1c[cut]) mean_S2oS1_e[index]=mean(log10(S2c[cut]/S1c[cut])) std_S2oS1_e[index]=std(log10(S2c[cut]/S1c[cut])) #calculate discrimination num_leak_e[index]=sum(log10(S2c[cut]/S1c[cut])<sNR(S1c[cut])) #num below NR mean num_total_e[index]=sum(cut) #Gaussian overlap nsig=(mean_S2oS1_e[index]-sNR(S1_bin_cen_e[index]))/std_S2oS1_e[index] #(meanER-meanNR)/sigER leak_gauss_e[index]=sp.special.erfc(nsig/sqrt(2))/2 E_S1_e[index]=mean(Flat_Ee[cut]) #average E for a given S1 #Calc Er Efficiency vs E E_bins=linspace(0,maxEe,maxEe) E_bin_cen_e=empty_like(E_bins) Eff_e=empty_like(E_bins) det_cuts= (S1c>0) & (S2>=S2raw_min) for index, Es in enumerate(E_bins): cut=det_cuts & inrange(Flat_Ee,[Es-0.5,Es+0.5]) E_bin_cen_e[index]=mean(Flat_Ee[cut]) Eff_e[index]=sum(cut)/sum(inrange(Flat_Ee,[Es-0.5,Es+0.5])) #cut/total_in_bin return S1_bin_cen_n, mean_S2oS1_n, std_S2oS1_n, S1_bin_cen_e, mean_S2oS1_e, std_S2oS1_e, E_bin_cen_e, Eff_e, E_S1_e, E_bin_cen_n, Eff_n, E_S1_n, num_leak_e, num_total_e, leak_gauss_e, sNR