/*
* Project: MoleCuilder
* Description: creates and alters molecular systems
* Copyright (C) 2010-2012 University of Bonn. All rights reserved.
*
*
* This file is part of MoleCuilder.
*
* MoleCuilder is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* MoleCuilder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MoleCuilder. If not, see .
*/
/*
* 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
}