eddy_em: (Default)
[personal profile] eddy_em
Выше я уже писал о работе с FITS-форматом в GNU Octave, однако, что это за формат такой и с чем его едят как работать с ним в своих приложениях на C не упомянул.




Краткое описание формата


Что такое FITS можно прочитать в википедии, поэтому здесь сделаю лишь краткую выжимку. Итак, FITS (Flexible Image Transport System — гибкая система передачи изображений) — цифровой формат файлов используемый в науке для хранения, передачи и редактирования изображений и их метаданных. В основном этот формат используется в астрономии для хранения изображений. Помимо изображений он позволяет хранить табличные данные, а также различные дескрипторы (ключи). Причем в одном файле может быть несколько изображений, таблиц и ключей. Сами дескрипторы хранятся в «шапке» файла в ASCII-формате, что позволяет при помощи less/more/F3 в mc и т.п. получить информацию о содержимом файла, даже не имея средств для просмотра FITS.

Библиотеки и программное обеспечение для работы с FITS


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


Математические пакеты (Matlab, Octave и т.п.) имеют средства для чтения/записи FITS-файлов (но тоже эти средства зачастую ограниченны); естественно, для астрофизиков есть и специальное ПО (например, MIDAS, Iraf и т.п.), позволяющее полноценно работать с разнообразным содержимым FITS-файлов.


Для работы в своих проектах можно выбрать одну из множества библиотек, позволяющих работать с FITS-файлами (а можно и свой "велосипед" сделать). В языке C наиболее популярной (и полноценной) является библиотека CFITSIO, вкратце о ней я и расскажу.

Краткое описание CFITSIO


На основе примеров работы с cfitsio можно понять основные функции библиотеки. Для работы с файлами cfitsio представляет функции чтения и записи, позволяющие работать со сжатыми файлами, задавать маски файлов (а также - области, необходимые для считывания) в имени файла. Маской в имени файла можно также задать необходимые таблицы и/или ключи для импорта, а также выполнить элементарную правку ключей.


При работе с FITS-файлами следует помнить, что наибольшее количество одновременно открытых файлов равно 25 (оно определяется значением константы NIOBUF при компиляции библиотеки). Максимальное количество расширений (блоков с данными - изображениями, таблицами, ключами), с которым может работать библиотека, составляет 1000 для одного файла (определяется константой MAXHDU). Библиотека не работает с файлами, чей размер превышает 2.1ГБ. Также библиотека не работает с данными, имеющими разрядность выше 32 бит (в принципе, это понятно: современные АЦП в светоприемной аппаратуре обычно имеют разрядность в лучшем случае 16 бит).


Библиотека позволяет одновременно несколько раз открыть один и тот же файл (например, для параллельной работы с шапкой, таблицами и изображениями в файле). При работе с файлами, чья «шапка» содержит несколько разделов с ключами, cfitsio может работать лишь с одним из разделов, поэтому если одновременно нужно брать данные из нескольких, необходимо будет открыть файл нужное количество раз.


При чтении и записи изображений cfitsio автоматически преобразует значения по значениям стандартных ключей BSCALE и BZERO:

output value = (FITS value) * BSCALE + BZERO
FITS value = ((input value) - BZERO) / BSCALE


Работая с ключами, следует помнить, что стандарт FITS вносит ограничение на размеры ключа: весь ключ (имя, значение, комментарий) не может иметь длину больше 80 байт; имя ключа не может превышать 8 байт. Если необходимо вписать, например, более длинное имя ключа, или же имя ключа должно содержать непотребные нестандартные символы (пробелы, а также символы, не являющиеся латинскими буквами или символом подчеркивания), перед таким ключом ставится префикс HIERARCH. В этом случае максимальная длина ключа составляет 67 символов (однако, при этом некуда будет вписывать значение переменной и комментарий). CFITSIO прозрачно работает с ключами и читает/записывает даже такие нестандартные ключи. Если при записи ключа возникает какая-то ошибка (например, ключ+значение+комментарий не вписываются в 80 байт, cfitsio возвращает ошибку). Кстати, 80 байт - это ограничение на всю строку, а т.к. имя ключа обычно отделено от значения знаком равенства, окруженным пробелами, а комментарий — косой чертой, окруженной пробелами, полный ключ со значением и комментарием суммарно может занимать не более 74 байт. Т.к. 8 байт занимает сам ключ (кроме указанного выше исключения), на значение и комментарий остается 66 байт.

Использование CFITSIO в своих проектах


Не мудрствуя лукаво, опишу работу с библиотекой на примере своих «велосипедов»: takepic — CLI-интерфейс для работы с камерой FLI Proline 9000, а также многострадальной fitsview — смотрелки FITS-файлов с возможностями простейшего редактирования (все никак не допилю модуль обработки гартманнограмм, да и вообще что-то подзабыл я о нем).

В takepic я взял за основу пример из SDK разработчиков камеры, добавив в него нужный мне функционал. Для упрощения диагностирования ошибок при работе с библиотекой cfitsio используются обертки:

