def _build_hdulist_(self, saveerror=False, savebackground=True): """ The fits hdulist that should be saved. Parameters ---------- saveerror: [bool] -optional- Set this to True if you wish to record the error and not the variance in you first hdu-table. if False, the table will be called VARIANCE and have self.v; if True, the table will be called ERROR and have sqrt(self.v) savebackground: [bool] -optional- Shall the background be saved ? Returns ------- Void """ from astropy.io.fits import ImageHDU self.header['PYSEDMT'] = ("ApertureSpectrum","Pysedm object Type") hdul = super(ApertureSpectrum, self)._build_hdulist_(saveerror=saveerror) hduAp = ImageHDU(self.apweight, name='APWEIGHT') hdul.append(hduAp) # -- Variance saving if self.has_background(): hduBkgd = ImageHDU(self.background.data, name='BKGD') hdul.append(hduBkgd) hduBkgdVar = ImageHDU(self.background.data, name='BKGDVAR') hdul.append(hduBkgdVar) hduApBkgd = ImageHDU(self.background.apweight, name='BKGDAPW') hdul.append(hduApBkgd) return hdul
def test_append_nddata_to_root_with_arbitrary_name(testfile2): ad = astrodata.open(testfile2) assert len(ad) == 6 ones = np.ones((10, 10)) hdu = ImageHDU(ones) nd = NDData(hdu.data) nd.meta['header'] = hdu.header hdu.header['EXTNAME'] = 'ARBITRARY' with pytest.raises(ValueError): ad.append(nd)
def trim_psf(indir, outdir, filename): assert os.path.abspath(indir) != os.path.abspath(outdir) infile = os.path.join(indir, filename) outfile = os.path.join(outdir, filename) fx = fits.open(infile) hdus = HDUList() #- HDU 0 XCOEFF - data unchanged but update keywords for less samples xcoeff = fx[0].data hdr = fx[0].header hdr['NWAVE'] = 3 #- down from 11 hdr['CRPIX1'] = 23 #- 23=45//2+1, down from 113=225//2+1 hdr['CRPIX1'] = 23 hdr['CDELT1'] = 0.005 #- 5mm instead of 1mm hdr['CDELT2'] = 0.005 #- 5mm instead of 1mm hdr['PIXSIZE'] = 0.005 #- 5mm instead of 1mm hdus.append(PrimaryHDU(xcoeff, header=hdr)) hdus.append(fx['YCOEFF']) #- subsample spots inspots = fx['SPOTS'].data spots = np.zeros((3,3,45,45)) spots[0,0] = rebin_image(inspots[0,0], 5) spots[1,0] = rebin_image(inspots[5,0], 5) spots[2,0] = rebin_image(inspots[10,0], 5) spots[0,1] = rebin_image(inspots[0,5], 5) spots[1,1] = rebin_image(inspots[5,5], 5) spots[2,1] = rebin_image(inspots[10,5], 5) spots[0,2] = rebin_image(inspots[0,10], 5) spots[1,2] = rebin_image(inspots[5,10], 5) spots[2,2] = rebin_image(inspots[10,10], 5) hdus.append(ImageHDU(spots, header=fx['SPOTS'].header)) #- subsample spots x,y locations dx = fx['SPOTX'].data hdus.append(ImageHDU(dx[::5, ::5], header=fx['SPOTX'].header)) dy = fx['SPOTY'].data hdus.append(ImageHDU(dy[::5, ::5], header=fx['SPOTY'].header)) #- Fiberpos unchanged hdus.append(fx['FIBERPOS']) #- Subsample SPOTPOS and SPOTWAVE d = fx['SPOTPOS'].data hdus.append(ImageHDU(d[::5], header=fx['SPOTPOS'].header)) d = fx['SPOTWAVE'].data hdus.append(ImageHDU(d[::5], header=fx['SPOTWAVE'].header)) hdus.writeto(outfile, clobber=True) fx.close()
def test_append_nddata_to_root_with_arbitrary_name(test_path): test_filename = 'GMOS/N20160524S0119.fits' ad = astrodata.open(os.path.join(test_path, test_filename)) lbefore = len(ad) ones = np.ones((100, 100)) hdu = ImageHDU(ones) nd = NDData(hdu.data) nd.meta['header'] = hdu.header hdu.header['EXTNAME'] = 'ARBITRARY' with pytest.raises(ValueError) as excinfo: ad.append(nd)
def test_save_image_hdu(dask_array_in_mem, tmp_path): # Saving an image HDU directly filename = tmp_path / 'test.fits' hdu = ImageHDU(data=dask_array_in_mem) hdu.writeto(filename) with fits.open(filename) as hdulist_new: assert isinstance(hdulist_new[1].data, np.ndarray) np.testing.assert_allclose(hdulist_new[1].data, dask_array_in_mem.compute())
def test_append_nddata_to_root_with_arbitrary_name(test_path): test_filename = 'GMOS/N20160524S0119.fits' ad = astrodata.open(os.path.join(test_path, test_filename)) lbefore = len(ad) ones = np.ones((100, 100)) hdu = ImageHDU(ones) nd = NDData(hdu.data) nd.meta['header'] = hdu.header hdu.header['EXTNAME'] = 'ARBITRARY' with pytest.raises(ValueError) as excinfo: ad.append(nd)
def _writeImpl(self, fits): """Implementation for writing to FITS file Parameters ---------- fits : `astropy.io.fits.HDUList` List of FITS HDUs. This has a Primary HDU already, the header of which may be supplemented with additional keywords. """ from astropy.io.fits import ImageHDU super()._writeImpl(fits) fits.append(ImageHDU(self.sky, name="SKY")) self.observations.toFits(fits) fits.append(ImageHDU(self.covar, name="COVAR")) fits.append(ImageHDU(self.covar2, name="COVAR2"))
def new_imagehdu(data, header, name=None): # Assigning data in a delayed way, won't reset BZERO/BSCALE in the header, # for some reason. Need to investigated. Maybe astropy.io.fits bug. Figure # out WHY were we delaying in the first place. # i = ImageHDU(data=DELAYED, header=header.copy(), name=name) # i.data = data return ImageHDU(data=data, header=header.copy(), name=name)
def cube_to_image(cube, slicepos=None): """Slice or project 3-dim cube into a 2-dim image. Parameters ---------- cube : `~astropy.io.fits.ImageHDU` 3-dim FITS cube slicepos : int or None, optional Slice position (None means to sum along the spectral axis) Returns ------- image : `~astropy.io.fits.ImageHDU` 2-dim FITS image """ header = cube.header.copy() header['NAXIS'] = 2 for key in ['NAXIS3', 'CRVAL3', 'CDELT3', 'CTYPE3', 'CRPIX3', 'CUNIT3']: if key in header: del header[key] if slicepos is None: data = cube.data.sum(0) else: data = cube.data[slicepos] return ImageHDU(data, header)
def test_extract(tmpdir): hdulist = HDUList() image = ImageHDU(np.random.random((25, 25))) hdulist.append(image) tree = { 'some_words': 'These are some words', 'nested': { 'a': 100, 'b': 42 }, 'list': [x for x in range(10)], 'image': image.data } asdf_in_fits = str(tmpdir.join('asdf.fits')) with AsdfInFits(hdulist, tree) as aif: aif.write_to(asdf_in_fits) pure_asdf = str(tmpdir.join('extract.asdf')) extract.extract_file(asdf_in_fits, pure_asdf) assert os.path.exists(pure_asdf) with asdf.open(pure_asdf) as af: assert not isinstance(af, AsdfInFits) assert_tree_match(tree, af.tree)
def setup_method(self, method): from astropy.table import Table from astropy.io.fits import HDUList, ImageHDU Registry().clear() x = [1, 2, 3] y = [2, 3, 4] u = [10, 20, 30, 40] v = [20, 40, 60, 80] self.xy = {'x': x, 'y': y} self.dict_data = {'u': u, 'v': v} self.recarray_data = np.rec.array([(0, 1), (2, 3)], dtype=[(str('a'), int), (str('b'), int)]) self.astropy_table = Table({'x': x, 'y': y}) self.bad_data = {'x': x, 'u': u} self.hdulist = HDUList([ImageHDU(x, name='PRIMARY')]) self.x = np.array(x) self.y = np.array(y) self.u = np.array(u) self.v = np.array(v)
def hdu_to_imagemodel(in_hdu): """ Workaround for initializing a `jwst.datamodels.ImageModel` from a normal FITS ImageHDU that could contain HST header keywords and unexpected WCS definition. TBD Parameters ---------- in_hdu : `astropy.io.fits.ImageHDU` Returns ------- img : `jwst.datamodels.ImageModel` """ from astropy.io.fits import ImageHDU, HDUList from astropy.coordinates import ICRS from jwst.datamodels import util import gwcs hdu = ImageHDU(data=in_hdu.data, header=in_hdu.header) new_header = strip_telescope_header(hdu.header) hdu.header = new_header # Initialize data model img = util.open(HDUList([hdu])) # Initialize GWCS tform = gwcs.wcs.utils.make_fitswcs_transform(new_header) hwcs = gwcs.WCS(forward_transform=tform, output_frame=ICRS()) #gwcs.CelestialFrame()) sh = hdu.data.shape hwcs.bounding_box = ((-0.5, sh[0] - 0.5), (-0.5, sh[1] - 0.5)) # Put gWCS in meta, where blot/drizzle expect to find it img.meta.wcs = hwcs return img
def test_append_nddata_to_root_no_name(testfile2): ad = astrodata.open(testfile2) lbefore = len(ad) ones = np.ones((10, 10)) hdu = ImageHDU(ones) nd = NDData(hdu.data) nd.meta['header'] = hdu.header ad.append(nd) assert len(ad) == (lbefore + 1)
def test_ignore_hdus_report(self, capsys): a = np.arange(100).reshape(10, 10) b = a.copy() + 1 ha = Header([('A', 1), ('B', 2), ('C', 3)]) phdu_a = PrimaryHDU(header=ha) phdu_b = PrimaryHDU(header=ha) ihdu_a = ImageHDU(data=a, name='SCI') ihdu_b = ImageHDU(data=b, name='SCI') hdulist_a = HDUList([phdu_a, ihdu_a]) hdulist_b = HDUList([phdu_b, ihdu_b]) tmp_a = self.temp('testa.fits') tmp_b = self.temp('testb.fits') hdulist_a.writeto(tmp_a) hdulist_b.writeto(tmp_b) numdiff = fitsdiff.main([tmp_a, tmp_b, "-u", "SCI"]) assert numdiff == 0 out, err = capsys.readouterr() assert "testa.fits" in out assert "testb.fits" in out
def test_append_nddata_to_root_no_name(test_path): test_filename = 'GMOS/N20160524S0119.fits' ad = astrodata.open(os.path.join(test_path, test_filename)) lbefore = len(ad) ones = np.ones((100, 100)) hdu = ImageHDU(ones) nd = NDData(hdu.data) nd.meta['header'] = hdu.header ad.append(nd) assert len(ad) == (lbefore + 1)
def test_fitsdiff_openfile(tmpdir): """Make sure that failing FITSDiff doesn't leave open files.""" path1 = str(tmpdir.join("file1.fits")) path2 = str(tmpdir.join("file2.fits")) hdulist = HDUList([PrimaryHDU(), ImageHDU(data=np.zeros(5))]) hdulist.writeto(path1) hdulist[1].data[0] = 1 hdulist.writeto(path2) diff = FITSDiff(path1, path2) assert diff.identical, diff.report()
def writeto(self, f: Any, *args: Any, **kwargs: Any) -> None: """Write image as FITS to given file object. Args: f: File object to write to. """ # create HDU list hdu_list = fits.HDUList([]) # create image HDU hdu = fits.PrimaryHDU(self.data, header=self.header) hdu_list.append(hdu) # catalog? if self.catalog is not None: hdu = table_to_hdu(self.catalog) hdu.name = "CAT" hdu_list.append(hdu) # mask? if self.mask is not None: hdu = ImageHDU(self.mask.astype(np.uint8)) hdu.name = "MASK" hdu_list.append(hdu) # errors? if self.uncertainty is not None: hdu = ImageHDU(self.uncertainty.data) hdu.name = "UNCERT" hdu_list.append(hdu) # write it hdu_list.writeto(f, *args, **kwargs)
def test_save_hdulist(dask_array_in_mem, tmp_path): # Saving an HDUList filename = tmp_path / 'test.fits' hdu1 = PrimaryHDU(data=dask_array_in_mem) hdu2 = ImageHDU(data=np.random.random((128, 128))) hdu3 = ImageHDU(data=dask_array_in_mem * 2) hdulist = fits.HDUList([hdu1, hdu2, hdu3]) assert isinstance(hdulist[0].data, da.Array) hdulist.writeto(filename) with fits.open(filename) as hdulist_new: assert isinstance(hdulist_new[0].data, np.ndarray) np.testing.assert_allclose(hdulist_new[0].data, dask_array_in_mem.compute()) assert isinstance(hdulist_new[1].data, np.ndarray) np.testing.assert_allclose(hdulist_new[1].data, hdu2.data) assert isinstance(hdulist_new[2].data, np.ndarray) np.testing.assert_allclose(hdulist_new[2].data, dask_array_in_mem.compute() * 2)
def writeto(self, f, *args, **kwargs): # create HDU list hdu_list = fits.HDUList([]) # create image HDU hdu = fits.PrimaryHDU(self.data, header=self.header) hdu_list.append(hdu) # catalog? if self.catalog is not None: hdu = table_to_hdu(self.catalog) hdu.name = 'CAT' hdu_list.append(hdu) # mask? if self.mask is not None: hdu = ImageHDU(self.mask.data.astype(np.uint8)) hdu.name = 'BPM' hdu_list.append(hdu) # write it hdu_list.writeto(f, *args, **kwargs)
def _writeImpl(self, fits): """Implementation for writing to FITS file We attempt to write the wavelength to the header (as a WCS; this results in a modest size savings), which works if the wavelength is a specified as a `WavelengthArray`; otherwise we write it as an explicit extension. Parameters ---------- fits : `astropy.io.fits.HDUList` List of FITS HDUs. This has a Primary HDU already, the header of which may be supplemented with additional keywords. Returns ------- header : `astropy.io.fits.Header` FITS headers which may contain the wavelength WCS. """ from astropy.io.fits import ImageHDU, Header haveWavelengthHeader = False try: header = self.wavelength.toFitsHeader() # For WavelengthArray haveWavelengthHeader = True except AttributeError: header = Header() if self.metadata: header.extend(astropyHeaderFromDict(self.metadata)) fits.append(ImageHDU(self.flux, header=header, name="FLUX")) maskHeader = astropyHeaderFromDict(self.flags.toFitsHeader()) maskHeader.extend(header) fits.append(ImageHDU(self.mask, header=maskHeader, name="MASK")) if not haveWavelengthHeader: fits.append( ImageHDU(self.wavelength, header=header, name="WAVELENGTH")) self.target.toFits(fits) return header
def test_file_handle(mode, dask_array_in_mem, tmp_path): filename = tmp_path / 'test.fits' hdu1 = PrimaryHDU(data=dask_array_in_mem) hdu2 = ImageHDU(data=np.arange(10)) hdulist = fits.HDUList([hdu1, hdu2]) with filename.open(mode=mode) as fp: hdulist.writeto(fp) with fits.open(filename) as hdulist_new: assert isinstance(hdulist_new[0].data, np.ndarray) np.testing.assert_allclose(hdulist_new[0].data, dask_array_in_mem.compute()) assert isinstance(hdulist_new[1].data, np.ndarray) np.testing.assert_allclose(hdulist_new[1].data, np.arange(10))
def _prepare_hdulist(hdulist, default_extension='SCI', extname_parser=None): new_list = [] highest_ver = 0 recognized = set() if len(hdulist) > 1 or (len(hdulist) == 1 and hdulist[0].data is None): # MEF file # First get HDUs for which EXTVER is defined for n, hdu in enumerate(hdulist): if extname_parser: extname_parser(hdu) ver = hdu.header.get('EXTVER') if ver not in (-1, None) and hdu.name: highest_ver = max(highest_ver, ver) elif not isinstance(hdu, PrimaryHDU): continue new_list.append(hdu) recognized.add(hdu) # Then HDUs that miss EXTVER for hdu in hdulist: if hdu in recognized: continue elif isinstance(hdu, ImageHDU): highest_ver += 1 if 'EXTNAME' not in hdu.header: hdu.header['EXTNAME'] = (default_extension, 'Added by AstroData') if hdu.header.get('EXTVER') in (-1, None): hdu.header['EXTVER'] = (highest_ver, 'Added by AstroData') new_list.append(hdu) recognized.add(hdu) else: # Uh-oh, a single image FITS file new_list.append(PrimaryHDU(header=hdulist[0].header)) image = ImageHDU(header=hdulist[0].header, data=hdulist[0].data) # Fudge due to apparent issues with assigning ImageHDU from data image._orig_bscale = hdulist[0]._orig_bscale image._orig_bzero = hdulist[0]._orig_bzero for keyw in ('SIMPLE', 'EXTEND'): if keyw in image.header: del image.header[keyw] image.header['EXTNAME'] = (default_extension, 'Added by AstroData') image.header['EXTVER'] = (1, 'Added by AstroData') new_list.append(image) return HDUList(sorted(new_list, key=fits_ext_comp_key))
def setup_class(self): self.data1 = np.array(list( zip([1, 2, 3, 4], ['a', 'b', 'c', 'd'], [2.3, 4.5, 6.7, 8.9])), dtype=[('a', int), ('b', 'U1'), ('c', float)]) self.data2 = np.array(list( zip([1.4, 2.3, 3.2, 4.7], [2.3, 4.5, 6.7, 8.9])), dtype=[('p', float), ('q', float)]) self.data3 = np.array(list(zip([1, 2, 3, 4], [2.3, 4.5, 6.7, 8.9])), dtype=[('A', int), ('B', float)]) hdu0 = PrimaryHDU() hdu1 = BinTableHDU(self.data1, name='first') hdu2 = BinTableHDU(self.data2, name='second') hdu3 = ImageHDU(np.ones((3, 3)), name='third') hdu4 = BinTableHDU(self.data3) self.hdus = HDUList([hdu0, hdu1, hdu2, hdu3, hdu4]) self.hdusb = HDUList([hdu0, hdu3, hdu2, hdu1]) self.hdus3 = HDUList([hdu0, hdu3, hdu2]) self.hdus2 = HDUList([hdu0, hdu1, hdu3]) self.hdus1 = HDUList([hdu0, hdu1])
def __init__(self, exclusion, fov, min_on_distance=0.1, angle_increment=0.1): self.exclusion = exclusion self.fov = fov self.min_on_distance = min_on_distance self.regions = None self.angle_increment = angle_increment # For a "distance to exclusion region" map. # This will allow a fast check if a given position # is a valid off region position simply by looking # up the distance of the corresponding pixel in this map. header = exclusion.header CDELT = exclusion.header['CDELT2'] distance = CDELT * exclusion_distance(exclusion.data) from astropy.io.fits import ImageHDU self.exclusion_distance = ImageHDU(distance, header)
def _flux_correlation_radius(kernel, containment=CONTAINMENT): """ Compute equivalent Tophat kernel radius for a given kernel instance and containment fraction. Parameters ---------- kernel : `astropy.convolution.Kernel2D` Name of the kernel type. containment : float Containment fraction. Returns ------- kernel : `astropy.convolution.Tophat2DKernel` Equivalent Tophat kernel. """ kernel_image = ImageHDU(kernel.array) y, x = kernel.center r_c = measure_containment_radius(kernel_image, x, y, containment) # Containment radius of Tophat kernel is given by r_c_tophat = r_0 * sqrt(C) # by setting r_c = r_c_tophat we can estimate the equivalent containment radius r_0 return r_c / np.sqrt(containment)
def test_returns_headers(self): apl = ApertureList(filename="test_aperture_list.dat", no_mask=False, pixel_scale=0.01) hdrs = apl.fov_grid() assert all([isinstance(hdr, fits.Header) for hdr in hdrs]) if PLOTS: from scopesim.optics.image_plane import ImagePlane from scopesim.optics.image_plane_utils import header_from_list_of_xy from astropy.io.fits import ImageHDU x = np.array([-3, 3]) / 3600. y = np.array([-3, 3]) / 3600. pixel_scale = 0.01 / 3600 hdr = header_from_list_of_xy(x, y, pixel_scale) implane = ImagePlane(hdr) for i in range(4): hdu = ImageHDU(data=apl[i].mask.astype(int)+1, header=apl[i].header) implane.add(hdu) plt.imshow(implane.data, origin="lower") plt.show()
def dataset_fits(): hdu = ImageHDU(np.random.random((256, 256))) return hdu
def fits_header(self, msghdr, message): try: lastimg = sorted(glob(datapath + '/' + utdate + '_*.fits'))[-1][-9:-5] seq = int(lastimg) + 1 self.seqno = '%04d' % seq seqnum = self.seqno datafile = datapath + '/' + datetime.utcnow().strftime( '%Y%m%d') + '_' + str(self.seqno) + '.fits' except IndexError: lastimg = datetime.utcnow().strftime('%Y%m%d') + '_0001.fits' datafile = datapath + '/' + lastimg seqnum = '0001' self.environmental() self.sun_moon() imgdata = ImageHDU.fromstring(base64.b64decode(message)) prihdr = imgdata.header print('msghdr: ' + str(msghdr)) unixtime = int(msghdr['timestamp'][0:-3]) message_tstamp = datetime.fromtimestamp(unixtime).strftime( '%Y-%m-%d %H:%M:%S') print(message_tstamp) try: prihdr['DATE-OBS'] except KeyError: pass try: self.testif = prihdr['PIXSIZE1'] # Delete unwanted INDI keywords from header del prihdr['TELESCOP'] del prihdr['OBSERVER'] del prihdr['OBJECT'] del prihdr['FRAME'] del prihdr['SCALE'] del prihdr['PIXSIZE1'] del prihdr['PIXSIZE2'] del prihdr['XBINNING'] del prihdr['YBINNING'] del prihdr['INSTRUME'] del prihdr['COMMENT'] # Append desired keywords to file header prihdr.append(('LST-OBS ', self.sun_moon()[0], 'Local Sidereal Time of exposure start'), end=True) prihdr.append(('CREATOR ', 'LOASC_INDI', 'File creator'), end=True) prihdr.append(('CAMERA ', 'SX Superstar 1.10', 'Manufacturer driver version'), end=True) prihdr.append(('MODEL ', 25, 'Camera model number'), end=True) prihdr.append(('PIXSIZE ', 4.65, 'Pixel Size in Microns'), end=True) prihdr.append(('CCDSUM ', '1 1', 'On Chip binned summation'), end=True) prihdr.append(('IMGTYPE ', 'OBJECT', 'Image Type'), end=True) prihdr.append(('OBJECT ', 'Sky Above DCT', 'Object Name'), end=True) prihdr.append(('OBSERVAT', 'DCT Telescope', 'Observatory'), end=True) prihdr.append( ('OBSLOCAT', 'Happy Jack, AZ', 'Observatory Location'), end=True) prihdr.append( ('OBSLAT ', 34.89708, 'Observatory Latitude (degrees)'), end=True) prihdr.append( ('OBSLONG ', -111.5367, 'Observatory Longitude (degrees)'), end=True) prihdr.append(('OBSALT ', 2202., 'Observatory Altitude (meters)'), end=True) prihdr.append(('INSTRUME', 'DCT_ALLSKY', 'Instrument'), end=True) prihdr.append(('SEQNUM ', int(seqnum), 'File Sequence Number'), end=True) prihdr.append(('TEMPAMB ', float( self.environmental()[0]), 'Mean Ambient Temperature in deg C'), end=True) prihdr.append(('HUMIDITY', int( self.environmental()[1]), 'Relative Humidity (percent)'), end=True) prihdr.append(('SUN_ALT ', float( self.sun_moon()[1]), 'Altitude of Sun (degrees)'), end=True) prihdr.append(('MOON_ALT', float( self.sun_moon()[2]), 'Altitude of Moon (degrees)'), end=True) prihdr.append(('MOONILLU', float( self.sun_moon()[3]), 'Moon illumination (percent)'), end=True) print('Write the data to ' + str(datafile)) fits.writeto(datafile, imgdata.data, imgdata.header, overwrite=True) except KeyError as e: print('error: ' + str(e)) print('This header has already been processed')
def basic_pmh(): hdr = ImageHDU(data=np.zeros((10, 10))).header return PoorMansHeader(hdr)
def test_tpf_from_images(): """Basic tests of tpf.from_fits_images()""" from astropy.io.fits import ImageHDU images = [ImageHDU(data=np.ones((5, 5))) for i in range(5)] tpf = KeplerTargetPixelFile.from_fits_images(images, size=(3, 3))
def test_update_with_other_poormansheader(self): pmh1 = PoorMansHeader(ImageHDU(data=np.zeros((10, 10))).header) pmh2 = PoorMansHeader(ImageHDU(data=np.zeros((20, 15))).header) pmh1.update(pmh2) assert pmh1["NAXIS1"] == 15