Imported python modules can't call nwchem functions


Click here for full thread
Gets Around
I think that all you need to do is import nwchem inside the external module and then reference e.g. rtdb_get as nwchem.rtdb_get (or maybe do 'from nwchem import *', but I prefer the explicit naming).

Here's a module I was toying around with last summer. I called it nwhelp.py. You can import it while running NWChem and call the various functions.

import nwchem

class Helper(object):
    def __init__(self):
        pass
    
    def rtdb_keys(self, prefix=""):
        """Get keys currently in the rtdb.

        @param prefix: if non-empty, only include keys that start with it
        @type prefix : str
        @return: keys
        @rtype : list
        """

        #initialize/rewind to first rtdb key
        keys = [nwchem.rtdb_first()]
        while True:
            try:
                keys.append(nwchem.rtdb_next())
            except nwchem.NWChemError:
                break

        filtered = [k for k in keys if k.startswith(prefix)]
        return filtered

    def rtdb_data(self, prefix=""):
        """Get a dict containing rtdb data keyed by name."""

        d = {}
        for key in self.rtdb_keys(prefix=prefix):
            data = nwchem.rtdb_get(key)
            meta = nwchem.rtdb_get_info(key)
            d[key] = (data, meta)

        return d


    def geom_get_coords(self, name):
        """Get named geometry in atomic units."""
        try:
            actualname = nwchem.rtdb_get(name)
        except nwchem.NWChemError:
            actualname = name
            
        coords = nwchem.rtdb_get('geometry:' + actualname + ':coords')
        units  = nwchem.rtdb_get('geometry:' + actualname + ':user units')
        
        if (units == 'a.u.'):
            factor = 1.0
        elif (units == 'angstroms'):
            prop = 'geometry:{0}:angstrom_to_au'.format(actualname)
            factor = nwchem.rtdb_get(prop)
            
        else:
            raise nwchem.NWChemError('unknown units {0}'.format(repr(units)))

        for k in range(len(coords)):
            coords[k] /= factor

        return coords


Here's a demonstration NWChem deck that calls it. If you have ipdb installed you get an interactive environment running inside Python inside NWChem. Not tested with parallel execution.

echo
start testpy
# test some basic python wrappers.
# if it did not abort, it worked.

print none

basis
  h library 3-21g
end

python

import nwhelp
H = nwhelp.Helper()

import ipdb
print "value check:"
print "INT     = ", INT
print "DBL     = ", DBL
print "CHAR    = ", CHAR
print "LOGICAL = ", LOGICAL

rtdb_put("test_int2", 22)
print ' Done 1'
rtdb_put("test_int", [22, 10, 3],    INT)
print ' Done 2'
rtdb_put("test_dbl", [22.9, 12.4, 23.908],  DBL)
print ' Done 3'
rtdb_put("test_str", "hello", CHAR)
print ' Done 4'
rtdb_put("test_logic", [0,1,0,1,0,1], LOGICAL)
print ' Done 5'
rtdb_put("test_logic2", 0, LOGICAL)
print ' Done 6'

rtdb_print(1)

print "test_str    = ", rtdb_get("test_str")
print "test_int    = ", rtdb_get("test_int")
print "test_in2    = ", rtdb_get("test_int2")
print "test_dbl    = ", rtdb_get("test_dbl")
print "test_logic  = ", rtdb_get("test_logic")
print "test_logic2 = ", rtdb_get("test_logic2")

def energy(r):
  input_parse('''
    geometry noprint noautoz
      h 0 0 0
      h 0 0 %f
   end
  ''' % r)
  return task_energy('scf')

for r in (0.4, 0.5, 0.6):
  print r, energy(r)

print task_optimize('scf')

keys = H.rtdb_keys()
import pprint
pprint.pprint(keys)
ipdb.set_trace()
end

task python