GeophyAI

Python与地球物理数据处理

0%

如何在Python环境中使用Madagascrar函数

Madagascrar-python

这里简单讲解如何在python中使用Madagascrar中的函数,读者需要自行安装好swigMadagascrarpythonnumpy等环境。

实际应用中有下列网址可供参考:
Madagascrar官方:https://reproducibility.org/wiki/Main_Page
Madagascrar模块介绍:https://reproducibility.org/RSF/
SWIG官方:http://www.swig.org/tutorial.html

安装完Madagascrar之后,即可在python中调用m8r module来使用其中的各种函数,本文以源码下/src/bei/ft1/autocor/SConstruct为例简单讲述如何在python中调用Madagascrar中的函数。autocor源码主要展示了利用spikecausint函数来创建不同信号。我们经常需要在python脚本中实现各类数学变换以满足开发需求,通过python调用Madagascrar中相关函数的方式能够极大的简化我们的开发过程,提升开发效率。

首先,在/src/bei/ft1/autocor路径下打开terminal,执行scons命令,即可按照脚本SConstruct中命令的顺序获得所需要的文件,下面我们逐条语句解释SConstruct中出现的各种Madagascrar命令,并以纯numpy语句和pythonMadagascrar语句(m8r.command)两种形式来实现相同功能。以下语句均在Linux环境下Jupyter notebook中完成。

引入相关模块

1
2
3
4
5
6
7
8
9
10
11
import m8r, os, math
import numpy as np
import matplotlib.pyplot as plt
n1 = 128
def integrate(d):
t = 0
d_copy = np.zeros_like(d)
for i in range(n1):
t += d[i]
d_copy[i] += t
return d_copy

Spike

SConstruct源码

1
Flow('spike',None,'spike n1=%d o1=0 d1=1 label1=" " ' % n1)

该语句通过spike函数(可在terminal中输入sfspike查看该函数的功能及所需参数,当需要查看Flow中出现函数的doc时,需要在该命令前加前缀sf)创建了一个共n1=128个采样点、每个采样点的值均为1的一维信号,并将其生成的文件保存在./spike.rsf中。

python中读取rsf文件,需要用到m8r中的Input函数:

1
spike_file = m8r.Input(os.path.join(root_path, 'spike.rsf'))

当需要读取该文件中的数据时,需要用的read方法:
1
spike = spike_file.read()

此时,./spike.rsf文件中的数据就已经被保存到了名为spikenumpy变量中。

m8r方法

使用如下语句即可在python中调用Madagascrar函数:

1
2
3
4
n1 = 128
spike_op = m8r.spike(n1=n1, o1=0, d1=1, label1=" ")
spike2 = np.zeros(n1)
spike2 = spike_op.apply(spike2)

首先,m8r.spike(n1=n1, o1=0, d1=1, label1=" ")创建了一个operation赋值给spike_op,表示需要进行的运算;同时我们创建一个元素均为0的一维数据spike2,其数据类型为float64,使用spike_opapply方法即可即可将该运算的结果赋值给spike2,此时spike2的数据类型已经变为了float32

numpy方法

1
2
n1 = 128
spike3 = np.ones(n1, dtype=np.float32)

使用plt.plot对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
spike01

Cos

该示例使用math函数生成了一个角频率为(2*math.pi*6/n1)的弦信号。

SConstruct源码

1
Flow('cos','spike','math output="cos(%g*x1)" ' % (2*math.pi*6/n1))

读取源码所生成的数据:

1
2
cos_file = m8r.Input(os.path.join(root_path, 'cos.rsf'))
cos = cos_file.read()

m8r方法

1
2
cos_op = m8r.math(output="cos(%g*x1)"%((2*np.pi*6/n1)))
cos2 = np.zeros(n1, dtype=np.float32)

numpy方法

1
2
3
w = 2*np.pi*6/n1
x = np.arange(0, n1, 1, dtype=np.float32)
cos3 = np.cos(w*(x)).astype(np.float32)

使用plt.plot对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
cos

Sinc

该示例通过spike函数生成了一个采样函数。

SConstruct源码

1
2
3
Flow('sinc','spike',
'math output="%g*(x1+%g)" | math output="sin(input)/input" ' %
(12*math.pi/n1,1-0.001-n1//2)

读取数据:

1
2
sinc_file = m8r.Input(os.path.join(root_path, 'sinc.rsf'))
sinc = sinc_file.read()

m8r方法

1
2
3
4
sinc_op1 = m8r.math(output="%g*(x1+%g)"%((12*np.pi/n1,1-0.001-n1//2)))
sinc_op2 = m8r.math(output="sin(input)/input")
sinc2 = np.zeros(n1)
sinc2 = sinc_op2.apply(sinc_op1.apply(sinc2))

numpy方法

1
2
x = (12*math.pi/n1)*(np.arange(0, n1, 1)+1-0.001-n1//2)
sinc3 = np.sin(x)/x

使用plt.plot对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
sinc

Widebox

该示例使用spike生成了一个有两个尖脉冲的信号,并使用causint对其积分得到门信号。

SConstruct源码

1
2
3
Flow('widebox',None,
'spike n1=%d o1=0 d1=1 nsp=2 k1=%d,%d mag=1,-1 | causint' %
(n1,n1//8+1,n1//8+3*n1//16))

m8r方法

1
2
3
4
5
6
7
widebox_op1 = m8r.spike(n1=n1, o1=0, d1=1, nsp=2, k1=[n1//8+1,n1//8+3*n1//16], mag=[1,-1])
# signal
widebox2 = np.zeros(n1)
widebox2 = widebox_op1.apply(widebox2)
# apply intergrate
widebox_op2 = m8r.causint()
widebox2 = widebox_op2.apply(widebox2)

numpy方法

1
2
3
4
5
6
7
8

widebox3 = np.zeros(n1)
widebox3[n1//8] = 1
widebox3[n1//8+3*n1//16-1] = -1

temp = np.zeros_like(widebox3)
# apply intergrate
temp = integrate(widebox3)

使用plt.plot对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:

积分前:
widebox_a
积分后:
widebox_b

Narrowbox

与上类似。

SConstruct源码

1
2
3
Flow('narrowbox',None,
'spike n1=%d o1=0 d1=1 nsp=2 k1=%d,%d mag=1,-1 | causint' %
(n1,n1//8+1,n1//8+n1//16))

m8r方法

1
2
3
4
5
6
narrowbox_op1 = m8r.spike(n1=n1, o1=0, d1=1, nsp=2, k1=[n1//8+1,n1//8+n1//16], mag=[1,-1])
narrowbox2 = np.zeros(n1)
narrowbox2 = narrowbox_op1.apply(narrowbox2)
# apply intergrate
narrowbox_op2 = m8r.causint()
narrowbox2 = widebox_op2.apply(narrowbox2)

numpy方法

1
2
3
4
5
6
7
narrowbox3 = np.zeros(n1)
narrowbox3[n1//8] = 1
narrowbox3[n1//8+n1//16-1] = -1

temp = np.zeros_like(narrowbox3)
# apply intergrate
temp = integrate(narrowbox3)

使用plt.plot对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
积分前:
narrowbox_a
积分后:
narrowbox_b

Twin

该示例生成了一个具有两个尖脉冲的信号。

SConstruct源码

1
2
Flow('twin',None,
'spike n1=%d o1=0 d1=1 nsp=2 k1=1,%d' % (n1,1+3*n1//16))

m8r方法

1
2
3
twin_op = m8r.spike(n1=n1, o1=0, d1=1, nsp=2, k1=[1,1+3*n1//16])
twin = np.zeros(n1)
twin = twin_op.apply(twin)

numpy方法

1
2
3
twin2 = np.zeros(n1)
twin2[0] = 1
twin2[3*n1//16] = 1

使用plt.plot对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
twin

Double

该示例使用spike生成了一个具有四个尖脉冲的信号,并使用causint对其进行积分。

SConstruct源码

1
2
3
Flow('doublebox',None,
'spike n1=%d o1=0 d1=1 nsp=4 k1=1,%d,%d,%d mag=1,-1,1,-1 | causint' %
(n1,n1//16,1+3*n1//16,n1//16+3*n1//16))

m8r方法

1
2
3
4
5
double_op1 = m8r.spike(n1=n1, o1=0, d1=1, nsp=4, k1=[1, n1//16,1+3*n1//16,n1//16+3*n1//16],
mag=[1,-1,1,-1])
double_op2 = m8r.causint()
double2 = np.zeros(n1)
double2 = double_op1.apply(double2)

numpy方法

1
2
3
4
doublebox2 = np.zeros(n1)
for idx, value in zip([0,n1//16-1,3*n1//16,n1//16+3*n1//16-1], [1,-1,1,-1]):
doublebox2[idx] = value
doublebox2 = integrate(doublebox2)

使用plt.plot对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
积分前:
double_a
积分后:
double_b

Combs

SConstruct源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
combs = [
range(1,1+n1//2,4),
range(1,1+n1//4,4),
range(1,1+n1//2,8),
range(1,1+n1//4,8),
range(1,1+n1,32)
]
for case in range(len(combs)):
comb = combs[case]
name = 'comb%d' % case
Flow(name,None,
'spike n1=%d o1=0 d1=1 nsp=%d k1=%s' %
(n1,len(comb),','.join(map(str,comb))))
signals.append(name)
labels = labels + ':cmb%d' % (case+1)

m8r方法

1
2
3
4
5
comb_idx = 4 #\in [0,4)
assert comb_idx<=4, 'comb_idx must <= 4!'
k_list = [int(i) for i in map(str,combs[comb_idx])]
comb0_op = m8r.spike(n1=n1, o1=0, d1=1, nsp=len(combs[comb_idx]), k1=k_list)
comb0_2 = np.zeros(n1)

numpy方法

1
2
3
4
5
6
comb_idx = 4 #\in [0,4)
assert comb_idx<=4, 'comb_idx must <= 4!'
k_list = [int(i) for i in map(str,combs[comb_idx])]
comb0_3 = np.zeros(n1)
k_list2 = [i-1 for i in k_list]
comb0_3[k_list2]=1

使用plt.plot对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
comb04

Exponent

该示例使用math生成了指数型信号。

SConstruct源码

1
2
Flow('exponent','spike',
'math output="exp(-%g*(2*x1-%d))" ' % (8./n1,n1-2))

m8r方法

1
2
3
exponent2_op = m8r.math(output="exp(-%g*(2*x1-%d))"%(8./n1,n1-2))
exponent2 = np.zeros(n1)
exponent2 = exponent2_op.apply(exponent2)

numpy方法

1
2
x = np.arange(0, n1, 1)
exponent3 = np.exp(-(8./n1)*(2*x-(n1-2)))

使用plt.plot对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
exponent

Gaussian

该示例使用spikemath生成Gaussian信号。

SConstruct源码

1
2
3
Flow('gaussian','spike',
'math output="%g*(2*x1-%d)" | math output="exp(-input*input)" ' %
(8./n1,n1-2))

m8r方法

1
2
3
4
gaussian_op1 = m8r.math(output="%g*(2*x1-%d)"%(8./n1,n1-2))
gaussian_op2 = m8r.math(output="exp(-input*input)")
gaussian2 = np.ones(n1)
gaussian2 = gaussian_op2.apply(gaussian_op1.apply(gaussian2))

numpy方法

1
2
3
4
x = np.arange(0, n1, 1)
gaussian3 = np.zeros(n1)
gaussian3 = 8./n1*(2*x-(n1-2))
gaussian3 = np.exp(-gaussian3*gaussian3)

使用plt.plot对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
Gaussian

White

该示例使用noise生成白噪。

SConstruct源码

1
Flow('white','spike','noise type=n seed=1990 | math output="2*(input-1)" ')

m8r方法

1
2
3
4
white_op1 = m8r.noise(type=False, seed = 1990)
white_op2 = m8r.math(output="2*(input-1)")
white2 = np.ones(n1)
white2 = white_op2.apply(white_op1.apply(white2))

numpy方法

1
2
white3 = np.random.random(n1)+0.5
white3 = 2*(white3-1)

注:m8rnumpy种子设置方法不同,获取的随机数结果不同。

colored

该示例使用smooth对生成的白噪(m8r)信号进行平滑。

SConstruct源码

1
Flow('colored', 'white', 'smooth rect1=3')

m8r方法

1
2
3
colored_op = m8r.smooth(rect1=3)
colored = np.zeros(n1)
colored_op = colored_op.apply(white2)

numpy方法

未阅读其中的平滑函数。
使用plt.plot对所得到的数据进行绘图,均可得到如下所示图件:
平滑前:
smBefore
平滑后:
smAfter

其它函数的使用,举一反三即可(在terminal中查找函数的参数,然后使用m8r.command的方式来调用)。