17 #ifndef PyOpalObject_H
18 #define PyOpalObject_H
21 #include <structmember.h>
26 #include <boost/python.hpp>
27 #include <boost/noncopyable.hpp>
28 #include <boost/mpl/front.hpp>
66 namespace PyOpalObjectNS {
156 inline boost::python::class_<PyC>
make_class(
const char* className);
176 template <
class PYCLASS>
181 template <
class PYCLASS>
187 template <
class PYCLASS>
193 template <
class PYCLASS>
199 template <
class PYCLASS>
205 template <
class PYCLASS>
212 template <
class PYCLASS>
223 template <
class PYCLASS>
244 template <
class PYCLASS>
246 double distanceUnits,
double timeUnits,
247 double bfieldUnits,
double efieldUnits);
252 template <
class ValueType>
263 template <
class ValueType>
264 inline void dummySet(ValueType test);
304 double x,
double y,
double z,
double t);
320 static boost::python::object
setAttributes(boost::python::tuple args,
321 boost::python::dict kwargs);
346 template <
class ValueType>
355 double x,
double y,
double z,
double t) {
361 if (component ==
nullptr) {
363 "Failed to deduce Component from ElementBase.");
365 Vector_t R(x*distanceUnits_m, y*distanceUnits_m, z*distanceUnits_m);
370 bool outOfBounds = component->
apply(R, P, t, E, B);
371 return boost::python::make_tuple(outOfBounds,
372 B[0]*bfieldUnits_m, B[1]*bfieldUnits_m, B[2]*bfieldUnits_m,
373 E[0]*efieldUnits_m, E[1]*efieldUnits_m, E[2]*efieldUnits_m);
379 boost::python::dict kwargs) {
380 if (boost::python::len(args) == 0) {
382 "Did not find class instance (i.e. 'self') when calling "
384 }
else if (boost::python::len(args) > 1) {
386 "set_attributes cannot take any non-keyword args (except the class"
389 PyOpalObject<C> self = boost::python::extract<PyOpalObject<C> >(args[0]);
390 boost::python::list key_list = kwargs.keys();
391 for (boost::python::ssize_t i = 0; i < boost::python::len(key_list); ++i) {
392 boost::python::object key = key_list[i];
393 std::string keyStr = boost::python::extract<std::string>(key);
394 boost::python::object value = kwargs[key];
398 "Did not recognise attribute '"+keyStr+
"'");
403 boost::python::object obj;
426 template <
class ArgumentPackage>
457 template <
class ArgumentPackage>
458 PyObject*
postcall(ArgumentPackage
const& args, PyObject*
result);
475 objectPtr->execute();
482 if (objectPtr ==
nullptr) {
484 "Trying to register something that was not a Opal Object");
493 return objectPtr->getOpalName();
499 objectPtr->setOpalName(name);
505 objectPtr->setOpalName(name);
506 if (objectPtr->getElement()) {
507 objectPtr->getElement()->setName(name);
513 std::shared_ptr<OpalElement> elementPtr =
515 if (elementPtr.get() ==
nullptr) {
517 "Wrapped object was not an OpalElement");
520 boost::python::object pyelement(element);
536 "Object was not initialised");
538 Attribute* attribute = object_m->findAttribute(opalName);
539 if (attribute ==
nullptr) {
541 "Failed to parse attribute "+opalName);
553 pyvalue = PyFloat_FromDouble(value);
559 pyvalue = PyLong_FromDouble(value);
567 pyvalue = PyUnicode_FromString(value.c_str());
583 pyvalue = PyList_New(value.size());
584 for (
size_t i = 0; i < value.size(); ++i) {
585 PyList_SetItem(pyvalue, i, PyFloat_FromDouble(value[i]));
592 pyvalue = PyList_New(value.size());
593 for (
size_t i = 0; i < value.size(); ++i) {
594 PyList_SetItem(pyvalue, i, PyUnicode_FromString(value[i].c_str()));
613 "Element was not initialised");
615 Attribute* attribute = object_m->findAttribute(opalName);
616 if (attribute ==
nullptr) {
618 "Failed to parse attribute "+opalName);
623 double value = PyFloat_AsDouble(pyvalue);
629 double value = PyLong_AsDouble(pyvalue);
635 std::string value = PyUnicode_AsUTF8(pyvalue);
645 std::string value = PyUnicode_AsUTF8(pyvalue);
651 std::string value = PyUnicode_AsUTF8(pyvalue);
657 bool value = PyObject_IsTrue(pyvalue);
663 Py_ssize_t listSize = PyList_Size(pyvalue);
664 std::vector<double> value(listSize);
665 for (Py_ssize_t i = 0; i < listSize; ++i) {
666 double value_i = PyFloat_AsDouble(PyList_GetItem(pyvalue, i));
674 Py_ssize_t listSize = PyList_Size(pyvalue);
675 std::vector<std::string> value(listSize);
676 for (Py_ssize_t i = 0; i < listSize; ++i) {
677 PyObject* pyvalue_i = PyList_GetItem(pyvalue, i);
678 std::string value_i = PyUnicode_AsUTF8(pyvalue_i);
699 if (attribute ==
nullptr) {
717 typedef boost::python::class_<PyOpalObject<C> > PyClass;
718 boost::python::docstring_options docop(
true,
true,
false);
719 PyClass pyclass = PyClass(className);
721 addAttributes(pyclass);
722 addGetOpalName(pyclass);
723 addSetAttributes(pyclass);
725 std::cerr <<
"Failed to initialise class because '" << exc.
what()
729 std::cerr <<
"Failed to initialise class because '" << exc.
what()
733 if (gmsg ==
nullptr) {
735 "Failed to initialise class because gmsg was not initialised.\n"
736 "PyOpal::Globals::Initialise() must be called before attempting to\n"
739 "Globals not initialised");
746 auto pyclass = make_generic_class(className);
747 addSetOpalName(pyclass);
753 auto pyclass = make_generic_class(className);
754 addSetOpalElementName(pyclass);
755 addGetOpalElement(pyclass);
760 template <
class PYCLASS>
766 template <
class PYCLASS>
772 template <
class PYCLASS>
778 template <
class PYCLASS>
780 pyclass.def(
"set_attributes",
786 template <
class PYCLASS>
792 template <
class PYCLASS>
798 template <
class PYCLASS>
804 template <
class PYCLASS>
806 double distanceUnits,
double timeUnits,
807 double efieldUnits,
double bfieldUnits) {
808 distanceUnits_m = distanceUnits;
809 timeUnits_m = timeUnits;
810 bfieldUnits_m = bfieldUnits;
811 efieldUnits_m = efieldUnits;
812 pyclass.def(
"get_field_value",
814 boost::python::args(
"x",
"y",
"z",
"t"),
815 getFieldValueDocString.c_str());
819 template <
class PYCLASS>
822 pyNameToAttribute[iter->pyName_m] = *iter;
825 std::string docString = getDocString(*iter);
826 std::string pyname = iter->pyName_m.c_str();
827 switch (iter->type_m) {
830 pyclass.add_property(pyname.c_str(),
831 boost::python::make_function(&PyC::dummyGet<double>, getProp),
832 boost::python::make_function(&PyC::dummySet<double>, setProp),
839 pyclass.add_property(pyname.c_str(),
840 boost::python::make_function(&PyC::dummyGet<int>, getProp),
841 boost::python::make_function(&PyC::dummySet<int>, setProp),
850 pyclass.add_property(pyname.c_str(),
851 boost::python::make_function(&PyC::dummyGet<std::string>, getProp),
852 boost::python::make_function(&PyC::dummySet<std::string>, setProp),
859 pyclass.add_property(pyname.c_str(),
860 boost::python::make_function(&PyC::dummyGet<bool>, getProp),
861 boost::python::make_function(&PyC::dummySet<bool>, setProp),
869 pyclass.add_property(pyname.c_str(),
870 boost::python::make_function(&PyC::dummyGet<boost::python::list>, getProp),
871 boost::python::make_function(&PyC::dummySet<boost::python::list>, setProp),
881 throw OpalException(
"PyOpalObject<C>::addAttributes",
"Type not implemented");
893 "Get the field value at a point in the field map.\n"
895 "The field lookup is performed against the last RINGDEFINITION that was\n"
896 "instantiated. This should be instantiated by calling\n"
897 "pyopal.parser.initialise_from_opal_file\n"
912 "The function returns a tuple containing 7 values:\n"
913 "out of bounds : int\n"
914 " 1 if the event was out of the field map boundary, else 0.\n"
916 " x magnetic field [T]\n"
918 " y magnetic field [T]\n"
920 " z magnetic field [T]\n"
922 " x electric field [MV/m]\n"
924 " y electric field [MV/m]\n"
926 " z electric field [MV/m]\n";
932 template <
class ArgumentPackage>
935 result = object_m->getAttribute(type_m, opalName_m);
945 template <
class ArgumentPackage>
949 if (!PyArg_ParseTuple(args,
"OO", &pyObject, &value)) {
953 object_m->setAttribute(type_m, opalName_m, value);
964 #endif // PyOpalObject_H
static OpalData * getInstance()
void setString(Attribute &attr, const std::string &val)
Set string value.
static double distanceUnits_m
void setRealArray(Attribute &attr, const std::vector< double > &value)
Set array value.
const std::string & getHelp() const
Return the help string.
The base class for all OPAL objects.
void setReal(Attribute &attr, double val)
Set real value.
std::string getString(const Attribute &attr)
Get string value.
virtual const std::string & what() const
Return the message string for the exception.
void addExecute(PYCLASS &pyclass)
std::map< AttributeType, std::string > attributeName
void define(Object *newObject)
Define a new object.
static boost::python::object setAttributes(boost::python::tuple args, boost::python::dict kwargs)
item[EANGLE] Entrance edge counterclockwise This enables to obtain skew at each point along the its radius is computed such that the reference trajectory always remains in the centre of the magnet In the body of the magnet the radius is set from the LENGTH and ANGLE attributes It is then continuously changed to be proportional to the dipole field on the reference trajectory while entering the end fields This attribute is only to be set TRUE for a non zero dipole component(Default:FALSE)\item[VARSTEP] The step size(meters) used in calculating the reference trajectory for VARRARDIUS
PyOpalObjectSetProperty(AttributeType type, std::string opalName)
static void setObject(const PyOpalObject< C > *object)
static std::map< std::string, AttributeDef > pyNameToAttribute
void setStringArray(Attribute &attr, const std::vector< std::string > &value)
Set string array value.
PyObject * postcall(ArgumentPackage const &args, PyObject *result)
static double timeUnits_m
static const std::string getFieldValueDocString
static void execute(PyOpalObject< C > &pyobject)
boost::python::class_< PyC > make_generic_class(const char *className)
std::shared_ptr< C > getOpalShared()
std::string getDocString(AttributeDef &def)
static double bfieldUnits_m
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
PyObject * getAttribute(AttributeType type, std::string opalName) const
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special the source code distributed need not include anything that is normally and so on of the operating system on which the executable unless that component itself accompanies the executable If distribution of executable or object code is made by offering access to copy from a designated then offering equivalent access to copy the source code from the same place counts as distribution of the source even though third parties are not compelled to copy the source along with the object code You may not or distribute the Program except as expressly provided under this License Any attempt otherwise to sublicense or distribute the Program is void
static double efieldUnits_m
Inform & endl(Inform &inf)
~PyOpalObjectSetProperty()
const T * find(const T table[], const std::string &name)
Look up name.
bool getBool(const Attribute &attr)
Return logical value.
std::string::iterator iterator
void update(PyOpalObjectNS::PyOpalObject< C > pyelement)
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B)
static void setOpalElementName(PyOpalObject< C > &pyobject, std::string name)
static boost::python::object getPyOpalElement(PyOpalObject< C > &pyobject)
void setUpperCaseString(Attribute &attr, const std::string &val)
Set uppercase string value.
static void registerObject(PyOpalObject< C > &pyobject)
PyObject * postcall(ArgumentPackage const &, PyObject *result)
The base class for all OPAL exceptions.
static void setOpalName(PyOpalObject< C > &pyobject, std::string name)
static std::string classDocstring
void addRegister(PYCLASS &pyclass)
boost::python::class_< PyC > make_element_class(const char *className)
void addAttributes(PYCLASS &pyclass)
PyOpalObjectGetProperty(AttributeType type, std::string opalName)
void addSetOpalName(PYCLASS &pyclass)
std::shared_ptr< C > object_m
void setPredefinedString(Attribute &attr, const std::string &val)
Set predefined string value.
~PyOpalObjectGetProperty()
void setBool(Attribute &attr, bool val)
Set logical value.
static bool converterRegistered
PyOpalObject(std::shared_ptr< C > object)
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special exception
std::shared_ptr< C > getOpalShared() const
static std::vector< AttributeDef > attributes
static boost::python::object getFieldValue(PyOpalObjectNS::PyOpalObject< C > &pyobject, double x, double y, double z, double t)
double getReal(const Attribute &attr)
Return real value.
void addGetFieldValue(PYCLASS &pyclass, double distanceUnits, double timeUnits, double bfieldUnits, double efieldUnits)
ValueType dummyGet() const
std::vector< std::string > getStringArray(const Attribute &attr)
Get string array value.
boost::python::class_< PyC > make_class(const char *className)
static const PyOpalObject< C > * object_m
static PyOpalObject< C > * object_m
Interface for a single beam element.
static std::string getOpalName(const PyOpalObject< C > &pyobject)
void setAttribute(AttributeType type, std::string opalName, PyObject *value)
void addSetOpalElementName(PYCLASS &pyclass)
void addSetAttributes(PYCLASS &pyclass)
void addGetOpalName(PYCLASS &pyclass)
void dummySet(ValueType test)
static void setObject(PyOpalObject< C > *object)
void addGetOpalElement(PYCLASS &pyclass)
A representation of an Object attribute.