24from 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.
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, effectiveWavelength, bandwidth, filterLabel=None, psf=None,
53 mask=None, variance=None, photoCalib=None):
65 def fromImage(cls, maskedImage, dcrNumSubfilters, effectiveWavelength, bandwidth,
66 filterLabel=None, psf=None, photoCalib=None):
67 """Initialize a DcrModel by dividing a coadd between the subfilters.
72 Input coadded image to divide equally between the subfilters.
73 dcrNumSubfilters : `int`
74 Number of sub-filters used to model chromatic effects within a
76 effectiveWavelength : `float`
77 The effective wavelengths of the current filter, in nanometers.
79 The bandwidth of the current filter,
in nanometers.
81 The filter label, set
in the current instruments
' obs package.
82 Required for any calculation of DCR, including making matched
85 Point spread function (PSF) of the model.
86 Required
if the ``DcrModel`` will be persisted.
88 Calibration to convert instrumental flux
and
89 flux error to nanoJansky.
93 dcrModel : `lsst.pipe.tasks.DcrModel`
94 Best fit model of the true sky after correcting chromatic effects.
98 model = maskedImage.image.clone()
99 mask = maskedImage.mask.clone()
105 variance = maskedImage.variance.clone()
106 variance /= dcrNumSubfilters
107 model /= dcrNumSubfilters
108 modelImages = [model, ]
109 for subfilter
in range(1, dcrNumSubfilters):
110 modelImages.append(model.clone())
111 return cls(modelImages, effectiveWavelength, bandwidth,
112 filterLabel=filterLabel, psf=psf, mask=mask, variance=variance, photoCalib=photoCalib)
115 def fromDataRef(cls, dataRef, effectiveWavelength, bandwidth, datasetType="dcrCoadd", numSubfilters=None,
117 """Load an existing DcrModel from a Gen 2 repository.
121 dataRef : `lsst.daf.persistence.ButlerDataRef`
122 Data reference defining the patch for coaddition
and the
124 effectiveWavelength : `float`
125 The effective wavelengths of the current filter,
in nanometers.
127 The bandwidth of the current filter,
in nanometers.
128 datasetType : `str`, optional
129 Name of the DcrModel
in the registry {
"dcrCoadd",
"dcrCoadd_sub"}
130 numSubfilters : `int`
131 Number of sub-filters used to model chromatic effects within a
134 Additional keyword arguments to
pass to look up the model
in the
136 Common keywords
and their types include: ``tract``:`str`,
137 ``patch``:`str`, ``bbox``:`lsst.afw.geom.Box2I`
141 dcrModel : `lsst.pipe.tasks.DcrModel`
142 Best fit model of the true sky after correcting chromatic effects.
150 if "subfilter" in kwargs:
151 kwargs.pop(
"subfilter")
152 for subfilter
in range(numSubfilters):
153 dcrCoadd = dataRef.get(datasetType, subfilter=subfilter,
154 numSubfilters=numSubfilters, **kwargs)
155 if filterLabel
is None:
156 filterLabel = dcrCoadd.getFilterLabel()
158 psf = dcrCoadd.getPsf()
162 variance = dcrCoadd.variance
163 if photoCalib
is None:
164 photoCalib = dcrCoadd.getPhotoCalib()
165 modelImages.append(dcrCoadd.image)
166 return cls(modelImages, effectiveWavelength, bandwidth, filterLabel, psf, mask, variance, photoCalib)
169 def fromQuantum(cls, availableCoaddRefs, effectiveWavelength, bandwidth):
170 """Load an existing DcrModel from a Gen 3 repository.
174 availableCoaddRefs : `dict` [`int`, `lsst.daf.butler.DeferredDatasetHandle`]
175 Dictionary of spatially relevant retrieved coadd patches,
176 indexed by their sequential patch number.
177 effectiveWavelength : `float`
178 The effective wavelengths of the current filter, in nanometers.
180 The bandwidth of the current filter,
in nanometers.
184 dcrModel : `lsst.pipe.tasks.DcrModel`
185 Best fit model of the true sky after correcting chromatic effects.
192 modelImages = [
None]*len(availableCoaddRefs)
194 for coaddRef
in availableCoaddRefs:
195 subfilter = coaddRef.dataId[
"subfilter"]
196 dcrCoadd = coaddRef.get()
197 if filterLabel
is None:
198 filterLabel = dcrCoadd.getFilterLabel()
200 psf = dcrCoadd.getPsf()
204 variance = dcrCoadd.variance
205 if photoCalib
is None:
206 photoCalib = dcrCoadd.getPhotoCalib()
207 modelImages[subfilter] = dcrCoadd.image
208 return cls(modelImages, effectiveWavelength, bandwidth, filterLabel, psf, mask, variance, photoCalib)
211 """Return the number of subfilters.
215 dcrNumSubfilters : `int`
216 The number of DCR subfilters in the model.
221 """Iterate over the subfilters of the DCR model.
226 Index of the current ``subfilter`` within the full band.
227 Negative indices are allowed, and count
in reverse order
228 from the highest ``subfilter``.
233 The DCR model
for the given ``subfilter``.
238 If the requested ``subfilter``
is greater
or equal to the number
239 of subfilters
in the model.
241 if np.abs(subfilter) >= len(self):
242 raise IndexError(
"subfilter out of bounds.")
246 """Update the model image for one subfilter.
251 Index of the current subfilter within the full band.
253 The DCR model to set for the given ``subfilter``.
258 If the requested ``subfilter``
is greater
or equal to the number
259 of subfilters
in the model.
261 If the bounding box of the new image does
not match.
263 if np.abs(subfilter) >= len(self):
264 raise IndexError(
"subfilter out of bounds.")
265 if maskedImage.getBBox() != self.
bbox:
266 raise ValueError(
"The bounding box of a subfilter must not change.")
271 """Return the effective wavelength of the model.
275 effectiveWavelength : `float`
276 The effective wavelength of the current filter, in nanometers.
282 """Return the filter label for the model.
287 The filter used for the input observations.
293 """Return the bandwidth of the model.
298 The bandwidth of the current filter, in nanometers.
304 """Return the psf of the model.
309 Point spread function (PSF) of the model.
315 """Return the common bounding box of each subfilter image.
319 bbox : `lsst.afw.geom.Box2I`
320 Bounding box of the DCR model.
322 return self[0].getBBox()
326 """Return the common mask of each subfilter image.
331 Mask plane of the DCR model.
337 """Return the common variance of each subfilter image.
342 Variance plane of the DCR model.
347 """Calculate a reference image from the average of the subfilter
352 bbox : `lsst.afw.geom.Box2I`, optional
353 Sub-region of the coadd. Returns the entire image if `
None`.
357 refImage : `numpy.ndarray`
358 The reference image
with no chromatic effects applied.
360 bbox = bbox or self.
bbox
361 return np.mean([model[bbox].array
for model
in self], axis=0)
363 def assign(self, dcrSubModel, bbox=None):
364 """Update a sub-region of the ``DcrModel`` with new values.
368 dcrSubModel : `lsst.pipe.tasks.DcrModel`
369 New model of the true scene after correcting chromatic effects.
370 bbox : `lsst.afw.geom.Box2I`, optional
371 Sub-region of the coadd.
372 Defaults to the bounding box of ``dcrSubModel``.
377 If the new model has a different number of subfilters.
379 if len(dcrSubModel) != len(self):
380 raise ValueError(
"The number of DCR subfilters must be the same "
381 "between the old and new models.")
382 bbox = bbox
or self.
bbox
383 for model, subModel
in zip(self, dcrSubModel):
384 model.assign(subModel[bbox], bbox)
387 visitInfo=None, bbox=None, wcs=None, mask=None,
388 splitSubfilters=True, splitThreshold=0., amplifyModel=1.):
389 """Create a DCR-matched template image for an exposure.
394 The input exposure to build a matched template for.
395 May be omitted
if all of the metadata
is supplied separately
396 order : `int`, optional
397 Interpolation order of the DCR shift.
399 Metadata
for the exposure. Ignored
if ``exposure``
is set.
400 bbox : `lsst.afw.geom.Box2I`, optional
401 Sub-region of the coadd. Ignored
if ``exposure``
is set.
403 Coordinate system definition (wcs)
for the exposure.
404 Ignored
if ``exposure``
is set.
406 reference mask to use
for the template image.
407 splitSubfilters : `bool`, optional
408 Calculate DCR
for two evenly-spaced wavelengths
in each subfilter,
409 instead of at the midpoint. Default:
True
410 splitThreshold : `float`, optional
411 Minimum DCR difference within a subfilter required to use
413 amplifyModel : `float`, optional
414 Multiplication factor to amplify differences between model planes.
415 Used to speed convergence of iterative forward modeling.
419 templateImage : `lsst.afw.image.ImageF`
420 The DCR-matched template
425 If neither ``exposure``
or all of ``visitInfo``, ``bbox``,
and
429 raise ValueError(
"'effectiveWavelength' and 'bandwidth' must be set for the DcrModel in order "
431 if exposure
is not None:
432 visitInfo = exposure.getInfo().getVisitInfo()
433 bbox = exposure.getBBox()
434 wcs = exposure.getInfo().getWcs()
435 elif visitInfo
is None or bbox
is None or wcs
is None:
436 raise ValueError(
"Either exposure or visitInfo, bbox, and wcs must be set.")
438 splitSubfilters=splitSubfilters)
439 templateImage = afwImage.ImageF(bbox)
441 for subfilter, dcr
in enumerate(dcrShift):
443 model = (self[subfilter][bbox].array - refModel)*amplifyModel + refModel
445 model = self[subfilter][bbox].array
446 templateImage.array +=
applyDcr(model, dcr, splitSubfilters=splitSubfilters,
447 splitThreshold=splitThreshold, order=order)
451 visitInfo=None, bbox=None, wcs=None, mask=None):
452 """Wrapper to create an exposure from a template image.
457 The input exposure to build a matched template for.
458 May be omitted
if all of the metadata
is supplied separately
460 Metadata
for the exposure. Ignored
if ``exposure``
is set.
461 bbox : `lsst.afw.geom.Box2I`, optional
462 Sub-region of the coadd. Ignored
if ``exposure``
is set.
464 Coordinate system definition (wcs)
for the exposure.
465 Ignored
if ``exposure``
is set.
467 reference mask to use
for the template image.
471 templateExposure : `lsst.afw.image.exposureF`
472 The DCR-matched template
477 If no `photcCalib`
is set.
480 bbox = exposure.getBBox()
482 bbox=bbox, wcs=wcs, mask=mask)
483 maskedImage = afwImage.MaskedImageF(bbox)
484 maskedImage.image = templateImage[bbox]
485 maskedImage.mask = self.
mask[bbox]
486 maskedImage.variance = self.
variance[bbox]
490 templateExposure = afwImage.ExposureF(bbox, wcs)
491 templateExposure.setMaskedImage(maskedImage[bbox])
492 templateExposure.setPsf(self.
psf)
493 templateExposure.setFilterLabel(self.filterLabel)
495 raise RuntimeError(
"No PhotoCalib set for the DcrModel. "
496 "If the DcrModel was created from a masked image"
497 " you must also specify the photoCalib.")
498 templateExposure.setPhotoCalib(self.
photoCalib)
499 return templateExposure
502 """Average two iterations' solutions to reduce oscillations.
507 The new DCR model images from the current iteration.
508 The values will be modified
in place.
509 bbox : `lsst.afw.geom.Box2I`
510 Sub-region of the coadd
511 gain : `float`, optional
512 Relative weight to give the new solution when updating the model.
513 Defaults to 1.0, which gives equal weight to both solutions.
516 for model, newModel
in zip(self, modelImages):
518 newModel += model[bbox]
519 newModel /= 1. + gain
522 regularizationWidth=2):
523 """Restrict large variations in the model between iterations.
528 Index of the current subfilter within the full band.
530 The new DCR model for one subfilter
from the current iteration.
531 Values
in ``newModel`` that are extreme compared
with the last
532 iteration are modified
in place.
533 bbox : `lsst.afw.geom.Box2I`
535 regularizationFactor : `float`
536 Maximum relative change of the model allowed between iterations.
537 regularizationWidth : int, optional
538 Minimum radius of a region to include
in regularization,
in pixels.
540 refImage = self[subfilter][bbox].array
541 highThreshold = np.abs(refImage)*regularizationFactor
542 lowThreshold = refImage/regularizationFactor
543 newImage = newModel.array
545 regularizationWidth=regularizationWidth)
548 regularizationWidth=2, mask=None, convergenceMaskPlanes="DETECTED"):
549 """Restrict large variations in the model between subfilters.
554 The new DCR model images from the current iteration.
555 The values will be modified
in place.
556 bbox : `lsst.afw.geom.Box2I`
559 Statistics control object
for coaddition.
560 regularizationFactor : `float`
561 Maximum relative change of the model allowed between subfilters.
562 regularizationWidth : `int`, optional
563 Minimum radius of a region to include
in regularization,
in pixels.
565 Optional alternate mask
566 convergenceMaskPlanes : `list` of `str`,
or `str`, optional
567 Mask planes to use to calculate convergence.
571 This implementation of frequency regularization restricts each
572 subfilter image to be a smoothly-varying function times a reference
578 maxDiff = np.sqrt(regularizationFactor)
579 noiseLevel = self.
calculateNoiseCutoff(modelImages[0], statsCtrl, bufferSize=5, mask=mask, bbox=bbox)
581 badPixels = np.isnan(referenceImage) | (referenceImage <= 0.)
582 if np.sum(~badPixels) == 0:
585 referenceImage[badPixels] = 0.
586 filterWidth = regularizationWidth
587 fwhm = 2.*filterWidth
591 smoothRef = ndimage.filters.gaussian_filter(referenceImage, filterWidth, mode=
'constant')
595 smoothRef += 3.*noiseLevel
597 lowThreshold = smoothRef/maxDiff
598 highThreshold = smoothRef*maxDiff
599 for model
in modelImages:
601 highThreshold=highThreshold,
602 lowThreshold=lowThreshold,
603 regularizationWidth=regularizationWidth)
604 smoothModel = ndimage.filters.gaussian_filter(model.array, filterWidth, mode=
'constant')
605 smoothModel += 3.*noiseLevel
606 relativeModel = smoothModel/smoothRef
609 relativeModel2 = ndimage.filters.gaussian_filter(relativeModel, filterWidth/alpha)
610 relativeModel += alpha*(relativeModel - relativeModel2)
611 model.array = relativeModel*referenceImage
614 convergenceMaskPlanes="DETECTED", mask=None, bbox=None):
615 """Helper function to calculate the background noise level of an image.
620 The input image to evaluate the background noise properties.
622 Statistics control object for coaddition.
624 Number of additional pixels to exclude
625 from the edges of the bounding box.
626 convergenceMaskPlanes : `list` of `str`,
or `str`
627 Mask planes to use to calculate convergence.
629 Optional alternate mask
630 bbox : `lsst.afw.geom.Box2I`, optional
631 Sub-region of the masked image to calculate the noise level over.
635 noiseCutoff : `float`
636 The threshold value to treat pixels
as noise
in an image..
641 mask = self.
mask[bbox]
643 bboxShrink.grow(-bufferSize)
644 convergeMask = mask.getPlaneBitMask(convergenceMaskPlanes)
646 backgroundPixels = mask[bboxShrink].array & (statsCtrl.getAndMask() | convergeMask) == 0
647 noiseCutoff = np.std(image[bboxShrink].array[backgroundPixels])
651 """Restrict image values to be between upper and lower limits.
653 This method flags all pixels in an image that are outside of the given
654 threshold values. The threshold values are taken
from a reference
655 image, so noisy pixels are likely to get flagged. In order to exclude
656 those noisy pixels, the array of flags
is eroded
and dilated, which
657 removes isolated pixels outside of the thresholds
from the list of
658 pixels to be modified. Pixels that remain flagged after this operation
659 have their values set to the appropriate upper
or lower threshold
664 image : `numpy.ndarray`
665 The image to apply the thresholds to.
666 The values will be modified
in place.
667 highThreshold : `numpy.ndarray`, optional
668 Array of upper limit values
for each pixel of ``image``.
669 lowThreshold : `numpy.ndarray`, optional
670 Array of lower limit values
for each pixel of ``image``.
671 regularizationWidth : `int`, optional
672 Minimum radius of a region to include
in regularization,
in pixels.
677 filterStructure = ndimage.iterate_structure(ndimage.generate_binary_structure(2, 1),
679 if highThreshold
is not None:
680 highPixels = image > highThreshold
681 if regularizationWidth > 0:
683 highPixels = ndimage.morphology.binary_opening(highPixels, structure=filterStructure)
684 image[highPixels] = highThreshold[highPixels]
685 if lowThreshold
is not None:
686 lowPixels = image < lowThreshold
687 if regularizationWidth > 0:
689 lowPixels = ndimage.morphology.binary_opening(lowPixels, structure=filterStructure)
690 image[lowPixels] = lowThreshold[lowPixels]
693def applyDcr(image, dcr, useInverse=False, splitSubfilters=False, splitThreshold=0.,
694 doPrefilter=True, order=3):
695 """Shift an image along the X and Y directions.
699 image : `numpy.ndarray`
700 The input image to shift.
702 Shift calculated with ``calculateDcr``.
703 Uses numpy axes ordering (Y, X).
704 If ``splitSubfilters``
is set, each element
is itself a `tuple`
705 of two `float`, corresponding to the DCR shift at the two wavelengths.
706 Otherwise, each element
is a `float` corresponding to the DCR shift at
707 the effective wavelength of the subfilter.
708 useInverse : `bool`, optional
709 Apply the shift
in the opposite direction. Default:
False
710 splitSubfilters : `bool`, optional
711 Calculate DCR
for two evenly-spaced wavelengths
in each subfilter,
712 instead of at the midpoint. Default:
False
713 splitThreshold : `float`, optional
714 Minimum DCR difference within a subfilter required to use
716 doPrefilter : `bool`, optional
717 Spline filter the image before shifting,
if set. Filtering
is required,
718 so only set to
False if the image
is already filtered.
719 Filtering takes ~20% of the time of shifting, so
if `applyDcr` will be
720 called repeatedly on the same image it
is more efficient to
721 precalculate the filter.
722 order : `int`, optional
723 The order of the spline interpolation, default
is 3.
727 shiftedImage : `numpy.ndarray`
728 A copy of the input image
with the specified shift applied.
731 prefilteredImage = ndimage.spline_filter(image, order=order)
733 prefilteredImage = image
735 shiftAmp = np.max(np.abs([_dcr0 - _dcr1
for _dcr0, _dcr1
in zip(dcr[0], dcr[1])]))
736 if shiftAmp >= splitThreshold:
738 shift = [-1.*s
for s
in dcr[0]]
739 shift1 = [-1.*s
for s
in dcr[1]]
743 shiftedImage = ndimage.shift(prefilteredImage, shift, prefilter=
False, order=order)
744 shiftedImage += ndimage.shift(prefilteredImage, shift1, prefilter=
False, order=order)
750 dcr = (np.mean(dcr[0]), np.mean(dcr[1]))
752 shift = [-1.*s
for s
in dcr]
755 shiftedImage = ndimage.shift(prefilteredImage, shift, prefilter=
False, order=order)
759def calculateDcr(visitInfo, wcs, effectiveWavelength, bandwidth, dcrNumSubfilters, splitSubfilters=False):
760 """Calculate the shift in pixels of an exposure due to DCR.
765 Metadata for the exposure.
767 Coordinate system definition (wcs)
for the exposure.
768 effectiveWavelength : `float`
769 The effective wavelengths of the current filter,
in nanometers.
771 The bandwidth of the current filter,
in nanometers.
772 dcrNumSubfilters : `int`
773 Number of sub-filters used to model chromatic effects within a band.
774 splitSubfilters : `bool`, optional
775 Calculate DCR
for two evenly-spaced wavelengths
in each subfilter,
776 instead of at the midpoint. Default:
False
780 dcrShift : `tuple` of two `float`
781 The 2D shift due to DCR,
in pixels.
782 Uses numpy axes ordering (Y, X).
786 weight = [0.75, 0.25]
790 diffRefractAmp0 = differentialRefraction(wavelength=wl0, wavelengthRef=effectiveWavelength,
791 elevation=visitInfo.getBoresightAzAlt().getLatitude(),
792 observatory=visitInfo.getObservatory(),
793 weather=visitInfo.getWeather())
794 diffRefractAmp1 = differentialRefraction(wavelength=wl1, wavelengthRef=effectiveWavelength,
795 elevation=visitInfo.getBoresightAzAlt().getLatitude(),
796 observatory=visitInfo.getObservatory(),
797 weather=visitInfo.getWeather())
799 diffRefractPix0 = diffRefractAmp0.asArcseconds()/wcs.getPixelScale().asArcseconds()
800 diffRefractPix1 = diffRefractAmp1.asArcseconds()/wcs.getPixelScale().asArcseconds()
801 diffRefractArr = [diffRefractPix0*weight[0] + diffRefractPix1*weight[1],
802 diffRefractPix0*weight[1] + diffRefractPix1*weight[0]]
803 shiftX = [diffRefractPix*np.sin(rotation.asRadians())
for diffRefractPix
in diffRefractArr]
804 shiftY = [diffRefractPix*np.cos(rotation.asRadians())
for diffRefractPix
in diffRefractArr]
805 dcrShift.append(((shiftY[0], shiftX[0]), (shiftY[1], shiftX[1])))
807 diffRefractAmp = (diffRefractAmp0 + diffRefractAmp1)/2.
808 diffRefractPix = diffRefractAmp.asArcseconds()/wcs.getPixelScale().asArcseconds()
809 shiftX = diffRefractPix*np.sin(rotation.asRadians())
810 shiftY = diffRefractPix*np.cos(rotation.asRadians())
811 dcrShift.append((shiftY, shiftX))
816 """Calculate the total sky rotation angle of an exposure.
821 Metadata for the exposure.
823 Coordinate system definition (wcs)
for the exposure.
828 The rotation of the image axis, East
from North.
829 Equal to the parallactic angle plus any additional rotation of the
831 A rotation angle of 0 degrees
is defined
with
832 North along the +y axis
and East along the +x axis.
833 A rotation angle of 90 degrees
is defined
with
834 North along the +x axis
and East along the -y axis.
836 parAngle = visitInfo.getBoresightParAngle().asRadians()
837 cd = wcs.getCdMatrix()
839 cdAngle = (np.arctan2(-cd[0, 1], cd[0, 0]) + np.arctan2(cd[1, 0], cd[1, 1]))/2.
840 rotAngle = (cdAngle + parAngle)*geom.radians
842 cdAngle = (np.arctan2(cd[0, 1], -cd[0, 0]) + np.arctan2(cd[1, 0], cd[1, 1]))/2.
843 rotAngle = (cdAngle - parAngle)*geom.radians
848 """Iterate over the wavelength endpoints of subfilters.
852 effectiveWavelength : `float`
853 The effective wavelength of the current filter, in nanometers.
855 The bandwidth of the current filter,
in nanometers.
856 dcrNumSubfilters : `int`
857 Number of sub-filters used to model chromatic effects within a band.
861 `tuple` of two `float`
862 The next set of wavelength endpoints
for a subfilter,
in nanometers.
864 lambdaMin = effectiveWavelength - bandwidth/2
865 lambdaMax = effectiveWavelength + bandwidth/2
866 wlStep = bandwidth/dcrNumSubfilters
867 for wl
in np.linspace(lambdaMin, lambdaMax, dcrNumSubfilters, endpoint=
False):
868 yield (wl, wl + wlStep)
def calculateNoiseCutoff(self, image, statsCtrl, bufferSize, convergenceMaskPlanes="DETECTED", mask=None, bbox=None)
def buildMatchedTemplate(self, exposure=None, order=3, visitInfo=None, bbox=None, wcs=None, mask=None, splitSubfilters=True, splitThreshold=0., amplifyModel=1.)
def applyImageThresholds(self, image, highThreshold=None, lowThreshold=None, regularizationWidth=2)
def buildMatchedExposure(self, exposure=None, visitInfo=None, bbox=None, wcs=None, mask=None)
def getReferenceImage(self, bbox=None)
def conditionDcrModel(self, modelImages, bbox, gain=1.)
def regularizeModelIter(self, subfilter, newModel, bbox, regularizationFactor, regularizationWidth=2)
def fromDataRef(cls, dataRef, effectiveWavelength, bandwidth, datasetType="dcrCoadd", numSubfilters=None, **kwargs)
def assign(self, dcrSubModel, bbox=None)
def regularizeModelFreq(self, modelImages, bbox, statsCtrl, regularizationFactor, regularizationWidth=2, mask=None, convergenceMaskPlanes="DETECTED")
def __setitem__(self, subfilter, maskedImage)
def __getitem__(self, subfilter)
def fromQuantum(cls, availableCoaddRefs, effectiveWavelength, bandwidth)
def fromImage(cls, maskedImage, dcrNumSubfilters, effectiveWavelength, bandwidth, filterLabel=None, psf=None, photoCalib=None)
def __init__(self, modelImages, effectiveWavelength, bandwidth, filterLabel=None, psf=None, mask=None, variance=None, photoCalib=None)
def effectiveWavelength(self)
def applyDcr(image, dcr, useInverse=False, splitSubfilters=False, splitThreshold=0., doPrefilter=True, order=3)
def wavelengthGenerator(effectiveWavelength, bandwidth, dcrNumSubfilters)
def calculateImageParallacticAngle(visitInfo, wcs)
def calculateDcr(visitInfo, wcs, effectiveWavelength, bandwidth, dcrNumSubfilters, splitSubfilters=False)