KeyError: "Keyword 'CTYPE3' not found."

Hi,
I am new here. Trying spectrography using fits files for the first time. I have:
python 3.9.6.
and using the following code to read a fits file and plot it. I am getting the following error. Could you please help?

Traceback (most recent call last):
  File "/Volumes/astronomy/spectra-test1.py", line 12, in <module>
    w = WCS(h1, naxis=1, relax=False, fix=False)
  File "/Users/codeNick7/Library/Python/3.9/lib/python/site-packages/astropy/wcs/wcs.py", line 526, in __init__
    sip = self._read_sip_kw(header, wcskey=key)
  File "/Users/codeNick7/Library/Python/3.9/lib/python/site-packages/astropy/wcs/wcs.py", line 1298, in _read_sip_kw
    ctype = [header[f"CTYPE{nax}{wcskey}"] for nax in range(1, self.naxis + 1)]
  File "/Users/codeNick7/Library/Python/3.9/lib/python/site-packages/astropy/wcs/wcs.py", line 1298, in <listcomp>
    ctype = [header[f"CTYPE{nax}{wcskey}"] for nax in range(1, self.naxis + 1)]
  File "/Users/codeNick7/Library/Python/3.9/lib/python/site-packages/astropy/io/fits/header.py", line 170, in __getitem__
    card = self._cards[self._cardindex(key)]
  File "/Users/codeNick7/Library/Python/3.9/lib/python/site-packages/astropy/io/fits/header.py", line 1726, in _cardindex
    raise KeyError(f"Keyword {keyword!r} not found.")
KeyError: "Keyword 'CTYPE3' not found."

Code:

import numpy as np
import matplotlib.pyplot as plt
from astropy.io import fits
from astropy.wcs import WCS

hdul = fits.open('M101.fits')
data = hdul[0].data
h1 = hdul[0].header
obj_name = h1.get('OBJECT', 'Unknown')

flux = data[0]
w = WCS(h1, naxis=1, relax=False, fix=False)
lam = w.wcs_pix2world(np.arange(len(flux)), 0)[0]

plt.plot(lam, flux)
plt.ylim(0, )
plt.xlabel('Wavelength (Angstrom)')
plt.ylabel('Normalized flux')
plt.savefig(obj_name + '.png')

Hi @codeNick7,

Can you provide some context what that file is?
Also what version of astropy you are using?

The error suggests that something is wrong with the metadata, it is telling WCS that there are 3 axes but then the metadata for the third one is missing, causing that error.

But since you specify naxis=1, I would have assumed that WCS would ignore the third axis keywords.

Hi @nabobalis,
Here’s the file that I used. This file is captured using SeeStar S50. I am using: asdf_astropy-0.6.1

