def angdist(ra, dec, ps, ds=None): """ Calculate angular distance of point sources to point in the sky Parameters ---------- ra: float, R.A. of ROI (in degree) dec: float, DEC. of ROI (in degree) ps: list, list of point sources as generated with pointlike kwargs ------ ds: list, list of point sources as generated with pointlike, if None, don't use it and don't return it Returns ------- list that contains the angular distance in degrees to point sources """ skydir = SkyDir(ra, dec, SkyDir.EQUATORIAL) diffPs = empty(len(ps)) for i, p in enumerate(ps): diffPs[i] = skydir.difference( p.skydir) * 180. / pi # angular separation in degree if not ds == None: diffDs = empty(len(ds)) for i, d in enumerate(ds): diffDs[i] = skydir.difference( d.skydir) * 180. / pi # angular separation in degree return diffPs, diffDs else: return diffPs
def update_positions(self, tsmin=10, qualmax=8): """ use the localization information associated with each source to update position require ts>tsmin, qual<qualmax """ print '---Updating positions---' sources = [s for s in self.sources if s.skydir is not None and np.any(s.spectral_model.free)] #print 'sources:', [s.name for s in sources] print '%-15s%6s%8s %8s' % ('name','TS','qual', 'delta_ts') for source in sources: has_ts= hasattr(source, 'ts') print '%-15s %6.0f' % (source.name, source.ts if has_ts else -1.0) , if not hasattr(source, 'ellipse') or source.ellipse is None: print ' no localization info' continue if not has_ts: print ' no TS' continue if source.ts<tsmin: print ' TS<%.0f' % (tsmin) continue newdir = SkyDir(*source.ellipse[:2]); qual, delta_ts = source.ellipse[-2:] print '%6.1f%6.1f' % (qual, delta_ts) , if qual>qualmax: print ' qual>%.1f' % qualmax continue print ' %s -> %s, moved %.2f' % (source.skydir,newdir, np.degrees(newdir.difference(source.skydir))) source.skydir = newdir
def setup(self, **kw): self.plotfolder = 'limb_refit' self.source_name = 'limb' self.title = 'Limb refit' files, pickles = self.load_pickles('limb') rdict = dict() for f, p in zip(files, pickles): name = os.path.split(f)[-1][:9] front, back = p['model'].parameters if 'model' in p else (np.nan, np.nan) if 'model' not in p: p['model'] = None ra, dec = p['ra'], p['dec'] skydir = SkyDir(ra, dec) glat, glon = skydir.b(), skydir.l() if glon > 180: glon -= 360. rdict[name] = dict(ra=ra, dec=dec, glat=glat, glon=glon, skydir=skydir, front=front, back=back) self.df = pd.DataFrame(rdict).transpose() self.fpar = self.df.front self.bpar = self.df.back
def localize(self): """Localize a source using an elliptic approximation to the likelihood surface. return fit position, number of iterations, distance moved, delta TS """ roi = self.roi which = self.which bandfits = self.bandfits verbose = self.verbose update = self.update tolerance= self.tolerance l = quadform.Localize(self,verbose = verbose) ld = SkyDir(l.dir.ra(),l.dir.dec()) ll0 = self.spatialLikelihood(self.sd,update=False) if not self.quiet: fmt ='Localizing source %s, tolerance=%.1e...\n\t'+7*'%10s' tup = (self.name, tolerance,)+tuple('moved delta ra dec a b qual'.split()) print fmt % tup print ('\t'+4*'%10.4f')% (0,0,self.sd.ra(), self.sd.dec()) diff = l.dir.difference(self.sd)*180/np.pi print ('\t'+7*'%10.4f')% (diff,diff, l.par[0],l.par[1],l.par[3],l.par[4], l.par[6]) old_sigma=1.0 for i in xrange(self.max_iteration): try: l.fit(update=True) except: #raise l.recenter() if not self.quiet: print 'trying a recenter...' continue diff = l.dir.difference(ld)*180/np.pi delt = l.dir.difference(self.sd)*180/np.pi sigma = l.par[3] if not self.quiet: print ('\t'+7*'%10.4f')% (diff, delt, l.par[0],l.par[1],l.par[3],l.par[4], l.par[6]) if delt>self.maxdist: if not self.quiet: print '\t -attempt to move beyond maxdist=%.1f' % self.maxdist raise Exception('roi_localize failure: -attempt to move beyond maxdist=%.1f' % self.maxdist) if (diff < tolerance) and (abs(sigma-old_sigma) < tolerance): break ld = SkyDir(l.dir.ra(),l.dir.dec()) old_sigma=sigma roi.qform = l roi.ldir = l.dir roi.lsigma = l.sigma ll1 = self.spatialLikelihood(l.dir,update=update) if not self.quiet: print 'TS change: %.2f'%(2*(ll0 - ll1)) roi.delta_loc_logl = (ll0 - ll1) # this is necessary in case the fit always fails. delt = l.dir.difference(self.sd)*180/np.pi return l.dir, i, delt, 2*(ll0-ll1)
def ecliptic_coords(self): enp=SkyDir(270,90-23.439281) #ecliptic north pole gdir = [SkyDir(l,b, SkyDir.GALACTIC) for l,b in zip(self.df.glon, self.df.glat)] edir = np.array([ g.zenithCoords(enp) for g in gdir]); edir[0] sinlat = np.sin(np.radians(edir[:,1])) lon = edir[:,0] lon[lon>180] -= 360 return lon, sinlat
def fit(self, p): m_x, m_y, d_x, d_y = p roi = self.roi s2 = SkyDir(m_x + d_x, m_y + d_y) s1 = SkyDir(m_x - d_x, m_y - d_y) rot_back_1 = rotations.anti_rotate_equator(s1, self.middle) rot_back_2 = rotations.anti_rotate_equator(s2, self.middle) roi.modify(which=self.p1, skydir=rot_back_1) roi.modify(which=self.p2, skydir=rot_back_2) ll = roi.fit(use_gradient=self.use_gradient, estimate_errors=False) if ll < self.ll_best: prev = roi.parameters().copy() roi.set_parameters(self.best_spectral.copy()) roi.__update_state__() ll_alt = roi.fit(use_gradient=self.use_gradient, estimate_errors=False) if ll_alt > ll: ll = ll_alt else: roi.set_parameters(prev.copy()) roi.__update_state__() if ll < self.ll_0: prev = roi.parameters().copy() roi.set_parameters(self.init_spectral.copy()) roi.__update_state__() ll_alt = roi.fit(use_gradient=self.use_gradient, estimate_errors=False) if ll_alt > ll: ll = ll_alt else: roi.set_parameters(prev.copy()) roi.__update_state__() if ll > self.ll_best: self.ll_best = ll self.best_spectral = roi.parameters().copy() if self.verbose: print 'd=%s f=%.1e, d2=%s, f=%.1e, dist=%.3f logL=%.3f dlogL=%.3f' % \ (rot_back_1, rotations.print_flux(self.p1,roi), rot_back_2, rotations.print_flux(self.p2,roi), np.degrees(rot_back_1.difference(rot_back_2)), ll,ll-self.ll_0) return -ll # minimize negative log likelihood
def __getitem__(self, index): sdir = self.dirfun(index) t = self.skyfun(sdir) # problem with C++ code at exactly 180 deg. if np.isnan(t): sdir = SkyDir(sdir.l() + 1e-3, sdir.b(), SkyDir.GALACTIC) t = self.skyfun(sdir) assert not np.isnan(t), 'Failed for index %d' % index return t
def rotate_north(skydir,target,anti=False): """ Transformation that will rotate target to celestial north """ axis=SkyDir(target.ra()-90,0) theta=np.radians(90-target.dec()) if anti: theta*=-1 newdir=SkyDir(skydir.ra(),skydir.dec()) newdir().rotate(axis(),theta) return newdir
def approx_mid_point(skydir1,skydir2): """ This method is only valid in the small distance limit, in which case space is approximatly flat and the rhomb line is equal to the great circle line. """ if abs(skydir1.b()) < abs(skydir1.dec()): return SkyDir(skydir1.l() + DualLocalizer.symmetric_mod(skydir2.l()-skydir1.l(),360)/2, skydir1.b() + DualLocalizer.symmetric_mod(skydir2.b()-skydir1.b(),360)/2, SkyDir.GALACTIC) else: return SkyDir(skydir1.ra() + DualLocalizer.symmetric_mod(skydir2.ra()-skydir1.ra(),360)/2, skydir1.dec() + DualLocalizer.symmetric_mod(skydir2.dec()-skydir1.dec(),360)/2, SkyDir.EQUATORIAL)
def moment_analysis(tsmap, wcs, fudge=1.44): """ perform localization by a moment analysis of a TS map tsmap : array of float: TS values on a grid, must be square wcs : Projector object implements pix2sph function of two ints to return ra,dec fudge : float Additional factor to multiply the ellipse radii (Determined empirically) returns: ra, dec, ax, bx, ang """ vals = np.exp(-0.5* tsmap**2).flatten(); peak_fraction = vals.max()/sum(vals) n = len(vals) nx = ny =int(np.sqrt(n)) #centers of pixels have index +0.5 ix = np.array([ i % nx for i in range(n)]) +0.5 iy = np.array([ i //nx for i in range(n)]) +0.5 norm = 1./sum(vals) t = [sum(u*vals)*norm for u in ix,iy, ix**2, ix*iy, iy**2] center = (t[0],t[1]) C = np.matrix(center) variance = (np.matrix(((t[2], t[3]),(t[3], t[4]))) - C.T * C) ra,dec = wcs.pix2sph(center[0]+0.5,center[1]+0.5) peak = SkyDir(ra,dec) # get coords of center, measure degrees/pixel nc = (nx+1)/2 rac, decc = wcs.pix2sph(nc, nc) scale = wcs.pix2sph(nc, nc+1)[1] - decc size = nx*scale # adjust variance variance = scale**2 * variance offset = np.degrees(peak.difference(SkyDir(rac,decc))) # add effects of binsize var = variance #NO+ np.matrix(np.diag([1,1]))*(scale/3)**2 #Eigenvalue analysis to get ellipse coords u,v =np.linalg.eigh(var) ang =np.degrees(np.arctan2(v[1,1], -v[1,0])) if min(u)< 0.5* max(u): print 'Too elliptical : %s, setting circular' % u u[0]=u[1] = max(u) tt = np.sqrt(u) * fudge if u[1]>u[0]: ax,bx = tt[1], tt[0] ang = 90-ang else: ax,bx = tt return ra, dec, ax,bx, ang
def random_point_near(skydir, distance): """ Generate a random point within a given distance of another point """ while True: x = np.random.uniform(-distance, distance) y = np.random.uniform(-distance, distance) if np.sqrt(x**2 + y**2) < distance: break if skydir.ra() < 0.1 and skydir.dec() < 0.1: # Rotation fails in this case. return SkyDir(x + skydir.ra(), y + skydir.dec()) else: rotated_dir = SkyDir(x, y) return DualLocalizer.anti_rotate_equator(rotated_dir, skydir)
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 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 _calculate_weights(self, event_type, skydir=None): """Mostly a copy of like.pypsf.Psf.__calc_weights__ Adjusted to do a single event type """ aeff_info = self.cdbman('aeff', event_type=event_type) filename = aeff_info['filename'] # Have to redundantly open to get the ext name aeff_hdus = fits.open(aeff_info['filename']) extname = aeff_hdus[aeff_info['extensions'] ['EFF_AREA']].header['EXTNAME'] elo, ehi, clo, chi = self.e_los, self.e_his, self.c_los[:: -1], self.c_his[:: -1] # note that it is designed to do front and back, so need to copy filenames and extname ew = ExposureWeighter(filename, filename, self._ltfile(event_type), extname, extname) dummy = skydir or SkyDir() weights = np.zeros([len(elo), len(clo)]) for i in xrange(len(elo)): # iterator over energies em = (elo[i] * ehi[i])**0.5 for k, (c0, c1) in enumerate(zip( clo, chi)): # iterator over cos(theta) on-axis to edge if c0 < 0.35: continue # exclude bins below cos(theta)=0.4 weights[i, k] = ew(c0, c1, elo[i], ehi[i], 0, dummy) # exposure at energy/cos(theta) weights[i, :] /= weights[ i, :].sum() # normalize weights over cos(theta) return weights
def polar_plots(self, values, title=None, vmin=0, vmax=2, vticks=5, vlabel=None, thetamax=60): """ values : array of float Creates a Figure that must be cleared """ fig, axes = plt.subplots(1,2, figsize=(8,4),subplot_kw=dict(polar=True)) plt.subplots_adjust(bottom=0.12, top=0.90, wspace=0.3) plot_kw = dict(s=120, edgecolor='none', vmin=vmin, vmax=vmax) galeq = [SkyDir(float(u),0, SkyDir.GALACTIC) for u in np.arange(0,360,1)] galra = np.array([sd.ra() for sd in galeq]) galdec = np.array([sd.dec() for sd in galeq]) def radius( dec, i): return [90-dec, 90+dec][i] ra = np.array(map(lambda dir: dir.ra(), self.df.skydir)) dec = np.array(map(lambda dir: dir.dec(), self.df.skydir)) for i, ax in enumerate(axes[:2]): cut = [dec>(90-thetamax), dec<(thetamax-90)][i] r = [90-dec, 90+dec][i] theta = np.radians(ra) c = np.array(values)[cut] sc =ax.scatter(theta[cut], radius(dec[cut],i), c=c, **plot_kw); galtheta = galra; galrad = radius(galdec,i) ax.plot(np.radians(galtheta[galrad<thetamax]),galrad[galrad<thetamax], '-', color='grey', lw=2) ax.set_ylim(ymax=thetamax) ax.set_title(['North','South'][i], ha='right', fontsize='small') cbax = fig.add_axes((0.25,0.08,0.5, 0.04)) cb=plt.colorbar(sc, cbax, orientation='horizontal') if vlabel is not None: cb.set_label(vlabel) if vmin is not None and vmax is not None: cb.set_ticks(np.linspace(vmin, vmax, vticks)) if title is not None: plt.suptitle(title) return fig
class FromCCube(HParray): """Manage the gtlike HEALPix counts map """ def __init__(self, filename): """ load array from a HEALPix-format FITS file """ assert os.path.exists(filename), 'File "{}" not found'.format(filename) self.hdus = pyfits.open(filename) self.data = self.hdus[1].data self.nside = self.hdus[1].header['NSIDE'] # expect to find circle in header hdr = self.hdus[0].header try: dstypes = sorted( filter(lambda n: n.startswith('DSTYP'), hdr.keys())) i = [hdr[x] for x in dstypes].index('POS(RA,DEC)') i circ = hdr['DSVAL{}'.format(i)] ra, dec, self.radius = np.array(circ[7:-1].split(','), float) except Exception, msg: print 'failed to parse file {}: expected header to have a DSVAL with POS(RA,DEC)'.format( filename), msg raise self.center = SkyDir(ra, dec) self.indexfun = Band(self.nside).index self.lookup = dict(zip(self.data.PIX, self.data.CHANNEL1))
def __init__(self, source_name, **kwargs): """ """ keyword_options.process(self, kwargs) if self.energy_count is not None: self.energy_bins = self.energy_bins[:self.energy_count] if type(source_name) == str: t = SkyCoord.from_name(source_name) ra, dec = (t.fk5.ra.value, t.fk5.dec.value) else: ra, dec = source_name # select an ROI by the ra, dec specified or found from SkyCoord if self.verbose > 0: print 'Selecting ROI at (ra,dec)=({:.2f},{:.2f})'.format(ra, dec) self.roi = roi = main.ROI('.', (ra, dec)) # find the model source by position and select it distances = np.degrees( np.array([ s.skydir.difference(SkyDir(ra, dec)) if s.skydir is not None else 1e9 for s in roi.sources ])) min_dist = distances.min() assert min_dist < self.min_dist, 'Not within {} deg of any source in RoI'.format( self.min_dist) si = np.arange(len(distances))[distances == min_dist][0] sname = roi.sources.source_names[si] self.source = roi.get_source(sname) if self.verbose > 0: print 'Found model source "{}" within {:.3f} deg of "{}"'.format( self.source.name, min_dist, source_name)
def load_moment_analysis(self): """ check results of moment analysis """ m = self.df.moment has_moment = [x is not None for x in m] print 'Found %d sources with moment analysis' % sum(has_moment) if sum(has_moment) == 0: return None mdf = pd.DataFrame(m[has_moment]) u = np.array([list(x) for x in mdf.moment]) self.dfm = md = pd.DataFrame( u, index=mdf.index, columns='rax decx ax bx angx size peak_fract'.split()) md['locqual'] = self.df.locqual md['ts'] = self.df.ts md['delta_ts'] = self.df.delta_ts md['roiname'] = self.df.roiname md['a'] = self.df.a # generate the angular difference of fit vs. current positions delta = [] for n, t in self.df.iterrows(): ellipse = t['ellipse'] delta.append( np.degrees(SkyDir(*ellipse[:2]).difference(t['skydir']) ) if ellipse is not None else None) self.df['delta'] = delta md['delta'] = self.df.delta filename = 'moment_localizations.csv' md.to_csv(filename) print 'Wrote file %s' % filename return md
def __calc_weights__(self, livetimefile='', skydir=None): aeffstrs = self.CALDBManager.get_aeff() if len(self.CALDBhandles[0]) >= 7: # new format try: ew = ExposureWeighter(aeffstrs[0], aeffstrs[1], livetimefile, 'EFFECTIVE AREA_FRONT', 'EFFECTIVE AREA_BACK') except Exception: ew = ExposureWeighter(aeffstrs[0], aeffstrs[1], livetimefile) else: ew = ExposureWeighter(aeffstrs[0], aeffstrs[1], livetimefile) dummy = skydir or SkyDir() elo, ehi, clo, chi = self.e_los, self.e_his, self.c_los[:: -1], self.c_his[:: -1] weights = np.zeros([2, len(elo), len(clo)]) for i in xrange(len(elo)): # iterator over energies em = (elo[i] * ehi[i])**0.5 for j in [0, 1]: # iterate over conversion types for k, (c0, c1) in enumerate(zip( clo, chi)): # iterator over cos(theta) on-axis to edge if c0 < 0.35: continue # exclude bins below cos(theta)=0.4 weights[j, i, k] = ew(c0, c1, elo[i], ehi[i], j, dummy) # exposure at energy/cos(theta) weights[j, i, :] /= weights[ j, i, :].sum() # normalize weights over cos(theta) self.weights = weights
def equatorial_coords(self): gdir = [SkyDir(l,b, SkyDir.GALACTIC) for l,b in zip(self.df.glon, self.df.glat)] lon = np.array([x.ra() for x in gdir]) lat = np.array([x.dec() for x in gdir]) sinlat = np.sin(np.radians(lat)) lon[lon>180] -= 360 return lon, sinlat
def process_filedata(roi, selected_bands): """ The radius parameter will apply a radius cut. Assume that all bands are contiguous (hope this is always true!) """ radius = roi.sa.maxROI emin = min(b.emin for b in selected_bands) emax = max(b.emax for b in selected_bands) ft1files = roi.sa.pixeldata.ft1files cuts = [ 'ENERGY > %s' % emin, 'ENERGY < %s' % emax, 'ZENITH_ANGLE < %s' % roi.sa.pixeldata.zenithcut, 'THETA < %s' % roi.sa.pixeldata.thetacut, 'EVENT_CLASS >= %s' % roi.sa.pixeldata.event_class ] data = get_fields(ft1files, ['RA', 'DEC', 'TIME', 'ENERGY', 'CONVERSION_TYPE'], cuts) # convert into skydirs skydirs = [ SkyDir(float(data['RA'][i]), float(data['DEC'][i])) for i in xrange(len(data['RA'])) ] # apply the same gti cut used to read in the initial WSDL. gti = roi.sa.pixeldata.gti good_dirs = [] front_bins = [b for b in selected_bands if b.ct == 0] front_emin = min(b.emin for b in front_bins) if len(front_bins) > 0 else None front_emax = max(b.emax for b in front_bins) if len(front_bins) > 0 else None back_bins = [b for b in selected_bands if b.ct == 1] back_emin = min(b.emin for b in back_bins) if len(back_bins) > 0 else None back_emax = max(b.emax for b in back_bins) if len(back_bins) > 0 else None good_photons = [] for skydir, time, energy, ct in zip(skydirs, data['TIME'], data['ENERGY'], data['CONVERSION_TYPE']): if gti.accept(time) and np.degrees(skydir.difference( roi.roi_dir)) < radius: if ct == 0 and \ front_emin is not None and front_emax is not None and \ energy > front_emin and energy < front_emax: good_photons.append(skydir) if ct == 1 and \ back_emin is not None and back_emax is not None and \ energy > back_emin and energy < back_emax: good_photons.append(skydir) return good_photons
def rotate_equator(skydir,target,anti=False): """ Rotate skydir such that target would be rotated to the celestial equator. A few simple tests: >>> a = SkyDir(0,0) >>> b = SkyDir(30,30) >>> rotate_equator(a, b) SkyDir(330.000,-30.000) >>> anti_rotate_equator(a, b) SkyDir(30.000,30.000) There was previously a bug when the 'target' was the equator. I think it is fixed now: >>> rotate_equator(b, a) SkyDir(30.000,30.000) >>> anti_rotate_equator(b, a) SkyDir(30.000,30.000) Another test: >>> sd = SkyDir(-.2,-.2) >>> target = SkyDir(5,5) >>> l=rotate_equator(sd, target) >>> print '%.2f, %.2f' % (l.ra(), l.dec()) 354.80, -5.20 >>> l=anti_rotate_equator(sd, target) >>> print '%.2f, %.2f' % (l.ra(), l.dec()) 4.80, 4.80 """ if np.allclose([target.ra(), target.dec()], [0,0]): return skydir equator=SkyDir(0,0) axis=target.cross(equator) theta=equator.difference(target) if anti: theta*=-1 newdir=SkyDir(skydir.ra(),skydir.dec()) newdir().rotate(axis(),theta) return newdir
def __call__(self, v): sd = SkyDir(Hep3Vector(v[0], v[1], v[2])) v1 = self.tscalc(sd, repeat_diffuse=False, bright_source_mask=None) if self.bright_source_mask is not None: return self.tscalc(sd, repeat_diffuse=True, bright_source_mask=self.bright_source_mask) return v1
def loadsrcs(self): self.srcs = [] ff = open(self.srcdir + self.name + '.txt') header = ff.readline() for lines in ff: line = lines.split() self.srcs.append(SkyDir(float(line[1]), float( line[2]))) #Hep3Vector([float(line[1])/rd,float(line[2])/rd]))
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 make_test_source(self, offset, expected_overlap): model = sources.PowerLaw(1e-11, 2.0) source = sources.PointSource(name='test source', skydir=SkyDir(self.skydir.ra(), self.skydir.dec() + offset), model=model) conv = source.response(self.back_band) overlap = conv.overlap self.assertAlmostEqual(expected_overlap, overlap, delta=0.001)
def __call__(self, v, skydir=None): sd = skydir or SkyDir(Hep3Vector(v[0], v[1], v[2])) rval = 0 for band in self.bands: PythonUtilities.arclength(band.rvals, band.wsdl, sd) mask = band.rvals < band.max_rad rval += (band.psf(band.rvals[mask], density=True) * band.pix_counts[mask]).sum() return rval
def drawit(self): self.tsp.overplot(self.ellipse, color='w', lw=2, ls='-', contours=[2.45]) self.tsp.plot(SkyDir(*self.ellipse[:2]), color='w', symbol='o') return self.tsp.zea.axes.figure
def find_nearest_to(self, *pars): """Given the ra, dec, or a skydir, find nearest source, return name, distance""" from skymaps import SkyDir sd = SkyDir(*pars) if len(pars) == 2 else pars[0] dists = [x.difference(sd) for x in self.df.skydir] t = min(dists) i = dists.index(t) return self.df.index[i], np.degrees(t)
def __init__(self, config_dir, roi_spec=None, xml_file=None, **kwargs): """Start pointlike v2 (like2) in the specified ROI parameters ---------- config_dir : string file path to a folder containing a file config.txt see configuration.Configuration roi_spec : [None |integer | (ra,dec) tuple ] If None, require that the input_model dict has a key 'xml_file' if an integer, it must be <1728, the ROI number if a string, assume a source name and load the ROI containing it """ keyword_options.process(self, kwargs) self.config = config = configuration.Configuration( config_dir, quiet=self.quiet, postpone=self.postpone) ecat = extended.ExtendedCatalog(config.extended) if isinstance(roi_spec, str): # try: # roi_sources =from_xml.ROImodelFromXML(config, roi_spec) # roi_index = roi_sources.index # except: # print 'No ROI specification (an index) or presence of an xml file' # raise # Change to just expecting the name of a source sourcelist = glob.glob('sources_*.csv')[0] df = pd.read_csv(sourcelist, index_col=3 if roi_spec[0] == 'J' else 0) if roi_spec not in df.index: print 'Source name "{}" not found '.format(roi_spec) raise Exception roi_index = int(df.loc[roi_spec]['roiname'][-4:]) print 'Loading ROI #{}, containing source "{}"'.format( roi_index, roi_spec) elif isinstance(roi_spec, int): roi_index = roi_spec elif type(roi_spec) == tuple and len(roi_spec) == 2: roi_index = Band(12).index(SkyDir(*roi_spec)) else: raise Exception('Did not recoginze roi_spec: %s' % (roi_spec)) roi_sources = from_healpix.ROImodelFromHealpix( config, roi_index, ecat=ecat, ) config.roi_spec = configuration.ROIspec(healpix_index=roi_index) self.name = config.roi_spec.name if config.roi_spec is not None else roi_spec roi_bands = bands.BandSet(config, roi_index) roi_bands.load_data() super(ROI, self).__init__(roi_bands, roi_sources)
def angle_equatorial_from_galactic(center, angle_galactic): """ For a given position in the sky, and a given angle defined as a rotation east of galactic north, comute the angle defined as a rotation east of celestial north. """ l,b=center.l(),center.b() ra,dec=center.ra(),center.dec() # define a galacitc projection coordiante system centered on our position in the sky wcs = pywcs.WCS(naxis=2) # n.b. (l,b) has an image coordiante of (0,0), which is convenient wcs.wcs.crpix = [0, 0] wcs.wcs.cdelt = np.array([-0.1, 0.1]) wcs.wcs.crval = [l, b] wcs.wcs.ctype = ["GLON-ZEA", "GLAT-ZEA"] # compute the axes of increasing 'dec' and 'b' gal_axis = wcs.wcs_sky2pix(np.array([[l,b + 0.01]], float),1)[0] # find the image vector of increasing galactic latitude gal_axis /= np.sqrt(gal_axis.dot(gal_axis)) cel_dir = SkyDir(ra,dec+0.01) # find the image vector of increasing equatorial latitude cel_axis = wcs.wcs_sky2pix(np.array([[cel_dir.l(),cel_dir.b()]], float),1)[0] cel_axis /= np.sqrt(cel_axis.dot(cel_axis)) # compute the angle between the two axes # N.B. use compute angle of each axes using atan2 to get correct coordinate. # The difference of these two angles should be the absolute angle # with the correct minus sign. rotation = np.degrees( np.arctan2(gal_axis[1],gal_axis[0]) - np.arctan2(cel_axis[1],cel_axis[0]) ) # the new angle is just the old angle + the difference between axes # The + sign was determined emperically angle_equatorial = angle_galactic + rotation return angle_equatorial
extensions = np.linspace(min_extension, max_extension, 2**3+1) np.random.shuffle(extensions) # formula to interpolate from the flux at lowest to highest extension flux_mc = lambda extension: np.exp(np.log(min_flux_mc) + (np.log(max_flux_mc) - np.log(min_flux_mc))*\ (extension-min(extensions))/(max(extensions)-min(extensions))) index_mc = args.index emin=1e2 emax=1e5 irf="P7SOURCE_V6" skydir_mc = SkyDir() bg = get_sreekumar() ft2 = dict2fgl['ft2'] ltcube = dict2fgl['ltcube'] results = [] for extension_mc in extensions: print 'Looping over extension_mc=%g' % extension_mc model_mc = PowerLaw(index=index_mc) model_mc.set_flux(flux_mc(extension_mc), emin, emax)