def fit_ellipse_for_source( friendid=None, detectid=None, coords=None, shotid=None, subcont=True, convolve_image=False, pixscale=pixscale, imsize=imsize, wave_range=None, ): if detectid is not None: global deth5 detectid_obj = detectid if detectid_obj <= 2190000000: det_info = deth5.root.Detections.read_where("detectid == detectid_obj")[0] linewidth = det_info["linewidth"] wave_obj = det_info["wave"] redshift = wave_obj / (1216) - 1 else: det_info = conth5.root.Detections.read_where("detectid == detectid_obj")[0] redshift = 0 wave_obj = 4500 coords_obj = SkyCoord(det_info["ra"], det_info["dec"], unit="deg") shotid_obj = det_info["shotid"] fwhm = surveyh5.root.Survey.read_where("shotid == shotid_obj")["fwhm_virus"][0] amp = det_info["multiframe"] if wave_range is not None: wave_range_obj = wave_range else: if detectid_obj <= 2190000000: wave_range_obj = [wave_obj - 2 * linewidth, wave_obj + 2 * linewidth] else: wave_range_obj = [4100, 4200] if coords is not None: coords_obj = coords if shotid is not None: shotid_obj = shotid fwhm = surveyh5.root.Survey.read_where("shotid == shotid_obj")[ "fwhm_virus" ][0] try: hdu = make_narrowband_image( coords=coords_obj, shotid=shotid_obj, wave_range=wave_range_obj, imsize=imsize * u.arcsec, pixscale=pixscale * u.arcsec, subcont=subcont, convolve_image=convolve_image, include_error=True, ) except: print("Could not make narrowband image for {}".format(detectid)) return np.nan, np.nan elif friendid is not None: global friend_cat sel = friend_cat["friendid"] == friendid group = friend_cat[sel] coords_obj = SkyCoord(ra=group["icx"][0] * u.deg, dec=group["icy"][0] * u.deg) wave_obj = group["icz"][0] redshift = wave_obj / (1216) - 1 linewidth = group["linewidth"][0] shotid_obj = group["shotid"][0] fwhm = group["fwhm"][0] amp = group["multiframe"][0] if wave_range is not None: wave_range_obj = wave_range else: wave_range_obj = [wave_obj - 2 * linewidth, wave_obj + 2 * linewidth] if shotid is not None: shotid_obj = shotid fwhm = surveyh5.root.Survey.read_where("shotid == shotid_obj")[ "fwhm_virus" ][0] try: hdu = make_narrowband_image( coords=coords_obj, shotid=shotid_obj, wave_range=wave_range_obj, imsize=imsize * u.arcsec, pixscale=pixscale * u.arcsec, subcont=subcont, convolve_image=convolve_image, include_error=True, ) except: print("Could not make narrowband image for {}".format(friendid)) return None elif coords is not None: coords_obj = coords if wave_range is not None: wave_range_obj = wave_range else: print( "You need to supply wave_range=[wave_start, wave_end] for collapsed image" ) if shotid is not None: shotid_obj = shotid fwhm = surveyh5.root.Survey.read_where("shotid == shotid_obj")[ "fwhm_virus" ][0] else: print("Enter the shotid to use (eg. 20200123003)") hdu = make_narrowband_image( coords=coords_obj, shotid=shotid_obj, wave_range=wave_range_obj, imsize=imsize * u.arcsec, pixscale=pixscale * u.arcsec, subcont=subcont, convolve_image=convolve_image, include_error=True, ) else: print("You must provide a detectid, friendid or coords/wave_range/shotid") return np.nan, np.nan w = wcs.WCS(hdu[0].header) if friendid is not None: sel_friend_group = friend_cat["friendid"] == friendid group = friend_cat[sel_friend_group] eps = 1 - group["a2"][0] / group["b2"][0] pa = group["pa"][0] * np.pi / 180.0 - 90 sma = group["a"][0] * 3600 / pixscale coords = SkyCoord(ra=group["icx"][0] * u.deg, dec=group["icy"][0] * u.deg) wave_obj = group["icz"][0] redshift = wave_obj / (1216) - 1 linewidth = np.nanmedian(group["linewidth"]) shotid_obj = group["shotid"][0] fwhm = group["fwhm"][0] geometry = EllipseGeometry( x0=w.wcs.crpix[0], y0=w.wcs.crpix[0], sma=sma, eps=eps, pa=pa ) else: geometry = EllipseGeometry( x0=w.wcs.crpix[0], y0=w.wcs.crpix[0], sma=20, eps=0.2, pa=20.0 ) geometry = EllipseGeometry( x0=w.wcs.crpix[0], y0=w.wcs.crpix[0], sma=20, eps=0.2, pa=20.0 ) # geometry.find_center(hdu.data) # aper = EllipticalAperture((geometry.x0, geometry.y0), geometry.sma, # geometry.sma*(1 - geometry.eps), geometry.pa) # plt.imshow(hdu.data, origin='lower') # aper.plot(color='white') ellipse = Ellipse(hdu[0].data) isolist = ellipse.fit_image() iso_tab = isolist.to_table() if len(iso_tab) == 0: geometry.find_center(hdu[0].data, verbose=False, threshold=0.5) ellipse = Ellipse(hdu[0].data, geometry) isolist = ellipse.fit_image() iso_tab = isolist.to_table() if len(iso_tab) == 0: return np.nan, np.nan, np.nan try: # compute iso's manually in steps of 3 pixels ellipse = Ellipse(hdu[0].data) # reset ellipse iso_list = [] for sma in np.arange(1, 60, 2): iso = ellipse.fit_isophote(sma) if np.isnan(iso.intens): # print('break at {}'.format(sma)) break else: iso_list.append(iso) isolist = IsophoteList(iso_list) iso_tab = isolist.to_table() except: return np.nan, np.nan, np.nan try: model_image = build_ellipse_model(hdu[0].data.shape, isolist) residual = hdu[0].data - model_image except: return np.nan, np.nan, np.nan sma = iso_tab["sma"] * pixscale const_arcsec_to_kpc = cosmo.kpc_proper_per_arcmin(redshift).value / 60.0 def arcsec_to_kpc(sma): dist = const_arcsec_to_kpc * sma return dist def kpc_to_arcsec(dist): sma = dist / const_arcsec_to_kpc return sma dist_kpc = ( sma * u.arcsec.to(u.arcmin) * u.arcmin * cosmo.kpc_proper_per_arcmin(redshift) ) dist_arcsec = kpc_to_arcsec(dist_kpc) # print(shotid_obj, fwhm) # s_exp1d = models.Exponential1D(amplitude=0.2, tau=-50) alpha = 3.5 s_moffat = models.Moffat1D( amplitude=1, gamma=(0.5 * fwhm) / np.sqrt(2 ** (1.0 / alpha) - 1.0), x_0=0.0, alpha=alpha, fixed={"amplitude": False, "x_0": True, "gamma": True, "alpha": True}, ) s_init = models.Exponential1D(amplitude=0.2, tau=-50) fit = fitting.LevMarLSQFitter() s_r = fit(s_init, dist_kpc, iso_tab["intens"]) # Fitting can be done using the uncertainties as weights. # To get the standard weighting of 1/unc^2 for the case of # Gaussian errors, the weights to pass to the fitting are 1/unc. # fitted_line = fit(line_init, x, y, weights=1.0/yunc) # s_r = fit(s_init, dist_kpc, iso_tab['intens'])#, weights=iso_tab['intens']/iso_tab['intens_err'] ) print(s_r) try: r_n = -1.0 * s_r.tau # _0 #* const_arcsec_to_kpc except: r_n = np.nan # r_n = -1. * s_r.tau_0 try: sel_iso = np.where(dist_kpc >= 2 * r_n)[0][0] except: sel_iso = -1 aper = EllipticalAperture( (isolist.x0[sel_iso], isolist.y0[sel_iso]), isolist.sma[sel_iso], isolist.sma[sel_iso] * (1 - isolist.eps[sel_iso]), isolist.pa[sel_iso], ) phottable = aperture_photometry(hdu[0].data, aper, error=hdu[1].data) flux = phottable["aperture_sum"][0] * 10 ** -17 * u.erg / (u.cm ** 2 * u.s) flux_err = phottable["aperture_sum_err"][0] * 10 ** -17 * u.erg / (u.cm ** 2 * u.s) lum_dist = cosmo.luminosity_distance(redshift).to(u.cm) lum = flux * 4.0 * np.pi * lum_dist ** 2 lum_err = flux_err * 4.0 * np.pi * lum_dist ** 2 if detectid: name = detectid elif friendid: name = friendid # Get Image data from Elixer catlib = catalogs.CatalogLibrary() try: cutout = catlib.get_cutouts( position=coords_obj, side=imsize, aperture=None, dynamic=False, filter=["r", "g", "f606W"], first=True, allow_bad_image=False, allow_web=True, )[0] except: print("Could not get imaging for " + str(name)) zscale = ZScaleInterval(contrast=0.5, krej=1.5) vmin, vmax = zscale.get_limits(values=hdu[0].data) fig = plt.figure(figsize=(20, 12)) fig.suptitle( "{} ra={:3.2f}, dec={:3.2f}, wave={:5.2f}, z={:3.2f}, mf={}".format( name, coords_obj.ra.value, coords_obj.dec.value, wave_obj, redshift, amp ), fontsize=22, ) ax1 = fig.add_subplot(231, projection=w) plt.imshow(hdu[0].data, vmin=vmin, vmax=vmax) plt.xlabel("RA") plt.ylabel("Dec") plt.colorbar() plt.title("Image summed across 4*linewidth") ax2 = fig.add_subplot(232, projection=w) plt.imshow(model_image, vmin=vmin, vmax=vmax) plt.xlabel("RA") plt.ylabel("Dec") plt.colorbar() plt.title("model") ax3 = fig.add_subplot(233, projection=w) plt.imshow(residual, vmin=vmin, vmax=vmax) plt.xlabel("RA") plt.ylabel("Dec") plt.colorbar() plt.title("residuals (image-model)") # fig = plt.figure(figsize=(10,5)) im_zscale = ZScaleInterval(contrast=0.5, krej=2.5) im_vmin, im_vmax = im_zscale.get_limits(values=cutout["cutout"].data) ax4 = fig.add_subplot(234, projection=cutout["cutout"].wcs) plt.imshow( cutout["cutout"].data, vmin=im_vmin, vmax=im_vmax, origin="lower", cmap=plt.get_cmap("gray"), interpolation="none", ) plt.text( 0.8, 0.9, cutout["instrument"] + cutout["filter"], transform=ax4.transAxes, fontsize=20, color="w", ) plt.contour(hdu[0].data, transform=ax4.get_transform(w)) plt.xlabel("RA") plt.ylabel("Dec") aper.plot( color="white", linestyle="dashed", linewidth=2, transform=ax4.get_transform(w) ) ax5 = fig.add_subplot(235) plt.errorbar( dist_kpc.value, iso_tab["intens"], yerr=iso_tab["intens_err"] * iso_tab["intens"], linestyle="none", marker="o", label="Lya SB profile", ) plt.plot(dist_kpc, s_r(dist_kpc), color="r", label="Lya exp SB model", linewidth=2) plt.xlabel("Semi-major axis (kpc)") # plt.xlabel('Semi-major axis (arcsec)') plt.ylabel("Flux ({})".format(10 ** -17 * (u.erg / (u.s * u.cm ** 2)))) plt.text(0.4, 0.7, "r_n={:3.2f}".format(r_n), transform=ax5.transAxes, fontsize=16) plt.text( 0.4, 0.6, "L_lya={:3.2e}".format(lum), transform=ax5.transAxes, fontsize=16 ) secax = ax5.secondary_xaxis("top", functions=(kpc_to_arcsec, kpc_to_arcsec)) secax.set_xlabel("Semi-major axis (arcsec)") # secax.set_xlabel('Semi-major axis (kpc)') plt.xlim(0, 100) # plt.plot(sma, s_r(sma), label='moffat psf') # plt.plot(dist_kpc.value, s1(kpc_to_arcsec(dist_kpc.value)), # linestyle='dashed', linewidth=2, # color='green', label='PSF seeing:{:3.2f}'.format(fwhm)) # These two are the exact same # s1 = models.Moffat1D() # s1.amplitude = iso_tab['intens'][0] # alpha=3.5 # s1.gamma = 0.5*(fwhm*const_arcsec_to_kpc)/ np.sqrt(2 ** (1.0 / alpha) - 1.0) # s1.alpha = alpha # plt.plot(r_1d, moffat_1d, color='orange') # plt.plot(dist_kpc.value, (s1(dist_kpc.value)), # linestyle='dashed', linewidth=2, # color='blue', label='PSF seeing:{:3.2f}'.format(fwhm)) E = Extract() E.load_shot(shotid_obj) moffat_psf = E.moffat_psf(seeing=fwhm, boxsize=imsize, scale=pixscale) moffat_shape = np.shape(moffat_psf) xcen = int(moffat_shape[1] / 2) ycen = int(moffat_shape[2] / 2) moffat_1d = ( moffat_psf[0, xcen:-1, ycen] / moffat_psf[0, xcen, ycen] * iso_tab["intens"][0] ) r_1d = moffat_psf[1, xcen:-1, ycen] E.close() plt.plot( arcsec_to_kpc(pixscale * np.arange(80)), iso_tab["intens"][0] * (moffat_psf[0, 80:-1, 80] / moffat_psf[0, 80, 80]), linestyle="dashed", color="green", label="PSF seeing:{:3.2f}".format(fwhm), ) plt.legend() if friendid is not None: ax6 = fig.add_subplot(236, projection=cutout["cutout"].wcs) plot_friends(friendid, friend_cat, cutout, ax=ax6, label=False) plt.savefig("fit2d_{}.png".format(name)) # filename = 'param_{}.txt'.format(name) # np.savetxt(filename, (r_n.value, lum.value)) return r_n, lum, lum_err
def main(argv=None): """ Main Function """ parser = get_parser() args = parser.parse_args(argv) args.log = setup_logging() args.log.info(args) class FiberImage2D(tb.IsDescription): detectid = tb.Int64Col(pos=0) im_wave = tb.Float32Col(args.width, pos=1) im_sum = tb.Float32Col((args.height, args.width), pos=2) im_array = tb.Float32Col((4, args.height, args.width), pos=3) if args.merge: fileh = tb.open_file("merged_im2D.h5", "w") fibim2D_table = fileh.create_table(fileh.root, "FiberImages", FiberImage2D, "Fiber Cutout Images", expectedrows=1000000) phot_table = fileh.create_table(fileh.root, "PhotImages", PhotImage, "Photometric Images", expectedrows=1000000) spec_table = fileh.create_table(fileh.root, "Spec1D", Spec1D, "Aperture Summed Spectrum", expectedrows=1000000) files = sorted(glob.glob("im2D*.h5")) for file in files: args.log.info('Ingesting %s' % file) fileh_i = tb.open_file(file, "r") fibim2D_table_i = fileh_i.root.FiberImages.read() phot_table_i = fileh_i.root.PhotImages.read() spec_table_i = fileh_i.root.Spec1D.read() fibim2D_table.append(fibim2D_table_i) phot_table.append(phot_table_i) spec_table.append(spec_table_i) fileh_i.close() fibim2D_table.flush() phot_table.flush() spec_table.flush() fibim2D_table.cols.detectid.create_csindex() phot_table.cols.detectid.create_csindex() spec_table.cols.detectid.create_csindex() fibim2D_table.flush() phot_table.flush() spec_table.flush() fileh.close() sys.exit("Merged h5 files in current directory. Exiting") shotid_i = args.shotid detects = Detections(args.survey, loadtable=False) if args.infile: try: catalog = Table.read(args.infile, format="ascii") except: catalog = Table.read(args.infile) selcat = catalog["shotid"] == args.shotid detectlist = np.array(catalog["detectid"][selcat]) elif args.dets: if op.exists(args.dets): try: catalog = Table.read(args.dets, format="ascii") selcat = catalog["shotid"] == int(shotid_i) detectlist = np.array(catalog["detectid"][selcat]) except: detectlist = np.loadtxt(args.dets, dtype=int) else: args.log.warning('No dets for ' + str(shotid_i)) sys.exit() if len(detectlist) == 0: sys.exit() # open up catalog library from elixer catlib = catalogs.CatalogLibrary() args.log.info("Opening shot: " + str(shotid_i)) fibers = Fibers(args.shotid, survey=args.survey) if args.h5file: fileh = tb.open_file("im2D_" + str(args.shotid) + ".h5", "w") fibim2D_table = fileh.create_table(fileh.root, "FiberImages", FiberImage2D, "Fiber Cutout Images") phot_table = fileh.create_table(fileh.root, "PhotImages", PhotImage, "Photometric Images") spec_table = fileh.create_table(fileh.root, "Spec1D", Spec1D, "Aperture Summed Spectrum") for detectid_i in detectlist: # add data to HDF5 file row = fibim2D_table.row row["detectid"] = detectid_i sel = detects.detectid == detectid_i try: row["im_wave"] = get_2Dimage_wave(detectid_i, detects, fibers, width=args.width, height=args.height) except: args.log.error("Could not get wave array for %s" % detectid_i) try: row["im_sum"] = get_2Dimage(detectid_i, detects, fibers, width=args.width, height=args.height) except: args.log.error("Could not get Fiber sum for %s" % detectid_i) try: im_arr, fiber_table = get_2Dimage_array(detectid_i, detects, fibers, width=args.width, height=args.height) row["im_array"] = im_arr except: args.log.error("Could not get 4 Fiber info for %s" % detectid_i) row.append() row_spec = spec_table.row spec_tab = detects.get_spectrum(detectid_i) row_spec["detectid"] = detectid_i row_spec["spec1D"] = spec_tab["spec1d"] row_spec["spec1D_err"] = spec_tab["spec1d_err"] row_spec.append() row_phot = phot_table.row # add in phot image, need RA/DEC from catalog # sel_det = detects.detectid == detectid_i # coord = detects.coords[sel_det] det_row = detects.hdfile.root.Detections.read_where( 'detectid == detectid_i') coord = SkyCoord(ra=det_row["ra"] * u.deg, dec=det_row["dec"] * u.deg) row_phot["detectid"] = detectid_i # ignore the Fall data for now if coord.dec.value > 10: try: cutout = catlib.get_cutouts( position=coord, radius=5, aperture=None, dynamic=False, filter="r", first=True, )[0] if cutout["instrument"] == "HSC": # get shape to ensure slicing on cropped images phot = np.shape(cutout["cutout"].data) row_phot["im_phot"] = cutout["cutout"].data header = cutout["cutout"].wcs.to_header() row_phot["im_phot_hdr"] = header.tostring() except: pass #args.log.warning("No imaging available for source") else: pass row_phot.append() spec_table.flush() phot_table.flush() fibim2D_table.flush() fileh.close() else: for detectid_i in detectlist: save_2Dimage( detectid_i, detects, fibers, width=args.width, height=args.height, path=args.path, ) if args.ra and args.dec: # NOTE this has not been updated yet.. will build functionality soon obj_coords = SkyCoord(args.ra * u.deg, args.dec * u.deg, frame="icrs") idx = fibers.query_region_idx(obj_coords, radius=(args.rad / 3600.0)) output = Table() output["ra"] = fibers.coords.ra[idx] * u.deg output["dec"] = fibers.coords.dec[idx] * u.deg filenames = [] fileidx = 101 for i in idx: filename = "tmp" + str(fileidx) + ".dat" filenames.append(filename) save_rsp_spectrum( fibers, i, file=filename, ) fileidx += 1 output["filename"] = np.array(filenames) ascii.write(output, "fib_coords.dat", overwrite=True) fibers.close() detects.close() tb.file._open_files.close_all()
from regions import LineSkyRegion, PixCoord, LinePixelRegion from hetdex_api.config import HDRconfig from hetdex_api.survey import Survey from hetdex_api.detections import Detections import hetdex_tools.fof_kdtree as fof from hetdex_api.elixer_widget_cls import ElixerWidget from hetdex_api.flux_limits.hdf5_sensitivity_cubes import SensitivityCubeHDF5Container from elixer import catalogs from hetdex_api.extinction import * import extinction catlib = catalogs.CatalogLibrary() config = HDRconfig() agn_tab = None cont_gals = None cont_stars = None wavelya = 1215.67 waveoii = 3727.8 deth5 = None conth5 = None def return_fiber_ratio(det, det_type):
def __init__( self, coords=None, detectid=None, survey="hdr2.1", aperture=3.0 * u.arcsec, cutout_size=5.0 * u.arcmin, zoom=3, ): self.survey = survey.lower() self.detectid = detectid self.aperture = aperture self.cutout_size = cutout_size self.zoom = zoom config = HDRconfig(survey=survey) self.fileh5dets = tb.open_file(config.detecth5, "r") self.catlib = catalogs.CatalogLibrary() if coords: self.coords = coords self.detectid = 1000000000 elif detectid: self.detectid = detectid self.update_det_coords() else: self.coords = SkyCoord(191.663132 * u.deg, 50.712696 * u.deg, frame="icrs") self.detectid = 2101848640 # initialize the image widget from astrowidgets self.imw = ImageWidget(image_width=600, image_height=600) self.survey_widget = widgets.Dropdown( options=["HDR1", "HDR2", "HDR2.1"], value=self.survey.upper(), layout=Layout(width="10%"), ) self.detectbox = widgets.BoundedIntText( value=self.detectid, min=1000000000, max=3000000000, step=1, description="DetectID:", disabled=False, ) self.im_ra = widgets.FloatText( value=self.coords.ra.value, description="RA (deg):", layout=Layout(width="20%"), ) self.im_dec = widgets.FloatText( value=self.coords.dec.value, description="DEC (deg):", layout=Layout(width="20%"), ) self.pan_to_coords = widgets.Button(description="Pan to coords", disabled=False, button_style="success") self.marking_button = widgets.Button(description="Mark Sources", button_style="success") self.reset_marking_button = widgets.Button(description="Reset", button_style="success") self.extract_button = widgets.Button(description="Extract Object", button_style="success") self.marker_table_output = widgets.Output( layout={"border": "1px solid black"}) # self.spec_output = widgets.Output(layout={'border': '1px solid black'}) self.spec_output = widgets.Tab(description="Extracted Spectra:", layout={"border": "1px solid black"}) self.textimpath = widgets.Text(description="Source: ", value="", layout=Layout(width="90%")) self.topbox = widgets.HBox([ self.survey_widget, self.detectbox, self.im_ra, self.im_dec, self.pan_to_coords, ]) self.leftbox = widgets.VBox([self.imw, self.textimpath], layout=Layout(width="800px")) self.rightbox = widgets.VBox( [ widgets.HBox([ self.marking_button, self.reset_marking_button, self.extract_button, ]), self.marker_table_output, self.spec_output, ], layout=Layout(width="800px"), ) self.bottombox = widgets.Output(layout={"border": "1px solid black"}) self.load_image() self.all_box = widgets.VBox([ self.topbox, widgets.HBox([self.leftbox, self.rightbox]), #self.spec_output, self.bottombox ]) display(self.all_box) self.detectbox.observe(self.on_det_change) self.pan_to_coords.on_click(self.pan_to_coords_click) self.marking_button.on_click(self.marking_on_click) self.reset_marking_button.on_click(self.reset_marking_on_click) self.extract_button.on_click(self.extract_on_click) self.survey_widget.observe(self.on_survey_change)