Beispiel #1
0
    def test_under_fraserMode(self):
        'Test ``bgFinder._fraserMode``'
        data = array(range(0, 255), int)
        b = bgFinder(data)
        r = b._fraserMode()

        self.assertAlmostEqual(4.5, r, places=1)
Beispiel #2
0
    def test_stats(self):
        data = array(range(0, 255), int)
        b = bgFinder(data)
        r = b._stats()

        self.assertEqual(8, r[0])
        self.assertAlmostEqual(85.1, r[1], places=1)
Beispiel #3
0
    def test_stats(self):
        data = array(range(0, 255), int)
        b = bgFinder(data)
        r = b._stats()

        self.assertEqual(8, r[0])
        self.assertAlmostEqual(85.1, r[1], places=1)
Beispiel #4
0
    def test_under_fraserMode(self):
        'Test ``bgFinder._fraserMode``'
        data = array(range(0, 255), int)
        b = bgFinder(data)
        r = b._fraserMode()

        self.assertAlmostEqual(4.5, r, places=1)
Beispiel #5
0
    def test_gaussFit(self):
        data = array(range(0, 255), int)
        b = bgFinder(data)
        r = b._gaussFit()

        self.assertAlmostEqual(127.0, r, places=1)
        self.assertAlmostEqual(r, b.gauss[0], places=1)
        self.assertAlmostEqual(73.61159329, b.gauss[1], places=1)
Beispiel #6
0
    def test_gaussFit(self):
        data = array(range(0, 255), int)
        b = bgFinder(data)
        r = b._gaussFit()

        self.assertAlmostEqual(127.0, r, places=1)
        self.assertAlmostEqual(r, b.gauss[0], places=1)
        self.assertAlmostEqual(73.61159329, b.gauss[1], places=1)
Beispiel #7
0
    def fitWithModelPSF(self,
                        x_in,
                        y_in,
                        m_in=-1.,
                        fitWidth=7,
                        bg=None,
                        ftol=1.e-8,
                        useLinePSF=False,
                        verbose=False):
        """
        This is still experimental and hasn't been fully vetted yet.

        Use at your own risk.
        """

        self.useLinePSF = useLinePSF
        if fitWidth > self.psf.boxSize:
            raise NotImplementedError('Need to keep the fitWidth <= boxSize.')

        (A, B) = self.imageData.shape
        #ai = max(0,int(y_in)-fitWidth)
        #bi = min(A,int(y_in)+fitWidth+1)
        #ci = max(0,int(x_in)-fitWidth)
        #di = min(B,int(x_in)+fitWidth+1)
        dat = np.copy(self.imageData)

        if bg == None:
            bgf = bgFinder.bgFinder(self.imageData)
            bg = bgf.smartBackground()
            dmbg = dat - bg
            print('Subtracting background {}'.format(bg))
        else:
            dmbg = dat - bg
        if m_in == -1.:
            if useLinePSF:
                m_in = self.psf.repFact * self.psf.repFact * np.sum(
                    dat) / np.sum(self.psf.longPSF)
            else:
                m_in = self.psf.repFact * self.psf.repFact * np.sum(
                    dat) / np.sum(self.psf.fullPSF)

        lsqf = opti.leastsq(resid, (x_in, y_in, m_in),
                            args=(dmbg, self.psf, fitWidth, useLinePSF,
                                  verbose),
                            maxfev=1000,
                            ftol=ftol)
        fitPars = lsqf[0]
        l = likelihood_for_LS(fitPars,
                              dat,
                              bg,
                              self.psf,
                              boxWidth=fitWidth,
                              useLinePSF=useLinePSF)
        fitPars = np.concatenate([fitPars, np.array([l])])

        return fitPars
Beispiel #8
0
    def __call__(self,moffatWidth,moffatSNR,initAlpha=5.,initBeta=2.,repFact=5,xWidth=51,yWidth=51,
                 includeCheesySaturationCut=True,autoTrim=False,noVisualSelection=False,verbose=False):
        self.moffatWidth=moffatWidth
        self.moffatSNR=moffatSNR
        self.initAlpha=initAlpha
        self.initBeta=initBeta
        self.repFact=repFact

        self.fwhms=[]
        self.points=[]
        self.moffs=[]
        self.moffr=num.linspace(0,30,80)
        self.starsFlatR=[]
        self.starsFlatF=[]
        self.subsecs=[]
        self.goodStars=[]
        self.starsScat=None

        print 'Fitting stars with moffat profiles...'


        for j in range(len(self.XWIN_IMAGE)):
            if self.FLUX_AUTO[j]/self.FLUXERR_AUTO[j]>self.moffatSNR:
                if self.XWIN_IMAGE[j]-1<0 or self.XWIN_IMAGE[j]-1>=self.data.shape[1] or self.YWIN_IMAGE[j]-1<0 or self.YWIN_IMAGE[j]-1>=self.data.shape[0]:
                    continue
                mpsf=psf.modelPSF(num.arange(xWidth),num.arange(yWidth),alpha=self.initAlpha,beta=self.initBeta,repFact=self.repFact)
                mpsf.fitMoffat(self.data,self.XWIN_IMAGE[j],self.YWIN_IMAGE[j],boxSize=self.moffatWidth,verbose=verbose)

                fwhm=mpsf.FWHM(fromMoffatProfile=True)
                #if includeCheesySaturationCut:
                #    if (mpsf.fDist[0]-mpsf.bg)/(mpsf.moffat(0)*mpsf.A)<0.9: #cheesy saturation cut
                #        #print 'Saturated'
                #        continue

                #norm=Im.normalise(mpsf.subsec,[self.z1,self.z2])
                norm=self.normer(mpsf.subSec)
                if fwhm<>None and not (num.isnan(mpsf.beta) or num.isnan(mpsf.alpha)):
                    #print self.XWIN_IMAGE[j],self.YWIN_IMAGE[j],mpsf.alpha,mpsf.beta,fwhm
                    print '{: 8.2f} {: 8.2f} {: 5.2f} {: 5.2f} {: 5.2f}'.format(self.XWIN_IMAGE[j],self.YWIN_IMAGE[j],mpsf.alpha,mpsf.beta,fwhm)

                    self.subsecs.append(norm*1.)
                    self.goodStars.append(True)

                    self.moffs.append(mpsf.moffat(self.moffr)*1.)

                    self.starsFlatR.append(psf.downSample2d(mpsf.repRads,mpsf.repFact))
                    self.starsFlatF.append((mpsf.subSec-mpsf.bg)/(mpsf.moffat(0)*mpsf.A))

                    self.moffs[len(self.moffs)-1]/=num.max(self.moffs[len(self.moffs)-1])

                    self.points.append([fwhm,mpsf.chi,mpsf.alpha,mpsf.beta,self.XWIN_IMAGE[j],self.YWIN_IMAGE[j],mpsf.bg])
        self.points=num.array(self.points)
        self.goodStars=num.array(self.goodStars)

        if autoTrim:
            bg=bgFinder.bgFinder(self.points[:,0])
            mode=bg('fraserMode')
            w=num.where(num.abs(self.points[:,0]-mode)>0.5)
            self.goodStars[w]=False



        self.figPSF=pyl.figure('Point Source Selector')
        self.sp1=pyl.subplot2grid((4,4),(0,1),colspan=3,rowspan=2)
        pyl.scatter(self.points[:,0],self.points[:,1],picker=True)
        pyl.title('Select PSF range with zoom and then close the plot window.')
        self.sp2=pyl.subplot2grid((4,4),(2,1),colspan=3,sharex=self.sp1,rowspan=1)
        bins=num.arange(num.min(self.points[:,0]),num.max(self.points[:,0])+0.5,0.5)
        pyl.hist(self.points[:,0],bins=bins)
        pyl.xlabel('FWHM (pix)')
        self.sp3=pyl.subplot2grid((4,4),(0,0),rowspan=2,sharey=self.sp1)
        pyl.hist(self.points[:,1],bins=30,orientation='horizontal')
        pyl.ylabel('RMS')
        self.sp4=pyl.subplot2grid((4,4),(2,0),rowspan=2)

        self.moffPatchList=[]
        self.showing=[]

        for j in range(len(self.moffs)):
            self.moffPatchList.append(self.sp4.plot(self.moffr,self.moffs[j]))
            self.showing.append(1)
        self.sp4.set_xlim(0,30)
        self.sp4.set_ylim(0,1.02)
        self.sp5=pyl.subplot2grid((4,4),(3,1))
        self.sp5.set_aspect('equal')
        self.psfPlotLimits=[self.sp1.get_xlim(),self.sp1.get_ylim()]
        self.conn1=self.sp1.callbacks.connect('ylim_changed',self.PSFrange)
        self.conn2=pyl.connect('pick_event',self.ScatterPSF)
        if not noVisualSelection: pyl.show()


        fwhm_lim=self.sp1.get_xlim()
        chi_lim=self.sp1.get_ylim()

        w=num.where((self.points[:,0]>fwhm_lim[0])&(self.points[:,0]<fwhm_lim[1])&(self.points[:,1]>chi_lim[0])&(self.points[:,1]<chi_lim[1])&(self.goodStars==True))
        pyl.close()

        goodFits=self.points[w]
        goodMeds=num.median(goodFits[:4],axis=0)
        goodSTDs=num.std(goodFits[:4],axis=0)
        return (goodFits,goodMeds,goodSTDs)
