2016-02-09 4 views
2

Предупреждение ..... Я относительный python noob и совершенно новый для использования f2py.Как распределить входные массивы с помощью f2py?

Я попытался проявить должную осмотрительность и найти ответ на мои вопросы здесь и в другом месте на веб-сайте, но мне не повезло. Это очень вероятно из-за моего собственного невежества по этому вопросу.

Моя проблема: у меня есть подпрограмма fortran (f77) и несколько функций, которые используются подпрограммой для чтения в различных массивах из файла данных. Этот файл данных сам по себе является результатом одного из нескольких кодов атомной физики f77.

Я хотел бы обернуть подпрограммы/функции fortran с помощью f2py и получить доступ к данным, хранящимся в файле, в виде массивов numpy. Я застрял в том, как правильно распределять массивы в python. Я использую Anaconda python distibrution (Python 3.4 - 64 бит) и компилятор gfortran на Ubuntu 14.04 (64 бит).

Я успешно (надеюсь) удалось создать файл подписи python с использованием py2f, используя py2f -h <filename.py2f> <input files>. Вот содержимое файла подписи. Прошу прощения за его длину. Это довольно длинная подпрограмма и имеет много переменных.

! -*- f90 -*- 
! Note: the context of this file is case sensitive. 

subroutine xxdata_04(iunit,ndlev,ndtrn,ndmet,ndqdn,nvmax,titled,iz,iz0,iz1,bwno,npl,bwnoa,lbseta,prtwta,cprta,il,qdorb,lqdorb,qdn,iorb,ia,cstrga,isa,ila,xja,wa,cpla,npla,ipla,zpla,nv,scef,itran,maxlev,tcode,i1a,i2a,aval,scom,beth,iadftyp,lprn,lcpl,lorb,lbeth,letyp,lptyp,lrtyp,lhtyp,lityp,lstyp,lltyp,itieactn,ltied) ! in xxdata04_string.for 
    integer :: iunit 
    integer, optional,check(len(ia)>=ndlev),depend(ia) :: ndlev=len(ia) 
    integer, optional,check(shape(tcode,0)==ndtrn),depend(tcode) :: ndtrn=shape(tcode,0) 
    integer, optional,check(len(bwnoa)>=ndmet),depend(bwnoa) :: ndmet=len(bwnoa) 
    integer, optional,check(len(qdn)>=ndqdn),depend(qdn) :: ndqdn=len(qdn) 
    integer, optional,check(len(scef)>=nvmax),depend(scef) :: nvmax=len(scef) 
    character*3 :: titled 
    integer :: iz 
    integer :: iz0 
    integer :: iz1 
    real*8 :: bwno 
    integer :: npl 
    real*8 dimension(ndmet) :: bwnoa 
    logical dimension(ndmet),depend(ndmet) :: lbseta 
    real*8 dimension(ndmet),depend(ndmet) :: prtwta 
    character dimension(ndmet,9),depend(ndmet) :: cprta 
    integer :: il 
    real*8 dimension((ndqdn*(ndqdn+1))/2),depend(ndqdn) :: qdorb 
    logical dimension((ndqdn*(ndqdn+1))/2),depend(ndqdn) :: lqdorb 
    real*8 dimension(ndqdn) :: qdn 
    integer :: iorb 
    integer dimension(ndlev) :: ia 
    character dimension(ndlev,(*)),depend(ndlev) :: cstrga 
    integer dimension(ndlev),depend(ndlev) :: isa 
    integer dimension(ndlev),depend(ndlev) :: ila 
    real*8 dimension(ndlev),depend(ndlev) :: xja 
    real*8 dimension(ndlev),depend(ndlev) :: wa 
    character dimension(ndlev,1),depend(ndlev) :: cpla 
    integer dimension(ndlev),depend(ndlev) :: npla 
    integer dimension(ndmet,ndlev),depend(ndmet,ndlev) :: ipla 
    real*8 dimension(ndmet,ndlev),depend(ndmet,ndlev) :: zpla 
    integer :: nv 
    real*8 dimension(nvmax) :: scef 
    integer :: itran 
    integer :: maxlev 
    character dimension(ndtrn,1) :: tcode 
    integer dimension(ndtrn),depend(ndtrn) :: i1a 
    integer dimension(ndtrn),depend(ndtrn) :: i2a 
    real*8 dimension(ndtrn),depend(ndtrn) :: aval 
    real*8 dimension(nvmax,ndtrn),depend(nvmax,ndtrn) :: scom 
    real*8 dimension(ndtrn),depend(ndtrn) :: beth 
    integer :: iadftyp 
    logical :: lprn 
    logical :: lcpl 
    logical :: lorb 
    logical :: lbeth 
    logical :: letyp 
    logical :: lptyp 
    logical :: lrtyp 
    logical :: lhtyp 
    logical :: lityp 
    logical :: lstyp 
    logical :: lltyp 
    integer :: itieactn 
    logical dimension(ndlev),depend(ndlev) :: ltied 