2:52:11: Running command: dumpheader
22:52:11: =FITS header for currently loaded image=
22:52:11: SIMPLE  =                    T / file does conform to FITS standard
22:52:11: BITPIX  =                   16 / number of bits per data pixel
22:52:11: NAXIS   =                    3 / number of data axes
22:52:11: NAXIS1  =                 1080 / length of data axis 1
22:52:11: NAXIS2  =                 1920 / length of data axis 2
22:52:11: NAXIS3  =                    3 / length of data axis 3
22:52:11: EXTEND  =                    T / FITS dataset may contain extensions
22:52:11: COMMENT   FITS (Flexible Image Transport System) format is defined in 'Astronomy
22:52:11: COMMENT   and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H
22:52:11: BZERO   =                32768 / offset data range to that of unsigned short
22:52:11: BSCALE  =                    1 / default scaling factor
22:52:11: CREATOR = 'ZWO Seestar S50'    / Capture software
22:52:11: XORGSUBF=                    0 / Subframe X position in binned pixels
22:52:11: YORGSUBF=                    0 / Subframe Y position in binned pixels
22:52:11: FOCALLEN=                  250 / Focal length of telescope in mm
22:52:11: XBINNING=                    1 / Camera X Bin
22:52:11: YBINNING=                    1 / Camera Y Bin
22:52:11: CCDXBIN =                    1 / Camera X Bin
22:52:11: CCDYBIN =                    1 / Camera Y Bin
22:52:11: XPIXSZ  =     2.90000009536743 / pixel size in microns (with binning)
22:52:11: YPIXSZ  =     2.90000009536743 / pixel size in microns (with binning)
22:52:11: IMAGETYP= 'Light   '           / Type of image
22:52:11: STACKCNT=                   29 / Stack frames
22:52:11: EXPOSURE=                  10. / Exposure time in seconds
22:52:11: EXPTIME =                  10. / Exposure time in seconds
22:52:11: CCD-TEMP=              33.1875 / sensor temperature in C
22:52:11: RA      =           210.987495 / Object Right Ascension in degrees
22:52:11: DEC     =            54.238056 / Object Declination in degrees
22:52:11: SITELONG=              77.5077 / longitude of the imaging site in degrees
22:52:11: SITELAT =              12.9834 / latitude of the imaging site in degrees
22:52:11: DATE-OBS= '2024-05-04T18:22:26.928727' / Image created time
22:52:11: FILTER  = 'IRCUT   '           / Filter used when taking image
22:52:11: INSTRUME= 'Seestar S50'        / Camera model
22:52:11: BAYERPAT= 'GRBG    '           / Bayer pattern
22:52:11: GAIN    =                   80 / Gain Value
22:52:11: FOCUSPOS=                 1568 / Focuser position in steps
22:52:11: TELESCOP= 'Seestar S50'        / Telescope name
22:52:11: OBJECT  = 'M 101   '           / name or catalog number of object being imaged
22:52:11: CTYPE1  = 'RA---TAN-SIP'       / TAN (gnomic) projection + SIP distortions
22:52:11: CTYPE2  = 'DEC--TAN-SIP'       / TAN (gnomic) projection + SIP distortions
22:52:11: CRVAL1  =         210.67574679 / RA  of reference point
22:52:11: CRVAL2  =        54.3819379292 / DEC of reference point
22:52:11: CRPIX1  =        457.662189484 / X reference pixel
22:52:11: CRPIX2  =         1009.6452446 / Y reference pixel
22:52:11: CD1_1   =    0.000656747939577 / Transformation matrix
22:52:11: CD1_2   =    -6.0857038141E-05 / no comment
22:52:11: CD2_1   =    6.06438188336E-05 / no comment
22:52:11: CD2_2   =    0.000656794243055 / no comment
22:52:11: A_ORDER =                    2 / Polynomial order, axis 1
22:52:11: B_ORDER =                    2 / Polynomial order, axis 2
22:52:11: AP_ORDER=                    2 / Inv polynomial order, axis 1
22:52:11: BP_ORDER=                    2 / Inv polynomial order, axis 2
22:52:11: A_0_0   =                    0 / no comment
22:52:11: A_0_1   =                    0 / no comment
22:52:11: A_0_2   =   -1.15118558177E-07 / no comment
22:52:11: A_1_0   =                    0 / no comment
22:52:11: A_1_1   =    2.72788989551E-07 / no comment
22:52:11: A_2_0   =    1.50170638765E-07 / no comment
22:52:11: B_0_0   =                    0 / no comment
22:52:11: B_0_1   =                    0 / no comment
22:52:11: B_0_2   =   -5.16561285475E-07 / no comment
22:52:11: B_1_0   =                    0 / no comment
22:52:11: B_1_1   =   -2.31779288975E-06 / no comment
22:52:11: B_2_0   =   -1.60092365451E-06 / no comment
22:52:11: AP_0_0  =   -3.80900109533E-06 / no comment
22:52:11: AP_0_1  =    4.08520616831E-08 / no comment
22:52:11: AP_0_2  =    1.15140843091E-07 / no comment
22:52:11: AP_1_0  =    7.46941853683E-08 / no comment
22:52:11: AP_1_1  =   -2.72855408182E-07 / no comment
22:52:11: AP_2_0  =   -1.50260895011E-07 / no comment
22:52:11: BP_0_0  =   -8.49709919304E-05 / no comment
22:52:11: BP_0_1  =    1.05768082533E-06 / no comment
22:52:11: BP_0_2  =     5.1671394943E-07 / no comment
22:52:11: BP_1_0  =    1.67001034226E-06 / no comment
22:52:11: BP_1_1  =    2.31841779531E-06 / no comment
22:52:11: BP_2_0  =    1.60143414023E-06 / no comment
22:52:11: IMAGEW  =                 1080 / Image width,  in pixels.
22:52:11: IMAGEH  =                 1920 / Image height, in pixels.
22:52:11: END

-codeNIck7

I am no expert on FITS standards but the third axis has been defined but given no metadata for it to be a valid axis.

I would suggest as a quick hack would to drop “NAXIS3” from the header and change “NAXIS” to be 2 before you pass it into WCS and see if that helps.