LSSTApplications  19.0.0+10,19.0.0+80,19.0.0-1-g20d9b18+31,19.0.0-1-g49a97f9+4,19.0.0-1-g8c57eb9+31,19.0.0-1-g9a028c0+13,19.0.0-1-ga72da6b+3,19.0.0-1-gb77924a+15,19.0.0-1-gbfe0924+66,19.0.0-1-gc3516c3,19.0.0-1-gefe1d0d+49,19.0.0-1-gf8cb8b4+3,19.0.0-14-g7511ce4+6,19.0.0-16-g3dc1a33c+6,19.0.0-17-g59f0e8a+4,19.0.0-17-g9c22e3c+9,19.0.0-18-g35bb99870+2,19.0.0-19-g2772d4a+9,19.0.0-2-g260436e+53,19.0.0-2-g31cdcee,19.0.0-2-g9675b69+3,19.0.0-2-gaa2795f,19.0.0-2-gbcc4de1,19.0.0-2-gd6f004e+6,19.0.0-2-gde8e5e3+5,19.0.0-2-gff6972b+15,19.0.0-21-ge306cd8,19.0.0-21-gf122e69+2,19.0.0-3-g2d43a51+2,19.0.0-3-gf3b1435+6,19.0.0-4-g56feb96,19.0.0-4-gac56cce+17,19.0.0-49-gce872c1+1,19.0.0-5-g66946eb+6,19.0.0-5-gd8897ba+6,19.0.0-51-gfc4a647e,19.0.0-7-g686a884+5,19.0.0-7-g886f805+5,19.0.0-8-g305ff64,w.2020.17
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 __init__(self, required=False, helpMsg=None)
Definition: instrument.py:27
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)