9 Configuration for ReplaceWithNoiseTask.
11 noiseSource = pexConfig.ChoiceField(doc=
'How do we choose the mean and variance of the Gaussian noise we generate?',
13 'measure':
'Measure clipped mean and variance from the whole image',
14 'meta':
'Mean = 0, variance = the "BGMEAN" metadata entry',
15 'variance':
"Mean = 0, variance = the image's variance",
20 noiseOffset = pexConfig.Field(dtype=float, optional=
False, default=0.,
21 doc=
'Add ann offset to the generated noise.')
23 noiseSeed = pexConfig.Field(dtype=int, default=0, doc=
'The seed value to use for random number generation.')
26 ConfigClass = ReplaceWithNoiseConfig
27 _DefaultName =
"replaceWithNoise"
29 def begin(self, exposure, sources, noiseImage=None, noiseMeanVar=None):
33 if not sources.isSorted():
35 mi = exposure.getMaskedImage()
42 for maskname
in [
'THISDET',
'OTHERDET']:
45 plane = mask.getMaskPlane(maskname)
46 self.log.logdebug(
'Mask plane "%s" already existed' % maskname)
49 plane = mask.addMaskPlane(maskname)
50 self.removeplanes.append(maskname)
51 mask.clearMaskPlane(plane)
52 bitmask = mask.getPlaneBitMask(maskname)
53 bitmasks.append(bitmask)
54 self.log.logdebug(
'Mask plane "%s": plane %i, bitmask %i = 0x%x' %
55 (maskname, plane, bitmask, bitmask))
67 for source
in sources:
68 fp = source.getFootprint()
69 hfp = afwDet.cast_HeavyFootprintF(fp)
70 if source.getParent()
and hfp
is not None:
75 self.heavies.append(hfp)
85 self.heavies.append(heavy)
91 self.log.logdebug(
'Using noise generator: %s' % (str(noisegen)))
92 for source
in sources:
93 if source.getParent():
95 fp = source.getFootprint()
96 heavy = noisegen.getHeavyFootprint(fp)
107 mi = exposure.getMaskedImage()
119 mi = exposure.getMaskedImage()
124 while ancestor.getParent():
125 ancestor = sources.find(ancestor.getParent())
127 if not ancestor
or j == 100:
128 raise RuntimeError(
'Source hierarchy too deep, or (more likely) your Source table is botched.')
136 def end(self, exposure, sources):
139 mi = exposure.getMaskedImage()
142 for source,heavy
in zip(sources,self.
heavies):
143 if source.getParent():
147 mask.removeAndClearMaskPlane(maskname,
True)
156 if noiseImage
is not None:
159 if self.config.noiseSeed:
161 rand =
afwMath.Random(afwMath.Random.MT19937, self.config.noiseSeed)
162 if noiseMeanVar
is not None:
165 noiseMean,noiseVar = noiseMeanVar
166 noiseMean = float(noiseMean)
167 noiseVar = float(noiseVar)
168 noiseStd = math.sqrt(noiseVar)
169 self.log.logdebug(
'Using passed-in noise mean = %g, variance = %g -> stdev %g' %
170 (noiseMean, noiseVar, noiseStd))
173 self.log.logdebug(
'Failed to cast passed-in noiseMeanVar to floats: %s' %
175 offset = self.config.noiseOffset
176 noiseSource = self.config.noiseSource
178 if noiseSource ==
'meta':
180 meta = exposure.getMetadata()
183 bgMean = meta.getAsDouble(
'BGMEAN')
185 noiseStd = math.sqrt(bgMean)
186 self.log.logdebug(
'Using noise variance = (BGMEAN = %g) from exposure metadata' %
190 self.log.logdebug(
'Failed to get BGMEAN from exposure metadata')
192 if noiseSource ==
'variance':
193 self.log.logdebug(
'Will draw noise according to the variance plane.')
194 var = exposure.getMaskedImage().getVariance()
198 im = exposure.getMaskedImage().getImage()
200 noiseMean = s.getValue(afwMath.MEANCLIP)
201 noiseStd = s.getValue(afwMath.STDEVCLIP)
202 self.log.logdebug(
"Measured from image: clipped mean = %g, stdev = %g" %
203 (noiseMean,noiseStd))
208 Base class for noise generators used by the "doReplaceWithNoise" routine:
209 these produce HeavyFootprints filled with noise generated in various ways.
211 This is an abstract base class.
219 return afwImage.MaskedImageF(im)
225 "Generates" noise by cutting out a subimage from a user-supplied noise Image.
229 img: an afwImage.ImageF
231 self.
mim = afwImage.MaskedImageF(img)
237 Generates noise using the afwMath.Random() and afwMath.randomGaussianImage() routines.
239 This is an abstract base class.
247 rim = afwImage.ImageF(bb.getWidth(), bb.getHeight())
248 rim.setXY0(bb.getMinX(), bb.getMinY())
254 Generates Gaussian noise with a fixed mean and standard deviation.
257 super(FixedGaussianNoiseGenerator, self).
__init__(rand=rand)
261 return 'FixedGaussianNoiseGenerator: mean=%g, std=%g' % (self.
mean, self.
std)
270 Generates Gaussian noise whose variance matches that of the variance plane of the image.
274 var: an afwImage.ImageF; the variance plane.
275 mean: floating-point or afwImage.Image
277 super(VariancePlaneNoiseGenerator, self).
__init__(rand=rand)
279 if mean
is not None and mean == 0.:
283 return 'VariancePlaneNoiseGenerator: mean=' + str(self.
mean)
287 stdev = afwImage.ImageF(self.
var, bb, afwImage.LOCAL,
True)
290 if self.
mean is not None:
heavyNoise
FIXME: the heavy footprint includes the mask and variance planes, which we shouldn't need (I don't th...
void randomGaussianImage(ImageT *image, Random &rand)
MaskT clearMaskFromFootprint(lsst::afw::image::Mask< MaskT > *mask, Footprint const &footprint, MaskT const bitmask)
(AND ~bitmask) all the Mask's pixels that are in the Footprint; that is, set to zero in the Mask-inte...
MaskT setMaskFromFootprint(lsst::afw::image::Mask< MaskT > *mask, Footprint const &footprint, MaskT const bitmask)
OR bitmask into all the Mask's pixels that are in the Footprint.
Statistics makeStatistics(afwImage::Mask< afwImage::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl)
Specialization to handle Masks.
HeavyFootprint< ImagePixelT, MaskPixelT, VariancePixelT > makeHeavyFootprint(Footprint const &foot, lsst::afw::image::MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > const &img, HeavyFootprintCtrl const *ctrl=NULL)