def log_likelihood(self, x): # non detected logL_non_detected = 0.0 zgal = x['zgal'] log_p_non_det = self.log_prob_non_detected_galaxies(x) if np.isinf(log_p_non_det): logL_non_detected = -np.inf else: logL_non_detected += Gaussexp( lal.LuminosityDistance(self.omega, zgal), DL, dDL) logL_non_detected += Gaussexp(x['alpha'], GW.ra.rad, 1.0 / 10.0) logL_non_detected += Gaussexp(x['delta'], GW.dec.rad, 1.0 / 10.0) logL_non_detected += log_p_non_det # detected logL_detected = 0.0 zgw = x['zgw'] # estimate the probability of detecting a galaxy as 1-prob_non_detection log_p_det = logsumexp([0.0, log_p_non_det], b=[1, -1]) logL_detected += Gaussexp(lal.LuminosityDistance(self.omega, zgw), DL, dDL) logL_detected += logsumexp([ Gaussexp(zgw, zgi, zgi / 10.0) + Gaussexp(np.radians(rai), GW.ra.rad, 1.0 / 10.0) + Gaussexp(np.pi / 2.0 - np.radians(di), GW.dec.rad, 1.0 / 10.0) for zgi, rai, di in zip(self.catalog['z'], self.catalog['RAJ2000'], self.catalog['DEJ2000']) ]) logL_detected += log_p_det logL = logsumexp([logL_detected, logL_non_detected]) return logL
def readGC(file, standard_cosmology=True): ra, dec, zs, zp = [], [], [], [] dl = [] with open(file, 'r') as f: if standard_cosmology: omega = lal.CreateCosmologicalParameters(0.7, 0.3, 0.7, -1.0, 0.0, 0.0) for line in f: fields = line.split(None) if 0.0 < np.float(fields[40]) > 0.0 or np.float(fields[41]) > 0.0: if not (standard_cosmology): h = np.random.uniform(0.5, 1.0) om = np.random.uniform(0.0, 1.0) ol = 1.0 - om omega = lal.CreateCosmologicalParameters( h, om, ol, -1.0, 0.0, 0.0) ra.append(np.float(fields[0])) dec.append(np.float(fields[1])) zs.append(np.float(fields[40])) zp.append(np.float(fields[41])) if not (np.isnan(zs[-1])): dl.append(lal.LuminosityDistance(omega, zs[-1])) elif not (np.isnan(zp[-1])): dl.append(lal.LuminosityDistance(omega, zp[-1])) else: dl.append(-1) f.close() return np.column_stack( (np.radians(np.array(ra)), np.radians(np.array(dec)), np.array(dl)))
def log_prob_non_detected_galaxies(self, x): # controllo finitezza e theta(M-Mth) self.omega.h = x['h'] self.omega.om = x['om'] self.omega.ol = x['ol'] zgal = x['zgal'] mgal = x['mgal'] logP = 0.0 DL = lal.LuminosityDistance(self.omega, zgal) Mth = Mthreshold(DL) Mabsi = mabs(mgal, DL) if Mthreshold(DL) > Mabsi: return -np.inf else: # compute the allowed volume for the source gDL = 33.4 gdDL = 3.34 V = (4. / 3.) * np.pi * (gDL - gdDL)**3 # find the number density of galaxies from the low end of the Schecter # distribution n0 = 1. / normalise(self.omega, Mmax=Mth) K = np.int(V * n0) - len(self.catalog) if K <= 0.0: # no galaxies are missing return -np.inf logP += np.log(Schechter(Mabsi, self.omega)) logP += np.log(lal.ComovingVolumeElement(zgal, self.omega)) # norm = np.log(dblquad(normalise_integrand, self.bounds[0][0], self.bounds[0][1], # lambda x: mabs(mgal,lal.LuminosityDistance(self.omega, self.bounds[4][0])), # lambda x: mabs(mgal,lal.LuminosityDistance(self.omega, self.bounds[4][0])), # args = (self.omega, 1, ))[0]) # since for alpha < 0.0 the Schecter distribution diverges, approximate the integral with the # maximum of the integral norm = K * (np.log( Schechter( mabs(self.bounds[4][1], lal.LuminosityDistance( self.omega, self.bounds[0][1])), self.omega)) + np.log( lal.ComovingVolumeElement(self.bounds[0][1], self.omega))) return K * (logP - norm)
def log_likelihood(self, x): logL = 0.0 logL += np.log( gaussian(lal.LuminosityDistance(self.omega, x['z']), 33.4, 3.34)) logL += np.log(gaussian(x['ra'], GW.ra.rad, GW.ra.rad / 10.)) logL += np.log(gaussian(x['dec'], GW.dec.rad, GW.dec.rad / 10.)) return logL
def log_prior(self, x): # controllo finitezza e theta(M-Mth) if not(np.isfinite(super(completeness, self).log_prior(x))): return -np.inf else: self.omega.h = x['h'] self.omega.om = x['om'] self.omega.ol = x['ol'] zgw = x['z'] logP = 0.0 for zi,mi in zip(self.catalog['z'],self.catalog['Bmag']): DL = lal.LuminosityDistance(self.omega, zi) Mabsi = mabs(mi,DL) if Mthreshold(DL) < Mabsi: return -np.inf else: # Update parametri cosmologici con simulazione # Calcolo prior. Ciascuna coordinata è pesata con le probabilità # delle coordinate ('banane') GW, così come z. # Temporaneamente, è assunta gaussiana intorno a un evento. logP += np.log(Schechter(Mabsi, self.omega)) #log_P_RA = np.log(gaussian(x['ra'],Gal.ra.rad,Gal.ra.rad/100.)) #log_P_DEC = np.log(gaussian(x['dec'],Gal.dec.rad,Gal.dec.rad/100.)) logP += np.log(lal.ComovingVolumeElement(zi, self.omega)) return logP
def log_likelihood(self, x): logL = 0. zgw = x['zgw'] # Manca da correggere per il moto proprio (assunto, per ora, gaussiano con errore del 10%) # logL = logsumexp([Gaussexp(lal.LuminosityDistance(self.omega, zgi), DL, dDL)+Gaussexp(zgw, zgi, zgi/10.0)+Gaussexp(np.radians(rai), GW.ra.rad, 2.0)+Gaussexp(np.pi/2.0-np.radians(di), GW.dec.rad, 2.0) for zgi,rai,di in zip(self.catalog['z'],self.catalog['RAJ2000'],self.catalog['DEJ2000'])]) Lh = np.array([gaussian(zgw, zgi, zgi/10.0)*M.pLD(lal.LuminosityDistance(self.omega, zgi))*np.exp(M.p_pos.score_samples([[np.deg2rad(rai),np.deg2rad(di)]])[0])for zgi,rai,di in zip(self.catalog['z'],self.catalog['RAJ2000'],self.catalog['DEJ2000'])]) logL = np.log(Lh.sum()) return logL
def horizon(freq, psd, omega=OMEGA, **params): """Detector horizon distance in Mpc See horizon_redshift(). @returns distance in Mpc as a float """ zhor = horizon_redshift(freq, psd, omega=omega, **params) return lal.LuminosityDistance(omega, zhor)
def log_likelihood(self, x): logL = 0.0 zgw = x['z'] logL += np.log(gaussian(lal.LuminosityDistance(self.omega, zgw), DL,dDL)) logL += logsumexp([gaussian(zgw, zgi, zgi/10.0) for zgi in self.catalog['z']]) #logL += np.log(gaussian(x['ra'],GW.ra.rad,GW.ra.rad/10.)) #logL += np.log(gaussian(x['dec'],GW.dec.rad,GW.dec.rad/10.)) return logL
def log_likelihood(self, x): logL = 0. zgw = x['zgw'] # Proper motion is here assumed to be gaussian (sigma ~10%) Lh = np.array([ gaussian(zgw, zgi, zgi / 10.0) * M.pLD(lal.LuminosityDistance(self.omega, zgi)) * np.exp( M.p_pos.score_samples([[np.deg2rad(rai), np.deg2rad(di)]])[0]) for zgi, rai, di in zip(self.catalog['z'], self.catalog['RA'], self.catalog['Dec']) ]) logL = np.log(Lh.sum()) return logL
def log_likelihood(self, x): logL_detected = 0.0 zgw = x['zgw'] log_p_det = self.log_prob_detected_galaxies(x) if np.isinf(log_p_det): print('failed 1!') return -np.inf # detected logL_detected += np.log( gaussian(lal.LuminosityDistance(self.omega, zgw), DL, dDL)) logL_detected += logsumexp([ Gaussexp(zgw, zgi, zgi / 10.0) + Gaussexp(ai, GW.ra.rad, 1.0 / 10.0) + Gaussexp(di, GW.dec.rad, 1.0 / 10.0) for zgi, ai, di in zip(self.catalog['z'], self.catalog['RAJ2000'], self.catalog['DEJ2000']) ]) logL_detected += log_p_det # non detected logL_non_detected = 0.0 zgal = x['zgal'] log_p_non_det = self.log_prob_non_detected_galaxies(x) if np.isinf(log_p_non_det): print('failed 2!') return -np.inf logL_non_detected += np.log( gaussian(lal.LuminosityDistance(self.omega, zgal), DL, dDL)) logL_non_detected += np.log(gaussian(x['alpha'], GW.ra.rad, 1.0 / 10.0)) logL_non_detected += np.log( gaussian(x['delta'], GW.dec.rad, 1.0 / 10.0)) logL_non_detected += log_p_non_det logL = logsumexp([logL_detected, logL_non_detected]) # print(logL,logL_detected,logL_non_detected,log_p_det,log_p_non_det) return logL
def log_prob_detected_galaxies(self, x): # controllo finitezza e theta(M-Mth) self.omega.h = x['h'] self.omega.om = x['om'] self.omega.ol = x['ol'] zgw = x['zgw'] logP = 0.0 Vmax = lal.ComovingVolume(self.omega, self.bounds[0][1]) for zi, mi in zip(self.catalog['z'], self.catalog['Bmag']): DL = lal.LuminosityDistance(self.omega, zi) Mabsi = mabs(mi, DL) if Mthreshold(DL) < Mabsi: return -np.inf else: logP += np.log(Schechter(Mabsi, self.omega)) logP += np.log( lal.ComovingVolumeElement(zi, self.omega) / Vmax) return logP
def log_prob_detected_galaxies(self, x): # controllo finitezza e theta(M-Mth) if not (np.isfinite(super(completeness, self).log_prior(x))): return -np.inf else: self.omega.h = x['h'] self.omega.om = x['om'] self.omega.ol = x['ol'] zgw = x['zgw'] logP = 0.0 for zi, mi in zip(self.catalog['z'], self.catalog['Bmag']): DL = lal.LuminosityDistance(self.omega, zi) Mabsi = mabs(mi, DL) if Mthreshold(DL) < Mabsi: return -np.inf else: logP += np.log(Schechter(Mabsi, self.omega)) logP += np.log(lal.ComovingVolumeElement(zi, self.omega)) return logP
def log_prob_non_detected_galaxies(self, x): # controllo finitezza e theta(M-Mth) if not (np.isfinite(super(completeness, self).log_prior(x))): return -np.inf else: self.omega.h = x['h'] self.omega.om = x['om'] self.omega.ol = x['ol'] zgal = x['zgal'] mgal = x['mgal'] logP = 0.0 K = 38 DL = lal.LuminosityDistance(self.omega, zgal) Mabsi = mabs(mgal, DL) if Mthreshold(DL) > Mabsi: print(Mthreshold(DL), Mabsi) return -np.inf else: logP += np.log(Schechter(Mabsi, self.omega)) logP += np.log(lal.ComovingVolumeElement(zgal, self.omega)) return K * logP
def gen_waveform(freq, z=0, omega=OMEGA, **params): """Generate frequency-domain inspiral waveform `freq` should be an array of frequency points at which the waveform should be interpolated. Returns a tuple of (h_tilde^plus, h_tilde^cross) real-valued (amplitude only) arrays. The waveform is generated with lalsimulation.SimInspiralChooseFDWaveform(). Keyword arguments are used to update the default waveform parameters (1.4/1.4 Msolar, optimally-oriented, 100 Mpc, (see DEFAULT_PARAMS macro)). The mass parameters ('m1' and 'm2') should be specified in solar masses and the 'distance' parameter should be specified in parsecs**. Waveform approximants may be given as string names (see `lalsimulation` documentation for more info). If the approximant is not specified explicitly, DEFAULT_APPROXIMANT_BNS waveform will be used if either mass is less than 5 Msolar and DEFAULT_APPROXIMANT_BBH waveform will be used otherwise. If a redshift `z` is specified (with optional `omega`), it's equivalent distance will be used (ignoring any `distance` parameter provided) and the masses will be redshift-corrected appropriately. Otherwise no mass redshift correction will be applied. For example, to generate a 20/20 Msolar BBH waveform: >>> hp,hc = waveform.gen_waveform(freq, 'm1'=20, 'm2'=20) **NOTE: The requirement that masses are specified in solar masses and distances are specified in parsecs is different than that of the underlying lalsimulation method which expects mass and distance parameters to be in SI units. """ iparams = _get_waveform_params(**params) # if redshift specified use that as distance and correct # appropriately, ignoring any distance specified in params. if z != 0: iparams['distance'] = lal.LuminosityDistance(omega, z) * 1e6 iparams['m1'] *= 1.0 + z iparams['m2'] *= 1.0 + z # convert to SI units iparams['distance'] *= lal.PC_SI iparams['m1'] *= lal.MSUN_SI iparams['m2'] *= lal.MSUN_SI iparams['approximant'] = lalsimulation.SimInspiralGetApproximantFromString( iparams['approximant']) iparams['deltaF'] = freq[1] - freq[0] iparams['f_min'] = freq[0] # FIXME: the max frequency in the generated waveform is not always # greater than f_max, so as a workaround we generate over the full # band. Probably room for speedup here # iparams['f_max'] = freq[-1] iparams['f_max'] = 10000 # print(iparams) # logging.debug('waveform params = {}'.format(iparams)) # generate waveform h = lalsimulation.SimInspiralChooseFDWaveform(**iparams) # print(h) freq_h = h[0].f0 + np.arange(len(h[0].data.data)) * h[0].deltaF def interph(h): "interpolate amplitude of h array" # FIXME: this only interpolates/returns the amplitude, and not # the full complex data (throws out phase), because this was # not working: # hir = scipy.interpolate.interp1d(freq_h, np.real(h.data.data))(freq) # hii = scipy.interpolate.interp1d(freq_h, np.imag(h.data.data))(freq) # return hir + 1j * hii return scipy.interpolate.interp1d(freq_h, np.absolute(h.data.data))(freq) hi = map(interph, h) return hi
p0 = p Z.append(z0) return np.array(Z) max_redshift = 0.7 Uniform_in_Vc = True # From Planck2015, Table IV omega = lal.CreateCosmologicalParametersAndRate().omega lal.SetCosmologicalParametersDefaultValue(omega) omega.h = 0.679 omega.om = 0.3065 omega.ol = 0.6935 omega.ok = 1.0 - omega.om - omega.ol omega.w0 = -1.0 omega.w1 = 0.0 omega.w2 = 0.0 zz = sample_redshifts_ligo_method(3, 100000) dc = [] dvdz = [] for z in zz: dc.append(lal.LuminosityDistance(OMEGA, z) / (1 + z)) dvdz.append(pdf(z, OMEGA)) dc = np.array(dc) dvdz = np.array(dvdz) plt.hist(zz, 35) plt.plot(zz, dvdz / 5e7, 'o') plt.show()
# RUN="O1" RUN = "O2" WPATH = "/home/shreejit.jadhav/WORK" # WPATH="/home/shreejit/Dropbox/Academic/WORK" H1L1_PSD = "{0}/CBCMassesToGWSNR/Data/PSDs/{1}/H1L1_{1}_PSD.txt".format( WPATH, RUN) psd = np.genfromtxt(H1L1_PSD, delimiter=" ") freqs = psd[:, 0][4000:] psd = psd[:, 1][4000:] m = 50 z_hor = horizon_redshift(freqs, psd, omega=OMEGA, m1=m, m2=m) D_hor = lal.LuminosityDistance(OMEGA, z_hor) print z_hor, D_hor # # First we create an injection sim file each for upper and lower cutoffs # # RUN="O1" # RUN="O2" # LIMIT="Upper" # # LIMIT="Lower" # if [ $LIMIT == "Lower" ] # then # MASS=5. # DMIN=10000 # DMAX=90000
def Mthreshold(z, omega, mth=24): ''' Magnitudine assoluta di soglia ''' return mth - 5.0 * np.log10(1e5 * lal.LuminosityDistance(omega, z))
def dropgal(self): for i in self.catalog.index: if self.pLD(lal.LuminosityDistance(self.omega, self.catalog['z'][i])) < 0.0001: self.catalog = self.catalog.drop(i)
def convert_to_dlum(z, omega=OMEGA): Dlum = [] for rs in z: Dlum.append(lal.LuminosityDistance(omega, rs)) return np.array(Dlum)
def find_z_root(z, dl, omega): return dl - lal.LuminosityDistance(omega, z)
def Mthreshold(z, omega, mth=24): return mth - 5.0 * np.log10(1e5 * lal.LuminosityDistance(omega, z))