我在使用CFITSIO库从FITS表的条目中读取可变长度数组时遇到了困难(由于我正在开发的另一个软件,我不得不使用它们)。
现在,我尝试读取的FITS表如下所示:

如您所见,最后三列的单元格中没有标量值,而是包含可变长度的数组。
CFITSIO对于这种特殊情况,文档并不是很有帮助:大多数基本例程都被认为是通过直接读取常规列来生成数组的(在它们的单元格中包含标量,请参阅https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node46.html)。fits_read_col将不适用于此数据结构。
现在,建议使用fits_read_descript读取变量列时的例程。问题是此函数返回低级信息,特别是存储数组的堆中的起始偏移量(请参阅https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node82.html)。因此,即使我获得了包含多个数组的单元格的低级信息,也不清楚如何使用它来获取数值!
CFITSIO迭代器是有一定帮助的,而且没有这样复杂的数据结构的例子。
以前有没有人这样做过?有没有人可以使用CFITSIO读取可变长度数组?这将是非常有帮助的。
可以找到我为其拍摄屏幕截图的FITS文件这里。
这里是一个试探性的代码片段,打开文件并检查列和行,应用建议的fits_read_descript函数用于可变长度列。我不知道如何继续下去,因为我不知道如何利用返回的参数来获取表中的实际数值。
#include "fitsio.h"
#include
int main(){
fitsfile *fp = 0; // pointer to fitsfile type provided in CFITSIO library
int status = 0; // variable passed down to different CFITSIO functions
// open the fits file, go to the Header Data Unit 1 containing the table
// with variable-length arrays
fits_open_file(&fp, "rmf_obs5029747.fits[1]", READONLY, &status);
// read HDU type
int hdutype;
fits_get_hdu_type(fp, &hdutype, &status);
std::cout << "found type " << hdutype << " HDU type." << "\n";
// read number of rows and columns
long nTableRows;
int nTableCols;
fits_get_num_rows(fp, &nTableRows, &status);
fits_get_num_cols(fp, &nTableCols, &status);
std::cout << "the table has " << nTableRows << " rows" << "\n";
std::cout << "the table has " << nTableCols << " columns" << "\n";
// loop through the columns and consider only those with a negative typecode
// indicating that they contain a variable-length array
// https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node29.html
int typecode;
long repeat;
long width;
long offset;
for (int colnum = 0; colnum < nTableCols; ++colnum) {
fits_get_coltype(fp, colnum+1, &typecode, &repeat, &width, &status);
if (typecode < 1) {
std::cout << "->column " << colnum << " contains a variable-length array" << "\n";
std::cout << "->examining its rows..." << "\n";
// loop through the rows
for (int rownum = 0; rownum < nTableRows; ++rownum)
fits_read_descript(fp, colnum, rownum, &repeat, &offset, &status);
}
}
}发布于 2021-02-25 00:37:33
感谢@lorenz和@CraigM的建议。
我实际上找到了解决方案,并在根类与CFITSIO库,所以如果其他人有同样的问题,可以复制解决方案或直接使用ROOT。我介绍的用于读取根目录中的可变长度单元格的函数是:TFITSHDU::GetTabVarLengthVectorCell()我一年前就这样做了,但忘了在这里发布答案:)
您可以在解决方案中找到代码这里。
我实际上使用了您提出的@CraigM方案,即组合fits_read_descript和fits_read_col。
发布于 2020-03-04 00:07:15
这只是一个想法,也许你可能已经看到过这个/想过这个,但如果你还没有的话,只是以防万一。
配合_获取_列_显示_width() =了解可用字符数
如果合适_阅读_descript()给出了数组中元素的数量和起始偏移量,是否可以将总字节数读入一个字符串,并使用分隔符",“对其进行标记化,然后获得这些数字?
发布于 2021-02-23 23:44:08
在FITS中有很多奇怪的特殊情况,你已经找到了其中的一个。
我已经成功地使用了这一点。
fits_read_descript{s}{ll}()来确定有问题的行的重复和偏移量。您还可以使用descripts变量一次确定多个行的重复和偏移量。fits_read_col{null}()若要读取数据,请一次读取一行。元素的数量是您在步骤1中找到的重复计数,如果需要子集,则为更小的数量像往常一样设置列、行号和第一个元素。使用variant运行得很好。重要的是,您只能以这种方式一次一行地读取可变长度数据,但它省去了执行所有字节解码和堆索引的麻烦。即使您使用fits_read_descripts()variant要在一个函数调用中确定多个重复计数,仍必须调用fits_阅读_对您感兴趣的每个表行执行一次col()。
读取可变长度字符串或位数组本身就是一种有趣的消遣,但您看起来只是想读取X射线响应矩阵数据(浮点),所以这应该可以回答您的问题。
https://stackoverflow.com/questions/60509665
复制相似问题