def from_cone(ra, dec, error, dateobs): localization_name = "%.5f_%.5f_%.5f" % (ra, dec, error) center = SkyCoord(ra * u.deg, dec * u.deg) radius = error * u.deg # Determine resolution such that there are at least # 16 pixels across the error radius. hpx = HEALPix(pixel_resolution_to_nside(radius / 16, round='up'), 'nested', frame=ICRS()) # Find all pixels in the 4-sigma error circle. ipix = hpx.cone_search_skycoord(center, 4 * radius) # Convert to multi-resolution pixel indices and sort. uniq = moc.nest2uniq(nside_to_level(hpx.nside), ipix) i = np.argsort(uniq) ipix = ipix[i] uniq = uniq[i] # Evaluate Gaussian. distance = hpx.healpix_to_skycoord(ipix).separation(center) probdensity = np.exp(-0.5 * np.square(distance / radius).to_value( u.dimensionless_unscaled)) probdensity /= probdensity.sum() * hpx.pixel_area.to_value(u.steradian) models.db.session.merge( models.Localization( localization_name=localization_name, dateobs=dateobs, uniq=uniq.tolist(), probdensity=probdensity.tolist())) models.db.session.commit() return localization_name
def from_cone(ra, dec, error): localization_name = "%.5f_%.5f_%.5f" % (ra, dec, error) center = SkyCoord(ra * u.deg, dec * u.deg) radius = error * u.deg # Determine resolution such that there are at least # 16 pixels across the error radius. hpx = HEALPix(pixel_resolution_to_nside(radius / 16, round='up'), 'nested', frame=ICRS()) # Find all pixels in the 4-sigma error circle. ipix = hpx.cone_search_skycoord(center, 4 * radius) # Convert to multi-resolution pixel indices and sort. uniq = ligo.skymap.moc.nest2uniq(nside_to_level(hpx.nside), ipix.astype(np.int64)) i = np.argsort(uniq) ipix = ipix[i] uniq = uniq[i] # Evaluate Gaussian. distance = hpx.healpix_to_skycoord(ipix).separation(center) probdensity = np.exp( -0.5 * np.square(distance / radius).to_value(u.dimensionless_unscaled)) probdensity /= probdensity.sum() * hpx.pixel_area.to_value(u.steradian) skymap = table.Table( [np.asarray(uniq), np.asarray(probdensity)], names=['UNIQ', 'PROBDENSITY']) return skymap, uniq
def main(pool, distance=20, filename='output_file.txt', nside=64): #calculate pole centers hp = HEALPix(nside=nside, order='ring', frame=coord.Galactic()) centers = hp.healpix_to_skycoord(np.arange(0, hp.npix)) #only keep poles above equator to not redo calculate with opposite pole centers = centers[centers.b >= 0.0 * u.deg] #pad centers to match to number of processors ncenters = centers.shape[0] nprocs = pool.size if nprocs == 0.: nprocs = 1 ncenters_per_proc = np.ceil(ncenters / float(nprocs)) npads = nprocs * ncenters_per_proc - ncenters skypad = coord.SkyCoord(np.zeros(int(npads)), np.zeros(int(npads)), frame='galactic', unit=u.deg) centers = coord.concatenate((centers, skypad)) #reshape centers so each worker gets a block of them centers = centers.reshape(nprocs, int(ncenters_per_proc)) print('number of workers: ', nprocs) print('number of poles: ', ncenters) print('number of poles per worker: ', ncenters_per_proc) print('number of poles added as padding: ', npads) print('shape of poles array: ', np.shape(centers)) #instantiate worker with filename results will be saved to worker = Worker(filename, args.dist) #you better work ! for r in pool.map(worker, list(centers), callback=worker.callback): pass
def reg2moc(region, moc_field, wcs, moc_order=15): """ Transform a the intersection of moc_field with a Region object into a MOC. """ list_cells = np.array([c for c in moc_field.flattened()]) hp = HEALPix(nside=2**moc_order, order='nested', frame=ICRS()) cells_skycoords = hp.healpix_to_skycoord(list_cells) mask = region.contains(cells_skycoords, wcs) region_moc = MOC(moc_order, list_cells[mask]) return region_moc
def coordinates(self): if type(self.wcs) is dict: hp = HEALPix(nside=self.wcs['nside'], order=self.wcs['order'], frame=Galactic()) coords = hp.healpix_to_skycoord(np.arange(self.map.shape[0])) return coords else: x, y = np.meshgrid(np.arange(self.map.shape[1]), np.arange(self.map.shape[0]), sparse=True) coords = self.wcs.pixel_to_world(x, y) return coords
def retrieve_gaia_data_for_map(): if len(argv) == 1: data_dir = input('Please enter the path to the output data directory: ') else: data_dir = argv[1] # Read the Galactic Plane survey priority pointing map, identify those # pixels above the given priority threshold, and calculate the spatial # coordinates of the corresponding pixels: ahp = HEALPix(nside=NSIDE, order='ring', frame=TETE()) map = hp.read_map(path.join(MAPS_DIR,'GalPlane_priority_map_r.fits')) NPIX = hp.nside2npix(NSIDE) pixels = np.arange(0,NPIX,1, dtype='int') priority_min_threshold = 0.4 index = (map >= priority_min_threshold,1,0)[0] priority_healpixels = np.unique(pixels[index]) priority_coords = ahp.healpix_to_skycoord(priority_healpixels) c = priority_coords[0] # For each HEALpix pointing, query the Gaia catalog and retrieve a random # sampling of the point source catalog for that sky location: tap_service = init_tap_service() for i in range(0,len(priority_coords),1): coord = priority_coords[i] if not check_for_existing_output(data_dir, coord): try: data = run_async_gaia_tap_query(tap_service, coord) output_gaia_to_fits(data_dir,data,coord) except requests.exceptions.ConnectionError: tap_service = init_tap_service() data = run_async_gaia_tap_query(tap_service, coord) output_gaia_to_fits(data_dir,data,coord)
class Skymap(object): """ A skymap object is an HEALPix map equipped with a custom coordinate system -- from LAL. """ def __init__(self, nside, coordsystem, order='nested', array=None): """ grid: HEALPix map object nside: HEALPix nside parameter (int, power of 2) order: pixel ordering scheme of the HEALPix map coordsystem: Coordsystem object that describes the coordinate system Note: The HEALPix map used for the grid is initialized with a dummy ICRS coordinate frame, that is not used in practise as healpy nor astropy don't support ECEF/Geographic coordinate systems. Instead the grid coordinates are defined through a coordinate system obtained from the LAL library. """ if array is not None: assert len(array) == healpy.nside2npix(nside), "Data array has incorrect size" self.grid = HEALPix(nside=nside, order=order, frame=ICRS()) self.nside = nside self.order = order self.coordsystem = coordsystem self.data = numpy.empty(healpy.nside2npix(nside)) if array is None else array @classmethod def like(cls, skymap, coordsystem=None, data=None): """ Instantiate a Skymap object with the same feature as the input skymap unless otherwise requested. skymap: reference Skymap object coordsystem: Coordsystem object that defines the coordinate system of the new Skymap object data: data of the new Skymap object """ if coordsystem is not None: assert coordsystem.is_valid(), "Unsupported coordinate system" if data is not None: assert len(data) == skymap.grid.npix, 'Input data has wrong dimensions' return cls(skymap.nside, \ coordsystem if coordsystem is not None else skymap.coordsystem, \ skymap.order, \ data if data is not None else skymap.data) def is_nested(self): return self.order == 'nested' def grid_points(self): return [Skypoint(math.radians(p.ra.value), math.radians(p.dec.value), self.coordsystem) \ for p in self.grid.healpix_to_skycoord(range(self.grid.npix))] def feed(self, data): """ Update the skymap data with the given array """ assert len(data) == self.grid.npix, 'Input data has wrong dimensions' self.data = data def value(self, skypoint): """ Returns the skymap value at a skypoint. The skymap and skypoint must have the same coordinate system. """ assert self.coordsystem.is_same(skypoint.coordsystem), \ "The skymap and skypoint must have the same coordinate system" # Get the pixel index that corresponds to the skypoint coordinates idx = healpy.ang2pix(self.nside, \ *skypoint.coords(), \ nest=self.is_nested()) return self.data[idx] def transformed_to(self, coordsystem): """ Transforms the skymap to another coordinate system If initial and target coordinate systems have the same type, the reference time of the coordinate system is the only parameter that is changed. """ if self.coordsystem.has_same_type_as(coordsystem): return Skymap.like(self, coordsystem=coordsystem) # Get co-latitude and longitude coordinates of the skygrid in the target coord system colat, lon = healpy.pix2ang(self.nside, \ numpy.arange(healpy.nside2npix(self.nside)), \ nest=self.is_nested()) # Map target to original coordinates points = [Skypoint(l, math.pi/2-c, coordsystem).transformed_to(self.coordsystem) \ for l, c in zip(lon, colat)] # Transform the list of coordinate tuples [(lon, lat), ...] into two lists [lons, lats] coords_rot = [p.coords() for p in points] (colat_rot, lon_rot) = tuple(map(list,zip(*coords_rot))) # Compute skymap in target coord system: interpolate the skymap at points that map to target coords data_rotated = healpy.get_interp_val(self.data, numpy.array(colat_rot), numpy.array(lon_rot), \ nest=self.is_nested()) # Create target skymap and update its data return Skymap.like(self, coordsystem=coordsystem, data=data_rotated) def argmin(self, label = 'skymap minimum'): """ Returns the location of the skymap minimum """ coords = healpy.pix2ang(self.nside,numpy.argmin(self.data), nest=self.is_nested()) return Skypoint(coords[1], math.pi/2-coords[0], self.coordsystem, \ label + " (val={0:.2f})".format(numpy.min(self.data))) def display(self, title, cmap_name='gray_r'): """ Display the skymap """ cmap = plt.get_cmap(cmap_name) cmap.set_under('w') healpy.mollview(self.data, \ nest=self.is_nested(), cmap=cmap, \ title=title + " ({})".format(self.coordsystem))
cmb_map = hpy.pixelfunc.ud_grade(map1, nside, order_in = 'RING', order_out = 'RING') ##### Convert to Coordinates ##### # initialise and pre allocate arrays for speed x = np.zeros(len(cmb_map)) y = np.zeros(len(cmb_map)) z = np.zeros(len(cmb_map)) temp = cmb_map coords = [] xf = np.zeros(len(cmb_map)) yf = np.zeros(len(cmb_map)) zf = np.zeros(len(cmb_map)) # get celestial coordinates coords = hp.healpix_to_skycoord(np.arange(len(cmb_map))) print coords # store cartesian coordinates of each data point # This is for a plain sphere with no height attribute for i in range(0,len(cmb_map)): x[i], y[i], z[i] = hpy.pix2vec(nside, i, nest = False) r = 30 theta = m.acos(z[i]/m.sqrt(m.pow(x[i],2)+m.pow(y[i],2)+m.pow(z[i],2))) phi = m.atan2(y[i],x[i]) xf[i] = (r*m.sin(theta)*m.cos(phi)) yf[i] = (r*m.sin(theta)*m.sin(phi)) zf[i] = (r*m.cos(theta)) # open file to write data file = open('plaindata.txt', 'w')
unique_pixels = list(np.unique(np.array(pixels))) return unique_pixels NSIDE = 64 footprint_maps_dir = getenv('FOOTPRINT_MAPS_DIR') map = hp.nside2npix(NSIDE) priority_map = hp.read_map( path.join(footprint_maps_dir, 'GalPlane_priority_map_r.fits')) ahp = HEALPix(nside=NSIDE, order='ring', frame=TETE()) (high_priority_regions, regions_outside_plane ) = science_priority_regions.fetch_priority_region_data(ahp) unique_pixels = condense_pixel_list(high_priority_regions, regions_outside_plane) coords = ahp.healpix_to_skycoord(unique_pixels) priority_values = priority_map[unique_pixels] output = open(path.join(footprint_maps_dir, 'GalPlane_pointings_list.txt'), 'w') output.write('# Field center RA, Dec [deg] Priority\n') for i, c in enumerate(coords): output.write( str(c.ra.deg) + ' ' + str(c.dec.deg) + ' ' + str(priority_values[i]) + '\n') output.close()
class Skymap(object): """ A skymap object is an HEALPix map equipped with a custom coordinate system -- from LAL. """ def __init__(self, nside, coordsystem, order='nested', array=None): """ grid: HEALPix map object nside: HEALPix nside parameter (int, power of 2) order: pixel ordering scheme of the HEALPix map coordsystem: Coordsystem object that describes the coordinate system Note: The HEALPix map used for the grid is initialized with a dummy ICRS coordinate frame, that is not used in practise as healpy nor astropy don't support ECEF/Geographic coordinate systems. Instead the grid coordinates are defined through a coordinate system obtained from the LAL library. """ if array is not None: assert len(array) == healpy.nside2npix( nside), "Data array has incorrect size" self.grid = HEALPix(nside=nside, order=order, frame=ICRS()) self.nside = nside self.order = order self.coordsystem = coordsystem self.data = numpy.empty( healpy.nside2npix(nside)) if array is None else array @classmethod def like(cls, skymap, coordsystem=None, data=None): """ Instantiate a Skymap object with the same feature as the input skymap unless otherwise requested. skymap: reference Skymap object coordsystem: Coordsystem object that defines the coordinate system of the new Skymap object data: data of the new Skymap object """ if coordsystem is not None: assert coordsystem.is_valid(), "Unsupported coordinate system" if data is not None: assert len( data) == skymap.grid.npix, 'Input data has wrong dimensions' return cls(skymap.nside, \ coordsystem if coordsystem is not None else skymap.coordsystem, \ skymap.order, \ data if data is not None else skymap.data) def is_nested(self): return self.order == 'nested' def grid_points(self): return [Skypoint(math.radians(p.ra.value), math.radians(p.dec.value), self.coordsystem) \ for p in self.grid.healpix_to_skycoord(range(self.grid.npix))] def feed(self, data): """ Update the skymap data with the given array """ assert len(data) == self.grid.npix, 'Input data has wrong dimensions' self.data = data def value(self, skypoint): """ Returns the skymap value at a skypoint. The skymap and skypoint must have the same coordinate system. """ assert self.coordsystem.is_same(skypoint.coordsystem), \ "The skymap and skypoint must have the same coordinate system" # Get the pixel index that corresponds to the skypoint coordinates idx = healpy.ang2pix(self.nside, \ *skypoint.coords(), \ nest=self.is_nested()) return self.data[idx] def transformed_to(self, coordsystem): """ Transforms the skymap to another coordinate system If initial and target coordinate systems have the same type, the reference time of the coordinate system is the only parameter that is changed. """ if self.coordsystem.has_same_type_as(coordsystem): return Skymap.like(self, coordsystem=coordsystem) # Get co-latitude and longitude coordinates of the skygrid in the target coord system colat, lon = healpy.pix2ang(self.nside, \ numpy.arange(healpy.nside2npix(self.nside)), \ nest=self.is_nested()) # Map target to original coordinates points = [Skypoint(l, math.pi/2-c, coordsystem).transformed_to(self.coordsystem) \ for l, c in zip(lon, colat)] # Transform the list of coordinate tuples [(lon, lat), ...] into two lists [lons, lats] coords_rot = [p.coords() for p in points] (colat_rot, lon_rot) = tuple(map(list, zip(*coords_rot))) # Compute skymap in target coord system: interpolate the skymap at points that map to target coords data_rotated = healpy.get_interp_val(self.data, numpy.array(colat_rot), numpy.array(lon_rot), \ nest=self.is_nested()) # Create target skymap and update its data return Skymap.like(self, coordsystem=coordsystem, data=data_rotated) def argmin(self, label='skymap minimum'): """ Returns the location of the skymap minimum """ coords = healpy.pix2ang(self.nside, numpy.argmin(self.data), nest=self.is_nested()) return Skypoint(coords[1], math.pi/2-coords[0], self.coordsystem, \ label + " (val={0:.2f})".format(numpy.min(self.data))) def argmax(self, label='skymap maximum'): """ Returns the location of the skymap maximum """ coords = healpy.pix2ang(self.nside, numpy.argmax(self.data), nest=self.is_nested()) return Skypoint(coords[1], math.pi/2-coords[0], self.coordsystem, \ label + " (val={0:.2f})".format(numpy.max(self.data))) def nearest_pixel( self, skypoint): ## Modify to accept several points instead of just one """ Returns the nearest pixel's indice of skypoint """ colat, lon = skypoint.coords() return healpy.ang2pix(self.nside, colat, lon, nest=self.is_nested()) def find_greedy_credible_levels(self): """Find the greedy credible levels of a (possibly multi-dimensional) array. from : https://lscsoft.docs.ligo.org/ligo.skymap/_modules/ligo/skymap/postprocess/util.html#find_greedy_credible_levels Returns ------- cls : np.ndarray An array with the same shape as slef.data, with values ranging from `0` to `self.data.sum()`, representing the greedy credible level to which each entry in the array belongs. """ i = numpy.flipud(numpy.argsort(self.data)) cs = numpy.cumsum(self.data[i]) cls = numpy.empty_like(self.data) cls[i] = cs return cls def test_skypoint_credible_level(self, skypoint, level=0.9, verbose=False): ipix = self.nearest_pixel(skypoint) credible_levels = self.find_greedy_credible_levels() if np.min(credible_levels) > level: if verbose: print('No region with this low credible level.') if credible_levels[ipix] == np.min(credible_levels): if verbose: print( 'This skypoint alone have a credible level of {:.3}.'. format(credible_levels[ipix])) return True else: return False else: return credible_levels[ipix] <= level def display(self, title, cmap_name='gray_r'): """ Display the skymap """ cmap = plt.get_cmap(cmap_name) cmap.set_under('w') healpy.mollview(self.data, \ nest=self.is_nested(), cmap=cmap, \ title=title + " ({})".format(self.coordsystem))
def _npixels_to_coords(npixels, level): hp = HEALPix(nside=2**level, order="nested", frame=ICRS()) return hp.healpix_to_skycoord(npixels)
def create_external_skymap(ra, dec, error, pipeline, notice_type=111): """Create a sky map, either a gaussian or a single pixel sky map, given an RA, dec, and error radius. If from Fermi, convolves the sky map with both a core and tail Gaussian and then sums these to account for systematic effects as measured in :doi:`10.1088/0067-0049/216/2/32` If from Swift, converts the error radius from that containing 90% of the credible region to ~68% (see description of Swift error here:`https://gcn.gsfc.nasa.gov/swift.html#tc7`) Parameters ---------- ra : float right ascension in deg dec: float declination in deg error: float error radius in deg Returns ------- skymap : numpy array sky map array """ max_nside = 2048 if error: # Correct 90% containment to 1-sigma for Swift if pipeline == 'Swift': error /= np.sqrt(-2 * np.log1p(-.9)) error_radius = error * u.deg nside = pixel_resolution_to_nside(error_radius, round='up') else: nside = np.inf if nside >= max_nside: nside = max_nside # Find the one pixel the event can localized to hpx = HEALPix(nside, 'ring', frame=ICRS()) skymap = np.zeros(hpx.npix) ind = hpx.lonlat_to_healpix(ra * u.deg, dec * u.deg) skymap[ind] = 1. else: # If larger error, create gaussian sky map hpx = HEALPix(nside, 'ring', frame=ICRS()) ipix = np.arange(hpx.npix) # Evaluate Gaussian. center = SkyCoord(ra * u.deg, dec * u.deg) distance = hpx.healpix_to_skycoord(ipix).separation(center) skymap = np.exp(-0.5 * np.square(distance / error_radius).to_value( u.dimensionless_unscaled)) skymap /= skymap.sum() if pipeline == 'Fermi': # Correct for Fermi systematics based on recommendations from GBM team # Convolve with both a narrow core and wide tail Gaussian with error # radius determined by the scales respectively, each comprising a # fraction determined by the weights respectively if notice_type == gcn.NoticeType.FERMI_GBM_FLT_POS: # Flight notice # Values from first row of Table 7 weights = [0.897, 0.103] scales = [7.52, 55.6] elif notice_type == gcn.NoticeType.FERMI_GBM_GND_POS: # Ground notice # Values from first row of Table 3 weights = [0.804, 0.196] scales = [3.72, 13.7] elif notice_type == gcn.NoticeType.FERMI_GBM_FIN_POS: # Final notice # Values from second row of Table 3 weights = [0.900, 0.100] scales = [3.71, 14.3] else: raise AssertionError( 'Need to provide a supported Fermi notice type') skymap = sum(weight * hp.sphtfunc.smoothing(skymap, sigma=np.radians(scale)) for weight, scale in zip(weights, scales)) # Renormalize due to possible lack of precision return skymap / skymap.sum()
def make_plot(args): """ Take the steps to make the plot. Parameters ---------- args: array-like Command line arguments Returns ------- Nothing """ basename = 'PMmap-qso-galactic-aberration' gx = 5.04 gy = -0.10 gz = -0.29 if args['quiver']: hplevel = 3 else: hplevel = 5 nside = hp.order2nside(hplevel) npix = hp.nside2npix(nside) ahp = HEALPix(nside=nside, order='nested', frame=Galactic()) hpindices = np.arange(npix) skycoords = ahp.healpix_to_skycoord(hpindices) pm_l_cosb = -gx * np.sin(skycoords.l.to(u.rad)) + gy * np.cos( skycoords.l.to(u.rad)) pm_b = -gx * np.sin(skycoords.b.to(u.rad)) * np.cos(skycoords.l.to(u.rad)) \ - gy * np.sin(skycoords.b.to(u.rad)) * np.sin(skycoords.l.to(u.rad)) \ + gz * np.cos(skycoords.b.to(u.rad)) pmtot = np.sqrt(pm_l_cosb**2 + pm_b**2) backgr = plt.imread( '../star-trail-animation/sky-images/GaiaSky-colour-2k.png') default_proj = ccrs.PlateCarree() sky_proj = ccrs.Mollweide() fig = plt.figure(figsize=(16, 9), dpi=120, frameon=False, tight_layout={'pad': 0.01}) gs = GridSpec(1, 1, figure=fig) ax = fig.add_subplot(gs[0, 0], projection=sky_proj) ax.imshow(np.fliplr(backgr), transform=default_proj, zorder=-1, origin='upper') veccolor = plt.cm.get_cmap('tab10').colors[9] linecolor = plt.cm.get_cmap('tab10').colors[9] if args['quiver']: vscale = np.median(pmtot) / 50 ax.quiver(skycoords.l.value, skycoords.b.value, pm_l_cosb, pm_b, transform=default_proj, angles='xy', scale=vscale, scale_units='dots', color=veccolor, headwidth=4, headlength=4, headaxislength=3.5) else: if args['colourstreams']: ax.streamplot(skycoords.l.value, skycoords.b.value, pm_l_cosb, pm_b, transform=default_proj, linewidth=2.0, density=2, color=pmtot, cmap='viridis', maxlength=0.5, arrowsize=1, arrowstyle=ArrowStyle.Fancy(head_length=1.0, head_width=.4, tail_width=.4)) elif args['lwcode'] > 0: ax.streamplot(skycoords.l.value, skycoords.b.value, pm_l_cosb, pm_b, transform=default_proj, linewidth=args['lwcode'] * pmtot / np.median(pmtot), density=2, color=linecolor, maxlength=0.5, arrowsize=1, arrowstyle=ArrowStyle.Fancy(head_length=1.0, head_width=.4, tail_width=.4)) else: ax.streamplot(skycoords.l.value, skycoords.b.value, pm_l_cosb, pm_b, transform=default_proj, linewidth=1.5, density=2.5, color=linecolor, maxlength=0.5, arrowsize=1, arrowstyle=ArrowStyle.Fancy(head_length=1.0, head_width=.4, tail_width=.4)) # ax.gridlines() ax.invert_xaxis() if args['pdfOutput']: plt.savefig(basename + '.pdf') elif args['pngOutput']: plt.savefig(basename + '.png') else: plt.show()