【问题标题】:Reading variable-length arrays from a FITS table using the CFITSIO library使用 CFITSIO 库从 FITS 表中读取可变长度数组
【发布时间】:2020-03-03 14:40:48
【问题描述】:

我很难使用 CFITSIO 库从 FITS 表的条目中读取可变长度数组(由于我正在开发另一个软件,我必须使用它们)。

现在,我尝试读取的 FITS 表如下所示:

如您所见,最后三列的单元格中没有标量值,而是包含可变长度数组。

CFITSIO 文档对于这种特殊情况不是很有帮助:大多数基本例程被认为是通过直接读取常规列来生成数组(在其单元格中带有标量,请参阅https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node46.html 的第 2 节)。 fits_read_col 不适用于此数据结构。

现在建议在读取变量列时使用fits_read_descript 例程。问题是该函数返回低级信息,特别是存储数组的堆中的起始偏移量(参见https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node82.html 的第 7 节)。 因此,即使我获得了包含多个数组的单元格的低级信息,也不清楚如何使用它来获取数值!

CFITSIO Iterators有点用处,没有这么复杂数据结构的例子。

以前有人做过吗?有没有人能够使用CFITSIO 生成一个 sn-p 来读取可变长度数组?这将非常有帮助。

我截取的FITS文件可以在here找到。

这里试探性的 sn-p 打开文件并检查列和行,将建议的 fits_read_descript 函数应用于可变长度列。我不知道如何进一步进行,因为我不知道如何利用返回的参数来获取表中的实际数值。

#include "fitsio.h"
#include <iostream>

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);
        }
    }
}

【问题讨论】:

    标签: c++ c fits


    【解决方案1】:

    只是一个想法,可能您可能已经看到/想到了这个,但以防万一。

    fits_get_col_display_width() = 了解可用字符数

    如果fits_read_descript()给出了数组中的元素个数和起始偏移量,是否可以将总字节数读入字符串并用分隔符“,”进行标记并得到数字?

    【讨论】:

    • 嗨@lorenz,感谢您的帮助。 fits_get_col_display_width() 在可变长度列上使用时会崩溃。但你是对的fits_read_descript(fitsfile *fptr, int colnum, LONGLONG rownum, &gt; long *repeat, long *offset, int *status) 返回元素的数量repeat 和起始offset。只是我不知道如何使用它们......有一个fits_read_tblbytes(fitsfile *fptr, LONGLONG firstrow, LONGLONG firstchar, LONGLONG nchars, &gt; unsigned char *values, int *status),但文档不清楚firstrowfirstcharnchars 是什么。
    【解决方案2】:

    FITS中有很多奇怪的特殊情况,你已经找到了其中之一。

    我已经成功使用了。

    1. 致电fits_read_descript{s}{ll}() 以确定相关行的重复和偏移量。您还可以使用descripts 变体一次确定多行的重复和偏移量。
    2. 调用fits_read_col{null}() 读取数据,一次一行。元素的数量是您在第 1 步中找到的重复计数,或者如果您想要一个子集则更少。像往常一样设置列、行号和第一个元素。使用 null 变体就可以了。

    重要的是您一次只能读取一行可变长度数据,但它可以省去您进行所有字节解码和堆索引的麻烦。即使您使用fits_read_descripts() 变体来确定一个函数调用中的多个重复计数,您仍然必须为您感兴趣的每个表行调用一次fits_read_col()。

    读取可变长度字符串或位数组是他们自己有趣的消遣,但您看起来只是想读取 X 射线响应矩阵数据(浮点),所以这应该可以回答您的问题。

    【讨论】:

      【解决方案3】:

      感谢@lorenz 和@CraigM 的建议。

      其实我在ROOT class interfacing with the CFITSIO library找到了解决方案并实现了,所以如果其他人有同样的问题可以复制解决方案或直接使用ROOT。 我介绍的在 ROOT 中读取可变长度单元的函数是: TFITSHDU::GetTabVarLengthVectorCell()

      我是一年前做的,忘了在这里发布答案:)

      你可以找到解决方案here的代码。

      我实际上使用了@CraigM 提出的方案,即结合fits_read_descriptfits_read_col

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 2017-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多