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"
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':
92 elif self.config.fallbackValueType ==
'MEDIAN':
94 elif self.config.fallbackValueType ==
'MEANCLIP':
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, growFootprints=0)
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:
172 self.config.useFallbackValueAtEdge)
174 self.log.info(
"Interpolated over %d %s pixels." % (len(defectList), planeName))
tuple useFallbackValueAtEdge
Fit spatial kernel using approximate fluxes for candidates, and solving a linear system of equations...
def run
Interpolate in place over pixels in a maskedImage marked as bad.
tuple negativeFallbackAllowed
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.
void interpolateOverDefects(MaskedImageT &mimage, lsst::afw::detection::Psf const &, std::vector< Defect::Ptr > &_badList, double fallbackValue, bool useFallbackValueAtEdge)
Process a set of known bad pixels in an image.