Example #1
0
class GradientCylinder(cylinder.UnpolarisedCylinderTelescope):

    min_spacing = config.Property(proptype=float, default=-1.0)
    max_spacing = config.Property(proptype=float, default=20.0)

    def feed_positions_cylinder(self, cylinder_index):

        if cylinder_index >= self.num_cylinders or cylinder_index < 0:
            raise Exception("Cylinder index is invalid.")

        nf = self.num_feeds

        # Parameters for gradient feedspacing
        a = self.wavelengths[
            -1] / 2.0 if self.min_spacing < 0.0 else self.min_spacing
        # b = 2 * (sp - a) / nf
        b = 2.0 * (self.max_spacing - a * (nf - 1)) / (nf - 1)**2.0

        pos = np.empty([nf, 2], dtype=np.float64)

        i = np.arange(nf)

        pos[:, 0] = cylinder_index * self.cylinder_spacing
        pos[:, 1] = a * i + 0.5 * b * i**2

        return pos
Example #2
0
class RestrictedBeam(cylinder.CylinderTelescope):

    beam_height = config.Property(proptype=typeutil.nonnegative_float, default=30.0)
    beam_type = config.Property(proptype=str, default='box')



    def bmask_gaussian(self, feed, freq):

        pointing = self.zenith
        bdist = (self._angpos - pointing[np.newaxis, :])
        bdist = np.abs(np.where((bdist[:, 1] < np.pi)[:, np.newaxis], bdist, bdist - np.array([0, 2*np.pi])[np.newaxis, :]))

        bmask =  gaussian_fwhm(bdist[:, 0], np.radians(self.beam_height))

        return bmask


    def bmask_box(self, feed, freq):

        pointing = self.zenith
        bdist = (self._angpos - pointing[np.newaxis, :])
        bdist = np.abs(np.where((bdist[:, 1] < np.pi)[:, np.newaxis], bdist, bdist - np.array([0, 2*np.pi])[np.newaxis, :]))
        bmask =  (np.abs(bdist[:, 0] / np.radians(self.beam_height)) < 0.5)

        return bmask
Example #3
0
class UnequalFeedsCylinder(cylinder.PolarisedCylinderTelescope):
    """A polarized unequal number of feeds cylinder array.

    A class for multiple side by side placed cylinders, each may have different number of equal spacing feeds.
    """

    num_cylinders = config.Property(proptype=typeutil.positive_int, default=3)
    num_feeds = config.Property(
        proptype=typeutil.positive_int_or_non_empty_list, default=[31, 32, 33])
    feed_spacing = config.Property(
        proptype=typeutil.positive_float_or_non_empty_list,
        default=[15.5 / 30, 0.5, 15.5 / 32])
    cylinder_width = config.Property(proptype=typeutil.positive_float,
                                     default=15.0)

    def feed_positions_cylinder(self, cylinder_index):
        """Get the feed positions on the specified cylinder.

        Parameters
        ----------
        cylinder_index : integer
            The cylinder index, an integer from 0 to self.num_cylinders.

        Returns
        -------
        feed_positions : np.ndarray
            The positions in the telescope plane of the receivers. Packed as
            [[u1, v1], [u2, v2], ...].
        """

        if cylinder_index >= self.num_cylinders or cylinder_index < 0:
            raise Exception("Cylinder index is invalid.")

        ncyl = self.num_cylinders
        if len(self.num_feeds) == 1:
            self.num_feeds *= ncyl
        if len(self.num_feeds) != ncyl:
            raise Exception('Invalid num_feeds.')

        if len(self.feed_spacing) == 1:
            self.feed_spacing *= ncyl
        if len(self.feed_spacing) != ncyl:
            raise Exception('Invalid feed_spacings.')

        nf = self.num_feeds[cylinder_index]
        sp = self.feed_spacing[cylinder_index]
        if self.non_commensurate:
            nf = nf - cylinder_index
            sp = sp / (nf - 1.0) * nf

        pos = np.empty([nf, 2], dtype=np.float64)

        pos[:, 0] = cylinder_index * self.cylinder_spacing
        pos[:, 1] = np.arange(nf) * sp

        return pos
