Пример #1
0
def readRawAmps(fileName, detector):
    """Given a file name read the amps and attach the detector.

    Parameters
    ----------
    fileName : `str`
        The full path to a file containing data from a single CCD.
    detector : `lsst.afw.cameraGeom.Detector`
        Detector to associate with the amps.

    Returns
    -------
    ampExps : `list` of `lsst.afw.image.Exposure`
       All the individual amps read from the file.
    """
    amps = []
    for hdu in range(1, len(detector)+1):
        reader = afwImage.ImageFitsReader(fileName, hdu=hdu)
        exp = afwImage.makeExposure(afwImage.makeMaskedImage(reader.read(dtype=np.dtype(np.int32),
                                                                         allowUnsafe=True)))
        exp.setDetector(detector)
        exp.setMetadata(reader.readMetadata())
        amps.append(exp)
    return amps
Пример #2
0
def readFitsWithOptions(filename, stamp_factory, options):
    """Read stamps from FITS file, allowing for only a
    subregion of the stamps to be read.

    Parameters
    ----------
    filename : `str`
        A string indicating the file to read
    stamp_factory : classmethod
        A factory function defined on a dataclass for constructing
        stamp objects a la `lsst.meas.alrogithm.Stamp`
    options : `PropertyList` or `dict`
        A collection of parameters. If it contains a bounding box
        (``bbox`` key), or if certain other keys (``llcX``, ``llcY``,
        ``width``, ``height``) are available for one to be  constructed,
        the bounding box is passed to the ``FitsReader`` in order to
        return a sub-image.

    Returns
    -------
    stamps : `list` of dataclass objects like `Stamp`, PropertyList
        A tuple of a list of `Stamp`-like objects
    metadata : `PropertyList`
        The metadata
    """
    # extract necessary info from metadata
    metadata = afwFits.readMetadata(filename, hdu=0)
    nStamps = metadata["N_STAMPS"]
    has_archive = metadata["HAS_ARCHIVE"]
    if has_archive:
        archive_ids = metadata.getArray("ARCHIVE_IDS")
    with afwFits.Fits(filename, 'r') as f:
        nExtensions = f.countHdus()
        # check if a bbox was provided
        kwargs = {}
        if options:
            # gen3 API
            if "bbox" in options.keys():
                kwargs["bbox"] = options["bbox"]
            # gen2 API
            elif "llcX" in options.keys():
                llcX = options["llcX"]
                llcY = options["llcY"]
                width = options["width"]
                height = options["height"]
                bbox = Box2I(Point2I(llcX, llcY), Extent2I(width, height))
                kwargs["bbox"] = bbox
        stamp_parts = {}
        # We need to be careful because nExtensions includes the primary
        # header data unit
        for idx in range(nExtensions - 1):
            md = afwFits.readMetadata(filename, hdu=idx + 1)
            if md['EXTNAME'] in ('IMAGE', 'VARIANCE'):
                reader = afwImage.ImageFitsReader(filename, hdu=idx + 1)
            elif md['EXTNAME'] == 'MASK':
                reader = afwImage.MaskFitsReader(filename, hdu=idx + 1)
            elif md['EXTNAME'] == 'ARCHIVE_INDEX':
                f.setHdu(idx + 1)
                archive = afwTable.io.InputArchive.readFits(f)
                continue
            elif md['EXTTYPE'] == 'ARCHIVE_DATA':
                continue
            else:
                raise ValueError(f"Unknown extension type: {md['EXTNAME']}")
            stamp_parts.setdefault(
                md['EXTVER'],
                {})[md['EXTNAME'].lower()] = reader.read(**kwargs)
    if len(stamp_parts) != nStamps:
        raise ValueError(
            f'Number of stamps read ({len(stamp_parts)}) does not agree with the '
            f'number of stamps recorded in the metadata ({nStamps}).')
    # construct stamps themselves
    stamps = []
    for k in range(nStamps):
        # Need to increment by one since EXTVER starts at 1
        maskedImage = afwImage.MaskedImageF(**stamp_parts[k + 1])
        archive_element = archive.get(archive_ids[k]) if has_archive else None
        stamps.append(stamp_factory(maskedImage, metadata, k, archive_element))

    return stamps, metadata
