Visual Basic语言在地震数据读取与格式转换中的应用研究

2022-03-05 06:42陈新党
资源信息与工程 2022年1期
关键词:字节间隔标准

付 波, 陈新党

(江西省地质调查勘查院,江西 南昌 330001)

0 引言

地震勘探作为一种地球物理方法,原始数据的重要性不言而喻。每个行业或多或少都有自己的行业标准和数据存储标准,现在一般的地震仪器野外数据采集大多数采用的数据存储格式为行业中的标准格式,较为通用的是野外采集原始地震数据格式为SEG委员会提出的SEG-Y和SEG-D[1-4]。而在实际生产中,部分野外采集的原始地震数据与 SEG 协会相关标准存在着偏差,和标准原始地震数据有一定的差别。对于此类数据,现有处理系统和解编专业软件无法识别和读取,给地震资料处理生产工作造成了极大的困难。

对于每一种地球物理方法,原始数据是至关重要的,地震勘探也不例外。对原始数据进行解编和转储是数据处理的前提,但是由于标准格式还没有全面推广,导致某些仪器所采集到的数据不是标准格式,使得解编存储无法进行,地震资料处理工作无法进行。还有地震数据格式的行业标准大多是由国外的相关机构和行业协会提出的,国内使用的大部分地震资料处理软件也是由国外软件公司开发的。这种现状导致国内自主创新的方法和技术难于在实际数据处理方面运用。因此,对于不是标准格式的数据文件的转储处理问题的研究很必要,本文主要研究关于非标准格式的数据文件转为SEG委员会提取的标准格式SEGY的过程,通过Visual Basic语言来实现文件数据的读入和写出,在程序中加入了成图程序,将每炮的数据成图,用于验证数据读入的正确性。

1 SEGY标准格式说明

最早的SEGY数据交换格式是在1975年出版的,在2002年修订了一些条目。现在标准的SEGY格式主要由两部分构成,分别是文件头和道记录块[1-4](图1)。

文件头道头1数据1道头2数据2……

其中,文件头包含两部分:前3 200个字节为ASCII 区域,包含40行原文信息,提供SEGY文件中地震数据的可读性描述;后400个字节为二进制数区域,在二进制文件头中的值定义为2字节或4字节,两者是等效的整数,这些中包含了采样间隔、道长和编码格式的重要信息[4]。

3 217~3 218字节-采样间隔(μs)

3 221~3 222字节-样点数/每道(道长)

3 225~3 226字节-数据采样格式编码。

1=4字节IBM浮点数

2=4字节,两互补整数

3=2字节,两互补整数

4=4字节带增益定点数(过时,不再使用)

5=4字节IEEE浮点数

6=现在没有使用

7=现在没有使用

8=1字节,两互补整数

道记录块包含了道头和数据块,其摆列方式为一炮接着一炮,其中道头有240个字节组成,紧接着是此道的数据,每一道都有占240个字节的道头。其中道头包含的值有限并用来提供可能道间变化信息和处理、道识别的基本信息,在240个字节中采样点、采样间隔和炮号的记录很重要。数据块中每个样点值为浮点型数据,以二进制方式存储。

9-12 原始的野外记录号(炮号)

115-116 本道的采样点数

117-118 本道的采样间隔,以μs表示。

2 VB实现

2.1 格式转换流程

在有道头和数据的文件下,通过Visual Basic程序,选取SEGY标准数据格式文件的文件头和标准道头,改变其中的道头的炮号,文件头中采样间隔、采样点和采样长度等参数;再读取24道含有数据的文件,通过加载标准文件头,每道数据加上道头,这样就成了标准的SEGY格式了。

步骤:1.打开模型数据取卷头道头;2.dat文件转为sgy;3.sgy文件改变炮号[5-6]。

图2 Visual Basic可视化界面

2.2 文件头和道头的提取

在Visual Basic界面运行下先输入样点个数,采样间隔→再按打开模型数据取卷头道头。在模型数据文件目录下就会生成卷头文件juan和道头文件dat。先定义一个动态字节数组变量,在提取文件头时,就定为3 600个字节长度;在提取道头时定为240个字节长度。改变其中的采样间隔和道长参数,分别放在两个文件下,为后面数据转换做准备。程序如下:

Private Sub juandaoClick()

Dim char() As Byte ‘定义一维动态字节数组用于存储文件头和道头

