def setup_pop(n_srcs): pop = CosmicPopulation.simple(n_srcs, n_days=MAX_DAYS, repeaters=True) pop.set_dist(z_max=0.01) pop.set_lum(model='powerlaw', per_source='different', low=1e35, high=1e40, power=-1.7) pop.set_w(model='constant', value=1) pop.set_dm(mw=False, igm=True, host=False) pop.set_dm_igm(model='ioka', slope=1000, std=0) return pop
def simple_rates(remake=REMAKE, alphas=ALPHAS, size=SIZE, surveys=SURVEYS): """Calculate expected rates for a simple populations.""" rates = defaultdict(list) # Don't always regenerate a population if remake is False: for alpha in alphas: for s in surveys: surv_rates = unpickle(f'simple_alpha_{alpha}_{s}').rates() pprint(f'Alpha:{alpha:.2}, Survey: {s}, Det: {surv_rates.det}') rate = (surv_rates.det / surv_rates.days) rates[s].append(rate) else: pops = [] for alpha in alphas: pop = CosmicPopulation.simple(size) pop.alpha = alpha pop.name = f'simple_alpha_{alpha}' pops.append(pop) # Set up surveys ss = [] for s in surveys: survey = Survey(name=s, gain_pattern='perfect', n_sidelobes=0.5) ss.append(survey) surv_pops = LargePopulation(pop, *ss).pops for i, s in enumerate(surveys): surv_rates = surv_pops[i].rates() pprint(f'Alpha:{alpha:.2}, Survey: {s}, Det: {surv_rates.det}') rate = (surv_rates.det / surv_rates.days) rates[s].append(rate) # Scale rates to HTRU for s in surveys: if s != 'htru': norm = [] for i, r in enumerate(rates[s]): norm.append(r / rates['htru'][i]) rates[s] = norm rates['htru'] = [r / r for r in rates['htru']] return rates
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
# ... or adapt the population per parameter, e.g. cosmic_pop.set_dist(z_max=2.5) # Or to adapt the luminosity cosmic_pop.set_lum(model='powerlaw', low=1e44, high=1e45) # Generate the population cosmic_pop.generate() # Setup a survey survey = Survey('wsrt-apertif') # and adapt the survey with survey.set_beam('airy', n_sidelobes=2) survey.snr_limit = 2 # For a full list of available arguments or parameters check the classes as # defined in /frbpoppy/*.py # Some more difficult examples # Use a convolution of two distributions cosmic_pop = CosmicPopulation.simple(n_srcs=1e4, repeaters=True) # Draw the mean value per source from a normal distribution mean_dist = gd.trunc_norm(mean=1, std=2, shape=int(1e4)) # And use those means as a _means_ to generate from a new Gaussian # distribution per source cosmic_pop.set_w(model='gauss', per_source='different', mean=mean_dist, std=0.01 * mean_dist) # And generate afterwards cosmic_pop.generate()
"""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)
import numpy as np import matplotlib.pyplot as plt from scipy.signal import savgol_filter from frbpoppy import CosmicPopulation, Survey, SurveyPopulation from convenience import plot_aa_style, rel_path SIS = (-2, 0, 2) # Spectral indices n_tot = 1e5 # Number of sources pop = {} for si in SIS: if si == min(SIS): pop[si] = CosmicPopulation.simple(n_tot) pop[si].name = f'si-{si}' pop[si].si_mu = si pop[si].z_max = 2.5 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:
"""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]
"""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()}')
"""Compare the resulting logNlogS and logNLog(S/N).""" import matplotlib.pyplot as plt import numpy as np from frbpoppy import CosmicPopulation, Survey, SurveyPopulation, hist from tests.convenience import plot_aa_style # Generate an FRB population cosmic_pop = CosmicPopulation.simple(1e4) cosmic_pop.set_lum(model='powerlaw', low=1e40, high=1e45) cosmic_pop.generate() # Setup a survey survey = Survey('perfect') # Observe the FRB population survey_pop = SurveyPopulation(cosmic_pop, survey) plot_aa_style(cols=2) f, axes = plt.subplots(1, 2) s = survey_pop.frbs bins, values = hist(s.snr, bin_type='log') # Cumulative sum values = np.cumsum(values[::-1])[::-1] axes[0].step(bins, values, where='mid') axes[0].set_title('SNR') bins, values = hist(s.fluence, bin_type='log')
"""Plot the 'burstiness': the observed repetition rate versus redshift.""" import matplotlib.pyplot as plt import numpy as np from frbpoppy import CosmicPopulation, Survey, SurveyPopulation, pprint, split_pop from frbcat import ChimeRepeaters from tests.convenience import plot_aa_style, rel_path n_srcs = 1e5 n_days = 4 RATE = 3 CHIME_HIST = False SCATTER = False pop = CosmicPopulation.simple(n_srcs, n_days=n_days, repeaters=True) pop.set_dist(z_max=2.0) pop.set_w(model='constant', value=1) pop.set_dm(mw=False, igm=True, host=False) pop.set_dm_igm(model='ioka', slope=1000, std=0) pop.set_time(model='poisson', rate=RATE) pop.set_time(model='regular', rate=RATE) pop.set_w('constant', value=1) pop.generate() survey = Survey('perfect', n_days=n_days) survey.snr_limit = 4e6 plot_aa_style(cols=1) f, ax1 = plt.subplots(1, 1) colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
"""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)
import frbpoppy.galacticops as go from tests.convenience import plot_aa_style, rel_path from tests.rates.alpha_real import EXPECTED MAKE = True SURVEYS = ('parkes-htru', 'wsrt-apertif', 'fast-crafts', 'puma-full', 'chord', 'ska1-low', 'ska1-mid') SIZE = 5e4 if MAKE: # Calculate the fraction of the sky that the survey covers surv_f_area = {} for name in SURVEYS: pop = CosmicPopulation.simple(5e5) pop.gen_direction() survey = Survey(name) mask = survey.in_region(pop.frbs.ra, pop.frbs.dec, pop.frbs.gl, pop.frbs.gb) in_surv_region = np.sum(mask) tot_region = len(mask) area_sky = 4 * np.pi * (180 / np.pi)**2 # In sq. degrees f_area = (survey.beam_size / area_sky) * (tot_region / in_surv_region) surv_f_area[name] = f_area print(f'{name} covers {f_area*100}% of the sky') surv_pops = []
"""Generate a repeater population and split into repeaters and one-offs.""" import numpy as np from frbpoppy import CosmicPopulation, Survey, SurveyPopulation from frbpoppy import split_pop, pprint, plot DAYS = 1 r = CosmicPopulation.simple(int(1e4), n_days=DAYS, repeaters=True) r.set_time(model='regular', rate=2) r.set_lum(model='powerlaw', low=1e40, high=1e45, per_source='different') r.generate() survey = Survey('chime-frb', n_days=DAYS) survey.set_beam(model='perfect') surv_pop = SurveyPopulation(r, survey) # Split population into seamingly one-off and repeater populations mask = ((~np.isnan(surv_pop.frbs.time)).sum(1) > 1) pop_ngt1, pop_nle1 = split_pop(surv_pop, mask) pop_ngt1.name += ' (> 1 burst)' pop_nle1.name += ' (1 burst)' pops = [pop_nle1, pop_ngt1] pprint(f'{surv_pop.n_sources()} sources detected') pprint(f'{surv_pop.n_bursts()} bursts detected') plot(surv_pop)
# Dispersion measure properties pop.set_dm_host(model='gauss', mean=100, std=200) pop.set_dm_igm(model='ioka', slope=1000, std=None) pop.set_dm_mw(model='ne2001') # Emission range of FRB sources pop.set_emission_range(low=100e6, high=10e9) # Luminsity of FRBs # See the per_source argument? That allows you to give different properties # to different bursts from the same source. You can do that for the luminosity, # or any of the following parameters pop.set_lum(model='powerlaw', low=1e38, high=1e38, power=0, per_source='different') # Pulse width pop.set_w(model='uniform', low=10, high=10) # Spectral index pop.set_si(model='gauss', mean=0, std=0) # If repeaters, how they repeat pop.set_time(model='regular', rate=2) # And then generate the population! pop.generate() # Or simply use some predefined models pop_simple = CosmicPopulation.simple(1e4, generate=True) pop_complex = CosmicPopulation.complex(1e4, generate=True)
"""Plot DM/SNR distributions of repeater populations.""" import numpy as np import matplotlib.pyplot as plt from scipy.stats import ks_2samp from frbpoppy import CosmicPopulation, Survey, SurveyPopulation, plot from frbpoppy import split_pop, pprint, hist from tests.convenience import plot_aa_style, rel_path DAYS = 4 INTERACTIVE_PLOT = False PLOTTING_LIMIT_N_SRCS = 0 SNR = False r = CosmicPopulation.simple(n_srcs=int(1e5), n_days=DAYS, repeaters=True) r.set_dist(z_max=0.01) r.set_lum(model='powerlaw', low=1e35, high=1e45, power=-1.5, per_source='different') r.set_time(model='poisson', rate=3) r.set_dm_igm(model='ioka', slope=1000, std=0) r.set_dm(mw=False, igm=True, host=False) r.set_w('constant', value=1) r.generate() # Set up survey survey = Survey('perfect', n_days=DAYS)
from tests.convenience import plot_aa_style, rel_path MAKE = True NUM_FRBS = True DENSITY_FRBS = True pop = {} pop_types = ('cst', 'sfr', 'smd', 'shallow', 'steep') titles = ('Constant', 'SFR', 'SMD', r'$\alpha_{\text{in}}=-0.5$', r'$\alpha_{\text{in}}=-2.0$') if MAKE: n_frbs = int(1e5) # Generate population following a constant number density / comoving volume pop['cst'] = CosmicPopulation.simple(n_frbs) pop['cst'].set_dist(model='vol_co', z_max=3.) pop['cst'].name = 'cst' pop['cst'].generate() # Generate population following star forming rate pop['sfr'] = CosmicPopulation.simple(n_frbs) pop['sfr'].set_dist(model='sfr', z_max=3.) pop['sfr'].name = 'sfr' pop['sfr'].generate() # Generate population following stellar mass density pop['smd'] = CosmicPopulation.simple(n_frbs) pop['smd'].set_dist(model='smd', z_max=3.) pop['smd'].name = 'smd' pop['smd'].generate()
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
def gen_def_pop(self): self.default_pop = CosmicPopulation.simple(self.size) self.default_pop.set_lum(model='constant', value=1e43) self.default_pop.generate()
import numpy as np import matplotlib.pyplot as plt from frbpoppy import CosmicPopulation, log10normal, Survey, SurveyPopulation from frbpoppy import hist from tests.convenience import plot_aa_style, rel_path N_DAYS = 50 N_SRCS = int(1e3) RATE = 0.1 # per day SINGLE_INPUT_RATE = True init_surv_time_frac = 0.1 # Set up a population pop = CosmicPopulation.simple(N_SRCS, n_days=N_DAYS, repeaters=True) pop.set_dist(z_max=0.01) pop.set_lum(model='powerlaw', low=1e30, high=1e40, power=-1) pop.set_w(model='constant', value=1) pop.set_dm(mw=False, igm=True, host=False) # Add a distribution of Poisson burst rates if SINGLE_INPUT_RATE: rate_dist = RATE else: rate_dist = log10normal(RATE, 2, N_SRCS) pop.set_time(model='poisson', rate=rate_dist) pop.generate() # Survey the high fluences survey = Survey('perfect', n_days=N_DAYS)