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 .cameraGeomLib
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` 71 if not amp.getHasRawInfo():
72 raise RuntimeError(
"Cannot modify wcs without raw amp information")
74 ampBox = amp.getRawDataBBox()
76 ampBox = amp.getRawBBox()
81 trim_shift = ampBox.getMin() - amp.getBBox().getMin()
82 wcs = wcs.copyAtShiftedPixelOrigin(
lsst.geom.Extent2D(-trim_shift.getX(), -trim_shift.getY()))
84 offset = amp.getRawXYOffset()
88 def plotFocalPlane(camera, fieldSizeDeg_x=0, fieldSizeDeg_y=None, dx=0.1, dy=0.1, figsize=(10., 10.),
89 useIds=
False, showFig=
True, savePath=
None):
90 """Make a plot of the focal plane along with a set points that sample 95 camera : `lsst.afw.cameraGeom.Camera` 97 fieldSizeDeg_x : `float` 98 Amount of the field to sample in x in degrees 99 fieldSizeDeg_y : `float` or `None` 100 Amount of the field to sample in y in degrees 102 Spacing of sample points in x in degrees 104 Spacing of sample points in y in degrees 105 figsize : `tuple` containing two `float` 106 Matplotlib style tuple indicating the size of the figure in inches 108 Label detectors by name, not id? 110 Display the figure on the screen? 111 savePath : `str` or `None` 112 If not `None`, save a copy of the figure to this name. 115 from matplotlib.patches
import Polygon
116 from matplotlib.collections
import PatchCollection
117 import matplotlib.pyplot
as plt
120 "Can't run plotFocalPlane: matplotlib has not been set up")
123 if fieldSizeDeg_y
is None:
124 fieldSizeDeg_y = fieldSizeDeg_x
126 field_gridx, field_gridy = numpy.meshgrid(
127 numpy.arange(0., fieldSizeDeg_x + dx, dx) - fieldSizeDeg_x/2.,
128 numpy.arange(0., fieldSizeDeg_y + dy, dy) - fieldSizeDeg_y/2.)
129 field_gridx, field_gridy = field_gridx.flatten(), field_gridy.flatten()
131 field_gridx, field_gridy = [], []
139 for x, y
in zip(field_gridx, field_gridy)]
140 posFocalPlaneList = camera.transform(posFieldAngleList, FIELD_ANGLE, FOCAL_PLANE)
141 for posFocalPlane
in posFocalPlaneList:
142 xs.append(posFocalPlane.getX())
143 ys.append(posFocalPlane.getY())
144 dets = camera.findDetectors(posFocalPlane, FOCAL_PLANE)
150 colorMap = {DetectorType.SCIENCE:
'b', DetectorType.FOCUS:
'y',
151 DetectorType.GUIDER:
'g', DetectorType.WAVEFRONT:
'r'} 155 plt.figure(figsize=figsize) 160 corners = [(c.getX(), c.getY())
for c
in det.getCorners(FOCAL_PLANE)]
161 for corner
in corners:
162 xvals.append(corner[0])
163 yvals.append(corner[1])
164 colors.append(colorMap[det.getType()])
165 patches.append(Polygon(corners,
True))
166 center = det.getOrientation().getFpPosition()
167 ax.text(center.getX(), center.getY(), det.getId()
if useIds
else det.getName(),
168 horizontalalignment=
'center', size=6)
170 patchCollection = PatchCollection(patches, alpha=0.6, facecolor=colors)
171 ax.add_collection(patchCollection)
172 ax.scatter(xs, ys, s=10, alpha=.7, linewidths=0., c=pcolors)
173 ax.set_xlim(
min(xvals) -
abs(0.1*
min(xvals)),
175 ax.set_ylim(
min(yvals) -
abs(0.1*
min(yvals)),
177 ax.set_xlabel(
'Focal Plane X (mm)')
178 ax.set_ylabel(
'Focal Plane Y (mm)')
179 if savePath
is not None:
180 plt.savefig(savePath)
185 def makeImageFromAmp(amp, imValue=None, imageFactory=afwImage.ImageU, markSize=10, markValue=0,
186 scaleGain=lambda gain: (gain*1000)//10):
187 """Make an image from an amp object. 189 Since images are integer images by default, the gain needs to be scaled to 190 give enough dynamic range to see variation from amp to amp. 191 The scaling algorithm is assignable. 195 amp : `lsst.afw.table.AmpInfoRecord` 196 Amp record to use for constructing the raw amp image. 197 imValue : `float` or `None` 198 Value to assign to the constructed image, or scaleGain(gain) if `None`. 199 imageFactory : callable like `lsst.afw.image.Image` 200 Type of image to construct. 202 Size of mark at read corner in pixels. 204 Value of pixels in the read corner mark. 206 The function by which to scale the gain (must take a single argument). 210 ampImage : `lsst.afw.image` 211 An untrimmed amp image, of the type produced by ``imageFactory``. 213 if not amp.getHasRawInfo():
215 "Can't create a raw amp image without raw amp information")
216 bbox = amp.getRawBBox()
217 dbbox = amp.getRawDataBBox()
218 img = imageFactory(bbox)
220 img.set(int(scaleGain(amp.getGain())))
225 if amp.getReadoutCorner() == afwCameraGeom.ReadoutCorner.LL:
226 markbbox.include(dbbox.getMin())
228 elif amp.getReadoutCorner() == afwCameraGeom.ReadoutCorner.LR:
230 markbbox.include(cornerPoint)
232 elif amp.getReadoutCorner() == afwCameraGeom.ReadoutCorner.UR:
234 markbbox.include(cornerPoint)
236 elif amp.getReadoutCorner() == afwCameraGeom.ReadoutCorner.UL:
238 markbbox.include(cornerPoint)
241 raise RuntimeError(
"Could not set readout corner")
242 mimg = imageFactory(img, markbbox)
248 """Calculate the raw ccd bounding box. 252 ccd : `lsst.afw.cameraGeom.Detector` 253 Detector for which to calculate the un-trimmed bounding box. 257 bbox : `lsst.geom.Box2I` or `None` 258 Bounding box of the un-trimmed Detector, or `None` if there is not enough 259 information to calculate raw BBox. 263 if not amp.getHasRawInfo():
265 tbbox = amp.getRawBBox()
266 tbbox.shift(amp.getRawXYOffset())
271 def makeImageFromCcd(ccd, isTrimmed=True, showAmpGain=True, imageFactory=afwImage.ImageU, rcMarkSize=10,
273 """Make an Image of a CCD. 277 ccd : `lsst.afw.cameraGeom.Detector` 278 Detector to use in making the image. 280 Assemble a trimmed Detector image. 282 Use the per-amp gain to color the pixels in the image? 283 imageFactory : callable like `lsst.afw.image.Image` 284 Image type to generate. 286 Size of the mark to make in the amp images at the read corner. 288 Bin the image by this factor in both dimensions. 292 image : `lsst.afw.image.Image` 293 Image of the Detector (type returned by ``imageFactory``). 302 if amp.getHasRawInfo():
305 amp, imageFactory=imageFactory, markSize=rcMarkSize))
308 imageFactory=imageFactory, markSize=rcMarkSize))
311 if len(ampImages) > 0:
312 ccdImage = imageFactory(bbox)
313 for ampImage, amp
in zip(ampImages, ccd):
321 "Cannot create untrimmed CCD without amps with raw information")
322 ccdImage = imageFactory(ccd.getBBox())
328 """A class to retrieve synthetic images for display by the show* methods 333 Should amps be trimmed? 337 The value of any pixels that lie outside the CCDs. 339 Color the amp segments with the gain of the amp? 341 Size of the side of the box used to mark the read corner. 343 Value to assign the read corner mark. 344 ampImValue : `float` or `None` 345 Value to assign to amps; scaleGain(gain) is used if `None`. 347 Function to scale the gain by. 349 def __init__(self, isTrimmed=True, verbose=False, background=numpy.nan,
350 showAmpGain=True, markSize=10, markValue=0,
351 ampImValue=None, scaleGain=lambda gain: (gain*1000)//10):
362 """Return a CCD image for the detector and the (possibly updated) Detector. 366 det : `lsst.afw.cameraGeom.Detector` 367 Detector to use for making the image. 368 imageFactory : callable like `lsst.afw.image.Image` 369 Image constructor for making the image. 371 Bin the image by this factor in both dimensions. 375 ccdImage : `lsst.afw.image.Image` 376 The constructed image. 379 imageFactory=imageFactory, binSize=binSize)
383 """Return an amp segment image. 387 amp : `lsst.afw.table.AmpInfoTable` 388 AmpInfoTable for this amp. 389 imageFactory : callable like `lsst.afw.image.Image` 390 Image constructor for making the image. 394 ampImage : `lsst.afw.image.Image` 395 The constructed image. 401 ampImage = ampImage.Factory(ampImage, amp.getRawDataBBox())
406 """A class to return an Image of a given Ccd using the butler. 410 butler : `lsst.daf.persistence.Butler` or `None` 411 The butler to use. If `None`, an empty image is returned. 413 The type of image to read (e.g. raw, bias, flat, calexp). 415 If true, the showCamera command expects to be given trimmed images. 417 Be chatty (in particular, log any error messages from the butler)? 419 The value of any pixels that lie outside the CCDs. 421 A function called with (image, ccd, butler) for every image, which 422 returns the image to be displayed (e.g. rawCallback). The image must 423 be of the correct size, allowing for the value of isTrimmed. 425 Passed to the butler. 427 Passed to the butler. 431 You can define a short named function as a callback:: 433 def callback(im, ccd, imageSource): 434 return cameraGeom.utils.rawCallback(im, ccd, imageSource, correctGain=True) 436 def __init__(self, butler=None, type="raw",
437 isTrimmed=True, verbose=False, background=numpy.nan,
438 callback=None, *args, **kwargs):
439 super(ButlerImage, self).
__init__(*args)
449 def _prepareImage(self, ccd, im, binSize, allowRotate=True):
455 im, ccd.getOrientation().getNQuarter())
459 def getCcdImage(self, ccd, imageFactory=afwImage.ImageF, binSize=1, asMaskedImage=False):
460 """Return an image of the specified ccd, and also the (possibly updated) ccd""" 470 if self.
butler is not None:
472 for dataId
in [dict(detector=ccd.getId()), dict(ccd=ccd.getId()), dict(ccd=ccd.getName())]:
475 except FitsError
as e:
476 err = IOError(e.args[0].split(
'\n')[0])
478 except Exception
as e:
483 ccd = im.getDetector()
488 im = im.getMaskedImage()
490 im = im.getMaskedImage().getImage()
494 print(f
"Reading {ccd.getId()}: {err}")
496 log.warn(f
"Reading {ccd.getId()}: {err}")
499 return self.
_prepareImage(ccd, imageFactory(*bbox.getDimensions()), binSize), ccd
501 if self.
type ==
"raw":
502 if hasattr(im,
'convertF'):
510 im = self.
callback(im, ccd, imageSource=self)
511 except Exception
as e:
513 log.error(f
"callback failed: {e}")
514 im = imageFactory(*bbox.getDimensions())
518 return self.
_prepareImage(ccd, im, binSize, allowRotate=allowRotate), ccd
522 correctGain=False, subtractBias=False, convertToFloat=False, obeyNQuarter=True):
523 """A callback function that may or may not subtract bias/correct gain/trim 528 im : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage` or `lsst.afw.image.Exposure` 529 An image of a chip, ready to be binned and maybe rotated. 530 ccd : `lsst.afw.cameraGeom.Detector` or `None` 531 The Detector; if `None` assume that im is an exposure and extract its Detector. 532 imageSource : `FakeImageDataSource` or `None` 533 Source to get ccd images. Must have a `getCcdImage()` method. 535 Correct each amplifier for its gain? 536 subtractBias : `bool` 537 Subtract the bias from each amplifier? 538 convertToFloat : `bool` 539 Convert ``im`` to floating point if possible. 540 obeyNQuarter : `bool` 541 Obey nQuarter from the Detector (default: True) 545 image : `lsst.afw.image.Image` like 546 The constructed image (type returned by ``im.Factory``). 550 If imageSource is derived from ButlerImage, imageSource.butler is available. 553 ccd = im.getDetector()
554 if hasattr(im,
"getMaskedImage"):
555 im = im.getMaskedImage()
556 if convertToFloat
and hasattr(im,
"convertF"):
559 isTrimmed = imageSource.isTrimmed
568 data = im[a.getRawDataBBox()]
573 bias = im[a.getRawHorizontalOverscanBBox()]
578 ampImages.append(data)
580 ccdImage = im.Factory(bbox)
581 for ampImage, amp
in zip(ampImages, ccd):
588 nQuarter = ccd.getOrientation().getNQuarter()
595 isTrimmed=False, ccdOrigin=(0, 0), display=
None, binSize=1):
596 """Overlay bounding boxes on an image display. 600 ccd : `lsst.afw.cameraGeom.Detector` 601 Detector to iterate for the amp bounding boxes. 602 untrimmedCcdBbox : `lsst.geom.Box2I` or `None` 603 Bounding box of the un-trimmed Detector. 605 number of 90 degree rotations to apply to the bounding boxes (used for rotated chips). 607 Is the Detector image over which the boxes are layed trimmed? 608 ccdOrigin : `tuple` of `float` 609 Detector origin relative to the parent origin if in a larger pixel grid. 610 display : `lsst.afw.display.Display` 611 Image display to display on. 613 Bin the image by this factor in both dimensions. 618 - Entire detector GREEN 619 - All data for amp GREEN 620 - HorizontalPrescan YELLOW 621 - HorizontalOverscan RED 623 - VerticalOverscan MAGENTA 624 - VerticalOverscan MAGENTA 627 raise RuntimeError(
"Please specify a display")
629 if untrimmedCcdBbox
is None:
631 untrimmedCcdBbox = ccd.getBBox()
634 for a
in ccd.getAmplifiers():
635 bbox = a.getRawBBox()
636 untrimmedCcdBbox.include(bbox)
638 with display.Buffering():
639 ccdDim = untrimmedCcdBbox.getDimensions()
643 ampbbox = amp.getBBox()
645 ampbbox = amp.getRawBBox()
649 displayUtils.drawBBox(ampbbox, origin=ccdOrigin, borderWidth=0.49,
650 display=display, bin=binSize)
652 if not isTrimmed
and amp.getHasRawInfo():
653 for bbox, ctype
in ((amp.getRawHorizontalOverscanBBox(), afwDisplay.RED),
654 (amp.getRawDataBBox(), afwDisplay.BLUE),
655 (amp.getRawVerticalOverscanBBox(),
657 (amp.getRawPrescanBBox(), afwDisplay.YELLOW)):
660 displayUtils.drawBBox(bbox, origin=ccdOrigin, borderWidth=0.49, ctype=ctype,
661 display=display, bin=binSize)
663 xc, yc = ((ampbbox.getMin()[0] + ampbbox.getMax()[0])//2,
664 (ampbbox.getMin()[1] + ampbbox.getMax()[1])//2)
677 ccdHeight = ccdBbox.getHeight()
678 ccdWidth = ccdBbox.getWidth()
682 xc, yc = 0.5*ccdHeight + c*xc + s*yc, 0.5*ccdWidth + -s*xc + c*yc
687 display.dot(str(amp.getName()), xc/binSize,
688 yc/binSize, textAngle=nQuarter*90)
690 displayUtils.drawBBox(ccdBbox, origin=ccdOrigin,
691 borderWidth=0.49, ctype=afwDisplay.MAGENTA, display=display, bin=binSize)
694 def showAmp(amp, imageSource=FakeImageDataSource(isTrimmed=
False), display=
None, overlay=
True,
695 imageFactory=afwImage.ImageU):
696 """Show an amp in an image display. 700 amp : `lsst.afw.tables.AmpInfoRecord` 701 Amp record to use in display. 702 imageSource : `FakeImageDataSource` or `None` 703 Source for getting the amp image. Must have a ``getAmpImage()`` method. 704 display : `lsst.afw.display.Display` 705 Image display to use. 707 Overlay bounding boxes? 708 imageFactory : callable like `lsst.afw.image.Image` 709 Type of image to display (only used if ampImage is `None`). 712 display = _getDisplayFromDisplayOrFrame(display)
714 ampImage = imageSource.getAmpImage(amp, imageFactory=imageFactory)
715 ampImSize = ampImage.getDimensions()
716 title = amp.getName()
717 display.mtv(ampImage, title=title)
719 with display.Buffering():
720 if amp.getHasRawInfo()
and ampImSize == amp.getRawBBox().getDimensions():
721 bboxes = [(amp.getRawBBox(), 0.49, afwDisplay.GREEN), ]
722 xy0 = bboxes[0][0].getMin()
724 (amp.getRawHorizontalOverscanBBox(), 0.49, afwDisplay.RED))
725 bboxes.append((amp.getRawDataBBox(), 0.49, afwDisplay.BLUE))
726 bboxes.append((amp.getRawPrescanBBox(),
727 0.49, afwDisplay.YELLOW))
728 bboxes.append((amp.getRawVerticalOverscanBBox(),
729 0.49, afwDisplay.MAGENTA))
731 bboxes = [(amp.getBBox(), 0.49,
None), ]
732 xy0 = bboxes[0][0].getMin()
734 for bbox, borderWidth, ctype
in bboxes:
739 displayUtils.drawBBox(
740 bbox, borderWidth=borderWidth, ctype=ctype, display=display)
743 def showCcd(ccd, imageSource=FakeImageDataSource(), display=
None, overlay=
True,
744 imageFactory=afwImage.ImageF, binSize=1, inCameraCoords=
False):
745 """Show a CCD on display. 749 ccd : `lsst.afw.cameraGeom.Detector` 750 Detector to use in display. 751 imageSource : `FakeImageDataSource` or `None` 752 Source to get ccd images. Must have a ``getCcdImage()`` method. 753 display : `lsst.afw.display.Display` 754 image display to use. 756 Show amp bounding boxes on the displayed image? 757 imageFactory : callable like `lsst.afw.image.Image` 758 The image factory to use in generating the images. 760 Bin the image by this factor in both dimensions. 761 inCameraCoords : `bool` 762 Show the Detector in camera coordinates? 764 display = _getDisplayFromDisplayOrFrame(display)
768 ccdImage, ccd = imageSource.getCcdImage(
769 ccd, imageFactory=imageFactory, binSize=binSize)
771 ccdBbox = ccdImage.getBBox()
772 if ccdBbox.getDimensions() == ccd.getBBox().getDimensions():
778 nQuarter = ccd.getOrientation().getNQuarter()
780 title = ccd.getName()
785 display.mtv(ccdImage, title=title)
789 ccdOrigin, display, binSize)
795 """Get the bounding boxes of a list of Detectors within a camera sized pixel grid 799 ccdList : `lsst.afw.cameraGeom.Detector` 802 Bin the image by this factor in both dimensions. 803 pixelSize_o : `float` 804 Size of the pixel in mm. 806 Origin of the camera pixel grid in pixels. 810 boxList : `list` [`lsst.geom.Box2I`] 811 A list of bounding boxes in camera pixel coordinates. 815 if not pixelSize_o == ccd.getPixelSize():
817 "Cameras with detectors with different pixel scales are not currently supported")
820 for corner
in ccd.getCorners(FOCAL_PLANE):
821 dbbox.include(corner)
823 nQuarter = ccd.getOrientation().getNQuarter()
824 cbbox = ccd.getBBox()
825 ex = cbbox.getDimensions().getX()//binSize
826 ey = cbbox.getDimensions().getY()//binSize
831 int(llc.getY()//pixelSize_o.getY()/binSize)))
833 -int(origin.getY())//binSize))
839 """Get the bounding box of a camera sized image in pixels 843 camBbox : `lsst.geom.Box2D` 844 Camera bounding box in focal plane coordinates (mm). 846 Size of a detector pixel in mm. 848 Buffer around edge of image in pixels. 852 box : `lsst.geom.Box2I` 853 The resulting bounding box. 856 int(camBbox.getMinY()//pixelSize.getY()))
858 int(camBbox.getMaxY()//pixelSize.getY()))
860 retBox.grow(bufferSize)
864 def makeImageFromCamera(camera, detectorNameList=None, background=numpy.nan, bufferSize=10,
865 imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageU, binSize=1):
866 """Make an Image of a Camera. 868 Put each detector's image in the correct location and orientation on the 869 focal plane. The input images can be binned to an integer fraction of their 874 camera : `lsst.afw.cameraGeom.Camera` 875 Camera object to use to make the image. 876 detectorNameList : `list` [`str`] 877 List of detector names from ``camera`` to use in building the image. 878 Use all Detectors if `None`. 880 Value to use where there is no Detector. 882 Size of border in binned pixels to make around the camera image. 883 imageSource : `FakeImageDataSource` or `None` 884 Source to get ccd images. Must have a ``getCcdImage()`` method. 885 imageFactory : callable like `lsst.afw.image.Image` 886 Type of image to build. 888 Bin the image by this factor in both dimensions. 892 image : `lsst.afw.image.Image` 893 Image of the entire camera. 897 if detectorNameList
is None:
900 ccdList = [camera[name]
for name
in detectorNameList]
902 if detectorNameList
is None:
903 camBbox = camera.getFpBBox()
906 for detName
in detectorNameList:
907 for corner
in camera[detName].getCorners(FOCAL_PLANE):
908 camBbox.include(corner)
910 pixelSize_o = camera[
next(camera.getNameIter())].getPixelSize()
912 origin = camBbox.getMin()
914 camIm = imageFactory(int(math.ceil(camBbox.getDimensions().getX()/binSize)),
915 int(math.ceil(camBbox.getDimensions().getY()/binSize)))
916 camIm[:] = imageSource.background
918 assert imageSource.isTrimmed,
"isTrimmed is False isn't supported by getCcdInCamBBoxList" 921 for det, bbox
in zip(ccdList, boxList):
922 im = imageSource.getCcdImage(det, imageFactory, binSize)[0]
926 imView = camIm.Factory(camIm, bbox, afwImage.LOCAL)
930 log.error(f
"Unable to fit image for detector \"{det.getName()}\" into image of camera: {e}")
935 def showCamera(camera, imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageF,
936 detectorNameList=
None, binSize=10, bufferSize=10, overlay=
True, title=
"",
937 showWcs=
None, ctype=afwDisplay.GREEN, textSize=1.25, originAtCenter=
True, display=
None,
939 """Show a Camera on display, with the specified display. 941 The rotation of the sensors is snapped to the nearest multiple of 90 deg. 942 Also note that the pixel size is constant over the image array. The lower 943 left corner (LLC) of each sensor amp is snapped to the LLC of the pixel 944 containing the LLC of the image. 948 camera : `lsst.afw.cameraGeom.Camera` 949 Camera object to use to make the image. 950 imageSource : `FakeImageDataSource` or `None` 951 Source to get ccd images. Must have a ``getCcdImage()`` method. 952 imageFactory : `lsst.afw.image.Image` 953 Type of image to make 954 detectorNameList : `list` [`str`] or `None` 955 List of detector names from `camera` to use in building the image. 956 Use all Detectors if `None`. 958 Bin the image by this factor in both dimensions. 960 Size of border in binned pixels to make around the camera image. 962 Overlay Detector IDs and boundaries? 964 Title to use in display. 966 Include a WCS in the display? 967 ctype : `lsst.afw.display.COLOR` or `str` 968 Color to use when drawing Detector boundaries. 970 Size of detector labels 971 originAtCenter : `bool` 972 Put origin of the camera WCS at the center of the image? 973 If `False`, the origin will be at the lower left. 974 display : `lsst.afw.display` 975 Image display on which to display. 977 All remaining keyword arguments are passed to makeImageFromCamera 981 image : `lsst.afw.image.Image` 984 display = _getDisplayFromDisplayOrFrame(display)
988 cameraImage =
makeImageFromCamera(camera, detectorNameList=detectorNameList, bufferSize=bufferSize,
989 imageSource=imageSource, imageFactory=imageFactory, binSize=binSize,
992 if detectorNameList
is None:
993 ccdList = [camera[name]
for name
in camera.getNameIter()]
995 ccdList = [camera[name]
for name
in detectorNameList]
997 if detectorNameList
is None:
998 camBbox = camera.getFpBBox()
1001 for detName
in detectorNameList:
1002 for corner
in camera[detName].getCorners(FOCAL_PLANE):
1003 camBbox.include(corner)
1004 pixelSize = ccdList[0].getPixelSize()
1009 cameraImage.getBBox()).getCenter()
1018 title = camera.getName()
1019 display.mtv(cameraImage, title=title, wcs=wcs)
1022 with display.Buffering():
1024 camBbox, pixelSize, bufferSize*binSize)
1026 ccdList, binSize, pixelSize, camBbox.getMin())
1027 for bbox, ccd
in zip(bboxList, ccdList):
1028 nQuarter = ccd.getOrientation().getNQuarter()
1031 displayUtils.drawBBox(
1032 bbox, borderWidth=0.5, ctype=ctype, display=display)
1033 dims = bbox.getDimensions()
1034 display.dot(ccd.getName(), bbox.getMinX() + dims.getX()/2, bbox.getMinY() + dims.getY()/2,
1035 ctype=ctype, size=textSize, textAngle=nQuarter*90)
1041 """Make a WCS for the focal plane geometry 1042 (i.e. one that returns positions in "mm") 1047 Size of the image pixels in physical units 1048 referencePixel : `lsst.geom.Point2D` 1049 Pixel for origin of WCS 1054 Wcs object for mapping between pixels and focal plane. 1057 if referencePixel
is None:
1060 md.set(
"CRPIX%d"%(i + 1), referencePixel[i])
1061 md.set(
"CRVAL%d"%(i + 1), 0.)
1062 md.set(
"CDELT1", pixelSize[0])
1063 md.set(
"CDELT2", pixelSize[1])
1064 md.set(
"CTYPE1",
"CAMERA_X")
1065 md.set(
"CTYPE2",
"CAMERA_Y")
1066 md.set(
"CUNIT1",
"mm")
1067 md.set(
"CUNIT2",
"mm")
1073 """Find the Amp with the specified pixel position within the composite 1077 ccd : `lsst.afw.cameraGeom.Detector` 1078 Detector to look in. 1079 pixelPosition : `lsst.geom.Point2I` 1080 The pixel position to find the amp for. 1084 `lsst.afw.table.AmpInfoCatalog` 1085 Amp record in which ``pixelPosition`` falls or `None` if no Amp found. 1088 if amp.getBBox().
contains(pixelPosition):
def makeImageFromAmp(amp, imValue=None, imageFactory=afwImage.ImageU, markSize=10, markValue=0, scaleGain=lambda gain:(gain *1000)//10)
Angle abs(Angle const &a)
def makeFocalPlaneWcs(pixelSize, referencePixel)
A floating-point coordinate rectangle geometry.
def plotFocalPlane(camera, fieldSizeDeg_x=0, fieldSizeDeg_y=None, dx=0.1, dy=0.1, figsize=(10., 10.), useIds=False, showFig=True, savePath=None)
Reports attempts to exceed implementation-defined length limits for some classes. ...
def getCcdInCamBBoxList(ccdList, binSize, pixelSize_o, origin)
def getCcdImage(self, det, imageFactory, binSize)
def findAmp(ccd, pixelPosition)
def getCameraImageBBox(camBbox, pixelSize, bufferSize)
Statistics makeStatistics(lsst::afw::math::MaskedVector< EntryT > const &mv, std::vector< WeightPixel > const &vweights, int const flags, StatisticsControl const &sctrl=StatisticsControl())
The makeStatistics() overload to handle lsst::afw::math::MaskedVector<>
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 _prepareImage(self, ccd, im, binSize, allowRotate=True)
def makeImageFromCamera(camera, detectorNameList=None, background=numpy.nan, bufferSize=10, imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageU, binSize=1)
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.
def __init__(self, butler=None, type="raw", isTrimmed=True, verbose=False, background=numpy.nan, callback=None, args, kwargs)
def makeImageFromCcd(ccd, isTrimmed=True, showAmpGain=True, imageFactory=afwImage.ImageU, rcMarkSize=10, binSize=1)
def rawCallback(im, ccd=None, imageSource=None, correctGain=False, subtractBias=False, convertToFloat=False, obeyNQuarter=True)
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< ImageT > rotateImageBy90(ImageT const &image, int nQuarter)
Rotate an image by an integral number of quarter turns.
def assembleAmplifierImage(destImage, rawImage, amplifier)
def showAmp(amp, imageSource=FakeImageDataSource(isTrimmed=False), display=None, overlay=True, imageFactory=afwImage.ImageU)
static Log getLogger(Log const &logger)
def showCcd(ccd, imageSource=FakeImageDataSource(), display=None, overlay=True, imageFactory=afwImage.ImageF, binSize=1, inCameraCoords=False)
def prepareWcsData(wcs, amp, isTrimmed=True)
std::shared_ptr< SkyWcs > makeSkyWcs(TransformPoint2ToPoint2 const &pixelsToFieldAngle, lsst::geom::Angle const &orientation, bool flipX, lsst::geom::SpherePoint const &boresight, std::string const &projection="TAN")
Construct a FITS SkyWcs from camera geometry.
Class for storing generic metadata.
std::shared_ptr< ImageT > binImage(ImageT const &inImage, int const binsize, lsst::afw::math::Property const flags=lsst::afw::math::MEAN)
def assembleAmplifierRawImage(destImage, rawImage, amplifier)
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects...
def overlayCcdBoxes(ccd, untrimmedCcdBbox=None, nQuarter=0, isTrimmed=False, ccdOrigin=(0, 0), display=None, binSize=1)
An integer coordinate rectangle.
def rotateBBoxBy90(bbox, n90, dimensions)
def getCcdImage(self, ccd, imageFactory=afwImage.ImageF, binSize=1, asMaskedImage=False)