Пример #1
0
 def determine_center(self, centering): # mostly for internal use from fit_image...
         self.vprint(self, "\n    **** LG_Model.NRM_Model.determine_center: centering {}".format(centering))
         sys.exit("    **** LG_Model.NRM_Model.determine_center")
         # First find the fractional-pixel centering
         if centering== "auto":
             if hasattr(self.bandpass, "__iter__"):
                 self.auto_find_center(
                     "centermodel_poly_{0}mas.fits".format(utils.rad2mas(self.pixel)))
             else:
                 self.auto_find_center(
                     "centermodel_{0}m_{1}mas.fits".format(self.bandpass, \
                     utils.rad2mas(self.pixel)))
             self.bestcenter = 0.5-self.over*self.xpos, 0.5-self.over*self.ypos
             sys.exit("    **** NRM_Model.fit_image: {}".format(self.bestcenter))
         else:
             self.bestcenter = centering
Пример #2
0
    def auto_find_center(self, modelfitsname, overwrite=0):
        """
        This is the major method in this driver to be called. It is basically
        Deepashri's cormat driver & peak finder.

        Takes an image at the detector pixel scale and a fits file name
        * tries to read in the fits file
        * if there's no file it will go on to generate an oversampled PSF
        * if the data is a cube it will generate a cube of oversampled PSFs
        * if not it will generate a single array of oversampled PSF
        * then calculates cormat & finds the peak.

        returns center location on the detector scale.

        *************************************************************
        ***                                                       ***
        ***   NOTE: to plug this centering back into NRM_Model:   ***
        ***   ( 0.5 - model_oversampling*ctr[0],                  ***
        ***     0.5 - model_oversampling*ctr[1] )                 ***
        ***                                             LG+       ***
        *************************************************************
        This is different in LG++: 
        In nrm_core.fit_fringes_single_integration() I experimented with:
        nrm.bestcenter = 0.5-nrm.over*nrm.xpos, 0.5-nrm.over*nrm.ypos  ################ AS LG+
        nrm.bestcenter =    -nrm.over*nrm.xpos,    -nrm.over*nrm.ypos  ################ AS try in LG++
        nrm.bestcenter =              nrm.xpos,              nrm.ypos  ################ AS try in LG++  Works!
        *************************************************************

        """
        self.pscale_rad = self.pixel
        self.pscale_mas = utils.rad2mas(self.pscale_rad)
        _npix = self.reference.shape[1] + 2
        if ((not os.path.isfile(modelfitsname)) or (overwrite == 1)):
            # Creates a new oversampled model, default is pixel-centered
            self.simulate(fov=_npix, over=self.over, bandpass=self.bandpass)

            hdulist = fits.PrimaryHDU(data=self.psf_over)
            hdulist.header[""] = ("", "Written from auto_find_center method")
            #hdulist.header.update()
            hdulist.writeto(self.datapath + modelfitsname, clobber=True)
        else:
            # Looks for this file to read in if it's already been written and overwrite flag not set
            try:
                self.read_model(modelfitsname)
            except:
                self.psf_over = 0
            if self.psf_over.shape[0] == self.reference.shape[0]:
                pass
            else:
                # if overwrite flag not set, but read model doesn't match, just make a new one
                self.simulate(fov=_npix,
                              over=self.over,
                              bandpass=self.bandpass)

        # finds correlation matrix between oversampled and detector psf
        self.cormat = utils.crosscorrelatePSFs(self.reference, self.psf_over,
                                               self.over)
        self.find_location_of_peak()
