哈喽!大家好,这里是小Yang!
上一章向大家分享了如何从官网获取Argo数据,以及它所被记录的文件格式—dat文件,那么这部分小Yang将向大家继续分享一下如何读取dat文件的内容吧!


  • dat文件数据内容的分析
  • dat文件数据的提取
  • dat文件提取Argo的编号、数据提取时间和Argo的位置信息


dat文件数据内容的分析

我们在MATLAB打开任意一个dat文件的时候,可以发现它包含了这些信息:

bes查看dat文件_matlab


其中,我们比较感兴趣的信息一般有Argo的编号(PLATFORM NUMBER)、它获得该数据的具体时间(JULIAN DAY)、它所在的位置–经纬度(LOCATION)、以及它所测得的数据(FILE)。在MATLAB,我们可以用importdata来读取dat文件,先在命令行窗口测试一下:

bes查看dat文件_bes查看dat文件_02


接着会得到一个结构体数组,可以继续输入ans.dataans.textdata来分别进一步查看里面的内容。

对于ans.data部分,小Yang这里就不多展示啦,从‘double’可见,里面其实就是该Argo测得的一些海洋物理参数,比如垂向温度分布、盐度分布等。如果想要提取到文件与Argo有关的基本信息,我们更多是要对ans.textdata部分进行处理,这一部分的内容是元胞形式的:

bes查看dat文件_bes查看dat文件_03


以上就是dat文件的基本内容,下面一起来看看怎么提取dat文件的基本信息吧!

dat文件数据的提取

dat文件提取Argo的编号、数据提取时间和Argo的位置信息

参考杭州Argo官网提供的解析dat文件的源程序"read_data_from_single_file”(在进入ftp链接后的“matlab”文件夹中可以找到,但是该程序只能读一些Argo基本参数,无法读取我们想要的参数),可以利用识别每个cell中包含的字符来判断该cell是否为我们所需要。
话不多说,先上代码!
看不懂没关系!小Yang后面会一步步解释

function [SID,date,lon,lat] = read_time_coord_from_dat(filename)
% READ_TIME_COORD_FROM_DAT 输出argo的编号、时间和坐标
argodata=importdata(filename);
l=length(argodata.textdata);
n=0;
for i=1:l
    if strncmp(argodata.textdata(i),'     PLATFORM NUMBER',20)
        SID=split(argodata.textdata(i),':');
        SID=SID(2);
        n=n+1;
    elseif strncmp(argodata.textdata(i),'     JULIAN DAY',15)
        date=split(argodata.textdata(i),'(');
        date=split(date(1),':');
        date=str2double(cell2mat(date(2)))+712224;
        date={datetime(date,'ConvertFrom','datenum')};
        n=n+1;
    elseif strncmp(argodata.textdata(i),'     LATITUDE',13)
        lat=split(argodata.textdata(i),':');
        lat=lat(2);
        n=n+1;
    elseif strncmp(argodata.textdata(i),'     LONGITUDE',14)
        lon=split(argodata.textdata(i),':');
        lon=lon(2);
        n=n+1;
    elseif n >= 4
        break
    end
end
if n<4
    SID=[];
    date=[];
    lon=[];
    lat=[];
end
end

为了在后面实现对多个dat文件同时处理,小Yang也使用了函数的形式来编译。
首先是函数句柄的形式,比较基础的啦,小Yang就不深入解释,总之该函数希望达到的目的就是:输入文件名,能够返回一个数组,数组包含Argo的SID、记录数据的时间、经度、纬度这四个参数。

function [SID,date,lon,lat] = read_time_coord_from_dat(filename)

第二步:就是刚刚说的用importdata来读取dat文件,并把读出来的两部分数据—data和textdataargodata来保存。

argodata=importdata(filename);

第三步,也是最关键的部分:

l=length(argodata.textdata);
n=0;
for i=1:l
    if strncmp(argodata.textdata(i),'     PLATFORM NUMBER',20)
        SID=split(argodata.textdata(i),':');
        SID=SID(2);
        n=n+1;
    elseif strncmp(argodata.textdata(i),'     JULIAN DAY',15)
        date=split(argodata.textdata(i),'(');
        date=split(date(1),':');
        date=str2double(cell2mat(date(2)))+712224;
        date={datetime(date,'ConvertFrom','datenum')};
        n=n+1;
    elseif strncmp(argodata.textdata(i),'     LATITUDE',13)
        lat=split(argodata.textdata(i),':');
        lat=lat(2);
        n=n+1;
    elseif strncmp(argodata.textdata(i),'     LONGITUDE',14)
        lon=split(argodata.textdata(i),':');
        lon=lon(2);
        n=n+1;
    elseif n >= 4
        break
    end
end

因为我们想要的数据在textdata中,因此只从该部分来提取。在讲解这部分内容之前,大家需要先知道strncmpsplit的作用:
1.strncmp:比较字符串的前 n 个字符(区分大小写)。小Yang直接摘一段官网的话吧:tf = strncmp(s1,s2,n) 比较 s1 和 s2 的前 n 个字符。如果二者相同,函数将返回 1 (true),否则返回 0 (false)。如果两个文本段的内容一直到结尾都相同或前 n 个字符相同(以先出现者为准),则将这两个文本段视为相同。返回结果 tf 的数据类型为 logical。
以代码为例,这段代码的意思就是:把argodata.textdata(i)的前20个字符 (包括空格) 部分与' PLATFORM NUMBER'这一段字符作比较,如果一模一样,那么判断为1,执行 if 中的语句,若不一样,那么就跳过。

if strncmp(argodata.textdata(i),'     PLATFORM NUMBER',20)

可以回看一下在textdata中对应的部分:

bes查看dat文件_官网_04


所以当 i = 3 时,能通过识别,可以执行 if 语句中的部分。

2.split:在分隔符处拆分字符串。 例如在代码中:

SID=split(argodata.textdata(i),':');

当 i = 3 时,执行 if 语句中的部分,此时argodata.textdata(i)对应的就是上图的红色框部分,我们要提取出冒号后面的那一串数字,即Argo的编号,因此,用split在冒号 ‘ :’处分割字符,原来的字符变成两部分,第一部分是冒号左边的' PLATFORM NUMBER ',第二部分是冒号右边的数字'1900832'
再单独把第二部分提出来,用SID来储存就好啦。这就是 if 语句中所包含的关键部分。

SID=SID(2);

后面的三个elseif部分,原理是一模一样的,在此就不再赘述咯。

至于此处用到的n,想法是每记录一个数据,n就加1,当四个数据都记录完了,此时n=4,可以直接跳出循环,而不需要把整个argodata.textdata都遍历一次。

elseif n >= 4
        break
    end

第四步:若整个argodata.textdata都遍历一次后,但 n还是小于4,说明该dat文件存在数据缺失,因此跳过该dat文件的读取,并把可能读取到的部分信息(如SID)清空,说明这个dat文件无法正常读取。

if n<4
   SID=[];
   date=[];
   lon=[];
   lat=[];
end

那么,以上就是dat文件提取Argo的编号、数据提取时间和Argo的位置信息的内容,如果对你有帮助的话,可以收藏一下啦

下一部分, 小Yang将向大家分享一下如何一次性读取dat文件夹的所有dat文件!