Example #1
0
 def rotated(self, exp):
     nQuarter = exp.getDetector().getOrientation().getNQuarter()
     exp.setMaskedImage(afwMath.rotateImageBy90(exp.getMaskedImage(), nQuarter))
     try:
         yield exp
     finally:
         exp.setMaskedImage(afwMath.rotateImageBy90(exp.getMaskedImage(), 4 - nQuarter))
Example #2
0
 def rotated(self, exp):
     nQuarter = exp.getDetector().getOrientation().getNQuarter()
     exp.setMaskedImage(
         afwMath.rotateImageBy90(exp.getMaskedImage(), 4 - nQuarter))
     try:
         yield exp
     finally:
         exp.setMaskedImage(
             afwMath.rotateImageBy90(exp.getMaskedImage(), nQuarter))
Example #3
0
def makeImageFromCamera(camera,
                        detectorNameList=None,
                        background=numpy.nan,
                        bufferSize=10,
                        imageSource=FakeImageDataSource(),
                        imageFactory=afwImage.ImageU,
                        binSize=1):
    """!Make an Image of a Camera

    @param[in] camera  Camera object to use to make the image
    @param[in] detectorNameList  List of detector names to use in building the image.
               Use all Detectors if None.
    @param[in] background  Value to use where there is no Detector
    @param[in] bufferSize  Size of border in binned pixels to make around the camera image
    @param[in] imageSource  Source to get ccd images.  Must have a getCcdImage method
    @param[in] imageFactory  Type of image to build
    @param[in] binSize  bin factor
    @return an image of the camera
    """
    if detectorNameList is None:
        ccdList = camera
    else:
        ccdList = [camera[name] for name in detectorNameList]

    if detectorNameList is None:
        camBbox = camera.getFpBBox()
    else:
        camBbox = afwGeom.Box2D()
        for detName in detectorNameList:
            for corner in camera[detName].getCorners(FOCAL_PLANE):
                camBbox.include(corner)

    pixelSize_o = camera[next(camera.getNameIter())].getPixelSize()
    camBbox = getCameraImageBBox(camBbox, pixelSize_o, bufferSize * binSize)
    origin = camBbox.getMin()

    camIm = imageFactory(
        int(math.ceil(camBbox.getDimensions().getX() / binSize)),
        int(math.ceil(camBbox.getDimensions().getY() / binSize)))
    camIm[:] = imageSource.background

    assert imageSource.isTrimmed, "isTrimmed is False isn't supported by getCcdInCamBBoxList"

    boxList = getCcdInCamBBoxList(ccdList, binSize, pixelSize_o, origin)
    for det, bbox in zip(ccdList, boxList):
        im = imageSource.getCcdImage(det, imageFactory, binSize)[0]

        nQuarter = det.getOrientation().getNQuarter()
        im = afwMath.rotateImageBy90(im, nQuarter)

        imView = camIm.Factory(camIm, bbox, afwImage.LOCAL)
        import lsst.pex.exceptions as pexExceptions
        try:
            imView[:] = im
        except pexExceptions.LengthError:
            print(
                "Unable to fit image for detector \"%s\" into image of camera"
                % (det.getName()))

    return camIm
Example #4
0
def showCcd(ccd, imageSource=FakeImageDataSource(), frame=None, overlay=True, imageFactory=afwImage.ImageU, binSize=1, inCameraCoords=False):
    """!Show a CCD on ds9

    @param[in] ccd  Detector to use in display
    @param[in] imageSource  Source for producing images to display.  Must have a getCcdImage method.
    @param[in] frame  ds9 frame to use, defaults to frame zero
    @param[in] overlay  Show amp bounding boxes on the displayed image?
    @param[in] imageFactory  The image factory to use in generating the images.
    @param[in] binSize  Binning factor
    @param[in] inCameraCoords  Show the Detector in camera coordinates?
    """
    ccdOrigin = afwGeom.Point2I(0,0)
    nQuarter = 0
    ccdImage = imageSource.getCcdImage(ccd, imageFactory=imageFactory, binSize=binSize)

    ccdBbox = ccdImage.getBBox()
    if ccdBbox.getDimensions() == ccd.getBBox().getDimensions():
        isTrimmed = True
    else:
        isTrimmed = False

    if inCameraCoords:
        nQuarter = ccd.getOrientation().getNQuarter()
        ccdImage = afwMath.rotateImageBy90(ccdImage, nQuarter)
    title = ccd.getName()
    if isTrimmed:
        title += "(trimmed)"
    ds9.mtv(ccdImage, frame=frame, title=title)

    if overlay:
        overlayCcdBoxes(ccd, ccdBbox, nQuarter, isTrimmed, ccdOrigin, frame, binSize)
Example #5
0
    def testRotate(self):
        """Test that we end up with the correct image after rotating by 90 degrees"""

        for nQuarter, x, y in [(0, 0, 0), (1, 9, 0), (2, 19, 9), (3, 0, 19)]:
            outImage = afwMath.rotateImageBy90(self.inImage, nQuarter)
            if display:
                ds9.mtv(outImage, frame=nQuarter, title="out %d" % nQuarter)
            self.assertEqual(self.inImage.get(0, 0), outImage.get(x, y))
Example #6
0
 def _prepareImage(self, ccd, im, binSize, allowRotate=True):
     if binSize > 1:
         im = afwMath.binImage(im, binSize)
 
     if allowRotate:
         im = afwMath.rotateImageBy90(im, ccd.getOrientation().getNQuarter())
             
     return im
Example #7
0
    def _prepareImage(self, ccd, im, binSize, allowRotate=True):
        if binSize > 1:
            im = afwMath.binImage(im, binSize)

        if allowRotate:
            im = afwMath.rotateImageBy90(im,
                                         ccd.getOrientation().getNQuarter())

        return im
Example #8
0
 def testRotate(self):
     """Test that we end up with the correct image after rotating by 90 degrees.
     """
     for nQuarter, x, y in [(0, 0, 0), (1, 9, 0), (2, 19, 9), (3, 0, 19)]:
         outImage = afwMath.rotateImageBy90(self.inImage, nQuarter)
         if display:
             afwDisplay.Display(frame=nQuarter).mtv(outImage,
                                                    title=f"out {nQuarter}")
         self.assertEqual(self.inImage[0, 0, afwImage.LOCAL],
                          outImage[x, y, afwImage.LOCAL])
def eimageCallback(im, ccd=None, imageSource=None):
    """A callback to handle eimages"""

    im = im.convertF()

    nQuarter = 1
    im = rotateImageBy90(im, nQuarter)
    im = flipImage(im, True, False)

    return im
