首页 > 解决方案 > 无法使用 astropy.io 的拟合打印整个数据集

问题描述

我有一个大文件(21.4 MB)。我想将其内容打印到文本文件中,但只能访问其中的一部分。我正在寻求将整个文件转换为文本格式的帮助。

> from astropy.io import fits
> hdulist = fits.open('N20190326G0041i.fits')

文件上的信息。请注意,所有内容都在主 HDU 中。

> hdulist.info()  
Filename: N20190326G0041i.fits  
No.    Name      Ver    Type      Cards   Dimensions   Format  
  0  PRIMARY       1 PrimaryHDU     183   (190685, 28)   float32

我可以访问完整的标题,但它非常长。我把它放在这篇文章的末尾。

> hdu = hdulist[0]  
> hdu.header

但是,我只使用 hdu.data 获取部分数据

> hdu.data
array([[ 4.0630740e+02,  4.0631021e+02,  4.0631290e+02, ...,
         1.0478779e+03,  1.0478831e+03,  1.0478882e+03],
       [ 2.7955999e+01,  3.1493999e+01,  1.2378000e+01, ...,
        -4.3614998e+00, -1.8785000e+00, -8.8672000e-01],
       [ 2.8534999e+00,  2.8862000e+00,  2.9282999e+00, ...,
        -6.1020999e+00, -5.2989998e+00, -5.1680999e+00],
       ...,
       [ 1.7951000e+04,  2.9099000e+04,  3.5257000e+03, ...,
         1.0594000e+03,  7.9347998e+02,  1.6349001e+02],
       [ 3.1568999e+03,  3.1631001e+03,  3.2426001e+03, ...,
         3.2828000e+02,  3.2062000e+02,  3.2189001e+02],
       [ 3.3338000e+03,  3.3806001e+03,  3.4557000e+03, ...,
         2.1803000e+02,  2.2574001e+02,  2.3003999e+02]], dtype=float32)

我通常将适合文件打印到文本文件的操作是......

> table = hdulist[0].data
> print(table, file = open('test.txt','a'))

这“有效”,并输出与 hdu.data 在屏幕上打印的数据相同的摘录。

> [[ 4.0630740e+02  4.0631021e+02  4.0631290e+02 ...  1.0478779e+03
   1.0478831e+03  1.0478882e+03]
 [ 2.7955999e+01  3.1493999e+01  1.2378000e+01 ... -4.3614998e+00
  -1.8785000e+00 -8.8672000e-01]
 [ 2.8534999e+00  2.8862000e+00  2.9282999e+00 ... -6.1020999e+00
  -5.2989998e+00 -5.1680999e+00]
 ...
 [ 1.7951000e+04  2.9099000e+04  3.5257000e+03 ...  1.0594000e+03
   7.9347998e+02  1.6349001e+02]
 [ 3.1568999e+03  3.1631001e+03  3.2426001e+03 ...  3.2828000e+02
   3.2062000e+02  3.2189001e+02]
 [ 3.3338000e+03  3.3806001e+03  3.4557000e+03 ...  2.1803000e+02
   2.2574001e+02  2.3003999e+02]]

此外,我使用 memmap = True 重复了上述所有操作,但得到了相同的结果。

> from astropy.io import fits
> hdulist = fits.open('N20190326G0041i.fits', memmap = True)

我也尝试了便利功能,但它产生了与 hdu.data 完全相同的摘录。

> tbdata = fits.getdata('N20190326G0041i.fits')
> print(tbdata,file=open('test.txt','a'))

我也尝试了 astropy.table 包,但也无法让它工作。

> from astropy.table import Table
> t = Table.read(hdulist[0], format = 'fits')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/anaconda3/lib/python3.7/site-packages/astropy/table/connect.py", line 52, in __call__
    out = registry.read(cls, *args, **kwargs)
  File "/anaconda3/lib/python3.7/site-packages/astropy/io/registry.py", line 523, in read
    data = reader(*args, **kwargs)
  File "/anaconda3/lib/python3.7/site-packages/astropy/io/fits/connect.py", line 195, in read_table_fits
    memmap=memmap)
  File "/anaconda3/lib/python3.7/site-packages/astropy/io/fits/hdu/hdulist.py", line 151, in fitsopen
    lazy_load_hdus, **kwargs)
  File "/anaconda3/lib/python3.7/site-packages/astropy/io/fits/hdu/hdulist.py", line 390, in fromfile
    lazy_load_hdus=lazy_load_hdus, **kwargs)
  File "/anaconda3/lib/python3.7/site-packages/astropy/io/fits/hdu/hdulist.py", line 1039, in _readfrom
    fileobj = _File(fileobj, mode=mode, memmap=memmap, cache=cache)
  File "/anaconda3/lib/python3.7/site-packages/astropy/utils/decorators.py", line 521, in wrapper
    return function(*args, **kwargs)
  File "/anaconda3/lib/python3.7/site-packages/astropy/io/fits/file.py", line 180, in __init__
    self._open_filelike(fileobj, mode, overwrite)
  File "/anaconda3/lib/python3.7/site-packages/astropy/io/fits/file.py", line 533, in _open_filelike
    "method, required for mode '{}'.".format(self.mode))