Beispiel #9
0
    def fitDoubleWithModelPSF(self,
                              x_in,
                              y_in,
                              X_in,
                              Y_in,
                              bRat_in,
                              m_in=-1.,
                              bg=None,
                              fitWidth=20,
                              nWalkers=30,
                              nBurn=50,
                              nStep=100,
                              useErrorMap=False,
                              useLinePSF=False,
                              verbose=False):
        """
        Using emcee (It's hammer time!) two sources are fit using
        the provided psf to find the best x,y and amplitude, and confidence
        range on the fitted parameters.

        x_in, y_in, m_in, X_in, Y_in, bRat - initial guesses on the true centroids, the amplitude and brightness ratio
                                             of the two sources
        fitWidth - the width +- of x_in/y_in of the data used in the fit
        nWalkers, nBurn, nStep - emcee fitting paramters. If you don't know what these are RTFM
        bg - the background of the image. Needed for the uncertainty table.
             **Defaults to None.** When set to default, it will invoke
             the background measurement and apply that. Otherwise, it assumes you are dealing with
             background subtracted data already.
        useErrorMap - if true, a simple pixel uncertainty map is used in the fit. This is adopted as
                      ue_ij=(imageData_ij+bg)**0.5, that is, the poisson noise estimate. Note the fit confidence range
                      is only honest if useErrorMap=True.
        useLinePSF - use the TSF? If not, use the PSF
        verbose - if set to true, lots of information printed to screen
        """

        self.useLinePSF = useLinePSF

        (A, B) = self.imageData.shape
        ai = max(0, int((y_in + Y_in) / 2) - fitWidth)
        bi = min(A, int((y_in + Y_in) / 2) + fitWidth + 1)
        ci = max(0, int((x_in + X_in) / 2) - fitWidth)
        di = min(B, int((x_in + X_in) / 2) + fitWidth + 1)
        dat = np.copy(self.imageData)

        if bg == None:
            bgf = bgFinder.bgFinder(self.imageData)
            bg = bgf.smartBackground()
            dat -= bg

        if not useErrorMap:
            ue = dat * 0.0 + 1.
        else:
            ue = (dat + bg)**0.5

        if m_in == -1.:
            if useLinePSF:
                m_in = np.sum(dat) / np.sum(self.psf.longPSF)
            else:
                m_in = np.sum(dat) / np.sum(self.psf.fullPSF)

        nDim = 6
        r0 = []
        for ii in range(nWalkers):
            r0.append(
                np.array([x_in, y_in, m_in, X_in, Y_in, m_in * bRat_in]) +
                sci.randn(6) *
                np.array([1., 1., m_in * 0.4, 1., 1., m_in * 0.4 * bRat_in]))
        r0 = np.array(r0)

        sampler = emcee.EnsembleSampler(nWalkers,
                                        nDim,
                                        lnprobDouble,
                                        args=[
                                            dat, (ai, bi, ci, di), self.psf,
                                            ue, self.useLinePSF, verbose
                                        ])
        pos, prob, state = sampler.run_mcmc(r0, nBurn)
        sampler.reset()
        pos, prob, state = sampler.run_mcmc(pos, nStep, rstate0=state)
        self.samps = sampler.chain
        self.probs = sampler.lnprobability
        self.dat = np.copy(dat)
        self.fitted = True
Beispiel #10
0
    def fitWithModelPSF(self,
                        x_in,
                        y_in,
                        m_in=-1.,
                        fitWidth=20,
                        nWalkers=20,
                        nBurn=10,
                        nStep=20,
                        bg=None,
                        useErrorMap=False,
                        useLinePSF=False,
                        fitRateAngle=False,
                        rate_in=None,
                        angle_in=None,
                        exptime=None,
                        pixScale=None,
                        verbose=False,
                        rand_pos=0.1):
        """
        Using emcee (It's hammer time!) the provided image is fit using
        the provided psf to find the best x,y and amplitude, and confidence
        range on the fitted parameters.

        x_in, y_in, m_in - initial guesses on the true centroid and amplitude of the object
        fitWidth - the width +- of x_in/y_in of the data used in the fit
        nWalkers, nBurn, nStep - emcee fitting paramters. If you don't know what these are RTFM
        bg - the background of the image. Needed for the uncertainty table.
             **Defaults to None.** When set to default, it will invoke
             the background measurement and apply that. Otherwise, it assumes you are dealing with
             background subtracted data already.
        useErrorMap - if true, a simple pixel uncertainty map is used in the fit. This is adopted as
                      ue_ij=(imageData_ij+bg)**0.5, that is, the poisson noise estimate. Note the fit confidence range
                      is only honest if useErrorMap=True.
        useLinePSF - use the TSF? If not, use the PSF
        verbose - if set to true, lots of information printed to screen
        """

        print "Initializing sampler"

        self.nForFitting = 0
        self.useLinePSF = useLinePSF

        if fitWidth > self.psf.boxSize:
            raise NotImplementedError('Need to keep the fitWidth <= boxSize.')

        (A, B) = self.imageData.shape
        ai = max(0, int(y_in) - fitWidth)
        bi = min(A, int(y_in) + fitWidth + 1)
        ci = max(0, int(x_in) - fitWidth)
        di = min(B, int(x_in) + fitWidth + 1)
        dat = np.copy(self.imageData)

        if bg == None:
            bgf = bgFinder.bgFinder(self.imageData)
            bg = bgf.smartBackground()
            dat -= bg
            print 'Subtracting background {}'.format(bg)

        if not useErrorMap:
            ue = dat * 0.0 + 1.
        else:
            ue = (dat + bg)**0.5

        self.fitted = True

        if m_in == -1.:
            if useLinePSF:
                m_in = self.psf.repFact * self.psf.repFact * np.sum(
                    dat) / np.sum(self.psf.longPSF)
            else:
                m_in = self.psf.repFact * self.psf.repFact * np.sum(
                    dat) / np.sum(self.psf.fullPSF)

        if not fitRateAngle:

            nDim = 2
            r0 = []
            for ii in range(nWalkers):
                r0.append(
                    np.array([x_in, y_in]) +
                    sci.randn(2) * np.array([rand_pos, rand_pos]))
            r0 = np.array(r0)

            #fit first using input best guess amplitude
            sampler = emcee.EnsembleSampler(nWalkers,
                                            nDim,
                                            lnprob,
                                            args=[
                                                dat, (ai, bi, ci, di),
                                                self.psf, ue, useLinePSF,
                                                verbose, (-1, -1, m_in)
                                            ])
            print "Executing xy burn-in... this may take a while."
            pos, prob, state = sampler.run_mcmc(r0, nBurn)  #, 10)
            sampler.reset()
            print "Executing xy production run... this will also take a while."
            pos, prob, state = sampler.run_mcmc(pos, nStep, rstate0=state)
            self.samps = sampler.chain
            self.probs = sampler.lnprobability
            self.dat = np.copy(dat)

            out = self.fitResults()
            (x, y, junk) = out[0]
            dx = (out[1][0][1] - out[1][0][0]) / 2.0
            dy = (out[1][1][1] - out[1][1][0]) / 2.0

            nDim = 1  # need to put two here rather than one because the fitresults code does a residual subtraction
            r0 = []
            for ii in range(nWalkers):
                r0.append(
                    np.array([m_in]) + sci.randn(1) * np.array([m_in * 0.25]))
            r0 = np.array(r0)

            #now fit the amplitude using the best-fit x,y from above
            #could probably cut the nBurn and nStep numbers down by a factor of 2
            sampler = emcee.EnsembleSampler(nWalkers,
                                            nDim,
                                            lnprob,
                                            args=[
                                                dat, (ai, bi, ci, di),
                                                self.psf, ue, useLinePSF,
                                                verbose, (x, y, -1)
                                            ])
            print "Executing amplitude burn-in... this may take a while."
            pos, prob, state = sampler.run_mcmc(r0, max(nBurn / 2, 10))
            sampler.reset()
            print "Executing amplitude production run... this will also take a while."
            pos, prob, state = sampler.run_mcmc(pos,
                                                max(nStep / 2, 10),
                                                rstate0=state)
            self.samps = sampler.chain
            self.probs = sampler.lnprobability
            self.dat = np.copy(dat)

            out = self.fitResults()
            amp = out[0][0]
            damp = (out[1][0][1] - out[1][0][0]) / 2.0

            #now do a full 3D fit using a small number of burn and steps.
            nDim = 3
            r0 = []
            for ii in range(nWalkers):
                r0.append(
                    np.array([x, y, amp]) +
                    sci.randn(3) * np.array([dx, dy, damp]))
            r0 = np.array(r0)

            sampler = emcee.EnsembleSampler(nWalkers,
                                            nDim,
                                            lnprob,
                                            args=[
                                                dat, (ai, bi, ci, di),
                                                self.psf, ue, useLinePSF,
                                                verbose
                                            ])
            print "Executing xy-amp burn-in... this may take a while."
            pos, prob, state = sampler.run_mcmc(r0, nBurn)
            sampler.reset()
            print "Executing xy-amp production run... this will also take a while."
            pos, prob, state = sampler.run_mcmc(pos, nStep, rstate0=state)

        else:

            nDim = 5
            r0 = []
            for ii in range(nWalkers):
                r0.append(
                    np.array([x_in, y_in, m_in, rate_in, angle_in]) +
                    sci.randn(nDim) *
                    np.array([0.1, 0.1, m_in * 0.1, rate_in * 0.1, 4.0]))
            r0 = np.array(r0)

            #fit first using input best guess amplitude
            sampler = emcee.EnsembleSampler(nWalkers,
                                            nDim,
                                            lnprob_varRateAngle_LSSTHACK,
                                            args=[
                                                dat, (ai, bi, ci, di),
                                                self.psf, ue, useLinePSF,
                                                exptime, pixScale, verbose
                                            ])
            #dat,lims,psf,ue,useLinePSF, exptime, pixScale, verbose=False):
            print "Executing burn-in... this may take a while."
            pos, prob, state = sampler.run_mcmc(r0, nBurn, 10)
            sampler.reset()
            print "Executing production run... this will also take a while."
            pos, prob, state = sampler.run_mcmc(pos, nStep, rstate0=state)
            self.samps = sampler.chain
            self.probs = sampler.lnprobability
            self.dat = np.copy(dat)

        self.samps = sampler.chain
        self.probs = sampler.lnprobability
        self.dat = np.copy(dat)
