I'm trying to extract the spectral axis of a FITS data set using astropy/spectral_cube. Specifically I want to convert the channel values into velocity values, accounting for the different radio/optical conventions and rest frequency of the spectral line being examined. This is working just fine for one FITS file but not for another. I presume this is due to a difference in the headers, but I can't figure out what the critical difference is.
My code :
from astropy.io import fits as pyfits
from astropy.wcs import WCS
from astropy import units
import spectral_cube
from spectral_cube import SpectralCube
fitsfile = pyfits.open(fitsfilename)
scube = SpectralCube.read(fitsfile)
vcube = scube.with_spectral_unit(units.km / units.s, velocity_convention='optical', rest_value=1420405750.0 * units.Hz)
Where 'fitsfilename' obviously sets the name of the file to load. The 'rest_value' is obtained from the header. Both cubes are HI data.
I then print out the spectral axis with :
vcube.spectral_axis
(When using this in anger, I would do additional steps, as I need to convert back and forth between non-integer channel values and velocities, e.g. :
cubewcs = vcube.wcs
wx, wy, wz = cubewcs.all_pix2world(150.0,125,0.0,0)
print(wx,wy,wz/vunit)
But this is not crucial to the main problem, I think)
Now for the case of the THINGS data sets (e.g. NGC 628) this prints out the exact velocity values I'm expecting, ranging from 588 to 735 km/s (verified with kvis and miriad, both of which are ultra reliable). If I change the velocity convention to radio, the results change as expected.
But for the AGES data sets (e.g. VC2), I get substantially different values. I expect the range -2277 - 20108 km/s; what I actually get is -2350 - 19370, off by over 700 km/s at the upper end ! Interestingly if I don't use .with_spectral_unit, i.e. if I just do :
vcube.spectral_axis
... then I get the correct result. So it's something to do with the unit conversion, but I don't know what. I tried plotting the velocities as a function of channel. The differences from the correct velocity follows a parabola, but the lowest difference is NOT at the reference channel.
My only suspicion is that it may relate to how the cubes are gridded. AGES grids so that the channels are of constant size in frequency, so that the velocity width of each channel varies slightly. I believe THINGS uses a constant velocity interval instead. So, can spectral_cube handle the necessary conversion, or am I barking up the wrong tree ?
question from:https://stackoverflow.com/questions/66064469/converting-the-spectral-axis-of-a-fits-file-using-spectral-cube