imutil.pixels.fixpix
imutil.pixels.fixpix(
ccd,
mask=None,
maskpath=None,
extension=None,
mask_extension=None,
priority=None,
update_header=True,
verbose=True,
)Interpolate the masked location (N-D generalization of IRAF PROTO.FIXPIX)
Parameters
ccd :~astropy.nddata.CCDData-like (e.g.,~astropy.io.fits.PrimaryHDU,~astropy.io.fits.ImageHDU,~astropy.io.fits.HDUList),~numpy.ndarray, path-like, or number-like-
The CCD data to be “fixed”.
mask :~astropy.nddata.CCDData-like (e.g.,~astropy.io.fits.PrimaryHDU,~astropy.io.fits.ImageHDU,~astropy.io.fits.HDUList),~numpy.ndarray, path-like, optional. = None-
The mask to be used for fixing pixels (pixels to be fixed are where
maskisTrue). IfNone, nothing will happen andccdis returned. extension : HDUExt = None-
The extension of FITS to be used. It can be given as integer (0-indexing) of the extension,
EXTNAME(singlestr), or atupleofstrandint:(EXTNAME, EXTVER). IfNone(default), the first extension with data will be used. Default:None. mask_extension : HDUExt = None-
The extension of FITS to be used. It can be given as integer (0-indexing) of the extension,
EXTNAME(singlestr), or atupleofstrandint:(EXTNAME, EXTVER). IfNone(default), the first extension with data will be used. Default:None. priority : tuple[int, …] | None = None-
The priority of axis as a
tupleof non-repeatingintfrom0toccd.ndim. It will be used if the mask has the same size along two or more of the directions. To specify, use the integers for axis directions, descending priority. For example,(2, 1, 0)will be identical topriority=None(default) for 3-D images. Default isNoneto follow IRAF’s PROTO.FIXPIX: Priority is higher for larger axis number (e.g., in 2-D, x-axis (axis=1) has higher priority than y-axis (axis=0)).
Notes
Run boundaries are computed from the original mask with storage proportional to the number of masked pixels times the dimension. Interpolation retains C-order traversal and repeated writes where runs cross. Precomputation adds index storage and sorting overhead, including for isolated bad pixels.
Examples
Timing test: MBP 15” [2018, macOS 11.4, i7-8850H (2.6 GHz; 6-core), RAM 16 GB (2400MHz DDR4), Radeon Pro 560X (4GB)], 2021-11-05 11:14:04 (KST: GMT+09:00)
>>> np.random.RandomState(123) # RandomState(MT19937) at 0x7FAECA768D40
>>> data = np.random.normal(size=(1000, 1000))
>>> mask = np.zeros_like(data).astype(bool)
>>> mask[10, 10] = True
>>> %timeit air.fixpix(data, mask)
19.7 ms +- 1.53 ms per loop (mean +- std. dev. of 7 runs, 100 loops each)Same benchmark on MBP 14” [2024, macOS 26.4.1, M4Pro(8P+4E/G20c/N16c/48G)], 2026-05-27:
>>> rng = np.random.default_rng(123)
>>> data = rng.normal(size=(1000, 1000))
>>> mask = np.zeros_like(data, dtype=bool)
>>> mask[10, 10] = True
>>> %timeit air.fixpix(data, mask)
8.55 ms ± 124 µs per loop (7 runs, 20 loops each)Same M4Pro benchmark after run-span interpolation was added:
>>> %timeit air.fixpix(data, mask, update_header=False, verbose=False)
166 µs ± 8 µs per loop (5 runs, 200 loops each)>>> mask100 = np.zeros_like(data, dtype=bool)
>>> mask100.ravel()[::10000] = True
>>> %timeit air.fixpix(data, mask100, update_header=False, verbose=False)
620 µs ± 25 µs per loop (5 runs, 100 loops each)>>> print(data[9:12, 9:12], air.fixpix(data, mask)[9:12, 9:12])
# [[ 1.64164502 -1.00385046 -1.24748504]
# [-1.31877621 1.37965928 0.66008966]
# [-0.7960262 -0.14613834 -1.34513327]]
# [[ 1.64164502 -1.00385046 -1.24748504]
# [-1.31877621 -0.32934328 0.66008966]
# [-0.7960262 -0.14613834 -1.34513327]] adu