def getPositionAtTime(self, t): from astrometry.util.starutil_numpy import radectoxyz, arcsecperrad, axistilt, xyztoradec dt = (t - self.epoch).toYears() # Assume "pos" is an RaDecPos p = self.pos + dt * self.pm suntheta = t.getSunTheta() # print 'dt', dt, 'pos', self.pos, 'pm', self.pm, 'dt*pm:', dt * self.pm # print 'p0: (%.8f, %.8f)' % (self.pos.ra, self.pos.dec) # print 'p1: (%.8f, %.8f)' % (p.ra, p.dec) xyz = radectoxyz(p.ra, p.dec) xyz = xyz[0] # d(celestial coords)/d(parallax) # - takes numerical derivatives when it could take analytic ones # output is in [degrees / arcsec]. Yep. Crazy but true. # HACK: fmods dRA when it should do something continuous. # rd2xyz(0,0) is a unit vector; 1/arcsecperrad is (a good approximation to) # the distance on the unit sphere spanned by an angle of 1 arcsec. # We take a step of that length and return the change in RA,Dec. # It's about 1e-5 so we don't renormalize the xyz unit vector. dxyz1 = radectoxyz(0., 0.) / arcsecperrad dxyz1 = dxyz1[0] # - imprecise angle of obliquity # - implicitly assumes circular orbit # output is in [degrees / arcsec]. Yep. Crazy but true. dxyz2 = radectoxyz(90., axistilt) / arcsecperrad dxyz2 = dxyz2[0] xyz += self.parallax.getValue() * (dxyz1 * np.cos(suntheta) + dxyz2 * np.sin(suntheta)) r,d = xyztoradec(xyz) return RaDecPos(r,d)
def cat_sdss(req, ver): import json import numpy as np from astrometry.util.starutil_numpy import degrees_between, radectoxyz, xyztoradec from map.views import sdss_ccds_near from astrometry.util.fits import fits_table, merge_tables tag = 'sdss-cat' ralo = float(req.GET['ralo']) rahi = float(req.GET['rahi']) declo = float(req.GET['declo']) dechi = float(req.GET['dechi']) ver = int(ver) if not ver in catversions[tag]: raise RuntimeError('Invalid version %i for tag %s' % (ver, tag)) rad = degrees_between(ralo, declo, rahi, dechi) / 2. xyz1 = radectoxyz(ralo, declo) xyz2 = radectoxyz(rahi, dechi) xyz = (xyz1 + xyz2) xyz /= np.sqrt(np.sum(xyz**2)) rc,dc = xyztoradec(xyz) rad = rad + np.hypot(10.,14.)/2./60. ccds = sdss_ccds_near(rc[0], dc[0], rad) if ccds is None: print('No SDSS CCDs nearby') return HttpResponse(json.dumps(dict(rd=[])), content_type='application/json') print(len(ccds), 'SDSS CCDs') T = [] for ccd in ccds: # env/BOSS_PHOTOOBJ/301/2073/3/photoObj-002073-3-0088.fits fn = os.path.join(settings.SDSS_BASEDIR, 'env', 'BOSS_PHOTOOBJ', str(ccd.rerun), str(ccd.run), str(ccd.camcol), 'photoObj-%06i-%i-%04i.fits' % (ccd.run, ccd.camcol, ccd.field)) print('Reading', fn) T.append(fits_table(fn, columns='ra dec objid mode objc_type objc_flags objc_flags nchild tai expflux devflux psfflux cmodelflux fracdev mjd'.split())) T = merge_tables(T) T.cut((T.dec >= declo) * (T.dec <= dechi)) # FIXME T.cut((T.ra >= ralo) * (T.ra <= rahi)) # primary T.cut(T.mode == 1) types = ['P' if t == 6 else 'C' for t in T.objc_type] fluxes = [p if t == 6 else c for t,p,c in zip(T.objc_type, T.psfflux, T.cmodelflux)] return HttpResponse(json.dumps(dict( rd=[(float(o.ra),float(o.dec)) for o in T], sourcetype=types, fluxes = [dict(u=float(f[0]), g=float(f[1]), r=float(f[2]), i=float(f[3]), z=float(f[4])) for f in fluxes], )), content_type='application/json')
def match_radec(ra1, dec1, ra2, dec2, radius_in_deg, notself=False, nearest=False, indexlist=False): ''' (m1,m2,d12) = match_radec(ra1,dec1, ra2,dec2, radius_in_deg) Cross-matches numpy arrays of RA,Dec points. Behaves like spherematch.pro of IDL ra1,dec1 (and 2): RA,Dec in degrees of points to match. Must be scalars or numpy arrays. radius_in_deg: search radius in degrees. notself: if True, avoids returning 'identity' matches; ASSUMES that ra1,dec1 == ra2,dec2. nearest: if True, returns only the nearest match in (ra2,dec2) for each point in (ra1,dec1). indexlist: returns a list of length len(ra1), containing None or a list of ints of matched points in ra2,dec2. Returns this list. Returns: m1: indices into the "ra1,dec1" arrays of matching points. Numpy array of ints. m2: same, but for "ra2,dec2". d12: distance, in degrees, between the matching points. ''' # Convert to coordinates on the unit sphere xyz1 = radectoxyz(ra1, dec1) #if all(ra1 == ra2) and all(dec1 == dec2): if ra1 is ra2 and dec1 is dec2: xyz2 = xyz1 else: xyz2 = radectoxyz(ra2, dec2) r = deg2dist(radius_in_deg) if nearest: (inds,dists2) = _nearest_func(xyz2, xyz1, r, notself=notself) I = np.flatnonzero(inds >= 0) J = inds[I] d = distsq2deg(dists2[I]) else: X = match(xyz1, xyz2, r, notself=notself, indexlist=indexlist) if indexlist: return X (inds,dists) = X dist_in_deg = dist2deg(dists) I,J = inds[:,0], inds[:,1] d = dist_in_deg[:,0] return (I, J, d)
def match_radec(ra1, dec1, ra2, dec2, radius_in_deg, notself=False, nearest=False): ''' (m1,m2,d12) = match_radec(ra1,dec1, ra2,dec2, radius_in_deg) Cross-matches numpy arrays of RA,Dec points. Behaves like spherematch.pro of IDL ra1,dec1 (and 2): RA,Dec in degrees of points to match. Must be scalars or numpy arrays. radius_in_deg: search radius in degrees. notself: if True, avoids returning 'identity' matches; ASSUMES that ra1,dec1 == ra2,dec2. nearest: if True, returns only the nearest match in (ra2,dec2) for each point in (ra1,dec1). Returns: m1: indices into the "ra1,dec1" arrays of matching points. Numpy array of ints. m2: same, but for "ra2,dec2". d12: distance, in degrees, between the matching points. ''' # Convert to coordinates on the unit sphere xyz1 = radectoxyz(ra1, dec1) #if all(ra1 == ra2) and all(dec1 == dec2): if ra1 is ra2 and dec1 is dec2: xyz2 = xyz1 else: xyz2 = radectoxyz(ra2, dec2) r = deg2dist(radius_in_deg) if nearest: (inds,dists2) = _nearest_func(xyz2, xyz1, r, notself=notself) I = np.flatnonzero(inds >= 0) J = inds[I] d = distsq2deg(dists2[I]) else: (inds,dists) = match(xyz1, xyz2, r, notself) dist_in_deg = dist2deg(dists) I,J = inds[:,0], inds[:,1] d = dist_in_deg[:,0] return (I, J, d)
def cat_kd(req, ver, tag, fn): tag = 'spec' ralo = float(req.GET['ralo']) rahi = float(req.GET['rahi']) declo = float(req.GET['declo']) dechi = float(req.GET['dechi']) ver = int(ver) if not ver in catversions[tag]: raise RuntimeError('Invalid version %i for tag %s' % (ver, tag)) import numpy as np from astrometry.util.fits import fits_table, merge_tables from astrometry.libkd.spherematch import tree_open, tree_search_radec from astrometry.util.starutil_numpy import radectoxyz, xyztoradec, degrees_between xyz1 = radectoxyz(ralo, declo) xyz2 = radectoxyz(rahi, dechi) xyz = (xyz1 + xyz2) / 2. xyz /= np.sqrt(np.sum(xyz**2)) rc, dc = xyztoradec(xyz) rc = rc[0] dc = dc[0] rad = degrees_between(rc, dc, ralo, declo) kd = tree_open(fn) I = tree_search_radec(kd, rc, dc, rad) print('Matched', len(I), 'from', fn) if len(I) == 0: return None T = fits_table(fn, rows=I) debug(len(T), 'spectra') if ralo > rahi: # RA wrap T.cut( np.logical_or(T.ra > ralo, T.ra < rahi) * (T.dec > declo) * (T.dec < dechi)) else: T.cut( (T.ra > ralo) * (T.ra < rahi) * (T.dec > declo) * (T.dec < dechi)) debug(len(T), 'in cut') return T
def cat_targets_dr2(req, ver): import json tag = 'targets-dr2' ralo = float(req.GET['ralo']) rahi = float(req.GET['rahi']) declo = float(req.GET['declo']) dechi = float(req.GET['dechi']) ver = int(ver) if not ver in catversions[tag]: raise RuntimeError('Invalid version %i for tag %s' % (ver, tag)) from astrometry.util.fits import fits_table, merge_tables import numpy as np from cat.models import DR2_Target as Target from astrometry.util.starutil_numpy import radectoxyz, xyztoradec, degrees_between xyz1 = radectoxyz(ralo, declo) xyz2 = radectoxyz(rahi, dechi) xyz = (xyz1 + xyz2) / 2. xyz /= np.sqrt(np.sum(xyz**2)) rc, dc = xyztoradec(xyz) rc = rc[0] dc = dc[0] rad = degrees_between(rc, dc, ralo, declo) objs = Target.objects.extra(where=[ 'q3c_radial_query(target.ra, target.dec, %.4f, %.4f, %g)' % (rc, dc, rad * 1.01) ]) print('Got', objs.count(), 'targets') print('types:', np.unique([o.type for o in objs])) print('versions:', np.unique([o.version for o in objs])) return HttpResponse(json.dumps( dict( rd=[(float(o.ra), float(o.dec)) for o in objs], name=[o.type for o in objs], )), content_type='application/json')
def cat_kd(req, ver, tag, fn): tag = 'spec' ralo = float(req.GET['ralo']) rahi = float(req.GET['rahi']) declo = float(req.GET['declo']) dechi = float(req.GET['dechi']) ver = int(ver) if not ver in catversions[tag]: raise RuntimeError('Invalid version %i for tag %s' % (ver, tag)) import numpy as np from astrometry.util.fits import fits_table, merge_tables from astrometry.libkd.spherematch import tree_open, tree_search_radec from astrometry.util.starutil_numpy import radectoxyz, xyztoradec, degrees_between xyz1 = radectoxyz(ralo, declo) xyz2 = radectoxyz(rahi, dechi) xyz = (xyz1 + xyz2)/2. xyz /= np.sqrt(np.sum(xyz**2)) rc,dc = xyztoradec(xyz) rc = rc[0] dc = dc[0] rad = degrees_between(rc, dc, ralo, declo) kd = tree_open(fn) I = tree_search_radec(kd, rc, dc, rad) print('Matched', len(I), 'from', fn) if len(I) == 0: return None T = fits_table(fn, rows=I) debug(len(T), 'spectra') if ralo > rahi: # RA wrap T.cut(np.logical_or(T.ra > ralo, T.ra < rahi) * (T.dec > declo) * (T.dec < dechi)) else: T.cut((T.ra > ralo) * (T.ra < rahi) * (T.dec > declo) * (T.dec < dechi)) debug(len(T), 'in cut') return T
def cat_targets_dr2(req, ver): import json tag = 'targets-dr2' ralo = float(req.GET['ralo']) rahi = float(req.GET['rahi']) declo = float(req.GET['declo']) dechi = float(req.GET['dechi']) ver = int(ver) if not ver in catversions[tag]: raise RuntimeError('Invalid version %i for tag %s' % (ver, tag)) from astrometry.util.fits import fits_table, merge_tables import numpy as np from cat.models import DR2_Target as Target from astrometry.util.starutil_numpy import radectoxyz, xyztoradec, degrees_between xyz1 = radectoxyz(ralo, declo) xyz2 = radectoxyz(rahi, dechi) xyz = (xyz1 + xyz2)/2. xyz /= np.sqrt(np.sum(xyz**2)) rc,dc = xyztoradec(xyz) rc = rc[0] dc = dc[0] rad = degrees_between(rc, dc, ralo, declo) objs = Target.objects.extra(where=[ 'q3c_radial_query(target.ra, target.dec, %.4f, %.4f, %g)' % (rc, dc, rad * 1.01)]) print('Got', objs.count(), 'targets') print('types:', np.unique([o.type for o in objs])) print('versions:', np.unique([o.version for o in objs])) return HttpResponse(json.dumps(dict( rd=[(float(o.ra),float(o.dec)) for o in objs], name=[o.type for o in objs], )), content_type='application/json')
def read_astrans(fn, hdu, hdr=None, W=None, H=None, fitsfile=None): from astrometry.sdss import AsTransWrapper, AsTrans from astrometry.util.util import Tan, fit_sip_wcs_py from astrometry.util.starutil_numpy import radectoxyz import numpy as np astrans = AsTrans.read(fn, F=fitsfile, primhdr=hdr) # Approximate as SIP. if hdr is None and fn.endswith('.bz2'): import fitsio hdr = fitsio.read_header(fn, 0) if hdr is not None: tan = Tan(*[ float(hdr[k]) for k in [ 'CRVAL1', 'CRVAL2', 'CRPIX1', 'CRPIX2', 'CD1_1', 'CD1_2', 'CD2_1', 'CD2_2', 'NAXIS1', 'NAXIS2' ] ]) else: # Frame files include a TAN header... start there. tan = Tan(fn) # Evaluate AsTrans on a pixel grid... h, w = tan.shape xx = np.linspace(1, w, 20) yy = np.linspace(1, h, 20) xx, yy = np.meshgrid(xx, yy) xx = xx.ravel() yy = yy.ravel() rr, dd = astrans.pixel_to_radec(xx, yy) xyz = radectoxyz(rr, dd) fieldxy = np.vstack((xx, yy)).T sip_order = 5 inv_order = 7 sip = fit_sip_wcs_py(xyz, fieldxy, None, tan, sip_order, inv_order) return sip
def read_astrans(fn, hdu, hdr=None, W=None, H=None, fitsfile=None): from astrometry.sdss import AsTransWrapper, AsTrans from astrometry.util.util import Tan, fit_sip_wcs_py from astrometry.util.starutil_numpy import radectoxyz import numpy as np astrans = AsTrans.read(fn, F=fitsfile, primhdr=hdr) # Approximate as SIP. if hdr is None and fn.endswith('.bz2'): import fitsio hdr = fitsio.read_header(fn, 0) if hdr is not None: tan = Tan(*[float(hdr[k]) for k in [ 'CRVAL1', 'CRVAL2', 'CRPIX1', 'CRPIX2', 'CD1_1', 'CD1_2', 'CD2_1', 'CD2_2', 'NAXIS1','NAXIS2']]) else: # Frame files include a TAN header... start there. tan = Tan(fn) # Evaluate AsTrans on a pixel grid... h,w = tan.shape xx = np.linspace(1, w, 20) yy = np.linspace(1, h, 20) xx,yy = np.meshgrid(xx, yy) xx = xx.ravel() yy = yy.ravel() rr,dd = astrans.pixel_to_radec(xx, yy) xyz = radectoxyz(rr, dd) fieldxy = np.vstack((xx, yy)).T sip_order = 5 inv_order = 7 sip = fit_sip_wcs_py(xyz, fieldxy, None, tan, sip_order, inv_order) return sip
def match_radec(ra1, dec1, ra2, dec2, radius_in_deg, notself=False, nearest=False, indexlist=False, count=False): ''' Cross-matches numpy arrays of RA,Dec points. Behaves like spherematch.pro of IDL. Parameters ---------- ra1, dec1, ra2, dec2 : numpy arrays, or scalars. RA,Dec in degrees of points to match. radius_in_deg : float Search radius in degrees. notself : boolean If True, avoids returning 'identity' matches; ASSUMES that ra1,dec1 == ra2,dec2. nearest : boolean If True, returns only the nearest match in *(ra2,dec2)* for each point in *(ra1,dec1)*. indexlist : boolean If True, returns a list of length *len(ra1)*, containing *None* or a list of ints of matched points in *ra2,dec2*. Returns ------- m1 : numpy array of integers Indices into the *ra1,dec1* arrays of matching points. m2 : numpy array of integers Same, but for *ra2,dec2*. d12 : numpy array, float Distance, in degrees, between the matching points. ''' # Convert to coordinates on the unit sphere xyz1 = radectoxyz(ra1, dec1) #if all(ra1 == ra2) and all(dec1 == dec2): if ra1 is ra2 and dec1 is dec2: xyz2 = xyz1 else: xyz2 = radectoxyz(ra2, dec2) r = deg2dist(radius_in_deg) extra = () if nearest: X = _nearest_func(xyz2, xyz1, r, notself=notself, count=count) if not count: (inds,dists2) = X I = np.flatnonzero(inds >= 0) J = inds[I] d = distsq2deg(dists2[I]) else: #print 'X', X #(inds,dists2,counts) = X J,I,d,counts = X extra = (counts,) print('I', I.shape, I.dtype) print('J', J.shape, J.dtype) print('counts', counts.shape, counts.dtype) else: X = match(xyz1, xyz2, r, notself=notself, indexlist=indexlist) if indexlist: return X (inds,dists) = X dist_in_deg = dist2deg(dists) I,J = inds[:,0], inds[:,1] d = dist_in_deg[:,0] return (I, J, d) + extra
def cat_targets_drAB(req, ver, cats=[], tag='', bgs=False, sky=False, bright=False, dark=False, color_name_func=desitarget_color_names): ''' color_name_func: function that selects names and colors for targets (eg based on targeting bit values) ''' import json ralo = float(req.GET['ralo']) rahi = float(req.GET['rahi']) declo = float(req.GET['declo']) dechi = float(req.GET['dechi']) ver = int(ver) if not ver in catversions[tag]: raise RuntimeError('Invalid version %i for tag %s' % (ver, tag)) from astrometry.util.fits import fits_table, merge_tables from astrometry.libkd.spherematch import tree_open, tree_search_radec import numpy as np from astrometry.util.starutil_numpy import radectoxyz, xyztoradec, degrees_between xyz1 = radectoxyz(ralo, declo) xyz2 = radectoxyz(rahi, dechi) xyz = (xyz1 + xyz2) / 2. xyz /= np.sqrt(np.sum(xyz**2)) rc, dc = xyztoradec(xyz) rc = rc[0] dc = dc[0] rad = degrees_between(rc, dc, ralo, declo) ''' startree -i /project/projectdirs/desi/target/catalogs/targets-dr4-0.20.0.fits -o data/targets-dr4-0.20.0.kd.fits -P -k -T ''' TT = [] for fn in cats: kd = tree_open(fn) I = tree_search_radec(kd, rc, dc, rad) print('Matched', len(I), 'from', fn) if len(I) == 0: continue T = fits_table(fn, rows=I) TT.append(T) if len(TT) == 0: return HttpResponse(json.dumps(dict(rd=[], name=[])), content_type='application/json') T = merge_tables(TT, columns='fillzero') if bgs: T.cut(T.bgs_target > 0) if bright: T.cut(np.logical_or(T.bgs_target > 0, T.mws_target > 0)) if dark: T.cut(T.desi_target > 0) names = None colors = None if color_name_func is not None: names, colors = color_name_func(T) if sky: fluxes = [ dict(g=float(g), r=float(r), z=float(z)) for (g, r, z) in zip(T.apflux_g[:, 0], T.apflux_r[:, 0], T.apflux_z[:, 0]) ] nobs = None else: fluxes = [ dict(g=float(g), r=float(r), z=float(z), W1=float(W1), W2=float(W2)) for (g, r, z, W1, W2) in zip(T.flux_g, T.flux_r, T.flux_z, T.flux_w1, T.flux_w2) ] nobs = [ dict(g=int(g), r=int(r), z=int(z)) for g, r, z in zip(T.nobs_g, T.nobs_r, T.nobs_z) ], rtn = dict( rd=[(t.ra, t.dec) for t in T], targetid=[int(t) for t in T.targetid], fluxes=fluxes, ) if names is not None: rtn.update(name=names) if colors is not None: rtn.update(color=colors) if nobs is not None: rtn.update(nobs=nobs) return HttpResponse(json.dumps(rtn), content_type='application/json')
def cat_targets_drAB(req, ver, cats=None, tag='', bgs=False, sky=False, bright=False, dark=False, color_name_func=desitarget_color_names): ''' color_name_func: function that selects names and colors for targets (eg based on targeting bit values) ''' if cats is None: cats = [] import json ralo = float(req.GET['ralo']) rahi = float(req.GET['rahi']) declo = float(req.GET['declo']) dechi = float(req.GET['dechi']) ver = int(ver) if not ver in catversions[tag]: raise RuntimeError('Invalid version %i for tag %s' % (ver, tag)) from astrometry.util.fits import fits_table, merge_tables from astrometry.libkd.spherematch import tree_open, tree_search_radec import numpy as np from astrometry.util.starutil_numpy import radectoxyz, xyztoradec, degrees_between xyz1 = radectoxyz(ralo, declo) xyz2 = radectoxyz(rahi, dechi) xyz = (xyz1 + xyz2)/2. xyz /= np.sqrt(np.sum(xyz**2)) rc,dc = xyztoradec(xyz) rc = rc[0] dc = dc[0] rad = degrees_between(rc, dc, ralo, declo) ''' startree -i /project/projectdirs/desi/target/catalogs/targets-dr4-0.20.0.fits -o data/targets-dr4-0.20.0.kd.fits -P -k -T ''' TT = [] for fn in cats: kd = tree_open(fn) I = tree_search_radec(kd, rc, dc, rad) print('Matched', len(I), 'from', fn) if len(I) == 0: continue T = fits_table(fn, rows=I) TT.append(T) if len(TT) == 0: return HttpResponse(json.dumps(dict(rd=[], name=[])), content_type='application/json') T = merge_tables(TT, columns='fillzero') if bgs: T.cut(T.bgs_target > 0) if bright: T.cut(np.logical_or(T.bgs_target > 0, T.mws_target > 0)) if dark: T.cut(T.desi_target > 0) names = None colors = None if color_name_func is not None: names,colors = color_name_func(T) if sky: fluxes = [dict(g=float(g), r=float(r), z=float(z)) for (g,r,z) in zip(T.apflux_g[:,0], T.apflux_r[:,0], T.apflux_z[:,0])] nobs = None else: fluxes = [dict(g=float(g), r=float(r), z=float(z), W1=float(W1), W2=float(W2)) for (g,r,z,W1,W2) in zip(T.flux_g, T.flux_r, T.flux_z, T.flux_w1, T.flux_w2)] nobs=[dict(g=int(g), r=int(r), z=int(z)) for g,r,z in zip(T.nobs_g, T.nobs_r, T.nobs_z)], rtn = dict(rd=[(t.ra, t.dec) for t in T], targetid=[int(t) for t in T.targetid], fluxes=fluxes, ) if names is not None: rtn.update(name=names) if colors is not None: rtn.update(color=colors) if nobs is not None: rtn.update(nobs=nobs) # Convert targetid to string to prevent rounding errors rtn['targetid'] = [str(s) for s in rtn['targetid']] return HttpResponse(json.dumps(rtn), content_type='application/json')
def cat_sdss(req, ver): import json import numpy as np from astrometry.util.starutil_numpy import degrees_between, radectoxyz, xyztoradec from map.views import sdss_ccds_near from astrometry.util.fits import fits_table, merge_tables tag = 'sdss-cat' ralo = float(req.GET['ralo']) rahi = float(req.GET['rahi']) declo = float(req.GET['declo']) dechi = float(req.GET['dechi']) ver = int(ver) if not ver in catversions[tag]: raise RuntimeError('Invalid version %i for tag %s' % (ver, tag)) rad = degrees_between(ralo, declo, rahi, dechi) / 2. xyz1 = radectoxyz(ralo, declo) xyz2 = radectoxyz(rahi, dechi) xyz = (xyz1 + xyz2) xyz /= np.sqrt(np.sum(xyz**2)) rc, dc = xyztoradec(xyz) rad = rad + np.hypot(10., 14.) / 2. / 60. ccds = sdss_ccds_near(rc[0], dc[0], rad) if ccds is None: print('No SDSS CCDs nearby') return HttpResponse(json.dumps(dict(rd=[])), content_type='application/json') print(len(ccds), 'SDSS CCDs') T = [] for ccd in ccds: # env/BOSS_PHOTOOBJ/301/2073/3/photoObj-002073-3-0088.fits fn = os.path.join( settings.SDSS_BASEDIR, 'env', 'BOSS_PHOTOOBJ', str(ccd.rerun), str(ccd.run), str(ccd.camcol), 'photoObj-%06i-%i-%04i.fits' % (ccd.run, ccd.camcol, ccd.field)) print('Reading', fn) T.append( fits_table( fn, columns= 'ra dec objid mode objc_type objc_flags objc_flags nchild tai expflux devflux psfflux cmodelflux fracdev mjd' .split())) T = merge_tables(T) T.cut((T.dec >= declo) * (T.dec <= dechi)) # FIXME T.cut((T.ra >= ralo) * (T.ra <= rahi)) # primary T.cut(T.mode == 1) types = ['P' if t == 6 else 'C' for t in T.objc_type] fluxes = [ p if t == 6 else c for t, p, c in zip(T.objc_type, T.psfflux, T.cmodelflux) ] return HttpResponse(json.dumps( dict( rd=[(float(o.ra), float(o.dec)) for o in T], sourcetype=types, fluxes=[ dict(u=float(f[0]), g=float(f[1]), r=float(f[2]), i=float(f[3]), z=float(f[4])) for f in fluxes ], )), content_type='application/json')
gridr = np.hypot(gridx, gridy) crpixx,crpixy = (petal.ccdw+1.)/2., (petal.ccdh+1.)/2. crx,cry = petal.gfa_pix_to_focal_mm(crpixx, crpixy) theta = Tpsfunc(gridr) gridu = theta * gridx / gridr gridv = theta * gridy / gridr crr = np.hypot(crx, cry) crd = Tpsfunc(crr) cru = crd * crx / crr crv = crd * cry / crr griddec = gridv gridra = -gridu / np.cos(np.deg2rad(griddec)) starxyz = radectoxyz(gridra, griddec) fieldxy = np.vstack((ccdgridpx, ccdgridpy)).T weights = np.ones(len(gridra)) crdec = crv[0] crra = -cru[0] / np.cos(np.deg2rad(crdec)) ps = 0.2/3600. tan_in = Tan(crra, crdec, crpixx, crpixy, -ps, 0., 0., ps, float(petal.ccdw), float(petal.ccdh)) sip_order = inv_order = 4 sip = fit_sip_wcs_py(starxyz, fieldxy, weights, tan_in, sip_order, inv_order) hdr = fitsio.FITSHDR() sip.add_to_header(hdr) for i,(x,y) in enumerate(zip(petal.gfa.gif_1_pix_x, petal.gfa.gif_1_pix_y)): hdr.add_record(dict(name='GIF1X%i' % (i+1), value=x, comment='Pinhole pixel pos')) hdr.add_record(dict(name='GIF1Y%i' % (i+1), value=y))
def match_radec(ra1, dec1, ra2, dec2, radius_in_deg, notself=False, nearest=False, indexlist=False, count=False): ''' (m1,m2,d12) = match_radec(ra1,dec1, ra2,dec2, radius_in_deg) Cross-matches numpy arrays of RA,Dec points. Behaves like spherematch.pro of IDL ra1,dec1 (and 2): RA,Dec in degrees of points to match. Must be scalars or numpy arrays. radius_in_deg: search radius in degrees. notself: if True, avoids returning 'identity' matches; ASSUMES that ra1,dec1 == ra2,dec2. nearest: if True, returns only the nearest match in (ra2,dec2) for each point in (ra1,dec1). indexlist: returns a list of length len(ra1), containing None or a list of ints of matched points in ra2,dec2. Returns this list. Returns: m1: indices into the "ra1,dec1" arrays of matching points. Numpy array of ints. m2: same, but for "ra2,dec2". d12: distance, in degrees, between the matching points. ''' # Convert to coordinates on the unit sphere xyz1 = radectoxyz(ra1, dec1) #if all(ra1 == ra2) and all(dec1 == dec2): if ra1 is ra2 and dec1 is dec2: xyz2 = xyz1 else: xyz2 = radectoxyz(ra2, dec2) r = deg2dist(radius_in_deg) extra = () if nearest: X = _nearest_func(xyz2, xyz1, r, notself=notself, count=count) if not count: (inds,dists2) = X I = np.flatnonzero(inds >= 0) J = inds[I] d = distsq2deg(dists2[I]) else: #print 'X', X #(inds,dists2,counts) = X J,I,d,counts = X extra = (counts,) print 'I', I.shape, I.dtype print 'J', J.shape, J.dtype print 'counts', counts.shape, counts.dtype else: X = match(xyz1, xyz2, r, notself=notself, indexlist=indexlist) if indexlist: return X (inds,dists) = X dist_in_deg = dist2deg(dists) I,J = inds[:,0], inds[:,1] d = dist_in_deg[:,0] return (I, J, d) + extra
def build_groupcat_sky(parent, linking_length=2, verbose=True, groupcatfile='groupcat.fits', parentfile='parent.fits'): """Build a group catalog based on just RA, Dec coordinates. """ from astropy.table import Column, Table from astrometry.util.starutil_numpy import radectoxyz, xyztoradec, arcsec_between grp, mult, frst, nxt = fof_groups(parent, linking_length=linking_length, verbose=verbose) ngrp = max(grp) + 1 groupid = np.arange(ngrp) groupcat = Table() groupcat.add_column(Column(name='groupid', dtype='i4', length=ngrp, data=groupid)) # unique ID number #groupcat.add_column(Column(name='galaxy', dtype='S1000', length=ngrp)) groupcat.add_column(Column(name='nmembers', dtype='i4', length=ngrp)) groupcat.add_column(Column(name='ra', dtype='f8', length=ngrp)) # average RA groupcat.add_column(Column(name='dec', dtype='f8', length=ngrp)) # average Dec groupcat.add_column(Column(name='width', dtype='f4', length=ngrp)) # maximum separation groupcat.add_column(Column(name='d25max', dtype='f4', length=ngrp)) groupcat.add_column(Column(name='d25min', dtype='f4', length=ngrp)) groupcat.add_column(Column(name='fracmasked', dtype='f4', length=ngrp)) # Add the groupid to the input catalog. outparent = parent.copy() #t0 = time.time() npergrp, _ = np.histogram(grp, bins=len(grp), range=(0, len(grp))) #print('Time to build the histogram = {:.3f} minutes.'.format( (time.time() - t0) / 60 ) ) big = np.where( npergrp > 1 )[0] small = np.where( npergrp == 1 )[0] if len(small) > 0: groupcat['nmembers'][small] = 1 groupcat['groupid'][small] = groupid[small] groupcat['ra'][small] = parent['ra'][grp[small]] groupcat['dec'][small] = parent['dec'][grp[small]] groupcat['d25max'][small] = parent['d25'][grp[small]] groupcat['d25min'][small] = parent['d25'][grp[small]] groupcat['width'][small] = parent['d25'][grp[small]] outparent['groupid'][grp[small]] = groupid[small] for igrp in range(len(big)): jj = frst[big[igrp]] ig = list() ig.append(jj) while (nxt[jj] != -1): ig.append(nxt[jj]) jj = nxt[jj] ig = np.array(ig) ra1, dec1 = parent['ra'][ig].data, parent['dec'][ig].data ra2, dec2 = xyztoradec(np.mean(radectoxyz(ra1, dec1), axis=0)) groupcat['ra'][big[igrp]] = ra2 groupcat['dec'][big[igrp]] = dec2 d25min, d25max = np.min(parent['d25'][ig]), np.max(parent['d25'][ig]) groupcat['d25max'][big[igrp]] = d25max groupcat['d25min'][big[igrp]] = d25min groupcat['nmembers'][big[igrp]] = len(ig) outparent['groupid'][ig] = groupcat['groupid'][big[igrp]] # Get the distance of each object from every other object. #diff = arcsec_between(ra1, dec1, ra2, dec2) / 60 # [arcmin] # group center diff = list() for _ra, _dec in zip(ra1, dec1): diff.append(arcsec_between(ra1, dec1, _ra, _dec) / 60) # [arcmin] #if len(ig) > 2: # import pdb ; pdb.set_trace() diameter = np.hstack(diff).max() groupcat['width'][big[igrp]] = diameter print('Writing {}'.format(groupcatfile)) groupcat.write(groupcatfile, overwrite=True) print('Writing {}'.format(parentfile)) outparent.write(parentfile, overwrite=True) return groupcat, outparent
def arcsec_between(ra1, dec1, ra2, dec2): xyz1 = radectoxyz(ra1, dec1) xyz2 = radectoxyz(ra2, dec2) d2 = np.sum((xyz1 - xyz2)**2, axis=1) rad = np.arccos(1. - d2 / 2.) return 3600. * np.rad2deg(rad)