lsst.pipe.drivers gef6abdcebb+c31c1e6b5f
visualizeVisit.py
Go to the documentation of this file.
1import numpy as np
2
3import lsst.afw.math as afwMath
4import lsst.afw.image as afwImage
5
6from lsst.afw.cameraGeom.utils import makeImageFromCamera
7from lsst.pipe.base import ArgumentParser
8from lsst.pex.config import Config, Field
9from lsst.ctrl.pool.pool import Pool
10from lsst.ctrl.pool.parallel import BatchPoolTask
11
12
13def makeCameraImage(camera, exposures, binning):
14 """Make and write an image of an entire focal plane
15
16 Parameters
17 ----------
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.
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)
def batchWallTime(cls, time, parsedCmd, numCores)
def makeCameraImage(camera, exposures, binning)