def _setup_gridbeam_interpolation(self): # grid beam coordinates self._x_grid = self._primary_beam.phi[:] self._y_grid = self._primary_beam.theta[:] # celestial coordinates angpos = hputil.ang_positions(self._nside) x_cel = coord.sph_to_cart(angpos).T # rotate to telescope coords # first align y with N, then polar axis with NCP self._x_tel = cylbeam.rotate_ypr( (1.5 * np.pi, np.radians(90.0 - self.latitude), 0), *x_cel) # mask any pixels outside grid x_t, y_t, z_t = self._x_tel self._pix_mask = ((z_t > 0) & (np.abs(x_t) < np.abs(self._x_grid.max())) & (np.abs(y_t) < np.abs(self._y_grid.max()))) # pre-compute polarisation pattern # taken from driftscan zenith = np.array([np.pi / 2.0 - np.radians(self.latitude), 0.0]) that, phat = coord.thetaphi_plane_cart(zenith) xhat, yhat, zhat = cylbeam.rotate_ypr([-self.rotation_angle, 0.0, 0.0], phat, -that, coord.sph_to_cart(zenith)) self._pvec_x = cylbeam.polpattern(angpos, xhat) self._pvec_y = cylbeam.polpattern(angpos, yhat)
def beam(self, feed, freq): # bm = visibility.cylinder_beam(self._angpos, self.zenith, # self.cylinder_width / self.wavelengths[freq]) # 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 uhatc, vhatc = visibility.uv_plane_cart(self.zenith) ## Note sinc function is normalised hence lack of pi bmh = np.sinc( np.inner( coord.sph_to_cart(self._angpos), self.cylinder_width * uhatc / self.wavelengths[freq], )) bmv = np.where( np.abs(np.inner(coord.sph_to_cart(self._angpos), vhatc)) * 180.0 / np.pi < self.vwidth / 2.0, np.ones_like(bmh), np.zeros_like(bmh), ) bmv = healpy.smoothing(bmv, degree=True, fwhm=(self.vwidth / 10.0)) return bmv * bmh
def beam(self, feed, freq): # bm = visibility.cylinder_beam(self._angpos, self.zenith, # self.cylinder_width / self.wavelengths[freq]) # 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 uhatc, vhatc = visibility.uv_plane_cart(self.zenith) ## Note sinc function is normalised hence lack of pi bmh = np.sinc(np.inner(coord.sph_to_cart(self._angpos), self.cylinder_width * uhatc / self.wavelengths[freq])) bmv = np.where( np.abs(np.inner(coord.sph_to_cart(self._angpos), vhatc)) * 180.0 / np.pi < self.vwidth / 2.0, np.ones_like(bmh), np.zeros_like(bmh), ) bmv = healpy.smoothing(bmv, degree=True, fwhm=(self.vwidth / 10.0)) return bmv * bmh
def polpattern(angpos, dipole): """Calculate the unit polarisation vectors at each position on the sphere for a dipole direction. Parameters ---------- angpos : np.ndarray[npoints, 2] The positions on the sphere to calculate at. dipole : np.ndarray[2 or 3] The unit vector for the dipole direction. If length is 2, assume in vector is in spherical polars, if 3 it's cartesian. Returns ------- vectors : np.ndarray[npoints, 2] Vector at each point in thetahat, phihat basis. """ if dipole.shape[0] == 2: dipole = coord.sph_to_cart(dipole) thatp, phatp = coord.thetaphi_plane_cart(angpos) polvec = np.zeros(angpos.shape[:-1] + (2,), dtype=angpos.dtype) # Calculate components by projecting into basis. polvec[..., 0] = np.dot(thatp, dipole) polvec[..., 1] = np.dot(phatp, dipole) # Normalise length to unity. coord.norm_vec2(polvec) return polvec
def beam_y(angpos, zenith, width, fwhm_e, fwhm_h, rot=[0.0, 0.0, 0.0]): """Beam amplitude across the sky for the Y dipole (points N). Using ExpTan model. Parameters ---------- angpos : np.ndarray[npoints, 2] Angular position on the sky. zenith : np.ndarray[2] Position of zenith in spherical polars. width : scalar Cylinder width in wavelengths. fwhm_e, fwhm_h Full with at half power in the E and H planes of the antenna. Returns ------- beam : np.ndarray[npoints, 2] Amplitude vector of beam at each point (in thetahat, phihat) """ # Reverse as thetahat points south that, phat = coord.thetaphi_plane_cart(zenith) xhat, yhat, zhat = rotate_ypr(rot, phat, -that, coord.sph_to_cart(zenith)) pvec = polpattern(angpos, yhat) amp = beam_amp(angpos, zenith, width, fwhm_h, fwhm_e, rot=rot) return amp[:, np.newaxis] * pvec
def polpattern(angpos, dipole): """Calculate the unit polarisation vectors at each position on the sphere for a dipole direction. Parameters ---------- angpos : np.ndarray[npoints, 2] The positions on the sphere to calculate at. dipole : np.ndarray[2 or 3] The unit vector for the dipole direction. If length is 2, assume in vector is in spherical polars, if 3 it's cartesian. Returns ------- vectors : np.ndarray[npoints, 2] Vector at each point in thetahat, phihat basis. """ if dipole.shape[0] == 2: dipole = coord.sph_to_cart(dipole) thatp, phatp = coord.thetaphi_plane_cart(angpos) polvec = np.zeros(angpos.shape[:-1] + (2,), dtype=angpos.dtype) # Calculate components by projecting into basis. polvec[..., 0] = np.dot(thatp, dipole) polvec[..., 1] = np.dot(phatp, dipole) # Normalise length to unity. polvec = polvec * (np.sum(polvec**2, axis=-1)**-0.5)[..., np.newaxis] return polvec
def cylinder_beam(sph_arr, zenith, cylwidth): r"""The beam function for a cylinder aligned N-S. Beam will be a thin strip in the N-S direction (controlled by the cylinder width in the E-W direction). Parameters ---------- sph_arr : np.ndarray Angular positions (in spherical polar co-ordinates). zenith : np.ndarray The zenith vector in spherical polar-coordinates. cylwidth : scalar The effective cylinder width. Returns ------- beam : np.ndarray The beam function at each angular position. """ # Construct uhat. uhatc, vhatc = uv_plane_cart(zenith) ## Note sinc function is normalised hence lack of pi return np.sinc(np.inner(coord.sph_to_cart(sph_arr), cylwidth * uhatc))
def fringe(sph_arr, zenith, baseline): r"""The fringe for a specified baseline at each angular position. Parameters ---------- sph_arr : np.ndarray Angular positions (in spherical polar co-ordinates). zenith : np.ndarray The zenith vector in spherical polar-coordinates. baseline : array_like The baseline to calculate, given in (u,v) coordinates. Returns ------- fringe : np.ndarray The fringe. Notes ----- For each position :math:`\hat{n}` in `sph_arr` calculate: .. math:: \exp{\left(2\pi i * \hat{n}\cdot u_{12}\right)} """ uhatc, vhatc = uv_plane_cart(zenith) uv = baseline[0] * uhatc + baseline[1] * vhatc return np.exp(2j*np.pi* np.inner(coord.sph_to_cart(sph_arr), uv))
def fringe(sph_arr, zenith, baseline): r"""The fringe for a specified baseline at each angular position. Parameters ---------- sph_arr : np.ndarray Angular positions (in spherical polar co-ordinates). zenith : np.ndarray The zenith vector in spherical polar-coordinates. baseline : array_like The baseline to calculate, given in (u,v) coordinates. Returns ------- fringe : np.ndarray The fringe. Notes ----- For each position :math:`\hat{n}` in `sph_arr` calculate: .. math:: \exp{\left(2\pi i * \hat{n}\cdot u_{12}\right)} """ uhatc, vhatc = uv_plane_cart(zenith) uv = baseline[0] * uhatc + baseline[1] * vhatc return np.exp(2j * np.pi * np.inner(coord.sph_to_cart(sph_arr), uv))
def beam_amp(angpos, zenith, width, fwhm_x, fwhm_y, rot=[0.0, 0.0, 0.0]): """Beam amplitude across the sky. Parameters ---------- angpos : np.ndarray[npoints] Angular position on the sky. zenith : np.ndarray[2] Position of zenith on spherical polars. width : scalar Cylinder width in wavelengths. fwhm_x, fwhm_y : scalar Full with at half power in the x and y directions. rot : [yaw, pitch, roll] Rotation to apply to cylinder in yaw, pitch and roll from North. Returns ------- beam : np.ndarray[npoints] Amplitude of beam at each point. """ global _beam_pat_cache if _beam_pat_cache is None: _beam_pat_cache = cachetools.LRUCache(maxsize=100) that, phat = coord.thetaphi_plane_cart(zenith) xhat, yhat, zhat = rotate_ypr(rot, phat, -that, coord.sph_to_cart(zenith)) yplane = lambda t: beam_exptan(t, fwhm_y) # Get the diffracted beam pattern from the cache, or calculate it if it's not # present bpkey = (fwhm_x, width) if bpkey not in _beam_pat_cache: xplane = lambda t: beam_exptan(t, fwhm_x) _beam_pat_cache[bpkey] = fraunhofer_cylinder(xplane, width) beampat = _beam_pat_cache[bpkey] cvec = coord.sph_to_cart(angpos) horizon = (np.dot(cvec, coord.sph_to_cart(zenith)) > 0.0).astype(np.float64) ew_amp = beampat(np.dot(cvec, xhat)) ns_amp = yplane(np.dot(cvec, yhat)) return ew_amp * ns_amp * horizon
def beam_amp(angpos, zenith, width, fwhm_x, fwhm_y, rot=[0.0, 0.0, 0.0]): """Beam amplitude across the sky. Parameters ---------- angpos : np.ndarray[npoints] Angular position on the sky. zenith : np.ndarray[2] Position of zenin on spherical polars. width : scalar Cylinder width in wavelengths. fwhm_x, fwhm_y : scalar Full with at half power in the x and y directions. rot : [yaw, pitch, roll] Rotation to apply to cylinder in yaw, pitch and roll from North. Returns ------- beam : np.ndarray[npoints] Amplitude of beam at each point. """ that, phat = coord.thetaphi_plane_cart(zenith) xhat, yhat, zhat = rotate_ypr(rot, phat, -that, coord.sph_to_cart(zenith)) xplane = lambda t: beam_exptan(t, fwhm_x) yplane = lambda t: beam_exptan(t, fwhm_y) beampat = fraunhofer_cylinder(xplane, width) cvec = coord.sph_to_cart(angpos) horizon = (np.dot(cvec, coord.sph_to_cart(zenith)) > 0.0).astype( np.float64) ew_amp = beampat(np.dot(cvec, xhat)) ns_amp = yplane(np.arcsin(np.dot(cvec, yhat))) return ew_amp * ns_amp * horizon
def beam_amp(angpos, zenith, width, fwhm_x, fwhm_y, rot=[0.0, 0.0, 0.0]): """Beam amplitude across the sky. Parameters ---------- angpos : np.ndarray[npoints] Angular position on the sky. zenith : np.ndarray[2] Position of zenin on spherical polars. width : scalar Cylinder width in wavelengths. fwhm_x, fwhm_y : scalar Full with at half power in the x and y directions. rot : [yaw, pitch, roll] Rotation to apply to cylinder in yaw, pitch and roll from North. Returns ------- beam : np.ndarray[npoints] Amplitude of beam at each point. """ that, phat = coord.thetaphi_plane_cart(zenith) xhat, yhat, zhat = rotate_ypr(rot, phat, -that, coord.sph_to_cart(zenith)) xplane = lambda t: beam_exptan(t, fwhm_x) yplane = lambda t: beam_exptan(t, fwhm_y) beampat = fraunhofer_cylinder(xplane, width) cvec = coord.sph_to_cart(angpos) horizon = (np.dot(cvec, coord.sph_to_cart(zenith)) > 0.0).astype(np.float64) ew_amp = beampat(np.dot(cvec, xhat)) ns_amp = yplane(np.arcsin(np.dot(cvec, yhat))) return (ew_amp * ns_amp * horizon)