def gen_dist(self): """Generate distances.""" # Cosmology calculations r = go.Redshift(self.z_max, H_0=self.H_0, W_m=self.W_m, W_v=self.W_v) self.dist_co_max = r.dist_co() self.vol_co_max = r.vol_co() # Ensure precalculations are done if necessary pc.DistanceTable(H_0=self.H_0, W_m=self.W_m, W_v=self.W_v) # Set up number density n_den = NumberDensity(model=self.n_model, z_max=self.z_max, alpha=self.alpha, H_0=self.H_0, W_m=self.W_m, W_v=self.W_v).draw frbs = self.frbs # Draw from number density frbs.z, frbs.dist_co = n_den(self.n_gen)
def import_frbcat(): """Import frbcat.""" cat = Frbcat(frbpoppy=False) cat.frbpoppify() cat.filter(one_offs=True, repeaters=True, repeat_bursts=False) df = cat.df # Remove Pushichino events df = df[~df.telescope.str.startswith('pushchino')] db = pd.DataFrame() dm_igm = df['dm'] - df['dm_mw'] db['z'] = dm_igm / 950 db['dist_co'] = go.Redshift(db['z']).dist_co() * 1e6 # Gpc -> kpc db['pseudo_lum'] = (df.fluence / df.w_eff) * db.dist_co**2 # Observing bandwidth db['bw'] = df['bandwidth'] # MHz # Pulse width db['w_eff'] = df['w_eff'] * 1e-3 # ms -> s # Object type db['type'] = df['type'] return db
def create_table(self): """Create a lookup table for distances.""" m = [ 'Creating a distance table', ' - Only needs to happen once', ' - May take up to 2m on a single core' ] for n in m: pprint(n) # Connect to database conn = sqlite3.connect(self.file_name) c = conn.cursor() H_0 = self.H_0 W_m = self.W_m W_v = self.W_v W_k = 1.0 - W_m - W_v # Omega curvature if W_k != 0.0: pprint('Careful - Your cosmological parameters do not sum to 1.0') zs = np.arange(0, self.z_max + self.step, self.step) # Create database t = 'real' par = f'(z {t}, dist {t}, vol {t}, dvol {t}, cdf_sfr {t}, cdf_smd {t})' s = f'create table distances {par}' c.execute(s) results = [] pprint(' - Calculating parameters at various redshifts') conv = go.Redshift(zs, H_0=H_0, W_m=W_m, W_v=W_v) dists = conv.dist_co() vols = conv.vol_co() # Get dV dvols = np.zeros_like(vols) dvols[1:] = np.diff(vols) pprint(' - Calculating Star Formation Rate') # Get pdf sfr pdf_sfr = sfr(zs) * dvols cdf_sfr = np.cumsum(pdf_sfr) # Unnormalized cdf_sfr /= cdf_sfr[-1] pprint(' - Calculating Stellar Mass Density') # Get pdf csmd pdf_smd = smd(zs, H_0=H_0, W_m=W_m, W_v=W_v) * dvols cdf_smd = np.cumsum(pdf_smd) # Unnormalized cdf_smd /= cdf_smd[-1] results = np.stack((zs, dists, vols, dvols, cdf_sfr, cdf_smd)).T pprint(' - Saving values to database') # Save results to database data = map(tuple, results.tolist()) c.executemany('insert into distances values (?,?,?,?,?,?)', data) # Make for easier searching # I don't really understand SQL index names... c.execute('create index ix on distances (z)') c.execute('create index ixx on distances (dist)') c.execute('create index ixxx on distances (vol)') c.execute('create index ixxxx on distances (dvol)') c.execute('create index ixxxxx on distances (cdf_sfr)') c.execute('create index ixxxxxx on distances (cdf_smd)') # Save conn.commit() pprint('Finished distance table')
def __init__(self, n_gen, days=1, name='cosmic', H_0=67.74, W_m=0.3089, W_v=0.6911, dm_host_model='normal', dm_host_mu=100, dm_host_sigma=200, dm_igm_index=1000, dm_igm_sigma=None, dm_mw_model='ne2001', emission_range=[10e6, 10e9], lum_range=[1e40, 1e45], lum_index=0, n_model='sfr', alpha=-1.5, pulse_model='lognormal', pulse_range=[0.1, 10], pulse_mu=0.1, pulse_sigma=0.5, si_mu=-1.4, si_sigma=1., z_max=2.5): """Generate a popuation of FRBs. Args: n_gen (int): Number of FRB sources/sky/time to generate. days (float): Number of days over which FRBs are generated. name (str): Population name. H_0 (float): Hubble constant. W_m (float): Density parameter Ω_m. W_v (float): Cosmological constant Ω_Λ. dm_host_model (float): Dispersion measure host model. Options are 'normal' or 'lognormal'. dm_host_mu (float): Mean dispersion measure host [pc/cm^3]. dm_host_sigma (float): Deviation dispersion measure host [pc/cm^3]. dm_igm_index (float): Dispersion measure slope for IGM [pc/cm^3]. dm_igm_sigma (float): Scatter around dm_igm. Defaults 0.2*slope*z dm_mw_model (str): Dispersion measure model for the Milky Way. Options are 'ne2001' or 'zero'. emission_range (list): The frequency range [Hz] between which FRB sources should emit the given bolometric luminosity. lum_range (list): Bolometric luminosity (distance) range [erg/s]. lum_index (float): Power law index. n_model (str): Number density model. Either 'vol_co', 'sfr' or 'smd'. alpha (float): Desired logN/logS of perfectly detected population. pulse_model (str): Pulse width model, 'lognormal' or 'uniform'. pulse_range (list): Pulse width range [ms]. pulse_mu (float): Mean pulse width [ms]. pulse_sigma (float): Deviation pulse width [ms]. si_mu (float): Mean spectral index. si_sigma (float): Standard deviation spectral index. z_max (float): Maximum redshift. Returns: Population: Population of FRBs. """ # Set up population Population.__init__(self) self.alpha = alpha self.dm_host_model = dm_host_model self.dm_host_mu = dm_host_mu self.dm_host_sigma = dm_host_sigma self.dm_igm_index = dm_igm_index self.dm_igm_sigma = dm_igm_sigma self.dm_mw_model = dm_mw_model self.f_max = emission_range[1] self.f_min = emission_range[0] self.H_0 = H_0 self.lum_max = lum_range[1] self.lum_min = lum_range[0] self.lum_pow = lum_index self.name = name self.n_gen = n_gen self.n_model = n_model self.si_mu = si_mu self.si_sigma = si_sigma self.time = days * 86400 # Convert to seconds self.w_model = pulse_model self.w_max = pulse_range[1] self.w_min = pulse_range[0] self.w_mu = pulse_mu self.w_sigma = pulse_sigma self.W_m = W_m self.W_v = W_v self.z_max = z_max # Cosmology calculations r = go.Redshift(self.z_max, H_0=self.H_0, W_m=self.W_m, W_v=self.W_v) self.dist_co_max = r.dist_co() self.vol_co_max = r.vol_co() # Ensure precalculations are done if necessary pc.DistanceTable(H_0=self.H_0, W_m=self.W_m, W_v=self.W_v) # Set up number density n_den = NumberDensity(model=self.n_model, z_max=self.z_max, alpha=self.alpha, H_0=self.H_0, W_m=self.W_m, W_v=self.W_v).draw # Let user know what's happening pprint(f'Generating {self.name} population') frbs = self.frbs # Add random directional coordinates frbs.gl = np.random.random(n_gen) * 360.0 - 180 frbs.gb = np.degrees(np.arcsin(np.random.random(n_gen))) frbs.gb[::2] *= -1 # Convert frbs.ra, frbs.dec = go.lb_to_radec(frbs.gl, frbs.gb) # Draw from number density frbs.z, frbs.dist_co = n_den(n_gen) # Get the proper distance dist_pr = frbs.dist_co / (1 + frbs.z) # Convert into galactic coordinates frbs.gx, frbs.gy, frbs.gz = go.lb_to_xyz(frbs.gl, frbs.gb, dist_pr) # Dispersion measure of the Milky Way if self.dm_mw_model == 'ne2001': frbs.dm_mw = pc.NE2001Table().lookup(frbs.gl, frbs.gb) elif self.dm_mw_model == 'zero': frbs.dm_mw = np.zeros_like(frbs.z) # Dispersion measure of the intergalactic medium frbs.dm_igm = go.ioka_dm_igm(frbs.z, slope=self.dm_igm_index, sigma=self.dm_igm_sigma) # Dispersion measure of the host (Tendulkar) if self.dm_host_model == 'normal': frbs.dm_host = dis.trunc_norm(self.dm_host_mu, self.dm_host_sigma, n_gen).astype(np.float64) elif self.dm_host_model == 'lognormal': frbs.dm_host = np.random.lognormal(self.dm_host_mu, self.dm_host_sigma, n_gen).astype(np.float64) frbs.dm_host /= (1 + frbs.z) # Total dispersion measure frbs.dm = frbs.dm_mw + frbs.dm_igm + frbs.dm_host # Get a random intrinsic pulse width [ms] if self.w_model == 'lognormal': frbs.w_int = np.random.lognormal(self.w_mu, self.w_sigma, n_gen) if self.w_model == 'uniform': frbs.w_int = np.random.uniform(self.w_min, self.w_max, n_gen) # Calculate the pulse width upon arrival to Earth frbs.w_arr = frbs.w_int * (1 + frbs.z) # Add bolometric luminosity [erg/s] frbs.lum_bol = dis.powerlaw(self.lum_min, self.lum_max, self.lum_pow, n_gen) # Add spectral index frbs.si = np.random.normal(si_mu, si_sigma, n_gen) pprint('Finished')