LSSTApplications  18.0.0+69,19.0.0+5,19.0.0+58,19.0.0+69,19.0.0+9,19.0.0-1-g20d9b18+25,19.0.0-1-g49a97f9+3,19.0.0-1-g5549ca4+4,19.0.0-1-g8c57eb9+25,19.0.0-1-g9a028c0+4,19.0.0-1-ga72da6b+3,19.0.0-1-gb77924a+5,19.0.0-1-gbfe0924+56,19.0.0-1-gd0f30f5+5,19.0.0-1-ge272bc4+25,19.0.0-1-gefe1d0d+40,19.0.0-11-g57ef05f+7,19.0.0-12-g076c4364+3,19.0.0-14-g706b86db4+3,19.0.0-14-gb19e6fb+3,19.0.0-17-g9c22e3c,19.0.0-18-g2c901ce,19.0.0-18-g80ee988,19.0.0-18-gef3cd1a+3,19.0.0-2-g0d9f9cd+64,19.0.0-2-g260436e+44,19.0.0-2-g361aba8+5,19.0.0-2-g9675b69+3,19.0.0-2-gde8e5e3+3,19.0.0-2-gff6972b+9,19.0.0-3-ga642a0f,19.0.0-4-g33ce3a3+6,19.0.0-4-gac56cce+7,19.0.0-4-gdb4f201+5,19.0.0-45-g25df2313,19.0.0-45-ge80c878,19.0.0-5-g50cbe22+1,19.0.0-7-g3343160,19.0.0-7-g686a884+4,w.2020.16
LSSTDataManagementBasePackage
visualizeVisit.py
Go to the documentation of this file.
1 import numpy as np
2 
3 import lsst.afw.math as afwMath
4 import lsst.afw.image as afwImage
5 
6 from lsst.afw.cameraGeom.utils import makeImageFromCamera
7 from lsst.pipe.base import ArgumentParser
8 from lsst.pex.config import Config, Field
9 from lsst.ctrl.pool.pool import Pool
10 from lsst.ctrl.pool.parallel import BatchPoolTask
11 
12 
13 def makeCameraImage(camera, exposures, binning):
14  """Make and write an image of an entire focal plane
15 
16  Parameters
17  ----------
18  camera : `lsst.afw.cameraGeom.Camera`
19  Camera description.
20  exposures : `dict` mapping detector ID to `lsst.afw.image.Exposure`
21  CCD exposures, binned by `binning`.
22  binning : `int`
23  Binning size that has been applied to images.
24  """
25  class ImageSource:
26  """Source of images for makeImageFromCamera"""
27  def __init__(self, exposures):
28  """Constructor
29 
30  Parameters
31  ----------
32  exposures : `dict` mapping detector ID to `lsst.afw.image.Exposure`
33  CCD exposures, already binned.
34  """
35  self.isTrimmed = True
36  self.exposures = exposures
37  self.background = np.nan
38 
39  def getCcdImage(self, detector, imageFactory, binSize):
40  """Provide image of CCD to makeImageFromCamera"""
41  detId = detector.getId()
42  if detId not in self.exposures:
43  dims = detector.getBBox().getDimensions()/binSize
44  image = imageFactory(*[int(xx) for xx in dims])
45  image.set(self.background)
46  else:
47  image = self.exposures[detector.getId()]
48  if hasattr(image, "getMaskedImage"):
49  image = image.getMaskedImage()
50  if hasattr(image, "getMask"):
51  mask = image.getMask()
52  isBad = mask.getArray() & mask.getPlaneBitMask("NO_DATA") > 0
53  image = image.clone()
54  image.getImage().getArray()[isBad] = self.background
55  if hasattr(image, "getImage"):
56  image = image.getImage()
57 
58  image = afwMath.rotateImageBy90(image, detector.getOrientation().getNQuarter())
59 
60  return image, detector
61 
62  image = makeImageFromCamera(
63  camera,
64  imageSource=ImageSource(exposures),
65  imageFactory=afwImage.ImageF,
66  binSize=binning
67  )
68  return image
69 
70 
71 class VisualizeVisitConfig(Config):
72  binning = Field(dtype=int, default=8, doc="Binning factor to apply")
73 
74 
76  ConfigClass = VisualizeVisitConfig
77  _DefaultName = "visualizeVisit"
78 
79  def __init__(self, *args, **kwargs):
80  BatchPoolTask.__init__(self, *args, **kwargs)
81  self._storedButler = False # Stored butler in the Pool? Doing this once increases efficiency
82 
83  @classmethod
84  def _makeArgumentParser(cls, *args, **kwargs):
85  kwargs.pop("doBatch", False)
86  parser = ArgumentParser(name="visualizeVisit", *args, **kwargs)
87  parser.add_id_argument("--id", datasetType="calexp", level="visit",
88  help="data ID, e.g. --id visit=12345")
89  return parser
90 
91  @classmethod
92  def batchWallTime(cls, time, parsedCmd, numCores):
93  """Return walltime request for batch job
94 
95  Subclasses should override if the walltime should be calculated
96  differently (e.g., addition of some serial time).
97 
98  Parameters
99  ----------
100  time : `float`
101  Requested time per iteration.
102  parsedCmd : `argparse.Namespace`
103  Results of argument parsing.
104  numCores : `int`
105  Number of cores.
106  """
107  numTargets = len(cls.RunnerClass.getTargetList(parsedCmd))
108  return time*numTargets
109 
110  def runDataRef(self, expRef):
111  """Generate an image of the entire visit
112 
113  Only the master node executes this method; it controls the slave nodes,
114  which do the data retrieval.
115 
116  Parameters
117  ----------
118  expRef : `lsst.daf.persistence.ButlerDataRef`
119  Data reference for exposure.
120  """
121  pool = Pool()
122 
123  if not self._storedButler:
124  pool.storeSet(butler=expRef.getButler())
125 
126  with self.logOperation("processing %s" % (expRef.dataId,)):
127  camera = expRef.get("camera")
128  dataIdList = [ccdRef.dataId for ccdRef in expRef.subItems("ccd") if
129  ccdRef.datasetExists("calexp")]
130 
131  exposures = pool.map(self.readImage, dataIdList)
132  exposures = dict(keyValue for keyValue in exposures if keyValue is not None)
133  image = makeCameraImage(camera, exposures, self.config.binning)
134  expRef.put(image, "calexp_camera")
135 
136  def readImage(self, cache, dataId):
137  """Collect original image for visualisation
138 
139  This method runs on the slave nodes.
140 
141  Parameters
142  ----------
143  cache : `lsst.pipe.base.Struct`
144  Process pool cache.
145  dataId : `dict`
146  Data identifier.
147 
148  Returns
149  -------
150  detId : `int`
151  Detector identifier.
152  image : `lsst.afw.image.MaskedImage`
153  Binned image.
154  """
155  exposure = cache.butler.get("calexp", dataId)
156  return (exposure.getDetector().getId(),
157  afwMath.binImage(exposure.getMaskedImage(), self.config.binning))
158 
159  def _getConfigName(self):
160  """It's not worth preserving the configuration"""
161  return None
162 
163  def _getMetadataName(self):
164  """There's no metadata to write out"""
165  return None
def makeImageFromCamera(camera, detectorNameList=None, background=numpy.nan, bufferSize=10, imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageU, binSize=1)
Definition: utils.py:865
std::shared_ptr< ImageT > rotateImageBy90(ImageT const &image, int nQuarter)
Rotate an image by an integral number of quarter turns.
Definition: rotateImage.cc:39
def batchWallTime(cls, time, parsedCmd, numCores)
def logOperation(self, operation, catch=False, trace=True)
Provide a context manager for logging an operation.
Definition: parallel.py:502
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
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects...
def makeCameraImage(camera, exposures, binning)