def _fit_simple_lm(self, obs, model, guesser): from ngmix.fitting import LMSimple max_pars = self['max_pars'] prior = self['search_prior'] #if obs.has_psf(): # print("psf _data:",obs.psf.gmix._data) # print("psf copy _data:",obs.psf.gmix.copy()._data) fitter = LMSimple(obs, model, prior=prior, use_logpars=self['use_logpars'], lm_pars=max_pars['lm_pars']) for i in xrange(max_pars['ntry']): guess = guesser(prior=prior) print_pars(guess, front=' lm_guess: ') fitter.run_max(guess) res = fitter.get_result() if res['flags'] == 0: break return fitter
def _fit_simple_lm(self, mb_obs_list, model, params, use_prior=True): """ Fit one of the "simple" models, e.g. exp or dev use flat g prior """ from ngmix.fitting import LMSimple if use_prior: prior=self['model_pars'][model]['gflat_prior'] else: prior=None ok=False ntry=params['lm_ntry'] for i in xrange(ntry): guess=self.guesser(prior=prior) fitter=LMSimple(mb_obs_list, model, prior=prior, lm_pars=params['lm_pars']) fitter.run_lm(guess) res=fitter.get_result() if res['flags']==0: ok=True break res['ntry']=i+1 return fitter
def _fit_simple_lm(self, obs, model, guesser): from ngmix.fitting import LMSimple max_pars=self['max_pars'] prior=self['search_prior'] #if obs.has_psf(): # print("psf _data:",obs.psf.gmix._data) # print("psf copy _data:",obs.psf.gmix.copy()._data) fitter=LMSimple(obs, model, prior=prior, use_logpars=self['use_logpars'], lm_pars=max_pars['lm_pars']) for i in xrange(max_pars['ntry']): guess=guesser(prior=prior) print_pars(guess,front=' lm_guess: ') fitter.run_max(guess) res=fitter.get_result() if res['flags']==0: break return fitter
def go(self, ntry=1): from ngmix.fitting import LMSimple for i in xrange(ntry): guess=self.get_guess() fitter=LMSimple(self.obs,self.model,lm_pars=self.lm_pars) fitter.go(guess) res=fitter.get_result() if res['flags']==0: break self.fitter=fitter
def go(self, ntry=1): from ngmix.fitting import LMSimple for i in xrange(ntry): guess = self.get_guess() fitter = LMSimple(self.obs, self.model, lm_pars=self.lm_pars) fitter.go(guess) res = fitter.get_result() if res['flags'] == 0: break self.fitter = fitter
def _go_lm(self, ntry=1): from ngmix.fitting import LMSimple for i in xrange(ntry): guess=self.guesser() fitter=LMSimple(self.obs, self.model, lm_pars=self.send_pars, use_logpars=self.use_logpars, prior=self.prior) fitter.go(guess) res=fitter.get_result() if res['flags']==0: break self.fitter=fitter
def _run_ml_fitter(mbobs, rng): # fit the PSF _fit_psf(mbobs[0][0].psf) # overall flags, or'ed from each moments fit res = {'mcal_flags': 0} try: fitter = LMSimple(mbobs[0][0], 'exp') fitter.go(np.array([0, 0, 0, 0, 1, 10])) fres = fitter.get_result() except Exception as err: print('err:', err) fres = {'flags': np.ones(1, dtype=[('flags', 'i4')])} res['mcal_flags'] |= fres['flags'] if not res['mcal_flags']: res['g'] = fres['g'] return res
def _go_lm(self, ntry=1): from ngmix.fitting import LMSimple for i in xrange(ntry): guess = self.guesser() fitter = LMSimple(self.obs, self.model, lm_pars=self.send_pars, use_logpars=self.use_logpars, prior=self.prior) fitter.go(guess) res = fitter.get_result() if res['flags'] == 0: break self.fitter = fitter
def _fit_simple_lm(self, mb_obs_list, model, max_pars, prior): """ Fit one of the "simple" models, e.g. exp or dev use flat g prior """ from ngmix.fitting import LMSimple ntry=max_pars['ntry'] for i in xrange(ntry): guess=self.guesser(prior=prior) # catch case where guess is just no good... try: fitter=LMSimple(mb_obs_list, model, prior=prior, lm_pars=max_pars['lm_pars']) fitter.go(guess) res=fitter.get_result() if res['flags']==0: break except GMixRangeError: # probably bad guesser print(" caught gmix range, using psf guesser") self.guesser=self._get_guesser_from_me_psf() res={'flags': GAL_FIT_FAILURE} fitter=None if res['flags']==0 and max_pars['replace_cov']: self._try_replace_cov(fitter) res['ntry']=i+1 return fitter
def _fit_psf_max(self, obs): from ngmix.fitting import MaxSimple, LMSimple assert self['psf_model'] in ["turb", "gauss"], "gauss,turb only for now" max_pars = self['psf_max_pars'] if self['psf_method'] == 'Nelder-Mead': fitter = MaxSimple(obs, self['psf_model'], method=self['psf_method']) else: fitter = LMSimple(obs, self['psf_model'], lm_pars=max_pars) Tguess = 2 * self['psf_sigma_guess']**2 Fguess = obs.image.sum() guess0 = array([0.0, 0.0, 0.0, 0.0, Tguess, Fguess]) for i in xrange(self['psf_ntry']): guess = guess0.copy() guess[0:0 + 2] += 0.01 * srandu(2) guess[2:2 + 2] += 0.1 * srandu(2) guess[4] *= (1.0 + 0.1 * srandu()) guess[5] *= (1.0 + 0.1 * srandu()) print_pars(guess, front=' guess: ') if self['psf_method'] == 'lm': fitter.run_max(guess) else: fitter.run_max(guess, **max_pars) res = fitter.get_result() if res['flags'] == 0: print(" max_nfev:", res['nfev']) break return fitter
def test_ml_fitting_exp_obj_gauss_psf_smoke(g1_true, g2_true, wcs_g1, wcs_g2): rng = np.random.RandomState(seed=10) image_size = 33 cen = (image_size - 1) / 2 gs_wcs = galsim.ShearWCS(0.25, galsim.Shear(g1=wcs_g1, g2=wcs_g2)).jacobian() scale = np.sqrt(gs_wcs.pixelArea()) g_prior = ngmix.priors.GPriorBA(0.1) cen_prior = ngmix.priors.CenPrior(0, 0, scale, scale) T_prior = ngmix.priors.FlatPrior(0.01, 2) F_prior = ngmix.priors.FlatPrior(1e-4, 1e9) prior = ngmix.joint_prior.PriorSimpleSep(cen_prior, g_prior, T_prior, F_prior) gal = galsim.Exponential(half_light_radius=0.5).shear( g1=g1_true, g2=g2_true).withFlux(400) obj = galsim.Convolve([gal, galsim.Gaussian(fwhm=0.5)]) psf_im = galsim.Gaussian(fwhm=0.5).drawImage(nx=33, ny=33, wcs=gs_wcs, method='no_pixel').array psf_gmix = ngmix.gmix.make_gmix_model( [0, 0, 0, 0, fwhm_to_T(0.5), 1], "gauss") psf_obs = Observation(image=psf_im, gmix=psf_gmix) im = obj.drawImage(nx=image_size, ny=image_size, wcs=gs_wcs, method='no_pixel').array noise = np.sqrt(np.sum(im**2)) / 1e16 wgt = np.ones_like(im) / noise**2 guess = np.ones(6) * 0.1 guess[0] = 0 guess[1] = 0 guess[2] = g1_true guess[3] = g2_true guess[4] = fwhm_to_T(0.5) guess[5] = 400 g1arr = [] g2arr = [] farr = [] xarr = [] yarr = [] for _ in range(50): shift = rng.uniform(low=-scale / 2, high=scale / 2, size=2) xy = gs_wcs.toImage(galsim.PositionD(shift)) im = obj.shift(dx=shift[0], dy=shift[1]).drawImage(nx=image_size, ny=image_size, wcs=gs_wcs, method='no_pixel', dtype=np.float64).array jac = Jacobian(y=cen + xy.y, x=cen + xy.x, dudx=gs_wcs.dudx, dudy=gs_wcs.dudy, dvdx=gs_wcs.dvdx, dvdy=gs_wcs.dvdy) _im = im + (rng.normal(size=im.shape) * noise) obs = Observation(image=_im, weight=wgt, jacobian=jac, psf=psf_obs) fitter = LMSimple(obs, 'exp', prior=prior) fitter.go(guess + rng.normal(size=6) * 0.01) res = fitter.get_result() if res['flags'] == 0: _g1, _g2, _ = res['g'][0], res['g'][1], res['pars'][4] g1arr.append(_g1) g2arr.append(_g2) farr.append(res['pars'][5]) xarr.append(res['pars'][1]) yarr.append(res['pars'][0]) g1 = np.mean(g1arr) g2 = np.mean(g2arr) gtol = 1e-5 assert np.abs(g1 - g1_true) < gtol assert np.abs(g2 - g2_true) < gtol xerr = np.std(xarr) / np.sqrt(len(xarr)) assert np.abs(np.mean(xarr)) < xerr * 5 yerr = np.std(yarr) / np.sqrt(len(yarr)) assert np.abs(np.mean(yarr)) < yerr * 5
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)
def _fit_smooth_model(self): dxy = 256 ny = 4096 // dxy + 1 nx = 2048 // dxy + 1 xloc = np.empty((ny, nx), dtype=np.float64) yloc = np.empty((ny, nx), dtype=np.float64) pars = np.empty((ny, nx, 3), dtype=np.float64) for yi, yl in enumerate(np.linspace(1, 4096, ny)): for xi, xl in enumerate(np.linspace(1, 2048, nx)): rng = np.random.RandomState(seed=yi + nx * xi) xloc[yi, xi] = xl yloc[yi, xi] = yl pos = galsim.PositionD(x=xl, y=yl) img = self._draw(pos).drawImage( nx=19, ny=19, scale=0.25, method='sb').array nse = np.std( np.concatenate([img[0, :], img[-1, :]])) obs = ngmix.Observation( image=img, weight=np.ones_like(img)/nse**2, jacobian=ngmix.jacobian.DiagonalJacobian( x=9, y=9, scale=0.25)) _g1 = np.nan _g2 = np.nan _T = np.nan for _ in range(5): try: am = Admom(obs, rng=rng) am.go(0.3) res = am.get_result() if res['flags'] != 0: continue lm = LMSimple(obs, 'turb') lm.go(res['pars']) lm_res = lm.get_result() if lm_res['flags'] == 0: _g1 = lm_res['pars'][2] _g2 = lm_res['pars'][3] _T = lm_res['pars'][4] break except ngmix.gexceptions.GMixRangeError: pass pars[yi, xi, 0] = _g1 pars[yi, xi, 1] = _g2 pars[yi, xi, 2] = _T xloc = xloc.ravel() yloc = yloc.ravel() pos = np.stack([xloc, yloc], axis=1) assert pos.shape == (xloc.shape[0], 2) # make interps g1 = pars[:, :, 0].ravel() msk = np.isfinite(g1) if len(msk) < 10: raise ValueError('DES Piff fitting failed too much!') if np.any(~msk): g1[~msk] = np.mean(g1[msk]) self._g1int = CloughTocher2DInterpolator(pos, g1) g2 = pars[:, :, 1].ravel() msk = np.isfinite(g2) if len(msk) < 10: raise ValueError('DES Piff fitting failed too much!') if np.any(~msk): g2[~msk] = np.mean(g2[msk]) self._g2int = CloughTocher2DInterpolator(pos, g2) T = pars[:, :, 2].ravel() msk = np.isfinite(T) if len(msk) < 10: raise ValueError('DES Piff fitting failed too much!') if np.any(~msk): T[~msk] = np.mean(T[msk]) self._Tint = CloughTocher2DInterpolator(pos, T) self._did_fit = True
def test_ml_fitting_gauss_smoke(g1_true, g2_true, wcs_g1, wcs_g2): rng = np.random.RandomState(seed=42) # allow some small relative bias due to approximate exp function tol = 1.0e-5 image_size = 33 cen = (image_size - 1) / 2 gs_wcs = galsim.ShearWCS(0.25, galsim.Shear(g1=wcs_g1, g2=wcs_g2)).jacobian() scale = np.sqrt(gs_wcs.pixelArea()) g_prior = ngmix.priors.GPriorBA(0.2) cen_prior = ngmix.priors.CenPrior(0, 0, scale, scale) T_prior = ngmix.priors.FlatPrior(0.1, 2) F_prior = ngmix.priors.FlatPrior(1e-4, 1e9) prior = ngmix.joint_prior.PriorSimpleSep(cen_prior, g_prior, T_prior, F_prior) obj = galsim.Gaussian(fwhm=0.9).shear(g1=g1_true, g2=g2_true).withFlux(400) im = obj.drawImage(nx=image_size, ny=image_size, wcs=gs_wcs, method='no_pixel').array noise = np.sqrt(np.sum(im**2)) / 1e16 wgt = np.ones_like(im) / noise**2 g1arr = [] g2arr = [] Tarr = [] farr = [] xarr = [] yarr = [] for _ in range(100): shift = rng.uniform(low=-scale / 2, high=scale / 2, size=2) xy = gs_wcs.toImage(galsim.PositionD(shift)) im = obj.shift(dx=shift[0], dy=shift[1]).drawImage(nx=image_size, ny=image_size, wcs=gs_wcs, method='no_pixel', dtype=np.float64).array jac = Jacobian(y=cen + xy.y, x=cen + xy.x, dudx=gs_wcs.dudx, dudy=gs_wcs.dudy, dvdx=gs_wcs.dvdx, dvdy=gs_wcs.dvdy) _im = im + (rng.normal(size=im.shape) * noise) obs = Observation(image=_im, weight=wgt, jacobian=jac) fitter = LMSimple(obs, 'gauss', prior=prior) guess = np.ones(6) * 0.1 guess[0] = 0 guess[1] = 0 guess[2] = g1_true guess[3] = g2_true guess[4] = fwhm_to_T(0.9) guess[5] = 400 * scale * scale fitter.go(guess + rng.normal(size=6) * 0.01) res = fitter.get_result() if res['flags'] == 0: _g1, _g2, _T = res['g'][0], res['g'][1], res['pars'][4] g1arr.append(_g1) g2arr.append(_g2) Tarr.append(_T) farr.append(res['pars'][5]) xarr.append(res['pars'][1]) yarr.append(res['pars'][0]) g1 = np.mean(g1arr) g2 = np.mean(g2arr) assert np.abs(g1 - g1_true) < tol assert np.abs(g2 - g2_true) < tol if g1_true == 0 and g2_true == 0: T = np.mean(Tarr) Ttrue = fwhm_to_T(0.9) assert T / Ttrue - 1 < tol fmn = np.mean(farr) / scale / scale assert np.abs(fmn / 400 - 1) < tol xerr = np.std(xarr) / np.sqrt(len(xarr)) assert np.abs(np.mean(xarr)) < xerr * 5 yerr = np.std(yarr) / np.sqrt(len(yarr)) assert np.abs(np.mean(yarr)) < yerr * 5