def match(self, other, matchrad=None, nnearest=0, maxmatches=-1): if not isinstance(other, (NP.ndarray, Catalog)): raise TypeError('"other" must be a Nx2 numpy array or an instance of class Catalog.') if isinstance(other, Catalog): if (self.epoch == other.epoch) and (self.coords == other.coords): return GEOM.spherematch(self.location[:,0], self.location[:,1], other.location[:,0], other.location[:,1], matchrad, nnearest, maxmatches) else: raise ValueError('epoch and/or sky coordinate type mismatch. Cannot match.') else: return GEOM.spherematch(self.location[:,0], self.location[:,1], other[:,0], other[:,1], matchrad, nnearest, maxmatches)
def observe( self, timestamp, Tsys, bandpass, pointing_center, skymodel, tobs, pb_min=0.1, fov_radius=None, lst=None ): if bandpass.size != self.bp.shape[1]: raise ValueError("bandpass length does not match.") self.Tsys = self.Tsys + [Tsys] self.vis_rms_freq = self.vis_rms_freq + [ 2.0 * FCNST.k * Tsys / self.A_eff / self.eff_Q / NP.sqrt(2) / tobs / self.freq_resolution / CNST.Jy ] self.tobs = self.tobs + [tobs] self.lst = self.lst + [lst] if self.timestamp == []: self.bp = NP.asarray(bandpass).reshape(1, -1) self.pointing_center = NP.asarray(pointing_center).reshape(1, -1) else: self.bp = NP.vstack((self.bp, NP.asarray(bandpass).reshape(1, -1))) self.pointing_center = NP.vstack((self.pointing_center, NP.asarray(pointing_center).reshape(1, -1))) pointing_lon = self.pointing_center[-1, 0] pointing_lat = self.pointing_center[-1, 1] if self.skycoords == "radec": if self.pointing_coords == "hadec": if lst is not None: pointing_lon = lst - self.pointing_center[-1, 0] pointing_lat = self.pointing_center[-1, 1] else: raise ValueError( "LST must be provided. Sky coordinates are in RA-Dec format while pointing center is in HA-Dec format." ) elif self.pointing_coords == "altaz": pointing_lonlat = lst - GEOM.altaz2hadec(self.pointing_center[-1, :], self.latitude, units="degrees") pointing_lon = pointing_lonlat[0] pointing_lat = pointing_lonlat[1] elif self.skycoords == "hadec": if self.pointing_coords == "radec": if lst is not None: pointing_lon = lst - self.pointing_center[-1, 0] pointing_lat = self.pointing_center[-1, 1] else: raise ValueError( "LST must be provided. Sky coordinates are in RA-Dec format while pointing center is in HA-Dec format." ) elif self.pointing_coords == "altaz": pointing_lonlat = lst - GEOM.altaz2hadec(self.pointing_center[-1, :], self.latitude, units="degrees") pointing_lon = pointing_lonlat[0] pointing_lat = pointing_lonlat[1] else: if self.pointing_coords == "radec": if lst is not None: pointing_lonlat = GEOM.hadec2altaz( NP.asarray([lst - self.pointing_center[-1, 0], self.pointing_center[-1, 1]]), self.latitude, units="degrees", ) pointing_lon = pointing_lonlat[0] pointing_lat = pointing_lonlat[1] else: raise ValueError( "LST must be provided. Sky coordinates are in Alt-Az format while pointing center is in RA-Dec format." ) elif self.pointing_coords == "hadec": pointing_lonlat = GEOM.hadec2altaz(self.pointing_center, self.latitude, units="degrees") pointing_lon = pointing_lonlat[0] pointing_lat = pointing_lonlat[1] pointing_phase = 0.0 baseline_in_local_frame = self.baseline if self.baseline_coords == "equatorial": baseline_in_local_frame = GEOM.xyz2enu(self.baseline, self.latitude, "degrees") ptmp = self.pointing_center[-1, :] # Convert pointing center to Alt-Az coordinates if self.pointing_coords == "hadec": ptmp = GEOM.hadec2altaz(self.pointing_center[-1, :], self.latitude, units="degrees") elif self.pointing_coords == "radec": if lst is not None: ptmp = GEOM.hadec2altaz( NP.asarray([lst - self.pointing_center[-1, 0], self.pointing_center[-1, 1]]), self.latitude, units="degrees", ) else: raise ValueError( "LST must be provided. Sky coordinates are in Alt-Az format while pointing center is in RA-Dec format." ) ptmp = GEOM.altaz2dircos(ptmp, "degrees") # Convert pointing center to direction cosine coordinates pointing_phase = ( 2.0 * NP.pi * NP.dot(baseline_in_local_frame.reshape(1, -1), ptmp.reshape(-1, 1)) * self.channels.reshape(1, -1) / FCNST.c ) if fov_radius is None: fov_radius = 90.0 # PDB.set_trace() m1, m2, d12 = GEOM.spherematch( pointing_lon, pointing_lat, skymodel.catalog.location[:, 0], skymodel.catalog.location[:, 1], fov_radius, maxmatches=0, ) # if fov_radius is not None: # m1, m2, d12 = GEOM.spherematch(pointing_lon, pointing_lat, skymodel.catalog.location[:,0], skymodel.catalog.location[:,1], fov_radius, maxmatches=0) # else: # m1 = [0] * skymodel.catalog.location.shape[0] # m2 = xrange(skymodel.catalog.location.shape[0]) # d12 = GEOM.sphdist(NP.empty(skymodel.catalog.shape[0]).fill(pointing_lon), NP.empty(skymodel.catalog.shape[0]).fill(pointing_lat), skymodel.catalog.location[:,0], skymodel.catalog.location[:,1]) if len(d12) != 0: pb = NP.empty((len(d12), len(self.channels))) fluxes = NP.empty((len(d12), len(self.channels))) coords_str = self.skycoords if self.skycoords == "radec": coords_str = "altaz" source_positions = GEOM.hadec2altaz( NP.hstack( ( NP.asarray(lst - skymodel.catalog.location[m2, 0]).reshape(-1, 1), skymodel.catalog.location[m2, 1].reshape(-1, 1), ) ), self.latitude, "degrees", ) for i in xrange(len(self.channels)): # pb[:,i] = PB.primary_beam_generator(d12, self.channels[i]/1.0e9, 'degrees', self.telescope) pb[:, i] = PB.primary_beam_generator( source_positions, self.channels[i] / 1.0e9, "altaz", self.telescope ) fluxes[:, i] = ( skymodel.catalog.flux_density[m2] * (self.channels[i] / skymodel.catalog.frequency) ** skymodel.catalog.spectral_index[m2] ) geometric_delays = DLY.geometric_delay( baseline_in_local_frame, source_positions, altaz=(coords_str == "altaz"), hadec=(coords_str == "hadec"), latitude=self.latitude, ) self.geometric_delays = self.geometric_delays + [geometric_delays.reshape(len(source_positions))] phase_matrix = 2.0 * NP.pi * NP.repeat( geometric_delays.reshape(-1, 1), len(self.channels), axis=1 ) * NP.repeat(self.channels.reshape(1, -1), len(d12), axis=0) - NP.repeat(pointing_phase, len(d12), axis=0) skyvis = NP.sum( pb * fluxes * NP.repeat(NP.asarray(bandpass).reshape(1, -1), len(d12), axis=0) * NP.exp(-1j * phase_matrix), axis=0, ) if fov_radius is not None: self.obs_catalog_indices = self.obs_catalog_indices + [m2] # self.obs_catalog = self.obs_catalog + [skymodel.catalog.subset(m2)] else: print "No sources found in the catalog within matching radius. Simply populating the observed visibilities with noise." skyvis = NP.zeros((1, len(self.channels))) if self.timestamp == []: self.skyvis_freq = skyvis.reshape(1, -1) self.vis_noise_freq = self.vis_rms_freq[-1] * ( NP.random.randn(len(self.channels)).reshape(1, -1) + 1j * NP.random.randn(len(self.channels)).reshape(1, -1) ) self.vis_freq = self.skyvis_freq + self.vis_noise_freq else: self.skyvis_freq = NP.vstack((self.skyvis_freq, skyvis.reshape(1, -1))) self.vis_noise_freq = NP.vstack( ( self.vis_noise_freq, self.vis_rms_freq[-1] * ( NP.random.randn(len(self.channels)).reshape(1, -1) + 1j * NP.random.randn(len(self.channels)).reshape(1, -1) ), ) ) self.vis_freq = NP.vstack( (self.vis_freq, (self.skyvis_freq[-1, :] + self.vis_noise_freq[-1, :]).reshape(1, -1)) ) self.timestamp = self.timestamp + [timestamp]
theta, phi = HP.pix2ang(out_nside, NP.arange(HP.nside2npix(out_nside))) if dsm_coord == 'galactic': gc = SkyCoord(l=NP.degrees(phi), b=90.0 - NP.degrees(theta), unit='deg', frame='galactic') ec = gc.transform_to('icrs') echpx = SkyCoord(ra=NP.degrees(phi), dec=90.0 - NP.degrees(theta), unit='deg', frame='icrs') m1, m2, d12 = GEOM.spherematch(echpx.ra.degree, echpx.dec.degree, ec.ra.degree, ec.dec.degree, matchrad=NP.degrees( HP.nside2resol(out_nside)), nnearest=1, maxmatches=1) else: ec = SkyCoord(ra=NP.degrees(phi), dec=90.0 - NP.degrees(theta), unit='deg', frame='icrs') gc = ec.transform_to('galactic') gchpx = SkyCoord(l=NP.degrees(phi), b=90.0 - NP.degrees(theta), unit='deg', frame='galactic') m1, m2, d12 = GEOM.spherematch(gchpx.l.degree, gchpx.b.degree,
def match(self, other, matchrad=None, nnearest=0, maxmatches=-1): """ ------------------------------------------------------------------------- Match the source positions in an instance of class SkyModel with another instance of the same class to a specified angular radius using spherematch() in the geometry module Inputs: other [2-column numpy array instance of class SkyModel] Numpy array with two columns specifying the source positions in the other sky model or the other instance of class SkyModel with which the current instance is to be matched with matchrad [scalar] Angular radius (in degrees) inside which matching should occur. If not specified, if maxmatches is positive, all the nearest maxmatches neighbours are found, and if maxmatches is not positive, the nnearest-th nearest neighbour specified by nnearest is found. maxmatches [scalar] The maximum number of matches (all of the maxmatches nearest neighbours) that lie within matchrad are found. If matchrad is not specified, all the maxmatches nearest neighbours are found. If maxmatches < 0, and matchrad is not set, then the nnearest-th nearest neighbour is found (which defaults to the nearest neighbour if nnearest <= 0) nnearest [scalar] nnearest-th neighbour to be found. Used only when maxmatches is not positive. If matchrad is set, the specified neighbour is identified if found inside matchrad, otherwise the nnearest-th neighbour is identified regardless of the angular distance. Outputs: m1 [list] List of indices of matches in the current instance of class SkyModel m2 [list] List of indices of matches in the other instance of class SkyModel d12 [list] List of angular distances between the matched subsets of the two sky models indexed by m1 and m2 respectively ------------------------------------------------------------------------- """ if not isinstance(other, (NP.ndarray, SkyModel)): raise TypeError('"other" must be a Nx2 numpy array or an instance of class SkyModel.') if isinstance(other, SkyModel): if (self.epoch == other.epoch) and (self.coords == other.coords): return GEOM.spherematch(self.location[:,0], self.location[:,1], other.location[:,0], other.location[:,1], matchrad, nnearest, maxmatches) else: raise ValueError('epoch and/or sky coordinate type mismatch. Cannot match.') else: return GEOM.spherematch(self.location[:,0], self.location[:,1], other[:,0], other[:,1], matchrad, nnearest, maxmatches)