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()
493 print(
"Reading %s: %s" % (ccd.getId(), err))
495 log.warn(
"Reading %s: %s", ccd.getId(), err)
498 return self.
_prepareImage(ccd, imageFactory(*bbox.getDimensions()), binSize), ccd
500 if self.
type ==
"raw":
501 if hasattr(im,
'convertF'):
509 im = self.
callback(im, ccd, imageSource=self)
510 except Exception
as e:
512 log.error(
"callback failed: %s" % e)
513 im = imageFactory(*bbox.getDimensions())
517 return self.
_prepareImage(ccd, im, binSize, allowRotate=allowRotate), ccd
521 correctGain=False, subtractBias=False, convertToFloat=False, obeyNQuarter=True):
522 """A callback function that may or may not subtract bias/correct gain/trim 527 im : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage` or `lsst.afw.image.Exposure` 528 An image of a chip, ready to be binned and maybe rotated. 529 ccd : `lsst.afw.cameraGeom.Detector` or `None` 530 The Detector; if `None` assume that im is an exposure and extract its Detector. 531 imageSource : `FakeImageDataSource` or `None` 532 Source to get ccd images. Must have a `getCcdImage()` method. 534 Correct each amplifier for its gain? 535 subtractBias : `bool` 536 Subtract the bias from each amplifier? 537 convertToFloat : `bool` 538 Convert ``im`` to floating point if possible. 539 obeyNQuarter : `bool` 540 Obey nQuarter from the Detector (default: True) 544 image : `lsst.afw.image.Image` like 545 The constructed image (type returned by ``im.Factory``). 549 If imageSource is derived from ButlerImage, imageSource.butler is available. 552 ccd = im.getDetector()
553 if hasattr(im,
"getMaskedImage"):
554 im = im.getMaskedImage()
555 if convertToFloat
and hasattr(im,
"convertF"):
558 isTrimmed = imageSource.isTrimmed
567 data = im[a.getRawDataBBox()]
572 bias = im[a.getRawHorizontalOverscanBBox()]
577 ampImages.append(data)
579 ccdImage = im.Factory(bbox)
580 for ampImage, amp
in zip(ampImages, ccd):
587 nQuarter = ccd.getOrientation().getNQuarter()
594 isTrimmed=False, ccdOrigin=(0, 0), display=
None, binSize=1):
595 """Overlay bounding boxes on an image display. 599 ccd : `lsst.afw.cameraGeom.Detector` 600 Detector to iterate for the amp bounding boxes. 601 untrimmedCcdBbox : `lsst.geom.Box2I` or `None` 602 Bounding box of the un-trimmed Detector. 604 number of 90 degree rotations to apply to the bounding boxes (used for rotated chips). 606 Is the Detector image over which the boxes are layed trimmed? 607 ccdOrigin : `tuple` of `float` 608 Detector origin relative to the parent origin if in a larger pixel grid. 609 display : `lsst.afw.display.Display` 610 Image display to display on. 612 Bin the image by this factor in both dimensions. 617 - Entire detector GREEN 618 - All data for amp GREEN 619 - HorizontalPrescan YELLOW 620 - HorizontalOverscan RED 622 - VerticalOverscan MAGENTA 623 - VerticalOverscan MAGENTA 626 raise RuntimeError(
"Please specify a display")
628 if untrimmedCcdBbox
is None:
630 untrimmedCcdBbox = ccd.getBBox()
633 for a
in ccd.getAmplifiers():
634 bbox = a.getRawBBox()
635 untrimmedCcdBbox.include(bbox)
637 with display.Buffering():
638 ccdDim = untrimmedCcdBbox.getDimensions()
642 ampbbox = amp.getBBox()
644 ampbbox = amp.getRawBBox()
648 displayUtils.drawBBox(ampbbox, origin=ccdOrigin, borderWidth=0.49,
649 display=display, bin=binSize)
651 if not isTrimmed
and amp.getHasRawInfo():
652 for bbox, ctype
in ((amp.getRawHorizontalOverscanBBox(), afwDisplay.RED),
653 (amp.getRawDataBBox(), afwDisplay.BLUE),
654 (amp.getRawVerticalOverscanBBox(),
656 (amp.getRawPrescanBBox(), afwDisplay.YELLOW)):
659 displayUtils.drawBBox(bbox, origin=ccdOrigin, borderWidth=0.49, ctype=ctype,
660 display=display, bin=binSize)
662 xc, yc = (ampbbox.getMin()[0] + ampbbox.getMax()[0])//2, (ampbbox.getMin()[1] +
663 ampbbox.getMax()[1])//2
676 ccdHeight = ccdBbox.getHeight()
677 ccdWidth = ccdBbox.getWidth()
681 xc, yc = 0.5*ccdHeight + c*xc + s*yc, 0.5*ccdWidth + -s*xc + c*yc
686 display.dot(str(amp.getName()), xc/binSize,
687 yc/binSize, textAngle=nQuarter*90)
689 displayUtils.drawBBox(ccdBbox, origin=ccdOrigin,
690 borderWidth=0.49, ctype=afwDisplay.MAGENTA, display=display, bin=binSize)
693 def showAmp(amp, imageSource=FakeImageDataSource(isTrimmed=
False), display=
None, overlay=
True,
694 imageFactory=afwImage.ImageU):
695 """Show an amp in an image display. 699 amp : `lsst.afw.tables.AmpInfoRecord` 700 Amp record to use in display. 701 imageSource : `FakeImageDataSource` or `None` 702 Source for getting the amp image. Must have a ``getAmpImage()`` method. 703 display : `lsst.afw.display.Display` 704 Image display to use. 706 Overlay bounding boxes? 707 imageFactory : callable like `lsst.afw.image.Image` 708 Type of image to display (only used if ampImage is `None`). 711 display = _getDisplayFromDisplayOrFrame(display)
713 ampImage = imageSource.getAmpImage(amp, imageFactory=imageFactory)
714 ampImSize = ampImage.getDimensions()
715 title = amp.getName()
716 display.mtv(ampImage, title=title)
718 with display.Buffering():
719 if amp.getHasRawInfo()
and ampImSize == amp.getRawBBox().getDimensions():
720 bboxes = [(amp.getRawBBox(), 0.49, afwDisplay.GREEN), ]
721 xy0 = bboxes[0][0].getMin()
723 (amp.getRawHorizontalOverscanBBox(), 0.49, afwDisplay.RED))
724 bboxes.append((amp.getRawDataBBox(), 0.49, afwDisplay.BLUE))
725 bboxes.append((amp.getRawPrescanBBox(),
726 0.49, afwDisplay.YELLOW))
727 bboxes.append((amp.getRawVerticalOverscanBBox(),
728 0.49, afwDisplay.MAGENTA))
730 bboxes = [(amp.getBBox(), 0.49,
None), ]
731 xy0 = bboxes[0][0].getMin()
733 for bbox, borderWidth, ctype
in bboxes:
738 displayUtils.drawBBox(
739 bbox, borderWidth=borderWidth, ctype=ctype, display=display)
742 def showCcd(ccd, imageSource=FakeImageDataSource(), display=
None, overlay=
True,
743 imageFactory=afwImage.ImageF, binSize=1, inCameraCoords=
False):
744 """Show a CCD on display. 748 ccd : `lsst.afw.cameraGeom.Detector` 749 Detector to use in display. 750 imageSource : `FakeImageDataSource` or `None` 751 Source to get ccd images. Must have a ``getCcdImage()`` method. 752 display : `lsst.afw.display.Display` 753 image display to use. 755 Show amp bounding boxes on the displayed image? 756 imageFactory : callable like `lsst.afw.image.Image` 757 The image factory to use in generating the images. 759 Bin the image by this factor in both dimensions. 760 inCameraCoords : `bool` 761 Show the Detector in camera coordinates? 763 display = _getDisplayFromDisplayOrFrame(display)
767 ccdImage, ccd = imageSource.getCcdImage(
768 ccd, imageFactory=imageFactory, binSize=binSize)
770 ccdBbox = ccdImage.getBBox()
771 if ccdBbox.getDimensions() == ccd.getBBox().getDimensions():
777 nQuarter = ccd.getOrientation().getNQuarter()
779 title = ccd.getName()
784 display.mtv(ccdImage, title=title)
788 ccdOrigin, display, binSize)
794 """Get the bounding boxes of a list of Detectors within a camera sized pixel grid 798 ccdList : `lsst.afw.cameraGeom.Detector` 801 Bin the image by this factor in both dimensions. 802 pixelSize_o : `float` 803 Size of the pixel in mm. 805 Origin of the camera pixel grid in pixels. 809 boxList : `list` [`lsst.geom.Box2I`] 810 A list of bounding boxes in camera pixel coordinates. 814 if not pixelSize_o == ccd.getPixelSize():
816 "Cameras with detectors with different pixel scales are not currently supported")
819 for corner
in ccd.getCorners(FOCAL_PLANE):
820 dbbox.include(corner)
822 nQuarter = ccd.getOrientation().getNQuarter()
823 cbbox = ccd.getBBox()
824 ex = cbbox.getDimensions().getX()//binSize
825 ey = cbbox.getDimensions().getY()//binSize
830 int(llc.getY()//pixelSize_o.getY()/binSize)))
832 -int(origin.getY())//binSize))
838 """Get the bounding box of a camera sized image in pixels 842 camBbox : `lsst.geom.Box2D` 843 Camera bounding box in focal plane coordinates (mm). 845 Size of a detector pixel in mm. 847 Buffer around edge of image in pixels. 851 box : `lsst.geom.Box2I` 852 The resulting bounding box. 855 int(camBbox.getMinY()//pixelSize.getY()))
857 int(camBbox.getMaxY()//pixelSize.getY()))
859 retBox.grow(bufferSize)
863 def makeImageFromCamera(camera, detectorNameList=None, background=numpy.nan, bufferSize=10,
864 imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageU, binSize=1):
865 """Make an Image of a Camera. 867 Put each detector's image in the correct location and orientation on the 868 focal plane. The input images can be binned to an integer fraction of their 873 camera : `lsst.afw.cameraGeom.Camera` 874 Camera object to use to make the image. 875 detectorNameList : `list` [`str`] 876 List of detector names from ``camera`` to use in building the image. 877 Use all Detectors if `None`. 879 Value to use where there is no Detector. 881 Size of border in binned pixels to make around the camera image. 882 imageSource : `FakeImageDataSource` or `None` 883 Source to get ccd images. Must have a ``getCcdImage()`` method. 884 imageFactory : callable like `lsst.afw.image.Image` 885 Type of image to build. 887 Bin the image by this factor in both dimensions. 891 image : `lsst.afw.image.Image` 892 Image of the entire camera. 896 if detectorNameList
is None:
899 ccdList = [camera[name]
for name
in detectorNameList]
901 if detectorNameList
is None:
902 camBbox = camera.getFpBBox()
905 for detName
in detectorNameList:
906 for corner
in camera[detName].getCorners(FOCAL_PLANE):
907 camBbox.include(corner)
909 pixelSize_o = camera[
next(camera.getNameIter())].getPixelSize()
911 origin = camBbox.getMin()
913 camIm = imageFactory(int(math.ceil(camBbox.getDimensions().getX()/binSize)),
914 int(math.ceil(camBbox.getDimensions().getY()/binSize)))
915 camIm[:] = imageSource.background
917 assert imageSource.isTrimmed,
"isTrimmed is False isn't supported by getCcdInCamBBoxList" 920 for det, bbox
in zip(ccdList, boxList):
921 im = imageSource.getCcdImage(det, imageFactory, binSize)[0]
925 imView = camIm.Factory(camIm, bbox, afwImage.LOCAL)
929 log.error(
"Unable to fit image for detector \"%s\" into image of camera: %s" % (det.getName(), e))
934 def showCamera(camera, imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageF,
935 detectorNameList=
None, binSize=10, bufferSize=10, overlay=
True, title=
"",
936 showWcs=
None, ctype=afwDisplay.GREEN, textSize=1.25, originAtCenter=
True, display=
None,
938 """Show a Camera on display, with the specified display. 940 The rotation of the sensors is snapped to the nearest multiple of 90 deg. 941 Also note that the pixel size is constant over the image array. The lower 942 left corner (LLC) of each sensor amp is snapped to the LLC of the pixel 943 containing the LLC of the image. 947 camera : `lsst.afw.cameraGeom.Camera` 948 Camera object to use to make the image. 949 imageSource : `FakeImageDataSource` or `None` 950 Source to get ccd images. Must have a ``getCcdImage()`` method. 951 imageFactory : `lsst.afw.image.Image` 952 Type of image to make 953 detectorNameList : `list` [`str`] or `None` 954 List of detector names from `camera` to use in building the image. 955 Use all Detectors if `None`. 957 Bin the image by this factor in both dimensions. 959 Size of border in binned pixels to make around the camera image. 961 Overlay Detector IDs and boundaries? 963 Title to use in display. 965 Include a WCS in the display? 966 ctype : `lsst.afw.display.COLOR` or `str` 967 Color to use when drawing Detector boundaries. 969 Size of detector labels 970 originAtCenter : `bool` 971 Put origin of the camera WCS at the center of the image? 972 If `False`, the origin will be at the lower left. 973 display : `lsst.afw.display` 974 Image display on which to display. 976 All remaining keyword arguments are passed to makeImageFromCamera 980 image : `lsst.afw.image.Image` 983 display = _getDisplayFromDisplayOrFrame(display)
987 cameraImage =
makeImageFromCamera(camera, detectorNameList=detectorNameList, bufferSize=bufferSize,
988 imageSource=imageSource, imageFactory=imageFactory, binSize=binSize,
991 if detectorNameList
is None:
992 ccdList = [camera[name]
for name
in camera.getNameIter()]
994 ccdList = [camera[name]
for name
in detectorNameList]
996 if detectorNameList
is None:
997 camBbox = camera.getFpBBox()
1000 for detName
in detectorNameList:
1001 for corner
in camera[detName].getCorners(FOCAL_PLANE):
1002 camBbox.include(corner)
1003 pixelSize = ccdList[0].getPixelSize()
1008 cameraImage.getBBox()).getCenter()
1017 title = camera.getName()
1018 display.mtv(cameraImage, title=title, wcs=wcs)
1021 with display.Buffering():
1023 camBbox, pixelSize, bufferSize*binSize)
1025 ccdList, binSize, pixelSize, camBbox.getMin())
1026 for bbox, ccd
in zip(bboxList, ccdList):
1027 nQuarter = ccd.getOrientation().getNQuarter()
1030 displayUtils.drawBBox(
1031 bbox, borderWidth=0.5, ctype=ctype, display=display)
1032 dims = bbox.getDimensions()
1033 display.dot(ccd.getName(), bbox.getMinX() + dims.getX()/2, bbox.getMinY() + dims.getY()/2,
1034 ctype=ctype, size=textSize, textAngle=nQuarter*90)
1040 """Make a WCS for the focal plane geometry 1041 (i.e. one that returns positions in "mm") 1046 Size of the image pixels in physical units 1047 referencePixel : `lsst.geom.Point2D` 1048 Pixel for origin of WCS 1053 Wcs object for mapping between pixels and focal plane. 1056 if referencePixel
is None:
1059 md.set(
"CRPIX%d"%(i + 1), referencePixel[i])
1060 md.set(
"CRVAL%d"%(i + 1), 0.)
1061 md.set(
"CDELT1", pixelSize[0])
1062 md.set(
"CDELT2", pixelSize[1])
1063 md.set(
"CTYPE1",
"CAMERA_X")
1064 md.set(
"CTYPE2",
"CAMERA_Y")
1065 md.set(
"CUNIT1",
"mm")
1066 md.set(
"CUNIT2",
"mm")
1072 """Find the Amp with the specified pixel position within the composite 1076 ccd : `lsst.afw.cameraGeom.Detector` 1077 Detector to look in. 1078 pixelPosition : `lsst.geom.Point2I` 1079 The pixel position to find the amp for. 1083 `lsst.afw.table.AmpInfoCatalog` 1084 Amp record in which ``pixelPosition`` falls or `None` if no Amp found. 1087 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)