Пример #1
0
    def set_file_name(self):
        """Determine filename."""
        uni_mods = os.path.join(paths.models(), 'universe/')
        self.file_name = uni_mods + 'dm_mw.db'

        if self.test:
            uni_mods = os.path.join(paths.models(), 'universe/')
            self.file_name = uni_mods + 'test_dm_mw.db'
Пример #2
0
def dm_mw(gl, gb, model='ne2001'):
    """ Return DM values for given coordinates from NE2001 healpix

    Args:
        gl (array): Galactic longitude [fractional degrees]
        gb (array): Galactic latitude [fractional degrees]
        model (str): one of 'ne2001', 'ymw16'

    Returns:
        dm_mw (array): Galactic dispersion measure [pc*cm^-3]
    """
    if model == 'ne2001':
        data_file = os.path.join(paths.models(),
                                 'healpix/dm-ne2001-30kpc.fits')
    elif model == 'ymw16':
        data_file = os.path.join(paths.models(), 'healpix/dm-ymw16-30kpc.fits')
    data = hp.read_map(data_file, verbose=False, dtype=np.float64)
    nside = hp.npix2nside(len(data))  # This sets map resolution  (NSIDE)
    pixloc = hp.ang2pix(nside, gl, gb, lonlat=True)
    return data[pixloc]
Пример #3
0
    def set_file_name(self):
        """Determine filename."""
        uni_mods = os.path.join(paths.models(), 'universe/')

        def cvt(value):
            """Convert a float to a string without a period."""
            return str(value).replace('.', 'd')

        # Convert
        paras = ['h0', cvt(self.H_0), 'wm', cvt(self.W_m), 'wv', cvt(self.W_v)]
        f = '-'.join(paras)

        self.file_name = uni_mods + f + '.db'
Пример #4
0
def get_beam_props(model, fwhm):
    """Get beam properties.

    Args:
        model (str): Which model to use.
        fwhm (float): FWHM [frac. deg].

    Returns:
        beam_size, pixel_scale, beam_array

    """
    # Set up beam arrays
    models = ('wsrt-apertif', 'parkes-htru', 'chime-frb', 'gaussian', 'airy',
              'wsrt-apertif_real')
    if model in models:
        place = paths.models() + f'/beams/{model}.npy'
        beam_array = np.load(place)

    # Set up details if using beam arrays
    if model.startswith('wsrt-apertif'):
        pixel_scale = 0.94 / 60  # Degrees per pixel [deg]
        beam_size = 25.  # [sq deg]
    elif model == 'parkes-htru':
        pixel_scale = 54 / 3600  # Degrees per pixel [deg]
        beam_size = 9.  # [sq deg]
    elif model == 'chime-frb':
        pixel_scale = 0.08  # Degrees per pixel [deg]
        beam_size = 180 * 80  # [sq deg]
        # If integrating over 180*80 degrees
        # Wolfram Alpha input:
        # integral_0^pi integral_0^(4*pi/9) sin(theta) d theta d phi
        # square radians to square degrees
        beam_size = 8522  # [sq deg]
    elif model == 'gaussian':
        pixel_scale = fwhm / 95  # Degrees per pixel [deg]
        beam_size = (pixel_scale * beam_array.shape[0])**2
    elif model == 'airy':
        pixel_scale = fwhm / 31  # Degrees per pixel [deg]
        beam_size = (pixel_scale * beam_array.shape[0])**2
    elif model.startswith('perfect'):
        pixel_scale = None
        beam_size = None
        beam_array = None
    else:
        raise ValueError('Beam model input not recognised.')

    return beam_size, pixel_scale, beam_array
Пример #5
0
"""
Series of galactic operations (doesn't that sound cool?!).

...as in converting coordinates, calculating DM etc.
"""

import ctypes as C
import math
import os
import numpy as np

from frbpoppy.paths import paths
from frbpoppy.log import pprint

