HITRAN数据库是分子旋转振动过渡的列表。它在一个文本文件中给出,其中每行为160个字符,固定宽度字段定义分子,同位素等。格式有详细记录,甚至在MathWorks File Exchange上的程序将在数据库中读取并模拟一部分频谱。但是,我需要读取光谱的特定部分,然后使用它来对测量光谱做一些拟合,所以我需要更多的定制。
如该函数的注释部分以及其他地方所述,以下行应正确读取每一行:
database = which('HITRAN2012.par');
fid = fopen(database);
hitran = textscan(fid,'%2u%1u%12f%10f%10f%5f%5f%10f%4f%8f%15c%15c%15c%15c%6c%12c%1c%7f%7f','delimiter','','whitespace','');
fclose(fid);
前两个字段表示分子代码,从1-47开始,同位素代码从1-9开始。
不幸的是,分子1-9没有前导零,无论我做什么,它似乎都默默地混淆了MATLAB。如果我加载整个数据库然后键入
unique(hitran{1})
我没有得到1-47的数字,但是我得到了10-92,但缺少一些数字。据我所知,当MATLAB遇到一个前导空格时,它将线移过然后填充结束,使'12'变为'12',但我不完全确定。我也试过
hitran = textscan(fid,'%160c','delimiter','\n','whitespace','');
然后尝试解析生成的字符串,但有时也会被第一个空格弄糊涂。
例如,第一条水线看起来像
exampleHitranLine = ' 14 0.007002 1.165E-32 2.071E-14.05870.305 818.00670.590.000000 0 0 0 0 0 0 7 5 2 7 5 3 005540 02227 5 2 0 90.0 90.0';
第一行代码遇到此行并返回'14'
而不是' 1'
和'4'
。如果我只读取仅包含分子1的子集(如本例所示),则第二种读取方法可以正常工作。但是,如果我尝试在整个数据库中读取,则分子1-9的线在左侧移动,这会扰乱所有其他区域。
我应该注意到我已经尝试将数字字段作为浮点数和整数读取,并且都没有给出令人满意的结果。文本形式的整个数据库接近700 MB,因此我需要尽可能高效的工作。
我做错了什么?
答案 0 :(得分:0)
我没有回答为什么会发生这种情况,但我确实有一个解决方案。如果有人对原因有答案,我会很乐意接受它。
这是领先的空间。 MATLAB有点过于聪明,当textscan
遇到一个前导空格时,它会确定它是额外的并丢弃它并转移到接下来的两个字符。为了让它在文件中正确读取,我必须逐行检查并测试第一个字符是否为空格,然后将其替换为前导零,如下所示:
database = which('HITRAN2012_First100Lines.par');
fileParams = dir(database);
K = fileParams.bytes/162;
hitran = cell(K,19);
fid = fopen(database);
for k = 1:K
hitranTemp = fgetl(fid);
if abs(hitranTemp(1)) == 32;
hitranTemp(1) = '0';
end
hitran(k,:) = deal(textscan(hitranTemp,'%2u%1u%12f%10f%10f%5f%5f%10f%4f%8f%15c%15c%15c%15c%6c%12c%1c%7f%7f','delimiter','','whitespace',''));
end
fclose(fid);
我在MATLAB 2013a工作。我应该认为这是一个错误并报告它吗?是否有一些理由认为领先的空间应该像这样被吞噬?
<强>更新强>
我上面的解决方法很慢,但很有效。然后我不得不处理几倍大的HITEMP数据库,所以我最终向MathWorks提交了一张支持票。 MathWorks技术支持建议的解决方法是以文本形式读取所有内容然后进行转换。这节省了大量磁盘读取和工作。
fileParams = dir(database);
fid = fopen(database);
hitran = textscan(fid,'%2c%1c%12c%10c%10c%5c%5c%10c%4c%8c%15c%15c%15c%15c%6c%12c%1c%7c%7c','delimiter','','whitespace','');
fclose(fid);
moleculeNumber = uint8(str2num(hitran{1}));
isotopologueNumber = uint8(str2num(hitran{2});
vacuumWavenumber = str2num(hitran{3});
...
etc.
根据应用程序的不同,对于较大的数据库,人们可能希望这样做in chunks而不是一次完成。
他还表示,他会将此行为转发给开发团队,以便在将来的更新中考虑。
答案 1 :(得分:0)
我have a new file on the FileExchange that will read in HITRAN 2004+ format data。请尝试一下,如果有任何问题请告诉我。