Example #10
0
def showCcd(ccd,
            imageSource=FakeImageDataSource(),
            display=None,
            overlay=True,
            imageFactory=afwImage.ImageF,
            binSize=1,
            inCameraCoords=False):
    """Show a CCD on display.

    Parameters
    ----------
    ccd : `lsst.afw.cameraGeom.Detector`
        Detector to use in display.
    imageSource : `FakeImageDataSource` or `None`
        Source to get ccd images.  Must have a ``getCcdImage()`` method.
    display : `lsst.afw.display.Display`
        image display to use.
    overlay : `bool`
        Show amp bounding boxes on the displayed image?
    imageFactory : callable like `lsst.afw.image.Image`
        The image factory to use in generating the images.
    binSize : `int`
        Bin the image by this factor in both dimensions.
    inCameraCoords : `bool`
        Show the Detector in camera coordinates?
    """
    display = _getDisplayFromDisplayOrFrame(display)

    ccdOrigin = lsst.geom.Point2I(0, 0)
    nQuarter = 0
    ccdImage, ccd = imageSource.getCcdImage(ccd,
                                            imageFactory=imageFactory,
                                            binSize=binSize)

    ccdBbox = ccdImage.getBBox()
    if ccdBbox.getDimensions() == ccd.getBBox().getDimensions():
        isTrimmed = True
    else:
        isTrimmed = False

    if inCameraCoords:
        nQuarter = ccd.getOrientation().getNQuarter()
        ccdImage = afwMath.rotateImageBy90(ccdImage, nQuarter)
    title = ccd.getName()
    if isTrimmed:
        title += "(trimmed)"

    if display:
        display.mtv(ccdImage, title=title)

        if overlay:
            overlayCcdBoxes(ccd, ccdBbox, nQuarter, isTrimmed, ccdOrigin,
                            display, binSize)

    return ccdImage
Example #11
0
def showCcd(ccd, imageSource=FakeImageDataSource(), display=None, frame=None, overlay=True,
            imageFactory=afwImage.ImageF, binSize=1, inCameraCoords=False):
    """Show a CCD on display.

    Parameters
    ----------
    ccd : `lsst.afw.cameraGeom.Detector`
        Detector to use in display.
    imageSource : `FakeImageDataSource` or `None`
        Source to get ccd images.  Must have a ``getCcdImage()`` method.
    display : `lsst.afw.display.Display`
        image display to use.
    frame : `None`
        frame ID on which to display. **Deprecated** in v12.
    overlay : `bool`
        Show amp bounding boxes on the displayed image?
    imageFactory : callable like `lsst.afw.image.Image`
        The image factory to use in generating the images.
    binSize : `int`
        Bin the image by this factor in both dimensions.
    inCameraCoords : `bool`
        Show the Detector in camera coordinates?
    """
    if frame is not None:
        warnings.warn("The frame kwarg is deprecated; use the `lsst.afw.display` system instead.",
                      DeprecationWarning)

    display = _getDisplayFromDisplayOrFrame(display, frame)

    ccdOrigin = lsst.geom.Point2I(0, 0)
    nQuarter = 0
    ccdImage, ccd = imageSource.getCcdImage(
        ccd, imageFactory=imageFactory, binSize=binSize)

    ccdBbox = ccdImage.getBBox()
    if ccdBbox.getDimensions() == ccd.getBBox().getDimensions():
        isTrimmed = True
    else:
        isTrimmed = False

    if inCameraCoords:
        nQuarter = ccd.getOrientation().getNQuarter()
        ccdImage = afwMath.rotateImageBy90(ccdImage, nQuarter)
    title = ccd.getName()
    if isTrimmed:
        title += "(trimmed)"

    if display:
        display.mtv(ccdImage, title=title)

        if overlay:
            overlayCcdBoxes(ccd, ccdBbox, nQuarter, isTrimmed,
                            ccdOrigin, display, binSize)

    return ccdImage
Example #12
0
def getDonut(icRecord, icExp, donutConfig):
    """Return numpy array containing donut cutout.
    """
    nquarter = icExp.getDetector().getOrientation().getNQuarter()
    if donutConfig.flip:
        nquarter += 2

    maskedImage = getCutout(icRecord.getX(), icRecord.getY(), icExp,
                            donutConfig.stampSize)
    maskedImage = afwMath.rotateImageBy90(maskedImage, nquarter)
    return maskedImage.getImage().getArray()
Example #13
0
    def testRotate(self):
        """Test that we end up with the correct image after rotating by 90 degrees"""

        for nQuarter, x, y in [(0, 0, 0),
                               (1, 9, 0),
                               (2, 19, 9),
                               (3, 0, 19)]:
            outImage = afwMath.rotateImageBy90(self.inImage, nQuarter)
            if display:
                ds9.mtv(outImage, frame=nQuarter, title="out %d" % nQuarter)
            self.assertEqual(self.inImage.get(0, 0), outImage.get(x, y))
Example #14
0
    def fitOneRecord(self,
                     record,
                     icExp,
                     camera,
                     nquarter=None,
                     pupilFactory=None,
                     wavelength=None,
                     detector=None,
                     pixelScale=None,
                     alpha=1.0,
                     oversampling=1.0,
                     padFactor=1.0):
        if pixelScale is None:
            pixelScale = icExp.getWcs().pixelScale()
        if detector is None:
            detector = icExp.getDetector()
        if wavelength is None:
            wavelength = self.getWavelength(icExp)
        if pupilFactory is None:
            visitInfo = icExp.getInfo().getVisitInfo()
            pupilFactory = self.getPupilFactory(camera, wavelength * alpha,
                                                pixelScale, visitInfo,
                                                oversampling, padFactor)
        if nquarter is None:
            nquarter = detector.getOrientation().getNQuarter()

        imX = record.getX()
        imY = record.getY()

        point = afwGeom.Point2D(record.getX(), record.getY())
        if self.config.doJacobian:
            jacobian = _getJacobian(detector, point)
        else:
            jacobian = np.eye(2)
        # Need to apply quarter rotations transformation to Jacobian.
        th = np.pi / 2 * nquarter
        sth, cth = np.sin(th), np.cos(th)
        rot = np.array([[cth, sth], [-sth, cth]])
        jacobian = np.dot(rot.T, np.dot(jacobian, rot))

        fpX = record['base_FPPosition_x']
        fpY = record['base_FPPosition_y']
        self.log.info("Donut is at {}, {}".format(fpX, fpY))
        subMaskedImage = afwMath.rotateImageBy90(
            getCutout(imX, imY, icExp, self.config.stampSize), nquarter)
        pupil = pupilFactory.getPupil(afwGeom.Point2D(fpX, fpY))

        return self.fitOneDonut(subMaskedImage,
                                wavelength,
                                pupil,
                                camera,
                                pixelScale,
                                jacobian,
                                alpha=alpha)
Example #15
0
 def testRotate(self):
     """Test that we end up with the correct image after rotating by 90 degrees.
     """
     for nQuarter, x, y in [(0, 0, 0),
                            (1, 9, 0),
                            (2, 19, 9),
                            (3, 0, 19)]:
         outImage = afwMath.rotateImageBy90(self.inImage, nQuarter)
         if display:
             afwDisplay.Display(frame=nQuarter).mtv(outImage, title="out %d" % nQuarter)
         self.assertEqual(self.inImage[0, 0, afwImage.LOCAL], outImage[x, y, afwImage.LOCAL])
Example #16
0
def makeImageFromCamera(camera, detectorNameList=None, background=numpy.nan, bufferSize=10,
                        imageSource=FakeImageDataSource(), imageFactory=afwImage.ImageU, binSize=1):
    """!Make an Image of a Camera

    @param[in] camera  Camera object to use to make the image
    @param[in] detectorNameList  List of detector names to use in building the image.
               Use all Detectors if None.
    @param[in] background  Value to use where there is no Detector
    @param[in] bufferSize  Size of border in binned pixels to make around the camera image
    @param[in] imageSource  Source to get ccd images.  Must have a getCcdImage method
    @param[in] imageFactory  Type of image to build
    @param[in] binSize  bin factor
    @return an image of the camera
    """
    if detectorNameList is None:
        ccdList = camera
    else:
        ccdList = [camera[name] for name in detectorNameList]

    if detectorNameList is None:
        camBbox = camera.getFpBBox()
    else:
        camBbox = afwGeom.Box2D()
        for detName in detectorNameList:
            for corner in camera[detName].getCorners(FOCAL_PLANE):
                camBbox.include(corner)

    pixelSize_o = camera[camera.getNameIter().next()].getPixelSize()
    camBbox = getCameraImageBBox(camBbox, pixelSize_o, bufferSize*binSize)
    origin = camBbox.getMin()

    camIm = imageFactory(int(math.ceil(camBbox.getDimensions().getX()/binSize)),
                         int(math.ceil(camBbox.getDimensions().getY()/binSize)))
    camIm[:] = imageSource.background

    assert imageSource.isTrimmed, "isTrimmed is False isn't supported by getCcdInCamBBoxList"

    boxList = getCcdInCamBBoxList(ccdList, binSize, pixelSize_o, origin) 
    for det, bbox in itertools.izip(ccdList, boxList):
        im = imageSource.getCcdImage(det, imageFactory, binSize)

        nQuarter = det.getOrientation().getNQuarter()
        im = afwMath.rotateImageBy90(im, nQuarter)
        
        imView = camIm.Factory(camIm, bbox, afwImage.LOCAL)
        try:
            imView[:] = im
        except Exception:
            pass

    return camIm
Example #17
0
    def run(self, expRef, butler):
        """Make summary plots of full focalplane images.
        """
        sbi = SimButlerImage(butler,
                             type=expRef.butlerSubset.datasetType,
                             visit=expRef.dataId['visit'])

        # Get the per ccd images
        def parse_name_to_dataId(name_str):
            raft, sensor = name_str.split()
            return {'raft': raft[-3:], 'sensor': sensor[-3:]}

        for ccd in butler.get('camera'):
            data_id = parse_name_to_dataId(ccd.getName())
            data_id.update(expRef.dataId)
            try:
                binned_im = sbi.getCcdImage(ccd,
                                            binSize=self.config.sensorBinSize,
                                            as_masked_image=True)[0]
                binned_im = rotateImageBy90(binned_im,
                                            ccd.getOrientation().getNQuarter())
                if self.config.putFullSensors:
                    butler.put(binned_im, 'binned_sensor_fits', **data_id)
            except (TypeError, RuntimeError):
                # butler couldn't put the image or there was no image to put
                continue
            (x, y) = binned_im.getDimensions()
            boxes = {
                'A':
                afwGeom.Box2I(afwGeom.PointI(0, y / 2),
                              afwGeom.ExtentI(x, y / 2)),
                'B':
                afwGeom.Box2I(afwGeom.PointI(0, 0), afwGeom.ExtentI(x, y / 2))
            }
            for half in ('A', 'B'):
                box = boxes[half]
                butler.put(afwImage.MaskedImageF(binned_im, box),
                           'binned_sensor_fits_halves',
                           half=half,
                           **data_id)

        im = cgu.showCamera(butler.get('camera'),
                            imageSource=sbi,
                            binSize=self.config.binSize)
        expRef.put(im, 'focalplane_summary_fits')
        im = flipImage(im, False, True)
        zmap = ZScaleMapping(im, contrast=self.config.contrast)
        rgb = zmap.makeRgbImage(im, im, im)
        file_name = expRef.get('focalplane_summary_png_filename')
        writeRGB(file_name[0], rgb)
Example #18
0
def makeImageFromCamera(camera,
                        detectorNameList=None,
                        background=numpy.nan,
                        bufferSize=10,
                        imageSource=FakeImageDataSource(),
                        imageFactory=afwImage.ImageU,
                        binSize=1):
    """!Make an Image of a Camera

    @param[in] camera  Camera object to use to make the image
    @param[in] detectorNameList  List of detector names to use in building the image.
               Use all Detectors if None.
    @param[in] background  Value to use where there is no Detector
    @param[in] bufferSize  Size of border in binned pixels to make around the camera image
    @param[in] imageSource  Source to get ccd images.  Must have a getCcdImage method
    @param[in] imageFactory  Type of image to build
    @param[in] binSize  bin factor
    @return an image of the camera
    """
    if detectorNameList is None:
        ccdList = camera
    else:
        ccdList = [camera[name] for name in detectorNameList]

    if detectorNameList is None:
        camBbox = camera.getFpBBox()
    else:
        camBbox = afwGeom.Box2D()
        for detName in detectorNameList:
            for corner in camera[detName].getCorners(FOCAL_PLANE):
                camBbox.include(corner)

    pixelSize_o = camera[camera.getNameIter().next()].getPixelSize()
    camBbox = getCameraImageBBox(camBbox, pixelSize_o, bufferSize * binSize)
    origin = camBbox.getMin()

    camIm = imageFactory(
        int(math.ceil(camBbox.getDimensions().getX() / binSize)),
        int(math.ceil(camBbox.getDimensions().getY() / binSize)))
    boxList = getCcdInCamBBoxList(ccdList, binSize, pixelSize_o, origin)
    for det, bbox in itertools.izip(ccdList, boxList):
        im = imageSource.getCcdImage(det, imageFactory, binSize)
        nQuarter = det.getOrientation().getNQuarter()
        im = afwMath.rotateImageBy90(im, nQuarter)
        imView = camIm.Factory(camIm, bbox, afwImage.LOCAL)
        imView <<= im

    return camIm
