def dRdE_nu(E_r,t,sol,E_nu,Flux,Nuc): N = Nuc.NumberOfNeutrons Z = Nuc.NumberOfProtons Q_W = 1.0*N-(1-4.0*sinTheta_Wsq)*Z # weak nuclear hypercharge m_N_GeV = 0.93141941*(N+Z) # nucleus mass in GeV m_N_keV = m_N_GeV*1.0e6 # nucleus mass in keV dRdE = zeros(shape=shape(E_r)) FF = LabFuncs.FormFactorHelm(E_r,N+Z)**2.0 ne = size(E_r) if Flux[1]>0.0: for i in range(0,ne): diff_sigma = (G_F_GeV**2.0 /(4.0*pi))*(Q_W**2.0)*m_N_GeV*(1.0 \ -(m_N_keV*E_r[i])/(2.0*(E_nu*1000.0)**2.0))*\ (0.197e-13)**2.0*(1.0e-6)*1000.0/(1.0*N+1.0*Z)*(N_A) diff_sigma[diff_sigma<0.0] = 0.0 dRdE[i] = trapz(diff_sigma*Flux*FF[i],x=E_nu) else: for i in range(0,ne): diff_sigma = (G_F_GeV**2.0 /(4.0*pi))*(Q_W**2.0)*m_N_GeV*(1.0 \ -(m_N_keV*E_r[i])/(2.0*(E_nu[0]*1000.0)**2.0))*\ (0.197e-13)**2.0*(1.0e-6)*1000.0/(1.0*N+1.0*Z)*(N_A) if diff_sigma>0: dRdE[i] = diff_sigma*Flux[0]*E_nu[0] # for monochromatic nu's if sol: fMod = LabFuncs.EarthSunDistanceMod(t) else: fMod = 1.0 # Convert into /ton/year/keV dRdE = fMod*dRdE*(365.0*3600.0*24.0*1000.0) return dRdE
def dRdE_wimp(E_r,t,DM,\ HaloModel=Params.SHM,Nuc=Params.Ar40,Loc=Params.GranSasso): # relevant constants A = Nuc.MassNumber # mass number of nucleus m_chi = DM.Mass mu_p = 1.0e6 * m_chi * m_p_keV / (1.0e6 * m_chi + m_p_keV) sigma_p = DM.SICrossSection v_0 = sqrt(2.0) * HaloModel.Dispersion v_esc = HaloModel.EscapeSpeed rho_0 = HaloModel.Density N_esc = HaloModel.Normalisation FF = LabFuncs.FormFactorHelm(E_r, A)**2.0 v_min = MinimumWIMPSpeed(E_r, A, m_chi) R0 = (c_cm * c_cm) * ((rho_0 * 1.0e6 * A * A * sigma_p) / (2 * m_chi * GeV_2_kg * mu_p * mu_p)) # init ne = size(E_r) nt = size(t) dR = zeros(shape=ne) gvmin = zeros(ne) # Mean inverse speed x = v_min / v_0 z = v_esc / v_0 if t[0] == t[-1]: v_e = norm(LabFuncs.LabVelocity(t[0], Loc, HaloModel.RotationSpeed)) y = v_e / v_0 gvmin[(x < abs(y - z)) & (z < y)] = (1.0 / (v_0 * y)) else: v_e = zeros(shape=ne) for i in range(0, nt): v_e[i] = norm( LabFuncs.LabVelocity(t[i], Loc, HaloModel.RotationSpeed)) y = v_e / v_0 g1 = (1.0 / (v_0 * y)) gvmin[(x < abs(y - z)) & (z < y)] = g1[(x < abs(y - z)) & (z < y)] g2 = (1.0 / (2.0 * N_esc * v_0 * y)) * (erf(x + y) - erf(x - y) - (4.0 / sqrt(pi)) * y * exp(-z**2)) g3 = (1.0 / (2.0 * N_esc * v_0 * y)) * (erf(z) - erf(x - y) - (2.0 / sqrt(pi)) * (y + z - x) * exp(-z**2)) gvmin[(x < abs(y - z)) & (z > y)] = g2[(x < abs(y - z)) & (z > y)] gvmin[(abs(y - z) < x) & (x < (y + z))] = g3[(abs(y - z) < x) & (x < (y + z))] gvmin[(y + z) < x] = 0.0 gvmin = gvmin / (1000.0 * 100.0) # convert to cm^-1 s # Compute rate = (Rate amplitude * gmin * form factor) dR = R0 * gvmin * FF dR = dR * seconds2year * 1000.0 # convert to per ton-year return dR
def dRdEdO_wimp(E,t,DM,HaloModel=Params.SHM,Nuc=Params.Ar40,\ Loc=Params.GranSasso,CygnusTracking=False): E_r = sqrt(E[:, 0]**2 + E[:, 1]**2 + E[:, 2]**2) # Recoil energy x = zeros(shape=shape(E)) x[:, 0] = E[:, 0] / E_r # Recoil direction x[:, 1] = E[:, 1] / E_r x[:, 2] = E[:, 2] / E_r # relevant constants A = Nuc.MassNumber # mass number of nucleus m_chi = DM.Mass mu_p = 1.0e6 * m_chi * m_p_keV / (1.0e6 * m_chi + m_p_keV) sigma_p = DM.SICrossSection sig_v = HaloModel.Dispersion v_esc = HaloModel.EscapeSpeed rho_0 = HaloModel.Density N_esc = HaloModel.Normalisation FF = LabFuncs.FormFactorHelm(E_r, A)**2.0 v_min = MinimumWIMPSpeed(E_r, A, m_chi) R0 = (c_cm * c_cm) * ((rho_0 * 1.0e6 * A * A * sigma_p) / (4 * pi * m_chi * GeV_2_kg * mu_p * mu_p)) # Calculate v_lab ne = size(E_r) nt = size(t) dR = zeros(shape=(size(E_r))) v_lab = zeros(shape=(size(E_r), 3)) for i in range(0, nt): v_lab[i, :] = LabFuncs.LabVelocity(t[i], Loc, HaloModel.RotationSpeed) # Just put vlab towards north pole for cygnus tracking experiment: if CygnusTracking == True: for i in range(0, nt): v_lab[i, :] = array([0.0, 0.0, sqrt(sum(v_lab[i, :]**2.0))]) # recoil projection vlabdotq = (x[:, 0] * v_lab[:, 0] + x[:, 1] * v_lab[:, 1] + x[:, 2] * v_lab[:, 2]) # Radon transform fhat = zeros(shape=shape(E_r)) fhat[((v_min+vlabdotq)<(v_esc))] = (1/(N_esc*sqrt(2*pi*sig_v**2.0)))\ *(exp(-(v_min[((v_min+vlabdotq)<(v_esc))]\ +vlabdotq[((v_min+vlabdotq)<(v_esc))])\ **2.0/(2*sig_v**2.0))\ -exp(-v_esc**2.0/(2*sig_v**2.0))) fhat = fhat / (1000.0 * 100.0) # convert to cm^-1 s # Compute rate = (Rate amplitude * radon trans. * form factor) dR = R0 * fhat * FF # correct for form factor dR = dR * seconds2year * 1000.0 # convert to per ton-year return dR
def dRdEdO_wimp(E, t, DM, HaloModel, Nuc, Loc): E_r = sqrt(E[:, 0]**2 + E[:, 1]**2 + E[:, 2]**2) # Recoil energy x = zeros(shape=shape(E)) x[:, 0] = E[:, 0] / E_r # Recoil direction x[:, 1] = E[:, 1] / E_r x[:, 2] = E[:, 2] / E_r # relevant constants A = Nuc.MassNumber # mass number of nucleus m_chi = DM.Mass mu_p = 1.0e6 * m_chi * m_p / (1.0e6 * m_chi + m_p) sigma_p = DM.SICrossSection sig_v = HaloModel.Dispersion v_esc = HaloModel.EscapeSpeed rho_0 = HaloModel.Density N_esc = HaloModel.Normalisation FF = LabFuncs.FormFactorHelm(E_r, A)**2.0 v_min = MinimumWIMPSpeed(E_r, A, m_chi) R0 = (c_cm * c_cm) * ((rho_0 * 1.0e6 * A * A * sigma_p) / (4 * pi * m_chi * GeV_2_kg * mu_p * mu_p)) # init ne = size(E_r) nt = size(t) dR = zeros(shape=(size(E_r))) v_lab = zeros(shape=(size(E_r), 3)) for i in range(0, nt): v_lab[i, :] = LabFuncs.LabVelocity(t[i], Loc, HaloModel) vlabdotq = (x[:, 0] * v_lab[:, 0] + x[:, 1] * v_lab[:, 1] + x[:, 2] * v_lab[:, 2]) # recoil projection # Radon transform fhat = zeros(shape=shape(E_r)) fhat[((v_min+vlabdotq)<(v_esc))] = (1/(N_esc*sqrt(2*pi*sig_v**2.0)))\ *(exp(-(v_min[((v_min+vlabdotq)<(v_esc))]\ +vlabdotq[((v_min+vlabdotq)<(v_esc))])\ **2.0/(2*sig_v**2.0))\ -exp(-v_esc**2.0/(2*sig_v**2.0))) fhat = fhat / (1000.0 * 100.0) # convert to cm^-1 s # Compute rate = (Rate amplitude * radon trans. * form factor) dR = R0 * fhat * FF # correct for form factor dR = dR * 3600 * 24 * 365 * 1000.0 # convert to per ton-year return dR
def diffRecoilRate_SI(E_r, HaloIntegral, A, sigma_p, m_chi, rho_0=0.55): # E_r = Recoil energy in keVr # HaloIntegral = g(vmin) or fhat(vmin,q) for non-dir. or dir. experiment # A = Nucleus Mass Number # sigma_p = SI WIMP-proton cross section in cm^2 # m_chi = WIMP mass in GeV # rho_0 = Local DM density mu_p = 1.0e6 * m_chi * m_p / (1.0e6 * m_chi + m_p) # reduced mass FF = LabFuncs.FormFactorHelm(E_r, A)**2.0 # Form Factor^2 R0 = (c_cm * c_cm) * ((rho_0 * 1.0e6 * A * A * sigma_p) / (2 * m_chi * GeV_2_kg * mu_p * mu_p)) HaloIntegral = HaloIntegral / (1000.0 * 100.0) # convert to cm^-1 s # Compute rate = (Rate amplitude * HaloIntegral * form factor) dR = R0 * HaloIntegral * FF dR = dR * 3600 * 24 * 365 * 1000.0 # convert to units of 1/(keVr ton year) return dR
def dRdEdO_solarnu(E,t,E_nu,Flux,Nuc,Loc): # Directional CEnuNS for Solar N = Nuc.NumberOfNeutrons Z = Nuc.NumberOfProtons Q_W = N-(1-4.0*sinTheta_Wsq)*Z # weak nuclear hypercharge m_N_GeV = 0.93141941*(N+Z) # nucleus mass in GeV m_N_keV = m_N_GeV*1.0e6 # nucleus mass in keV E_nu_keV = E_nu*1e3 E_r = sqrt(E[:,0]**2 + E[:,1]**2 + E[:,2]**2) # Recoil energy x = zeros(shape=shape(E)) x_sun = zeros(shape=shape(E)) x[:,0] = E[:,0]/E_r # Recoil direction x[:,1] = E[:,1]/E_r x[:,2] = E[:,2]/E_r ne =size(E_r) dRdEdO = zeros(shape=ne) for i in range(0,ne): x_sun[i,:] = LabFuncs.SolarDirection(t[i],Loc) cos_th_sun = -(x_sun[:,0]*x[:,0]+x_sun[:,1]*x[:,1]+x_sun[:,2]*x[:,2]) FF = LabFuncs.FormFactorHelm(E_r,N+Z)**2.0 # CHROMATIC NEUTRINOS if Flux[1]>0.0: E_max = 2*m_N_keV*E_nu_keV[-1]**2.0/(m_N_keV+E_nu_keV[-1])**2 i_range = range(0,ne)*(E_r<=E_max) i_sel = i_range[i_range!=0] for i in i_sel: costh = cos_th_sun[i] E_nu_min = sqrt(m_N_keV*E_r[i]/2.0) if costh>(E_nu_min/m_N_keV): Eps = 1.0/(costh/E_nu_min - 1.0/m_N_keV) diff_sigma = (G_F_GeV**2/(4*pi))*Q_W**2*m_N_GeV*\ (1-(m_N_keV*E_r[i])/(2*Eps**2))*(0.197e-13)**2.0\ *1e-6*1000/(N+1.0*Z)*(N_A) Eps = Eps*(Eps>E_nu_min) Eps = Eps*(Eps<E_nu_keV[-1]) F_value = interp(Eps,E_nu_keV,Flux) dRdEdO[i] = diff_sigma*F_value*Eps**2.0/(1000*E_nu_min)*FF[i] # /kg/keV # MONOCHROMATIC NEUTRINOS else: E_max = 2*m_N_keV*E_nu_keV[0]**2.0/(m_N_keV+E_nu_keV[0])**2 i_range = range(0,ne)*(E_r<=E_max) i_sel = i_range[i_range!=0] for i in i_sel: costh = cos_th_sun[i] E_nu_min = sqrt(m_N_keV*E_r[i]/2.0) costh_r = ((E_nu_keV[0]+m_N_keV)/E_nu_keV[0])*sqrt(E_r[i]/(2*m_N_keV)) # just need to accept angles close enough to costh_r to be accurate # around 0.01 is enough to be disguised by most angular resolutions if abs((costh)-(costh_r))<0.01: Eps = E_nu_keV[0] diff_sigma = (G_F_GeV**2/(4*pi))*Q_W**2*m_N_GeV*\ (1-(m_N_keV*E_r[i])/(2*Eps**2))*(0.197e-13)**2.0\ *1e-6*1000/(N+1.0*Z)*(N_A)*FF[i] dRdEdO[i] = diff_sigma*(Flux[0]/1000.0)*E_nu_keV[0] # /kg/keV fMod = LabFuncs.EarthSunDistanceMod(t) dRdEdO = fMod*dRdEdO*3600*24*365*1000/(2*pi) # /ton/year return dRdEdO
def GenerateAtmNuDirections(ngen, E_fine, Phi_fine, E_high, Phi_Ang, cosZ, phi_Az, Nuc): ngen_large = 2 * ngen ngen_red = 0 # Nucleus mass A = Nuc.MassNumber m_N_keV = A * 0.9315 * 1e6 # Flux binning nc = size(cosZ) np = size(phi_Az) [C, P] = meshgrid(cosZ, phi_Az) C = reshape(C, nc * np) P = reshape(P, nc * np) # Neutrino energy distribution fdist = (E_fine**2.0) * Phi_fine fdist = fdist / sum(fdist) # Get energies: E_gen_full = array([]) E_r_gen_full = array([]) while ngen_red < ngen: # Generate neutrino energies E_gen = random.choice(E_fine, p=fdist, size=ngen_large) # Generate recoil energies E_r_gen = (2 * m_N_keV * (E_gen * 1000)**2.0 / (m_N_keV + 1000 * E_gen)**2.0) * ( 1 - sqrt(random.uniform(size=ngen_large))) # Form Factor correction mask = (random.uniform(size=ngen_large) < LabFuncs.FormFactorHelm( E_r_gen, A)**2.0) E_gen_full = append(E_gen_full, E_gen[mask]) E_r_gen_full = append(E_r_gen_full, E_r_gen[mask]) ngen_red = shape(E_gen_full)[0] print('Filled ', 100 * ngen_red / (1.0 * ngen), '% of', ngen, 'samples') E_gen = E_gen_full[0:ngen] E_r_gen = E_r_gen_full[0:ngen] # Get angles: # Digitize to find which energy bin to use E_bin_gen = digitize(log10(E_gen), log10(E_high)) nhigh = size(E_high) phi_nu_gen = zeros(shape=ngen) costh_nu_gen = zeros(shape=ngen) for i in range(0, nhigh): # Select energy bin mask = E_bin_gen == i ngen_i = count_nonzero(mask) # Generate indices corresponding to 2D angular distribution fdist_CP = Phi_Ang[:, :, i] fdist_CP = reshape(fdist_CP, nc * np) fdist_CP = fdist_CP / sum(fdist_CP) igen = random.choice(arange(0, nc * np), p=fdist_CP, size=ngen_i) # Select phi and costh from generated index phi_nu_gen[mask] = P[igen] * pi / 180.0 costh_nu_gen[mask] = C[igen] dphi = (pi / 180) * (phi_Az[1] - phi_Az[0]) dcosth = (cosZ[1] - cosZ[0]) phi_nu_gen += (dphi / 2.0) * (2 * random.uniform(size=ngen) - 1) costh_nu_gen += (dcosth / 2.0) * (2 * random.uniform(size=ngen) - 1) return E_gen, phi_nu_gen, costh_nu_gen, E_r_gen