Beispiel #1
0
    def _get_mof_obs(self):
        im, psf_im, coords, dims, dx1, dy1, noises = self.sim()

        bg_rms = self.sim['Image']['Bgrms'] / np.sqrt(len(im))
        bg_rms_psf = self.sim['Psf']['Bgrms_psf']

        psf_ccen = (np.array(psf_im.shape) - 1.0) / 2.0
        psf_jacob = ngmix.UnitJacobian(
            row=psf_ccen[0],
            col=psf_ccen[1],
        )
        psf_weight = psf_im * 0 + 1.0 / bg_rms_psf**2
        psf_obs = ngmix.Observation(
            psf_im,
            weight=psf_weight,
            jacobian=psf_jacob,
        )

        psf_gmix = self._fit_psf_admom(psf_obs)
        psf_obs.set_gmix(psf_gmix)

        mb = MultiBandObsList()
        for i in range(len(im)):
            if self.show:
                import images
                tim = im[i] / im[i].max()
                tim = np.log10(tim - tim.min() + 1.0)

                images.view(tim)
                if 'q' == input('hit a key: (q to quit) '):
                    stop

            weight = im[i] * 0 + 1.0 / bg_rms**2
            jacobian = ngmix.UnitJacobian(
                row=0,
                col=0,
            )

            obs = ngmix.Observation(
                im[i],
                weight=weight,
                jacobian=jacobian,
                psf=psf_obs,
            )
            obs.noise = noises[i]
            olist = ObsList()
            olist.append(obs)
            mb.append(olist)

        return mb, coords
def observation(image,sigma,row,col,psf_sigma,psf_im):
    # sigma is the standard deviation of the noise
    weight = image*0 + 1.0/sigma**2
    # row,col are the center of the object in the model
    # image, so we need to figure that out somehow
    jacob = ngmix.UnitJacobian(row=row, col=col)
    psf_weight = psf_im*0 + 1.0/psf_sigma**2
    # psf should be centered
    cen = [(np.array(psf_im.shape[0]) - 1.0)/2.0,(np.array(psf_im.shape[1]) - 1.0)/2.0]
    psf_jacob = ngmix.UnitJacobian(row=cen[0], col=cen[1])
    psf_obs = ngmix.Observation(psf_im, weight=psf_weight, jacobian=psf_jacob)
    obs = ngmix.Observation(image,weight=weight,jacobian=jacob,psf=psf_obs)

    return obs
    def _get_mof_obs(self):
        im, psf_im, coords, dims, dx1, dy1, noise, sep_coords = self.sim()
        #import images
        #images.view(im)
        #if 'q'==input('hit a key'):
        #    stop

        bg_rms = self.sim['Image']['Bgrms']
        bg_rms_psf = self.sim['Psf']['Bgrms_psf']

        psf_ccen = (np.array(psf_im.shape) - 1.0) / 2.0
        psf_jacob = ngmix.UnitJacobian(
            row=psf_ccen[0],
            col=psf_ccen[1],
        )
        psf_weight = psf_im * 0 + 1.0 / bg_rms_psf**2
        psf_obs = ngmix.Observation(
            psf_im,
            weight=psf_weight,
            jacobian=psf_jacob,
        )

        psf_gmix = self._fit_psf_admom(psf_obs)
        psf_obs.set_gmix(psf_gmix)

        weight = im * 0 + 1.0 / bg_rms**2
        jacobian = ngmix.UnitJacobian(
            row=0,
            col=0,
        )

        obs = ngmix.Observation(
            im,
            weight=weight,
            jacobian=jacobian,
            psf=psf_obs,
        )
        obs.noise = noise

        return obs, sep_coords, dims
