Example #1
0
def Photutils_Fit(IMG, results, options):
    """
    Function to run the photutils automated isophote analysis on an image.
    """

    dat = IMG - results['background']
    geo = EllipseGeometry(x0=results['center']['x'],
                          y0=results['center']['y'],
                          sma=results['init R'] / 2,
                          eps=results['init ellip'],
                          pa=results['init pa'])
    ellipse = Photutils_Ellipse(dat, geometry=geo)

    isolist = ellipse.fit_image(fix_center=True, linear=False)
    res = {
        'fit R': isolist.sma[1:],
        'fit ellip': isolist.eps[1:],
        'fit ellip_err': isolist.ellip_err[1:],
        'fit pa': isolist.pa[1:],
        'fit pa_err': isolist.pa_err[1:],
        'auxfile fitlimit':
        'fit limit semi-major axis: %.2f pix' % isolist.sma[-1]
    }

    if 'ap_doplot' in options and options['ap_doplot']:
        ranges = [[
            max(0, int(results['center']['y'] - res['fit R'][-1] * 1.2)),
            min(dat.shape[1],
                int(results['center']['y'] + res['fit R'][-1] * 1.2))
        ],
                  [
                      max(0,
                          int(results['center']['x'] -
                              res['fit R'][-1] * 1.2)),
                      min(dat.shape[0],
                          int(results['center']['x'] + res['fit R'][-1] * 1.2))
                  ]]
        LSBImage(dat[ranges[1][0]:ranges[1][1], ranges[0][0]:ranges[0][1]],
                 results['background noise'])
        for i in range(len(res['fit R'])):
            plt.gca().add_patch(
                Ellipse(
                    (int(res['fit R'][-1] * 1.2), int(res['fit R'][-1] * 1.2)),
                    2 * res['fit R'][i],
                    2 * res['fit R'][i] * (1. - res['fit ellip'][i]),
                    res['fit pa'][i] * 180 / np.pi,
                    fill=False,
                    linewidth=0.5,
                    color='r'))
        if not ('ap_nologo' in options and options['ap_nologo']):
            AddLogo(plt.gcf())
        plt.savefig(
            '%sfit_ellipse_%s.jpg' %
            (options['ap_plotpath'] if 'ap_plotpath' in options else '',
             options['ap_name']),
            dpi=300)
        plt.close()

    return IMG, res
Example #2
0
    def maximize_intens(self, par):
        if self.photomorph == 'ellipse':
            geom = EllipseGeometry(
                par[0],
                par[1],
                par[2],
                par[3],
                par[4],
            )
            sample = EllipseSample(self.im,
                                   sma=geom.sma,
                                   astep=0,
                                   sclip=0.3,
                                   nclip=0,
                                   linear_growth=False,
                                   geometry=geom,
                                   integrmode='bilinear')
            data2min = np.mean(sample.extract()[2])
        elif self.photomorph == 'annulus':
            aper = EllipticalAnnulus(
                (par[0], par[1]), par[2] - self.beam_size_pix / 2.,
                par[2] + self.beam_size_pix / 2.,
                (par[2] + self.beam_size_pix / 2.) * (1. - par[3]), par[4])
            annulus_mask = aper.to_mask()
            data2min = annulus_mask.multiply(self.im)
        elif self.photomorph == 'circle':
            aper = CircularAperture((par[0], par[1]), par[2])
            circular_mask = aper.to_mask()
            data2min = circular_mask.multiply(self.im)
        elif self.photomorph == 'ellipse_area':
            aper = EllipticalAperture((par[0], par[1]), par[2],
                                      par[2] * (1. - par[3]), par[4])
            ellipse_mask = aper.to_mask()
            data2min = ellipse_mask.multiply(self.im)

        if self.q2min == 'sum':
            tominimize = np.sum(data2min)
        elif self.q2min == 'mean':
            tominimize = np.mean(data2min)

        return -tominimize
