def random_u_grade_ang(m_inds, nside_in=0, nside_out=16384, is_nest=False): """ Random upscaling of the PS positions, given the pixel centres at resolution nside_in. Each PS is moved to one of the high-resolution pixel centres at resolution nside_out. For example, for nside_in = 128 and nside_out = 16384, there are npix_out / npix_in = 16384 possible PS locations within each pixel. :param m_inds: indices of the PSs w.r.t. nside_in, in RING ordering :param nside_in: nside in :param nside_out: nside to use for upscaling :param is_nest: if True: indices are assumed to correspond to NEST format instead of RING :return: theta, phi of randomly placed PSs within each pixel """ if len(m_inds) == 0: return m_inds n_ps = len(m_inds) # number of point sources if is_nest: m_inds_nest = m_inds else: m_inds_nest = hp.ring2nest(nside_in, m_inds) # convert to NEST ordering hp.isnsideok(nside_out, nest=True) # check that nside_out is okay npix_in = hp.nside2npix(nside_in) npix_out = hp.nside2npix(nside_out) rat2 = npix_out // npix_in # For each PS, draw a random fine pixel within the coarse pixel inds_fine = np.random.choice(rat2, size=n_ps) # Set indices w.r.t. upscaled nside (NEST): rat2 * m_inds_nest -> high-res. pixel 0, inds_fine adds 0 ... rat2 - 1 inds_out = rat2 * m_inds_nest + inds_fine # Calculate angles th_out, ph_out = hp.pix2ang(nside_out, inds_out, nest=True, lonlat=False) # Note: for rat2 = 16384 and 150 PSs, the chance that there exists at least a pair of equal th/ph_out is > 50%! return th_out, ph_out
def dgrade(nside_in, nside_out): """ map ordering to down grade an healpix map Parameters ---------- nside_in : integer Nside parameter for the input map. Must be a valid healpix Nside value nside_out: integer Nside parameter for the output map. Must be a valid healpix Nside value Returns ------- order_out : array array defining the re-ordering of the input map to obtain a map with nside_out while performing convolution """ assert hp.isnsideok( nside_in, nest=True), "invalid input nside {0} in call to dgrade".format( nside_in) assert hp.isnsideok( nside_out, nest=True), "invalid output nside {0} in call to dgrade".format( nside_out) assert nside_out < nside_in try: return read_dgrade(nside_in, nside_out) except FileNotFoundError: fact = nside_in // nside_out pixels = hp.nside2npix(nside_out) stride = fact * fact result = np.empty(pixels * stride) x, y, f = hp.pix2xyf(nside_out, np.arange(pixels)) i = np.empty(stride, dtype="int") j = np.empty(stride, dtype="int") f_spread = np.empty(stride, dtype="int") for pixnum in range(pixels): make_indices( i, j, fact * x[pixnum], fact * (x[pixnum] + 1), fact * y[pixnum], fact * (y[pixnum] + 1), ) f_spread[:] = f[pixnum] result[(pixnum * stride):((pixnum + 1) * stride)] = hp.xyf2pix( nside_in, i, j, f_spread) file_name = dgrade_file_name(nside_in, nside_out) write_ancillary_file(file_name, result) return result
def __init__(self, nside=128, lonCol='fieldRA', latCol='fieldDec', verbose=True, badval=hp.UNSEEN, useCache=True, leafsize=100, radius=1.75, useCamera=False, rotSkyPosColName='rotSkyPos', mjdColName='expMJD', chipNames='all'): """Instantiate and set up healpix slicer object.""" super(HealpixSlicer, self).__init__(verbose=verbose, lonCol=lonCol, latCol=latCol, badval=badval, radius=radius, leafsize=leafsize, useCamera=useCamera, rotSkyPosColName=rotSkyPosColName, mjdColName=mjdColName, chipNames=chipNames) # Valid values of nside are powers of 2. # nside=64 gives about 1 deg resolution # nside=256 gives about 13' resolution (~1 CCD) # nside=1024 gives about 3' resolution # Check validity of nside: if not (hp.isnsideok(nside)): raise ValueError('Valid values of nside are powers of 2.') self.nside = int(nside) self.pixArea = hp.nside2pixarea(self.nside) self.nslice = hp.nside2npix(self.nside) self.spatialExtent = [0, self.nslice - 1] self.shape = self.nslice if self.verbose: print('Healpix slicer using NSIDE=%d, ' % (self.nside) + \ 'approximate resolution %f arcminutes' % (hp.nside2resol(self.nside, arcmin=True))) # Set variables so slicer can be re-constructed self.slicer_init = { 'nside': nside, 'lonCol': lonCol, 'latCol': latCol, 'radius': radius } if useCache: # useCache set the size of the cache for the memoize function in sliceMetric. binRes = hp.nside2resol(nside) # Pixel size in radians # Set the cache size to be ~2x the circumference self.cacheSize = int(np.round(4. * np.pi / binRes)) # Set up slicePoint metadata. self.slicePoints['nside'] = nside self.slicePoints['sid'] = np.arange(self.nslice) self.slicePoints['ra'], self.slicePoints['dec'] = self._pix2radec( self.slicePoints['sid']) # Set the default plotting functions. self.plotFuncs = [ HealpixSkyMap, HealpixHistogram, HealpixPowerSpectrum ]
def pixel_1st_neighbours(ipix, nside): """ find first pixel get_all_neighbours in the healpix ring scheme Parameters ---------- ipix : integer pixel number for which to find the neighbours nside : integer Nside parameter defining the healpix pixelization scheme. Must be a valid healpix Nside value Returns ------- pix_num : array array with 9 elements, corresponding to the first neighbours and the ipix itself. The order of the array is (SW, W, NW, N, ipix, NE, E, SE, S) Notes ------- If a neighbour does not exist (it can be the case for W, N, E and S) the corresponding pixel number will be -1 """ assert hp.isnsideok( nside, nest=True), "invalid nside {0} in call to pixel_1st_neighbours".format( nside) pix_array = np.empty(9, dtype="int") pix_array[0] = ipix pix_array[1:9] = hp.pixelfunc.get_all_neighbours(nside, ipix) return pix_array
def pixel_1st_neighbours(ipix, nside): """Return the indexes of the neighbour pixels in a HEALPix ``RING`` map. Args: * ipix (int): pixel number for which to find the neighbours * nside (integer): ``NSIDE`` parameter defining the resolution of the HEALPix map. It must be a valid healpix Nside value Returns: An array of integers containing 9 elements: the first element is the argument ``ipix`` itself, and the following 8 are the indexes of its neighbours. The order of the array is (SW, W, NW, N, ipix, NE, E, SE, S). If the pixel has only 7 neighbours, the missing position will be filled with -1. >>> nnhealpix.pixel_1st_neighbours(1, 16) array([ 1, 6, 5, 0, 3, 2, 8, 7, 16]) """ assert hp.isnsideok( nside, nest=True), "invalid nside {0} in call to pixel_1st_neighbours".format( nside) pix_array = np.empty(9, dtype="int") pix_array[0] = ipix pix_array[1:9] = hp.pixelfunc.get_all_neighbours(nside, ipix) return pix_array
def main(catalog_dir, nside, out_dir): # define map resolution, create map of zeros assert hp.isnsideok(nside), ("nside must be a power of 2") npix = hp.nside2npix(nside) hmap = np.zeros(npix) # create destination directory if not isdir(out_dir): mkdir(out_dir) else: assert listdir(out_dir) == [], ("out_dir already exists/has content, choose a new destination directory") # create count maps mapper1(catalog_dir, nside, out_dir) # merge count maps for cmap in listdir(out_dir): if cmap.endswith(".fits"): m = hp.read_map(join(out_dir, cmap)) hmap += m # assign filename & write final map if not all(x == 0 for x in hmap): out_filename = basename(normpath(catalog_dir)) + "_" + str(nside) + "cmap.fits" hp.write_map(join(out_dir, out_filename), hmap) else: print("empty map") return None
def get_binned_healpy_map(theta, phi, NSIDE): """ Get a binned healpy map from single directions. Converts directions to indices and uses bincount to bin them in healpixels. Parameters ---------- theta : array-like healpy ``theta`` angle in ``[0, pi]``. phi : array-like, shape (len(theta)) healpy ``phi`` angle in ``[0, 2pi]``. NSIDE : int How many pixels to use for the binning. Returns ------- m : array-like, shape(NPIX) healpy map with resolution ``NSIDE`` with number of given directions falling in the bins specified by ``NSIDE``. """ phi = np.atleast_1d(phi) theta = np.atleast_1d(theta) if not len(theta) == len(phi): raise ValueError("`theta` and `phi` must have same length.") if not hp.isnsideok(NSIDE): raise ValueError("`NSIDE` is not a valid value of form 2^n.") # Get pixel indices and use idx binning routine idx = hp.ang2pix(theta=theta, phi=phi, nside=NSIDE) return get_binned_healpy_map_from_idx(idx, NSIDE)
def img2healpix(img, nside, delta_theta, delta_phi, rot=np.eye(3)): """Projection of a 2D image on a Healpix map. This function is a wrapper to `img2map`. Use the latter function if you have already allocated a map. Parameters ---------- img: A 2D matrix containing the image to be projected on the map nside: The resolution of the Healpix map delta_theta: the width of the image along the meridian, in degrees delta_phi: the height of the image along the meridian, in degrees rot: Either a 3×3 matrix or a `healpy.rotator.Rotator` object Result ------ A tuple containing the map and the hit map. Unseen pixels in the map are set to zero. """ assert hp.isnsideok(nside) assert delta_theta < 180.0 assert delta_phi < 180.0 result = np.zeros(hp.nside2npix(nside)) hits = np.zeros(result.size, dtype="int") img2map(img, result, hits, delta_theta, delta_phi, rot, reset_map=False) return result, hits
def __init__( self, threshold, sig, freq, nside, LMAX, CMB_file_name='/home/amber/data/cmb/COM_CMB_IQU-commander-field-Int_2048_R2.01_full.fits' ): self.threshold = threshold self.sig = sig self.freq = freq #check that nside value is valid if not np.all(hp.isnsideok(nside)): raise ValueError( "%s is not a valid nside parameter (must be a power of 2, less than 2**30)" % str(nside)) self.nside = nside self.LMAX = LMAX self.CMB_file_name = CMB_file_name #can read and downgrade cmb in same step #use nside instead of 512. change both cmb and gsm to nside self.CMB_map = hp.ud_grade(hp.read_map(CMB_file_name), nside) #power spectrum of downgraded CMB map self.CMB_PS = hp.anafast(self.CMB_map, lmax=LMAX) self.ell = np.arange(len(self.CMB_PS)) self.signal = np.sqrt((np.sum( (self.ell * (self.ell + 1) * self.CMB_PS)**2)) / (len(self.CMB_PS))) self.GSM_map = hp.ud_grade(gsm.generate(self.freq), nside) self.GSM_PS = hp.anafast(self.GSM_map, lmax=LMAX)
def getAllFacesIndex(nside, nested=False): #RETURN FOR EACH PIXEL ITS INDEX IN CUBE OF FACES if not hp.isnsideok(nside): raise ValueError('Incorrect nside') npix = hp.nside2npix(nside) index_map = np.zeros((npix)) offset = nside * nside #Number one face if (nested): #Only need to do it for one face index = np.array([ hp.xyf2pix(nside, range(nside), y, 0, nested) for y in range(nside) ]) for face in range(12): index_map[index + face * offset] = np.linspace( 0, offset - 1, offset) + face * offset else: for face in range(12): index = np.array([ hp.xyf2pix(nside, range(nside), y, face, nested) for y in range(nside) ]) index_map[index] = np.linspace(0, offset - 1, offset) + face * offset return index_map
def nside(self): """Nside parameter of the sky healpix map.""" try: return healpy.get_nside(self.sky_intensity[0]) except TypeError: if not healpy.isnsideok(self._nside): raise ValueError("nside must be a power of 2") return self._nside
def setup_map(self, nside): """Setups the HEALPix map. Parameters ---------- nside : int HEALPix nside. """ assert hp.isnsideok(nside) == True, "nside given is not ok." self.nside = nside
def valid_nside(arg): """ Check that the argument can be a valid Nside parameter, and return it as an int """ try: val = int(arg) except (TypeError, ValueError): raise argparse.ArgumentTypeError("Value must be an integer") if not hp.isnsideok(val): raise argparse.ArgumentTypeError("Value must be a valid Nside") return val
def choose_pixelization(**config): """Construct a pixelization scheme based on configuration choices. Currently only the Healpix pixelization is defined. If kwargs['pixelization']=='healpix' then these parameters will be checked: Parameters ---------- pixelization: str Choice of pixelization, currently only "healpix" is supported nside: int, optional Only used if pixelization=='healpix'. Healpix resolution parameter, must be power of 2. nest: bool, optional Only used if pixelization=='healpix'. Healpix ordering scheme. Default=False Returns ------- scheme: PixelizationScheme Instance of a pixelization scheme subclass """ pixelization = config['pixelization'].lower() if pixelization == 'healpix': import healpy nside = config['nside'] if not healpy.isnsideok(nside): raise ValueError( "nside pixelization parameter must be set to a power of two (used value {nside})" ) nest = config.get('nest', False) if nest: raise ValueError( "Please do not attempt to use the NEST pixelization. It will only end badly for you." ) scheme = HealpixScheme(nside, nest=nest) elif pixelization == 'gnomonic': ra_cent = config['ra_cent'] dec_cent = config['dec_cent'] nx = config['npix_x'] ny = config['npix_y'] pixel_size = config['pixel_size'] if np.isnan([ra_cent, dec_cent, pixel_size ]).any() or nx == -1 or ny == -1: raise ValueError( "Must set ra_cent, dec_cent, nx, ny, pixel_size to use Gnomonic/Tangent pixelization" ) scheme = GnomonicPixelScheme(ra_cent, dec_cent, pixel_size, nx, ny) else: raise ValueError(f"Pixelization scheme {pixelization} unknown") return scheme
def read_configuration(conf_parser: ConfigParser) -> Configuration: ''''Build a Configuration object and initialize its fields using the parameters read by the ConfigParser object''' conf_sect = conf_parser['config'] nside = conf_sect.getint('nside', 128) if not healpy.isnsideok(nside): log.error('error, wrong NSIDE (%d)', nside) sys.exit(1) delta_time = conf_sect.getfloat('delta_time') number_of_frames = conf_sect.getint('number_of_frames') show_fsky = conf_sect.getboolean('show_fsky', True) figure_width = conf_sect.getfloat('figure_width') figure_height = conf_sect.getfloat('figure_height') figure_file_name_mask = conf_sect.get('figure_file_name_mask', 'anim%04d.png') time_measure_unit = conf_sect.get('time_measure_unit', '') data_source_names = [ x.strip() for x in conf_sect.get('data_sources').split(',') ] data_sources = [] # type: List[DataSource] for cur_name in data_source_names: source_sect = conf_parser[cur_name] file_name_mask = source_sect.get('file_name_mask') table_hdu = int_or_str(source_sect.get('table_hdu')) time_column = int_or_str(source_sect.get('time_column')) theta_column = int_or_str(source_sect.get('theta_column')) phi_column = int_or_str(source_sect.get('phi_column')) time_factor = source_sect.getfloat('time_factor', 1.0) angle_factor = source_sect.getfloat('angle_factor', 1.0) subplot = source_sect.getint('subplot', 111) data_sources.append( DataSource(name=cur_name, file_name_mask=file_name_mask, table_hdu=table_hdu, time_column=time_column, theta_column=theta_column, phi_column=phi_column, time_factor=time_factor, angle_factor=angle_factor, subplot=subplot)) return Configuration(nside=nside, delta_time=delta_time, number_of_frames=number_of_frames, show_fsky=show_fsky, figure_width=figure_width, figure_height=figure_height, figure_file_name_mask=figure_file_name_mask, time_measure_unit=time_measure_unit, data_sources=data_sources)
def get2DPatchesCoverage(nside, PatchWidth, PatchIndices, nested=False): #Get the covering map for all patches if not hp.isnsideok(nside): raise ValueError('Incorrect map nside {0}'.format(nside)) MapCover = np.zeros((hp.nside2npix(nside))) npatches = PatchIndices.shape[0] PatchesPosition = get2DPatchesPositions(nside, PatchWidth, PatchIndices, nested=False) for kp in range(npatches): MapCover.flat[PatchesPosition[kp]] += np.ones(PatchWidth * PatchWidth) return MapCover
def gather2DPatches(nside, Patches, PatchIndices, nested=False): #Get all pixel position on the sphere for all patches if not hp.isnsideok(nside): raise ValueError('Incorrect map nside {0}'.format(nside)) PatchWidth = np.int(np.sqrt(Patches[0].size)) MapRecons = np.zeros((hp.nside2npix(nside))) MapCover = np.zeros((hp.nside2npix(nside))) npatches = PatchIndices.shape[0] PatchesPosition = get2DPatchesPositions(nside, PatchWidth, PatchIndices, nested=False) for kp in range(npatches): MapCover.flat[PatchesPosition[kp]] += np.ones(PatchWidth * PatchWidth) MapRecons.flat[PatchesPosition[kp]] += Patches[kp].flatten() lstCover = np.where(MapCover > 0)[0] MapRecons[lstCover] /= MapCover[lstCover] return MapRecons, MapCover
def __init__(self,threshold,sig,freq,nside,LMAX,CMB_file_name='/home/amber/data/cmb/COM_CMB_IQU-commander-field-Int_2048_R2.01_full.fits'): self.threshold=threshold self.sig=sig self.freq=freq #check that nside value is valid if not np.all(hp.isnsideok(nside)): raise ValueError("%s is not a valid nside parameter (must be a power of 2, less than 2**30)"%str(nside)) self.nside=nside self.LMAX=LMAX self.CMB_file_name=CMB_file_name #can read and downgrade cmb in same step #use nside instead of 512. change both cmb and gsm to nside self.CMB_map=hp.ud_grade(hp.read_map(CMB_file_name),nside) #power spectrum of downgraded CMB map self.CMB_PS=hp.anafast(self.CMB_map,lmax=LMAX) self.ell=np.arange(len(self.CMB_PS)) self.signal=np.sqrt((np.sum((self.ell*(self.ell+1)*self.CMB_PS)**2))/(len(self.CMB_PS))) self.GSM_map=hp.ud_grade(gsm.generate(self.freq),nside) self.GSM_PS=hp.anafast(self.GSM_map,lmax=LMAX)
def get2DPatchesPositions(nside, PatchWidth, PatchIndices, nested=False, Verbose=False): #Get all pixel position on the sphere for the different patches if not hp.isnsideok(nside): raise ValueError('Incorrect map nside {0}'.format(nside)) nside2 = nside * nside NpatchesCap = (nside2 - (PatchWidth - 1)**2 ) #For Northern/Southern cap Patches NpatchesEq = nside2 # Number of Equatorial Patches npatches = NpatchesCap * 8 + NpatchesEq * 4 #Start by sorting the indices to process face by face SortingIndices = np.argsort(PatchIndices) sortedIndices = PatchIndices[SortingIndices] AllPatchesPosition = np.zeros((npatches, PatchWidth * PatchWidth), dtype='int64') NPatchPerFace = np.zeros((12), dtype='int64') NPatchPerSide = nside offsetPatchIndex = 0 #Process all patches without -1 for f in range(12): if (Verbose): print("PROCESS FACE {0}".format(f)) FaceIndices = constructExtendedFaceIndices(nside, f, PatchWidth, nested=nested) FacePatches2D = np.array([ np.ndarray.flatten(FaceIndices[y:y + PatchWidth, x:x + PatchWidth]) for y in range(nside) for x in range(nside) if -1 not in FaceIndices[y:y + PatchWidth, x:x + PatchWidth] ]) NPatchPerFace[f] = np.shape(FacePatches2D)[0] AllPatchesPosition[offsetPatchIndex:offsetPatchIndex+NPatchPerFace[f]]=\ FacePatches2D offsetPatchIndex = offsetPatchIndex + NPatchPerFace[f] PatchesPosition = AllPatchesPosition[PatchIndices] return PatchesPosition
def ang2pix(nside, phi, theta, nest=False): """ Convert spherical angle (astrotools definition) to HEALpixel ipix Substitutes hp.ang2pix :param nside: nside of the healpy pixelization :param phi: longitude in astrotools definition :param theta: latitude in astrotools definition :param nest: set True in case you work with healpy's nested scheme :return: pixel number(s) """ v = ang2vec(phi, theta) # mimic ValueError behavior from healpys function ang2pix() if not np.all(hp.isnsideok(nside)): raise ValueError( "%s is not a valid nside parameter (must be a power of 2, less than 2**30)" % str(nside)) ipix = hp.vec2pix(nside, *v, nest=nest) return ipix
def __init__(self, nside=128, lonCol ='fieldRA', latCol='fieldDec', latLonDeg=True, verbose=True, badval=hp.UNSEEN, useCache=True, leafsize=100, radius=1.75, useCamera=False, rotSkyPosColName='rotSkyPos', mjdColName='observationStartMJD', chipNames='all'): """Instantiate and set up healpix slicer object.""" super(HealpixSlicer, self).__init__(verbose=verbose, lonCol=lonCol, latCol=latCol, badval=badval, radius=radius, leafsize=leafsize, useCamera=useCamera, rotSkyPosColName=rotSkyPosColName, mjdColName=mjdColName, chipNames=chipNames, latLonDeg=latLonDeg) # Valid values of nside are powers of 2. # nside=64 gives about 1 deg resolution # nside=256 gives about 13' resolution (~1 CCD) # nside=1024 gives about 3' resolution # Check validity of nside: if not(hp.isnsideok(nside)): raise ValueError('Valid values of nside are powers of 2.') self.nside = int(nside) self.pixArea = hp.nside2pixarea(self.nside) self.nslice = hp.nside2npix(self.nside) self.spatialExtent = [0, self.nslice-1] self.shape = self.nslice if self.verbose: print('Healpix slicer using NSIDE=%d, ' % (self.nside) + \ 'approximate resolution %f arcminutes' % (hp.nside2resol(self.nside, arcmin=True))) # Set variables so slicer can be re-constructed self.slicer_init = {'nside': nside, 'lonCol': lonCol, 'latCol': latCol, 'radius': radius} if useCache: # useCache set the size of the cache for the memoize function in sliceMetric. binRes = hp.nside2resol(nside) # Pixel size in radians # Set the cache size to be ~2x the circumference self.cacheSize = int(np.round(4.*np.pi/binRes)) # Set up slicePoint metadata. self.slicePoints['nside'] = nside self.slicePoints['sid'] = np.arange(self.nslice) self.slicePoints['ra'], self.slicePoints['dec'] = self._pix2radec(self.slicePoints['sid']) # Set the default plotting functions. self.plotFuncs = [HealpixSkyMap, HealpixHistogram, HealpixPowerSpectrum]
def filter(nside, order=1): """map ordering to implement a convolutional neural network with a kernel convolving the first neighbour of each pixel on an healpix map Args: * nside (int): ``NSIDE`` for the input map. It must be a valid HEALPix value. * order (int): the order level. Currently it can only be 1. Returns: An array of integers defining the re-ordering of the input map to perform the convolution. """ assert hp.isnsideok( nside, nest=True), "invalid nside ({0}) in call to filter".format(nside) try: return __read_filter_cache(nside, order) except FileNotFoundError: order_fn = {1: pixel_1st_neighbours, 2: pixel_2nd_neighbours} assert ( order in order_fn.keys() ), "invalid order ({0}) passed to filter, valid values are {1}".format( order, ", ".join([str(x) for x in order_fn.keys()])) result = np.empty(0, dtype="int") fn = order_fn[order] for i in range(hp.nside2npix(nside)): result = np.concatenate((result, fn(i, nside))) result[result == -1] = hp.nside2npix(nside) file_name = filter_file_name(nside, order) __write_ancillary_file(file_name, result) return result
def get_binned_healpy_map_from_idx(idx, NSIDE): """ Get a binned healpy map from given map indices. Uses bincount to bin them in healpixels. Parameters ---------- idx : array-like Integer map indices. NSIDE : int How many pixels to use for the binning. Returns ------- m : array-like, shape(NPIX) healpy map with resolution ``NSIDE`` with number of given indices falling in the bins specified by ``NSIDE``. """ if not hp.isnsideok(NSIDE): raise ValueError("NSIDE has not a valid value of 2^n.") # Use bincount to bin the given indices. This is then the final binned map NPIX = hp.nside2npix(NSIDE) return np.bincount(idx, minlength=NPIX)
def filter(nside, order=1): """ map ordering to implement a convolutional neural network with a kernel convolving the first neighbour of each pixel on an healpix map Parameters ---------- nside: integer Nside parameter for the input map. Must be a valid healpix Nside value Returns ------- filter : array array defining the re-ordering of the input map to perform the convolution """ assert hp.isnsideok( nside, nest=True), "invalid nside ({0}) in call to filter".format(nside) order_fn = {1: pixel_1st_neighbours, 2: pixel_2nd_neighbours} assert (order in order_fn.keys( )), "invalid order ({0}) passed to filter, valid values are {1}".format( order, ", ".join([str(x) for x in order_fn.keys()])) result = np.empty(0, dtype="int") fn = order_fn[order] for i in range(hp.nside2npix(nside)): result = np.concatenate((result, fn(i, nside))) result[result == -1] = hp.nside2npix(nside) file_name = filter_file_name(nside, order) write_ancillary_file(file_name, result) return result
def check_nside(nside): """Flag an error if nside is not OK for NESTED HEALPixels. Parameters ---------- nside : :class:`int` or `~numpy.ndarray` The HEALPixel nside number (NESTED scheme) or an array of such numbers. Returns ------- Nothing, but raises a ValueRrror for a bad `nside`. """ if nside is None: msg = "need to pass the NSIDE parameter?" log.critical(msg) raise ValueError(msg) nside = np.atleast_1d(nside) good = hp.isnsideok(nside, nest=True) if not np.all(good): msg = "NSIDE = {} not valid in the NESTED scheme" \ .format(np.array(nside)[~good]) log.critical(msg) raise ValueError(msg)
def __init__(self, nside=128, spatialkey1 ='fieldRA' , spatialkey2='fieldDec', verbose=True, useCache=True, radius=1.75, leafsize=100, plotFuncs='all', useCamera=False, rotSkyPosColName='rotSkyPos', mjdColName='expMJD'): """Instantiate and set up healpix slicer object.""" super(HealpixSlicer, self).__init__(verbose=verbose, spatialkey1=spatialkey1, spatialkey2=spatialkey2, badval=hp.UNSEEN, radius=radius, leafsize=leafsize, plotFuncs=plotFuncs, useCamera=useCamera, rotSkyPosColName=rotSkyPosColName, mjdColName=mjdColName) # Valid values of nside are powers of 2. # nside=64 gives about 1 deg resolution # nside=256 gives about 13' resolution (~1 CCD) # nside=1024 gives about 3' resolution # Check validity of nside: if not(hp.isnsideok(nside)): raise ValueError('Valid values of nside are powers of 2.') self.nside = int(nside) self.pixArea = hp.nside2pixarea(self.nside) self.nslice = hp.nside2npix(self.nside) if self.verbose: print 'Healpix slicer using NSIDE=%d, '%(self.nside) + \ 'approximate resolution %f arcminutes'%(hp.nside2resol(self.nside,arcmin=True)) # Set variables so slicer can be re-constructed self.slicer_init = {'nside':nside, 'spatialkey1':spatialkey1, 'spatialkey2':spatialkey2, 'radius':radius} if useCache: # useCache set the size of the cache for the memoize function in sliceMetric. binRes = hp.nside2resol(nside) # Pixel size in radians # Set the cache size to be ~2x the circumference self.cacheSize = int(np.round(4.*np.pi/binRes)) # Set up slicePoint metadata. self.slicePoints['nside'] = nside self.slicePoints['sid'] = np.arange(self.nslice) self.slicePoints['ra'], self.slicePoints['dec'] = self._pix2radec(self.slicePoints['sid'])
def read_map(filename, nest=False, hdu=None, h=False, verbose=True): """Read a healpix map from a fits file. Partial-sky files, if properly identified, are expanded to full size and filled with UNSEEN. Uses fitsio to mirror much (but not all) of the functionality of healpy.read_map Parameters: ----------- filename : str the fits file name nest : bool, optional If True return the map in NEST ordering, otherwise in RING ordering; use fits keyword ORDERING to decide whether conversion is needed or not If None, no conversion is performed. hdu : int, optional the header number to look at (start at 0) h : bool, optional If True, return also the header. Default: False. verbose : bool, optional If True, print a number of diagnostic messages Returns ------- m [, header] : array, optionally with header appended The map read from the file, and the header if *h* is True. """ data, hdr = fitsio.read(filename, header=True, ext=hdu) nside = int(hdr.get('NSIDE')) if verbose: print('NSIDE = {0:d}'.format(nside)) if not healpy.isnsideok(nside): raise ValueError('Wrong nside parameter.') sz = healpy.nside2npix(nside) ordering = hdr.get('ORDERING', 'UNDEF').strip() if verbose: print('ORDERING = {0:s} in fits file'.format(ordering)) schm = hdr.get('INDXSCHM', 'UNDEF').strip() if verbose: print('INDXSCHM = {0:s}'.format(schm)) if schm == 'EXPLICIT': partial = True elif schm == 'IMPLICIT': partial = False # monkey patch on a field method fields = data.dtype.names # Could be done more efficiently (but complicated) by reordering first if hdr['INDXSCHM'] == 'EXPLICIT': m = healpy.UNSEEN * np.ones(sz, dtype=data[fields[1]].dtype) m[data[fields[0]]] = data[fields[1]] else: m = data[fields[0]].ravel() if (not healpy.isnpixok(m.size) or (sz > 0 and sz != m.size)) and verbose: print('nside={0:d}, sz={1:d}, m.size={2:d}'.format(nside, sz, m.size)) raise ValueError('Wrong nside parameter.') if nest is not None: if nest and ordering.startswith('RING'): idx = healpy.nest2ring(nside, np.arange(m.size, dtype=np.int32)) m = m[idx] if verbose: print('Ordering converted to NEST') elif (not nest) and ordering.startswith('NESTED'): idx = healpy.ring2nest(nside, np.arange(m.size, dtype=np.int32)) m = m[idx] if verbose: print('Ordering converted to RING') if h: return m, hdr else: return m
def check_nside(nside): """Raises exception if nside is not valid""" if not np.all(hp.isnsideok(nside)): raise ValueError("%s is not a valid nside parameter (must be a power of 2, less than 2**30)"%str(nside))
def main(infile, nside, RA, DEC, zname, zbins, cuts): filelist = glob.glob(infile) filelist.sort() folder = os.getcwd() # Create empty Healpix map full_countmap = np.zeros(hp.nside2npix(nside)) # Get number of pixels from the map npix = hp.nside2npix(nside) for filename in filelist: # 1) Open catalogs and perform checks filepath = os.path.join(folder, filename) print (filepath) # Open the catalog as a table header_row=["objID","ra","dec","type","clean","insideMask","z","zErr","photoErrorClass","nnCount","chisq","rnorm","bestFitTemplateID","absMagU","absMagG","absMagR","absMagI","absMagZ"] data = Table(np.array(pd.read_csv(filepath,skiprows=1)),header_row) #Check if the file is empty if (len(data) == 0): print ("file is empty") continue else: print ("file is not empty") #Renaming columns selectcols = ["col0","col1","col2","col3","col4","col5","col6"] newcolnames = ["objID","ra","dec","type","clean","insideMask","z"] for oldname, newname in zip(selectcols, newcolnames): data.rename_column(oldname,newname) colnames = data.colnames # Make sure that RA and DEC columns are in the catalog assert (RA in colnames) and (DEC in colnames), ("Both ra and dec must" + "be in the catalog") # Make sure that Nside is a power of 2 assert hp.isnsideok(nside), "nside must be a power of 2" # 2) Apply general cuts and bin in redshift # Apply general cuts to catalog if cuts is not None: data = apply_cuts(data) # Apply redshift bin if (zname is not None) and (zbins is not None): datalist = bin_data(data, zname, zbins) zsuffix = ["_z%.2f-%.2f" % (inf, sup) for (inf, sup) in zbins] else: print ("For redshift binning, both zname and zbins must be given.") print ("Proceeding without binning.") datalist = [data] zsuffix = [""] # 3) Create count maps for each redshift bin # Translate radec coordinates to healpix format theta = np.deg2rad(90.0 - data['dec']) phi = np.deg2rad(data['ra']) # Affect each galaxy to a healpix pixel try: gal_hppix = hp.ang2pix(nside, theta=theta, phi=phi, nest=False) except ValueError: print("BEWARE! Problem with RA DEC range, creating fake random map.") theta = np.random.uniform(0, np.pi, size=len(data)) phi = np.random.uniform(0, 2*np.pi, size=len(data)) gal_hppix = hp.ang2pix(nside, theta=theta, phi=phi, nest=False) # Count number of galaxies in each pixel countmap = np.bincount(gal_hppix, minlength=npix) # Make sure size of count map is the same as number of pixels assert len(countmap) == npix, ("Size of count map must be the same" + "as minimum length") # Add counts to the originally empty map full_countmap += countmap # Save final map savemap = hp.write_map("/share/splinter/visit10/sdss_full_countmap.fits", full_countmap) return None
def from_galfile(cls, filename, nside=0, hpix=0, border=0.0): """ Name: from_galfile Purpose: do the actual reading in of the data fields in some galaxy catalog file Calling Squence: TODO Inputs: filename: a name of a galaxy catalog file Optional Inputs: nside: integer healpix nside of sub-pixel hpix: integer healpix pixel (ring order) of sub-pixel Outputs: A galaxy catalog object """ if hpix == 0: _hpix = None else: _hpix = hpix # do we have appropriate keywords if _hpix is not None and nside is None: raise ValueError("If hpix is specified, must also specify nside") if border < 0.0: raise ValueError("Border must be >= 0.0.") # ensure that nside is valid, and hpix is within range (if necessary) if nside > 0: if not hp.isnsideok(nside): raise ValueError("Nside not valid") if _hpix is not None: if _hpix < 0 or _hpix >= hp.nside2npix(nside): raise ValueError("hpix out of range.") # check that the file is there and the right format # this will raise an exception if it's not there. hdr = fitsio.read_header(filename, ext=1) pixelated, fitsformat = hdr.get("PIXELS", 0), hdr.get("FITS", 0) if not pixelated: cat = fitsio.read(filename, ext=1, upper=True) return cls(cat) # this is to keep us from trying to use old IDL galfiles if not fitsformat: raise ValueError("Input galfile must describe fits files.") # now we can read in the galaxy table summary file... tab = fitsio.read(filename, ext=1, upper=True) nside_tab = tab[0]['NSIDE'] if nside > nside_tab: raise ValueError("""Requested nside (%d) must not be larger than table nside (%d).""" % (nside, nside_tab)) # which files do we want to read? path = os.path.dirname(os.path.abspath(filename)) if _hpix is None: # all of them! indices = np.arange(tab[0]['FILENAMES'].size) else: # first we need all the pixels that are contained in the big pixel theta, phi = hp.pix2ang(nside_tab, tab[0]['HPIX']) ipring_big = hp.ang2pix(nside, theta, phi) indices, = np.where(ipring_big == _hpix) if border > 0.0: # now we need to find the extra boundary... boundaries = hp.boundaries(nside, _hpix, step=nside_tab/nside) inhpix = tab[0]['HPIX'][indices] for i in xrange(boundaries.shape[1]): pixint = hp.query_disc(nside_tab, boundaries[:,i], border*np.pi/180., inclusive=True, fact=8) inhpix = np.append(inhpix, pixint) inhpix = np.unique(inhpix) _, indices = esutil.numpy_util.match(inhpix, tab[0]['HPIX']) # create the catalog array to read into elt = fitsio.read('%s/%s' % (path, tab[0]['FILENAMES'][indices[0]].decode()),ext=1, rows=0, upper=True) cat = np.zeros(np.sum(tab[0]['NGALS'][indices]), dtype=elt.dtype) # read the files ctr = 0 for index in indices: cat[ctr : ctr+tab[0]['NGALS'][index]] = fitsio.read('%s/%s' % (path, tab[0]['FILENAMES'][index].decode()), ext=1, upper=True) ctr += tab[0]['NGALS'][index] # In the IDL version this is trimmed to the precise boundary requested. # that's easy in simplepix. Not sure how to do in healpix. return cls(cat)
if dsm_units == 'K': if not isinstance(dsm_pixres, (int, float)): raise TypeError( 'diffuse model pixel resolution must be scalar') elif dsm_pixres <= 0.0: raise ValueError( 'Invalid pixel resolution specified for diffuse model') if not isinstance(out_coord, str): raise TypeError('Output coordinate system must be a string') elif out_coord not in ['galactic', 'equatorial']: raise ValueError('Invalid coordinate system specified for output') if not isinstance(out_nside, int): raise TypeError('nside for HEALPIX output must be an integer') elif not HP.isnsideok(out_nside): raise ValueError('Invalid nside specified for HEALPIX output') if not isinstance(out_units, str): raise TypeError('Output model units must be a string') elif out_units not in ['K', 'Jy']: raise ValueError('Invalid units specified for output model') if not isinstance(freqs, (int, float, list)): raise TypeError('Frequencies must be a scalar or a list') else: freqs = NP.asarray(freqs).reshape(-1) if not isinstance(freq_units, str): raise TypeError('Frequency units must be a string') elif freq_units not in [
def __init__(self, **kwargs): self.nside = kwargs.get('nside', 64) assert hp.isnsideok(self.nside), '`nside` value {} not correct'.format( self.nside)
def constructExtendedFaceIndices(nside, face, PatchWidth, nested=False, Verbose=False): #THE CATCH IS THAT THE NEIGHBOUR ORDERING IS NOT WITH RESPECT TO THE CURRENT #PIXEL, BUT TO A POINT OUTSIDE THE SPHERE SO FOR A PIXEL IN A CAP WE HAVE # TO IDENTIFY: # 1) SINGULAR PIXELS, WITH ONLY 7-NEIGHBOUR # 2) WHAT IS THE RELEVANT ORIENTATION WITH RESPECT TO THE CURRENT PIXEL # IN THE GRID #(1) IS DONE BY LOOKING AT A VALUE OF -1 IN THE LIST OF NEIGHBOUR PIXELS #(2) IS DONE BY TAKING A REFERENCE POINT IN THE GRID WITH RESPECT TO CURRENT # PIXEL (UPPER PIXEL FOR RIGHT BORDER EXTENSION, AND RIGHT PIXEL FOR TOP # BORDER EXTENSION) AND FILLING THE GRID ACCORDINGLY FaceExtension = np.zeros( (nside + PatchWidth - 1, nside + PatchWidth - 1)) - 1 FaceExtension[PatchWidth - 1:nside + PatchWidth - 1, 0:nside] = getAllIndicesForFace( nside, face, nested=nested).astype('int64') #RIGHT BORDER EXTENSION if not hp.isnsideok(nside): raise ValueError('Incorrect map nside {0}'.format(nside)) for kx in range(nside, nside + PatchWidth - 1): lstPix = FaceExtension[PatchWidth - 1:nside + PatchWidth - 1, kx - 1].astype('int64').flatten() PixBorder = np.array(hp.get_all_neighbours(nside, lstPix, nest=nested)) for ky in range(PatchWidth - 1, nside + PatchWidth - 2): UpPix = FaceExtension[ky + 1, kx - 1] if (-1 in PixBorder[0:8, ky - PatchWidth + 1]): if (Verbose): print("({0},{1}):".format(kx, ky)) print("CANNOT PROCESS SINGULAR 7-NEIGHBOUR PIXEL") else: startInd = (np.where(PixBorder[0:8, ky - PatchWidth + 1] == UpPix))[0][0] FaceExtension[ky + 1, kx] = PixBorder[(startInd + 1) % 8, ky - PatchWidth + 1] FaceExtension[ky, kx] = PixBorder[(startInd + 2) % 8, ky - PatchWidth + 1] if (ky > 0) and (FaceExtension[ky - 1, kx] == -1): FaceExtension[ky - 1, kx] = PixBorder[(startInd + 3) % 8, ky - PatchWidth + 1] #BOTTOM BORDER EXTENSION for ky in range(PatchWidth - 2, -1, -1): lstPix = FaceExtension[ky + 1, 0:nside].astype('int64').flatten() PixBorder = np.array(hp.get_all_neighbours(nside, lstPix, nest=nested)) for kx in range(1, nside): LeftPix = FaceExtension[ky + 1, kx - 1] if (-1 in PixBorder[0:8, kx]): if (Verbose): print("({0},{1}):".format(kx, ky)) print("CANNOT PROCESS SINGULAR 7-NEIGHBOUR PIXEL") else: lstStart = (np.where(PixBorder[0:8, kx] == LeftPix)) if (len(lstStart[0]) > 0): startInd = lstStart[0][0] if (FaceExtension[ky, kx - 1] == -1): FaceExtension[ky, kx - 1] = PixBorder[(startInd - 1) % 8, kx] FaceExtension[ky, kx] = PixBorder[(startInd - 2) % 8, kx] FaceExtension[ky, kx + 1] = PixBorder[(startInd - 3) % 8, kx] #DIAGONAL EXTENSION FROM RIGHT BORDER EXTENSION for ky in range(PatchWidth - 2, -1, -1): lstPix = FaceExtension[ky + 1, nside:nside + PatchWidth - 1].astype('int64').flatten() if (-1 in lstPix): if (Verbose): print("NOTHING TO DO") else: PixBorder = np.array( hp.get_all_neighbours(nside, lstPix, nest=nested)) for kx in range(nside, nside + PatchWidth - 1): UpperPix = FaceExtension[ky + 2, kx] if (-1 in PixBorder[0:8, kx - nside]): if (Verbose): print("CANNOT PROCESS PIXEL ({0},{1})".format(kx, ky)) else: lstStart = (np.where(PixBorder[0:8, kx - nside] == UpperPix)) if (len(lstStart[0]) > 0): if (Verbose): print("PROCESS PIXEL ({0},{1})".format(kx, ky)) startInd = lstStart[0][0] FaceExtension[ky, kx] = PixBorder[(startInd + 4) % 8, kx - nside] if (kx < nside + PatchWidth - 2): FaceExtension[ky, kx + 1] = PixBorder[(startInd + 5) % 8, kx - nside] if Verbose: print(FaceExtension.astype('int64')) return FaceExtension.astype('int64')
def from_galfile(cls, filename, zredfile=None, nside=0, hpix=0, border=0.0, truth=False): """ Generate a GalaxyCatalog from a redmapper "galfile." Parameters ---------- filename: `str` Filename of the redmapper "galfile" galaxy file. This file may be a straight fits file or (recommended) a galaxy table "master_table.fit" summary file. zredfile: `str`, optional Filename of the redmapper zred "zreds_master_table.fit" summary file. nside: `int`, optional Nside of healpix sub-region to read in. Default is 0 (full catalog). hpix: `int`, optional Healpix number (ring format) of sub-region to read in. Default is 0 (full catalog). border: `float`, optional Border around hpix (in degrees) to read in. Default is 0.0. truth: `bool`, optional Read in truth information if available (e.g. mocks)? Default is False. """ if zredfile is not None: use_zred = True else: use_zred = False if hpix == 0: _hpix = None else: _hpix = hpix # do we have appropriate keywords if _hpix is not None and nside is None: raise ValueError("If hpix is specified, must also specify nside") if border < 0.0: raise ValueError("Border must be >= 0.0.") # ensure that nside is valid, and hpix is within range (if necessary) if nside > 0: if not hp.isnsideok(nside): raise ValueError("Nside not valid") if _hpix is not None: if _hpix < 0 or _hpix >= hp.nside2npix(nside): raise ValueError("hpix out of range.") # check that the file is there and the right format # this will raise an exception if it's not there. hdr = fitsio.read_header(filename, ext=1) pixelated = hdr.get("PIXELS", 0) fitsformat = hdr.get("FITS", 0) # check zredfile if use_zred: zhdr = fitsio.read_header(zredfile, ext=1) zpixelated = zhdr.get("PIXELS", 0) if not pixelated: cat = fitsio.read(filename, ext=1, upper=True) if use_zred: zcat = fitsio.read(zredfile, ext=1, upper=True) if zcat.size != cat.size: raise ValueError("zredfile is a different length (%d) than catfile (%d)" % (zcat.size, cat.size)) return cls(cat, zcat) else: return cls(cat) else: if use_zred: if not zpixelated: raise ValueError("galfile is pixelated but zredfile is not") # this is to keep us from trying to use old IDL galfiles if not fitsformat: raise ValueError("Input galfile must describe fits files.") # now we can read in the galaxy table summary file... tab = Entry.from_fits_file(filename, ext=1) nside_tab = tab.nside if nside > nside_tab: raise ValueError("""Requested nside (%d) must not be larger than table nside (%d).""" % (nside, nside_tab)) if use_zred: ztab = Entry.from_fits_file(zredfile, ext=1) zpath = os.path.dirname(zredfile) # which files do we want to read? path = os.path.dirname(os.path.abspath(filename)) indices = get_subpixel_indices(tab, hpix=_hpix, border=border, nside=nside) # Make sure all the zred files are there if use_zred: # The default mode, copied from the IDL code, is that we just don't # read in any galaxy pixels that don't have an associated zred. # I don't know if this is what we want going forward, but I'll leave # it like this at the moment. # Also, we are assuming that the files actually match up in terms of length, etc. mark = np.zeros(indices.size, dtype=np.bool) for i, f in enumerate(ztab.filenames[indices]): if os.path.isfile(os.path.join(zpath, f.decode())): mark[i] = True bad, = np.where(~mark) if bad.size == indices.size: raise ValueError("There are no zred files associated with the galaxy pixels.") indices = np.delete(indices, bad) # create the catalog array to read into # FIXME: filter out any TRUTH information if necessary # will need to also get the list of columns from the thingamajig. # and need to be able to cut? elt = fitsio.read(os.path.join(path, tab.filenames[indices[0]].decode()), ext=1, rows=0, lower=True) dtype_in = elt.dtype.descr if not truth: mark = [] for dt in dtype_in: if (dt[0] != 'ztrue' and dt[0] != 'm200' and dt[0] != 'central' and dt[0] != 'halo_id'): mark.append(True) else: mark.append(False) dtype = [dt for i, dt in enumerate(dtype_in) if mark[i]] columns = [dt[0] for dt in dtype] else: dtype = dtype_in columns = None cat = np.zeros(np.sum(tab.ngals[indices]), dtype=dtype) if use_zred: zelt = fitsio.read(os.path.join(zpath, ztab.filenames[indices[0]].decode()), ext=1, rows=0, upper=False) zcat = np.zeros(cat.size, dtype=zelt.dtype) # read the files ctr = 0 for index in indices: cat[ctr: ctr + tab.ngals[index]] = fitsio.read(os.path.join(path, tab.filenames[index].decode()), ext=1, lower=True, columns=columns) if use_zred: # Note that this effectively checks that the numbers of rows in each file match properly (though the exception will be cryptic...) zcat[ctr: ctr + tab.ngals[index]] = fitsio.read(os.path.join(zpath, ztab.filenames[index].decode()), ext=1, upper=False) ctr += tab.ngals[index] if _hpix is not None and nside > 0 and border > 0.0: # Trim to be closer to the border if necessary... nside_cutref = 512 boundaries = hp.boundaries(nside, hpix, step=nside_cutref/nside) theta, phi = hp.pix2ang(nside_cutref, np.arange(hp.nside2npix(nside_cutref))) ipring_coarse = hp.ang2pix(nside, theta, phi) inhpix, = np.where(ipring_coarse == hpix) for i in xrange(boundaries.shape[1]): pixint = hp.query_disc(nside_cutref, boundaries[:, i], np.radians(border), inclusive=True, fact=8) inhpix = np.append(inhpix, pixint) inhpix = np.unique(inhpix) theta = np.radians(90.0 - cat['dec']) phi = np.radians(cat['ra']) ipring = hp.ang2pix(nside_cutref, theta, phi) _, indices = esutil.numpy_util.match(inhpix, ipring) if use_zred: return cls(cat[indices], zcat[indices]) else: return cls(cat[indices]) else: # No cuts if use_zred: return cls(cat, zcat) else: return cls(cat)
if infile_prefix is None: infile_prefix = '' infile_suffix = parms['dirstruct']['infile_suffix'] if infile_suffix is None: infile_suffix = '' outdir = parms['dirstruct']['outdir'] outfile_prefix = parms['dirstruct']['outfile_prefix'] if outfile_prefix is None: outfile_prefix = 'smoothed_cosmocube_' elif not isinstance(outfile_prefix, str): raise TypeError('Output filename prefix must be set to None or a string') nside = parms['output']['nside'] if nside is not None: if isinstance(nside, int): if HP.isnsideok(nside): fwhm_angres = HP.nside2resol(nside, arcmin=True) * U.arcmin # arcmin else: raise ValueError('NSIDE parameter invalid') else: raise TypeError('NSIDE parameter must be an integer') else: fwhm_angres = parms['output']['angres'] if not isinstance(fwhm_angres, (int,float)): raise TypeError('Angular resolution parameter must be a scalar') fwhm_angres = fwhm_angres * U.arcmin cosmoparms = parms['sim']['cosmo'] if cosmoparms['name'] is None: cosmo = None elif cosmoparms['name'].lower() == 'custom':
def setup_polar(self, rmin, rmax, numr, nside, center=[0., 0., 0.], rebin_shell=2, rebin_r=2, periodicx=[0, 0], periodicy=[0, 0], periodicz=[0, 0]): """Setups the polar grid. Parameters ---------- rmin : float Minimum r. rmax : float Maximum r. numr : int Number of bins along r-axis. nside : int Nside for healpix maps for each shell. center : list Center point of polar coordinate grid. rebin_shell : int Integer factor (a power of 2) for regriding the healpix shells to a higher nside than desired. This is then downgraded to the desired nside. rebin_r : int Integer factor for regridding the r axis by a factor rebin_r. This is then rebinned to the desired grid. """ assert rmin >= 0., "rmin must be greater or equal to zero." assert rmin < rmax, "rmin must be smaller than rmax." assert numr > 0, "numr must be greater than zero." assert len(center) == 3, "center list must have length 3." assert rebin_shell >= 1, "rebin_shell must be greater or equal to 1." assert hp.isnsideok(nside) == True, "Incompatible nside." assert hp.isnsideok( nside * rebin_shell ) == True, "Incompatible shell_rebin must be power of 2." assert rebin_r >= 1, "rebin_r must be greater or equal to 1." self.redges = np.linspace(rmin, rmax, numr + 1) self.rmid = 0.5 * (self.redges[1:] + self.redges[:-1]) self.dr = self.rmid[1] - self.rmid[0] self.nside = nside self.center = center self.rebin_shell = rebin_shell self.rebin_r = rebin_r centers = [] for i in range(periodicx[0], periodicx[1] + 1): for j in range(periodicy[0], periodicy[1] + 1): for k in range(periodicz[0], periodicz[1] + 1): centers.append([ center[0] + i * (self.xedges[-1] - self.xedges[0]), center[1] + j * (self.yedges[-1] - self.yedges[0]), center[2] + k * (self.zedges[-1] - self.zedges[0]) ]) self.centers = centers self.rebin_redges = np.linspace(self.redges[0], self.redges[-1], self.rebin_r * len(self.rmid) + 1) self.rebin_rmid = 0.5 * (self.rebin_redges[1:] + self.rebin_redges[:-1])
def check_nside(nside): """Raises exception if nside is not valid""" if not np.all(hp.isnsideok(nside)): raise ValueError( "%s is not a valid nside parameter (must be a power of 2, less than 2**30)" % str(nside))
def from_galfile(cls, filename, zredfile=None, nside=0, hpix=0, border=0.0, truth=False): """ Generate a GalaxyCatalog from a redmapper "galfile." Parameters ---------- filename: `str` Filename of the redmapper "galfile" galaxy file. This file may be a straight fits file or (recommended) a galaxy table "master_table.fit" summary file. zredfile: `str`, optional Filename of the redmapper zred "zreds_master_table.fit" summary file. nside: `int`, optional Nside of healpix sub-region to read in. Default is 0 (full catalog). hpix: `int`, optional Healpix number (ring format) of sub-region to read in. Default is 0 (full catalog). border: `float`, optional Border around hpix (in degrees) to read in. Default is 0.0. truth: `bool`, optional Read in truth information if available (e.g. mocks)? Default is False. """ if zredfile is not None: use_zred = True else: use_zred = False if hpix == 0: _hpix = None else: _hpix = hpix # do we have appropriate keywords if _hpix is not None and nside is None: raise ValueError("If hpix is specified, must also specify nside") if border < 0.0: raise ValueError("Border must be >= 0.0.") # ensure that nside is valid, and hpix is within range (if necessary) if nside > 0: if not hp.isnsideok(nside): raise ValueError("Nside not valid") if _hpix is not None: if _hpix < 0 or _hpix >= hp.nside2npix(nside): raise ValueError("hpix out of range.") # check that the file is there and the right format # this will raise an exception if it's not there. hdr = fitsio.read_header(filename, ext=1) pixelated = hdr.get("PIXELS", 0) fitsformat = hdr.get("FITS", 0) # check zredfile if use_zred: zhdr = fitsio.read_header(zredfile, ext=1) zpixelated = zhdr.get("PIXELS", 0) if not pixelated: cat = fitsio.read(filename, ext=1, upper=True) if use_zred: zcat = fitsio.read(zredfile, ext=1, upper=True) if zcat.size != cat.size: raise ValueError( "zredfile is a different length (%d) than catfile (%d)" % (zcat.size, cat.size)) return cls(cat, zcat) else: return cls(cat) else: if use_zred: if not zpixelated: raise ValueError( "galfile is pixelated but zredfile is not") # this is to keep us from trying to use old IDL galfiles if not fitsformat: raise ValueError("Input galfile must describe fits files.") # now we can read in the galaxy table summary file... tab = Entry.from_fits_file(filename, ext=1) nside_tab = tab.nside if nside > nside_tab: raise ValueError("""Requested nside (%d) must not be larger than table nside (%d).""" % (nside, nside_tab)) if use_zred: ztab = Entry.from_fits_file(zredfile, ext=1) zpath = os.path.dirname(zredfile) # which files do we want to read? path = os.path.dirname(os.path.abspath(filename)) indices = get_subpixel_indices(tab, hpix=_hpix, border=border, nside=nside) # Make sure all the zred files are there if use_zred: # The default mode, copied from the IDL code, is that we just don't # read in any galaxy pixels that don't have an associated zred. # I don't know if this is what we want going forward, but I'll leave # it like this at the moment. # Also, we are assuming that the files actually match up in terms of length, etc. mark = np.zeros(indices.size, dtype=np.bool) for i, f in enumerate(ztab.filenames[indices]): if os.path.isfile(os.path.join(zpath, f.decode())): mark[i] = True bad, = np.where(~mark) if bad.size == indices.size: raise ValueError( "There are no zred files associated with the galaxy pixels." ) indices = np.delete(indices, bad) # create the catalog array to read into # FIXME: filter out any TRUTH information if necessary # will need to also get the list of columns from the thingamajig. # and need to be able to cut? elt = fitsio.read(os.path.join(path, tab.filenames[indices[0]].decode()), ext=1, rows=0, lower=True) dtype_in = elt.dtype.descr if not truth: mark = [] for dt in dtype_in: if (dt[0] != 'ztrue' and dt[0] != 'm200' and dt[0] != 'central' and dt[0] != 'halo_id'): mark.append(True) else: mark.append(False) dtype = [dt for i, dt in enumerate(dtype_in) if mark[i]] columns = [dt[0] for dt in dtype] else: dtype = dtype_in columns = None cat = np.zeros(np.sum(tab.ngals[indices]), dtype=dtype) if use_zred: zelt = fitsio.read(os.path.join( zpath, ztab.filenames[indices[0]].decode()), ext=1, rows=0, upper=False) zcat = np.zeros(cat.size, dtype=zelt.dtype) # read the files ctr = 0 for index in indices: cat[ctr:ctr + tab.ngals[index]] = fitsio.read(os.path.join( path, tab.filenames[index].decode()), ext=1, lower=True, columns=columns) if use_zred: # Note that this effectively checks that the numbers of rows in each file match properly (though the exception will be cryptic...) zcat[ctr:ctr + tab.ngals[index]] = fitsio.read(os.path.join( zpath, ztab.filenames[index].decode()), ext=1, upper=False) ctr += tab.ngals[index] if _hpix is not None and nside > 0 and border > 0.0: # Trim to be closer to the border if necessary... nside_cutref = 512 boundaries = hp.boundaries(nside, hpix, step=nside_cutref / nside) theta, phi = hp.pix2ang(nside_cutref, np.arange(hp.nside2npix(nside_cutref))) ipring_coarse = hp.ang2pix(nside, theta, phi) inhpix, = np.where(ipring_coarse == hpix) for i in xrange(boundaries.shape[1]): pixint = hp.query_disc(nside_cutref, boundaries[:, i], np.radians(border), inclusive=True, fact=8) inhpix = np.append(inhpix, pixint) inhpix = np.unique(inhpix) theta = np.radians(90.0 - cat['dec']) phi = np.radians(cat['ra']) ipring = hp.ang2pix(nside_cutref, theta, phi) _, indices = esutil.numpy_util.match(inhpix, ipring) if use_zred: return cls(cat[indices], zcat[indices]) else: return cls(cat[indices]) else: # No cuts if use_zred: return cls(cat, zcat) else: return cls(cat)