OSError: File-like object does not have a 'write' method, required for mode 'ostream'.

但是,如果我使用

> t=Table.read(hdu.data, format='fits')

然后我得到一个不同的错误

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/anaconda3/lib/python3.7/site-packages/astropy/table/connect.py", line 52, in __call__
    out = registry.read(cls, *args, **kwargs)
  File "/anaconda3/lib/python3.7/site-packages/astropy/io/registry.py", line 523, in read
    data = reader(*args, **kwargs)
  File "/anaconda3/lib/python3.7/site-packages/astropy/io/fits/connect.py", line 195, in read_table_fits
    memmap=memmap)
  File "/anaconda3/lib/python3.7/site-packages/astropy/io/fits/hdu/hdulist.py", line 147, in fitsopen
    if not name:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

我还在 PyRAF 中尝试过 tprint 和 tdump,它只是给出了错误“警告:”,没有其他有用的信息。我还尝试使用 PyRaf 中的 wspectext 函数将 fit 文件写入文本,但它无法这样做。

但是,我希望能够只使用 astropy 中的 fit 包将数据输出到文本文件。我已经用来自各种望远镜管道的其他拟合文件无数次地这样做了,但这次它不起作用。任何帮助深表感谢。

该文件的标题如下。我想知道,如果我能够访问信息的唯一方法是通过 IDL,那么标题是用 IDL 编写的?这对我来说似乎不太可能。如果可能的话,我真的宁愿避免使用 IDL。我们在大学拥有站点许可证,但在大流行期间我们不允许在校园内使用,而且我们的 VPN 功能也很缺乏。

