LSST Applications g034a557a3c+0df69e75ff,g0afe43252f+b86e4b8053,g11f7dcd041+017865fdd3,g1cd03abf6b+1c8dc8730a,g1ce3e0751c+f991eae79d,g28da252d5a+a136f03385,g2bbee38e9b+b6588ad223,g2bc492864f+b6588ad223,g2cdde0e794+8523d0dbb4,g347aa1857d+b6588ad223,g35bb328faa+b86e4b8053,g3a166c0a6a+b6588ad223,g461a3dce89+b86e4b8053,g52b1c1532d+b86e4b8053,g6233c72cae+da9c58a417,g7f3b0d46df+ad13c1b82d,g80478fca09+f29c5d6c70,g858d7b2824+4fc997592f,g8cd86fa7b1+5f14beadf5,g965a9036f2+4fc997592f,g979bb04a14+87f76c17e6,g9ddcbc5298+f24b38b85a,gae0086650b+b86e4b8053,gbb886bcc26+77117948e7,gc28159a63d+b6588ad223,gc30aee3386+a2f0f6cab9,gcaf7e4fdec+4fc997592f,gcd45df26be+4fc997592f,gcdd4ae20e8+0acf6430b1,gcf0d15dbbd+0acf6430b1,gdaeeff99f8+006e14e809,gdbce86181e+467b805b48,ge3d4d395c2+224150c836,ge5f7162a3a+1d9667e7ad,ge6cb8fbbf7+0992c83eee,ge79ae78c31+b6588ad223,gf048a9a2f4+41d6ddaca1,gf0baf85859+b4cca3d10f,w.2024.30
LSST Data Management Base Package
Loading...
Searching...
No Matches
visualizeVisit.py
Go to the documentation of this file.
1# This file is part of pipe_tasks.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22__all__ = [
23 "VisualizeBinExpConfig",
24 "VisualizeBinExpTask",
25 "VisualizeMosaicExpConfig",
26 "VisualizeMosaicExpTask",
27 "VisualizeBinCalibConfig",
28 "VisualizeBinCalibTask",
29 "VisualizeMosaicCalibConfig",
30 "VisualizeMosaicCalibTask",
31 "VisualizeBinCalibFilterConfig",
32 "VisualizeBinCalibFilterTask",
33 "VisualizeMosaicCalibFilterConfig",
34 "VisualizeMosaicCalibFilterTask",
35]
36
37import lsst.afw.cameraGeom.utils as afwUtils
38import lsst.afw.image as afwImage
39import lsst.afw.math as afwMath
40import lsst.pex.config as pexConfig
41import lsst.pipe.base as pipeBase
42import lsst.pipe.base.connectionTypes as cT
43import numpy as np
44
45
46# VisualizeBinExp (here) & VisualizeMosaicExp (below):
47# Inputs to bin task have dimensions: {instrument, exposure, detector}
48# Output of the mosaic task have: {instrument, exposure}
49class VisualizeBinExpConnections(pipeBase.PipelineTaskConnections,
50 dimensions=("instrument", "exposure", "detector")):
51 inputExp = cT.Input(
52 name="calexp",
53 doc="Input exposure data to mosaic.",
54 storageClass="ExposureF",
55 dimensions=("instrument", "exposure", "detector"),
56 )
57 camera = cT.PrerequisiteInput(
58 name="camera",
59 doc="Input camera to use for mosaic geometry.",
60 storageClass="Camera",
61 dimensions=("instrument",),
62 isCalibration=True,
63 )
64
65 outputExp = cT.Output(
66 name="calexpBin",
67 doc="Output binned image.",
68 storageClass="ExposureF",
69 dimensions=("instrument", "exposure", "detector"),
70 )
71
72
73class VisualizeBinExpConfig(pipeBase.PipelineTaskConfig, pipelineConnections=VisualizeBinExpConnections):
74 """Configuration for focal plane visualization."""
75
76 binning = pexConfig.Field(
77 dtype=int,
78 default=8,
79 doc="Binning factor to apply to each input exposure's image data.",
80 )
81 detectorKeyword = pexConfig.Field(
82 dtype=str,
83 default="DET-ID",
84 doc="Metadata keyword to use to find detector if not available from input.",
85 )
86
87
88class VisualizeBinExpTask(pipeBase.PipelineTask):
89 """Bin the detectors of an exposure.
90
91 The outputs of this task should be passed to
92 VisualizeMosaicExpTask to be mosaicked into a full focal plane
93 visualization image.
94 """
95
96 ConfigClass = VisualizeBinExpConfig
97 _DefaultName = "VisualizeBinExp"
98
99 def run(self, inputExp, camera):
100 """Bin input image, attach associated detector.
101
102 Parameters
103 ----------
104 inputExp : `lsst.afw.image.Exposure`
105 Input exposure data to bin.
106 camera : `lsst.afw.cameraGeom.Camera`
107 Input camera to use for mosaic geometry.
108
109 Returns
110 -------
111 output : `lsst.pipe.base.Struct`
112 Results struct with attribute:
113
114 ``outputExp``
115 Binned version of input image (`lsst.afw.image.Exposure`).
116 """
117 if inputExp.getDetector() is None:
118 detectorId = inputExp.getMetadata().get(self.config.detectorKeyword)
119 if detectorId is not None:
120 inputExp.setDetector(camera[detectorId])
121
122 binned = inputExp.getMaskedImage()
123 binned = afwMath.binImage(binned, self.config.binning)
124 outputExp = afwImage.makeExposure(binned)
125
126 outputExp.setInfo(inputExp.getInfo())
127
128 return pipeBase.Struct(outputExp=outputExp)
129
130
131# VisualizeBinExp (above) & VisualizeMosaicExp (here):
132# Inputs to bin task have dimensions: {instrument, exposure, detector}
133# Output of the mosaic task have: {instrument, exposure}
134class VisualizeMosaicExpConnections(pipeBase.PipelineTaskConnections,
135 dimensions=("instrument", "exposure")):
136 inputExps = cT.Input(
137 name="calexpBin",
138 doc="Input binned images mosaic.",
139 storageClass="ExposureF",
140 dimensions=("instrument", "detector", "exposure"),
141 multiple=True,
142 )
143 camera = cT.PrerequisiteInput(
144 name="camera",
145 doc="Input camera to use for mosaic geometry.",
146 storageClass="Camera",
147 dimensions=("instrument", ),
148 isCalibration=True,
149 )
150
151 outputData = cT.Output(
152 name="calexpFocalPlane",
153 doc="Output binned mosaicked frame.",
154 storageClass="ImageF",
155 dimensions=("instrument", "exposure"),
156 )
157
158
160 pipeBase.PipelineTaskConfig, pipelineConnections=VisualizeMosaicExpConnections
161):
162 """Configuration for focal plane visualization."""
163
164 binning = pexConfig.Field(
165 dtype=int,
166 default=8,
167 doc="Binning factor previously applied to input exposures.",
168 )
169
170
171class VisualizeMosaicExpTask(pipeBase.PipelineTask):
172 """Task to mosaic binned products.
173
174 The config.binning parameter must match that used in the
175 VisualizeBinExpTask. Otherwise there will be a mismatch between
176 the input image size and the expected size of that image in the
177 full focal plane frame.
178 """
179
180 ConfigClass = VisualizeMosaicExpConfig
181 _DefaultName = "VisualizeMosaicExp"
182
183 def makeCameraImage(self, inputExps, camera, binning):
184 """Make an image of an entire focal plane.
185
186 Parameters
187 ----------
188 exposures: `dict` [`int`, `lsst.afw.image.Exposure`]
189 CCD exposures, binned by `binning`. The keys are the
190 detectorIDs, with the values the binned image exposure.
191
192 Returns
193 -------
194 image : `lsst.afw.image.Image`
195 Image mosaicked from the individual binned images for each
196 detector.
197 """
198 image = afwUtils.makeImageFromCamera(
199 camera, imageSource=ImageSource(inputExps), imageFactory=afwImage.ImageF, binSize=binning
200 )
201 return image
202
203 def run(self, inputExps, camera, inputIds=None):
204 """Mosaic inputs together to create focal plane image.
205
206 Parameters
207 ----------
208 inputExps : `list` [`lsst.afw.image.Exposure`]
209 Input exposure data to bin.
210 camera : `lsst.afw.cameraGeom.Camera`
211 Input camera to use for mosaic geometry.
212 inputIds : `list` [`int`], optional
213 Optional list providing exposure IDs corresponding to input
214 exposures. Will be generated via the exposure data `getDetector`
215 method if not provided.
216
217 Returns
218 -------
219 output : `lsst.pipe.base.Struct`
220 Results struct with attribute:
221
222 ``outputExp``
223 Binned version of input image (`lsst.afw.image.Exposure`).
224 """
225 if not inputIds:
226 inputIds = [exp.getDetector().getId() for exp in inputExps]
227 expDict = {id: exp for id, exp in zip(inputIds, inputExps)}
228 image = self.makeCameraImage(expDict, camera, self.config.binning)
229
230 return pipeBase.Struct(outputData=image)
231
232
234 """Source of images for makeImageFromCamera"""
235
236 def __init__(self, exposures):
237 self.exposures = exposures
238 self.isTrimmed = True
239 self.background = np.nan
240
241 def getCcdImage(self, detector, imageFactory, binSize):
242 """Provide image of CCD to makeImageFromCamera
243
244 Parameters
245 ----------
246 detector : `int`
247 Detector ID to get image data for.
248 imageFactory : `lsst.afw.image.Image`
249 Type of image to construct.
250 binSize : `int`
251 Binsize to use to recompute dimensions.
252
253 Returns
254 -------
255 image : `lsst.afw.image.Image`
256 Appropriately rotated, binned, and transformed
257 image to be mosaicked.
258 detector : `lsst.afw.cameraGeom.Detector`
259 Camera detector that the returned image data
260 belongs to.
261 """
262 detId = detector.getId()
263
264 if detId not in self.exposures:
265 dims = detector.getBBox().getDimensions() / binSize
266 image = imageFactory(*[int(xx) for xx in dims])
267 image.set(self.background)
268 else:
269 image = self.exposures[detector.getId()]
270 if hasattr(image, "getMaskedImage"):
271 image = image.getMaskedImage()
272 if hasattr(image, "getMask"):
273 mask = image.getMask()
274 isBad = mask.getArray() & mask.getPlaneBitMask("NO_DATA") > 0
275 image = image.clone()
276 image.getImage().getArray()[isBad] = self.background
277 if hasattr(image, "getImage"):
278 image = image.getImage()
279
280 # afwMath.rotateImageBy90 checks NQuarter values,
281 # so we don't need to here.
282 image = afwMath.rotateImageBy90(image, detector.getOrientation().getNQuarter())
283 return image, detector
284
285
286# VisualizeBinCalib (here) & VisualizeMosaicCalib (below):
287# Inputs to bin task have dimensions: {instrument, detector}
288# Output of the mosaic task have: {instrument, }
289class VisualizeBinCalibConnections(pipeBase.PipelineTaskConnections, dimensions=("instrument", "detector")):
290 inputExp = cT.Input(
291 name="bias",
292 doc="Input exposure data to mosaic.",
293 storageClass="ExposureF",
294 dimensions=("instrument", "detector"),
295 isCalibration=True,
296 )
297 camera = cT.PrerequisiteInput(
298 name="camera",
299 doc="Input camera to use for mosaic geometry.",
300 storageClass="Camera",
301 dimensions=("instrument",),
302 isCalibration=True,
303 )
304
305 outputExp = cT.Output(
306 name="biasBin",
307 doc="Output binned image.",
308 storageClass="ExposureF",
309 dimensions=("instrument", "detector"),
310 )
311
312
313class VisualizeBinCalibConfig(VisualizeBinExpConfig, pipelineConnections=VisualizeBinCalibConnections):
314 pass
315
316
318 """Bin the detectors of an calibration.
319
320 The outputs of this task should be passed to
321 VisualizeMosaicCalibTask to be mosaicked into a full focal plane
322 visualization image.
323 """
324
325 ConfigClass = VisualizeBinCalibConfig
326 _DefaultName = "VisualizeBinCalib"
327
328 pass
329
330
331# VisualizeBinCalib (above) & VisualizeMosaicCalib (here):
332# Inputs to bin task have dimensions: {instrument, detector}
333# Output of the mosaic task have: {instrument, }
334class VisualizeMosaicCalibConnections(pipeBase.PipelineTaskConnections, dimensions=("instrument",)):
335 inputExps = cT.Input(
336 name="biasBin",
337 doc="Input binned images mosaic.",
338 storageClass="ExposureF",
339 dimensions=("instrument", "detector"),
340 multiple=True,
341 )
342 camera = cT.PrerequisiteInput(
343 name="camera",
344 doc="Input camera to use for mosaic geometry.",
345 storageClass="Camera",
346 dimensions=("instrument",),
347 isCalibration=True,
348 )
349
350 outputData = cT.Output(
351 name="biasFocalPlane",
352 doc="Output binned mosaicked frame.",
353 storageClass="ImageF",
354 dimensions=("instrument",),
355 )
356
357
359 VisualizeMosaicExpConfig, pipelineConnections=VisualizeMosaicCalibConnections
360):
361 pass
362
363
365 """Task to mosaic binned products.
366
367 The config.binning parameter must match that used in the
368 VisualizeBinCalibTask. Otherwise there will be a mismatch between
369 the input image size and the expected size of that image in the
370 full focal plane frame.
371 """
372
373 ConfigClass = VisualizeMosaicCalibConfig
374 _DefaultName = "VisualizeMosaicCalib"
375
376 pass
377
378
379# VisualizeBinCalibFilter (here) & VisualizeMosaicCalibFilter (below):
380# Inputs to bin task have dimensions: {instrument, detector, physical_filter}
381# Output of the mosaic task have: {instrument, physical_filter}
382class VisualizeBinCalibFilterConnections(pipeBase.PipelineTaskConnections,
383 dimensions=("instrument", "detector", "physical_filter")):
384 inputExp = cT.Input(
385 name="flat",
386 doc="Input exposure data to mosaic.",
387 storageClass="ExposureF",
388 dimensions=("instrument", "detector", "physical_filter"),
389 isCalibration=True,
390 )
391 camera = cT.PrerequisiteInput(
392 name="camera",
393 doc="Input camera to use for mosaic geometry.",
394 storageClass="Camera",
395 dimensions=("instrument",),
396 isCalibration=True,
397 )
398
399 outputExp = cT.Output(
400 name="flatBin",
401 doc="Output binned image.",
402 storageClass="ExposureF",
403 dimensions=("instrument", "detector", "physical_filter"),
404 )
405
406
408 pipelineConnections=VisualizeBinCalibFilterConnections):
409 pass
410
411
413 """Bin the detectors of an calibration.
414
415 The outputs of this task should be passed to
416 VisualizeMosaicCalibTask to be mosaicked into a full focal plane
417 visualization image.
418 """
419
420 ConfigClass = VisualizeBinCalibFilterConfig
421 _DefaultName = "VisualizeBinCalibFilter"
422
423 pass
424
425
426# VisualizeBinCalibFilter (above) & VisualizeMosaicCalibFilter (here):
427# Inputs to bin task have dimensions: {instrument, detector, physical_filter}
428# Output of the mosaic task have: {instrument, physical_filter}
429class VisualizeMosaicCalibFilterConnections(pipeBase.PipelineTaskConnections,
430 dimensions=("instrument", "physical_filter",)):
431 inputExps = cT.Input(
432 name="flatBin",
433 doc="Input binned images mosaic.",
434 storageClass="ExposureF",
435 dimensions=("instrument", "detector", "physical_filter"),
436 multiple=True,
437 )
438 camera = cT.PrerequisiteInput(
439 name="camera",
440 doc="Input camera to use for mosaic geometry.",
441 storageClass="Camera",
442 dimensions=("instrument",),
443 isCalibration=True,
444 )
445
446 outputData = cT.Output(
447 name="flatFocalPlane",
448 doc="Output binned mosaicked frame.",
449 storageClass="ImageF",
450 dimensions=("instrument",),
451 )
452
453
455 VisualizeMosaicExpConfig, pipelineConnections=VisualizeMosaicCalibFilterConnections
456):
457 pass
458
459
461 """Task to mosaic binned products.
462
463 The config.binning parameter must match that used in the
464 VisualizeBinCalibFilterTask. Otherwise there will be a mismatch between
465 the input image size and the expected size of that image in the
466 full focal plane frame.
467 """
468
469 ConfigClass = VisualizeMosaicCalibFilterConfig
470 _DefaultName = "VisualizeMosaicCalibFilter"
471
472 pass
getCcdImage(self, detector, imageFactory, binSize)
makeCameraImage(self, inputExps, camera, binning)
run(self, inputExps, camera, inputIds=None)
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.
Definition Exposure.h:484
std::shared_ptr< ImageT > rotateImageBy90(ImageT const &image, int nQuarter)
Rotate an image by an integral number of quarter turns.
std::shared_ptr< ImageT > binImage(ImageT const &inImage, int const binX, int const binY, lsst::afw::math::Property const flags=lsst::afw::math::MEAN)
Definition binImage.cc:44