You can use it as a script (argsparse module):
$ python wrapper.py –X 170 3 0.05
All of this might seem complex, but wrappers are repetitive and otwrapy is here for you !
ot.OpenTURNSPythonFunction
for which at least the method _exec(X)
should be
overloaded. Additionally, you can overload _exec_sample(X)
, but
with otwrapy.Parallelizer() there is no need to._gradient(X)
and _hessian(X)
.class Wrapper(ot.OpenTURNSPythonFunction): """Wrapper of my external code. """ def __init__(self): """Initialize the wrapper with 4 and 1 as input and output dimension. """ super(Wrapper, self).__init__(4, 1) # Do other stuff if necessary def _exec(self, X): """Run the model in the shell for the input vector X """ pass
_exec
is the default OpenTURNS method that executes the function
on a given point. Semantically speaking, the function is divided on
three parts :
def _exec(self, X): """Run the model in the shell for the input vector X """ # Move to temp work dir. Cleanup at the end with otw.TempWorkDir(cleanup=True): # Prepare the input self._prepare_input(X) # Run the external code self._run_code(X) # Parse the output parameters Y = self._parse_output() return Y
import otwrapy as otw # I'm on a given dir, e.g. ~/beam-wrapper with otw.TempWorkDir(base_temp_work_dir='/tmp', prefix='run-', cleanup=True, transfer=None): """ ... Do stuff safely on an exclusive temporary directory and erase it afterwards ... """ # The current working directory is something like /tmp/run-pZYpzQ # Back on ~/beam-wrapper and /tmp/run-pZYpzQ does not exist anymore
def _prepare_input(self, X): """Create the input file required by the code. """ ot.coupling_tools.replace( infile='input_templatefile.xml', outfile='input.xml', tokens=['@X1','@X2','@X3','@X4'], values=X)
def _run_code(self): time_start = time.time() ot.coupling_tools.execute('/path/to/executable -x input.xml')) return time.time() - time_start
.csv
file, pandas.read_csv
is the fastest option, but it
introduces pandas as a dependency. Otherwise, if speed is not an
issue, try ot.coupling_tools.get_value
or numpy.loadttxt
..xml
files minidom package from the python standard library does the trick.get_stdout=True
when calling
ot.coupling_tools.execute(...)
. (or use use subprocess.check_output
)def _parse_output(self): # Retrieve output (see also ) xmldoc = minidom.parse('outputs.xml') itemlist = xmldoc.getElementsByTagName('outputs') Y = float(itemlist[0].attributes['Y1'].value) return [Y]
otwrapy
has two useful functions to do so: otwrapy.dump_array
and otwrapy.load_array
protocol=2
)gzip
library. If the extension is `pklz`
, it compresses by default.ot.NumericalSample
to a np.array
before dumping. An np.array
is lighter !import otwrapy as otw otw.dump_array(np.array(X), 'InputSample.pklz', compress=True)
import otwrapy as otw import openturns as ot X = otw.load_array('InputSample.pklz') X = ot.NumericalSample(X)
import otwrapy as otw class Wrapper(ot.OpenTURNSPythonFunction): @otw.Debug('wrapper.log') def _exec(self, X): #Do stuff return Y
argparse
library might seem complicated, but they have a great
cookbook and there are good chances that a simple copy/paste will be
enough.if __name__ == '__main__': import argparse parser = argparse.ArgumentParser(description="Python wrapper example.") parser.add_argument('-X', nargs=3, metavar=('X1', 'X2', 'X3'), help='Vector on which the model will be evaluated') args = parser.parse_args() model = Wrapper(3, 1) X = ot.NumericalPoint([float(x) for x in args.X]) Y = model(X) dump_array(X, 'InputSample.pkl') dump_array(Y, 'OutputSample.pkl')
python wrapper.py –X 170 3 0.05
import otwrapy as otw from otwrapy.examples.beam import Wrapper parallelized_beam_wrapper = otw.Parallelizer(Wrapper())
Felipe Aguirre Martinez
Github : otwrapy