Пример #1
0
    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)
Пример #2
0
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
Пример #3
0
    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')
Пример #4
0
    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')