def radiusofm(self, m): """Radius in km. """ try: r_SI = lalsimulation.SimNeutronStarRadius(m*lal.MSUN_SI, self.fam) return r_SI/1000.0 except: return -1
def radiusofm(self, m): """Radius in km. """ if self.properties_flag==None: self.calculate_ns_properties() r_SI = lalsimulation.SimNeutronStarRadius(m*lal.MSUN_SI, self.fam) return r_SI/1000.0
def Lambdas(params): #Unpack params eosname = params['eosname'] m1 = params['m1'] m2 = params['m2'] #Create EOS/Family structures eos = lalsim.SimNeutronStarEOSByName(eosname) fam = lalsim.CreateSimNeutronStarFamily(eos) r1 = lalsim.SimNeutronStarRadius(m1 * MSUN_SI, fam) r2 = lalsim.SimNeutronStarRadius(m2 * MSUN_SI, fam) k1 = lalsim.SimNeutronStarLoveNumberK2(m1 * MSUN_SI, fam) k2 = lalsim.SimNeutronStarLoveNumberK2(m2 * MSUN_SI, fam) c1 = m1 * MRSUN_SI / r1 c2 = m2 * MRSUN_SI / r2 Lambda1 = (2.0 / 3.0) * k1 / c1**5. Lambda2 = (2.0 / 3.0) * k2 / c2**5. return [Lambda1, Lambda2]
def lambda_from_m(m): eos = lalsim.SimNeutronStarEOSByName("AP4") eos_fam = lalsim.CreateSimNeutronStarFamily(eos) if m < 10**15: m = m * lal.MSUN_SI k2 = lalsim.SimNeutronStarLoveNumberK2(m, eos_fam) r = lalsim.SimNeutronStarRadius(m, eos_fam) m = m * lal.G_SI / lal.C_SI**2 lam = 2. / (3 * lal.G_SI) * k2 * r**5 dimensionless_lam = lal.G_SI * lam * (1 / m)**5 return dimensionless_lam
def lal_inf_sd_gammas_mass_to_radius(fam, mass_m_sol): ''' Modified from LALInferenceSDGammasMasses2Lambdas: https://lscsoft.docs.ligo.org/lalsuite/lalinference/_l_a_l_inference_8c_source.html#l02364 ''' # calculate radius(m|eos) in km mass_kg = mass_m_sol * m_sol_kg rad = lalsim.SimNeutronStarRadius(mass_kg, fam) / 1.0e3 return rad
def calc_lambda_from_m(m, eos_fam): if m < 10**15: m = m * lal.MSUN_SI k2 = lalsim.SimNeutronStarLoveNumberK2(m, eos_fam) r = lalsim.SimNeutronStarRadius(m, eos_fam) m = m * lal.G_SI / lal.C_SI**2 lam = 2. / (3 * lal.G_SI) * k2 * r**5 dimensionless_lam = lal.G_SI * lam * (1 / m)**5 return dimensionless_lam
def lal_inf_sd_gammas_mass_to_lambda(fam, mass_m_sol): ''' Modified from LALInferenceSDGammasMasses2Lambdas: https://lscsoft.docs.ligo.org/lalsuite/lalinference/_l_a_l_inference_8c_source.html#l02364 ''' # calculate lambda(m|eos) mass_kg = mass_m_sol * m_sol_kg rad = lalsim.SimNeutronStarRadius(mass_kg, fam) love = lalsim.SimNeutronStarLoveNumberK2(mass_kg, fam) comp = big_g * mass_kg / (c**2) / rad return 2.0 / 3.0 * love / comp**5
def lal_inf_sd_gammas_mass_to_lambda(gammas, mass_m_sol): ''' Modified from LALInferenceSDGammasMasses2Lambdas: https://lscsoft.docs.ligo.org/lalsuite/lalinference/_l_a_l_inference_8c_source.html#l02364 ''' # create EOS & family eos = lalsim.SimNeutronStarEOS4ParameterSpectralDecomposition(*gammas) fam = lalsim.CreateSimNeutronStarFamily(eos) # calculate lambda(m|eos) mass_kg = mass_m_sol * m_sol_kg rad = lalsim.SimNeutronStarRadius(mass_kg, fam) love = lalsim.SimNeutronStarLoveNumberK2(mass_kg, fam) comp = big_g * mass_kg / (c**2) / rad return 2.0 / 3.0 * love / comp**5
def make_mr_lambda_lal(eos, n_bins=100): """ Construct mass-radius curve from EOS Based on modern code resources (https://git.ligo.org/publications/gw170817/bns-eos/blob/master/scripts/eos-params.py) which access low-level structures """ fam = lalsim.CreateSimNeutronStarFamily(eos) max_m = lalsim.SimNeutronStarMaximumMass(fam) / lal.MSUN_SI min_m = lalsim.SimNeutronStarFamMinimumMass(fam) / lal.MSUN_SI mgrid = np.linspace(min_m, max_m, n_bins) mrL_dat = np.zeros((n_bins, 3)) mrL_dat[:, 0] = mgrid for indx in np.arange(n_bins): mass_now = mgrid[indx] r = lalsim.SimNeutronStarRadius(mass_now * lal.MSUN_SI, fam) / 1000. mrL_dat[indx, 1] = r k = lalsim.SimNeutronStarLoveNumberK2(mass_now * lal.MSUN_SI, fam) c = mass_now * lal.MRSUN_SI / (r * 1000.) mrL_dat[indx, 2] = (2. / 3.) * k / c**5. return mrL_dat
samples =add_field(samples, [('m_max_msun',float)]) if opts.annotate_lambda and 'm1' in param_names: samples =add_field(samples, [('lambda1',float)]) samples =add_field(samples, [('lambda2',float)]) for indx in np.arange(npts): # Do not populate BBH entries if samples['eos_name'][indx]=='BBH': continue # Generate EOS eos_now = generate_eos_from_samples(samples, indx,format=opts.eos_format) # Fill fiducial mass samples['R_fiducial_km'][indx] = lalsim.SimNeutronStarRadius(opts.fiducial_mass*lal.MSUN_SI,eos_now.eos_fam)/1e3 # Fill maximum mass if opts.annotate_m_max: samples['m_max_msun'][indx] = eos_now.mMaxMsun # Fill lambda(m) values if opts.annotate_lambda and 'm1' in param_names: True # write format specifier : fmt = "" for param_name in samples.dtype.names: if param_name == 'eos_name': fmt += " %s " else: fmt += " %.18e "
eos_0 = eos_list[0] print("p2nuc missed by", eos_0.eval_baryon_density(p) - nuc_rho_si) ######################### for n, eos in enumerate(eos_list): # There has to be a better way to do this in the long run P2nucs.append( np.log10((find_pressure_of_density(2 * nuc_rho_si, eos)) / ccgs**2 * 10)) # SI -> cgs is x 10 P6nucs.append( np.log10( (find_pressure_of_density(6 * nuc_rho_si, eos)) / ccgs**2 * 10)) if max_masses[n] > 1.43: try: R1p4s.append( lalsim.SimNeutronStarRadius(M1p4s, eos.family) / 1000.) # P2nucs.append(np.log10(lalsim.SimNeutronStarCentralPressure(M1p4s, eos.family)/10/ccgs**2)) # In cgs) except: pass else: print("failed to produce a reasonable max mass") #Loves = np.array([lalsim.SimNeutronStarLoveNumberK2(M1p4s, eos.family) for eos in eos_list]) # Mass plot plt.hist(max_masses, bins=30) plt.xlabel("max_mass") plt.ylabel("frequency") plt.savefig("better_prior_masses.png")
def calc_radius(self, EOS, TOV, polytrope=False): """ """ if TOV not in ['Monica', 'Wolfgang', 'lalsim']: raise ValueError('You have provided a TOV ' 'for which we have no data ' 'and therefore cannot ' 'calculate the radius.') if EOS not in get_eos_list(TOV): raise ValueError('You have provided a EOS ' 'for which we have no data ' 'and therefore cannot ' 'calculate the radius.') if TOV == 'Monica': import gwemlightcurves.EOS.TOV.Monica.MonotonicSpline as ms import gwemlightcurves.EOS.TOV.Monica.eos_tools as et MassRadiusBaryMassTable = Table.read(find_executable(EOS + '_mr.dat'), format='ascii') radius_of_mass_const = ms.interpolate( MassRadiusBaryMassTable['mass'], MassRadiusBaryMassTable['radius']) # after obtaining the radius_of_mass constants we now can either take values directly from table or use pre calculated spline to extrapolate the values # also radius is in km in table. need to convert to SI (i.e. meters) self['r1'] = et.values_from_table( self['m1'], MassRadiusBaryMassTable['mass'], MassRadiusBaryMassTable['radius'], radius_of_mass_const) * 10**3 self['r2'] = et.values_from_table( self['m2'], MassRadiusBaryMassTable['mass'], MassRadiusBaryMassTable['radius'], radius_of_mass_const) * 10**3 elif TOV == 'Wolfgang': import gwemlightcurves.EOS.TOV.Monica.MonotonicSpline as ms import gwemlightcurves.EOS.TOV.Monica.eos_tools as et try: import lal G = lal.G_SI c = lal.C_SI msun = lal.MSUN_SI except: import astropy.units as u import astropy.constants as C G = C.G.value c = C.c.value msun = u.M_sun.to(u.kg) MassRadiusBaryMassTable = Table.read(find_executable(EOS + '.tidal.seq'), format='ascii') radius_of_mass_const = ms.interpolate( MassRadiusBaryMassTable['grav_mass'], MassRadiusBaryMassTable['Circumferential_radius']) unit_conversion = (msun * G / c**2) self['r1'] = et.values_from_table( self['m1'], MassRadiusBaryMassTable['grav_mass'], MassRadiusBaryMassTable['Circumferential_radius'], radius_of_mass_const) * unit_conversion self['r2'] = et.values_from_table( self['m2'], MassRadiusBaryMassTable['grav_mass'], MassRadiusBaryMassTable['Circumferential_radius'], radius_of_mass_const) * unit_conversion elif TOV == 'lalsim': import lalsimulation as lalsim if polytrope == True: try: import lal G = lal.G_SI c = lal.C_SI msun = lal.MSUN_SI except: import astropy.units as u import astropy.constants as C G = C.G.value c = C.c.value msun = u.M_sun.to(u.kg) ns_eos, eos_fam = construct_eos_from_polytrope(EOS) self['r1'] = lalsim.SimNeutronStarRadius( self['m1'] * msun, eos_fam) self['r2'] = lalsim.SimNeutronStarRadius( self['m2'] * msun, eos_fam) else: MassRadiusBaryMassTable = Table.read( find_executable(EOS + '_lalsim_mr.dat'), format='ascii') radius_of_mass_const = ms.interpolate( MassRadiusBaryMassTable['mass'], MassRadiusBaryMassTable['radius']) # after obtaining the radius_of_mass constants we now can either take values directly from table or use pre calculated spline to extrapolate the values # also radius is in km in table. need to convert to SI (i.e. meters) self['r1'] = et.values_from_table( self['m1'], MassRadiusBaryMassTable['mass'], MassRadiusBaryMassTable['radius'], radius_of_mass_const) * 10**3 self['r2'] = et.values_from_table( self['m2'], MassRadiusBaryMassTable['mass'], MassRadiusBaryMassTable['radius'], radius_of_mass_const) * 10**3 return self
def make_tidal_waveform(approx='TaylorT4', rate=4096, Lambda1=None, Lambda2=None, mass1=1.4, mass2=1.3, inclination=0, distance=100, eccentricity=0, meanPerAno=0, phiRef=0, f_min=30, f_ref=0, longAscNodes=0, s1x=0, s1y=0, s1z=0, s2x=0, s2y=0, s2z=0, eos=None, save=False): # Sanity check if (Lambda1 is None) and (Lambda2 is None) and (eos is None): # Assuming Lambdas to be zero is not provided print("Assuming tidal deformability is zero") print( "Use arguments Lambda1=, and Lambda2= to provide deformabilities") Lambda1 = 0.0 Lambda2 = 0.0 if eos: if Lambda1 or Lambda2: print( "Warning: Both eos and Lambda1 and/or Lambda2 has been provided" ) print("Ignoring Lambdas in favor of the eos") e = lalsim.SimNeutronStarEOSByName(eos) fam = lalsim.CreateSimNeutronStarFamily(e) max_mass = lalsim.SimNeutronStarMaximumMass(fam) / lal.MSUN_SI assert mass1 < max_mass, "mass1 greater than maximum mass allowed for the neutron star" assert mass2 < max_mass, "mass2 greater than the maximum mass allowed for the neutron star" r1 = lalsim.SimNeutronStarRadius(mass1 * lal.MSUN_SI, fam) k1 = lalsim.SimNeutronStarLoveNumberK2(mass1 * lal.MSUN_SI, fam) r2 = lalsim.SimNeutronStarRadius(mass2 * lal.MSUN_SI, fam) k2 = lalsim.SimNeutronStarLoveNumberK2(mass2 * lal.MSUN_SI, fam) c2 = mass2 * lal.MRSUN_SI / r2 c1 = mass1 * lal.MRSUN_SI / r1 Lambda1 = (2 / 3) * k1 / (c1**5) Lambda2 = (2 / 3) * k2 / (c2**5) mass1 = mass1 * lal.MSUN_SI mass2 = mass2 * lal.MSUN_SI distance = distance * 1e6 * lal.PC_SI deltaT = 1.0 / rate approximant = lalsim.GetApproximantFromString(approx) lal_pars = lal.CreateDict() lalsim.SimInspiralWaveformParamsInsertTidalLambda1(lal_pars, Lambda1) lalsim.SimInspiralWaveformParamsInsertTidalLambda2(lal_pars, Lambda2) hp, hc = lalsim.SimInspiralChooseTDWaveform(mass1, mass2, s1x=s1x, s1y=s1y, s1z=s1z, s2x=s2x, s2y=s2y, s2z=s2z, distance=distance, inclination=inclination, phiRef=phiRef, longAscNodes=longAscNodes, eccentricity=eccentricity, meanPerAno=meanPerAno, deltaT=deltaT, f_min=f_min, f_ref=f_ref, params=lal_pars, approximant=approximant) if save: plus_data = hp.data.data cross_data = hc.data.data tstart_p = hp.epoch.gpsSeconds + hp.epoch.gpsNanoSeconds * 1e-9 tstart_c = hc.epoch.gpsSeconds + hc.epoch.gpsNanoSeconds * 1e-9 tp = np.arange(tstart_p, 0, hp.deltaT) tp = tp[:len(hp.data.data)] tc = np.arange(tstart_c, 0, hc.deltaT) tc = tc[:len(hc.data.data)] output_plus = np.vstack((tp, plus_data)).T output_cross = np.vstack((tc, cross_data)).T np.savetxt("plus_polarization_data.txt", output_plus, fmt="%f\t%e") np.savetxt("cross_polarization_data.txt", output_cross, fmt="%f\t%e") return (hp, hc)
def make_mr_lambda(eos, use_lal=False): """ construct mass-radius curve from EOS DOES NOT YET WORK RELIABLY """ if use_lal: make_mr_lambda_lal(eos) fam = lalsim.CreateSimNeutronStarFamily(eos) r_cut = 40 # Some EOS we consider for PE purposes will have very large radius! #set p_nuc max # - start at a fiducial nuclear density # - not sure what these termination conditions are designed to do ... generally this pushes to 20 km # - generally this quantity is the least reliable p_nuc = 3. * 10**33 # consistent with examples fac_min = 0 r_fin = 0 while r_fin > r_cut + 8 or r_fin < r_cut: # Generally tries to converge to density corresponding to 20km radius try: answer = lalsim.SimNeutronStarTOVODEIntegrate( (10**fac_min) * p_nuc, eos) # r(SI), m(SI), lambda except: # If failure, backoff fac_min = -0.05 break r_fin = answer[0] r_fin = r_fin * 10**-3 # convert to SI # print "R: ",r_fin if r_fin < r_cut: fac_min -= 0.05 elif r_fin > r_cut + 8: fac_min += 0.01 answer = lalsim.SimNeutronStarTOVODEIntegrate((10**fac_min) * p_nuc, eos) # r(SI), m(SI), lambda m_min = answer[1] / lal.MSUN_SI #set p_nuc min # - tries to converge to central pressure corresponding to maximum NS mass # - very frustrating...this data is embedded in the C code fac_max = 1.6 r_fin = 20. m_ref = lalsim.SimNeutronStarMaximumMass(fam) / lal.MSUN_SI r_ref = lalsim.SimNeutronStarRadius(lalsim.SimNeutronStarMaximumMass(fam), fam) / (10**3) answer = None while r_fin > r_ref or r_fin < 7: #print "Trying min:" # print "p_c: ",(10**fac_max)*p_nuc try: answer = lalsim.SimNeutronStarTOVODEIntegrate( (10**fac_max) * p_nuc, eos) if answer[0] * 10**-3 < r_ref: break except: fac_max -= 0.05 working = False while working == False: try: answer_tmp = lalsim.SimNeutronStarTOVODEIntegrate( (10**fac_max) * p_nuc, eos) working = True except: fac_max -= 0.05 break #print lalsim.SimNeutronStarTOVODEIntegrate((10**fac_max)*p_nuc, eos) r_fin = answer[0] / 10**3 # convert to km if rosDebug: print("R: ", r_fin, r_ref, " M: ", answer[1] / lal.MSUN_SI, m_ref, m_min) # should converge to maximum mass if r_fin > 8: fac_max += 0.05 if r_fin < 6: fac_max -= 0.01 # print 10**fac_max #generate mass-radius curve npts_out = 1000 scale = np.logspace(fac_min, fac_max, npts_out) mr_array = np.zeros((npts_out, 3)) for s, i in zip(scale, range(0, len(scale))): # print s mr_array[i, :] = lalsim.SimNeutronStarTOVODEIntegrate(s * p_nuc, eos) mr_array[:, 0] = mr_array[:, 0] / 10**3 mr_array[:, 1] = mr_array[:, 1] / lal.MSUN_SI mr_array[:, 2] = 2. / (3 * lal.G_SI) * mr_array[:, 2] * (mr_array[:, 0] * 10**3)**5 mr_array[:, 2] = lal.G_SI * mr_array[:, 2] * ( 1 / (mr_array[:, 1] * lal.MSUN_SI * lal.G_SI / lal.C_SI**2))**5 # print mr_array[:,1] return mr_array
def __init__(self, sim, eos="WFF1"): # Load if from sim inspiral table if isinstance(sim, lsctables.SimInspiral): self.sim = sim # Set NS self.m_ns = sim.mass2 self.s_ns_x = sim.spin2x self.s_ns_y = sim.spin2y self.s_ns_z = sim.spin2z # Set BH self.m_bh = sim.mass1 self.s_bh_x = sim.spin1x self.s_bh_y = sim.spin1y self.s_bh_z = sim.spin1z self.s_bh = np.sqrt(self.s_bh_x**2 + self.s_bh_y**2 + self.s_bh_z**2) self.s_bh_tilt = np.arccos(self.s_bh_z / self.s_bh) # Load if from LALInference posterior samples elif isinstance(sim, np.void): # Set NS self.m_ns = sim["m2"] # Set BH self.m_bh = sim["m1"] self.s_bh = sim["a1"] self.s_bh_tilt = sim["tilt1"] self.s_bh_z = self.s_bh * np.cos(self.s_bh_tilt) elif isinstance(sim, dict): # Set NS self.m_ns = sim['mass2'] self.s_ns_x = sim['spin2x'] self.s_ns_y = sim['spin2y'] self.s_ns_z = sim['spin2z'] # Set BH self.m_bh = sim['mass1'] self.s_bh_x = sim['spin1x'] self.s_bh_y = sim['spin1y'] self.s_bh_z = sim['spin1z'] self.s_bh = np.sqrt(self.s_bh_x**2 + self.s_bh_y**2 + self.s_bh_z**2) self.s_bh_tilt = np.arccos(self.s_bh_z / self.s_bh) else: raise NotImplementedError( "Input of type {} not yet supported!".format(type(sim))) #print("BH = {:.2f}, NS = {:.2f}".format(self.m_bh, self.m_ns)) if eos in list(lalsim.SimNeutronStarEOSNames): eos_obj = lalsim.SimNeutronStarEOSByName(eos) self.eos = lalsim.CreateSimNeutronStarFamily(eos_obj) # Get limiting NS masses and ensure valid input m_max = lalsim.SimNeutronStarMaximumMass(self.eos) self.m_max = m_max / lal.MSUN_SI assert (self.m_ns < self.m_max) m_min = lalsim.SimNeutronStarFamMinimumMass(self.eos) self.m_min = m_min / lal.MSUN_SI assert (self.m_ns > self.m_min) # Get NS radius self.r_ns = lalsim.SimNeutronStarRadius(self.m_ns * lal.MSUN_SI, self.eos) # NS tidal deformability self.compactness = self.get_compactness() self.love = lalsim.SimNeutronStarLoveNumberK2( self.m_ns * lal.MSUN_SI, self.eos) self.lamb = 2. / 3. * self.love * self.compactness**-5 else: eos_func, mr_func, self.m_max, self.m_min = choose_func(eos) assert (self.m_ns < self.m_max) assert (self.m_ns > self.m_min) self.lamb = eos_func(self.m_ns) self.r_ns = mr_func(self.m_ns) * 1e3 self.compactness = self.get_compactness()
logp1[i] - 1, gamma1[i], gamma2[i], gamma3[i]) if model == 'spectral': eos = lalsim.SimNeutronStarEOSSpectralDecomposition_for_plot( sd_gamma0[i], sd_gamma1[i], sd_gamma2[i], sd_gamma3[i], spec_size) assert eos is not None fam = lalsim.CreateSimNeutronStarFamily(eos) max_m = lalsim.SimNeutronStarMaximumMass(fam) / lal.MSUN_SI # [M_sun] min_m = lalsim.SimNeutronStarFamMinimumMass( fam) / lal.MSUN_SI # [M_sun] # Find NS properties for each EOS sample max_mass.append(max_m) # [M_sun] m1_d.append(mass1[i]) # [M_sun] m1_s.append(m1_d[i] / (1. + red_z)) # [M_sun] r1.append( lalsim.SimNeutronStarRadius(m1_s[i] * lal.MSUN_SI, fam) / 1000.) # [km] k1.append(lalsim.SimNeutronStarLoveNumberK2(m1_s[i] * lal.MSUN_SI, fam)) # [ ] c1.append(m1_s[i] * lal.MRSUN_SI / (r1[i] * 1000.)) # [ ] l1.append((2. / 3.) * k1[i] / c1[i]**5.) # [ ] pc1.append( lalsim.SimNeutronStarCentralPressure(m1_s[i] * lal.MSUN_SI, fam) * 10.) # [dyne/cm^2] m2_d.append(mass2[i]) # [M_sun] m2_s.append(m2_d[i] / (1. + red_z)) # [M_sun] r2.append( lalsim.SimNeutronStarRadius(m2_s[i] * lal.MSUN_SI, fam) / 1000.) # [km] k2.append(lalsim.SimNeutronStarLoveNumberK2(m2_s[i] * lal.MSUN_SI, fam)) # [ ]