> hdu.header  
SIMPLE  =                    T / Written by IDL:    
BITPIX  =                  -32 / Real*4 (complex, stored as float)              
NAXIS   =                    2 / Number of axes                                 
NAXIS1  =               190685 / Number of pixel columns                        
NAXIS2  =                   28 / Number of pixel rows                           
INHERIT =                    F / No need to inherit global keywords             
BZERO   =                   0. / Data is Unsigned Integer                       
BSCALE  =                   1. / Scale factor                                                  
IMAGESWV= 'CFHT DetCom v3.60.18 (Apr 20 2017)' / Image creation software version
OBSTYPE = 'OBJECT  '           / Observation / Exposure type                    
EXPTYPE = 'OBJECT  '           / See OBSTYPE                                    
EXPTIME =               2561.0 / Integration time (seconds)                     
DARKTIME=               2561.0 / Dark current time (seconds)                           
DETECTOR= 'OLAPA   '           / Science Detector                               
CCD     = 'Unknown '           / Science Detector (use DETECTOR)                
IMAGEID =                    0 / CCD chip number                                
CHIPID  =                    0 / Use IMAGEID instead                            
DETSIZE = '[1:2048,1:4608]'    / Total data pixels in full mosaic               
RASTER  = 'FULL    '           / Active raster description                      
CCDSUM  = '1 1     '           / Binning factors                                
CCDBIN1 =                    1 / Binning factor along first axis                
CCDBIN2 =                    1 / Binning factor along second axis               
PIXSIZE =                 13.5 / Pixel size for both axes (microns)             
AMPLIST = 'a,b     '           / List of amplifiers for this image              
CCDSIZE = '[1:2048,1:4608]'    / Detector imaging area size                     
CCDSEC  = '[21:2068,1:4608]'   / Read out area of the detector (unbinned)       
TRIMSEC = '[21:2068,4:4605]'   / Useful imaging area of the detector            
BSECA   = '[1:20,1:4608]'      / Overscan/prescan (bias) area from Amp A        
BSECB   = '[2069:2088,1:4608]' / Overscan/prescan (bias) area from Amp B        
CSECA   = '[21:1044,1:4608]'   / Section in full CCD for DSECA                  
CSECB   = '[1045:2068,1:4608]' / Section in full CCD for DSECB                  
DSECA   = '[21:1044,1:4608]'   / Imaging area from Amp A                        
DSECB   = '[1045:2068,1:4608]' / Imaging area from Amp B                        
TSECA   = '[21:1044,4:4605]'   / Trim section for Amp A                         
TSECB   = '[1045:2068,4:4605]' / Trim section for Amp B                         
MAXLIN  =                65535 / Maximum linearity value (ADU)                  
SATURATE=                65535 / Saturation value (ADU)                         
GAINA   =                 1.10 / Amp A gain (electrons/ADU)                     
GAINB   =                 1.20 / Amp B gain (electrons/ADU)                     
RDNOISEA=                 2.90 / Amp A read noise (electrons)                   
RDNOISEB=                 2.90 / Amp B read noise (electrons)                   
DARKCUR =                    0 / Dark current (e-/pixel/hour)                   
RDTIME  =                30.00 / Read out time (sec)                            
CONSWV  = 'olD=137,DCU=49'     / Controller software DSPID and SERNO versions   
DETSTAT = 'ok      '           / Detector temp range (-105..-90)                
DETTEM  =               -100.2 / Detector temp deg C = 745.502 + -0.278 * 3042  
INSTRUME= 'GRACES  '           / Instrument Name                                
ECAMFOC =                -3.61 / ESPaDOnS camera focus position (mm)            
EHARTPOS= 'OUT     '           / ESPaDOnS hartmann position FULL/DOWN/UP/OUT    
EEMSHUT = 'CLOSE   '           / ESPaDOnS exposure meter shutter OPEN/CLOSED    
EEMSTATE= 'OFF     '           / ESPaDOnS exposure meter state ON/OFF           
EEMCNTS =                -9999 / ESPaDOnS exposure meter count average          
ETSP1BEG=                17.38 / ESPaDOnS down mirror temp at start (deg C)     
ETSP2BEG=                17.61 / ESPaDOnS camera temp at start (deg C)          
ETSP3BEG=                17.55 / ESPaDOnS up mirror temp at start (deg C)       
ETSP4BEG=                17.31 / ESPaDOnS hygrometer temp at start (deg C)      
EPRSPBEG=                -3.35 / ESPaDOnS relative pressure at start (mb)       
ERHSPBEG=                21.11 / ESPaDOnS relative humidity at start (%)        
ETSP1END=                17.38 / ESPaDOnS down mirror temp at end (deg C)       
ETSP2END=                17.59 / ESPaDOnS camera temp at end (deg C)            
ETSP3END=                17.55 / ESPaDOnS up mirror temp at end (deg C)         
ETSP4END=                17.31 / ESPaDOnS hygrometer temp at end (deg C)        
EPRSPEND=                -3.29 / ESPaDOnS relative pressure at end (mb)         
EREADSPD= 'Slow: 2.90e noise, 1.15e/ADU, 30s' / ESPaDOnS det read out xslow/slow
GSLIPOS = 'TWOSLICE'           / GRACES slicer bench position (# and mm)        
GSLICER = 'TWOSLICE'           / GRACES slicer position (# and deg)             
GDEKKER = 'TWOSLICE'           / GRACES dekker position (# and mm)              
GPMIRROR= 'GEMINI  '           / GRACES pickoff mirror position (# and mm)      
GFIBMODE= 'GRACES  '           / GRACES fiber position (ESPADONS or GRACES)     
O_BSCALE=              1.00000 / Original BSCALE Value                          
RAWIQ   = '85-percentile'      /Raw Image Quality                               
RAWCC   = '50-percentile'      /Raw Cloud Cover                                 
RAWWV   = '20-percentile'      /Raw Water Vapour/Transparency                   
RAWBG   = '50-percentile'      /Raw Background                                  
TELESCOP= 'Gemini-North'       /Gemini-North                                    
EPOCH   =              2000.00 /Epoch for Target coordinates                    
CRPA    =        80.7411581783 /Current Cass Rotator Position Angle             
AIRMASS = '1.271   '           /Mean airmass for the observation                
AMSTART = '1.365   '           /Airmass at start of exposure                    
AMEND   = '1.191   '           /Airmass at end of exposure                      
HA      = '-03:02:41.87'       /Hour Angle Sexagesimal                          
HAD     = '-3.0449640'         /Hour Angle Decimal                              
OBSCLASS= 'science '           /Observe class                                   
INSTMODE= 'Spectroscopy, star+sky' /Observing mode                                                         
RAWPIREQ= 'YES     '           /PI Requirements Met                             
RAWGEMQA= 'USABLE  '           /Gemini Quality Assessment                       
COMMENT ----------------------------------------------------                    
COMMENT | Processed by the CFHT OPERA Open Source Pipeline |                    
COMMENT ----------------------------------------------------                    
COMMENT opera-1.0.1228 build date Fri May 19 18:53:30 HST 2017                  
COMMENT Processing Date                                                         
COMMENT ---------------                                                         
COMMENT Mon May  4 14:50:27 HST 2020                                            
COMMENT ------------------------------------------------------------------------
COMMENT 20                                                                      
SNR22   = '0.50798 / 0.61051'  / snr per spectral / ccd bin                     
SNR23   = '0.84309 / 1.0133'   / snr per spectral / ccd bin                     
SNR24   = '1.2171 / 1.4627'    / snr per spectral / ccd bin                     
SNR25   = '1.9608 / 2.3567'    / snr per spectral / ccd bin                     
SNR26   = '2.1154 / 2.5425'    / snr per spectral / ccd bin                     
SNR27   = '2.1107 / 2.5368'    / snr per spectral / ccd bin                     
SNR28   = '2.2236 / 2.6725'    / snr per spectral / ccd bin                     
SNR29   = '2.1241 / 2.5528'    / snr per spectral / ccd bin                     
SNR30   = '2.2457 / 2.6991'    / snr per spectral / ccd bin                     
SNR31   = '1.9948 / 2.3975'    / snr per spectral / ccd bin                     
SNR32   = '1.6974 / 2.04'      / snr per spectral / ccd bin                     
SNR33   = '1.4978 / 1.8001'    / snr per spectral / ccd bin                     
SNR34   = '1.2949 / 1.5562'    / snr per spectral / ccd bin                     
SNR35   = '1.3562 / 1.63'      / snr per spectral / ccd bin                     
SNR36   = '1.0198 / 1.2257'    / snr per spectral / ccd bin                     
SNR37   = '1.5021 / 1.8053'    / snr per spectral / ccd bin                     
SNR38   = '1.01 / 1.2139'      / snr per spectral / ccd bin                     
SNR39   = '0.71061 / 0.85405'  / snr per spectral / ccd bin                     
SNR40   = '0.59577 / 0.71603'  / snr per spectral / ccd bin                     
SNR41   = '0.62022 / 0.74541'  / snr per spectral / ccd bin                     
SNR42   = '0.57458 / 0.69056'  / snr per spectral / ccd bin                     
SNR43   = '0.52749 / 0.63397'  / snr per spectral / ccd bin                     
SNR44   = '0.49149 / 0.5907'   / snr per spectral / ccd bin                     
SNR45   = '0.48021 / 0.57714'  / snr per spectral / ccd bin                     
SNR46   = '0.50494 / 0.60687'  / snr per spectral / ccd bin                     
SNR47   = '0.52551 / 0.63159'  / snr per spectral / ccd bin                     
SNR48   = '0.5106 / 0.61367'   / snr per spectral / ccd bin                     
SNR49   = '0.42632 / 0.51237'  / snr per spectral / ccd bin                     
SNR50   = '0.42451 / 0.5102'   / snr per spectral / ccd bin                     
SNR51   = '0.42025 / 0.50508'  / snr per spectral / ccd bin                     
SNR52   = '0.41137 / 0.49441'  / snr per spectral / ccd bin                     
SNR53   = '0.41708 / 0.50127'  / snr per spectral / ccd bin                     
SNR54   = '0.41904 / 0.50362'  / snr per spectral / ccd bin                     
SNR55   = '0.4284 / 0.51487'   / snr per spectral / ccd bin                     
HRV     =              -8.9311 / Heliocentric RV correction (km/s)              
HRVLUNAR=            0.0125599 / lunar component of HRV correction (km/s)       
HRVORBIT=             -9.19911 / orbital component of HRV correction (km/s)     
HRVDIURN=             0.255451 / diurnal component of HRV correction (km/s)     
HJDUTC  =        2458568.79603 / Heliocentric Julian date (UTC) mid-exposure    
HJDTT   =       2458568.796831 / Heliocentric Julian date (TT) mid-exposure     
TELLRV  =                   0. / telluric RV correction (km/s)                  
TELLERR =                   0. / telluric RV correction error (km/s)            
REDUCTIO= 'Intensity'          / Type of reduction                              
NORMAL  = '2       '           / Normalized and Un-normalized Data              
COMMENT File contains automatic wavelength correction and uncorrected data.     
COL1    = 'Wavelength'         / Normalized                                     
COL2    = 'Star    '           / Normalized                                     
COL3    = 'Sky     '           / Normalized                                     
COL4    = 'Star+sky'           / Normalized                                     
COL5    = 'ErrorBarStar'       / Normalized                                     
COL6    = 'ErrorBarSky'        / Normalized                                     
COL7    = 'ErrorBarStar+Sky'   / Normalized                                     
COL8    = 'Wavelength'         / UnNormalized                                   
COL9    = 'Star    '           / UnNormalized                                   
COL10   = 'Sky     '           / UnNormalized                                   
COL11   = 'Star+sky'           / UnNormalized                                   
COL12   = 'ErrorBarStar'       / UnNormalized                                   
COL13   = 'ErrorBarSky'        / UnNormalized                                   
COL14   = 'ErrorBarStar+Sky'   / UnNormalized                                   
COL15   = 'Wavelength'         / Normalized, no autowave correction             
COL16   = 'Star    '           / Normalized, no autowave correction             
COL17   = 'Sky     '           / Normalized, no autowave correction             
COL18   = 'Star+sky'           / Normalized, no autowave correction             
COL19   = 'ErrorBarStar'       / Normalized, no autowave correction             
COL20   = 'ErrorBarSky'        / Normalized, no autowave correction             
COL21   = 'ErrorBarStar+Sky'   / Normalized, no autowave correction             
COL22   = 'Wavelength'         / UnNormalized, no autowave correction           
COL23   = 'Star    '           / UnNormalized, no autowave correction           
COL24   = 'Sky     '           / UnNormalized, no autowave correction           
COL25   = 'Star+sky'           / UnNormalized, no autowave correction           
COL26   = 'ErrorBarStar'       / UnNormalized, no autowave correction           
COL27   = 'ErrorBarSky'        / UnNormalized, no autowave correction           
COL28   = 'ErrorBarStar+Sky'   / UnNormalized, no autowave correction 

标签: python-3.xastropyfits

解决方案


由于它们似乎对我有帮助,因此我将上面的评论重写为答案:

FITS 文件(例如hdulist[0].data)中的数据作为 Numpy 数组返回。Numpy 是许多科学 Python 包的核心库,用于处理类似二进制数组的数据。需要注意这一点,因为它不是特定于 Astropy 或 FITS,任何关于如何处理来自 FITS 文件的数据(不是特定于天文学)的问题实际上都是关于 Numpy 的问题。Numpy为此目的有一个内置函数np.savetxt 。例如

>>> import numpy as np
>>> np.savetxt(hdulist[0].data)

np.savetxt您可以在 API 文档中阅读有关如何格式化数据的许多选项。

(附带问题:为什么要将其保存为纯文本文件?它似乎是一个相当大的数组——您是否想将其作为文本文件处理,而您不能以二进制形式处理它?)

其次,是您尝试使用Table.read失败的几个原因。一方面,您的数据似乎不是表格的,因此这不适合这种形式的 CCD 数据。其次Table.read是一个更抽象的函数,它只接受文件的名称(或“类文件对象,意味着与 Python 内置的 open 函数返回的文件对象具有相同接口的东西)。它会自动猜测如何读取通过识别一些受支持的文件格式来获取表格数据。您传递给它的对象它不知道如何处理,因此会出现看似模糊的错误。

例如Table.read这样使用:

>>> Table.read('path/to/fits/file/containing/table.fits')

在后台,这是使用astropy.io.fits包来解析 FITS 文件并提取表格内容。该界面旨在从用户那里抽象出这些细节。在您的第一次尝试中,您向它传递了一个实际的 HDU 对象 ( hdulist[0])。由于您指定format='fits'它尝试在此对象上使用其 FITS 阅读器,但它不知道如何处理它,因为它不是文件名或类似文件的对象。您第二次尝试的类似问题。

最后因为这没有像你希望的那样工作:

>>> tbdata = fits.getdata('N20190326G0041i.fits')
>>> print(tbdata,file=open('test.txt','a'))

这与print(tbdata). 当您将 Numpy 数组打印到屏幕上时,它具有标准的打印表示,对于大型数组通常会截断数据。使用file=不会做任何事情:它只是输出与将数组打印到终端相同的东西,但它将文本输出到文件而不是屏幕。


推荐阅读