def test_igmDM(): DM = igm.average_DM(1.) # Value and unit assert DM.unit == u.pc / u.cm**3 assert np.isclose(DM.value, 917.6353186402, rtol=0.001) # Cumulative DM_cum, _ = igm.average_DM(1., cumul=True) assert DM == DM_cum[-1] # Cross through HeII reionization DM4 = igm.average_DM(4.) assert np.isclose(DM4.value, 3527.87768558123, rtol=0.001)
def test_igmDM(): DM = igm.average_DM(1.) # Value and unit assert DM.unit == u.pc / u.cm**3 assert np.isclose(DM.value, 923.074, rtol=0.001) # Cumulative DM_cum, _ = igm.average_DM(1., cumul=True) assert DM == DM_cum[-1] # Cross through HeII reionization DM4 = igm.average_DM(4.) assert np.isclose(DM4.value, 3542.598, rtol=0.001)
def test_igmDM_varyH0(): DM = igm.average_DM(1., cosmo=Planck15) # New cosmology cosmo2 = FlatLambdaCDM(H0=Planck15.H0.value * 2, Ob0=Planck15.Ob0, Om0=Planck15.Om0, Neff=Planck15.Neff, Tcmb0=2.725) DM2 = igm.average_DM(1., cosmo=cosmo2) # Test assert DM2 > DM * 2 # Not sure why it is so much higher
def grid_P_DMcosmic_z(beta=3., F=0.31, zvals=None, DM_cosmics=None, cosmo=defs.frb_cosmo): """ Generate a grid of P(DM_cosmic|z) Args: beta (float, optional): sigma_DM_cosmic parameter F (float, optional): Feedback parameter (higher F means weaker feedback) zvals (np.ndarray, optional): Redshifts for the grid DMcosmic (np.ndarray, optional): DMs for the grid cosmo (optional): Cosmology Returns: tuple: z, DM_cosmic, P(DM_cosmic|z) """ # Check if not np.isclose(beta, 3.): raise IOError("Not prepared for this beta value (yet)") # Load # sigma_DM f_C0_3 = cosmic.grab_C0_spline() # Grid if zvals is None: zvals = np.linspace(0., 2., 200) if DM_cosmics is None: DM_cosmics = np.linspace(1., 5000., 1000) PDF_grid = np.zeros((DM_cosmics.size, zvals.size)) # Loop for kk, zval in enumerate(zvals): # z=0 if zval == 0: PDF_grid[0, 0] = 1. continue avgDM = igm.average_DM(zval, cosmo=cosmo).value # Params sigma = F / np.sqrt(zval) C0 = f_C0_3(sigma) # Delta Delta = DM_cosmics / avgDM # PDF time PDF = cosmic.DMcosmic_PDF(Delta, C0, sigma) # Normalize PDF_grid[:, kk] = PDF / np.sum(PDF) # Return return zvals, DM_cosmics, PDF_grid
Delta_values = np.linspace(1./400., 20., 20000)# / 400. # Fiducial DM_MWhalo = 50. # Fixed value for Macquart+20 # Init as blank frbs = [] frb_DMs = None #np.array([frb.DM.value-frb.DMISM.value for frb in frbs]) frb_zs = None #np.array([frb.z for frb in frbs]) DM_FRBp_grid = None DMhost_grid = None #np.outer(DM_values, (1+z_FRB)) # Host rest-frame DMs DMvalues_grid = None # np.outer(DM_values, np.ones(DM_FRBp.size)) Deltavalues_grid = None #np.outer(Delta_values, np.ones_like(C0)), # # DM Cosmic DM_cosmic, zeval = igm.average_DM(1., cosmo=defs.frb_cosmo, cumul=True) spl_DMc = IUS(zeval, DM_cosmic.value) cosmo_ObH0 = defs.frb_cosmo.Ob0 * defs.frb_cosmo.H0.value cosmo_Obh70 = defs.frb_cosmo.Ob0 * (defs.frb_cosmo.H0.value/70.) # Load splines spl_sigma = cosmic.grab_sigma_spline() f_C0_3 = cosmic.grab_C0_spline() # Parameters def grab_parmdict(tight_ObH=False): """ Generate the parameter dict for the MCMC run Args: tight_ObH (bool, optional): [description]. Defaults to False.
def estimate_dm_cosmic(self): if not frb_installed: raise ImportError("FRB is not installed.") return igm.average_DM(self.host_galaxy.z, cosmo=cosmo.Planck18)
def fig_mag_vs_DM(outfile='fig_mag_vs_DM.png'): """ mini Maquart relation Args: outfile: Returns: """ set_mplrc() # Load f_mL f_mL = analysis.load_f_mL() # Init prior prior = associate_defs.adopted.copy() # Plot plt.figure(figsize=(8, 5)) gs = gridspec.GridSpec(1, 1) cm = plt.get_cmap('jet') # Bayesian + parse frbA_tbl, model_mags, model_theta, max_PMix = analysis.run(prior) # Colors N = len(frbA_tbl) + 1 plt.rcParams["axes.prop_cycle"] = plt.cycler("color", cm(np.linspace(0, 1, N))) # Plot -- must come after colors ax = plt.subplot(gs[0]) # Plot em Pmin = 0.01 unit_size = 150. order = [0, 1, 6, 3, 2, 4, 5, 7, 8, 9, 10, 11, 12] DMcosmic = [ frb_row.frbA.frb.DM.value - frb_row.frbA.frb.DMISM.value - 100 for _, frb_row in frbA_tbl.iterrows() ] order = np.argsort(DMcosmic) #for _, frb_row in frbA_tbl.iterrows(): for ss in order: # Restrict to candiates with min frb_row = frbA_tbl.iloc[ss] ok_c = frb_row.frbA.candidates.P_Ox > Pmin N_c = np.sum(ok_c) # Scatter plot em ax.scatter( [frb_row.frbA.frb.DM.value - frb_row.frbA.frb.DMISM.value - 100] * N_c, frb_row.frbA.candidates[ok_c][frb_row.frbA.filter], label=frb_row.frb, edgecolor='darkslategrey', marker='o', s=unit_size * frb_row.frbA.candidates[ok_c].P_Ox, ) # Fiducial relation L_Lstar = 0.270 # Grabbed from PL numL = int(np.round(1. / L_Lstar)) log10_L_Lstar = np.log10(L_Lstar) std_log10_L_Lstar = 0.47 # Grabbed from fig_PL # Load up DM_cosmic dm_cosmic, z = igm.average_DM(1., cumul=True) f_DMz = interp1d(z, dm_cosmic.value) zval = np.linspace(0.02, 1., 100) DMs = f_DMz(zval) mLstar = f_mL(zval) m_FRB = mLstar - 2.5 * log10_L_Lstar ax.plot(DMs, m_FRB, 'k-', label=r'$L=L*/${}'.format(numL)) # Label me ax.set_xlabel( r'DM$_{\rm cosmic} \equiv$ DM$_{\rm FRB}$ - DM$_{\rm ISM}$ - 100') ax.set_ylabel(r'$m_r$') #ax.xaxis.set_major_locator(plt.MultipleLocator(1.)) #ax.xaxis.set_major_formatter(FormatStrFormatter(r'$%.3f$')) ax.set_xlim(0., 800.) # Legend legend = ax.legend(loc='lower right', scatterpoints=1, borderpad=0.0, handletextpad=handletextpad, fontsize=10.) # Font size set_fontsize(ax, 15.) # End plt.tight_layout(pad=0.2, h_pad=0., w_pad=0.1) print('Writing {:s}'.format(outfile)) kwargs = {} if 'png' in outfile: kwargs['dpi'] = 700 plt.savefig(outfile, **kwargs) plt.close()
def sub_cartoon(ax1, ax2, coord, zFRB, halos=False, host_DM=50., ymax=None, IGM_only=True, smin=0.1, cosmo=None, show_M31=None, fg_halos=None, dsmx=0.05, FRB_DM=None, yscl = 0.97): """ Cartoon of DM cumulative Plot of increasing DM from Earth to the FRB Args: ax1 (matplotlib.Axis): First axis. Used for Milky Way and local group ax2 (matplotlib.Axis): Second axis. Used for Cosmic and Host coord (astropy.coord.SkyCoord): Coordinate of the FRB used with ne2001 zFRB (float): Redshift of the FRB halos (?, optional): Not implemented! host_DM (float): DM to use for the Host ymax (tuple or list): ymin, ymax values for the y-axis IGM_only (bool, optional): Use only the IGM for DM_Cosmic, i.e. ignore the presumed average halo contribution show_M31 (bool, optional): Include M31 in the calculation? NOT IMPLEMENTED RIGHT NOW fg_halos (dict or Table): Used to add to DM_IGM Keys must include 'z' 'DM' 'lbl' smin (float, optional): Minimum value in axis2 (Gpc) dsmx (float, optional): Padding on the x-axis; Gpc Allows for host. Set to 0 to ignore host FRB_DM (float): Observed value; sets ymax = FRB_DM+50 yscl (float, optional): Controls placement of labels cosmo (astropy.cosmology, optional): Defaults to Planck15 """ if cosmo is None: cosmo = Planck15 if halos: # NOT READY FOR THIS embed() gcoord = coord.transform_to('galactic') l, b = gcoord.l.value, gcoord.b.value ds = [] # kpc DM_cumul = [] # ISM ne = density.ElectronDensity() # **PARAMS) for ss in np.linspace(2., 4, 5): # log pc idd = 10. ** ss / 1e3 # kpc iDM = ne.DM(l, b, idd) # Append ds.append(idd) # kpc DM_cumul.append(iDM.value) # print(idd, iDM) max_ISM = DM_cumul[-1] # MW Mhalo = np.log10(1.5e12) # Boylan-Kolchin et al. 2013 f_hot = 0.75 # Allows for disk + ISM c = 7.7 mnfw_2 = ModifiedNFW(log_Mhalo=Mhalo, f_hot=f_hot, y0=2, alpha=2, c=c) # Zero out inner 10kpc mnfw_2.zero_inner_ne = 10. # kpc params = dict(F=1., e_density=1.) model_ne = density.NEobject(mnfw_2.ne, **params) for ss in np.linspace(1., np.log10(mnfw_2.r200.value), 5): # log kpc idd = 10. ** ss # kpc iDM = model_ne.DM(l, b, idd).value # Add it in if idd == ds[-1]: DM_cumul[-1] = DM_cumul[-1] + iDM else: ds.append(idd) DM_cumul.append(max_ISM + iDM) DM_ISM_Halo = DM_cumul[-1] if show_M31: raise NotImplemented # M31 m31 = M31() a,c =1,0 x0, y0 = m31.distance.to('kpc').value, 0. # kpc (Riess, A.G., Fliri, J., & Valls - Gabaud, D. 2012, ApJ, 745, 156) sep = m31.coord.separation(coord) atan = np.arctan(sep.radian) b = -1 * a / atan M31_Rperp = np.abs(a * x0 + b * y0 + c) / np.sqrt(a ** 2 + b ** 2) # kpc zval, M31_DM_cumul = m31.Ne_Rperp(M31_Rperp * u.kpc, rmax=1., cumul=True) # Add em in ds += (zval+x0).tolist() DM_cumul += (M31_DM_cumul+DM_ISM_Halo).tolist() #DM_LG = 0. DM_LG = DM_cumul[-1] # IGM z0 = z_at_value(cosmo.comoving_distance, 1 * units.Mpc) zvals = np.linspace(z0, 0.5, 50) dz_vals = zvals[1] - zvals[0] # DM_cosmic_cumul, zeval = frb_igm.average_DM(zvals[-1], cumul=True) dzeval = zeval[1] - zeval[0] dDM_cosmic = DM_cosmic_cumul - np.roll(DM_cosmic_cumul, 1) dDM_cosmic[0] = dDM_cosmic[1] # DM_interp = IUS(zeval, dDM_cosmic) dDM_cosm = DM_interp(zvals) * dz_vals / dzeval sub_DM_cosm = np.cumsum(dDM_cosm) f_cosm = IUS(zvals, sub_DM_cosm) zvals2 = np.linspace(z0, zFRB, 1000) DM_cosmic = f_cosm(zvals2) # Ignore halos? if IGM_only: # fhalos = frb_halos.frac_in_halos(zvals, 3e10, 1e16, rmax=1.) fIGM = 1. - fhalos # dDM_IGM = DM_interp(zvals) * fIGM * dz_vals / dzeval sub_DM_IGM = np.cumsum(dDM_IGM) f_IGM = IUS(zvals, sub_DM_IGM) DM_IGM = f_IGM(zvals2) # DM_cosmic = DM_IGM.copy() # Halos at last if fg_halos is not None: for z, halo_DM, lbl in zip(fg_halos['z'], fg_halos['DM'], fg_halos['lbl']): iz = np.argmin(np.abs(zvals2 - z)) DM_cosmic[iz:] += halo_DM # Label d = cosmo.comoving_distance(z) ax1.text(d.to('Gpc').value, DM_cosmic[iz], lbl, color='black', fontsize=13, ha='left', va='top') Dc = cosmo.comoving_distance(zvals2).to('kpc') ds += Dc.value.tolist() DM_cumul += (DM_cosmic + DM_LG).tolist() # Host if host_DM > 0.: ds.append(ds[-1]) DM_cumul.append(DM_cumul[-1] + host_DM) # Plot the DM curve ax1.plot(ds, DM_cumul, 'k') # max_y = np.max(DM_cumul) if FRB_DM is not None: ymax = FRB_DM + 50. if ymax is not None: max_y = ymax # Shade me lsz = 14. ax1.fill_between((0.1, 10.), 0, max_y, color='green', alpha=0.4) # ISM ax1.text(0.15, max_y * yscl, r'\textbf{Galactic}'+'\n'+r'\textbf{ISM}', color='black', fontsize=lsz, ha='left', va='top') ax1.fill_between((10., mnfw_2.r200.value), 0, max_y, color='blue', alpha=0.4) # Galactic Halo ax1.text(12., max_y * yscl, r'\textbf{Galactic}'+'\n'+r'\textbf{Halo}', color='black', fontsize=lsz, ha='left', va='top') if show_M31: ax1.fill_between((mnfw_2.r200.value, 2e3), 0, max_y, color='red', alpha=0.4) # Galactic Halo ax1.text(300., max_y * yscl, r'\texgbf{M31}', color='black', fontsize=lsz, ha='left', va='top') ax1.set_xscale("log", nonposx='clip') # ax.set_yscale("log", nonposy='clip') if show_M31: ax1.set_xlim(0.1, 2e3) # kpc else: ax1.set_xlim(0.1, mnfw_2.r200.value) # kpc ax1.set_ylim(0., max_y) ax1.spines['right'].set_visible(False) ax1.set_xlabel(r'\textbf{Distance (kpc)}') ax1.set_ylabel(r'\textbf{Cumulative DM (pc cm$^{-3}$)}') # IGM Gds = np.array(ds) / 1e6 ax2.plot(Gds, DM_cumul, 'k') ax2.spines['left'].set_visible(False) ax2.yaxis.tick_right() ax2.tick_params(labelright='off') ax2.minorticks_on() ax2.set_xlabel(r'\textbf{Distance (Gpc)}') smax = cosmo.comoving_distance(zFRB).to('Gpc').value #ax2.fill_between((0.1, smax-dsmx), 0, max_y, color='gray', alpha=0.4) # Galactic Halo ax2.fill_between((smin, smax-dsmx), 0, max_y, color='gray', alpha=0.4) # Cosmic ilbl = r'\textbf{Cosmic}' ax2.text(0.2, max_y * yscl, ilbl, color='black', fontsize=lsz, ha='left', va='top') # Host if host_DM > 0.: ax2.fill_between((smax-dsmx, smax+dsmx), 0, max_y, color='red', alpha=0.4) # Host ax2.set_xlim(smin, smax+dsmx) # Gpc else: ax2.set_xlim(smin, smax) # Gpc if FRB_DM is not None: ax1.axhline(y=FRB_DM, ls='--', color='black', lw=3) ax2.axhline(y=FRB_DM, ls='--', color='black', lw=3)
def fig_cosmic(frbs, clrs=None, outfile=None, multi_model=False, no_curves=False, widen=False, show_nuisance=False, ax=None, show_sigmaDM=False, cl=(16,84), beta=3., gold_only=True, gold_frbs=None): """ Args: frbs (list): list of FRB objects clrs (list, optional): outfile (str, optional): multi_model (deprecated): no_curves (bool, optional): If True, just show the data widen (bool, optional): If True, make the plot wide show_nuisance (bool, optional): if True, add a label giving the Nuiscance value show_sigmaDM (bool, optional): If True, show a model estimate of the scatter in the DM relation cl (tuple, optional): Confidence limits for the scatter beta (float, optional): Parameter to the DM scatter estimation gold_only (bool, optional): If True, limit to the gold standard sample gold_frbs (list, optional): List of gold standard FRBs ax (matplotlib.Axis, optional): Use this axis instead of creating one Returns: """ # Init if gold_frbs is None: gold_frbs = cosmic.gold_frbs # Plotting ff_utils.set_mplrc() bias_clr = 'darkgray' # Start the plot if ax is None: if widen: fig = plt.figure(figsize=(12, 8)) else: fig = plt.figure(figsize=(8, 8)) plt.clf() ax = plt.gca() # DM_cosmic from cosmology zmax = 0.75 DM_cosmic, zeval = frb_igm.average_DM(zmax, cumul=True) DMc_spl = IUS(zeval, DM_cosmic) if not no_curves: #ax.plot(zeval, DM_cosmic, 'k-', label=r'DM$_{\rm cosmic} (z) \;\; [\rm Planck15]$') ax.plot(zeval, DM_cosmic, 'k-', label='Planck15') if multi_model: # Change Omega_b cosmo_highOb = FlatLambdaCDM(Ob0=Planck15.Ob0*1.2, Om0=Planck15.Om0, H0=Planck15.H0) DM_cosmic_high, zeval_high = frb_igm.average_DM(zmax, cumul=True, cosmo=cosmo_highOb) ax.plot(zeval_high, DM_cosmic_high, '--', color='gray', label=r'DM$_{\rm cosmic} (z) \;\; [1.2 \times \Omega_b]$') # Change H0 cosmo_lowH0 = FlatLambdaCDM(Ob0=Planck15.Ob0, Om0=Planck15.Om0, H0=Planck15.H0/1.2) DM_cosmic_lowH0, zeval_lowH0 = frb_igm.average_DM(zmax, cumul=True, cosmo=cosmo_lowH0) ax.plot(zeval_lowH0, DM_cosmic_lowH0, ':', color='gray', label=r'DM$_{\rm cosmic} (z) \;\; [H_0/1.2]$') if show_sigmaDM: #f_C0 = frb_cosmology.build_C0_spline() f_C0_3 = cosmic.grab_C0_spline(beta=3.) # Updated F = 0.2 nstep=50 sigma_DM = F * zeval**(-0.5) #* DM_cosmic.value sub_sigma_DM = sigma_DM[::nstep] sub_z = zeval[::nstep] sub_DM = DM_cosmic.value[::nstep] # Loop me sigmas, C0s, sigma_lo, sigma_hi = [], [], [], [] for kk, isigma in enumerate(sub_sigma_DM): #res = frb_cosmology.minimize_scalar(frb_cosmology.deviate2, args=(f_C0, isigma)) #sigmas.append(res.x) sigmas.append(isigma) C0s.append(float(f_C0_3(isigma))) # PDF PDF = cosmic.DMcosmic_PDF(cosmic.Delta_values, C0s[-1], sigma=sigmas[-1], beta=beta) cumsum = np.cumsum(PDF) / np.sum(PDF) #if sub_DM[kk] > 200.: # embed(header='131') # DO it DM = cosmic.Delta_values * sub_DM[kk] sigma_lo.append(DM[np.argmin(np.abs(cumsum-cl[0]/100))]) sigma_hi.append(DM[np.argmin(np.abs(cumsum-cl[1]/100))]) # Plot ax.fill_between(sub_z, sigma_lo, sigma_hi, # DM_cosmic.value-sigma_DM, DM_cosmic.value+sigma_DM, color='gray', alpha=0.3) # Do each FRB DM_subs = [] for ifrb in frbs: DM_sub = ifrb.DM - ifrb.DMISM DM_subs.append(DM_sub.value) DM_subs = np.array(DM_subs) # chi2 DMs_MW_host = np.linspace(30., 100., 100) zs = np.array([ifrb.z for ifrb in frbs]) DM_theory = DMc_spl(zs) chi2 = np.zeros_like(DMs_MW_host) for kk,DM_MW_host in enumerate(DMs_MW_host): chi2[kk] = np.sum(((DM_subs-DM_MW_host)-DM_theory)**2) imin = np.argmin(chi2) DM_MW_host_chisq = DMs_MW_host[imin] print("DM_nuisance = {}".format(DM_MW_host)) # MW + Host term def DM_MW_host(z, min_chisq=False): if min_chisq: return DM_MW_host_chisq else: return 50. + 50./(1+z) # Gold FRBs for kk,ifrb in enumerate(frbs): if ifrb.frb_name not in gold_frbs: continue if clrs is not None: clr = clrs[kk] else: clr = None ax.scatter([ifrb.z], [DM_subs[kk]-DM_MW_host(ifrb.z)], label=ifrb.frb_name, marker='s', s=90, color=clr) # ################################ # Other FRBs s_other = 90 if not gold_only: labeled = False for kk, ifrb in enumerate(frbs): if ifrb.frb_name in gold_frbs: continue if not labeled: lbl = "Others" labeled = True else: lbl = None ax.scatter([ifrb.z], [ifrb.DM.value - ifrb.DMISM.value - DM_MW_host(ifrb.z)], label=lbl, marker='o', s=s_other, color=bias_clr) legend = ax.legend(loc='upper left', scatterpoints=1, borderpad=0.2, handletextpad=0.3, fontsize=19) ax.set_xlim(0, 0.7) ax.set_ylim(0, 1000.) #ax.set_xlabel(r'$z_{\rm FRB}$', fontname='DejaVu Sans') ax.set_xlabel(r'$z_{\rm FRB}$', fontname='DejaVu Sans') ax.set_ylabel(r'$\rm DM_{cosmic} \; (pc \, cm^{-3})$', fontname='DejaVu Sans') # if show_nuisance: ax.text(0.05, 0.60, r'$\rm DM_{MW,halo} + DM_{host} = $'+' {:02d} pc '.format(int(DM_MW_host))+r'cm$^{-3}$', transform=ax.transAxes, fontsize=23, ha='left', color='black') ff_utils.set_fontsize(ax, 23.) # Layout and save if outfile is not None: plt.tight_layout(pad=0.2,h_pad=0.1,w_pad=0.1) plt.savefig(outfile, dpi=400) print('Wrote {:s}'.format(outfile)) plt.close() else: return ax
def simulate_frb_dm(frb_data, z_stepsize=10**-4, z_max=3, dm_min=0, dm_max=3000, dm_stepsize=10**-2, save_to_path=None): """ Simulate DM_FRB by constructing PDFs for DM_cosmic, DM_host and DM_halo. Please check your frbcat_df matches the template used here. Change the halo and host distributions as you feel appropriate. Arguments: transient_data (str): Path to data (in .csv format). z_stepsize (float, optional): Redshift stepsize. Default=10**-4. z_max (int, optimal): Maximum redshift value. Default=3. dm_min (int, optional): Minimum value of DM grid. Default=-10. dm_max (int, optional): Minimum value of DM grid. Default=5000. dm_stepsize (float, optional): DM_grid stepsize. Default=10**-2. save_to_path (str, optional): To save data outputs (as .npy), specify path. Default=None. Outputs: dm_grid (array): DM grid dm_frb_sim (array): PDF of DM_FRB """ # Estimate redshift distribution from observed FRB DMs (corrected for ISM) logging.info('Estimating redshift distribution...') frbcat_df = pd.read_csv(frb_data) dm_frb = np.array(frbcat_df['deltaDM'])*units.pc/units.cm**3 z_grid = np.arange(0,z_max,z_stepsize) z = [] for i in range(len(dm_frb)): z_ = igm.z_from_DM(dm_frb[i], corr_nuisance=False) z = np.append(z,z_) # Kernel density estimation z_func_ = make_kde_funtion(grid=z_grid, draws=z, min_bandwidth=0.01, max_bandwidth=0.5, bandwidth_stepsize=0.01, cv=5, kernel='gaussian') z_func = z_func_/np.sum(z_func_) z = make_pdf(distribution=z_func,num_of_draws=rv_amount,grid=z_grid,stepsize=z_stepsize) z_draws = z[0] # Calculate average cosmic DM logging.info('Estimating cosmic DM...') dm_ave_fn = igm.average_DM(z_max, cumul=True, neval=rv_amount+1, mu=1.3) dm_ave_ = dm_ave_fn[0].value z_ave = dm_ave_fn[1] dm_int_ave = sp.interpolate.CubicSpline(z_ave,dm_ave_) dm_ave = np.sort(dm_int_ave(z_draws)) # Find cosmic DM F = 0.2 sigma_dm = np.minimum(F*z_draws**(-0.5),0.5) sigma_dm = [i for i in sigma_dm if i<0.5] sigma_gauss = 1 rand_draws_gauss = np.random.normal(loc=0, scale=sigma_gauss, size=rv_amount) rand_draws_gauss = [i for i in rand_draws_gauss if i>-sigma_gauss and i<sigma_gauss] sigma_dm = random.sample(sigma_dm,len(rand_draws_gauss)) dm_ave = np.array(random.sample(list(dm_ave),len(rand_draws_gauss))) dm_cos = dm_ave + rand_draws_gauss*dm_ave*sigma_dm dm_cos = [i for i in dm_cos if i > 0] # Estimate halo logging.info('Adding MW halo and host...') dm_halo = 30. #some assigned MW halo DM # Host DM - adjust this to your prefered (estimated) host DM mu_host = 40. sigma_host = 0.5 dm_host = lognorm(s=sigma_host, loc=-4, scale=mu_host).rvs(size=len(dm_cos)) dm_host = np.random.normal(mu_host, sigma_host, len(dm_cos)) dm_host = [i for i in dm_host if i > 0] dm_cos = np.array(random.sample(list(dm_cos),len(dm_host))) dm_frb_sim = np.sort(dm_cos)+dm_halo+np.sort(dm_host) dm_grid = np.arange(dm_min,dm_max,dm_stepsize) if save_to_path==None: pass else: np.save(save_to_path+'/dm_frb_sim_gauss.npy', dm_frb_sim) np.save(save_to_path+'/dm_grid.npy', dm_grid) logging.info('Data saved to '+save_to_path) return dm_grid, dm_frb_sim