28 __all__ = [
"InterpImageConfig",
"InterpImageTask"]
32 """Config for InterpImageTask 34 modelPsf = measAlg.GaussianPsfFactory.makeField(doc=
"Model Psf factory")
36 useFallbackValueAtEdge = pexConfig.Field(
38 doc=
"Smoothly taper to the fallback value at the edge of the image?",
41 fallbackValueType = pexConfig.ChoiceField(
43 doc=
"Type of statistic to calculate edge fallbackValue for interpolation",
47 "MEANCLIP":
"clipped mean",
48 "USER":
"user value set in fallbackUserValue config",
52 fallbackUserValue = pexConfig.Field(
54 doc=
"If fallbackValueType is 'USER' then use this as the fallbackValue; ignored otherwise",
57 negativeFallbackAllowed = pexConfig.Field(
59 doc=(
"Allow negative values for egde interpolation fallbackValue? If False, set " 60 "fallbackValue to max(fallbackValue, 0.0)"),
65 pexConfig.Config.validate(self)
69 raise ValueError(
"User supplied fallbackValue is negative (%.2f) but " 74 """Interpolate over bad image pixels 76 ConfigClass = InterpImageConfig
77 _DefaultName =
"interpImage" 79 def _setFallbackValue(self, mi=None):
80 """Set the edge fallbackValue for interpolation 82 \param[in] mi input maksedImage on which to calculate the statistics 83 Must be provided if fallbackValueType != "USER". 85 \return fallbackValue The value set/computed based on the fallbackValueType 86 and negativeFallbackAllowed config parameters 88 if self.config.fallbackValueType !=
'USER':
89 assert mi,
"No maskedImage provided" 90 if self.config.fallbackValueType ==
'MEAN':
91 fallbackValue = afwMath.makeStatistics(mi, afwMath.MEAN).getValue()
92 elif self.config.fallbackValueType ==
'MEDIAN':
93 fallbackValue = afwMath.makeStatistics(mi, afwMath.MEDIAN).getValue()
94 elif self.config.fallbackValueType ==
'MEANCLIP':
95 fallbackValue = afwMath.makeStatistics(mi, afwMath.MEANCLIP).getValue()
96 elif self.config.fallbackValueType ==
'USER':
97 fallbackValue = self.config.fallbackUserValue
99 raise NotImplementedError(
"%s : %s not implemented" %
100 (
"fallbackValueType", self.config.fallbackValueType))
102 if not self.config.negativeFallbackAllowed
and fallbackValue < 0.0:
103 self.log.warn(
"Negative interpolation edge fallback value computed but " 104 "negativeFallbackAllowed is False: setting fallbackValue to 0.0")
105 fallbackValue = max(fallbackValue, 0.0)
107 self.log.info(
"fallbackValueType %s has been set to %.4f" %
108 (self.config.fallbackValueType, fallbackValue))
113 def run(self, image, planeName=None, fwhmPixels=None, defects=None):
114 """!Interpolate in place over pixels in a maskedImage marked as bad 116 Pixels to be interpolated are set by either a mask planeName provided 117 by the caller OR a defects list of type measAlg.DefectListT. If both 118 are provided an exception is raised. 120 Note that the interpolation code in meas_algorithms currently doesn't 121 use the input PSF (though it's a required argument), so it's not 122 important to set the input PSF parameters exactly. This PSF is set 123 here as the psf attached to the "image" (i.e if the image passed in 124 is an Exposure). Otherwise, a psf model is created using 125 measAlg.GaussianPsfFactory with the value of fwhmPixels (the value 126 passed in by the caller, or the default defaultFwhm set in 127 measAlg.GaussianPsfFactory if None). 129 \param[in,out] image MaskedImage OR Exposure to be interpolated 130 \param[in] planeName name of mask plane over which to interpolate 131 If None, must provide a defects list. 132 \param[in] fwhmPixels FWHM of core star (pixels) 133 If None the default is used, where the default 134 is set to the exposure psf if available 135 \param[in] defects List of defects of type measAlg.DefectListT 136 over which to interpolate. 139 maskedImage = image.getMaskedImage()
140 except AttributeError:
144 if planeName
is None:
146 raise ValueError(
"No defects or plane name provided")
149 planeName =
"defects" 151 if defects
is not None:
152 raise ValueError(
"Provide EITHER a planeName OR a list of defects, not both")
153 if planeName
not in maskedImage.getMask().getMaskPlaneDict():
154 raise ValueError(
"maskedImage does not contain mask plane %s" % planeName)
155 defectList = ipIsr.getDefectListFromMask(maskedImage, planeName)
160 self.log.info(
"Setting psf for interpolation from image")
161 except AttributeError:
162 self.log.info(
"Creating psf model for interpolation from fwhm(pixels) = %s" %
163 (str(fwhmPixels)
if fwhmPixels
is not None else 164 (str(self.config.modelPsf.defaultFwhm)) +
" [default]"))
165 psf = self.config.modelPsf.apply(fwhm=fwhmPixels)
168 if self.config.useFallbackValueAtEdge:
171 measAlg.interpolateOverDefects(maskedImage, psf, defectList, fallbackValue,
172 self.config.useFallbackValueAtEdge)
174 self.log.info(
"Interpolated over %d %s pixels." % (len(defectList), planeName))
def _setFallbackValue(self, mi=None)
def run(self, image, planeName=None, fwhmPixels=None, defects=None)
Interpolate in place over pixels in a maskedImage marked as bad.