7. Examples

Here, we present some examples illustrating the functionalities of both the Fits and FitsArray classes.

7.1. Fits

In this example, we demonstrate the process of updating the header of a FITS file and retrieving a list of coordinates of sources from the data.

Fits updates header and finds sources on data of a FITS file.
from myraflib import Fits

fits = Fits.from_path("sample.fits")
fits.hedit(
    ["Ke1y", "Key2"], ["Value1", "Value2"], ["Comment1", "Comment2"]
)

sources = fits.daofind(sigma=1.2)

The same goal can be achieved using Astropy and photutils as shown in the following example:

Updating header and finding sources on data of a FITS file.
from astropy.io import fits
from astropy.stats import sigma_clipped_stats
from photutils.detection import DAOStarFinder

with fits.open("sample.fits", "update") as hdu:
    for key, value, comment in zip(
            ["Ke1y", "Key2"], ["Value1", "Value2"],
            ["Comment1", "Comment2"]
    ):
        hdu[0].header[key] = value
        hdu[0].header.comments[key] = comment

    hdu.flush()

data = fits.getdata("sample.fits")
mean, median, std = sigma_clipped_stats(data, sigma=1.2)
daofind = DAOStarFinder(fwhm=3.0, threshold=3.0 * std)
sources = daofind(data - median)

7.2. FitsArray

As mentioned before, FitsArray can perform operations on multiple FITS files. Below is an example where we update the header and align multiple FITS files.

FitsArray updates header and aligns multiple FITS files.
from myraflib import FitsArray

fa = FitsArray.from_pattern("PATTERN/OF/FILES/*.fits")
fa.hedit(
    ["Ke1y", "Key2"], ["Value1", "Value2"], ["Comment1", "Comment2"]
)

aligned_fa = fa.align(reference=0)

The same goal can be achieved using Astropy and AstroAlign:

Updating header and aligning multiple FITS files.
import astroalign
from astropy.io import fits
from glob import glob

files = glob("PATTERN/OF/FILES/*.fits")
reference_data = fits.getdata(files[0])

for file in files[1:]:
    with fits.open(file, "update") as hdu:
        for key, value, comment in zip(
                ["Ke1y", "Key2"], ["Value1", "Value2"],
                ["Comment1", "Comment2"]
        ):
            hdu[0].header[key] = value
            hdu[0].header.comments[key] = comment
            hdu.flush()


    data = fits.getdata(file)
    header = fits.getheader(file)
    registered_image, footprint = astroalign.register(
        data, reference_data, max_control_points=50, min_area=5
    )
    # A new fits file creation and WCS correction will not be
    # considered here



The code demonstrating how to perform operations without MYRaf essentially reflects the processes that MYRaf executes internally. MYRaf simplifies these operations by making them more human-readable and writable, while maintaining the same underlying functionality.

7.3. Video

The FitsArray class extends its functionality to support the importation of video files. By utilizing the FitsArray.from_video class method, users can decompose a video into individual frames, with each frame being assigned corresponding time and exposure metadata in the FITS header. This feature has demonstrated significant utility, particularly in the context of occultation observations.

7.4. Photometry

In theory, the following example is capable of performing both calibration and photometry on a given list of FITS files, even when the calibration data and image data are not stored separately.

Photometry With MYRaf.
from myraflib import FitsArray

# Create FitsArray
fa = FitsArray.from_pattern("ALL/FILES/*.fits")

# Group files by IMAGETYP in header
groups = fa.group_by("IMAGETYP")

# Separate files by types
light = groups["light"]
zeros = groups["zero"]
darks = groups["dark"]
flats = groups["flat"]

# Create master calibration files
master_zero = zeros.zero_combine()
master_dark = darks.dark_combine()
master_flat = flats.flat_combine()

# Calibrate the data images
# Zero, Dark, and Flat correction
calibrated = light.ccdproc(
    master_zero=master_zero,
    master_dark=master_dark,
    master_flat=master_flat
)

# Align the calibrated images
aligned = calibrated.align()

# Find sources on first fits file
sources = aligned.daofind(index=0, sigma=1.2)

# Do a photometry on found sources
# x coordinates are xcentriod
# y coordinates are ycentriod
# Aperture radii are [10, 20, 30]
photometry = aligned.photometry(
    sources["xcentriod"].to_list(),
    sources["ycentriod"].to_list(), 
    [10, 20, 30]
)