# Import fortran libraries
uni_mods = os.path.join(paths.models(), 'universe/')
dm_mods = os.path.join(paths.models(), 'ne2001/')
loc = os.path.join(dm_mods, 'libne2001.so')
ne2001lib = C.CDLL(loc)
ne2001lib.dm_.restype = C.c_float


def frac_deg(ra, dec):
    """Convert coordinates expressed in hh:mm:ss to fractional degrees."""
    # Inspired by Joe Filippazzo calculator
    rh, rm, rs = [float(r) for r in ra.split(':')]
    ra = rh * 15 + rm / 4 + rs / 240
    dd, dm, ds = [float(d) for d in dec.split(':')]
    if dd < 0:
        sign = -1
    else:
Пример #6
0
    def intensity_profile(self, shape=1, dimensions=2, rep_loc='random'):
        """Calculate intensity profile.

        Args:
            shape (tuple): Usually the shape of frbs.s_peak
            dimensions (int): Use a 2D beampattern or a 1D one.
            rep_loc (str): 'same' or 'random'. Whether repeaters are observed
                in the same spot or a different spot

        Returns:
            array, array: intensity profile, offset from beam [arcmin]

        """
        # Calculate Full Width Half Maximum from beamsize
        self.fwhm = 2 * math.sqrt(
            self.beam_size_fwhm / math.pi) * 60  # [arcmin]
        offset = self.fwhm / 2  # Radius = diameter/2.

        if rep_loc == 'same':
            r = r = np.random.random(shape[0])
        else:
            r = np.random.random(shape)

        if dimensions == 2:  # 2D
            offset *= np.sqrt(r)
        elif dimensions == 1:  # 1D
            offset *= r

        # Allow for a perfect beam pattern in which all is detected
        if self.gain_pattern == 'perfect':
            int_pro = np.ones(shape)
            self.beam_size = self.beam_size_fwhm
            return int_pro, offset

        # Formula's based on 'Interferometry and Synthesis in Radio
        # Astronomy' by A. Richard Thompson, James. M. Moran and
        # George W. Swenson, JR. (Second edition), around p. 15

        max_offset = self.max_offset(self.n_sidelobes)
        self.beam_size = math.pi * (self.fwhm / 2 * max_offset /
                                    60)**2  # [sq degrees]

        if self.gain_pattern == 'gaussian':
            # Set the maximum offset equal to the null after a sidelobe
            # I realise this pattern isn't an airy, but you have to cut
            # somewhere
            offset *= max_offset
            alpha = 2 * math.sqrt(math.log(2))
            int_pro = np.exp(-(alpha * offset / self.fwhm)**2)
            return int_pro, offset

        elif self.gain_pattern == 'airy':
            # Set the maximum offset equal to the null after a sidelobe
            offset *= max_offset
            c = 299792458
            conv = math.pi / (60 * 180)  # Conversion arcmins -> radians
            eff_diam = c / (self.central_freq * 1e6 * conv * self.fwhm)
            a = eff_diam / 2  # Effective radius of telescope
            lamda = c / (self.central_freq * 1e6)
            ka = (2 * math.pi * a / lamda)
            kasin = ka * np.sin(offset * conv)
            int_pro = 4 * (j1(kasin) / kasin)**2
            return int_pro, offset

        elif self.gain_pattern in ['parkes', 'apertif']:

            place = paths.models() + f'/beams/{self.gain_pattern}.npy'
            beam_array = np.load(place)
            b_shape = beam_array.shape
            ran_x = np.random.randint(0, b_shape[0], shape)
            ran_y = np.random.randint(0, b_shape[1], shape)
            int_pro = beam_array[ran_x, ran_y]
            offset = np.sqrt((ran_x - b_shape[0] / 2)**2 +
                             (ran_y - b_shape[1] / 2)**2)

            # Scaling factors to correct for pixel scale
            if self.gain_pattern == 'apertif':  # 1 pixel = 0.94'
                offset *= 240 / 256  # [arcmin]
                self.beam_size = 25.
            if self.gain_pattern == 'parkes':  # 1 pixel = 54"
                offset *= 0.9  # [arcmin]
                self.beam_size = 9.

            return int_pro, offset

        else:
            pprint(f'Gain pattern "{self.gain_pattern}" not recognised')
