24 from scipy
import ndimage
29 __all__ = [
"DcrModel",
"applyDcr",
"calculateDcr",
"calculateImageParallacticAngle"]
33 """A model of the true sky after correcting chromatic effects. 37 dcrNumSubfilters : `int` 38 Number of sub-filters used to model chromatic effects within a band. 39 modelImages : `list` of `lsst.afw.image.Image` 40 A list of masked images, each containing the model for one subfilter 44 The ``DcrModel`` contains an estimate of the true sky, at a higher 45 wavelength resolution than the input observations. It can be forward- 46 modeled to produce Differential Chromatic Refraction (DCR) matched 47 templates for a given ``Exposure``, and provides utilities for conditioning 48 the model in ``dcrAssembleCoadd`` to avoid oscillating solutions between 49 iterations of forward modeling or between the subfilters of the model. 52 def __init__(self, modelImages, filterInfo=None, psf=None, mask=None, variance=None, photoCalib=None):
62 def fromImage(cls, maskedImage, dcrNumSubfilters, filterInfo=None, psf=None, photoCalib=None):
63 """Initialize a DcrModel by dividing a coadd between the subfilters. 67 maskedImage : `lsst.afw.image.MaskedImage` 68 Input coadded image to divide equally between the subfilters. 69 dcrNumSubfilters : `int` 70 Number of sub-filters used to model chromatic effects within a band. 71 filterInfo : `lsst.afw.image.Filter`, optional 72 The filter definition, set in the current instruments' obs package. 73 Required for any calculation of DCR, including making matched templates. 74 psf : `lsst.afw.detection.Psf`, optional 75 Point spread function (PSF) of the model. 76 Required if the ``DcrModel`` will be persisted. 77 photoCalib : `lsst.afw.image.PhotoCalib`, optional 78 Calibration to convert instrumental flux and 79 flux error to nanoJansky. 83 dcrModel : `lsst.pipe.tasks.DcrModel` 84 Best fit model of the true sky after correcting chromatic effects. 89 If there are any unmasked NAN values in ``maskedImage``. 93 model = maskedImage.image.clone()
94 mask = maskedImage.mask.clone()
100 variance = maskedImage.variance.clone()
101 variance /= dcrNumSubfilters
102 model /= dcrNumSubfilters
103 modelImages = [model, ]
104 for subfilter
in range(1, dcrNumSubfilters):
105 modelImages.append(model.clone())
106 return cls(modelImages, filterInfo, psf, mask, variance, photoCalib=photoCalib)
109 def fromDataRef(cls, dataRef, datasetType="dcrCoadd", numSubfilters=None, **kwargs):
110 """Load an existing DcrModel from a repository. 114 dataRef : `lsst.daf.persistence.ButlerDataRef` 115 Data reference defining the patch for coaddition and the 117 datasetType : `str`, optional 118 Name of the DcrModel in the registry {"dcrCoadd", "dcrCoadd_sub"} 119 numSubfilters : `int` 120 Number of sub-filters used to model chromatic effects within a band. 122 Additional keyword arguments to pass to look up the model in the data registry. 123 Common keywords and their types include: ``tract``:`str`, ``patch``:`str`, 124 ``bbox``:`lsst.afw.geom.Box2I` 128 dcrModel : `lsst.pipe.tasks.DcrModel` 129 Best fit model of the true sky after correcting chromatic effects. 137 for subfilter
in range(numSubfilters):
138 dcrCoadd = dataRef.get(datasetType, subfilter=subfilter,
139 numSubfilters=numSubfilters, **kwargs)
140 if filterInfo
is None:
141 filterInfo = dcrCoadd.getFilter()
143 psf = dcrCoadd.getPsf()
147 variance = dcrCoadd.variance
148 if photoCalib
is None:
149 photoCalib = dcrCoadd.getPhotoCalib()
150 modelImages.append(dcrCoadd.image)
151 return cls(modelImages, filterInfo, psf, mask, variance, photoCalib)
154 """Return the number of subfilters. 158 dcrNumSubfilters : `int` 159 The number of DCR subfilters in the model. 164 """Iterate over the subfilters of the DCR model. 169 Index of the current ``subfilter`` within the full band. 170 Negative indices are allowed, and count in reverse order 171 from the highest ``subfilter``. 175 modelImage : `lsst.afw.image.Image` 176 The DCR model for the given ``subfilter``. 181 If the requested ``subfilter`` is greater or equal to the number 182 of subfilters in the model. 184 if np.abs(subfilter) >= len(self):
185 raise IndexError(
"subfilter out of bounds.")
189 """Update the model image for one subfilter. 194 Index of the current subfilter within the full band. 195 maskedImage : `lsst.afw.image.Image` 196 The DCR model to set for the given ``subfilter``. 201 If the requested ``subfilter`` is greater or equal to the number 202 of subfilters in the model. 204 If the bounding box of the new image does not match. 206 if np.abs(subfilter) >= len(self):
207 raise IndexError(
"subfilter out of bounds.")
208 if maskedImage.getBBox() != self.
bbox:
209 raise ValueError(
"The bounding box of a subfilter must not change.")
214 """Return the filter of the model. 218 filter : `lsst.afw.image.Filter` 219 The filter definition, set in the current instruments' obs package. 225 """Return the psf of the model. 229 psf : `lsst.afw.detection.Psf` 230 Point spread function (PSF) of the model. 236 """Return the common bounding box of each subfilter image. 240 bbox : `lsst.afw.geom.Box2I` 241 Bounding box of the DCR model. 243 return self[0].getBBox()
247 """Return the common mask of each subfilter image. 251 mask : `lsst.afw.image.Mask` 252 Mask plane of the DCR model. 258 """Return the common variance of each subfilter image. 262 variance : `lsst.afw.image.Image` 263 Variance plane of the DCR model. 268 """Calculate a reference image from the average of the subfilter images. 272 bbox : `lsst.afw.geom.Box2I`, optional 273 Sub-region of the coadd. Returns the entire image if `None`. 277 refImage : `numpy.ndarray` 278 The reference image with no chromatic effects applied. 280 bbox = bbox
or self.
bbox 281 return np.mean([model[bbox].array
for model
in self], axis=0)
283 def assign(self, dcrSubModel, bbox=None):
284 """Update a sub-region of the ``DcrModel`` with new values. 288 dcrSubModel : `lsst.pipe.tasks.DcrModel` 289 New model of the true scene after correcting chromatic effects. 290 bbox : `lsst.afw.geom.Box2I`, optional 291 Sub-region of the coadd. 292 Defaults to the bounding box of ``dcrSubModel``. 297 If the new model has a different number of subfilters. 299 if len(dcrSubModel) != len(self):
300 raise ValueError(
"The number of DCR subfilters must be the same " 301 "between the old and new models.")
302 bbox = bbox
or self.
bbox 303 for model, subModel
in zip(self, dcrSubModel):
304 model.assign(subModel[bbox], bbox)
307 visitInfo=None, bbox=None, wcs=None, mask=None,
308 splitSubfilters=True, splitThreshold=0., amplifyModel=1.):
309 """Create a DCR-matched template image for an exposure. 313 exposure : `lsst.afw.image.Exposure`, optional 314 The input exposure to build a matched template for. 315 May be omitted if all of the metadata is supplied separately 316 order : `int`, optional 317 Interpolation order of the DCR shift. 318 visitInfo : `lsst.afw.image.VisitInfo`, optional 319 Metadata for the exposure. Ignored if ``exposure`` is set. 320 bbox : `lsst.afw.geom.Box2I`, optional 321 Sub-region of the coadd. Ignored if ``exposure`` is set. 322 wcs : `lsst.afw.geom.SkyWcs`, optional 323 Coordinate system definition (wcs) for the exposure. 324 Ignored if ``exposure`` is set. 325 mask : `lsst.afw.image.Mask`, optional 326 reference mask to use for the template image. 327 splitSubfilters : `bool`, optional 328 Calculate DCR for two evenly-spaced wavelengths in each subfilter, 329 instead of at the midpoint. Default: True 330 splitThreshold : `float`, optional 331 Minimum DCR difference within a subfilter required to use ``splitSubfilters`` 332 amplifyModel : `float`, optional 333 Multiplication factor to amplify differences between model planes. 334 Used to speed convergence of iterative forward modeling. 338 templateImage : `lsst.afw.image.ImageF` 339 The DCR-matched template 344 If neither ``exposure`` or all of ``visitInfo``, ``bbox``, and ``wcs`` are set. 347 raise ValueError(
"'filterInfo' must be set for the DcrModel in order to calculate DCR.")
348 if exposure
is not None:
349 visitInfo = exposure.getInfo().getVisitInfo()
350 bbox = exposure.getBBox()
351 wcs = exposure.getInfo().getWcs()
352 elif visitInfo
is None or bbox
is None or wcs
is None:
353 raise ValueError(
"Either exposure or visitInfo, bbox, and wcs must be set.")
354 dcrShift =
calculateDcr(visitInfo, wcs, self.
filter, len(self), splitSubfilters=splitSubfilters)
355 templateImage = afwImage.ImageF(bbox)
357 for subfilter, dcr
in enumerate(dcrShift):
359 model = (self[subfilter][bbox].array - refModel)*amplifyModel + refModel
361 model = self[subfilter][bbox].array
362 templateImage.array +=
applyDcr(model, dcr, splitSubfilters=splitSubfilters,
363 splitThreshold=splitThreshold, order=order)
367 visitInfo=None, bbox=None, wcs=None, mask=None):
368 """Wrapper to create an exposure from a template image. 372 exposure : `lsst.afw.image.Exposure`, optional 373 The input exposure to build a matched template for. 374 May be omitted if all of the metadata is supplied separately 375 visitInfo : `lsst.afw.image.VisitInfo`, optional 376 Metadata for the exposure. Ignored if ``exposure`` is set. 377 bbox : `lsst.afw.geom.Box2I`, optional 378 Sub-region of the coadd. Ignored if ``exposure`` is set. 379 wcs : `lsst.afw.geom.SkyWcs`, optional 380 Coordinate system definition (wcs) for the exposure. 381 Ignored if ``exposure`` is set. 382 mask : `lsst.afw.image.Mask`, optional 383 reference mask to use for the template image. 387 templateExposure : `lsst.afw.image.exposureF` 388 The DCR-matched template 391 bbox = exposure.getBBox()
393 bbox=bbox, wcs=wcs, mask=mask)
394 maskedImage = afwImage.MaskedImageF(bbox)
395 maskedImage.image = templateImage[bbox]
396 maskedImage.mask = self.
mask[bbox]
397 maskedImage.variance = self.
variance[bbox]
401 templateExposure = afwImage.ExposureF(bbox, wcs)
402 templateExposure.setMaskedImage(maskedImage[bbox])
403 templateExposure.setPsf(self.
psf)
404 templateExposure.setFilter(self.
filter)
406 raise RuntimeError(
"No PhotoCalib set for the DcrModel. " 407 "If the DcrModel was created from a masked image" 408 " you must also specify the photoCalib.")
409 templateExposure.setPhotoCalib(self.
photoCalib)
410 return templateExposure
413 """Average two iterations' solutions to reduce oscillations. 417 modelImages : `list` of `lsst.afw.image.Image` 418 The new DCR model images from the current iteration. 419 The values will be modified in place. 420 bbox : `lsst.afw.geom.Box2I` 421 Sub-region of the coadd 422 gain : `float`, optional 423 Relative weight to give the new solution when updating the model. 424 Defaults to 1.0, which gives equal weight to both solutions. 427 for model, newModel
in zip(self, modelImages):
429 newModel += model[bbox]
430 newModel /= 1. + gain
433 regularizationWidth=2):
434 """Restrict large variations in the model between iterations. 439 Index of the current subfilter within the full band. 440 newModel : `lsst.afw.image.Image` 441 The new DCR model for one subfilter from the current iteration. 442 Values in ``newModel`` that are extreme compared with the last 443 iteration are modified in place. 444 bbox : `lsst.afw.geom.Box2I` 446 regularizationFactor : `float` 447 Maximum relative change of the model allowed between iterations. 448 regularizationWidth : int, optional 449 Minimum radius of a region to include in regularization, in pixels. 451 refImage = self[subfilter][bbox].array
452 highThreshold = np.abs(refImage)*regularizationFactor
453 lowThreshold = refImage/regularizationFactor
454 newImage = newModel.array
456 regularizationWidth=regularizationWidth)
459 regularizationWidth=2, mask=None, convergenceMaskPlanes="DETECTED"):
460 """Restrict large variations in the model between subfilters. 464 modelImages : `list` of `lsst.afw.image.Image` 465 The new DCR model images from the current iteration. 466 The values will be modified in place. 467 bbox : `lsst.afw.geom.Box2I` 469 statsCtrl : `lsst.afw.math.StatisticsControl` 470 Statistics control object for coaddition. 471 regularizationFactor : `float` 472 Maximum relative change of the model allowed between subfilters. 473 regularizationWidth : `int`, optional 474 Minimum radius of a region to include in regularization, in pixels. 475 mask : `lsst.afw.image.Mask`, optional 476 Optional alternate mask 477 convergenceMaskPlanes : `list` of `str`, or `str`, optional 478 Mask planes to use to calculate convergence. 482 This implementation of frequency regularization restricts each subfilter 483 image to be a smoothly-varying function times a reference image. 487 maxDiff = np.sqrt(regularizationFactor)
488 noiseLevel = self.
calculateNoiseCutoff(modelImages[0], statsCtrl, bufferSize=5, mask=mask, bbox=bbox)
490 badPixels = np.isnan(referenceImage) | (referenceImage <= 0.)
491 if np.sum(~badPixels) == 0:
494 referenceImage[badPixels] = 0.
495 filterWidth = regularizationWidth
496 fwhm = 2.*filterWidth
499 smoothRef = ndimage.filters.gaussian_filter(referenceImage, filterWidth, mode=
'constant')
502 smoothRef += 3.*noiseLevel
504 lowThreshold = smoothRef/maxDiff
505 highThreshold = smoothRef*maxDiff
506 for model
in modelImages:
508 highThreshold=highThreshold,
509 lowThreshold=lowThreshold,
510 regularizationWidth=regularizationWidth)
511 smoothModel = ndimage.filters.gaussian_filter(model.array, filterWidth, mode=
'constant')
512 smoothModel += 3.*noiseLevel
513 relativeModel = smoothModel/smoothRef
516 relativeModel2 = ndimage.filters.gaussian_filter(relativeModel, filterWidth/alpha)
517 relativeModel += alpha*(relativeModel - relativeModel2)
518 model.array = relativeModel*referenceImage
521 convergenceMaskPlanes="DETECTED", mask=None, bbox=None):
522 """Helper function to calculate the background noise level of an image. 526 image : `lsst.afw.image.Image` 527 The input image to evaluate the background noise properties. 528 statsCtrl : `lsst.afw.math.StatisticsControl` 529 Statistics control object for coaddition. 531 Number of additional pixels to exclude 532 from the edges of the bounding box. 533 convergenceMaskPlanes : `list` of `str`, or `str` 534 Mask planes to use to calculate convergence. 535 mask : `lsst.afw.image.Mask`, Optional 536 Optional alternate mask 537 bbox : `lsst.afw.geom.Box2I`, optional 538 Sub-region of the masked image to calculate the noise level over. 542 noiseCutoff : `float` 543 The threshold value to treat pixels as noise in an image.. 548 mask = self.
mask[bbox]
550 bboxShrink.grow(-bufferSize)
551 convergeMask = mask.getPlaneBitMask(convergenceMaskPlanes)
553 backgroundPixels = mask[bboxShrink].array & (statsCtrl.getAndMask() | convergeMask) == 0
554 noiseCutoff = np.std(image[bboxShrink].array[backgroundPixels])
558 """Restrict image values to be between upper and lower limits. 560 This method flags all pixels in an image that are outside of the given 561 threshold values. The threshold values are taken from a reference image, 562 so noisy pixels are likely to get flagged. In order to exclude those 563 noisy pixels, the array of flags is eroded and dilated, which removes 564 isolated pixels outside of the thresholds from the list of pixels to be 565 modified. Pixels that remain flagged after this operation have their 566 values set to the appropriate upper or lower threshold value. 570 image : `numpy.ndarray` 571 The image to apply the thresholds to. 572 The values will be modified in place. 573 highThreshold : `numpy.ndarray`, optional 574 Array of upper limit values for each pixel of ``image``. 575 lowThreshold : `numpy.ndarray`, optional 576 Array of lower limit values for each pixel of ``image``. 577 regularizationWidth : `int`, optional 578 Minimum radius of a region to include in regularization, in pixels. 583 filterStructure = ndimage.iterate_structure(ndimage.generate_binary_structure(2, 1),
585 if highThreshold
is not None:
586 highPixels = image > highThreshold
587 if regularizationWidth > 0:
589 highPixels = ndimage.morphology.binary_opening(highPixels, structure=filterStructure)
590 image[highPixels] = highThreshold[highPixels]
591 if lowThreshold
is not None:
592 lowPixels = image < lowThreshold
593 if regularizationWidth > 0:
595 lowPixels = ndimage.morphology.binary_opening(lowPixels, structure=filterStructure)
596 image[lowPixels] = lowThreshold[lowPixels]
599 def applyDcr(image, dcr, useInverse=False, splitSubfilters=False, splitThreshold=0.,
600 doPrefilter=True, order=3):
601 """Shift an image along the X and Y directions. 605 image : `numpy.ndarray` 606 The input image to shift. 608 Shift calculated with ``calculateDcr``. 609 Uses numpy axes ordering (Y, X). 610 If ``splitSubfilters`` is set, each element is itself a `tuple` 611 of two `float`, corresponding to the DCR shift at the two wavelengths. 612 Otherwise, each element is a `float` corresponding to the DCR shift at 613 the effective wavelength of the subfilter. 614 useInverse : `bool`, optional 615 Apply the shift in the opposite direction. Default: False 616 splitSubfilters : `bool`, optional 617 Calculate DCR for two evenly-spaced wavelengths in each subfilter, 618 instead of at the midpoint. Default: False 619 splitThreshold : `float`, optional 620 Minimum DCR difference within a subfilter required to use ``splitSubfilters`` 621 doPrefilter : `bool`, optional 622 Spline filter the image before shifting, if set. Filtering is required, 623 so only set to False if the image is already filtered. 624 Filtering takes ~20% of the time of shifting, so if `applyDcr` will be 625 called repeatedly on the same image it is more efficient to precalculate 627 order : `int`, optional 628 The order of the spline interpolation, default is 3. 632 shiftedImage : `numpy.ndarray` 633 A copy of the input image with the specified shift applied. 636 prefilteredImage = ndimage.spline_filter(image, order=order)
638 prefilteredImage = image
640 shiftAmp = np.max(np.abs([_dcr0 - _dcr1
for _dcr0, _dcr1
in zip(dcr[0], dcr[1])]))
641 if shiftAmp >= splitThreshold:
643 shift = [-1.*s
for s
in dcr[0]]
644 shift1 = [-1.*s
for s
in dcr[1]]
648 shiftedImage = ndimage.shift(prefilteredImage, shift, prefilter=
False, order=order)
649 shiftedImage += ndimage.shift(prefilteredImage, shift1, prefilter=
False, order=order)
655 dcr = (np.mean(dcr[0]), np.mean(dcr[1]))
657 shift = [-1.*s
for s
in dcr]
660 shiftedImage = ndimage.shift(prefilteredImage, shift, prefilter=
False, order=order)
664 def calculateDcr(visitInfo, wcs, filterInfo, dcrNumSubfilters, splitSubfilters=False):
665 """Calculate the shift in pixels of an exposure due to DCR. 669 visitInfo : `lsst.afw.image.VisitInfo` 670 Metadata for the exposure. 671 wcs : `lsst.afw.geom.SkyWcs` 672 Coordinate system definition (wcs) for the exposure. 673 filterInfo : `lsst.afw.image.Filter` 674 The filter definition, set in the current instruments' obs package. 675 dcrNumSubfilters : `int` 676 Number of sub-filters used to model chromatic effects within a band. 677 splitSubfilters : `bool`, optional 678 Calculate DCR for two evenly-spaced wavelengths in each subfilter, 679 instead of at the midpoint. Default: False 683 dcrShift : `tuple` of two `float` 684 The 2D shift due to DCR, in pixels. 685 Uses numpy axes ordering (Y, X). 689 weight = [0.75, 0.25]
690 lambdaEff = filterInfo.getFilterProperty().getLambdaEff()
693 diffRefractAmp0 = differentialRefraction(wavelength=wl0, wavelengthRef=lambdaEff,
694 elevation=visitInfo.getBoresightAzAlt().getLatitude(),
695 observatory=visitInfo.getObservatory(),
696 weather=visitInfo.getWeather())
697 diffRefractAmp1 = differentialRefraction(wavelength=wl1, wavelengthRef=lambdaEff,
698 elevation=visitInfo.getBoresightAzAlt().getLatitude(),
699 observatory=visitInfo.getObservatory(),
700 weather=visitInfo.getWeather())
702 diffRefractPix0 = diffRefractAmp0.asArcseconds()/wcs.getPixelScale().asArcseconds()
703 diffRefractPix1 = diffRefractAmp1.asArcseconds()/wcs.getPixelScale().asArcseconds()
704 diffRefractArr = [diffRefractPix0*weight[0] + diffRefractPix1*weight[1],
705 diffRefractPix0*weight[1] + diffRefractPix1*weight[0]]
706 shiftX = [diffRefractPix*np.sin(rotation.asRadians())
for diffRefractPix
in diffRefractArr]
707 shiftY = [diffRefractPix*np.cos(rotation.asRadians())
for diffRefractPix
in diffRefractArr]
708 dcrShift.append(((shiftY[0], shiftX[0]), (shiftY[1], shiftX[1])))
710 diffRefractAmp = (diffRefractAmp0 + diffRefractAmp1)/2.
711 diffRefractPix = diffRefractAmp.asArcseconds()/wcs.getPixelScale().asArcseconds()
712 shiftX = diffRefractPix*np.sin(rotation.asRadians())
713 shiftY = diffRefractPix*np.cos(rotation.asRadians())
714 dcrShift.append((shiftY, shiftX))
719 """Calculate the total sky rotation angle of an exposure. 723 visitInfo : `lsst.afw.image.VisitInfo` 724 Metadata for the exposure. 725 wcs : `lsst.afw.geom.SkyWcs` 726 Coordinate system definition (wcs) for the exposure. 731 The rotation of the image axis, East from North. 732 Equal to the parallactic angle plus any additional rotation of the 734 A rotation angle of 0 degrees is defined with 735 North along the +y axis and East along the +x axis. 736 A rotation angle of 90 degrees is defined with 737 North along the +x axis and East along the -y axis. 739 parAngle = visitInfo.getBoresightParAngle().asRadians()
740 cd = wcs.getCdMatrix()
742 cdAngle = (np.arctan2(-cd[0, 1], cd[0, 0]) + np.arctan2(cd[1, 0], cd[1, 1]))/2.
743 rotAngle = (cdAngle + parAngle)*geom.radians
745 cdAngle = (np.arctan2(cd[0, 1], -cd[0, 0]) + np.arctan2(cd[1, 0], cd[1, 1]))/2.
746 rotAngle = (cdAngle - parAngle)*geom.radians
751 """Iterate over the wavelength endpoints of subfilters. 755 filterInfo : `lsst.afw.image.Filter` 756 The filter definition, set in the current instruments' obs package. 757 dcrNumSubfilters : `int` 758 Number of sub-filters used to model chromatic effects within a band. 762 `tuple` of two `float` 763 The next set of wavelength endpoints for a subfilter, in nm. 765 lambdaMin = filterInfo.getFilterProperty().getLambdaMin()
766 lambdaMax = filterInfo.getFilterProperty().getLambdaMax()
767 wlStep = (lambdaMax - lambdaMin)/dcrNumSubfilters
768 for wl
in np.linspace(lambdaMin, lambdaMax, dcrNumSubfilters, endpoint=
False):
769 yield (wl, wl + wlStep)
def __setitem__(self, subfilter, maskedImage)
def calculateImageParallacticAngle(visitInfo, wcs)
def applyDcr(image, dcr, useInverse=False, splitSubfilters=False, splitThreshold=0., doPrefilter=True, order=3)
def regularizeModelIter(self, subfilter, newModel, bbox, regularizationFactor, regularizationWidth=2)
def __getitem__(self, subfilter)
def calculateNoiseCutoff(self, image, statsCtrl, bufferSize, convergenceMaskPlanes="DETECTED", mask=None, bbox=None)
def wavelengthGenerator(filterInfo, dcrNumSubfilters)
def applyImageThresholds(self, image, highThreshold=None, lowThreshold=None, regularizationWidth=2)
def buildMatchedExposure(self, exposure=None, visitInfo=None, bbox=None, wcs=None, mask=None)
def fromDataRef(cls, dataRef, datasetType="dcrCoadd", numSubfilters=None, kwargs)
def getReferenceImage(self, bbox=None)
def buildMatchedTemplate(self, exposure=None, order=3, visitInfo=None, bbox=None, wcs=None, mask=None, splitSubfilters=True, splitThreshold=0., amplifyModel=1.)
def fromImage(cls, maskedImage, dcrNumSubfilters, filterInfo=None, psf=None, photoCalib=None)
def assign(self, dcrSubModel, bbox=None)
def __init__(self, modelImages, filterInfo=None, psf=None, mask=None, variance=None, photoCalib=None)
def calculateDcr(visitInfo, wcs, filterInfo, dcrNumSubfilters, splitSubfilters=False)
def regularizeModelFreq(self, modelImages, bbox, statsCtrl, regularizationFactor, regularizationWidth=2, mask=None, convergenceMaskPlanes="DETECTED")
def conditionDcrModel(self, modelImages, bbox, gain=1.)