Example #3
0
def burst_drift(npy, fslice=':', tslice=':'):

    #Load npy array
    burst = np.load(npy)

    #Subband in Frequency
    subfac = 16
    rb_sub = np.nanmean(R3H.reshape(-1, subfac, R3H.shape[1]), axis=1)

    rb_sub_zm = rb_sub[fslice, tslice]

    ynorm = (rb_sub_zm.sum(0) / np.max(rb_sub_zm.sum(0)))
    x = np.linspace(0, len(ynorm) - 1, len(ynorm))

    #Smooth

    sav = ss.savgol_filter(rb_sub_zm, 49, 6)

    #Calculate 2D ACF

    acf = ss.correlate(sav, sav)

    #Provide the initial Ellipse to be fitted
    #Calculate Ellipse Geometry
    geometry = EllipseGeometry(x0=acf.shape[1] / 2,
                               y0=acf.shape[0] / 2,
                               sma=20,
                               eps=0.4,
                               pa=60 * np.pi / 180.)
    #Show Initial Guess Ellipsee
    aper = EllipticalAperture((geometry.x0, geometry.y0), geometry.sma,
                              geometry.sma * (1 - geometry.eps), geometry.pa)

    #Plot Initial Guess Ellipse on ACF

    #plt.imshow(acf, aspect = 'auto')
    #aper.plot(color='white')

    #Fit Ellipse to 2D ACF

    ellipse = Ellipse(acf, geometry)
    isolist = ellipse.fit_image()
    model_image = build_ellipse_model(acf.shape, isolist)
    residual = acf - model_image

    fig = plt.figure(figsize=(40, 10))
    ax1 = fig.add_subplot(131)
    plt.gca().invert_yaxis()
    x = np.linspace(0, acf.shape[1] - 1, acf.shape[1])
    y = lambda x: (0.809) * x + 37.65

    plt.plot(x, y(x), color='white', label='Drift Rate = -33 MHz/ms')
    plt.imshow(sav, interpolation=None)
    plt.yticks(np.arange(0, sav.shape[0], 60), [1000, 900, 800, 700, 600])
    plt.xticks(np.arange(0, sav.shape[1], 48), [0, 2, 4, 6, 8, 10])
    plt.ylabel('Frequency (MHz)')
    plt.xlabel('Time (ms)')
    plt.title('Dynamic Spectrum R3H')
    plt.legend()

    ax2 = fig.add_subplot(132)

    plt.imshow(acf)  #, origin='lower')
    plt.ylabel('Frequency Shift (MHz)')
    plt.xlabel('Time Shfit (ms)')
    plt.yticks(np.arange(0, acf.shape[0], 79),
               [1000, 600, 200, 0, -200, -600, -1000])
    plt.xticks(np.arange(0, acf.shape[1], 49),
               [-10, -8, -6, -4, -3, 0, 2, 4, 6, 8, 10])

    #plt.plot(x, y(x))
    plt.title('2D ACF R3H')

    smas = np.linspace(10, 100, 8)
    for sma in smas:
        iso = isolist.get_closest(sma)
        x, y, = iso.sampled_coordinates()
        plt.plot(x, y, color='white')

    #ax3.imshow(model_image, origin='lower')
    #ax3.set_title('Ellipse Model')

    #ax3.imshow(residual, origin='lower')

    ax3 = fig.add_subplot(133)

    #plt.set_aspect('auto')
    x = np.linspace(0, len(ynorm) - 1, len(ynorm))
    plt.plot(x, ss.savgol_filter(ynorm, 19, 6))
    plt.title('Timeseries R3H')
    plt.ylabel('Normalized Intensity')
    plt.xlabel('Time (ms)')
    plt.xticks(np.arange(0, sav.shape[1], 48), [0, 2, 4, 6, 8, 10])
    #ax3.set_title('Residual')
    fig.savefig('Drift Rate R3H')
    return
Example #4
0
bkg_rms = np.std(phot['aperture_sum'] / box.area) # 4.568966255984001
plt.figure(figsize=(8, 8))
norm = simple_norm(data*~boolmask, 'sqrt', percent=99.)
im=plt.imshow(data*~boolmask, cmap='viridis',interpolation='nearest',norm=norm)
plt.colorbar(im)
aperture.plot(color='#d62728')
box.plot(color='#d62728')
print(bkg_mean,bkg_rms,bkg_mean - 1*bkg_rms,bkg_mean + 1*bkg_rms,bkg_mean - 3*bkg_rms,bkg_mean + 3*bkg_rms)
#data = data - (bkg_mean+3*bkg_rms)#(bkg_mean - 1*bkg_rms) 
### np.median(data[box_cutout.data==0]) # == 15.167292
### np.std(data[box_cutout.data==0]) #== 10.078673
# ----------------------------------------------------------------------------
#datamask = deepcopy(data)
#datamask[mask>0]=0

geometry = EllipseGeometry(x0=cat.xcentroid, y0=cat.ycentroid, sma=a, eps=1-b/a,
                            pa=(theta+90)*np.pi/180.)


ellipse = Ellipse(ma.masked_where(mask > 0, data), geometry)
#isolist = ellipse.fit_image(integrmode='median', step=5, linear=True, 
#                                  maxsma=nsize/2, fflag=0.3, sclip=3, nclip=3)
isolist = ellipse.fit_image(integrmode='median', step=.1, linear=False, 
                                  maxsma=nsize/2, fflag=0.3, sclip=3, nclip=3)


