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
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)
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
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)