end subroutine xxdata_04 
function i4unit(iunit) ! in i4unit.for 
    integer :: iunit 
    integer :: i4unit 
end function i4unit 
subroutine xxword(ctext,cdelim,nfirst,iwords,ifirst,ilast,nwords) ! in xxword.for 
    character*(*) :: ctext 
    character*(*) :: cdelim 
    integer :: nfirst 
    integer, optional,check(len(ifirst)>=iwords),depend(ifirst) :: iwords=len(ifirst) 
    integer dimension(iwords) :: ifirst 
    integer dimension(iwords),depend(iwords) :: ilast 
    integer :: nwords 
end subroutine xxword 
subroutine xxslen(cstrng,ifirst,ilast) ! in xxslen.for 
    character*(*) :: cstrng 
    integer :: ifirst 
    integer :: ilast 
end subroutine xxslen 
subroutine xxprs1(ndmet,string_bn,wno,cpl,npt,ipla,zpla,ifail) ! in xxprs1.for 
    integer*4, optional,check(len(ipla)>=ndmet),depend(ipla) :: ndmet=len(ipla) 
    character*(*) :: string_bn 
    real*8 :: wno 
    character*1 :: cpl 
    integer*4 :: npt 
    integer*4 dimension(ndmet) :: ipla 
    real*8 dimension(ndmet),depend(ndmet) :: zpla 
    integer*4 :: ifail 
end subroutine xxprs1 
function r8fctn(str,iabt) ! in r8fctn.for 
    character*(*) :: str 
    integer :: iabt 
    real*8 :: r8fctn 
end function r8fctn 
function i4fctn(str,iabt) ! in i4fctn.for 
    character*(*) :: str 
    integer :: iabt 
    integer :: i4fctn 
end function i4fctn 
function i4idfl(n,l) ! in i4idfl.for 
    integer :: n 
    integer :: l 
    integer :: i4idfl 
end function i4idfl 
subroutine xxpars(ndmet,strng1,npt,bwnoa,lseta,prtwta,cprta,ifail,itype) ! in xxpars.for 
    integer*4, optional,check(len(bwnoa)>=ndmet),depend(bwnoa) :: ndmet=len(bwnoa) 
    character*(*) :: strng1 
    integer*4 :: npt 
    real*8 dimension(ndmet) :: bwnoa 
    logical dimension(ndmet),depend(ndmet) :: lseta 
    real*8 dimension(ndmet),depend(ndmet) :: prtwta 
    character dimension(ndmet,(*)),depend(ndmet) :: cprta 
    integer*4 :: ifail 
    integer*4 :: itype 
end subroutine xxpars 
subroutine xxrmve(cstrg1,cstrg2,crmve) ! in xxrmve.for 
    character*(*) :: cstrg1 
    character*(*) :: cstrg2 
    character*1 :: crmve 
end subroutine xxrmve 
subroutine xxcase(input,output,type_bn) ! in xxcase.for 
    character*(*) :: input 
    character*(*) :: output 
    character*2 :: type_bn 
end subroutine xxcase 

! This file was auto-generated with f2py (version:2). 
! See http://cens.ioc.ee/projects/f2py2e/ 

Затем я скомпилировал f2py -c -m <filename> <input files>. Компиляция завершена несколькими предупреждениями, но ошибок нет. Результирующий общий объект python равен adf04_2py.cpython-35m-x86_64-linux-gnu.so

Я начал создавать скрипт python, который я хотел бы использовать для импорта общего объекта и вызова подпрограммы «xxdata_04». Мой процесс до сих пор был таким ...

  1. Позвоните в подпрограмму.
  2. Дайте ему потерпеть неудачу и выясните, какую переменную мне нужно передать.
  3. Инициализировать и выделить эту переменную в моем сценарии python.
  4. повторить.

Я уверен, что есть лучший способ сделать это, но код fortran много и несколько длинный, а не мой, поэтому это казалось самым прямым методом.

Пока мой сценарий выглядит следующим образом:

import adf04_2py as adf 
import numpy as np 

itieactn = 1 