Example #19
0
File: utils.py Project: brianv0/afw
def showCcd(ccd,
            imageSource=FakeImageDataSource(),
            display=None,
            frame=None,
            overlay=True,
            imageFactory=afwImage.ImageF,
            binSize=1,
            inCameraCoords=False):
    """!Show a CCD on display

    @param[in] ccd  Detector to use in display
    @param[in] imageSource  Source for producing images to display.  Must have a getCcdImage method.
    @param[in] display image display to use
    @param[in] frame  frame ID on which to display
    @param[in] overlay  Show amp bounding boxes on the displayed image?
    @param[in] imageFactory  The image factory to use in generating the images.
    @param[in] binSize  Binning factor
    @param[in] inCameraCoords  Show the Detector in camera coordinates?
    """
    display = _getDisplayFromDisplayOrFrame(display, frame)

    ccdOrigin = afwGeom.Point2I(0, 0)
    nQuarter = 0
    ccdImage = imageSource.getCcdImage(ccd,
                                       imageFactory=imageFactory,
                                       binSize=binSize)

    ccdBbox = ccdImage.getBBox()
    if ccdBbox.getDimensions() == ccd.getBBox().getDimensions():
        isTrimmed = True
    else:
        isTrimmed = False

    if inCameraCoords:
        nQuarter = ccd.getOrientation().getNQuarter()
        ccdImage = afwMath.rotateImageBy90(ccdImage, nQuarter)
    title = ccd.getName()
    if isTrimmed:
        title += "(trimmed)"

    if display:
        display.mtv(ccdImage, title=title)

        if overlay:
            overlayCcdBoxes(ccd, ccdBbox, nQuarter, isTrimmed, ccdOrigin,
                            display, binSize)

    return ccdImage
Example #20
0
    def getCcdImage(self, detector, imageFactory, binSize):
        """Provide image of CCD to makeImageFromCamera

        Parameters
        ----------
        detector : `int`
            Detector ID to get image data for.
        imageFactory : `lsst.afw.image.Image`
            Type of image to construct.
        binSize : `int`
            Binsize to use to recompute dimensions.

        Returns
        -------
        image : `lsst.afw.image.Image`
            Appropriately rotated, binned, and transformed
            image to be mosaicked.
        detector : `lsst.afw.cameraGeom.Detector`
            Camera detector that the returned image data
            belongs to.
        """
        detId = detector.getId()

        if detId not in self.exposures:
            dims = detector.getBBox().getDimensions() / binSize
            image = imageFactory(*[int(xx) for xx in dims])
            image.set(self.background)
        else:
            image = self.exposures[detector.getId()]
        if hasattr(image, "getMaskedImage"):
            image = image.getMaskedImage()
        if hasattr(image, "getMask"):
            mask = image.getMask()
            isBad = mask.getArray() & mask.getPlaneBitMask("NO_DATA") > 0
            image = image.clone()
            image.getImage().getArray()[isBad] = self.background
        if hasattr(image, "getImage"):
            image = image.getImage()

        # afwMath.rotateImageBy90 checks NQuarter values,
        # so we don't need to here.
        image = afwMath.rotateImageBy90(
            image,
            detector.getOrientation().getNQuarter())
        return image, detector
Example #21
0
def applyMosaicResultsExposure(dataRef, calexp=None):
    """Update an Exposure with the Wcs, Calib, and flux scaling from meas_mosaic.

    If None, the calexp will be loaded from the dataRef.  Otherwise it is
    updated in-place.

    This assumes that the mosaic solution exists; an exception will be raised
    in the event that it does not.
    """
    if calexp is None:
        calexp = dataRef.get("calexp", immediate=True)

    nQuarter = calexp.getDetector().getOrientation().getNQuarter()
    dims = calexp.getDimensions()
    hscRun = mosaicUtils.checkHscStack(calexp.getMetadata())

    # Need the dimensions in coordinates used by meas_mosaic which defines 0,0 as the
    # lower-left hand corner on the sky
    if hscRun is None:
        if nQuarter % 2 != 0:
            width, height = calexp.getDimensions()
            dims = afwGeom.Extent2I(height, width)

    # return results in meas_mosaic coordinate system
    mosaic = getMosaicResults(dataRef, dims)

    # rotate wcs back to LSST coordinate system
    if nQuarter % 4 != 0 and hscRun is None:
        import lsst.meas.astrom as measAstrom
        mosaic.wcs = measAstrom.rotateWcsPixelsBy90(mosaic.wcs, 4 - nQuarter,
                                                    dims)
    calexp.setWcs(mosaic.wcs)

    fluxMag0 = mosaic.calib.getInstFluxAtZeroMagnitude()
    calexp.setPhotoCalib(
        afwImage.makePhotoCalibFromCalibZeroPoint(fluxMag0, 0.0))

    mi = calexp.getMaskedImage()
    # rotate photometric correction to LSST coordiantes
    if nQuarter % 4 != 0 and hscRun is None:
        mosaic.fcor = afwMath.rotateImageBy90(mosaic.fcor, 4 - nQuarter)
    mi *= mosaic.fcor

    return Struct(exposure=calexp, mosaic=mosaic)
Example #22
0
def makeImageFromCcd(ccd, imageSource=SynthesizeCcdImage(), amp=None,
                     isTrimmed=None, imageFactory=afwImage.ImageU, bin=1, natural=False):
    """Make an Image of a Ccd (or just a single amp)

    If natural is True, return the CCD image without worrying about whether it's rotated when
    placed into the camera
    """

    if isTrimmed is None:
        isTrimmed = ccd.isTrimmed()
    imageSource.setTrimmed(isTrimmed)

    if amp:
        ampImage = imageFactory(amp.getAllPixels(isTrimmed).getDimensions())
        ampImage <<= imageSource.getImage(ccd, amp, imageFactory=imageFactory)

        if bin > 1:
            ampImage = afwMath.binImage(ampImage, bin)
            
        return ampImage
    #
    # Start by building the image in "Natural" (non-rotated) orientation
    # (unless it's 'raw', in which case it's just easier to prepareAmpData)
    #
    if imageSource.isRaw:
        ccdImage = imageFactory(ccd.getAllPixelsNoRotation(isTrimmed))

        for a in ccd:
            im = ccdImage.Factory(ccdImage, a.getAllPixels(isTrimmed), afwImage.LOCAL)
            im <<= a.prepareAmpData(imageSource.getImage(ccd, a, imageFactory=imageFactory))
    else:
        ccdImage = imageSource.getImage(ccd, imageFactory=imageFactory)

    if bin > 1:
        ccdImage = afwMath.binImage(ccdImage, bin)
    #
    # Now rotate to the as-installed orientation
    #
    if not natural and not imageSource.isRaw:
        ccdImage = afwMath.rotateImageBy90(ccdImage, ccd.getOrientation().getNQuarter())

    return ccdImage
