FIT文件格式解析及MATLAB读取程序

本文详细介绍了如何使用UltraEdit查看FIT文件,并解释了FIT文件的数据存储方式。文章提供了MATLAB程序用于读取FIT文件数据并保存为TXT格式,同时展示了从FIT文件中读取的5条光谱数据。

转载自:ShiZhixin的专栏

FIT文件格式解析

摘要:本文档主要介绍了用UltraEdit查看FIT文件及简要的说明了FIT文件的数据存储方式,并附上了FIT文件数据读取及保存为TXT的MATLAB程序。此外,通过读取lamda的相关信息,文中还显示了5条FIT文件中读取出来的光谱。
 

用UltraEdit打开一个光谱FIT文件,其十六进制表示如下:



一个 FIT 文件包含一系列逻辑单元,而每个单元的开头都是用一组标题记录描述随后的数据记录。一个 FIT 文件的逻辑记录长度总是 2880 字节(bytes),每字节8 位(bits)。标题和数据组都在一个新的逻辑记录里起始。FIT标题用 ASCII 码编辑成每一个开始用一个 8 字符的关键词(keyword) 定义信息的类型(80字符)。一个 FIT 标题卡片映象的基本语法格式是:

Keyword=Value/Comment

(关键词=参数值/注释说明)

关键词是一个左边对齐的 8 字符 ASCII 码字符串, 放在 1-8 列里, 字母必须大写。“=”号出现在第 9 列, 而第 10 列是空格。逻辑值(F 或 T)和数值在数值区中紧靠右排列,字符串用符号: ' ' 括出,字母大写。符号“/”用来表示数值区结束。注释说明紧接符号“/”,用大小写ASCII码字符书写。因此,为了在普通计算机上简化参数译码,要求对大多数基本参数使用一个固定格式,而且对所有其他参数也建议使用这个固定格式,建议和部分要求的固定格式如下:

1) Logical Variable (逻辑变量): T 或 F, 在 30 列里。

2) Integer Variable (整数变量): 右对齐在 11-30 列里,若有虚部右对齐在31-5 0 列里。

3) Real Variable (实变量): 要求 10 进制小数点,右对齐(如果用指数记数法)在 11-30 列里, 若有虚部,右对齐(如果用指数记数法)在 31-50 列里。

4) Character Variable (字符变量):虽然允许较长的字符串,但正常的长度用 8 个字符表示。在11 列里用符号 ' 随后跟字符串,紧接着用一个符号 '结束,它不能出现在 20 列之前。

按照此方法,可以读取出来FIT文件的头文件记录如下:

[plain]  view plain copy
  1. SIMPLE  =                    T / NORMAL FIT IMAGE                               
  2. BITPIX  =                  -64 / DATA PRECISION                                  
  3. NAXIS   =                    2 / NUMBER OF IMAGEDIMENSIONS                      
  4. NAXIS1  =                 3992 / NUMBER OF COLUMNS                               
  5. NAXIS2  =                  250 / NUMBER OF ROWS                                  
  6. EXTEND  =                    T /Extensions may bepresent                        
  7. CRVAL1  =        3.56089999899 / Central wavelength(log10) of first pixel       
  8. .  
  9. .  
  10. .  
  11. WAT0_001= 'system=linear'      /                                                 
  12. WAT1_001= 'wtype=linear label=Wavelength units=Angstroms'/                      
  13. CD1_1   =          0.000100000 / Log10 dispersion perpixel                      
  14. CRPIX1  =                    1 / Starting pixel(1-indexed)                      
  15. CTYPE1  ='LINEAR  '           /                                                  
  16. DC-FLAG =                   1 / Log-linear flag                                 
  17. END    


头文件读取完后,紧接的是数据文件,但是这里注意的是头文件的字节大小必须如开始说的是2880的整数倍,否则在后补空格。全部记录长度均为 23040 bits (2880bytes *8 bit, 3840bytes*6 bit)。这个长度能用市场上出售的所有计算机的位长和字长除尽, (即 6,8,12,16,18,24,32,36,48,60 和 64 bits)。这种通用性适用于在各种各样的计算机上读写记录。如图:


END结束的位置在0x27b2(第10162个字节处,可以通过读取这个关键字获取),所以从0x27b3开始补空格,空格的结束位置应该计算如下:

NUMBER_HEAD_UNIT= 10162/2880=3.5284722222222222222222222222222

因而头文件应该包括四个2880的数据单元,即头文件结束的位置:

END_HEADER_POSITION= 2880*4=11520(0x2cff)

空格应该在0x2cff处结束。从文件开头到偏移11520个字节,即0x2d00处开始正式的数据存储,如下图所示:

这里注意的是上图中0x2d00处的00表示起始数据就是0,不是其他标志。数据的实际长度为:

NAXIS1* NAXIS2 * BITPIX /8 = 8276000

其中:

NAXIS1:数据列数;