Beispiel #4
0
    def measure(self, measRecord, exposure):
        if exposure.getPsf() is None:
            raise MeasurementError(
                self.flagHandler.getDefinition(SingleFrameEmPsfApproxPlugin.ErrEnum.flag_noPsf).doc,
                SingleFrameEmPsfApproxPlugin.ErrEnum.flag_noPsf)
        psfArray = exposure.getPsf().computeKernelImage().getArray()
        psfObs = ngmix.observation.Observation(psfArray,
            jacobian=ngmix.UnitJacobian(row=(psfArray.shape[0]-1)/2, col=(psfArray.shape[1]-1)/2))

        #  Need a guess at the sum of the diagonal moments
        nGauss = self.config.nGauss
        shape = exposure.getPsf().computeShape()
        Tguess = shape.getIxx() + shape.getIyy()
        emPars = {'maxiter': self.config.maxIters, 'tol': self.config.tolerance}

        runner = EMRunner(psfObs, Tguess, nGauss, emPars)
        runner.go(ntry=self.config.nTries)
        fitter = runner.get_fitter()
        res = fitter.get_result()

        #   Set the results, including the fit info returned by EMRunner
        measRecord.set(self.iterKey, res['numiter'])
        measRecord.set(self.fdiffKey, res['fdiff'])

        #   We only know about two EM errors.  Anything else is thrown as "unknown".
        if res['flags'] != 0:
            if res['flags'] & EM_RANGE_ERROR:
                raise MeasurementError(
                    self.flagHandler.getDefinition(SingleFrameEmPsfApproxPlugin.ErrEnum.flag_rangeError).doc,
                    SingleFrameEmPsfApproxPlugin.ErrEnum.flag_rangeError)
            if res['flags'] & EM_MAXITER:
                raise MeasurementError(
                    self.flagHandler.getDefinition(SingleFrameEmPsfApproxPlugin.ErrEnum.flag_maxIters).doc,
                    SingleFrameEmPsfApproxPlugin.ErrEnum.flag_maxIters)
            raise RuntimeError("Unknown EM fitter exception")

        #   Convert the nGauss Gaussians to ShapeletFunction's.  Zeroth order HERMITES are Gaussians.
        #   There are always 6 parameters for each Gaussian.
        psf_pars = fitter.get_gmix().get_full_pars()
        #  Gaussian pars are 6 numbers long.  Pick the results off one at a time
        for i in range(self.config.nGauss):
            flux, y, x, iyy, ixy, ixx = psf_pars[i*self.gaussian_pars_len: (i+1)*self.gaussian_pars_len]
            quad = lsst.afw.geom.ellipses.Quadrupole(ixx, iyy, ixy)
            ellipse = lsst.afw.geom.ellipses.Ellipse(quad, lsst.afw.geom.Point2D(x, y))
            # create a 0th order (gaussian) shapelet function.
            sf = lsst.shapelet.ShapeletFunction(0, lsst.shapelet.HERMITE, ellipse)
            sf.getCoefficients()[0] = flux/lsst.shapelet.ShapeletFunction.FLUX_FACTOR
            measRecord.set(self.keys[i], sf)
Beispiel #5
0
    def _measure_moments(self, gs_kimage, weight):
        import ngmix

        if self._deweight:
            raise NotImplementedError("no dweight yet for gauss moms")

        dk = gs_kimage.scale
        dk2 = dk**2
        dk4 = dk**4

        kwt, cen, dims = self._get_weight_object(gs_kimage)

        jacob = ngmix.UnitJacobian(
            row=cen[0],
            col=cen[1],
        )

        medwt = numpy.median(weight)
        dim = weight.shape[0]
        #noise_factor=self._get_noise_factor(dim)
        noise_factor = dim
        weight_factor = 1.0 / noise_factor**2

        kivar = zeros(gs_kimage.array.shape) + medwt * weight_factor

        kobs = ngmix.Observation(
            gs_kimage.array,
            weight=kivar,
            jacobian=jacob,
        )

        res = kwt.get_weighted_moments(kobs)

        # put onto a common scale
        if res['flags'] == 0:
            res['pars'][0:0 + 2] *= dk
            res['pars'][2:2 + 3] *= dk2

            res['pars_cov'][0:0 + 2, 0:0 + 2] *= dk2
            res['pars_cov'][2:2 + 2, 2:2 + 2] *= dk4

        return res