Beispiel #11
0
    def fitDoubleWithModelPSF(self,x_in,y_in,X_in,Y_in,bRat_in,m_in=-1.,bg=None,
                              fitWidth=20,nWalkers=30,nBurn=50,nStep=100,
                              useErrorMap=False,
                              useLinePSF=False,verbose=False):
        """
        Using emcee (It's hammer time!) two sources are fit using
        the provided psf to find the best x,y and amplitude, and confidence
        range on the fitted parameters.

        x_in, y_in, m_in, X_in, Y_in, bRat - initial guesses on the true centroids, the amplitude and brightness ratio
                                             of the two sources
        fitWidth - the width +- of x_in/y_in of the data used in the fit
        nWalkers, nBurn, nStep - emcee fitting paramters. If you don't know what these are RTFM
        bg - the background of the image. Needed for the uncertainty table.
             **Defaults to None.** When set to default, it will invoke
             the background measurement and apply that. Otherwise, it assumes you are dealing with
             background subtracted data already.
        useErrorMap - if true, a simple pixel uncertainty map is used in the fit. This is adopted as
                      ue_ij=(imageData_ij+bg)**0.5, that is, the poisson noise estimate. Note the fit confidence range
                      is only honest if useErrorMap=True.
        useLinePSF - use the TSF? If not, use the PSF
        verbose - if set to true, lots of information printed to screen
        """


        self.useLinePSF=useLinePSF

        (A,B)=self.imageData.shape
        ai=max(0,int((y_in+Y_in)/2)-fitWidth)
        bi=min(A,int((y_in+Y_in)/2)+fitWidth+1)
        ci=max(0,int((x_in+X_in)/2)-fitWidth)
        di=min(B,int((x_in+X_in)/2)+fitWidth+1)
        dat=num.copy(self.imageData)


        if bg==None:
            bgf=bgFinder.bgFinder(self.imageData)
            bg=bgf.smartBackground()
            dat-=bg


        if not useErrorMap:
            ue=dat*0.0+1.
        else:
            ue=(dat+bg)**0.5



        if m_in==-1.:
            if useLinePSF:
                m_in=num.sum(dat)/num.sum(self.psf.longPSF)
            else:
                m_in=num.sum(dat)/num.sum(self.psf.fullPSF)

        nDim=6
        r0=[]
        for ii in range(nWalkers):
            r0.append(num.array([x_in,y_in,m_in,X_in,Y_in,m_in*bRat_in])+sci.randn(6)*num.array([1.,1.,
                                                                                                          m_in*0.4,
                                                                                                    1.,1.,
                                                                                               m_in*0.4*bRat_in]))
        r0=num.array(r0)

        sampler=emcee.EnsembleSampler(nWalkers,nDim,lnprobDouble,args=[dat,(ai,bi,ci,di),self.psf,ue,self.useLinePSF,verbose])
        pos, prob, state=sampler.run_mcmc(r0,nBurn)
        sampler.reset()
        pos, prob, state = sampler.run_mcmc(pos, nStep, rstate0=state)
        self.samps=sampler.chain
        self.probs=sampler.lnprobability
        self.dat=num.copy(dat)
        self.fitted=True
Beispiel #12
0
    def test_gaussLike(self):
        data = array(range(0, 255), int)
        b = bgFinder(data)
        r = b._gaussLike([1.0, 2.0])

        self.assertAlmostEqual(679178.581857, r, places=1)
Beispiel #13
0
 def create_finder():
     retval = bgFinder(MagicMock())
     retval.data = MagicMock()
     return retval