Example #4
0
class CylinderExtra(cylinder.UnpolarisedCylinderTelescope):

    extra_feeds = config.Property(proptype=np.array, default=[])

    def feed_positions_cylinder(self, cylinder_index):

        pos = super(CylinderExtra,
                    self).feed_positions_cylinder(cylinder_index)

        nextra = self.extra_feeds.shape[0]

        pos2 = np.zeros((pos.shape[0] + nextra, 2), dtype=np.float64)

        pos2[nextra:] = pos

        pos2[:nextra, 0] = cylinder_index * self.cylinder_spacing
        pos2[:nextra, 1] = self.extra_feeds

        return pos2
Example #5
0
class PolarisedCylinderShift(cylinder.PolarisedCylinderTelescope):

    shift = config.Property(proptype=typeutil.float_or_non_empty_list,
                            default=0.0)

    def feed_positions_cylinder(self, cylinder_index):

        if cylinder_index >= self.num_cylinders or cylinder_index < 0:
            raise Exception("Cylinder index is invalid.")

        ncyl = self.num_cylinders
        if len(self.shift) == 1:
            self.shift *= ncyl
        if len(self.shift) != ncyl:
            raise Exception('Invalid shifts.')

        pos = super(PolarisedCylinderShift,
                    self).feed_positions_cylinder(cylinder_index)
        v_shift = np.ones_like(pos)
        v_shift[:, 0] = 0.0  # u-direction doesn't change
        pos += self.shift[cylinder_index] * v_shift

        return pos
Example #6
0
File: gmrt.py Project: wufq/tlpipe
class GmrtArray(telescope.TransitTelescope):
    """A Telescope describing an interferometric array of dishes.

    Attributes
    ----------
    gridu, gridv : integer
        Number of dishes in u and v directions.
    dish_width : scalar
        Width of the dish in metres.
    """

    fwhm = 3.1  # degrees

    freq_lower = 139.33
    freq_upper = 156.00
    num_freq = 64

    _pos_file = os.path.dirname(__file__) + '/gmrtpositions.dat'
    _compact = True

    _bc_freq = None
    _bc_nside = None

    _positions = None

    pointing = config.Property(proptype=float, default=0.0)

    dish_width = 45.0

    tsys_flat = 582.0

    minlength = 0.0
    maxlength = 600.0

    def __init__(self, pointing=0.0):
        super(GmrtArray, self).__init__(latitude=19.09, longitude=74.05)

        self._positions = np.loadtxt(self._pos_file)
        #self._positions = self._positions[np.where((self._positions**2).sum(axis=1)**0.5 < 1000)]
        self.pointing = pointing

    @property
    def u_width(self):
        return self.dish_width

    @property
    def v_width(self):
        return self.dish_width

    def beam(self, feed, freq):
        """Beam for a particular feed.

        Parameters
        ----------
        feed : integer
            Index for the feed.
        freq : integer
            Index for the frequency.

        Returns
        -------
        beam : np.ndarray
            A Healpix map (of size self._nside) of the beam. Potentially
            complex.
        """

        if self._bc_freq != freq or self._bc_nside != self._nside:
            sigma = np.radians(self.fwhm) / (8.0 * np.log(2.0))**0.5 / (
                self.frequencies[freq] / 150.0)

            pointing = np.array(
                [np.pi / 2.0 - np.radians(self.pointing), self.zenith[1]])

            x2 = (1.0 - coord.sph_dot(self._angpos, pointing)**2) / (4 *
                                                                     sigma**2)
            self._bc_map = np.exp(-x2)

            self._bc_freq = freq
            self._bc_nside = self._nside

        return self._bc_map

    beamx = beam
    beamy = beam

    @property
    def _single_feedpositions(self):
        """The set of feed positions in the CMU telescope.

        Returns
        -------
        feedpositions : np.ndarray
            The positions in the telescope plane of the receivers. Packed as
            [[u1, v1], [u2, v2], ...].
        """
        if self._positions is None:
            self._positions = np.loadtxt(self._pos_file)

        return self._positions