Beispiel #6
0
    def measure(self, measRecord, exposure):
        psf = exposure.getPsf()
        if psf is None:
            raise MeasurementError(
                self.flagHandler.getDefinition(
                    SingleFrameLMSimpleShapePlugin.ErrEnum.flag_noPsf).doc,
                SingleFrameLMSimpleShapePlugin.ErrEnum.flag_noPsf)
        # make an observation for the psf image
        psfArray = psf.computeKernelImage().getArray()
        psfJacob = ngmix.UnitJacobian(row=psfArray.shape[0] / 2.0,
                                      col=psfArray.shape[1] / 2.0)
        psfObs = Observation(psfArray, jacobian=psfJacob)

        #   Fallback code if no psf algorithm is requested.  Then just do an LM single gaussian fit
        if self.config.psfName is None:
            pfitter = LMSimple(psfObs, 'gauss')
            #   gues parameters for a simple Gaussian
            psfPars = [0.0, 0.0, -0.03, 0.02, 8.0, 1.0]
            pfitter.go(psfPars)
            psfGMix = pfitter.get_gmix()
        else:
            shape = psfArray.shape
            image = lsst.afw.image.ImageD(shape[1], shape[0])
            evaluate = measRecord.get(self.psfMsfKey).evaluate()
            evaluate.addToImage(
                image.getArray(),
                lsst.afw.geom.Point2I(-(shape[0] - 1) // 2,
                                      -(shape[1] - 1) // 2))
            psfObs = Observation(image.getArray(), jacobian=psfJacob)
            #   Now create a gmix directly from what the PsfApprox algorithm produced
            multiShapeletFunction = measRecord.get(self.psfMsfKey)
            shapeletFunctions = multiShapeletFunction.getComponents()
            psfPars = []
            #   add pars in the order flux, y, x, yy, xy, xx
            for sf in shapeletFunctions:
                psfPars.append(sf.getCoefficients()[0])
                psfPars.append(sf.getEllipse().getCenter().getY())
                psfPars.append(sf.getEllipse().getCenter().getX())
                psfPars.append(sf.getEllipse().getCore().getIyy())
                psfPars.append(sf.getEllipse().getCore().getIxy())
                psfPars.append(sf.getEllipse().getCore().getIxx())
            psfGMix = ngmix.gmix.GMix(len(shapeletFunctions), psfPars)
        psfObs.set_gmix(psfGMix)

        #   Now create an obs for the galaxy itself, including the weight plane
        galArray = exposure.getMaskedImage().getImage().getArray()
        galShape = galArray.shape
        galJacob = ngmix.UnitJacobian(row=galShape[1] / 2.0,
                                      col=galShape[0] / 2.0)
        variance = exposure.getMaskedImage().getVariance().getArray()
        gal_weight = 1 / variance
        obs = Observation(galArray,
                          weight=gal_weight,
                          jacobian=galJacob,
                          psf=psfObs)

        fp = measRecord.getFootprint()

        bbox = fp.getBBox()
        ymin = bbox.getBeginY() - exposure.getXY0().getY()
        ymax = bbox.getEndY() - exposure.getXY0().getY()
        xmin = bbox.getBeginX() - exposure.getXY0().getX()
        xmax = bbox.getEndX() - exposure.getXY0().getX()
        flux = exposure.getMaskedImage().getImage().getArray()[
            ymin:ymax, xmin:xmax].sum()

        xx = fp.getShape().getIxx()
        yy = fp.getShape().getIyy()
        xy = fp.getShape().getIxy()

        #   Now run the shape algorithm, using the config parameters
        lmPars = {
            'maxfev': self.config.maxfev,
            'ftol': self.config.ftol,
            'xtol': self.config.xtol
        }
        maxPars = {'method': 'lm', 'lm_pars': lmPars}
        guesser = ngmix.guessers.TFluxGuesser(xx + yy, flux)
        runner = ngmix.bootstrap.MaxRunner(obs, self.config.model, maxPars,
                                           guesser)
        runner.go(ntry=4)
        fitter = runner.fitter
        res = fitter.get_result()

        #   Set the results, including the fit info returned by MaxRunner
        if res['flags'] != 0:
            if res['flags'] & LM_SINGULAR_MATRIX:
                raise MeasurementError(
                    self.flagHandler.getDefinition(
                        SingleFrameLMSimpleShapePlugin.ErrEnum.
                        flag_singularMatrix).doc,
                    SingleFrameLMSimpleShapePlugin.ErrEnum.flag_singularMatrix)
            if res['flags'] & LM_NEG_COV_EIG:
                raise MeasurementError(
                    self.flagHandler.getDefinition(
                        SingleFrameLMSimpleShapePlugin.ErrEnum.
                        flag_negativeCovEig).doc,
                    SingleFrameLMSimpleShapePlugin.ErrEnum.flag_negativeCovEig)
            if res['flags'] & LM_NEG_COV_DIAG:
                raise MeasurementError(
                    self.flagHandler.getDefinition(
                        SingleFrameLMSimpleShapePlugin.ErrEnum.
                        flag_negativeCovDiag).doc,
                    SingleFrameLMSimpleShapePlugin.ErrEnum.flag_negativeCovDiag
                )
            if res['flags'] & EIG_NOTFINITE:
                raise MeasurementError(
                    self.flagHandler.getDefinition(
                        SingleFrameLMSimpleShapePlugin.ErrEnum.
                        flag_eigNotFinite).doc,
                    SingleFrameLMSimpleShapePlugin.ErrEnum.flag_eigNotFinite)
            if res['flags'] & LM_FUNC_NOTFINITE:
                raise MeasurementError(
                    self.flagHandler.getDefinition(
                        SingleFrameLMSimpleShapePlugin.ErrEnum.
                        flag_funcNotFinite).doc,
                    SingleFrameLMSimpleShapePlugin.ErrEnum.flag_funcNotFinite)
            if res['flags'] & DIV_ZERO:
                raise MeasurementError(
                    self.flagHandler.getDefinition(
                        SingleFrameLMSimpleShapePlugin.ErrEnum.flag_divZero).
                    doc, SingleFrameLMSimpleShapePlugin.ErrEnum.flag_divZero)
            if res['nfev'] >= self.config.maxfev:
                raise MeasurementError(
                    self.flagHandler.getDefinition(
                        SingleFrameLMSimpleShapePlugin.ErrEnum.flag_maxFev).
                    doc, SingleFrameLMSimpleShapePlugin.ErrEnum.flag_maxFev)
            #   Unknown error, but there should be an errmsg set by ngmix
            raise RuntimeError(res['errmsg'])

        #   Convert the nGauss Gaussians to ShapeletFunction's. Zeroth order HERMITES are Gaussians.
        #   There are always 6 parameters for each Gaussian.
        galGMix = fitter.get_gmix()
        galPars = galGMix.get_full_pars()

        # convert the center in row,col coordinates to pixel coordinates and save
        cen = galGMix.get_cen()
        measRecord.set(self.xKey, cen[1] + galShape[1] / 2.0)
        measRecord.set(self.yKey, cen[0] + galShape[0] / 2.0)
        # save the model flux
        measRecord.set(self.fluxKey, galGMix.get_flux())
        # save the model T=xx+yy, e1, and e2
        (e1, e2, T) = galGMix.get_e1e2T()
        measRecord.set(self.e1Key, e1)
        measRecord.set(self.e2Key, e2)
        measRecord.set(self.TKey, T)
        for i in range(self.nGauss):
            flux, y, x, iyy, ixy, ixx = galPars[i *
                                                self._gaussian_pars_len:(i +
                                                                         1) *
                                                self._gaussian_pars_len]
            quad = lsst.afw.geom.ellipses.Quadrupole(ixx, iyy, ixy)
            ellipse = lsst.afw.geom.ellipses.Ellipse(
                quad, lsst.afw.geom.Point2D(x, y))
            # create a 0th order (gaussian) shapelet function.
            sf = ShapeletFunction(0, HERMITE, ellipse)
            sf.getCoefficients()[0] = flux / ShapeletFunction.FLUX_FACTOR
            measRecord.set(self.keys[i], sf)