2012-01-13 48 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