Пример #7
0
    def create_table(self, parallel=True):
        """Create a lookup table for dispersion measure."""
        # Connect to database
        conn = sqlite3.connect(self.file_name)
        c = conn.cursor()

        # Set array of coordinates
        gls = np.arange(-180., 180. + self.step, self.step).round(1)
        gbs = np.arange(-90., 90. + self.step, self.step).round(1)
        dist = 0.1  # [Gpc]

        gls = gls.astype(np.float32)
        gbs = gbs.astype(np.float32)

        # Create database
        c.execute('create table dm ' + '(gl real, gb real, dm_mw real)')

        # Give an update on the progress
        m = [
            'Creating a DM lookup table', '  - Only needs to happen once',
            '  - Unfortunately pretty slow',
            '  - Prepare to wait for ~1.5h (4 cores)',
            '  - Time given as [time_spent<time_left] in (hh:)mm:ss',
            'Starting to calculate DM values'
        ]
        for n in m:
            pprint(n)

        n_opt = len(gls) * len(gbs)
        options = np.array(np.meshgrid(gls, gbs)).T.reshape(-1, 2)
        dm_mw = np.zeros(len(options)).astype(np.float32)

        def dm_tot(i, dm_mw):
            gl, gb = options[i]
            dm_mw[i] = go.ne2001_dist_to_dm(dist, gl, gb)

        if parallel:

            temp_path = os.path.join(paths.models(), 'universe/') + 'temp.mmap'
            self.temp_path = temp_path

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

            # Parallel process in order to populate array
            r = range(n_opt)
            j = min([4, os.cpu_count() - 1])
            print(os.cpu_count())
            Parallel(n_jobs=j)(delayed(dm_tot)(i, temp) for i in tqdm(r))

            # Map results
            r = np.concatenate((options, temp[:, np.newaxis]), axis=1)
            results = map(tuple, r.tolist())

            # Delete the temporary directory and contents
            try:
                os.remove(temp_path)
            except FileNotFoundError:
                print(f'Unable to remove {temp_path}')

        else:
            for i in tqdm(range(n_opt)):
                dm_tot(i, dm_mw)

            # Save results to database
            dm_mw = dm_mw.astype(np.float32)
            r = np.concatenate((options, dm_mw[:, np.newaxis]), axis=1)
            results = map(tuple, r.tolist())

        pprint('  - Saving results')
        c.executemany('insert into dm values (?,?,?)', results)

        # Make for easier searching
        c.execute('create index ix on dm (gl, gb)')

        # Save
        conn.commit()

        pprint('Finished DM table')
Пример #8
0
...as in converting coordinates, calculating DM etc.
"""

import ctypes as C
import csv
import math
import os
import random
import numpy as np

from frbpoppy.paths import paths
from frbpoppy.log import pprint

# Import fortran libraries
uni_mods = os.path.join(paths.models(), 'universe/')
dm_mods = os.path.join(paths.models(), 'dm/')
loc = os.path.join(dm_mods, 'libne2001.so')
ne2001lib = C.CDLL(loc)
ne2001lib.dm_.restype = C.c_float


def frac_deg(ra, dec):
    """Convert coordinates expressed in hh:mm:ss to fractional degrees."""
    # Inspired by Joe Filippazzo calculator
    rh, rm, rs = [float(r) for r in ra.split(':')]
    ra = rh*15 + rm/4 + rs/240
    dd, dm, ds = [float(d) for d in dec.split(':')]
    if dd < 0:
        sign = -1
    else: