爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 32341|回复: 10

[源代码] 【混合编程】Python调用小波分析Fortran程序并画图(附源代码)

[复制链接]

新浪微博达人勋

发表于 2019-1-15 19:58:43 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
本帖最后由 凉茶啦啦啦啦啦 于 2019-1-16 09:22 编辑

python调用Fortran程序一直是想要学习的内容,之前上一门python的课,为了完成大作业恶补了一下关于这一内容的知识,虽然了解得不是很深入,但起码能够简单地使用了。把之前的作业和程序总结了一下,希望能够给大家一点帮助,如有不对的地方也请多多指教!其中,有些内容是气象家园上面一些朋友总结出来的【参考链接:http://bbs.06climate.com/forum.p ... 7&fromuid=52493(出处: 气象家园)
】。例子是在李建平教授网站上下载的一个关于小波分析的程序,另外,图片上我忘记画显著性检验了。。。pdf文件和贴出来的内容是一样的可以不用下载,压缩包是相关的源代码。
Python调用Fortran的方法
                   --命令行工具f2py介绍
1.引言
在海洋与大气研究领域,Fortran作为一门高效的编程语言被应用于各项研究中。但由于其本身的局限性,只能计算而无法绘制图像,不便于研究分析,这就使得MATLAB、NCL、IDL一类的软件流行起来。在之前的海洋与大气研究中,MATLAB的普及程度较高,但其软件过于庞大且收费。相比之下,Python作为一门开源免费的综合性程序设计语言,同时还拥有着许多标准扩展库,如Numpy、Scipy、Matplotlib等,开始逐渐取代MATLAB的位置,在国内外普及。
Python作为一门在海洋与大气领域刚刚兴起的语言,专业性计算代码是有限的,比如计算流体旋度、散度等。将大量的计算代码重新用Python语言编写,这在无形之中给我们增加了工作量。但是,已经有大量现成的Fortran代码来做这些工作了,倘若能实现在Python中调用Fortran,将计算的工作交给Fortran程序,而用Python作图,这将大大地提高我们的工作效率。因此,实现Python、Fortran混合编程对于海洋与大气研究领域,是一项非常有意义的工作。
2.命令行工具f2py
2.1 F2PY简介
F2PY项目的目的是在Python和Fortran语言之间建立一个连接。F2PY是一个Python 包(包含一个命令行工具f2py和一个模块f2py2e),用来建立Python C/API 扩展模块,从而能够:
(1)    调用Fortran 77/90/95外部子程序、Fortran 90/95模块子程序以及C函数
(2)    访问Fortran 77 COMMON blocks和Fortran 90/95 模块数据,包括可变大小的动态数组。
2.2 命令行工具f2py使用方法
下述方法全部是基于Linux环境,需要先在Linux机上安装Linux版本的Anaconda,安装方法本文不再赘述。安装完成后,已经包括了命令行工具f2py,无需再另行安装,是非常方便的。如果在Windows环境下,考虑到要使用Fortran编译器,需要安装Mingw,在命令行的模式下使用,较为麻烦,因此,建议在Linux环境下使用该方法。
以下介绍具体使用方法,以下面的Fortran 90 代码为例说明。
QQ截图20181022212724.png
表2.2.1为一个简单的Fortran 90 subroutine,名为test.f90,现在我们要在用f2py将其封装为一个Python模块,并在Python中调用它,在封装之前需要在原程序声明变量之后加入f2py的接口(表2.2.2,红色部分):
!f2py intent(in)::a,b
!f2py intent(out)::c,d
表示输入变量a,b,返回的变量为c,d。即在Python中调用该模块中的addsubroutine只需要两个参数,对应返回两个参数。
接下来,在终端中使用下述语句,其中-c 表示编译的Fortran文件,-m表示编译成的模块名:
f2py -c test.f90 -m test
此时,在该目录下将会生成一个test.so的文件,即为Python调用的模块。
进入Python的命令行格式,如图2.2.1中操作,即可调用成功。
QQ截图20181022214028.png
3.在海洋与大气研究中的应用——小波变换
小波变换是分析海洋与大气时间序列的一种常用方法,用以分析时间序列中的时域和频域信息。本文分析的时间序列是1870年-2000年的nino3指数,原Fortran程序是大气科学与地球流体力学数值模拟国家重点实验室的李建平教授编写的F77程序,其主要结构如图3.1.1所示。

QQ截图20181022214214.png
         图3.1.1 小波变换F77程序结构图
