handle frame module

This module contains functions for processing astronomical FITS frames. Includes functions for arithmetic operations, combining data, removing cosmic rays, and smoothing gradients.

Functions: - operate_process - combine_process - divide_smoothgradient - remove_cosmic_rays

ariastrotools.handle_frame.combine_process(files, opfilename, path='.', method='mean', scale=None, fluxext=[0], varext=None, mask=None, mask_method='interpolate', instrument=None)[source]

Combine spectral or image data from multiple FITS files into a single output FITS file.

This function supports two modes of operation:

  1. If an instrument is specified, it calls an instrument-specific routine (combine_spectra).

  2. Otherwise, it manually reads data arrays and (optionally) variance arrays from the input files, combines them using the given method, and writes the results into a new FITS file.

Parameters:
  • files (list of str or str) –

    Input FITS files. May be either:

    • A list of FITS file paths.

    • A glob pattern used to match FITS files within path.

    • A string specifying a pattern/regular expression to match files in path.

  • opfilename (str) – Output FITS filename to write the combined data.

  • path (str, optional) – Path to search for FITS files if files is provided as a string pattern. Default is ‘.’.

  • method (str, optional) – Combination method for data arrays (e.g., ‘mean’, ‘median’). Passed to combine_data. Default is ‘mean’.

  • scale (str or None, optional) – Percentile-based scaling scheme used to normalize the input frames before combination. The value should follow the 'pXX' format, where XX specifies the percentile used to determine the scaling factor. For example, 'p50' uses the 50th percentile (median) of each frame for scaling. The corresponding variance arrays are scaled consistently. If None, no scaling is applied. Default is None.

  • fluxext (list of int, optional) – List of FITS extensions containing flux (or image) data. Default is [0].

  • varext (list of int or None, optional) – List of FITS extensions containing variance data corresponding to fluxext. If None, variance is not processed. Default is None.

  • mask (array_like or str or None, optional) – Bad-pixel mask to apply to the input data. If provided, bad pixels are either interpolated or replaced with NaN according to mask_method. Default is None.

  • mask_method ({'interpolate', 'nan'}, optional) – Method used to handle bad pixels when mask is provided and variance data are available. 'interpolate' replaces bad pixels by interpolating from surrounding valid pixels, while 'nan' replaces bad pixels with NaN. Default is 'interpolate'.

  • instrument (str or None, optional) – Instrument name. If provided, the function calls combine_spectra instead of the default combination logic. Default is None.

Returns:

The combined FITS data is written directly to opfilename.

Return type:

None

Raises:
  • TypeError – If files is neither a list of filenames nor a glob pattern.

  • FileNotFoundError – If files is given as a glob pattern and no matching files are found in path.

Notes

  • If instrument is not None, this function delegates to combine_spectra and returns immediately.

  • Input data are combined using combine_data

  • Variance extensions are processed only if varext is provided.

  • If mask is supplied, bad pixels are masked or interpolated using masking_frame before the output is written.

  • The primary HDU is replaced when fluxext contains extension 0.

Examples

Combine the primary extension of a list of FITS files using the mean:

>>> combine_process(files=["file1.fits", "file2.fits"],
...                 opfilename="combined.fits",
...                 fluxext=[0],
...                 method="mean")

Combine flux and variance from extensions 1 and 2:

>>> combine_process(files=["obs1.fits", "obs2.fits"],
...                 opfilename="combined.fits",
...                 fluxext=[1],
...                 varext=[2],
...                 method="median")
ariastrotools.handle_frame.divide_smoothgradient(filename, opfilename, path='.', medsmoothsize=(25, 51), fluxext=[0], varext=None)[source]

Apply a median filter to an astronomical FITS image and normalize it by dividing the original image by the smoothed background gradient.

This is typically used to remove large-scale background gradients while preserving smaller-scale features in the image.

Parameters:
  • filename (str) – Input FITS file containing the data to be processed.

  • opfilename (str) – Output FITS file where the processed result will be saved.

  • path (str, optional) – Path to the input file. Default is the current directory (‘.’).

  • medsmoothsize (tuple of int, optional) – Size of the median filter window. Larger sizes smooth more strongly. Default is (25, 51).

  • fluxext (list of int, optional) – List of extensions in the FITS file that contain the flux/image data to be normalized. Default is [0] (primary extension).

  • varext (list of int, optional) – List of extensions corresponding to variance maps for each flux extension. If provided, the variance maps will also be normalized by the squared smoothed gradient. Default is None.

Notes

  • The function clips the input image values to avoid division by zero: inputimgdata = np.clip(inputimgdata, 1, np.max(inputimgdata+1)).

  • Median filtering may be memory intensive. If a MemoryError occurs, try using a smaller medsmoothsize.

  • For each extension processed:
    • The flux is divided by the median-smoothed version of itself.

    • If variance data are provided, they are divided by the square of the median-smoothed image.

  • The output FITS file contains the normalized data (and variance maps, if applicable) with updated headers recording the operation history.

