22__all__ = [
"BinImageDataTask",
"BinImageDataConfig",
"binImageData"]
24import lsst.afw.image
as afwImage
28import lsst.pipe.base.connectionTypes
as cT
29from lsst.utils.timer
import timeMethod
33 pipeBase.PipelineTaskConnections,
34 dimensions=(
"instrument",
"exposure",
"detector"),
35 defaultTemplates={
"inputName":
"postISRCCD",
"outputName":
"postISRCCDBin"},
40 doc=
"Input image data to bin.",
41 storageClass=
"ExposureF",
42 dimensions=[
"instrument",
"exposure",
"detector"],
44 outputData = cT.Output(
46 doc=
"Binned image data.",
47 storageClass=
"ExposureF",
48 dimensions=[
"instrument",
"exposure",
"detector"],
51 def __init__(self, *, config=None):
52 """Customize the connections and storageClass for a specific
53 instance. This enables both to be dynamically set at runtime,
54 allowing BinImageDataTask to work with different types of
55 image and image-like data.
59 config : `BinExposureConfig`
60 A config for `BinExposureTask`.
62 super().__init__(config=config)
63 if config
and config.inputDimensions != self.inputData.dimensions:
64 self.dimensions.clear()
65 self.dimensions.update(config.inputDimensions)
66 self.inputData = cT.Input(
67 name=self.inputData.name,
68 doc=self.inputData.doc,
69 storageClass=self.inputData.storageClass,
70 dimensions=frozenset(config.inputDimensions),
72 self.outputData = cT.Output(
73 name=self.outputData.name,
74 doc=self.outputData.doc,
75 storageClass=self.outputData.storageClass,
76 dimensions=frozenset(config.inputDimensions),
78 if config
and config.inputStorageClass != self.inputData.storageClass:
79 self.inputData = cT.Input(
80 name=self.inputData.name,
81 doc=self.inputData.doc,
82 storageClass=config.inputStorageClass,
83 dimensions=self.inputData.dimensions,
85 self.outputData = cT.Output(
86 name=self.outputData.name,
87 doc=self.outputData.doc,
88 storageClass=config.inputStorageClass,
89 dimensions=self.outputData.dimensions,
93class BinImageDataConfig(
94 pipeBase.PipelineTaskConfig, pipelineConnections=BinImageDataConnections
96 """Config for BinImageDataTask"""
98 inputDimensions = pexConfig.ListField(
100 default=sorted(BinImageDataConnections.dimensions),
102 doc=
"Override for the dimensions of the input and output data.",
104 inputStorageClass = pexConfig.Field(
108 "Override the storageClass of the input and output data. "
109 "Must be of type `Image`, `MaskedImage`, or `Exposure`, "
110 "or one of their subtypes."
113 binFactor = pexConfig.Field(
115 doc=
"Binning factor applied to both spatial dimensions.",
117 check=
lambda x: x > 1,
121class BinImageDataTask(pipeBase.PipelineTask):
122 """Perform an nxn binning of an image or image-like dataset.
124 The binning factor is the same in both spatial dimensions (i.e.,
125 an nxn binning is performed). In the case of MaskedImages and Exposures,
126 each of the input image planes are binned by the same factor.
129 ConfigClass = BinImageDataConfig
130 _DefaultName =
"binImageData"
133 def run(self, inputData, binFactor=None):
134 """Perform an nxn binning of image and image-like data.
138 inputData : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage` or
139 `lsst.afw.image.Exposure` or one of their sub-types.
140 Data to spatially bin
141 binFactor : `int`, optional.
142 nxn binning factor. If not provided then self.config.binFactor
147 result : `lsst.pipe.base.Struct`
148 Results as a struct with attributes:
151 Binned data (`lsst.afw.image.Image` or
152 `lsst.afw.image.MaskedImage` or `lsst.afw.image.Exposure`
153 or one of their sub-types. The type matches that of the input.).
156 binFactor = self.config.binFactor
157 return pipeBase.Struct(outputData=binImageData(inputData, binFactor))
160def binImageData(inputData, binFactor=8):
161 """Bin image and image-like data to reduce its spatial dimensions.
163 Performs an nxn binning of the input data, reducing both spatial
164 dimensions of each of the input image data by the provided
169 inputData: `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage` or
170 `lsst.afw.image.Exposure` or one of their sub-types.
173 Binning factor to apply to each input exposure's image data.
178 binnedImage or binnedExposure: `lsst.afw.image.Image` or
179 `lsst.afw.image.MaskedImage` or `lsst.afw.image.Exposure` or one of
181 Binned version of input image.
186 Raised if either the binning factor is not of type `int`, or if the
187 input data to be binned is not of type `lsst.afw.image.Exposure`
188 or one of its sub-types.
191 if not isinstance(binFactor, int):
192 raise TypeError(
"binFactor must be of type int")
195 inputImage = inputData.getMaskedImage()
198 inputImage = inputData
202 "inputData must be of type `lsst.afw.image.Image`, `lsst.afw.MaskedImage`, "
203 "or `lsst.afw.image.Exposure`, or one of their sub-types."
205 raise TypeError(message)
211 binnedExposure.setInfo(inputData.getInfo())
212 return binnedExposure
A class to contain the data, WCS, and other information needed to describe an image of the sky.
A class to represent a 2-dimensional array of pixels.
A class to manipulate images, masks, and variance as a single object.
std::shared_ptr< Exposure< ImagePixelT, MaskPixelT, VariancePixelT > > makeExposure(MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > &mimage, std::shared_ptr< geom::SkyWcs const > wcs=std::shared_ptr< geom::SkyWcs const >())
A function to return an Exposure of the correct type (cf.
std::shared_ptr< ImageT > binImage(ImageT const &inImage, int const binX, int const binY, lsst::afw::math::Property const flags=lsst::afw::math::MEAN)