23 Support for displaying cameraGeom objects.
26 __all__ = [
'prepareWcsData',
'plotFocalPlane',
'makeImageFromAmp',
'calcRawCcdBBox',
'makeImageFromCcd',
27 'FakeImageDataSource',
'ButlerImage',
'rawCallback',
'overlayCcdBoxes',
28 'showAmp',
'showCcd',
'getCcdInCamBBoxList',
'getCameraImageBBox',
29 'makeImageFromCamera',
'showCamera',
'makeFocalPlaneWcs',
'findAmp']
44 from ._rotateBBoxBy90
import rotateBBoxBy90
45 from ._assembleImage
import assembleAmplifierImage, assembleAmplifierRawImage
46 from ._cameraGeom
import FIELD_ANGLE, FOCAL_PLANE
55 """Put Wcs from an Amp image into CCD coordinates
59 wcs : `lsst.afw.geom.SkyWcs`
60 The WCS object to start from.
61 amp : `lsst.afw.table.AmpInfoRecord`
64 Is the image to which the WCS refers trimmed of non-imaging pixels?
68 ampWcs : `lsst.afw.geom.SkyWcs`
72 ampBox = amp.getRawDataBBox()
74 ampBox = amp.getRawBBox()
79 trim_shift = ampBox.getMin() - amp.getBBox().getMin()
80 wcs = wcs.copyAtShiftedPixelOrigin(
lsst.geom.Extent2D(-trim_shift.getX(), -trim_shift.getY()))
82 offset = amp.getRawXYOffset()
86 def plotFocalPlane(camera, fieldSizeDeg_x=0, fieldSizeDeg_y=None, dx=0.1, dy=0.1, figsize=(10., 10.),
87 useIds=
False, showFig=
True, savePath=
None):
88 """Make a plot of the focal plane along with a set points that sample
93 camera : `lsst.afw.cameraGeom.Camera`
95 fieldSizeDeg_x : `float`
96 Amount of the field to sample in x in degrees
97 fieldSizeDeg_y : `float` or `None`
98 Amount of the field to sample in y in degrees
100 Spacing of sample points in x in degrees
102 Spacing of sample points in y in degrees
103 figsize : `tuple` containing two `float`
104 Matplotlib style tuple indicating the size of the figure in inches
106 Label detectors by name, not id?
108 Display the figure on the screen?
109 savePath : `str` or `None`
110 If not `None`, save a copy of the figure to this name.
113 from matplotlib.patches
import Polygon
114 from matplotlib.collections
import PatchCollection
115 import matplotlib.pyplot
as plt
118 "Can't run plotFocalPlane: matplotlib has not been set up")
121 if fieldSizeDeg_y
is None:
122 fieldSizeDeg_y = fieldSizeDeg_x
124 field_gridx, field_gridy = numpy.meshgrid(
125 numpy.arange(0., fieldSizeDeg_x + dx, dx) - fieldSizeDeg_x/2.,
126 numpy.arange(0., fieldSizeDeg_y + dy, dy) - fieldSizeDeg_y/2.)
127 field_gridx, field_gridy = field_gridx.flatten(), field_gridy.flatten()
129 field_gridx, field_gridy = [], []
137 for x, y
in zip(field_gridx, field_gridy)]
138 posFocalPlaneList = camera.transform(posFieldAngleList, FIELD_ANGLE, FOCAL_PLANE)
139 for posFocalPlane
in posFocalPlaneList:
140 xs.append(posFocalPlane.getX())
141 ys.append(posFocalPlane.getY())
142 dets = camera.findDetectors(posFocalPlane, FOCAL_PLANE)
148 colorMap = {DetectorType.SCIENCE:
'b', DetectorType.FOCUS:
'y',
149 DetectorType.GUIDER:
'g', DetectorType.WAVEFRONT:
'r'}
153 plt.figure(figsize=figsize)
158 corners = [(c.getX(), c.getY())
for c
in det.getCorners(FOCAL_PLANE)]
159 for corner
in corners:
160 xvals.append(corner[0])
161 yvals.append(corner[1])
162 colors.append(colorMap[det.getType()])
163 patches.append(Polygon(corners,
True))
164 center = det.getOrientation().getFpPosition()
165 ax.text(center.getX(), center.getY(), det.getId()
if useIds
else det.getName(),
166 horizontalalignment=
'center', size=6)
168 patchCollection = PatchCollection(patches, alpha=0.6, facecolor=colors)
169 ax.add_collection(patchCollection)
170 ax.scatter(xs, ys, s=10, alpha=.7, linewidths=0., c=pcolors)
171 ax.set_xlim(
min(xvals) -
abs(0.1*
min(xvals)),
173 ax.set_ylim(
min(yvals) -
abs(0.1*
min(yvals)),
175 ax.set_xlabel(
'Focal Plane X (mm)')
176 ax.set_ylabel(
'Focal Plane Y (mm)')
177 if savePath
is not None:
178 plt.savefig(savePath)
183 def makeImageFromAmp(amp, imValue=None, imageFactory=afwImage.ImageU, markSize=10, markValue=0,
184 scaleGain=lambda gain: (gain*1000)//10):
185 """Make an image from an amp object.
187 Since images are integer images by default, the gain needs to be scaled to
188 give enough dynamic range to see variation from amp to amp.
189 The scaling algorithm is assignable.
193 amp : `lsst.afw.table.AmpInfoRecord`
194 Amp record to use for constructing the raw amp image.
195 imValue : `float` or `None`
196 Value to assign to the constructed image, or scaleGain(gain) if `None`.
197 imageFactory : callable like `lsst.afw.image.Image`
198 Type of image to construct.
200 Size of mark at read corner in pixels.
202 Value of pixels in the read corner mark.
204 The function by which to scale the gain (must take a single argument).
208 ampImage : `lsst.afw.image`
209 An untrimmed amp image, of the type produced by ``imageFactory``.
211 bbox = amp.getRawBBox()
212 dbbox = amp.getRawDataBBox()
213 img = imageFactory(bbox)
215 img.set(int(scaleGain(amp.getGain())))
220 if amp.getReadoutCorner() == afwCameraGeom.ReadoutCorner.LL:
221 markbbox.include(dbbox.getMin())
223 elif amp.getReadoutCorner() == afwCameraGeom.ReadoutCorner.LR:
225 markbbox.include(cornerPoint)
227 elif amp.getReadoutCorner() == afwCameraGeom.ReadoutCorner.UR:
229 markbbox.include(cornerPoint)
231 elif amp.getReadoutCorner() == afwCameraGeom.ReadoutCorner.UL:
233 markbbox.include(cornerPoint)
236 raise RuntimeError(
"Could not set readout corner")
237 mimg = imageFactory(img, markbbox)
243 """Calculate the raw ccd bounding box.
247 ccd : `lsst.afw.cameraGeom.Detector`
248 Detector for which to calculate the un-trimmed bounding box.
252 bbox : `lsst.geom.Box2I` or `None`
253 Bounding box of the un-trimmed Detector, or `None` if there is not enough
254 information to calculate raw BBox.
258 tbbox = amp.getRawBBox()
259 tbbox.shift(amp.getRawXYOffset())
264 def makeImageFromCcd(ccd, isTrimmed=True, showAmpGain=True, imageFactory=afwImage.ImageU, rcMarkSize=10,
266 """Make an Image of a CCD.
270 ccd : `lsst.afw.cameraGeom.Detector`
271 Detector to use in making the image.
273 Assemble a trimmed Detector image.
275 Use the per-amp gain to color the pixels in the image?
276 imageFactory : callable like `lsst.afw.image.Image`
277 Image type to generate.
279 Size of the mark to make in the amp images at the read corner.
281 Bin the image by this factor in both dimensions.
285 image : `lsst.afw.image.Image`
286 Image of the Detector (type returned by ``imageFactory``).
297 amp, imageFactory=imageFactory, markSize=rcMarkSize))
300 imageFactory=imageFactory, markSize=rcMarkSize))
303 if len(ampImages) > 0:
304 ccdImage = imageFactory(bbox)
305 for ampImage, amp
in zip(ampImages, ccd):
313 "Cannot create untrimmed CCD without amps with raw information")
314 ccdImage = imageFactory(ccd.getBBox())
320 """A class to retrieve synthetic images for display by the show* methods
325 Should amps be trimmed?
329 The value of any pixels that lie outside the CCDs.
331 Color the amp segments with the gain of the amp?
333 Size of the side of the box used to mark the read corner.
335 Value to assign the read corner mark.
336 ampImValue : `float` or `None`
337 Value to assign to amps; scaleGain(gain) is used if `None`.
339 Function to scale the gain by.
341 def __init__(self, isTrimmed=True, verbose=False, background=numpy.nan,
342 showAmpGain=True, markSize=10, markValue=0,
343 ampImValue=None, scaleGain=lambda gain: (gain*1000)//10):
354 """Return a CCD image for the detector and the (possibly updated) Detector.
358 det : `lsst.afw.cameraGeom.Detector`
359 Detector to use for making the image.
360 imageFactory : callable like `lsst.afw.image.Image`
361 Image constructor for making the image.
363 Bin the image by this factor in both dimensions.
367 ccdImage : `lsst.afw.image.Image`
368 The constructed image.
371 imageFactory=imageFactory, binSize=binSize)
375 """Return an amp segment image.
379 amp : `lsst.afw.table.AmpInfoTable`
380 AmpInfoTable for this amp.
381 imageFactory : callable like `lsst.afw.image.Image`
382 Image constructor for making the image.
386 ampImage : `lsst.afw.image.Image`
387 The constructed image.
393 ampImage = ampImage.Factory(ampImage, amp.getRawDataBBox())
398 """A class to return an Image of a given Ccd using the butler.
402 butler : `lsst.daf.persistence.Butler` or `None`
403 The butler to use. If `None`, an empty image is returned.
405 The type of image to read (e.g. raw, bias, flat, calexp).
407 If true, the showCamera command expects to be given trimmed images.
409 Be chatty (in particular, log any error messages from the butler)?
411 The value of any pixels that lie outside the CCDs.
413 A function called with (image, ccd, butler) for every image, which
414 returns the image to be displayed (e.g. rawCallback). The image must
415 be of the correct size, allowing for the value of isTrimmed.
417 Passed to the butler.
419 Passed to the butler.
423 You can define a short named function as a callback::
425 def callback(im, ccd, imageSource):
426 return cameraGeom.utils.rawCallback(im, ccd, imageSource, correctGain=True)
429 isTrimmed=True, verbose=False, background=numpy.nan,
430 callback=None, *args, **kwargs):
431 super(ButlerImage, self).
__init__(*args)
441 def _prepareImage(self, ccd, im, binSize, allowRotate=True):
447 im, ccd.getOrientation().getNQuarter())
451 def getCcdImage(self, ccd, imageFactory=afwImage.ImageF, binSize=1, asMaskedImage=False):
452 """Return an image of the specified ccd, and also the (possibly updated) ccd"""
462 if self.
butlerbutler
is not None:
464 for dataId
in [dict(detector=ccd.getId()), dict(ccd=ccd.getId()), dict(ccd=ccd.getName())]:
467 except FitsError
as e:
468 err = IOError(e.args[0].split(
'\n')[0])
470 except Exception
as e:
475 ccd = im.getDetector()
480 im = im.getMaskedImage()
482 im = im.getMaskedImage().getImage()
486 print(f
"Reading {ccd.getId()}: {err}")
488 log.warn(f
"Reading {ccd.getId()}: {err}")
491 return self.
_prepareImage_prepareImage(ccd, imageFactory(*bbox.getDimensions()), binSize), ccd
493 if self.
typetype ==
"raw":
494 if hasattr(im,
'convertF'):
496 if False and self.
callbackcallback
is None:
502 im = self.
callbackcallback(im, ccd, imageSource=self)
503 except Exception
as e:
505 log.error(f
"callback failed: {e}")
506 im = imageFactory(*bbox.getDimensions())
510 return self.
_prepareImage_prepareImage(ccd, im, binSize, allowRotate=allowRotate), ccd
514 correctGain=False, subtractBias=False, convertToFloat=False, obeyNQuarter=True):
515 """A callback function that may or may not subtract bias/correct gain/trim
520 im : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage` or `lsst.afw.image.Exposure`
521 An image of a chip, ready to be binned and maybe rotated.
522 ccd : `lsst.afw.cameraGeom.Detector` or `None`
523 The Detector; if `None` assume that im is an exposure and extract its Detector.
524 imageSource : `FakeImageDataSource` or `None`
525 Source to get ccd images. Must have a `getCcdImage()` method.
527 Correct each amplifier for its gain?
528 subtractBias : `bool`
529 Subtract the bias from each amplifier?
530 convertToFloat : `bool`
531 Convert ``im`` to floating point if possible.
532 obeyNQuarter : `bool`
533 Obey nQuarter from the Detector (default: True)
537 image : `lsst.afw.image.Image` like
538 The constructed image (type returned by ``im.Factory``).
542 If imageSource is derived from ButlerImage, imageSource.butler is available.
545 ccd = im.getDetector()
546 if hasattr(im,
"getMaskedImage"):
547 im = im.getMaskedImage()
548 if convertToFloat
and hasattr(im,
"convertF"):
551 isTrimmed = imageSource.isTrimmed
560 data = im[a.getRawDataBBox()]
565 bias = im[a.getRawHorizontalOverscanBBox()]
570 ampImages.append(data)
572 ccdImage = im.Factory(bbox)
573 for ampImage, amp
in zip(ampImages, ccd):
580 nQuarter = ccd.getOrientation().getNQuarter()
587 isTrimmed=False, ccdOrigin=(0, 0), display=
None, binSize=1):
588 """Overlay bounding boxes on an image display.
592 ccd : `lsst.afw.cameraGeom.Detector`
593 Detector to iterate for the amp bounding boxes.
594 untrimmedCcdBbox : `lsst.geom.Box2I` or `None`
595 Bounding box of the un-trimmed Detector.
597 number of 90 degree rotations to apply to the bounding boxes (used for rotated chips).
599 Is the Detector image over which the boxes are layed trimmed?
600 ccdOrigin : `tuple` of `float`
601 Detector origin relative to the parent origin if in a larger pixel grid.
602 display : `lsst.afw.display.Display`
603 Image display to display on.
605 Bin the image by this factor in both dimensions.
610 - Entire detector GREEN
611 - All data for amp GREEN
612 - HorizontalPrescan YELLOW
613 - HorizontalOverscan RED
615 - VerticalOverscan MAGENTA
616 - VerticalOverscan MAGENTA
619 raise RuntimeError(
"Please specify a display")
621 if untrimmedCcdBbox
is None:
623 untrimmedCcdBbox = ccd.getBBox()
626 for a
in ccd.getAmplifiers():
627 bbox = a.getRawBBox()
628 untrimmedCcdBbox.include(bbox)
630 with display.Buffering():
631 ccdDim = untrimmedCcdBbox.getDimensions()
635 ampbbox = amp.getBBox()
637 ampbbox = amp.getRawBBox()
641 displayUtils.drawBBox(ampbbox, origin=ccdOrigin, borderWidth=0.49,
642 display=display, bin=binSize)
645 for bbox, ctype
in ((amp.getRawHorizontalOverscanBBox(), afwDisplay.RED),
646 (amp.getRawDataBBox(), afwDisplay.BLUE),
647 (amp.getRawVerticalOverscanBBox(),
649 (amp.getRawPrescanBBox(), afwDisplay.YELLOW)):
652 displayUtils.drawBBox(bbox, origin=ccdOrigin, borderWidth=0.49, ctype=ctype,
653 display=display, bin=binSize)
655 xc, yc = ((ampbbox.getMin()[0] + ampbbox.getMax()[0])//2,
656 (ampbbox.getMin()[1] + ampbbox.getMax()[1])//2)
669 ccdHeight = ccdBbox.getHeight()
670 ccdWidth = ccdBbox.getWidth()
674 xc, yc = 0.5*ccdHeight + c*xc + s*yc, 0.5*ccdWidth + -s*xc + c*yc
679 display.dot(str(amp.getName()), xc/binSize,
680 yc/binSize, textAngle=nQuarter*90)
682 displayUtils.drawBBox(ccdBbox, origin=ccdOrigin,
683 borderWidth=0.49, ctype=afwDisplay.MAGENTA, display=display, bin=binSize)
686 def showAmp(amp, imageSource=FakeImageDataSource(isTrimmed=
False), display=
None, overlay=
True,
687 imageFactory=afwImage.ImageU):
688 """Show an amp in an image display.
692 amp : `lsst.afw.tables.AmpInfoRecord`
693 Amp record to use in display.
694 imageSource : `FakeImageDataSource` or `None`
695 Source for getting the amp image. Must have a ``getAmpImage()`` method.
696 display : `lsst.afw.display.Display`
697 Image display to use.
699 Overlay bounding boxes?
700 imageFactory : callable like `lsst.afw.image.Image`
701 Type of image to display (only used if ampImage is `None`).
704 display = _getDisplayFromDisplayOrFrame(display)
706 ampImage = imageSource.getAmpImage(amp, imageFactory=imageFactory)
707 ampImSize = ampImage.getDimensions()
708 title = amp.getName()
709 display.mtv(ampImage, title=title)
711 with display.Buffering():
712 if ampImSize == amp.getRawBBox().getDimensions():
713 bboxes = [(amp.getRawBBox(), 0.49, afwDisplay.GREEN), ]
714 xy0 = bboxes[0][0].getMin()
716 (amp.getRawHorizontalOverscanBBox(), 0.49, afwDisplay.RED))
717 bboxes.append((amp.getRawDataBBox(), 0.49, afwDisplay.BLUE))
718 bboxes.append((amp.getRawPrescanBBox(),
719 0.49, afwDisplay.YELLOW))
720 bboxes.append((amp.getRawVerticalOverscanBBox(),
721 0.49, afwDisplay.MAGENTA))
723 bboxes = [(amp.getBBox(), 0.49,
None), ]
724 xy0 = bboxes[0][0].getMin()
726 for bbox, borderWidth, ctype
in bboxes:
731 displayUtils.drawBBox(
732 bbox, borderWidth=borderWidth, ctype=ctype, display=display)
735 def showCcd(ccd, imageSource=FakeImageDataSource(), display=
None, overlay=
True,
736 imageFactory=afwImage.ImageF, binSize=1, inCameraCoords=
False):
737 """Show a CCD on display.
741 ccd : `lsst.afw.cameraGeom.Detector`
742 Detector to use in display.
743 imageSource : `FakeImageDataSource` or `None`
744 Source to get ccd images. Must have a ``getCcdImage()`` method.
745 display : `lsst.afw.display.Display`
746 image display to use.
748 Show amp bounding boxes on the displayed image?
749 imageFactory : callable like `lsst.afw.image.Image`
750 The image factory to use in generating the images.
752 Bin the image by this factor in both dimensions.
753 inCameraCoords : `bool`
754 Show the Detector in camera coordinates?
756 display = _getDisplayFromDisplayOrFrame(display)
760 ccdImage, ccd = imageSource.getCcdImage(
761 ccd, imageFactory=imageFactory, binSize=binSize)
763 ccdBbox = ccdImage.getBBox()
764 if ccdBbox.getDimensions() == ccd.getBBox().getDimensions():
770 nQuarter = ccd.getOrientation().getNQuarter()
772 title = ccd.getName()
777 display.mtv(ccdImage, title=title)
781 ccdOrigin, display, binSize)
787 """Get the bounding boxes of a list of Detectors within a camera sized pixel grid
791 ccdList : `lsst.afw.cameraGeom.Detector`
794 Bin the image by this factor in both dimensions.
795 pixelSize_o : `float`
796 Size of the pixel in mm.
798 Origin of the camera pixel grid in pixels.
802 boxList : `list` [`lsst.geom.Box2I`]
803 A list of bounding boxes in camera pixel coordinates.
807 if not pixelSize_o == ccd.getPixelSize():
809 "Cameras with detectors with different pixel scales are not currently supported")
812 for corner
in ccd.getCorners(FOCAL_PLANE):
813 dbbox.include(corner)
815 nQuarter = ccd.getOrientation().getNQuarter()
816 cbbox = ccd.getBBox()
817 ex = cbbox.getDimensions().getX()//binSize
818 ey = cbbox.getDimensions().getY()//binSize
823 int(llc.getY()//pixelSize_o.getY()/binSize)))
825 -int(origin.getY())//binSize))
831 """Get the bounding box of a camera sized image in pixels
835 camBbox : `lsst.geom.Box2D`
836 Camera bounding box in focal plane coordinates (mm).
838 Size of a detector pixel in mm.
840 Buffer around edge of image in pixels.
844 box : `lsst.geom.Box2I`
845 The resulting bounding box.
848 int(camBbox.getMinY()//pixelSize.getY()))
850 int(camBbox.getMaxY()//pixelSize.getY()))
852 retBox.grow(bufferSize)
857 imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageU, binSize=1):
858 """Make an Image of a Camera.
860 Put each detector's image in the correct location and orientation on the
861 focal plane. The input images can be binned to an integer fraction of their
866 camera : `lsst.afw.cameraGeom.Camera`
867 Camera object to use to make the image.
868 detectorNameList : `list` [`str`]
869 List of detector names from ``camera`` to use in building the image.
870 Use all Detectors if `None`.
872 Value to use where there is no Detector.
874 Size of border in binned pixels to make around the camera image.
875 imageSource : `FakeImageDataSource` or `None`
876 Source to get ccd images. Must have a ``getCcdImage()`` method.
877 imageFactory : callable like `lsst.afw.image.Image`
878 Type of image to build.
880 Bin the image by this factor in both dimensions.
884 image : `lsst.afw.image.Image`
885 Image of the entire camera.
889 if detectorNameList
is None:
892 ccdList = [camera[name]
for name
in detectorNameList]
894 if detectorNameList
is None:
895 camBbox = camera.getFpBBox()
898 for detName
in detectorNameList:
899 for corner
in camera[detName].getCorners(FOCAL_PLANE):
900 camBbox.include(corner)
902 pixelSize_o = camera[
next(camera.getNameIter())].getPixelSize()
904 origin = camBbox.getMin()
906 camIm = imageFactory(int(math.ceil(camBbox.getDimensions().getX()/binSize)),
907 int(math.ceil(camBbox.getDimensions().getY()/binSize)))
908 camIm[:] = imageSource.background
910 assert imageSource.isTrimmed,
"isTrimmed is False isn't supported by getCcdInCamBBoxList"
913 for det, bbox
in zip(ccdList, boxList):
914 im = imageSource.getCcdImage(det, imageFactory, binSize)[0]
918 imView = camIm.Factory(camIm, bbox, afwImage.LOCAL)
922 log.error(f
"Unable to fit image for detector \"{det.getName()}\" into image of camera: {e}")
927 def showCamera(camera, imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageF,
928 detectorNameList=
None, binSize=10, bufferSize=10, overlay=
True, title=
"",
929 showWcs=
None, ctype=afwDisplay.GREEN, textSize=1.25, originAtCenter=
True, display=
None,
931 """Show a Camera on display, with the specified display.
933 The rotation of the sensors is snapped to the nearest multiple of 90 deg.
934 Also note that the pixel size is constant over the image array. The lower
935 left corner (LLC) of each sensor amp is snapped to the LLC of the pixel
936 containing the LLC of the image.
940 camera : `lsst.afw.cameraGeom.Camera`
941 Camera object to use to make the image.
942 imageSource : `FakeImageDataSource` or `None`
943 Source to get ccd images. Must have a ``getCcdImage()`` method.
944 imageFactory : `lsst.afw.image.Image`
945 Type of image to make
946 detectorNameList : `list` [`str`] or `None`
947 List of detector names from `camera` to use in building the image.
948 Use all Detectors if `None`.
950 Bin the image by this factor in both dimensions.
952 Size of border in binned pixels to make around the camera image.
954 Overlay Detector IDs and boundaries?
956 Title to use in display.
958 Include a WCS in the display?
959 ctype : `lsst.afw.display.COLOR` or `str`
960 Color to use when drawing Detector boundaries.
962 Size of detector labels
963 originAtCenter : `bool`
964 Put origin of the camera WCS at the center of the image?
965 If `False`, the origin will be at the lower left.
966 display : `lsst.afw.display`
967 Image display on which to display.
969 All remaining keyword arguments are passed to makeImageFromCamera
973 image : `lsst.afw.image.Image`
976 display = _getDisplayFromDisplayOrFrame(display)
980 cameraImage =
makeImageFromCamera(camera, detectorNameList=detectorNameList, bufferSize=bufferSize,
981 imageSource=imageSource, imageFactory=imageFactory, binSize=binSize,
984 if detectorNameList
is None:
985 ccdList = [camera[name]
for name
in camera.getNameIter()]
987 ccdList = [camera[name]
for name
in detectorNameList]
989 if detectorNameList
is None:
990 camBbox = camera.getFpBBox()
993 for detName
in detectorNameList:
994 for corner
in camera[detName].getCorners(FOCAL_PLANE):
995 camBbox.include(corner)
996 pixelSize = ccdList[0].getPixelSize()
1001 cameraImage.getBBox()).getCenter()
1010 title = camera.getName()
1011 display.mtv(cameraImage, title=title, wcs=wcs)
1014 with display.Buffering():
1016 camBbox, pixelSize, bufferSize*binSize)
1018 ccdList, binSize, pixelSize, camBbox.getMin())
1019 for bbox, ccd
in zip(bboxList, ccdList):
1020 nQuarter = ccd.getOrientation().getNQuarter()
1023 displayUtils.drawBBox(
1024 bbox, borderWidth=0.5, ctype=ctype, display=display)
1025 dims = bbox.getDimensions()
1026 display.dot(ccd.getName(), bbox.getMinX() + dims.getX()/2, bbox.getMinY() + dims.getY()/2,
1027 ctype=ctype, size=textSize, textAngle=nQuarter*90)
1033 """Make a WCS for the focal plane geometry
1034 (i.e. one that returns positions in "mm")
1039 Size of the image pixels in physical units
1040 referencePixel : `lsst.geom.Point2D`
1041 Pixel for origin of WCS
1046 Wcs object for mapping between pixels and focal plane.
1049 if referencePixel
is None:
1052 md.set(
"CRPIX%d"%(i + 1), referencePixel[i])
1053 md.set(
"CRVAL%d"%(i + 1), 0.)
1054 md.set(
"CDELT1", pixelSize[0])
1055 md.set(
"CDELT2", pixelSize[1])
1056 md.set(
"CTYPE1",
"CAMERA_X")
1057 md.set(
"CTYPE2",
"CAMERA_Y")
1058 md.set(
"CUNIT1",
"mm")
1059 md.set(
"CUNIT2",
"mm")
1065 """Find the Amp with the specified pixel position within the composite
1069 ccd : `lsst.afw.cameraGeom.Detector`
1070 Detector to look in.
1071 pixelPosition : `lsst.geom.Point2I`
1072 The pixel position to find the amp for.
1076 `lsst.afw.table.AmpInfoCatalog`
1077 Amp record in which ``pixelPosition`` falls or `None` if no Amp found.
1080 if amp.getBBox().
contains(pixelPosition):
def __init__(self, butler=None, type="raw", isTrimmed=True, verbose=False, background=numpy.nan, callback=None, *args, **kwargs)
def _prepareImage(self, ccd, im, binSize, allowRotate=True)
def getCcdImage(self, ccd, imageFactory=afwImage.ImageF, binSize=1, asMaskedImage=False)
def getAmpImage(self, amp, imageFactory)
def __init__(self, isTrimmed=True, verbose=False, background=numpy.nan, showAmpGain=True, markSize=10, markValue=0, ampImValue=None, scaleGain=lambda gain:(gain *1000)//10)
def getCcdImage(self, det, imageFactory, binSize)
Class for storing generic metadata.
A floating-point coordinate rectangle geometry.
An integer coordinate rectangle.
static Log getLogger(Log const &logger)
Reports attempts to exceed implementation-defined length limits for some classes.
def assembleAmplifierRawImage(destImage, rawImage, amplifier)
def assembleAmplifierImage(destImage, rawImage, amplifier)
def rotateBBoxBy90(bbox, n90, dimensions)
def makeFocalPlaneWcs(pixelSize, referencePixel)
def plotFocalPlane(camera, fieldSizeDeg_x=0, fieldSizeDeg_y=None, dx=0.1, dy=0.1, figsize=(10., 10.), useIds=False, showFig=True, savePath=None)
def showAmp(amp, imageSource=FakeImageDataSource(isTrimmed=False), display=None, overlay=True, imageFactory=afwImage.ImageU)
def makeImageFromCcd(ccd, isTrimmed=True, showAmpGain=True, imageFactory=afwImage.ImageU, rcMarkSize=10, binSize=1)
def makeImageFromCamera(camera, detectorNameList=None, background=numpy.nan, bufferSize=10, imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageU, binSize=1)
def overlayCcdBoxes(ccd, untrimmedCcdBbox=None, nQuarter=0, isTrimmed=False, ccdOrigin=(0, 0), display=None, binSize=1)
def findAmp(ccd, pixelPosition)
def makeImageFromAmp(amp, imValue=None, imageFactory=afwImage.ImageU, markSize=10, markValue=0, scaleGain=lambda gain:(gain *1000)//10)
def prepareWcsData(wcs, amp, isTrimmed=True)
def getCcdInCamBBoxList(ccdList, binSize, pixelSize_o, origin)
def rawCallback(im, ccd=None, imageSource=None, correctGain=False, subtractBias=False, convertToFloat=False, obeyNQuarter=True)
def getCameraImageBBox(camBbox, pixelSize, bufferSize)
def showCcd(ccd, imageSource=FakeImageDataSource(), display=None, overlay=True, imageFactory=afwImage.ImageF, binSize=1, inCameraCoords=False)
def showCamera(camera, imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageF, detectorNameList=None, binSize=10, bufferSize=10, overlay=True, title="", showWcs=None, ctype=afwDisplay.GREEN, textSize=1.25, originAtCenter=True, display=None, **kwargs)
std::shared_ptr< SkyWcs > makeSkyWcs(daf::base::PropertySet &metadata, bool strip=false)
Construct a SkyWcs from FITS keywords.
std::shared_ptr< SkyWcs > makeFlippedWcs(SkyWcs const &wcs, bool flipLR, bool flipTB, lsst::geom::Point2D const ¢er)
Return a copy of a FITS-WCS with pixel positions flipped around a specified center.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
Statistics makeStatistics(lsst::afw::image::Image< Pixel > const &img, lsst::afw::image::Mask< image::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl=StatisticsControl())
Handle a watered-down front-end to the constructor (no variance)
std::shared_ptr< ImageT > rotateImageBy90(ImageT const &image, int nQuarter)
Rotate an image by an integral number of quarter turns.
std::shared_ptr< ImageT > binImage(ImageT const &inImage, int const binX, int const binY, lsst::afw::math::Property const flags=lsst::afw::math::MEAN)
Angle abs(Angle const &a)