Beispiel #14
0
def runSex(file,
           fn,
           chip,
           mask_file,
           svsPath,
           showProgress=False,
           verbose=False,
           includeImageMask=False,
           kron_cut=-0.5,
           runSextractor=True):

    badflags = 1 + 512 + 8 + 64 + 16 + 4 + 256 + 2 + 128 + 4096

    if path.isfile(mask_file):
        mask = mask_file + '[0]'

        if includeImageMask:
            with fits.open(mask_file) as han:
                mask_data = han[0].data
            #print('Using image mask')
        else:
            mask_data = None

    else:
        mask = None
        mask_data = None

    with fits.open(file) as han:

        header = han[0].header
        header1 = han[1].header
        if includeImageMask:
            han2 = han[2].data
            if mask_data is None:
                mask_data = np.zeros(han2.shape).astype(han2.dtype)

            #good pixels in sextractor have mask value == 1, bad have mask value==0
            """
            w = np.where((han2>2080)|(han2==12)|(han2==5)|(han2==1024)) #12 is cosmic rays, everything above 32 seems to be saturation or bad columns
            try:
                mask_data[w] = 0.0
            """
            w = np.where(((han2 & badflags) == 0))  #good pixels
            try:
                mask_data[w] = 1
            except:
                print(np.max(w[0]), np.max(w[1]))
                exit()

            if runSextractor:
                fits.writeto(file + '.mask', mask_data, overwrite=True)

            mask = file + '.mask'

        if showProgress:
            data = han[0].data

    seeing = header['SEEING_MODE']

    try:
        apNum = apertures[round(seeing)]
    except:
        #seeing variable is -9999. This apNum variable will be reset based on sextractor output
        apNum = apertures[2]

    catObject = catObj()
    catObject.seeing = header['SEEING_MODE']
    catObject.ellip = header['ELL_MED']
    catObject.astrms = header['WCS_RMS']

    if showProgress:
        pyl.imshow(data, interpolation='nearest', cmap='gray', origin='lower')
        pyl.colorbar()
        pyl.show()

    if runSextractor:
        if mask is not None:
            scamp.runSex('subaru_LDAC.sex',
                         file + '[0]',
                         options={
                             'CATALOG_NAME':
                             svsPath + fn.replace('.fits', '.cat'),
                             'WEIGHT_IMAGE': mask,
                             'WEIGHT_TYPE': 'map_weight'
                         },
                         verbose=verbose)
        else:
            scamp.runSex('subaru_LDAC.sex',
                         file + '[0]',
                         options={
                             'CATALOG_NAME':
                             svsPath + fn.replace('.fits', '.cat')
                         },
                         verbose=verbose)

    catalog = scamp.getCatalog(svsPath + fn.replace('.fits', '.cat'),
                               paramFile='sextract.param')

    #get rid of the flux=0 sources
    w = np.where((catalog['FLUX_APER(9)'][:,0]>0) & (catalog['FLUX_APER(9)'][:,1]>0) & (catalog['FLUX_APER(9)'][:,2]>0) & (catalog['FLUX_APER(9)'][:,3]>0) & (catalog['FLUX_APER(9)'][:,4]>0)\
                 & (catalog['FLUX_APER(9)'][:,5]>0) & (catalog['FLUX_APER(9)'][:,6]>0)\
                 & (catalog['FLUX_AUTO']>0))
    for key in catalog:
        catalog[key] = catalog[key][w]

    if chip < 100:
        x_high = 2045
        y_high = 4173
    else:
        print('Chip>100')
        x_high = 4173
        y_high = 2045

    if catObject.seeing <= 0:
        #need to estimate seeing because header value is non-sense
        #use all snr>40 sources, and take the median FWHM_IMAGE value
        FWHM_IMAGE = np.sort(catalog['FWHM_IMAGE'][np.where(
            (catalog['X_IMAGE'] > 50) & (catalog['X_IMAGE'] < x_high - 50)
            & (catalog['Y_IMAGE'] > 50) & (catalog['Y_IMAGE'] < y_high - 50)
            & (catalog['FLUX_APER(9)'][:, apNum] /
               catalog['FLUXERR_APER(9)'][:, apNum] > 40))])
        #fwhm_mode = FWHM_IMAGE[len(FWHM_IMAGE)/2]
        fwhm_median = np.median(FWHM_IMAGE)
        catObject.seeing = fwhm_median
        apNum = apertures[int(round(catObject.seeing))]

    #setup cut on Kron magnitude, by getting the median difference between kron and aperture magnitude for star-like objects.
    #avoid the edges
    w = np.where((catalog['X_IMAGE'] > 50) & (catalog['X_IMAGE'] < x_high - 50)
                 & (catalog['Y_IMAGE'] > 50)
                 & (catalog['Y_IMAGE'] < y_high - 50)
                 & ((catalog['FLUX_APER(9)'][:, apNum] /
                     catalog['FLUXERR_APER(9)'][:, apNum]) > 40)
                 & (catalog['FWHM_IMAGE'] > 1.5))

    mag_aper = -2.5 * np.log10(catalog['FLUX_APER(9)'][:, apNum][w] /
                               header['EXPTIME']) + header['MAGZERO']
    mag_auto = -2.5 * np.log10(
        catalog['FLUX_AUTO'][w] / header['EXPTIME']) + header['MAGZERO']

    mag_diff = mag_auto - mag_aper

    bgf = bgFinder.bgFinder(mag_diff)
    med_mag_diff = bgf.fraserMode(0.4)
    #med_mag_diff = getMeanMagDiff(mag_aper,mag_diff)
    #if np.isnan(med_mag_diff):
    #    med_mag_diff = getMeanMagDiff(mag_aper,mag_diff,returnMax = True)

    #cut on position, SNR, and FWHM
    snr = catalog['FLUX_APER(9)'][:, apNum] / catalog['FLUXERR_APER(9)'][:,
                                                                         apNum]
    if catObject.seeing > 0:
        w = np.where((catalog['X_IMAGE'] > 3) & (catalog['X_IMAGE'] < x_high)
                     & (catalog['Y_IMAGE'] > 3) & (catalog['Y_IMAGE'] < y_high)
                     & (catalog['FWHM_IMAGE'] < catObject.seeing * 5.0)
                     & (snr > 3) & (catalog['FWHM_IMAGE'] > 1.5)
                     & (catalog['A_IMAGE'] > 1.0) & (catalog['B_IMAGE'] > 1.0))
    else:
        w = np.where(
            (catalog['X_IMAGE'] > 3) & (catalog['X_IMAGE'] < x_high) &
            (catalog['Y_IMAGE'] > 3) & (catalog['Y_IMAGE'] < y_high) &
            (catalog['FWHM_IMAGE'] < 10.0) & (snr > 3) &
            (catalog['FWHM_IMAGE'] > 1.5) & (catalog['A_IMAGE'] > 1.5) &
            (catalog['B_IMAGE'] >
             1.0))  #now measured in arcseconds rather than in units of FWHM

    #now cut on difference between kron and aperture magnitudes, assuming there were enough sources for the cut
    if not np.isnan(med_mag_diff):
        mag_aper = -2.5 * np.log10(catalog['FLUX_APER(9)'][:, apNum][w] /
                                   header['EXPTIME']) + header['MAGZERO']
        mag_auto = -2.5 * np.log10(
            catalog['FLUX_AUTO'][w] / header['EXPTIME']) + header['MAGZERO']
        mag_diff = mag_auto - mag_aper - med_mag_diff
        w = [w[0][np.where(mag_diff > kron_cut)]]
        #pyl.scatter(mag_aper,mag_diff)
        #print(len(w[0]))
        #pyl.scatter(mag_aper[np.where(np.abs(mag_diff)<kron_cut)],mag_diff[np.where(np.abs(mag_diff)<kron_cut)])
        #pyl.show()
        #exit()

    catObject.fwhm_image = catalog['FWHM_IMAGE'][w]
    catObject.x = catalog['X_IMAGE'][w] - 1.0
    catObject.y = catalog['Y_IMAGE'][w] - 1.0
    catObject.flux = catalog['FLUX_APER(9)'][:, apNum][w]
    catObject.snr = snr[w]
    catObject.jd = 2400000.5 + header['MJD'] + header['EXPTIME'] / (24.0 *
                                                                    3600.0)

    WCS = wcs.WCS(header1)
    (ra, dec) = WCS.all_pix2world(catObject.x, catObject.y, 0)
    catObject.ra = ra
    catObject.dec = dec
    catObject.mag = 2.5 * np.log10(
        catObject.flux / header['EXPTIME']) + header['MAGZERO']

    pickle.dump(catObject,
                open(svsPath + fn.replace('.fits', '.sex_save'), 'wb'))

    if includeImageMask and runSextractor:
        os.remove(file + '.mask')

    print(file, len(catObject.ra))
    return catObject
def make_trippy_profile(psf_image, stamp):

    with fits.open(psf_image) as seepsf:        # Get pixel values and Gaussian fit value par1 from seepsf image
        for ext in range(len(seepsf)):
            try:
                header = seepsf[ext].header
                psfdata = seepsf[ext].data      # PSF image data
                par1 = header['PAR1']
            except:
                continue

    with fits.open(stamp) as stp:       # Postage stamp image
        header = stp[0].header
        ra_rate = header['RARATE']      # Values placed in header ext 0 previously
        dec_rate = header['DECRATE']
        for ext in range(len(stp)):     # Look in each header section for these values
            try:
                header = stp[ext].header
                stampdata = stp[ext].data       # Stamp image data
                exptime = header['EXPTIME']
                zpt = header['PHOTZP']
                pixscale = header['PIXSCAL1']
            except:
                continue

    imgdim = 501        # Should be odd number so that we have a central pixel

    halfdim = (imgdim-1)/2

    emptyimg = (np.random.poisson(1000, (imgdim, imgdim)) - 1000).astype('float64')    # Create empty array with "noise", place psf in center of larger "image" for giving to trippy

    leftsize = (psfdata.shape[0]-1)/2     # Pixels left of center
    rightsize = (psfdata.shape[0]+1)/2    # Pixels right of center

    emptyimg[halfdim-leftsize : halfdim+rightsize, halfdim-leftsize : halfdim+rightsize] += psfdata     # Plant PSF from seepsf in center of empty image

    fwhm = 2*math.sqrt(2*math.log(2))*par1      # Get full width/half max using par1 of Gaussian PSF

    rate = math.sqrt(ra_rate**2+dec_rate**2)
    angle = math.degrees(math.atan2(dec_rate, ra_rate))      # Angle w.r.t. horizontal, between +/-90
    
    if angle>90:        # Since angle can only be in range +/-90
        angle -= 180

    if angle <-90:
        angle += 180

    if dec_rate<0:
        angle=-1*angle

    # the center of the source is the center of the image
    seecen = np.array([emptyimg.shape[1]/2.+0.5])

    # Generate model of size 61x61, alpha and beta are moffat fit values, 1.75 determined experimentally when matching moffat to Gaussian shape
    goodPSF=psf.modelPSF(np.arange(61), np.arange(61), alpha=1.75*par1, beta=2)
    goodPSF.genLookupTable(emptyimg, seecen, seecen)    # Generate lookup table for model PSF, centered at the center of the psf image
    
    '''z2 = goodPSF.lookupTable.max()
    z1 = goodPSF.lookupTable.min()
    normer=interval.ManualInterval(z1,z2)
    pyl.imshow(normer(goodPSF.lookupTable))
    pyl.show()'''

    goodPSF.line(rate, angle, exptime/3600., pixScale=pixscale, useLookupTable=True)    # Generate trailed/line PSF

    # Use if you want to save image of the trippy psf model
    #modelimg = psf_image.replace('seepsf','model')
    #goodPSF.psfStore(modelimg)

    stampdata = stampdata.astype('float64')     # Stamp data is originally ints
    bgf=bgFinder.bgFinder(stampdata)            # Calculate and subtract background
    bg=bgf.smartBackground()
    stampdata-=bg

    centroid = sep_phot(stampdata, 0.002, 3)        # Use Kristi's code to get centroid info using SEP

    r_close = 1000                                        # Arbitrary number that will intentionally be too large 

    for i in range(len(centroid['x'])):             # For all the objects identified in the stamp by SEP, find the one closest to the center of the image
        dist = (centroid['x'][i]-stampdata.shape[0]/2)**2 + (centroid['y'][i]-stampdata.shape[1]/2)**2
        if dist < r_close:
            r_close = dist
            closest = i
        
    xcen, ycen = centroid['x'][closest], centroid['y'][closest]     # Use the centroid that was closest to the center, since it will correspond to the asteroid

    print 'Using centroid {} {} (in numpy coordinates)'.format(xcen,ycen)

    phot=pill.pillPhot(stampdata)       # Perform trailed source photometry, calculate SNR, total flux
    phot(xcen, ycen, radius=1.1*fwhm, l=(exptime/3600.)*rate/pixscale, a=angle, skyRadius=4*fwhm, width=6*fwhm, zpt=zpt, exptime=exptime)
    phot.SNR(verbose=True)

    fitter = MCMCfit.MCMCfitter(goodPSF, stampdata)     # Fit trailed model to background subtracted stamp image
    fitter.fitWithModelPSF(xcen, ycen, m_in=-1, bg=bg, useLinePSF=True,fitWidth=15,nWalkers=20,nStep=20,nBurn=20,useErrorMap=True)
    (fitPars,fitRange)=fitter.fitResults(0.67)      # 0.67 = fit to 1 sigma
    print '1-sigma range on Best Point', fitRange

    modelImage=goodPSF.plant(fitPars[0],fitPars[1],fitPars[2],stampdata,addNoise=False,useLinePSF=True,returnModel=True)        # Model the trailed source
    
    pyl.imshow(modelImage)
    pyl.show()

    removed=goodPSF.remove(fitPars[0],fitPars[1],fitPars[2],stampdata,useLinePSF=True)      # Subtract the model from the stamp

    HDU=fits.PrimaryHDU(removed)
    List=fits.HDUList([HDU])
    psf_removed = psf_image.replace('seepsf','removed')
    os.unlink(psf_image)
    List.writeto(psf_removed,clobber=True)

    print 'Asteroid PSF source flux: {}'.format(np.sum(modelImage))

    z1 = stampdata[stampdata.shape[0]/2-30:stampdata.shape[0]/2 + 30,stampdata.shape[1]/2-30:stampdata.shape[1]/2 + 30].min()
    z2 = stampdata[stampdata.shape[0]/2-30:stampdata.shape[0]/2 + 30,stampdata.shape[1]/2-30:stampdata.shape[1]/2 + 30].max()
    normer=interval.ManualInterval(z1,z2)
    pyl.imshow(normer(stampdata))
    pyl.show()
    pyl.imshow(normer(removed))
    pyl.show()
