def Compute_dNdf(input, output, h): # Meat of the code we are computing ''' Compute d4N/(dz dM dq df) for a given df bin This formula is made to work with the joblib python package @param input: An array of appropriate parameters, see first few lines of this formula which unpacks the input array @param output: An empty array which gets filled by this formula @param h: The index for which df bin to fill in the output array ''' alpha = input[0][h] # gravitational wave frequency specific to a bin Redshifts = input[1] logGalMass = input[2] MassRatios = input[3] dz = input[4] dMass = input[5] dq = input[6] Dist = input[7] Vc_interp = input[8] # comoving volume to use for interpolation z_interp = input[9] # redshift to use for interpolation dist4interp = input[10] # proper distance to use for interpolation dVdz_interp = interp.interp1d(z_interp, Vc_interp) # Does 1-dimensional interpolation to find the slope dist_interp = interp.interp1d(z_interp, dist4interp) RandState = np.random.RandomState() dNdt_ET = 1e-100 # initialize number of early type memory events dNdt_LT = 1e-100 # initialize numer of late type memory events epsilon = RandState.normal(0, 0.36, (2, len(Redshifts), len(logGalMass), len(MassRatios))) for ii in xrange(len(Redshifts)): z = Redshifts[ii] frac = ABBSutils.KeenanPairFraction(z) dV = ABBSinit.CoMoveVolume(z) dVcdz = ABBSinit.Vdz(z) dtrdt = 1/(1+z) dist = Dist[ii] for jj in xrange(len(logGalMass)): logM1 = logGalMass[jj] M1 = 10**logM1 dM = dMass[jj] PhiET = ABBSutils.CANDELS_ZFOURGE_MF(logM1, z, 'early') PhiLT = ABBSutils.CANDELS_ZFOURGE_MF(logM1, z, 'late') for kk in xrange(len(MassRatios)): q = MassRatios[kk] dfrac = -frac / (q * np.log(0.4)) # from Sesana 2013 - [ dfrac/d(log q) = constant from Xu 2012 ] tau = (1.264e16) * (M1 * 1.75e-11)**(-0.3) * (1 + (z/8)) # from Lotz 2011 - units of secs d3nET = (PhiET * dfrac * dtrdt * dVcdz / tau) # Differential Number of Early-Type Galaxy Mergers d3nLT = (PhiLT * dfrac * dtrdt * dVcdz / tau) # Differential Number of Late-Type Galaxy Mergers # McET, MtotET, MqET = ABBSinit.MChirpEarlyType_NoScatter(M1, q, 8.46, 1.05) # McLT, MtotLT, MqLT = ABBSinit.MChirpLateType_NoScatter(M1, q, 8.46, 1.05) ep_ET = epsilon[0, ii, jj, kk] McET, MtotET, MqET = ABBS.init.MChirpEarlyType(M1, q, 8.46, 1.05, ep_ET) ep_LT = epsilon[1, ii, jj, kk] McLT, MtotLT, MqLT = ABBSinit.MChirpLateType(M1, q, 8.46, 1.05, ep_LT) # # Calculate Memory Signal # tauET = ABBSinit.Tau_GW_alpha(alpha, MtotET, McET) #. Convert f to output of Kepler's third law (use alpha for semi-major axis) tauLT = ABBSinit.Tau_GW_alpha(alpha, MtotLT, McLT) #. Convert f to output of Kepler's third law z_coalET = ABBSinit.z_coal(z, tauET) z_coalLT = ABBSinit.z_coal(z, tauLT) #print tauET, z_coalET muET = MtotET * (MqET / (1 + MqET)) muLT = MtotLT * (MqLT / (1 + MqLT)) i_ET = np.arcsin(RandState.uniform()) i_LT = np.arcsin(RandState.uniform()) dist_mem_ET = dist_interp(z_coalET) * 1e6 dist_mem_LT = dist_interp(z_coalLT) * 1e6 h_mem_ET = ABBSinit.h_mem_plus(i_ET, muET, dist_mem_ET, z_coalET) h_mem_LT = ABBSinit.h_mem_plus(i_LT, muLT, dist_mem_LT, z_coalLT) dVcdzET_mem = dVdz_interp(z_coalET) dVcdzLT_mem = dVdz_interp(z_coalLT) dzdt_ET_mem = ABBSinit.tdz(z_coalET)**(-1) dzdt_LT_mem = ABBSinit.tdz(z_coalLT)**(-1) dtdz_merger = ABBSinit.tdz(z) #. In order to find the number of memory events occuring during some observation time, we need to first #. convert the rate of events from that measured in the binary's rest frame to that measured on Earth. #. Multiply by one Earth year to find the number of events observed. prefactor = (dfrac / tau) * dtdz_merger * dtrdt #print PhiET, prefactor, dVcdzET_mem, dzdt_ET_mem, dq, dM, dz dNdt_ET += PhiET * prefactor * dVcdzET_mem * dzdt_ET_mem * dq * dM * dz * (3.1e7) dNdt_LT += PhiLT * prefactor * dVcdzLT_mem * dzdt_LT_mem * dq * dM * dz * (3.1e7) print dNdt_ET, dNdt_LT output[0,h] = dNdt_ET # output in 1/yr output[1,h] = dNdt_LT
def Compute_dNdf(input, output, h): ''' Compute d4N/(dz dM dq df) for a given df bin This formula is made to work with the joblib python package @param input: An array of appropriate parameters, see first few lines of this formula which unpacks the input array @param output: An empty array which gets filled by this formula @param h: The index for which df bin to fill in the output array ''' f = input[0][h] dfdlnf = f Redshifts = input[1] logGalMass = input[2] MassRatios = input[3] dz = input[4] dMass = input[5] dq = input[6] dlnf = input[7][h] Dist = input[8] Vc_interp = input[9] z_interp = input[10] dist4interp = input[11] dVdz_interp = interp.interp1d(z_interp, Vc_interp) dist_interp = interp.interp1d(z_interp, dist4interp) RandState = np.random.RandomState() for ii in xrange(len(Redshifts)): z = Redshifts[ii] frac = ABBSutils.KeenanPairFraction(z) dVcdz = ABBSinit.Vdz(z) dtrdt = 1/(1+z) dtdz = ABBSinit.tdz(z) dist = Dist[ii] for jj in xrange(len(logGalMass)): logM1 = logGalMass[jj] M1 = 10**logM1 dM = dMass[jj] PhiET = ABBSutils.CANDELS_ZFOURGE_MF(logM1, z, 'early') PhiLT = ABBSutils.CANDELS_ZFOURGE_MF(logM1, z, 'late') for kk in xrange(len(MassRatios)): q = MassRatios[kk] dfrac = -frac / (q * np.log(0.4)) # from Sesana 2013 - [ dfrac/d(log q) = constant from Xu 2012 ] tau = (1.264e16) * (M1 * 1.75e-11)**(-0.3) * (1 + (z/8)) # from Lotz 2011 - units of secs d3nET = (PhiET * dfrac * dtrdt * dVcdz / tau) # Differential Number of Early-Type Galaxy Mergers d3nLT = (PhiLT * dfrac * dtrdt * dVcdz / tau) # Differential Number of Late-Type Galaxy Mergers McET, MtotET, MqET = ABBSinit.MChirpEarlyType_NoScatter(M1, q, 8.46, 1.05) McLT, MtotLT, MqLT = ABBSinit.MChirpLateType_NoScatter(M1, q, 8.46, 1.05) dtdfET = ABBSinit.tdf(z, McET, f) dtdfLT = ABBSinit.tdf(z, McLT, f) h_insp_ET = ABBSinit.RMSStrainFAST(z, McET, f, dist) h_insp_LT = ABBSinit.RMSStrainFAST(z, McLT, f, dist) d4NET_insp = d3nET * dtdfET * dfdlnf * dz * dM * dq * dlnf d4NLT_insp = d3nLT * dtdfLT * dfdlnf * dz * dM * dq * dlnf # Calculate Memory Signal # # tau_GW_ET = ABBSinit.Tau_GW(z, McET, f) # tau_GW_LT = ABBSinit.Tau_GW(z, McLT, f) # z_coalET = ABBSinit.z_coal(z, tau_GW_ET) # z_coalLT = ABBSinit.z_coal(z, tau_GW_LT) muET = MtotET * (MqET / (1 + MqET)**2) muLT = MtotLT * (MqLT / (1 + MqLT)**2) i_ET = np.pi / 2. #np.arcsin(RandState.uniform()) i_LT = np.pi / 2. #np.arcsin(RandState.uniform()) # dist_mem_ET = dist_interp(z_coalET) * 1e6 # dist_mem_LT = dist_interp(z_coalLT) * 1e6 h_mem_ET = ABBSinit.h_mem_plus(i_ET, muET, dist * 1e6, z) # dist needs to be in parsec h_mem_LT = ABBSinit.h_mem_plus(i_LT, muLT, dist * 1e6, z) # dist needs to be in parsec # dVcdzET_mem = dVdz_interp(z_coalET) # dVcdzLT_mem = dVdz_interp(z_coalLT) # dzdt_ET_mem = ABBSinit.tdz(z_coalET)**(-1) # dzdt_LT_mem = ABBSinit.tdz(z_coalLT)**(-1) # d3nET_mem = (PhiET * dfrac * dtrdt * dtdz * dzdt_ET_mem * dVcdzET_mem / tau) # d3nLT_mem = (PhiLT * dfrac * dtrdt * dtdz * dzdt_LT_mem * dVcdzLT_mem / tau) d4NET_mem = d3nET * dz * dM * dq * dfdlnf d4NLT_mem = d3nLT * dz * dM * dq * dfdlnf output[0, h, ii, jj, kk] = d4NET_insp output[1, h, ii, jj, kk] = d4NLT_insp output[2, h, ii, jj, kk] = h_insp_ET**2 output[3, h, ii, jj, kk] = h_insp_LT**2 output[4, h, ii, jj, kk] = d4NET_mem output[5, h, ii, jj, kk] = d4NLT_mem output[6, h, ii, jj, kk] = (h_mem_ET / f)**2 output[7, h, ii, jj, kk] = (h_mem_LT / f)**2