# This file is part of libkd. # Licensed under a 3-clause BSD style license - see LICENSE from astrometry.libkd import spherematch import numpy as np from time import time N1 = 1000 N2 = 1000 D = 2 r = 0.02 x1 = np.random.rand(N1, D) x2 = np.random.rand(N2, D) t0 = time() (inds,dists) = spherematch.match(x1, x2, r) dt = time() - t0 print 'spherematch.match: found', len(inds), 'pairs in', int(dt*1000.), 'ms' order = np.argsort(inds[:,0]*N2 + inds[:,1]) inds = inds[order] dists = dists[order] t0 = time() pairs = [] truedists = [] for i in range(N1): pt1 = x1[i,:] d2s = np.sum((x2 - pt1)**2, axis=1) good = np.where(d2s <= r**2)[0]
def whynot(field, index, qidx, wcs): # find index stars in the field. (ra,dec) = wcs.get_radec_center() rad = arcsec2deg(wcs.get_pixel_scale() * hypot(wcs.get_width(), wcs.get_height())) (xyz, radec, starinds) = index_search_stars(index, ra, dec, rad) print('xyz', xyz.shape) print('radec', radec.shape) print('starinds', starinds.shape) istars = tabledata() istars.xyz = xyz istars.radec = radec istars.starind = starinds W,H = wcs.get_width(), wcs.get_height() pix = array([wcs.radec2pixelxy(r, d) for (r,d) in radec]) print('pix', pix.shape) # within image bounds I = (pix[:,0] > 0) * (pix[:,0] < W) * (pix[:,1] > 0) * (pix[:,1] < H) # find nearby pairs of stars... nsigma = 3 pixeljitter = 1 sigma = hypot(index.index_jitter / wcs.get_pixel_scale(), pixeljitter) rad = nsigma * sigma fieldxy = vstack((field.x, field.y)).T print('field', fieldxy.shape) (cinds, cdists) = match(pix, fieldxy, rad) print('matches:', cinds.shape) #print cdists.shape corrs = tabledata() corrs.dist = cdists[:,0] corrs.star = starinds[cinds[:,0]] corrs.field = cinds[:,1] allquads = [] # All quads built from stars in the field... for starind in starinds[I]: #print qidx, starind quads = qidxfile_get_quad_list(qidxfile_addr(qidx), starind) #print 'quads:', quads.shape allquads.append(quads) allquads = unique(hstack(allquads)) print('%i unique quads touch stars in the field' % len(allquads)) ''' "quads" object: all quads that touch index stars in this field. .quad : (int) quad index .stars : (DQ x int) star indices .starsinfield: (DQ x bool) stars in field ''' quads = tabledata() quads.quad = allquads qstars = quadfile_get_stars_for_quads(quadfile_addr(index), quads.quad) print('stars in quads:', qstars.shape) #print qstars quads.stars = qstars quads.starsinfield = array([[s in starinds[I] for s in q] for q in qstars]) #print quads.starsinfield allin = quads.starsinfield.min(axis=1) #print quads.allin quads.allin = allin quadsin = quads[allin] print('%i quads use stars that are in the field' % (len(quadsin))) print('stars:', starinds) c_s2f = {} for c in corrs: #i in range(len(corrs)): #print 'corr', c if not c.star in c_s2f: c_s2f[c.star] = [] c_s2f[c.star].append(c.field) #c_s2f[corrs.star[i]] #print c_s2f # [[[213], [35], [265], [63]], [[186]], [[]], [[11], [19]], ...] # For each quad, for each star in the quad, the list of field stars corresponding. fq = [] for q in quadsin.stars: fq1 = [] for s in q: if s in c_s2f: fq1.append(c_s2f[s]) else: fq1.append([]) fq.append(fq1) #print fq # For each quad, the list of sets of field stars corresponding. # [[[213, 35, 265, 63]], [], [], fq2 = [] for q in fq: #print 'q:', q #ac = allcombinations([q[0]], q[1:]) #ac = allcombinations([[]], q) #print '--> ac:', ac fq2.append(allcombinations([[]], q)) #print fq2 quadsin.fq2 = fq2 hasf = array([len(x) > 0 for x in quadsin.fq2]) #print 'hasf:', hasf okquads = quadsin[hasf] #forder = argsort([max(x) for x in okquads.fq2]) #okquads = okquads[forder] print('ok quads:', len(okquads)) print('quad nums:', okquads.quad) print('stars:', okquads.stars) print('field stars:', okquads.fq2) #qmatches = table_data() #fqs = [] #qs = [] #for okq,fq in zip(okquads, okquads.fq2): # fqs = fqs + fq # qs.append(okq) #qmatches.fieldquad = fqs qmatches = [] for okq,fqs in zip(okquads, okquads.fq2): for fq in fqs: #print 'field stars', fq #print 'quad:', okq.quad qmatches.append((fq, okq)) forder = argsort([max(fq) for fq,okq in qmatches]) #print 'forder', forder print() print('Quads in the order they will be found') for i in forder: fq,okq = qmatches[i] print() print('object', max(fq)) print('field stars', fq) print('quad:', okq.quad) # Index stars, by sweep (or "r" mag)... # --which quads are they part of #skdt = starkd_addr(index) istars.sweep = array([startree_get_sweep(index.starkd, si) for si in istars.starind]) mystars = istars[I] order = argsort(mystars.sweep) print() print() print('Index stars:', end=' ') for ms in mystars[order]: print() print('Star', ms.starind, 'sweep', ms.sweep, 'radec', ms.radec) print('Field star(s) nearby:', len(c_s2f.get(ms.starind, []))) for c in corrs[corrs.star == ms.starind]: print(' field star', c.field, 'dist', c.dist, 'pixels') myquads = quads[array([(ms.starind in q.stars) for q in quads])] print('In %i quads' % len(myquads)) for q in myquads: print(' quad %i: %i stars in the field' % (q.quad, sum(q.starsinfield))) if q.allin: print(' stars:', q.stars) print(' correspondences for stars:', [c_s2f.get(s, None) for s in q.stars])
def plotshift(ixy, rxy, dcell=50, ncells=18, outfn=None, W=None, H=None, hist=False, nhistbins=21): #histbinsize=None): # correspondences we could have hit... radius = dcell * sqrt(2.) #print 'ixy', ixy.shape #print 'rxy', rxy.shape assert ((len(rxy) == 0) or (rxy.shape[1] == 2)) assert ((len(ixy) == 0) or (ixy.shape[1] == 2)) ix = ixy[:, 0] iy = ixy[:, 1] if W is None: W = max(ix) if H is None: H = max(iy) if len(rxy): keep = (rxy[:, 0] > -dcell) * (rxy[:, 0] < W + dcell) * ( rxy[:, 1] > -dcell) * (rxy[:, 1] < H + dcell) rxy = rxy[keep] #print 'Cut to %i ref sources in range' % len(rxy) cellsize = sqrt(W * H / ncells) nw = int(round(W / cellsize)) nh = int(round(H / cellsize)) #print 'Grid cell size', cellsize #print 'N cells', nw, 'x', nh edgesx = linspace(0, W, nw + 1) edgesy = linspace(0, H, nh + 1) #print 'Edges:' #print ' x:', edgesx #print ' y:', edgesy if len(rxy) == 0: binx = array([]) biny = array([]) else: binx = digitize(rxy[:, 0], edgesx) biny = digitize(rxy[:, 1], edgesy) binx = clip(binx - 1, 0, nw - 1) biny = clip(biny - 1, 0, nh - 1) bin = biny * nw + binx clf() for i in range(nh): for j in range(nw): thisbin = i * nw + j R = (bin == thisbin) #print 'cell %i, %i' % (j, i) #print '%i ref sources' % sum(R) matchdx = [] if sum(R) > 0: (inds, dists) = spherematch.match(rxy[R, :], ixy, radius) #print 'Found %i matches within %g pixels' % (len(dists), radius) ri = inds[:, 0] # un-cut ref inds... ri = (flatnonzero(R))[ri] ii = inds[:, 1] matchx = rxy[ri, 0] matchy = rxy[ri, 1] matchdx = ix[ii] - matchx matchdy = iy[ii] - matchy #print 'All matches:' #for dx,dy in zip(matchdx,matchdy): # print ' %.1f, %.1f' % (dx,dy) ok = (matchdx >= -dcell) * (matchdx <= dcell) * ( matchdy >= -dcell) * (matchdy <= dcell) matchdx = matchdx[ok] matchdy = matchdy[ok] #print 'Cut to %i within %g x %g square' % (sum(ok), dcell*2, dcell*2) #print 'Cut matches:' #for dx,dy in zip(matchdx,matchdy): # print ' %.1f, %.1f' % (dx,dy) # Subplot places plots left-to-right, TOP-to-BOTTOM. subplot(nh, nw, 1 + ((nh - i - 1) * nw + j)) if len(matchdx) > 0: #plot(matchdx, matchdy, 'ro', mec='r', mfc='r', ms=5, alpha=0.2) #plot(matchdx, matchdy, 'ro', mec='r', mfc='none', ms=5, alpha=0.2) if hist: #if histbinsize is None: # histbinsize = dcell / 10. edges = linspace(-dcell, dcell, nhistbins + 1) (H, xe, ye) = histogram2d(matchdx, matchdy, bins=(edges, edges)) imshow(H.T, extent=(min(xe), max(xe), min(ye), max(ye)), aspect='auto', origin='lower', interpolation='nearest') text(dcell, dcell, '%i' % H.max(), color='y', horizontalalignment='right', verticalalignment='top') else: plot(matchdx, matchdy, 'r.', alpha=0.3) if hist: axhline(0, color='b', alpha=0.8) axvline(0, color='b', alpha=0.8) else: axhline(0, color='k', alpha=0.5) axvline(0, color='k', alpha=0.5) if i == 0 and j == 0: xticks([-dcell, 0, dcell]) yticks([-dcell, 0, dcell]) else: xticks([], []) yticks([], []) axis('scaled') axis([-dcell, dcell, -dcell, dcell]) if outfn is not None: #print 'Saving', outfn savefig(outfn)
def showSipSolutions(srcs, wcs0, andDir, x0, y0, W, H, filterName, plotPrefix): ''' srcs: afw Catalog of sources wcs0: original WCS andDir: astrometry_net_data directory ''' imargs = dict(imageSize=(W, H), filterName=filterName, x0=x0, y0=y0) # Set up astrometry_net_data os.environ['ASTROMETRY_NET_DATA_DIR'] = andDir andConfig = measAstrom.AstrometryNetDataConfig() fn = os.path.join(andDir, 'andConfig.py') andConfig.load(fn) # Set up meas_astrom conf = measAstrom.ANetBasicAstrometryConfig(sipOrder=4) ast = measAstrom.ANetBasicAstrometryTask(conf, andConfig, logLevel=Log.DEBUG) # What reference sources are in the original WCS refs = ast.getReferenceSourcesForWcs(wcs0, **imargs) print('Got', len(refs), 'reference objects for initial WCS') # How does a straight TAN solution look? conf2 = measAstrom.ANetBasicAstrometryConfig(sipOrder=4, calculateSip=False) ast2 = measAstrom.ANetBasicAstrometryTask(conf2, andConfig, logLevel=Log.DEBUG) solve = ast2.determineWcs2(srcs, **imargs) tanwcs = solve.tanWcs # How about if we fit a SIP WCS using the *original* WCS? wcs2 = ast.getSipWcsFromWcs(wcs0, (W, H), x0=x0, y0=y0) # (We determineWcs() for a SIP solution below...) # Make some plots in pixel space by pushing ref sources through WCSes rx0, ry0 = [], [] rx2, ry2 = [], [] rx3, ry3 = [], [] for src in refs: xy = wcs0.skyToPixel(src.getCoord()) rx0.append(xy[0]) ry0.append(xy[1]) xy = tanwcs.skyToPixel(src.getCoord()) rx2.append(xy[0]) ry2.append(xy[1]) xy = wcs2.skyToPixel(src.getCoord()) rx3.append(xy[0]) ry3.append(xy[1]) rx0 = np.array(rx0) ry0 = np.array(ry0) rx2 = np.array(rx2) ry2 = np.array(ry2) rx3 = np.array(rx3) ry3 = np.array(ry3) x = np.array([src.getX() for src in srcs]) y = np.array([src.getY() for src in srcs]) from astrometry.libkd.spherematch import match from astrometry.util.plotutils import plothist, PlotSequence ps = PlotSequence(plotPrefix) # Match up various sources... R = 2. II, d = match(np.vstack((x, y)).T, np.vstack((rx0, ry0)).T, R) I = II[:, 0] J = II[:, 1] pa = dict(range=((-R, R), (-R, R))) plt.clf() plothist(x[I] - rx0[J], y[I] - ry0[J], 200, **pa) plt.title('Source positions - Reference positions (initial WCS)') plt.xlabel('delta-X (pixels)') plt.ylabel('delta-Y (pixels)') ps.savefig() II, d = match(np.vstack((x, y)).T, np.vstack((rx2, ry2)).T, R) I = II[:, 0] J = II[:, 1] plt.clf() plothist(x[I] - rx2[J], y[I] - ry2[J], 200, **pa) plt.title('Source positions - Reference positions (TAN WCS)') plt.xlabel('delta-X (pixels)') plt.ylabel('delta-Y (pixels)') ps.savefig() II, d = match(np.vstack((x, y)).T, np.vstack((rx3, ry3)).T, R) I = II[:, 0] J = II[:, 1] plt.clf() plothist(x[I] - rx3[J], y[I] - ry3[J], 200, **pa) plt.title('Source positions - Reference positions (SIP WCS #2)') plt.xlabel('delta-X (pixels)') plt.ylabel('delta-Y (pixels)') ps.savefig() II, d = match(np.vstack((rx0, ry0)).T, np.vstack((rx3, ry3)).T, R) I = II[:, 0] J = II[:, 1] plt.clf() plothist(rx0[I] - rx3[J], ry0[I] - ry3[J], 200, **pa) plt.title( 'Reference positions (Original WCS) - Reference positions (SIP WCS #2)' ) plt.xlabel('delta-X (pixels)') plt.ylabel('delta-Y (pixels)') ps.savefig() matches = solve.tanMatches msx, msy = [], [] mrx, mry = [], [] for m in matches: ref, src = m.first, m.second xy = tanwcs.skyToPixel(ref.getCoord()) mrx.append(xy[0]) mry.append(xy[1]) msx.append(src.getX()) msy.append(src.getY()) plt.clf() plt.plot(x, y, 'r.') plt.plot(msx, msy, 'o', mec='r') plt.plot(rx0, ry0, 'g.') plt.plot(mrx, mry, 'gx') plt.title('TAN matches') ps.savefig() # Get SIP solution (4th order) solve = ast.determineWcs2(srcs, **imargs) wcs1 = solve.sipWcs matches = solve.sipMatches msx, msy = [], [] mrx, mry = [], [] for m in matches: ref, src = m.first, m.second xy = tanwcs.skyToPixel(ref.getCoord()) mrx.append(xy[0]) mry.append(xy[1]) msx.append(src.getX()) msy.append(src.getY()) plt.clf() plt.plot(x, y, 'r.') plt.plot(msx, msy, 'o', mec='r') plt.plot(rx0, ry0, 'g.') plt.plot(mrx, mry, 'gx') plt.title('SIP matches') ps.savefig() rx1, ry1 = [], [] for src in refs: xy = wcs1.skyToPixel(src.getCoord()) rx1.append(xy[0]) ry1.append(xy[1]) rx1 = np.array(rx1) ry1 = np.array(ry1) plt.clf() plt.plot(x, y, 'o', mec='r', mfc='none') plt.plot(rx0, ry0, 'bx') plt.plot(rx1, ry1, 'g+') plt.plot(rx2, ry2, 'mx') plt.plot(rx3, ry3, 'r+') ps.savefig() plt.axis([x0, x0 + 500, y0, y0 + 500]) ps.savefig() II, d = match(np.vstack((x, y)).T, np.vstack((rx1, ry1)).T, R) I = II[:, 0] J = II[:, 1] plt.clf() plothist(x[I] - rx1[J], y[I] - ry1[J], 200, **pa) plt.title('Source positions - Reference positions (SIP WCS)') plt.xlabel('delta-X (pixels)') plt.ylabel('delta-Y (pixels)') ps.savefig()
def OLD_radec_to_sdss_rcf(ra, dec, spherematch=True, radius=0, tablefn=None, contains=False): # This file is generated by merging the files "dr7_e.fits", "dr7_g.fits", and "dr7_a.fits", # whose construction is described in http://trac.astrometry.net/browser/trunk/projects/sdss-tests/README # (and in comments below that I didn't notice before writing this) if tablefn is None: tablefn = find_data_file('dr7fields.fits') sdss = table_fields(tablefn) if sdss is None: print('Failed to read table of SDSS fields from file', tablefn) raise Exception('Failed to read table of SDSS fields from file: "' + str(tablefn) + '"') sdssxyz = radectoxyz(sdss.ra, sdss.dec) ## HACK - magic 13x9 arcmin. if radius == 0: radius = sqrt(13.**2 + 9.**2)/2. radius2 = arcmin2distsq(radius) if not spherematch: rcfs = [] for r,d in broadcast(ra,dec): xyz = radectoxyz(r,d) dist2s = sum((xyz - sdssxyz)**2, axis=1) I = flatnonzero(dist2s < radius2) if False: print('I:', I) print('fields:', sdss[I].run, sdss[I].field, sdss[I].camcol) print('RA', sdss[I].ra) print('Dec', sdss[I].dec) rcfs.append(zip(sdss[I].run, sdss[I].camcol, sdss[I].field, sdss[I].ra, sdss[I].dec)) else: from astrometry.libkd import spherematch rds = array([x for x in broadcast(ra,dec)]) xyz = radectoxyz(rds[:,0], rds[:,1]).astype(double) (inds,dists) = spherematch.match(xyz, sdssxyz, sqrt(radius2)) #print 'found %i matches' % len(inds) if len(inds) == 0: return [] #print 'inds:', inds.shape I = np.argsort(dists[:,0]) #print 'dists:', dists.shape inds = inds[I,:] rcfs = [[] for i in range(len(rds))] cols = sdss.columns() gotem = False if contains: if 'ramin' in cols and 'ramax' in cols and 'decmin' in cols and 'decmax' in cols: gotem = True for i,j in inds: (r,d) = rds[i] if r >= sdss.ramin[j] and r <= sdss.ramax[j] and d >= sdss.decmin[j] and d <= sdss.decmax[j]: rcfs[i].append((sdss.run[j], sdss.camcol[j], sdss.field[j], sdss.ra[j], sdss.dec[j])) print('%i fields contain the first query RA,Dec' % len(rcfs[0])) else: print('you requested fields *containing* the query RA,Dec,') print('but the fields list file \"%s\" doesn\'t contain RAMIN,RAMAX,DECMIN, and DECMAX columns' % tablefn) if not gotem: for i,j in inds: rcfs[i].append((sdss.run[j], sdss.camcol[j], sdss.field[j], sdss.ra[j], sdss.dec[j])) if isscalar(ra) and isscalar(dec): return rcfs[0] return rcfs
def OLD_radec_to_sdss_rcf(ra, dec, spherematch=True, radius=0, tablefn=None, contains=False): # This file is generated by merging the files "dr7_e.fits", "dr7_g.fits", and "dr7_a.fits", # whose construction is described in http://trac.astrometry.net/browser/trunk/projects/sdss-tests/README # (and in comments below that I didn't notice before writing this) if tablefn is None: tablefn = find_data_file('dr7fields.fits') sdss = table_fields(tablefn) if sdss is None: print('Failed to read table of SDSS fields from file', tablefn) raise Exception('Failed to read table of SDSS fields from file: "' + str(tablefn) + '"') sdssxyz = radectoxyz(sdss.ra, sdss.dec) ## HACK - magic 13x9 arcmin. if radius == 0: radius = sqrt(13.**2 + 9.**2) / 2. radius2 = arcmin2distsq(radius) if not spherematch: rcfs = [] for r, d in broadcast(ra, dec): xyz = radectoxyz(r, d) dist2s = sum((xyz - sdssxyz)**2, axis=1) I = flatnonzero(dist2s < radius2) if False: print('I:', I) print('fields:', sdss[I].run, sdss[I].field, sdss[I].camcol) print('RA', sdss[I].ra) print('Dec', sdss[I].dec) rcfs.append( zip(sdss[I].run, sdss[I].camcol, sdss[I].field, sdss[I].ra, sdss[I].dec)) else: from astrometry.libkd import spherematch rds = array([x for x in broadcast(ra, dec)]) xyz = radectoxyz(rds[:, 0], rds[:, 1]).astype(double) (inds, dists) = spherematch.match(xyz, sdssxyz, sqrt(radius2)) #print 'found %i matches' % len(inds) if len(inds) == 0: return [] #print 'inds:', inds.shape I = np.argsort(dists[:, 0]) #print 'dists:', dists.shape inds = inds[I, :] rcfs = [[] for i in range(len(rds))] cols = sdss.columns() gotem = False if contains: if 'ramin' in cols and 'ramax' in cols and 'decmin' in cols and 'decmax' in cols: gotem = True for i, j in inds: (r, d) = rds[i] if r >= sdss.ramin[j] and r <= sdss.ramax[ j] and d >= sdss.decmin[j] and d <= sdss.decmax[j]: rcfs[i].append( (sdss.run[j], sdss.camcol[j], sdss.field[j], sdss.ra[j], sdss.dec[j])) print('%i fields contain the first query RA,Dec' % len(rcfs[0])) else: print('you requested fields *containing* the query RA,Dec,') print( 'but the fields list file \"%s\" doesn\'t contain RAMIN,RAMAX,DECMIN, and DECMAX columns' % tablefn) if not gotem: for i, j in inds: rcfs[i].append((sdss.run[j], sdss.camcol[j], sdss.field[j], sdss.ra[j], sdss.dec[j])) if isscalar(ra) and isscalar(dec): return rcfs[0] return rcfs
from pylab import * from numpy import * import os if __name__ == '__main__': parser = OptionParser() parser.add_option('-p', '--prefix', dest='prefix', help='Prefix for output plot names') parser.add_option('-r', '--range', dest='range', type='float', help='Set search radius range (in arcsec) of stars-1 plot, default 15') parser.set_defaults(prefix='', range=15.) opt,args = parser.parse_args() if 'plots' in args: # DEBUG! cat = fits_table('cat2.fits') xyz = radectoxyz(cat.ra, cat.dec) R = 15. inds,dists = match(xyz, xyz, deg2rad(R/3600.)) notself = (inds[:,0] != inds[:,1]) clf() hist(rad2deg(dists[notself]) * 3600., 200) title('ImSim reference catalog') xlabel('Distance between pairs of sources (arcsec)') ylabel('Counts') xlim(0, R) savefig('cat-stars-1.png') cat = fits_table('stars3.fits') xyz = radectoxyz(cat.ra, cat.dec) R = 15. inds,dists = match(xyz, xyz, deg2rad(R/3600.)) notself = (inds[:,0] != inds[:,1]) clf()
# This file is part of libkd. # Licensed under a 3-clause BSD style license - see LICENSE from astrometry.libkd import spherematch import numpy as np from time import time N1 = 1000 N2 = 1000 D = 2 r = 0.02 x1 = np.random.rand(N1, D) x2 = np.random.rand(N2, D) t0 = time() (inds, dists) = spherematch.match(x1, x2, r) dt = time() - t0 print 'spherematch.match: found', len(inds), 'pairs in', int(dt * 1000.), 'ms' order = np.argsort(inds[:, 0] * N2 + inds[:, 1]) inds = inds[order] dists = dists[order] t0 = time() pairs = [] truedists = [] for i in range(N1): pt1 = x1[i, :] d2s = np.sum((x2 - pt1)**2, axis=1) good = np.where(d2s <= r**2)[0]
def whynot(field, index, qidx, wcs): # find index stars in the field. (ra,dec) = wcs.get_radec_center() rad = arcsec2deg(wcs.get_pixel_scale() * hypot(wcs.get_width(), wcs.get_height())) (xyz, radec, starinds) = index_search_stars(index, ra, dec, rad) print 'xyz', xyz.shape print 'radec', radec.shape print 'starinds', starinds.shape istars = tabledata() istars.xyz = xyz istars.radec = radec istars.starind = starinds W,H = wcs.get_width(), wcs.get_height() pix = array([wcs.radec2pixelxy(r, d) for (r,d) in radec]) print 'pix', pix.shape # within image bounds I = (pix[:,0] > 0) * (pix[:,0] < W) * (pix[:,1] > 0) * (pix[:,1] < H) # find nearby pairs of stars... nsigma = 3 pixeljitter = 1 sigma = hypot(index.index_jitter / wcs.get_pixel_scale(), pixeljitter) rad = nsigma * sigma fieldxy = vstack((field.x, field.y)).T print 'field', fieldxy.shape (cinds, cdists) = match(pix, fieldxy, rad) print 'matches:', cinds.shape #print cdists.shape corrs = tabledata() corrs.dist = cdists[:,0] corrs.star = starinds[cinds[:,0]] corrs.field = cinds[:,1] allquads = [] # All quads built from stars in the field... for starind in starinds[I]: #print qidx, starind quads = qidxfile_get_quad_list(qidxfile_addr(qidx), starind) #print 'quads:', quads.shape allquads.append(quads) allquads = unique(hstack(allquads)) print '%i unique quads touch stars in the field' % len(allquads) ''' "quads" object: all quads that touch index stars in this field. .quad : (int) quad index .stars : (DQ x int) star indices .starsinfield: (DQ x bool) stars in field ''' quads = tabledata() quads.quad = allquads qstars = quadfile_get_stars_for_quads(quadfile_addr(index), quads.quad) print 'stars in quads:', qstars.shape #print qstars quads.stars = qstars quads.starsinfield = array([[s in starinds[I] for s in q] for q in qstars]) #print quads.starsinfield allin = quads.starsinfield.min(axis=1) #print quads.allin quads.allin = allin quadsin = quads[allin] print '%i quads use stars that are in the field' % (len(quadsin)) print 'stars:', starinds c_s2f = {} for c in corrs: #i in range(len(corrs)): #print 'corr', c if not c.star in c_s2f: c_s2f[c.star] = [] c_s2f[c.star].append(c.field) #c_s2f[corrs.star[i]] #print c_s2f # [[[213], [35], [265], [63]], [[186]], [[]], [[11], [19]], ...] # For each quad, for each star in the quad, the list of field stars corresponding. fq = [] for q in quadsin.stars: fq1 = [] for s in q: if s in c_s2f: fq1.append(c_s2f[s]) else: fq1.append([]) fq.append(fq1) #print fq # For each quad, the list of sets of field stars corresponding. # [[[213, 35, 265, 63]], [], [], fq2 = [] for q in fq: #print 'q:', q #ac = allcombinations([q[0]], q[1:]) #ac = allcombinations([[]], q) #print '--> ac:', ac fq2.append(allcombinations([[]], q)) #print fq2 quadsin.fq2 = fq2 hasf = array([len(x) > 0 for x in quadsin.fq2]) #print 'hasf:', hasf okquads = quadsin[hasf] #forder = argsort([max(x) for x in okquads.fq2]) #okquads = okquads[forder] print 'ok quads:', len(okquads) print 'quad nums:', okquads.quad print 'stars:', okquads.stars print 'field stars:', okquads.fq2 #qmatches = table_data() #fqs = [] #qs = [] #for okq,fq in zip(okquads, okquads.fq2): # fqs = fqs + fq # qs.append(okq) #qmatches.fieldquad = fqs qmatches = [] for okq,fqs in zip(okquads, okquads.fq2): for fq in fqs: #print 'field stars', fq #print 'quad:', okq.quad qmatches.append((fq, okq)) forder = argsort([max(fq) for fq,okq in qmatches]) #print 'forder', forder print print 'Quads in the order they will be found' for i in forder: fq,okq = qmatches[i] print print 'object', max(fq) print 'field stars', fq print 'quad:', okq.quad # Index stars, by sweep (or "r" mag)... # --which quads are they part of #skdt = starkd_addr(index) istars.sweep = array([startree_get_sweep(index.starkd, si) for si in istars.starind]) mystars = istars[I] order = argsort(mystars.sweep) print print print 'Index stars:', for ms in mystars[order]: print print 'Star', ms.starind, 'sweep', ms.sweep, 'radec', ms.radec print 'Field star(s) nearby:', len(c_s2f.get(ms.starind, [])) for c in corrs[corrs.star == ms.starind]: print ' field star', c.field, 'dist', c.dist, 'pixels' myquads = quads[array([(ms.starind in q.stars) for q in quads])] print 'In %i quads' % len(myquads) for q in myquads: print ' quad %i: %i stars in the field' % (q.quad, sum(q.starsinfield)) if q.allin: print ' stars:', q.stars print ' correspondences for stars:', [c_s2f.get(s, None) for s in q.stars]
def plotshift(ixy, rxy, dcell=50, ncells=18, outfn=None, W=None, H=None, hist=False, nhistbins=21): print 'plotshift...' # correspondences we could have hit... radius = dcell * sqrt(2.) print 'ixy', ixy.shape print 'rxy', rxy.shape print 'asserts' assert((len(rxy) == 0) or (rxy.shape[1] == 2)) assert((len(ixy) == 0) or (ixy.shape[1] == 2)) print 'slice' ix = ixy[:,0] iy = ixy[:,1] print 'w,h' if W is None: W = max(ix) if H is None: H = max(iy) print 'rxy' if len(rxy): keep = (rxy[:,0] > -dcell) * (rxy[:,0] < W+dcell) * (rxy[:,1] > -dcell) * (rxy[:,1] < H+dcell) rxy = rxy[keep] print 'Cut to %i ref sources in range' % len(rxy) print 'bin...' cellsize = sqrt(W * H / ncells) nw = int(round(W / cellsize)) nh = int(round(H / cellsize)) #print 'Grid cell size', cellsize #print 'N cells', nw, 'x', nh edgesx = linspace(0, W, nw+1) edgesy = linspace(0, H, nh+1) #print 'Edges:' #print ' x:', edgesx #print ' y:', edgesy if len(rxy) == 0: binx = array([]) biny = array([]) else: binx = digitize(rxy[:,0], edgesx) biny = digitize(rxy[:,1], edgesy) binx = clip(binx - 1, 0, nw-1) biny = clip(biny - 1, 0, nh-1) bin = biny * nw + binx print 'plot...' plt.clf() for i in range(nh): for j in range(nw): print 'cell %i, %i' % (j, i) thisbin = i * nw + j R = (bin == thisbin) print '%i ref sources' % sum(R) matchdx = [] if sum(R) > 0: print 'match...' (inds,dists) = spherematch.match(rxy[R,:], ixy, radius) #print 'Found %i matches within %g pixels' % (len(dists), radius) ri = inds[:,0] # un-cut ref inds... ri = (flatnonzero(R))[ri] ii = inds[:,1] matchx = rxy[ri,0] matchy = rxy[ri,1] matchdx = ix[ii] - matchx matchdy = iy[ii] - matchy #print 'All matches:' #for dx,dy in zip(matchdx,matchdy): # print ' %.1f, %.1f' % (dx,dy) ok = (matchdx >= -dcell) * (matchdx <= dcell) * (matchdy >= -dcell) * (matchdy <= dcell) matchdx = matchdx[ok] matchdy = matchdy[ok] #print 'Cut to %i within %g x %g square' % (sum(ok), dcell*2, dcell*2) #print 'Cut matches:' #for dx,dy in zip(matchdx,matchdy): # print ' %.1f, %.1f' % (dx,dy) # Subplot places plots left-to-right, TOP-to-BOTTOM. subplot(nh, nw, 1 + ((nh - i - 1)*nw + j)) if len(matchdx) > 0: #plot(matchdx, matchdy, 'ro', mec='r', mfc='r', ms=5, alpha=0.2) #plot(matchdx, matchdy, 'ro', mec='r', mfc='none', ms=5, alpha=0.2) if hist: #if histbinsize is None: # histbinsize = dcell / 10. edges = linspace(-dcell, dcell, nhistbins+1) (H,xe,ye) = histogram2d(matchdx, matchdy, bins=(edges,edges)) imshow(H.T, extent=(min(xe), max(xe), min(ye), max(ye)), aspect='auto', origin='lower', interpolation='nearest') text(dcell, dcell, '%i' % H.max(), color='y', horizontalalignment='right', verticalalignment='top') else: plot(matchdx, matchdy, 'r.', alpha=0.3) if hist: axhline(0, color='b', alpha=0.8) axvline(0, color='b', alpha=0.8) else: axhline(0, color='k', alpha=0.5) axvline(0, color='k', alpha=0.5) if i == 0 and j == 0: xticks([-dcell,0,dcell]) yticks([-dcell,0,dcell]) else: xticks([],[]) yticks([],[]) axis('scaled') axis([-dcell, dcell, -dcell, dcell]) if outfn is not None: #print 'Saving', outfn savefig(outfn)
def plotCorrespondences(imgsources, refsources, matches, wcs, W, H, prefix): ix = np.array([s.getXAstrom() for s in imgsources]) iy = np.array([s.getYAstrom() for s in imgsources]) rx, ry = [], [] for r in refsources: xy = wcs.skyToPixel(r.getRaDec()) rx.append(xy[0]) ry.append(xy[1]) rx = np.array(rx) ry = np.array(ry) # correspondences we could have hit... ixy = np.vstack((ix, iy)).T rxy = np.vstack((rx, ry)).T dcell = 50. radius = dcell * np.sqrt(2.) # print 'ixy', ixy.shape # print 'rxy', rxy.shape if False: (inds, dists) = spherematch.match(rxy, ixy, radius) mi = inds[:, 0] ii = inds[:, 1] matchx = rx[mi] matchy = ry[mi] matchdx = ix[ii] - matchx matchdy = iy[ii] - matchy ok = (matchdx >= -dcell) * (matchdx <= dcell) * (matchdy >= -dcell) * ( matchdy <= dcell) matchx = matchx[ok] matchy = matchy[ok] matchdx = matchdx[ok] matchdy = matchdy[ok] mi = mi[ok] ii = ii[ok] print('Found %i matches within %g pixels' % (len(dists), radius)) ncells = 18. cellsize = np.sqrt(W * H / ncells) nw = int(round(W / cellsize)) nh = int(round(H / cellsize)) # print 'Grid cell size', cellsize # print 'N cells', nw, 'x', nh edgesx = np.linspace(0, W, nw + 1) edgesy = np.linspace(0, H, nh + 1) binx = np.digitize(rx, edgesx) biny = np.digitize(ry, edgesy) binx = np.clip(binx - 1, 0, nw - 1) biny = np.clip(biny - 1, 0, nh - 1) bin = biny * nw + binx plt.clf() for i in range(nh): for j in range(nw): thisbin = i * nw + j R = (bin == thisbin) # print 'cell %i, %i' % (j, i) # print '%i ref sources' % sum(R) if sum(R) == 0: continue (inds, dists) = spherematch.match(rxy[R, :], ixy, radius) # print 'Found %i matches within %g pixels' % (len(dists), radius) ri = inds[:, 0] # un-cut ref inds... ri = (np.flatnonzero(R))[ri] ii = inds[:, 1] matchx = rx[ri] matchy = ry[ri] matchdx = ix[ii] - matchx matchdy = iy[ii] - matchy ok = (matchdx >= -dcell) * (matchdx <= dcell) * ( matchdy >= -dcell) * (matchdy <= dcell) # matchx = matchx[ok] # matchy = matchy[ok] matchdx = matchdx[ok] matchdy = matchdy[ok] # print 'Cut to %i within %g x %g square' % (sum(ok), dcell*2, dcell*2) # Subplot places plots left-to-right, TOP-to-BOTTOM. plt.subplot(nh, nw, 1 + ((nh - i - 1) * nw + j)) plt.plot(matchdx, matchdy, 'ro', mec='r', mfc='r', ms=5, alpha=0.2) plt.plot(matchdx, matchdy, 'ro', mec='r', mfc='none', ms=5, alpha=0.2) plt.axhline(0, color='k', alpha=0.5) plt.axvline(0, color='k', alpha=0.5) plt.xticks([], []) plt.yticks([], []) plt.axis('scaled') plt.axis([-dcell, dcell, -dcell, dcell]) fn = prefix + '-missed.png' print('Saving', fn) plt.savefig(fn)
# Licensed under a 3-clause BSD style license - see LICENSE from __future__ import print_function from astrometry.libkd import spherematch import numpy as np from time import time N1 = 1000 N2 = 1000 D = 2 r = 0.02 x1 = np.random.rand(N1, D) x2 = np.random.rand(N2, D) t0 = time() (inds,dists) = spherematch.match(x1, x2, r) dt = time() - t0 print('spherematch.match: found', len(inds), 'pairs in', int(dt*1000.), 'ms') order = np.argsort(inds[:,0]*N2 + inds[:,1]) inds = inds[order] dists = dists[order] t0 = time() pairs = [] truedists = [] for i in range(N1): pt1 = x1[i,:] d2s = np.sum((x2 - pt1)**2, axis=1) good = np.where(d2s <= r**2)[0]
# Licensed under a 3-clause BSD style license - see LICENSE from __future__ import print_function from astrometry.libkd import spherematch import numpy as np from time import time N1 = 1000 N2 = 1000 D = 2 r = 0.02 x1 = np.random.rand(N1, D) x2 = np.random.rand(N2, D) t0 = time() (inds, dists) = spherematch.match(x1, x2, r) dt = time() - t0 print('spherematch.match: found', len(inds), 'pairs in', int(dt * 1000.), 'ms') order = np.argsort(inds[:, 0] * N2 + inds[:, 1]) inds = inds[order] dists = dists[order] t0 = time() pairs = [] truedists = [] for i in range(N1): pt1 = x1[i, :] d2s = np.sum((x2 - pt1)**2, axis=1) good = np.where(d2s <= r**2)[0]