LSSTApplications  17.0+124,17.0+14,17.0+73,18.0.0+37,18.0.0+80,18.0.0-4-g68ffd23+4,18.1.0-1-g0001055+12,18.1.0-1-g03d53ef+5,18.1.0-1-g1349e88+55,18.1.0-1-g2505f39+44,18.1.0-1-g5315e5e+4,18.1.0-1-g5e4b7ea+14,18.1.0-1-g7e8fceb+4,18.1.0-1-g85f8cd4+48,18.1.0-1-g8ff0b9f+4,18.1.0-1-ga2c679d+1,18.1.0-1-gd55f500+35,18.1.0-10-gb58edde+2,18.1.0-11-g0997b02+4,18.1.0-13-gfe4edf0b+12,18.1.0-14-g259bd21+21,18.1.0-19-gdb69f3f+2,18.1.0-2-g5f9922c+24,18.1.0-2-gd3b74e5+11,18.1.0-2-gfbf3545+32,18.1.0-26-g728bddb4+5,18.1.0-27-g6ff7ca9+2,18.1.0-3-g52aa583+25,18.1.0-3-g8ea57af+9,18.1.0-3-gb69f684+42,18.1.0-3-gfcaddf3+6,18.1.0-32-gd8786685a,18.1.0-4-gf3f9b77+6,18.1.0-5-g1dd662b+2,18.1.0-5-g6dbcb01+41,18.1.0-6-gae77429+3,18.1.0-7-g9d75d83+9,18.1.0-7-gae09a6d+30,18.1.0-9-gc381ef5+4,w.2019.45
LSSTDataManagementBasePackage
assembleImage.py
Go to the documentation of this file.
1 # This file is part of afw.
2 #
3 # Developed for the LSST Data Management System.
4 # This product includes software developed by the LSST Project
5 # (https://www.lsst.org).
6 # See the COPYRIGHT file at the top-level directory of this distribution
7 # for details of code ownership.
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <https://www.gnu.org/licenses/>.
21 
22 __all__ = ['assembleAmplifierImage', 'assembleAmplifierRawImage',
23  'makeUpdatedDetector']
24 
25 import lsst.geom
26 
27 # dict of doFlip: slice
28 _SliceDict = {
29  False: slice(None, None, 1),
30  True: slice(None, None, -1),
31 }
32 
33 
34 def _insertPixelChunk(outView, inView, amplifier, hasArrays):
35  # For the sake of simplicity and robustness, this code does not short-circuit the case flipX=flipY=False.
36  # However, it would save a bit of time, including the cost of making numpy array views.
37  # If short circuiting is wanted, do it here.
38 
39  xSlice = _SliceDict[amplifier.getRawFlipX()]
40  ySlice = _SliceDict[amplifier.getRawFlipY()]
41  if hasArrays:
42  # MaskedImage
43  inArrList = inView.getArrays()
44  outArrList = outView.getArrays()
45  else:
46  inArrList = [inView.getArray()]
47  outArrList = [outView.getArray()]
48 
49  for inArr, outArr in zip(inArrList, outArrList):
50  # y,x because numpy arrays are transposed w.r.t. afw Images
51  outArr[:] = inArr[ySlice, xSlice]
52 
53 
54 def assembleAmplifierImage(destImage, rawImage, amplifier):
55  """Assemble the amplifier region of an image from a raw image.
56 
57  Parameters
58  ----------
59  destImage : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage`
60  Assembled image; the region amplifier.getBBox() is overwritten with
61  the assembled amplifier image.
62  rawImage : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage`
63  Raw image (same type as destImage).
64  amplifier : `lsst.afw.cameraGeom.Amplifier`
65  Amplifier geometry, with raw amplifier info.
66 
67  Raises
68  ------
69  RuntimeError
70  Raised if image types do not match or amplifier has no raw amplifier info.
71  """
72  if not amplifier.getHasRawInfo():
73  raise RuntimeError("amplifier must contain raw amplifier info")
74  if type(destImage.Factory) != type(rawImage.Factory): # noqa: E721
75  raise RuntimeError("destImage type = %s != %s = rawImage type" %
76  type(destImage.Factory).__name__, type(rawImage.Factory).__name__)
77  inView = rawImage.Factory(rawImage, amplifier.getRawDataBBox())
78  outView = destImage.Factory(destImage, amplifier.getBBox())
79 
80  _insertPixelChunk(outView, inView, amplifier,
81  hasattr(rawImage, "getArrays"))
82 
83 
84 def assembleAmplifierRawImage(destImage, rawImage, amplifier):
85  """Assemble the amplifier region of a raw CCD image.
86 
87  For most cameras this is a no-op: the raw image already is an assembled
88  CCD image.
89  However, it is useful for camera such as LSST for which each amplifier
90  image is a separate image.
91 
92  Parameters
93  ----------
94  destImage : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage`
95  CCD Image; the region amplifier.getRawAmplifier().getBBox()
96  is overwritten with the raw amplifier image.
97  rawImage : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage`
98  Raw image (same type as destImage).
99  amplifier : `lsst.afw.cameraGeom.Amplifier`
100  Amplifier geometry with raw amplifier info
101 
102  Raises
103  ------
104  RuntimeError
105  Raised if image types do not match or amplifier has no raw amplifier info.
106  """
107  if not amplifier.getHasRawInfo():
108  raise RuntimeError("amplifier must contain raw amplifier info")
109  if type(destImage.Factory) != type(rawImage.Factory): # noqa: E721
110  raise RuntimeError("destImage type = %s != %s = rawImage type" %
111  type(destImage.Factory).__name__, type(rawImage.Factory).__name__)
112  inBBox = amplifier.getRawBBox()
113  inView = rawImage.Factory(rawImage, inBBox)
114  outBBox = amplifier.getRawBBox()
115  outBBox.shift(amplifier.getRawXYOffset())
116  outView = destImage.Factory(destImage, outBBox)
117 
118  _insertPixelChunk(outView, inView, amplifier,
119  hasattr(rawImage, "getArrays"))
120 
121 
123  """Return a Detector that has had the definitions of amplifier geometry
124  updated post assembly.
125 
126  Parameters
127  ----------
128  ccd : `lsst.afw.image.Detector`
129  The detector to copy and update.
130  """
131  builder = ccd.rebuild()
132  for amp in builder.getAmplifiers():
133  assert amp.getHasRawInfo()
134 
135  bbox = amp.getRawBBox()
136  awidth, aheight = bbox.getDimensions()
137  #
138  # Figure out how far flipping the amp LR and/or TB offsets the bboxes
139  #
140  boxMin0 = bbox.getMin() # initial position of rawBBox's LLC corner
141  if amp.getRawFlipX():
142  bbox.flipLR(awidth)
143  if amp.getRawFlipY():
144  bbox.flipTB(aheight)
145  shift = boxMin0 - bbox.getMin()
146 
147  for bboxName in ("",
148  "HorizontalOverscan",
149  "Data",
150  "VerticalOverscan",
151  "Prescan"):
152  bbox = getattr(amp, "getRaw%sBBox" % bboxName)()
153  if amp.getRawFlipX():
154  bbox.flipLR(awidth)
155  if amp.getRawFlipY():
156  bbox.flipTB(aheight)
157  bbox.shift(amp.getRawXYOffset() + shift)
158 
159  getattr(amp, "setRaw%sBBox" % bboxName)(bbox)
160  #
161  # All of these have now been transferred to the per-amp geometry
162  #
163  amp.setRawXYOffset(lsst.geom.ExtentI(0, 0))
164  amp.setRawFlipX(False)
165  amp.setRawFlipY(False)
166 
167  return builder.finish()
table::Key< int > type
Definition: Detector.cc:163
def assembleAmplifierImage(destImage, rawImage, amplifier)
def assembleAmplifierRawImage(destImage, rawImage, amplifier)