Beispiel #16
0
 def create_finder():
     retval = bgFinder(MagicMock())
     retval.data = MagicMock()
     return retval
Beispiel #17
0
    def __call__(self,
                 moffatWidth,
                 moffatSNR,
                 initAlpha=5.,
                 initBeta=2.,
                 repFact=5,
                 xWidth=51,
                 yWidth=51,
                 includeCheesySaturationCut=False,
                 autoTrim=False,
                 noVisualSelection=False,
                 verbose=False):
        self.moffatWidth = moffatWidth
        self.moffatSNR = moffatSNR
        self.initAlpha = initAlpha
        self.initBeta = initBeta
        self.repFact = repFact

        self.fwhms = []
        self.points = []
        self.moffs = []
        self.moffr = np.linspace(0, self.moffatWidth, self.moffatWidth * 3)
        self.starsFlatR = []
        self.starsFlatF = []
        self.subsecs = []
        self.goodStars = []
        self.starsScat = None

        print 'Fitting stars with moffat profiles...'
        print '      X         Y    chi    a     b    FWHM'

        for j in range(len(self.XWIN_IMAGE)):
            if self.FLUX_AUTO[j] / self.FLUXERR_AUTO[j] > self.moffatSNR:
                if self.XWIN_IMAGE[j] - 1 - (
                        moffatWidth + 1) < 0 or self.XWIN_IMAGE[j] - 1 + (
                            moffatWidth + 1
                        ) >= self.data.shape[1] or self.YWIN_IMAGE[j] - 1 - (
                            moffatWidth + 1) < 0 or self.YWIN_IMAGE[j] - 1 + (
                                moffatWidth + 1) >= self.data.shape[0]:
                    continue
                #this psf object creator has to be here. It's to do with the way PSF objects are initialized. Some time
                #in the future I will adjust this for a small speed boost.
                mpsf = psf.modelPSF(np.arange(xWidth),
                                    np.arange(yWidth),
                                    alpha=self.initAlpha,
                                    beta=self.initBeta,
                                    repFact=self.repFact)
                mpsf.fitMoffat(self.data,
                               self.XWIN_IMAGE[j],
                               self.YWIN_IMAGE[j],
                               boxSize=self.moffatWidth,
                               verbose=verbose)

                fwhm = mpsf.FWHM(fromMoffatProfile=True)

                #norm=Im.normalise(mpsf.subsec,[self.z1,self.z2])
                norm = self.normer(mpsf.subSec)
                if (fwhm is not None) and not (np.isnan(mpsf.beta)
                                               or np.isnan(mpsf.alpha)):
                    print '   {: 8.2f} {: 8.2f} {:3.2f} {: 5.2f} {: 5.2f} {: 5.2f} '.format(
                        self.XWIN_IMAGE[j], self.YWIN_IMAGE[j],
                        mpsf.chiFluxNorm, mpsf.alpha, mpsf.beta, fwhm)

                    self.subsecs.append(norm * 1.)
                    self.goodStars.append(True)

                    self.moffs.append(mpsf.moffat(self.moffr) * 1.)

                    self.starsFlatR.append(
                        psf.downSample2d(mpsf.repRads, mpsf.repFact))
                    self.starsFlatF.append(
                        (mpsf.subSec - mpsf.bg) / (mpsf.moffat(0) * mpsf.A))

                    self.moffs[len(self.moffs) - 1] /= np.max(
                        self.moffs[len(self.moffs) - 1])

                    self.points.append([
                        fwhm, mpsf.chi, mpsf.alpha, mpsf.beta,
                        self.XWIN_IMAGE[j], self.YWIN_IMAGE[j], mpsf.bg
                    ])
        self.points = np.array(self.points)
        self.goodStars = np.array(self.goodStars)

        FWHM_mode_width = 1.0  #could be 0.5 just as well
        ab_std_width = 2.0
        if autoTrim:
            print '\nDoing auto star selection.'
            #first use Frasermode on the distribution of FWHM to get a good handle on the true FWHM of stars
            #select only those stars with FWHM of +-1 pixel of the mode.
            bg = bgFinder.bgFinder(self.points[:, 0])
            mode = bg('fraserMode')
            w = np.where(np.abs(self.points[:, 0] - mode) > FWHM_mode_width)
            self.goodStars[w] = False

            #now mean select on both moffat a and b parameters to get only those with common shapes
            w = np.where(self.goodStars)
            mean_a = np.mean(self.points[w][:, 2])
            std_a = np.std(self.points[w][:, 2])
            mean_b = np.mean(self.points[w][:, 3])
            std_b = np.std(self.points[w][:, 3])

            w = np.where(
                (np.abs(self.points[:, 0] - mode) > FWHM_mode_width)
                | (np.abs(self.points[:, 2] - mean_a) > ab_std_width * std_a)
                | (np.abs(self.points[:, 3] - mean_b) > ab_std_width * std_b))
            self.goodStars[w] = False

            #now eliminate the ones with sources nearby
            for ii in range(len(self.goodStars)):
                dist = ((self.XWIN_IMAGE - self.points[ii, 4])**2 +
                        (self.YWIN_IMAGE - self.points[ii, 5])**2)**0.5
                args = np.argsort(dist)
                dist = dist[args]
                #print self.points[ii,4:6],dist
                if dist[1] < moffatWidth:
                    self.goodStars[ii] = False
            """

            #now print out the number of pixels that are 3-sigma above the naive expectation of the moffat profile itself
            mpsf = psf.modelPSF(np.arange(xWidth), np.arange(yWidth), alpha=mean_a, beta=mean_b,
                                repFact=self.repFact)
            print 'Fitting amplitudes to each good star.'
            for ii in range(len(self.moffs)):
                if self.goodStars[ii]:
                    mpsf.fitMoffat(self.data,
                                   self.XWIN_IMAGE[ii], self.YWIN_IMAGE[ii],
                                   boxSize = self.moffatWidth,
                                   fixAB = True)
                    a,b = int(self.YWIN_IMAGE[ii]-yWidth/2),int(self.YWIN_IMAGE[ii]+yWidth/2)+1
                    c,d = int(self.XWIN_IMAGE[ii]-xWidth/2),int(self.XWIN_IMAGE[ii]+xWidth/2)+1
                    x,y = self.XWIN_IMAGE[ii]-int(self.XWIN_IMAGE[ii])+xWidth/2+1.0, self.YWIN_IMAGE[ii]-int(self.YWIN_IMAGE[ii])+yWidth/2+1.0
                    cut = self.data[a:b,c:d]

                    removed = mpsf.remove(self.XWIN_IMAGE[ii]-0.5,self.YWIN_IMAGE[ii]-0.5, mpsf.A, self.data)[a:b,c:d]-mpsf.bg
                    print  ii,len(np.where( np.abs(removed/cut**0.5)>3)[0])

            exit()
            """

        self.figPSF = pyl.figure('Point Source Selector')
        self.sp1 = pyl.subplot2grid((4, 4), (0, 1), colspan=3, rowspan=2)
        pyl.scatter(self.points[:, 0], self.points[:, 1], picker=True)
        pyl.title(
            'Select PSF range with zoom,\n' +
            'inspect stars (a = next, d = previous, w = toggle on/off,\n' +
            'or left/right click to show/toggle),\n' +
            'then close the plot window.')
        self.sp2 = pyl.subplot2grid((4, 4), (2, 1),
                                    colspan=3,
                                    sharex=self.sp1,
                                    rowspan=1)
        bins = np.arange(np.min(self.points[:, 0]),
                         np.max(self.points[:, 0]) + 0.5, 0.5)
        pyl.hist(self.points[:, 0], bins=bins)
        pyl.xlabel('FWHM (pix)')
        self.sp3 = pyl.subplot2grid((4, 4), (0, 0), rowspan=2, sharey=self.sp1)
        pyl.hist(self.points[:, 1], bins=30, orientation='horizontal')
        pyl.ylabel('RMS')
        self.sp4 = pyl.subplot2grid((4, 4), (2, 0), rowspan=2)

        self.moffPatchList = []
        self.showing = []
        self.selected_star = -1

        for j in range(len(self.moffs)):
            self.moffPatchList.append(self.sp4.plot(self.moffr, self.moffs[j]))
            self.showing.append(1)
        self.sp4.set_xlim(0, 30)
        self.sp4.set_ylim(0, 1.02)
        self.sp5 = pyl.subplot2grid((4, 4), (3, 1))
        self.sp5.set_aspect('equal')
        self.psfPlotLimits = [self.sp1.get_xlim(), self.sp1.get_ylim()]
        self.conn1 = self.sp1.callbacks.connect('ylim_changed', self.PSFrange)
        self.conn2 = pyl.connect('pick_event', self.ScatterPSF)
        self.conn3 = pyl.connect('key_press_event', self.ScatterPSF_keys)
        self.conn4 = pyl.connect('close_event', self.HandleClose)

        self.ScatterPSF(None)

        if not noVisualSelection:
            pyl.show()
        self._fwhm_lim = self.sp1.get_xlim()
        self._chi_lim = self.sp1.get_ylim()

        w = np.where((self.points[:, 0] > self._fwhm_lim[0])
                     & (self.points[:, 0] < self._fwhm_lim[1])
                     & (self.points[:, 1] > self._chi_lim[0])
                     & (self.points[:, 1] < self._chi_lim[1])
                     & (self.goodStars == True))
        pyl.clf()
        pyl.close()

        goodFits = self.points[w]
        goodMeds = np.median(goodFits[:4], axis=0)
        goodSTDs = np.std(goodFits[:4], axis=0)
        return (goodFits, goodMeds, goodSTDs)