iunit = 19 ; titled = '---' ; iz = 18 ; iz0 = 0 ; iz1 = 0 ; il = 0 
bwno = 0.0 ; npl = 0 ; bwnoa = 1.0 ; prtwta = 0.0 
qdorb = 0.0 ; qdn =0.0 ; iorb = 0 ; ia = 0 ; cstrga = '-' 
isa = 0 ; ila = 0 ; xja = 0.0 ; wa = 0.0 ; cpla = '-' ; npla = 0 ; ipla = 0 
zpla = 0 ; nv = 0 ; scef = 0.0 ; itran = 0 ; maxlev = 0 ; tcode = '-' 
ila = 0 ; i2a = 0 ; aval = 0.0 ; scom = 0.0 ; beth = 0 ; iadftyp = 0 

cprta = np.asarray([['---------'],['---------'],['---------']],dtype='c') 


lbseta = False ; lqdorb = False ; lprn = False ; lcpl= False ; lorb = False 
lbeth = False ; letyp = False ; lptyp = False ; lrtyp = False ; lhtyp = False 
lityp = False ; lstyp = False ; lltyp = False ; ltied = False 


adf04_dat = adf.xxdata_04(iunit, titled, iz, iz0, iz1 , bwno, npl, bwnoa , 
          lbseta , prtwta , cprta , il , qdorb , lqdorb , 
          qdn , iorb , ia , cstrga , isa , ila , xja , wa , 
          cpla , npla, ipla , zpla , nv , scef , itran , 
          maxlev , tcode , ila , i2a , aval , scom , beth , 
          iadftyp , lprn, lcpl , lorb , lbeth , letyp, lptyp , 
          lrtyp , lhtyp , lityp , lstyp , lltyp , itieactn , 

В настоящее время он терпит неудачу с:

runfile('/home/ivan/GoogleDrive/AUAMO/codes/read_adf04_2py/xxdata_04/read_adf2py.py', wdir='/home/ivan/GoogleDrive/AUAMO/codes/read_adf04_2py/xxdata_04') 

    File "/home/ivan/anaconda3/lib/python3.5/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 699, in runfile 
    execfile(filename, namespace) 

    File "/home/ivan/anaconda3/lib/python3.5/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 88, in execfile 
    exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace) 

    File "/home/ivan/GoogleDrive/AUAMO/codes/read_adf04_2py/xxdata_04/read_adf2py.py", line 32, in <module> 
    ltied) 

error: failed in converting 11st argument `cprta' of adf04_2py.xxdata_04 to C/Fortran array 

по подписи файла, cprta должен быть символьный массив формы ((ndmet) , (# символов)), где ndmet - число метастабильных состояний, а # символов - 9. Я попытался выделить это, используя np.asarray. Я все еще получаю сообщение об ошибке «не удалось преобразовать 11-й аргумент« cprta »из adf04_2py.xxdata_04 в массив C/Fortran».

Любая помощь? Я полностью осознаю, что понятия не имею, что я делаю.

+0

Звучит как проблема несоответствия измерения. Можете ли вы взглянуть на окно терминала и посмотреть, есть ли строки, такие как «1-е измерение должно быть исправлено до _M_, но получено _N_'? –

+0

Спасибо за ваш ответ. Похоже, это было по крайней мере частью проблемы, хотя теперь у меня может быть больше проблем. Запуск сценария из терминала с присвоенным «0-м измерением» должен быть зафиксирован на 1, но получен 3 (действительный индекс = 0) Traceback (последний последний звонок): Файл «read_adf2py.py», строка 33, в ltied) adf04_2py.error: не удалось преобразовать 11-й аргумент 'cprta 'из adf04_2py.xxdata_04 в массив C/Fortran' – ivanarnold

+0

Конечно, теперь я получаю segfault, так что, возможно, пришло время для нового вопроса? – ivanarnold

ответ

1

Благодаря CT Zhu для решения этой проблемы. Запуск сценария с терминала дало более информативное сообщение об ошибке.

0-th dimension must be fixed to 1 but got 3 (real index=0) 
Traceback (most recent call last): 
    File "read_adf2py.py", line 33, in <module> 
    ltied) 
adf04_2py.error: failed in converting 11st argument `cprta' of adf04_2py.xxdata_04 to C/Fortran array 

Я перераспределил массив строк с размером 1 х 9 и эта ошибка исчезла.

cprta = np.asarray(['---------'],dtype='c') 

Теперь я получаю segfault, но я думаю, что это отдельная проблема.

Спасибо CT Zhu!

 Смежные вопросы

  • Нет связанных вопросов^_^