前言:最近有个同仁急用一个测井数据文件,但数据为二进制,他利用各种软件,尝试了la716、bit、lis、dlis、tif、wis等等格式进行解编都没有成功,由于在勘探风暴公众号中看到我解编过segy数据就与我探讨。通过对二进制文件的分析,我对这个数据文件解编成了ASCII码格式,今天与大家一起分享,不过整个过程充满了猜想和运气,实属偶然。
一、二进制文件分析
大多数非测井专业的人遇到数据大部分都是las等ASCII码格式的文件,可以很容易的使用,可以加载到各种软件中进行合成地震记录的制作、小层划分及对比等工作,相信大家接触二进制文件不多。但现场或者解释处理的人存储的格式一般都是二进制,比如我们常见的WIS格式,LA716及BIT等等,尽管二进制只要告诉了格式,是很容易转换成las或者一般的txt文件的,这里不再赘述,感兴趣的可以查阅测井数据格式的相关文献。
把文件直接拖入UltraEdit编辑器,在文件的开始可以清楚的看到'XX石油局"
以及井名的相关信息(1、2),下面也看到了一堆测井曲线的名字(3),首先推测这是文件头,可以参照BIT、la716等格式,很像。分析来看,前面有4个字节像ECC,80个字节存测井单位信息,若干字节存曲线名称。
对照La716格式,分析这个文件应该是个自定义的类la716格式的二进制文件,重点应该是分析出标题块的信息。
对照上图分析在曲线名前应该是曲线条数,找到了16进制的16,转换成十进制是22,按照每四个字节一个曲线来对比,正好也是22条曲线。(显示的十六进制的20实际是ASCII码中的空格)。
进一步分析红色(4)部分应该含有测井的起始、终止深度和采样间隔等数据通过了解本井的测井起始是6700.6米,终止是7387.0m,推测应该是用分米作为计数单位,算出的数据换成m需要除以10,因此采样间隔是0.1m。
二进制转换时要注意PC格式和SUN格式浮点数的存贮是存在差别的。
5红框到文件结尾应该是测井数据,文件头为512字节。这就是一个变异了的la716格式文件。
二、文件的解编
根据分析,利用fortran程序对二进制文件进行了解编。解编程序如下:
program la2txt
implicit none
!字头定义总共512字节
type La716Head
character(len=4) ECC ! 成果号,每个测井中心所分配的代码
character(len=80) ICO ! 公司名
character(len=80) IWELL ! 井名
integer(kind=2) NUMLOG ! 曲线数目
integer(kind=2) BAK1 ! 单位
character(len=4) LOGNAM(64) ! 曲线名,最多4个字节
real(kind=4) STDEP ! 起始深度
real(kind=4) ENDEP ! 终止深度
real(kind=4) RLEV ! 采样间隔
character(len=76) BakCha ! 备用字节
end type
real(kind=4),allocatable::Real_data(:) !定义一个动态存储数组准备存储每一个采样点的曲线数据
real(kind=4) data_rlev,data_stdep,data_endep!定义变量
type(La716Head) usrlahead
integer(kind=4) i,j,numsamples,lognum
character(len=80) lafile,txtfile !定义输入输出的文件名
!输入输出文件
write(*,*)"------------------------------------------------------------------------------"
write(*,*)"输入需要转换的文件:"
read(*,*)lafile
write(*,*)"输入转出的ascii码文件:"
read(*,*)txtfile
write(*,*)"------------------------------------------------------------------------------"
!读写文件
open(2,file=txtfile)
!把数据头读出
open (1,file=lafile,access='direct',form='binary',recl=512)
read(1,rec=1)usrlahead
lognum=usrlahead%Numlog !得到曲线数目
data_stdep=usrlahead%stdep/10 !得到起始深度
data_endep=usrlahead%endep/10 !得到终止深度
data_rlev=usrlahead%rlev/10 !得到采样间隔
!计算全部样点数目
numsamples=int((data_endep-data_stdep)/data_rlev)+1
!给动态数组按照得到的曲线数目进行定义
allocate(Real_data(lognum))
close(1)
!把得到的基本信息写入输出文件
write(2,*)"------------------------------------------------------------------------------"
write(2,10)"起始深度:",data_stdep
write(2,10)"结束深度:",data_endep
write(2,10)"采样间隔:",data_rlev
write(2,11)"曲线条数:",lognum
write(2,12)"曲线名称: ",(usrlahead%lognam(i),i=1,lognum)
write(2,*)"------------------------------------------------------------------------------"
10 format(A10,F10.3)
11 format(A10,I4)
12 format(A11,A5)
!在文件中按格式写入深度及曲线名
write(2,13)"DEPTH",(usrlahead%lognam(i),i=1,lognum)
13 format(5x,A5,A12)
14 format(2x,F10.3,F12.3)
!从文件中直接读取每个样点的测井曲线数值并写入到文件中转换成ASCII码
open (1,file=lafile,access='direct',form='binary',recl=4)
do j=1,numsamples
read(1,rec=129+(j-1)*lognum)(real_data(i),i=1,lognum)
write(2,14)data_stdep+(j-1)*data_rlev, (real_data(i),i=1,lognum)
enddo
close(1)
close(2)
end program
程序十分简单,主要是输入输出的一些简单操作,如果大家觉得有用可以参考(我编程实在是不行)。
三、解编的结果
通过对解编数据的分析,重点是井径、bit数据分析来看,与实际钻井中使用的钻头一致,数据的解编应该是正确的。
结束语:
在实际工作中,如果能开动脑筋想想我们学过的基本知识,然后结合一些数据处理和编程会解决很多问题,可以事半功倍。希望我的分析对你有一点点小的用处,欢迎大家点击“在看”。