Пример #3
0
def readFitsWithOptions(filename, stamp_factory, options):
    """Read stamps from FITS file, allowing for only a
    subregion of the stamps to be read.

    Parameters
    ----------
    filename : `str`
        A string indicating the file to read
    stamp_factory : classmethod
        A factory function defined on a dataclass for constructing
        stamp objects a la `lsst.meas.alrogithm.Stamp`
    options : `PropertyList`
        A collection of parameters.  If certain keys are available
        (``llcX``, ``llcY``, ``width``, ``height``), a bounding box
        is constructed and passed to the ``FitsReader`` in order
        to return a sub-image.

    Returns
    -------
    stamps : `list` of dataclass objects like `Stamp`, PropertyList
        A tuple of a list of `Stamp`-like objects
    metadata : `PropertyList`
        The metadata
    """
    # extract necessary info from metadata
    metadata = afwFits.readMetadata(filename, hdu=0)
    f = afwFits.Fits(filename, 'r')
    nExtensions = f.countHdus()
    nStamps = metadata["N_STAMPS"]
    # check if a bbox was provided
    kwargs = {}
    if options and options.exists("llcX"):
        llcX = options["llcX"]
        llcY = options["llcY"]
        width = options["width"]
        height = options["height"]
        bbox = Box2I(Point2I(llcX, llcY), Extent2I(width, height))
        kwargs["bbox"] = bbox
    stamp_parts = {}
    # We need to be careful because nExtensions includes the primary
    # header data unit
    for idx in range(nExtensions - 1):
        md = afwFits.readMetadata(filename, hdu=idx + 1)
        if md['EXTNAME'] in ('IMAGE', 'VARIANCE'):
            reader = afwImage.ImageFitsReader(filename, hdu=idx + 1)
        elif md['EXTNAME'] == 'MASK':
            reader = afwImage.MaskFitsReader(filename, hdu=idx + 1)
        else:
            raise ValueError(f"Unknown extension type: {md['EXTNAME']}")
        stamp_parts.setdefault(
            md['EXTVER'], {})[md['EXTNAME'].lower()] = reader.read(**kwargs)
    if len(stamp_parts) != nStamps:
        raise ValueError(
            f'Number of stamps read ({len(stamp_parts)}) does not agree with the '
            f'number of stamps recorded in the metadata ({nStamps}).')
    # construct stamps themselves
    stamps = []
    for k in range(nStamps):
        # Need to increment by one since EXTVER starts at 1
        maskedImage = afwImage.MaskedImageF(**stamp_parts[k + 1])
        stamps.append(stamp_factory(maskedImage, metadata, k))

    return stamps, metadata
Пример #4
0
    def readFits(fileName, hdu=0, flags=0):
        """Read our list of Backgrounds from a file.

        Parameters
        ----------
        fileName : `str`
            FITS file to read
        hdu : `int`
            First Header/Data Unit to attempt to read from
        flags : `int`
            Flags to control details of reading; currently unused, but present
            for consistency with `lsst.afw.table.BaseCatalog.readFits`.

        See Also
        --------
        getImage()
        """
        if not isinstance(fileName, MemFileManager) and not os.path.exists(fileName):
            raise RuntimeError(f"File not found: {fileName}")

        self = BackgroundList()

        f = Fits(fileName, 'r')
        nHdus = f.countHdus()
        f.closeFile()
        if nHdus % 3 != 0:
            raise RuntimeError(f"BackgroundList FITS file {fileName} has {nHdus} HDUs;"
                               f"expected a multiple of 3 (compression is not supported).")

        for hdu in range(0, nHdus, 3):
            # It seems like we ought to be able to just use
            # MaskedImageFitsReader here, but it warns about EXTTYPE and still
            # doesn't work quite naturally when starting from a nonzero HDU.
            imageReader = afwImage.ImageFitsReader(fileName, hdu=hdu)
            maskReader = afwImage.MaskFitsReader(fileName, hdu=hdu + 1)
            varianceReader = afwImage.ImageFitsReader(fileName, hdu=hdu + 2)
            statsImage = afwImage.MaskedImageF(imageReader.read(), maskReader.read(), varianceReader.read())
            md = imageReader.readMetadata()

            x0 = md["BKGD_X0"]
            y0 = md["BKGD_Y0"]
            width = md["BKGD_WIDTH"]
            height = md["BKGD_HEIGHT"]
            imageBBox = lsst.geom.BoxI(lsst.geom.PointI(x0, y0), lsst.geom.ExtentI(width, height))

            interpStyle = afwMath.Interpolate.Style(md["INTERPSTYLE"])
            undersampleStyle = afwMath.UndersampleStyle(md["UNDERSAMPLESTYLE"])

            # Older outputs won't have APPROX* settings.  Provide alternative defaults.
            # Note: Currently X- and Y-orders must be equal due to a limitation in
            #       math::Chebyshev1Function2.  Setting approxOrderY = -1 is equivalent
            #       to saying approxOrderY = approxOrderX.
            approxStyle = md.get("APPROXSTYLE", afwMath.ApproximateControl.UNKNOWN)
            approxStyle = afwMath.ApproximateControl.Style(approxStyle)
            approxOrderX = md.get("APPROXORDERX", 1)
            approxOrderY = md.get("APPROXORDERY", -1)
            approxWeighting = md.get("APPROXWEIGHTING", True)

            bkgd = afwMath.BackgroundMI(imageBBox, statsImage)
            bctrl = bkgd.getBackgroundControl()

            # TODO: DM-22814: remove this after v20.
            # Still needed until then because other code might call the old-style getImageF.
            with suppress_deprecations():
                bctrl.setInterpStyle(interpStyle)

            bctrl.setUndersampleStyle(undersampleStyle)
            actrl = afwMath.ApproximateControl(approxStyle, approxOrderX, approxOrderY, approxWeighting)
            bctrl.setApproximateControl(actrl)
            bgInfo = (bkgd, interpStyle, undersampleStyle, approxStyle,
                      approxOrderX, approxOrderY, approxWeighting)
            self.append(bgInfo)

        return self