LSST Applications  21.0.0-147-g0e635eb1+1acddb5be5,22.0.0+052faf71bd,22.0.0+1ea9a8b2b2,22.0.0+6312710a6c,22.0.0+729191ecac,22.0.0+7589c3a021,22.0.0+9f079a9461,22.0.1-1-g7d6de66+b8044ec9de,22.0.1-1-g87000a6+536b1ee016,22.0.1-1-g8e32f31+6312710a6c,22.0.1-10-gd060f87+016f7cdc03,22.0.1-12-g9c3108e+df145f6f68,22.0.1-16-g314fa6d+c825727ab8,22.0.1-19-g93a5c75+d23f2fb6d8,22.0.1-19-gb93eaa13+aab3ef7709,22.0.1-2-g8ef0a89+b8044ec9de,22.0.1-2-g92698f7+9f079a9461,22.0.1-2-ga9b0f51+052faf71bd,22.0.1-2-gac51dbf+052faf71bd,22.0.1-2-gb66926d+6312710a6c,22.0.1-2-gcb770ba+09e3807989,22.0.1-20-g32debb5+b8044ec9de,22.0.1-23-gc2439a9a+fb0756638e,22.0.1-3-g496fd5d+09117f784f,22.0.1-3-g59f966b+1e6ba2c031,22.0.1-3-g849a1b8+f8b568069f,22.0.1-3-gaaec9c0+c5c846a8b1,22.0.1-32-g5ddfab5d3+60ce4897b0,22.0.1-4-g037fbe1+64e601228d,22.0.1-4-g8623105+b8044ec9de,22.0.1-5-g096abc9+d18c45d440,22.0.1-5-g15c806e+57f5c03693,22.0.1-7-gba73697+57f5c03693,master-g6e05de7fdc+c1283a92b8,master-g72cdda8301+729191ecac,w.2021.39
LSST Data Management Base Package
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 
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_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_storedButler:
124  pool.storeSet(butler=expRef.getButler())
125 
126  with self.logOperationlogOperation("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.readImagereadImage, 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 logOperation(self, operation, catch=False, trace=True)
Provide a context manager for logging an operation.
Definition: parallel.py:502
def batchWallTime(cls, time, parsedCmd, numCores)
def makeImageFromCamera(camera, detectorNameList=None, background=numpy.nan, bufferSize=10, imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageU, binSize=1)
Definition: utils.py:857
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
std::shared_ptr< ImageT > rotateImageBy90(ImageT const &image, int nQuarter)
Rotate an image by an integral number of quarter turns.
Definition: rotateImage.cc:39
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
def makeCameraImage(camera, exposures, binning)