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']
43 from .rotateBBoxBy90
import rotateBBoxBy90
44 from .assembleImage
import assembleAmplifierImage, assembleAmplifierRawImage
45 from .cameraGeomLib
import FIELD_ANGLE, FOCAL_PLANE
53 """Put Wcs from an Amp image into CCD coordinates 57 wcs : `lsst.afw.geom.SkyWcs` 58 The WCS object to start from. 59 amp : `lsst.afw.table.AmpInfoRecord` 62 Is the image to which the WCS refers trimmed of non-imaging pixels? 66 ampWcs : `lsst.afw.geom.SkyWcs` 69 if not amp.getHasRawInfo():
70 raise RuntimeError(
"Cannot modify wcs without raw amp information")
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 = {0:
'b', 1:
'y', 2:
'g', 3:
'r'} 152 plt.figure(figsize=figsize) 157 corners = [(c.getX(), c.getY())
for c
in det.getCorners(FOCAL_PLANE)]
158 for corner
in corners:
159 xvals.append(corner[0])
160 yvals.append(corner[1])
161 colors.append(colorMap[det.getType()])
162 patches.append(Polygon(corners,
True))
163 center = det.getOrientation().getFpPosition()
164 ax.text(center.getX(), center.getY(), det.getId()
if useIds
else det.getName(),
165 horizontalalignment=
'center', size=6)
167 patchCollection = PatchCollection(patches, alpha=0.6, facecolor=colors)
168 ax.add_collection(patchCollection)
169 ax.scatter(xs, ys, s=10, alpha=.7, linewidths=0., c=pcolors)
170 ax.set_xlim(
min(xvals) -
abs(0.1*
min(xvals)),
172 ax.set_ylim(
min(yvals) -
abs(0.1*
min(yvals)),
174 ax.set_xlabel(
'Focal Plane X (mm)')
175 ax.set_ylabel(
'Focal Plane Y (mm)')
176 if savePath
is not None:
177 plt.savefig(savePath)
182 def makeImageFromAmp(amp, imValue=None, imageFactory=afwImage.ImageU, markSize=10, markValue=0,
183 scaleGain=lambda gain: (gain*1000)//10):
184 """Make an image from an amp object. 186 Since images are integer images by default, the gain needs to be scaled to 187 give enough dynamic range to see variation from amp to amp. 188 The scaling algorithm is assignable. 192 amp : `lsst.afw.table.AmpInfoRecord` 193 Amp record to use for constructing the raw amp image. 194 imValue : `float` or `None` 195 Value to assign to the constructed image, or scaleGain(gain) if `None`. 196 imageFactory : callable like `lsst.afw.image.Image` 197 Type of image to construct. 199 Size of mark at read corner in pixels. 201 Value of pixels in the read corner mark. 203 The function by which to scale the gain (must take a single argument). 207 ampImage : `lsst.afw.image` 208 An untrimmed amp image, of the type produced by ``imageFactory``. 210 if not amp.getHasRawInfo():
212 "Can't create a raw amp image without raw amp information")
213 bbox = amp.getRawBBox()
214 dbbox = amp.getRawDataBBox()
215 img = imageFactory(bbox)
217 img.set(
int(scaleGain(amp.getGain())))
222 if amp.getReadoutCorner() == 0:
223 markbbox.include(dbbox.getMin())
225 elif amp.getReadoutCorner() == 1:
227 markbbox.include(cornerPoint)
229 elif amp.getReadoutCorner() == 2:
231 markbbox.include(cornerPoint)
233 elif amp.getReadoutCorner() == 3:
235 markbbox.include(cornerPoint)
238 raise RuntimeError(
"Could not set readout corner")
239 mimg = imageFactory(img, markbbox)
245 """Calculate the raw ccd bounding box. 249 ccd : `lsst.afw.cameraGeom.Detector` 250 Detector for which to calculate the un-trimmed bounding box. 254 bbox : `lsst.geom.Box2I` or `None` 255 Bounding box of the un-trimmed Detector, or `None` if there is not enough 256 information to calculate raw BBox. 260 if not amp.getHasRawInfo():
262 tbbox = amp.getRawBBox()
263 tbbox.shift(amp.getRawXYOffset())
268 def makeImageFromCcd(ccd, isTrimmed=True, showAmpGain=True, imageFactory=afwImage.ImageU, rcMarkSize=10,
270 """Make an Image of a CCD. 274 ccd : `lsst.afw.cameraGeom.Detector` 275 Detector to use in making the image. 277 Assemble a trimmed Detector image. 279 Use the per-amp gain to color the pixels in the image? 280 imageFactory : callable like `lsst.afw.image.Image` 281 Image type to generate. 283 Size of the mark to make in the amp images at the read corner. 285 Bin the image by this factor in both dimensions. 289 image : `lsst.afw.image.Image` 290 Image of the Detector (type returned by ``imageFactory``). 299 if amp.getHasRawInfo():
302 amp, imageFactory=imageFactory, markSize=rcMarkSize))
305 imageFactory=imageFactory, markSize=rcMarkSize))
308 if len(ampImages) > 0:
309 ccdImage = imageFactory(bbox)
310 for ampImage, amp
in zip(ampImages, ccd):
318 "Cannot create untrimmed CCD without amps with raw information")
319 ccdImage = imageFactory(ccd.getBBox())
325 """A class to retrieve synthetic images for display by the show* methods 330 Should amps be trimmed? 334 The value of any pixels that lie outside the CCDs. 336 Color the amp segments with the gain of the amp? 338 Size of the side of the box used to mark the read corner. 340 Value to assign the read corner mark. 341 ampImValue : `float` or `None` 342 Value to assign to amps; scaleGain(gain) is used if `None`. 344 Function to scale the gain by. 346 def __init__(self, isTrimmed=True, verbose=False, background=numpy.nan,
347 showAmpGain=True, markSize=10, markValue=0,
348 ampImValue=None, scaleGain=lambda gain: (gain*1000)//10):
359 """Return a CCD image for the detector and the (possibly updated) Detector. 363 det : `lsst.afw.cameraGeom.Detector` 364 Detector to use for making the image. 365 imageFactory : callable like `lsst.afw.image.Image` 366 Image constructor for making the image. 368 Bin the image by this factor in both dimensions. 372 ccdImage : `lsst.afw.image.Image` 373 The constructed image. 376 imageFactory=imageFactory, binSize=binSize), det
379 """Return an amp segment image. 383 amp : `lsst.afw.table.AmpInfoTable` 384 AmpInfoTable for this amp. 385 imageFactory : callable like `lsst.afw.image.Image` 386 Image constructor for making the image. 390 ampImage : `lsst.afw.image.Image` 391 The constructed image. 397 ampImage = ampImage.Factory(ampImage, amp.getRawDataBBox())
402 """A class to return an Image of a given Ccd using the butler. 406 butler : `lsst.daf.persistence.Butler` or `None` 407 The butler to use. If `None`, an empty image is returned. 409 The type of image to read (e.g. raw, bias, flat, calexp). 411 If true, the showCamera command expects to be given trimmed images. 413 Be chatty (in particular, log any error messages from the butler)? 415 The value of any pixels that lie outside the CCDs. 417 A function called with (image, ccd, butler) for every image, which 418 returns the image to be displayed (e.g. rawCallback). The image must 419 be of the correct size, allowing for the value of isTrimmed. 421 Passed to the butler. 423 Passed to the butler. 427 You can define a short named function as a callback:: 429 def callback(im, ccd, imageSource): 430 return cameraGeom.utils.rawCallback(im, ccd, imageSource, correctGain=True) 432 def __init__(self, butler=None, type="raw",
433 isTrimmed=True, verbose=False, background=numpy.nan,
434 callback=None, *args, **kwargs):
435 super(ButlerImage, self).
__init__(*args)
445 def _prepareImage(self, ccd, im, binSize, allowRotate=True):
451 im, ccd.getOrientation().getNQuarter())
455 def getCcdImage(self, ccd, imageFactory=afwImage.ImageF, binSize=1, asMaskedImage=False):
456 """Return an image of the specified ccd, and also the (possibly updated) ccd""" 466 if self.
butler is not None:
468 for dataId
in [dict(detector=ccd.getId()), dict(ccd=ccd.getId()), dict(ccd=ccd.getName())]:
471 except FitsError
as e:
472 err = IOError(e.args[0].split(
'\n')[0])
474 except Exception
as e:
479 ccd = im.getDetector()
484 im = im.getMaskedImage()
486 im = im.getMaskedImage().getImage()
489 print(
"Reading %s: %s" % (ccd.getId(), err))
491 log.warn(
"Reading %s: %s", ccd.getId(), err)
494 return self.
_prepareImage(ccd, imageFactory(*bbox.getDimensions()), binSize), ccd
496 if self.
type ==
"raw":
497 if hasattr(im,
'convertF'):
505 im = self.
callback(im, ccd, imageSource=self)
506 except Exception
as e:
508 log.error(
"callback failed: %s" % e)
509 im = imageFactory(*bbox.getDimensions())
513 return self.
_prepareImage(ccd, im, binSize, allowRotate=allowRotate), ccd
517 correctGain=False, subtractBias=False, convertToFloat=False, obeyNQuarter=True):
518 """A callback function that may or may not subtract bias/correct gain/trim 523 im : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage` or `lsst.afw.image.Exposure` 524 An image of a chip, ready to be binned and maybe rotated. 525 ccd : `lsst.afw.cameraGeom.Detector` or `None` 526 The Detector; if `None` assume that im is an exposure and extract its Detector. 527 imageSource : `FakeImageDataSource` or `None` 528 Source to get ccd images. Must have a `getCcdImage()` method. 530 Correct each amplifier for its gain? 531 subtractBias : `bool` 532 Subtract the bias from each amplifier? 533 convertToFloat : `bool` 534 Convert ``im`` to floating point if possible. 535 obeyNQuarter : `bool` 536 Obey nQuarter from the Detector (default: True) 540 image : `lsst.afw.image.Image` like 541 The constructed image (type returned by ``im.Factory``). 545 If imageSource is derived from ButlerImage, imageSource.butler is available. 548 ccd = im.getDetector()
549 if hasattr(im,
"getMaskedImage"):
550 im = im.getMaskedImage()
551 if convertToFloat
and hasattr(im,
"convertF"):
554 isTrimmed = imageSource.isTrimmed
563 data = im[a.getRawDataBBox()]
568 bias = im[a.getRawHorizontalOverscanBBox()]
573 ampImages.append(data)
575 ccdImage = im.Factory(bbox)
576 for ampImage, amp
in zip(ampImages, ccd):
583 nQuarter = ccd.getOrientation().getNQuarter()
590 isTrimmed=False, ccdOrigin=(0, 0), display=
None, binSize=1):
591 """Overlay bounding boxes on an image display. 595 ccd : `lsst.afw.cameraGeom.Detector` 596 Detector to iterate for the amp bounding boxes. 597 untrimmedCcdBbox : `lsst.geom.Box2I` or `None` 598 Bounding box of the un-trimmed Detector. 600 number of 90 degree rotations to apply to the bounding boxes (used for rotated chips). 602 Is the Detector image over which the boxes are layed trimmed? 603 ccdOrigin : `tuple` of `float` 604 Detector origin relative to the parent origin if in a larger pixel grid. 605 display : `lsst.afw.display.Display` 606 Image display to display on. 608 Bin the image by this factor in both dimensions. 613 - Entire detector GREEN 614 - All data for amp GREEN 615 - HorizontalPrescan YELLOW 616 - HorizontalOverscan RED 618 - VerticalOverscan MAGENTA 619 - VerticalOverscan MAGENTA 622 raise RuntimeError(
"Please specify a display")
624 if untrimmedCcdBbox
is None:
626 untrimmedCcdBbox = ccd.getBBox()
629 for a
in ccd.getAmpInfoCatalog():
630 bbox = a.getRawBBox()
631 untrimmedCcdBbox.include(bbox)
633 with display.Buffering():
634 ccdDim = untrimmedCcdBbox.getDimensions()
638 ampbbox = amp.getBBox()
640 ampbbox = amp.getRawBBox()
644 displayUtils.drawBBox(ampbbox, origin=ccdOrigin, borderWidth=0.49,
645 display=display, bin=binSize)
647 if not isTrimmed
and amp.getHasRawInfo():
648 for bbox, ctype
in ((amp.getRawHorizontalOverscanBBox(), afwDisplay.RED),
649 (amp.getRawDataBBox(), afwDisplay.BLUE),
650 (amp.getRawVerticalOverscanBBox(),
652 (amp.getRawPrescanBBox(), afwDisplay.YELLOW)):
655 displayUtils.drawBBox(bbox, origin=ccdOrigin, borderWidth=0.49, ctype=ctype,
656 display=display, bin=binSize)
658 xc, yc = (ampbbox.getMin()[0] + ampbbox.getMax()[0])//2, (ampbbox.getMin()[1] +
659 ampbbox.getMax()[1])//2
672 ccdHeight = ccdBbox.getHeight()
673 ccdWidth = ccdBbox.getWidth()
677 xc, yc = 0.5*ccdHeight + c*xc + s*yc, 0.5*ccdWidth + -s*xc + c*yc
682 display.dot(
str(amp.getName()), xc/binSize,
683 yc/binSize, textAngle=nQuarter*90)
685 displayUtils.drawBBox(ccdBbox, origin=ccdOrigin,
686 borderWidth=0.49, ctype=afwDisplay.MAGENTA, display=display, bin=binSize)
689 def showAmp(amp, imageSource=FakeImageDataSource(isTrimmed=
False), display=
None, overlay=
True,
690 imageFactory=afwImage.ImageU):
691 """Show an amp in an image display. 695 amp : `lsst.afw.tables.AmpInfoRecord` 696 Amp record to use in display. 697 imageSource : `FakeImageDataSource` or `None` 698 Source for getting the amp image. Must have a ``getAmpImage()`` method. 699 display : `lsst.afw.display.Display` 700 Image display to use. 702 Overlay bounding boxes? 703 imageFactory : callable like `lsst.afw.image.Image` 704 Type of image to display (only used if ampImage is `None`). 707 display = _getDisplayFromDisplayOrFrame(display)
709 ampImage = imageSource.getAmpImage(amp, imageFactory=imageFactory)
710 ampImSize = ampImage.getDimensions()
711 title = amp.getName()
712 display.mtv(ampImage, title=title)
714 with display.Buffering():
715 if amp.getHasRawInfo()
and ampImSize == amp.getRawBBox().getDimensions():
716 bboxes = [(amp.getRawBBox(), 0.49, afwDisplay.GREEN), ]
717 xy0 = bboxes[0][0].getMin()
719 (amp.getRawHorizontalOverscanBBox(), 0.49, afwDisplay.RED))
720 bboxes.append((amp.getRawDataBBox(), 0.49, afwDisplay.BLUE))
721 bboxes.append((amp.getRawPrescanBBox(),
722 0.49, afwDisplay.YELLOW))
723 bboxes.append((amp.getRawVerticalOverscanBBox(),
724 0.49, afwDisplay.MAGENTA))
726 bboxes = [(amp.getBBox(), 0.49,
None), ]
727 xy0 = bboxes[0][0].getMin()
729 for bbox, borderWidth, ctype
in bboxes:
734 displayUtils.drawBBox(
735 bbox, borderWidth=borderWidth, ctype=ctype, display=display)
738 def showCcd(ccd, imageSource=FakeImageDataSource(), display=
None, overlay=
True,
739 imageFactory=afwImage.ImageF, binSize=1, inCameraCoords=
False):
740 """Show a CCD on display. 744 ccd : `lsst.afw.cameraGeom.Detector` 745 Detector to use in display. 746 imageSource : `FakeImageDataSource` or `None` 747 Source to get ccd images. Must have a ``getCcdImage()`` method. 748 display : `lsst.afw.display.Display` 749 image display to use. 751 Show amp bounding boxes on the displayed image? 752 imageFactory : callable like `lsst.afw.image.Image` 753 The image factory to use in generating the images. 755 Bin the image by this factor in both dimensions. 756 inCameraCoords : `bool` 757 Show the Detector in camera coordinates? 759 display = _getDisplayFromDisplayOrFrame(display)
763 ccdImage, ccd = imageSource.getCcdImage(
764 ccd, imageFactory=imageFactory, binSize=binSize)
766 ccdBbox = ccdImage.getBBox()
767 if ccdBbox.getDimensions() == ccd.getBBox().getDimensions():
773 nQuarter = ccd.getOrientation().getNQuarter()
775 title = ccd.getName()
780 display.mtv(ccdImage, title=title)
784 ccdOrigin, display, binSize)
790 """Get the bounding boxes of a list of Detectors within a camera sized pixel grid 794 ccdList : `lsst.afw.cameraGeom.Detector` 797 Bin the image by this factor in both dimensions. 798 pixelSize_o : `float` 799 Size of the pixel in mm. 801 Origin of the camera pixel grid in pixels. 805 boxList : `list` of `lsst.geom.Box2I` 806 A list of bounding boxes in camera pixel coordinates. 810 if not pixelSize_o == ccd.getPixelSize():
812 "Cameras with detectors with different pixel scales are not currently supported")
815 for corner
in ccd.getCorners(FOCAL_PLANE):
816 dbbox.include(corner)
818 nQuarter = ccd.getOrientation().getNQuarter()
819 cbbox = ccd.getBBox()
820 ex = cbbox.getDimensions().getX()//binSize
821 ey = cbbox.getDimensions().getY()//binSize
826 int(llc.getY()//pixelSize_o.getY()/binSize)))
828 -
int(origin.getY())//binSize))
834 """Get the bounding box of a camera sized image in pixels 838 camBbox : `lsst.geom.Box2D` 839 Camera bounding box in focal plane coordinates (mm). 841 Size of a detector pixel in mm. 843 Buffer around edge of image in pixels. 847 box : `lsst.geom.Box2I` 848 The resulting bounding box. 851 int(camBbox.getMinY()//pixelSize.getY()))
853 int(camBbox.getMaxY()//pixelSize.getY()))
855 retBox.grow(bufferSize)
859 def makeImageFromCamera(camera, detectorNameList=None, background=numpy.nan, bufferSize=10,
860 imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageU, binSize=1):
861 """Make an Image of a Camera. 863 Put each detector's image in the correct location and orientation on the 864 focal plane. The input images can be binned to an integer fraction of their 869 camera : `lsst.afw.cameraGeom.Camera` 870 Camera object to use to make the image. 871 detectorNameList : `list` of `str` 872 List of detector names from ``camera`` to use in building the image. 873 Use all Detectors if `None`. 875 Value to use where there is no Detector. 877 Size of border in binned pixels to make around the camera image. 878 imageSource : `FakeImageDataSource` or `None` 879 Source to get ccd images. Must have a ``getCcdImage()`` method. 880 imageFactory : callable like `lsst.afw.image.Image` 881 Type of image to build. 883 Bin the image by this factor in both dimensions. 887 image : `lsst.afw.image.Image` 888 Image of the entire camera. 892 if detectorNameList
is None:
895 ccdList = [camera[name]
for name
in detectorNameList]
897 if detectorNameList
is None:
898 camBbox = camera.getFpBBox()
901 for detName
in detectorNameList:
902 for corner
in camera[detName].getCorners(FOCAL_PLANE):
903 camBbox.include(corner)
905 pixelSize_o = camera[next(camera.getNameIter())].getPixelSize()
907 origin = camBbox.getMin()
909 camIm = imageFactory(
int(math.ceil(camBbox.getDimensions().getX()/binSize)),
910 int(math.ceil(camBbox.getDimensions().getY()/binSize)))
911 camIm[:] = imageSource.background
913 assert imageSource.isTrimmed,
"isTrimmed is False isn't supported by getCcdInCamBBoxList" 916 for det, bbox
in zip(ccdList, boxList):
917 im = imageSource.getCcdImage(det, imageFactory, binSize)[0]
921 imView = camIm.Factory(camIm, bbox, afwImage.LOCAL)
925 log.error(
"Unable to fit image for detector \"%s\" into image of camera: %s" % (det.getName(), e))
930 def showCamera(camera, imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageF,
931 detectorNameList=
None, binSize=10, bufferSize=10, overlay=
True, title=
"",
932 showWcs=
None, ctype=afwDisplay.GREEN, textSize=1.25, originAtCenter=
True, display=
None,
934 """Show a Camera on display, with the specified display. 936 The rotation of the sensors is snapped to the nearest multiple of 90 deg. 937 Also note that the pixel size is constant over the image array. The lower 938 left corner (LLC) of each sensor amp is snapped to the LLC of the pixel 939 containing the LLC of the image. 943 camera : `lsst.afw.cameraGeom.Camera` 944 Camera object to use to make the image. 945 imageSource : `FakeImageDataSource` or `None` 946 Source to get ccd images. Must have a ``getCcdImage()`` method. 947 imageFactory : `lsst.afw.image.Image` 948 Type of image to make 949 detectorNameList : `list` of `str` or `None` 950 List of detector names from `camera` to use in building the image. 951 Use all Detectors if `None`. 953 Bin the image by this factor in both dimensions. 955 Size of border in binned pixels to make around the camera image. 957 Overlay Detector IDs and boundaries? 959 Title to use in display. 961 Include a WCS in the display? 962 ctype : `lsst.afw.display.COLOR` or `str` 963 Color to use when drawing Detector boundaries. 965 Size of detector labels 966 originAtCenter : `bool` 967 Put origin of the camera WCS at the center of the image? 968 If `False`, the origin will be at the lower left. 969 display : `lsst.afw.display` 970 Image display on which to display. 972 All remaining keyword arguments are passed to makeImageFromCamera 976 image : `lsst.afw.image.Image` 979 display = _getDisplayFromDisplayOrFrame(display)
983 cameraImage =
makeImageFromCamera(camera, detectorNameList=detectorNameList, bufferSize=bufferSize,
984 imageSource=imageSource, imageFactory=imageFactory, binSize=binSize,
987 if detectorNameList
is None:
988 ccdList = [camera[name]
for name
in camera.getNameIter()]
990 ccdList = [camera[name]
for name
in detectorNameList]
992 if detectorNameList
is None:
993 camBbox = camera.getFpBBox()
996 for detName
in detectorNameList:
997 for corner
in camera[detName].getCorners(FOCAL_PLANE):
998 camBbox.include(corner)
999 pixelSize = ccdList[0].getPixelSize()
1004 cameraImage.getBBox()).getCenter()
1013 title = camera.getName()
1014 display.mtv(cameraImage, title=title, wcs=wcs)
1017 with display.Buffering():
1019 camBbox, pixelSize, bufferSize*binSize)
1021 ccdList, binSize, pixelSize, camBbox.getMin())
1022 for bbox, ccd
in zip(bboxList, ccdList):
1023 nQuarter = ccd.getOrientation().getNQuarter()
1026 displayUtils.drawBBox(
1027 bbox, borderWidth=0.5, ctype=ctype, display=display)
1028 dims = bbox.getDimensions()
1029 display.dot(ccd.getName(), bbox.getMinX() + dims.getX()/2, bbox.getMinY() + dims.getY()/2,
1030 ctype=ctype, size=textSize, textAngle=nQuarter*90)
1036 """Make a WCS for the focal plane geometry 1037 (i.e. one that returns positions in "mm") 1042 Size of the image pixels in physical units 1043 referencePixel : `lsst.geom.Point2D` 1044 Pixel for origin of WCS 1049 Wcs object for mapping between pixels and focal plane. 1052 if referencePixel
is None:
1055 md.set(
"CRPIX%d"%(i + 1), referencePixel[i])
1056 md.set(
"CRVAL%d"%(i + 1), 0.)
1057 md.set(
"CDELT1", pixelSize[0])
1058 md.set(
"CDELT2", pixelSize[1])
1059 md.set(
"CTYPE1",
"CAMERA_X")
1060 md.set(
"CTYPE2",
"CAMERA_Y")
1061 md.set(
"CUNIT1",
"mm")
1062 md.set(
"CUNIT2",
"mm")
1068 """Find the Amp with the specified pixel position within the composite 1072 ccd : `lsst.afw.cameraGeom.Detector` 1073 Detector to look in. 1074 pixelPosition : `lsst.geom.Point2I` 1075 The pixel position to find the amp for. 1079 `lsst.afw.table.AmpInfoCatalog` 1080 Amp record in which ``pixelPosition`` falls or `None` if no Amp found. 1083 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)
bool contains(VertexIterator const begin, VertexIterator const end, UnitVector3d const &v)
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)