def applyMosaicResultsExposure(dataRef, calexp=None):
    """Update an Exposure with the Wcs, Calib, and flux scaling from meas_mosaic.

    If None, the calexp will be loaded from the dataRef.  Otherwise it is
    updated in-place.

    This assumes that the mosaic solution exists; an exception will be raised
    in the event that it does not.
    """
    if calexp is None:
        calexp = dataRef.get("calexp", immediate=True)

    nQuarter = calexp.getDetector().getOrientation().getNQuarter()
    dims = calexp.getDimensions()
    hscRun = mosaicUtils.checkHscStack(calexp.getMetadata())

    # Need the dimensions in coordinates used by meas_mosaic which defines 0,0 as the
    # lower-left hand corner on the sky
    if hscRun is None:
        if nQuarter%2 != 0:
            width, height = calexp.getDimensions()
            dims = afwGeom.Extent2I(height, width)

    # return results in meas_mosaic coordinate system
    mosaic = getMosaicResults(dataRef, dims)

    # rotate wcs back to LSST coordinate system
    if nQuarter%4 != 0 and hscRun is None:
        import lsst.meas.astrom as measAstrom
        mosaic.wcs = measAstrom.rotateWcsPixelsBy90(mosaic.wcs, 4 - nQuarter, dims)
    calexp.setWcs(mosaic.wcs)

    fluxMag0 = mosaic.calib.getInstFluxAtZeroMagnitude()
    calexp.setPhotoCalib(afwImage.makePhotoCalibFromCalibZeroPoint(fluxMag0, 0.0))

    mi = calexp.getMaskedImage()
    # rotate photometric correction to LSST coordiantes
    if nQuarter%4 != 0 and hscRun is None:
        mosaic.fcor = afwMath.rotateImageBy90(mosaic.fcor, 4 - nQuarter)
    mi *= mosaic.fcor

    return Struct(exposure=calexp, mosaic=mosaic)
Example #24
0
    def getCcdImage(self, det, imageFactory, binSize):
        """Return a CCD image for the detector and the (possibly updated) Detector.

        Parameters
        ----------
        det : `lsst.afw.cameraGeom.Detector`
            Detector to use for making the image.
        imageFactory : callable like `lsst.afw.image.Image`
            Image constructor for making the image.
        binSize : `int`
            Bin the image by this factor in both dimensions.

        Returns
        -------
        ccdImage : `lsst.afw.image.Image`
            The constructed image.
        """
        ccdImage = makeImageFromCcd(det, isTrimmed=self.isTrimmed, showAmpGain=self.showAmpGain,
                                    imageFactory=imageFactory, binSize=binSize)
        return afwMath.rotateImageBy90(ccdImage, det.getOrientation().getNQuarter()), det
Example #25
0
    def getCcdImage(self, ccd, imageFactory=afwImage.ImageF, binSize=1):
        bbox = ccd.getBBox()
        try:
            ffp = self.ffp[ccd.getId()]
            wcs = self.wcs[ccd.getId()]
        except KeyError:
            result = imageFactory(bbox)
            return afwMath.binImage(result, binSize), ccd

        nQuarter = ccd.getOrientation().getNQuarter()
        # Rotate WCS from persisted LSST coords to meas_mosaic coords
        if nQuarter % 4 != 0:
            # Have to put this import here due to circular dependencies
            import lsst.meas.astrom as measAstrom
            wcs = measAstrom.rotateWcsPixelsBy90(wcs, nQuarter,
                                                 bbox.getDimensions())

        if nQuarter % 2:
            width, height = bbox.getHeight(), bbox.getWidth()
        else:
            width, height = bbox.getWidth(), bbox.getHeight()
        if self.fcor:
            result = getFCorImg(ffp, width, height)
            if self.jacobian:
                result *= getJImg(wcs, width, height)
        elif self.jacobian:
            result = getJImg(wcs, width, height)
        else:
            result = imageFactory(bbox)
            return afwMath.binImage(result, binSize), ccd

        # Rotate images to LSST coords
        if nQuarter % 4 != 0:
            result = afwMath.rotateImageBy90(result, 4 - nQuarter)
        result.setXY0(bbox.getMin())
        assert bbox == result.getBBox(), "%s != %s" % (bbox, result.getBBox())
        assert type(result) == imageFactory
        return afwMath.binImage(result, binSize), ccd
Example #26
0
    def getCcdImage(self, ccd, imageFactory=afwImage.ImageF, binSize=1):
        bbox = ccd.getBBox()
        try:
            ffp = self.ffp[ccd.getId()]
            wcs = self.wcs[ccd.getId()]
        except KeyError:
            result = imageFactory(bbox)
            return afwMath.binImage(result, binSize), ccd

        nQuarter = ccd.getOrientation().getNQuarter()
        # Rotate WCS from persisted LSST coords to meas_mosaic coords
        if nQuarter%4 != 0:
            # Have to put this import here due to circular dependencies
            import lsst.meas.astrom as measAstrom
            wcs = measAstrom.rotateWcsPixelsBy90(wcs, nQuarter, bbox.getDimensions())

        if nQuarter%2:
            width, height = bbox.getHeight(), bbox.getWidth()
        else:
            width, height = bbox.getWidth(), bbox.getHeight()
        if self.fcor:
            result = getFCorImg(ffp, width, height)
            if self.jacobian:
                result *= getJImg(wcs, width, height)
        elif self.jacobian:
            result = getJImg(wcs, width, height)
        else:
            result = imageFactory(bbox)
            return afwMath.binImage(result, binSize), ccd

        # Rotate images to LSST coords
        if nQuarter%4 != 0:
            result = afwMath.rotateImageBy90(result, 4 - nQuarter)
        result.setXY0(bbox.getMin())
        assert bbox == result.getBBox(), "%s != %s" % (bbox, result.getBBox())
        assert type(result) == imageFactory
        return afwMath.binImage(result, binSize), ccd
Example #27
0
        def getCcdImage(self, detector, imageFactory, binSize):
            """Provide image of CCD to makeImageFromCamera"""
            detId = detector.getId()
            if detId not in self.exposures:
                dims = detector.getBBox().getDimensions() / binSize
                image = imageFactory(*[int(xx) for xx in dims])
                image.set(self.background)
            else:
                image = self.exposures[detector.getId()]
            if hasattr(image, "getMaskedImage"):
                image = image.getMaskedImage()
            if hasattr(image, "getMask"):
                mask = image.getMask()
                isBad = mask.getArray() & mask.getPlaneBitMask("NO_DATA") > 0
                image = image.clone()
                image.getImage().getArray()[isBad] = self.background
            if hasattr(image, "getImage"):
                image = image.getImage()

            image = afwMath.rotateImageBy90(
                image,
                detector.getOrientation().getNQuarter())

            return image, detector
Example #28
0
def trimCcd(ccd, ccdImage=""):
    """Trim a Ccd and maybe the image of the untrimmed Ccd"""
    
    if ccdImage == "":
        ccdImage = cameraGeomUtils.makeImageFromCcd(ccd, natural=True)

    if ccd.isTrimmed():
        return ccdImage

    ccd.setTrimmed(True)

    if ccdImage is not None:
        trimmedImage = ccdImage.Factory(ccd.getAllPixelsNoRotation())
        for a in ccd:
            data = ccdImage.Factory(ccdImage, a.getDataSec(False), afwImage.LOCAL)
            tdata = trimmedImage.Factory(trimmedImage, a.getDataSec(), afwImage.LOCAL)
            tdata <<= data
    else:
        trimmedImage = None

    if trimmedImage:
        trimmedImage = afwMath.rotateImageBy90(trimmedImage, ccd.getOrientation().getNQuarter())

    return trimmedImage