Wavetest是主程序,其中调用的subroutine都在wavelet.f、chisqr.f、cfftpack.f中。因此要将该程序封装成Python的模块,只需要将wavetest改成一个subroutine,并提前编译其他几个F77文件,在使用f2py命令时,指定特定的库即可。具体操作如下:
(1)将主程序改成一个subroutine。可以通过编写接口自由指定所需要传出的变量,其中wave,signif,period分别表示功率谱变量,进行统计检验后的变量和时间尺度。
QQ截图20181022214327.png
(2)编译库文件
gfortran -c -fPICwavelet.f chisqr.f cfftpack.f
最终生成,wavelet.o,chisqr.o,cfftpack.o库文件。
(3)f2py命令封装成Python模块
f2py -c –-fcompiler=gfortran -I wavelet.ochisqr.o cfftpack.o -m wave wavetest.f
其中,--fcompiler指定编译器,-I 指定链接的库文件,-m模块名,-c封装的subroutine
(4)在python中调用模块并绘图
编写wave.py程序:
QQ截图20181022214345.png

命令行:
python wave.py
输出结果:
pic1.png
5.在使用中需要注意的问题
(1)   数据类型
Numpy 默认的数据类型为float64也就是双精度浮点数,所以Fortran里的浮点数也必须是双精度的,需要声明real*8,默认的real是单精度的,不会报错但是会造成内存溢出。
(2)   数组行列关系
一般在使用Fortran的时候需要注意二维数组的行列关系的问题。即Fortran里面的数组是先填充一列,再填充一行,而Python数组遵循C语法规范,先填充一行,再填充一列。利用f2py进行参数传递时,已经进行过智能转换,所以不需要考虑该问题,按照相同的方式使用即可。
(3)   数组的传递
在调用时,输入变量跟维数有关的信息必须放置在最后。例如,函数名为foo(a,b,c,d,n),这里的a、b、c、d都是普通的变量或数组,但n必须是一个跟维数有关的变量,用来在Fortran程序中定义数组使用。如果将维数放在最前面可能出现的错误是:“(shape(u,0)==m)failed for1st keyword m: vector2:m=0”
(4)编写接口
加intent(out)之后,会把python对应函数中的相应变量隐藏,也就是不需要输入了。接口中的虚参不存在,intent(inout)属性,因为在python中不认可,如果一个虚参具备intent(inout)属性,则会出现以下报错:” ValueError:failed to initialize intent(inout) array -- inputnot fortran contiguous --input 'l' not compatible to 'd'”
6.总结
本文重点讲述了在Python中调用Fortran的方法,具体做法是将Fortran主程序改写成subroutine,并使用f2py封装,编译时指定Fortran程序调用的库文件。并且,通过改写一个小波变换的Fortran程序,展示了该方法在海洋与大气研究中的应用。总的说来,该方法使用起来非常的简单高效,掌握该方法,定会在以后的研究中有不小的助益。

说明:本文的所有代码均在压缩文件中,利用上述命令,在Linux环境下直接运行即可。


Python调用Fortran接口.pdf

376.57 KB, 下载次数: 69, 下载积分: 金钱 -5

examples.rar

467.13 KB, 下载次数: 85, 下载积分: 金钱 -5

评分

参与人数 5金钱 +76 贡献 +15 收起 理由
lime_ade + 16 很给力!
流星大气 + 5 很给力!
mofangbao + 20 + 10
D_Fora + 10 赞一个!
尽头的尽头 + 25 + 5 很给力!

查看全部评分

密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2019-1-16 04:51:53 | 显示全部楼层
多谢楼主分享,收藏学习了
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2019-1-16 06:25:35 | 显示全部楼层
厉害,厉害厉害
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2019-1-16 08:52:08 | 显示全部楼层
厉害了,楼主
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2019-1-16 11:18:58 | 显示全部楼层
6666,不明觉厉,为楼主点赞,分享之~
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2019-1-19 11:39:21 | 显示全部楼层
很棒啊楼主!这个感觉和NCL调用Fortran有相似的地方
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2019-1-21 14:38:04 | 显示全部楼层
点赞
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

新浪微博达人勋

发表于 2021-10-12 19:31:16 | 显示全部楼层
必须在linux下调用,能不能在windows下调用
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2021-11-24 00:18:37 | 显示全部楼层
厉害了厉害了
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2023-5-29 15:14:27 | 显示全部楼层
之前看了你的帖子,成功用f2py将众多fortran程序打包,但是现在用同样的命令不行了,提示很多子程序找不到,感觉像是 -I后面的 .o文件都没生效,不知道你遇到过相同的问题吗
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表