/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * pyMoleCuilder.cpp * * Created on: Sep 21, 2011 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "CodePatterns/MemDebug.hpp" //!> define all present actions #include "GlobalListOfActions.hpp" //!> python wrapping for all of these actions #include "AllActionPython.hpp" #include "cleanUp.hpp" #include "Actions/ActionHistory.hpp" #include "cleanUp.hpp" namespace MoleCuilder { namespace detail { void module_exit() { // save everything std::cout << "Saving." << std::endl; saveAll(); // purge everything std::cout << "Cleaning memory." << std::endl; cleanUp(); } void module_reinit() { // save everything std::cout << "Saving." << std::endl; saveAll(); // purge everything std::cout << "Cleaning static instances from memory." << std::endl; purgeStaticInstances(); // need to init the history before any action is created std::cout << "Reinitializing." << std::endl; MoleCuilder::ActionHistory::init(); } } /* namespace detail */ namespace PythonTypes { inline void IndexError(){ PyErr_SetString(PyExc_IndexError, "Index out of range"); boost::python::throw_error_already_set(); } template struct vec_item{ typedef typename T::value_type V; static V& get(T& x, int i){ static V nothing; if(i < 0) i += x.size(); if(i >= 0 && i < int(x.size())) return x[i]; IndexError(); return nothing; } static void set(T& x, int i, V const& v){ if(i < 0) i += x.size(); if(i >= 0 && i < int(x.size())) x[i] = v; else IndexError(); } static void del(T& x, int i){ if(i < 0) i += x.size(); if(i >= 0 && i < int(x.size())) x.erase(x.begin() + i); else IndexError(); } static void add(T& x, V const& v){ x.push_back(v); } }; } /* namespace PythonTypes */ } /* namespace MoleCuilder */ BOOST_PYTHON_MODULE(pyMoleCuilder) { // need to init the history before any action is created MoleCuilder::ActionHistory::init(); // from this moment on, we need to be sure to deeinitialize in the correct order // this is handled by the cleanup function atexit(MoleCuilder::detail::module_exit); // set the docstring of the current module scope 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."; boost::python::def("reinit", MoleCuilder::detail::module_reinit, "Reinitializes the internal state of the python module as if it had been freshly imported, saves all input files beforehand."); // STL Vectors: // doubleVec boost::python::class_< std::vector< double > >("PythonType_doubleVec") .def("__len__", &std::vector< double >::size) .def("clear", &std::vector< double >::clear) .def("append", &MoleCuilder::PythonTypes::vec_item< std::vector< double > >::add, boost::python::with_custodian_and_ward<1, 2>()) // let container keep value .def("__getitem__", &MoleCuilder::PythonTypes::vec_item< std::vector< double > >::get, boost::python::return_value_policy()) .def("__setitem__", &MoleCuilder::PythonTypes::vec_item< std::vector< double > >::set, boost::python::with_custodian_and_ward<1,2>()) // to let container keep value .def("__delitem__", &MoleCuilder::PythonTypes::vec_item< std::vector< double > >::del) .def("__iter__", boost::python::iterator< std::vector< double > >()) ; #define export_print(z,n,list) \ BOOST_PP_CAT(export_, BOOST_PP_SEQ_ELEM(n, list))(); #define BOOST_PP_LOCAL_MACRO(n) export_print(~, n, GLOBALLISTOFACTIONS) #define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(GLOBALLISTOFACTIONS))) #include BOOST_PP_LOCAL_ITERATE() #undef instance_print }