0

I have compiled a fortran code in python using f2py (inputUtil.pyd). I import this function into my main python code and I pass two characters to this function (locationAID and locationBID) from a string.

Here is the error message:

>>> Traceback (most recent call last):
  File "C:\FROM_OLD_HD\SynBio\Contact 5-23-12\contactsource_workingcopy\python\main.py", line 234, in batchExecute
    self.prepareProteins(tempList[1].replace("protA: ",""),tempList[2].replace("protAID: ",""),tempList[3].replace("protB: ",""),tempList[4].replace("protBID: ",""))
  File "C:\FROM_OLD_HD\SynBio\Contact 5-23-12\contactsource_workingcopy\python\main.py", line 668, in prepareProteins
    total = inputUtil(locationAID,locationBID)
NameError: global name 'inputUtil' is not defined

Here are parts of my main python code:

#import fortran modules
from contact import *
from inputUtil import *

....
def prepareProteins(self, locationA, locationAID, locationB, locationBID):
    self.output("Generating temporary protein files...")
    start_time = time.time()

    shutil.copyfile(locationA,"."+os.sep+"prota.pdb")
    shutil.copyfile(locationB,"."+os.sep+"protb.pdb")


    total = inputUtil(locationAID,locationBID)
...

Here is part the fortran code that I converted to python using f2py that shows the character passing to this function:

     subroutine inputUtil(chida,chidb)
c
       integer resnr,nbar,ljnbar,ljrsnr
       integer resns,nbars
       integer resnc,nbarc
       integer resnn,nbarn
c
       integer numa,numb,ns,n
c
       character*6 card,cards,cardc,cardn,ljcard
c
       character*1 alt,ljalt,chid,ljchid,code,ljcode
       character*1 alts,chids,codes
       character*1 altc,chidc,codec
       character*1 altn,chidn,coden
       character*1 chida,chidb
....

f2py worked great, so I do not think that is the problem. I am just learning python - I'm an old time Fortran programmer (started back in the day of the punch card!). So, please respond with something that an old guy can follow.

Thanks for any help.

PunchDaddy

bananafish
  • 2,877
  • 20
  • 29
pete
  • 9
  • 1

1 Answers1

1

I think you are confusing functions and modules here. When you do from inputUtil import * and then call inputUtil, that is the same as calling the function inputUtil.inputUtil.

I ran f2py on the Fortran code you provided, with one additional line: print*, "hello from fortran!". I also had to remove the C comment lines, presumably since I used .f90. Here is the command I used:

python "c:\python27\scripts\f2py.py" -c --fcompiler=gnu95 --compiler=mingw32 -lmsvcr71 -m inputUtil inputUtil.f90

Now I get should a python module called inputUtil. Let's try that. Simple Python:

import inputUtil
inputUtil.inputUtil('A', 'B')

From this I get:

AttributeError: 'module' object has no attribute 'inputUtil'

So what's going on? Let's look at the module:

print dir(inputUtil)

This returns:

['__doc__', '__file__', '__name__', '__package__', '__version__', 'inpututil']

Apparently the capital U in inputUtil has been converted to lowercase. Let's call the function with the name in lowercase:

inputUtil.inpututil('A', 'B')

Now it prints:

hello from fortran!

Success!

Looks like it might be an issue/feature of f2py to translate the function names to lower case. I've never run into it since I use lower case names in general.

For future reference, I'd also recommend putting the Fortran in a module and adding intent statements to your subroutine arguments. This will make it easier to pass variables between f2py modules and Python. Wrap in a module like so:

module inpututils

contains

subroutine foo(a, b)
...code here...
end subroutine

end module

Then you import all subroutines from the module with use inpututils at the top of a subroutine in another file (before implicit none).

bananafish
  • 2,877
  • 20
  • 29
  • No problem! Please consider accepting the answer (click the tick mark next to the down arrow) if it solved your problem. – bananafish Apr 15 '13 at 21:32