예제 #1
0
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
예제 #2
0
 def set_up_surveys(self):
     """Set up surveys."""
     surveys = []
     for name in self.survey_names:
         survey = Survey(name=name)
         survey.set_beam(model='airy', n_sidelobes=1)
         if name in ('chime-frb', 'wsrt-apertif', 'parkes-htru'):
             survey.set_beam(model=name)
         surveys.append(survey)
     return surveys
예제 #3
0
def complex_rates(remake=REMAKE, alphas=ALPHAS, size=SIZE, surveys=SURVEYS):
    """Calculate expected rates for a complex 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'complex_alpha_{alpha}_{s}').source_rate
                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:
            if alpha <= -1.0 and ADAPTATIVE_SCALING:
                size = 1e7
            if alpha <= -1.5 and ADAPTATIVE_SCALING:
                size = 1e8
            pop = CosmicPopulation.complex(size)
            pop.set_dist(model='vol_co',
                         z_max=2.5,
                         alpha=alpha,
                         H_0=67.74,
                         W_m=0.3089,
                         W_v=0.6911)
            pop.set_lum(model='powerlaw', low=1e40, high=1e45, power=-1)
            pop.name = f'complex_alpha_{alpha}'
            pops.append(pop)

            # Set up surveys
            ss = []
            for s in surveys:
                survey = Survey(name=s)
                survey.set_beam(model='airy', n_sidelobes=1)
                ss.append(survey)

            surv_pops = LargePopulation(pop, *ss).pops

            for i, s in enumerate(surveys):
                surv_rates = surv_pops[i].source_rate
                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 first survey in list
    for s in surveys:
        if s != surveys[0]:
            norm = []
            for i, r in enumerate(rates[s]):
                norm.append(r / rates[surveys[0]][i])
            rates[s] = norm
    rates[surveys[0]] = [r / r for r in rates[surveys[0]]]

    return rates
예제 #4
0
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}').source_rate
                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.set_dist(alpha=alpha)
            pop.name = f'simple_alpha_{alpha}'
            pops.append(pop)

            # Set up surveys
            ss = []
            for s in surveys:
                survey = Survey(name=s)
                survey.set_beam(model='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].source_rate
                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 != 'parkes-htru':
            norm = []
            for i, r in enumerate(rates[s]):
                norm.append(r/rates['parkes-htru'][i])
            rates[s] = norm
    rates['parkes-htru'] = [r/r for r in rates['parkes-htru']]

    return rates
예제 #5
0
파일: sim.py 프로젝트: telegraphic/frbpoppy
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()}')
예제 #6
0
def analytical_rates(surveys=SURVEYS, alphas=ALPHAS):
    """Use a analytical model to scale detection rates to various alphas."""
    rates = {}

    for surv in surveys:

        # Get survey parameters
        surv1 = Survey(surv)
        surv1.set_beam('perfect', n_sidelobes=0.5)
        surv2 = Survey(surveys[0])
        surv2.set_beam('perfect', n_sidelobes=0.5)

        # Calculate rate per alpha
        rate = []
        for alpha in alphas:
            rate.append(compare_surveys(surv1, surv2, alpha))
        rates[surv] = rate

    return rates
예제 #7
0
def get_data():
    """Get survey populations."""
    # Don't always regenerate a population
    if REMAKE is False:
        # Check where a possible population would be located
        path = ''
        surv_pops = []
        for telescope in TELESCOPES:
            survey = telescope
            if telescope == 'askap':
                survey = 'askap-fly'
            if telescope == 'parkes':
                survey = 'parkes-htru'
            name = f'{survey}'
            path = paths.populations() + f'complex_{name}.p'
            surv_pops.append(unpickle(path))

        return surv_pops

    cosmic_pop = CosmicPopulation.complex(SIZE, generate=False)

    surveys = []
    for telescope in TELESCOPES:

        pattern = 'airy'
        if telescope == 'parkes':
            pattern = 'parkes-htru'

        s = telescope
        if telescope == 'askap':
            s = 'askap-fly'

        survey = Survey(s)
        survey.set_beam(model=pattern, n_sidelobes=1)
        surveys.append(survey)

    return LargePopulation(cosmic_pop, *surveys).pops
예제 #8
0
from obs_rep_frac import calc_rep_frac

init_surv_time_frac = 0.05
MAKE = False
PLOT_CHIME = False

N_SRCS = 3.6e4
N_DAYS = 100
RATE = 9  # per day
# Chime started in Aug 2018. Assuming 2/day for one-offs.
# Total of 9 repeaters published on 9 Aug 2019. = ~year
N_CHIME = {'rep': 9, 'one-offs': 365 * 2, 'time': 365}

# Set up survey
chime = Survey('chime-frb', n_days=N_DAYS)
chime.set_beam(model='chime-frb')

if MAKE:

    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)
from frbpoppy import CosmicPopulation, Survey
import frbpoppy.gen_dists as gd

# Set up a population
cosmic_pop = CosmicPopulation(1e4, generate=False)
# ... 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',
예제 #10
0
pop.set_dist(model='sfr', z_max=2.5, H_0=67.74, W_m=0.3089, W_v=0.6911)
pop.set_dm_igm(model='ioka', slope=1200, std=0)
pop.set_dm(mw=False, host=False, igm=True)
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
예제 #11
0
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm
from frbpoppy import CosmicPopulation, Survey, SurveyPopulation, hist

from tests.convenience import plot_aa_style, rel_path
from alpha_real import EXPECTED, poisson_interval

N_DAYS = 1  # Not used in eventual result
SCALE_TO = 'parkes-htru'

pop = CosmicPopulation.complex(n_srcs=1e5, n_days=N_DAYS)
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)
예제 #12
0
        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(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()}')
예제 #13
0
            linestyle = self.lz[pop.z_max]
            colour = self.colours[int(i % (len(pops)/2))]
            label = '_'.join(pop.name.split('_')[0:-1])
            if i > (len(pops)/2 - 1):  # Turn off some line labels
                label = f'_{label}'
            ax.step(*self.calc_cum_hist(pop), where='mid',
                    label=rf'{label}', linestyle=linestyle,
                    color=colour)

    def calc_cum_hist(self, pop):
        # Bin up parameter in a cumulative bin
        edges, values = hist(pop.frbs.snr, bin_type='log')
        if isinstance(edges, float):
            return np.nan, np.nan
        n_gt_s = np.cumsum(values[::-1])[::-1]

        # Normalise to S/N of 10^5
        log_diff = (np.log10(edges[0]) - np.log10(1e0))
        edges = 10**(np.log10(edges) - log_diff)

        return edges, n_gt_s


if __name__ == '__main__':
    for s in SURVEYS:
        survey = Survey(s)
        survey.set_beam('gaussian')
        if s == 'perfect':
            survey.set_beam('perfect')
        Flattening(SIZE, survey)
예제 #14
0
# Generate population with standard candles
pop = CosmicPopulation(n_srcs=5e5, n_days=1, name='standard')
pop.set_dist(model='sfr', z_max=2.5, H_0=67.74, W_m=0.3089, W_v=0.6911)
pop.set_dm_igm(model='ioka', slope=1200, std=0)
pop.set_dm(mw=False, host=False, igm=True)
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')
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:
예제 #15
0
def generate(parallel=False):
    from joblib import Parallel, delayed
    from frbpoppy import CosmicPopulation, Survey, pprint
    from frbpoppy import SurveyPopulation
    from tqdm import tqdm

    # Set up rate dataframe
    paras = [ALPHAS, LIS, SIS]
    vals = np.array(np.meshgrid(*paras)).T.reshape(-1, len(paras))
    cols = ['alpha', 'li', 'si']
    df = pd.DataFrame(vals, columns=cols)

    # Set up surveys
    surveys = []
    for name in SURVEY_NAMES:
        survey = Survey(name=name)
        survey.set_beam(model='airy', n_sidelobes=1)
        surveys.append(survey)
        df[name] = np.nan

    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

    if parallel:
        n_cpu = min([3, os.cpu_count() - 1])
        pprint(f'{os.cpu_count()} CPUs available')
        r = range(len(ALPHAS))

        temp_path = ('./temp.mmap')

        # Make a temp memmap to have a sharedable memory object
        temp = np.memmap(temp_path,
                         dtype=np.float64,
                         shape=(len(vals), len(SURVEY_NAMES)),
                         mode='w+')

        Parallel(n_jobs=n_cpu)(delayed(iter_alpha)(i, parallel=temp)
                               for i in tqdm(r))

        for name in SURVEY_NAMES:
            col = SURVEY_NAMES.index(name)
            df[name] = temp[:, col]
    else:
        for i in tqdm(range(len(ALPHAS)), desc='Alphas'):
            iter_alpha(i)

    df.to_csv(CSV_PATH)
예제 #16
0
"""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)
예제 #17
0
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
from matplotlib.lines import Line2D

