我正在尝试从初始template.fits
创建一个新的拟合文件此template.fits包含3915行的语音1表,而我的新文件必须包含超过50000行。
代码的一部分如下:
hdulist = fits.open('/Users/Martina/Desktop/Ubuntu_Condivisa/Post_Doc_IAPS/ASTRI/ASTRI_scienceTools/Astrisim_MC/template.fits')
hdu0=hdulist[0]
hdu0.writeto(out_pile+'.fits', clobber=True)
hdu1=hdulist[1]
hdu1.header['NAXIS2'] = na
hdu1.header['ONTIME'] = tsec
hdu1.header['LIVETIME'] = tsec
hdu1.writeto(out_pile+'.fits', clobber=True)
hdu1_data=hdu1.data
for j in range(na-1):
hdu1_data[j+1][1]=j+1
hdu1_data[j+1][3]=t[j]+0.
hdu1_data[j+1][7]=ra[j]
hdu1_data[j+1][8]=dec[j]
hdu1_data[j+1][21]=enetot[j]
hdu1.writeto(out_pile+'.fits', clobber=True)
当我尝试填充新表(代码的最后一部分)时,错误如下:
Traceback (most recent call last): File "C:\Users\Martina\AppData\Local\Programs\Python\Python36\lib\site-packages\astropy\utils\decorators.py", line 734, in __get__ return obj.__dict__[self._key] KeyError: 'data' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "Astrisim_MC_4.py", line 340, in hdu1_data=hdu1.data File "C:\Users\Martina\AppData\Local\Programs\Python\Python36\lib\site-packages\astropy\utils\decorators.py", line 736, in __get__ val = self.fget(obj) File "C:\Users\Martina\AppData\Local\Programs\Python\Python36\lib\site-packages\astropy\io\fits\hdu\table.py", line 404, in data data = self._get_tbdata() File "C:\Users\Martina\AppData\Local\Programs\Python\Python36\lib\site-packages\astropy\io\fits\hdu\table.py", line 171, in _get_tbdata self._data_offset) File "C:\Users\Martina\AppData\Local\Programs\Python\Python36\lib\site-packages\astropy\io\fits\hdu\base.py", line 478, in _get_raw_data return self._file.readarray(offset=offset, dtype=code, shape=shape) File "C:\Users\Martina\AppData\Local\Programs\Python\Python36\lib\site-packages\astropy\io\fits\file.py", line 279, in readarray buffer=self._mmap) TypeError: buffer is too small for requested array
我尝试改变行数,代码正常工作,最多可达3969行。
我该如何解决这个问题?
非常感谢您提前,
喝彩!
的Martina
答案 0 :(得分:0)
您最初的问题在哪里执行此操作:
hdu1.header['NAXIS2'] = na
认为你可以做的很自然,但实际上你不应该这样做。通常,在使用astropy.io.fits
时,几乎不应该手动弄乱FITS标头中描述数据本身结构的关键字。这部分源于FITS本身的设计 - 它将这些结构关键字与元数据关键字混合在一起 - 部分是astropy.io.fits
的设计问题,它允许您在以下操作这些关键字所有,或者它没有更紧密地将数据绑定到它们。我在这里更详细地写了这个问题:https://github.com/astropy/astropy/issues/3836但是从来没有在文档中添加更多解释。
基本上你可以考虑的方法是,当打开FITS文件时,首先读取它的头并将其解析为包含所有头关键字的Header
对象。还进行了一些簿记以跟踪标题后文件中的数据量。然后,当您访问HDU的数据时,标题关键字用于确定数据的类型和形状。所以做一些像
hdu1.header['NAXIS2'] = na
hdu1_data = hdu1.data
这不是增长文件中的数据。相反,它只是混淆它认为文件中有更多的数据行然后实际存在,因此错误“缓冲区对于请求的数组来说太小”。在这种情况下,它所指的“缓冲区”是文件中的其余数据,并且您要求它读取的文件比文件中的数据长。
它允许你完全打破这个事实是 Astropy IMO中的 bug 。首次打开文件时,它应该在后台保存所有正确的结构关键字,这样即使用户不小心修改了这些关键字(或者用户应该是completely prevented from modifying these keywords directly),仍然可以正确加载数据。 / p>
这有很长的路要说明你出错的地方,但也许这有助于更好地了解图书馆的运作方式。
至于你的实际问题,我认为@Evert的建议是好的,使用更高级别更容易使用astropy.table
来创建一个你需要的大小的新表,然后复制现有的表进入新的。您可以直接打开FITS表作为Table
对象以及Table.read
。我想你也可以复制FITS元数据,但我不确定最好的方法。
与您的主要问题无关的另一个小评论 - 在使用数组时,您不必(实际上不应该)使用for
循环来执行可向量化的操作。
例如,因为这只是循环遍历数组索引:
表示范围内的j(na-1): hdu1_data [J + 1] [1] = J + 1 hdu1_data [J + 1] [3] = T [j]的0。 hdu1_data [J + 1] [7] = RA [j]的 hdu1_data [J + 1] [8] =癸[j]的 hdu1_data [J + 1] [21] = enetot [j]的
你可以写下这样的操作:
hdu1_data[:][1] = np.arange(na)
hdu1_data[:][3] = t + 0.
hdu1_data[:][7] = ra
依此类推(我不确定你为什么要做j+1
,因为这是跳过第一行,但这一点仍然存在)。这当然假设正在更新的数组(在这种情况下为hdu1_data
)已经有na
行。但这就是为什么你需要首先增长或连接你的数组,如果它不是那么大。