22 from __future__
import absolute_import, division, print_function
28 from lsstDebug
import getDebugFrame
31 __all__ = [
"AssembleCcdTask"]
35 doTrim = pexConfig.Field(
36 doc=
"trim out non-data regions?",
40 keysToRemove = pexConfig.ListField(
41 doc=
"FITS headers to remove (in addition to DATASEC, BIASSEC, TRIMSEC and perhaps GAIN)",
56 @anchor AssembleCcdTask_ 58 @brief Assemble a set of amplifier images into a full detector size set of pixels. 60 @section ip_isr_assemble_Contents Contents 62 - @ref ip_isr_assemble_Purpose 63 - @ref ip_isr_assemble_Initialize 64 - @ref ip_isr_assemble_IO 65 - @ref ip_isr_assemble_Config 66 - @ref ip_isr_assemble_Debug 67 - @ref ip_isr_assemble_Example 69 @section ip_isr_assemble_Purpose Description 71 This task assembles sections of an image into a larger mosaic. The sub-sections 72 are typically amplifier sections and are to be assembled into a detector size pixel grid. 73 The assembly is driven by the entries in the raw amp information. The task can be configured 74 to return a detector image with non-data (e.g. overscan) pixels included. The task can also 75 renormalize the pixel values to a nominal gain of 1. The task also removes exposure metadata that 76 has context in raw amps, but not in trimmed detectors (e.g. 'BIASSEC'). 78 @section ip_isr_assemble_Initialize Task initialization 82 @section ip_isr_assemble_IO Inputs/Outputs to the assembleCcd method 86 @section ip_isr_assemble_Config Configuration parameters 88 See @ref AssembleCcdConfig 90 @section ip_isr_assemble_Debug Debug variables 92 The @link lsst.pipe.base.cmdLineTask.CmdLineTask command line task@endlink interface supports a 93 flag @c -d to import @b debug.py from your @c PYTHONPATH; see <a 94 href="http://lsst-web.ncsa.illinois.edu/~buildbot/doxygen/x_masterDoxyDoc/base_debug.html"> 95 Using lsstDebug to control debugging output</a> for more about @b debug.py files. 97 The available variables in AssembleCcdTask are: 100 <DD> A dictionary containing debug point names as keys with frame number as value. Valid keys are: 102 <DT> assembledExposure 103 <DD> display assembled exposure 107 @section ip_isr_assemble_Example A complete example of using AssembleCcdTask 109 This code is in runAssembleTask.py in the examples directory, and can be run as @em e.g. 111 python examples/runAssembleTask.py 114 @dontinclude runAssembleTask.py 115 Import the task. There are other imports. Read the source file for more info. 116 @skipline AssembleCcdTask 118 @dontinclude exampleUtils.py 119 Create some input images with the help of some utilities in examples/exampleUtils.py 120 @skip makeAssemblyInput 122 The above numbers can be changed. The assumption that the readout corner is flipped on every other amp is 123 hardcoded in createDetector. 125 @dontinclude runAssembleTask.py 126 Run the assembler task 131 To investigate the @ref ip_isr_assemble_Debug, put something like 135 di = lsstDebug.getInfo(name) # N.b. lsstDebug.Info(name) would call us recursively 136 if name == "lsst.ip.isr.assembleCcdTask": 137 di.display = {'assembledExposure':2} 140 lsstDebug.Info = DebugInfo 142 into your debug.py file and run runAssembleTask.py with the @c --debug flag. 146 Display code should be updated once we settle on a standard way of controlling what is displayed. 148 ConfigClass = AssembleCcdConfig
149 _DefaultName =
"assembleCcd" 152 """!Initialize the AssembleCcdTask 154 The keys for removal specified in the config are added to a default set: 155 ('DATASEC', 'BIASSEC', 'TRIMSEC', 'GAIN') 157 pipeBase.Task.__init__(self, **kwargs)
159 self.
allKeysToRemove = (
'DATASEC',
'BIASSEC',
'TRIMSEC',
'GAIN') + tuple(self.config.keysToRemove)
162 """!Assemble a set of amps into a single CCD size image 163 @param[in] assembleInput -- Either a dictionary of amp lsst.afw.image.Exposures or a single 164 lsst.afw.image.Exposure containing all raw 165 amps. If a dictionary of amp exposures, 166 the key should be the amp name. 167 @return assembledCcd -- An lsst.afw.image.Exposure of the assembled amp sections. 169 @throws TypeError with the following string: 172 <DT> Expected either a dictionary of amp exposures or a single raw exposure 173 <DD> The input exposures to be assembled do not adhere to the required format. 176 @throws RuntimeError with the following string: 179 <DT> No ccd detector found 180 <DD> The detector set on the input exposure is not set. 184 if isinstance(assembleInput, dict):
188 ccd = next(iter(assembleInput.values())).getDetector()
190 def getNextExposure(amp):
191 return assembleInput[amp.getName()]
192 elif hasattr(assembleInput,
"getMaskedImage"):
194 ccd = assembleInput.getDetector()
196 def getNextExposure(amp):
199 raise TypeError(
"Expected either a dictionary of amp exposures or a single raw exposure")
202 raise RuntimeError(
"No ccd detector found")
204 if not self.config.doTrim:
205 outBox = cameraGeomUtils.calcRawCcdBBox(ccd)
207 outBox = ccd.getBBox()
208 outExposure = afwImage.ExposureF(outBox)
209 outMI = outExposure.getMaskedImage()
211 if self.config.doTrim:
212 assemble = cameraGeom.assembleAmplifierImage
214 assemble = cameraGeom.assembleAmplifierRawImage
217 inMI = getNextExposure(amp).getMaskedImage()
218 assemble(outMI, inMI, amp)
224 if not self.config.doTrim:
225 ccd = cameraGeom.makeUpdatedDetector(ccd)
227 outExposure.setDetector(ccd)
233 """Set exposure non-image attributes, including wcs and metadata and display exposure (if requested) 235 Call after assembling the pixels 237 @param[in,out] outExposure assembled exposure: 238 - removes unwanted keywords 239 - sets calib, filter, and detector 240 @param[in] inExposure input exposure 242 self.
setWcs(outExposure=outExposure, inExposure=inExposure)
244 exposureMetadata = inExposure.getMetadata()
246 if exposureMetadata.exists(key):
247 exposureMetadata.remove(key)
248 outExposure.setMetadata(exposureMetadata)
251 outExposure.setFilter(inExposure.getFilter())
252 outExposure.getInfo().setVisitInfo(inExposure.getInfo().getVisitInfo())
254 frame = getDebugFrame(self._display,
"assembledExposure")
256 getDisplay(frame).mtv(outExposure)
258 def setWcs(self, outExposure, inExposure):
259 """Set output WCS = input WCS, adjusted as required for datasecs not starting at lower left corner 261 @param[in,out] outExposure assembled exposure; wcs is set 262 @param[in] inExposure input exposure 264 if inExposure.hasWcs():
265 wcs = inExposure.getWcs()
266 ccd = outExposure.getDetector()
269 raise RuntimeError(
"No amplifier detector information found")
270 adjustedWcs = cameraGeomUtils.prepareWcsData(wcs, amp0, isTrimmed=self.config.doTrim)
271 outExposure.setWcs(adjustedWcs)
Assemble a set of amplifier images into a full detector size set of pixels.
def setWcs(self, outExposure, inExposure)
def __init__(self, kwargs)
Initialize the AssembleCcdTask.
def postprocessExposure(self, outExposure, inExposure)
def assembleCcd(self, assembleInput)
Assemble a set of amps into a single CCD size image.