logo资料库

c语言读写sgy格式.pdf

第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
资料共16页,剩余部分请下载后查看
Author: Yangwqcumt 用用 CC 语语言言读读写写 SSGGYY 格格式式的的地地震震数数据据 Yangwqcumt 百度专用,转载需授权 地震勘探野外采集的数据,以及经过资料处理获得的三维数据 体,只要是放在计算机里,都是以二进制文件的形式存放的。这些文 件的处理显示等工作,一般都可以用商业化的软件进行。但是作为一 个从事地震勘探研究的技术人员,有时会有些想法,有某种灵感,但 是原有的软件又不允许你去做某种试验以验证你的想法。这时候,自 编个小程序显然有必要,而且弄好后你的成就感会很强烈。 1. SEGY 格式地震数据文件 地震数据,是以各种格式存放的。所谓格式,指的是地震数据以 及各种信息在文件内部的存放方式及顺序。 常见的地震数据格式,有 segy 格式、seg2 格式、segd 格式等。 同样的格式,还有微机版、工作站版及其它版本。 本文仅是入门级材料,我们仅就微机版 segy 格式进行分析。 Segy 格式的地震数据文件,属于典型的流式文件,它的信息和 数据都是按字节顺序一个个地存放的,每个字节都有其特定的含义。 这种格式的文件,由文件头部的 3600 字节以及地震道组成。 文件头前部的 3200 字节共分为 40 行,每行 80 个字符,但这些 字符不是 ascii 码,是一种称为 ebcdic 的编码。一般这部分都不去 读,或者只能显示出来查看其中的内容。 接下来是 400 字节的二进制部分。这里面有长整型数和短整型 数,其具体含义参见附录一。
Author: Yangwqcumt 每个地震道由道头 240 字节(参见附录一)和地震数据组成。地 震数据的个数和类型(指它是浮点数整数还是什么)文件头中有定义。 此处我们假定所有的数据都是微机的四字节浮点数。 2. 文件头部 3200 字节特殊编码部分的读取。 该部分共分为40行,每行80个字符,但这些字符不是ascii码,是一 种称为ebcdic的编码。转换成ascii码可以采用查表的方法进行。一 般处理地震数据不用读这部分的内容。 #include "stdio.h" #include "stdlib.h" void main() { unsigned char E2A[256]={ 0, 1, 2, 3,156, 9,134,127,151,141,142, 11, 12, 13, 14, 15, 16, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31, 128,129,130,131,132,10,23, 27,136,137,138,139,140, 5, 6, 7, 144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26, 32,160,161,162,163,164,165,166,167,168, 91, 46, 60, 40, 43, 33, 38,169,170,171,172,173,174,175,176,177, 93, 36, 42, 41, 59, 94, 45, 47,178,179,180,181,182,183,184,185,124, 44, 37, 95, 62, 63, 186,187,188,189,190,191,192,193,194, 96, 58, 35, 64, 39, 61, 34, 195, 97, 98, 99,100,101,102,103,104,105,196,197,198,199,200,201, 202,106,107,108,109,110,111,112,113,114,203,204,205,206,207, 208,209,126,115,116,117,118,119,120,121,122,210,211,212,213,214,215, 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231, 123, 65, 66, 67, 68, 69, 70,71, 72, 73,232,233,234,235,236,237, 125, 74, 75, 76, 77,78,79,80,81,82,238,239,240,241,242,243, 92,159, 83, 84, 85, 86, 87, 88, 89, 90,244,245,246,247,248,249, 48,49, 50, 51, 52, 53, 54, 55, 56, 57,250,251,252,253,254,255}; int i,j; unsigned char f3200[3200]; FILE *f1; char s1[200]; printf("Input Sgy File Name:\n"); scanf("%s",s1); //输入文件名 f1=fopen(s1,"rb"); fread(f3200,3200,1,f1); fclose(f1); for(i=0;i<40;i++) { for(j=0;j<80;j++) printf("%c",E2A[f3200[i*80+j]]); } printf("\n"); }
Author: Yangwqcumt 3. 文件头 400 字节二进制部分的读取 可以把 400 字节作为若干个长整型及短整型数据读入: #include "stdio.h" #include "stdlib.h" void main() { FILE *f1; int i,l; int traces; unsigned char f3200[3200]; char FileName[200]; long int s1[100]; short int s2[200]; printf("输入地震文件名[*.sgy]:"); scanf("%s",FileName); f1=fopen(FileName,"rb"); if(f1==NULL) //文件打开不成就显示错误信息,然后退出。 { printf("File Open error!\n"); exit(0); } fread(f3200,3200,1,f1); //读入前面的字节 fread(s1,400,1,f1); //读入接着的字节,作为长整型数 fseek(f1,3200,0); //退回去, fread(s2,400,1,f1); //再以短整型数读入那些个字节 ////////////////////////////////// for(i=0;i<3;i++) printf("[%d]:%d \n",i+1,s1[i]); //显示文件头格式说明中的二进制部分的前三项 for(i=3;i<15;i++) //显示4-1,4-2,。。。,15-1,15-2 { } printf("[%d-1]:%d \n",i+1,s2[2*i]); printf("[%d-2]:%d \n",i+1,s2[2*i+1]); ////////////////////////////////// /* 在文件头中,最重要的是下面几项: 5-1:这个文件的地震道的时间采样间隔,单位是微秒; 6-1:每个地震道的样点数; 7-1:数据的格式。现在一般都是四字节的浮点数,格式取. */ printf("时间采样间隔[微秒]:%d\n",s2[8]); printf("地震道的样点数:%d\n",s2[10]); printf("数据格式代码:%d\n",s2[12]); /* 有了这些信息,这个文件含有的地震道数是多少呢?
Author: Yangwqcumt 若文件长度: l 则道数:traces=(l-3600)/(240+s2[10]*4) */ fseek(f1,0,2); // l=ftell(f1); //l此时就是文件的字节数; printf("文件的长度=%d\n",l); traces=(l-3600)/(240+4*s2[10]); printf("地震道数是:%d\n",traces); fclose(f1); } 也可以把那个 400 字节作为一个结构体,该结构体定义见附录二。 //这个例子使用了结构体来读取文件头信息 #include "stdio.h" #include "stdlib.h" #include "segyHeader.h" void main() { FILE *f1; int i,l; int traces,trace_length; char FileName[]="100.sgy"; struct SegyReelHdrStruct FileHeader; f1=fopen(FileName,"rb"); if(f1==NULL) //文件打开不成就显示错误信息,然后退出。 { } printf("File Open error!\n"); exit(0); fread(&FileHeader,sizeof(FileHeader),1,f1); trace_length=FileHeader.hns; printf("%s:%d\n","时间采样间隔[微秒]",FileHeader.hdt); printf("%s:%d\n","每道的样点数",FileHeader.hns); printf("%s:%d\n","数据的格式代号",FileHeader.format); fseek(f1,0,2); // l=ftell(f1); //l此时就是文件的字节数; printf("文件的长度[字节数]=%d\n",l); traces=(l-3600)/(240+4*trace_length); fclose(f1); printf("%s:%d\n","地震道数",traces); } 4. 某道数据的读取
Author: Yangwqcumt include "stdio.h" //包含头文件 #include "string.h" // #include "stdlib.h" // void main() { FILE *f1,*f2; //定义两个文件指针变量 int i,l; char FileName[200]; //字符数组,存放文件名 int Traces,Trace_length,Trace2read; //顾名思义,这几个变量用来存放:地震道数、地震道的长度、要读的那一个地震道的序号 float *TraceData; //定义一个浮点型的指针,一会儿开辟内存后放一个地震道的数据 /////////////////////////获得地震那个文件名/////////// printf("输入地震文件名[*.sgy]:"); scanf("%s",FileName); //当然上面两行,可用一个这样的语句代替:strcpy(FileName,"100.sgy"); f1=fopen(FileName,"rb"); //打开文件,打开形式为:二进制读 rb if(f1==NULL) //判断打开了没有,不成功就返回吧。 { } printf("Cannot open input file!\n"); //显示信息 exit(0); //退出 Trace2read=430; // 要读取哪一道,可以键盘输入,为方便在这就给定了,设为第430道 Trace_length=800; //一个地震道里面 数据的个数,可以从文件头获得,这里先拿来用了 Traces=631; //该文件地震道的个数,也可以通过文件头里面的信息设法获得,也是先拿来用 l=3600L+(240+Trace_length*4L)*(Trace2read)+240; //要读取的那一个地震道的,数据部分,在这个文件中的开始的位置,这个很重要,下面做点说明 /* 一般来说,地震勘探的数据文件是有格式的。所谓格式,就是地震数据、及相关的信息在地震文件 中的存放顺序。 现在研究的这个叫做sgy格式。这种格式比较普遍。它由文件头和地震道组成,文件头字节,每个 地震道由字节的道头和数据组成。 所以一个sgy格式的文件的组成为:3600字节+240字节+第一道数据+240字节+第二道数据+240字节+ 第三道数据+。。。。。。。 文件头部的字节以及每道的字节道头有信息,这个先不研究。 对于我们给的这个数据,道数据的长度800,是指个浮点数,所以其字节数要乘以,得到,加上字节的 道头,共计字节, 所以第道的开始位置,就是:+430*3440,然后由于我们不读这个地震道的道头,数据部分的位置还 要加, l=3600+3440*430+240; 请时刻注意,c的数组以及其他什么东西的编号多是从0开始的。 */ fseek(f1,l,0); //定位到那个地震道的 数据的 开始位置 TraceData=new float[Trace_length];
Author: Yangwqcumt //先开一块内存,要不数据没地方放,你看事先定好可以吗,比如:float TraceData[800]; fread(TraceData,4L*Trace_length,1,f1); /* 读数据了,嘿嘿。这个fread函数,括弧内有四个东西: 第一个,读了数据放在哪,可以是数组名或者指针 第二个:一次读入多少字节 第三个:读多少次, 第四个,文件指针 看起来,里面的第二个和第三个,暂时叫参数吧,是可以互换的, 但是这个,我猜测它的读取的速度不同,没有验证过。 与他对应的有个二进制写的函数,叫做fwrite();里面也有四个参数,四个参数的意义也和fread一样, 只是那个文件指针是要写出的文件的指针 */ fclose(f1); //记得用完文件要关闭,有的时候,没有关闭动作数据会被破坏,是教材上这么说的,我也都是这么做的 f2=fopen("aline.txt","w"); //打开一个文件文件,用来输出,一会你运行完了看看aline.txt里面的内容 for(i=0;i
Author: Yangwqcumt short int f400[200]; //文件头的字节二进制部分 float xmax; //用来存放某一个地震道的绝对值最大值 char Trace_header[240]; float *tracedata;//浮点型的指针,用来开辟内存,放置地震道的数据 ////////////////////////////////////////////////////////////// printf("输入文件名[*.sgy]:\n"); scanf("%s",inputfile); printf("输出文件名[*.sgy]:\n"); scanf("%s",outputfile); //////////////////////////////////////////////////////////// filein=fopen(inputfile,"rb"); if(filein==NULL) { } printf("Can not open File %s\n",inputfile); exit(0); /////////////////////////////////////////////////////////// fileout=fopen(outputfile,"wb"); if(filein==NULL) { } printf("Can not open File %s \n",outputfile); fclose(filein); exit(0); fread(f3200,3200,1,filein); //读入3200字节文件头部分 fread(f400,400,1,filein); //读入400字节文件头部分 samp_interval=f400[8]; trace_length=f400[11]; fseek(filein,0,2); l=ftell(filein); traces=(l-3600)/(240+4L*trace_length); fseek(filein,3600,0); fwrite(f3200,3200,1,fileout);//写出3200字节 fwrite(f400,400,1,fileout);//写出400字节 tracedata=new float[trace_length]; for(i=0;i
Author: Yangwqcumt xmax=fabs(tracedata[0]); for(j=1;j0) //如果非0,就对每个数据除以该最大 { } for(j=0;j
分享到:
收藏