def time_delay(theta, phi, ifo1, ifo2, coord="E", tgeocent=None, degrees=False): """ returns the time delay between two ifo's (in seconds) interprets direction as (theta, phi) or (dec, ra) depending on \"coord\" """ if ifo1 not in detectors.keys(): raise ValueError("ifo1=%s not understood" % ifo1) if ifo2 not in detectors.keys(): raise ValueError("ifo2=%s not understood" % ifo2) dr = detectors[ifo1].dr - detectors[ifo2].dr if degrees: theta *= deg2rad phi *= deg2rad if coord == "C": theta, phi = __celest2earth(theta, phi, tgeocent) theta = theta % np.pi phi = phi % (2 * np.pi) if isinstance(theta, float): return np.sum(hp.ang2vec(theta, phi) * dr) else: return np.sum(hp.ang2vec(theta, phi) * dr, axis=1)
def test_pointingTree(fname, opsimversion, tableNames, angleUnit): """test that `PointingTree` is set up correctly to handle pointings provided by `OpSimOutput.summary` by checking that distance calculations for the 10 nearest ones match """ fname = os.path.join(oss.example_data, fname) ops_out = OpSimOutput.fromOpSimDB(fname, opsimversion=opsimversion, tableNames=tableNames) pointings = ops_out.summary.iloc[:100] # Find distances to a specific location ra=54.0 deg, dec=-27.5 deg radeg = 54.0 decdeg = -27.5 ra = np.radians(radeg) dec = np.radians(decdeg) ptree = PointingTree(pointings, raCol='_ra', decCol='_dec') # Find the 10 nearest pointings dists, idxs = ptree.tree.query([(dec, ra)], k=10) # Now calculate the distances more directly # order the 10 pointings as above obs = pointings.iloc[idxs[0]] vec = hp.ang2vec(radeg, decdeg, lonlat=True) vecs = hp.ang2vec(np.degrees(obs._ra), np.degrees(obs._dec), lonlat=True) assert_allclose(np.dot(vecs, vec), np.cos(dists[0]))
def mask_unseen(hpmap, az, el, doconvert = False, nest = False): ''' Mask unseen directions in the scan. Use as input the house keeping coordinates. Parameters: hpmap. Healpix map (npix) az and el. Azimuth and Elevation coordinates read from azimuth.fits and elevation.fits doconvert. Consider the data as real azimuth and elevation (not implemented in that way in demodulation yet). Return: hpmap[masked] ''' if doconvert: hkcoords = np.meshgrid(az, el) radec = qubic.hor2equ(hkcoords[0].ravel(), hkcoords[1].ravel(), 0) phi = radec[0] theta = radec[1] #Rotation from Az,El housekiping to Az, El = 0,0 newcoords = np.dot(sbfit.rotmatY(qubic.hor2equ(0,+50,0)[1]), hp.ang2vec(np.pi/2-np.deg2rad(theta), np.deg2rad(phi)).T).T else: hkcoords = np.meshgrid(az, el-50) phi = hkcoords[0].ravel() theta = hkcoords[1].ravel() newcoords = hp.ang2vec(np.pi/2-np.deg2rad(theta), np.deg2rad(phi)) nside = hp.get_nside(hpmap) coordspix = hp.vec2pix(nside, newcoords[...,0], newcoords[...,1], newcoords[...,2], nest = nest) mask = np.zeros((12 * nside **2 ), dtype = bool) mask[coordspix] = 1 hpmap[~mask] = hp.UNSEEN #hp.mollview(hpmap, nest = True) show() return hpmap
def test_synopsimPTree(fname, opsimversion, tableNames, angleUnit): """ test that the pointings for a particular point at ra = 54.0 deg and dec = -27.5 deg are found through the pointing tree and through a calculation through the vectors and dot products match """ fname = os.path.join(oss.example_data, fname) synopsim = SynOpSim.fromOpSimDB(fname, opsimversion=opsimversion, tableNames=tableNames, usePointingTree=True, angleUnit=angleUnit) # Find distances to a specific location ra=54.0 deg, dec=-27.5 deg radeg = 54.0 decdeg = -27.5 pts = synopsim.pointingTree.pointingsEnclosing(ra=radeg, dec=decdeg, circRadius=0., pointingRadius=1.75) res = np.sort(pts[0]) # calculate differently X = synopsim.pointings[['_dec', '_ra']].apply(np.degrees) dec = X.values[:, 0] ra = X.values[:, 1] vecs = hp.ang2vec(ra, dec, lonlat=True) vec = hp.ang2vec(radeg, decdeg, lonlat=True) X.loc[:, 'dist'] = np.dot(vecs, vec) costhresh = np.cos(np.radians(1.75)) assert_array_equal(np.sort(X.query('dist > @costhresh').index), res)
def get_points(self, idx, get_childs=False): x = [] y = [] z = [] c = [] if len(idx.split("cen_")) > 1: unit_vector = hp.ang2vec(self.centers[idx].phi, self.centers[idx].theta, lonlat=True) curr_vector = (unit_vector * self.centers[idx].r)[0] #print(curr_vector) x.append(curr_vector[0]) y.append(curr_vector[1]) z.append(curr_vector[2]) c.append("b") if not get_childs: return x, y, z, c for key in self.centers[idx].childs: x_, y_, z_, c_ = self.get_points(key, get_childs) x.append(x_[0]) y.append(y_[0]) z.append(z_[0]) c.append(c_[0]) if len(idx.split("rim_")) > 1: unit_vector = hp.ang2vec(self.rims[idx].phi, self.rims[idx].theta, lonlat=True) curr_vector = (unit_vector * self.rims[idx].r)[0] x.append(curr_vector[0]) y.append(curr_vector[1]) z.append(curr_vector[2]) c.append("red") if not get_childs: return x, y, z, c for key in self.rims[idx].childs: x_, y_, z_, c_ = self.get_points(key, get_childs) x.append(x_[0]) y.append(y_[0]) z.append(z_[0]) c.append(c_[0]) if len(idx.split("cenClump_")) > 1: unit_vector = hp.ang2vec(self.clumps_center[idx].phi, self.clumps_center[idx].theta, lonlat=True) curr_vector = (unit_vector * self.clumps_center[idx].r)[0] x.append(curr_vector[0]) y.append(curr_vector[1]) z.append(curr_vector[2]) c.append("green") if len(idx.split("flatClump_")) > 1: unit_vector = hp.ang2vec(self.clumps_flat[idx].phi, self.clumps_flat[idx].theta, lonlat=True) curr_vector = (unit_vector * self.clumps_flat[idx].r)[0] x.append(curr_vector[0]) y.append(curr_vector[1]) z.append(curr_vector[2]) c.append("blue") return x, y, z, c
def getCirclePixels(ra_pointing, dec_pointing, radius, nside, alpha=0.4, color='k', edgecolor='k', rotation=None): theta = 0.5 * np.pi - np.deg2rad(dec_pointing) phi = np.deg2rad(ra_pointing) xyz = hp.ang2vec(theta, phi) ipix = hp.query_disc(nside, xyz, np.deg2rad(radius)) radecs = get_ellipse_coords(a=radius / np.cos(np.deg2rad(dec_pointing)), b=radius, x=ra_pointing, y=dec_pointing, angle=0.0, npts=25) idx = np.where(radecs[:, 1] > 90.0)[0] radecs[idx, 1] = 180.0 - radecs[idx, 1] idx = np.where(radecs[:, 1] < -90.0)[0] radecs[idx, 1] = -180.0 - radecs[idx, 1] idx = np.where(radecs[:, 0] > 360.0)[0] radecs[idx, 0] = 720.0 - radecs[idx, 0] idx = np.where(radecs[:, 0] < 0.0)[0] radecs[idx, 0] = 360.0 + radecs[idx, 0] radecs = np.array(radecs) idx1 = np.where(radecs[:, 0] >= 180.0)[0] idx2 = np.where(radecs[:, 0] < 180.0)[0] idx3 = np.where(radecs[:, 0] > 300.0)[0] idx4 = np.where(radecs[:, 0] < 60.0)[0] if (len(idx1) > 0 and len(idx2) > 0) and not (len(idx3) > 0 and len(idx4) > 0): alpha = 0.0 xyz = hp.ang2vec(radecs[:, 0], radecs[:, 1], lonlat=True) proj = hp.projector.MollweideProj(rot=rotation, coord=None) x, y = proj.vec2xy(xyz[:, 0], xyz[:, 1], xyz[:, 2]) xy = np.zeros(radecs.shape) xy[:, 0] = x xy[:, 1] = y #path = matplotlib.path.Path(xyz[:,1:3]) path = matplotlib.path.Path(xy) patch = matplotlib.patches.PathPatch(path, alpha=alpha, color=color, fill=True, zorder=3, edgecolor=edgecolor) area = np.pi * radius**2 return ipix, radecs, patch, area
def pointingsEnclosing(self, ra, dec, circRadius=0., pointingRadius=1.75, usePointingTree=None, transform=None, subset='all'): """ Helper method returning a generator of pointings overlapping with circles of radius `circRadius around a sequence of positions given in terms of `ra` and `dec`. The calculation uses a `Tree` to make the calculations more efficient if `usePointingTree` is True, or uses direct calculations if this variable is set to `False`. A user may choose to obtain a subset of the `pointing` by supplying a subset in the form a list via the parameter `subset`. Parameters ---------- ra : `np.ndarray` or a float, unit of degrees a float or an array of floats representing the ra values dec : `np.ndarray` or a float, unit of degrees a float or an array of floats representing the dec values circRadius: float, unit of degrees, defaults to 0. a circle around each of the pointingRadius : degrees, defaults to 1.75 radius of the field of view usePointingTree: {None|True|False}, defaults to `None` if None, usePointingTree = self.usePointingTree else the variable takes the {True|False} values assigned transform: function, Not implemented subset: (list of strings| 'all') if 'all', df is returned. Otherwise, return df[subset], with the same index. Returns ------- A generator with the pointings that overlap with ra, dec .. note: 1. the values in the generator may be accessed by next(generator) 2. subset=[] returns only the index """ print('check using ptree', usePointingTree) if transform is not None: raise NotImplementedError('transforms are not implemented yet') if usePointingTree is None: usePointingTree = self.usePointingTree if usePointingTree: hidxs = self.pointingTree.pointingsEnclosing(ra, dec, circRadius, pointingRadius) for hidx in hidxs: yield self.df_subset_columns(self.pointings.loc[hidx], subset) else: print(self.pointings['_ra'].max()) x = self.pointings[['_ra', '_dec']].copy().apply(np.degrees) pvecs = hp.ang2vec(x._ra, x._dec, lonlat=True) vecs = hp.ang2vec(ra, dec, lonlat=True) prad = np.radians(pointingRadius + circRadius) for vec in vecs: x.loc[:, 'dist'] = np.arccos(np.dot(pvecs, vec)) idx = x.query('dist < @prad').index yield self.df_subset_columns(self.pointings.loc[idx], subset)
def makeGauss(nside, ra, dec, amp, varparam=np.sqrt(2 * np.pi)): #bounds=None):#radius=6447797.0): print('RA length:' + str(len(ra))) print('dec length:' + str(len(dec))) print('amp length:' + str(len(amp))) raMin = min(ra) - 2.0 raMax = max(ra) + 2.0 decMin = min(dec) - 2.0 decMax = max(dec) + 2.0 #m = np.arange(hp.nside2npix(nside)) vertices = hp.ang2vec([raMin, raMin, raMax, raMax], [decMin, decMax, decMax, decMin], lonlat=True) m = hp.query_polygon(nside, vertices) m_ra, m_dec = hp.pix2ang(nside, m, lonlat=True) m_amp = np.zeros_like(m, dtype='float64') #ra = ra*1.0 #dec = dec*1.0 numpix = m.size #if True: #bounds != None: # raMin = min(ra)-2.0 # raMax = max(ra)+2.0 # decMin = min(dec)-2.0 # decMax = min(dec)+2.0 # Compute distance of center of data to each pixel # centDist = haversine(np.full_like(m,raCent),np.full_like(m,decCent),m_ra,m_dec) # Get indices of pixels to delete # toDelete = [ k for (i,j,k) in zip(m_ra,m_dec,m) if i < raMin or i > raMax or j < decMin or j > decMax ] # #m = np.delete(m, toDelete) # m_ra = np.delete(m_ra, toDelete) # m_dec = np.delete(m_dec, toDelete) # m_amp = np.delete(m_amp, toDelete) # numdeleted = str(len(toDelete)) # print(numdeleted + ' uninteresting pixels deleted of '+str(numpix)) ### TO IMPLEMENT: Check ra, dec, amp are of same size #if isinstance(ra, np.ndarray): for rai, deci, ampi in itertools.izip(ra, dec, amp): # Used to convert from ra/dec to pixel to vec; should not be necessary #nearpix = hp.pix2vec(nside,hp.ang2pix(nside,rai,deci,lonlat=True)) nearpix = hp.ang2vec(rai, deci, lonlat=True) # Calculate Gaussian on pixels within following radius (in degrees) radius = 3.0 / 60.0 # Hard-coded; remove eventually pxls = hp.query_disc(nside, nearpix, radius * np.pi / 180.0) indices = np.searchsorted(m, pxls) near_ra, near_dec = hp.pix2ang(nside, pxls, lonlat=True) #print('Using nearest '+str(len(near_ra))+' pixels to source.') #near_ra = m_ra[pxls] #near_dec = m_dec[pxls] m_dist = np.zeros_like(near_ra) var = varparam * 1.0 m_dist = haversine(np.full_like(near_ra, rai), np.full_like(near_ra, deci), near_ra, near_dec) m_amp[indices] += computeGauss(ampi, m_dist, var) print('makeGauss output length: ' + str(m_ra.size)) return m_ra, m_dec, m_dist, m_amp
def make_ring_mask(inner, outer, ring_b, ring_l, nside): """ Masks outside inner < r < outer, of a ring centred at (ring_b,ring_l) """ mask_none = np.arange(hp.nside2npix(nside)) return np.logical_not( (np.cos(np.radians(inner)) >= np.dot( hp.ang2vec(np.radians(90 - ring_b), np.radians(ring_l)), hp.pix2vec(nside, mask_none))) * (np.dot(hp.ang2vec(np.radians(90 - ring_b), np.radians(ring_l)), hp.pix2vec(nside, mask_none)) >= np.cos(np.radians(outer))))
def integrate_intensity_map(Imap,nside,latmin=-2,latmax=2. ,nsteps_long=500,rad_units=False,planck_map=False): """ Compute the integral of the intensity map along latitude and longitude; to compare observed intensity map and the model one. To check consistency of the model we compute the integral as in eqs.(6) and (7) of `Puglisi+ 2017 <http://arxiv.org/abs/1701.07856>`_. *Parameters* - `Imap`:{array} intensity map - `nside`: {int} :mod:`healpy` gridding parameter - `latmin`, `latmax`:{double} minimum and maximum latitudes in `degree` where to perform the integral (default :math:`\pm 2\, deg`) if you have the angles in radiants set `rad_units` to `True`. - `nsteps_long`:{int} number of longitudinal bins, (default 500) - `planck_map`:{bool} if set to `True`, it sets to zero all the :mod:`healpy.UNSEEN` masked pixels of the map, (useful when dealing with observational maps). **Returns** - `I_l` :{array} latitude integration within the set interval :math:`[b_{min}, b_{max}]` - `I_tot`:{double} integration of `I_l` in :math:`\ell \in [0,2 \pi]`. """ if planck_map: arr=np.ma.masked_equal(Imap,hp.UNSEEN) Imap[arr.mask]=0. if not rad_units: latmin=np.pi/2.+(np.deg2rad(latmin)) latmax=np.pi/2.+(np.deg2rad(latmax)) nbins_long=nsteps_long-1 long_edges=np.linspace(0.,2*np.pi,num=nsteps_long) long_centr=[.5*(long_edges[i]+ long_edges[i+1]) for i in range(nbins_long)] listpix=[] for i in range(nbins_long): v=[ hp.ang2vec(latmax, long_edges[i]), hp.ang2vec(latmax, long_edges[i+1]), hp.ang2vec(latmin, long_edges[i+1]), hp.ang2vec(latmin, long_edges[i])] listpix.append(hp.query_polygon(nside,v)) delta_b=pixelsize(nside,arcmin=False) delta_l=2*np.pi/nbins_long I_l=[sum(Imap[l])*delta_b for l in listpix ] Itot= sum(I_l)*delta_l return Itot,I_l
def angsep2(lon_1, lat_1, lon_2, lat_2): """ Angular separation (deg) between two sky coordinates. """ import healpy v10, v11, v12 = healpy.ang2vec(np.radians(90. - lat_1), np.radians(lon_1)).transpose() v20, v21, v22 = healpy.ang2vec(np.radians(90. - lat_2), np.radians(lon_2)).transpose() val = (v10 * v20) + (v11 * v21) + (v12 * v22) val = np.clip(val, -1., 1.) return np.degrees(np.arccos(val))
def antipode(x, y, coord="C", degrees=False): """ if coord=C : x->ra, y->dec if coord=E : x->phi, y->theta returns the anitpode position """ if coord == "C": Y, X = hp.vec2ang(-hp.ang2vec(0.5 * np.pi - y, x)) Y = 0.5 * np.pi - Y elif coord == "E": Y, X = hp.vec2ang(-hp.ang2vec(y, x)) return X, Y
def gamma_from_pol(gal, pol, fixed_basis=False): ''' It should be possible to distribute the inner product among all time observations, but the matrix algebra is escaping me right now. In any case, for a one time operation this doesn't seem too slow yet. ''' # gal and pol are galactic lonlat vectors dir_A_gal = hp.ang2vec(gal[:, 0] % np.pi, gal[:, 1] % (2 * np.pi), lonlat=False) dir_A_pol = hp.ang2vec(pol[:, 0] % np.pi, pol[:, 1] % (2 * np.pi), lonlat=False) dir_Z = np.array([0, 0, 1]) sin_theta_A = np.sqrt(dir_A_gal[:, 0]**2 + dir_A_gal[:, 1]**2) dir_A_west_x = dir_A_gal[:, 1] / sin_theta_A dir_A_west_y = -dir_A_gal[:, 0] / sin_theta_A dir_A_west_z = dir_A_gal[:, 1] * 0 dir_A_west = np.array([dir_A_west_x, dir_A_west_y, dir_A_west_z]).T dir_A_north = (dir_Z - dir_A_gal[2] * dir_A_gal) / sin_theta_A[:, np.newaxis] ''' if sin_theta_A == 0: dir_A_west = np.array([1,0,0]) dir_A_north = np.array([0,1,0]) assert dir_A_north.dot(dir_A_west) == approx(0), 'Vectors not orthogonal' assert dir_A_north.dot(dir_A_north) == approx(1), 'North-vector not normalized' assert dir_A_west.dot(dir_A_west) == approx(1), 'North-vector not normalized' ''' sin_gamma_A = dir_A_pol[:, 0] * dir_A_west[:, 0] + dir_A_pol[:, 1] * dir_A_west[:, 1] + dir_A_pol[:, 2] * dir_A_west[:, 2] cos_gamma_A = dir_A_pol[:, 0] * dir_A_north[:, 0] + dir_A_pol[:, 1] * dir_A_north[:, 1] + dir_A_pol[:, 2] * dir_A_north[:, 2] cos_2_gamma_A = 2 * cos_gamma_A**2 - 1 sin_2_gamma_A = 2 * sin_gamma_A * cos_gamma_A return sin_2_gamma_A, cos_2_gamma_A
def orthoslant_project(shell, center, radius, degrees=False): """ Take a conical section of a sphere and bin into a cube for power spectrum estimation. """ Npix, Nfreq = shell.shape Nside = hp.npix2nside(Npix) if degrees: radius *= np.pi/180. if len(center) == 2: # This is an (az, alt) coordinate. if degrees: center = hp.ang2vec(center[0], center[1], lonlat=True) else: center = hp.ang2vec(np.pi - center[1], center[0]) # Define xy grid by the pixel area and selection radius. radpix = hp.nside2resol(Nside) extent = 2*np.floor(radius/radpix).astype(int) orthogrid = np.zeros((extent,extent, Nfreq)) # Get vectors, rotate so center is overhead, project vectors to get xy bins hpx_inds = hp.query_disc(Nside, center, 2*np.sqrt(2)*radius) #TODO This can be replaced with a "query_polygon" vecs = hp.pix2vec(Nside, hpx_inds) dp, dt = hp.rotator.vec2dir(center, lonlat=True) rot = hp.rotator.Rotator(rot=(dp, dt, 0)) vx, vy, vz = hp.rotator.rotateVector(rot.mat, vecs) ## Project onto the yz plane, having rotated so the x axis is at zenith xinds = np.floor(vy/radpix).astype(int) + extent/2 yinds = np.floor(vz/radpix).astype(int) + extent/2 #Center on the grid boxinds = np.where((xinds < extent)&(xinds>-1)&(yinds < extent)&(yinds>-1)) xinds = xinds[boxinds] yinds = yinds[boxinds] #Radial selection was bigger than the grid hpx_inds = hpx_inds[boxinds] weights = np.ones((orthogrid.shape[0], orthogrid.shape[1])) #np.add.at(weights, (xinds,yinds), 1.0) #nz = np.where(weights > 0) #weights[nz] = 1/weights[nz] for fi in np.arange(Nfreq): np.add.at(orthogrid[:,:,fi],(xinds, yinds), shell[hpx_inds,fi]) orthogrid[:,:,fi] *= weights return orthogrid
def plot_exposures(pointings, Aeff_fact, index=1, lat=0., lon=np.radians(260.), Earth=True, antiEarth=False, NSIDE=32, doplot=True): npointings = len(pointings) sc = Spacecraft(pointings, lat=lat, lon=lon) exposure_positions_hp = np.arange(hp.nside2npix(NSIDE)) exposure_positions_pix = hp.pix2ang(NSIDE, exposure_positions_hp, lonlat=True) exposure_positions = np.vstack(exposure_positions_pix) exposures = np.array([[ detector.exposure(position[0], position[1], alt=-90., index=index) for position in exposure_positions.T ] for detector in sc.detectors]) exps = exposures.sum(axis=0) * Aeff_fact fs = exps #-min(gbm_exps))/max(gbm_exps) if Earth: vec = hp.ang2vec(180, 0, lonlat=True) i = hp.query_disc(NSIDE, vec, 67 * np.pi / 180.) fs[i] = 0 exposures[:, i] = 0 if antiEarth: vec = hp.ang2vec(np.degrees(lon) - 260. + 180., 0, lonlat=True) i = hp.query_disc(NSIDE, vec, 67 * np.pi / 180.) fs[i] = 0 exposures[:, i] = 0 if doplot: plot.figure(figsize=(20, npointings)) s = np.argsort(pointings.keys()) for j in range(npointings): i = s[j] hp.mollview(exposures[i]/max(exposures[i])*Aeff_fact,title='Detector ',\ sub = [np.round(npointings/3.+0.5),3,int(str(j+1))]) #+pointings.keys()[i],\ hp.mollview(fs, title='Sum of All Detectors') # plot.savefig(biadir+'exposure_maps_'+str(ang)+'.png') return sc, fs, exposure_positions, pointings, exposures
def addring(nside, ra, dec, anga, angb): """ take a map, and add 1 to elements between anga and angb from ra, dec """ theta = np.deg2rad(90-dec) phi = np.deg2rad(ra) temp_map = np.zeros(hp.nside2npix(nside)) assert angb > anga # else error # Everything from 0 to angb = 1 pixlist = hp.query_disc(nside, hp.ang2vec(theta, phi), np.deg2rad(angb)) temp_map[pixlist] += 1 # now delete everything from 0 to anga pixlist = hp.query_disc(nside, hp.ang2vec(theta, phi), np.deg2rad(anga)) temp_map[pixlist] -= 1 return temp_map
def _get_response_B(theta, phi, spectral_irradiance, nu, horn, primary_beam): """ Return the complex electric amplitude and phase [W^(1/2)] from sources of specified spectral irradiance [W/m^2/Hz] going through each horn. Parameters ---------- theta : array-like The source zenith angle [rad]. phi : array-like The source azimuthal angle [rad]. spectral_irradiance : array-like The source spectral power per unit surface [W/m^2/Hz]. nu : float The frequency for which the response is computed [Hz]. horn : PackedArray The horn layout. primary_beam : Beam The primary beam. Returns ------- out : complex array of shape (#horns, #sources) The phase and amplitudes from the sources to the horns. """ shape = np.broadcast(theta, phi, spectral_irradiance).shape theta, phi, spectral_irradiance = [np.ravel(_) for _ in theta, phi, spectral_irradiance] uvec = hp.ang2vec(theta, phi) source_E = np.sqrt(spectral_irradiance * primary_beam(theta, phi) * np.pi * horn.radius ** 2) const = 2j * np.pi * nu / c product = np.dot(horn[horn.open].center, uvec.T) out = ne.evaluate("source_E * exp(const * product)") return out.reshape((-1,) + shape)
def gc2radec(self, gc_phi, gc_theta, min_lon=None): """ convert coordinates in galactic coordinate system to equatorial ra, dec. Parameters ---------- gc_phi : `np.ndarray`, float angular coordinate in Galactic coordinate system, where the MW disk is at theta=0. gc_theta : `np.ndarray`, float azimuthal coordinate in Galactic coordinate system. min_lon : degrees, defaults to None min longitude beyond which the galaxy is cut off. If None, `self.min_lon` is used. max_lon : None, Not implemented yet """ vec = hp.ang2vec(gc_theta, gc_phi) vec_radec = np.asarray(list(np.dot(self.rmat_inv, v) for v in vec)) theta, phi = hp.vec2ang(vec_radec) ra, dec = convertToCelestialCoordinates(theta, phi) if min_lon is None: min_lon = self.min_lon mask = dec > min_lon return ra[mask], dec[mask]
def _get_mask(self): if self.config.get('mask_file', None) is not None: mask = hp.read_map(self.config['mask_file']) mask = hp.ud_grade(rotate_mask(mask, self.rot), nside_out=self.nside) mask[mask > 0.5] = 1. mask[mask <= 0.5] = 0. else: mask = np.ones(self.npix) r = hp.Rotator(coord=['C', 'G']) RApix, DEpix = hp.pix2ang(self.nside, np.arange(self.npix), lonlat=True) lpix, bpix = r(RApix, DEpix, lonlat=True) # angular conditions mask[(DEpix < self.config.get('DEC_min_deg', -40)) | (np.fabs(bpix) < self.config.get('GLAT_max_deg', 5))] = 0 if self.file_sourcemask is not None: # holes catalog RAmask, DEmask, radmask = np.loadtxt(self.file_sourcemask, unpack=True) vecmask = hp.ang2vec(RAmask, DEmask, lonlat=True) for vec, radius in zip(vecmask, radmask): ipix_hole = hp.query_disc(self.nside, vec, np.radians(radius), inclusive=True) mask[ipix_hole] = 0 mask = rotate_mask(mask, self.rot, binarize=True) return mask
def write_k2_moc(campaign=0, norder_moc=NORDER_MOC, output_fn=None): if output_fn is None: fieldinfo = getFieldInfo(campaign) if "preliminary" in fieldinfo: output_fn = "../moc/k2-footprint-c{:02d}-proposed.moc".format(campaign) else: output_fn = "../moc/k2-footprint-c{:02d}.moc".format(campaign) # Obtain the footprint corners in polar coordinates log.info("Preparing footprint polygons for C{}".format(campaign)) polygons = [] for _, channel in FOOTPRINT["c{}".format(campaign)]["channels"].items(): polygon = [np.pi/2. - np.radians(channel["corners_dec"]), np.radians(channel["corners_ra"])] polygons.append(polygon) # Obtain the healpix diamonds that cover the polygons entirely # and add these to a `MOC` object log.info("Converting polygons into healpix format") moc = mocpy.MOC(moc_order=norder_moc) for p in polygons: pix_list = hp.query_polygon(2**norder_moc, hp.ang2vec(p[0], p[1]), inclusive=True, nest=True) for pix in pix_list: moc.add_pix(norder_moc, pix) # Finally, write the resulting MOC file to disk log.info("Writing {}".format(output_fn)) moc.plot() # IMPORTANT! moc.write is corrupt if plot is not called first moc.write(output_fn)
def pencil(self, theta, phi, angrad, **kwargs): """Query a pencil beam from this `SkyMap` Returns the subset of this `SkyMap` that covers an angular disc on the sky (i.e., a pencil beam) Parameters ---------- theta : `float` zenith angle (radians) at the center of the disc phi : `float` azimuth angle (radians) at the center of the disc angrad : `float` or `~astropy.units.Quantity` angular radius (radians) subtended by the disc **kwargs : `dict`, optional additional keyword arguments to `~healpy.query_disc` Returns ------- out : `SkyMap` the subset of `SkyMap` subtended by this pencil beam """ if isinstance(angrad, units.Quantity): angrad = angrad.to("rad").value direction = healpy.ang2vec(theta, phi) indices = healpy.query_disc(self.nside, direction, angrad, nest=self.nest, **kwargs) return self[indices]
def angToVec(lon, lat, convention, unit): """ Compute an array of unit vectors corresponding to the array of longitude and latitude in either celestial conventions (ra, dec) or usual spherical coordinate system conventions. Parameters ---------- lon : scalar or `numpy.ndarray` of floats co-longitude which may be ra, or phi depending on the convention lat : scalar or `numpy.ndarray` of floats co-latitude which may be dec, or theta depending on the convention convention : {'celestial'|'spherical'} whether the input angular positions are in spherical or celestial coordinates. unit : string {'degrees'| 'radians'} """ if unit.lower() not in ('degrees', 'radians'): raise ValueError('illegal value for units, ' 'must be either degrees or radians') if convention.lower() not in ('celestial', 'spherical'): raise ValueError('illegal value for convention, ' 'must be either spherical or celestial') lon = np.ravel(lon) lat = np.ravel(lat) if convention.lower() == 'celestial': theta, phi = convertToSphericalCoordinates(lon, lat, unit=unit.lower()) if convention.lower() == 'spherical' and unit.lower() == 'degrees': theta = np.radians(lat) phi = np.radians(lon) return hp.ang2vec(theta, phi)
def grow_hp(inmap, hpids, radius=1.75, replace_val=np.nan): """ grow a healpix mask Parameters ---------- inmap : np.array A HEALpix map hpids : array The healpixel values to grow around radius : float (1.75) The radius to grow around each point (degrees) replace_val : float (np.nan) The value to plug into the grown areas """ nside = hp.npix2nside(np.size(inmap)) theta, phi = hp.pix2ang(nside=nside, ipix=hpids) vec = hp.ang2vec(theta, phi) ipix_disc = [ hp.query_disc(nside=nside, vec=vector, radius=np.radians(radius)) for vector in vec ] ipix_disc = np.unique(np.concatenate(ipix_disc)) outmap = inmap + 0 outmap[ipix_disc] = replace_val return outmap
def find_field_visits(visits, ra, decl, nside=512, field_radius_deg=1.75): """Return visits centered near a pointing Parameters ---------- visits : `pandas.DataFrame` The visits in which to look for fields ra : `float` The RA around which to search. decl : `float` The declination around which to search nside : `int` The nside for the healpix search field_radious_deg : `float` The radious round which to search, in degrees Returns ------- field_visits : `pandas.DataFrame` The visits on the field. """ field_hpxs = healpy.query_disc( nside, healpy.ang2vec(ra, decl, lonlat=True), np.radians(field_radius_deg), ) visit_hpxs = healpy.ang2pix(nside, visits["fieldRA"].values, visits["fieldDec"].values, lonlat=True) field_visits = visits.loc[np.isin(visit_hpxs, field_hpxs)] return field_visits
def pixels_with_clusters(clusters_files, big_pixels, nside, min_rad=0.62): from astropy.coordinates import SkyCoord from astropy import units as u import pandas as pd import healpy as hp import numpy as np from DS_healpix_fragmentation import radec2pix df = [pd.read_csv(clusters_file) for clusters_file in clusters_files] df = pd.concat(df, ignore_index=True) pix2 = radec2pix(df['RA'], df['DEC'], 2) df = df[np.in1d(pix2, big_pixels)] df.index = np.arange(df.shape[0]) small_pixels = set() sc = SkyCoord(ra=np.array(df['RA']) * u.degree, dec=np.array(df['DEC']) * u.degree, frame='icrs') vecs = hp.ang2vec(theta=sc.galactic.l.degree, phi=sc.galactic.b.degree, lonlat=True) for i in range(df.shape[0]): small_pixels = small_pixels.union( hp.query_disc(nside, vecs[i], np.radians(min_rad), nest=True)) small_pixels = np.array(list(small_pixels)) return small_pixels, df
def query_disc(self, lon, lat, radius, fact=4): """ Find pixels that overlap with discs centered at (lon,lat) Inputs ------ lon : float, ndarray longitude (degr) lat : float, ndarray latitude (degr) radius : float, ndarray radius of disk (degrees) fact : float supersampling factor to find overlapping pixels (see healpy.query_disc doc) Returns ------ ndarray : pixel indices """ phi = np.array(lon) * self.deg2rad theta = (90 - np.array(lat)) * self.deg2rad vec = healpy.ang2vec(theta, phi) pix = healpy.query_disc(self.nside, vec, radius * self.deg2rad, inclusive=True, fact=fact, nest=self.nest) return pix
def calculate_efficiency(hpx, d0, s0, s1, nfields, fieldop): '''This function determines the score of a given set of tiling parameters for the optimization. The figure of merit is the sum value of the for the <nfields> higher fields of the tiling''' nside = hp.npix2nside(len(hpx)) keptfields = build_fields(hpx, d0, s0, s1, nfields, fieldop) # totaldots = np.sum(keptfields["prob"]) total = 0 prob_integral = [] for indec in range(0, len(keptfields)): # cornerra, cornerdec = getcorners(keptfields["ra"][indec],keptfields["dec"][indec],field=4.2) # xyz = hp.ang2vec(checktheta(dectotheta(cornerdec)),checkphi(ratophi(cornerdec))) # hp.query_polygon(nside,xyz) xyz = hp.ang2vec(dectotheta(keptfields["dec"][indec]), ratophi(keptfields["ra"][indec])) ipix_disc = hp.query_disc(nside, xyz, np.deg2rad( fieldop)) #here radius seems to be a diameter instead * (sq2+1)/4) totdisc = hpx[ipix_disc].sum() prob_integral.append(totdisc) total += totdisc # efficiency = total / nfields #print (total) return total, prob_integral
def handling_exception(params, constraints): NSIDEmax = params['NSIDE max'] vec = hp.ang2vec(params["ang"][0], params["ang"][1], lonlat=True) pixels = hp.query_disc(NSIDEmax, vec, np.radians(params['r'] / 3600.), inclusive=True) subjobs = mastcasjobs.MastCasJobs(context="PanSTARRS_DR2") for pixel in pixels: ang, r = qr.parameters(NSIDEmax, pixel) subquery = sub_query_string(ang[0], ang[1], r) accept = True while accept: try: subtab = subjobs.quick(subquery, task_name="python cone search") accept = False except Exception: from time import sleep sleep(60) pass subtab = qr.fixcolnames(ascii.read(subtab)) subtab = qr.query_constraints(subtab, constraints) if pixel == pixels[0]: table = subtab else: table = vstack([table, subtab]) return table
def gen_map_disc(radec_cen, rad, nside): '''Generates a Healpix map with the only non-zero values in the pixels inside the input disc. Parameters ---------- radec_cen : array-like with shape (2,) The center ra,dec of the disc in degrees rad : float The radius of the disc in degrees nside : int The nside of the output Healpix map Returns ------- hpx_map : array-like A Healpix map with non-zero values inside the disc ''' theta = np.pi/2 - np.radians(radec_cen[1]) phi = np.radians(radec_cen[0]) vec = H.ang2vec(theta, phi) ipix = H.query_disc(nside, vec, np.radians(rad)) hpx_map = np.zeros(H.nside2npix(nside)) hpx_map[ipix] = 1.0 return hpx_map
def _get_box_pix(self, nside, ra_cent, dec_cent, width, height): """ Get healpix pixels overlapping a box. Parameters ---------- nside : `int` ra_cent : `float` dec_cent : `float` width : `float` height : `float` Returns ------- pixels : `np.ndarray` """ wid = width / np.cos(np.deg2rad(dec_cent)) vertices = hp.ang2vec(np.array([ra_cent - wid/2., ra_cent - wid/2., ra_cent + wid/2., ra_cent + wid/2.]), np.array([dec_cent - height/2., dec_cent + height/2., dec_cent + height/2., dec_cent - height/2.]), lonlat=True) return hp.query_polygon(nside, vertices, nest=True)
def beamfunc(pixels, fwhm_arcmin, amplitude, ecc, incl_rad, theta_beam, phi_beam): pixel_theta, pixel_phi = pixels sigma_u = np.deg2rad(fwhm_arcmin / 60.0) / (2 * np.sqrt(2 * np.log(2))) sigma_v = sigma_u * (1 - ecc) vec = healpy.ang2vec(pixel_theta, pixel_phi) Ry = [ [np.cos(theta_beam), 0, np.sin(theta_beam)], [0, 1, 0], [-np.sin(theta_beam), 0, np.cos(theta_beam)], ] Rz = [ [np.cos(phi_beam), -np.sin(phi_beam), 0], [np.sin(phi_beam), np.cos(phi_beam), 0], [0, 0, 1], ] RotMat = np.dot(Rz, Ry) vecrot = np.dot(vec, RotMat) beam = np.zeros(len(vecrot)) x = np.transpose(vecrot)[0] y = np.transpose(vecrot)[1] z = np.transpose(vecrot)[2] u = np.cos(incl_rad) * x + np.sin(incl_rad) * y v = -np.sin(incl_rad) * x + np.cos(incl_rad) * y beam = amplitude * np.exp( -((u / (np.sqrt(2) * sigma_u)) ** 2 + (v / (np.sqrt(2) * sigma_v)) ** 2) ) beam[z < 0] = 0.0 return beam
def gen_map_disc(radec_cen, rad, nside): '''Generates a Healpix map with the only non-zero values in the pixels inside the input disc. Parameters ---------- radec_cen : array-like with shape (2,) The center ra,dec of the disc in degrees rad : float The radius of the disc in degrees nside : int The nside of the output Healpix map Returns ------- hpx_map : array-like A Healpix map with non-zero values inside the disc ''' theta = np.pi / 2 - np.radians(radec_cen[1]) phi = np.radians(radec_cen[0]) vec = H.ang2vec(theta, phi) ipix = H.query_disc(nside, vec, np.radians(rad)) hpx_map = np.zeros(H.nside2npix(nside)) hpx_map[ipix] = 1.0 return hpx_map
def corner_xyz(self): if len(self.__corner_xyz) == 0: # coord_vertices = self.corner_coords # xyz_vertices = [] # for c in coord_vertices: # theta = 0.5 * np.pi - np.deg2rad(c.dec.degree) # phi = np.deg2rad(c.ra.degree) # xyz_vertices.append(hp.ang2vec(theta, phi)) # self.__corner_xyz = np.asarray(xyz_vertices) coord_vertices = self.corner_coords xyz_vertices = [] for c in coord_vertices: theta = 0.5 * np.pi - np.deg2rad(c[1]) phi = np.deg2rad(c[0]) xyz_vertices.append(hp.ang2vec(theta, phi)) self.__corner_xyz = np.asarray(xyz_vertices) return self.__corner_xyz
def compute_circle(N, t, p, r, r_in): # Compute query (outer circle) and query_in (inner circle) query = hp.query_disc(nside=N, vec=hp.ang2vec(np.pi / 2 - t, p), radius=r, inclusive=False, nest=False) query_in = hp.query_disc(nside=N, vec=hp.ang2vec(np.pi / 2 - t, p), radius=r_in, inclusive=False, nest=False) # Inverse intersection of query (outer circle) and query_in (inner circle) inner = minus(query, query_in) return inner
def get_pixels(centr_ra, centr_decl, fov_radius): """ Get a list of HEALPIX zones that contain a given image. """ vector = healpy.ang2vec(radians(90.0 - centr_decl), radians(centr_ra)) pixels = healpy.query_disc(32, vector, radians(fov_radius), inclusive=True, nest=True) return str(pixels.tolist())[1:-1]
def gaussian_on_a_sphere(mean_th, mean_phi, sigma): """ This function returns a 2D normal pdf on a discretized healpy grid. To chose the function values correctly in spherical coordinates, the true angular distances to the mean are used. Pixels farther away from the mean than clip * sigma are clipped because the normal distribution falls quickly to zero. The error made by this can be easily estimated and a discussion can be found in [arXiv:1005.1929](https://arxiv.org/abs/1005.1929v2). Parameters ---------- mean_th : float Position of the mean in healpy coordinate `theta`. `theta` is in [0, pi] going from north to south pole. mean_phi : float Position of the mean in healpy coordinate `phi`. `phi` is in [0, 2pi] and is equivalent to the azimuth angle. sigma : float Standard deviation of the 2D normal distribution. Only symmetric normal pdfs are used here. Returns ------- kernel : array Values of the 2D normal distribution at the selected pixels. If clip False, kernel is a valid healpy map with resolution NSIDE. keep_idx : array Pixel indices that are kept from the full healpy map after clipping. If clip is False this is a sorted integer array with values [0, 1, ..., NPIX-1] with NPIX tha number of pixels in the full healpy map with resolution NSIDE. """ # Clip unneccessary pixels, just keep clip*sigma (radians) # around the mean. Using inlusive=True to make sure at least # one pixel gets returned. # Always returns a list, so no manual np.array() required. keep_idx = hp.query_disc( self._nside, hp.ang2vec(mean_th, mean_phi), self._clip * sigma, inclusive=True) # Create only the needed the pixel healpy coordinates th, phi = hp.pix2ang(self._nside, keep_idx) sinTh = np.sin(th) # For each pixel get the distance to (mean_th, mean_phi) direction dist = angdist(mean_phi, mean_th, phi, sinTh) # Get the 2D gaussian values at those distances -> kernel function # Because the kernel is radial symmetric we use a simplified # version -> 1D gaussian, properly normed sigma2 = 2 * sigma**2 kernel = np.exp(-dist**2 / sigma2) / (np.pi * sigma2) return kernel, keep_idx
def sky2vec(cls,sky): """ Convert sky positions in to 3d-vectors :param sky: [(ra,dec), ...] :return: [(x,y,z), ...] """ theta_phi = cls.sky2ang(sky) theta,phi = map(np.array,zip(*theta_phi)) vec=hp.ang2vec(theta,phi) return vec
def compute_healpix_vec(self): """ convert galactic latitude and longitude positions in :mod:`healpy` mapping quantinties: position vectors. """ rtod=180./np.pi b_h=np.pi/2. - self.lat l_h=self.long vec=hp.ang2vec(b_h,l_h) return vec
def from_point_sources(self,d,t): # if p.circular_pol == True: # I,Q,U,V = sky_list # else: # I,Q,U = sky_list print "t is " + str(t) total_angle = float(self.nhours * 15) # degrees offset_angle = float(self.hour_offset * 15) # degrees zl_ra = ((float(t) / float(self.ntime)) * np.radians(total_angle) + np.radians(offset_angle)) % (2.*np.pi)# radians RotAxis = np.array([0.,0.,1.]) RotAngle = -zl_ra # basicly Hour Angle with t=0 # R_t = irf.rotation_matrix(RotAxis, RotAngle) # s0 = hp.ang2vec(src_cza,src_ra) # sf = np.einsum('...ab,...b->...b', R_t, s0) self.src_ra_f = self.src_ra + RotAngle sf = hp.ang2vec(self.src_cza, self.src_ra_f) # s0 = hp.ang2vec(src_cza,src_ra) # hpR_t = hp.Rotator(rot=[RotAngle]) # sf = np.array(hpR_t(s0[:,0],s0[:,1],s0[:,2])).T if len(sf.shape) > 1: inds_f = hp.vec2pix(self.nside, sf[:,0],sf[:,1],sf[:,2]) else: inds_f = hp.vec2pix(self.nside, sf[0],sf[1],sf[2]) It = self.I #XXX ?? ijones_t = self.ijones[:,inds_f,:,:] ijonesH_t = self.ijonesH[:,inds_f,:,:] Kt = self.K[:,inds_f] if self.unpolarized == True: Ut = np.zeros((self.nfreq,It.shape[-1])) sky_t = np.array([ [It, Ut], [Ut, It]]).transpose(2,3,0,1) # sky_t.shape = (p.nfreq, p.npix, 2, 2) else: Ut = self.U Qt = self.Q sky_t = np.array([ [It + Qt, Ut], [Ut, It - Qt]]).transpose(2,3,0,1) # sky_t.shape = (p.nfreq, p.npix, 2, 2) irnf.instrRIME_integral(ijones_t, sky_t, ijonesH_t, Kt, self.Vis[d,t,:,:,:].squeeze())
def probability_inside_circle(self, ra, dec, radius): """Return the probability inside a circle.""" prob = hp.read_map(self.skymap, verbose=False) theta = 0.5 * np.pi - np.deg2rad(dec) phi = np.deg2rad(ra) radius = np.deg2rad(radius) xyz = hp.ang2vec(theta, phi) ipix_disc = hp.query_disc(self.nside, xyz, radius) probability_inside_disc = prob[ipix_disc].sum() return "%.1e" % probability_inside_disc
def probability_inside_box(self, infile, ra_vertices, dec_vertices): """Return the probability inside a polygon.""" prob = hp.read_map(self.skymap, verbose=False) theta = 0.5 * np.pi - np.deg2rad(dec_vertices) phi = np.deg2rad(ra_vertices) xyz = hp.ang2vec(theta, phi) ipix_poly = hp.query_polygon(self.nside, xyz) probability_inside_polygon = prob[ipix_poly].sum() return probability_inside_polygon
def hp_interpolator(map_, el, az, n_pix=4): NSide = hp.pixelfunc.get_nside(map_) direction = np.array([np.pi/2.-el.to_rad(),az.to_rad()]) steplength = hp.pixelfunc.max_pixrad(NSide) for i, r in enumerate(np.arange(steplength, np.pi, steplength)): pixels = np.array(hp.query_disc(NSide,hp.ang2vec(direction[0], direction[1]), r)) filled = np.where(map_[pixels] > -1.)[0] l = len(filled) if l >= n_pix: # print(i, l) filled_pixel = pixels[filled] filled_pixel_directions = hp.pix2vec(NSide, filled_pixel) angular_distance = hp.rotator.angdist(direction, filled_pixel_directions) if angular_distance.min() == 0.: # do we really want this? return map_[filled_pixel[angular_distance.argmin()]] return np.average(map_[filled_pixel], weights=np.power(1./angular_distance, 2))
def addVec(df, raCol='ditheredRA', decCol='ditheredDec'): """ Add a column of vectors to the dataFrame df Parameters ---------- df : `pd.DataFrame` dataframe with two columns raCol and decCol having ra, dec in radians. raCol : string, optional, defaults to 'ditheredRA' column name for the column which has ra values decCol : string, optional, defaults to 'ditheredDec' column name for the column which has dec values """ thetas = - df[decCol] + np.pi /2. phis = df[raCol] df['vec'] = list(hp.ang2vec(thetas, phis))
def wmap5_parameters(): """WMAP5 solar system dipole parameters, from: http://arxiv.org/abs/0803.0732""" # 369.0 +- .9 Km/s SOLSYSSPEED = 369e3 #l.critical('USING 371') #SOLSYSSPEED = 371e3 ## direction in galactic coordinates ##(d, l, b) = (3.355 +- 0.008 mK,263.99 +- 0.14,48.26deg +- 0.03) SOLSYSDIR_GAL_THETA = np.deg2rad( 90 - 48.26 ) SOLSYSDIR_GAL_PHI = np.deg2rad( 263.99 ) SOLSYSSPEED_GAL_U = healpy.ang2vec(SOLSYSDIR_GAL_THETA,SOLSYSDIR_GAL_PHI) #SOLSYSSPEED_GAL_V = SOLSYSSPEED * SOLSYSSPEED_GAL_U SOLSYSSPEED_ECL_U = gal2ecl(SOLSYSSPEED_GAL_U) SOLSYSDIR_ECL_THETA, SOLSYSDIR_ECL_PHI = healpy.vec2ang(SOLSYSSPEED_ECL_U) ########## /WMAP5 return SOLSYSSPEED, SOLSYSDIR_ECL_THETA, SOLSYSDIR_ECL_PHI
def randsphere(num, system='eq', **kw): """ Generate random points on the sphere parameters ---------- num: integer The number of randoms to generate system: string 'eq' for equatorial ra,dec in degrees ra in [0,360] dec in [-90,90] 'ang' for angular theta,phi in radians theta in [0,pi] phi in [0,2*pi] 'vec' for x,y,z on the unit sphere **kw: ra_range=, dec_range= to limit range of randoms in ra,dec system theta_range=, phi_range= to limit range of randoms in theta,phi system output ------ ra,dec: tuple of arrays the random points """ if system=='eq': return randsphere_eq(num, **kw) elif system=='ang': return randsphere_ang(num, **kw) elif system=='vec': import healpy theta,phi=randsphere_ang(num) return healpy.ang2vec(theta,phi) else: raise ValueError("bad system: '%s'" % sytem)
def test_query_disc(self): if not DO_HEALPY: # not possible on Windows return with NumpyRNGContext(12345): nside = 1024 hpx = Healpix(nside) disc_size = np.radians(0.5 / 60.) thetas = np.random.uniform(0, np.pi, 10) phis = np.random.uniform(0, 2 * np.pi, 10) for theta, phi in zip(thetas, phis): _vec = hp.ang2vec(theta, phi) hp_disc = hp.query_disc(nside, _vec, disc_size) assert_equal( hp_disc, hpx.query_disc(theta, phi, disc_size) )
def create_healpix_tsz_template(rm, n_theta_core=5., weight_min=0.1, beta=0.7): fill_free_electron_parameters(rm) # only add those above some weight threshold wh=np.where(rm['weight']>weight_min)[0] print 'USING %i CLUSTERS WITH WEIGHT>%0.2f'%(len(wh), weight_min) for k in rm.keys(): rm[k]=rm[k][wh] npix = hp.nside2npix(nside) template = np.zeros(npix) ncl = len(rm['ra']) vec_hpix = hp.ang2vec(rm['th_gal'], rm['phi_gal']) ind_hpix = hp.ang2pix(nside, rm['th_gal'], rm['phi_gal'], nest=False) for i in range(ncl): this_vec = vec_hpix[i,:] this_theta_c = rm['theta_c'][i] #radians this_ind = ind_hpix[i] ind_nearby = hp.query_disc(nside, this_vec, n_theta_core*this_theta_c, nest=False) vec_nearby = hp.pix2vec(nside, ind_nearby, nest=False) theta_nearby = hp.rotator.angdist(this_vec, vec_nearby) values_nearby = (1.+(theta_nearby/this_theta_c)**2.)**((1.-3.*beta)/2.) #values_nearby *= rm['t0'][i] template[ind_nearby] += values_nearby return template
def gen_map_polygon(vertices, nside): '''Generates a Healpix map with the only non-zero values in the pixels inside the input polygon Parameters ---------- vertices : array-like with shape (n,2) or (2,n) The lon,lat vertices of the polygon in degrees. n >= 3 nside : int The nside of the output Healpix map Returns ------- hpx_map : array-like A Healpix map with non-zero values inside the polygon ''' vertices = np.array(vertices) if vertices.shape[1] != 2: vertices = np.transpose(vertices) if vertices.shape[1] != 2: raise ValueError("Need a n x 2 or 2 x n input vertices array") thetas = np.pi/2 - np.radians(vertices[:, 1]) phis = np.radians(vertices[:, 0]) vecs = H.ang2vec(thetas, phis) ipix = H.query_polygon(nside, vecs) hpx_map = np.zeros(H.nside2npix(nside)) hpx_map[ipix] = 1.0 return hpx_map
def angToVec(lon, lat): theta = lat2theta(lat) phi = lon2phi(lon) vec = hp.ang2vec(theta, phi) return vec
#onestep_fit_flux( write_png=False, inc_disc=False, inc_haze=True, inc_bubbles=True, raw_sync=False, # mfile='ebvh_mask_top-half_disc_40_ns0128.fits', model_list=['12132h'], plot_moll=False ) sys.exit() dir = '/global/scratch2/sd/dpietrob/DM-haze/data/maps/ns0128/' nside = 128 snside = '0128' # ==================================================================== # Make bubbles template as two discs for the haze/gamma-rays counterpart # Not used: back to Gaussian for consistency and much difference after masking if False: dirn = hp.ang2vec( (90.-22.5)/180.*np.pi, 0. ) dn = make_disc( nside, 20., direction=dirn) dirs = hp.ang2vec( (90.+22.5)/180.*np.pi, 0. ) ds = make_disc( nside, 20., direction=dirs) bubbles = (ds + dn ) * 0.01 bubbles = hp.smoothing( bubbles, fwhm=10./180.*np.pi) hp.mollview( bubbles ) hp.write_map( dir+'fermi_bubbles_ns'+snside+'.fits', bubbles) pl.show() # ==================================================================== # Residual maps for the best fit: Tab3col1 first and 11113 if False: from myclass import * from mcmc import *
############################################################################# nside = 256 lmax = 3*nside-1 #### Mask maxang = 5. center = [0.,0.] veccenter = hp.ang2vec(pi/2-np.radians(center[1]), np.radians(center[0])) vecpix = hp.pix2vec(nside,np.arange(12*nside**2)) cosang = np.dot(veccenter,vecpix) maskok = np.degrees(np.arccos(cosang)) < maxang maskmap=np.zeros(12*nside**2) maskmap[maskok]=1 wl = hp.anafast(maskmap,regression=False) wl = wl[0:lmax+1] #### Do a Monte-Carlo nbmc = 1000 allcls = np.zeros((nbmc, lmax+1)) for i in np.arange(nbmc): print(i)
opts.input.name, distances=True) npix = len(prob) nside = hp.npix2nside(npix) progress.update(-1, 'Preparing projection') if opts.align_to is None: prob2, mu2, sigma2 = prob, mu, sigma else: (prob2, mu2, sigma2, _), _ = fits.read_sky_map( opts.align_to.name, distances=True) R = np.ascontiguousarray(principal_axes(prob2, mu2, sigma2)) if opts.chain: chain = np.recfromtxt(opts.chain, names=True) chain = np.dot(R.T, (hp.ang2vec( 0.5 * np.pi - chain['dec'], chain['ra']) * np.atleast_2d(chain['dist']).T).T) fig = plt.figure(frameon=False) n = 1 if opts.projection else 2 gs = gridspec.GridSpec( n, n, left=0.01, right=0.99, bottom=0.01, top=0.99, wspace=0.05, hspace=0.05) imgwidth = int(opts.dpi * opts.figure_width / n) s = np.linspace(-opts.max_distance, opts.max_distance, imgwidth) xx, yy = np.meshgrid(s, s) dtheta = 0.5 * np.pi / nside / 4 # Color palette for markers colors = seaborn.color_palette(n_colors=len(opts.radecdist) + 1)
maprms_dust = FitsArray('small2_maprms_dust.fits') maprms_all = FitsArray('small2_maprms_all.fits') racenter = 0 deccenter = -57.0 deltatheta = 15. deltatheta2 = 20. deltatheta3 = 25. racirc, deccirc = circ_around_radec([racenter, deccenter], deltatheta) racirc2, deccirc2 = circ_around_radec([racenter, deccenter], deltatheta2) racirc3, deccirc3 = circ_around_radec([racenter, deccenter], deltatheta3) # Initial dust map clf() l,b = equ2gal(racenter, deccenter) vv = hp.ang2vec(np.radians(90-b), np.radians(l)) pixels = hp.query_disc(hp.npix2nside(len(mapdust)), vv, np.radians(15)) mm = np.min(mapdust[pixels]) #hp.gnomview(mapdust-mm, coord='GE', title='Planck Dust Map', rot=[racenter,deccenter], fig=1, reso=25,min=0,max=1e-4) hp.mollview(mapdust-mm, coord='GE', title='Planck Dust Map', rot=[racenter,deccenter], fig=2, min=0,max=1e-4) hp.projplot(pi/2-np.radians(deccenter), np.radians(racenter), 'kx') hp.projplot(pi/2-np.radians(deccirc), np.radians(racirc), 'k') hp.projplot(pi/2-np.radians(deccirc2), np.radians(racirc2), 'k') hp.projplot(pi/2-np.radians(deccirc3), np.radians(racirc3), 'k') hp.projplot(pi/2-np.radians(-45), np.radians(4*15+40/60+12/3600), 'ko') hp.projplot(pi/2-np.radians(-30/60), np.radians(11*15+453/60+0/3600), 'ko') hp.projplot(pi/2 - np.radians(-32-48/60), np.radians(23*15+1/60+48/3600), 'ko') bicepalpha = np.ravel([np.zeros(10)-60, np.linspace(-60, 60, 10), np.zeros(10)+60, np.linspace(60, -60, 10)]) bicepdelta = np.ravel([np.linspace(-70, -45, 10),np.zeros(10)-45, np.linspace(-45, -70, 10),np.zeros(10)-70]) hp.projplot(pi/2-np.radians(bicepdelta), np.radians(bicepalpha), 'k--')
def compute_SOLSYSSPEED_V(norm, theta, phi): return norm * healpy.ang2vec(theta,phi)
width = 10 poles_margin = 0.1 halfwidth = width/2 for theta in range(halfwidth, 180, width): for phi in range(halfwidth, 360, width): filename = "plancktest/submaps/%03d_%03d_%03d" % (freq, theta, phi) print filename vertex_angles = np.radians( [[theta-halfwidth, phi-halfwidth], [theta+halfwidth, phi-halfwidth], [theta+halfwidth, phi+halfwidth], [theta-halfwidth, phi+halfwidth]]) if theta - halfwidth == 0: vertex_angles[0,0] = np.radians(poles_margin) vertex_angles[3,0] = np.radians(poles_margin) if theta + halfwidth == 180: vertex_angles[1,0] = np.radians(180-poles_margin) vertex_angles[2,0] = np.radians(180-poles_margin) pix=hp.query_polygon(nside, hp.ang2vec(vertex_angles[:,0], vertex_angles[:,1]), np.radians(13)) submap = np.zeros(len(pix), dtype=[("pix",np.int64), ("temp", np.float64)]) submap["pix"] = pix submap["temp"] = m[pix] np.save(filename, submap)
from lalinference import plot from wcsaxes import WCS import numpy as np from matplotlib import pyplot as plt import healpy as hp from matplotlib import collections from matplotlib import patches from matplotlib import ticker ra0 = 130 dec0 = -10 phi0 = np.deg2rad(ra0) theta0 = 0.5 * np.pi - np.deg2rad(dec0) # ra0 = 137.8 # dec0 = -39.9 xyz0 = hp.ang2vec(0.5*np.pi - np.deg2rad(dec0), np.deg2rad(ra0)) prob, meta = fits.read_sky_map('../cbc/emfollowup/papers/first2years/data/2015/compare/18951/bayestar.fits.gz', nest=True) def get_vertices(m): m = np.copy(m) top_npix = len(m) top_nside = hp.npix2nside(top_npix) top_order = int(np.log2(top_nside)) for order in range(top_order + 1): nside = 1 << order npix = hp.nside2npix(nside) stride = 1 << (2 * (top_order - order)) keep = (hp.pix2vec(nside, np.arange(npix), nest=True) * np.expand_dims(xyz0, 1)).sum(0) >= np.cos(np.deg2rad(30)) if order < top_order: mm = m.reshape((-1, stride))
def query_disc(self, coord1, coord2, radius, system='eq', mine=False, **kw): """ get pixels that are contained within or intersect the disc hpix.query_disc(ra,dec,radius_degrees) hpix.query_disc(theta,phi,radius_radians,system='ang') parameters ---------- coord1: scalar If system=='eq' this is ra degrees If system=='ang' this is theta radians coord2: scalar If system=='eq' this is dec degrees If system=='ang' this is phi radians radius: scalar radius of disc If system=='eq' this is in degrees If system=='ang' this is in radians system: string 'eq' for equatorial ra,dec in degrees 'ang' for angular theta,phi in radians default 'eq' keywords for healpy.query_disc inclusive: bool, optional If False, return the exact set of pixels whose pixel centers lie within the disk; if True, return all pixels that overlap with the disk, and maybe a few more. Default: False fact : int, optional Only used when inclusive=True. The overlapping test will be done at the resolution fact*nside. For NESTED ordering, fact must be a power of 2, else it can be any positive integer. Default: 4. nest: bool, optional if True, assume NESTED pixel ordering, otherwise, RING pixel ordering buff: int array, optional if provided, this numpy array is used to contain the return values and must be at least long enough to do so returns ------- pixnums: array Array of pixel numbers that are contained or intersect the disc examples -------- from hpix_util import HealPix hpix = HealPix("ring", 4096) ra=200.0 dec=0.0 radius=1.0 pixnums=hpix.query_disc(ra, dec, radius) """ import healpy if mine: if system=='eq': sysnum=coords.SYSTEM_EQ elif system=='ang': sysnum=SYSTEM_ANG else: raise ValueError("system should be 'eq' or 'ang'") inclusive=kw.get('inclusive',False) incnum = 1 if inclusive else 0 pixnums=self._query_disc(coord1,coord2,radius,sysnum,incnum) else: if system=='eq': vec=coords.eq2vec(coord1, coord2) rad_send=numpy.deg2rad(radius) elif system=='ang': vec=healpy.ang2vec(coord1, coord2) rad_send=radius else: raise ValueError("system should be 'eq' or 'ang'") kw['nest'] = self.nested pixnums=healpy.query_disc(self.nside, vec, rad_send, **kw) return pixnums
print 'split :',split vis_root=np.empty([BL_NUM/split,4],dtype=np.complex128) UV_root=np.empty([BL_NUM,3],dtype=np.float) #========== ###############calculating UVW#################### UV_bl=Vis.BL_radec mpi_UV_bl_index=np.array_split(np.arange(len(UV_bl)),size) UV = [] for i in mpi_UV_bl_index[rank]: UV.append(Vis.Get_UV_radec(source[0], source[1], bl=Vis.BL_radec[i])[0]) UV = np.array(UV,dtype=np.float) ##############################mpi util########################################## theta, phi = hp.pix2ang(map_nside, np.arange(map_nside**2 * 12)) thphi=np.c_[theta,phi] sigma=hp.ang2vec(theta,phi) BL_bl_split=np.array_split(BL_bl,split) for i in np.arange(len(BL_bl_split)): mpi_bl=np.array_split(BL_bl_split[i],size) vis=np.dot(np.exp(-2*np.pi/lam*1j*np.dot(mpi_bl[rank],sigma.T)),map) vis_result=np.c_[mpi_bl[rank],vis/(map_nside**2*12.)] comm.Gather(vis_result,vis_root,root=0) if rank==0: # print mpi_bl[rank] # print i,mpi_bl[rank] # print vis_result.shape print '%d...'%(i+1) if i==0: vis_all_root=np.vstack(vis_root) else:
def main(): # parse command-line arguments parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--verbose', action='store_true', help='more verbose output') parser.add_argument('--order', type=int, default=5, help='order of healpix hierachical tesselation') parser.add_argument('--input', type=str, default=None, help='input file name') args = parser.parse_args() nside = 2**args.order npix = hp.nside2npix(nside) m = np.arange(npix) print 'HEALPix map info:' print '\tn pixels:', npix print '\tresolution:', hp.nside2resol(nside) print '\tpixel area:', hp.nside2pixarea(nside) print '\tmax distance from center:', hp.max_pixrad(nside) print 'xi binning info:' transerve_comoving_scale = 3820.43 # Mpc, at z = 2.1 maxang = 200/transerve_comoving_scale print '\tmax ang scale:', maxang print 'test stuff:' test_theta = 1.58853 test_phi = 0.154 testvec = hp.ang2vec(test_theta, test_phi) testmax = 0.03 print '\ttheta, phi:', test_theta, test_phi print '\t3d vec:', testvec print '\tpixel index:', hp.ang2pix(nside, test_theta, test_phi) print '\tclosest neighbors:', hp.pixelfunc.get_all_neighbours(nside, test_theta, test_phi) print '\tneighbors within max ang scale:', hp.query_disc(nside, testvec, testmax, inclusive=True) # include_pix = hp.query_disc(nside, hp.ang2vec(5./6.*np.pi/2, 7./6.*np.pi), 2*maxang, inclusive=True) # print '\tn pixels for test:', len(include_pix) qso_pos = np.loadtxt(args.input) print 'Shape of input data: ', qso_pos.shape m = {} qso_pos[:,0] = np.deg2rad(qso_pos[:,0]) qso_pos[:,1] = np.deg2rad(90-qso_pos[:,1]) class Quasar(): def __init__(self, theta, phi, z): self.theta = theta self.phi = phi self.z = z # fake this for now self.wave = np.log10((1+z)*(1100+np.arange(10))) quasars = [] for i, qso in enumerate(qso_pos): ra, dec, z = qso phi = ra theta = dec q = Quasar(theta, phi, z) map_index = hp.ang2pix(nside, theta, phi) # if map_index not in include_pix: # continue #q.map_index = map_index if map_index in m: m[map_index].append(i) else: m[map_index] = [i] q.i = i quasars.append(q) print 'Number of pixels with at least one quasar: %d' % (len(m.keys())) print 'Average number of quasars per pixel: %f' % (float(len(quasars))/len(m.keys())) nearby_pixels_sum = 0 nearby_quasars_sum = 0 for q_index, q in enumerate(quasars): nearby_pixels = hp.query_disc(nside, hp.ang2vec(q.theta, q.phi), maxang, inclusive=True) nearby_pixels_sum += len(nearby_pixels) for nearby_pixel in nearby_pixels: if nearby_pixel in m: nearby_quasars = m[nearby_pixel] nearby_quasars_sum += len(nearby_quasars) p_phi = qso_pos[nearby_quasars,0] p_theta = qso_pos[nearby_quasars,1] angdist = np.sin(q.theta)*np.sin(p_theta) + np.cos(q.theta)*np.cos(p_theta)*(np.cos(q.phi)*np.cos(p_phi) + np.sin(q.phi)*np.sin(p_phi)) for p_i, p_index in enumerate(nearby_quasars): theta, phi, z = qso_pos[p_index] p = Quasar(theta, phi, z) loglamdist = abs(np.subtract.outer(q.wave, p.wave)) p_angdist = angdist[p_i] #losdist = abs(np.log(q_wave/p.wave)) print 'Average number of pixels within 200 Mpc of a quasar: %f' % (float(nearby_pixels_sum)/len(quasars)) print 'Average number of quasars within nearby pixels of a quasar: %f' % (float(nearby_quasars_sum)/len(quasars)) mask = np.ones(npix).astype(np.bool) mask[m.keys()] = False mm = hp.ma(np.zeros(npix)) mm.mask = mask mm[~mm.mask] = [len(m[i]) for i in m.keys()] hp.mollview(mm.filled(), rot=(270,0,0), flip='geo') plt.show()