Чтение массивов переменной длины из таблицы FITS с использованием библиотеки CFITSIO - PullRequest
5 голосов
/ 03 марта 2020

Мне трудно читать массивы переменной длины из записей таблицы FITS, используя библиотеки CFITSIO (я должен использовать их из-за другого программного обеспечения, которое я разрабатываю).

Теперь Таблица FITS, которую я пытаюсь прочитать, выглядит следующим образом:

enter image description here

Как видите, последние три столбца вместо скалярных значений в своих ячейках , содержат массивы переменной длины.

Документация CFITSIO не очень полезна в этом конкретном случае: считается, что большая часть подпрограммы basi c генерирует массив, читая непосредственно обычные столбцы (со скаляром в их ячейки, см. раздел 2 из https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node46.html). fits_read_col не будет работать с этой структурой данных.

Теперь рекомендуется использовать процедуру fits_read_descript при чтении переменных столбцов. Проблема заключается в том, что эта функция возвращает информацию низкого уровня, в частности, начальное смещение в куче, где хранится массив (см. Раздел 7 https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node82.html). Так что даже если я получу низкоуровневую информацию о ячейке, содержащей несколько массивов, то неясно, как использовать ее для получения числовых значений!

CFITSIO Итераторы полезны незначительно, и нет примера с такой сложной структурой данных.

Кто-нибудь когда-либо делал это раньше? Кто-нибудь может создать фрагмент, используя CFITSIO для чтения массива переменной длины? Это было бы очень полезно.

Файл FITS, снимок которого я сделал, можно найти здесь .

Вот предварительный фрагмент, открывающий файл и исследующий столбцы и строк, применяя предложенную функцию 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);
        }
    }
}

1 Ответ

0 голосов
/ 03 марта 2020

Просто мысль, возможно, вы, возможно, видели это / думали об этом, но на всякий случай, если у вас нет.

fits_get_col_display_width () = узнать количество доступных символов

Если fits_read_descript () дает количество элементов в массиве и начальное смещение, может ли общее число байтов быть прочитано в строку и токенизироваться с разделителем "," и получить числа?

...