Output

FITS file

A FITS file (opfilename) containing the normalized image(s) and optional variance extensions.

Example

>>> divide_smoothgradient("input.fits", "output.fits",
...                       medsmoothsize=(25, 51),
...                       fluxext=[0, 1],
...                       varext=[2, 3])
ariastrotools.handle_frame.masking_frame(frame, mask, variance=None, method='interpolate')[source]

Apply a bad-pixel mask to a data frame.

Pixels where the mask is not equal to 1 are either replaced with NaN values or interpolated from neighboring pixels, depending on the selected method.

Parameters:
  • frame (numpy.ndarray) – Input 2D data array.

  • mask (numpy.ndarray, str, pathlib.Path, or list) –

    Mask information. Supported inputs are:

    • numpy.ndarray : Boolean/integer mask array with the same shape as frame. Pixels with value 1 are considered valid.

    • str or pathlib.Path : Path to a .npy mask file that will be loaded using numpy.load.

    • list : If a list is provided, only the first element is used. This is useful when arguments are parsed using argparse with nargs='+'.

  • variance (numpy.ndarray, optional) – Variance array corresponding to frame. If provided, variances of masked pixels are multiplied by 1000 after masking/interpolation to reflect their reduced reliability.

  • method ({'nan', 'interpolate'}, optional) –

    Method used to handle masked pixels.

    • 'nan' : Replace masked pixels with NaN values.

    • 'interpolate' : Fill masked pixels using biharmonic inpainting from neighboring valid pixels.

    Default is 'interpolate'.

Returns:

If variance is not provided, returns the processed frame.

If variance is provided, returns (frame, variance), where the variance of masked pixels has been increased.

Return type:

numpy.ndarray or tuple

Notes

For method='nan', the input frame is modified in place.

For method='interpolate', a new array is returned by the interpolation routine.

Interpolated pixels should be treated with caution, particularly for large masked regions. When a variance map is supplied, the variance of masked pixels is increased to reduce their influence in subsequent weighted analyses.

ariastrotools.handle_frame.operate_process(ip1, ip2, opfilename, operation='+', fluxext=[0], varext=None)[source]

Perform arithmetic operations on FITS file extensions and write results.

This function takes one FITS file (ip1) and either another FITS file or a constant value (ip2), performs the specified operation on the selected extensions, and writes the result to a new FITS file.

Parameters:
  • ip1 (str) – Path to the first FITS file.

  • ip2 (str or float) – Path to the second FITS file, or a constant value to apply the operation. - If a filename, the same extensions as in fluxext will be read. - If a float, the value is broadcasted to the data in ip1.

  • opfilename (str) – Output FITS filename where the result will be written.

  • operation ({'+', '-', '*', '/', ...}, optional) – Arithmetic operation to perform. Default is '+'. The valid set depends on what ari_operations supports.

  • fluxext (list of int, optional) – List of extension numbers containing flux data in the input files. Each extension in this list will be processed. Default is [0] (primary HDU).

  • varext (list of int or None, optional) – List of extension numbers containing variance data corresponding to each entry in fluxext. If None (default), variance propagation is skipped.

Notes

  • For each extension in fluxext:

    1. Data are read from ip1 and ip2.

    2. The operation is applied using ari_operations.

    3. Results are stored in the output HDUList.

    4. If varext is provided, the corresponding variance extensions are also operated on and appended to the output.

  • If an extension index is 0, the result is stored in the PrimaryHDU. Otherwise, results are stored as ImageHDU extensions.

  • A HISTORY entry is added to the output headers to track the operation.

Examples

Add fluxes in the primary HDU of two FITS files:

operate_process("file1.fits", "file2.fits",
                "sum.fits", operation='+', fluxext=[0])

Subtract a constant value from a flux extension:

operate_process("file1.fits", 10.0,
                "output.fits", operation='-', fluxext=[1])

Perform multiplication with variance propagation:

operate_process("file1.fits", "file2.fits",
                "multiplied.fits", operation='*',
                fluxext=[1, 2], varext=[3, 4])
ariastrotools.handle_frame.remove_cosmic_rays(input_fname, opfilename, fluxext=[0], varext=None)[source]

Remove cosmic rays from FITS image extensions using astroscrappy.

This function reads one or more image extensions from a FITS file, detects and removes cosmic rays using the astroscrappy.detect_cosmics algorithm, and writes the cleaned images (along with cosmic-ray masks and optional variance extensions) into a new output FITS file.

