def segmentation_figure(label, cat, segfile): """ Make a figure showing a cutout of the segmentation file """ import matplotlib.pyplot as plt import numpy as np import astropy.io.fits as pyfits import astropy.wcs as pywcs from grizli import utils plt.ioff() seg = pyfits.open(segfile) seg_data = seg[0].data seg_wcs = pywcs.WCS(seg[0].header) # Randomize seg to get dispersion between neighboring objects np.random.seed(hash(label.split('_')[0]) % (10 ** 8)) rnd_ids = np.append([0], np.argsort(np.random.rand(len(cat)))+1) # Make cutout th = pyfits.open('{0}.thumb.fits'.format(label), mode='update') th_wcs = pywcs.WCS(th[0].header) blot_seg = utils.blot_nearest_exact(seg_data, seg_wcs, th_wcs, stepsize=-1, scale_by_pixel_area=False) rnd_seg = rnd_ids[np.cast[int](blot_seg)]*1. th_ids = np.unique(blot_seg) sh = th[0].data.shape yp, xp = np.indices(sh) thumb_height = 2. fig = plt.figure(figsize=[thumb_height*sh[1]/sh[0], thumb_height]) ax = fig.add_subplot(111) rnd_seg[rnd_seg == 0] = np.nan ax.imshow(rnd_seg, aspect='equal', cmap='terrain_r', vmin=-0.05*len(cat), vmax=1.05*len(cat)) ax.set_xticklabels([]) ax.set_yticklabels([]) ix = utils.column_values_in_list(cat['number'], th_ids) xc, yc = th_wcs.all_world2pix(cat['ra'][ix], cat['dec'][ix], 0) xc = np.clip(xc, 0.09*sh[1], 0.91*sh[1]) yc = np.clip(yc, 0.08*sh[0], 0.92*sh[0]) for th_id, x_i, y_i in zip(cat['number'][ix], xc, yc): if th_id == 0: continue ax.text(x_i, y_i, '{0:.0f}'.format(th_id), ha='center', va='center', fontsize=8, color='w') ax.text(x_i, y_i, '{0:.0f}'.format(th_id), ha='center', va='center', fontsize=8, color='k', alpha=0.95) ax.set_xlim(0, sh[1]-1) ax.set_ylim(0, sh[0]-1) ax.set_axis_off() fig.tight_layout(pad=0.01) fig.savefig('{0}.seg.png'.format(label)) plt.close(fig) # Append to thumbs file seg_hdu = pyfits.ImageHDU(data=np.cast[int](blot_seg), name='SEG') if 'SEG' in th: th.pop('SEG') th.append(seg_hdu) th.writeto('{0}.thumb.fits'.format(label), overwrite=True, output_verify='fix') th.close()
def resample_array(img, wht=None, pixratio=2, slice_if_int=True, int_tol=1.e-3, method='drizzle', drizzle_kwargs=DRIZZLE_KWARGS, rescale_kwargs=RESCALE_KWARGS, scale_by_area=False, verbose=False, blot_stepsize=-1, **kwargs): """ Resample an image to a new grid. If pixratio is an integer, just return a slice of the input `img`. Otherwise resample with `~drizzlepac` or `~resample`. """ from grizli.utils import (make_wcsheader, drizzle_array_groups, blot_nearest_exact) from skimage.transform import rescale, resize, downscale_local_mean is_int = np.isclose(pixratio, np.round(pixratio), atol=int_tol) if is_int & (pixratio > 1): # Integer scaling step = int(np.round(pixratio)) if method.lower() == 'drizzle': _, win = make_wcsheader(ra=90, dec=0, size=img.shape, pixscale=1., get_hdu=False, theta=0.) _, wout = make_wcsheader(ra=90, dec=0, size=img.shape, pixscale=pixratio, get_hdu=False, theta=0.) if wht is None: wht = np.ones_like(img) _drz = drizzle_array_groups([img], [wht], [win], outputwcs=wout, **drizzle_kwargs) res = _drz[0] res_wht = _drz[1] method_used = 'drizzle' elif slice_if_int: # Simple slice res = img[step // 2::step, step // 2::step] * 1 res_wht = np.ones_like(res) method_used = 'slice' else: # skimage downscale with averaging res = downscale_local_mean(img, (step, step), cval=0, clip=True) res_wht = np.ones_like(res) method_used = 'downscale' else: if method.lower() == 'drizzle': # Drizzle _, win = make_wcsheader(ra=90, dec=0, size=img.shape, pixscale=1., get_hdu=False, theta=0.) _, wout = make_wcsheader(ra=90, dec=0, size=img.shape, pixscale=pixratio, get_hdu=False, theta=0.) if wht is None: wht = np.ones_like(img) _drz = drizzle_array_groups([img], [wht], [win], outputwcs=wout, **drizzle_kwargs) res = _drz[0] res_wht = _drz[1] method_used = 'drizzle' elif method.lower() == 'blot': # Blot exact values _, win = make_wcsheader(ra=90, dec=0, size=img.shape, pixscale=1., get_hdu=False, theta=0.) _, wout = make_wcsheader(ra=90, dec=0, size=img.shape, pixscale=pixratio, get_hdu=False, theta=0.) # Ones for behaviour around zeros res = blot_nearest_exact(img + 1, win, wout, verbose=False, stepsize=blot_stepsize, scale_by_pixel_area=False, wcs_mask=False, fill_value=0) - 1 res_wht = np.ones_like(res) method_used = 'blot' elif method.lower() == 'rescale': res = rescale(img, 1. / pixratio, **rescale_kwargs) res_wht = np.ones_like(res) method_used = 'rescale' else: raise ValueError("method must be 'drizzle', 'blot' or 'rescale'.") if scale_by_area: scale = 1. / pixratio**2 else: scale = 1 if verbose: msg = 'resample_array x {4:.1f}: {0} > {1}, method={2}, scale={3:.2f}' print(msg.format(img.shape, res.shape, method_used, scale, pixratio)) if not np.isclose(scale, 1, 1.e-4): res = res * scale res_wht = res_wht / scale**2 #print(res_wht, res_wht.dtype, scale, res_wht.shape) #res_wht /= scale**2 return res, res_wht
def run_root(root='j002532m1223', min_zoom=2, get_grism=True): """ Prepare images for fitsmap.convert """ from grizli.pipeline import auto_script from grizli import utils import eazy.utils from fitsmap import convert print('sync') os.system( f'aws s3 sync s3://grizli-v1/Pipeline/{root}/Prep/ {root}/ --exclude "*" --include "*sci.fits.gz" --include "*phot.fits" --include "*seg.fits.gz"' ) os.system( f'aws s3 sync s3://grizli-v1/Pipeline/{root}/IRAC/ {root}/ --exclude "*" --include "*sci.fits*" --include "*model.fits"' ) os.system( f'aws s3 sync s3://grizli-v1/Pipeline/{root}/Map/ {root}/ --exclude "*" --include "{root}.*png"' ) os.chdir(root) if not os.path.exists(f'{root}.rgb.png'): _ = auto_script.field_rgb(root=root, xsize=6, full_dimensions=True, HOME_PATH=None, gzext='*', suffix='.rgb', output_format='png') # IR files = glob.glob(f'{root}-[if][r01]*sci.fits*') files.sort() filts = [file.split(f'{root}-')[1].split('_')[0] for file in files] for filt in filts: if os.path.exists(f'{root}.{filt}.png'): continue _ = auto_script.field_rgb(root=root, xsize=6, full_dimensions=True, HOME_PATH=None, gzext='*', filters=[filt], suffix=f'.{filt}', output_format='png', invert=True, scl=2) # Optical, 2X pix files = glob.glob(f'{root}-[f][2-8]*sci.fits*') files.sort() filts = [file.split(f'{root}-')[1].split('_')[0] for file in files] for filt in filts: if os.path.exists(f'{root}.{filt}.png'): continue _ = auto_script.field_rgb(root=root, xsize=6, full_dimensions=2, HOME_PATH=None, gzext='*', filters=[filt], suffix=f'.{filt}', output_format='png', invert=True, scl=2) # Spitzer if glob.glob(f'{root}-ch*fits*'): import reproject out_img = pyfits.open(f'{root}-ir_drz_sci.fits.gz') repr_hdu = out_img[0] # repr_hdu = utils.make_maximal_wcs([out_wcs], pixel_scale=0.2, # verbose=False, pad=0, poly_buffer=0) repr_wcs = pywcs.WCS(repr_hdu.header) mosaics = glob.glob(f'{root}-ch[12]*sci.fits*') mosaics.sort() for mos in mosaics: ch = mos.split(f'{root}-')[1].split('_')[0] if os.path.exists(f'{root}.{ch}.png'): continue print(f'Reproject {ch}') in_img = pyfits.open(mos) in_wcs = pywcs.WCS(in_img[0].header) reproj = utils.blot_nearest_exact(in_img[0].data, in_wcs, repr_wcs, scale_by_pixel_area=False) pyfits.writeto(f'{root}-{ch}s_drz_sci.fits', data=reproj, header=repr_hdu.header, overwrite=True) ext = [ch + 's'] if os.path.exists(f'{root}-{ch}_model.fits'): # resid print(f' {ch} model') in_img = pyfits.open(f'{root}-{ch}_model.fits') reproj = utils.blot_nearest_exact(in_img[1].data, in_wcs, repr_wcs, scale_by_pixel_area=False) pyfits.writeto(f'{root}-{ch}m_drz_sci.fits', data=reproj, header=repr_hdu.header, overwrite=True) ext.append(ch + 'm') for filt in ext: _ = auto_script.field_rgb(root=root, xsize=6, full_dimensions=True, HOME_PATH=None, gzext='', filters=[filt], suffix=f'.{filt}', output_format='png', invert=True, scl=2) if not os.path.exists(f'{root}.seg.png'): sfig = make_seg(f'{root}-ir_seg.fits.gz', outfile=f'{root}.seg.png') filelist = [] for q in ['*f[2-8]', '*f[01]*', '*ir*', '*ch[12]', '*seg', '*rgb']: l_i = glob.glob(q + '*png') l_i.sort() filelist.extend(l_i) ph = utils.read_catalog(f'{root}_phot.fits') ph['id'] = ph['number'] ph['ra'].format = '.6f' ph['dec'].format = '.6f' ph['mag'] = ph['mag_auto'] ph['mag'].format = '.2f' ph['query'] = [ eazy.utils.query_html(r, d).split(') ')[1] for r, d in zip(ph['ra'], ph['dec']) ] ph['id', 'ra', 'dec', 'query', 'mag'].write('phot.cat', format='ascii.csv', overwrite=True) filelist += ['phot.cat'] if get_grism: from grizli.aws import db engine = db.get_db_engine() gr = db.from_sql( f"select root, id, ra, dec, z_map from redshift_fit where root='{root}'", engine) print(f'grism.cat: {len(gr)} sources') if len(gr) > 0: gr['query'] = [ eazy.utils.query_html(r, d).split(') ')[1] for r, d in zip(gr['ra'], gr['dec']) ] gr['stack'] = [ f'<img src="https://s3.amazonaws.com/grizli-v1/Pipeline/{root}/Extractions/{root}_{id:05d}.stack.png" height="100px"/>' for id in gr['id'] ] gr['full'] = [ f'<img src="https://s3.amazonaws.com/grizli-v1/Pipeline/{root}/Extractions/{root}_{id:05d}.full.png" height="100px"/>' for id in gr['id'] ] gr['line'] = [ f'<img src="https://s3.amazonaws.com/grizli-v1/Pipeline/{root}/Extractions/{root}_{id:05d}.line.png" height="80px"/>' for id in gr['id'] ] gr['ra'].format = '.6f' gr['dec'].format = '.6f' gr['z_map'].format = '.4f' gr['id', 'ra', 'dec', 'query', 'z_map', 'stack', 'full', 'line'].write('grism.cat', format='ascii.csv', overwrite=True) filelist += ['grism.cat'] convert.MPL_CMAP = 'gray_r' convert.cartographer.MARKER_HTML_WIDTH = '650px' convert.cartographer.MARKER_HTML_HEIGHT = '440px' convert.POPUP_CSS = [ "span { text-decoration:underline; font-weight:bold; line-height:12pt; }", "tr { line-height: 7pt; }", "table { width: 100%; }", "img { height: 100px; width: auto; }", ] convert.dir_to_map("./", filelist=filelist, out_dir="output", cat_wcs_fits_file=f"{root}-ir_drz_sci.fits.gz", catalog_delim=',', min_zoom=min_zoom, task_procs=False, image_engine='MPL') plt.close('all') if os.path.exists('output/index.html'): os.system( f'aws s3 sync output/ s3://grizli-v1/Pipeline/{root}/Map/ --acl public-read --quiet' ) os.system( f'aws s3 sync ./ s3://grizli-v1/Pipeline/{root}/Map/ --exclude "*" --include "{root}.*png" --acl public-read' )