def make_pictures(config_dir='.', image_folder = 'extended_images'): """ make a folder with images for all extended sources """ from uw.like2 import configuration from skymaps import Band if not os.path.exists(image_folder): os.mkdir(image_folder) cf = configuration.Configuration(config_dir, quiet=True, postpone=True) class Bandlite(object): def __init__(self, roi_dir, event_type=1, energy =133.352): self.event_type=event_type self.energy=energy self.sd=roi_dir self.psf=cf.psfman(event_type,energy) self.exposure = cf.exposureman(event_type,energy) self.radius =5 ecat = ExtendedCatalog(cf.extended) for name in ecat.names: print 'processing %s ...' % name , source = ecat.lookup(name) b12 = Band(12); roi_index = b12.index(source.skydir); roi_dir = b12.dir(roi_index) conv = convolution.ExtendedConvolver(source, Bandlite(roi_dir=roi_dir)) conv.create_grid() fig = conv.show_source() fig.savefig('%s/%s_map.png' %(image_folder,name.replace(' ','_'))) print
class MultiHealpixKDEMap(object): def __init__(self, glob_expansion): """glob_expansion: an expression that can be expanded by glob into a list of the pickles of HealpixTSMaps that this class will access N.B. it is necessary that these objects all have been constructed with the same settings of base nside and sub-grid factor! """ tsmaps = [HealpixKDEMap(pickle=x) for x in glob(glob_expansion)] nside1 = tsmaps[0].band1.nside() self.band1 = Band(nside1) self.tsmaps = [False] * 12 * nside1**2 for tsmap in tsmaps: self.tsmaps[tsmap.index] = tsmap self.scale = 0 def __call__(self, v, skydir=None): sd = skydir or SkyDir(Hep3Vector(v[0], v[1], v[2])) id = self.band1.index(sd) tsmap = self.tsmaps[id] if not tsmap: return np.nan return tsmap.multipix_call(sd) def make_zea(self, center, size=10, pixelsize=0.02, galactic=False): z = ZEA(center, size=size, pixelsize=pixelsize, galactic=galactic) z.fill(PySkyFunction(self)) self.z = z
class HealpixMap(object): """map from a set of Healpix to values, supporting a SkyFunction interface and interpolation. The implentation here is not really appropriate for a sparse map (much less than all-sky if the number of pixels are large, since the storage system is a vector with indices==healpix_index. An alternative (perhaps realizable with a child class) can use a sorted lookup and store only populated entries.""" def __init__(self, nside, inds, vals): self.band = Band(nside) #s = np.argsort(inds) #self.inds = inds[s] #self.vals = vals[s] self.vals = np.empty(12 * nside**2) self.vals[:] = np.nan self.vals[inds] = vals from libpointlike import IntVector self.iv = IntVector() def __call__(self, v, skydir=None): sd = skydir or SkyDir(Hep3Vector(v[0], v[1], v[2])) healpix_index = self.band.index(sd) return self.vals[healpix_index] def bilinear_interp(self, v, skydir=None): b = self.band sd = skydir or SkyDir(Hep3Vector(v[0], v[1], v[2])) healpix_index = b.index(sd) d = b.dir(healpix_index) b.findNeighbors(healpix_index, self.iv) idx = np.asarray([x for x in iv] + [healpix_index]) dirs = [b.dir(idx) for idx in self.iv] + [d] diffs = np.asarray([sd.difference(di) for di in dirs]) # use co-ordinate system that puts pixels closest to equator use_gal = abs(d.b()) < abs(d.dec()) if use_gal: lons = np.asarray([d.b() for d in dirs]) lats = np.asarray([d.l() for d in dirs]) sdlon = sd.b() sdlat = sd.l() else: lons = np.asarray([d.ra() for d in dirs]) lats = np.asarray([d.dec() for d in dirs]) sdlon = sd.ra() sdlat = sd.dec() s = np.argsort(diffs) lons = lons[s][:4] lats = lats[s][:4] vals = np.asarray([self(0, skydir=dirs[x]) for x in s[:4]]) return (np.abs(lons - sdlon) * np.abs(lats - sdlat) * vals).sum()
def make_index_table(nside, subnside, usefile=True): filename = 'index_table_%02d_%03d.pickle' % (nside, subnside) if os.path.exists(filename) and usefile: return pickle.load(open(filename)) print 'generating index table for nside, subnside= %d %d' % (nside, subnside) band, subband = Band(nside), Band(subnside) npix, nsubpix = 12 * nside**2, 12 * subnside**2 t = np.array([band.index(subband.dir(i)) for i in xrange(nsubpix)]) a = np.arange(nsubpix) index_table = [a[t == i] for i in xrange(npix)] if usefile: pickle.dump(index_table, open(filename, 'w')) return index_table
def setup_from_roi(self, hr, factor): band1 = hr.band band2 = Band(int(round(band1.nside() * factor))) rd = band1.dir(hr.index) # get pixels within a radius 10% greater than the base Healpix diagonal dimension radius = (np.pi / (3 * band1.nside()**2))**0.5 * 2**0.5 * 1.1 wsdl = WeightedSkyDirList(band2, rd, radius, True) # then cut down to just the pixels inside the base Healpixel inds = np.asarray([band1.index(x) for x in wsdl]) mask = inds == hr.index dirs = [wsdl[i] for i in xrange(len(mask)) if mask[i]] inds = np.asarray([band2.index(x) for x in dirs]).astype(int) # sanity check if abs(float(mask.sum()) / factor**2 - 1) > 0.01: print 'Warning: number of pixels found does not agree with expectations!' # calculate TS for each sub-pixel tsc = TSCalc(hr.roi) if self.bright_sources is not None: ts_vals = self.ts_vals = [deque(), deque(), deque()] bsm = np.asarray([ x.source_name in self.bright_sources for x in hr.roi.psm.models ]) for d in dirs: ts_vals[0].append(tsc(d)) ts_vals[1].append(tsc(d, repeat_diffuse=True)) ts_vals[2].append( tsc(d, repeat_diffuse=True, bright_source_mask=bsm)) else: self.ts_vals = ts_vals = [deque(), deque()] for d in dirs: ts_vals[0].append(tsc(d)) ts_vals[1].append(tsc(d, repeat_diffuse=True)) self.band1 = band1 self.band2 = band2 sorting = np.argsort(inds) self.inds = inds[sorting] for i in range(len(ts_vals)): ts_vals[i] = np.asarray(ts_vals[i])[sorting] self.previous_index = -1 self.index = hr.index self.mode = 0 self.ts = self.ts_vals[0]
def make_index_table(nside=12, subnside=512, usefile=True): """create, and/or use a table to convert between different nside pixelizations """ filename = os.path.expandvars('$FERMI/misc/index_table_%02d_%03d.pickle' % (nside, subnside) ) if os.path.exists(filename) and usefile: return pickle.load(open(filename)) print 'generating index table for nside, subnside= %d %d' % (nside, subnside) band, subband = Band(nside), Band(subnside) npix, nsubpix = 12*nside**2, 12*subnside**2 t=np.array([band.index(subband.dir(i)) for i in xrange(nsubpix)]) a = np.arange(nsubpix) index_table = [a[t==i] for i in xrange(npix)] if usefile: pickle.dump(index_table, open(filename,'w')) return index_table
def setup_from_roi(self, hr, factor): band1 = hr.band band2 = Band(int(round(band1.nside() * factor))) rd = band1.dir(hr.index) # get pixels within a radius 10% greater than the base Healpix diagonal dimension radius = (np.pi / (3 * band1.nside()**2))**0.5 * 2**0.5 * 1.1 wsdl = WeightedSkyDirList(band2, rd, radius, True) # then cut down to just the pixels inside the base Healpixel inds = np.asarray([band1.index(x) for x in wsdl]) mask = inds == hr.index dirs = [wsdl[i] for i in xrange(len(mask)) if mask[i]] inds = np.asarray([band2.index(x) for x in dirs]).astype(int) # sanity check if abs(float(mask.sum()) / factor**2 - 1) > 0.01: print 'Warning: number of pixels found does not agree with expectations!' # loop through the bands and image pixels to calculate the KDE from libpointlike import DoubleVector #dv = DoubleVector() rvs = [np.empty(len(band.wsdl), dtype=float) for band in hr.roi.bands] img = np.zeros(len(inds)) weights = [ np.asarray([x.weight() for x in b.wsdl]).astype(int) for b in hr.roi.bands ] for idir, mydir in enumerate(dirs): #print 'Processing pixel %d'%(idir) for iband, band in enumerate(hr.roi.bands): PythonUtilities.arclength(band.rvals, band.wsdl, mydir) img[idir] += (band.psf(rvs[iband], density=True) * weights[iband]).sum() self.band1 = band1 self.band2 = band2 self.previous_index = -1 sorting = np.argsort(inds) self.inds = inds[sorting] self.img = img[sorting] self.index = hr.index
class Display_map(object): """ utility class to handle nice displays of a HParray object """ def __init__(self, hptable, outdir, map_dir=None, nside=12, imshow_kw=dict( interpolation='bilinear', vmin=0, vmax=100, ), **kwargs): """ hptable : HParray object expect to have vec, nside members outdir : string folder containing the skymodel map_dir : None, string folder name to save the images """ from .. import skymodel self.v = hptable.vec self.subband = Band(hptable.nside) self.band = Band(nside) self.n = 12 * nside**2 self.imshow_kw = imshow_kw self.scale = kwargs.pop('scale', lambda x: x) if type(self.scale) == types.StringTypes: if self.scale == 'sqrt': self.scale = lambda x: np.sqrt(max(x, 0)) elif self.scale == 'log': self.scale = lambda x: np.log10(max(x, 0.1)) else: raise Exception, 'unrecognized scale function, %s' % self.scale print 'Can generate %d map figures' % (self.n) self.outdir = outdir self.ZEA_kw = kwargs.pop('ZEA_kw', dict()) if map_dir is not None: self.map_path = os.path.join(outdir, map_dir) if not os.path.exists(self.map_path): os.makedirs(self.map_path) print 'will save figures in folder %s' % self.map_path else: self.map_path = None skm = skymodel.SkyModel(outdir) self.sources = skm.point_sources + skm.extended_sources print 'loaded %d sources from skymodel %s' % (len( self.sources), outdir) def get_pyskyfun(self): return PySkyFunction(self) def skyfun(self, v): skydir = SkyDir(Hep3Vector(v[0], v[1], v[2])) return self.v[self.subband.index(skydir)] def __call__(self, v): skydir = SkyDir(Hep3Vector(v[0], v[1], v[2])) t = self.v[self.subband.index(skydir)] #if self.scale=='sqrt': return np.sqrt(max(t,0)) #elif self.scale=='log': return np.log10(max(t, 1e-1)) return self.scale(t) def fill_ait(self, fignum=11, axes=None, show_kw={}, **kwargs): if axes is None: plt.close(fignum) fig = plt.figure(fignum, figsize=(12, 8)) axes = fig.gca() pixelsize = kwargs.pop('pixelsize', 0.25) ait = image.AIT(self.get_pyskyfun(), axes=axes, pixelsize=pixelsize, **kwargs) self.imgplot = ait.imshow(**show_kw) return ait def fill_zea(self, index, fignum=12, axes=None, **kwargs): """ sources is a recarray with name, ra, dec """ if axes is None: plt.close(fignum) fig = plt.figure(fignum, figsize=(6, 6)) axes = fig.gca() size = kwargs.pop('size', 10) pixelsize = kwargs.pop('pixelsize', 0.1) title = kwargs.pop('title', hpname(index)) label = kwargs.pop('label', '') zea = image.ZEA(self.band.dir(index), size=size, pixelsize=pixelsize, **self.ZEA_kw) zea.grid() zea.fill(self.get_pyskyfun()) imshow_kw = self.imshow_kw # imshow_kw.update(kwargs) zea.imshow(**imshow_kw) zea.colorbar(label=label) axes.set_title(title) if self.sources is not None: count = 0 for s in self.sources: sdir = s.skydir if not zea.inside(sdir): continue count += 1 inside = self.band.index(sdir) == index zea.plot_source(s.name, sdir, symbol='*' if inside else 'd', markersize=14 if inside else 8, color='w') print 'found %d sources to plot' % count if self.map_path is not None: fout = os.path.join(self.map_path, hpname(index) + '.png') plt.savefig(fout) print 'saved figure to %s' % fout plt.draw_if_interactive()
class DisplayMap(object): """ display the contents of a HEALpix table as ait or zea """ def __init__(self, table, sources=None, imshow_kw=dict(interpolation='bilinear', ), **kwargs): """table : string or iterable If a string, the name of a pickled file sources : None or a string if a string, the name of a pickled rec with name, ra, dec fields """ if type(table)==types.StringType: self.v = pickle.load(open(table)) print 'Loaded HEALpix table from file %s' %table else: self.v=table self.nside = int(np.sqrt(len(self.v)/12)) assert len(self.v)==12*self.nside**2, 'size of map not consistent with expected nside %d' % nside self.band = Band(self.nside) self.imshow_kw=imshow_kw self.scale = kwargs.pop('scale', lambda x: x) if type(self.scale) == types.StringTypes: if self.scale=='sqrt': self.scale= lambda x: np.sqrt(max(x,0)) elif self.scale=='log': self.scale=lambda x: np.log10(max(x,0.1)) else: raise Exception, 'unrecognized scale function, %s' %self.scale self.ZEA_kw = kwargs.pop('ZEA_kw', dict(galactic=True, size=10, pixelsize=0.1)) if sources is not None: self.sources = pickle.load(open(sources)) print 'loaded %d sources from %s' % (len(self.sources),sources) else:self.sources=None self.map_path = kwargs.pop('map_path',None) def get_pyskyfun(self): return PySkyFunction(self) def skyfun(self, v): skydir = SkyDir(Hep3Vector(v[0],v[1],v[2])) return self.v[self.band.index(skydir)] def __call__(self,v): skydir = SkyDir(Hep3Vector(v[0],v[1],v[2])) t =self.v[self.band.index(skydir)] return self.scale(t) def fill_ait(self, fignum=11, axes=None, show_kw={}, source_kw={}, figwidth=12, margin=0.15, **kwargs): if axes is None: # set up a figure for 2x1 image with equal margins plt.close(fignum) figheight = figwidth*(1.+2*margin)/(1+margin)/2. fig=plt.figure(fignum, figsize=(figwidth, figheight)); axes=plt.gca() plt.subplots_adjust(left=0.05, right=0.95) #gives reasonable equal margins pixelsize = kwargs.pop('pixelsize', 0.25) ait = image.AIT(self.get_pyskyfun(),axes=axes, pixelsize=pixelsize, **kwargs) self.imgplot=ait.imshow(**show_kw) ait.axes.set_autoscale_on(False) if self.sources is not None: sdirs = map(SkyDir, self.sources.ra, self.sources.dec) ait.plot(sdirs, **source_kw) print 'found %d sources to plot' % len(sdirs) plt.draw_if_interactive() return ait def fill_zea(self, index, fignum=12, axes=None, show_kw=None, **kwargs): """ index: integer, or a SkyDir the HP12 index if integer figmun: integer used if axes is None show_kw : dict override imshow keywords kwargs size pixelsize galactic """ if axes is None: plt.close(fignum) fig = plt.figure(fignum,figsize=(6,6)); axes = fig.gca() if type(index) == types.IntType: sdir = Band(12).dir(index) title = 'HP12_%4d'%index else: sdir = index title = 'l = %.1f, b=%.1f' % (sdir.l(), sdir.b()) title = kwargs.pop('title',title) kw = self.ZEA_kw kw.update(kwargs) zea = image.ZEA(sdir, **kw) zea.grid() zea.fill(self.get_pyskyfun()) zea.imshow( **(show_kw if show_kw is not None else self.imshow_kw)) zea.colorbar() if title is not None: axes.set_title(title) if self.sources is not None: count = 0 for s in self.sources: sdir = SkyDir(s.ra,s.dec) if not zea.inside(sdir):continue count += 1 inside =self.band.index(sdir)==index zea.plot_source(s.name, sdir, symbol='*' if inside else 'd', markersize=14 if inside else 8, color='w') print 'found %d sources to plot' %count if self.map_path is not None: fout = os.path.join(self.map_path,hpname(index)+'.png') plt.savefig(fout, bbox_inches='tight') print 'saved figure to %s' % fout plt.draw_if_interactive() return zea
class ROIWrapper(object): """Wrap up an ROI as if it were a HealpixROI, for testing.""" def __init__(self, roi, nside=6): self.roi = roi self.band = Band(nside) self.index = self.band.index(roi.roi_dir)
class HealpixKDEMap(object): defaults = dict( factor=100, emin=[500, 1000], ) def __init__(self, hr=None, pickle=None, do_healpix=False, **kwargs): """hr : an instance of HealpixROI pickle : a pickle saved from a previous HealpixTSMap factor : number of intervals to divide base Healpixel side into""" self.__dict__.update(HealpixKDEMap.defaults) self.__dict__.update(kwargs) if hr is not None: if do_healpix: self.__call__ = self.call self.setup_from_roi(hr, self.factor) else: self.__call__ = self.call2 self.setup_from_roi2(hr) elif pickle is not None: self.load(pickle) else: print 'Must provide either a HealpixROI instance or a pickle file!' raise Exception def setup_from_roi2(self, hr): self.bands = [] for iband, band in enumerate(hr.roi.bands): if band.emin < self.emin[band.ct]: continue else: self.bands += [band] band.rvals = np.empty(len(band.wsdl), dtype=float) band.r99 = np.radians(band.psf.inverse_integral_on_axis(0.95)) def call2(self, v, skydir=None): sd = skydir or SkyDir(Hep3Vector(v[0], v[1], v[2])) rval = 0 for band in self.bands: if band.photons == 0: continue band.rvals = np.empty(len(band.wsdl), dtype=float) PythonUtilities.arclength(band.rvals, band.wsdl, sd) mask = band.rvals < band.r99 rval += (band.psf(band.rvals[mask], density=True) * band.pix_counts[mask]).sum() return rval def setup_from_roi(self, hr, factor): band1 = hr.band band2 = Band(int(round(band1.nside() * factor))) rd = band1.dir(hr.index) # get pixels within a radius 10% greater than the base Healpix diagonal dimension radius = (np.pi / (3 * band1.nside()**2))**0.5 * 2**0.5 * 1.1 wsdl = WeightedSkyDirList(band2, rd, radius, True) # then cut down to just the pixels inside the base Healpixel inds = np.asarray([band1.index(x) for x in wsdl]) mask = inds == hr.index dirs = [wsdl[i] for i in xrange(len(mask)) if mask[i]] inds = np.asarray([band2.index(x) for x in dirs]).astype(int) # sanity check if abs(float(mask.sum()) / factor**2 - 1) > 0.01: print 'Warning: number of pixels found does not agree with expectations!' # loop through the bands and image pixels to calculate the KDE from libpointlike import DoubleVector #dv = DoubleVector() rvs = [np.empty(len(band.wsdl), dtype=float) for band in hr.roi.bands] img = np.zeros(len(inds)) weights = [ np.asarray([x.weight() for x in b.wsdl]).astype(int) for b in hr.roi.bands ] for idir, mydir in enumerate(dirs): #print 'Processing pixel %d'%(idir) for iband, band in enumerate(hr.roi.bands): PythonUtilities.arclength(band.rvals, band.wsdl, mydir) img[idir] += (band.psf(rvs[iband], density=True) * weights[iband]).sum() self.band1 = band1 self.band2 = band2 self.previous_index = -1 sorting = np.argsort(inds) self.inds = inds[sorting] self.img = img[sorting] self.index = hr.index def dump(self, filename): d = dict() d['inds'] = self.inds d['img'] = self.img d['nside1'] = self.band1.nside() d['nside2'] = self.band2.nside() d['index'] = self.index dump(d, file(filename, 'w')) def load(self, filename): d = load(file(filename)) self.inds = d['inds'] self.band1 = Band(d['nside1']) self.band2 = Band(d['nside2']) self.img = d['img'] self.index = d['index'] self.previous_index = -1 def pyskyfun(self): return PySkyFunction(self) def __call__(self, v, skydir=None): sd = skydir or SkyDir(Hep3Vector(v[0], v[1], v[2])) if self.band1.index(sd) != self.index: return np.nan id = self.band2.index(sd) if id != self.previous_index: self.previous_value = self.img[np.searchsorted(self.inds, id)] self.previous_index = id return self.previous_value def multipix_call(self, sd): """A faster version of the skydir lookup where it assumed that the argument lies within the boundaries of this Healpixel.""" id = self.band2.index(sd) if id != self.previous_index: self.previous_value = self.img[np.searchsorted(self.inds, id)] self.previous_index = id return self.previous_value
class MultiHealpixTSMap(object): def __init__(self, glob_expansion): """glob_expansion: an expression that can be expanded by glob into a list of the pickles of HealpixTSMaps that this class will access N.B. it is necessary that these objects all have been constructed with the same settings of base nside and sub-grid factor! """ tsmaps = [HealpixTSMap(pickle=x) for x in glob(glob_expansion)] nside1 = tsmaps[0].band1.nside() self.band1 = Band(nside1) self.tsmaps = [False] * 12 * nside1**2 for tsmap in tsmaps: self.tsmaps[tsmap.index] = tsmap self.scale = 0 def __call__(self, v, skydir=None): sd = skydir or SkyDir(Hep3Vector(v[0], v[1], v[2])) id = self.band1.index(sd) tsmap = self.tsmaps[id] if not tsmap: return np.nan return tsmap.multipix_call(sd) def set_mode(self, mode=1): """Change display mode. 1 == TS map with all known point sources included in models 2 == TS map using only diffuse models for background """ if mode not in [0, 1, 2]: print 'Error! Not a valid mode. Please use 1 or 2.' return for tsmap in self.tsmaps: if tsmap: tsmap.set_mode(mode) def make_zea(self, center, size=10, pixelsize=0.02, galactic=False): from uw.utilities.image import ZEA z = ZEA(center, size=size, pixelsize=pixelsize, galactic=galactic) z.fill(PySkyFunction(self)) self.z = z def get_1FGL_sources(self, z): """z == ZEA object""" fgl = get_latalog() sd_ul = z.skydir(0, 0) # upper left corner sd_lr = z.skydir(z.nx, z.ny) # lower right corner if z.galactic: az_max, po_min = sd_ul.l(), sd_ul.b() az_min, po_max = sd_lr.l(), sd_lr.b() else: az_max, po_min = sd_ul.ra(), sd_ul.dec() az_min, po_max = sd_lr.ra(), sd_lr.dec() # since longitude runs backward, this condition means we looped over 0 az_zero_cross = az_min > az_max az_key, po_key = ['GLON', 'GLAT'] if z.galactic else ['RA', 'DEC'] az = fgl.get(az_key).astype(float) po = fgl.get(po_key).astype(float) na = fgl.get('Source_Name') print po_min, po_max, az_min, az_max mask = (po > po_min) & (po < po_max) if az_zero_cross: mask = mask & ((az < az_max) | (az > az_min)) else: mask = mask & (az > az_min) & (az < az_max) sds = [ SkyDir(a, p, SkyDir.GALACTIC if z.galactic else SkyDir.EQUATORIAL) for a, p in zip(az[mask], po[mask]) ] return na[mask], sds def make_map(self, center, size=10, pixelsize=0.02, galactic=False, axes=None, scale=1, thresh_low=0, thresh_high=np.inf, label_1FGL=True, mode=1, cmap=None, log_transform=False, labels=None): """ scale : 0 == linear, 1 == sqrt """ import pylab as P from uw.utilities.image import ZEA from matplotlib.colorbar import ColorbarBase from matplotlib.colors import Normalize self.set_mode(mode) if axes is None: axes = P.gca() cmap = cmap or P.cm.jet cmap.set_bad('white') z = ZEA(center, size=size, pixelsize=pixelsize, galactic=galactic, axes=axes) z.fill(PySkyFunction(self)) im = z.image.copy() print 'Max Value: %.2f' % (im.max()) im[im < thresh_low] = np.nan im[im > thresh_high] = thresh_high z.grid() im = im**(0.5 if scale else 1) if log_transform: im[im < 1] = 1 im = np.log10(im) P.imshow(im, cmap=cmap) #P.colorbar(ax=axes,cmap=cmap,orientation='horizontal') #P.contour(im,np.asarray([9,16,25,50,100,1000])**(0.5 if scale else 1)) #P.contour(im,10) #contours = np.asarray([9,16,25,36,49,64,81,100,225,400,625,900,1225,1600])**(0.5 if scale else 1) #if log_transform: contours = np.log10(contours) #P.contour(im,contours) if label_1FGL: names, skydirs = self.get_1FGL_sources(z) for na, sd in zip(names, skydirs): z.plot_source(na, sd, color='gray' if thresh_low > 0 else 'white') if labels is not None: try: names, skydirs = labels except: skydirs = labels names = ['S%d' % (i) for i in xrange(len(labels))] for na, sd in zip(names, skydirs): z.plot_source(na, sd, color='gray' if thresh_low > 0 else 'white') return z #colorbar = ColorbarBase(axes,orientation='vertical',cmap=cmap) def make_3panel(self, center, size=10, pixelsize=0.02, galactic=False, scale=1, label_1FGL=True, labels=None, separate_figures=False, fignum_base=10): import pylab as P from matplotlib.colorbar import ColorbarBase from matplotlib.colors import Normalize from uw.utilities.image import ZEA cmap = P.cm.jet cmap.set_bad('white') if separate_figures: axes = [] for i in xrange(1, 4): P.figure(i + fignum_base) axes += [P.gca()] else: axes = [P.subplot(1, 3, i) for i in xrange(1, 4)] zeas = [ ZEA(center, size=size, pixelsize=pixelsize, galactic=galactic, axes=ax) for ax in axes ] mods = [1, 2, 0] for i in xrange(0, 3): self.set_mode(mods[i]) zeas[i].fill(PySkyFunction(self)) zeas[i].grid() axes[i].imshow(zeas[i].image**(0.5 if scale else 1), cmap=cmap) if label_1FGL: names, skydirs = self.get_1FGL_sources(zeas[0]) for na, sd in zip(names, skydirs): for z in zeas: z.plot_source(na, sd, color='white') if labels is not None: names, skydirs = labels for na, sd in zip(names, skydirs): for z in zeas: z.plot_source(na, sd, color='white') if separate_figures: # basically a "show" for i in xrange(1, 4): P.figure(i + fignum_base) axes[i - 1].set_autoscale_on(True) cb = ColorbarBase(axes[i - 1], orientation='vertical', cmap=cmap) #P.colorbar() return axes, zeas
class HealpixTSMap(object): def __init__(self, hr=None, pickle=None, factor=100, bright_sources=None): """hr : an instance of HealpixROI pickle : a pickle saved from a previous HealpixTSMap factor : number of intervals to divide base Healpixel side into""" self.bright_sources = bright_sources if hr is not None: self.setup_from_roi(hr, factor) elif pickle is not None: self.load(pickle) else: print 'Must provide either a HealpixROI instance or a pickle file!' raise Exception def setup_from_roi(self, hr, factor): band1 = hr.band band2 = Band(int(round(band1.nside() * factor))) rd = band1.dir(hr.index) # get pixels within a radius 10% greater than the base Healpix diagonal dimension radius = (np.pi / (3 * band1.nside()**2))**0.5 * 2**0.5 * 1.1 wsdl = WeightedSkyDirList(band2, rd, radius, True) # then cut down to just the pixels inside the base Healpixel inds = np.asarray([band1.index(x) for x in wsdl]) mask = inds == hr.index dirs = [wsdl[i] for i in xrange(len(mask)) if mask[i]] inds = np.asarray([band2.index(x) for x in dirs]).astype(int) # sanity check if abs(float(mask.sum()) / factor**2 - 1) > 0.01: print 'Warning: number of pixels found does not agree with expectations!' # calculate TS for each sub-pixel tsc = TSCalc(hr.roi) if self.bright_sources is not None: ts_vals = self.ts_vals = [deque(), deque(), deque()] bsm = np.asarray([ x.source_name in self.bright_sources for x in hr.roi.psm.models ]) for d in dirs: ts_vals[0].append(tsc(d)) ts_vals[1].append(tsc(d, repeat_diffuse=True)) ts_vals[2].append( tsc(d, repeat_diffuse=True, bright_source_mask=bsm)) else: self.ts_vals = ts_vals = [deque(), deque()] for d in dirs: ts_vals[0].append(tsc(d)) ts_vals[1].append(tsc(d, repeat_diffuse=True)) self.band1 = band1 self.band2 = band2 sorting = np.argsort(inds) self.inds = inds[sorting] for i in range(len(ts_vals)): ts_vals[i] = np.asarray(ts_vals[i])[sorting] self.previous_index = -1 self.index = hr.index self.mode = 0 self.ts = self.ts_vals[0] def dump(self, filename): d = dict() d['inds'] = self.inds d['ts_vals'] = self.ts_vals d['nside1'] = self.band1.nside() d['nside2'] = self.band2.nside() d['index'] = self.index dump(d, file(filename, 'w')) def load(self, filename): d = load(file(filename)) self.inds = d['inds'] self.band1 = Band(d['nside1']) self.band2 = Band(d['nside2']) if 'ts_vals' in d.keys(): self.ts_vals = d['ts_vals'] else: dim = (self.band2.nside() / self.band1.nside())**2 self.ts_vals = np.empty([3, dim]) self.ts_vals[:] = np.nan self.index = d['index'] self.ts = self.ts_vals[0] self.previous_index = -1 self.mode = 0 def pyskyfun(self): return PySkyFunction(self) def __call__(self, v, skydir=None): sd = skydir or SkyDir(Hep3Vector(v[0], v[1], v[2])) if self.band1.index(sd) != self.index: return np.nan id = self.band2.index(sd) if id != self.previous_index: self.previous_value = self.ts[np.searchsorted(self.inds, id)] self.previous_index = id return self.previous_value def multipix_call(self, sd): """A faster version of the skydir lookup where it assumed that the argument lies within the boundaries of this Healpixel.""" id = self.band2.index(sd) if id != self.previous_index: self.previous_value = self.ts[np.searchsorted(self.inds, id)] self.previous_index = id return self.previous_value def set_mode(self, mode=1): if mode not in [0, 1, 2]: print 'Not a valid mode... taking no action.' return self.ts = self.ts_vals[mode] self.mode = mode