Source code for sofia_redux.spectroscopy.scaleimgs

# Licensed under a 3-clause BSD style license - see LICENSE.rst

from astropy import log
import numpy as np
from sofia_redux.toolkit.utilities.func import slicer
import warnings

__all__ = ['scaleimgs']


[docs] def scaleimgs(images, variances=None, axis=0, nan=True): """ Scales a set of images to the median flux level of all images Determines the median signal of each image in the cube M_i. Then it computes the median of these values M and then determines scale factors to scale M_i ti M. It then applied these scale factors to the images in the cubes. Parameters ---------- images : array_like of float (shape) Images of arbitrary shape variances : array_like of float (shape), optional Variances to update in parallel with images axis : int, optional The axis determining separate images. nan : bool, optional If True, ignore NaNs when determining median values. Returns ------- scaled_images, [scaled_variances] : numpy.ndarray, [numpy.ndarray] Images and optionally variances (if variances were supplied) scaled to the same median level. Both arrays are of float type and (shape). """ images = np.array(images).astype(float) dovar = variances is not None if dovar: variances = np.array(variances).astype(float) if variances.shape != images.shape: log.error("Images and variances shape mismatch") return with warnings.catch_warnings(): warnings.simplefilter('ignore', RuntimeWarning) median = np.nanmedian if nan else np.median nimages = images.shape[axis] medimages = np.zeros(nimages) slices = [] for imagei in range(nimages): imslice = slicer(images, axis, imagei, ind=True) slices.append(imslice) medimages[imagei] = median(images[imslice]) scale = np.full(nimages, np.nan) nzi = medimages != 0 scale[nzi] = median(medimages) / medimages[nzi] vscale = scale ** 2 if dovar else None for imagei, imslicer in enumerate(slices): images[imslicer] *= scale[imagei] if dovar: variances[imslicer] *= vscale[imagei] if dovar: return images, variances else: return images