| [14de8e1] | 1 | /*
 | 
|---|
 | 2 |  * PythonScripting.hpp
 | 
|---|
 | 3 |  *
 | 
|---|
 | 4 |  *  Created on: Apr 13, 2012
 | 
|---|
 | 5 |  *      Author: heber
 | 
|---|
 | 6 |  */
 | 
|---|
 | 7 | 
 | 
|---|
 | 8 | #ifndef PYTHONSCRIPTING_HPP_
 | 
|---|
 | 9 | #define PYTHONSCRIPTING_HPP_
 | 
|---|
 | 10 | 
 | 
|---|
 | 11 | 
 | 
|---|
 | 12 | // include config.h
 | 
|---|
 | 13 | #ifdef HAVE_CONFIG_H
 | 
|---|
 | 14 | #include <config.h>
 | 
|---|
 | 15 | #endif
 | 
|---|
 | 16 | 
 | 
|---|
 | 17 | 
 | 
|---|
 | 18 | #include <boost/python.hpp>
 | 
|---|
 | 19 | #include <boost/python/module.hpp>
 | 
|---|
 | 20 | #include <boost/python/args.hpp>
 | 
|---|
 | 21 | 
 | 
|---|
 | 22 | //!> define all present actions
 | 
|---|
 | 23 | #include "GlobalListOfActions.hpp"
 | 
|---|
 | 24 | 
 | 
|---|
 | 25 | //!> python wrapping for all of these actions
 | 
|---|
 | 26 | #include "AllActionPython.hpp"
 | 
|---|
 | 27 | 
 | 
|---|
 | 28 | namespace MoleCuilder {
 | 
|---|
 | 29 | 
 | 
|---|
 | 30 | namespace PythonTypes {
 | 
|---|
 | 31 | 
 | 
|---|
 | 32 | inline void IndexError(){
 | 
|---|
 | 33 |     PyErr_SetString(PyExc_IndexError, "Index out of range");
 | 
|---|
 | 34 |     boost::python::throw_error_already_set();
 | 
|---|
 | 35 | }
 | 
|---|
 | 36 | 
 | 
|---|
 | 37 | template<class T>
 | 
|---|
 | 38 | struct vec_item{
 | 
|---|
 | 39 |     typedef typename T::value_type V;
 | 
|---|
 | 40 |     static V& get(T& x, int i){
 | 
|---|
 | 41 |         static V nothing;
 | 
|---|
 | 42 |         if(i < 0) i += x.size();
 | 
|---|
 | 43 |         if(i >= 0 && i < int(x.size())) return x[i];
 | 
|---|
 | 44 |         IndexError();
 | 
|---|
 | 45 |         return nothing;
 | 
|---|
 | 46 |     }
 | 
|---|
 | 47 |     static void set(T& x, int i, V const& v){
 | 
|---|
 | 48 |         if(i < 0) i += x.size();
 | 
|---|
 | 49 |         if(i >= 0 && i < int(x.size())) x[i] = v;
 | 
|---|
 | 50 |         else IndexError();
 | 
|---|
 | 51 |     }
 | 
|---|
 | 52 |     static void del(T& x, int i){
 | 
|---|
 | 53 |         if(i < 0) i += x.size();
 | 
|---|
 | 54 |         if(i >= 0 && i < int(x.size())) x.erase(x.begin() + i);
 | 
|---|
 | 55 |         else IndexError();
 | 
|---|
 | 56 |     }
 | 
|---|
 | 57 |     static void add(T& x, V const& v){
 | 
|---|
 | 58 |         x.push_back(v);
 | 
|---|
 | 59 |     }
 | 
|---|
 | 60 | };
 | 
|---|
 | 61 | 
 | 
|---|
 | 62 | 
 | 
|---|
 | 63 | } /* namespace PythonTypes */
 | 
|---|
 | 64 | } /* namespace MoleCuilder */
 | 
|---|
 | 65 | 
 | 
|---|
 | 66 | BOOST_PYTHON_MODULE(pyMoleCuilder)
 | 