Beispiel #18
0
    HDU = fits.PrimaryHDU(data, header)
    IHDU = fits.ImageHDU(bg)
    RHDU = fits.ImageHDU(rem)

    List = fits.HDUList([HDU, IHDU, RHDU])
    List.writeto(fitsFile.replace('.', '_bgr.'), overwrite=True)
    sys.exit()

    div = 50
    for i in range(0, B, B / div):

        f = np.median(data[:, i:i + B / div], axis=1)

        print poly(np.arange(len(f)) + 1.0, f, skip)
        continue
        sys.exit()
        #g = np.std(data[:,i:i+B/20],axis=1)*(B/20)**-0.5
        #print g/f
        #sys.exit()
        bgf = bgFinder.bgFinder(f)
        fraser = bgf.fraserMode()
        median = np.median(f)
        pyl.plot([0, len(f)], [fraser, fraser], 'r-')
        pyl.plot([0, len(f)], [median, median], 'k-')
        pyl.plot(f)
        #pyl.plot(f+g,'k--')
        #pyl.plot(f-g,'k--')
        pyl.title(i + B / 40)
        pyl.show()
Beispiel #19
0
    def fitWithModelPSF(self, x_in, y_in, m_in=-1., fitWidth=20,
                        nWalkers=20, nBurn=10, nStep=20,
                        bg=None, useErrorMap=False,
                        useLinePSF=False, verbose=False):
        """
        Using emcee (It's hammer time!) the provided image is fit using
        the provided psf to find the best x,y and amplitude, and confidence
        range on the fitted parameters.

        :param float x_in: initial guess on the x coordinate of the true centroid of the object
        :param float y_in: initial guess on the y coordinate of the true centroid of the object
        :param float m_in: initial guess on the true amplitude of the object
        :param float fitWidth: the width +- of x_in/y_in of the data used in the fit
        :param int nWalkers: The number of Goodman & Weare “walkers”. See :class:`emcee.EnsembleSampler`.
        :param int nBurn: The number of iterations to run the chain during burn-in.
                          See :class:`emcee.EnsembleSampler.run_mcmc`.
        :param int nStep: The number of iterations to run the chain in the production run.
                          See :class:`emcee.EnsembleSampler.run_mcmc`.
        :param bg: the background of the image. Needed for the uncertainty table.
                   **Defaults to None.**
                   When set to default, it will invoke the background measurement and apply that.
                   Otherwise, it assumes you are dealing with background subtracted data already.
        :param boolean useErrorMap: If true, a simple pixel uncertainty map is used in the fit.
                                    This is adopted as ue_ij=(imageData_ij+bg)**0.5, that is, the poisson noise estimate.
                                    Note the fit confidence range is only honest if useErrorMap=True.
        :param boolean useLinePSF: If True, use the TSF. If False, use the PSF
        :param boolean verbose: lots of information printed to screen
        """

        print("Initializing sampler")

        self.nForFitting = 0
        self.useLinePSF = useLinePSF

        if fitWidth > self.psf.boxSize:
            raise NotImplementedError('Need to keep the fitWidth <= boxSize.')

        (A, B) = self.imageData.shape
        ai = max(0, int(y_in) - fitWidth)
        bi = min(A, int(y_in) + fitWidth + 1)
        ci = max(0, int(x_in) - fitWidth)
        di = min(B, int(x_in) + fitWidth + 1)
        dat = num.copy(self.imageData)

        if bg == None:
            bgf = bgFinder.bgFinder(self.imageData)
            bg = bgf.smartBackground()
            dat -= bg

        if not useErrorMap:
            ue = dat * 0.0 + 1.
        else:
            ue = (dat + bg) ** 0.5

        if m_in == -1.:
            if useLinePSF:
                m_in = self.psf.repFact * self.psf.repFact * num.sum(dat) / num.sum(self.psf.longPSF)
            else:
                m_in = self.psf.repFact * self.psf.repFact * num.sum(dat) / num.sum(self.psf.fullPSF)

        nDim = 3
        r0 = []
        for ii in range(nWalkers):
            r0.append(num.array([x_in, y_in, m_in]) + sci.randn(3) * num.array([0.1, 0.1, m_in * 0.25]))
        r0 = num.array(r0)

        sampler = emcee.EnsembleSampler(nWalkers, nDim, lnprob,
                                        args=[dat, (ai, bi, ci, di), self.psf, ue, useLinePSF, verbose])
        print("Executing burn-in... this may take a while.")
        pos, prob, state = sampler.run_mcmc(r0, nBurn)
        sampler.reset()
        print("Executing production run... this will also take a while.")
        pos, prob, state = sampler.run_mcmc(pos, nStep, rstate0=state)
        self.samps = sampler.chain
        self.probs = sampler.lnprobability
        self.dat = num.copy(dat)
        self.fitted = True
Beispiel #20
0
    def test_gaussLike(self):
        data = array(range(0, 255), int)
        b = bgFinder(data)
        r = b._gaussLike([1.0, 2.0])

        self.assertAlmostEqual(679178.581857, r, places=1)