NAXIS2数据行数,这里数据250应该为250条光谱数据(通过焦面上4000根光纤和16台光谱仪);

BITPIX:数据表示的位数,64位,8个字节;

但是,8276000/2880 = 2873.6111111111111111111111111111,不是2880的整数倍,所以文件存储的长度应该为:

DATA_LENGTH= 2874*2880 = 8277120

所以,结束地址应该是:

END_DATA_POSTION= END_HEADER_POSITION + DATA_LENGTH

= 11520+8277120=8288640(0x7e7980)

如图所示:

 从上图也可以看出,数据结束后又开始了新的文件头,新的数据块,这里的数据存储及读取方式如开始所述类似,此处不再赘述。

    下面附上MATLAB程序,其中包含了对数据的读取和写入TXT文件:

[plain]  view plain copy
  1. clc,clear,close all;  
  2. filename = '20100121\9b_1_sp01.FIT';  
  3. fr_id = fopen(filename,'r','s'); %FITfile  
  4. info=FITinfo(filename);   
  5. %FIT file head info, which includeprimarydata and image  
  6. oset=info.PrimaryData.Offset;  
  7. %thesize of primarydata head and it is also the start of primarydata  
  8. cols =info.PrimaryData.Size(1);%the columns of primary data  
  9. rows =info.PrimaryData.Size(2);%the rows of primary data  
  10. SIZE_UNIT = 2880;   %The size of a FIT logical record  
  11. SIZE_TYPE_NAME= 8; % size of keyword, Keyword= Value/Comment  
  12. SIZE_TYPE = 80;     % size of (Keyword= Value/Comment)  
  13. num_type_prim = oset / SIZE_TYPE;%the numbers of primarydata head type  
  14.    
  15. %-------get the start position oflamda and its step(log10)  
  16. for i=1:num_type_prim  
  17.    fseek(fr_id, (i-1)*SIZE_TYPE,-1);  
  18.    type_name = fread(fr_id, SIZE_TYPE_NAME,'*char');  
  19.    switch type_name'  
  20.         case 'BITPIX  ' %data dispersion  
  21.             fseek(fr_id,2,0); %skip two bytes,cause there are '= ' after type_name  
  22.             str_tmp = fread(fr_id, SIZE_TYPE -SIZE_TYPE_NAME - 2,'*char');  
  23.             data_percision =str2num(str_tmp(1:20)');  
  24.             data_percision = abs(data_percision);  
  25.         case 'CRVAL1  '  %thestart position of lamda  
  26.             fseek(fr_id,2,0);  
  27.             str_tmp = fread(fr_id, SIZE_TYPE -SIZE_TYPE_NAME - 2,'*char');  
  28.             lamda_start =str2num(str_tmp(1:20)');  
  29.         case 'CD1_1   ' %the step of lamda  
  30.             fseek(fr_id,2,0);  
  31.             str_tmp = fread(fr_id, SIZE_TYPE -SIZE_TYPE_NAME - 2,'*char');  
  32.             lamda_deta =str2num(str_tmp(1:20)');  
  33.    end  
  34. end  
  35.    
  36. % calc the array of lamda(not logformat)  
  37. lamda = lamda_start:lamda_deta:lamda_start+lamda_deta*(cols-1);  
  38. for i=1:length(lamda)  
  39.    lamda(i) = 10^lamda(i);  
  40. end  
  41.    
  42. %--------------------write primaryhead----------------------  
  43. fph_id =fopen('primary_head_info.txt','w','b');  
  44. fseek(fr_id,0,-1);  
  45. for i=1:num_type_prim  
  46.    head_info = fread(fr_id,SIZE_TYPE);  
  47.    fwrite(fph_id,head_info);  
  48.    fprintf(fph_id,'\r\n');  
  49. end  
  50. fclose(fph_id);  
  51.    
  52. %--------------------write primarydata----------------------  
  53. fpd_id =fopen('prim_data.txt','w','s');  
  54. fseek(fr_id,oset,-1);  
  55. for i=1:5 %because of the openspeed in txt, this only write five rows data into txt file.If you want all, youcan replace 5 with rows  
  56.    data_prim = fread(fr_id, cols, 'double');  
  57.    figure  
  58.    plot(lamda, data_prim);  
  59.    fprintf(fpd_id,'%f ',data_prim);  
  60. end  
  61. fclose(fpd_id);  


程序运行结果:
 




 

参考文献

[1]柯大荣 赵永恒.FIT 基本格式及其扩展.中国科学院北京天文台,1993年7月,

http://www.lamost.org/~yzhao/doc/FIT.html

[2] FIT Standard, Definition of theFlexible Image Transport System 

<think>好的,我现在需要帮助用户解决如何使用Matlab读取解析.log文件的问题。用户提供了几个引用资料,我需要先仔细看看这些引用的内容,然后结合自己的知识生成回答。 首先,查看引用[1],里面提到用fopen打开文件,检查是否成功,然后用fscanf读取内容,最后关闭文件。代码示例看起来是读取整个文件内容为一个字符串,可能适用于结构简单的.log文件。不过fscanf的%s格式可能会一次性读取所有内容,需要注意是否有换行符的问题。 引用[2]使用了textscan函数,并且指定了分隔符为换行符,这样可以把每一行读入到元胞数组中。这种方法可能更适合按行处理.log文件,尤其是当文件内容有结构化的行时,可以逐行解析。 引用[3]和[4]提到了处理特定格式的文件,比如FIT文件和GNSS坐标信息。用户的问题是一般的.log文件,但可能需要根据具体格式调整解析方法。例如,引用[4]中的例子是提取坐标信息并绘图,这可能涉及到数据的分隔符处理,比如空格或逗号分割的数据。 接下来,我需要整理出通用的步骤。首先是如何打开读取文件的基本操作,然后是根据文件结构选择合适的读取方法。如果.log文件是逐行记录的,可能用textscan按行读取更好。如果数据是结构化的,比如每行有固定格式,可以使用格式字符串来提取变量。 另外,要注意错误处理,比如文件无法打开的情况,如引用[1]中的检查fileID是否为-1。同时,关闭文件是必要的,避免资源泄露。 用户可能需要代码示例,所以需要结合引用中的代码,给出两种方法:一种是读取整个文件为字符串,另一种是按行读取到元胞数组。然后,针对不同格式的解析,比如空格分隔的数据,使用textscan或strsplit进行处理。 还需要考虑.log文件可能包含不同类型的数据,比如文本和数字混合的情况,这时候可能需要更复杂的解析方法,比如正则表达式或者自定义解析函数。 最后,生成相关问题,可能涉及性能优化、特定格式处理、错误处理等,这些问题可以帮助用户进一步探索。</think>以下是如何使用MATLAB读取解析.log文件的分步指南,包含多种实现方式及代码示例: ### 一、基础文件读取操作 1. **打开文件与安全检查** ```matlab fileID = fopen('data.log','r'); if fileID == -1 error('文件打开失败,请检查路径或权限'); end ``` *所有文件操作前必须进行有效性验证*[^1] 2. **三种常用读取方式** - **整体读取**(适合小型文件): ```matlab content = fscanf(fileID, '%s'); % 将文件内容读取为连续字符串 ``` - **逐行读取**(推荐通用方式): ```matlab dataCell = textscan(fileID, '%s', 'Delimiter', '\n'); % 按行存储到元胞数组 lines = dataCell{1}; % 提取字符串数组 ``` - **格式化读取**(结构化数据专用): ```matlab % 示例:读取含时间戳和坐标的数据 dataStruct = textscan(fileID, '%s %f %f %f', 'HeaderLines',2); % 跳过前两行注释,按字符串+3浮点数格式解析 ``` 3. **必做操作** ```matlab fclose(fileID); % 无论读取是否成功都必须关闭文件[^1][^2] ``` ### 二、数据解析方法 **案例:解析GNSS定位数据** ```matlab % 读取示例文件(含经度、纬度、高度) posData = textscan(fileID, 'UTC: %s Lat: %f Lon: %f Alt: %f'); % 提取三维坐标 coordinates = [posData{2:4}]; % 可视化(需要MATLAB图形工具箱) figure plot3(coordinates(:,2), coordinates(:,1), coordinates(:,3)); xlabel('经度'); ylabel('纬度'); zlabel('海拔'); grid on ``` *该可视化方法来自GNSS数据处理示例*[^4] ### 三、高级处理技巧 1. **正则表达式解析** ```matlab logEntries = regexp(content, '\[(\d+-\d+-\d+) (\d+:\d+)\] (\w+): (.*?)\.', 'tokens'); % 解析格式:[日期 时间] 类型: 信息 ``` 2. **异常数据处理** ```matlab try data = textscan(fileID, '%f,%f,%f'); catch ME fprintf('解析错误:第%d行格式异常\n', find(~cellfun(@isnumeric, data))); end ``` 3. **大文件分块读取** ```matlab while ~feof(fileID) chunk = textscan(fileID, '%s', 1000); % 每次读取1000行 processChunk(chunk{1}); % 自定义处理函数 end ``` ### 四、完整工作流示例 ```matlab function parseLogFile(filename) fileID = fopen(filename, 'r'); if fileID == -1 error('文件%s打开失败', filename); end % 读取含表头的数据 headers = textscan(fileID, '%s', 5, 'Delimiter', '|'); % 读取前5行表头 data = textscan(fileID, '%{yyyy-MM-dd}D %f %f %f %s', 'Delimiter', ','); fclose(fileID); % 转换为时间表 tt = timetable(data{1}, data{2}, data{3}, data{4}, data{5}, ... 'VariableNames', {'Temperature','Pressure','Humidity','Status'}); % 数据筛选 validData = tt(tt.Status == 'OK', :); end ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值