# Try to fit further more (from the last ellipse) with larger step to increase S/N
# and capture outer parts of the galaxy
#geometry = EllipseGeometry(x0=cat.xcentroid, y0=cat.ycentroid, sma=np.max(isolist.sma), 
#                           eps=1-b/a, pa=(theta+90)*np.pi/180.)
#ellipse = Ellipse(data, geometry)
#isolist_outer = ellipse.fit_image(integrmode='median', step=0.3, minsma=isolist.sma[-1],
Example #5
0
def _prep_2dacf(time_smooth,
                freq_smooth,
                time_res,
                subband_freq_res,
                diagnostic=True):

    #Calculate 2d acf
    acf2d = ss.correlate(savts_2d_c, savsp_2d_c)

    #Cap spiked central values in acf
    cap = np.mean(
        acf2d[len(acf2d.sum(1)) // 2 + 10:len(acf2d.sum(1)) // 2 + 10,
              len(acf2d.sum(0)) // 2 + 10:len(acf2d.sum(0)) // 2 + 10])
    acf2d_cap = np.where(acf2d > cap, cap, acf2d)

    #Smooth Data w Savitzky Golay filter (t - time) (s - spectrum)
    twinlen = acf2d.shape[1] // 4
    if twinlen % 2 == 0:
        twinlen = twinlen + 1
    swinlen = acf2d.shape[0] // 4
    if swinlen % 2 == 0:
        swinlen = swinlen + 1
    polyo = 6
    savacft = ss.savgol_filter(acf2d, twinlen, polyo, axis=1)
    savacff = ss.savgol_filter(acf2d, swinlen, polyo, axis=0)
    print('ACF Time Window Length: ', twinlen)
    print('ACF Freq Window Length: ', swinlen)

    #Calculate initial guess parameters spectrum acf time
    savt = savacft.sum(0) / np.max(savacft.sum(0))
    maximt = np.max(savt)
    stdt = np.std(savt)
    meant = np.where(savt == maximt)[0][0]
    xt = np.linspace(0, len(savt), len(savt))

    #Fit 1D Gaussian to Spectrum
    fittert = modeling.fitting.LevMarLSQFitter()
    modelt = modeling.models.Gaussian1D(amplitude=maximt,
                                        mean=meant,
                                        stddev=stdt)
    fitted_modelt = fittert(modelt, xt, savt)

    #Calculate initial guess parameters spectrum acf freq
    savsp = savacff.sum(1) / np.max(savacff.sum(1))
    maximsp = np.max(savsp)
    stdsp = np.std(savsp)
    meansp = np.where(savsp == maximsp)[0][0]
    xsp = np.linspace(0, len(savsp), len(savsp))

    #Fit 1D Gaussian to Spectrum
    fittersp = modeling.fitting.LevMarLSQFitter()
    modelsp = modeling.models.Gaussian1D(amplitude=maximsp,
                                         mean=meansp,
                                         stddev=stdsp)
    fitted_modelsp = fittersp(modelsp, xsp, savsp)

    #Get Ellipse Ratio
    sigmat = fitted_modelt.stddev.value
    sigmaf = fitted_modelsp.stddev.value
    #Up to sig 3 -- MAKE EDIT TO ADJUST ITERATIVELY IN FIT FUNCTION
    sigt1 = sigmat
    sigf1 = sigmaf
    sigt2 = sigmat * 2
    sigf2 = sigmaf * 2
    sigt3 = sigmat * 3
    sigf3 = sigmaf * 3

    sigmat = sigmat * 0.3
    sigmaf = sigmaf * 0.3

    #Sigmas form a rectangle, get slope of the rectangle diagonal to estimate semi major axis PA
    hyp = np.sqrt(sigmat**2 + sigmaf**2)
    estpa = np.arccos(sigmat / hyp)  #in radians

    #Estimate ellipticity (eps) with sigma ratio
    oppestpa = np.arccos(sigmaf / hyp)
    estsmajax = np.tan(oppestpa) * (hyp / 2)
    estsminax = hyp / 2
    esteps = 1 - (estsminax / estsmajax)

    print(estsmajax, estsminax)

    print('Estimated Ellipticity: ', esteps)
    print('Estmated Semimajor Axis: ', estsmajax)
    print('Estimated PA: ', estpa)

    print('Initial guess ellipse applied!')

    #Provide the initial ellipse to be fitted
    #Calculate ellipse geometry
    geometry = EllipseGeometry(x0 = acf2d.shape[1]/2, \
      y0 = acf2d.shape[0]/2, sma = estsmajax, eps = esteps, pa = estpa)
    #Show initial guess ellipse
    aper = EllipticalAperture((geometry.x0, geometry.y0), \
      geometry.sma, geometry.sma*(1-geometry.eps),geometry.pa)

    if diagnostic == True:
        fig = plt.figure()
        plt.imshow(acf2d, aspect='auto')
        aper.plot(color='white')
        plt.title('Diagnostic - Pre-fit Estimate')
        plt.show()
        fig.savefig('Diagnostic_' + str(burst_npy) + '.png')

    print('Now for the fit...')

    return acf2d, geometry, aper, sigmat, sigmaf, sigf3
Example #6
0
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
from photutils.datasets import make_noise_image
from photutils.isophote import EllipseGeometry, Ellipse
from photutils import EllipticalAperture

#===================================
#Reading fits file containing data to be fitted
#===================================

bulge = fits.getdata('/home/elismar/Documentos/Fisica/IC/imfit-1.7.1/ngc2992-93/images/NICMOS/n4sb08040/bulge.fits')

#===================================
#Fitting elliptical isophotes to bulge
#===================================

geometry = EllipseGeometry(x0=50, y0=65, sma=3, eps=0.1, pa=0)

ellipse = Ellipse(bulge, geometry)
isolist = ellipse.fit_image()

#===================================
#Plotting results
#===================================

fig = plt.figure()
axs = fig.add_subplot(111)
norm = plt.Normalize(-2, 10)
axs.imshow(bulge, origin='lower', norm=norm)
axs.set_title('Data')

smas = np.linspace(1, 10, 10)
Example #8
0
    def __init__(self,
                 image_cube,
                 header,
                 db_name='database',
                 x0=None,
                 y0=None,
                 sma=None,
                 eps=None,
                 pa=None,
                 box='init',
                 **kwargs):
        """
        Kwargs can be: init_chan
        """
        self.params = {'x0': x0, 'y0': y0, 'sma': sma, 'eps': eps, 'pa': pa}
        for param in self.params:
            self.params[param] = self.params[param] \
                    if self.params[param] is not None \
                    else self.init_params[param]
        self.geom = EllipseGeometry(**self.params)
        self.box = self.init_box if box == 'init' else box
        self.fig = plt.figure(figsize=(8, 8))
        self.fig.subplots_adjust(left=0.25, bottom=0.35)
        self.header = header
        self.nchans = self.header['NAXIS3']
        self.init_chan = int(np.round(self.nchans / 2))
        if self.header is not None:
            self.wcs = WCS(header).celestial
            self.beam_size_pix = (self.header['BMAJ'] + self.header['BMIN']
                                  ) * 0.5 / self.header['CDELT2']
            self.ax = plt.subplot(projection=self.wcs)
        else:
            self.header = None
            self.wcs = None
            self.beam_size_pix = None
            self.ax = self.fig.add_subplot()
        self.ax_text = self.fig.add_axes([0.05, 0.025, 0.1, 0.04])
        self.ax_text.set_axis_off()
        self.chan = self.init_chan
        self.image_cube = image_cube
        self.operation = kwargs['operation'] if 'operation' in kwargs else None
        self.interpolation = kwargs['interpolation'] \
                             if 'interpolation' in kwargs \
                             else 'bilinear'
        self.filterrad = kwargs['filterrad'] if 'filterrad' in kwargs else 4.0
        self.width_chan = 3
        self.color_ref_ellip = 'r'

        self.max_vmax = np.max([np.max(x) for x in self.image_cube])
        #self.max_vmax = 0.1
        self.vmax = 0.08
        self.vcenter = 0.03
        self.vmin = 0.01
        self.cmap = kwargs['cmap'] if 'cmap' in kwargs else mf.default_params[
            'cmap']
        self.norm = 'divnorm'

        self.v0 = kwargs['v0'] if 'v0' in kwargs else mf.default_params['v0']
        self.vf = kwargs['vf'] if 'vf' in kwargs else mf.default_params['vf']

        self.photomorph = kwargs['photomorph'] if 'photomorph' in kwargs \
                          else 'ellipse'
        self.sample = None
        self.ellip_data = None
        self.q2min = kwargs['q2min'] if 'q2min' in kwargs else 'mean'
        self.mean_intens = 0
        self.sum_intens = 0
        self.fit_results = {}
        self.im = None
        self.fit_tol = 1 * 10**(-8)
        self.fit_method = None
        self.pickling = False
        self.db_name = db_name
        self.path_database = '{}{}.db'.format(
            mf.default_params['path_database'], self.db_name)
        self.limit_fit = kwargs['limit_fit'] if 'limit_fit' in kwargs \
                         else mf.default_params['limit_fit']
        self.slider_ax = None
        self.channels_ax = None
        self.fit_button_ax = None
        self.next_chan_button_ax = None
        self.prev_chan_button_ax = None
        self.max_cbar_ax = None
        self.center_cbar_ax = None
        self.min_cbar_ax = None
        self.create_axes()

        self.param_sliders = None
        self.channels_slider = None
        self.max_cbar_slider = None
        self.center_cbar_slider = None
        self.min_cbar_slider = None
        self.fit_button = None
        self.next_chan_button = None
        self.prev_chan_button = None
        self.update_buttons()

        self.plot_image()
        self.update_ellipse(first_time=True)
Example #9
0
def Isophote_Extract_Photutils(IMG, results, options):
    """Wrapper of photutils method for extracting SB profiles.

    This simply gives users access to the photutils isophote
    extraction methods. The one exception is that SB values are taken
    as the median instead of the mean, as recomended in the photutils
    documentation. See: `photutils
    <https://photutils.readthedocs.io/en/stable/isophote.html>`_ for
    more information.

    Parameters
    ----------
    ap_zeropoint : float, default 22.5
      Photometric zero point. For converting flux to mag units.

    ap_fluxunits : str, default "mag"
      units for outputted photometry. Can either be "mag" for log
      units, or "intensity" for linear units.
    
    ap_plot_sbprof_ylim : tuple, default None
      Tuple with axes limits for the y-axis in the SB profile
      diagnostic plot. Be careful when using intensity units
      since this will change the ideal axis limits.
    
    ap_plot_sbprof_xlim : tuple, default None
      Tuple with axes limits for the x-axis in the SB profile
      diagnostic plot.
    
    ap_plot_sbprof_set_errscale : float, default None
      Float value by which to scale errorbars on the SB profile
      this makes them more visible in cases where the statistical
      errors are very small.
    
    Notes
    ----------
    :References:
    - 'background'
    - 'background noise'
    - 'psf fwhm'
    - 'center'
    - 'init R' (optional)
    - 'init ellip' (optional)
    - 'init pa' (optional)
    - 'fit R' (optional)
    - 'fit ellip' (optional)
    - 'fit pa' (optional)
    - 'fit photutils isolist' (optional)

    Returns
    -------
    IMG : ndarray
      Unaltered galaxy image

    results : dict
      .. code-block:: python

        {'prof header': , # List object with strings giving the items in the header of the final SB profile (list)
         'prof units': , # dict object that links header strings to units (given as strings) for each variable (dict)
         'prof data': # dict object linking header strings to list objects containing the rows for a given variable (dict)

        }

    """

    zeropoint = options["ap_zeropoint"] if "ap_zeropoint" in options else 22.5
    fluxunits = options["ap_fluxunits"] if "ap_fluxunits" in options else "mag"

    if fluxunits == "intensity":
        params = [
            "R",
            "I",
            "I_e",
            "totflux",
            "totflux_e",
            "ellip",
            "ellip_e",
            "pa",
            "pa_e",
            "a3",
            "a3_e",
            "b3",
            "b3_e",
            "a4",
            "a4_e",
            "b4",
            "b4_e",
        ]
        SBprof_units = {
            "R": "arcsec",
            "I": "flux*arcsec^-2",
            "I_e": "flux*arcsec^-2",
            "totflux": "flux",
            "totflux_e": "flux",
            "ellip": "unitless",
            "ellip_e": "unitless",
            "pa": "deg",
            "pa_e": "deg",
            "a3": "unitless",
            "a3_e": "unitless",
            "b3": "unitless",
            "b3_e": "unitless",
            "a4": "unitless",
            "a4_e": "unitless",
            "b4": "unitless",
            "b4_e": "unitless",
        }
    else:
        params = [
            "R",
            "SB",
            "SB_e",
            "totmag",
            "totmag_e",
            "ellip",
            "ellip_e",
            "pa",
            "pa_e",
            "a3",
            "a3_e",
            "b3",
            "b3_e",
            "a4",
            "a4_e",
            "b4",
            "b4_e",
        ]
        SBprof_units = {
            "R": "arcsec",
            "SB": "mag*arcsec^-2",
            "SB_e": "mag*arcsec^-2",
            "totmag": "mag",
            "totmag_e": "mag",
            "ellip": "unitless",
            "ellip_e": "unitless",
            "pa": "deg",
            "pa_e": "deg",
            "a3": "unitless",
            "a3_e": "unitless",
            "b3": "unitless",
            "b3_e": "unitless",
            "a4": "unitless",
            "a4_e": "unitless",
            "b4": "unitless",
            "b4_e": "unitless",
        }
    SBprof_data = dict((h, []) for h in params)
    res = {}
    dat = IMG - results["background"]
    if not "fit R" in results and not "fit photutils isolist" in results:
        logging.info(
            "%s: photutils fitting and extracting image data" % options["ap_name"]
        )
        geo = EllipseGeometry(
            x0=results["center"]["x"],
            y0=results["center"]["y"],
            sma=results["init R"] / 2,
            eps=results["init ellip"],
            pa=results["init pa"],
        )
        ellipse = Photutils_Ellipse(dat, geometry=geo)

        isolist = ellipse.fit_image(fix_center=True, linear=False)
        res.update(
            {
                "fit photutils isolist": isolist,
                "auxfile fitlimit": "fit limit semi-major axis: %.2f pix"
                % isolist.sma[-1],
            }
        )
    elif not "fit photutils isolist" in results:
        logging.info("%s: photutils extracting image data" % options["ap_name"])
        list_iso = []
        for i in range(len(results["fit R"])):
            if results["fit R"][i] <= 0:
                continue
            # Container for ellipse geometry
            geo = EllipseGeometry(
                sma=results["fit R"][i],
                x0=results["center"]["x"],
                y0=results["center"]["y"],
                eps=results["fit ellip"][i],
                pa=results["fit pa"][i],
            )
            # Extract the isophote information
            ES = EllipseSample(dat, sma=results["fit R"][i], geometry=geo)
            ES.update(fixed_parameters=None)
            list_iso.append(Isophote(ES, niter=30, valid=True, stop_code=0))

        isolist = IsophoteList(list_iso)
        res.update(
            {
                "fit photutils isolist": isolist,
                "auxfile fitlimit": "fit limit semi-major axis: %.2f pix"
                % isolist.sma[-1],
            }
        )
    else:
        isolist = results["fit photutils isolist"]

    for i in range(len(isolist.sma)):
        SBprof_data["R"].append(isolist.sma[i] * options["ap_pixscale"])
        if fluxunits == "intensity":
            SBprof_data["I"].append(
                np.median(isolist.sample[i].values[2]) / options["ap_pixscale"] ** 2
            )
            SBprof_data["I_e"].append(isolist.int_err[i])
            SBprof_data["totflux"].append(isolist.tflux_e[i])
            SBprof_data["totflux_e"].append(isolist.rms[i] / np.sqrt(isolist.npix_e[i]))
        else:
            SBprof_data["SB"].append(
                flux_to_sb(
                    np.median(isolist.sample[i].values[2]),
                    options["ap_pixscale"],
                    zeropoint,
                )
            )
            SBprof_data["SB_e"].append(
                2.5 * isolist.int_err[i] / (isolist.intens[i] * np.log(10))
            )
            SBprof_data["totmag"].append(flux_to_mag(isolist.tflux_e[i], zeropoint))
            SBprof_data["totmag_e"].append(
                2.5
                * isolist.rms[i]
                / (np.sqrt(isolist.npix_e[i]) * isolist.tflux_e[i] * np.log(10))
            )
        SBprof_data["ellip"].append(isolist.eps[i])
        SBprof_data["ellip_e"].append(isolist.ellip_err[i])
        SBprof_data["pa"].append(isolist.pa[i] * 180 / np.pi)
        SBprof_data["pa_e"].append(isolist.pa_err[i] * 180 / np.pi)
        SBprof_data["a3"].append(isolist.a3[i])
        SBprof_data["a3_e"].append(isolist.a3_err[i])
        SBprof_data["b3"].append(isolist.b3[i])
        SBprof_data["b3_e"].append(isolist.b3_err[i])
        SBprof_data["a4"].append(isolist.a4[i])
        SBprof_data["a4_e"].append(isolist.a4_err[i])
        SBprof_data["b4"].append(isolist.b4[i])
        SBprof_data["b4_e"].append(isolist.b4_err[i])
        for k in SBprof_data.keys():
            if not np.isfinite(SBprof_data[k][-1]):
                SBprof_data[k][-1] = 99.999
    res.update(
        {"prof header": params, "prof units": SBprof_units, "prof data": SBprof_data}
    )

    if "ap_doplot" in options and options["ap_doplot"]:
        if fluxunits == "intensity":
            Plot_I_Profile(
                dat,
                np.array(SBprof_data["R"]),
                np.array(SBprof_data["I"]),
                np.array(SBprof_data["I_e"]),
                np.array(SBprof_data["ellip"]),
                np.array(SBprof_data["pa"]),
                results,
                options,
            )
        else:
            Plot_SB_Profile(
                dat,
                np.array(SBprof_data["R"]),
                np.array(SBprof_data["SB"]),
                np.array(SBprof_data["SB_e"]),
                np.array(SBprof_data["ellip"]),
                np.array(SBprof_data["pa"]),
                results,
                options,
            )

    return IMG, res
Example #10
0
#!/usr/bin/env python

import fitsio
import numpy.ma as ma
from photutils.isophote import EllipseGeometry, Ellipse

img = fitsio.read('data/image.fits')
img = ma.masked_array(img, img == 0)

g = EllipseGeometry(x0=266, y0=266, eps=0.240, sma=110, pa=1.0558)
ell = Ellipse(img, geometry=g)
iso = ell.fit_image(3,
                    integrmode='median',
                    sclip=3,
                    nclip=2,
                    linear=False,
                    step=0.1)
Example #11
0
import numpy as np

from photutils.datasets import make_noise_image
from photutils.isophote import EllipseGeometry, Ellipse
from photutils import EllipticalAperture

g = Gaussian2D(100., 75, 75, 20, 12, theta=40. * np.pi / 180.)
ny = nx = 150
y, x = np.mgrid[0:ny, 0:nx]

noise = make_noise_image((ny, nx),
                         distribution='gaussian',
                         mean=0.,
                         stddev=2.,
                         random_state=12345)
data = g(x, y) + noise

#==========================================

geometry = EllipseGeometry(x0=75, y0=75, sma=20, eps=0.5, pa=20. * np.pi / 180)

aper = EllipticalAperture((geometry.x0, geometry.y0), geometry.sma,
                          geometry.sma * (1 - geometry.eps), geometry.pa)

plt.imshow(data, origin='lower')
aper.plot(color='white')
plt.show()

ellipse = Ellipse(data, geometry)
isolist = ellipse.fit_image()
Example #12
0
def Photutils_Fit(IMG, results, options):
    """Photutils elliptical isophote wrapper.

    This simply gives users access to the photutils isophote
    fitting method. See: `photutils
    <https://photutils.readthedocs.io/en/stable/isophote.html>`_ for
    more information.

    Notes
    ----------
    :References:
    - 'background'
    - 'center'
    - 'init R'
    - 'init ellip'
    - 'init pa'

    Returns
    -------
    IMG : ndarray
      Unaltered galaxy image

    results : dict
      .. code-block:: python

        {'fit ellip': , # array of ellipticity values (ndarray)
         'fit pa': , # array of PA values (ndarray)
         'fit R': , # array of semi-major axis values (ndarray)
         'fit ellip_err': , # optional, array of ellipticity error values (ndarray)
         'fit pa_err': , # optional, array of PA error values (ndarray)
         'auxfile fitlimit': # optional, auxfile message (string)

        }
    """

    dat = IMG - results["background"]
    geo = EllipseGeometry(
        x0=results["center"]["x"],
        y0=results["center"]["y"],
        sma=results["init R"] / 2,
        eps=results["init ellip"],
        pa=results["init pa"],
    )
    ellipse = Photutils_Ellipse(dat, geometry=geo)

    isolist = ellipse.fit_image(fix_center=True, linear=False)
    res = {
        "fit R":
        isolist.sma[1:],
        "fit ellip":
        isolist.eps[1:],
        "fit ellip_err":
        isolist.ellip_err[1:],
        "fit pa":
        isolist.pa[1:],
        "fit pa_err":
        isolist.pa_err[1:],
        "fit photutils isolist":
        isolist,
        "auxfile fitlimit":
        "fit limit semi-major axis: %.2f pix" % isolist.sma[-1],
    }

    if "ap_doplot" in options and options["ap_doplot"]:
        Plot_Isophote_Fit(
            dat,
            res["fit R"],
            res["fit ellip"],
            res["fit pa"],
            res["fit ellip_err"],
            res["fit pa_err"],
            results,
            options,
        )

    return IMG, res
Example #13
0
def get_amplitude_at_r(r, image, x0, y0, ellip, theta):
    """
    Finds the amplitude at an isophotal radius `r`.

    Parameters
    ----------

    r : float or int
        Isophotal radius in pixels.

    image : CCDData or array
        Image to of the source.

    x0, y0 : float
        The center pixel coordinate of the ellipse.

    ellip : ellipticity
        The ellipticity of the ellipse.

    theta : float
        The position angle (in radians) of the semimajor axis in
        relation to the positive x axis of the image array (rotating
        towards the positive y axis). Position angles are defined in the
        range :math:`0 < PA <= \pi`. Avoid using as starting position
        angle of 0., since the fit algorithm may not work properly.
        When the ellipses are such that position angles are near either
        extreme of the range, noise can make the solution jump back and
        forth between successive isophotes, by amounts close to 180
        degrees.

    Returns
    -------

    amplitude_at_r : float or np.nan

    """

    if isinstance(image, CCDData) or isinstance(image, Cutout2D):
        image = image.data

    r = float(r)

    try:
        # Define EllipseGeometry using ellip and theta
        g = EllipseGeometry(x0, y0, 1., ellip, theta)

        # Create Ellipse model
        ellipse = Ellipse(image, geometry=g)

        # Fit isophote at r_eff
        iso = ellipse.fit_isophote(r)

        # Get flux at r_eff
        amplitude = iso.intens

    except Exception as exception:
        import warnings
        warnings.warn("Amplitude could not be computed, returning np.nan. Exception: {}".format(str(exception)), Warning)
        amplitude = np.nan

    return amplitude
Example #14
0
import numpy as np

from photutils.datasets import make_noise_image
from photutils.isophote import EllipseGeometry, Ellipse
from photutils import EllipticalAperture

#================================

fits_file = '/home/elismar/Documentos/Fisica/IC/imfit-1.7.1/ngc2992-93/images/GMOS/ngc2992/ngc2992_model3.fits'

data = fits.getdata(fits_file)

#================================

geometry = EllipseGeometry(x0=237,
                           y0=168,
                           sma=87,
                           eps=0.3,
                           pa=-58. * np.pi / 180)

aper = EllipticalAperture((geometry.x0, geometry.y0), geometry.sma,
                          geometry.sma * (1 - geometry.eps), geometry.pa)

norm = plt.Normalize(0, 5000)
plt.imshow(data, origin='lower', norm=norm)
aper.plot(color='white')
plt.show()

ellipse = Ellipse(data, geometry)
isolist = ellipse.fit_image()
Example #15
0
 def update_params(self, x0, y0, sma, eps, pa):
     self.params = {'x0': x0, 'y0': y0, 'sma': sma, 'eps': eps, 'pa': pa}
     self.geom = EllipseGeometry(**self.params)
     self.update_ellipse()
Example #16
0
def ellipsefit_multiband(objid, objdir, data, sample, mgefit,
                         nowrite=False, verbose=False):
    """Ellipse-fit the multiband data.

    See
    https://github.com/astropy/photutils-datasets/blob/master/notebooks/isophote/isophote_example4.ipynb

    """
    from photutils.isophote import (EllipseGeometry, Ellipse, EllipseSample,
                                    Isophote, IsophoteList)
    from photutils.isophote.sample import CentralEllipseSample
    from photutils.isophote.fitter import CentralEllipseFitter

    band, refband, pixscale = data['band'], data['refband'], data['pixscale']

    ellipsefit = dict()
    ellipsefit['success'] = False
    ellipsefit['redshift'] = sample['z']
    ellipsefit['band'] = band
    ellipsefit['refband'] = refband
    ellipsefit['pixscale'] = pixscale
    for filt in band:
        ellipsefit['psfsigma_{}'.format(filt)] = sample['psfsize_{}'.format(filt)]

    # Default parameters
    integrmode, sclip, nclip, step, fflag = 'bilinear', 3, 0, 0.1, 0.5
    #integrmode, sclip, nclip, step, fflag = 'median', 3, 0, 0.1, 0.5

    # http://photutils.readthedocs.io/en/stable/isophote_faq.html#isophote-faq
    # Note: position angle in photutils is measured counter-clockwise from the
    # x-axis, while .pa in MGE measured counter-clockwise from the y-axis.
    geometry = EllipseGeometry(x0=mgefit['xpeak'], y0=mgefit['ypeak'],
                               eps=mgefit['eps'],
                               #sma=0.5*mgefit['majoraxis'], 
                               sma=10,
                               pa=np.radians(mgefit['pa']-90))
    ellipsefit['geometry'] = geometry

    def _sky(data, ellipsefit, diameter=2.0):
        """Estimate the sky brightness in each band."""
        #area = diameter**2 # arcsec^2
        for filt in band:
            img = data['{}_masked'.format(filt)]
            #ellipsefit['{}_sky'.format(filt)] = 22.5 - 2.5 * np.log10( ma.std(img) )
            #ellipsefit['mu_{}_sky'.format(filt)] = ellipsefit['{}_sky'.format(filt)] # + 2.5 * np.log10(area)
            ellipsefit['mu_{}_sky'.format(filt)] = 22.5 - 2.5 * np.log10( ma.std(img) )

    _sky(data, ellipsefit)

    # Fit in the reference band...
    if verbose:
        print('Ellipse-fitting the reference {}-band image.'.format(refband))
        
    img = data['{}_masked'.format(refband)]
    ellipse = Ellipse(img, geometry=geometry)

    # First fit with the default parameters.
    try:
        t0 = time.time()
        with warnings.catch_warnings():
            warnings.simplefilter('ignore')
            for minsma in (10, 1, 5): # try a few different starting minor axes
                print('  Trying minimum sma = {:.1f} pixels.'.format(minsma))
                isophot = ellipse.fit_image(minsma=minsma, maxsma=1.5*mgefit['majoraxis'],
                                            integrmode=integrmode, sclip=sclip, nclip=nclip,
                                            step=step, fflag=fflag)
                if len(isophot) > 0:
                    break
        if verbose:
            print('Time = {:.3f} sec'.format( (time.time() - t0) / 1))

        if len(isophot) == 0:
            print('Ellipse-fitting failed, likely due to complex morphology or poor initial geometry.')
        else:
            ellipsefit['success'] = True
            ellipsefit[refband] = isophot

            tall = time.time()
            for filt in band:
                t0 = time.time()
                if filt == refband: # we did it already!
                    continue

                if verbose:
                    print('Ellipse-fitting {}-band image.'.format(filt))

                img = data['{}_masked'.format(filt)]

                # Loop on the reference band isophotes but skip the first isophote,
                # which is a CentralEllipseSample object (see below).
                isobandfit = []
                for iso in isophot:
                #for iso in isophot[1:]:
                    g = iso.sample.geometry # fixed geometry

                    # Use the same integration mode and clipping parameters.
                    sample = EllipseSample(img, g.sma, geometry=g, integrmode=integrmode,
                                           sclip=sclip, nclip=nclip)
                    sample.update()

                    # Create an Isophote instance with the sample.
                    isobandfit.append(Isophote(sample, 0, True, 0))

                # Now deal with the central pixel; see
                # https://github.com/astropy/photutils-datasets/blob/master/notebooks/isophote/isophote_example4.ipynb
                #import pdb ; pdb.set_trace()
                #g = EllipseGeometry(x0=geometry.x0, y0=geometry.y0, eps=mgefit['eps'], sma=1.0)
                #g.find_center(img)

                ## Use the same integration mode and clipping parameters.
                #sample = CentralEllipseSample(img, g.sma, geometry=g, integrmode=integrmode,
                #                              sclip=sclip, nclip=nclip)
                #cen = CentralEllipseFitter(sample).fit()
                #isobandfit.append(cen)
                #isobandfit.sort()

                # Build the IsophoteList instance with the result.
                ellipsefit[filt] = IsophoteList(isobandfit)
                if verbose:
                    print('Time = {:.3f} sec'.format( (time.time() - t0) / 1))

            if verbose:
                print('Time for all images = {:.3f} sec'.format( (time.time() - tall) / 1))
                
    except:
        print('Ellipse-fitting failed, likely due to too many masked pixels.')

    # Write out
    if not nowrite:
        legacyhalos.io.write_ellipsefit(objid, objdir, ellipsefit, verbose=verbose)

    return ellipsefit
Example #17
0
image = fits.getdata(image)

#The center pixel coordinates of the bulge
x0 = 98.5
y0 = 98.5
bulge_3D = abel.Transform(image,
                          direction='inverse',
                          method='three_point',
                          center=(y0, x0)).transform

#=======================
#Fitting ellipses to the 3D image in order to get its brigthness profile
#=======================

# geometry = EllipseGeometry(x0=98, y0=98, sma=15, eps=0.19, pa=(np.pi/180)*226)
geometry = EllipseGeometry(x0=98, y0=98, sma=15, eps=0.0, pa=0)

ellipse = Ellipse(bulge_3D, geometry)
isolist = ellipse.fit_image(fix_pa=True, fix_eps=True)

#========================
#Converting to mass profile
#========================

#Considering 2MASS H-band of course
magzp = 20.4107
distance = 38e+6  #pc
solar_abs_mag = 3.32
gamma = 1.0

Example #18
0
def isophote_data() :
    
    from photutils.isophote import EllipseGeometry
    from photutils import EllipticalAperture
    from photutils.isophote import Ellipse
    
    test = 'a2744/cutouts/a2744_ID_5830_f160w.fits'
    (data, dim, photfnu, R_e,
     redshift, sma, smb, pa) = open_cutout(test)
    (noise, _, _, _,
     _, _, _, _) = open_cutout('a2744/cutouts/a2744_ID_5830_f160w_noise.fits')
    plt.display_image_simple(data, cmap=cm.viridis)
    
    xlen, ylen = dim[1], dim[0]
    
    geometry = EllipseGeometry(x0=xlen/2, y0=ylen/2, sma=20, eps=0.5,
                               pa=70*np.pi/180)
    aper = EllipticalAperture((geometry.x0, geometry.y0), geometry.sma,
                               geometry.sma*(1 - geometry.eps), geometry.pa)
    
    # pyp.imshow(data, origin='lower')
    # aper.plot(color='white')
    
    ellipse = Ellipse(data, geometry)
    isolist = ellipse.fit_image()
    
    # print(isolist.tflux_e)
    
    isophotes = True
    if isophotes :
        plt.display_isophotes(data, isolist, cmap=cm.viridis)
        
        # from photutils.isophote import build_ellipse_model
        # model = build_ellipse_model(data.shape, isolist)
        # residual = data - model
        # plt.display_image_simple(residual, norm=None)
    
    annuli = True
    if annuli :
        from photutils import EllipticalAnnulus
        from photutils import aperture_photometry
        
        center = (isolist[0].x0, isolist[0].y0)
        # print(center)
        
        last = np.where(isolist.stop_code == 0)[0][-1]
        isolist = isolist[last]
        
        pa = isolist.pa
        # print(pa*180/np.pi)
        
        a_outs = np.arange(1e-5, isolist.sma, isolist.sma/11)
        b_outs = a_outs*(1-isolist.eps)
        
        for i in range(len(a_outs) - 1) :
            a_in = a_outs[i]
            a_out = a_outs[i+1]
            b_in = b_outs[i]
            b_out = b_outs[i+1]
            # print(a_in, a_out, b_in, b_out)
            aper = EllipticalAnnulus(center, a_in, a_out, b_out, b_in=b_in,
                                     theta=isolist.pa)
            phot_table = aperture_photometry(data, aper, error=noise)
            flux = phot_table['aperture_sum'][0]
            flux_err = phot_table['aperture_sum_err'][0]
            # print(flux)
            # print(flux_err)
            
            annulus_mask = aper.to_mask()
            
            annulus_data = annulus_mask.multiply(data)
            # plt.display_image_simple(annulus_data, cmap=cm.viridis, norm=None)
            # print(np.sum(annulus_data))
            
            err_table = aperture_photometry(noise, aper)
            flux_err_alt = err_table['aperture_sum'][0]
            # print(flux_err)
            
            err_data = annulus_mask.multiply(noise)
            # print(np.sum(err_data))
            
            # print(flux/flux_err)
            print(flux/flux_err_alt)
            # print()
            
    return
Example #19
0
head = fits.open(fitsfile)[0].header


fig, ax = plt.subplots(figsize=(8, 7))
# ax0,ax1,ax2,ax3,ax4,ax5,ax6,ax7,ax8 = axarr[0,0],axarr[0,1],axarr[0,2],axarr[1,0],axarr[1,1],axarr[1,2],axarr[2,0],axarr[2,1],axarr[2,2]
ax.set_xlabel('x (Pixels)', fontsize=axisfont)
ax.set_ylabel('y (Pixels)', fontsize=axisfont)
cb = ax.imshow(data, vmin=10**11, vmax=2*10**14,
               cmap='gray_r', norm=LogNorm())
ax.tick_params(labelsize=ticksize, size=ticks)
colorbar = plt.colorbar(cb)
colorbar.ax.set_ylabel('Flux (erg/s/cm^2)', rotation=270, fontsize=axisfont-8)
colorbar.ax.tick_params(labelsize=ticksize-4)


geometry = EllipseGeometry(x0=350, y0=350, sma=20, eps=0, pa=0.)
aper = EllipticalAperture((geometry.x0, geometry.y0),
                          geometry.sma, geometry.sma*(1 - geometry.eps), geometry.pa)
ellipse = Ellipse(data, geometry)
isolist = ellipse.fit_image()
#model_image = build_ellipse_model(data.shape, isolist)
#residual = data - model_image

smas = np.linspace(10, 200, 5)
for sma in smas:
    iso = isolist.get_closest(sma)
    x, y, = iso.sampled_coordinates()
    ax.plot(x, y, color='red')

plt.tight_layout()
fig.savefig(figout+'kormendy_iso.pdf')