Beispiel #21
0
def sourceTrim(fn,snr_lim,doBright = True,doBinary = False, aperFWHMmulti = 1.0, medMagDiff = None):

    split = fn.split('-')[-1].split('.fits')[0]
    chip = int(float(split[:3]))

    if doBright :
        o = fn.replace('.fits','_bright_planted.coords')
        file = fn.replace('.fits','_bright_planted.fits')
    elif doBinary :
        o = fn.replace('.fits','_binary_planted.coords')
        file = fn.replace('.fits','_binary_planted.fits')
    else:
        o = fn.replace('.fits','_faint_planted.coords')
        file = fn.replace('.fits','_faint_planted.fits')

    with open(o) as han:
        d = han.readlines()
    if doBinary:
        planted = []
        for i in range(len(d)):
            s = d[i].split()
            (x,y,z,X,Y,Z) = (float(s[0]),float(s[1]),float(s[2]),float(s[3]),float(s[4]),float(s[5]))
            xg = (x*z+X*Z)/(z+Z)
            yg = (y*z+Y*Z)/(z+Z)
            planted.append([xg,yg,z+Z])
        planted = np.array(planted)
    else:
        planted = []
        for i in range(len(d)):
            s = d[i].split()
            planted.append([float(s[0]),float(s[1]),float(s[2])])
        planted = np.array(planted)

    mask_file = '/home/fraserw/idl_progs/hscp9/sextract/mask'+str(chip).zfill(3)+'.fits'


    runSex(file,file,chip,mask_file,svsPath = '',showProgress = False, verbose = False, includeImageMask = True,runSextractor=True)
    pcatalog = scamp.getCatalog(file.replace('.fits','.cat'),paramFile='sextract.param')

    with fits.open(file) as han:
        header = han[0].header
        data = han[1].data


    try:
        FWHM = header['FWHMplant']
    except:
        FWHM = header['fwhmRobust']
    apNum = apertures[round(FWHM*aperFWHMmulti)]


    w = np.where((pcatalog['FLUX_APER(5)'][:,0]>0) & (pcatalog['FLUX_APER(5)'][:,1]>0) &\
                  (pcatalog['FLUX_APER(5)'][:,2]>0) & (pcatalog['FLUX_APER(5)'][:,3]>0) &\
                  (pcatalog['FLUX_APER(5)'][:,4]>0) & (pcatalog['FLUX_AUTO']>0))
    for key in pcatalog:
        pcatalog[key] = pcatalog[key][w]

    psnr = pcatalog['FLUX_APER(5)'][:,apNum]/pcatalog['FLUXERR_APER(5)'][:,apNum]
    w = np.where((pcatalog['X_IMAGE']>50) & (pcatalog['X_IMAGE']<1995) & (pcatalog['Y_IMAGE']>50) & (pcatalog['Y_IMAGE']<4123) \
                 & (psnr>5) & (pcatalog['FWHM_IMAGE']>1.5))
    w1 = np.where((psnr[w]>=snr_lim[0])&(psnr[w]<snr_lim[1]))

    if doBinary:
        dist_max = 2.5
    else:
        dist_max = 1.5

    p = []
    planted_x,planted_y = [],[]
    for i in range(len(planted)):
        dist = ((planted[i,0]-pcatalog['X_IMAGE'][w][w1]+1)**2 + (planted[i,1]-pcatalog['Y_IMAGE'][w][w1]+1)**2)**0.5
        if np.min(dist)<dist_max:
            arg = np.argmin(dist)
            p.append(arg)
            planted_x.append(pcatalog['X_IMAGE'][w][w1][arg])
            planted_y.append(pcatalog['Y_IMAGE'][w][w1][arg])
        #else:
        #    print(i,planted[i],np.min(dist))
    p = np.array(p)
    planted_x = np.array(planted_x)
    planted_y = np.array(planted_y)
    print('Number of planted sources we are making use of:',len(p))

    pmag_aper = -2.5*np.log10(pcatalog['FLUX_APER(5)'][:,apNum][w][w1][p]/header['EXPTIME'])+header['MAGZERO']
    pmag_auto = -2.5*np.log10(pcatalog['FLUX_AUTO'][w][w1][p]/header['EXPTIME'])+header['MAGZERO']
    pmag_diff = pmag_auto - pmag_aper

    if doBright:
        bgf = bgFinder.bgFinder(pmag_diff)
        pmed_mag_diff = bgf.fraserMode(0.4)
        #pmed_mag_diff = getMeanMagDiff(pmag_aper,pmag_diff)
        #if np.isnan(pmed_mag_diff):
        #    pmed_mag_diff = getMeanMagDiff(pmag_aper,pmag_diff,returnMax = True)
    else:
        #use an input one from the planted single sources
        pmed_mag_diff = medMagDiff


    if not np.isnan(pmed_mag_diff):
        pmag_diff = pmag_auto-pmag_aper-pmed_mag_diff

    if doBright:
        plantedMedMagDiff = pmed_mag_diff





    catalog = scamp.getCatalog(fn.replace('.fits','.cat'),paramFile='sextract.param')

    with fits.open(fn) as han:
        header = han[0].header
        data = han[1].data
    (A,B) = data.shape



    w = np.where((catalog['FLUX_APER(5)'][:,0]>0) & (catalog['FLUX_APER(5)'][:,1]>0) &\
                  (catalog['FLUX_APER(5)'][:,2]>0) & (catalog['FLUX_APER(5)'][:,3]>0) &\
                  (catalog['FLUX_APER(5)'][:,4]>0) & (catalog['FLUX_AUTO']>0)&\
                  (catalog['X_IMAGE']>FWHM) & (catalog['X_IMAGE']<B-FWHM) & (catalog['Y_IMAGE']>FWHM) & (catalog['Y_IMAGE']<A-FWHM) )
    for key in catalog:
        catalog[key] = catalog[key][w]

    snr = catalog['FLUX_APER(5)'][:,apNum]/catalog['FLUXERR_APER(5)'][:,apNum]
    w = np.where((snr>5) & (catalog['FWHM_IMAGE']>1.5))
    w1 = np.where((snr[w]>snr_lim[0])&(snr[w]<snr_lim[1]))


    mag_aper = -2.5*np.log10(catalog['FLUX_APER(5)'][:,apNum][w][w1]/header['EXPTIME'])+header['MAGZERO']
    mag_auto = -2.5*np.log10(catalog['FLUX_AUTO'][w][w1]/header['EXPTIME'])+header['MAGZERO']

    if doBright:
        pyl.scatter(mag_auto,mag_auto-mag_aper)
        pyl.scatter(pmag_auto,pmag_auto-pmag_aper)
        pyl.show()
        exit()
    mag_diff = mag_auto-mag_aper-pmed_mag_diff

    if doBright:
        pred = np.ones(len(mag_diff))
        pred[np.where((mag_diff<snr_lim[2])| (mag_diff>np.max(mag_diff)))] = -1

    else:
        args = np.argsort(pmag_auto)
        x = pmag_auto[args]
        y = pmag_diff[args]


        bins = np.zeros(len(x))+abs(snr_lim[2])
        old_i = 0
        for i in range(len(x)):
            if bins[i]<y[i]:
                bins[old_i:] = y[i]
                old_i = i

        ww = np.where(bins==np.max(bins))



        #generate a quadratic function that encompasses the true sources
        b = (bins[ww[0][0]]+0.01+snr_lim_f[2])*((x[ww[0][0]]-np.min(x))**-2)
        X = np.linspace(np.min(mag_auto)-10,np.max(mag_auto)+10,200)
        Y = -snr_lim[2] + b*(X-np.min(x))**2
        ww = np.where(X<np.min(x))
        Y[ww] = -snr_lim[2]
        #now setup the lower limit function with the cutout to include binaries
        Yn=-Y
        ww = np.where(Yn>-0.5)
        Yn[ww]=-0.5


        f = interp.interp1d(X,Y)
        fneg = interp.interp1d(X,Yn)

        pred = -np.ones(len(mag_diff))
        for i in range(len(pred)):
            if mag_diff[i]<f(mag_auto[i]) and mag_diff[i]>(fneg(mag_auto[i])):
                pred[i]=1

    for k in catalog:
        catalog[k] = catalog[k][w][w1]

    if doBright:
        return (catalog,data,pred,mag_auto,mag_diff,pmag_auto,pmag_diff,p,apNum,plantedMedMagDiff)
    elif doBinary:
        return (catalog,data,pred,mag_auto,mag_diff,pmag_auto,pmag_diff,p,apNum)
    else:
        return (catalog,data,pred,mag_auto,mag_diff,pmag_auto,pmag_diff,p,f,fneg,apNum)