#define TRYFITS(f, ...)						\
do{	int status = 0;							\
	f(__VA_ARGS__, &status);				\
	if (status){							\
		fits_report_error(stderr, status);		\
		return -1;}						\
}while(0)
#define WRITEKEY(...)						\
do{ int status = 0;							\
	fits_write_key(__VA_ARGS__, &status);	\
	if(status) fits_report_error(stderr, status);	\
}while(0)

Если при выполнении функций cfitsio возвращает ошибку, генерируется сообщение об ошибке и внешняя функция, в которой произошла ошибка, завершается с возвращением -1. При записи ключа в случае ошибки просто генерируется сообщение об ошибке (т.к. это не так критично).


Сама функция записи FITS-файлов довольно проста: в качестве аргументов она принимает имя файла (filename), размеры полученного изображения (width, height) и указатель на массив с данными изображения (data). Так как изображение характеризуется двумя осями, необходимо создать массив из двух чисел, в который поместить ширину и высоту изображения (этот массив, naxes, мы передадим функции создания области с изображением в FITS-файле). Итак, предварительная подготовка:


long naxes[2] = {width, height};
fitsfile *fp;
TRYFITS(fits_create_file, &fp, filename);
TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);

Я создаю область изображения с типом unsigned short (т.к. для работы с камерой FLI его вполне хватает), однако, можно указать и другой тип изображения — cfitsio автоматически осуществит преобразование типов (главное — помнить, что преобразование из int в uint скорее всего, закончится ошибкой, если входная интенсивность будет превышать допустимый уровень в выходной).


Далее можно заполнить «шапку» файла необходимыми данными, например:


WRITEKEY(fp, TSTRING, "FILE", filename, "Input file original name");
WRITEKEY(fp, TSTRING, "DETECTOR", camera, "Detector model");
WRITEKEY(fp, TDOUBLE, "TEMPBODY", &t_ext, "Camera body temperature at exp. end (degr C)");
WRITEKEY(fp, TDOUBLE, "EXPTIME", &tmp, "actual exposition time (sec)");
WRITEKEY(fp, TSTRING, "OBJECT", objname, "Object name");

и т.д., и т.п. (помимо основных сведений я вписываю в «шапку» еще сведения о погодных условиях, координатах объекта и т.п.).


После заполнения «шапки» мы записываем изображение и закрываем файл: все готово!


TRYFITS(fits_write_img, fp, TUSHORT, 1, width * height, data);
TRYFITS(fits_close_file, fp);



В fitsview мне нужно было не только записывать, но и читать файлы. Я использовал все те же макросы-обертки, что и в takepic, но добавил еще одну:

#define FITSFUN(f, ...)						\
do{	gboolean status = FALSE;				\
	int ret = f(__VA_ARGS__, &status);		\
	if(ret || status)							\
		fits_report_error(stderr, status);		\
}while(0)

чтобы в некритических случаях не завершать работу вызывавшей функции.


Функция записи файла практически ничем не отличается от takepic, разве что ключи пишутся в формате «карты» — уже готовой строки (т.к. ключи имеют разные форматы и хранятся в GtkTree).


Чтение файла производится с параллельной обработкой ключей (т.к. некоторая информация из ключей используется в характеристиках изображения), кроме того, ключи сохраняются в GtkTree для возможности редактирования.
Итак, основные функции для чтения файла включают в себя открытие файла, получение количества «шапок» в файле, перемещение к первой, считывание и обработка ключей


fitsfile *fp; // gchar *filename, IMAGE *image - аргументы функции 
int dtype, j, hdunum, keynum, morekeys;
char keyname[FLEN_KEYWORD], keyval[FLEN_VALUE];
char keycomment[FLEN_COMMENT], cdtype[32];
TRYFITS(fits_open_file, &fp, filename, READWRITE);
FITSFUN(fits_get_num_hdus, fp, &hdunum);
FITSFUN(fits_get_hdrpos ,fp, &keynum, &morekeys);
for (j = 1; j <= keynum; j++){
	FITSFUN(fits_read_keyn, fp, j, keyname, keyval, keycomment);
	dtype = guess_type(keyval, cdtype);
	add_key(image, cdtype, keyname, keyval, keycomment, dtype);
}

Функция guess_type пытается определить тип данных: анализируется вид данных и последовательно вызываются функции преобразования строки в разные типы (double, long long). Если данные не подходят к типам double или long long, проверяется еще — не являются ли они комплексным числом. Если и комплексным не является, тип считается строковым.


Если файл содержит больше одной «шапки», считываются ключи и из других. При записи cfitsio автоматически разобьет ключи на нужное количество «шапок» (если ключей будет слишком много).
Далее мы получаем параметры изображения, считываем его (сразу преобразуя средствами cfitsio в тип float) и закрываем файл.


TRYFITS(fits_get_img_param, fp, 4, &dtype, &naxis, naxes);
TRYFITS(fits_read_img, fp, TFLOAT, 1, sz, &nullval, image->data, &stat);
TRYFITS(fits_close_file, fp);


Итак, работа с FITS-файлами при помощи cfitsio достаточно проста.

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org

October 2025

S M T W T F S
   1234
567 89 1011
121314 15161718
19202122232425
2627 28293031 

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Feb. 24th, 2026 06:51 pm
Powered by Dreamwidth Studios