23 __all__ = [
"InstallGaussianPsfConfig", 
"InstallGaussianPsfTask"]
 
   27 import lsst.pex.config 
as pexConfig
 
   31 FwhmPerSigma = 2.0*math.sqrt(2.0*math.log(2.0))
 
   35     """!Config for InstallGaussianPsfTask""" 
   36     fwhm = pexConfig.Field(
 
   38         default=1.5 * FwhmPerSigma,
 
   39         doc=
"Estimated FWHM of simple Gaussian PSF model, in pixels. " 
   40         "Ignored if input exposure has a PSF model." 
   42     width = pexConfig.RangeField(
 
   44         doc=
"Width and height of PSF model, in pixels. Must be odd.",
 
   50         if self.
width % 2 == 0:
 
   51             raise RuntimeError(
"width=%s must be odd" % (self.
width,))
 
   62     r"""!Install a Gaussian PSF model in an exposure 
   64     @anchor InstallGaussianPsfTask_ 
   66     @section pipe_tasks_installGaussianPsf_Contents  Contents 
   68      - @ref pipe_tasks_installGaussianPsf_Purpose 
   69      - @ref pipe_tasks_installGaussianPsf_Initialize 
   70      - @ref pipe_tasks_installGaussianPsf_IO 
   71      - @ref pipe_tasks_installGaussianPsf_Config 
   72      - @ref pipe_tasks_installGaussianPsf_Metadata 
   73      - @ref pipe_tasks_installGaussianPsf_Debug 
   74      - @ref pipe_tasks_installGaussianPsf_Example 
   76     @section pipe_tasks_installGaussianPsf_Purpose  Description 
   78     Install a Gaussian PSF model in an exposure. 
   79     If the exposure already has a PSF model then the new model 
   80     has the same sigma and size (width and height in pixels) of the existing model. 
   81     If the exposure does not have a PSF model then the PSF sigma and size 
   82     are taken from the config. 
   84     At present the produced model is always circularly symmetric, but it is planned 
   85     to change this to an elliptical PSF model (only for the case that the exposure 
   86     already has a PSF model), once the necessary PSF object is available. 
   88     A variant of this task may someday exist to estimate the PSF 
   89     from the pixel data if no PSF model is present. 
   91     @section pipe_tasks_installGaussianPsf_Initialize  Task initialisation 
   95     @section pipe_tasks_installGaussianPsf_IO  Invoking the Task 
   97     The main method is `run`. 
   99     @section pipe_tasks_installGaussianPsf_Config  Configuration parameters 
  101     See @ref InstallGaussianPsfConfig 
  103     @section pipe_tasks_installGaussianPsf_Debug  Debug variables 
  105     This task has no debug display 
  107     @section pipe_tasks_installGaussianPsf_Example  A complete example of using InstallGaussianPsfTask 
  109         from lsst.afw.image import ExposureF 
  110         from lsst.meas.algorithms.installGaussianPsf import InstallGaussianPsfTask, FwhmPerSigma 
  112         exposure = ExposureF(100, 100) 
  113         task = InstallGaussianPsfTask() 
  114         task.run(exposure=exposure) 
  116         # This particular exposure had no PSF model to begin with, so the new PSF model 
  117         # uses the config's FWHM. However, measured FWHM is based on the truncated 
  118         # PSF image, so it does not exactly match the input 
  119         measFwhm = exposure.getPsf().computeShape().getDeterminantRadius() * FwhmPerSigma 
  120         assert abs(measFwhm - task.config.fwhm) < 1e-3 
  122     ConfigClass = InstallGaussianPsfConfig
 
  123     _DefaultName = 
"installSimplePsfModel" 
  126         """!Set exposure's PSF to a simple PSF model 
  128         The sigma and width of the new simple PSF model matches the sigma and width of the current model, 
  129         if any, else the config parameters are used. 
  131         @param[in,out] exposure  exposure to which to replace or add the PSF model 
  133         if exposure.hasPsf():
 
  134             psfModel = exposure.getPsf()
 
  135             psfSigma = psfModel.computeShape().getDeterminantRadius()
 
  136             width, height = psfModel.computeImage().getDimensions()
 
  138             psfSigma = self.config.fwhm / FwhmPerSigma
 
  139             width = height = self.config.width
 
  142             raise RuntimeError(
"psfSigma = %s <= 0" % (psfSigma,))
 
  144         self.log.
debug(
"installing a simple Gaussian PSF model with width=%s, height=%s, FWHM=%0.3f",
 
  145                        width, height, psfSigma*FwhmPerSigma)
 
  147         exposure.setPsf(psfModel)