def add_zone(radec_box, footprint, Nside): ra1, ra2, dec1, dec2 = radec_box[0], radec_box[1], radec_box[2], radec_box[ 3] if (ra1 > 300) & (ra2 < 100): zone_tmp = np.array( hp_in_box(Nside, [ra1, 360, dec1, dec2]) + hp_in_box(Nside, [0, ra2, dec1, dec2])) else: zone_tmp = np.array(hp_in_box(Nside, [ra1, ra2, dec1, dec2])) return [zone_tmp[footprint[zone_tmp] == 1]]
def find_rabox_from_decline(dec_1, dec_2, footprint, Nside, is_des): zone_tmp = np.array(hp_in_box(Nside, [0, 360, dec_1, dec_2])) pix_list = zone_tmp[footprint[zone_tmp] == 1] ra_list, _ = hp.pix2ang(Nside, pix_list, nest=True, lonlat=True) if is_des: ra_list[ra_list > 300] = ra_list[ra_list > 300] - 360 ra_min, ra_max = np.floor(np.min(ra_list)), np.ceil(np.max(ra_list)) if is_des: ra_min += 360 return ra_min, ra_max
def read_targets_in_box(hpdirname, radecbox=[0., 360., -90., 90.], columns=None): """Read in targets in an RA/Dec box. Parameters ---------- hpdirname : :class:`str` Full path to either a directory containing targets that have been partitioned by HEALPixel (i.e. as made by `select_targets` with the `bundle_files` option). Or the name of a single file of targets. radecbox : :class:`list`, defaults to the entire sky 4-entry list of coordinates [ramin, ramax, decmin, decmax] forming the edges of a box in RA/Dec (degrees). columns : :class:`list`, optional Only read in these target columns. Returns ------- :class:`~numpy.ndarray` An array of targets in the passed RA/Dec box. """ # ADM we'll need RA/Dec for final cuts, so ensure they're read. addedcols = [] columnscopy = None if columns is not None: # ADM make a copy of columns, as it's a kwarg we'll modify. columnscopy = columns.copy() for radec in ["RA", "DEC"]: if radec not in columnscopy: columnscopy.append(radec) addedcols.append(radec) # ADM if a directory was passed, do fancy HEALPixel parsing... if os.path.isdir(hpdirname): # ADM approximate nside for area of passed box. nside = pixarea2nside(box_area(radecbox)) # ADM HEALPixels that touch the box for that nside. pixlist = hp_in_box(nside, radecbox) # ADM read in targets in these HEALPixels. targets = read_targets_in_hp(hpdirname, nside, pixlist, columns=columnscopy) # ADM ...otherwise just read in the targets. else: targets = fitsio.read(hpdirname, columns=columnscopy) # ADM restrict only to targets in the requested RA/Dec box... ii = is_in_box(targets, radecbox) # ADM ...and remove RA/Dec columns if we added them. targets = rfn.drop_fields(targets[ii], addedcols) return targets
def test_targets_spatial(self): """Test applying RA/Dec/HEALpixel inputs to sweeps recovers same targets """ # ADM only test some of the galaxy cuts for speed. There's a # ADM full run through all classes in test_cuts_basic. tc = ["LRG", "ELG", "BGS"] infiles = self.sweepfiles[2] targets = cuts.select_targets(infiles, numproc=1, tcnames=tc) # ADM test the RA/Dec box input. radecbox = [ np.min(targets["RA"]) - 0.01, np.max(targets["RA"]) + 0.01, np.min(targets["DEC"]) - 0.01, np.max(targets["DEC"] + 0.01) ] t1 = cuts.select_targets(infiles, numproc=1, tcnames=tc, radecbox=radecbox) # ADM test the RA/Dec/radius cap input. centra, centdec = 0.5 * (radecbox[0] + radecbox[1]), 0.5 * ( radecbox[2] + radecbox[3]) # ADM 20 degrees should be a large enough radius for the sweeps. maxrad = 20. radecrad = centra, centdec, maxrad t2 = cuts.select_targets(infiles, numproc=1, tcnames=tc, radecrad=radecrad) # ADM test the pixel input. nside = pixarea2nside(box_area(radecbox)) pixlist = hp_in_box(nside, radecbox) t3 = cuts.select_targets(infiles, numproc=1, tcnames=tc, nside=nside, pixlist=pixlist) # ADM sort each set of targets on TARGETID to compare them. targets = targets[np.argsort(targets["TARGETID"])] t1 = t1[np.argsort(t1["TARGETID"])] t2 = t2[np.argsort(t2["TARGETID"])] t3 = t3[np.argsort(t3["TARGETID"])] # ADM test the same targets were recovered and that # ADM each recovered target has the same bits set. for targs in t1, t2, t3: for col in "TARGETID", "DESI_TARGET", "BGS_TARGET", "MWS_TARGET": self.assertTrue(np.all(targs[col] == targets[col]))
def update_map(self, pixmap): """ Apply mask / ud_grade the pixmap before to return it Parameters ---------- pixmap: pixmap to return with mask at the correct Nside mask_des: bool --> to remove pixels around DES when dealing with South footprint """ if self.remove_LMC: pixmap[hp_in_box(256, [52, 120, -90, -50], inclusive=True)] = False if self.clear_south: pixmap[hp_in_box(256, [120, 150, -45, -10], inclusive=True) + hp_in_box(256, [150, 180, -45, -15], inclusive=True) + hp_in_box(256, [210, 240, -20, -12], inclusive=True)] = False if self.mask_around_des: mask_around_des = np.zeros(hp.nside2npix(256), dtype=bool) mask_around_des[hp_in_box(256, [-120, 0, -90, -18.5], inclusive=True) + hp_in_box(256, [0, 120, -90, -17.4], inclusive=True)] = True mask_around_des[self.data['ISDES']] = False pixmap[mask_around_des] = False if self.Nside != 256: pixmap = hp.ud_grade(pixmap, self.Nside, order_in='NESTED') return pixmap
def find_gaia_files_box(gaiabounds, neighbors=True): """Find full paths to all relevant Gaia healpix files in an RA/Dec box. Parameters ---------- gaiabounds : :class:`list` A region of the sky bounded by RA/Dec. Pass as a 4-entry list to represent an area bounded by [RAmin, RAmax, DECmin, DECmax] neighbors : :class:`bool`, optional, defaults to ``True`` Also return all neighboring pixels that touch the files of interest in order to prevent edge effects (e.g. if a Gaia source is 1 arcsec away from a primary source and so in an adjacent pixel) Returns ------- :class:`list` A list of all Gaia files that need to be read in to account for objects in the passed box. Notes ----- - Uses the `healpy` routines that rely on `fact`, so the usual warnings about returning different pixel sets at different values of `fact` apply. See: https://healpy.readthedocs.io/en/latest/generated/healpy.query_polygon.html - The environment variable $GAIA_DIR must be set. """ # ADM the resolution at which the healpix files are stored. nside = _get_gaia_nside() # ADM check that the GAIA_DIR is set and retrieve it. gaiadir = _get_gaia_dir() hpxdir = os.path.join(gaiadir, 'healpix') # ADM determine the pixels that touch the box. pixnum = hp_in_box(nside, gaiabounds, inclusive=True, fact=4) # ADM if neighbors was sent, then retrieve all pixels that touch each # ADM pixel covered by the provided locations, to prevent edge effects... if neighbors: pixnum = add_hp_neighbors(nside, pixnum) # ADM reformat in the Gaia healpix format used by desitarget. gaiafiles = [ os.path.join(hpxdir, 'healpix-{:05d}.fits'.format(pn)) for pn in pixnum ] return gaiafiles
def decode_sweep_name(sweepname, nside=None, inclusive=True, fact=4): """Retrieve RA/Dec edges from a full directory path to a sweep file Parameters ---------- sweepname : :class:`str` Full path to a sweep file, e.g., /a/b/c/sweep-350m005-360p005.fits nside : :class:`int`, optional, defaults to None (NESTED) HEALPixel nside inclusive : :class:`book`, optional, defaults to ``True`` see documentation for `healpy.query_polygon()` fact : :class:`int`, optional defaults to 4 see documentation for `healpy.query_polygon()` Returns ------- :class:`list` (if nside is None) A 4-entry list of the edges of the region covered by the sweeps file in the form [RAmin, RAmax, DECmin, DECmax] For the above example this would be [350., 360., -5., 5.] :class:`list` (if nside is not None) A list of HEALPixels that touch the files at the passed `nside` For the above example this would be [16, 17, 18, 19] """ # ADM extract just the file part of the name. sweepname = os.path.basename(sweepname) # ADM the RA/Dec edges. ramin, ramax = float(sweepname[6:9]), float(sweepname[14:17]) decmin, decmax = float(sweepname[10:13]), float(sweepname[18:21]) # ADM flip the signs on the DECs, if needed. if sweepname[9] == 'm': decmin *= -1 if sweepname[17] == 'm': decmax *= -1 if nside is None: return [ramin, ramax, decmin, decmax] pixnum = hp_in_box(nside, [ramin, ramax, decmin, decmax], inclusive=inclusive, fact=fact) return pixnum