Dim yuan As String ‘标准的SEGY格式文件名变量

Dim fen1 As String

Dim fen2 As String

Dim a As Integer

Dim b As Integer

‘需要打开一个sgy的文件,在它的目录下会生成卷头文件juan和道头文件dao,在用于转换时,需要将两文件放入要特定的文件下

CommonDialog1.Filter="所有文件 (*.*)|*.*|"& _

"道号数据文件(*.sgy)|*.sgy"

CommonDialog1.FilterIndex = 2

CommonDialog1.ShowOpen

yuan = CommonDialog1.FileName

On Error Resume Next

fen1 = Replace(yuan, "MdlReel", "juan")

fen2 = Replace(yuan, "MdlReel", "dao")

Open yuan For Binary As #1

Open fen1 For Binary As #2

Open fen2 For Binary As #3

a = Text2.Text

b = Text3.Text

‘从标准的SEGY文件中提取文件头并更改其中的采样间隔和道长

ReDimchar(3 600 -1)

For i = 0 To 3 599

Get #1, i + 1, char(i)

Next

Put #2, , char()

Put #2, 3217, b

Put #2, 3221, a

‘从标准的SEGY文件中提取道头并更改其中的采样间隔和道长

ReDimchar(240 -1)

Get #1, 3601, char()

Put #3, , char()

End Sub

2.3 文件头、道头和数据的合并与成图

在Visual Basic运行下,输入采样点数,再按dat-sgy,在原数据文件下就会生成后缀为sgy的文件,同时在Visual Basic窗口下会生成地震记录的图形。通过一个文件对话框,打开你想转换格式的数据(dat后缀)。原数据可能占两个字节或者四节。再通过读入原先有的文件头和道头就可以变为标准的SEGY格式了。程序如下:

Private Sub dat_Click()

Dim sh(1 To 3600) As Byte

Dim ch(1 To 240) As Byte

Dim char() As Byte

Dim dao As String

Dim zhong As String

Dim juan As String

Dim jian As String ‘作为存储数据的文件变量

Dim chong As String ‘作为存储道头和数据的文件变量

CommonDialog1.Filter="所有文件(*.*)|*.*|"&_

"道号数据文件(*.dat)|*.dat"

CommonDialog1.FilterIndex = 2

CommonDialog1.ShowOpen

filena = CommonDialog1.FileName

On Error Resume Next

zhong = Replace(filena, "dat", "sgy")

Label1 = zhong

chong = "d:sychong.sgy"‘必须保证你你的卷头道头在d:sy的目录之下(也可以将其改为其他路径)

dao = "d:sydao.sgy"

jian = "d:syjian.sgy"

juan = "d:syjuan.sgy"

Open chong For Binary As #101

Open dao For Binary As #42

Open zhong For Binary As #40

Open juan For Binary As #41

Open jian For Binary As #100

Open filena For Binary As #1

Dim singl() As Single

Dim inte() As Integer ‘(当你的每个数据只占两个字节使用)

Dim a As Single

Dim aa As Single

a = Val(Text2.Text)

ReDimsingl(1 To 24, 1 To a) As Single

ReDiminte(1 To 24, 1 To a) As Integer ‘(当你的每个数据只占两个字节使用)

ReDimchar(1 To 24, 1 To a * 4) As Byte

Dim t As Byte

If Val(Text4.Text) <> 4 Then

‘一个数据占二个字节使用

For j = 1 To 24

Seek #1, 241 + (a * 2 + 240) * (j - 1)

For k = 1 To a

Get #1, ,inte(j, k)

singl(j, k) = inte(j, k)

Put #100, (j - 1) * a * 4 + (k - 1) * 4 + 1, singl(j, k)

For m = 1 To 4

Get #100, (j - 1) * a * 4 + (k - 1) * 4 + m, char(j, (k - 1) * 4 + m)

Next m

Next k

Next j

Else

‘一个数据占四个字节使用

For j = 1 To 24

Seek #1, 241 + (a * 4 + 240) * (j - 1)

For k = 1 To a

Get #1, ,singl(j, k)

Put #100, (j - 1) * a * 4 + (k - 1) * 4 + 1, singl(j, k)

For m = 1 To 4

Get #100, (j - 1) * a * 4 + (k - 1) * 4 + m, char(j, (k - 1) * 4 + m)

Next m

Next k

Next j

End If

Dim g(1 To 24) As Single

Dim w As Integer