Example #29
0
    def testRaw(self):
        """Test retrieval of raw image"""

        frame = 1
        for ccdNum, rotated in zip(self.ccdList, self.rotated):
            butler = getButler(self.datadir)
            raw = butler.get("raw", visit=self.expId, ccd=ccdNum)
            ccd = raw.getDetector()

            print "Visit: ", self.expId
            print "width: ",              raw.getWidth()
            print "height: ",             raw.getHeight()
            ccdName = ccd.getId().getName()
            print "detector name: ", ccdName
            self.assertEqual(raw.getWidth(), self.untrimmedSize[0])
            self.assertEqual(raw.getHeight(), self.untrimmedSize[1])
            self.assertEqual(raw.getFilter().getFilterProperty().getName(), "g")
            self.assertEqual(ccd.getId().getName(), "hsc%03d" % ccdNum)

            # CCD size
            trimmed = ccd.getAllPixelsNoRotation(True).getDimensions()
            self.assertEqual(trimmed.getX(), self.trimmedSize[0])
            self.assertEqual(trimmed.getY(), self.trimmedSize[1])

            # Size in camera coordinates
            camera = ccd.getAllPixels(True).getDimensions()
            self.assertEqual(camera.getX(), self.trimmedSize[0] if not rotated else self.trimmedSize[1])
            self.assertEqual(camera.getY(), self.trimmedSize[1] if not rotated else self.trimmedSize[0])
            for i, amp in enumerate(ccd):
                amp = cameraGeom.cast_Amp(amp)
                print "amp: %s %i"%(amp.getId(), i)

                # Amplifier on CCD
                datasec = amp.getAllPixels(True)
                self.assertEqual(datasec.getWidth(), self.ampSize[0] if not rotated else self.ampSize[1])
                self.assertEqual(datasec.getHeight(), self.ampSize[1] if not rotated else self.ampSize[0])
                self.assertEqual(datasec.getMinX(), i*self.ampSize[0] if not rotated else 0)
                self.assertEqual(datasec.getMinY(), 0 if not rotated else i*self.ampSize[0])

                # Amplifier on disk
                datasec = amp.getRawDataBBox()
                self.assertEqual(datasec.getWidth(), self.ampSize[0])
                self.assertEqual(datasec.getHeight(), self.ampSize[1])

            if display:
                ds9.mtv(raw, frame=frame, title="Raw %s" % ccdName)
                frame += 1
                for amp in ccd:
                    amp = cameraGeom.cast_Amp(amp)
                    print ccd.getId(), amp.getId(), amp.getDataSec().toString(), \
                          amp.getBiasSec().toString(), amp.getElectronicParams().getGain()
                ccdIm = afwMath.rotateImageBy90(raw.getMaskedImage().getImage(),
                                                ccd.getOrientation().getNQuarter())
                cameraGeomUtils.showCcd(ccd, ccdImage=ccdIm, frame=frame)
                frame += 1
            if assemble:
                ccdIm = ca.assembleCcd([raw], ccd, reNorm=False, imageFactory=afwImage.ImageU)
                if display:
                    cameraGeomUtils.showCcd(ccd, ccdImage=ccdIm, frame=frame)
                    frame += 1
                    # If you'd like the image in un-rotated coordinates...
                    rotCcdIm = afwMath.rotateImageBy90(ccdIm.getMaskedImage().getImage(),
                                                       -ccd.getOrientation().getNQuarter())
                    ds9.mtv(rotCcdIm, frame=frame, title="Assembled derotated %s" % ccdName)
                    frame += 1
Example #30
0
    def runDataRef(self, expRefList, butler):
        """Make summary plots of full focalplane images.
        """
        if len(expRefList) == 0:
            return pipeBase.Struct(exitStatus=1)

        lsst.afw.fits.setAllowImageCompression(
            self.config.allowFitsCompression)

        dstype = expRefList[0].butlerSubset.datasetType

        if dstype == "raw":

            def callback(im, ccd, imageSource):
                return cgu.rawCallback(im,
                                       ccd,
                                       imageSource,
                                       correctGain=True,
                                       subtractBias=True)
        elif dstype == "eimage":
            callback = eimageCallback
        elif self.config.doApplySkyCorr:
            callback = skyCorrCallback
        else:
            callback = None

        for visit in set([er.dataId["visit"] for er in expRefList]):
            self.log.info("Processing visit %d", visit)
            expRefListForVisit = [
                er for er in expRefList if er.dataId["visit"] == visit
            ]

            dataId = expRefListForVisit[0].dataId
            bi = cgu.ButlerImage(butler,
                                 dstype,
                                 visit=visit,
                                 callback=callback,
                                 verbose=True)

            if self.config.doSensorImages:
                for dataId in (er.dataId for er in expRefListForVisit):
                    ccd = butler.get('calexp_detector', **dataId)
                    try:
                        md = butler.get('calexp_md', **dataId)
                    except RuntimeError:
                        md = None
                    if md:
                        afwGeom.makeSkyWcs(
                            md, strip=True
                        )  # strip WCS cards; they're invalidated by binning
                    try:
                        binned_im = bi.getCcdImage(
                            ccd,
                            binSize=self.config.sensorBinSize,
                            asMaskedImage=True)[0]
                        binned_im = rotateImageBy90(
                            binned_im,
                            ccd.getOrientation().getNQuarter())
                        if self.config.putFullSensors:
                            binned_exp = afwImage.ExposureF(binned_im)
                            binned_exp.setMetadata(md)
                            butler.put(binned_exp,
                                       'binned_sensor_fits',
                                       **dataId,
                                       dstype=dstype)
                    except (TypeError, RuntimeError) as e:
                        # butler couldn't put the image or there was no image to put
                        self.log.warn("Unable to make binned image: %s", e)
                        continue

                    (x, y) = binned_im.getDimensions()
                    boxes = {
                        'A':
                        afwGeom.Box2I(afwGeom.PointI(0, y / 2),
                                      afwGeom.ExtentI(x, y / 2)),
                        'B':
                        afwGeom.Box2I(afwGeom.PointI(0, 0),
                                      afwGeom.ExtentI(x, y / 2))
                    }
                    for half in ('A', 'B'):
                        box = boxes[half]
                        binned_exp = afwImage.ExposureF(binned_im[box])
                        binned_exp.setMetadata(md)
                        butler.put(binned_exp,
                                   'binned_sensor_fits_halves',
                                   half=half,
                                   **dataId,
                                   dstype=dstype)

            im = cgu.showCamera(butler.get('camera'),
                                imageSource=bi,
                                binSize=self.config.binSize)

            dstypeName = "%s-%s" % (
                dstype, self.config.fpId) if self.config.fpId else dstype

            butler.put(im, 'focal_plane_fits', visit=visit, dstype=dstypeName)

            # Compute the zscale stretch for just the CCDs that have data.
            detectorNameList = [
                "%s_%s" % (er.dataId["raftName"], er.dataId["detectorName"])
                for er in expRefListForVisit
            ]
            im_scaling = cgu.showCamera(butler.get('camera'),
                                        imageSource=bi,
                                        binSize=self.config.binSize,
                                        detectorNameList=detectorNameList)
            zmap = ZScaleMapping(im_scaling, contrast=self.config.contrast)

            im = flipImage(im, False, True)
            rgb = zmap.makeRgbImage(im, im, im)
            file_name = butler.get('focal_plane_png_filename',
                                   visit=visit,
                                   dstype=dstypeName)
            writeRGB(file_name[0], rgb)

        return pipeBase.Struct(exitStatus=0)