Пример #3
0
def save(nrmobj, outputname, savdir=""):
    """
    Probably don't need to use this unless have run a fit.
    This is only to save fitting parameters and results right now.
    """
    import json

    class savobj:
        def __init__(self):
            return None

    savobj.test = 1
    with open(r"{0}.ffo".format(savdir, outputname), "wb") as output_file:
        json.dump(savobj, output_file)
    print("success!")

    # init stuff
    savobj.pscale_rad, savobj.pscale_mas = nrmobj.pixel, utils.rad2mas(
        nrmobj.pixel)
    savobj.holeshape, savobj.ctrs, savobj.d, savobj.D, savobj.N, \
        savobj.datapath, savobj.refdir  =   nrmobj.holeshape, nrmobj.ctrs, nrmobj.d, \
                                            nrmobj.D, nrmobj.N, nrmobj.datapath, nrmobj.refdir

    if hasattr(nrmobj, "refpsf"):
        savobj.refpsf, savobj.rot_best = nrmobj.refpsf, nrmobj.rot_measured
    if hasattr(nrmobj, "fittingmodel"):
        # details
        savobj.weighted, savobj.pixweight, savobj.bestcenter, \
            savobj.bandpass, savobj.modelctrs, savobj.over,\
            savobj.modelpix  =  nrmobj.weighted, nrmobj.pixweight, nrmobj.bestcenter, \
                                nrmobj.bandpass, nrmobj.modelctrs, nrmobj.over, nrmobj.modelpix
        # resulting arrays
        savobj.modelmat, savobj.soln, \
            savobj.residual, savobj.cond, \
            savobj.rawDC, savobj.flux, \
            savobj.fringeamp, savobj.fringephase,\
            savobj.cps, savobj.cas  =   nrmobj.fittingmodel, nrmobj.soln, nrmobj.residual, \
                                nrmobj.cond, nrmobj.rawDC, nrmobj.flux, nrmobj.fringeamp, \
                                nrmobj.fringephase, nrmobj.redundant_cps, nrmobj.redundant_cas
        if not hasattr(nrmobj, "modelpsf"):
            nrmobj.plot_model()
        savobj.modelpsf = nrmobj.modelpsf
    with open(r"{0}.ffo".format(savdir, outputname), "wb") as output_file:
        pickle.dump(savobj, output_file)
Пример #4
0
    def fit_image(self, image, reference=None, pixguess=None, rotguess=0, psf_offset=(0,0),
                  modelin=None, savepsfs=False, dqm=None, weighted=False):
        """
        This works on 2D "centered" images fed to it.
        dqm is optional 2D bad pixel bool array, same size as image.  
        self.maskname is a maskdef object with property self.maskname.mask a string
        2021
        """

        self.vprint(self, "\n    **** LG_Model.NRM_Model.fit_image: psf_offset {}".format(psf_offset))
        if hasattr(modelin, 'shape'):
            self.vprint(self, "    **** LG_Model.NRM_Model.fit_image modelin passed in")
        else:
            self.vprint(self, "    **** LG_Model.NRM_Model.fit_image: modelin is None\n")

        """
        fit_image will run a least-squares fit on an input image.
        Specifying a model is optional. If a model is not specified then this
        method will find the appropriate wavelength scale, rotation (and 
        hopefully centering as well -- This is not written into the object yet, 
        but should be soon).
    
        Without specifying a model, fit_image can take a reference image 
        (a cropped deNaNed version of the data) to run correlations. It is 
        recommended that the symmetric part of the data be used to avoid piston
        confusion in scaling. Good luck!
        """
        self.model_in = modelin
        self.weighted = weighted
        self.saveval = savepsfs

        if modelin is None:
            self.vprint(self, "     LG_Model.NRM_Model.fit_image: fittingmodel   no modelin")
            # No model provided - now perform a set of automatic routines

            # A Cleaned up version of your image to enable Fourier fitting for 
            # centering crosscorrelation with FindCentering() and
            # magnification and rotation via new_and_better_scaling_routine().
            if reference==None:
                self.reference = image
                if np.isnan(image.any()):
                    raise ValueError("Must have non-NaN image to "+\
                        "crosscorrelate for scale. Reference "+\
                        "image should also be centered. Get to it.")
            else:
                self.reference=reference

            # IMAGE CENTERING
            """ moved original ~12 lines code to determine_center routine...
            """
            determine_center(self, centering) # populates self.best_center



            self.new_and_better_scaling_routine(self.reference, 
                    scaleguess=self.pixel, rotstart=rotguess,
                    centering=self.bestcenter, fitswrite=self.saveval)

            self.pixscale_measured=self.pixel
            self.vprint(self, "pixel scale (mas):", utils.rad2mas(self.pixel))
            self.fov=image.shape[0]
            self.fittingmodel=self.make_model(self.fov, bandpass=self.bandpass, 
                            over=self.over, rotate=True,
                            psf_offset=self.bestcenter, 
                            pixscale=self.pixel)
        else:
            # This is the standard implaneia path on JWST NIRISS slice data 
            #
            self.vprint(self, "    **** LG_Model.NRM_Model.fit_image: fittingmodel=modelin")
            self.fittingmodel = modelin
            
        # working code 2022 next line...
        #self.soln, self.residual, self.cond,self.linfit_result = \
        #        leastsqnrm.matrix_operations(image, self.fittingmodel, verbose=False, dqm=dqm)

        #######################################################33  very old snippet below
        #######################################################33  very old snippet below
        if self.weighted is False:
            self.soln, self.residual, self.cond, self.linfit_result = \
                leastsqnrm.matrix_operations(image, self.fittingmodel, verbose=False, dqm=dqm)
        else:
            self.soln, self.residual, self.cond, self.singvals = leastsqnrm.weighted_operations(image, \
                                        self.fittingmodel, verbose=False, dqm=dqm)
        #######################################################33  inew code line above


        self.vprint(self, "NRM_Model Raw Soln:")
        self.vprint(self, self.soln)

        self.rawDC = self.soln[-1]
        self.flux = self.soln[0]
        self.soln = self.soln/self.soln[0]

        # fringephase now in radians
        self.fringeamp, self.fringephase = leastsqnrm.tan2visibilities(self.soln)
        self.fringepistons = utils.fringes2pistons(self.fringephase, len(self.ctrs))
        self.redundant_cps = leastsqnrm.redundant_cps(self.fringephase, N=self.N)
        self.redundant_cas = leastsqnrm.return_CAs(self.fringeamp, N=self.N)
