def ccds_touching_wcs(targetwcs, T, ccdrad=0.17, polygons=True): ''' targetwcs: wcs object describing region of interest T: fits_table object of CCDs ccdrad: radius of CCDs, in degrees. Default 0.17 is for DECam. #If None, computed from T. Returns: index array I of CCDs within range. ''' trad = targetwcs.radius() if ccdrad is None: ccdrad = max(np.sqrt(np.abs(T.cd1_1 * T.cd2_2 - T.cd1_2 * T.cd2_1)) * np.hypot(T.width, T.height) / 2.) rad = trad + ccdrad #r,d = targetwcs.crval r,d = targetwcs.radec_center() #print len(T), 'ccds' #print 'trad', trad, 'ccdrad', ccdrad I = np.flatnonzero(np.abs(T.dec - d) < rad) #print 'Cut to', len(I), 'on Dec' I = I[degrees_between(T.ra[I], T.dec[I], r, d) < rad] #print 'Cut to', len(I), 'on RA,Dec' if not polygons: return I # now check actual polygon intersection tw,th = targetwcs.imagew, targetwcs.imageh targetpoly = [(0.5,0.5),(tw+0.5,0.5),(tw+0.5,th+0.5),(0.5,th+0.5)] cd = targetwcs.get_cd() tdet = cd[0]*cd[3] - cd[1]*cd[2] #print 'tdet', tdet if tdet > 0: targetpoly = list(reversed(targetpoly)) targetpoly = np.array(targetpoly) keep = [] for i in I: W,H = T.width[i],T.height[i] wcs = Tan(*[float(x) for x in [T.crval1[i], T.crval2[i], T.crpix1[i], T.crpix2[i], T.cd1_1[i], T.cd1_2[i], T.cd2_1[i], T.cd2_2[i], W, H]]) cd = wcs.get_cd() wdet = cd[0]*cd[3] - cd[1]*cd[2] #print 'wdet', wdet poly = [] for x,y in [(0.5,0.5),(W+0.5,0.5),(W+0.5,H+0.5),(0.5,H+0.5)]: rr,dd = wcs.pixelxy2radec(x,y) ok,xx,yy = targetwcs.radec2pixelxy(rr,dd) poly.append((xx,yy)) if wdet > 0: poly = list(reversed(poly)) poly = np.array(poly) if polygons_intersect(targetpoly, poly): keep.append(i) I = np.array(keep) #print 'Cut to', len(I), 'on polygons' return I
def ccds_touching_wcs(targetwcs, ccds, ccdrad=0.17, polygons=True): ''' targetwcs: wcs object describing region of interest ccds: fits_table object of CCDs ccdrad: radius of CCDs, in degrees. Default 0.17 is for DECam. #If None, computed from T. Returns: index array I of CCDs within range. ''' trad = targetwcs.radius() if ccdrad is None: ccdrad = max( np.sqrt(np.abs(ccds.cd1_1 * ccds.cd2_2 - ccds.cd1_2 * ccds.cd2_1)) * np.hypot(ccds.width, ccds.height) / 2.) rad = trad + ccdrad r, d = targetwcs.radec_center() I, = np.nonzero(np.abs(ccds.dec - d) < rad) I = I[np.atleast_1d(degrees_between(ccds.ra[I], ccds.dec[I], r, d) < rad)] if not polygons: return I # now check actual polygon intersection tw, th = targetwcs.imagew, targetwcs.imageh targetpoly = [(0.5, 0.5), (tw + 0.5, 0.5), (tw + 0.5, th + 0.5), (0.5, th + 0.5)] cd = targetwcs.get_cd() tdet = cd[0] * cd[3] - cd[1] * cd[2] if tdet > 0: targetpoly = list(reversed(targetpoly)) targetpoly = np.array(targetpoly) keep = [] for i in I: W, H = ccds.width[i], ccds.height[i] wcs = Tan(*[ float(x) for x in [ ccds.crval1[i], ccds.crval2[i], ccds.crpix1[i], ccds.crpix2[i], ccds.cd1_1[i], ccds.cd1_2[i], ccds.cd2_1[i], ccds.cd2_2[i], W, H ] ]) cd = wcs.get_cd() wdet = cd[0] * cd[3] - cd[1] * cd[2] poly = [] for x, y in [(0.5, 0.5), (W + 0.5, 0.5), (W + 0.5, H + 0.5), (0.5, H + 0.5)]: rr, dd = wcs.pixelxy2radec(x, y) ok, xx, yy = targetwcs.radec2pixelxy(rr, dd) poly.append((xx, yy)) if wdet > 0: poly = list(reversed(poly)) poly = np.array(poly) if polygons_intersect(targetpoly, poly): keep.append(i) I = np.array(keep) return I
def galex_tractor_image(tile, band, galex_dir, radecbox, bandname): from tractor import (NanoMaggies, Image, LinearPhotoCal, ConstantFitsWcs, ConstantSky) assert(band in ['n','f']) #nicegbands = ['NUV', 'FUV'] #zps = dict(n=20.08, f=18.82) #zp = zps[band] imfn = os.path.join(galex_dir, tile.tilename.strip(), '%s-%sd-intbgsub.fits.gz' % (tile.visitname.strip(), band)) gwcs = Tan(*[float(f) for f in [tile.crval1, tile.crval2, tile.crpix1, tile.crpix2, tile.cdelt1, 0., 0., tile.cdelt2, 3840., 3840.]]) (r0,r1,d0,d1) = radecbox H,W = gwcs.shape ok,xx,yy = gwcs.radec2pixelxy([r0,r0,r1,r1], [d0,d1,d1,d0]) #print('GALEX WCS pixel positions of RA,Dec box:', xx, yy) if np.any(np.logical_not(ok)): return None x0 = np.clip(np.floor(xx-1).astype(int).min(), 0, W-1) x1 = np.clip(np.ceil (xx-1).astype(int).max(), 0, W) if x1-x0 <= 1: return None y0 = np.clip(np.floor(yy-1).astype(int).min(), 0, H-1) y1 = np.clip(np.ceil (yy-1).astype(int).max(), 0, H) if y1-y0 <= 1: return None debug('Reading GALEX subimage x0,y0', x0,y0, 'size', x1-x0, y1-y0) gwcs = gwcs.get_subimage(x0, y0, x1 - x0, y1 - y0) twcs = ConstantFitsWcs(gwcs) roislice = (slice(y0, y1), slice(x0, x1)) fitsimg = fitsio.FITS(imfn)[0] hdr = fitsimg.read_header() img = fitsimg[roislice] inverr = np.ones_like(img) inverr[img == 0.] = 0. zp = tile.get('%s_zpmag' % band) photocal = LinearPhotoCal(NanoMaggies.zeropointToScale(zp), band=bandname) tsky = ConstantSky(0.) name = 'GALEX ' + hdr['OBJECT'] + ' ' + band psfimg = galex_psf(band, galex_dir) tpsf = PixelizedPSF(psfimg) tim = Image(data=img, inverr=inverr, psf=tpsf, wcs=twcs, sky=tsky, photocal=photocal, name=name) tim.roi = [x0,x1,y0,y1] return tim
def ccds_touching_wcs(targetwcs, ccds, ccdrad=0.17, polygons=True): ''' targetwcs: wcs object describing region of interest ccds: fits_table object of CCDs ccdrad: radius of CCDs, in degrees. Default 0.17 is for DECam. #If None, computed from T. Returns: index array I of CCDs within range. ''' trad = targetwcs.radius() if ccdrad is None: ccdrad = max(np.sqrt(np.abs(ccds.cd1_1 * ccds.cd2_2 - ccds.cd1_2 * ccds.cd2_1)) * np.hypot(ccds.width, ccds.height) / 2.) rad = trad + ccdrad r,d = targetwcs.radec_center() I, = np.nonzero(np.abs(ccds.dec - d) < rad) I = I[np.atleast_1d(degrees_between(ccds.ra[I], ccds.dec[I], r, d) < rad)] if not polygons: return I # now check actual polygon intersection tw,th = targetwcs.imagew, targetwcs.imageh targetpoly = [(0.5,0.5),(tw+0.5,0.5),(tw+0.5,th+0.5),(0.5,th+0.5)] cd = targetwcs.get_cd() tdet = cd[0]*cd[3] - cd[1]*cd[2] if tdet > 0: targetpoly = list(reversed(targetpoly)) targetpoly = np.array(targetpoly) keep = [] for i in I: W,H = ccds.width[i],ccds.height[i] wcs = Tan(*[float(x) for x in [ccds.crval1[i], ccds.crval2[i], ccds.crpix1[i], ccds.crpix2[i], ccds.cd1_1[i], ccds.cd1_2[i], ccds.cd2_1[i], ccds.cd2_2[i], W, H]]) cd = wcs.get_cd() wdet = cd[0]*cd[3] - cd[1]*cd[2] poly = [] for x,y in [(0.5,0.5),(W+0.5,0.5),(W+0.5,H+0.5),(0.5,H+0.5)]: rr,dd = wcs.pixelxy2radec(x,y) ok,xx,yy = targetwcs.radec2pixelxy(rr,dd) poly.append((xx,yy)) if wdet > 0: poly = list(reversed(poly)) poly = np.array(poly) if polygons_intersect(targetpoly, poly): keep.append(i) I = np.array(keep) return I
def sdss_image(req, calid=None, size='full'): cal = get_object_or_404(Calibration, pk=calid) key = 'sdss_size%s_cal%i' % (size, cal.id) df = CachedFile.get(key) if df is None: wcsfn = cal.get_wcs_file() from astrometry.util.util import Tan wcs = Tan(wcsfn) if size == 'display': image = cal.job.user_image scale = float( image.image.get_display_image().width) / image.image.width wcs = wcs.scale(scale) else: scale = 1.0 urlargs = urlencode( dict(crval1='%.6f' % wcs.crval[0], crval2='%.6f' % wcs.crval[1], crpix1='%.2f' % wcs.crpix[0], crpix2='%.2f' % wcs.crpix[1], cd11='%.6g' % wcs.cd[0], cd12='%.6g' % wcs.cd[1], cd21='%.6g' % wcs.cd[2], cd22='%.6g' % wcs.cd[3], imagew='%i' % int(wcs.imagew), imageh='%i' % int(wcs.imageh))) url = 'http://legacysurvey.org/viewer/cutout-wcs/?layer=sdssco&' + urlargs return HttpResponseRedirect(url) #print('Retrieving:', url) #f = urlopen(url) #plotfn = get_temp_file() #plotfn, headers = urlretrieve(url, plotfn) #print('Headers:', headers) #plot_sdss_image(wcsfn, plotfn, scale) # cache # logmsg('Caching key "%s"' % key) # df = CachedFile.add(key, plotfn) else: logmsg('Cache hit for key "%s" -> %s' % (key, df.get_path())) f = open(df.get_path(), 'rb') res = HttpResponse(f) res['Content-Type'] = 'image/jpeg' return res
def __init__(self, name, **kwargs): ## HACK -- don't call the PhatLayer constructor! #super(M33Layer, self).__init__(name, **kwargs) super(PhatLayer, self).__init__(name, **kwargs) self.nativescale = 17 self.pixscale = 0.035 #fn = self.get_base_filname(None, None) #self.fits = fitsio.FITS(fn)[0] #fn = os.path.join(settings.DATA_DIR, 'm33', 'F475W_wcs.fits') #fn = os.path.join(settings.DATA_DIR, 'm33', 'm33-wcs.fits') fn = os.path.join(settings.DATA_DIR, 'm33', 'm33-wcs814.fits') #self.wcs = anwcs_open_wcslib(fn, 0) from astrometry.util.util import Tan self.wcs = Tan(fn, 0) print('M33 WCS: center', self.wcs.radec_center())
def unWISE2BOSS(tilename, channelNumber, BOSSra, BOSSdec, plot=True, vmin=-50,vmax=300): # Input tile name RA = BOSSra.copy() DEC =BOSSdec.copy() tileName = tilename channel = channelNumber # Contructing file address fileaddress = get_unwise_filename(tileName, channel) tol = 2.00 if 'm' in tileName: ra = float(tileName.split('m')[0])/10.0 dec = float(tileName.split('m')[1])/10.0 else: ra = float(tileName.split('p')[0])/10.0 dec = float(tileName.split('p')[1])/10.0 iBool = degrees_between(ra, dec, RA,DEC) <tol # Getting x,y positions of the objects near by the center of the tile. wcs = Tan(fileaddress) ok, x, y = wcs.radec2pixelxy(RA[np.where(iBool==True)], DEC[np.where(iBool==True)]) a = np.isnan(x) b = np.isnan(y) x[a] = 0 y[b] = 0 iBool = (1<x)&(x<2048)&(1<y)&(y<2048) x -= 1 y -= 1 x=x[iBool] y=y[iBool] #From the result, I choose to use 1504p196 if plot: objs1 = fitsio.FITS(fileaddress) blockImage =objs1[0][:,:] plt.imshow(blockImage, cmap='gray', vmin=vmin, vmax=vmax, origin='lower',interpolation='nearest') # 10/8/2015: Becareful about the orientation of the matrix. plt.scatter(x, y, facecolors='none', edgecolors='r',s=100) plt.show() #Return RA/DEC return x, y
def __init__(self, wcs, hdu=0): ''' Creates a new ``FitsWcs`` given a :class:`~astrometry.util.util.Tan` object. To create one of these from a filename and FITS HDU extension, :: from astrometry.util.util import Tan fn = 'my-file.fits' ext = 0 TanWcs(Tan(fn, ext)) To create one from WCS parameters, tanwcs = Tan(crval1, crval2, crpix1, crpix2, cd11, cd12, cd21, cd22, imagew, imageh) TanWcs(tanwcs) ''' if hasattr(self, 'x0'): print('TanWcs has an x0 attr:', self.x0) self.x0 = 0 self.y0 = 0 if isinstance(wcs, basestring): from astrometry.util.util import Tan wcs = Tan(wcs, hdu) super(TanWcs, self).__init__(wcs) # ParamList keeps its params in a list; we don't want to do that. del self.vals
def read_tan_wcs(sourcefn, ext, hdr=None, W=None, H=None, fitsfile=None): from astrometry.util.util import Tan if not os.path.exists(sourcefn): return None wcs = read_tansip_wcs(sourcefn, ext, hdr=hdr, W=W, H=H, tansip=Tan) if wcs is None: import fitsio # maybe gzipped; try fitsio header. if hdr is None: hdr = fitsio.read_header(sourcefn, ext) if W is None or H is None: if fitsfile is None: F = fitsio.FITS(sourcefn) else: F = fitsfile info = F[ext].get_info() H,W = info['dims'] # PS1 wonky WCS if (not 'CD1_1' in hdr) and ('PC001001' in hdr): cdelt1 = hdr['CDELT1'] cdelt2 = hdr['CDELT2'] # ???? cd11 = hdr['PC001001'] * cdelt1 cd12 = hdr['PC001002'] * cdelt1 cd21 = hdr['PC002001'] * cdelt2 cd22 = hdr['PC002002'] * cdelt2 else: cd11,cd12,cd21,cd22 = hdr['CD1_1'], hdr['CD1_2'], hdr['CD2_1'], hdr['CD2_2'], wcs = Tan(*[float(x) for x in [ hdr['CRVAL1'], hdr['CRVAL2'], hdr['CRPIX1'], hdr['CRPIX2'], cd11, cd12, cd21, cd22, W, H]]) return wcs
def plot_into_wcs(wcsfn, plotfn, wcsext=0, basedir='.', scale=1.0): wcs = Tan(wcsfn, wcsext) ra, dec = wcs.radec_center() radius = wcs.radius() # The "index.fits" table has RA,Dec center and file paths. T = fits_table(os.path.join(basedir, 'index.fits')) # MAGIC 1: the GALEX fields are all smaller than 1 degree (~0.95) in radius, # so add that to the search r = radius + 1. # find rows in "T" that are within range. J = points_within_radius(ra, dec, r, T.ra, T.dec) T = T[J] debug(len(T), 'GALEX fields within range of RA,Dec = ', ra, dec, 'radius', radius) size = [int(scale * wcs.imagew), int(scale * wcs.imageh)] plot = ps.Plotstuff(outformat='png', wcsfn=wcsfn, wcsext=wcsext, size=size) plot.scale_wcs(scale) #debug('WCS:', str(plot.wcs)) #plot.wcs.write_to('/tmp/wcs.fits') img = plot.image img.format = ps.PLOTSTUFF_FORMAT_JPG img.resample = 1 if len(T): paths = [fn.strip() for fn in T.path] else: paths = [] plot.color = 'black' plot.plot('fill') for jpegfn in paths: jpegfn = os.path.join(basedir, jpegfn) imwcsfn = jpegfn.replace('.jpg', '.wcs') debug(' Plotting GALEX fields', jpegfn, imwcsfn) #debug('jpeg "%s"' % jpegfn) #debug('wcs "%s"' % imwcsfn) img.set_wcs_file(imwcsfn, 0) img.set_file(jpegfn) # convert black to transparent ps.plot_image_read(plot.pargs, img) ps.plot_image_make_color_transparent(img, 0, 0, 0) plot.plot('image') plot.write(plotfn) debug('wrote', plotfn)
def sdss_image(req, calid=None, size='full'): cal = get_object_or_404(Calibration, pk=calid) key = 'sdss_size%s_cal%i' % (size, cal.id) df = CachedFile.get(key) if df is None: wcsfn = cal.get_wcs_file() plotfn = get_temp_file() from astrometry.util.util import Tan wcs = Tan(wcsfn) if size == 'display': image = cal.job.user_image scale = float(image.image.get_display_image().width)/image.image.width wcs = wcs.scale(scale) else: scale = 1.0 urlargs = urllib.urlencode(dict(crval1='%.6f' % wcs.crval[0], crval2='%.6f' % wcs.crval[1], crpix1='%.2f' % wcs.crpix[0], crpix2='%.2f' % wcs.crpix[1], cd11='%.6g' % wcs.cd[0], cd12='%.6g' % wcs.cd[1], cd21='%.6g' % wcs.cd[2], cd22='%.6g' % wcs.cd[3], imagew='%i' % int(wcs.imagew), imageh='%i' % int(wcs.imageh))) url = 'http://legacysurvey.org/viewer-dev/sdss-wcs/?' + urlargs return HttpResponseRedirect(url) #print('Retrieving:', url) #f = urllib.urlopen(url) plotfn,headers = urllib.urlretrieve(url, plotfn) #print('Headers:', headers) #plot_sdss_image(wcsfn, plotfn, scale) # cache logmsg('Caching key "%s"' % key) df = CachedFile.add(key, plotfn) else: logmsg('Cache hit for key "%s" -> %s' % (key, df.get_path())) f = open(df.get_path()) res = HttpResponse(f) res['Content-Type'] = 'image/jpeg' return res
class M33Layer(PhatLayer): ''' # Image files: tifftopnm data/m33/M33_F814W_F475W_mosaic_181216_MJD.tif | ppmtorgb3 - pamflip -tb -- -.red | an-pnmtofits -o data/m33/m33-R.fits -v & pamflip -tb -- -.grn | an-pnmtofits -o data/m33/m33-G.fits -v & pamflip -tb -- -.blu | an-pnmtofits -o data/m33/m33-B.fits -v & # WCS header: hdr = fitsio.read_header('/Users/dstn/Downloads/F475W_wcs.fits') outhdr = fitsio.FITSHDR() for key in ['SIMPLE', 'BITPIX', 'NAXIS', 'WCSAXES', 'CRPIX1', 'CRPIX2', 'CTYPE1', 'CTYPE2', 'CRVAL1', 'CRVAL2']: v = hdr[key] outhdr[key] = v outhdr outhdr['CD1_1'] = hdr['CDELT1'] * hdr['PC1_1'] outhdr['CD1_2'] = hdr['CDELT1'] * hdr['PC1_2'] outhdr['CD2_1'] = hdr['CDELT2'] * hdr['PC2_1'] outhdr['CD2_2'] = hdr['CDELT2'] * hdr['PC2_2'] outhdr['IMAGEW'] = 32073 outhdr['IMAGEH'] = 41147 fitsio.write('/tmp/m33-wcs.fits', None, header=outhdr) ''' def __init__(self, name, **kwargs): ## HACK -- don't call the PhatLayer constructor! #super(M33Layer, self).__init__(name, **kwargs) super(PhatLayer, self).__init__(name, **kwargs) self.nativescale = 17 self.pixscale = 0.035 #fn = self.get_base_filname(None, None) #self.fits = fitsio.FITS(fn)[0] #fn = os.path.join(settings.DATA_DIR, 'm33', 'F475W_wcs.fits') #fn = os.path.join(settings.DATA_DIR, 'm33', 'm33-wcs.fits') fn = os.path.join(settings.DATA_DIR, 'm33', 'm33-wcs814.fits') #self.wcs = anwcs_open_wcslib(fn, 0) from astrometry.util.util import Tan self.wcs = Tan(fn, 0) print('M33 WCS: center', self.wcs.radec_center()) def read_wcs(self, brick, band, scale, fn=None): if scale == 0: return self.wcs return super(M33Layer, self).read_wcs(brick, band, scale, fn=fn) def get_bands(self): return 'RGB' def get_base_filename(self, brick, band, **kwargs): return os.path.join(settings.DATA_DIR, 'm33', 'm33-%s.fits' % band) def get_scaled_filename(self, brick, band, scale): return os.path.join(settings.DATA_DIR, 'm33', 'm33-%s-scale%i.fits' % (band, scale)) def get_rgb(self, imgs, bands, **kwargs): import numpy as np #for img in imgs: # print('Image', img.shape, img.dtype, img.min(), img.max()) return np.dstack(imgs) / 255.
def read_pv_wcs(self): '''extract wcs from fits header directly''' hdr = fitsio.read_header(self.imgfn, self.hdu) H,W = self.get_image_shape() wcs= Tan(hdr['CRVAL1'], hdr['CRVAL2'],hdr['CRPIX1'],hdr['CRPIX2'],\ hdr['CD1_1'],hdr['CD1_2'],hdr['CD2_1'],hdr['CD2_2'],\ float(W),float(H)) return wcs
def halfsize(sourcefn, halffn): ''' Reads and image and WCS from the given source file, Bins down by a factor of 2, and writes to the given output file. ''' im,hdr = fitsio.read(sourcefn, header=True) H,W = im.shape # make even size; smooth down if H % 2 == 1: im = im[:-1,:] if W % 2 == 1: im = im[:,:-1] # bin (excluding NaNs) q1 = im[::2,::2] q2 = im[1::2,::2] q3 = im[1::2,1::2] q4 = im[::2,1::2] f1 = np.isfinite(q1) f2 = np.isfinite(q2) f3 = np.isfinite(q3) f4 = np.isfinite(q4) im = (np.where(f1, q1, 0) + np.where(f2, q2, 0) + np.where(f3, q3, 0) + np.where(f4, q4, 0)) / np.maximum(1, f1+f2+f3+f4) #im = (im[::2,::2] + im[1::2,::2] + im[1::2,1::2] + im[::2,1::2])/4. im = im.astype(np.float32) # shrink WCS too wcs = Tan(sourcefn, 0) # include the even size clip; this may be a no-op H,W = im.shape wcs = wcs.get_subimage(0, 0, W, H) subwcs = wcs.scale(0.5) hdr = fitsio.FITSHDR() subwcs.add_to_header(hdr) dirnm = os.path.dirname(halffn) f,tmpfn = tempfile.mkstemp(suffix='.fits.tmp', dir=dirnm) os.close(f) # To avoid overwriting the (empty) temp file (and fitsio # printing "Removing existing file") os.unlink(tmpfn) fitsio.write(tmpfn, im, header=hdr, clobber=True) os.rename(tmpfn, halffn) print('Wrote', halffn)
def unwise_tile_wcs(ra, dec, W=2048, H=2048, pixscale=2.75): ''' Returns a Tan WCS object at the given RA,Dec center, axis aligned, with the given pixel W,H and pixel scale in arcsec/pixel. ''' cowcs = Tan(ra, dec, (W + 1) / 2., (H + 1) / 2., -pixscale / 3600., 0., 0., pixscale / 3600., W, H) return cowcs
def sdss_image(req, calid=None, size='full'): cal = get_object_or_404(Calibration, pk=calid) key = 'sdss_size%s_cal%i' % (size, cal.id) df = CachedFile.get(key) if df is None: wcsfn = cal.get_wcs_file() #plotfn = get_temp_file() from astrometry.util.util import Tan wcs = Tan(wcsfn) if size == 'display': image = cal.job.user_image scale = float( image.image.get_display_image().width) / image.image.width wcs = wcs.scale(scale) else: scale = 1.0 url = 'http://legacysurvey.org/viewer-dev/sdss-wcs/?crval1=%.6f&crval2=%.6f&crpix1=%.2f&crpix2=%.2f&cd11=%.6g&cd12=%.6g&cd21=%.6g&cd22=%.6g&imagew=%i&imageh=%i' % ( wcs.crval[0], wcs.crval[1], wcs.crpix[0], wcs.crpix[1], wcs.cd[0], wcs.cd[1], wcs.cd[2], wcs.cd[3], int(wcs.imagew), int(wcs.imageh)) print('Retrieving:', url) import urllib plotfn, headers = urllib2.urlretrieve(url) # jwcs = json.dumps(dict( # crval1=wcs.crval[0], crval2=wcs.crval[1], # crpix1=wcs.crpix[0], crpix2=wcs.crpix[1], # cd11=wcs.cd[0], cd12=wcs.cd[1], cd21=wcs.cd[2], cd22=wcs.cd[3], # imagew=wcs.imagew, imageh=wcs.imageh)) # plot_sdss_image(wcsfn, plotfn, scale) # cache logmsg('Caching key "%s"' % key) df = CachedFile.add(key, plotfn) else: logmsg('Cache hit for key "%s"' % key) f = open(df.get_path()) res = HttpResponse(f) res['Content-Type'] = 'image/jpeg' return res
def forwards(self, orm): "Write your forwards methods here." for calib in orm.Calibration.objects.all(): wcsfn = os.path.join(JOBDIR, '%08i' % calib.job.id) wcsfn = os.path.join(wcsfn, 'wcs.fits') wcs = Tan(str(wcsfn), 0) ra,dec = wcs.radec_center() radius = (wcs.pixel_scale() * math.hypot(wcs.imagew, wcs.imageh)/2. / 3600.) # Find cartesian coordinates ra *= math.pi/180 dec *= math.pi/180 tempr = math.cos(dec) calib.x = tempr*math.cos(ra) calib.y = tempr*math.sin(ra) calib.z = math.sin(dec) calib.r = radius/180*math.pi calib.save()
def example(): pixscale = 0.25 # [arcsec/pix] radius = 45.0 # [arcsec] ra, dec = 120.0, 15.0 # [degrees] diam = np.ceil(radius / pixscale).astype('int16') # [pixels] wcs = Tan(ra, dec, diam / 2 + 0.5, diam / 2 + 0.5, -pixscale / 3600.0, 0.0, 0.0, pixscale / 3600.0, float(diam), float(diam)) return wcs
def get_wcs(self, hdr): # Older images have ZPX, newer TPV. if hdr['CTYPE1'] == 'RA---TPV': from astrometry.util.util import wcs_pv2sip_hdr wcs = wcs_pv2sip_hdr(hdr) else: from astrometry.util.util import Tan hdr['CTYPE1'] = 'RA---TAN' hdr['CTYPE2'] = 'DEC--TAN' wcs = Tan(hdr) return wcs
def dither_sequence(start, ending): dither = fits_table() dither.expnum = [] dither.gfa_ra = [] dither.gfa_dec = [] dither.gfa05_ra = [] dither.gfa05_dec = [] dither.gfa27_ra = [] dither.gfa27_dec = [] dither.gfa38_ra = [] dither.gfa38_dec = [] dither.gfa_all_ra = [] dither.gfa_all_dec = [] dither.sky_ra = [] dither.sky_dec = [] headers = [] for expnum in range(start, ending): fns = glob('/global/cscratch1/sd/dstn/gfa-wcs/gfa-%i-GUIDE?.wcs' % expnum) if len(fns) != 6: #print('Do not have', expnum) continue #print('Got', expnum) fns.sort() rr, dd = [], [] for fn in fns: print('Reading', fn) wcs = Tan(fn) rr.append(wcs.crval[0]) dd.append(wcs.crval[1]) fn = gfa_filename(expnum) hdr = fitsio.read_header(fn, ext=1) dither.expnum.append(expnum) headers.append(hdr) r, d = average_radec(rr, dd) dither.gfa_ra.append(r) dither.gfa_dec.append(d) r, d = average_radec([rr[0], rr[3]], [dd[0], dd[3]]) dither.gfa05_ra.append(r) dither.gfa05_dec.append(d) r, d = average_radec([rr[1], rr[4]], [dd[1], dd[4]]) dither.gfa27_ra.append(r) dither.gfa27_dec.append(d) r, d = average_radec([rr[2], rr[5]], [dd[2], dd[5]]) dither.gfa38_ra.append(r) dither.gfa38_dec.append(d) dither.gfa_all_ra.append(rr) dither.gfa_all_dec.append(dd) dither.sky_ra.append(hdr['SKYRA']) dither.sky_dec.append(hdr['SKYDEC']) dither.to_np_arrays() dither.headers = headers return dither
def __init__(self, name, **kwargs): import fitsio from astrometry.util.util import Tan #from astrometry.util.util import anwcs_open_wcslib super(PhatLayer, self).__init__(name, **kwargs) self.nativescale = 17 self.pixscale = 0.05 fn = os.path.join(settings.DATA_DIR, 'm31_full.fits') self.fits = fitsio.FITS(fn)[0] #self.wcs = anwcs_open_wcslib(fn, 0) self.wcs = Tan(fn, 0)
def wcs_for_brick(b, W=3600, H=3600, pixscale=0.262): ''' b: row from decals-bricks.fits file W,H: size in pixels pixscale: pixel scale in arcsec/pixel. Returns: Tan wcs object ''' pixscale = pixscale / 3600. return Tan(b.ra, b.dec, W/2.+0.5, H/2.+0.5, -pixscale, 0., 0., pixscale, float(W), float(H))
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 get_subtile_wcs(name, x, y): """ pixscale: arcsec/pixel """ nsub = N_subtiles pixscale = decam_pixscale wcs = unwise_wcs_from_name(name) W, H = wcs.get_width(), wcs.get_height() # Tweak to DECam pixel scale and number of pixels. D = int(np.ceil((W * wcs.pixel_scale() / pixscale) / nsub)) * nsub DW, DH = D, D wcs.set_crpix(DW / 2 + 1.5, DH / 2 + 1.5) pixscale = pixscale / 3600.0 wcs.set_cd(-pixscale, 0.0, 0.0, pixscale) wcs.set_imagesize(DW, DH) W, H = wcs.get_width(), wcs.get_height() subw, subh = W / nsub, H / nsub subwcs = Tan(wcs) subwcs.set_crpix(wcs.crpix[0] - x * subw, wcs.crpix[1] - y * subh) subwcs.set_imagesize(subw, subh) return subwcs
def BOSS2unWISE(ra, dec, tileID, tileRA, tileDEC,plot=True): tol = 1.56 iBool = degrees_between(ra, dec, tileRA,tileDEC) <tol tilesCandidates = tileID[iBool] tiles = [] for tName in tilesCandidates: channel = 'w1' fileaddress = get_unwise_filename(tName, channel) wcs = Tan(fileaddress) ok, x, y = wcs.radec2pixelxy(ra, dec) x -= 1 y -= 1 iTile= (0<x) &(x<2047)&(0<y)&(y<2047) if iTile: tiles = np.append(tiles, [tName]) if plot: objs1 = fitsio.FITS(fileaddress) blockImage =objs1[0][:,:] plt.imshow(blockImage, cmap='gray', vmin=-50, vmax=300, origin='lower',interpolation='nearest') # 10/8/2015: Becareful about the orientation of the matrix. plt.scatter(x, y, facecolors='none', edgecolors='r',s=100) plt.show() return tiles
def get_wcs(hdr, tpv_to_sip=True): # Thanks Dstn :) # https://github.com/legacysurvey/legacypipe/blob/master/py/legacypipe/cpimage.py#102 width = hdr['NAXIS1'] height = hdr['NAXIS2'] if not (tpv_to_sip): # extract wcs from fits header directly wcs= Tan(hdr['CRVAL1'], hdr['CRVAL2'],hdr['CRPIX1'],hdr['CRPIX2'],\ hdr['CD1_1'],hdr['CD1_2'],hdr['CD2_1'],hdr['CD2_2'],\ float(width),float(height)) else: # Make sure the PV-to-SIP converter samples enough points for small # images stepsize = 0 if min(width, height) < 600: stepsize = min(width, height) / 10. wcs = wcs_pv2sip_hdr(hdr, stepsize=stepsize) # Dstn adds an offset correction i.e. # Correction: ccd,ccdraoff, decoff from zeropoints file # Should I do this? return wcs
def gettractor(): W, H = 200, 200 image = np.zeros((H, W)) invvar = np.zeros_like(image) + 1. ra, dec = 0, 0 # arcsec/pix pixscale = 1. wcs1 = Tan(ra, dec, W / 2, H / 2, -pixscale / 3600., 0, 0, -pixscale / 3600., W, H) wcs = FitsWcs(wcs1) photocal = NullPhotoCal() psf = NCircularGaussianPSF([1.], [1.]) sky = ConstantSky(0.) img = Image(data=image, invvar=invvar, psf=psf, wcs=wcs, sky=sky, photocal=photocal) tractor = SDSSTractor([img]) return tractor, wcs
def dojob(job, userimage, log=None, solve_command=None, solve_locally=None, tempfiles=None): print('dojob: tempdir:', tempfile.gettempdir()) jobdir = job.make_dir() #print('Created job dir', jobdir) #log = create_job_logger(job) #jobdir = job.get_dir() if log is None: log = create_job_logger(job) log.msg('Starting Job processing for', job) job.set_start_time() job.save() #os.chdir(dirnm) - not thread safe (working directory is global)! log.msg('Creating directory', jobdir) axyfn = 'job.axy' axypath = os.path.join(jobdir, axyfn) sub = userimage.submission log.msg('submission id', sub.id) df = userimage.image.disk_file img = userimage.image # Build command-line arguments for the augment-xylist program, which # detects sources in the image and adds processing arguments to the header # to produce a "job.axy" file. slo, shi = sub.get_scale_bounds() # Note, this must match Job.get_wcs_file(). wcsfile = 'wcs.fits' corrfile = 'corr.fits' axyflags = [] axyargs = { '--out': axypath, '--scale-low': slo, '--scale-high': shi, '--scale-units': sub.scale_units, '--wcs': wcsfile, '--corr': corrfile, '--rdls': 'rdls.fits', '--pixel-error': sub.positional_error, '--ra': sub.center_ra, '--dec': sub.center_dec, '--radius': sub.radius, '--downsample': sub.downsample_factor, # tuning-up maybe fixed; if not, turn it off with: #'--odds-to-tune': 1e9, # Other things we might want include... # --invert # -g / --guess-scale: try to guess the image scale from the FITS headers # --crpix-x <pix>: set the WCS reference point to the given position # --crpix-y <pix>: set the WCS reference point to the given position # -w / --width <pixels>: specify the field width # -e / --height <pixels>: specify the field height # -X / --x-column <column-name>: the FITS column name # -Y / --y-column <column-name> } if hasattr(img, 'sourcelist'): # image is a source list; use --xylist axyargs['--xylist'] = img.sourcelist.get_fits_path(tempfiles=tempfiles) w, h = img.width, img.height if sub.image_width: w = sub.image_width if sub.image_height: h = sub.image_height axyargs['--width'] = w axyargs['--height'] = h else: axyargs['--image'] = df.get_path() # UGLY if sub.parity == 0: axyargs['--parity'] = 'pos' elif sub.parity == 1: axyargs['--parity'] = 'neg' if sub.tweak_order == 0: axyflags.append('--no-tweak') else: axyargs['--tweak-order'] = '%i' % sub.tweak_order if sub.use_sextractor: axyflags.append('--use-source-extractor') if sub.crpix_center: axyflags.append('--crpix-center') if sub.invert: axyflags.append('--invert') cmd = 'augment-xylist ' for (k, v) in list(axyargs.items()): if v: cmd += k + ' ' + str(v) + ' ' for k in axyflags: cmd += k + ' ' log.msg('running: ' + cmd) (rtn, out, err) = run_command(cmd) if rtn: log.msg('out: ' + out) log.msg('err: ' + err) logmsg('augment-xylist failed: rtn val', rtn, 'err', err) raise Exception log.msg('created axy file', axypath) # shell into compute server... logfn = job.get_log_file() # the "tar" commands both use "-C" to chdir, and the ssh command # and redirect uses absolute paths. if solve_locally is not None: cmd = (('cd %(jobdir)s && %(solvecmd)s %(jobid)s %(axyfile)s >> ' + '%(logfile)s') % dict(jobid='job-%s-%i' % (settings.sitename, job.id), solvecmd=solve_locally, axyfile=axyfn, jobdir=jobdir, logfile=logfn)) log.msg('command:', cmd) w = os.system(cmd) if not os.WIFEXITED(w): log.msg('Solver failed (sent signal?)') logmsg('Call to solver failed for job', job.id) raise Exception rtn = os.WEXITSTATUS(w) if rtn: log.msg('Solver failed with return value %i' % rtn) logmsg('Call to solver failed for job', job.id, 'with return val', rtn) raise Exception log.msg('Solver completed successfully.') else: if solve_command is None: solve_command = 'ssh -x -T %(sshconfig)s' cmd = (( '(echo %(jobid)s; ' 'tar cf - --ignore-failed-read -C %(jobdir)s %(axyfile)s) | ' + solve_command + ' 2>>%(logfile)s | ' 'tar xf - --atime-preserve -m --exclude=%(axyfile)s -C %(jobdir)s ' '>>%(logfile)s 2>&1') % dict(jobid='job-%s-%i' % (settings.sitename, job.id), axyfile=axyfn, jobdir=jobdir, sshconfig=settings.ssh_solver_config, logfile=logfn)) log.msg('command:', cmd) w = os.system(cmd) if not os.WIFEXITED(w): log.msg('Solver failed (sent signal?)') logmsg('Call to solver failed for job', job.id) raise Exception rtn = os.WEXITSTATUS(w) if rtn: log.msg('Solver failed with return value %i' % rtn) logmsg('Call to solver failed for job', job.id, 'with return val', rtn) raise Exception log.msg('Solver completed successfully.') # Solved? wcsfn = os.path.join(jobdir, wcsfile) log.msg('Checking for WCS file', wcsfn) if os.path.exists(wcsfn): log.msg('WCS file exists') # Parse the wcs.fits file wcs = Tan(wcsfn, 0) # Convert to database model... tan = TanWCS(crval1=wcs.crval[0], crval2=wcs.crval[1], crpix1=wcs.crpix[0], crpix2=wcs.crpix[1], cd11=wcs.cd[0], cd12=wcs.cd[1], cd21=wcs.cd[2], cd22=wcs.cd[3], imagew=img.width, imageh=img.height) tan.save() log.msg('Created TanWCS:', tan) # Find field's healpix nside and index ra, dec, radius = tan.get_center_radecradius() nside = anutil.healpix_nside_for_side_length_arcmin(radius * 60) nside = int(2**round(math.log(nside, 2))) nside = max(1, nside) healpix = anutil.radecdegtohealpix(ra, dec, nside) try: sky_location, created = SkyLocation.objects.get_or_create( nside=nside, healpix=healpix) except MultipleObjectsReturned: log.msg('Multiple SkyLocations for nside %i, healpix %i' % (nside, healpix)) # arbitrarily take the first one. sky_location = SkyLocation.objects.filter(nside=nside, healpix=healpix)[0] log.msg('SkyLocation:', sky_location) # Find bounds for the Calibration object. r0, r1, d0, d1 = wcs.radec_bounds() # Find cartesian coordinates ra *= math.pi / 180 dec *= math.pi / 180 tempr = math.cos(dec) x = tempr * math.cos(ra) y = tempr * math.sin(ra) z = math.sin(dec) r = radius / 180 * math.pi calib = Calibration(raw_tan=tan, ramin=r0, ramax=r1, decmin=d0, decmax=d1, x=x, y=y, z=z, r=r, sky_location=sky_location) calib.save() log.msg('Created Calibration', calib) job.calibration = calib job.save() # save calib before adding machine tags job.status = 'S' job.user_image.add_machine_tags(job) job.user_image.add_sky_objects(job) else: job.status = 'F' job.set_end_time() job.save() log.msg('Finished job', job.id) logmsg('Finished job', job.id) return job.id
from glob import glob import os from astrometry.util.util import Tan wcsfn = "/data2/nova/BACKUP-jobs/00000046/wcs.fits" axyfn = wcsfn.replace('wcs.fits', 'job.axy') dirname = os.path.basename(os.path.dirname(wcsfn)) wcs = Tan(wcsfn) r1,d1 = wcs.radec_center() R1 = wcs.radius() print "RA is ", r1 print "Dec is ", d1 print "radius is ", R1 inds = glob("/data1/INDEXES/4000/index-4001*") for j, ind in enumerate(inds): cmdline = 'query-starkd -v -o rdls4001-{0}.fits -r {1} -d {2} -R {3} {4}'.format(j, r1, d1, R1, ind) os.system(cmdline)
def _computeTransformation(self, img, ylo=0, yhi=-1): imwcs = img.getWcs() # Pre-compute the "grid-spread function" transformation matrix... H,W = self.shape if yhi == -1: yhi = H Ngrid = W*H iH,iW = img.shape Nim = iW*iH Lorder = 2 S = (Lorder * 2 + 3) if False: i0 = S/2 else: print 'Image', img.name print 'Image PSF', img.getPsf() psfw = img.getPsf().getRadius() scale = img.getWcs().pixel_scale() / self.wcs.pixel_scale() print 'Image pixel scale', img.getWcs().pixel_scale() print 'Model pixel scale', self.wcs.pixel_scale() print 'PSF extent', psfw, 'pixels' print 'pixel scale factor', scale print '->', psfw * scale, 'model pixels' print 'Increasing S from', S S += int(np.ceil(psfw*scale)) * 2 print 'to', S i0 = S/2 cmock = np.zeros((S,S), np.float32) cmock[i0,i0] = 1. if True: spsf = img.getPsf().scale(scale) print 'Scaled PSF', spsf cmock = spsf.applyTo(cmock) #print 'cmock' #print cmock cwcs = Tan(self.wcs) cwcs.set_imagesize(S, S) cx0,cy0 = self.wcs.crpix[0], self.wcs.crpix[1] rim = np.zeros((iH,iW), np.float32) X = {} for i in range(ylo, yhi): print 'Precomputing matrix for image', img.name, 'model row', i for j in range(W): #print 'Precomputing matrix for grid pixel', j,i cwcs.set_crpix(cx0 - j + i0, cy0 - i + i0) rim[:,:] = 0 ## weighted = 1 res = tan_wcs_resample(cwcs, imwcs.wcs, cmock, rim, weighted, Lorder) assert(res == 0) if False: outimg = img.getPsf().applyTo(rim).ravel() else: outimg = rim.ravel() if sum(outimg) == 0: continue I = np.flatnonzero((outimg > 0) * (img.getInvError().ravel() > 0)) if len(I) == 0: continue #if True: # sumr.ravel()[I] += outimg[I] xx,yy = (I % iW), (I / iW) x0,y0 = xx.min(), yy.min() nzh,nzw = 1 + yy.max() - y0, 1 + xx.max() - x0 NZ = ((x0, y0), (nzh, nzw)) NZI = (xx - x0) + (yy - y0) * nzw X[i*W+j] = (I, outimg[I], NZ, NZI) # if True: # print 'sumr range', sumr.min(), sumr.max() # sumr[sumr == 0] = 1. # mn,mx = 0.,0. # for (I, outim, NZ, NZI) in X.values(): # outim /= sumr.ravel()[I] # mx = max(outim.max(), mx) # mn = max(outim.min(), mn) # print 'Min,Max grid-spread function:', mn,mx return X
hsc.dec = [] for band in 'grz': pat = '/global/project/projectdirs/cosmo/work/hsc/dr1/wide/deepCoadd/HSC-%s/*/*/calexp-*.fits' % (band.upper()) #pat = 'HSC-%s/*/*/calexp-*.fits' % (band.upper()) fns = glob(pat) print('Band', band, ':', len(fns), 'files') pat2 = '/global/project/projectdirs/cosmo/work/hsc/dr1/deep/deepCoadd/HSC-%s/*/*/calexp-*.fits' % (band.upper()) fns2 = glob(pat2) print('Band', band, ':', len(fns2), 'files from deep') fns = fns + fns2 for fn in fns: hdr = fitsio.read_header(fn, ext=1) wcs = Tan(hdr) r,d = wcs.radec_center() hsc.ra.append(r) hsc.dec.append(d) for c in wcsvals: hsc.get(c).append(hdr.get(c.upper())) hsc.width.append(hdr['NAXIS1']) hsc.height.append(hdr['NAXIS2']) hsc.band.append(band) parts = fn.split('/') path = '/'.join(parts[-7:]) print(path) hsc.filename.append(path) hsc.to_np_arrays()
def plotarea(ra, dec, radius, name, prefix, tims=None, rds=[]): from astrometry.util.util import Tan W,H = 512,512 scale = (radius * 60. * 4) / float(W) print 'SDSS jpeg scale', scale imgfn = 'sdss-mosaic-%s.png' % prefix if not os.path.exists(imgfn): url = (('http://skyservice.pha.jhu.edu/DR9/ImgCutout/getjpeg.aspx?' + 'ra=%f&dec=%f&scale=%f&width=%i&height=%i') % (ra, dec, scale, W, H)) f = urllib2.urlopen(url) of,tmpfn = tempfile.mkstemp(suffix='.jpg') os.close(of) of = open(tmpfn, 'wb') of.write(f.read()) of.close() cmd = 'jpegtopnm %s | pnmtopng > %s' % (tmpfn, imgfn) os.system(cmd) # Create WCS header for it cd = scale / 3600. args = (ra, dec, W/2. + 0.5, H/2. + 0.5, -cd, 0., 0., -cd, W, H) wcs = Tan(*[float(x) for x in args]) plt.clf() I = plt.imread(imgfn) plt.imshow(I, interpolation='nearest', origin='lower') x,y = wcs.radec2pixelxy(ra, dec) R = radius * 60. / scale ax = plt.axis() plt.gca().add_artist(matplotlib.patches.Circle(xy=(x,y), radius=R, color='g', lw=3, alpha=0.5, fc='none')) if tims is not None: print 'Plotting outlines of', len(tims), 'images' for tim in tims: H,W = tim.shape twcs = tim.getWcs() px,py = [],[] for x,y in [(1,1),(W,1),(W,H),(1,H),(1,1)]: rd = twcs.pixelToPosition(x,y) xx,yy = wcs.radec2pixelxy(rd.ra, rd.dec) print 'x,y', x, y x1,y1 = twcs.positionToPixel(rd) print ' x1,y1', x1,y1 print ' r,d', rd.ra, rd.dec, print ' xx,yy', xx, yy px.append(xx) py.append(yy) plt.plot(px, py, 'g-', lw=3, alpha=0.5) # plot full-frame image outline too # px,py = [],[] # W,H = 2048,1489 # for x,y in [(1,1),(W,1),(W,H),(1,H),(1,1)]: # r,d = twcs.pixelToRaDec(x,y) # xx,yy = wcs.radec2pixelxy(r,d) # px.append(xx) # py.append(yy) # plt.plot(px, py, 'g-', lw=1, alpha=1.) if rds is not None: px,py = [],[] for ra,dec in rds: print 'ra,dec', ra,dec xx,yy = wcs.radec2pixelxy(ra, dec) px.append(xx) py.append(yy) plt.plot(px, py, 'go') plt.axis(ax) fn = '%s.png' % prefix plt.savefig(fn) print 'saved', fn
def plot(self, img = None, off = [0., 0.], extra = [], extra_lines = [], grid = True, scale = 1): field_w = self.wcs.get_width() field_h = self.wcs.get_height() try: scale = float(scale) except ValueError: if scale.startswith('deg'): scale = float(scale[3:]) / (self.wcs.pixel_scale() * field_w / 3600.0) else: raise # the field moved by given offset pixels from the position in self.wcs (crpix1, crpix2) = self.wcs.crpix ra2, dec2 = self.wcs.pixelxy2radec(crpix1 - off[1], crpix2 - off[0]) # plot extra area with the original image in the center xborder = field_w * (scale - 1) / 2.0 yborder = field_h * (scale - 1) / 2.0 nw = field_w * scale nh = field_h * scale new_wcs = Tan(self.wcs) new_wcs.set_crval(ra2, dec2) new_wcs.set_width(nw) new_wcs.set_height(nh) new_wcs.set_crpix(crpix1 + xborder, crpix2 + yborder) #thumbnail size and pos tw = int(field_w / scale) th = int(field_h / scale) tx = int(xborder / scale) ty = int(yborder / scale) plot = Plotstuff(outformat=PLOTSTUFF_FORMAT_PPM) plot.wcs = anwcs_new_tan(new_wcs) plot.scale_wcs(1.0 / scale) plot.set_size_from_wcs() plot.color = 'black' plot.alpha = 1.0 plot.plot('fill') plot.color = 'gray' plot_area_deg = new_wcs.pixel_scale() * scale * field_w / 3600.0 #print "plot area", plot_area_deg if grid: log_step = [1, 2, 5]; log_ra = int(np.floor(np.log10(plot_area_deg / (0.01 + math.cos(math.radians(dec2)))) * 3)) - 1 log_dec = int(np.floor(np.log10(plot_area_deg) * 3)) - 1 grid_step_ra = 10 ** int(log_ra / 3) * log_step[log_ra % 3] grid_step_dec = 10 ** int(log_dec / 3) * log_step[log_dec % 3] grid_step_ra = min(10, grid_step_ra) grid_step_dec = min(10, grid_step_dec) #print "grid", plot_area_deg, log_ra, log_dec, grid_step_ra, grid_step_dec plot.plot_grid(grid_step_ra, grid_step_dec, grid_step_ra, grid_step_dec) ann = plot.annotations ann.NGC = (plot_area_deg < 60) ann.constellations = (plot_area_deg > 10) ann.constellation_labels = (plot_area_deg > 10) ann.constellation_labels_long = False ann.bright = (plot_area_deg < 60) ann.ngc_fraction = 0.05 / scale ann.HD = False #ann.HD = (plot_area_deg < 9) #ann.HD_labels = (plot_area_deg < 3) #ann.hd_catalog = "hd.fits" if plot_area_deg < 9: tra,tdec,I2 = match_kdtree_catalog(ra2, dec2, plot_area_deg, "tycho2.kd") T = fits_table("tycho2.kd", hdu=6) for r,d,t1,t2,t3 in zip(tra,tdec, T.tyc1[I2], T.tyc2[I2], T.tyc3[I2]): if not new_wcs.is_inside(r, d): continue if plot_area_deg < 2: ann.add_target(r, d, 'tyc %i-%i-%i' % (t1,t2,t3)) else: ann.add_target(r, d, '') for (r, d, name) in extra: ann.add_target(r, d, name) for (r1, d1, r2, d2) in extra_lines: plot.move_to_radec(r1, d1) plot.line_to_radec(r2, d2) plot.stroke() plot.color = 'green' plot.lw = 2 plot.valign = 'B' plot.halign = 'C' plot.label_offset_x = 0; plot.label_offset_y = -20; plot.plot('annotations') # frame around the image if scale > 1: plot.color = 'blue' plot.polygon([(tx, ty), (tx + tw, ty), (tx + tw, ty + th), (tx, ty + th)]) plot.close_path() plot.stroke() plot_image = plot.get_image_as_numpy() del plot if img is not None and scale <= 8: bg = np.zeros_like(plot_image) if scale == 1: thumb = img else: thumb = cv2.resize(img, (tw, th)) if thumb.ndim > 2: bg[ty:ty+th, tx:tx+tw, 0:3] = thumb[:, :, 0:3] else: bg[ty:ty+th, tx:tx+tw, 0] = bg[ty:ty+th, tx:tx+tw, 1] = bg[ty:ty+th, tx:tx+tw, 2] = thumb plot_image = cv2.add(plot_image, bg) return plot_image
def ptf_exposure_metadata(filenames, hdus=None, trim=None): nan = np.nan primkeys = [('FILTER',''), ('RA', nan), ('DEC', nan), ('AIRMASS', nan), ('DATE-OBS', ''), ('EXPTIME', nan), ('EXPNUM', 0), ('MJD-OBS', 0), ('PROPID', ''), ] hdrkeys = [('AVSKY', nan), ('ARAWGAIN', nan), ('FWHM', nan), ('CRPIX1',nan), ('CRPIX2',nan), ('CRVAL1',nan), ('CRVAL2',nan), ('CD1_1',nan), ('CD1_2',nan), ('CD2_1',nan), ('CD2_2',nan), ('EXTNAME',''), ('CCDNAME',''), ('CCDNUM',''), ('CAMERA',''), ] otherkeys = [('IMAGE_FILENAME',''), ('IMAGE_HDU',0), ('HEIGHT',0),('WIDTH',0), ] allkeys = primkeys + hdrkeys + otherkeys #for each hdu and file, append ptf header info to vals vals = dict([(k,[]) for k,d in allkeys]) for i,fn in enumerate(filenames): print('Reading', (i+1), 'of', len(filenames), ':', fn) F = fitsio.FITS(fn) cpfn = fn if trim is not None: cpfn = cpfn.replace(trim, '') if hdus is not None: hdulist = hdus else: hdulist = range(0, len(F)) #loop through hdus for hdu in hdulist: for k,d in allkeys: #d is not used below if k in F[hdu].read_header().keys(): vals[k].append(F[hdu].read_header()[k]) else: continue #will be set below #special handling H,W = F[hdu].get_info()['dims'] vals['HEIGHT'].append(H) vals['WIDTH'].append(W) vals['IMAGE_HDU'].append(hdu) vals['AVSKY'].append(0.) #estimate of sky level, ok to set to 0 in legacypipe vals['EXTNAME'].append(os.path.basename(fn)[-8:-5]) #CCD id, ex) N16 for DECam vals['CCDNAME'][-1]= os.path.basename(fn)[-8:-5] vals['FILTER'][-1]= vals['FILTER'][-1].strip().lower() #unique ptf band name vals['EXPNUM'].append(0) #default value givein in function "exposure_metadata" vals['CAMERA'].append('ptf') #default value givein in function "exposure_metadata" vals['IMAGE_FILENAME'].append(os.path.basename(fn)) #diff naming convenctions between (DECaLS,PTF) map=[ ('RA', 'OBJRA'), ('DEC', 'OBJDEC'), ('MJD-OBS', 'OBSMJD'), ('PROPID', 'PTFPID'), ('ARAWGAIN', 'GAIN'), ('FWHM', 'MEDFWHM'), ('CCDNUM','CCDID'), ] for decal,ptf in map: try: vals[decal].append(F[hdu].read_header()[ptf]) except AttributeError: print "WARNING, could not find ",decal,"or",ptf #for k,d in allkeys: print "FINAL vals: k= ",k,"vals[k]= ",vals[k] #header info now stord in val dict T = fits_table() for k,d in allkeys: T.set(k.lower().replace('-','_'), np.array(vals[k])) #finish naming conventions T.filter = np.array([s.split()[0] for s in T.filter]) #KJB LEFT OFF HERE T.ra_bore = np.array([hmsstring2ra (s) for s in T.ra ]) T.dec_bore = np.array([dmsstring2dec(s) for s in T.dec]) T.ra = np.zeros(len(T)) T.dec = np.zeros(len(T)) for i in range(len(T)): W,H = T.width[i], T.height[i] wcs = Tan(T.crval1[i], T.crval2[i], T.crpix1[i], T.crpix2[i], T.cd1_1[i], T.cd1_2[i], T.cd2_1[i], T.cd2_2[i], float(W), float(H)) xc,yc = W/2.+0.5, H/2.+0.5 rc,dc = wcs.pixelxy2radec(xc,yc) T.ra [i] = rc T.dec[i] = dc #anything with type int64 crashes fits.write() T.expnum= T.expnum.astype(np.int16) T.image_hdu= T.image_hdu.astype(np.int16) T.height= T.height.astype(np.int16) T.width= T.width.astype(np.int16) #for c in T.columns(): #if type(T.get(c)[0]) is np.int64: T.c= T.c.astype(np.int16) #answer='yes' #else:answer='no' #print('column= ',c,"type= ",type(T.get(c)),"type is int64?",answer) #sanity check for c in T.columns(): print (c,T.get(c)) return T
def cutout_jpg(req): import tempfile import fitsio from astrometry.util.util import Tan from astrometry.util.resample import resample_with_wcs form = CutoutSearchForm(req.GET) if not form.is_valid(): return HttpResponse('failed to parse request') ra = form.cleaned_data['ra'] dec = form.cleaned_data['dec'] if ra is None or dec is None: return HttpResponse('RA and Dec arguments are required') size = form.cleaned_data['size'] if size is None: size = 100 else: size = min(256, size) # Ignoring this for now... # bandstr = form.cleaned_data['bands'] # bands = [int(c) for c in bandstr] # bands = [b for b in bands if b in [1,2,3,4]] version = form.cleaned_data['version'] radius = size/2. * 2.75/3600. tiles = unwise_tiles_near_radec(ra, dec, radius) tiles = list(tiles) pixscale = 2.75 / 3600. cowcs = Tan(*[float(x) for x in [ra, dec, 0.5 + size/2., 0.5 + size/2., -pixscale, 0., 0., pixscale, size, size]]) bands = [1,2] coims = [np.zeros((size,size), np.float32) for b in bands] con = np.zeros((size,size), int) for tile in tiles: coadd = tile.coadd dirnm = os.path.join(settings.DATA_DIR, version, coadd[:3], coadd) base = os.path.join(dirnm, 'unwise-%s' % coadd) subwcs = None ims = [] for band in bands: fn = str(base + '-w%i-img-m.fits' % band) if subwcs is None: wcs = Tan(fn) ok,x,y = wcs.radec2pixelxy(ra, dec) x = int(round(x-1.)) y = int(round(y-1.)) x0 = x - size/2 x1 = x0 + size y0 = y - size/2 y1 = y0 + size if x1 <= 0 or y1 <= 0: break if x0 >= wcs.get_width() or y0 >= wcs.get_height(): break x0 = max(x0, 0) y0 = max(y0, 0) x1 = min(x1, wcs.get_width()) y1 = min(y1, wcs.get_height()) subwcs = wcs.get_subimage(x0, y0, x1-x0, y1-y0) if subwcs is None: break img = fitsio.FITS(fn)[0][y0:y1, x0:x1] ims.append(img) if subwcs is None: continue try: Yo,Xo,Yi,Xi,rims = resample_with_wcs(cowcs, subwcs, ims, 3) except: continue for rim,co in zip(rims, coims): co[Yo,Xo] += rim con[Yo,Xo] += 1 for co in coims: co /= np.maximum(con, 1) rgb = np.zeros((size,size,3), np.uint8) lo,hi = -3,10 scale = 10. rgb[:,:,2] = np.clip(255. * ((coims[1] / scale) - lo) / (hi-lo), 0, 255) rgb[:,:,1] = np.clip(255. * (((coims[0]+coims[1])/2. / scale) - lo) / (hi-lo), 0, 255) rgb[:,:,0] = np.clip(255. * ((coims[0] / scale) - lo) / (hi-lo), 0, 255) f,tempfn = tempfile.mkstemp(suffix='.jpg') os.close(f) # import matplotlib # matplotlib.use('Agg') # import pylab as plt # plt.imsave(tempfn, rgb, interpolation='nearest', origin='lower') from PIL import Image pic = Image.fromarray(rgb) pic.save(tempfn) return send_file(tempfn, 'image/jpeg', unlink=True)
def get_unwise_tractor_image(basedir, tile, band, bandname=None, masked=True, **kwargs): ''' masked: read "-m" images, or "-u"? bandname: PhotoCal band name to use: default: "w%i" % band ''' if bandname is None: bandname = 'w%i' % band mu = 'm' if masked else 'u' # Allow multiple colon-separated unwise-coadd directories. basedirs = basedir.split(':') foundFiles = False for basedir in basedirs: thisdir = get_unwise_tile_dir(basedir, tile) base = os.path.join(thisdir, 'unwise-%s-w%i-' % (tile, band)) imfn = base + 'img-%s.fits' % mu ivfn = base + 'invvar-%s.fits.gz' % mu # ppfn = base + 'std-%s.fits.gz' % mu nifn = base + 'n-%s.fits.gz' % mu nufn = base + 'n-u.fits.gz' if not os.path.exists(imfn): print('Does not exist:', imfn) continue print('Reading', imfn) wcs = Tan(imfn) twcs = ConstantFitsWcs(wcs) F = fitsio.FITS(imfn) img = F[0] hdr = img.read_header() H,W = img.get_info()['dims'] H,W = int(H), int(W) roi = interpret_roi(twcs, (H,W), **kwargs) if roi is None: # No overlap with ROI return None # interpret_roi returns None or a tuple; drop the second element in the tuple. roi,nil = roi (x0,x1,y0,y1) = roi wcs = wcs.get_subimage(x0, y0, x1-x0, y1-y0) twcs = ConstantFitsWcs(wcs) roislice = (slice(y0,y1), slice(x0,x1)) img = img[roislice] if not os.path.exists(ivfn) and os.path.exists(ivfn.replace('.fits.gz', '.fits')): ivfn = ivfn.replace('.fits.gz','.fits') if not os.path.exists(nifn) and os.path.exists(nifn.replace('.fits.gz', '.fits')): nifn = nifn.replace('.fits.gz','.fits') if not os.path.exists(nufn) and os.path.exists(nufn.replace('.fits.gz', '.fits')): nufn = nufn.replace('.fits.gz','.fits') if not (os.path.exists(ivfn) and os.path.exists(nifn) and os.path.exists(nufn)): print('Files do not exist:', ivfn, nifn, nufn) continue foundFiles = True break if not foundFiles: raise IOError('unWISE files not found in ' + str(basedirs) + ' for tile ' + tile) print('Reading', ivfn) invvar = fitsio.FITS(ivfn)[0][roislice] if band == 4: # due to upsampling, effective invvar is smaller (the pixels # are correlated) invvar *= 0.25 #print 'Reading', ppfn #pp = fitsio.FITS(ppfn)[0][roislice] print('Reading', nifn) nims = fitsio.FITS(nifn)[0][roislice] if nufn == nifn: nuims = nims else: print('Reading', nufn) nuims = fitsio.FITS(nufn)[0][roislice] #print 'Median # ims:', np.median(nims) good = (nims > 0) invvar[np.logical_not(good)] = 0. sig1 = 1./np.sqrt(np.median(invvar[good])) # Load the average PSF model (generated by wise_psf.py) psffn = os.path.join(os.path.dirname(__file__), 'wise-psf-avg.fits') print('Reading', psffn) P = fits_table(psffn, hdu=band) psf = GaussianMixturePSF(P.amp, P.mean, P.var) sky = 0. tsky = ConstantSky(sky) # if opt.errfrac > 0: # nz = (iv > 0) # iv2 = np.zeros_like(invvar) # iv2[nz] = 1./(1./invvar[nz] + (img[nz] * opt.errfrac)**2) # print 'Increasing error estimate by', opt.errfrac, 'of image flux' # invvar = iv2 tim = Image(data=img, invvar=invvar, psf=psf, wcs=twcs, sky=tsky, photocal=LinearPhotoCal(1., band=bandname), name='unWISE %s W%i' % (tile, band)) tim.sig1 = sig1 tim.roi = roi tim.nims = nims tim.nuims = nuims tim.hdr = hdr if 'MJDMIN' in hdr and 'MJDMAX' in hdr: from tractor.tractortime import TAITime tim.mjdmin = hdr['MJDMIN'] tim.mjdmax = hdr['MJDMAX'] tim.time = TAITime(None, mjd=(tim.mjdmin + tim.mjdmax)/2.) return tim
def main(): import argparse parser = argparse.ArgumentParser() parser.add_argument('-o', '--out', dest='outfn', help='Output filename', default='TMP/nexp.fits') parser.add_argument('--merge', action='store_true', help='Merge sub-tables') parser.add_argument('--plot', action='store_true', help='Plot results') parser.add_argument('files', metavar='nexp-file.fits.gz', nargs='+', help='List of nexp files to process') opt = parser.parse_args() fns = opt.files if opt.merge: from astrometry.util.fits import merge_tables TT = [] for fn in fns: T = fits_table(fn) print(fn, '->', len(T)) TT.append(T) T = merge_tables(TT) T.writeto(opt.outfn) print('Wrote', opt.outfn) if opt.plot: T = fits_table(opt.files[0]) import pylab as plt import matplotlib ax = [360, 0, -21, 36] def radec_plot(): plt.axis(ax) plt.xlabel('RA (deg)') plt.xticks(np.arange(0, 361, 45)) plt.ylabel('Dec (deg)') gl = np.arange(361) gb = np.zeros_like(gl) from astrometry.util.starutil_numpy import lbtoradec rr, dd = lbtoradec(gl, gb) plt.plot(rr, dd, 'k-', alpha=0.5, lw=1) rr, dd = lbtoradec(gl, gb + 10) plt.plot(rr, dd, 'k-', alpha=0.25, lw=1) rr, dd = lbtoradec(gl, gb - 10) plt.plot(rr, dd, 'k-', alpha=0.25, lw=1) plt.figure(figsize=(8, 5)) plt.subplots_adjust(left=0.1, right=0.98, top=0.93) # Map of the tile centers we want to observe... O = fits_table('obstatus/decam-tiles_obstatus.fits') O.cut(O.in_desi == 1) rr, dd = np.meshgrid(np.linspace(ax[1], ax[0], 700), np.linspace(ax[2], ax[3], 200)) from astrometry.libkd.spherematch import match_radec I, J, d = match_radec(O.ra, O.dec, rr.ravel(), dd.ravel(), 1.) desimap = np.zeros(rr.shape, bool) desimap.flat[J] = True def desi_map(): # Show the DESI tile map in the background. from astrometry.util.plotutils import antigray plt.imshow(desimap, origin='lower', interpolation='nearest', extent=[ax[1], ax[0], ax[2], ax[3]], aspect='auto', cmap=antigray, vmax=8) for band in 'grz': plt.clf() desi_map() N = T.get('nexp_%s' % band) I = np.flatnonzero(N > 0) #cm = matplotlib.cm.get_cmap('jet', 6) #cm = matplotlib.cm.get_cmap('winter', 5) cm = matplotlib.cm.viridis cm = matplotlib.cm.get_cmap(cm, 5) plt.scatter(T.ra[I], T.dec[I], c=N[I], s=2, edgecolors='none', vmin=0.5, vmax=5.5, cmap=cm) radec_plot() cax = colorbar_axes(plt.gca(), frac=0.06) plt.colorbar(cax=cax, ticks=range(6)) #plt.colorbar(ticks=range(6)) plt.title('DECaLS DR3: Number of exposures in %s' % band) plt.savefig('nexp-%s.png' % band) plt.clf() desi_map() plt.scatter(T.ra, T.dec, c=T.get('nexp_%s' % band), s=2, edgecolors='none', vmin=0, vmax=2.) radec_plot() plt.colorbar() plt.title('DECaLS DR3: PSF size, band %s' % band) plt.savefig('psfsize-%s.png' % band) return 0 for col in ['nobjs', 'npsf', 'nsimp', 'nexp', 'ndev', 'ncomp']: plt.clf() desi_map() N = T.get(col) mx = np.percentile(N, 99.5) plt.scatter(T.ra, T.dec, c=N, s=2, edgecolors='none', vmin=0, vmax=mx) radec_plot() plt.colorbar() plt.title('DECaLS DR3: Number of objects of type %s' % col[1:]) plt.savefig('nobjs-%s.png' % col[1:]) Ntot = T.nobjs for col in ['npsf', 'nsimp', 'nexp', 'ndev', 'ncomp']: plt.clf() desi_map() N = T.get(col) / Ntot.astype(np.float32) mx = np.percentile(N, 99.5) plt.scatter(T.ra, T.dec, c=N, s=2, edgecolors='none', vmin=0, vmax=mx) radec_plot() plt.colorbar() plt.title('DECaLS DR3: Fraction of objects of type %s' % col[1:]) plt.savefig('fobjs-%s.png' % col[1:]) return 0 # fnpats = opt.files # fns = [] # for pat in fnpats: # pfns = glob(pat) # fns.extend(pfns) # print('Pattern', pat, '->', len(pfns), 'files') #fns = glob('coadd/*/*/*-nexp*') #fns = glob('coadd/000/*/*-nexp*') #fns = glob('coadd/000/0001*/*-nexp*') fns.sort() print(len(fns), 'nexp files') brickset = set() bricklist = [] gn = [] rn = [] zn = [] gnhist = [] rnhist = [] znhist = [] nnhist = 6 gdepth = [] rdepth = [] zdepth = [] ibricks = [] nsrcs = [] npsf = [] nsimp = [] nexp = [] ndev = [] ncomp = [] gpsfsize = [] rpsfsize = [] zpsfsize = [] ebv = [] gtrans = [] rtrans = [] ztrans = [] bricks = fits_table('survey-bricks.fits.gz') #sfd = SFDMap() W = H = 3600 # H=3600 # xx,yy = np.meshgrid(np.arange(W), np.arange(H)) unique = np.ones((H, W), bool) tlast = 0 for fn in fns: print('File', fn) words = fn.split('/') dirprefix = '/'.join(words[:-4]) print('Directory prefix:', dirprefix) words = words[-4:] brick = words[2] print('Brick', brick) if not brick in brickset: brickset.add(brick) bricklist.append(brick) gn.append(0) rn.append(0) zn.append(0) gnhist.append([0 for i in range(nnhist)]) rnhist.append([0 for i in range(nnhist)]) znhist.append([0 for i in range(nnhist)]) index = -1 ibrick = np.nonzero(bricks.brickname == brick)[0][0] ibricks.append(ibrick) tfn = os.path.join(dirprefix, 'tractor', brick[:3], 'tractor-%s.fits' % brick) print('Tractor filename', tfn) T = fits_table(tfn, columns=[ 'brick_primary', 'type', 'decam_psfsize', 'ebv', 'decam_mw_transmission' ]) T.cut(T.brick_primary) nsrcs.append(len(T)) types = Counter([t.strip() for t in T.type]) npsf.append(types['PSF']) nsimp.append(types['SIMP']) nexp.append(types['EXP']) ndev.append(types['DEV']) ncomp.append(types['COMP']) print('N sources', nsrcs[-1]) gpsfsize.append(np.median(T.decam_psfsize[:, 1])) rpsfsize.append(np.median(T.decam_psfsize[:, 2])) zpsfsize.append(np.median(T.decam_psfsize[:, 4])) ebv.append(np.median(T.ebv)) gtrans.append(np.median(T.decam_mw_transmission[:, 1])) rtrans.append(np.median(T.decam_mw_transmission[:, 2])) ztrans.append(np.median(T.decam_mw_transmission[:, 4])) br = bricks[ibrick] print('Computing unique brick pixels...') #wcs = Tan(fn, 0) #W,H = int(wcs.get_width()), int(wcs.get_height()) pixscale = 0.262 / 3600. wcs = Tan(br.ra, br.dec, W / 2. + 0.5, H / 2. + 0.5, -pixscale, 0., 0., pixscale, float(W), float(H)) import time t0 = time.clock() unique[:, :] = True find_unique_pixels(wcs, W, H, unique, br.ra1, br.ra2, br.dec1, br.dec2) # for i in range(W/2): # allin = True # lo,hi = i, W-i-1 # # one slice per side # side = slice(lo,hi+1) # top = (lo, side) # bot = (hi, side) # left = (side, lo) # right = (side, hi) # for slc in [top, bot, left, right]: # #print('xx,yy', xx[slc], yy[slc]) # rr,dd = wcs.pixelxy2radec(xx[slc]+1, yy[slc]+1) # U = (rr >= br.ra1 ) * (rr < br.ra2 ) * (dd >= br.dec1) * (dd < br.dec2) # #print('Pixel', i, ':', np.sum(U), 'of', len(U), 'pixels are unique') # allin *= np.all(U) # unique[slc] = U # if allin: # print('Scanned to pixel', i) # break t1 = time.clock() U = np.flatnonzero(unique) t2 = time.clock() print(len(U), 'of', W * H, 'pixels are unique to this brick') # #t3 = time.clock() #rr,dd = wcs.pixelxy2radec(xx+1, yy+1) # #t4 = time.clock() # #u = (rr >= br.ra1 ) * (rr < br.ra2 ) * (dd >= br.dec1) * (dd < br.dec2) # #t5 = time.clock() # #U2 = np.flatnonzero(u) #U2 = np.flatnonzero((rr >= br.ra1 ) * (rr < br.ra2 ) * # (dd >= br.dec1) * (dd < br.dec2)) #assert(np.all(U == U2)) #assert(len(U) == len(U2)) # #t6 = time.clock() # print(len(U2), 'of', W*H, 'pixels are unique to this brick') # #print(t0-tlast, 'other time') #tlast = time.clock() #t2 #print('t1:', t1-t0, 't2', t2-t1) # #print('t4:', t4-t3, 't5', t5-t4, 't6', t6-t5) # else: index = bricklist.index(brick) assert (index == len(bricklist) - 1) index = bricklist.index(brick) assert (index == len(bricklist) - 1) filepart = words[-1] filepart = filepart.replace('.fits.gz', '') print('File:', filepart) band = filepart[-1] assert (band in 'grz') nlist, nhist = dict(g=(gn, gnhist), r=(rn, rnhist), z=(zn, znhist))[band] upix = fitsio.read(fn).flat[U] med = np.median(upix) print('Band', band, ': Median', med) nlist[index] = med hist = nhist[index] for i in range(nnhist): if i < nnhist - 1: hist[i] = np.sum(upix == i) else: hist[i] = np.sum(upix >= i) assert (sum(hist) == len(upix)) print('Number of exposures histogram:', hist) ibricks = np.array(ibricks) print('Maximum number of sources:', max(nsrcs)) T = fits_table() T.brickname = np.array(bricklist) T.ra = bricks.ra[ibricks] T.dec = bricks.dec[ibricks] T.nexp_g = np.array(gn).astype(np.int16) T.nexp_r = np.array(rn).astype(np.int16) T.nexp_z = np.array(zn).astype(np.int16) T.nexphist_g = np.array(gnhist).astype(np.int32) T.nexphist_r = np.array(rnhist).astype(np.int32) T.nexphist_z = np.array(znhist).astype(np.int32) T.nobjs = np.array(nsrcs).astype(np.int16) T.npsf = np.array(npsf).astype(np.int16) T.nsimp = np.array(nsimp).astype(np.int16) T.nexp = np.array(nexp).astype(np.int16) T.ndev = np.array(ndev).astype(np.int16) T.ncomp = np.array(ncomp).astype(np.int16) T.psfsize_g = np.array(gpsfsize).astype(np.float32) T.psfsize_r = np.array(rpsfsize).astype(np.float32) T.psfsize_z = np.array(zpsfsize).astype(np.float32) T.ebv = np.array(ebv).astype(np.float32) T.trans_g = np.array(gtrans).astype(np.float32) T.trans_r = np.array(rtrans).astype(np.float32) T.trans_z = np.array(ztrans).astype(np.float32) T.writeto(opt.outfn)
def main(): ra = 126.925 dec = 21.4833 itune1 = 5 itune2 = 5 ntune = 2 run = [4517,4576,4576] field = [103,99,100] camcol = [2,6,6] bands=['r'] bandname = 'r' flipBands = ['r'] rerun = 0 TI = [] sources = [] table = pyfits.open("J082742.02+212844.7-r.fits") table.info() header = table[0].header data = table[0].data invvar=table[1].data skyobj = ba.ConstantSky(header['skyval']) psffn = 'J082742.02+212844.7-r-bpsf.fits.gz' psfimg = pyfits.open(psffn)[0].data print 'PSF image shape', psfimg.shape # number of Gaussian components PS = psfimg.shape[0] K = 3 w,mu,sig = em_init_params(K, None, None, None) II = psfimg.copy() II /= II.sum() # HACK II = np.maximum(II, 0) print 'Multi-Gaussian PSF fit...' xm,ym = -(PS/2), -(PS/2) em_fit_2d(II, xm, ym, w, mu, sig) print 'w,mu,sig', w,mu,sig psf = GaussianMixturePSF(w, mu, sig) sources = [] # for run,camcol,field in zip(run,camcol,field): # sources.append(st.get_tractor_sources(run,camcol,field,bandname,bands=bands)) wcs = Tan("J082742.02+212844.7-r.fits",0) wcs = FitsWcs(wcs) wcs.setX0Y0(1.,1.) photocal = ba.NasaSloanPhotoCal(bandname) #Also probably not right TI.append(en.Image(data=data,invvar=invvar,sky=skyobj,psf=psf,wcs=wcs,photocal=photocal,name = "NASA-Sloan Test")) lvl = logging.DEBUG logging.basicConfig(level=lvl,format='%(message)s',stream=sys.stdout) tims = [TI[0]] tractor = st.SDSSTractor(tims) for source in sources: tractor.addSources(source) zr = np.array([-5.,+5.])# * info['skysig'] print bands prefix = 'ngc2595' # saveAll('initial-'+prefix, tractor,zr,flipBands,debug=True) bright = None lowbright = 1000 sources=[] for timg,sources in zip(tims,sources): wcs = timg.getWcs() xtr,ytr = wcs.positionToPixel(RaDecPos(ra,dec)) print xtr,ytr xt = xtr yt = ytr r = 250. for src in sources: xs,ys = wcs.positionToPixel(src.getPosition(),src) if (xs-xt)**2+(ys-yt)**2 <= r**2: print "Removed:", src print xs,ys tractor.removeSource(src) # saveAll('removed-'+prefix, tractor,zr,flipBands,debug=True) newShape = sg.GalaxyShape(30.,1.,0.) newBright = ba.Mags(r=15.0,g=15.0,u=15.0,z=15.0,i=15.0) EG = st.ExpGalaxy(RaDecPos(ra,dec),newBright,newShape) print EG tractor.addSource(EG) saveAll('added-'+prefix,tractor,zr,flipBands,debug=True) plotInvvar('added-'+prefix,tractor) for i in range(itune1): if (i % 5 == 0): tractor.optimizeCatalogLoop(nsteps=1,srcs=[EG],sky=True) else: tractor.optimizeCatalogLoop(nsteps=1,srcs=[EG],sky=False) tractor.changeInvvar(9.) tractor.clearCache() saveAll('itune1-%d-' % (i+1)+prefix,tractor,zr,flipBands,debug=True) plotInvvar('itune1-%d-' % (i+1)+prefix,tractor) CGPos = EG.getPosition() CGShape = EG.getShape() EGBright = EG.getBrightness() print EGBright CGg = EGBright[0]*1.25 CGi = EGBright[1]*1.25 CGr = EGBright[2]*1.25 CGu = EGBright[3]*1.25 CGz = EGBright[4]*1.25 CGBright = ba.Mags(r=CGr,g=CGg,u=CGu,z=CGz,i=CGi) print EGBright print CGBright CG = st.CompositeGalaxy(CGPos,CGBright,CGShape,CGBright,CGShape) tractor.removeSource(EG) tractor.addSource(CG) for i in range(itune2): if (i % 5 == 0): tractor.optimizeCatalogLoop(nsteps=1,srcs=[CG],sky=True) else: tractor.optimizeCatalogLoop(nsteps=1,srcs=[CG],sky=False) tractor.changeInvvar(9.) tractor.clearCache() saveAll('itune2-%d-' % (i+1)+prefix,tractor,zr,flipBands,debug=True) plotInvvar('itune2-%d-' % (i+1)+prefix,tractor) for i in range(ntune): tractor.optimizeCatalogLoop(nsteps=1,sky=True) saveAll('ntune-%d-' % (i+1)+prefix,tractor,zr,flipBands,debug=True) tractor.clearCache() makeflipbook(prefix,len(tractor.getImages()),itune1,itune2,ntune)
if not os.path.exists(qfn): if not os.path.exists(hfn): print('Reading', fn) halfsize(fn, hfn) #print('Wrote', hfn) halfsize(hfn, qfn) #print('Wrote', qfn) fn = qfn #fn = os.path.join('wise-coadds', brick[:2], brick[:4], '%s_ac51' % brick, # '%s_ac51-w%i-int-3.fits' % (brick, band)) print('Reading', fn) I = fitsio.read(fn) bwcs = Tan(fn, 0) bh,bw = I.shape print('Image shape', bh,bw) assert(np.all(np.isfinite(I))) xx,yy = np.meshgrid(np.arange(bw), np.arange(bh)) rr,dd = bwcs.pixelxy2radec(xx, yy) #print('RA,Dec range', rr.min(), rr.max(), dd.min(), dd.max()) ll,bb = radectolb(rr.ravel(), dd.ravel()) #print('L,B range', ll.min(), ll.max(), bb.min(), bb.max()) ll = ll.reshape(rr.shape) bb = bb.reshape(rr.shape) ok,ox,oy = wcs.radec2pixelxy(ll, bb) #print('Unique ok:', np.unique(ok))
def exposure_metadata(filenames, hdus=None, trim=None): ''' Creates a CCD table row object by reading metadata from a FITS file header. Parameters ---------- filenames : list of strings Filenames to read hdus : list of integers; None to read all HDUs List of FITS extensions (HDUs) to read trim : string String to trim off the start of the *filenames* for the *image_filename* table entry Returns ------- A table that looks like the CCDs table. ''' nan = np.nan primkeys = [('FILTER',''), ('RA', nan), ('DEC', nan), ('AIRMASS', nan), ('DATE-OBS', ''), ('EXPTIME', nan), ('EXPNUM', 0), ('MJD-OBS', 0), ('PROPID', ''), ('INSTRUME', ''), ('SEEING', nan), ] hdrkeys = [('AVSKY', nan), ('ARAWGAIN', nan), ('FWHM', nan), ('CRPIX1',nan), ('CRPIX2',nan), ('CRVAL1',nan), ('CRVAL2',nan), ('CD1_1',nan), ('CD1_2',nan), ('CD2_1',nan), ('CD2_2',nan), ('EXTNAME',''), ('CCDNUM',''), ] otherkeys = [('IMAGE_FILENAME',''), ('IMAGE_HDU',0), ('HEIGHT',0),('WIDTH',0), ] allkeys = primkeys + hdrkeys + otherkeys vals = dict([(k,[]) for k,d in allkeys]) for i,fn in enumerate(filenames): print('Reading', (i+1), 'of', len(filenames), ':', fn) F = fitsio.FITS(fn) primhdr = F[0].read_header() expstr = '%08i' % primhdr.get('EXPNUM') cpfn = fn if trim is not None: cpfn = cpfn.replace(trim, '') print('CP fn', cpfn) if hdus is not None: hdulist = hdus else: hdulist = range(1, len(F)) for hdu in hdulist: hdr = F[hdu].read_header() info = F[hdu].get_info() #'extname': 'S1', 'dims': [4146L, 2160L] H,W = info['dims'] for k,d in primkeys: vals[k].append(primhdr.get(k, d)) for k,d in hdrkeys: vals[k].append(hdr.get(k, d)) vals['IMAGE_FILENAME'].append(cpfn) vals['IMAGE_HDU'].append(hdu) vals['WIDTH'].append(int(W)) vals['HEIGHT'].append(int(H)) T = fits_table() for k,d in allkeys: T.set(k.lower().replace('-','_'), np.array(vals[k])) #T.about() # DECam: INSTRUME = 'DECam' T.rename('instrume', 'camera') T.camera = np.array([t.lower().strip() for t in T.camera]) #T.rename('extname', 'ccdname') T.ccdname = np.array([t.strip() for t in T.extname]) T.filter = np.array([s.split()[0] for s in T.filter]) T.ra_bore = np.array([hmsstring2ra (s) for s in T.ra ]) T.dec_bore = np.array([dmsstring2dec(s) for s in T.dec]) T.ra = np.zeros(len(T)) T.dec = np.zeros(len(T)) for i in range(len(T)): W,H = T.width[i], T.height[i] wcs = Tan(T.crval1[i], T.crval2[i], T.crpix1[i], T.crpix2[i], T.cd1_1[i], T.cd1_2[i], T.cd2_1[i], T.cd2_2[i], float(W), float(H)) xc,yc = W/2.+0.5, H/2.+0.5 rc,dc = wcs.pixelxy2radec(xc,yc) T.ra [i] = rc T.dec[i] = dc return T
def main(): ''' This function generates the plots in the paper. Some files and directories are assumed to exist in the current directory: * WISE atlas tiles, from http://unwise.me/data/allsky-atlas.fits * unwise-neo1-coadds, from http://unwise.me/data/neo1/ * unwise-neo1-coadds-half, unwise-neo1-coadds-quarter: directories ''' # First, create the WCS into which we want to render # degrees width to render in galactic coords # |l| < 60 # |b| < 30 width = 120 # ~2 arcmin per pixel W = int(width * 60.) / 2 H = W/2 zoom = 360. / width wcs = anwcs_create_hammer_aitoff(0., 0., zoom, W, H, 0) # Select WISE tiles that overlap. This atlas table is available # from http://unwise.me/data/allsky-atlas.fits # Select WISE tiles that overlap. T = fits_table('allsky-atlas.fits') print(len(T), 'tiles total') T.ll,T.bb = radectolb(T.ra, T.dec) I = np.flatnonzero(np.logical_or(T.ll < width+1, T.ll > (360-width-1)) * (T.bb > -width/2-1) * (T.bb < width/2+1)) T.cut(I) print(len(I), 'tiles in L,B range') # Create a coadd for each WISE band lbpat = 'unwise-neo1-w%i-lb.fits' imgs = [] for band in [1,2]: outfn = lbpat % (band) if os.path.exists(outfn): print('Exists:', outfn) img = fitsio.read(outfn) imgs.append(img) continue coimg = np.zeros((H,W), np.float32) conimg = np.zeros((H,W), np.float32) for i,brick in enumerate(T.coadd_id): # We downsample by 2, twice, just to make repeat runs a # little faster. # unWISE fn = os.path.join('unwise-neo1-coadds', brick[:3], brick, 'unwise-%s-w%i-img-u.fits' % (brick, band)) qfn = os.path.join('unwise-neo1-coadds-quarter', 'unwise-%s-w%i.fits' % (brick, band)) hfn = os.path.join('unwise-neo1-coadds-half', 'unwise-%s-w%i.fits' % (brick, band)) if not os.path.exists(qfn): if not os.path.exists(hfn): print('Reading', fn) halfsize(fn, hfn) halfsize(hfn, qfn) fn = qfn print('Reading', fn) img = fitsio.read(fn) bwcs = Tan(fn, 0) bh,bw = img.shape # Coadd each unWISE pixel into the nearest target pixel. xx,yy = np.meshgrid(np.arange(bw), np.arange(bh)) rr,dd = bwcs.pixelxy2radec(xx, yy) ll,bb = radectolb(rr.ravel(), dd.ravel()) ll = ll.reshape(rr.shape) bb = bb.reshape(rr.shape) ok,ox,oy = wcs.radec2pixelxy(ll, bb) ox = np.round(ox - 1).astype(int) oy = np.round(oy - 1).astype(int) K = (ox >= 0) * (ox < W) * (oy >= 0) * (oy < H) * ok #print('ok:', np.unique(ok), 'x', ox.min(), ox.max(), 'y', oy.min(), oy.max()) assert(np.all(np.isfinite(img))) if np.sum(K) == 0: # no overlap print('No overlap') continue np.add.at( coimg, (oy[K], ox[K]), img[K]) np.add.at(conimg, (oy[K], ox[K]), 1) img = coimg / np.maximum(conimg, 1) # Hack -- write and then read FITS WCS header. fn = 'wiselb.wcs' wcs.writeto(fn) hdr = fitsio.read_header(fn) hdr['CTYPE1'] = 'GLON-AIT' hdr['CTYPE2'] = 'GLAT-AIT' fitsio.write(outfn, img, header=hdr, clobber=True) fitsio.write(outfn.replace('.fits', '-n.fits'), conimg, header=hdr, clobber=True) imgs.append(img) w1,w2 = imgs # Get/confirm L,B bounds... H,W = w1.shape print('Image size', W, 'x', H) ok,l1,b1 = wcs.pixelxy2radec(1, (H+1)/2.) ok,l2,b2 = wcs.pixelxy2radec(W, (H+1)/2.) ok,l3,b3 = wcs.pixelxy2radec((W+1)/2., 1) ok,l4,b4 = wcs.pixelxy2radec((W+1)/2., H) print('L,B', (l1,b1), (l2,b2), (l3,b3), (l4,b4)) llo,lhi = l2,l1+360 blo,bhi = b3,b4 # Set plot sizes plt.figure(1, figsize=(10,5)) plt.subplots_adjust(left=0.1, right=0.95, bottom=0.1, top=0.95) plt.figure(2, figsize=(5,5)) plt.subplots_adjust(left=0.11, right=0.96, bottom=0.1, top=0.95) suffix = '.pdf' rgb = wise_rgb(w1, w2) xlo,ylo = 0,0 plt.figure(1) plt.clf() plt.imshow(rgb, origin='lower', interpolation='nearest') lbticks(wcs, xlo, ylo, lticks=[60,30,0,330,300], bticks=[-30,-15,0,15,30]) plt.savefig('xbulge-00' + suffix) # Compute the median of each row as a crude way of suppressing the # Galactic plane medy1 = np.median(w1, axis=1) medy2 = np.median(w2, axis=1) rgb = wise_rgb(w1 - medy1[:,np.newaxis], w2 - medy2[:,np.newaxis]) # Zoom in a bit for Galactic plane subtracted version lhi,llo,blo,bhi = 40, 320, -20, 20 okxy = np.array([wcs.radec2pixelxy(l,b) for l,b in [ (llo, blo), (llo, bhi), (lhi, blo), (lhi, bhi)]]) xlo = int(np.floor(min(okxy[:,-2]))) xhi = int(np.ceil (max(okxy[:,-2]))) ylo = int(np.floor(min(okxy[:,-1]))) yhi = int(np.ceil (max(okxy[:,-1]))) plt.clf() plt.imshow(rgb[ylo:yhi, xlo:xhi, :],origin='lower', interpolation='nearest') #lbticks(wcs, xlo, ylo, lticks=[40,20,0,340,320], bticks=[-20,-10,0,10,20]) lbticks(wcs, xlo, ylo, lticks=[30,15,0,345,330], bticks=[-20,-10,0,10,20]) plt.savefig('xbulge-01' + suffix) # Zoom in on the core lhi,llo,blo,bhi = 15, 345, -15, 15 ok,x1,y1 = wcs.radec2pixelxy(llo, blo) ok,x2,y2 = wcs.radec2pixelxy(llo, bhi) ok,x3,y3 = wcs.radec2pixelxy(lhi, blo) ok,x4,y4 = wcs.radec2pixelxy(lhi, bhi) xlo = int(np.floor(min(x1,x2,x3,x4))) xhi = int(np.ceil (max(x1,x2,x3,x4))) ylo = int(np.floor(min(y1,y2,y3,y4))) yhi = int(np.ceil (max(y1,y2,y3,y4))) print('xlo,ylo', xlo, ylo) w1 = w1[ylo:yhi, xlo:xhi] w2 = w2[ylo:yhi, xlo:xhi] plt.figure(2) # Apply color cut w1mag = -2.5*(np.log10(w1) - 9.) w2mag = -2.5*(np.log10(w2) - 9.) cc = w1mag - w2mag goodcolor = np.isfinite(cc) mlo,mhi = np.percentile(cc[goodcolor], [5,95]) print('W1 - W2 color masks:', mlo,mhi) mask = goodcolor * (cc > mlo) * (cc < mhi) plt.clf() rgb = wise_rgb(w1, w2) plt.imshow(rgb, origin='lower', interpolation='nearest') lbticks(wcs, xlo,ylo) plt.title('Data') plt.savefig('xbulge-fit-data' + suffix) plt.clf() rgb = wise_rgb(w1 * mask, w2 * mask) plt.imshow(rgb, origin='lower', interpolation='nearest') lbticks(wcs, xlo,ylo) plt.title('Data (masked)') plt.savefig('xbulge-fit-masked' + suffix) ie = mask.astype(np.float32) from tractor import (Image, NCircularGaussianPSF, LinearPhotoCal, Tractor, PixPos, Fluxes) from tractor.galaxy import ExpGalaxy, GalaxyShape # Create Tractor images tim1 = Image(data=w1 * mask, inverr=ie, psf=NCircularGaussianPSF([1.],[1.]), photocal=LinearPhotoCal(1., 'w1')) tim2 = Image(data=w2 * mask, inverr=ie, psf=NCircularGaussianPSF([1.],[1.]), photocal=LinearPhotoCal(1., 'w2')) H,W = w1.shape gal = ExpGalaxy(PixPos(W/2, H/2), Fluxes(w1=w1.sum(), w2=w2.sum()), GalaxyShape(200, 0.4, 90.)) tractor = Tractor([tim1, tim2],[gal]) # fitsio.write('data-w1.fits', w1 * mask, clobber=True) # fitsio.write('data-w2.fits', w2 * mask, clobber=True) # fitsio.write('mask.fits', mask.astype(np.uint8), clobber=True) # Optimize galaxy model tractor.freezeParam('images') for step in range(50): dlnp,x,alpha = tractor.optimize() print('dlnp', dlnp) print('x', x) print('alpha', alpha) print('Galaxy', gal) if dlnp == 0: break # Get galaxy model images, compute residuals mod1 = tractor.getModelImage(0) resid1 = w1 - mod1 mod2 = tractor.getModelImage(1) resid2 = w2 - mod2 rgb = wise_rgb(mod1, mod2) plt.clf() plt.imshow(rgb, origin='lower', interpolation='nearest') lbticks(wcs, xlo,ylo) plt.title('Model') plt.savefig('xbulge-fit-model' + suffix) rgb = resid_rgb(resid1, resid2) plt.clf() plt.imshow(rgb, origin='lower', interpolation='nearest') lbticks(wcs, xlo,ylo) plt.title('Residuals') plt.savefig('xbulge-fit-resid' + suffix) rgb = resid_rgb(resid1*mask, resid2*mask) plt.clf() plt.imshow(rgb, origin='lower', interpolation='nearest') lbticks(wcs, xlo,ylo) plt.title('Residuals (masked)') plt.savefig('xbulge-fit-residmasked' + suffix) # fitsio.write('resid1.fits', resid1, clobber=True) # fitsio.write('resid2.fits', resid2, clobber=True) # Compute median-smoothed residuals fr1 = np.zeros_like(resid1) fr2 = np.zeros_like(resid2) median_smooth(resid1, np.logical_not(mask), 25, fr1) median_smooth(resid2, np.logical_not(mask), 25, fr2) rgb = resid_rgb(fr1, fr2) plt.clf() plt.imshow(rgb, origin='lower', interpolation='nearest') lbticks(wcs, xlo,ylo) plt.title('Residuals (smoothed)') plt.savefig('xbulge-fit-smooth2' + suffix)
def main(outfn='ccds-annotated.fits', ccds=None): decals = Decals() if ccds is None: ccds = decals.get_ccds() # File from the "observing" svn repo: # https://desi.lbl.gov/svn/decam/code/observing/trunk tiles = fits_table('decam-tiles_obstatus.fits') #ccds.cut(np.arange(100)) #print("HACK!") #ccds.cut(np.array([name in ['N15', 'N16', 'N21', 'N9'] # for name in ccds.ccdname]) * # ccds.expnum == 229683) I = decals.photometric_ccds(ccds) ccds.photometric = np.zeros(len(ccds), bool) ccds.photometric[I] = True I = decals.apply_blacklist(ccds) ccds.blacklist_ok = np.zeros(len(ccds), bool) ccds.blacklist_ok[I] = True ccds.good_region = np.empty((len(ccds), 4), np.int16) ccds.good_region[:,:] = -1 ccds.ra0 = np.zeros(len(ccds), np.float64) ccds.dec0 = np.zeros(len(ccds), np.float64) ccds.ra1 = np.zeros(len(ccds), np.float64) ccds.dec1 = np.zeros(len(ccds), np.float64) ccds.ra2 = np.zeros(len(ccds), np.float64) ccds.dec2 = np.zeros(len(ccds), np.float64) ccds.ra3 = np.zeros(len(ccds), np.float64) ccds.dec3 = np.zeros(len(ccds), np.float64) ccds.dra = np.zeros(len(ccds), np.float32) ccds.ddec = np.zeros(len(ccds), np.float32) ccds.ra_center = np.zeros(len(ccds), np.float64) ccds.dec_center = np.zeros(len(ccds), np.float64) ccds.sig1 = np.zeros(len(ccds), np.float32) ccds.meansky = np.zeros(len(ccds), np.float32) ccds.stdsky = np.zeros(len(ccds), np.float32) ccds.maxsky = np.zeros(len(ccds), np.float32) ccds.minsky = np.zeros(len(ccds), np.float32) ccds.pixscale_mean = np.zeros(len(ccds), np.float32) ccds.pixscale_std = np.zeros(len(ccds), np.float32) ccds.pixscale_max = np.zeros(len(ccds), np.float32) ccds.pixscale_min = np.zeros(len(ccds), np.float32) ccds.psfnorm_mean = np.zeros(len(ccds), np.float32) ccds.psfnorm_std = np.zeros(len(ccds), np.float32) ccds.galnorm_mean = np.zeros(len(ccds), np.float32) ccds.galnorm_std = np.zeros(len(ccds), np.float32) gaussgalnorm = np.zeros(len(ccds), np.float32) # 2nd moments ccds.psf_mx2 = np.zeros(len(ccds), np.float32) ccds.psf_my2 = np.zeros(len(ccds), np.float32) ccds.psf_mxy = np.zeros(len(ccds), np.float32) # ccds.psf_a = np.zeros(len(ccds), np.float32) ccds.psf_b = np.zeros(len(ccds), np.float32) ccds.psf_theta = np.zeros(len(ccds), np.float32) ccds.psf_ell = np.zeros(len(ccds), np.float32) ccds.humidity = np.zeros(len(ccds), np.float32) ccds.outtemp = np.zeros(len(ccds), np.float32) ccds.tileid = np.zeros(len(ccds), np.int32) ccds.tilepass = np.zeros(len(ccds), np.uint8) ccds.tileebv = np.zeros(len(ccds), np.float32) plvers = [] for iccd,ccd in enumerate(ccds): im = decals.get_image_object(ccd) print('Reading CCD %i of %i:' % (iccd+1, len(ccds)), im) X = im.get_good_image_subregion() for i,x in enumerate(X): if x is not None: ccds.good_region[iccd,i] = x W,H = ccd.width, ccd.height psf = None wcs = None sky = None try: tim = im.get_tractor_image(pixPsf=True, splinesky=True, subsky=False, pixels=False) except: import traceback traceback.print_exc() plvers.append('') continue if tim is None: plvers.append('') continue psf = tim.psf wcs = tim.wcs.wcs sky = tim.sky hdr = tim.primhdr # print('Got PSF', psf) # print('Got sky', type(sky)) # print('Got WCS', wcs) ccds.humidity[iccd] = hdr.get('HUMIDITY') ccds.outtemp[iccd] = hdr.get('OUTTEMP') ccds.sig1[iccd] = tim.sig1 plvers.append(tim.plver) obj = hdr.get('OBJECT') # parse 'DECaLS_15150_r' words = obj.split('_') tile = None if len(words) == 3 and words[0] == 'DECaLS': try: tileid = int(words[1]) tile = tiles[tileid - 1] if tile.tileid != tileid: I = np.flatnonzero(tile.tileid == tileid) tile = tiles[I[0]] except: pass if tile is not None: ccds.tileid [iccd] = tile.tileid ccds.tilepass[iccd] = tile.get('pass') ccds.tileebv [iccd] = tile.ebv_med # Instantiate PSF on a grid S = 32 xx = np.linspace(1+S, W-S, 5) yy = np.linspace(1+S, H-S, 5) xx,yy = np.meshgrid(xx, yy) psfnorms = [] galnorms = [] for x,y in zip(xx.ravel(), yy.ravel()): p = im.psf_norm(tim, x=x, y=y) g = im.galaxy_norm(tim, x=x, y=y) psfnorms.append(p) galnorms.append(g) ccds.psfnorm_mean[iccd] = np.mean(psfnorms) ccds.psfnorm_std [iccd] = np.std (psfnorms) ccds.galnorm_mean[iccd] = np.mean(galnorms) ccds.galnorm_std [iccd] = np.std (galnorms) # PSF in center of field cx,cy = (W+1)/2., (H+1)/2. p = psf.getPointSourcePatch(cx, cy).patch ph,pw = p.shape px,py = np.meshgrid(np.arange(pw), np.arange(ph)) psum = np.sum(p) # print('psum', psum) p /= psum # centroids cenx = np.sum(p * px) ceny = np.sum(p * py) # print('cenx,ceny', cenx,ceny) # second moments x2 = np.sum(p * (px - cenx)**2) y2 = np.sum(p * (py - ceny)**2) xy = np.sum(p * (px - cenx)*(py - ceny)) # semi-major/minor axes and position angle theta = np.rad2deg(np.arctan2(2 * xy, x2 - y2) / 2.) theta = np.abs(theta) * np.sign(xy) s = np.sqrt(((x2 - y2)/2.)**2 + xy**2) a = np.sqrt((x2 + y2) / 2. + s) b = np.sqrt((x2 + y2) / 2. - s) ell = 1. - b/a # print('PSF second moments', x2, y2, xy) # print('PSF position angle', theta) # print('PSF semi-axes', a, b) # print('PSF ellipticity', ell) ccds.psf_mx2[iccd] = x2 ccds.psf_my2[iccd] = y2 ccds.psf_mxy[iccd] = xy ccds.psf_a[iccd] = a ccds.psf_b[iccd] = b ccds.psf_theta[iccd] = theta ccds.psf_ell [iccd] = ell # Galaxy norm using Gaussian approximation of PSF. realpsf = tim.psf tim.psf = im.read_psf_model(0, 0, gaussPsf=True, psf_sigma=tim.psf_sigma) gaussgalnorm[iccd] = im.galaxy_norm(tim, x=cx, y=cy) tim.psf = realpsf # Sky mod = np.zeros((ccd.height, ccd.width), np.float32) sky.addTo(mod) ccds.meansky[iccd] = np.mean(mod) ccds.stdsky[iccd] = np.std(mod) ccds.maxsky[iccd] = mod.max() ccds.minsky[iccd] = mod.min() # WCS ccds.ra0[iccd],ccds.dec0[iccd] = wcs.pixelxy2radec(1, 1) ccds.ra1[iccd],ccds.dec1[iccd] = wcs.pixelxy2radec(1, H) ccds.ra2[iccd],ccds.dec2[iccd] = wcs.pixelxy2radec(W, H) ccds.ra3[iccd],ccds.dec3[iccd] = wcs.pixelxy2radec(W, 1) midx, midy = (W+1)/2., (H+1)/2. rc,dc = wcs.pixelxy2radec(midx, midy) ra,dec = wcs.pixelxy2radec([1,W,midx,midx], [midy,midy,1,H]) ccds.dra [iccd] = max(degrees_between(ra, dc+np.zeros_like(ra), rc, dc)) ccds.ddec[iccd] = max(degrees_between(rc+np.zeros_like(dec), dec, rc, dc)) ccds.ra_center [iccd] = rc ccds.dec_center[iccd] = dc # Compute scale change across the chip # how many pixels to step step = 10 xx = np.linspace(1+step, W-step, 5) yy = np.linspace(1+step, H-step, 5) xx,yy = np.meshgrid(xx, yy) pixscale = [] for x,y in zip(xx.ravel(), yy.ravel()): sx = [x-step, x-step, x+step, x+step, x-step] sy = [y-step, y+step, y+step, y-step, y-step] sr,sd = wcs.pixelxy2radec(sx, sy) rc,dc = wcs.pixelxy2radec(x, y) # project around a tiny little TAN WCS at (x,y), with 1" pixels locwcs = Tan(rc, dc, 0., 0., 1./3600, 0., 0., 1./3600, 1., 1.) ok,lx,ly = locwcs.radec2pixelxy(sr, sd) #print('local x,y:', lx, ly) A = polygon_area((lx, ly)) pixscale.append(np.sqrt(A / (2*step)**2)) # print('Pixel scales:', pixscale) ccds.pixscale_mean[iccd] = np.mean(pixscale) ccds.pixscale_min[iccd] = min(pixscale) ccds.pixscale_max[iccd] = max(pixscale) ccds.pixscale_std[iccd] = np.std(pixscale) ccds.plver = np.array(plvers) sfd = tractor.sfd.SFDMap() allbands = 'ugrizY' filts = ['%s %s' % ('DES', f) for f in allbands] wisebands = ['WISE W1', 'WISE W2', 'WISE W3', 'WISE W4'] ebv,ext = sfd.extinction(filts + wisebands, ccds.ra_center, ccds.dec_center, get_ebv=True) ext = ext.astype(np.float32) ccds.ebv = ebv.astype(np.float32) ccds.decam_extinction = ext[:,:len(allbands)] ccds.wise_extinction = ext[:,len(allbands):] # Depth detsig1 = ccds.sig1 / ccds.psfnorm_mean depth = 5. * detsig1 # that's flux in nanomaggies -- convert to mag ccds.psfdepth = -2.5 * (np.log10(depth) - 9) detsig1 = ccds.sig1 / ccds.galnorm_mean depth = 5. * detsig1 # that's flux in nanomaggies -- convert to mag ccds.galdepth = -2.5 * (np.log10(depth) - 9) # Depth using Gaussian FWHM. psf_sigma = ccds.fwhm / 2.35 gnorm = 1./(2. * np.sqrt(np.pi) * psf_sigma) detsig1 = ccds.sig1 / gnorm depth = 5. * detsig1 # that's flux in nanomaggies -- convert to mag ccds.gausspsfdepth = -2.5 * (np.log10(depth) - 9) # Gaussian galaxy depth detsig1 = ccds.sig1 / gaussgalnorm depth = 5. * detsig1 # that's flux in nanomaggies -- convert to mag ccds.gaussgaldepth = -2.5 * (np.log10(depth) - 9) ccds.writeto(outfn)
def main(): ps = PlotSequence('cov') survey = LegacySurveyData() ra, dec = 242.0, 10.2 fn = 'coverage-ccds.fits' if not os.path.exists(fn): ccds = survey.get_ccds() ccds.cut(ccds.filter == 'r') ccds.cut(ccds.propid == '2014B-0404') ccds.cut(np.hypot(ccds.ra_bore - ra, ccds.dec_bore - dec) < 2.5) print(np.unique(ccds.expnum), 'unique exposures') print('propids', np.unique(ccds.propid)) ccds.writeto(fn) else: ccds = fits_table(fn) plt.clf() for e in np.unique(ccds.expnum): I = np.flatnonzero(ccds.expnum == e) plt.plot(ccds.ra[I], ccds.dec[I], '.') ps.savefig() degw = 3.0 pixscale = 10. W = degw * 3600 / 10. H = W hi = 6 cmap = cmap_discretize('jet', hi + 1) wcs = Tan(ra, dec, W / 2. + 0.5, H / 2. + 0.5, -pixscale / 3600., 0., 0., pixscale / 3600., float(W), float(H)) r0, d0 = wcs.pixelxy2radec(1, 1) r1, d1 = wcs.pixelxy2radec(W, H) extent = [min(r0, r1), max(r0, r1), min(d0, d1), max(d0, d1)] for expnums in [ [348666], [348666, 348710, 348686], [348659, 348667, 348658, 348666, 348665, 348669, 348668], None, [ 348683, 348687, 347333, 348686, 348685, 348692, 348694, 348659, 348667, 348658, 348666, 348665, 348669, 348668, 348707, 348709, 348708, 348710, 348711, 348716, 348717 ], ]: nexp = np.zeros((H, W), np.uint8) for ccd in ccds: if expnums is not None and not ccd.expnum in expnums: continue ccdwcs = survey.get_approx_wcs(ccd) r, d = ccdwcs.pixelxy2radec(1, 1) ok, x0, y0 = wcs.radec2pixelxy(r, d) r, d = ccdwcs.pixelxy2radec(ccd.width, ccd.height) ok, x1, y1 = wcs.radec2pixelxy(r, d) xlo = np.clip(int(np.round(min(x0, x1))) - 1, 0, W - 1) xhi = np.clip(int(np.round(max(x0, x1))) - 1, 0, W - 1) ylo = np.clip(int(np.round(min(y0, y1))) - 1, 0, H - 1) yhi = np.clip(int(np.round(max(y0, y1))) - 1, 0, H - 1) nexp[ylo:yhi + 1, xlo:xhi + 1] += 1 plt.clf() plt.imshow(nexp, interpolation='nearest', origin='lower', vmin=-0.5, vmax=hi + 0.5, cmap=cmap, extent=extent) plt.colorbar(ticks=np.arange(hi + 1)) ps.savefig() O = fits_table('obstatus/decam-tiles_obstatus.fits') O.cut(np.hypot(O.ra - ra, O.dec - dec) < 2.5) for p in [1, 2, 3]: print('Pass', p, 'exposures:', O.r_expnum[O.get('pass') == p]) O.cut(O.get('pass') == 2) print(len(O), 'pass 2 nearby') d = np.hypot(O.ra - ra, O.dec - dec) print('Dists:', d) I = np.flatnonzero(d < 0.5) assert (len(I) == 1) ocenter = O[I[0]] print('Center expnum', ocenter.r_expnum) I = np.flatnonzero(d >= 0.5) O.cut(I) #center = ccds[ccds.expnum == ocenter.r_expnum] #p2 = ccds[ccds. ok, xc, yc = wcs.radec2pixelxy(ocenter.ra, ocenter.dec) xx, yy = np.meshgrid(np.arange(W) + 1, np.arange(H) + 1) c_d2 = (xc - xx)**2 + (yc - yy)**2 best = np.ones((H, W), bool) for o in O: ok, x, y = wcs.radec2pixelxy(o.ra, o.dec) d2 = (x - xx)**2 + (y - yy)**2 best[d2 < c_d2] = False del d2 del c_d2, xx, yy # plt.clf() # plt.imshow(best, interpolation='nearest', origin='lower', cmap='gray', # vmin=0, vmax=1) # ps.savefig() plt.clf() plt.imshow(nexp * best, interpolation='nearest', origin='lower', vmin=-0.5, vmax=hi + 0.5, cmap=cmap, extent=extent) plt.colorbar(ticks=np.arange(hi + 1)) ps.savefig() plt.clf() n, b, p = plt.hist(np.clip(nexp[best], 0, hi), range=(-0.5, hi + 0.5), bins=hi + 1) plt.xlim(-0.5, hi + 0.5) ps.savefig() print('b', b) print('n', n) print('fracs', np.array(n) / np.sum(n)) print('pcts', ', '.join(['%.1f' % f for f in 100. * np.array(n) / np.sum(n)]))
def _simplewcs(gal): '''Build a simple WCS object for a single galaxy.''' diam = np.ceil(gal['RADIUS'] / PIXSCALE).astype('int16') # [pixels] galwcs = Tan(gal['RA'], gal['DEC'], diam / 2 + 0.5, diam / 2 + 0.5, -PIXSCALE, 0.0, PIXSCALE, 0.0, float(diam), float(diam)) return galwcs
def cutout_fits(req): import tempfile import fitsio from astrometry.util.util import Tan form = CutoutSearchForm(req.GET) if not form.is_valid(): return HttpResponse('failed to parse request') ra = form.cleaned_data['ra'] dec = form.cleaned_data['dec'] if ra is None or dec is None: return HttpResponse('RA and Dec arguments are required') size = form.cleaned_data['size'] if size is None: size = 100 else: size = min(256, size) bandstr = form.cleaned_data['bands'] bands = [int(c) for c in bandstr] bands = [b for b in bands if b in [1,2,3,4]] version = form.cleaned_data['version'] if version == 'neo1': bands = [b for b in bands if b in [1,2]] radius = size/2. * 2.75/3600. tiles = unwise_tiles_near_radec(ra, dec, radius) tiles = list(tiles) # Create a temp dir in which to place cutouts tempdir = tempfile.mkdtemp() fns = [] filetypes = [] types = ['img_m', 'invvar_m', 'n_m', 'std_m'] for t in types: if form.cleaned_data['file_' + t]: filetypes.append(t) # If none specified, include all filetypes. if len(filetypes) == 0: filetypes = types for tile in tiles: coadd = tile.coadd dirnm = os.path.join(settings.DATA_DIR, version, coadd[:3], coadd) base = os.path.join(dirnm, 'unwise-%s' % coadd) w1fn = str(base + '-w1-img-m.fits') wcs = Tan(w1fn, 0) ok,x,y = wcs.radec2pixelxy(ra, dec) x = int(round(x-1.)) y = int(round(y-1.)) x0 = x - size/2 x1 = x0 + size y0 = y - size/2 y1 = y0 + size if x1 <= 0 or y1 <= 0: continue if x0 >= wcs.get_width() or y0 >= wcs.get_height(): continue x0 = max(x0, 0) y0 = max(y0, 0) x1 = min(x1, wcs.get_width()) y1 = min(y1, wcs.get_height()) hdr = fitsio.FITSHDR() subwcs = wcs.get_subimage(x0, y0, x1-x0, y1-y0) subwcs.add_to_header(hdr) for band in bands: for ft in filetypes: pat = { 'img_m': '-w%i-img-m.fits', 'invvar_m': '-w%i-invvar-m.fits.gz', 'n_m': '-w%i-n-m.fits.gz', 'std_m': '-w%i-std-m.fits.gz' }[ft] fn = str(base + pat % band) img = fitsio.FITS(fn)[0][y0:y1, x0:x1] basefn = os.path.basename(fn) outfn = os.path.join(tempdir, basefn) fitsio.write(outfn, img, header=hdr) fns.append(basefn) fns.extend([';', 'rm', '-R', tempdir]) return tar_files(req, fns, 'cutouts-fits_%.4f_%.4f.tar.gz' % (ra, dec), basedir=tempdir)
def _computeTransformation(self, img, ylo=0, yhi=-1): ''' Pre-compute the "grid-spread function" transformation matrix for this parameter grid to the given image pixels. The result is a home-brewed sparse matrix representation: a dictionary mapping from model grid pixel indices (integers) to the tuple (I, G, nz, NZI), where: I: numpy index array (integers) in the image G: grid weights for those pixels nz = ((x0,y0), (h,w)): the subimage with non-zero weights NZI: numpy index array (integers) within the "nz" subimage ''' imwcs = img.getWcs() H,W = self.shape if yhi == -1: yhi = H Ngrid = W*H iH,iW = img.shape Nim = iW*iH Lorder = 2 S = (Lorder * 2 + 3) if False: i0 = S/2 else: print('Image', img.name) print('Image PSF', img.getPsf()) psfw = img.getPsf().getRadius() scale = img.getWcs().pixel_scale() / self.wcs.pixel_scale() print('Image pixel scale', img.getWcs().pixel_scale()) print('Model pixel scale', self.wcs.pixel_scale()) print('PSF extent', psfw, 'pixels') print('pixel scale factor', scale) print('->', psfw * scale, 'model pixels') print('Increasing S from', S) S += int(np.ceil(psfw*scale)) * 2 print('to', S) i0 = S/2 cmock = np.zeros((S,S), np.float32) cmock[i0,i0] = 1. if True: spsf = img.getPsf().scale(scale) print('Scaled PSF', spsf) cmock = spsf.applyTo(cmock) #print 'cmock' #print cmock cwcs = Tan(self.wcs) cwcs.set_imagesize(S, S) cx0,cy0 = self.wcs.crpix[0], self.wcs.crpix[1] rim = np.zeros((iH,iW), np.float32) X = {} for i in range(ylo, yhi): print('Precomputing matrix for image', img.name, 'model row', i) for j in range(W): #print 'Precomputing matrix for grid pixel', j,i cwcs.set_crpix(cx0 - j + i0, cy0 - i + i0) rim[:,:] = 0 ## weighted = 1 res = tan_wcs_resample(cwcs, imwcs.wcs, cmock, rim, weighted, Lorder) assert(res == 0) if False: outimg = img.getPsf().applyTo(rim).ravel() else: outimg = rim.ravel() I = np.flatnonzero((outimg > 0) * (img.getInvError().ravel() > 0)) if len(I) == 0: continue #if True: # sumr.ravel()[I] += outimg[I] xx,yy = (I % iW), (I / iW) x0,y0 = xx.min(), yy.min() nzh,nzw = 1 + yy.max() - y0, 1 + xx.max() - x0 NZ = ((x0, y0), (nzh, nzw)) NZI = (xx - x0) + (yy - y0) * nzw X[i*W+j] = (I, outimg[I], NZ, NZI) # if True: # print 'sumr range', sumr.min(), sumr.max() # sumr[sumr == 0] = 1. # mn,mx = 0.,0. # for (I, outim, NZ, NZI) in X.values(): # outim /= sumr.ravel()[I] # mx = max(outim.max(), mx) # mn = max(outim.min(), mn) # print 'Min,Max grid-spread function:', mn,mx return X
from legacypipe.survey import GaiaSource, GaiaPosition from astrometry.util.util import Tan from astrometry.util.starutil_numpy import mjdtodate from tractor import TAITime #ra,dec = 357.3060, 2.3957 #ccd1 = ccds[(ccds.expnum == 563212) * (ccds.ccdname == 'N17')] ra, dec = 124.0317, 1.3028 expnum, ccdname = 393203, 'N11' survey = LegacySurveyData() W, H = 200, 200 pixscale = 0.262 cd = pixscale / 3600. targetwcs = Tan(ra, dec, W / 2., H / 2., -cd, 0., 0., cd, float(W), float(H)) rr, dd = targetwcs.pixelxy2radec([1, W, W, 1, 1], [1, 1, H, H, 1]) targetrd = np.vstack((rr, dd)).T ccds = survey.ccds_touching_wcs(targetwcs) print(len(ccds), 'CCDs touching WCS') print('MJDs', ccds.mjd_obs) ccds.writeto('test-ccds.fits') ccd1 = ccds[(ccds.expnum == expnum) * (ccds.ccdname == ccdname)] print('CCD1:', ccd1) im1 = survey.get_image_object(ccd1[0]) print('Im:', im1)
TT = [] for b in bricks[I]: fn = survey.find_file('tractor', brick=b.brickname) print('Reading', fn) T = fits_table(fn) print('Read', len(T)) T.cut((T.ra >= ralo) * (T.ra <= rahi) * (T.dec >= declo) * (T.dec <= dechi)) print(len(T), 'survive cut') if len(T) == 0: continue TT.append(T) T = TT = merge_tables(TT) pixscale = dra / 1000. W,H = int(np.ceil(2.*dra / pixscale)), int(np.ceil(2.*ddec / pixscale)) wcs = Tan(ra, dec, (W+1.)/2., (H+1.)/2., -pixscale, 0., 0., pixscale, float(W), float(H)) print('WCS radec bounds:', wcs.radec_bounds()) idmap = dict([((b,oid),i) for i,(b,oid) in enumerate(zip(T.brickname, T.objid))]) bands = 'grz' lightcurves = dict([(b, [[] for i in range(len(T))]) for b in bands]) #ccds = survey.get_ccds_readonly() #I = np.flatnonzero((ccds.ra1 <= rahi ) * (ccds.ra2 >= ralo) * # (ccds.dec1 <= dechi) * (ccds.dec2 >= declo)) ccds = survey.ccds_touching_wcs(wcs) print(len(ccds), 'ccds overlap ROI') I = survey.photometric_ccds(ccds) ccds.cut(I) print('Cut to', len(ccds), 'CCDs that are photometric')
def run(self): tmp_dir = tempfile.mkdtemp() tbhdu = pyfits.BinTableHDU.from_columns([ pyfits.Column(name='X', format='E', array=self.sources_list[:, 1]), pyfits.Column(name='Y', format='E', array=self.sources_list[:, 0]), pyfits.Column(name='FLUX', format='E', array=self.sources_list[:, 2]) ]) prihdr = pyfits.Header() prihdr['IMAGEW'] = self.field_w prihdr['IMAGEH'] = self.field_h prihdr['ANRUN'] = True prihdr['ANVERUNI'] = True prihdr['ANVERDUP'] = False prihdr['ANCRPIXC'] = True prihdr['ANTWEAK'] = False prihdr['ANTWEAKO'] = 0 prihdr['ANSOLVED'] = tmp_dir + '/field.solved' #prihdr['ANMATCH'] = tmp_dir + '/field.match' prihdr['ANRDLS'] = tmp_dir + '/field.rdls' prihdr['ANWCS'] = tmp_dir + '/field.wcs' if self.field_corr is not None: prihdr['ANCORR'] = tmp_dir + '/field.corr' prihdr['ANCANCEL'] = tmp_dir + '/field.solved' prihdr['ANPOSERR'] = self.field_w / 400.0 if self.ra is not None: prihdr['ANERA'] = self.ra prihdr['ANEDEC'] = self.dec if self.radius is not None and self.radius > 0: prihdr['ANERAD'] = self.radius prihdr['ANDPL1'] = 1 prihdr['ANDPU1'] = 20 if self.field_deg is not None: prihdr['ANAPPL1'] = self.field_deg * 0.95 * 3600 / self.field_w prihdr['ANAPPU1'] = self.field_deg * 1.05 * 3600 / self.field_w if self.radius is not None and self.radius > 0 and self.radius < 5: prihdr['ANODDSSL'] = 1e6 else: prihdr['ANODDSSL'] = 1e8 prihdu = pyfits.PrimaryHDU(header=prihdr) thdulist = pyfits.HDUList([prihdu, tbhdu]) thdulist.writeto(tmp_dir + '/field.axy', clobber=True) if self.radius is not None and self.radius > 0 and self.radius < 5: conf_list = ['conf-all'] else: conf_list = ['conf-41', 'conf-42-1', 'conf-42-2' ] self.cancel_file = tmp_dir + '/field.solved' solved = None global engines for conf in conf_list: engine = engines.get(conf) engine.solve(tmp_dir + '/field.axy') self.engines.append(engine) while True: running = False for engine in self.engines: if not engine.check(): running = True if not running: break time.sleep(0.1) if os.path.exists(tmp_dir + '/field.wcs'): solved = tmp_dir + '/field' self.cancel_file = None if solved is None or not os.path.exists(solved + ".wcs"): self.ra = None self.dec = None self.field_deg = None shutil.rmtree(tmp_dir) return self.wcs = Tan(solved + ".wcs", 0) self.ra, self.dec = self.wcs.radec_center() self.field_deg = self.field_w * self.wcs.pixel_scale() / 3600 ind = pyfits.open(solved + '.rdls') tbdata = ind[1].data self.ind_sources = [] self.ind_radec = [] for l in tbdata: ok, x, y = self.wcs.radec2pixelxy(l['ra'], l['dec']) x = np.clip(int(x), 0, self.field_w - 1) y = np.clip(int(y), 0, self.field_h - 1) self.ind_sources.append((x,y)) self.ind_radec.append((l['ra'], l['dec'])) if self.field_corr is not None: corr = pyfits.open(solved + '.corr') for l in corr[1].data: self.field_corr.append((l['field_x'], l['field_y'], l['index_x'], l['field_y'])) shutil.rmtree(tmp_dir) self.solved = True
# plt.plot(x, L2, 'b-') # plt.savefig('l1.png') x = np.linspace(-3.5, 4.5, 8192).astype(np.float32) L1 = np.zeros_like(x) L2 = np.zeros_like(x) lanczos3_filter(x, L1) lanczos3_filter_table(x, L2, 1) print 'L2 - L1 RMS:', np.sqrt(np.mean((L2-L1)**2)) if True: ra,dec = 0.,0., pixscale = 1e-3 W,H = 10,1 cowcs = Tan(ra, dec, (W+1)/2., (H+1)/2., -pixscale, 0., 0., pixscale, W, H) dx,dy = 0.25, 0. wcs = Tan(ra, dec, (W+1)/2. + dx, (H+1)/2. + dy, -pixscale, 0., 0., pixscale, W, H) pix = np.zeros((H,W), np.float32) pix[0,W/2] = 1. Yo,Xo,Yi,Xi,(cpix,) = resample_with_wcs(cowcs, wcs, [pix], 3) print 'C', cpix Yo2,Xo2,Yi2,Xi2,(pypix,) = resample_with_wcs(cowcs, wcs, [pix], 3, cinterp=False, table=False) print 'Py', pypix print 'RMS', np.sqrt(np.mean((cpix - pypix)**2)) sys.exit(0)
def wise_cutouts(ra, dec, radius, ps, pixscale=2.75, tractor_base=".", unwise_dir="unwise-coadds"): """ radius in arcsec. pixscale: WISE pixel scale in arcsec/pixel; make this smaller than 2.75 to oversample. """ npix = int(np.ceil(radius / pixscale)) print("Image size:", npix) W = H = npix pix = pixscale / 3600.0 wcs = Tan(ra, dec, (W + 1) / 2.0, (H + 1) / 2.0, -pix, 0.0, 0.0, pix, float(W), float(H)) # Find DECaLS bricks overlapping decals = Decals() B = bricks_touching_wcs(wcs, decals=decals) print("Found", len(B), "bricks overlapping") TT = [] for b in B.brickname: fn = os.path.join(tractor_base, "tractor", b[:3], "tractor-%s.fits" % b) T = fits_table(fn) print("Read", len(T), "from", b) primhdr = fitsio.read_header(fn) TT.append(T) T = merge_tables(TT) print("Total of", len(T), "sources") T.cut(T.brick_primary) print(len(T), "primary") margin = 20 ok, xx, yy = wcs.radec2pixelxy(T.ra, T.dec) I = np.flatnonzero((xx > -margin) * (yy > -margin) * (xx < W + margin) * (yy < H + margin)) T.cut(I) print(len(T), "within ROI") # Pull out DECaLS coadds (image, model, resid). dwcs = wcs.scale(2.0 * pixscale / 0.262) dh, dw = dwcs.shape print("DECaLS resampled shape:", dh, dw) tags = ["image", "model", "resid"] coimgs = [np.zeros((dh, dw, 3), np.uint8) for t in tags] for b in B.brickname: fn = os.path.join(tractor_base, "coadd", b[:3], b, "decals-%s-image-r.fits" % b) bwcs = Tan(fn) try: Yo, Xo, Yi, Xi, nil = resample_with_wcs(dwcs, bwcs) except ResampleError: continue if len(Yo) == 0: continue print("Resampling", len(Yo), "pixels from", b) xl, xh, yl, yh = Xi.min(), Xi.max(), Yi.min(), Yi.max() print( "python legacypipe/runbrick.py -b %s --zoom %i %i %i %i --outdir cluster --pixpsf --splinesky --pipe --no-early-coadds" % (b, xl - 5, xh + 5, yl - 5, yh + 5) + " -P 'pickles/cluster-%(brick)s-%%(stage)s.pickle'" ) for i, tag in enumerate(tags): fn = os.path.join(tractor_base, "coadd", b[:3], b, "decals-%s-%s.jpg" % (b, tag)) img = plt.imread(fn) img = np.flipud(img) coimgs[i][Yo, Xo, :] = img[Yi, Xi, :] tt = dict(image="Image", model="Model", resid="Resid") for img, tag in zip(coimgs, tags): plt.clf() dimshow(img, ticks=False) plt.title("DECaLS grz %s" % tt[tag]) ps.savefig() # Find unWISE tiles overlapping tiles = unwise_tiles_touching_wcs(wcs) print("Cut to", len(tiles), "unWISE tiles") # Here we assume the targetwcs is axis-aligned and that the # edge midpoints yield the RA,Dec limits (true for TAN). r, d = wcs.pixelxy2radec(np.array([1, W, W / 2, W / 2]), np.array([H / 2, H / 2, 1, H])) # the way the roiradec box is used, the min/max order doesn't matter roiradec = [r[0], r[1], d[2], d[3]] ra, dec = T.ra, T.dec T.shapeexp = np.vstack((T.shapeexp_r, T.shapeexp_e1, T.shapeexp_e2)).T T.shapedev = np.vstack((T.shapedev_r, T.shapedev_e1, T.shapedev_e2)).T srcs = read_fits_catalog(T, ellipseClass=EllipseE) wbands = [1, 2] wanyband = "w" for band in wbands: T.wise_flux[:, band - 1] *= 10.0 ** (primhdr["WISEAB%i" % band] / 2.5) coimgs = [np.zeros((H, W), np.float32) for b in wbands] comods = [np.zeros((H, W), np.float32) for b in wbands] con = [np.zeros((H, W), np.uint8) for b in wbands] for iband, band in enumerate(wbands): print("Photometering WISE band", band) wband = "w%i" % band for i, src in enumerate(srcs): # print('Source', src, 'brightness', src.getBrightness(), 'params', src.getBrightness().getParams()) # src.getBrightness().setParams([T.wise_flux[i, band-1]]) src.setBrightness(NanoMaggies(**{wanyband: T.wise_flux[i, band - 1]})) # print('Set source brightness:', src.getBrightness()) # The tiles have some overlap, so for each source, keep the # fit in the tile whose center is closest to the source. for tile in tiles: print("Reading tile", tile.coadd_id) tim = get_unwise_tractor_image(unwise_dir, tile.coadd_id, band, bandname=wanyband, roiradecbox=roiradec) if tim is None: print("Actually, no overlap with tile", tile.coadd_id) continue print("Read image with shape", tim.shape) # Select sources in play. wisewcs = tim.wcs.wcs H, W = tim.shape ok, x, y = wisewcs.radec2pixelxy(ra, dec) x = (x - 1.0).astype(np.float32) y = (y - 1.0).astype(np.float32) margin = 10.0 I = np.flatnonzero((x >= -margin) * (x < W + margin) * (y >= -margin) * (y < H + margin)) print(len(I), "within the image + margin") subcat = [srcs[i] for i in I] tractor = Tractor([tim], subcat) mod = tractor.getModelImage(0) # plt.clf() # dimshow(tim.getImage(), ticks=False) # plt.title('WISE %s %s' % (tile.coadd_id, wband)) # ps.savefig() # plt.clf() # dimshow(mod, ticks=False) # plt.title('WISE %s %s' % (tile.coadd_id, wband)) # ps.savefig() try: Yo, Xo, Yi, Xi, nil = resample_with_wcs(wcs, tim.wcs.wcs) except ResampleError: continue if len(Yo) == 0: continue print("Resampling", len(Yo), "pixels from WISE", tile.coadd_id, band) coimgs[iband][Yo, Xo] += tim.getImage()[Yi, Xi] comods[iband][Yo, Xo] += mod[Yi, Xi] con[iband][Yo, Xo] += 1 for img, mod, n in zip(coimgs, comods, con): img /= np.maximum(n, 1) mod /= np.maximum(n, 1) for band, img, mod in zip(wbands, coimgs, comods): lo, hi = np.percentile(img, [25, 99]) plt.clf() dimshow(img, vmin=lo, vmax=hi, ticks=False) plt.title("WISE W%i Data" % band) ps.savefig() plt.clf() dimshow(mod, vmin=lo, vmax=hi, ticks=False) plt.title("WISE W%i Model" % band) ps.savefig() resid = img - mod mx = np.abs(resid).max() plt.clf() dimshow(resid, vmin=-mx, vmax=mx, ticks=False) plt.title("WISE W%i Resid" % band) ps.savefig() # kwa = dict(mn=-0.1, mx=2., arcsinh = 1.) kwa = dict(mn=-0.1, mx=2.0, arcsinh=None) rgb = _unwise_to_rgb(coimgs, **kwa) plt.clf() dimshow(rgb, ticks=False) plt.title("WISE W1/W2 Data") ps.savefig() rgb = _unwise_to_rgb(comods, **kwa) plt.clf() dimshow(rgb, ticks=False) plt.title("WISE W1/W2 Model") ps.savefig() kwa = dict(mn=-1, mx=1, arcsinh=None) rgb = _unwise_to_rgb([img - mod for img, mod in zip(coimgs, comods)], **kwa) plt.clf() dimshow(rgb, ticks=False) plt.title("WISE W1/W2 Resid") ps.savefig()
def get_unwise_tractor_image(basedir, tile, band, bandname=None, masked=True, **kwargs): ''' masked: read "-m" images, or "-u"? bandname: PhotoCal band name to use: default: "w%i" % band ''' if bandname is None: bandname = 'w%i' % band mu = 'm' if masked else 'u' thisdir = get_unwise_tile_dir(basedir, tile) base = os.path.join(thisdir, 'unwise-%s-w%i-' % (tile, band)) imfn = base + 'img-%s.fits' % mu ivfn = base + 'invvar-%s.fits.gz' % mu #ppfn = base + 'std-%s.fits.gz' % mu nifn = base + 'n-%s.fits.gz' % mu print 'Reading', imfn wcs = Tan(imfn) twcs = ConstantFitsWcs(wcs) img = fitsio.FITS(imfn)[0] H, W = img.get_info()['dims'] H, W = int(H), int(W) roi, nil = interpret_roi(twcs, (H, W), **kwargs) if roi is None: # No overlap with ROI return None (x0, x1, y0, y1) = roi twcs.setX0Y0(x0, y0) roislice = (slice(y0, y1), slice(x0, x1)) img = img[roislice] print 'Reading', ivfn invvar = fitsio.FITS(ivfn)[0][roislice] #print 'Reading', ppfn #pp = fitsio.FITS(ppfn)[0][roislice] print 'Reading', nifn nims = fitsio.FITS(nifn)[0][roislice] #print 'Median # ims:', np.median(nims) good = (nims > 0) invvar[np.logical_not(good)] = 0. sig1 = 1. / np.sqrt(np.median(invvar[good])) # Load the average PSF model (generated by wise_psf.py) psffn = os.path.join(os.path.dirname(__file__), 'wise-psf-avg.fits') print 'Reading', psffn P = fits_table(psffn, hdu=band) psf = GaussianMixturePSF(P.amp, P.mean, P.var) sky = 0. tsky = ConstantSky(sky) # if opt.errfrac > 0: # nz = (iv > 0) # iv2 = np.zeros_like(invvar) # iv2[nz] = 1./(1./invvar[nz] + (img[nz] * opt.errfrac)**2) # print 'Increasing error estimate by', opt.errfrac, 'of image flux' # invvar = iv2 tim = Image(data=img, invvar=invvar, psf=psf, wcs=twcs, sky=tsky, photocal=LinearPhotoCal(1., band=bandname), name='unWISE %s W%i' % (tile, band), domask=False) tim.sig1 = sig1 tim.roi = roi tim.nims = nims return tim
def create_tractor(opt): """ Brittle function to read Groves data sample and make the things we need for fitting. # issues: - Need to read the WCS too. - Need, for each image, to construct the rectangular nearest-neighbor interpolation indices to image 0. - Can I just blow up the SPIRE images with interpolation? """ dataList = [ ('m31_brick15_PACS100.fits', 7.23, 7.7), ('m31_brick15_PACS160.fits', 3.71, 12.0), ('m31_brick15_SPIRE250.fits', None, 18.0), ('m31_brick15_SPIRE350.fits', None, 25.0), ('m31_brick15_SPIRE500.fits', None, 37.0), ] # From Groves via Rix: # PSF FWHMs: 6.97, 11.01, 18.01, 24.73, 35.98 # Within the region Ive selected I found temperatures between 15 # and 21 K, averaging 17 K, and Beta= 1.5 to 2.5 (with a larger # uncertainty), averaging around 2.0. if opt.no100: dataList = dataList[1:] print 'Reading images...' tims = [] for i, (fn, noise, fwhm) in enumerate(dataList): print print 'Reading', fn P = pyfits.open(fn) image = P[0].data.astype(np.float32) #wcs = Tan(fn, 0) H,W = image.shape hdr = P[0].header wcs = Tan(hdr['CRVAL1'], hdr['CRVAL2'], hdr['CRPIX1'], hdr['CRPIX2'], hdr['CDELT1'], 0., 0., hdr['CDELT2'], W, H) assert(hdr['CROTA2'] == 0.) if noise is None: noise = float(hdr['NOISE']) print 'Noise', noise print 'Median image value', np.median(image) invvar = np.ones_like(image) / (noise**2) skyval = np.percentile(image, 5) sky = ConstantSky(skyval) lam = float(hdr['FILTER']) print 'Lambda', lam # calibrated, yo assert(hdr['BUNIT'] == 'MJy/Sr') # "Filter" is in *microns* in the headers; convert to *m* here, to match "lam0" pcal = DustPhotoCal(lam * 1e-6, wcs.pixel_scale()) #nm = '%s %i' % (hdr['INSTRUME'], lam) nm = fn.replace('.fits', '') #zr = noise * np.array([-3, 10]) + skyval zr = np.array([np.percentile(image.ravel(), p) for p in [1, 99]]) print 'Pixel scale:', wcs.pixel_scale() # meh sigma = fwhm / wcs.pixel_scale() / 2.35 print 'PSF sigma', sigma, 'pixels' psf = NCircularGaussianPSF([sigma], [1.]) twcs = FitsWcs(wcs) tim = Image(data=image, invvar=invvar, psf=psf, wcs=twcs, sky=sky, photocal=pcal, name=nm) tim.zr = zr tims.append(tim) # plt.clf() # plt.hist(image.ravel(), 100) # plt.title(nm) # plt.savefig('im%i-hist.png' % i) radecbounds = [] for tim in tims: H,W = tim.shape twcs = tim.getWcs() rds = [] for x,y in [(0.5,0.5),(W+0.5,0.5),(W+0.5,H+0.5),(0.5,H+0.5),(0.5,0.5)]: rd = twcs.pixelToPosition(x,y) rds.append(rd) rds = np.array(rds) radecbounds.append(rds) rd = np.vstack(radecbounds) #print 'rd', rd.shape ramin,decmin = rd.min(axis=0) ramax,decmax = rd.max(axis=0) dr,dd = ramax-ramin, decmax-decmin plotrange = (ramin - 0.05*dr, ramax + 0.05*dr, decmin - 0.05*dd, decmax + 0.05*dd) plt.clf() for rds,c in zip(radecbounds, ['b','g','y',(1,0.5,0),'r']): plt.plot(rds[:,0], rds[:,1], '-', color=c, lw=2, alpha=0.5) setRadecAxes(*plotrange) plt.savefig('radec1%s.png' % opt.suffix) print 'Creating dust sheet...' N = opt.gridn # Build a WCS for the dust sheet to match the first image # (assuming it's square and axis-aligned) #wcs = tims[0].getWcs().wcs #r,d = wcs.radec_center() #H,W = tims[0].shape #scale = wcs.pixel_scale() #scale *= float(W)/max(1, N-1) / 3600. #c = float(N)/2. + 0.5 #dwcs = Tan(r, d, c, c, scale, 0, 0, scale, N, N) # Build an axis-aligned WCS that contains all the images. r,d = (ramin + ramax) / 2., (decmin + decmax) / 2. # HACK -- ignore pole issues scale = max((ramax - ramin) * np.cos(np.deg2rad(d)), decmax - decmin) / float(N) scale *= float(N) / float(max(1, N-1)) scale *= (1. / opt.zoom) cpix = float(N)/2. + 0.5 dwcs = Tan(r, d, cpix, cpix, scale, 0, 0, scale, N, N) pixscale = dwcs.pixel_scale() logsa = np.log(1e-3) H,W = N,N logsa = np.zeros((H,W)) + logsa logt = np.zeros((H,W)) + np.log(17.) emis = np.zeros((H,W)) + 2. ds = DustSheet(logsa, logt, emis, dwcs) rds = ds.getRaDecCorners(0.5) plt.plot(rds[:,0], rds[:,1], 'k-', lw=1, alpha=1) setRadecAxes(*plotrange) plt.savefig('radec2%s.png' % opt.suffix) # plot grid of sample points. rds = [] H,W = N,N for y in range(N): for x in range(N): r,d = dwcs.pixelxy2radec(x+1, y+1) rds.append((r,d)) rds = np.array(rds) plt.plot(rds[:,0], rds[:,1], 'k.', lw=1, alpha=0.5) setRadecAxes(*plotrange) plt.savefig('radec3%s.png' % opt.suffix) #print 'DustSheet:', ds #print 'np', ds.numberOfParams() #print 'pn', ds.getParamNames() #print 'p', ds.getParams() # print 'PriorChi:', ds.getLogPriorChi() # ra,ca,va,pb = ds.getLogPriorChi() # print 'ra', ra # print 'ca', ca # print 'va', va # print 'pb', pb # for ri,ci,vi,bi in zip(ra,ca,va,pb): # print # print 'ri', ri # print 'ci', ci # print 'vi', vi # print 'bi', bi cat = Catalog() cat.append(ds) tractor = Tractor(Images(*tims), cat) return tractor
def plotarea(ra, dec, radius, ngcnum, tims=None, rds=[]): from astrometry.util.util import Tan W, H = 512, 512 scale = (radius * 60.0 * 4) / float(W) print "SDSS jpeg scale", scale imgfn = "sdss-mosaic-ngc%04i.png" % ngcnum if not os.path.exists(imgfn): url = ( "http://skyservice.pha.jhu.edu/DR8/ImgCutout/getjpeg.aspx?" + "ra=%f&dec=%f&scale=%f&width=%i&height=%i" ) % (ra, dec, scale, W, H) f = urllib2.urlopen(url) of, tmpfn = tempfile.mkstemp(suffix=".jpg") os.close(of) of = open(tmpfn, "wb") of.write(f.read()) of.close() cmd = "jpegtopnm %s | pnmtopng > %s" % (tmpfn, imgfn) os.system(cmd) # Create WCS header for it cd = scale / 3600.0 args = (ra, dec, W / 2.0 + 0.5, H / 2.0 + 0.5, -cd, 0.0, 0.0, -cd, W, H) wcs = Tan(*[float(x) for x in args]) plt.clf() I = plt.imread(imgfn) plt.imshow(I, interpolation="nearest", origin="lower") x, y = wcs.radec2pixelxy(ra, dec) R = radius * 60.0 / scale ax = plt.axis() plt.gca().add_artist(matplotlib.patches.Circle(xy=(x, y), radius=R, color="g", lw=3, alpha=0.5, fc="none")) if tims is not None: print "Plotting outlines of", len(tims), "images" for tim in tims: H, W = tim.shape twcs = tim.getWcs() px, py = [], [] for x, y in [(1, 1), (W, 1), (W, H), (1, H), (1, 1)]: rd = twcs.pixelToPosition(x, y) xx, yy = wcs.radec2pixelxy(rd.ra, rd.dec) print "x,y", x, y x1, y1 = twcs.positionToPixel(rd) print " x1,y1", x1, y1 print " r,d", rd.ra, rd.dec, print " xx,yy", xx, yy px.append(xx) py.append(yy) plt.plot(px, py, "g-", lw=3, alpha=0.5) # plot full-frame image outline too # px,py = [],[] # W,H = 2048,1489 # for x,y in [(1,1),(W,1),(W,H),(1,H),(1,1)]: # r,d = twcs.pixelToRaDec(x,y) # xx,yy = wcs.radec2pixelxy(r,d) # px.append(xx) # py.append(yy) # plt.plot(px, py, 'g-', lw=1, alpha=1.) if rds is not None: px, py = [], [] for ra, dec in rds: print "ra,dec", ra, dec xx, yy = wcs.radec2pixelxy(ra, dec) px.append(xx) py.append(yy) plt.plot(px, py, "go") plt.axis(ax) fn = "ngc-%04i.png" % ngcnum plt.savefig(fn) print "saved", fn
def check_priors(): np.seterrcall(np_err_handler) np.seterr(all='call') import logging import sys lvl = logging.DEBUG log_init(3) logging.basicConfig(level=lvl, format='%(message)s', stream=sys.stdout) if True: # Check two-pixel priors: smoothness. H,W = 1,2 logsa = np.zeros((H,W)) + np.log(1e-3) logt = np.zeros((H,W)) + np.log(17.) emis = np.zeros((H,W)) + 2. dwcs = Tan(11.2, 41.9, 1, 1, 1e-3, 0, 0, 1e-3, W, H) ds = DustSheet(logsa, logt, emis, dwcs) cat = Catalog() cat.append(ds) tractor = Tractor() tractor.setCatalog(cat) p0 = tractor.getParams() print('lnp0', tractor.getLogProb()) if True: # check getLogProb() for j,xx in enumerate([ np.linspace(np.log(1e-5), np.log(1e-1), 20), np.linspace(np.log(1e-5), np.log(1e-1), 20), np.linspace(np.log(10.), np.log(20.), 20), np.linspace(np.log(10.), np.log(20.), 20), np.linspace(0., 4., 20), np.linspace(0., 4., 20), ]): pp = [] for x in xx: tractor.setParam(j, x) p = tractor.getLogProb() pp.append(p) tractor.setParam(j, p0[j]) plt.clf() plt.plot(xx, pp, 'ro-') plt.title(ds.getParamNames()[j]) plt.savefig('p%i.png' % (20 + j)) # set the absolute priors to have little effect and repeat. ds.prior_logt_std = np.log(100.) ds.prior_emis_std = np.log(100.) for j,xx in enumerate([ np.linspace(np.log(1e-5), np.log(1e-1), 20), np.linspace(np.log(1e-5), np.log(1e-1), 20), np.linspace(np.log(10.), np.log(20.), 20), np.linspace(np.log(10.), np.log(20.), 20), np.linspace(0., 4., 20), np.linspace(0., 4., 20), ]): pp = [] for x in xx: tractor.setParam(j, x) p = tractor.getLogProb() pp.append(p) tractor.setParam(j, p0[j]) plt.clf() plt.plot(xx, pp, 'ro-') plt.title(ds.getParamNames()[j]) plt.savefig('p%i.png' % (30 + j)) # revert the priors ds.prior_logt_std = np.log(1.2) ds.prior_emis_std = np.log(0.5) # check getLogPriorChi. for j,(ip,val) in enumerate([ (0, np.log(1e-1)), (1, np.log(1e-5)), (2, np.log(5.)), (3, np.log(5.)), (2, np.log(30.)), (3, np.log(30.)), (4, 1.), (5, 1.), (4, 3.), (5, 3.), ]): print() print() print('Setting', ds.getParamNames()[ip], 'from', p0[ip], 'to', val) tractor.setParams(p0) tractor.setParam(ip, val) xx = [val] xxall = [tractor.getParams()] pp = [tractor.getLogProb()] for i in range(10): tractor.optimize()#damp=1e-3) xx.append(tractor.getParams()[ip]) pp.append(tractor.getLogProb()) xxall.append(tractor.getParams()) plt.clf() plt.plot(xx, pp, 'ro-') plt.axvline(val, color='r', lw=2, alpha=0.5) plt.title(ds.getParamNames()[ip]) plt.savefig('p%i.png' % (j+40)) plt.clf() xxall = np.vstack(xxall) print('xxall', xxall.shape) for i in range(6): #plt.subplot(1,3,(i/2)+1) #plt.plot(xxall[:,i], pp, 'ro-') #if i == ip: # plt.axvline(xxall[0,i], color='r', lw=2, alpha=0.5) #plt.title(ds.getParamNames()[i]) plt.subplot(3,1,(i/2)+1) c = 'b' if i == ip: c = 'r' plt.plot(xxall[:,i], 'o-', color=c) plt.title(ds.getParamNames()[i]) plt.savefig('p%i.png' % (j+50)) if False: # Check single-pixel priors: getLogPrior() N = 1 H,W = N,N logsa = np.zeros((H,W)) + np.log(1e-3) logt = np.zeros((H,W)) + np.log(17.) emis = np.zeros((H,W)) + 2. dwcs = Tan(11.2, 41.9, 1, 1, 1e-3, 0, 0, 1e-3, N, N) ds = DustSheet(logsa, logt, emis, dwcs) cat = Catalog() cat.append(ds) tractor = Tractor() tractor.setCatalog(cat) p0 = tractor.getParams() print('lnp0', tractor.getLogProb()) # no prior on solid angle # N(log(17.), log(1.2)) on T # N(2, 0.5) on emis for j,xx in enumerate([ np.linspace(np.log(1e-5), np.log(1e-1), 20), np.linspace(np.log(10.), np.log(20.), 20), np.linspace(0., 4., 20), ]): pp = [] for x in xx: tractor.setParam(j, x) p = tractor.getLogProb() pp.append(p) tractor.setParam(j, p0[j]) plt.clf() plt.plot(xx, pp, 'ro-') plt.title(ds.getParamNames()[j]) plt.savefig('p%i.png' % j) # Check single-pixel priors: getPriorChi() for j,(ip,val) in enumerate([ (0, 1e-2), (1, np.log(5.)), (1, np.log(30.)), (2, 1.), (2, 3.), ]): print() print() print('Setting', ds.getParamNames()[ip], 'to', val) tractor.setParams(p0) tractor.setParam(ip, val) xx = [val] pp = [tractor.getLogProb()] for i in range(10): tractor.optimize(damp=1e-3) xx.append(tractor.getParams()[ip]) pp.append(tractor.getLogProb()) plt.clf() plt.plot(xx, pp, 'ro-') plt.title(ds.getParamNames()[ip]) plt.savefig('p%i.png' % (j+10))
def main(): ps = PlotSequence('cov') survey = LegacySurveyData() ra,dec = 242.0, 10.2 fn = 'coverage-ccds.fits' if not os.path.exists(fn): ccds = survey.get_ccds() ccds.cut(ccds.filter == 'r') ccds.cut(ccds.propid == '2014B-0404') ccds.cut(np.hypot(ccds.ra_bore - ra, ccds.dec_bore - dec) < 2.5) print(np.unique(ccds.expnum), 'unique exposures') print('propids', np.unique(ccds.propid)) ccds.writeto(fn) else: ccds = fits_table(fn) plt.clf() for e in np.unique(ccds.expnum): I = np.flatnonzero(ccds.expnum == e) plt.plot(ccds.ra[I], ccds.dec[I], '.') ps.savefig() degw = 3.0 pixscale = 10. W = degw * 3600 / 10. H = W hi = 6 cmap = cmap_discretize('jet', hi+1) wcs = Tan(ra, dec, W/2.+0.5, H/2.+0.5, -pixscale/3600., 0., 0., pixscale/3600., float(W), float(H)) r0,d0 = wcs.pixelxy2radec(1,1) r1,d1 = wcs.pixelxy2radec(W,H) extent = [min(r0,r1),max(r0,r1), min(d0,d1),max(d0,d1)] for expnums in [ [348666], [348666,348710, 348686], [348659, 348667, 348658, 348666, 348665, 348669, 348668], None, [348683, 348687, 347333, 348686, 348685, 348692, 348694, 348659, 348667, 348658, 348666, 348665, 348669, 348668, 348707, 348709, 348708, 348710, 348711, 348716, 348717], ]: nexp = np.zeros((H,W), np.uint8) for ccd in ccds: if expnums is not None and not ccd.expnum in expnums: continue ccdwcs = survey.get_approx_wcs(ccd) r,d = ccdwcs.pixelxy2radec(1, 1) ok,x0,y0 = wcs.radec2pixelxy(r, d) r,d = ccdwcs.pixelxy2radec(ccd.width, ccd.height) ok,x1,y1 = wcs.radec2pixelxy(r, d) xlo = np.clip(int(np.round(min(x0,x1))) - 1, 0, W-1) xhi = np.clip(int(np.round(max(x0,x1))) - 1, 0, W-1) ylo = np.clip(int(np.round(min(y0,y1))) - 1, 0, H-1) yhi = np.clip(int(np.round(max(y0,y1))) - 1, 0, H-1) nexp[ylo:yhi+1, xlo:xhi+1] += 1 plt.clf() plt.imshow(nexp, interpolation='nearest', origin='lower', vmin=-0.5, vmax=hi+0.5, cmap=cmap, extent=extent) plt.colorbar(ticks=np.arange(hi+1)) ps.savefig() O = fits_table('obstatus/decam-tiles_obstatus.fits') O.cut(np.hypot(O.ra - ra, O.dec - dec) < 2.5) for p in [1,2,3]: print('Pass', p, 'exposures:', O.r_expnum[O.get('pass') == p]) O.cut(O.get('pass') == 2) print(len(O), 'pass 2 nearby') d = np.hypot(O.ra - ra, O.dec - dec) print('Dists:', d) I = np.flatnonzero(d < 0.5) assert(len(I) == 1) ocenter = O[I[0]] print('Center expnum', ocenter.r_expnum) I = np.flatnonzero(d >= 0.5) O.cut(I) #center = ccds[ccds.expnum == ocenter.r_expnum] #p2 = ccds[ccds. ok,xc,yc = wcs.radec2pixelxy(ocenter.ra, ocenter.dec) xx,yy = np.meshgrid(np.arange(W)+1, np.arange(H)+1) c_d2 = (xc - xx)**2 + (yc - yy)**2 best = np.ones((H,W), bool) for o in O: ok,x,y = wcs.radec2pixelxy(o.ra, o.dec) d2 = (x - xx)**2 + (y - yy)**2 best[d2 < c_d2] = False del d2 del c_d2,xx,yy # plt.clf() # plt.imshow(best, interpolation='nearest', origin='lower', cmap='gray', # vmin=0, vmax=1) # ps.savefig() plt.clf() plt.imshow(nexp * best, interpolation='nearest', origin='lower', vmin=-0.5, vmax=hi+0.5, cmap=cmap, extent=extent) plt.colorbar(ticks=np.arange(hi+1)) ps.savefig() plt.clf() n,b,p = plt.hist(np.clip(nexp[best], 0, hi), range=(-0.5,hi+0.5), bins=hi+1) plt.xlim(-0.5, hi+0.5) ps.savefig() print('b', b) print('n', n) print('fracs', np.array(n) / np.sum(n)) print('pcts', ', '.join(['%.1f' % f for f in 100. * np.array(n)/np.sum(n)]))
def create_tractor(opt): """ Brittle function to read Groves data sample and make the things we need for fitting. # issues: - Need to read the WCS too. - Need, for each image, to construct the rectangular nearest-neighbor interpolation indices to image 0. - Can I just blow up the SPIRE images with interpolation? """ dataList = [ ('m31_brick15_PACS100.fits', 'PACS 100', 7.23, 7.7), ('m31_brick15_PACS160.fits', 'PACS 160', 3.71, 12.0), ('m31_brick15_SPIRE250.fits', 'SPIRE 250', None, 18.0), ('m31_brick15_SPIRE350.fits', 'SPIRE 350', None, 25.0), ('m31_brick15_SPIRE500.fits', 'SPIRE 500', None, 37.0), ] # From Groves via Rix: # PSF FWHMs: 6.97, 11.01, 18.01, 24.73, 35.98 # Within the region Ive selected I found temperatures between 15 # and 21 K, averaging 17 K, and Beta= 1.5 to 2.5 (with a larger # uncertainty), averaging around 2.0. if opt.no100: dataList = dataList[1:] print('Reading images...') tims = [] for i, (fn, nm, noise, fwhm) in enumerate(dataList): print() print('Reading', fn) P = pyfits.open(fn) image = P[0].data.astype(np.float32) #wcs = Tan(fn, 0) H,W = image.shape hdr = P[0].header wcs = Tan(hdr['CRVAL1'], hdr['CRVAL2'], hdr['CRPIX1'], hdr['CRPIX2'], hdr['CDELT1'], 0., 0., hdr['CDELT2'], W, H) assert(hdr['CROTA2'] == 0.) if noise is None: noise = float(hdr['NOISE']) print('Noise', noise) print('Median image value', np.median(image)) inverr = np.ones_like(image) / noise skyval = np.percentile(image, 5) sky = ConstantSky(skyval) lam = float(hdr['FILTER']) print('Lambda', lam) # calibrated, yo assert(hdr['BUNIT'] == 'MJy/Sr') # "Filter" is in *microns* in the headers; convert to *m* here, to match "lam0" pcal = DustPhotoCal(lam * 1e-6, wcs.pixel_scale()) #nm = '%s %i' % (hdr['INSTRUME'], lam) #nm = fn.replace('.fits', '') #zr = noise * np.array([-3, 10]) + skyval zr = np.array([np.percentile(image.ravel(), p) for p in [1, 99]]) print('Pixel scale:', wcs.pixel_scale()) # meh sigma = fwhm / wcs.pixel_scale() / 2.35 print('PSF sigma', sigma, 'pixels') psf = NCircularGaussianPSF([sigma], [1.]) twcs = ConstantFitsWcs(wcs) tim = Image(data=image, inverr=inverr, psf=psf, wcs=twcs, sky=sky, photocal=pcal, name=nm) print('created', tim) tim.zr = zr tims.append(tim) # plt.clf() # plt.hist(image.ravel(), 100) # plt.title(nm) # plt.savefig('im%i-hist.png' % i) radecbounds = [] for tim in tims: H,W = tim.shape twcs = tim.getWcs() rds = [] for x,y in [(0.5,0.5),(W+0.5,0.5),(W+0.5,H+0.5),(0.5,H+0.5),(0.5,0.5)]: rd = twcs.pixelToPosition(x-1, y-1) rds.append(rd) rds = np.array(rds) radecbounds.append(rds) rd = np.vstack(radecbounds) #print 'rd', rd.shape ramin,decmin = rd.min(axis=0) ramax,decmax = rd.max(axis=0) dr,dd = ramax-ramin, decmax-decmin plotrange = (ramin - 0.05*dr, ramax + 0.05*dr, decmin - 0.05*dd, decmax + 0.05*dd) plt.clf() for rds,c in zip(radecbounds, ['b','g','y',(1,0.5,0),'r']): plt.plot(rds[:,0], rds[:,1], '-', color=c, lw=2, alpha=0.5) setRadecAxes(*plotrange) plt.savefig('radec1%s.png' % opt.suffix) print('Creating dust sheet...') N = opt.gridn # Build a WCS for the dust sheet to match the first image # (assuming it's square and axis-aligned) #wcs = tims[0].getWcs().wcs #r,d = wcs.radec_center() #H,W = tims[0].shape #scale = wcs.pixel_scale() #scale *= float(W)/max(1, N-1) / 3600. #c = float(N)/2. + 0.5 #dwcs = Tan(r, d, c, c, scale, 0, 0, scale, N, N) # Build an axis-aligned WCS that contains all the images. r,d = (ramin + ramax) / 2., (decmin + decmax) / 2. # HACK -- ignore pole issues scale = max((ramax - ramin) * np.cos(np.deg2rad(d)), decmax - decmin) / float(N) scale *= float(N) / float(max(1, N-1)) scale *= (1. / opt.zoom) cpix = float(N)/2. + 0.5 dwcs = Tan(r, d, cpix, cpix, scale, 0, 0, scale, N, N) pixscale = dwcs.pixel_scale() logsa = np.log(1e-3) H,W = N,N logsa = np.zeros((H,W)) + logsa logt = np.zeros((H,W)) + np.log(17.) emis = np.zeros((H,W)) + 2. ds = DustSheet(logsa, logt, emis, dwcs) rds = ds.getRaDecCorners(0.5) plt.plot(rds[:,0], rds[:,1], 'k-', lw=1, alpha=1) setRadecAxes(*plotrange) plt.savefig('radec2%s.png' % opt.suffix) # plot grid of sample points. rds = [] H,W = N,N for y in range(N): for x in range(N): r,d = dwcs.pixelxy2radec(x+1, y+1) rds.append((r,d)) rds = np.array(rds) plt.plot(rds[:,0], rds[:,1], 'k.', lw=1, alpha=0.5) setRadecAxes(*plotrange) plt.savefig('radec3%s.png' % opt.suffix) #print 'DustSheet:', ds #print 'np', ds.numberOfParams() #print 'pn', ds.getParamNames() #print 'p', ds.getParams() # print 'PriorChi:', ds.getLogPriorChi() # ra,ca,va,pb = ds.getLogPriorChi() # print 'ra', ra # print 'ca', ca # print 'va', va # print 'pb', pb # for ri,ci,vi,bi in zip(ra,ca,va,pb): # print # print 'ri', ri # print 'ci', ci # print 'vi', vi # print 'bi', bi cat = Catalog() cat.append(ds) tractor = Tractor(Images(*tims), cat) return tractor
def dojob(job, userimage, log=None): jobdir = job.make_dir() #print 'Created job dir', jobdir #log = create_job_logger(job) #jobdir = job.get_dir() if log is None: log = create_job_logger(job) log.msg('Starting Job processing for', job) job.set_start_time() job.save() #os.chdir(dirnm) - not thread safe (working directory is global)! log.msg('Creating directory', jobdir) axyfn = 'job.axy' axypath = os.path.join(jobdir, axyfn) sub = userimage.submission log.msg('submission id', sub.id) df = userimage.image.disk_file img = userimage.image # Build command-line arguments for the augment-xylist program, which # detects sources in the image and adds processing arguments to the header # to produce a "job.axy" file. slo,shi = sub.get_scale_bounds() # Note, this must match Job.get_wcs_file(). wcsfile = 'wcs.fits' axyflags = [] axyargs = { '--out': axypath, '--scale-low': slo, '--scale-high': shi, '--scale-units': sub.scale_units, '--wcs': wcsfile, '--rdls': 'rdls.fits', '--pixel-error': sub.positional_error, '--ra': sub.center_ra, '--dec': sub.center_dec, '--radius': sub.radius, '--downsample': sub.downsample_factor, # tuning-up maybe fixed; if not, turn it off with: #'--odds-to-tune': 1e9, # Other things we might want include... # --invert # -g / --guess-scale: try to guess the image scale from the FITS headers # --crpix-x <pix>: set the WCS reference point to the given position # --crpix-y <pix>: set the WCS reference point to the given position # -w / --width <pixels>: specify the field width # -e / --height <pixels>: specify the field height # -X / --x-column <column-name>: the FITS column name # -Y / --y-column <column-name> } if hasattr(img,'sourcelist'): # image is a source list; use --xylist axyargs['--xylist'] = img.sourcelist.get_fits_path() w,h = img.width, img.height if sub.image_width: w = sub.image_width if sub.image_height: h = sub.image_height axyargs['--width' ] = w axyargs['--height'] = h else: axyargs['--image'] = df.get_path() # UGLY if sub.parity == 0: axyargs['--parity'] = 'pos' elif sub.parity == 1: axyargs['--parity'] = 'neg' if sub.tweak_order == 0: axyflags.append('--no-tweak') else: axyargs['--tweak-order'] = '%i' % sub.tweak_order if sub.use_sextractor: axyflags.append('--use-sextractor') if sub.crpix_center: axyflags.append('--crpix-center') if sub.invert: axyflags.append('--invert') cmd = 'augment-xylist ' for (k,v) in axyargs.items(): if v: cmd += k + ' ' + str(v) + ' ' for k in axyflags: cmd += k + ' ' log.msg('running: ' + cmd) (rtn, out, err) = run_command(cmd) if rtn: log.msg('out: ' + out) log.msg('err: ' + err) logmsg('augment-xylist failed: rtn val', rtn, 'err', err) raise Exception log.msg('created axy file', axypath) # shell into compute server... logfn = job.get_log_file() # the "tar" commands both use "-C" to chdir, and the ssh command # and redirect uses absolute paths. cmd = ('(echo %(jobid)s; ' 'tar cf - --ignore-failed-read -C %(jobdir)s %(axyfile)s) | ' 'ssh -x -T %(sshconfig)s 2>>%(logfile)s | ' 'tar xf - --atime-preserve -m --exclude=%(axyfile)s -C %(jobdir)s ' '>>%(logfile)s 2>&1' % dict(jobid='job-%s-%i' % (settings.sitename, job.id), axyfile=axyfn, jobdir=jobdir, sshconfig=settings.ssh_solver_config, logfile=logfn)) log.msg('command:', cmd) w = os.system(cmd) if not os.WIFEXITED(w): log.msg('Solver failed (sent signal?)') logmsg('Call to solver failed for job', job.id) raise Exception rtn = os.WEXITSTATUS(w) if rtn: log.msg('Solver failed with return value %i' % rtn) logmsg('Call to solver failed for job', job.id, 'with return val', rtn) raise Exception log.msg('Solver completed successfully.') # Solved? wcsfn = os.path.join(jobdir, wcsfile) log.msg('Checking for WCS file', wcsfn) if os.path.exists(wcsfn): log.msg('WCS file exists') # Parse the wcs.fits file wcs = Tan(wcsfn, 0) # Convert to database model... tan = TanWCS(crval1=wcs.crval[0], crval2=wcs.crval[1], crpix1=wcs.crpix[0], crpix2=wcs.crpix[1], cd11=wcs.cd[0], cd12=wcs.cd[1], cd21=wcs.cd[2], cd22=wcs.cd[3], imagew=img.width, imageh=img.height) tan.save() log.msg('Created TanWCS:', tan) # Find field's healpix nside and index ra, dec, radius = tan.get_center_radecradius() nside = anutil.healpix_nside_for_side_length_arcmin(radius*60) nside = int(2**round(math.log(nside, 2))) healpix = anutil.radecdegtohealpix(ra, dec, nside) sky_location, created = SkyLocation.objects.get_or_create(nside=nside, healpix=healpix) log.msg('SkyLocation:', sky_location) # Find bounds for the Calibration object. r0,r1,d0,d1 = wcs.radec_bounds() # Find cartesian coordinates ra *= math.pi/180 dec *= math.pi/180 tempr = math.cos(dec) x = tempr*math.cos(ra) y = tempr*math.sin(ra) z = math.sin(dec) r = radius/180*math.pi calib = Calibration(raw_tan=tan, ramin=r0, ramax=r1, decmin=d0, decmax=d1, x=x,y=y,z=z,r=r, sky_location=sky_location) calib.save() log.msg('Created Calibration', calib) job.calibration = calib job.save() # save calib before adding machine tags job.status = 'S' job.user_image.add_machine_tags(job) job.user_image.add_sky_objects(job) else: job.status = 'F' job.set_end_time() job.save() log.msg('Finished job', job.id) logmsg('Finished job',job.id) return job.id