Example #31
0
def makeImageFromCamera(camera,
                        detectorNameList=None,
                        background=numpy.nan,
                        bufferSize=10,
                        imageSource=FakeImageDataSource(),
                        imageFactory=afwImage.ImageU,
                        binSize=1):
    """Make an Image of a Camera.

    Put each detector's image in the correct location and orientation on the
    focal plane. The input images can be binned to an integer fraction of their
    original bboxes.

    Parameters
    ----------
    camera : `lsst.afw.cameraGeom.Camera`
        Camera object to use to make the image.
    detectorNameList : `list` of `str`
        List of detector names from `camera` to use in building the image.
        Use all Detectors if None.
    background : `float`
        Value to use where there is no Detector.
    bufferSize : `int`
        Size of border in binned pixels to make around the camera image.
    imageSource : `FakeImageDataSource` or None
        Source to get ccd images.  Must have a ``getCcdImage()`` method.
    imageFactory : callable like `lsst.afw.image.Image`
        Type of image to build.
    binSize : `int`
        Bin the image by this factor in both dimensions.

    Returns
    -------
    image : `lsst.afw.image.Image`
        Image of the entire camera.
    """
    log = lsst.log.Log.getLogger("afw.cameraGeom.utils.makeImageFromCamera")

    if detectorNameList is None:
        ccdList = camera
    else:
        ccdList = [camera[name] for name in detectorNameList]

    if detectorNameList is None:
        camBbox = camera.getFpBBox()
    else:
        camBbox = lsst.geom.Box2D()
        for detName in detectorNameList:
            for corner in camera[detName].getCorners(FOCAL_PLANE):
                camBbox.include(corner)

    pixelSize_o = camera[next(camera.getNameIter())].getPixelSize()
    camBbox = getCameraImageBBox(camBbox, pixelSize_o, bufferSize * binSize)
    origin = camBbox.getMin()

    camIm = imageFactory(
        int(math.ceil(camBbox.getDimensions().getX() / binSize)),
        int(math.ceil(camBbox.getDimensions().getY() / binSize)))
    camIm[:] = imageSource.background

    assert imageSource.isTrimmed, "isTrimmed is False isn't supported by getCcdInCamBBoxList"

    boxList = getCcdInCamBBoxList(ccdList, binSize, pixelSize_o, origin)
    for det, bbox in zip(ccdList, boxList):
        im = imageSource.getCcdImage(det, imageFactory, binSize)[0]
        if im is None:
            continue

        nQuarter = det.getOrientation().getNQuarter()
        im = afwMath.rotateImageBy90(im, nQuarter)

        imView = camIm.Factory(camIm, bbox, afwImage.LOCAL)
        try:
            imView[:] = im
        except pexExceptions.LengthError as e:
            log.error(
                "Unable to fit image for detector \"%s\" into image of camera: %s"
                % (det.getName(), e))

    return camIm
Example #32
0
def rawCallback(im, ccd=None, imageSource=None,
                correctGain=False, subtractBias=False, convertToFloat=False, obeyNQuarter=True):
    """A callback function that may or may not subtract bias/correct gain/trim
    a raw image.

    Parameters
    ----------
    im : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage` or `lsst.afw.image.Exposure`
       An image of a chip, ready to be binned and maybe rotated.
    ccd : `lsst.afw.cameraGeom.Detector` or `None`
        The Detector; if `None` assume that im is an exposure and extract its Detector.
    imageSource : `FakeImageDataSource` or `None`
        Source to get ccd images.  Must have a `getCcdImage()` method.
    correctGain : `bool`
        Correct each amplifier for its gain?
    subtractBias : `bool`
        Subtract the bias from each amplifier?
    convertToFloat : `bool`
        Convert ``im`` to floating point if possible.
    obeyNQuarter : `bool`
        Obey nQuarter from the Detector (default: True)

    Returns
    -------
    image : `lsst.afw.image.Image` like
        The constructed image (type returned by ``im.Factory``).

    Notes
    -----
    If imageSource is derived from ButlerImage, imageSource.butler is available.
    """
    if ccd is None:
        ccd = im.getDetector()
    if hasattr(im, "getMaskedImage"):
        im = im.getMaskedImage()
    if convertToFloat and hasattr(im, "convertF"):
        im = im.convertF()

    isTrimmed = imageSource.isTrimmed
    if isTrimmed:
        bbox = ccd.getBBox()
    else:
        bbox = calcRawCcdBBox(ccd)

    ampImages = []
    for a in ccd:
        if isTrimmed:
            data = im[a.getRawDataBBox()]
        else:
            data = im

        if subtractBias:
            bias = im[a.getRawHorizontalOverscanBBox()]
            data -= afwMath.makeStatistics(bias, afwMath.MEANCLIP).getValue()
        if correctGain:
            data *= a.getGain()

        ampImages.append(data)

    ccdImage = im.Factory(bbox)
    for ampImage, amp in zip(ampImages, ccd):
        if isTrimmed:
            assembleAmplifierImage(ccdImage, ampImage, amp)
        else:
            assembleAmplifierRawImage(ccdImage, ampImage, amp)

    if obeyNQuarter:
        nQuarter = ccd.getOrientation().getNQuarter()
        ccdImage = afwMath.rotateImageBy90(ccdImage, nQuarter)

    return ccdImage
