lsst.pipe.drivers  6.0b0-hsc-16-geaac007+3
visualizeVisit.py
Go to the documentation of this file.
1 from __future__ import absolute_import, division, print_function
2 
3 import numpy as np
4 
5 import lsst.afw.math as afwMath
6 import lsst.afw.image as afwImage
7 
8 from lsst.afw.cameraGeom.utils import makeImageFromCamera
9 from lsst.pipe.base import ArgumentParser
10 from lsst.pex.config import Config, Field
11 from lsst.ctrl.pool.pool import Pool
12 from lsst.ctrl.pool.parallel import BatchPoolTask
13 
14 
15 def makeCameraImage(camera, exposures, binning):
16  """Make and write an image of an entire focal plane
17 
18  Parameters
19  ----------
20  camera : `lsst.afw.cameraGeom.Camera`
21  Camera description.
22  exposures : `dict` mapping detector ID to `lsst.afw.image.Exposure`
23  CCD exposures, binned by `binning`.
24  binning : `int`
25  Binning size that has been applied to images.
26  """
27  class ImageSource(object):
28  """Source of images for makeImageFromCamera"""
29  def __init__(self, exposures):
30  """Constructor
31 
32  Parameters
33  ----------
34  exposures : `dict` mapping detector ID to `lsst.afw.image.Exposure`
35  CCD exposures, already binned.
36  """
37  self.isTrimmed = True
38  self.exposures = exposures
39  self.background = np.nan
40 
41  def getCcdImage(self, detector, imageFactory, binSize):
42  """Provide image of CCD to makeImageFromCamera"""
43  if detector.getId() not in self.exposures:
44  return imageFactory(1, 1), detector
45  image = self.exposures[detector.getId()]
46  if hasattr(image, "getMaskedImage"):
47  image = image.getMaskedImage()
48  if hasattr(image, "getMask"):
49  mask = image.getMask()
50  isBad = mask.getArray() & mask.getPlaneBitMask("NO_DATA") > 0
51  image = image.clone()
52  image.getImage().getArray()[isBad] = self.background
53  if hasattr(image, "getImage"):
54  image = image.getImage()
55  return image, detector
56 
57  image = makeImageFromCamera(
58  camera,
59  imageSource=ImageSource(exposures),
60  imageFactory=afwImage.ImageF,
61  binSize=binning
62  )
63  return image
64 
65 
66 class VisualizeVisitConfig(Config):
67  binning = Field(dtype=int, default=8, doc="Binning factor to apply")
68 
69 
71  ConfigClass = VisualizeVisitConfig
72  _DefaultName = "visualizeVisit"
73 
74  def __init__(self, *args, **kwargs):
75  BatchPoolTask.__init__(self, *args, **kwargs)
76  self._storedButler = False # Stored butler in the Pool? Doing this once increases efficiency
77 
78  @classmethod
79  def _makeArgumentParser(cls, *args, **kwargs):
80  kwargs.pop("doBatch", False)
81  parser = ArgumentParser(name="visualizeVisit", *args, **kwargs)
82  parser.add_id_argument("--id", datasetType="calexp", level="visit",
83  help="data ID, e.g. --id visit=12345")
84  return parser
85 
86  @classmethod
87  def batchWallTime(cls, time, parsedCmd, numCores):
88  """Return walltime request for batch job
89 
90  Subclasses should override if the walltime should be calculated
91  differently (e.g., addition of some serial time).
92 
93  Parameters
94  ----------
95  time : `float`
96  Requested time per iteration.
97  parsedCmd : `argparse.Namespace`
98  Results of argument parsing.
99  numCores : `int`
100  Number of cores.
101  """
102  numTargets = len(cls.RunnerClass.getTargetList(parsedCmd))
103  return time*numTargets
104 
105  def run(self, expRef):
106  """Generate an image of the entire visit
107 
108  Only the master node executes this method; it controls the slave nodes,
109  which do the data retrieval.
110 
111  Parameters
112  ----------
113  expRef : `lsst.daf.persistence.ButlerDataRef`
114  Data reference for exposure.
115  """
116  pool = Pool()
117 
118  if not self._storedButler:
119  pool.storeSet(butler=expRef.getButler())
120 
121  with self.logOperation("processing %s" % (expRef.dataId,)):
122  camera = expRef.get("camera")
123  dataIdList = [ccdRef.dataId for ccdRef in expRef.subItems("ccd") if
124  ccdRef.datasetExists("calexp")]
125 
126  exposures = pool.map(self.readImage, dataIdList)
127  exposures = dict(keyValue for keyValue in exposures if keyValue is not None)
128  image = makeCameraImage(camera, exposures, self.config.binning)
129  expRef.put(image, "calexp_camera")
130 
131  def readImage(self, cache, dataId):
132  """Collect original image for visualisation
133 
134  This method runs on the slave nodes.
135 
136  Parameters
137  ----------
138  cache : `lsst.pipe.base.Struct`
139  Process pool cache.
140  dataId : `dict`
141  Data identifier.
142 
143  Returns
144  -------
145  detId : `int`
146  Detector identifier.
147  image : `lsst.afw.image.MaskedImage`
148  Binned image.
149  """
150  exposure = cache.butler.get("calexp", dataId)
151  return (exposure.getDetector().getId(),
152  afwMath.binImage(exposure.getMaskedImage(), self.config.binning))
153 
154  def _getConfigName(self):
155  """It's not worth preserving the configuration"""
156  return None
157 
158  def _getMetadataName(self):
159  """There's no metadata to write out"""
160  return None
def batchWallTime(cls, time, parsedCmd, numCores)
def logOperation(self, operation, catch=False, trace=True)
def makeCameraImage(camera, exposures, binning)