def set_geometry(self,healpix=True): from astropy_healpix import HEALPix from astropy.coordinates import SkyCoord import astropy.coordinates as cc from numpy import unique self.ra_min = self.ra - 1.0 self.ra_max = self.ra + 1.0 self.dec_min = self.dec - 1.0 self.dec_max = self.dec + 1.0 if healpix: hp = HEALPix(nside=self.nside, order='nested', frame=cc.ICRS()) self.healpix_indices = [] ra = [self.ra_min,self.ra_min,self.ra_max,self.ra_max] dec = [self.dec_min,self.dec_max,self.dec_min,self.dec_max] dx = self.ra_max - self.ra_min dy = self.dec_max - self.dec_min for i in arange(500): ra.append(self.ra_min+(random.random()*dx)) dec.append(self.dec_min+(random.random()*dy)) for r,d in zip(ra,dec): self.healpix_indices.append(hp.skycoord_to_healpix(SkyCoord(r,d,unit='deg'))) self.healpix_indices = unique(self.healpix_indices) return
def annular_search(self): from astropy_healpix import HEALPix from astropy.coordinates import SkyCoord import astropy.coordinates as cc hp = HEALPix(nside=self.nside, order='nested', frame=cc.ICRS()) self.set_geometry(healpix=False) r_min = self.ra_min - self.ra r_max = self.ra_max - self.ra radius = self.ra_max - self.ra #get the healpix IDs covering an annulus centred on self.ra,dec in_annulus = [] self.healpix_indices = [] print 'Populating annulus and determining HEALPix coverage...' while (len(in_annulus)) < 500: rnd_ra = self.ra + (2 * (random.random() - 0.5) * radius) rnd_dec = self.dec + (2 * (random.random() - 0.5) * radius) rnd_dist = (((rnd_ra - self.ra)**2) + ((rnd_dec - self.dec)**2))**0.5 if rnd_dist > r_min: if rnd_dist < r_max: self.healpix_indices.append( hp.skycoord_to_healpix( SkyCoord(rnd_ra, rnd_dec, unit='deg'))) in_annulus.append([rnd_ra, rnd_dec]) #print len(in_annulus) print '....done' self.healpix_indices = unique(self.healpix_indices) print self.healpix_indices self.retrieve_guidecats() target = self.select_target(annular=True) return target
def test_calc_healpix_for_region(): ahp = HEALPix(nside=NSIDE, order='ring', frame=TETE()) ahp_test = HEALPix(nside=NSIDE, order='ring', frame=TETE()) for target_params in [LMC_params, SMC_params]: r = generate_sky_maps.CelestialRegion(target_params) r.calc_healpixels_for_region(ahp) region_pixels = np.unique(r.pixels) corners = calc_box_corners_astropy(target_params) n_points = 500 l = np.linspace(corners[0], corners[1], n_points) * u.deg b = np.linspace(corners[2], corners[3], n_points) * u.deg LL, BB = np.meshgrid(l, b) coords = np.stack((LL.flatten(), BB.flatten()), axis=1) pointings = SkyCoord(coords[:, 0], coords[:, 1], frame=Galactic()) coords_in_region = calc_points_in_circle_original( target_params, coords) pixels = ahp_test.skycoord_to_healpix(coords_in_region) test_pixels = np.unique(pixels.flatten()) assert np.all(region_pixels == test_pixels)
def set_geometry(self, healpix=True): from astropy_healpix import HEALPix from astropy.coordinates import SkyCoord import astropy.coordinates as cc from numpy import unique if self.lifu: self.g_dx = 3.75 self.g_dy = 4.0 #testing - let's make it bigger # self.g_dx = 17.0 # self.g_dy = 20.0 #needs to be about 20x larger in area # self.g_dx = 16.8 # self.g_dy = 17.9 self.ra_max = self.ra + ((27.7 + (0.5 * self.g_dx)) / 60.0) self.ra_min = self.ra + ((27.7 - (0.5 * self.g_dx)) / 60.0) self.dec_max = self.dec + ((0.5 * self.g_dy) / 60.0) self.dec_min = self.dec - ((0.5 * self.g_dy) / 60.0) self.ra_gc0 = self.ra + (27.7 / 60.0) self.dec_gc0 = self.dec else: self.ra_min = self.ra - 1.0 self.ra_max = self.ra + 1.0 self.dec_min = self.dec - 1.0 self.dec_max = self.dec + 1.0 if healpix: hp = HEALPix(nside=self.nside, order='nested', frame=cc.ICRS()) self.healpix_indices = [] ra = [self.ra_min, self.ra_min, self.ra_max, self.ra_max] dec = [self.dec_min, self.dec_max, self.dec_min, self.dec_max] dx = self.ra_max - self.ra_min dy = self.dec_max - self.dec_min for i in arange(500): ra.append(self.ra_min + (random.random() * dx)) dec.append(self.dec_min + (random.random() * dy)) for r, d in zip(ra, dec): self.healpix_indices.append( hp.skycoord_to_healpix(SkyCoord(r, d, unit='deg'))) self.healpix_indices = unique(self.healpix_indices) return
def plot_statistics_on_sky(data_dir, statistics): NSIDE=64 ahp = HEALPix(nside=NSIDE, order='ring', frame=TETE()) coords = SkyCoord(statistics[:,0]*u.deg, statistics[:,1]*u.deg, frame='icrs') pixel_index = ahp.skycoord_to_healpix(coords) NPIX = hp.nside2npix(NSIDE) pixels = np.zeros((NPIX), dtype='int') pixels[pixel_index] = statistics[:,5] fig = plt.figure(1,(10,10)) hp.mollview(pixels, title="Gaia Parallax Distribution") hp.graticule() plt.tight_layout() plt.savefig(path.join(data_dir,'gaia_parallax_stddev_map.png')) plt.close(1)
def healpix_pixels_in_sky_image(geometry: WCSGeometry, order: int, healpix_frame: str) -> np.ndarray: """Compute HEALPix pixels within a given sky image. The algorithm used is as follows: * compute the sky position of every pixel in the image using the given ``geometry`` * compute the HEALPix pixel index for every pixel using `healpy.pixelfunc.ang2pix` * compute the unique set of HEALPix pixel values that occur via `numpy.unique` Parameters ---------- geometry : `WCSGeometry` Sky image WCS geometry order : int HEALPix order healpix_frame : {'icrs', 'galactic', 'ecliptic'} HEALPix coordinate frame Returns ------- pixels : `numpy.ndarray` HEALPix pixel numbers Examples -------- >>> from astropy.coordinates import SkyCoord >>> from hips import WCSGeometry >>> from hips.utils.healpix import healpix_pixels_in_sky_image >>> skycoord = SkyCoord(10, 20, unit="deg") >>> geometry = WCSGeometry.create( ... skydir=skycoord, shape=(10, 20), ... coordsys='CEL', projection='AIT', ... cdelt=1.0, crpix=(1., 1.), ... ) >>> healpix_pixels_in_sky_image(geometry, order=3, healpix_frame='galactic') array([321, 611, 614, 615, 617, 618, 619, 620, 621, 622]) """ hp = HEALPix(nside=2 ** order, order='nested', frame=healpix_frame) skycoord = geometry.pixel_skycoords # .transform_to(healpix_frame) ipix = hp.skycoord_to_healpix(skycoord) return np.unique(ipix)
class overlapRGESFootprintMetric(maf.BaseMetric): """Metric to evaluate the survey footprint overlap survey region for the Roman Galactic Exoplanet Survey Derived from the SpacialOverlapMetric by Michael Lund and revised and updated by Rachel Street Parameters ---------- fieldRA : float, RA in degrees of a given pointing fieldDec : float, Dec in degrees of a given pointing filter : str, filter bandpass used for a given observation """ def __init__(self, cols=['fieldRA', 'fieldDec', 'filter', 'fiveSigmaDepth'], metricName='overlapRGESFootprintMetric', **kwargs): """Kwargs must contain: filters list Filterset over which to compute the metric """ self.ra_col = 'fieldRA' self.dec_col = 'fieldDec' self.filterCol = 'filter' self.m5Col = 'fiveSigmaDepth' self.filters = ['u', 'g', 'r', 'i', 'z', 'y'] self.magLimit = 22.0 cwd = os.getcwd() self.create_map() self.load_RGES_footprint() super().__init__(col=cols, metricName=metricName) def create_map(self): self.NSIDE = 64 self.ahp = HEALPix(nside=self.NSIDE, order='ring', frame=TETE()) def load_RGES_footprint(self): # Location of the RGES survey field in Galactic Coordinates. # This is defined as a single pointing, since the survey # region will be ~2sq deg and fully encompassed within a single Rubin pointing l_center = 2.216 b_center = -3.14 l_width = 3.5 b_height = 3.5 n_points = 50 # Represent coordinate pointings within this region as a meshgrid halfwidth_l = l_width / 2.0 halfheight_b = b_height / 2.0 l_min = max((l_center - halfwidth_l), 0) l_max = min((l_center + halfwidth_l), 360.0) b_min = max((b_center - halfheight_b), -90.0) b_max = min((b_center + halfheight_b), 90.0) l = np.linspace(l_min, l_max, n_points) * u.deg b = np.linspace(b_min, b_max, n_points) * u.deg LL, BB = np.meshgrid(l, b) coords = SkyCoord(LL, BB, frame=Galactic()) # Calculate the corresponding HEALpixels pixels = self.ahp.skycoord_to_healpix(coords) self.RGES_pixels = np.unique(pixels.flatten()) def run(self, dataSlice, slicePoint=None): # Only count observations with adequate S/N match = np.where(dataSlice[self.m5Col] >= self.magLimit)[0] # Extract the RA,Dec coordinates of the fields surveyed by matching observations the dataSlice # and calculate which HEALpixels these correspond to coords_icrs = SkyCoord(dataSlice[self.ra_col][match], dataSlice[self.dec_col][match], frame='icrs', unit=(u.deg, u.deg)) coords_gal = coords_icrs.transform_to(Galactic()) surveyed_pixels = self.ahp.skycoord_to_healpix(coords_gal) surveyed_pixels = np.unique(surveyed_pixels.flatten()) # Calculate the fraction of the RGES survey pixels included in the surveyed pixels overlapping_pixels = set(self.RGES_pixels).intersection( set(surveyed_pixels)) metric_value = float(len(overlapping_pixels)) / float( len(self.RGES_pixels)) return metric_value
def DeclRaToIndex(decl, RA): return hp.pixelfunc.ang2pix(NSIDE, np.radians(-decl + 90.), np.radians(360. - RA)) # Test location in the Galactic Bulge in decimal degrees test_ra = (17.0 + 57.0 / 60.0 + 34.0 / 3600.0) * 15.0 test_dec = (29.0 + 13.0 / 60.0 + 15.0 / 3600.0) * -1.0 print('Input test coordinates, RA, DEC: ', test_ra, test_dec, 'deg') # Should be ring order by default phi = np.deg2rad(test_ra) theta = np.deg2rad(test_dec) + np.pi / 2.0 print('Phi, theta = ', phi, theta, ' rads') pixels_hp = hp.ang2pix(NSIDE, theta, phi, nest=False) print('Pixels from Healpy: ', pixels_hp) (return_dec, return_ra) = IndexToDeclRa(pixels_hp) print('Recalculating RA, Dec in deg from pixel index: ', return_ra, return_dec) #(theta, phi) = hp.pix2ang(NSIDE, ipix) #ra = np.rad2deg(phi) #dec = np.rad2deg(0.5 * np.pi - theta) # Astropy-healpix solution ahp = HEALPix(nside=NSIDE, order='ring', frame=Galactic()) coords_icrs = SkyCoord(test_ra, test_dec, frame="icrs", unit=(u.deg, u.deg)) coords_gal = coords_icrs.transform_to(Galactic()) pixels_ap = ahp.skycoord_to_healpix(coords_icrs) print('Pixels from astropy: ', pixels_ap)
def from_image(cls, header, max_norder, mask=None): """ Creates a `~mocpy.moc.MOC` from an image stored as a FITS file. Parameters ---------- header : `astropy.io.fits.Header` FITS header containing all the info of where the image is located (position, size, etc...) max_norder : int The moc resolution. mask : `numpy.ndarray`, optional A boolean array of the same size of the image where pixels having the value 1 are part of the final MOC and pixels having the value 0 are not. Returns ------- moc : `~mocpy.moc.MOC` The resulting MOC. """ # load the image data height = header['NAXIS2'] width = header['NAXIS1'] # use wcs from astropy to locate the image in the world coordinates w = wcs.WCS(header) if mask is not None: # We have an array of pixels that are part of of survey y, x = np.where(mask) pix_crd = np.dstack((x, y))[0] else: # If we do not have a mask array we create the moc of all the image # step_pix = 1 """ Coords returned by wcs_pix2world method correspond to pixel centers. We want to retrieve the moc pix crossing the borders of the image so we have to add 1/2 to the pixels coords before computing the lonlat. The step between two pix_crd is set to `step_pix` but can be diminished to have a better precision at the borders so that all the image is covered (a too big step does not retrieve all the moc pix crossing the borders of the image). """ x, y = np.mgrid[0.5:(width + 0.5 + step_pix):step_pix, 0.5:(height + 0.5 + step_pix):step_pix] pix_crd = np.dstack((x.ravel(), y.ravel()))[0] frame = wcs.utils.wcs_to_celestial_frame(w) world_pix_crd = SkyCoord(w.wcs_pix2world(pix_crd, 1), unit='deg', frame=frame) max_norder = np.uint8(max_norder) hp = HEALPix(nside=(1 << max_norder), order='nested', frame=ICRS()) ipix = hp.skycoord_to_healpix(world_pix_crd) ipix = ipix.astype(np.uint64) # remove doubles ipix = np.unique(ipix) shift = np.uint8(2) * (AbstractMOC.HPY_MAX_NORDER - max_norder) intervals_arr = np.vstack((ipix << shift, (ipix + np.uint64(1)) << shift)).T # This MOC will be consistent when one will do operations on the moc (union, inter, ...) or # simply write it to a fits or json file interval_set = IntervalSet(intervals_arr) return cls(interval_set=interval_set)
def map2healpix(mapname1, mapname2, mapname3, sb, freq): """ Function loading three maps at a given sideband and frequency to project their pixels into a healpix format to obtain a full-sky map with all three maps. Assuming that all three input maps have the same resolution, to compute the Nside parameter. -------------------- mapname1: str Filename of first map file to read (.h5 format HDF-file) mapname2: str Filename of second map file to read (.h5 format HDF-file) mapname3: str Filename of third map file to read (.h5 format HDF-file) sb: int Number of sideband to use (base 1 not 0, i.e first and second sideband are sb = 1 and sb = 2 respectively) freq: int Number of the frequency channel to use (base 1 not 0, i.e. first and second are freq = 1 and freq = 2 respectively) """ x1, y1, hits1 = readMap(mapname1) # Angular coord and # of hits per px of 1st map x2, y2, hits2 = readMap(mapname2) # Angular coord and # of hits per px of 2nd map x3, y3, hits3 = readMap(mapname3) # Angular coord and # of hits per px of 3rd map dx = np.array([x1[1] - x1[0], x2[1] - x2[0], x3[1] - x3[0]]) dy = np.array([y1[1] - y1[0], y2[1] - y2[0], y3[1] - y3[0]]) dx = np.max( dx ) # Right ascension resolution (the largest to ensure a nice HEALPix for all hitmaps) dy = np.max( dy ) # Declination resolution (the largest to ensure a nice HEALPix for all hitmaps) nx = len(x1) # Number of pixels in horizontal direction ny = len(y1) # Number of pixels in vertical direction Nside = int( round(np.sqrt(360 * 360 / (12 * np.pi * dx * dy))) ) # Nside parameter for healpix map (under the # assumption that each pixel in the input maps # is equal in area to the output healpix pixels). log2_Nside = np.log2(Nside) Nside = 2 ** (round(log2_Nside)) # Finding closest power of two for nside hits = np.zeros((3, nx, ny)) # Array of hits per pixel of all three maps lon1, lat1 = np.meshgrid( x1, y1, indexing="ij" ) # Making meshgrids om longitudes and latitudes lon2, lat2 = np.meshgrid(x2, y2, indexing="ij") lon3, lat3 = np.meshgrid(x3, y3, indexing="ij") lon1, lat1 = lon1.flatten(), lat1.flatten() # Making 1D arrays of coordinate pairs lon2, lat2 = lon2.flatten(), lat2.flatten() lon3, lat3 = lon3.flatten(), lat3.flatten() c1_icrs = SkyCoord( ra=lon1, dec=lat1, frame="icrs", unit="deg" ) # Generate sky-coordinates in ICRS coordinates c2_icrs = SkyCoord(ra=lon2, dec=lat2, frame="icrs", unit="deg") c3_icrs = SkyCoord(ra=lon3, dec=lat3, frame="icrs", unit="deg") c1_gal = c1_icrs.transform_to( "galactic" ) # Transforming hitmap coordinates from ICRS to Galactic coordinates c2_gal = c2_icrs.transform_to("galactic") c3_gal = c3_icrs.transform_to("galactic") heal = HEALPix( Nside, order="ring", frame="galactic" ) # Generating HEALPix object with ring-numbering px_indices1 = heal.skycoord_to_healpix( c1_gal ) # Generating HEALPix indices for each hitmap px_indices2 = heal.skycoord_to_healpix(c2_gal) px_indices3 = heal.skycoord_to_healpix(c3_gal) hits[0, ...] = np.sum( hits1[:, sb - 1, freq - 1, :, :], axis=0 ) # Co-adding hits of all detectors hits[1, ...] = np.sum(hits2[:, sb - 1, freq - 1, :, :], axis=0) hits[2, ...] = np.sum(hits3[:, sb - 1, freq - 1, :, :], axis=0) hits_list = np.zeros( (3, nx * ny) ) # List to contain hits of each pixel to be mapped to HEALPix format m = np.zeros(heal.npix) # Array to contain the projected HEALPix pixels m[px_indices1] = hits[0, ...].flatten() # Filling up HEALPix array with hitmaps m[px_indices2] = hits[1, ...].flatten() m[px_indices3] = hits[2, ...].flatten() """ lons = np.zeros_like(m) lats = np.zeros_like(m) lons[px_indices1], lons[px_indices2], lons[px_indices3] = lon1, lon2, lon3 lats[px_indices1], lats[px_indices2], lats[px_indices3] = lat1, lat2, lat3 temp = np.zeros((len(m[np.where(m!=0)]), 3)) temp[:, 0] = np.arange(0, len(m))[np.where(m!=0)] temp[:, 1], temp[:, 2] = lons[np.where(m!=0)], lats[np.where(m!=0)] np.savetxt("comap2healpix.txt", temp, header = "HEALPix number, lon, lat (for some of the hits, where lon/lat are non-zero)") """ return m
def from_image(cls, header, max_norder, mask_arr=None): """ Create a `~mocpy.moc.MOC` from an image stored as a fits file Parameters ---------- header : `~astropy.io.fits.Header` fits header containing all the info of where the image is located (position, size, etc...) max_norder : int the moc resolution mask_arr : `~numpy.ndarray`, optional a 2D boolean array of the same size of the image where pixels having the value 1 are part of the final MOC and pixels having the value 0 are not. Returns ------- moc : `mocpy.MOC` the MOC object loaded from the ``mask_arr`` and ``header`` extracted from the image """ # load the image data height = header['NAXIS2'] width = header['NAXIS1'] # use wcs from astropy to locate the image in the world coordinates w = wcs.WCS(header) if mask_arr is not None: # We have an array of pixels that are part of of survey y, x = np.where(mask_arr) pix_crd = np.dstack((x, y))[0] else: # If we do not have a mask array we create the moc of all the image # step_pix = 1 """ Coords returned by wcs_pix2world method correspond to pixel centers. We want to retrieve the moc pix crossing the borders of the image so we have to add 1/2 to the pixels coords before computing the lonlat. The step between two pix_crd is set to `step_pix` but can be diminished to have a better precision at the borders so that all the image is covered (a too big step does not retrieve all the moc pix crossing the borders of the image). """ x, y = np.mgrid[0.5:(width + 0.5 + step_pix):step_pix, 0.5:(height + 0.5 + step_pix):step_pix] pix_crd = np.dstack((x.ravel(), y.ravel()))[0] frame = wcs.utils.wcs_to_celestial_frame(w) world_pix_crd = SkyCoord(w.wcs_pix2world(pix_crd, 1), unit='deg', frame=frame) hp = HEALPix(nside=(1 << max_norder), order='nested', frame=ICRS()) ipix = hp.skycoord_to_healpix(world_pix_crd) # remove doubles ipix = np.unique(ipix) shift = 2 * (AbstractMOC.HPY_MAX_NORDER - max_norder) intervals_arr = np.vstack((ipix << shift, (ipix + 1) << shift)).T # This MOC will be consistent when one will do operations on the moc (union, inter, ...) or # simply write it to a fits or json file interval_set = IntervalSet.from_numpy_array(intervals_arr) return cls(interval_set=interval_set)
ra, dec = df_master["RA"], df_master["dec"] #using HEALPix to split the celestial sky into equal area sectors hp = HEALPix(nside=16, order='ring', frame=ICRS()) #making a holding array to hold the sectors for each galaxy hold = np.array([]) for i in range(len(ra)): ''' This loops over all the galaxies, at each one it takes the galaxies coordinates and uses skycoord_to_healpix to find what HEALPix sector that galaxies belongs to, the result is then appended to the hold array ''' coords = SkyCoord(ra[i], dec[i], unit="deg") sector = hp.skycoord_to_healpix(coords) hold = np.append(hold, sector) #adding the sector identifyier data to the master file df_master["Sector"] = hold for j in range(hp.npix): ''' This loops over the sectors defined by HEALPix, grabbing the corresponding galaxies from the main file and creating a new csv file for that sector ''' #isolating the galaxies in the sector sec = df_master.iloc[np.where(df_master["Sector"] == j)] #making a name for the current sector name = str("Sector_{}".format(j))