使用 CFITSIO 库从 FITS table 读取可变长度数组
Reading variable-length arrays from a FITS table using the CFITSIO library
我很难使用 CFITSIO 库从 FITS table 的条目中读取可变长度数组(由于我正在开发的另一个软件,我必须使用它们)。
现在,我尝试阅读的 FITS table 看起来像这样:
如您所见,最后三列的单元格中没有标量值,而是包含可变长度数组。
CFITSIO
文档对这种特殊情况不是很有帮助:大多数基本例程被认为是通过直接读取常规列来生成数组(在它们的单元格中带有标量,请参阅 [=18 的第 2 节) =]).
fits_read_col
不适用于此数据结构。
现在建议在读取变量列时使用fits_read_descript
例程。问题在于此函数 returns 低级信息,特别是存储数组的堆中的起始偏移量(请参阅 https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node82.html 的第 7 节)。
因此,即使我获得了包含多个数组的单元格的低级信息,也不清楚如何使用它来获取数值!
CFITSIO Iterators略有帮助,没有这么复杂的数据结构的例子。
以前有人做过吗?是否有人能够使用 CFITSIO
生成片段来读取可变长度数组?这将非常有帮助。
可以找到我截图的FITS文件here。
这里是打开文件并检查列和行的暂定片段,对可变长度列应用建议的 fits_read_descript
函数。我不知道如何进一步进行,因为我不知道如何利用返回的参数来获取 table.
中的实际数值
#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);
}
}
}
只是想一想,您可能已经 this/thought 看到了这方面的内容,但以防万一您还没有看到。
fits_get_col_display_width() = 了解可用字符数
如果fits_read_descript()给出了数组中的元素个数和起始偏移量,是否可以将总字节数读入字符串并用分隔符“,”分词得到数字?
FITS中有很多奇怪的特例,你找到了其中的一个。
我已经成功使用了这个。
- 调用
fits_read_descript{s}{ll}()
以确定相关行的重复和偏移量。您还可以使用 descripts
变体一次确定多行的重复和偏移量。
- 调用
fits_read_col{null}()
读取数据,一次一行。元素的数量是您从步骤 1 中找到的重复计数,或者如果您想要一个子集,则更少。像往常一样设置列、行号和第一个元素。使用 null
变体效果很好。
重要的是你一次只能读取一行这样的可变长度数据,但它省去了你做所有字节解码和堆索引的麻烦。即使您使用 fits_read_descripts()
变体来确定一次函数调用中的多次重复计数,您仍然必须为您感兴趣的每个 table 行调用一次 fits_read_col()。
阅读可变长度字符串或位数组本身就是一种有趣的消遣,但您看起来只是想阅读 X 射线响应矩阵数据(浮点数),所以这应该可以回答您的问题。
感谢@lorenz 和@CraigM 的建议。
其实我在ROOT class interfacing with the CFITSIO
library找到了解决方案并实现了,所以如果其他人有同样的问题可以复制解决方案或者直接ROOT。
我介绍的在ROOT中读取一个变长单元格的函数是:
TFITSHDU::GetTabVarLengthVectorCell()
我一年前做过,忘了 post 这里的答案:)
您可以找到解决方案的代码 here。
我实际上使用了你提出的@CraigM 方案,即结合 fits_read_descript
和 fits_read_col
。
我很难使用 CFITSIO 库从 FITS table 的条目中读取可变长度数组(由于我正在开发的另一个软件,我必须使用它们)。
现在,我尝试阅读的 FITS table 看起来像这样:
如您所见,最后三列的单元格中没有标量值,而是包含可变长度数组。
CFITSIO
文档对这种特殊情况不是很有帮助:大多数基本例程被认为是通过直接读取常规列来生成数组(在它们的单元格中带有标量,请参阅 [=18 的第 2 节) =]).
fits_read_col
不适用于此数据结构。
现在建议在读取变量列时使用fits_read_descript
例程。问题在于此函数 returns 低级信息,特别是存储数组的堆中的起始偏移量(请参阅 https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node82.html 的第 7 节)。
因此,即使我获得了包含多个数组的单元格的低级信息,也不清楚如何使用它来获取数值!
CFITSIO Iterators略有帮助,没有这么复杂的数据结构的例子。
以前有人做过吗?是否有人能够使用 CFITSIO
生成片段来读取可变长度数组?这将非常有帮助。
可以找到我截图的FITS文件here。
这里是打开文件并检查列和行的暂定片段,对可变长度列应用建议的 fits_read_descript
函数。我不知道如何进一步进行,因为我不知道如何利用返回的参数来获取 table.
#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);
}
}
}
只是想一想,您可能已经 this/thought 看到了这方面的内容,但以防万一您还没有看到。
fits_get_col_display_width() = 了解可用字符数
如果fits_read_descript()给出了数组中的元素个数和起始偏移量,是否可以将总字节数读入字符串并用分隔符“,”分词得到数字?
FITS中有很多奇怪的特例,你找到了其中的一个。
我已经成功使用了这个。
- 调用
fits_read_descript{s}{ll}()
以确定相关行的重复和偏移量。您还可以使用descripts
变体一次确定多行的重复和偏移量。 - 调用
fits_read_col{null}()
读取数据,一次一行。元素的数量是您从步骤 1 中找到的重复计数,或者如果您想要一个子集,则更少。像往常一样设置列、行号和第一个元素。使用null
变体效果很好。
重要的是你一次只能读取一行这样的可变长度数据,但它省去了你做所有字节解码和堆索引的麻烦。即使您使用 fits_read_descripts()
变体来确定一次函数调用中的多次重复计数,您仍然必须为您感兴趣的每个 table 行调用一次 fits_read_col()。
阅读可变长度字符串或位数组本身就是一种有趣的消遣,但您看起来只是想阅读 X 射线响应矩阵数据(浮点数),所以这应该可以回答您的问题。
感谢@lorenz 和@CraigM 的建议。
其实我在ROOT class interfacing with the CFITSIO
library找到了解决方案并实现了,所以如果其他人有同样的问题可以复制解决方案或者直接ROOT。
我介绍的在ROOT中读取一个变长单元格的函数是:
TFITSHDU::GetTabVarLengthVectorCell()
我一年前做过,忘了 post 这里的答案:)
您可以找到解决方案的代码 here。
我实际上使用了你提出的@CraigM 方案,即结合 fits_read_descript
和 fits_read_col
。