Madagascrar-python 这里简单讲解如何在python中使用Madagascrar中的函数,读者需要自行安装好swig、Madagascrar、python、numpy等环境。
实际应用中有下列网址可供参考: 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源码主要展示了利用spike和causint函数来创建不同信号。我们经常需要在python脚本中实现各类数学变换以满足开发需求,通过python调用Madagascrar中相关函数的方式能够极大的简化我们的开发过程,提升开发效率。
首先,在/src/bei/ft1/autocor路径下打开terminal,执行scons命令,即可按照脚本SConstruct中命令的顺序获得所需要的文件,下面我们逐条语句解释SConstruct中出现的各种Madagascrar命令,并以纯numpy语句和python中Madagascrar语句(m8r.command)两种形式来实现相同功能。以下语句均在Linux环境下Jupyter notebook中完成。
引入相关模块 1 2 3 4 5 6 7 8 9 10 11 import m8r, os, mathimport numpy as npimport matplotlib.pyplot as pltn1 = 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文件中的数据就已经被保存到了名为spike的numpy变量中。
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_op的apply方法即可即可将该运算的结果赋值给spike2,此时spike2的数据类型已经变为了float32。
numpy方法1 2 n1 = 128 spike3 = np.ones(n1, dtype=np.float32)
使用plt.plot对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
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对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
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对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
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 ]) widebox2 = np.zeros(n1) widebox2 = widebox_op1.apply(widebox2) 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) temp = integrate(widebox3)
使用plt.plot对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
积分前: 积分后:
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) 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) temp = integrate(narrowbox3)
使用plt.plot对以上三种方法所得到的数据进行绘图,均可得到如下所示图件: 积分前: 积分后:
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对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
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对以上三种方法所得到的数据进行绘图,均可得到如下所示图件: 积分前: 积分后:
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 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 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对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
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对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
Gaussian 该示例使用spike和math生成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对以上三种方法所得到的数据进行绘图,均可得到如下所示图件:
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 )
注:m8r与numpy种子设置方法不同,获取的随机数结果不同。
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对所得到的数据进行绘图,均可得到如下所示图件: 平滑前: 平滑后:
其它函数的使用,举一反三即可(在terminal中查找函数的参数,然后使用m8r.command的方式来调用)。