|---|
 | 67 | {
 | 
|---|
 | 68 |   // set the docstring of the current module scope
 | 
|---|
 | 69 |   boost::python::scope().attr("__doc__") = "pyMolecuilder are the python bindings to all Actions of the program suite MoleCuilder.\n\nMoleCuilder is a program to build molecular (dynamics) worlds, allowing you indefinite manipulation, control and analysis over the atoms and molecules within a simulation domain.";
 | 
|---|
 | 70 | 
 | 
|---|
 | 71 |   // STL Vectors:
 | 
|---|
 | 72 |   // doubleVec
 | 
|---|
 | 73 |   boost::python::class_< std::vector< double > >("PythonType_doubleVec")
 | 
|---|
 | 74 |       .def("__len__", &std::vector< double >::size)
 | 
|---|
 | 75 |       .def("clear", &std::vector< double >::clear)
 | 
|---|
 | 76 |       .def("append", &MoleCuilder::PythonTypes::vec_item< std::vector< double > >::add,
 | 
|---|
 | 77 |             boost::python::with_custodian_and_ward<1, 2>()) // let container keep value
 | 
|---|
 | 78 |       .def("__getitem__", &MoleCuilder::PythonTypes::vec_item< std::vector< double > >::get,
 | 
|---|
 | 79 |            boost::python::return_value_policy<boost::python::copy_non_const_reference>())
 | 
|---|
 | 80 |       .def("__setitem__", &MoleCuilder::PythonTypes::vec_item< std::vector< double > >::set,
 | 
|---|
 | 81 |            boost::python::with_custodian_and_ward<1,2>()) // to let container keep value
 | 
|---|
 | 82 |       .def("__delitem__", &MoleCuilder::PythonTypes::vec_item< std::vector< double > >::del)
 | 
|---|
 | 83 |       .def("__iter__", boost::python::iterator< std::vector< double > >())
 | 
|---|
 | 84 |   ;
 | 
|---|
 | 85 | 
 | 
|---|
 | 86 | 
 | 
|---|
 | 87 | #define export_print(z,n,list) \
 | 
|---|
 | 88 |   BOOST_PP_CAT(export_, BOOST_PP_SEQ_ELEM(n, list))();
 | 
|---|
 | 89 | #define BOOST_PP_LOCAL_MACRO(n) export_print(~, n, GLOBALLISTOFACTIONS)
 | 
|---|
 | 90 | #define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(GLOBALLISTOFACTIONS)))
 | 
|---|
 | 91 | #include BOOST_PP_LOCAL_ITERATE()
 | 
|---|
 | 92 | #undef instance_print
 | 
|---|
 | 93 | }
 | 
|---|
 | 94 | 
 | 
|---|
 | 95 | bool executePythonScript(const std::string &pythonfilename_string)
 | 
|---|
 | 96 | {
 | 
|---|
 | 97 |   boost::filesystem::path pythonfilename(pythonfilename_string);
 | 
|---|
 | 98 |   if (exists(pythonfilename)) {
 | 
|---|
 | 99 |     // parse in and execute the local and global config.py
 | 
|---|
 | 100 |     try {
 | 
|---|
 | 101 |       PyImport_AppendInittab( "pyMoleCuilder", &initpyMoleCuilder );
 | 
|---|
 | 102 | 
 | 
|---|
 | 103 |       Py_Initialize();
 | 
|---|
 | 104 | 
 | 
|---|
 | 105 |       boost::python::object main_module((
 | 
|---|
 | 106 |           boost::python::handle<>(boost::python::borrowed(PyImport_AddModule("__main__")))));
 | 
|---|
 | 107 | 
 | 
|---|
 | 108 |       boost::python::object main_namespace = main_module.attr("__dict__");
 | 
|---|
 | 109 | 
 | 
|---|
 | 110 |       boost::python::object molecuilder_module( (boost::python::handle<>(PyImport_ImportModule("pyMoleCuilder"))) );
 | 
|---|
 | 111 |       main_namespace["pyMoleCuilder"] = molecuilder_module;
 | 
|---|
 | 112 | 
 | 
|---|
 | 113 |       // parse file into a string
 | 
|---|
 | 114 |       std::ifstream pythonfile(pythonfilename.string().c_str());
 | 
|---|
 | 115 |       std::string pythonscript( std::istreambuf_iterator<char>(pythonfile),
 | 
|---|
 | 116 |           (std::istreambuf_iterator<char>()) );
 | 
|---|
 | 117 |       std::string enveloped_script("print \"BEGIN of "+pythonfilename_string+":\"\n");
 | 
|---|
 | 118 |       enveloped_script += pythonscript;
 | 
|---|
 | 119 |       enveloped_script += std::string("print \"END of "+pythonfilename_string+":\"\n");
 | 
|---|
 | 120 | 
 | 
|---|
 | 121 |       boost::python::handle<> ignored(( PyRun_String( enveloped_script.c_str(),
 | 
|---|
 | 122 |           Py_file_input,
 | 
|---|
 | 123 |           main_namespace.ptr(),
 | 
|---|
 | 124 |           main_namespace.ptr() ) ));
 | 
|---|
 | 125 | 
 | 
|---|
 | 126 |     } catch( boost::python::error_already_set ) {
 | 
|---|
 | 127 |       PyErr_Print();
 | 
|---|
 | 128 |     }
 | 
|---|
 | 129 |   }
 | 
|---|
 | 130 | }
 | 
|---|
 | 131 | 
 | 
|---|
 | 132 | #endif /* PYTHONSCRIPTING_HPP_ */
 | 
|---|