Example #33
0
def rawCallback(im, ccd=None, imageSource=None,
                correctGain=False, subtractBias=False, convertToFloat=False, obeyNQuarter=True):
    """A callback function that may or may not subtract bias/correct gain/trim
    a raw image.

    Parameters
    ----------
    im : `lsst.afw.image.Image` or `lsst.afw.image.MaskedImage` or `lsst.afw.image.Exposure`
       An image of a chip, ready to be binned and maybe rotated.
    ccd : `lsst.afw.cameraGeom.Detector` or `None`
        The Detector; if `None` assume that im is an exposure and extract its Detector.
    imageSource : `FakeImageDataSource` or `None`
        Source to get ccd images.  Must have a `getCcdImage()` method.
    correctGain : `bool`
        Correct each amplifier for its gain?
    subtractBias : `bool`
        Subtract the bias from each amplifier?
    convertToFloat : `bool`
        Convert ``im`` to floating point if possible.
    obeyNQuarter : `bool`
        Obey nQuarter from the Detector (default: True)

    Returns
    -------
    image : `lsst.afw.image.Image` like
        The constructed image (type returned by ``im.Factory``).

    Notes
    -----
    If imageSource is derived from ButlerImage, imageSource.butler is available.
    """
    if ccd is None:
        ccd = im.getDetector()
    if hasattr(im, "getMaskedImage"):
        im = im.getMaskedImage()
    if convertToFloat and hasattr(im, "convertF"):
        im = im.convertF()

    isTrimmed = imageSource.isTrimmed
    if isTrimmed:
        bbox = ccd.getBBox()
    else:
        bbox = calcRawCcdBBox(ccd)

    ampImages = []
    for a in ccd:
        if isTrimmed:
            data = im[a.getRawDataBBox()]
        else:
            data = im

        if subtractBias:
            bias = im[a.getRawHorizontalOverscanBBox()]
            data -= afwMath.makeStatistics(bias, afwMath.MEANCLIP).getValue()
        if correctGain:
            data *= a.getGain()

        ampImages.append(data)

    ccdImage = im.Factory(bbox)
    for ampImage, amp in zip(ampImages, ccd):
        if isTrimmed:
            assembleAmplifierImage(ccdImage, ampImage, amp)
        else:
            assembleAmplifierRawImage(ccdImage, ampImage, amp)

    if obeyNQuarter:
        nQuarter = ccd.getOrientation().getNQuarter()
        ccdImage = afwMath.rotateImageBy90(ccdImage, nQuarter)

    return ccdImage
Example #34
0
    def warpStamps(self, stamps, pixCenters):
        """Warps and shifts all given stamps so they are sampled on the same
        pixel grid and centered on the central pixel. This includes rotating
        the stamp depending on detector orientation.

        Parameters
        ----------
        stamps : `collections.abc.Sequence`
                     [`afwImage.exposure.exposure.ExposureF`]
            Image cutouts centered on a single object.
        pixCenters : `collections.abc.Sequence` [`geom.Point2D`]
            Positions of each object's center (as obtained from the refCat),
            in pixels.

        Returns
        -------
        warpedStars : `list` [`afwImage.maskedImage.maskedImage.MaskedImage`]
        """
        # warping control; only contains shiftingALg provided in config
        warpCont = afwMath.WarpingControl(self.config.warpingKernelName)
        # Compare model to star stamp sizes
        bufferPix = (self.modelStampSize[0] - self.config.stampSize[0],
                     self.modelStampSize[1] - self.config.stampSize[1])
        # Initialize detector instance (note all stars were extracted from an
        # exposure from the same detector)
        det = stamps[0].getDetector()
        # Define correction for optical distortions
        if self.config.doApplyTransform:
            pixToTan = det.getTransform(cg.PIXELS, cg.TAN_PIXELS)
        else:
            pixToTan = tFactory.makeIdentityTransform()
        # Array of all possible rotations for detector orientation:
        possibleRots = np.array([k*np.pi/2 for k in range(4)])
        # determine how many, if any, rotations are required
        yaw = det.getOrientation().getYaw()
        nb90Rots = np.argmin(np.abs(possibleRots - float(yaw)))

        # apply transformation to each star
        warpedStars = []
        for star, cent in zip(stamps, pixCenters):
            # (re)create empty destination image
            destImage = afwImage.MaskedImageF(*self.modelStampSize)
            bottomLeft = geom.Point2D(star.image.getXY0())
            newBottomLeft = pixToTan.applyForward(bottomLeft)
            newBottomLeft.setX(newBottomLeft.getX() - bufferPix[0]/2)
            newBottomLeft.setY(newBottomLeft.getY() - bufferPix[1]/2)
            # Convert to int
            newBottomLeft = geom.Point2I(newBottomLeft)
            # Set origin
            destImage.setXY0(newBottomLeft)

            # Define linear shifting to recenter stamps
            newCenter = pixToTan.applyForward(cent)  # center of warped star
            shift = self.modelCenter[0] + newBottomLeft[0] - newCenter[0],\
                self.modelCenter[1] + newBottomLeft[1] - newCenter[1]
            affineShift = geom.AffineTransform(shift)
            shiftTransform = tFactory.makeTransform(affineShift)

            # Define full transform (warp and shift)
            starWarper = pixToTan.then(shiftTransform)

            # Apply it
            goodPix = afwMath.warpImage(destImage, star.getMaskedImage(),
                                        starWarper, warpCont)
            if not goodPix:
                self.log.debug("Warping of a star failed: no good pixel in output")

            # Arbitrarily set origin of shifted star to 0
            destImage.setXY0(0, 0)

            # Apply rotation if apropriate
            if nb90Rots:
                destImage = afwMath.rotateImageBy90(destImage, nb90Rots)
            warpedStars.append(destImage.clone())
        return warpedStars
Example #35
0
    def getCcdImage(self,
                    ccd,
                    imageFactory=afwImage.ImageF,
                    binSize=1,
                    as_masked_image=False):
        """Return an image of the specified ccd, and also the (possibly updated) ccd

        Parameters
        ----------
        ccd : `afwImage.CameraGeom.Detector`
           Detector for the constructed image
        imageFactory : `afwImage.Image`, optional
           Image like factory for producing default images (`afwImage.ImageF` by default).
        binSize : `int`, optional
           Pixels to bin together.  Symmetric in x and y (1 by default)
        as_masked_image : `bool`, optional
           Return the image as an `afwImage.MaskedImage`? (False by default.  This returns an
           `afwImage.Image`)
        """
        bbox = ccd.getBBox()

        def parse_name_to_dataId(name_str):
            raft, sensor = name_str.split()
            return {'raft': raft[-3:], 'sensor': sensor[-3:]}

        im = None
        cid = ccd.getName()
        did = parse_name_to_dataId(cid)
        if self.butler is not None and did['raft'] not in [
                '0,0', '0,4', '4,0', '4,4'
        ]:
            self.kwargs.update(did)
            try:
                im = self.butler.get(self.type, **self.kwargs)
                ccd = im.getDetector()  # possibly modified by assembleCcdTask
                if self.type == 'eimage' or self.type == 'calexp':
                    im.setMaskedImage(rotateImageBy90(im.getMaskedImage(), 2))
                else:
                    raise ValueError(
                        "Only valid dataset types are 'eimage' and 'calexp'")
            except (NoResults, RuntimeError):
                pass
        else:
            return None, ccd

        if im is None:
            if not as_masked_image:
                im = self._prepareImage(ccd,
                                        imageFactory(*bbox.getDimensions()),
                                        binSize)
                return rotateImageBy90(im,
                                       ccd.getOrientation().getNQuarter()), ccd
            else:
                im = self._prepareImage(
                    ccd,
                    afwImage.makeMaskedImage(
                        imageFactory(*bbox.getDimensions())), binSize)
                return rotateImageBy90(im,
                                       ccd.getOrientation().getNQuarter()), ccd

        if self.type == "raw":
            raise ValueError("This class only handles ccd size images")

        if not as_masked_image:
            return self._prepareImage(ccd,
                                      im.getMaskedImage().getImage(),
                                      binSize), ccd
        else:
            return self._prepareImage(ccd, im.getMaskedImage(), binSize), ccd