Предупреждение ..... Я относительный 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». Мой процесс до сих пор был таким ...
- Позвоните в подпрограмму.
- Дайте ему потерпеть неудачу и выясните, какую переменную мне нужно передать.
- Инициализировать и выделить эту переменную в моем сценарии python.
- повторить.
Я уверен, что есть лучший способ сделать это, но код 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».
Любая помощь? Я полностью осознаю, что понятия не имею, что я делаю.
Звучит как проблема несоответствия измерения. Можете ли вы взглянуть на окно терминала и посмотреть, есть ли строки, такие как «1-е измерение должно быть исправлено до _M_, но получено _N_'? –
Спасибо за ваш ответ. Похоже, это было по крайней мере частью проблемы, хотя теперь у меня может быть больше проблем. Запуск сценария из терминала с присвоенным «0-м измерением» должен быть зафиксирован на 1, но получен 3 (действительный индекс = 0) Traceback (последний последний звонок): Файл «read_adf2py.py», строка 33, в ltied) adf04_2py.error: не удалось преобразовать 11-й аргумент 'cprta 'из adf04_2py.xxdata_04 в массив C/Fortran' –
ivanarnold
Конечно, теперь я получаю segfault, так что, возможно, пришло время для нового вопроса? – ivanarnold