Пример #5
0
    def new_and_better_scaling_routine(self,
                                       img,
                                       scaleguess=None,
                                       rotstart=0.0,
                                       datapath="",
                                       centering='PIXELCENTERED',
                                       fitswrite=True):
        """
        returns pixel scale factor, rotation in addition to guess, and a 
        goodness of fit parameter than can be compared in multiple iterations.
        correlations are calculated in the image plane, in anticipation of 
        data with many bad pixels.
        """
        if not hasattr(self, 'datapath'):
            self.datapath = datapath
        if not hasattr(self, 'bandpass'):
            raise ValueError(
                "This object has no specified bandpass/wavelength")

        reffov = img.shape[0]
        scal_corrlist = np.zeros((len(self.scallist), reffov, reffov))
        pixscl_corrlist = scal_corrlist.copy()
        scal_corr = np.zeros(len(self.scallist))
        self.pixscl_corr = scal_corr.copy()

        if fitswrite:
            pixfiles = [
                f for f in os.listdir(self.datapath + self.refdir)
                if 'refpsf_pixscl' in f
            ]
        else:
            pixfiles = []
        # ---------------------------------
        # user can specify a reference set of phases (m) at an earlier point so that
        # all PSFs are simulated with those phase pistons (e.g. measured from data at
        # an earlier iteration
        if not hasattr(self, 'refphi'):
            self.refphi = np.zeros(len(self.ctrs))
        else:
            pass
        # ---------------------------------
        # ---------------------------------
        if len(pixfiles) > 4:
            vprint("reading in existing reference files...")
            vprint('in directory {0}'.format(self.datapath + self.refdir))
            vprint(pixfiles)
            self.pixscales = np.zeros(len(pixfiles))
            pixscl_corrlist = np.zeros((len(pixfiles), reffov, reffov))
            for q, scalfile in enumerate(pixfiles):
                vprint(q)
                f = fits.open(self.datapath + self.refdir + pixfiles[q])
                psf, filehdr = f[0].data, f[0].header
                self.test_pixscale = filehdr['PIXSCL']
                self.pixscales[q] = self.test_pixscale
                f.close()
                pixscl_corrlist[q, :, :] = run_data_correlate(img, psf)
                self.pixscl_corr[q] = np.max(pixscl_corrlist[q])
                vprint('max correlation', self.pixscl_corr[q])
                if True in np.isnan(self.pixscl_corr):
                    raise ValueError("Correlation produced NaNs,"\
                             " please check your work!")

        else:
            vprint('creating new reference files...')
            vprint('in directory {0}'.format(self.datapath + self.refdir))
            self.pixscales = np.zeros(len(self.scallist))
            for q, scal in enumerate(self.scallist):
                vprint(q)
                self.test_pixscale = self.pixel * scal
                self.pixscales[q] = self.test_pixscale
                psf = self.simulate(
                    bandpass=self.bandpass,
                    fov=reffov,
                    pixel=self.test_pixscale,
                    centering=centering
                )  #, phi=self.refphi) #Removed phi from call to simulate. DT, AS Feb 2016
                # -------------------------------
                if fitswrite:
                    temphdu = fits.PrimaryHDU(data=psf, header=self.simhdr)
                    temphdu.header["pixscale"] = (self.test_pixscale,
                                                  "pixel scale (rad)")
                    temphdu.writeto(self.datapath+self.refdir+\
                        "refpsf_pixscl{0}.fits".format(self.test_pixscale),
                        clobber=True)
                # -------------------------------
                pixscl_corrlist[q, :, :] = run_data_correlate(img, psf)
                self.pixscl_corr[q] = np.max(pixscl_corrlist[q])
                if True in np.isnan(self.pixscl_corr):
                    raise ValueError("Correlation produced NaNs,"\
                             " please check your work!")
        np.savetxt(self.datapath + self.refdir + "pix_correlationvalues.txt",
                   self.pixscl_corr)
        np.savetxt(self.datapath + self.refdir + "pixelscalestested_rad.txt",
                   self.pixscales)
        np.savetxt(self.datapath + self.refdir + "pixscalestested_val.txt",
                   self.scallist)
        self.pixscale_optimal, scal_maxy = utils.findmax(mag=self.pixscales,
                                                         vals=self.pixscl_corr)
        self.pixscale_factor = self.pixscale_optimal / self.pixel
        closestpixscale = self.pixscales[self.pixscl_corr ==
                                         self.pixscl_corr.max()][0]
        vprint('PIXSCALE DEBUG')
        vprint(closestpixscale)

        vprint('NRM_Model pixel scale:', self.pixscale_optimal)
        vprint('fraction of guess:', self.pixscale_factor)
        radlist = self.rotlist_rad  #DT, AS Jan 2016
        corrlist = np.zeros((len(radlist), reffov, reffov))
        self.corrs = np.zeros(len(radlist))

        if fitswrite:
            rotfiles = [
                f for f in os.listdir(self.datapath + self.refdir)
                if 'refpsf_rot' in f
            ]
        else:
            rotfiles = []
        if len(rotfiles) > 4:
            vprint("reading from file")
            self.rots = np.zeros(len(rotfiles))
            for q, rotfilefile in enumerate(rotfiles):
                f = fits.open(self.datapath + self.refdir + rotfile)
                vprint(self.datapath + self.refdir + rotfile, end=' ')
                vprint("rotfile", rotfile)
                psf, filehdr = f[0].data, f[0].header
                self.rots[q] = filehdr['ROTRAD']
                f.close()
                corrlist[q, :, :] = run_data_correlate(psf, img)
                self.corrs[q] = np.max(corrlist[q])
                vprint('max rot correlation: ', self.corrs[q])
            self.corrs = self.corrs[np.argsort(self.rots)]
            self.rots = self.rots[np.argsort(self.rots)]
        else:
            self.rots = radlist
            for q, rad in enumerate(radlist):
                vprint('no rotation files found, creating new...')
                psf = self.simulate(
                    bandpass=self.bandpass,
                    fov=reffov,
                    #pixel = closestpixscale, rotate=rad,
                    pixel=self.pixscale_optimal,
                    rotate=rad,
                    centering=centering)
                # -------------------------------
                if fitswrite:
                    temphdu = fits.PrimaryHDU(data=psf, header=self.simhdr)
                    temphdu.header["pixscale"] = (self.pixscale_optimal, \
                        "pixel scale (rad)")
                    temphdu.writeto(self.datapath+self.refdir+\
                        "refpsf_rot{0}_pixel{1}.fits".format(rad,
                        closestpixscale),clobber=True)
                # -------------------------------
                corrlist[q, :, :] = run_data_correlate(psf, img)
                self.corrs[q] = np.max(corrlist[q])

        np.savetxt(self.datapath + self.refdir + "rot_correlationvalues.txt",
                   self.corrs)
        np.savetxt(self.datapath + self.refdir + "rotationstested_rad.txt",
                   self.rots)
        np.savetxt(self.datapath + self.refdir + "rotationstested_deg.txt",
                   self.rots * 180.0 / np.pi,
                   fmt=self.fmt)  #DT nov 20
        self.rot_measured, maxy, = utils.findmax(mag=self.rots,
                                                 vals=self.corrs)
        self.refpsf = self.simulate(bandpass=self.bandpass,
                                    pixel=self.pixscale_factor * self.pixel,
                                    fov=reffov,
                                    rotate=self.rot_measured,
                                    centering=centering)

        vprint(
            '--------------- WHAT THE MATCHING ROUTINE FOUND ---------------')
        vprint('scaling factor:', self.pixscale_factor)
        vprint('pixel scale (mas):', utils.rad2mas(self.pixscale_optimal))
        vprint('rotation (rad):', self.rot_measured)
        vprint('--------------- -------------- ---------------')

        try:
            self.gof = goodness_of_fit(img, self.refpsf)
        except:
            vprint("rewrite goodness_of_fit, it failed.")
            self.gof = False
        return self.pixscale_factor, self.rot_measured, self.gof