Dim h As Integer

Dim aal As Integer

Dim mm As Integer

Dim delt As Integer

mm = 1 * 2 ‘在vb中图形的放大倍数

delt = Text3.Text ‘采样间隔

Picture1.Cls

Picture1.ScaleMode = 1

Picture1.ScaleLeft = 0

Picture1.ScaleTop = 0

Picture1.ScaleWidth = Picture1.Width

Picture1.ScaleHeight = Picture1.Height

‘ (数据均衡

For il = 1 To 24

aa1 = 1

For ill = 1 To a

If (Abs(singl(il, ill)) > aa1) Then

aa1 = Abs(singl(il, ill))

End If

Next ill

g(il) = ((Picture1.ScaleHeight - 10) / 24) / aa1

Next il

‘数据均衡)

h = (Picture1.ScaleWidth - 10) / 25

w = (Picture1.ScaleHeight - 10) / a

For ii = 1 To 24

For ii1 = 1 To a

If ((singl(ii, ii1)) > 0) Then

Picture1.Line (10+ii*h,10+ii1*w)-(10+ii*h+singl(ii, ii1)*g(ii)*mm, 10+(ii1+1)*w),,BF

Else

Picture1.Line (10 + ii * h + singl(ii, ii1) * g(ii) * mm, 10 + ii1 * w)-(10 + ii * h + singl(ii, ii1 + 1) * g(ii) * mm, 10 + (ii1 + 1) * w), vbBlack

End If

Next ii1

Next ii

For j1 = 1 To 24

Picture1.CurrentX = 5 + j1 * h

Picture1.CurrentY = 5

Picture1.Print j1

Picture1.Line (10 + j1 * h, 10)-(10 + j1 * h, Picture1.ScaleHeight)

Next j1

For i = 1 To 11

Picture1.Line (10, 10 + (i - 1) * w * 50)-(Picture1.ScaleWidth, 10 + (i - 1) * w * 50), vbGreen

Picture1.CurrentX = 0

Picture1.CurrentY = 10 + (i - 1) * w * 50

Picture1.Print (i - 1) * delt * 50

Next i

‘读入道头,循环分别放在101编号代表的文件中的特定位置并将以上的二维字节数组数据放入其特定位置,使之按道头→第一道数据→道头→第二道数据…顺序存储

Get #42, ,ch()

For ii = 1 To 24

Seek #101, (4 * a + 240) * (ii - 1) + 1

Put #101, ,ch()

Next ii

For m = 1 To 24

For n = 1 To 4 * a

Put #101, (4 * a + 240) * (m - 1) + n + 240, char(m, n)

Next n

Next m

‘读入文件头并将其放入zhong变量代表的文件中

For m = 1 To 3600

Get #41, m, sh(m)

Next m

Put #40, 1, sh()

aa = 24 * (a * 4 + 240)

ReDimchar(1 To aa)

For i = 1 Toaa

Get #101, i, char(i)

Next i

‘将一维字节数组中的字节放入zhong变量代表的文件中

Seek #40, 3601

Put #40, , char()

Close

End Sub

2.4 SGY改变炮号

按要求输入野外炮号标记,在按sgy改变炮号。由于合并的sgy文件炮号没有按实际给出,使得在后续处理时存在困难,所以通过改变sgy文件中特定字节代表炮号的值来达到目的。

3 成果验证

使用某地区的地震数据,其源格式中样点值占两个字节,文件结构为以上程序所需的源格式。主要用于反射波地震勘探,图3(a)是第一炮在vista软件中所成的图形,图3(b)是使用Visual Basic界面识别读取的数据,可以看出vista和Visual Basic界面所成的图形一样,验证了程序转换的正确性。

4 结论

通过对比某地区的某炮原始数据Visual Basic界面读取成图与vista软件中所成的图形,表明可以使用Visual Basic的可视化界面实现文件数据的读入和写出,并在程序中加入了成图程序,将每炮的数据成图,用于验证数据读入的正确性,对于地震数据格式不匹配而需要转换具有一定的参考意义。

猜你喜欢
字节间隔标准
No.11 字节跳动计划自研芯片:仅供内部使用
最新出版团体标准
字节跳动瞄准教育等新业务
忠诚的标准
党员标准是什么?
间隔,是为了找到更好的自己
上楼梯的学问
优秀作品的标准
人类进入“泽它时代”
头夹球接力