def match_kdtree_catalog(wcs, catfn): from astrometry.libkd.spherematch import ( tree_open, tree_close, tree_build_radec, tree_free, trees_match, tree_permute, ) from astrometry.libkd import spherematch_c from astrometry.util.starutil_numpy import deg2dist, xyztoradec import numpy as np import sys rc, dc = wcs.get_center() rr = wcs.get_radius() kd = tree_open(catfn) kd2 = tree_build_radec(np.array([rc]), np.array([dc])) r = deg2dist(rr) I, J, nil = trees_match(kd, kd2, r, permuted=False) # HACK # I2,J,d = trees_match(kd, kd2, r) xyz = spherematch_c.kdtree_get_positions(kd, I.astype(np.uint32)) # print 'I', I I2 = tree_permute(kd, I) # print 'I2', I2 tree_free(kd2) tree_close(kd) tra, tdec = xyztoradec(xyz) return tra, tdec, I2
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 tree_search_radec(kd, ra, dec, radius, getdists=False, sortdists=False): ''' ra,dec in degrees radius in degrees ''' dec = np.deg2rad(dec) cosd = np.cos(dec) ra = np.deg2rad(ra) pos = np.array([cosd * np.cos(ra), cosd * np.sin(ra), np.sin(dec)]) rad = deg2dist(radius) return tree_search(kd, pos, rad, getdists=getdists, sortdists=sortdists)
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 match_kdtree_catalog(wcs, catfn): from astrometry.libkd.spherematch import tree_open, tree_close, tree_build_radec, tree_free, trees_match, tree_permute from astrometry.libkd import spherematch_c from astrometry.util.starutil_numpy import deg2dist, xyztoradec import numpy as np import sys rc,dc = wcs.get_center() rr = wcs.get_radius() kd = tree_open(catfn) kd2 = tree_build_radec(np.array([rc]), np.array([dc])) r = deg2dist(rr) I,J,nil = trees_match(kd, kd2, r, permuted=False) del kd2 xyz = kd.get_data(I.astype(np.uint32)) I = kd.permute(I) del kd tra,tdec = xyztoradec(xyz) return tra, tdec, I
def match_kdtree_catalog(wcs, catfn): from astrometry.libkd.spherematch import tree_open, tree_close, tree_build_radec, tree_free, trees_match, tree_permute from astrometry.libkd import spherematch_c from astrometry.util.starutil_numpy import deg2dist, xyztoradec import numpy as np import sys rc, dc = wcs.get_center() rr = wcs.get_radius() kd = tree_open(catfn) kd2 = tree_build_radec(np.array([rc]), np.array([dc])) r = deg2dist(rr) I, J, nil = trees_match(kd, kd2, r, permuted=False) # HACK #I2,J,d = trees_match(kd, kd2, r) xyz = spherematch_c.kdtree_get_positions(kd, I.astype(np.uint32)) #print 'I', I I2 = tree_permute(kd, I) #print 'I2', I2 tree_free(kd2) tree_close(kd) tra, tdec = xyztoradec(xyz) return tra, tdec, I2
def plot_wcs_outline(wcsfn, plotfn, W=256, H=256, width=36, zoom=True, zoomwidth=3.6, grid=10, hd=False, hd_labels=False, tycho2=False): anutil.log_init(3) #anutil.log_set_level(3) wcs = anutil.Tan(wcsfn, 0) ra, dec = wcs.radec_center() plot = ps.Plotstuff(outformat='png', size=(W, H), rdw=(ra, dec, width)) plot.linestep = 1. plot.color = 'verydarkblue' plot.plot('fill') plot.fontsize = 12 #plot.color = 'gray' # dark gray plot.rgb = (0.3, 0.3, 0.3) if grid is not None: plot.plot_grid(*([grid] * 4)) plot.rgb = (0.4, 0.6, 0.4) ann = plot.annotations ann.NGC = ann.bright = ann.HD = 0 ann.constellations = 1 ann.constellation_labels = 1 ann.constellation_labels_long = 1 plot.plot('annotations') plot.stroke() ann.constellation_labels = 0 ann.constellation_labels_long = 0 ann.constellation_lines = 0 ann.constellation_markers = 1 plot.markersize = 3 plot.rgb = (0.4, 0.6, 0.4) plot.plot('annotations') plot.fill() ann.constellation_markers = 0 ann.bright_labels = False ann.bright = True plot.markersize = 2 if zoom >= 2: ann.bright_labels = True plot.plot('annotations') ann.bright = False ann.bright_labels = False plot.fill() if hd: ann.HD = True ann.HD_labels = hd_labels ps.plot_annotations_set_hd_catalog(ann, settings.HENRY_DRAPER_CAT) plot.plot('annotations') plot.stroke() ann.HD = False ann.HD_labels = False if tycho2 and settings.TYCHO2_KD: from astrometry.libkd.spherematch import tree_open, tree_close, tree_build_radec, tree_free, trees_match from astrometry.libkd import spherematch_c from astrometry.util.starutil_numpy import deg2dist, xyztoradec import numpy as np import sys kd = tree_open(settings.TYCHO2_KD) # this is a bit silly: build a tree with a single point, then do match() kd2 = tree_build_radec(np.array([ra]), np.array([dec])) r = deg2dist(width * np.sqrt(2.) / 2.) #r = deg2dist(wcs.radius()) I, nil, nil = trees_match(kd, kd2, r, permuted=False) del nil #print 'Matched', len(I) xyz = spherematch_c.kdtree_get_positions(kd, I) del I tree_free(kd2) tree_close(kd) #print >>sys.stderr, 'Got', xyz.shape, xyz tra, tdec = xyztoradec(xyz) #print >>sys.stderr, 'RA,Dec', ra,dec plot.apply_settings() for r, d in zip(tra, tdec): plot.marker_radec(r, d) plot.fill() ann.NGC = 1 plot.plot('annotations') ann.NGC = 0 plot.color = 'white' plot.lw = 3 out = plot.outline out.wcs_file = wcsfn plot.plot('outline') if zoom: # MAGIC width, height are arbitrary zoomwcs = anutil.anwcs_create_box(ra, dec, zoomwidth, 1000, 1000) out.wcs = zoomwcs plot.lw = 1 plot.dashed(3) plot.plot('outline') plot.write(plotfn)
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
if not plot.wcs.is_inside(T.ra[i], T.dec[i]): continue ann.add_target(T.ra[i], T.dec[i], 'Abell %i' % T.aco[i]) if opt.t2cat: from astrometry.libkd.spherematch import tree_open, tree_close, tree_build_radec, tree_free, trees_match from astrometry.libkd import spherematch_c from astrometry.util.starutil_numpy import deg2dist, xyztoradec import numpy as np import sys wcs = plot.wcs rc,dc = wcs.get_center() rr = wcs.get_radius() kd = tree_open(opt.t2cat) kd2 = tree_build_radec(np.array([rc]), np.array([dc])) r = deg2dist(rr) I,J,d = trees_match(kd, kd2, r, permuted=False) # HACK I2,J,d = trees_match(kd, kd2, r) xyz = spherematch_c.kdtree_get_positions(kd, I) tree_free(kd2) tree_close(kd) tra,tdec = xyztoradec(xyz) T = fits_table(opt.t2cat, hdu=6) for r,d,t1,t2,t3 in zip(tra,tdec, T.tyc1[I2], T.tyc2[I2], T.tyc3[I2]): if not plot.wcs.is_inside(r, d): continue ann.add_target(r, d, 'Tycho-2 %i-%i-%i' % (t1,t2,t3)) plot.color = opt.textcolor
gaia_kd = tree_open(gaia_kd_fn) print('Read Gaia KD') print('Matching...') rad = 2. / 3600. print('GALAH RA range:', galah.raj2000.min(), galah.raj2000.max()) print('GALAH Dec range:', galah.dej2000.min(), galah.dej2000.max()) xyz = radectoxyz(galah.raj2000, galah.dej2000) print('xyz shape', xyz.shape) N, three = xyz.shape J = np.empty(N, np.int32) J[:] = -1 D = np.zeros(N, np.float32) dist = deg2dist(rad) print('unit-sphere distance:', dist) for i in range(N): j, d = gaia_kd.search(xyz[i, :], dist, 1, 1) #print('matched:', j) if len(j) == 0: continue J[i] = j[0] D[i] = d[0] if i % 1000 == 0: print(i) I, = np.nonzero(J > -1) J = J[I] # print(len(I), 'matches')
def plot_wcs_outline(wcsfn, plotfn, W=256, H=256, width=36, zoom=True, zoomwidth=3.6, grid=10, hd=False, hd_labels=False, tycho2=False): anutil.log_init(3) #anutil.log_set_level(3) wcs = anutil.Tan(wcsfn, 0) ra,dec = wcs.radec_center() plot = ps.Plotstuff(outformat='png', size=(W, H), rdw=(ra,dec,width)) plot.linestep = 1. plot.color = 'verydarkblue' plot.plot('fill') plot.fontsize = 12 #plot.color = 'gray' # dark gray plot.rgb = (0.3,0.3,0.3) if grid is not None: plot.plot_grid(*([grid]*4)) plot.rgb = (0.4, 0.6, 0.4) ann = plot.annotations ann.NGC = ann.bright = ann.HD = 0 ann.constellations = 1 ann.constellation_labels = 1 ann.constellation_labels_long = 1 plot.plot('annotations') plot.stroke() ann.constellation_labels = 0 ann.constellation_labels_long = 0 ann.constellation_lines = 0 ann.constellation_markers = 1 plot.markersize = 3 plot.rgb = (0.4, 0.6, 0.4) plot.plot('annotations') plot.fill() ann.constellation_markers = 0 ann.bright_labels = False ann.bright = True plot.markersize = 2 if zoom >= 2: ann.bright_labels = True plot.plot('annotations') ann.bright = False ann.bright_labels = False plot.fill() if hd: ann.HD = True ann.HD_labels = hd_labels ps.plot_annotations_set_hd_catalog(ann, settings.HENRY_DRAPER_CAT) plot.plot('annotations') plot.stroke() ann.HD = False ann.HD_labels = False if tycho2: from astrometry.libkd.spherematch import tree_open, tree_close, tree_build_radec, tree_free, trees_match from astrometry.libkd import spherematch_c from astrometry.util.starutil_numpy import deg2dist, xyztoradec import numpy as np import sys kd = tree_open(settings.TYCHO2_KD) # this is a bit silly: build a tree with a single point, then do match() kd2 = tree_build_radec(np.array([ra]), np.array([dec])) r = deg2dist(width * np.sqrt(2.) / 2.) #r = deg2dist(wcs.radius()) I,J,d = trees_match(kd, kd2, r, permuted=False) del J del d #print 'Matched', len(I) xyz = spherematch_c.kdtree_get_positions(kd, I) del I tree_free(kd2) tree_close(kd) #print >>sys.stderr, 'Got', xyz.shape, xyz tra,tdec = xyztoradec(xyz) #print >>sys.stderr, 'RA,Dec', ra,dec plot.apply_settings() for r,d in zip(tra,tdec): plot.marker_radec(r,d) plot.fill() ann.NGC = 1 plot.plot('annotations') ann.NGC = 0 plot.color = 'white' plot.lw = 3 out = plot.outline out.wcs_file = wcsfn plot.plot('outline') if zoom: # MAGIC width, height are arbitrary zoomwcs = anutil.anwcs_create_box(ra, dec, zoomwidth, 1000,1000) out.wcs = zoomwcs plot.lw = 1 plot.dashed(3) plot.plot('outline') plot.write(plotfn)
galah = fits_table('GALAH_DR2_catalog.fits') print(len(galah), 'GALAH') galah_kd = tree_build_radec(galah.raj2000, galah.dej2000) gaia_kd_fn = '/global/cscratch1/sd/dstn/gaia-all.kd.fits' gaia_kd = tree_open(gaia_kd_fn) print('Read Gaia KD') print('Matching...') rad = 2. / 3600. #I,J,d = trees_match(galah_kd, gaia_kd, deg2dist(rad), nearest=True) ### NOTE, this does not seem to be working correctly!! I, J, D = trees_match(galah_kd, gaia_kd, deg2dist(rad)) print(len(I), 'matches') # ugh, nearest bestdist = np.empty(len(galah), np.float32) bestdist[:] = 1000. bestmatch = np.empty(len(galah), np.int32) bestmatch[:] = -1 for i, j, d in zip(I, J, D): if d < bestdist[i]: bestdist[i] = d bestmatch[i] = j I, = np.nonzero(bestmatch > -1) J = bestmatch[I]
def main(): os.environ['DESIMODEL'] = '/global/homes/d/dstn/desimodel-data' global hw global stuck_x global stuck_y global stuck_loc global starkd hw = load_hardware() # From fiberassign/stucksky.py: find X,Y positions of stuck positioners. # (grab the hw dictionaries once -- these are python wrappers over C++ so not simple accessors) state = hw.state devtype = hw.loc_device_type stuck_loc = [ loc for loc in hw.locations if (((state[loc] & (FIBER_STATE_STUCK | FIBER_STATE_BROKEN) ) == FIBER_STATE_STUCK) and (devtype[loc] == 'POS')) ] print(len(stuck_loc), 'stuck positioners') theta_pos = hw.loc_theta_pos theta_off = hw.loc_theta_offset phi_pos = hw.loc_phi_pos phi_off = hw.loc_phi_offset stuck_theta = [theta_pos[loc] + theta_off[loc] for loc in stuck_loc] stuck_phi = [phi_pos[loc] + phi_off[loc] for loc in stuck_loc] curved_mm = hw.loc_pos_curved_mm theta_arm = hw.loc_theta_arm phi_arm = hw.loc_phi_arm theta_min = hw.loc_theta_min theta_max = hw.loc_theta_max phi_min = hw.loc_phi_min phi_max = hw.loc_phi_max # Convert positioner angle orientations to curved focal surface X / Y (not CS5) # Note: we could add some methods to the python bindings to vectorize this or make it less clunky... stuck_x = np.zeros(len(stuck_loc)) stuck_y = np.zeros(len(stuck_loc)) for iloc, (loc, theta, phi) in enumerate(zip(stuck_loc, stuck_theta, stuck_phi)): loc_x, loc_y = hw.thetaphi_to_xy(curved_mm[loc], theta, phi, theta_arm[loc], phi_arm[loc], theta_off[loc], phi_off[loc], theta_min[loc], phi_min[loc], theta_max[loc], phi_max[loc], True) stuck_x[iloc] = loc_x stuck_y[iloc] = loc_y tiles = Table.read( '/global/cfs/cdirs/desi/target/surveyops/ops/tiles-main.ecsv') print(len(tiles), 'tiles') # Deduplicate tiles with same RA,Dec center tilera = tiles['RA'] tiledec = tiles['DEC'] tileid = tiles['TILEID'] rdtile = {} tilemap = {} for tid, r, d in zip(tileid, tilera, tiledec): key = r, d if key in rdtile: # already seen a tile with this RA,Dec; point to it tilemap[tid] = rdtile[key] else: rdtile[key] = tid del rdtile tnow = datetime.now() tile_obstime = tnow.isoformat(timespec='seconds') mjd = Time(tnow).mjd stars = fits_table( '/global/cfs/cdirs/cosmo/data/legacysurvey/dr9/masking/gaia-mask-dr9.fits.gz' ) print(len(stars), 'stars for masking') print('Moving to MJD', mjd) ra, dec = radec_at_mjd(stars.ra, stars.dec, stars.ref_epoch.astype(float), stars.pmra, stars.pmdec, stars.parallax, mjd) assert (np.all(np.isfinite(ra))) assert (np.all(np.isfinite(dec))) stars.ra = ra stars.dec = dec print('Building kd-tree...') starkd = tree_build_radec(stars.ra, stars.dec) match_radius = deg2dist(30. / 3600.) stuck_loc = np.array(stuck_loc) allresults = {} mp = multiproc(32) print('Building arg lists...') args = [] for tid, tile_ra, tile_dec, tile_obsha in zip(tileid, tilera, tiledec, tiles['DESIGNHA']): # skip duplicate tiles if tid in tilemap: continue # "fieldrot" tile_theta = field_rotation_angle(tile_ra, tile_dec, mjd) args.append((tid, tile_ra, tile_dec, tile_obstime, tile_theta, tile_obsha, match_radius)) print('Matching', len(args), 'unique tile RA,Decs in parallel...') res = mp.map(_match_tile, args) print('Organizing results...') T = fits_table() T.tileid = [] T.loc = [] T.petal = [] T.device = [] T.fiber = [] T.pos_ra = [] T.pos_dec = [] T.star_ra = [] T.star_dec = [] T.dist_arcsec = [] T.mask_mag = [] loc_to_petal = hw.loc_petal loc_to_device = hw.loc_device loc_to_fiber = hw.loc_fiber for vals in res: if vals is None: continue tileid, I, pos_ra, pos_dec, pos_loc, dists = vals T.tileid.extend([tileid] * len(I)) T.loc.extend(pos_loc) for loc in pos_loc: T.petal.append(loc_to_petal[loc]) T.device.append(loc_to_device[loc]) T.fiber.append(loc_to_fiber[loc]) T.pos_ra.extend(pos_ra) T.pos_dec.extend(pos_dec) T.star_ra.extend(stars.ra[I]) T.star_dec.extend(stars.dec[I]) T.dist_arcsec.extend(dists) T.mask_mag.extend(stars.mask_mag[I]) T.to_np_arrays() T.writeto('stuck-on-stars.fits')
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