Beispiel #22
0
    def fitWithModelPSF(self,x_in,y_in,m_in=-1.,fitWidth=20,
                        nWalkers=20,nBurn=10,nStep=20,
                        bg=None,useErrorMap=False,
                        useLinePSF=False,verbose=False):

        """
        Using emcee (It's hammer time!) the provided image is fit using
        the provided psf to find the best x,y and amplitude, and confidence
        range on the fitted parameters.

        x_in, y_in, m_in - initial guesses on the true centroid and amplitude of the object
        fitWidth - the width +- of x_in/y_in of the data used in the fit
        nWalkers, nBurn, nStep - emcee fitting paramters. If you don't know what these are RTFM
        bg - the background of the image. Needed for the uncertainty table.
             **Defaults to None.** When set to default, it will invoke
             the background measurement and apply that. Otherwise, it assumes you are dealing with
             background subtracted data already.
        useErrorMap - if true, a simple pixel uncertainty map is used in the fit. This is adopted as
                      ue_ij=(imageData_ij+bg)**0.5, that is, the poisson noise estimate. Note the fit confidence range
                      is only honest if useErrorMap=True.
        useLinePSF - use the TSF? If not, use the PSF
        verbose - if set to true, lots of information printed to screen
        """

        print "Initializing sampler"

        self.nForFitting=0
        self.useLinePSF=useLinePSF

        if fitWidth>self.psf.boxSize:
            raise NotImplementedError('Need to keep the fitWidth <= boxSize.')

        (A,B)=self.imageData.shape
        ai=max(0,int(y_in)-fitWidth)
        bi=min(A,int(y_in)+fitWidth+1)
        ci=max(0,int(x_in)-fitWidth)
        di=min(B,int(x_in)+fitWidth+1)
        dat=num.copy(self.imageData)



        if bg==None:
            bgf=bgFinder.bgFinder(self.imageData)
            bg=bgf.smartBackground()
            dat-=bg

        if not useErrorMap:
            ue=dat*0.0+1.
        else:
            ue=(dat+bg)**0.5

        if m_in==-1.:
            if useLinePSF:
                m_in=self.psf.repFact*self.psf.repFact*num.sum(dat)/num.sum(self.psf.longPSF)
            else:
                m_in=self.psf.repFact*self.psf.repFact*num.sum(dat)/num.sum(self.psf.fullPSF)


        nDim=2
        r0=[]
        for ii in range(nWalkers):
            r0.append(num.array([x_in,y_in])+sci.randn(2)*num.array([0.1,0.1]))
        r0=num.array(r0)

        #fit first using input best guess amplitude
        sampler=emcee.EnsembleSampler(nWalkers,nDim,lnprob,args=[dat,(ai,bi,ci,di),self.psf,ue,useLinePSF,verbose,(-1,-1,m_in)])
        print "Executing xy burn-in... this may take a while."
        pos, prob, state=sampler.run_mcmc(r0, nBurn, 10)
        sampler.reset()
        print "Executing xy production run... this will also take a while."
        pos, prob, state = sampler.run_mcmc(pos, nStep, rstate0=state)
        self.samps=sampler.chain
        self.probs=sampler.lnprobability
        self.dat=num.copy(dat)
        self.fitted=True

        out = self.fitResults()
        (x,y,junk) = out[0]
        dx = (out[1][0][1] - out[1][0][0])/2.0
        dy = (out[1][1][1] - out[1][1][0])/2.0

        nDim = 1 # need to put two here rather than one because the fitresults code does a residual subtraction
        r0 = []
        for ii in range(nWalkers):
            r0.append(num.array([m_in]) + sci.randn(1) * num.array([m_in*0.25]))
        r0 = num.array(r0)


        #now fit the amplitude using the best-fit x,y from above
        #could probably cut the nBurn and nStep numbers down by a factor of 2
        sampler = emcee.EnsembleSampler(nWalkers, nDim, lnprob,
                                        args=[dat, (ai, bi, ci, di), self.psf, ue, useLinePSF, verbose, (x, y, -1)])
        print "Executing amplitude burn-in... this may take a while."
        pos, prob, state = sampler.run_mcmc(r0, max(nBurn/2,10))
        sampler.reset()
        print "Executing amplitude production run... this will also take a while."
        pos, prob, state = sampler.run_mcmc(pos, max(nStep/2,10), rstate0=state)
        self.samps = sampler.chain
        self.probs = sampler.lnprobability
        self.dat = num.copy(dat)
        self.fitted = True

        out = self.fitResults()
        amp = out[0][0]
        damp = (out[1][0][1]-out[1][0][0])/2.0


        #now do a full 3D fit using a small number of burn and steps.
        nDim=3
        r0=[]
        for ii in range(nWalkers):
            r0.append(num.array([x,y,amp])+sci.randn(3)*num.array([dx,dy,damp]))
        r0=num.array(r0)


        sampler=emcee.EnsembleSampler(nWalkers,nDim,lnprob,args=[dat,(ai,bi,ci,di),self.psf,ue,useLinePSF,verbose])
        print "Executing xy-amp burn-in... this may take a while."
        pos, prob, state=sampler.run_mcmc(r0,nBurn)
        sampler.reset()
        print "Executing xy-amp production run... this will also take a while."
        pos, prob, state = sampler.run_mcmc(pos, nStep, rstate0=state)
        self.samps=sampler.chain
        self.probs=sampler.lnprobability
        self.dat=num.copy(dat)
        self.fitted=True
Beispiel #23
0
    def setUpClass(self):

        self.rates = [0.4, 1.0, 2.5]
        self.angles = [37.0, 0.0, -58.7]
        self.EXPTIME = 360.0

        #os.system('gunzip test_image.fits.gz')

        self.gened_bg = 1000.0
        if not (os.path.isfile('test_image.fits')
                and os.path.isfile('planted_locations.pickle')):
            print('You may not have the necessary fits files for these tests.')
            print('Please execute the following two wget commands:')
            print(
                'wget https://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/files/vault/fraserw/test_psf.fits'
            )
            print(
                'wget https://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/files/vault/fraserw/test_image.fits'
            )
            print('')
            exit()

        with fits.open('test_image.fits') as han:
            self.image = han[0].data
        self.loadedPSF = psf.modelPSF(restore='test_psf.fits')

        with open('planted_locations.pickle', 'rb') as han:
            if sys.version_info[0] == 3:
                x = pickle.load(han, encoding='latin1')
            elif sys.version_info[0] == 2:
                x = pickle.load(han)

        self.planted_locations = np.array(x)

        self.bg = bgFinder.bgFinder(self.image)

        scamp.makeParFiles.writeConv()
        scamp.makeParFiles.writeParam()
        scamp.makeParFiles.writeSex('test.sex', minArea=2, threshold=2)

        scamp.runSex('test.sex', 'test_image.fits', verbose=True)
        self.catalog = scamp.getCatalog('def.cat', paramFile='def.param')

        os.remove('default.conv')
        os.remove('def.param')
        os.remove('test.sex')
        os.remove('def.cat')
        #os.system('gzip test_image.fits')

        starChooser = psfStarChooser.starChooser(self.image,
                                                 self.catalog['XWIN_IMAGE'],
                                                 self.catalog['YWIN_IMAGE'],
                                                 self.catalog['FLUX_AUTO'],
                                                 self.catalog['FLUXERR_AUTO'])
        (self.goodFits, self.goodMeds,
         self.goodSTDs) = starChooser(30,
                                      25,
                                      noVisualSelection=True,
                                      autoTrim=False,
                                      quickFit=False,
                                      repFact=5)
        (self.goodFitsQF, self.goodMedsQF,
         self.goodSTDsQF) = starChooser(30,
                                        25,
                                        noVisualSelection=True,
                                        autoTrim=False,
                                        quickFit=True,
                                        repFact=5)

        #using manual alpha and beta because the fitting done with the star chooser results in
        #different answers with the different versions of scipy
        ALPHA = 29.81210639392963
        BETA = 19.32497948470224

        self.goodPSF = psf.modelPSF(np.arange(51),
                                    np.arange(51),
                                    alpha=ALPHA,
                                    beta=BETA,
                                    repFact=10)
        #self.goodPSF = psf.modelPSF(np.arange(51),np.arange(51), alpha=self.goodMeds[2],beta=self.goodMeds[3],repFact=10)
        self.goodPSF.genLookupTable(self.image,
                                    self.goodFits[:, 4],
                                    self.goodFits[:, 5],
                                    verbose=False)
        self.goodPSF.line(self.rates[0],
                          self.angles[0],
                          self.EXPTIME / 3600.,
                          pixScale=0.185,
                          useLookupTable=True)
        #self.goodPSF.psfStore('test_psf.fits')

        self.pill = pill.pillPhot(self.image)
        rads = np.arange(5.0, 25.0, 5)
        x_test, y_test = 652.4552577047876, 101.62067493726078  #necessray to use custom coordinates to avoid errors due to different sextractor versions
        self.pill.computeRoundAperCorrFromSource(x_test,
                                                 y_test,
                                                 rads,
                                                 width=60.0,
                                                 skyRadius=50.0,
                                                 display=False,
                                                 displayAperture=False)

        self.pill(x_test,
                  y_test,
                  7.0,
                  l=5.0,
                  display=False,
                  enableBGSelection=False)
        self.pill.SNR(verbose=True)

        self.distances = {}
        self.distances[26] = 0.2913793325
        self.distances[16] = 0.5179553032
        self.distances[7] = 0.1751143336
        self.distances[0] = 0.7428739071
        self.distances[23] = 0.3347620368
        self.distances[18] = 0.7867022753
        self.distances[14] = 0.1851933748
        self.distances[5] = 0.4436303377
        self.distances[28] = 0.3333371580
        self.distances[9] = 0.1997155696
        self.distances[29] = 0.3528487086
        self.distances[22] = 0.4013085365
        self.distances[19] = 0.5801378489
        self.distances[17] = 0.6873673797
        self.distances[1] = 0.1621235311
        self.distances[6] = 0.1248580739
        self.distances[13] = 2.0296137333
        self.distances[24] = 1.3238428831
        self.distances[3] = 0.7816261053
        self.distances[25] = 0.3067137897
        self.distances[6] = 0.8099660873