def iter_alpha(i, surveys=surveys, parallel=None): alpha = ALPHAS[i] pop = CosmicPopulation.complex(SIZE) pop.set_dist(model='vol_co', z_max=1.0, alpha=alpha) pop.set_lum(model='powerlaw', low=1e40, high=1e45, power=-1) pop.generate() for li in LIS: pop.set_lum(model='powerlaw', low=1e40, high=1e45, power=li) pop.gen_lum() for si in SIS: pop.set_si(model='constant', value=si) pop.gen_si() pop.name = f'complex_alpha_{alpha}_lum_{li}_si_{si}' for survey in surveys: surv_pop = SurveyPopulation(pop, survey) print(surv_pop.name) surv_pop.save() sr = surv_pop.source_rate rate = sr.det / sr.days mask = (df.alpha == alpha) & (df.li == li) & (df.si == si) if parallel is not None: i = df[mask].index j = SURVEY_NAMES.index(survey.name) parallel[i, j] = rate else: df.loc[mask, survey.name] = rate
def get_data(): """Get the population data.""" # Construct population pop = CosmicPopulation(n_srcs=SIZE, n_days=1, name='standard_candle') pop.set_dist(model='sfr', z_max=2.5, H_0=67.74, W_m=0.3089, W_v=0.6911) pop.set_dm_host(model='constant', value=100) pop.set_dm_igm(model='ioka', slope=1000, std=None) pop.set_dm_mw(model='ne2001') pop.set_emission_range(low=10e6, high=10e9) pop.set_lum(model='constant', value=1e36) pop.set_w(model='constant', value=1.) pop.set_si(model='constant', value=0) pop.generate() # Survey population pops = {} for b in BEAMPATTERNS: pprint(f'Surveying with {b} beampattern') n_s = 0 bp = b if b.startswith('airy'): bp, n_s = b.split('-') n_s = int(n_s) survey = Survey(name='perfect-small') # Prevent beam from getting larger than the sky survey.set_beam(model=bp, n_sidelobes=n_s, size=10) surv_pop = SurveyPopulation(pop, survey) print(surv_pop.source_rate) pops[b] = surv_pop return pops
def loop_surveys(self, cosmic_pop, z_max): for survey in self.surveys: surv_pop = SurveyPopulation(cosmic_pop, survey) surv_pop.z_max = z_max rate = surv_pop.source_rate.det n = surv_pop.n_sources() errs = [np.abs(e - n) for e in poisson_interval(n)] d = { 'survey': survey.name, 'pop': cosmic_pop.name, 'rate': rate, 'err_low': errs[0], 'err_high': errs[1], 'z_max': z_max } self.data.append(d)
def iter_alpha(i): alpha = alphas[i] pop = CosmicPopulation.complex(self.pop_size) pop.set_dist(model='vol_co', z_max=1.0, alpha=alpha) pop.set_lum(model='constant', value=1) if not np.isnan(w_mean): pop.set_w(model='lognormal', mean=w_mean, std=w_std) if not np.isnan(dm_igm_slope): pop.set_dm_igm(model='ioka', slope=dm_igm_slope) pop.set_dm_host(model='constant', value=dm_host) pop.generate() for si in sis: pop.set_si(model='constant', value=si) pop.gen_si() for li in lis: pop.set_lum(model='powerlaw', low=1e40, high=1e45, power=li) if not np.isnan(lum_min): pop.set_lum(model='powerlaw', low=lum_min, high=lum_max, index=li) pop.gen_lum() for survey in self.surveys: surv_pop = SurveyPopulation(pop, survey) # Get unique identifier mask = (self.so.df.par_set == 1) mask &= (self.so.df.run == run) mask &= (self.so.df.alpha == alpha) mask &= (self.so.df.si == si) mask &= (self.so.df.li == li) mask &= (self.so.df.survey == survey.name) uuid = self.so.df[mask].uuid.iloc[0] surv_pop.name = f'mc/run_{run}/{uuid}' surv_pop.save()
def adapt_pop(e): w_mean, w_std = e t_pop = deepcopy(pop) t_pop.set_w(model='lognormal', mean=w_mean, std=w_std) t_pop.gen_w() for survey in self.surveys: surv_pop = SurveyPopulation(t_pop, survey) # Get unique identifier mask = (self.so.df.par_set == 3) mask &= (self.so.df.run == run) mask &= (self.so.df.run == run) mask &= (self.so.df.w_mean == w_mean) mask &= (self.so.df.w_std == w_std) mask &= (self.so.df.survey == survey.name) uuid = self.so.df[mask].uuid.iloc[0] surv_pop.name = f'mc/run_{run}/{uuid}' surv_pop.save()
def get_survey_pop(pop, survey, overwrite=False): """Quickly get survey populations. Args: pop (CosmicPopulation): Population to survey survey (Survey): Survey to use overwrite (bool): Check whether a population has already been run. If overwrite is true, it will always make a new instance. Returns: pop: Desired population. """ observe = True # Check where a possible population would be located path = '' if isinstance(pop, str): name = f'{pop}_{survey.name}' path = paths.populations() + name + '.p' # Check if the file exists if not overwrite: if os.path.isfile(path): observe = False return unpickle(path) # If all else fails observe again if observe: if isinstance(pop, str): m = f'No survey population at {path}, yet no surveying requested' raise ValueError(m) surv_pop = SurveyPopulation(pop, survey) surv_pop.name = f'{pop.name}_{survey.name}' surv_pop.save() return surv_pop
def adapt_pop(e): dm_igm_slope, dm_host = e t_pop = deepcopy(pop) t_pop.set_dm_igm(model='ioka', slope=dm_igm_slope) t_pop.gen_dm_igm() t_pop.set_dm_host(model='constant', value=dm_host) t_pop.gen_dm_host() t_pop.frbs.dm = t_pop.frbs.dm_mw + t_pop.frbs.dm_igm t_pop.frbs.dm += t_pop.frbs.dm_host for survey in self.surveys: surv_pop = SurveyPopulation(t_pop, survey) # Get unique identifier mask = (self.so.df.par_set == 4) mask &= (self.so.df.run == run) mask &= (self.so.df.dm_igm_slope == dm_igm_slope) mask &= (self.so.df.dm_host == dm_host) mask &= (self.so.df.survey == survey.name) uuid = self.so.df[mask].uuid.iloc[0] surv_pop.name = f'mc/run_{run}/{uuid}' surv_pop.save()
def get_local(make=MAKE, size=SIZE): # Construct populations pop = get_cosmic_pop('alpha_simple', size, load=True, overwrite=make, alpha=-1.5) # Survey populations survey = Survey(name='perfect', gain_pattern='perfect', n_sidelobes=0.5) surv_pop = SurveyPopulation(pop, survey) return surv_pop.frbs.fluence
def adapt_pop(e): li, lum_min, lum_max = e if lum_max < lum_min: return t_pop = deepcopy(pop) t_pop.set_lum(model='powerlaw', low=lum_min, high=lum_max, power=li) t_pop.gen_lum() for survey in self.surveys: surv_pop = SurveyPopulation(t_pop, survey) # Get unique identifier mask = (self.so.df.par_set == 2) mask &= (self.so.df.run == run) mask &= (self.so.df.li == li) mask &= (self.so.df.lum_min == lum_min) mask &= (self.so.df.lum_max == lum_max) mask &= (self.so.df.survey == survey.name) uuid = self.so.df[mask].uuid.iloc[0] surv_pop.name = f'mc/run_{run}/{uuid}' surv_pop.save()
def get_further(gamma, make=MAKE, size=SIZE): """Construct populations going further out.""" # Construct populations pop = get_cosmic_pop('gamma', size, load=True, overwrite=make, gamma=gamma) if gamma == 1: pop.frbs.lum_bol = np.ones_like(pop.frbs.lum_bol)*10**43 # Survey populations survey = Survey(name='perfect', gain_pattern='perfect', n_sidelobes=0.5) surv_pop = SurveyPopulation(pop, survey) return surv_pop.frbs.fluence
def get_data(): """Get the population data.""" # Construct population pop = CosmicPopulation(SIZE, days=1, name='standard_candle', H_0=67.74, W_m=0.3089, W_v=0.6911, dm_host_model='gaussian', dm_host_mu=100, dm_host_sigma=0, dm_igm_index=1000, dm_igm_sigma=None, dm_mw_model='ne2001', emission_range=[10e6, 10e9], lum_range=[1e36, 1e36], lum_index=0., n_model='sfr', alpha=-1.5, w_model='uniform', w_range=[1., 1.], w_mu=0.1, w_sigma=0., si_mu=0., si_sigma=0., z_max=2.5) # Survey population pops = {} for b in BEAMPATTERNS: n_s = 0 bp = b if b.startswith('airy'): bp, n_s = b.split('-') n_s = int(n_s) survey = Survey(name='perfect-small') survey.gain_pattern = bp survey.n_sidelobes = n_s surv_pop = SurveyPopulation(pop, survey) pops[b] = surv_pop return pops
def get_further(gamma): """Construct populations going further out.""" # Construct populations pop = CosmicPopulation.simple(SIZE) pop.si_mu = gamma pop.z_max = 2.5 pop.lum_min = 10**42.5 pop.lum_max = pop.lum_min pop.generate() if gamma == 1: pop.frbs.lum_bol = np.ones_like(pop.frbs.lum_bol)*10**43 # Survey populations survey = Survey('perfect') surv_pop = SurveyPopulation(pop, survey) return surv_pop.frbs.s_peak
def get_further(gamma): """Construct populations going further out.""" # Construct populations pop = CosmicPopulation.simple(SIZE) pop.set_dist(z_max=2.5) pop.set_si(model='constant', value=gamma) pop.set_lum(model='constant', value=10**42.5) pop.generate() if gamma == 1: pop.set_lum(model='constant', value=10**43) pop.gen_lum() # Survey populations survey = Survey('perfect') surv_pop = SurveyPopulation(pop, survey) return surv_pop.frbs.s_peak
def iter_run(i): r = CosmicPopulation(N_SRCS, n_days=N_DAYS, repeaters=True) r.set_dist(model='vol_co', z_max=1.0) r.set_dm_host(model='gauss', mean=100, std=200) r.set_dm_igm(model='ioka', slope=1000, std=None) r.set_dm(mw=True, igm=True, host=True) r.set_emission_range(low=100e6, high=10e9) r.set_lum(model='powerlaw', per_source='different', low=1e40, high=1e45, power=0) r.set_si(model='gauss', mean=-1.4, std=1) r.set_w(model='lognormal', per_source='different', mean=0.1, std=1) rate = lognormal(RATE, 2, N_SRCS) if LARGE_POP: rate = lognormal(RATE, 2, int(MAX_SIZE)) # Not completely kosher r.set_time(model='poisson', rate=rate) # Set up survey s = Survey('chime-frb', n_days=N_DAYS) s.set_beam(model='chime-frb') s.gen_pointings() # To ensure each sub pop has the same pointings # Only generate FRBs in CHIME's survey region r.set_direction(model='uniform', min_ra=s.ra_min, max_ra=s.ra_max, min_dec=s.dec_min, max_dec=s.dec_max) if LARGE_POP: surv_pop = LargePopulation(r, s, max_size=MAX_SIZE).pops[0] else: r.generate() surv_pop = SurveyPopulation(r, s) surv_pop.name = f'cosmic_chime_longer_{i}' surv_pop.save() print(surv_pop.source_rate) print(surv_pop.burst_rate) pprint(f'i: {i}') pprint(f'# one-offs: {surv_pop.n_one_offs()}') pprint(f'# repeaters: {surv_pop.n_repeaters()}')
def do_survey(): # Construct population pop = get_cosmic_pop('standard_candle', SIZE, load=True, overwrite=MAKE) # Survey population pops = {} for b in BEAMPATTERNS: n_s = 0 bp = b if b.startswith('airy'): bp, n_s = b.split('-') n_s = int(n_s) survey = Survey(name='perfect-small', gain_pattern=bp, n_sidelobes=n_s) surv_pop = SurveyPopulation(pop, survey) pops[b] = surv_pop return pops
def get_local(): """Construct a local population.""" pop = CosmicPopulation.simple(SIZE, generate=True) survey = Survey('perfect') surv_pop = SurveyPopulation(pop, survey) return surv_pop.frbs.s_peak
pop_obs = {} if OBSERVE: for n in (35, 36, 37): if not CREATE: pop[n] = unpickle(f'sc-{n}') # Create Survey perfect = Survey('perfect-small', gain_pattern='gaussian', n_sidelobes=8) # Observe populations pop_obs[n] = SurveyPopulation(pop[n], perfect) pop_obs[n].name = f'sc-{n}-obs' pop_obs[n].rates() pop_obs[n].save() else: for n in (35, 36, 37): pop_obs[n] = unpickle(f'sc-{n}-obs') f, (ax1) = plt.subplots(1, 1) for n in pop_obs: pop = pop_obs[n] limit = 1e-9
pop.generate() apertif = Survey('wsrt-apertif', n_days=N_DAYS) apertif.set_beam(model='apertif_real') if SCALE_TO == 'parkes-htru': htru = Survey('parkes-htru', n_days=N_DAYS) htru.set_beam(model='parkes') if SCALE_TO == 'askap': askap = Survey('askap-fly', n_days=N_DAYS) askap.set_beam(model='gaussian', n_sidelobes=0.5) days_per_frbs = [] for i in tqdm(range(2000), desc='Survey Run'): apertif_pop = SurveyPopulation(pop, apertif, mute=True) if SCALE_TO == 'parkes-htru': htru_pop = SurveyPopulation(pop, htru, mute=True) n_frbs_htru = EXPECTED['parkes-htru'][0] n_days_htru = EXPECTED['parkes-htru'][1] scaled_n_days = n_days_htru * (htru_pop.source_rate.det / n_frbs_htru) if SCALE_TO == 'askap': askap_pop = SurveyPopulation(pop, askap, mute=True) n_frbs_askap = EXPECTED['askap-fly'][0] n_days_askap = EXPECTED['askap-fly'][1] scaled_n_days = n_days_askap * (askap_pop.source_rate.det / n_frbs_askap) days_per_frb = scaled_n_days / apertif_pop.source_rate.det
pop.set_emission_range(low=10e6, high=10e9) pop.set_lum(model='constant', value=1e36) pop.set_w(model='constant', value=1) pop.set_si(model='constant', value=0) pop.generate() pop_obs = {} survey = Survey('perfect-small') for pattern in BEAMPATTERNS: survey.set_beam(model=pattern, n_sidelobes=0, size=90) # Observe populations pop_obs[pattern] = SurveyPopulation(pop, survey) pop_obs[pattern].name = f'obs-{pattern}' pop_obs[pattern].source_rate print(pop_obs[pattern].source_rate) pop_obs[pattern].save() plot_aa_style() f, (ax1) = plt.subplots(1, 1) for p in BEAMPATTERNS: pop = pop_obs[p] limit = 1e-9 s_peak = pop.frbs.s_peak dm_igm = pop.frbs.dm_igm
def survey_pop(self, pop): return SurveyPopulation(pop, self.survey)
r.set_emission_range(low=100e6, high=10e9) r.set_lum(model='powerlaw', per_source='different', low=1e40, high=1e45, power=0) r.set_si(model='gauss', mean=-1.4, std=1) r.set_w(model='lognormal', per_source='different', mean=0.1, std=1) rate = lognormal(ra, 1, int(n)) r.set_time(model='poisson', rate=rate) # Set up survey s = Survey('chime-frb', n_days=N_DAYS) s.set_beam(model='chime-frb') # Only generate FRBs in CHIME's survey region r.set_direction(model='uniform', min_ra=s.ra_min, max_ra=s.ra_max, min_dec=s.dec_min, max_dec=s.dec_max) r.generate() surv_pop = SurveyPopulation(r, s) surv_pop.name = 'cosmic_chime' print(surv_pop.source_rate) print(surv_pop.burst_rate) pprint(f'# one-offs: {surv_pop.n_one_offs()}') pprint(f'# repeaters: {surv_pop.n_repeaters()}')
"""Example of simulating a perfect survey.""" from frbpoppy import CosmicPopulation, Survey, SurveyPopulation, plot # Generate an FRB population cosmic_pop = CosmicPopulation.simple(1e4, generate=True) # Setup a survey survey = Survey('perfect') # Observe the FRB population survey_pop = SurveyPopulation(cosmic_pop, survey) # Check the detection rates print(survey_pop.rates()) # Note that due to redshift you won't see all bursts, as some will have # redshifted out of the observing time. But no matter how faint, you'll see # all bursts within the observing time # Plot populations plot(cosmic_pop, survey_pop, frbcat=False, mute=False)
pop.set_w(model='constant', value=1) pop.set_si(model='constant', value=0) pop.generate() pop_obs = {} survey = Survey('perfect-small') survey.beam_size_at_fwhm = 10. survey.set_beam(model='airy') for sidelobe in SIDELOBES: survey.set_beam(model='airy', n_sidelobes=sidelobe) # Observe populations pop_obs[sidelobe] = SurveyPopulation(pop, survey) pop_obs[sidelobe].name = f'obs-{sidelobe}' pop_obs[sidelobe].source_rate pop_obs[sidelobe].save() plot_aa_style() f, (ax1) = plt.subplots(1, 1) for p in SIDELOBES: pop = pop_obs[p] limit = 1e-9 s_peak = pop.frbs.s_peak dm_igm = pop.frbs.dm_igm
"""Check the log N log F slope of a local population.""" import numpy as np import matplotlib.pyplot as plt from frbpoppy import CosmicPopulation, Survey, SurveyPopulation from frbpoppy.population import unpickle from tests.convenience import plot_aa_style, rel_path MAKE = True if MAKE: population = CosmicPopulation.simple(1e5, generate=True) survey = Survey('perfect') surv_pop = SurveyPopulation(population, survey) surv_pop.name = 'lognlogflocal' surv_pop.save() else: surv_pop = unpickle('lognlogflocal') # Get parameter parms = surv_pop.frbs.fluence min_p = min(parms) max_p = max(parms) # Bin up min_f = np.log10(min(parms)) max_f = np.log10(max(parms)) log_bins = np.logspace(min_f, max_f, 50) hist, edges = np.histogram(parms, bins=log_bins) n_gt_s = np.cumsum(hist[::-1])[::-1]
pop[si].generate() pop[si].save() else: pop[si] = copy.deepcopy(pop[min(SIS)]) pop[si].frbs.si = np.random.normal(si, 0, int(n_tot)) pop[si].name = f'si-{si}' pop[si].save() pop_obs = {} for si in SIS: perfect = Survey('perfect') # Observe populations pop_obs[si] = SurveyPopulation(pop[si], perfect) pop_obs[si].name = f'si-{si}-obs' pop_obs[si].rates() pop_obs[si].save() plot_aa_style() # Plot log N and alpha versus log S f, (ax1, ax2) = plt.subplots(2, 1, sharex=True) min_s = 1e99 max_s = -1e99 for si in SIS: pop = pop_obs[si]
"""How to access frb population parameters.""" from frbpoppy import CosmicPopulation, Survey, SurveyPopulation cosmic_pop = CosmicPopulation.simple(1e3, repeaters=True, generate=True) dm = cosmic_pop.frbs.dm # Get dispersion measure values survey_pop = SurveyPopulation(cosmic_pop, Survey('perfect')) survey_dm = survey_pop.frbs.dm # Also works for SurveyPopulations # Inbuilt functions help with detection rates print(f'Number of sources: {survey_pop.n_sources()}') print(f'Number of bursts: {survey_pop.n_bursts()}') print(f'Number of repeating sources: {survey_pop.n_repeaters()}') print(f'Number of one-off sources: {survey_pop.n_oneoffs()}')
power=0) r.set_si(model='gauss', mean=-1.4, std=1) r.set_w(model='lognormal', per_source='different', mean=0.1, std=1) rate = lognormal(RATE, 1, int(N_SRCS)) r.set_time(model='poisson', rate=rate) # Only generate FRBs in CHIME's survey region r.set_direction(model='uniform', min_ra=chime.ra_min, max_ra=chime.ra_max, min_dec=chime.dec_min, max_dec=chime.dec_max) r.generate() surv_pop = SurveyPopulation(r, chime) surv_pop.save() else: surv_pop = unpickle('cosmic_chime') # Limit population to above S/N >= 10 mask = (surv_pop.frbs.snr >= 10) surv_pop.frbs.apply(mask) # Set up plot style plot_aa_style(cols=1) f, ax1 = plt.subplots(1, 1) # See how fraction changes over time n_pointings = chime.n_pointings days = np.linspace(0, N_DAYS, (N_DAYS * n_pointings) + 1)
"""Test perfect survey.""" import matplotlib.pyplot as plt from frbpoppy import CosmicPopulation, Survey, SurveyPopulation from convenience import hist, plot_aa_style, rel_path cosmic_pop = CosmicPopulation.simple(1e4, generate=False) cosmic_pop.z_max = 0.01 cosmic_pop.lum_min = 1e38 cosmic_pop.generate() survey = Survey('perfect') survey_pop = SurveyPopulation(cosmic_pop, survey) plot_aa_style() plt.rcParams["figure.figsize"] = (5.75373, 5.75373) f, axes = plt.subplots(2, 2) s = survey_pop.frbs axes[0, 0].step(*hist(s.snr, bin_type='log'), where='mid') axes[0, 0].set_title('SNR') axes[1, 0].step(*hist(s.T_sys, bin_type='log'), where='mid') axes[1, 0].set_title(r'T$_{\text{sys}}$') axes[1, 0].set_xlim(1, 1e2) axes[1, 0].set_ylim(1e-3, 1) axes[0, 1].step(*hist(s.s_peak, bin_type='log'), where='mid') axes[0, 1].set_title(r'S$_{\text{peak}}$') axes[0, 1].set_xlim(1e-3, 1)
# Assign the values frbs = pop.frbs frbs.ra, frbs.dec = coords[0], coords[1] frbs.gl, frbs.gb = coords[2], coords[3] # Continue with generation pop.gen_gal_coords() pop.gen_dm() pop.gen_w() pop.gen_lum() pop.gen_si() else: pop.generate() surv_pop = SurveyPopulation(pop, survey, scale_by_area=False) surv_pop.source_rate.f_area = surv_f_area[name] surv_pop.source_rate.scale_by_area() # surv_pop.save() surv_pops.append(surv_pop) else: surv_pops = [] for name in SURVEYS: surv_pops.append(unpickle(f'optimal_{name}')) # Start plot plot_aa_style(cols=2) plt.rcParams["figure.figsize"] = (3.556 * 3, 3.556) fig, axes = plt.subplots(1, 3)
from frbpoppy import unpickle, pprint from tests.convenience import plot_aa_style, rel_path MAKE = True SURVEYS = ('parkes-htru', 'fast-crafts', 'puma-full', 'chord', 'ska1-low', 'ska1-mid') if MAKE: surv_pops = [] pop = CosmicPopulation.complex(1e5, generate=False) pop.generate() for name in SURVEYS: survey = Survey(name) surv_pop = SurveyPopulation(pop, survey) surv_pop.save() surv_pops.append(surv_pop) else: surv_pops = [] for name in SURVEYS: surv_pops.append(unpickle(f'complex_{name}')) # Start plot plot_aa_style() fig, ax1 = plt.subplots(1, 1) # Fluence plot ax1.set_xlabel('S/N') ax1.set_xscale('log') ax1.set_ylabel(r'\#(${>}\text{S/N}$)')