Example #7
0
class FocalPlaneArray(telescope.UnpolarisedTelescope):


    beam_num_u = config.Property(proptype=typeutil.positive_int, default=10)
    beam_num_v = config.Property(proptype=typeutil.positive_int, default=10)


    beam_spacing_u = config.Property(proptype=typeutil.positive_float, default=0.1)
    beam_spacing_v = config.Property(proptype=typeutil.positive_float, default=0.1)

    beam_size = config.Property(proptype=typeutil.positive_float, default=0.1)
    beam_pivot = config.Property(proptype=typeutil.positive_float, default=400.0)

    beam_freq_scale = config.Property(proptype=bool, default=True)

    square_beam = config.Property(proptype=bool, default=False)


    @property
    def beam_pointings(self):
        pnt_u = self.beam_spacing_u * (np.arange(self.beam_num_u) - (self.beam_num_u - 1) / 2.0)
        pnt_v = self.beam_spacing_v * (np.arange(self.beam_num_v) - (self.beam_num_v - 1) / 2.0)

        pnt_u = np.radians(pnt_u) + self.zenith[1]
        pnt_v = np.radians(pnt_v) + self.zenith[0]

        pnt = np.zeros((self.beam_num_u, self.beam_num_v, 2))
        pnt[:, :, 1] = pnt_u[:, np.newaxis]
        pnt[:, :, 0] = pnt_v[np.newaxis, :]

        return pnt.reshape(-1, 2)

    #== Methods for calculating the unique baselines ===


    @util.cache_last
    def beam_gaussian(self, feed, freq):

        pointing = self.beam_pointings[feed]
        if self.beam_freq_scale:
            fwhm = self.beam_size * self.frequencies[freq] / self.beam_pivot
        else:
            fwhm = self.beam_size

        return gaussian_beam(self._angpos, pointing, fwhm)


    @util.cache_last
    def beam_square(self, feed, freq):

        pointing = self.beam_pointings[feed]
        bdist = (self._angpos - pointing[np.newaxis, :])
        bdist = np.abs(np.where((bdist[:, 1] < np.pi)[:, np.newaxis], bdist, bdist - np.array([0, 2*np.pi])[np.newaxis, :])) / np.radians(self.beam_size)
        #bdist = np.abs(np.where((bdist[:, 1] < np.pi)[:, np.newaxis], bdist, bdist - np.array([0, 2*np.pi])[np.newaxis, :])) / np.radians(self.beam_size)
        beam = np.logical_and(bdist[:, 0] < 0.5, bdist[:, 1] < 0.5).astype(np.float64)

        return beam

    def beam(self, feed, freq):
        if self.square_beam:
            return self.beam_square(feed, freq)
        else:
            return self.beam_gaussian(feed, freq)


    @property
    def dish_width(self):
        lpivot = (units.c / self.beam_pivot * 1e-6)
        return (lpivot / np.radians(self.beam_size))

    @property
    def u_width(self):
        return self.dish_width

    @property
    def v_width(self):
        return self.dish_width

    @property
    def nfeed(self):
        return self.beam_num_u * self.beam_num_v

    @property
    def feedpositions(self):
        """Feed positions (all zero in FPA).
        """
        return np.zeros([self.nfeed, 2])

    def _unique_beams(self):

        beam_mask = np.identity(self.nfeed, dtype=np.bool)
        beam_map = telescope._remap_keyarray(np.diag(np.arange(self.nfeed)), mask=beam_mask)

        return beam_map, beam_mask
Example #8
0
class PersonWithPet(Person):
    petname = config.Property(default='Molly', proptype=str)
    petage = 36
Example #9
0
class Person(config.Reader):
    name = config.Property(default='Bill', proptype=str)
    age = config.Property(default=26, proptype=float, key='ageinyears')