Montage Montage is an astronomical image toolkit with components for reprojection, background matching, coaddition and visualization of FITS files. It can be used as a set of command-line tools (Linux, OS X and Windows), C library calls (Linux and OS X) and as Python binary extension modules.
The Montage source is written in ANSI-C and code can be downloaded from GitHub ( https://github.com/Caltech-IPAC/Montage ). The Python package can be installed from PyPI ("</i>pip install MontagePy"). The package has no external dependencies. See http://montage.ipac.caltech.edu/ for details on the design and applications of Montage.
Most of Montage is focused on 2D astronomical image mosaics: reprojection, background matching, coaddition and so on. But there is also a need for tools that operate on data "cubes": three- or four-dimensional arrays where two of the axes represent the same projected sky coordinates as we find in the 2D images. Usually, the third axis is some form of wavelength.
The problem sets are not completely parallel: datacubes do not generally need background matching but you do frequently want cutouts in the none spatial dimensions and to transpose axes.
Montage includes a set of routines for manipulating datacubes:
This routine, mProjectCube, reprojects a cube assuming the first two axes are sky spatial and that the FITS cube has proper projection information. It uses the same algorithm as mProject. If the axes in some other order you can rearrange them with mTranspose.
Note: The MontagePy python package has no external dependencies. We include other utilities on this page to aid in visualizing MontagePy package results.
from MontagePy.main import mProjectCube, mViewer
help(mProjectCube)
mProjectCube can handle any projection and coordinate system and is flux-conserving. The algorithm is based on pixel overlap in spherical sky coordinates rather than in the input or output planar pixel space.
mProject has a few extra controls for things like excluding a border, though unlike 2D images, data cubes rarely have this sort of problem. The basic inputs are a FITS data cube and a FITS header describing the output cube we want, which must match the input in the non-spatial dimensions. The output is a FITS cube with the data from the input resampled to the output header pixel space.
The input FITS header (actually an ASCII file that looks like a FITS header but with newlines and unpadded line lengths) can be produced in a number of ways. There are Montage tools to take an image list (or point source list) and determine a bounding box (mMakeHdr) or just a location and size (mHdr). You can also pull the header off another file (mGetHdr) if you want to build a matching mosaic from other data. Or you can just create the output header by had (e.g., a simple all-sky Aitoff projection). It is up to the user to make sure that the header has appropriate (and matching) information for the non-spatial dimensions.
The data used in the datacube Jupyter pages come from the Galactic Arecibo L-band Feed Array HI (GALFA-HI) survey (Peek et al., 2011, Ap J Suppl, 194, 20; DOI 10.1088/0067-0049/194/2/20; ADS Bibcode 2011ApJS..194...20P). We start with five datacubes covering a contiguous region of the Galactic plane. Using mImgtbl and mMakeHdr we have generated a header that bounds all five and we use that here.
This reprojection can take tens of seconds, so be patient.
rtn = mProjectCube('GALFA/shrunken/GALFA_HI_RA+DEC_004.00+34.35_N.fits',
'work/GALFA/projected/GALFA_HI_RA+DEC_004.00+34.35_N.fits',
'GALFA/galfa.hdr')
print(rtn)
Here are the original image and the reprojected one. Since these are cubes, we have to collapse it in the third dimension for display. Here we have chosen to coadd a few of the central wavelengths HDU 0 (there is only the one HDU but we have to be explicity for notation reasons).
from IPython.display import Image
rtn = mViewer('-ct 4 -gray "GALFA/shrunken/GALFA_HI_RA+DEC_004.00+34.35_N.fits[0][60:68]" \
-2s max gaussian-log -out work/GALFA/GALFA_HI_RA+DEC_004.00+34.35_N.png',
'', mode=2 )
Image(filename='work/GALFA/GALFA_HI_RA+DEC_004.00+34.35_N.png')
rtn = mViewer('-ct 4 -gray "work/GALFA/projected/GALFA_HI_RA+DEC_004.00+34.35_N.fits[0][60:68]" \
-2s max gaussian-log -out work/GALFA/GALFA_HI_RA+DEC_004.00+34.35_N_projected.png',
'', mode=2)
Image(filename='work/GALFA/GALFA_HI_RA+DEC_004.00+34.35_N_projected.png')
If mProjectCube encounters an error, the return structure will just have two elements: a status of 1 ("error") and a message string that tries to diagnose the reason for the error.
For instance, if the user asks for a file that doesn't exist:
rtn = mProjectCube('GALFA/shrunken/unknown.fits',
'work/GALFA/projected/GALFA_HI_RA+DEC_004.00+34.35_N.fits',
'GALFA/galfa.hdr')
print(rtn)
mProjectCube can also be run as a command-line tool in Linux, OS X, and Windows:
Usage: mProjectCube [-z factor][-d level][-s statusfile][-h hdu][-x scale][-w weightfile][-t threshold][-X(expand)][-e(nergy-mode)][-f(ull-region)] in.fits out.fits hdr.template
If you are writing in C/C++, mProjectCube can be accessed as a library function:
/*-***********************************************************************/ /* */ /* mProjectCube */ /* */ /* Montage is a set of general reprojection / coordinate-transform / */ /* mosaicking programs. Any number of input images can be merged into */ /* an output FITS file. The attributes of the input are read from the */ /* input files; the attributes of the output are read a combination of */ /* the command line and a FITS header template file. */ /* */ /* This module, mProjectCube, processes a single input image and */ /* projects it onto the output space. It's output is actually a pair */ /* of FITS files, one for the sky flux the other for the fractional */ /* pixel coverage. Once this has been done for all input images, */ /* mAdd can be used to coadd them into a composite output. */ /* */ /* Each input pixel is projected onto the output pixel space and the */ /* exact area of overlap is computed. Both the total 'flux' and the */ /* total sky area of input pixels added to each output pixel is */ /* tracked, and the flux is appropriately normalized before writing to */ /* the final output file. This automatically corrects for any multiple */ /* coverages that may occur. */ /* */ /* In order to deal efficiently with cubes, mProjectCube differs from */ /* mProject in one major way. Rather than try to minimize the amount */ /* of memory used, mProjectCube reads the whole cube in up front and */ /* then reprojects all of it. While mProject could read a line at a */ /* time this would result in significant I/O thrashing and slowdown. */ /* */ /* char *input_file FITS file to reproject */ /* char *output_file Reprojected FITS file */ /* char *template_file FITS header file used to define the desired */ /* output */ /* */ /* int hdu Optional HDU offset for input file */ /* char *weight_file Optional pixel weight FITS file (must match */ /* input) */ /* */ /* double fixedWeight A weight value used for all pixels */ /* double threshold Pixels with values below this level treated */ /* as blank */ /* */ /* double drizzle Optional pixel area 'drizzle' factor */ /* double fluxScale Scale factor applied to all pixels */ /* int energyMode Pixel values are total energy rather than */ /* energy density */ /* int expand Expand output image area to include all of */ /* the input pixels */ /* int fullRegion Do not 'shrink-wrap' output area to non-blank */ /* pixels */ /* int debug Debugging output level */ /* */ /*************************************************************************/ struct mProjectCubeReturn *mProjectCube(char *input_file, char *output_file, char *template_file, int hduin, char *weight_file, double fixedWeight, double threshold, double drizzle, double fluxScale, int energyMode, int expand, int fullRegion, int debugin)
Return Structure
struct mProjectCubeReturn { int status; // Return status (0: OK, 1:ERROR) char msg [1024]; // Return message (for error return) char json[4096]; // Return parameters as JSON string double time; // Run time (sec) };