def healpy_rejection_sampler_OLD(m, n): """ Special version of the generic rejection sampler. Here we sample map indices uniformly across the map (range [0, pi]x[0, 2*pi]) and check if the rejection criterium is fullfilled at that point. We can sample indices uniformly because healpixel areas are are equal across the sphere. Rejection algorithm: For each point draw a uniform rand number and reject the point if the value of the pdf is smaller. Else accept it and repeat until the n points are sampled. Returns n map indices drawn from the map transformed to a pdf. The resolution is the same as the input map which is sampled from. """ if hp.maptype(m) != 0: raise ValueError( "Given map is no healpy map (-1) or a series of maps (>0) : " + "{}.".format(hp.maptype(m))) # Get map parameter NPIX = hp.get_map_size(m) # Make sure the map is in pdf form, which is all positive and area = 1 m = norm_healpy_map(m) # Get the pdf maximium to set the sampling bounding box fmax = np.amax(m) def pdf(ind): """Simple wrapper to consistently use the name pdf. Returns the mapvals at given indices""" return m[ind] # Create list to store the sampled events sample = [] # Rejection sampling loop nstart = n efficiency = 0 while n > 0: # Count trials for efficinecy, has nothing to do with the sampling efficiency += n # Only choose integer map indices randomly as we operate on discrete # maps r1 = np.random.randint(0, NPIX, size=n) # Create n uniform distributed rand numbers between 0 and the maximum # of the function r2 = fmax * np.random.uniform(0, 1, n) # Calculate the pdf value pdf(r1) and compare to r2 # --> If r2 is below or equal func(r1) accept the event, else reject it accepted = (r2 <= pdf(r1)) # --> Where func(r2) is near the box boundary of fmax the efficiency is # good, else it gets worse. Append only accepted random numbers sample += r1[accepted].tolist() # Redo with n = events that are missing until n = 0 and all n requested # events are generated n = np.sum(~accepted) # eff first counts how many events where drawn from the pdf and is then the # fraction of the actual desired events n by the generetaded events. efficiency = nstart / float(efficiency) return np.array(sample), efficiency
def _setup(self): # Generate mapping from pix <-> angles self.gsm.generate(100) self._n_pix = hp.get_map_size(self.gsm.generated_map_data) self._n_side = hp.npix2nside(self._n_pix) self._theta, self._phi = hp.pix2ang(self._n_side, np.arange(self._n_pix))
def supmaps(maps, supmapiso=None): r"""Sum an ensemble of maps. Parameters ---------- maps : float, array_like A map or a list/array of maps. supmapiso : float, ndarray, optional A map limited in :math:`\theta`, used to account for the pixel weights on map edges. Default: *None*. Returns ------- supmap : float, ndarray A 1-D array resultant of the sum of the elements in `maps`. If `supmapiso` is given, weights are assigned to the pixels on the edges of `supmap`. """ if maps[0].ndim == 0: maps = np.reshape(maps, (1, len(maps))) npix = hp.get_map_size(maps[0]) supmap = np.sum(maps, axis=0) supmap *= npix / np.sum(supmap) if np.any(supmapiso): pixs = np.nonzero(supmapiso) supmap[pixs] /= supmapiso[pixs] supmap *= npix / np.sum(supmap) return supmap
def _get_a_map(self,field=0): print "Loading healpix map field="+str(field)+"." h = hp.read_map(path.join(self.dir,self.fname),field) if self.nside != []: if (hp.get_map_size(h) > hp.nside2npix(self.nside)): print "Downgrading." h = hp.ud_grade(h,nside_out=self.nside) print "Scaling from K_CMB to uK_CMB." h = h * self.cal return h
def kSZ_map(self, data_name): self._map_ksz = hp.read_map(self.data_path + data_name, field=0, nest=self._nest, verbose=self._feedback) self.apply_mask(self._map_ksz) #print np.min(np.abs(self._map_ksz)) #self._map_ksz[np.abs(self._map_ksz) < 1.00408215076e-2] = hp.UNSEEN #self._map_ksz = hp.ma(self._map_ksz) self._nside = hp.get_nside(self._map_ksz) self._npix = hp.get_map_size(self._map_ksz)
def _setup(self): self._freq = 100 self._time = Time(self.date.datetime()) # Generate mapping from pix <-> angles self.gsm.generate(self._freq) self._n_pix = hp.get_map_size(self.gsm.generated_map_data) self._n_side = hp.npix2nside(self._n_pix) self._theta, self._phi = hp.pix2ang(self._n_side, np.arange(self._n_pix)) self._pix0 = None self._mask = None self._observed_ra = None self._observed_dec = None
def __init__(self): """ Initialize the Observer object. Calls ephem.Observer.__init__ function and adds on gsm """ super(GSMObserver, self).__init__() self.gsm = GlobalSkyModel() self.observed_sky = None # Generate mapping from pix <-> angles self.gsm.generate(100) self._n_pix = hp.get_map_size(self.gsm.generated_map_data) self._n_side = hp.npix2nside(self._n_pix) self._theta, self._phi = hp.pix2ang(self._n_side, np.arange(self._n_pix))
def __init__(self): """ Initialize the Observer object. Calls ephem.Observer.__init__ function and adds on gsm """ super(GSMObserver2016, self).__init__() self.gsm = GlobalSkyModel2016(freq_unit='MHz') self.observed_sky = None # Generate mapping from pix <-> angles self.gsm.generate(1000) self._n_pix = hp.get_map_size(self.gsm.generated_map_data) self._n_side = hp.npix2nside(self._n_pix) self._theta, self._phi = hp.pix2ang(self._n_side, np.arange(self._n_pix))
def cartesian_proj(hp_map, projector): """Create an array containing the Cartesian projection of the map. Parameters ---------- map : array-like An array containing a healpix map, can be complex. projector : cartesian projector The Cartesian projector. """ nside = healpy.npix2nside(healpy.get_map_size(hp_map.real)) vec2pix_func = lambda x, y, z: healpy.vec2pix(nside, x, y, z) cart_map = projector.projmap(hp_map.real, vec2pix_func) if np.iscomplexobj(hp_map): cart_map = cart_map + 1.0J * projector.projmap(hp_map.imag, vec2pix_func) return cart_map
def __init__(self, gsm_instance): """Initialize the common Observer object with a GSM instance Calls ephem.Observer.__init__ function and adds on gsm """ super(BaseObserver, self).__init__() self.observed_sky = None self.gsm = gsm_instance # Inline replacement of self._setup() follows. # Generate mapping from pix <-> angles gen_freq_Hz = 100e6 fu = gsm_instance.freq_unit gen_freq = 100 if fu == 'Hz': gen_freq = 100e6 elif fu == 'GHz': gen_freq = 0.1 self.gsm.generate(gen_freq) self._n_pix = hp.get_map_size(self.gsm.generated_map_data) self._n_side = hp.npix2nside(self._n_pix) self._theta, self._phi = hp.pix2ang(self._n_side, np.arange(self._n_pix))
def add_sources_to_sky_map( input_map, frequencies, sources, fwhm_deg=("Auto", 1), catalog_file="Auto", reference_frequency="143", ): """ This function takes a PySM map array and adds point sources with a frequency behaviour consistent with their SED as derived from the PCCS catalog. The point source is added in total intensity and polarization (Q and U). Stokes parameters Q and U are derived using the polarization angle present in the catalog Input input_map - NDARRAY - An array shaped (nfreq, npix, 3) containing sky maps in the frequencies defined in the QUBIC dictionary (n_sub is the number of frequencies, filter_nu is the center frequency, filter_relative_bandwidth is the relative bandwidth frequencies - LIST or NDARRAY - list of frequencies in Hz sources - LIST or NDARRAY - list of sources ad defined in the QUBIC pccs fwhm_deg - TUPLE - The fwhm in degrees of the gaussian used to smooth the source. fwhm_deg is specified as a tuple. If fwhm_deg[0] == 'Auto' then the fwhm is derived automatically by the pixel size multiplying it by the factor specified in fwhm_deg[1]. If fwhm_deg[0] == 'Man' then the fwhm is specified directly, in degrees, in fwhm_deg[1]. Default is fwhm_deg = ('Auto', 1) catalog_file - STRING - the catalog filename (in pickle format) If catalog_file = 'Auto' (Default) then catalog_file = qubic.data.PATH + 'qubic_pccs2.pickle' reference_frequency - STRING - the reference frequency in GHz in the catalog to derive the source coordinates. It defaults to 143 GHz. Can be left to this value also for 220 GHz, as the source location is weakly dependent on the frequency Output output_map - NDARRAY - An array shaped (nfreq, npix, 3) containing sky + point sources maps """ import qubic import pickle import numpy as np import healpy as h catalog_frequencies = ['030', '044', '070', '100', '143', '217', '353'] complement_frequencies = [ f for f in catalog_frequencies if f != reference_frequency ] output_map = input_map.copy() # Check that the number of frequencies is consistent with the input map if len(input_map) != len(frequencies): print("The number of maps and frequencies are inconsistent.") print("There are %i maps and %i frequencies" % (len(input_map), len(frequencies))) return -1 nside = h.get_nside(input_map[0, :, 0]) # Define catalog file if not provided manually if catalog_file == "Auto": catalog_file = qubic.data.PATH + "qubic_pccs2.pickle" # Define fwhm in degrees if type(fwhm_deg) is not tuple: print( "The variable fwhm_deg must be a tuple. Call help(add_sources_to_sky_map) for more info" ) return -1 if fwhm_deg[0] != "Auto" and fwhm_deg[0] != "Man": print("fwhm_deg[0] must be either 'Auto' or 'Man'") return -1 if fwhm_deg[0] == "Auto": # Then fwhm is the map pixel size npix = h.get_map_size(input_map[0, :, 0]) pix_size_deg = (2 * np.sqrt(np.pi / npix) * 180 / np.pi ) # It's sqrt(4pi/npix) converted to deg fwhm = fwhm_deg[1] * pix_size_deg else: fwhm = fwhm_deg[1] # Open point source catalog with open(catalog_file, "rb") as handle: catalog = pickle.load(handle) for source in sources: # Check if source is in catalog with the reference frequency otherwise shift to the previous # frequency if source not in catalog[reference_frequency].keys(): isincatalog = [ source in catalog[f].keys() for f in complement_frequencies ] if True not in isincatalog: print('Source %s is not in catalog' % source) return -1 print('Source %s is not in catalog at frequency %s GHz' % (source, reference_frequency)) goodfreq = [i for i, x in enumerate(isincatalog) if x] diff_freq = np.abs( np.array( list( map(float, [complement_frequencies[i] for i in goodfreq]))) - float(reference_frequency)) index = np.where(diff_freq == np.min(diff_freq))[0] reference_frequency = complement_frequencies[index[0]] print('Switched to new reference frequency %s GHz' % reference_frequency) print("Processing source %s (%i/%i)" % (source, list(sources).index(source) + 1, len(sources))) source_center_deg = ( catalog[reference_frequency][source]["GLON"], catalog[reference_frequency][source]["GLAT"], ) # Calculate SED of source in T and P and fitting polynomial sed = qubic.compact_sources_sed.build_sed(source, catalog, plot=False) fi = np.poly1d(sed[source]["i_fit"]) fp = np.poly1d(sed[source]["p_fit"]) # Loop over frequencies, for each frequency get the corresponding flux in I and P for fq in frequencies: fq_index = list(frequencies).index(fq) print("Processing frequency # %i of %i" % (fq_index + 1, len(frequencies))) i_flux = fi(fq / 1e9) / 1e3 # Conversion from mJy -> Jy p_flux = fp(fq / 1e9) / 1e3 # Conversion from mJy -> Jy polarization_angle = ( catalog[reference_frequency][source]["ANGLE_P"] * np.pi / 180.0) if p_flux > 0.0: q_flux = p_flux * np.cos(2.0 * polarization_angle) u_flux = p_flux * np.sin(2.0 * polarization_angle) else: q_flux = 0 u_flux = 0 flux = [i_flux, q_flux, u_flux] for index in [0, 1, 2]: outmap = insert_source( source_center_deg, fwhm, flux[index], nside, units="uK_CMB", input_map=input_map[fq_index, :, index], frequency=fq, ) output_map[fq_index, :, index] = outmap input_map = output_map.copy() print("") return output_map
def similar_range(params, map_struct): if params['doObservability']: observability_struct = map_struct['observability'] telescope = observability_struct.keys()[0] prob = observability_struct[telescope]['prob'] else: prob = map_struct['prob'] nested_map = hp.pixelfunc.reorder(prob, r2n=True) regions = params['Nregions'] region_nsides = int((regions / 12)**.5) res = hp.get_map_size(prob) region_size = res / regions sliced_array = np.zeros([regions, region_size]) start = 0 end = start + region_size for region in range(regions): sliced_array[region] = nested_map[start:end] start += region_size end += region_size # Theres def a way to do this with numpy but i'm on a train, can't see docs sum_hp = lambda arr: np.array([np.sum(row) for row in arr]) sums = sum_hp(sliced_array) sum_neighbours = lambda n: np.sum( [sums[p] for p in hp.get_all_neighbours(region_nsides, n, nest=True)]) nb_sums = np.array([sums[i] + sum_neighbours(i) for i in range(len(sums))]) region_order = np.argsort(nb_sums)[::-1] significant_regions = np.array([]) for idx in region_order: if sums[idx] > max(sums) * 0.0001: significant_regions = np.append(significant_regions, idx) significant_regions = significant_regions.astype(int) groups = [] def group_neighbours(group): neighbours = np.array([]) for i in group: neighbours = np.append( neighbours, hp.get_all_neighbours(region_nsides, int(i), nest=True)) return neighbours for idx in significant_regions: if len(groups) == 0: groups.append([idx]) continue for group in groups: if idx in group_neighbours(group): group.append(idx) break else: groups.append([idx]) group_maps = [] for group in groups: combined_map = np.array([]) for i in range(len(sliced_array)): if i in group: combined_map = np.append(combined_map, sliced_array[i]) else: combined_map = np.append(combined_map, np.zeros(len(sliced_array[0]))) group_maps.append(combined_map) group_maps = [hp.reorder(hp_map, n2r=True) for hp_map in group_maps] return group_maps
sys.stdout = open(os.devnull, "w") mask = hp.read_map('galacticMask.fits') sys.stdout = sys.__stdout__ map_mask = [] for i in range(6): map_mask.append(map_smooth[i] * mask) print 'ILC on full sky' f_nu = ilc.dist_SZ(freq) a = np.ones(n_obs) a_t = np.transpose(a) b = np.ones(n_obs) b = f_nu b_t = np.transpose(b) CMB = np.zeros(hp.get_map_size(map_smooth[0])) TSZ = np.zeros(hp.get_map_size(map_smooth[0])) J = np.cov((map_smooth[0], map_smooth[1], map_smooth[2], map_smooth[3], map_smooth[4], map_smooth[5])) K = np.linalg.inv(J) WK, WT = ilc.weight(K, a, a_t, b, b_t) # test with mask if args.mask: print 'ILC on full sky with mask' L = np.cov((map_mask[0], map_mask[1], map_mask[2], map_mask[3], map_mask[4], map_mask[5])) P = np.linalg.inv(L) WK_mask, WT_mask = ilc.weight(P, a, a_t, b, b_t) for i in range(n_obs):
fact = 1.42144524614e-05 filename = 'data/HFI_CompMap_ThermalDustModel_2048_R1.20.fits' filename = 'data/HFI_SkyMap_353_2048_R2.02_full.fits' test_map = hp.read_map(filename) #hp.mollview(test_map, title=filename, coord='G', unit='K', norm='hist', min=1e-7,max=1e-3, xsize=800) hp.mollview(test_map, title=filename, coord='G', unit='K', norm='hist', xsize=800) #hp.mollview(test_map) #hp.cartview(test_map, title=filename, coord='G', rot=[0,0], unit='K', norm='hist', min=-1375,max=2687, xsize=800, lonra=[-1,1], latra=[-1,1]) #hp.orthview(test_map) #hp.gnomview(test_map) print hp.get_nside(test_map) print hp.maptype(test_map) print hp.get_map_size(test_map) print len(test_map) print test_map[0:10]*np.float(fact) equateur_lon = [10.,0.] equateur_lat = [10.,0.] hp.projplot(equateur_lon, equateur_lat, lonlat=True, coord='G') # plt.loglog(hp.anafast(test_map)) # plt.grid() # plt.xlabel("$\ell$") # plt.ylabel("$C_\ell$") plt.grid() plt.show()
def make_normmaps(maps, supmap, etacut=0.9): r"""Divide an ensemble of maps by a single map, preferably the sum of said ensemble. Parameters ---------- maps : float, array_like A single map or an ensemble of maps. They should be limited in pseudorapidity by the value in `etacut`. supmap : float, ndarray A 1-D array usually representing the sum of all elements in `maps`. etacut : float, scalar, optional The value of the pseudorapidity limit, :math:`|\eta|` < `etacut`. If there is no limit, set it to *None*. Default: 0.9. Returns ------- norm_maps : float, array_like The result of dividing `maps` by `supmap`. Its shape will be the same as `maps`. Notes ----- In the power spectral analysis at hand [1]_ [2]_, `supmap` is the sum of all event maps and it is represented by :math:`F^{all}(\mathbf{n_p})`, where :math:`\mathbf{n_p}` is a pixel number. A normalized map is thus defined by the following expression: .. math:: \bar{f}(\mathbf{n_p}) = \frac{f(\mathbf{n_p})}{F^{all}(\mathbf{n_p})}, where :math:`f(\mathbf{n_p})` is a map from the original event ensemble, the latter denoted by the `maps` parameter. References ---------- .. [1] M. Machado, P.H. Damgaard, J.J. Gaardhoeje, and C. Bourjau, "Angular power spectrum of heavy ion collisions", Phys. Rev. C **99**, 054910 (2019). .. [2] M. Machado, "Heavy ion anisotropies: a closer look at the angular power spectrum", arXiv:1907.00413 [hep-ph] (2019). """ if maps[0].ndim == 0: maps = np.reshape(maps, (1, len(maps))) npix = hp.get_map_size(maps[0]) nside = hp.npix2nside(npix) if etacut: qi, qf = 2. * np.arctan(np.exp(-np.array([etacut, -etacut]))) mask = np.ones(npix) mask[hp.query_strip(nside, qi, qf)] = 0. else: qi, qf = 0., 2 * np.pi mask = 0. finmap = supmap / npix * (1. - mask) + mask pixs = np.where(finmap == 0.) finmap[pixs] = 1. norm_maps = maps / (npix * finmap) norm_maps *= npix / np.sum(norm_maps, axis=1)[:, None] return norm_maps
Nside = 4 # = 1, 2, 4, 8, 16, 64, ... Resolution = hp.nside2resol(Nside) print('(1)', Nside, '-->', Resolution, 'radians') Resolution = hp.nside2resol(Nside, arcmin=True) print('(2)', Nside, '-->', Resolution, 'arcmin =', Resolution / 60., 'deg') Area = hp.nside2pixarea(Nside, degrees=True) print('(3)', Nside, '-->', Area, 'square deg') # get_map_size / get_nside mapa = hp.read_map('COM_CMB_IQU-smica_1024_R2.02_full.fits') Npix_mapa = hp.get_map_size(mapa) Nside_mapa = hp.get_nside(mapa) print('Nside =', Nside_mapa) print('Npix =', Npix_mapa) #%% """ STEP 6: Nside / Npix / Resolution """ mapa = hp.read_map('COM_CMB_IQU-smica_1024_R2.02_full.fits') hp.mollview(mapa, title='CMB map - Nside=1024', unit='K') mapa_deg = hp.ud_grade(mapa, 64, order_in='RING', order_out='NEST')
def __init__(self, noise_cov, mask): self.tau = np.min(noise_cov[mask == 1]) self.t_cov = self.tau * np.ones(hp.get_map_size(noise_cov)) self.noise_cov = noise_cov