imutil.imarith.imarith
imutil.imarith.imarith(
im1,
op,
im2,
output=None,
extension1=None,
extension2=None,
name1=None,
name2=None,
offsets=None,
replace=0,
header_params=None,
dtype='float32',
error_calc=False,
ignore_header=False,
overwrite=False,
output_verify='exception',
verbose=True,
)Similar to IRAF IMARITH
Parameters
im1 :~astropy.nddata.CCDData,~numpy.ndarray, number-like, path-like-
The images to be operated. A string that can be converted to
float(float(im)) will be interpreted as numbers; if not, it will be interpreted as a path to the FITS file. im2 :~astropy.nddata.CCDData,~numpy.ndarray, number-like, path-like-
The images to be operated. A string that can be converted to
float(float(im)) will be interpreted as numbers; if not, it will be interpreted as a path to the FITS file. op : ('**', '%', '//', '+', '-', '*', '/') = "**"-
The operation to be done. Unlike IRAF, ‘min’ and ‘max’ are not implemented (easy to implement in the future but I don’t know the necessity).
"**","%", and"//"are not supported whenerror_calc=True. output : path-like, optional. = None-
The path for the resulting file to be saved.
extension1 :int,str, (str,int) = 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. extension2 :int,str, (str,int) = 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. name1 : str | None = None-
The names of the images that will be logged into the header (
HISTORY). IfNone, function automatically chooses appropriate name for it: the number (ifimis number-like), the path (ifimis path-like), or explanatory strings (ifimis either~numpy.ndarrayor~astropy.nddata.CCDData) Default:None. name2 : str | None = None-
The names of the images that will be logged into the header (
HISTORY). IfNone, function automatically chooses appropriate name for it: the number (ifimis number-like), the path (ifimis path-like), or explanatory strings (ifimis either~numpy.ndarrayor~astropy.nddata.CCDData) Default:None. replace : np.nan,float-like, optional. = 0-
The value to replace pixels where the value is NaN or Inf (i.e.,
~np.isfinite(ccd.data)). UseNoneto keep thenanandinfas is. Default is0, following IRAF. Note that both nan and inf are not representable in integer data types. header_params :strordict, optional. = None-
If a string, the output file’s
OBJECTkeyword will be replaced byheaddr_params. If adict, it must be adictof header keyword and value pairs, so that the output file’s header will have those key-value pairs (care is needed since it overwrites the pre-existing keys). Ifdict, it can be{key:value}or{key:(value, comment)}.Note: this differs from IRAF. In IRAF, hparams is used to propagate a header keyword, mainly
"EXPTIME", when two images are combined.Default:
None. dtype :str, dtype, optional. = 'float32'-
The data type of the output
~astropy.nddata.CCDDataand/or file. Default:'float32'. error_calc :bool, optional. = False-
If
True, the uncertainties are propagated by~astropy.nddataarithmetics. IfFalse(default), there is no need to load data as~astropy.nddata.CCDData(because header parsing time gets enromous if iterated through hundreds of files), and hence the cfitsio-likefitsiois used. Error calculation is done only ifignore_header=Falseat the moment. Default:False. ignore_header :bool, optional. = False-
Whether to ignore all the header informations of
im1andim2. This will boost the speed of the code because none of the effort will be put to find/parse header of any file. A cost is that virtually no information (including unit such asBUNIT) is preserved in the output. The returned HDU will only have meaningfulHISTORY.offsetswill be also be ignored, and it will raise critical error if FITS images have different shape. Error propagation is of course impossible at this moment, because there is no way to infer the extension for the uncertainty and its type (wheter variance or standard deviation, etc.) Default:False. output_verify :str, optional. = 'exception'-
FITS verification option passed to Astropy when
outputis written.
Returns
ccd :~astropy.nddata.CCDData-
If
ignore_headerisFalse(default). hdu :~astropy.io.fits.PrimaryHDU-
If
ignore_headerisTrue. This is not in~astropy.nddata.CCDDataformat since there is no way to infer the unit (e.g.,BUNIT).
Notes
Performance tip: if you iterate over many images but one is fixed (e.g., imarith(images[i], '/', mflat_path) for i in range(100)), load the multiply used file and give that HDU or ~astropy.nddata.CCDData to imarith. This will reduce the time spent for file I/O.
Converting an array to ~astropy.nddata.CCDData takes only ~ 10 us regardless on the array size on MBP 15”; this is because most time is spent on metadata generation. Note, however, that reading* a FITS file takes ~ 10 ms, i.e., 1000 times slower.
Tested on MBP 15” [2018, macOS 10.14.6, i7-8850H (2.6 GHz; 6-core), RAM 16 GB (2400MHz DDR4), Radeon Pro 560X (4GB)] 2020-11-02 21:50:07 (KST: GMT+09:00) - ysBach
Timing on MBP 14” [2024, macOS 26.4.1, M4Pro(8P+4E/G20c/N16c/48G)], 2026-05-27:
arr = np.ones((1000, 1000), dtype="float32")
fits.writeto("single.fits", arr, overwrite=True)
%timeit CCDData(arr, unit="adu")
# 2.21 µs ± 16.9 ns per loop (7 runs, 5000 loops each)
%timeit fits.getdata("single.fits")
# 175 µs ± 71.7 µs per loop (7 runs, 100 loops each)The type checking isinstance(im, `~astropy.nddata.CCDData`) takes only ~ 0.1 us.