from frbpoppy import Survey, int_pro_fixed

from tests.convenience import plot_aa_style, rel_path

T_OBS = 60 * 60  # seconds
OBJ_OFFSET = 1  # deg
INTENSITY_LIMIT = 1e-8

# Set up survey
survey = Survey('chime-frb', n_days=0.99)
survey.set_beam('chime-frb')

# Get beam properties
beam_array = survey.beam_array
pattern = survey.beam_pattern
pixel_scale = np.float64(survey.pixel_scale)
latitude = survey.latitude
mount_type = survey.mount_type

# Limit extent of intensity for plotting reasons
beam_array[beam_array < INTENSITY_LIMIT] = INTENSITY_LIMIT

# Set pointings
survey.gen_pointings()
pointings = survey.pointings
예제 #18
0
r.set_dist(z_max=2)
r.set_lum(model='powerlaw',
          low=1e35,
          high=1e45,
          power=-1.7,
          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('chime-frb', n_days=DAYS)
survey.set_beam(model='chime-frb')
survey.snr_limit = 1e-13

surv_pop = SurveyPopulation(r, survey)

pprint(f'{r.n_bursts()}:{surv_pop.n_bursts()}')
pprint(f'{surv_pop.n_sources()} sources detected')

if r.n_bursts() < PLOTTING_LIMIT_N_SRCS:
    pprint('Not sufficient FRB sources for plotting')
    exit()

# Split population into seamingly one-off and repeater populations
mask = ((~np.isnan(surv_pop.frbs.time)).sum(1) > 1)
pop_rep, pop_one = split_pop(surv_pop, mask)
pop_rep.name += ' (> 1 burst)'
"""Short example of how frbpoppy works.

The first time you run frbpoppy, a series of cosmological databases will be
constructed to set up subsequent runs. This first run can take ~2h on a 4 core
machine. Subsequent runs will take mere seconds.
"""
from frbpoppy import CosmicPopulation, Survey, SurveyPopulation, plot

# Set up an FRB population of one-offs
# Add repeaters=True to turn into an FRB population of repeaters
cosmic_pop = CosmicPopulation.complex(1e5, n_days=0.01)

# Generate your FRB population
cosmic_pop.generate()

# Setup a survey
survey = Survey('parkes-htru')
survey.set_beam(model='parkes-htru')

# Observe the FRB population
survey_pop = SurveyPopulation(cosmic_pop, survey)

# Check the detection rates
print(survey_pop.source_rate)

# Plot populations in a browser
plot(cosmic_pop, survey_pop, tns='parkes')
예제 #20
0
 def gen_survey(self, name):
     survey = Survey(name)
     survey.set_beam('gaussian')
     return survey
예제 #21
0
        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 = []

    for name in SURVEYS:
        # Set up survey
        survey = Survey(name)
        if name in ('parkes-htru', 'wsrt-apertif'):
            survey.set_beam(model=name)

        # Set up CosmicPopulation
        pop = CosmicPopulation.optimal(SIZE, generate=False)

        # Only generate FRBs in the survey region
        pop.set_direction(model='uniform',
                          min_ra=survey.ra_min,
                          max_ra=survey.ra_max,
                          min_dec=survey.dec_min,
                          max_dec=survey.dec_max)

        # Parkes also has galactic limits:
        if name == 'parkes-htru':
            pop.gen_index()
            pop.gen_dist()