首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用CFITSIO库从FITS表中读取可变长度数组

使用CFITSIO库从FITS表中读取可变长度数组
EN

Stack Overflow用户
提问于 2020-03-03 22:40:48
回答 3查看 155关注 0票数 5

我在使用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函数用于可变长度列。我不知道如何继续下去,因为我不知道如何利用返回的参数来获取表中的实际数值。

代码语言:javascript
复制
#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);
        }
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-02-25 00:37:33

感谢@lorenz和@CraigM的建议。

我实际上找到了解决方案,并在根类与CFITSIO,所以如果其他人有同样的问题,可以复制解决方案或直接使用ROOT。我介绍的用于读取根目录中的可变长度单元格的函数是:TFITSHDU::GetTabVarLengthVectorCell()我一年前就这样做了,但忘了在这里发布答案:)

您可以在解决方案中找到代码这里

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

票数 0
EN

Stack Overflow用户

发布于 2020-03-04 00:07:15

这只是一个想法,也许你可能已经看到过这个/想过这个,但如果你还没有的话,只是以防万一。

配合_获取_列_显示_width() =了解可用字符数

如果合适_阅读_descript()给出了数组中元素的数量和起始偏移量,是否可以将总字节数读入一个字符串,并使用分隔符",“对其进行标记化,然后获得这些数字?

票数 1
EN

Stack Overflow用户

发布于 2021-02-23 23:44:08

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

我已经成功地使用了这一点。

  1. 呼叫fits_read_descript{s}{ll}()来确定有问题的行的重复和偏移量。您还可以使用descripts变量一次确定多个行的重复和偏移量。
  2. 呼叫fits_read_col{null}()若要读取数据,请一次读取一行。元素的数量是您在步骤1中找到的重复计数,如果需要子集,则为更小的数量像往常一样设置列、行号和第一个元素。使用variant运行得很好。

重要的是,您只能以这种方式一次一行地读取可变长度数据,但它省去了执行所有字节解码和堆索引的麻烦。即使您使用fits_read_descripts()variant要在一个函数调用中确定多个重复计数,仍必须调用fits_阅读_对您感兴趣的每个表行执行一次col()。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60509665

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档