2012-01-13 45 views
2

我使用python作为模型中几个fortran文件的接口。我想多次复制fortran文件,但是在每个副本中,我将更改描述我的模型的参数。如何复制文件,但更改里面的几个参数?

例如:下面我有

!file.f 
! This is a fortran code 

!Parameters 
alpha = 0.5 
beta = 100 
... 

我想file.f几次这样的复制,我将有file1.f,file2.f,file3.f等,但在Fortran文件,在每个重复的文件中,我想自动更改参数alpha和beta。谢谢

编辑:让我再解释一点。我正在使用python将数据同化(卡尔曼过滤)应用到已经在fortran中开发的模型中。基本上,它是如何工作的,在每一个特定的时间步,Fortran模型停止运行,然后我将现实世界的数据集成到模型数据,我在python中这样做。然后,在整合(同化)之后,我重新运行相同的模型,但是这次使用了我通过融合来自模型和观测的数据以及新的初始条件而获得的新参数。我使用python来执行所有操作,除了运行由fortran完成的模型。

+0

你是否限制python代码的解决方案?或者你的界面是什么意思? – ardnew 2012-01-13 01:05:36

+4

如果这些是配置参数,为什么不让fortran程序读取配置文件?这样你就有0个代码重复,只需要为每组参数调整设置文件的副本。 Python [有一个很好的库](http://docs.python.org/library/configparser.html)。我确信在Fortran中加载类似的设置文件非常容易。 – jozzas 2012-01-13 01:05:52

+3

我只是使用'sed'来做这件事,在Python中使用脚本编写脚本在这里是浪费的 – wim 2012-01-13 01:06:38

回答

4

我认为最一致的方法是使用模板引擎。 Python有很多,通常部署在Web应用程序中。

但是,模板引擎的目的正是让人们拥有大量的代码,需要改变为静态文本,并通过一些特殊的标记来插入Python代码中生成的变量。

根据参数的复杂程度,您甚至可以根本不需要任何separte模板引擎,只需继续使用Python字符串格式化功能即可,如下例所示。

模板引擎可以为您提供一点额外的容量,因为可以在模板内展开循环和条件。

示例 - 写你的fortram模板是这样的:

!file.f 
! This is a fortran code 

!Parameters 
alpha = %(alpha)s 
beta = %(beta)s 

而在Python代码,写类似:

template = open("fortram_template.for", "rt").read() 
data = {"alpha": 0.5, "beta": 100} 

with open("fortram_1.for", "wt") as output: 
    output.write (template % data) 
+0

谢谢。这是一个非常好的做法。 – mikeP 2012-01-13 03:10:03

2

这里是你可以做一个例子。我已将各种(alpha,beta)对放入alpha_beta列表中。与alpha_beta我选择使用配对位置的索引作为增加文件名的值,但有多种方法可以做到这一点。这段代码很脆弱,因为它假定你的.f文件很多,但是由于这是你自己用于生成这些文件的个人用途,我认为你会没事的(例如,我假设你根据你提供的信息在文件中只有一个字母alpha的实例 - 如果这不是真的,你可能会更好地使用正则表达式)。

alpha_beta = [(0.1, 16), (0.9, 50), (0.4, 76)] 
file_name = 'file' 
file_ext = '.txt' 

for index, vars in enumerate(alpha_beta, start=1): 
    with open(file_name + file_ext) as f: 
     alpha, beta = vars 
     new_file = open(file_name + str(index) + file_ext, 'w') 
     for line in f: 
      if line.startswith('alpha'): 
       new_file.write('alpha = %s \n' % str(alpha)) 
      elif line.startswith('beta'): 
       new_file.write('beta = %s \n' % str(beta)) 
      else: 
       new_file.write(line) 
     new_file.close() 
+0

这是一个非常好的实现。谢谢 – mikeP 2012-01-13 03:14:58

2

Fortran的解决办法是在一个单独的文本文件中的参数行写,然后,在Fortran源文件,这样一行include

include 'parameters.inc' 

这种方式可以简单地重新生成参数文件,而不必触摸包含主Fortran代码的文件。

1

首先,我认为这个解决方案是过度消耗,正如一些评论中所述。我会选择以下两种选择之一,最好是第二种,如果你不会做很多fortran编码。

  1. 阅读要被从临时输入文件中使用的参数,像:

    !file.f 
    !This is a fortran code 
    
    !Parameters 
    open (unit=input, file='tmp_inp.txt', action='read', iostat=ierr) 
    read (input, '(...)') alpha, beta 
    

    然后改变在从Python或使用sed临时输入文件中的值。

  2. 将参数作为参数从python内部传递给fortran子例程,方法是使用f2py将fortran代码与python进行接口。该Fortran代码如下所示:

    !file.f 
    !This is a fortran code 
    subroutine my_sub(alpha, beta) 
    ... 
    

    然后用f2py编译:

    f2py -c -m my_fortran_code file.f 
    

    而且从蟒蛇内最后调用为:

    #python code 
    from my_fortran_code import my_sub 
    my_sub(alpha, beta) 
    

这两种解决方案不要求你重新编译任何fortran代码只是为了改变一些输入参数。

+0

最好不要每次重新编译,有时候可能是一个漫长的过程。我甚至正在考虑对一些用户定义的操作使用Scheme解释模块。 – 2012-01-13 08:53:25

相关问题