Parameters:
  • input_fname (str) – Path to the input FITS file containing the image data.

  • opfilename (str) – Path to the output FITS file where the cosmic-ray-cleaned data will be written.

  • fluxext (list of int, optional) – List of extension indices in the input FITS file that contain image data to be cleaned. Default is [0] (the primary HDU).

  • varext (list of int or None, optional) – List of extension indices corresponding to variance data for each flux extension. If provided, the same indices are used to fetch the variance arrays and pass them to astroscrappy.detect_cosmics for improved detection. If None (default), cosmic-ray detection is run without variance information.

Notes

  • The function uses the astroscrappy implementation of the LA Cosmic algorithm to detect and remove cosmic rays.

  • For each processed image extension, the following are written to the output file:

    • The cleaned image data

    • (Optionally) the corresponding variance extension, if varext is given

    • A binary mask extension named CRMASK with 1 where cosmic rays were detected

  • A HISTORY keyword is added to the header indicating that cosmic rays were removed with astroscrappy.

Output Structure

The output FITS file will contain, in order:

  1. Cleaned image(s) in the same order as fluxext

  2. Optional variance image(s), if varext is provided

  3. Corresponding cosmic-ray mask(s) named CRMASK

Example

>>> remove_cosmic_rays(
...     "raw_image.fits",
...     "cleaned_image.fits",
...     fluxext=[1, 2],
...     varext=[3, 4]
... )

This reads extensions 1 and 2 as flux images, uses extensions 3 and 4 as variance maps, removes cosmic rays, and writes a cleaned file containing the corrected images, variance maps, and cosmic-ray masks.

ariastrotools.handle_frame.scale_datacube(datacube, varcube=None, scale='p50', scale_mask=None)[source]

Scale the frames in a data cube using percentile-based scaling.

Each frame is assigned a scaling factor based on the specified percentile. The scaling factors are normalized by their median value before scaling the data cube. If a variance cube is provided, the variance is scaled consistently with the data.

Parameters:
  • datacube (numpy.ndarray) – Input data cube with shape (n_frames, ny, nx).

  • varcube (numpy.ndarray or None, optional) – Variance cube corresponding to datacube, with the same shape. If provided, the variance is scaled by the square of the scaling factor. Default is None.

  • scale (str, optional) – Scaling scheme to use. Currently, only percentile-based scaling in the form 'pXX' is supported, where XX specifies the percentile used to determine the scaling factor. For example, 'p50' uses the 50th percentile (median) of each frame. The scaling factors are normalized by their median value. Default is 'p50'.

  • scale_mask (numpy.ndarray or None, optional) – Boolean mask identifying pixels to exclude when calculating the percentile scaling factors. The same mask is applied to every frame. If None, all valid (non-NaN) pixels are used. Default is None.

Returns:

  • scaled_datacube (numpy.ndarray) – Scaled data cube with the same shape as datacube.

  • scaled_varcube (numpy.ndarray or None) – Scaled variance cube with the same shape as varcube, or None if varcube was not provided.

  • scale_array (numpy.ndarray) – One-dimensional array containing the normalized scaling factor for each frame. The median of the scaling factors is one.

Raises:

ValueError – If scale does not follow the supported 'pXX' format.

Notes

The scaling factor for each frame is calculated from the specified percentile and then normalized by the median of all frame scaling factors:

scale_factor = percentile(frame) / median(percentile_values)

The data and variance are then scaled as:

scaled_data = data / scale_factor

scaled_variance = variance / scale_factor**2

For example, with scale='p50', each frame is normalized using its median value relative to the median of the frame medians.

ariastrotools.handle_frame.shifting_frame(input_fname, opfilename, shifttoapply=array([0., 0.]), fluxext=[0], varext=None)[source]

Shift the image extensions of a FITS file by an integer pixel offset.

The specified flux extensions are shifted using numpy.roll, which performs a circular shift (pixels shifted off one edge reappear on the opposite edge). If corresponding variance extensions are provided, they are shifted by the same amount.

Parameters:
  • input_fname (str or pathlib.Path) – Path to the input FITS file.

  • opfilename (str or pathlib.Path) – Path to the output FITS file.

  • shifttoapply (array-like of int, optional) – Pixel shift to apply in the form (row_shift, column_shift). Positive values shift the image towards increasing row or column indices. The default is (0, 0).

  • fluxext (list of int, optional) – List of FITS extensions containing flux images to be shifted. The default is [0].

  • varext (list of int, optional) – List of FITS extensions containing variance images corresponding to fluxext. If provided, each variance extension is shifted by the same amount as its corresponding flux extension. The default is None.

Notes

  • Shifts are performed using numpy.roll and therefore are circular.

  • Only integer pixel shifts are supported.

  • The length of varext must match the length of fluxext when provided.

Returns:

The shifted FITS file is written to opfilename.

Return type:

None