seg2是野外地震勘探常用的数据存储格式之一,因此了解seg2文件的格式对于地震数据处理有很大的帮助,也给予程序编写许多便利。
seg2文件整体格式
下图是seg2文件的整体格式,(FILE DESCRIPTOR BLOCK:文件头)是整个文件的描述区域,位于文件的最开始位置,其中包括道数、测线数、每一道的指针、测量时间、所用的仪器型号等等一系列的信息。
我们可以根据文件头所描述的信息找到每一道的开头位置,(TRACE DESCRIPTOR BLOCK:道头)是每一道的描述区域,位于每一道的最开始位置,其中包含了数据长度、采样点数、数据格式等信息。
读取完道头以后接下来读取的就是每一道的实际数据了,将其绘制出来即为每一道的波形图。
由于每激发一炮都有多道接收,因此每个seg2文件中都有很多道数据,可以根据文件头的指示找到每一道对应的位置并将其读取下来。
seg2文件头(FILE DESCRIPTOR BLOCK)
下图为文件头区域的0-15个字节(FILE DESCRIPTOR BLOCK :0-15),其中包含了几个重要的参数,例如 0-1字节中的BLOCK ID表示该文件为seg2文件,如果BLOCK ID不等于3a55或者553a,则说明该文件不是seg2文件;6-7字节中的N=Number of traces显示了该文件总共有几道数据。
实际读取结果:
下图为头文件的16-31字节是保留字段,是为了之后的扩展而准备的;而之后的字节保存的则是道指针,每个指针占据4个字节,道指针的数目和道数是相同的。
读取的道指针:
道指针的后面则保存了一系列的键值对,如下图所示:
实际读取结果如下:
seg2道头(TRACE DESCRIPTOR BLOCK)
首先0-1字节为block id,若值为4422或者2244(16进制),说明该文件为seg2文件,否则不是seg2文件;
2-3字节代表该区域的大小,8-11字节代表了采样数,第12字节是非常重要的一个参数,其代表了地震数据的格式,其值为1-5,1代表数据为short型,2代表数据为long型,3代表数据为unsigned char,4代表数据为float,5代表数据为double型。
读取结果:
剩下的字段为保留字段和一些键值对信息。
实际读取结果如下:
seg2实际数据
在道头后面的存储区域即为实际数据的存储位置,直接根据采样点数和数据格式即可将数据全部读取下来,读取结果如下:
读取代码
#include
#define MAXSAMP 4096
intmain(void)
{
FILE*f;
f=fopen("data/DX30_1.sg2","rb");
//读取blockid
shortblockid;
fread(&blockid,2,1,f);
printf("blockid %x\n",blockid);
//读取revnum
shortrevnum;
fread(&revnum,2,1,f);
printf("revnum %d\n",revnum);
//读取pointerbytecount
shortpointerbytecount;
fread(&pointerbytecount,2,1,f);
printf("pointerbytecount %d\n",pointerbytecount);
//读取numtrace
shortnumtrace;
fread(&numtrace,2,1,f);
printf("numtrace %d\n",numtrace);
//读取stringtermcount
charstringtermcount;
fread(&stringtermcount,1,1,f);
printf("stringtermcount %d\n",stringtermcount);
//读取stringterm1
charstringterm1;
fread(&stringterm1,1,1,f);
printf("stringterm1 %d\n",stringterm1);
//读取stringterm2
charstringterm2;
fread(&stringterm2,1,1,f);
printf("stringterm2 %d\n",stringterm2);
//读取linetermcount
charlinetermcount;
fread(&linetermcount,1,1,f);
printf("linetermcount %d\n",linetermcount);
//读取lineterm1
charlineterm1;
fread(&lineterm1,1,1,f);
printf("lineterm1 %d\n",lineterm1);
//读取lineterm2
charlineterm2;
fread(&lineterm2,1,1,f);
printf("lineterm2 %d\n",lineterm2);
//读取保留区域18字节
charreserved[19];
fread(reserved,1,18,f);
//读取tracepointers
longtracepointers[numtrace];
fread(tracepointers,4,numtrace,f);
printf("tracepointers\n");
{
inti;
for(i=;i
printf("%ld\n",tracepointers[i]);
}
}
//读取文件描述区域
//读取stringlength
shortstringlength;
fread(&stringlength,2,1,f);
// printf("stringlength %d\n", stringlength);
//读取文件描述区域的每一行
charstring1[200];
while(!=stringlength) {
//读取整个字符串,包含了关键字和参数,string1是一个全局变量
//读取字符串长度-2,因为后两个字节表示下一个字符串的长度
fread(string1,1,stringlength-2,f);
printf("%s\n",string1);
//读取下一个字符串长度
fread(&stringlength,2,1,f);
// printf("nextStringlength %d\n", stringlength);
}
//读取每一道数据
long*linbuf;
linbuf=(long*)malloc(MAXSAMP*numtrace*sizeof(long));
inti,k;
FILE*test;
test=fopen("data/test2.txt","w");
fclose(test);
for(i=;i
printf("trace %d\n",i);
//找到每道的起始位置
fseek(f,tracepointers[i],SEEK_SET);
//读取blockid
fread(&blockid,2,1,f);
printf("blockid %x\n",blockid);
//读取blocklen
unsignedshortblocklen;
fread(&blocklen,2,1,f);
printf("blocklen %u\n",blocklen);
//读取datalen
unsignedlongdatalen;
fread(&datalen,4,1,f);
printf("datalen %lu\n",datalen);
//读取numsamples
unsignedlongnumsamples;
fread(&numsamples,4,1,f);
printf("numsamples %lu\n",numsamples);
//读取datatype
unsignedchardatatype;
fread(&datatype,1,1,f);
printf("datatype %d\n",datatype);
//读取保留字段
fread(reserved,1,19,f);
//读取stringlen
fread(&stringlength,2,1,f);
// printf("stringlength %d\n", stringlength);
while(!=stringlength) {
//读取整个字符串,包含了关键字和参数,string1是一个全局变量
//读取字符串长度-2,因为后两个字节表示下一个字符串的长度
fread(string1,1,stringlength-2,f);
printf("%s\n",string1);
//读取下一个字符串长度
fread(&stringlength,2,1,f);
// printf("nextStringlength %d\n", stringlength);
}
//读取实际数据
fseek(f,blocklen+tracepointers[i],SEEK_SET);
fread(linbuf,4, (int)numsamples,f);
test=fopen("data/test2.txt","a");
for(k=;k
fprintf(test,"%ld\n",linbuf[k]);
}
fclose(test);
}
free(linbuf);
return;
}
领取专属 10元无门槛券
私享最新 技术干货