LSSTApplications  19.0.0-10-g920eed2,19.0.0-11-g48a0200+2,19.0.0-18-gfc4e62b+13,19.0.0-2-g3b2f90d+2,19.0.0-2-gd671419+5,19.0.0-20-g5a5a17ab+11,19.0.0-21-g2644856+13,19.0.0-23-g84eeccb+1,19.0.0-24-g878c510+1,19.0.0-25-g6c8df7140,19.0.0-25-gb330496+1,19.0.0-3-g2b32d65+5,19.0.0-3-g8227491+12,19.0.0-3-g9c54d0d+12,19.0.0-3-gca68e65+8,19.0.0-3-gcfc5f51+5,19.0.0-3-ge110943+11,19.0.0-3-ge74d124,19.0.0-3-gfe04aa6+13,19.0.0-30-g9c3fd16+1,19.0.0-4-g06f5963+5,19.0.0-4-g3d16501+13,19.0.0-4-g4a9c019+5,19.0.0-4-g5a8b323,19.0.0-4-g66397f0+1,19.0.0-4-g8278b9b+1,19.0.0-4-g8557e14,19.0.0-4-g8964aba+13,19.0.0-4-ge404a01+12,19.0.0-5-g40f3a5a,19.0.0-5-g4db63b3,19.0.0-5-gfb03ce7+13,19.0.0-6-gbaebbfb+12,19.0.0-61-gec4c6e08+1,19.0.0-7-g039c0b5+11,19.0.0-7-gbea9075+4,19.0.0-7-gc567de5+13,19.0.0-71-g41c0270,19.0.0-9-g2f02add+1,19.0.0-9-g463f923+12,w.2020.22
LSSTDataManagementBasePackage
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 <http://www.gnu.org/licenses/>.
21 import numpy as np
22 
23 import lsst.pex.config as pexConfig
24 import lsst.pipe.base as pipeBase
26 import lsst.afw.math as afwMath
27 import lsst.afw.image as afwImage
28 import lsst.afw.cameraGeom.utils as afwUtils
29 
30 
31 __all__ = ['VisualizeBinExpConfig', 'VisualizeBinExpTask',
32  'VisualizeMosaicExpConfig', 'VisualizeMosaicExpTask']
33 
34 
35 class VisualizeBinExpConnections(pipeBase.PipelineTaskConnections,
36  dimensions=("instrument", "detector")):
37  inputExp = cT.Input(
38  name="calexp",
39  doc="Input exposure data to mosaic.",
40  storageClass="ExposureF",
41  dimensions=("instrument", "detector"),
42  )
43  camera = cT.PrerequisiteInput(
44  name="camera",
45  doc="Input camera to use for mosaic geometry.",
46  storageClass="Camera",
47  dimensions=("instrument", "calibration_label"),
48  )
49 
50  outputExp = cT.Output(
51  name="calexpBin",
52  doc="Output binned image.",
53  storageClass="ExposureF",
54  dimensions=("instrument", "detector"),
55  )
56 
57 
58 class VisualizeBinExpConfig(pipeBase.PipelineTaskConfig,
59  pipelineConnections=VisualizeBinExpConnections):
60  """Configuration for focal plane visualization.
61  """
62  binning = pexConfig.Field(
63  dtype=int,
64  default=8,
65  doc="Binning factor to apply to each input exposure's image data.",
66  )
67  detectorKeyword = pexConfig.Field(
68  dtype=str,
69  default='DET-ID',
70  doc="Metadata keyword to use to find detector if not available from input.",
71  )
72 
73 
74 class VisualizeBinExpTask(pipeBase.PipelineTask,
75  pipeBase.CmdLineTask):
76  """Bin the detectors of an exposure.
77 
78  The outputs of this task should be passed to
79  VisualizeMosaicExpTask to be mosaicked into a full focal plane
80  visualization image.
81  """
82  ConfigClass = VisualizeBinExpConfig
83  _DefaultName = 'VisualizeBinExp'
84 
85  def run(self, inputExp, camera):
86  """Bin input image, attach associated detector.
87 
88  Parameters
89  ----------
90  inputExp : `lsst.afw.image.Exposure`
91  Input exposure data to bin.
92  camera : `lsst.afw.cameraGeom.Camera`
93  Input camera to use for mosaic geometry.
94 
95  Returns
96  -------
97  output : `lsst.pipe.base.Struct`
98  Results struct with attribute:
99 
100  ``outputExp``
101  Binned version of input image (`lsst.afw.image.Exposure`).
102  """
103  if inputExp.getDetector() is None:
104  detectorId = inputExp.getMetadata().get(self.config.detectorKeyword)
105  if detectorId is not None:
106  inputExp.setDetector(camera[detectorId])
107 
108  binned = inputExp.getMaskedImage()
109  binned = afwMath.binImage(binned, self.config.binning)
110  outputExp = afwImage.makeExposure(binned)
111 
112  outputExp.setInfo(inputExp.getInfo())
113  outputExp.setFilter(inputExp.getFilter())
114  outputExp.setMetadata(inputExp.getMetadata())
115  outputExp.setDetector(inputExp.getDetector())
116 
117  return pipeBase.Struct(
118  outputExp=outputExp,
119  )
120 
121 
122 class VisualizeMosaicExpConnections(pipeBase.PipelineTaskConnections,
123  dimensions=("instrument", )):
124  inputExps = cT.Input(
125  name="calexpBin",
126  doc="Input binned images mosaic.",
127  storageClass="ExposureF",
128  dimensions=("instrument", "detector"),
129  multiple=True,
130  )
131  camera = cT.PrerequisiteInput(
132  name="camera",
133  doc="Input camera to use for mosaic geometry.",
134  storageClass="Camera",
135  dimensions=("instrument", "calibration_label"),
136  )
137 
138  outputData = cT.Output(
139  name="calexpFocalPlane",
140  doc="Output binned mosaicked frame.",
141  storageClass="ImageF",
142  dimensions=("instrument", ),
143  )
144 
145 
146 class VisualizeMosaicExpConfig(pipeBase.PipelineTaskConfig,
147  pipelineConnections=VisualizeMosaicExpConnections):
148  """Configuration for focal plane visualization.
149  """
150  binning = pexConfig.Field(
151  dtype=int,
152  default=8,
153  doc="Binning factor previously applied to input exposures.",
154  )
155 
156 
157 class VisualizeMosaicExpTask(pipeBase.PipelineTask,
158  pipeBase.CmdLineTask):
159  """Task to mosaic binned products.
160 
161  The config.binning parameter must match that used in the
162  VisualizeBinExpTask. Otherwise there will be a mismatch between
163  the input image size and the expected size of that image in the
164  full focal plane frame.
165  """
166  ConfigClass = VisualizeMosaicExpConfig
167  _DefaultName = 'VisualizeMosaicExp'
168 
169  def makeCameraImage(self, inputExps, camera, binning):
170  """Make an image of an entire focal plane.
171 
172  Parameters
173  ----------
174  exposures: `dict` [`int`, `lsst.afw.image.Exposure`]
175  CCD exposures, binned by `binning`. The keys are the
176  detectorIDs, with the values the binned image exposure.
177 
178  Returns
179  -------
180  image : `lsst.afw.image.Image`
181  Image mosaicked from the individual binned images for each
182  detector.
183  """
184  image = afwUtils.makeImageFromCamera(
185  camera,
186  imageSource=ImageSource(inputExps),
187  imageFactory=afwImage.ImageF,
188  binSize=binning
189  )
190  return image
191 
192  def run(self, inputExps, camera):
193  """Mosaic inputs together to create focal plane image.
194 
195  Parameters
196  ----------
197  inputExp : `list` [`lsst.afw.image.Exposure`]
198  Input exposure data to bin.
199  camera : `lsst.afw.cameraGeom.Camera`
200  Input camera to use for mosaic geometry.
201 
202  Returns
203  -------
204  output : `lsst.pipe.base.Struct`
205  Results struct with attribute:
206 
207  ``outputExp``
208  Binned version of input image (`lsst.afw.image.Exposure`).
209  """
210  expDict = {exp.getDetector().getId(): exp for exp in inputExps}
211  image = self.makeCameraImage(expDict, camera, self.config.binning)
212 
213  return pipeBase.Struct(
214  outputData=image,
215  )
216 
217 
219  """Source of images for makeImageFromCamera"""
220  def __init__(self, exposures):
221  self.exposures = exposures
222  self.isTrimmed = True
223  self.background = np.nan
224 
225  def getCcdImage(self, detector, imageFactory, binSize):
226  """Provide image of CCD to makeImageFromCamera
227 
228  Parameters
229  ----------
230  detector : `int`
231  Detector ID to get image data for.
232  imageFactory : `lsst.afw.image.Image`
233  Type of image to construct.
234  binSize : `int`
235  Binsize to use to recompute dimensions.
236 
237  Returns
238  -------
239  image : `lsst.afw.image.Image`
240  Appropriately rotated, binned, and transformed
241  image to be mosaicked.
242  detector : `lsst.afw.cameraGeom.Detector`
243  Camera detector that the returned image data
244  belongs to.
245  """
246  detId = detector.getId()
247 
248  if detId not in self.exposures:
249  dims = detector.getBBox().getDimensions()/binSize
250  image = imageFactory(*[int(xx) for xx in dims])
251  image.set(self.background)
252  else:
253  image = self.exposures[detector.getId()]
254  if hasattr(image, "getMaskedImage"):
255  image = image.getMaskedImage()
256  if hasattr(image, "getMask"):
257  mask = image.getMask()
258  isBad = mask.getArray() & mask.getPlaneBitMask("NO_DATA") > 0
259  image = image.clone()
260  image.getImage().getArray()[isBad] = self.background
261  if hasattr(image, "getImage"):
262  image = image.getImage()
263 
264  # afwMath.rotateImageBy90 checks NQuarter values,
265  # so we don't need to here.
266  image = afwMath.rotateImageBy90(image, detector.getOrientation().getNQuarter())
267  return image, detector
lsst::afw::image
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
Definition: imageAlgorithm.dox:1
lsst.pipe.tasks.visualizeVisit.ImageSource.__init__
def __init__(self, exposures)
Definition: visualizeVisit.py:220
lsst::afw::image::makeExposure
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:442
lsst.pipe.tasks.visualizeVisit.ImageSource.exposures
exposures
Definition: visualizeVisit.py:221
lsst.pipe.tasks.visualizeVisit.ImageSource.isTrimmed
isTrimmed
Definition: visualizeVisit.py:222
lsst.pipe.tasks.visualizeVisit.VisualizeBinExpTask
Definition: visualizeVisit.py:75
lsst::afw::cameraGeom.utils
Definition: utils.py:1
lsst.pipe.tasks.visualizeVisit.ImageSource.getCcdImage
def getCcdImage(self, detector, imageFactory, binSize)
Definition: visualizeVisit.py:225
lsst.pipe.tasks.visualizeVisit.VisualizeBinExpConnections
Definition: visualizeVisit.py:36
lsst.pipe.tasks.visualizeVisit.VisualizeMosaicExpTask.run
def run(self, inputExps, camera)
Definition: visualizeVisit.py:192
lsst.pipe.tasks.visualizeVisit.VisualizeMosaicExpTask.makeCameraImage
def makeCameraImage(self, inputExps, camera, binning)
Definition: visualizeVisit.py:169
lsst.pipe.tasks.visualizeVisit.ImageSource.background
background
Definition: visualizeVisit.py:223
lsst.pipe.tasks.visualizeVisit.VisualizeBinExpConfig
Definition: visualizeVisit.py:59
lsst.pipe.tasks.visualizeVisit.ImageSource
Definition: visualizeVisit.py:218
lsst::afw::math::rotateImageBy90
std::shared_ptr< ImageT > rotateImageBy90(ImageT const &image, int nQuarter)
Rotate an image by an integral number of quarter turns.
Definition: rotateImage.cc:39
lsst::afw::math
Definition: statistics.dox:6
lsst::afw::math::binImage
std::shared_ptr< ImageT > binImage(ImageT const &inImage, int const binsize, lsst::afw::math::Property const flags=lsst::afw::math::MEAN)
Definition: binImage.cc:38
lsst.pipe.tasks.visualizeVisit.VisualizeMosaicExpConfig
Definition: visualizeVisit.py:147
lsst.pipe.tasks.visualizeVisit.VisualizeMosaicExpTask
Definition: visualizeVisit.py:158
lsst.pipe.tasks.visualizeVisit.VisualizeBinExpTask.run
def run(self, inputExp, camera)
Definition: visualizeVisit.py:85
lsst.pipe.base
Definition: __init__.py:1
lsst.pipe.base.connectionTypes
Definition: connectionTypes.py:1
lsst.pipe.tasks.visualizeVisit.VisualizeMosaicExpConnections
Definition: visualizeVisit.py:123