OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
PyOpalObject.h
Go to the documentation of this file.
1//
2// Python API for PolynomialCoefficient (part of the multidimensional polynomial fitting routines)
3//
4// Copyright (c) 2008-2023, Chris Rogers, STFC Rutherford Appleton Laboratory, Didcot, UK
5//
6// This file is part of OPAL.
7//
8// OPAL is free software: you can redistribute it and/or modify
9// it under the terms of the GNU General Public License as published by
10// the Free Software Foundation, either version 3 of the License, or
11// (at your option) any later version.
12//
13// You should have received a copy of the GNU General Public License
14// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
15//
16
17#ifndef PyOpalObject_H
18#define PyOpalObject_H
19
20#include <Python.h>
21#include <structmember.h>
22
23#include <memory>
24#include <exception>
25#include <iostream>
26#include <boost/python.hpp>
27#include <boost/noncopyable.hpp>
28#include <boost/mpl/front.hpp>
29
37
38extern Inform *gmsg;
39
40namespace PyOpal {
41
66namespace PyOpalObjectNS {
67
68// forward declarations
69template <class C> class PyOpalObject;
70template <class C> struct PyOpalObjectGetProperty;
71template <class C> struct PyOpalObjectSetProperty;
72
82
84extern std::map<AttributeType, std::string> attributeName; // defined in PyOpalObject.cpp
85
95 std::string opalName_m;
96 std::string pyName_m;
97 std::string docString_m;
99 // could also add a "read only" flag as some attributes are read only
100};
101
137template <class C>
139public:
140 typedef PyOpalObject<C> PyC; // for convenience
142 inline PyOpalObject();
144 PyOpalObject(std::shared_ptr<C> object) : object_m(object) {}
146 PyOpalObject(const PyOpalObject<C>& rhs);
148 virtual ~PyOpalObject() = default;
149
156 inline boost::python::class_<PyC> make_class(const char* className);
157
163 inline boost::python::class_<PyC> make_element_class(const char* className);
164
165
171 inline boost::python::class_<PyC> make_generic_class(const char* className);
172
173
176 template <class PYCLASS>
177 void addAttributes(PYCLASS& pyclass);
178
181 template <class PYCLASS>
182 void addExecute(PYCLASS& pyclass);
183
187 template <class PYCLASS>
188 void addRegister(PYCLASS& pyclass);
189
193 template <class PYCLASS>
194 void addGetOpalName(PYCLASS& pyclass);
195
199 template <class PYCLASS>
200 void addSetAttributes(PYCLASS& pyclass);
201
205 template <class PYCLASS>
206 void addSetOpalName(PYCLASS& pyclass);
207
212 template <class PYCLASS>
213 void addSetOpalElementName(PYCLASS& pyclass);
214
223 template <class PYCLASS>
224 void addGetOpalElement(PYCLASS& pyclass);
225
244 template <class PYCLASS>
245 void addGetFieldValue(PYCLASS& pyclass,
246 double distanceUnits, double timeUnits,
247 double bfieldUnits, double efieldUnits);
248
252 template <class ValueType>
253 ValueType dummyGet() const {PyOpalObjectGetProperty<C>::setObject(this); return ValueType();}
254
258 virtual void doSetup() {}
259
263 template <class ValueType>
264 inline void dummySet(ValueType test);
265
274 PyObject* getAttribute(AttributeType type, std::string opalName) const;
275
283 void setAttribute(AttributeType type, std::string opalName, PyObject* value);
284
286 std::shared_ptr<C> getOpalShared() {return object_m;}
287
289 std::shared_ptr<C> getOpalShared() const {return object_m;}
290
291
292protected:
293 static std::vector<AttributeDef> attributes;
294 static std::map<std::string, AttributeDef> pyNameToAttribute;
295 static std::string classDocstring;
297 std::shared_ptr<C> object_m;
298
300 std::string getDocString(AttributeDef& def);
302 static boost::python::object getFieldValue(
304 double x, double y, double z, double t);
306 static std::string getOpalName(const PyOpalObject<C>& pyobject);
308 static void setOpalName(PyOpalObject<C>& pyobject, std::string name);
311 static void setOpalElementName(PyOpalObject<C>& pyobject, std::string name);
313 static void execute(PyOpalObject<C>& pyobject);
315 static void registerObject(PyOpalObject<C>& pyobject);
317 static boost::python::object getPyOpalElement(PyOpalObject<C>& pyobject);
320 static boost::python::object setAttributes(boost::python::tuple args,
321 boost::python::dict kwargs);
322 // unit definitions for getFieldValue method
323 static double distanceUnits_m;
324 static double timeUnits_m;
325 static double bfieldUnits_m;
326 static double efieldUnits_m;
327 static const std::string getFieldValueDocString;
328};
329
331template <class C>
332std::map<std::string, AttributeDef> PyOpalObject<C>::pyNameToAttribute;
333
339template <class C>
341 std::shared_ptr<C> objectPtr = pyelement.getOpalShared();
342 objectPtr->update();
343}
344
345template <class C>
346template <class ValueType>
347void PyOpalObject<C>::dummySet(ValueType test) {
348 (void)test; // disable Wunused-parameter
350}
351
352template <class C>
353boost::python::object PyOpalObject<C>::getFieldValue(
355 double x, double y, double z, double t) {
356 std::shared_ptr<C> objectPtr = pyobject.getOpalShared();
357 objectPtr->update();
358 pyobject.doSetup();
359 ElementBase* element = objectPtr->getElement();
360 Component* component = dynamic_cast<Component*>(element);
361 if (component == nullptr) {
362 throw OpalException("PyElement<C>::getFieldValue",
363 "Failed to deduce Component from ElementBase.");
364 }
366 Vector_t P(0.0, 0.0, 0.0);
367 Vector_t B;
368 Vector_t E;
369 t *= timeUnits_m;
370 bool outOfBounds = component->apply(R, P, t, E, B);
371 return boost::python::make_tuple(outOfBounds,
373 E[0]*efieldUnits_m, E[1]*efieldUnits_m, E[2]*efieldUnits_m);
374}
375
377template <class C>
378boost::python::object PyOpalObject<C>::setAttributes(boost::python::tuple args,
379 boost::python::dict kwargs) {
380 if (boost::python::len(args) == 0) {
381 throw OpalException("PyOpalObject::setAttributes",
382 "Did not find class instance (i.e. 'self') when calling "
383 "set_attributes");
384 } else if (boost::python::len(args) > 1) {
385 throw OpalException("PyOpalObject::setAttributes",
386 "set_attributes cannot take any non-keyword args (except the class"
387 " instance");
388 }
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];
395 if (PyOpalObject<C>::pyNameToAttribute.find(keyStr) ==
397 throw OpalException("PyOpalObject::setAttributes",
398 "Did not recognise attribute '"+keyStr+"'");
399 }
401 self.setAttribute(att.type_m, att.opalName_m, value.ptr());
402 }
403 boost::python::object obj;
404 return obj;
405}
406
408template <class C>
409struct PyOpalObjectGetProperty : boost::python::default_call_policies {
410public:
415 PyOpalObjectGetProperty(AttributeType type, std::string opalName): type_m(type), opalName_m(opalName) {}
418
426 template <class ArgumentPackage>
427 PyObject* postcall(ArgumentPackage const&, PyObject* result);
428
430 static void setObject(const PyOpalObject<C>* object) {object_m = object;}
431
432private:
434 std::string opalName_m;
436};
437
439template <class C>
440struct PyOpalObjectSetProperty : boost::python::default_call_policies {
441public:
446 PyOpalObjectSetProperty(AttributeType type, std::string opalName): type_m(type), opalName_m(opalName) {}
449
457 template <class ArgumentPackage>
458 PyObject* postcall(ArgumentPackage const& args, PyObject* result);
459
461 static void setObject(PyOpalObject<C>* object) {object_m = object;}
462
463private:
465 std::string opalName_m;
467};
468
470
471
472template <class C>
474 std::shared_ptr<C> objectPtr = pyobject.getOpalShared();
475 objectPtr->execute();
476}
477
478template <class C>
480 C* wrappedC = pyobject.getOpalShared().get();
481 Object* objectPtr = dynamic_cast<Object*>(wrappedC);
482 if (objectPtr == nullptr) {
483 throw OpalException("PyOpalObject<C>::registerObject",
484 "Trying to register something that was not a Opal Object");
485 }
486 //Object* objectPtr = &(*pyobject.getOpalShared());
487 OpalData::getInstance()->define(objectPtr);
488}
489
490template <class C>
491std::string PyOpalObject<C>::getOpalName(const PyOpalObject<C>& pyobject) {
492 std::shared_ptr<C> objectPtr = pyobject.getOpalShared();
493 return objectPtr->getOpalName();
494}
495
496template <class C>
498 std::shared_ptr<C> objectPtr = pyobject.getOpalShared();
499 objectPtr->setOpalName(name);
500}
501
502template <class C>
504 std::shared_ptr<C> objectPtr = pyobject.getOpalShared();
505 objectPtr->setOpalName(name);
506 if (objectPtr->getElement()) { // some OpalThings don't define an Element
507 objectPtr->getElement()->setName(name);
508 }
509}
510
511template <class C>
513 std::shared_ptr<OpalElement> elementPtr =
514 std::dynamic_pointer_cast<OpalElement, C>(pyobject.getOpalShared());
515 if (elementPtr.get() == nullptr) {
516 throw OpalException("PyOpalObject<C>::getPyOpalElement",
517 "Wrapped object was not an OpalElement");
518 }
519 PyOpalObject<OpalElement> element(elementPtr);
520 boost::python::object pyelement(element);
521 return pyelement;
522}
523
524
525// defined in PyOpalElement
526template <>
528
529template <class C>
531
532template <class C>
533PyObject* PyOpalObject<C>::getAttribute(AttributeType type, std::string opalName) const {
534 if (!object_m) {
535 throw OpalException("PyOpalObject<C>::getRealAttribute",
536 "Object was not initialised");
537 }
538 Attribute* attribute = object_m->findAttribute(opalName);
539 if (attribute == nullptr) {
540 throw OpalException("PyOpalObject<C>::getRealAttribute",
541 "Failed to parse attribute "+opalName);
542 }
543 PyObject* pyvalue;
544 // I spent quite a bit of time trying to get this type unwinding to work
545 // using templates (so it is done at compile time). In the end I couldn't
546 // fight the template syntax and had to do it at runtime using an enum; it's
547 // not so bad - the memory footprint is smaller and, tbh, template syntax is
548 // horrible so might be easier to use.
549 switch (type) {
550 case DOUBLE:
551 {
552 double value = Attributes::getReal(*attribute);
553 pyvalue = PyFloat_FromDouble(value);
554 break;
555 }
556 case INT:
557 {
558 double value = Attributes::getReal(*attribute);
559 pyvalue = PyLong_FromDouble(value);
560 break;
561 }
562 case STRING:
565 {
566 std::string value = Attributes::getString(*attribute);
567 pyvalue = PyUnicode_FromString(value.c_str());
568 break;
569 }
570 case BOOL:
571 {
572 bool value = Attributes::getBool(*attribute);
573 if (value) {
574 pyvalue = Py_True;
575 } else {
576 pyvalue = Py_False;
577 }
578 break;
579 }
580 case FLOAT_LIST:
581 {
582 std::vector<double> value = Attributes::getRealArray(*attribute);
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]));
586 }
587 break;
588 }
589 case STRING_LIST:
590 {
591 std::vector<std::string> value = Attributes::getStringArray(*attribute);
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()));
595 }
596 break;
597 }
598 default:
599 {
600 throw OpalException("PyOpalObject<C>::getAttribute",
601 "Attribute type "+attributeName[type]+" not implemented");
602 }
603 }
604 Py_INCREF(pyvalue);
605 return pyvalue;
606}
607
608
609template <class C>
610void PyOpalObject<C>::setAttribute(AttributeType type, std::string opalName, PyObject* pyvalue) {
611 if (!object_m) {
612 throw OpalException("PyOpalObject<C>::setAttribute",
613 "Element was not initialised");
614 }
615 Attribute* attribute = object_m->findAttribute(opalName);
616 if (attribute == nullptr) {
617 throw OpalException("PyOpalObject<C>::setAttribute",
618 "Failed to parse attribute "+opalName);
619 }
620 switch (type) {
621 case DOUBLE:
622 {
623 double value = PyFloat_AsDouble(pyvalue);
624 Attributes::setReal(*attribute, value);
625 break;
626 }
627 case INT:
628 {
629 double value = PyLong_AsDouble(pyvalue);
630 Attributes::setReal(*attribute, value);
631 break;
632 }
633 case STRING:
634 {
635 std::string value = PyUnicode_AsUTF8(pyvalue);
636 Attributes::setString(*attribute, value);
637 break;
638 }
640 {
641 // predefined string is a string with a list of options
642 // note that value checking never happens - method exists in
643 // src/Attributes/PredefinedString.h but requires a Statement object
644 // which seems hard to construct (Classic/Parser/Statement.h)
645 std::string value = PyUnicode_AsUTF8(pyvalue);
646 Attributes::setPredefinedString(*attribute, value);
647 break;
648 }
650 {
651 std::string value = PyUnicode_AsUTF8(pyvalue);
652 Attributes::setUpperCaseString(*attribute, value);
653 break;
654 }
655 case BOOL:
656 {
657 bool value = PyObject_IsTrue(pyvalue);
658 Attributes::setBool(*attribute, value);
659 break;
660 }
661 case FLOAT_LIST:
662 {
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));
667 value[i] = value_i;
668 }
669 Attributes::setRealArray(*attribute, value);
670 break;
671 }
672 case STRING_LIST:
673 {
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);
679 value[i] = value_i;
680 }
681 Attributes::setStringArray(*attribute, value);
682 break;
683 }
684 default:
685 {
686 throw OpalException("PyOpalObject<C>::setAttribute",
687 "Attribute type "+attributeName[type]+" not implemented");
688 }
689 }
690}
691
692template <class C>
695
696template <class C>
698 Attribute* attribute = object_m->findAttribute(def.opalName_m);
699 if (attribute == nullptr) {
700 throw OpalException("PyOpalObject<C>::getRealAttribute",
701 "Failed to parse attribute "+def.opalName_m);
702 }
703 std::string docString = def.pyName_m+" ("+attributeName[def.type_m]+"): "+attribute->getHelp();
704 if (def.docString_m != "") {
705 docString = def.pyName_m+" ("+attributeName[def.type_m]+"): "+def.docString_m;
706 }
707 return docString;
708}
709
710template <class C>
711boost::python::class_<PyOpalObject<C> > PyOpalObject<C>::make_generic_class(const char* className) {
712 // WARNING - boost::python is bugged so that in module initialisation,
713 // errors are not handled correctly
714 // https://github.com/boostorg/python/issues/280
715 // so if you get the attribute name wrong you get a bad error
716 // hence I do some local error handling
717 typedef boost::python::class_<PyOpalObject<C> > PyClass;
718 boost::python::docstring_options docop(true, true, false); // user_def, py_sig, cpp_sig
719 PyClass pyclass = PyClass(className);
720 try {
721 addAttributes(pyclass);
722 addGetOpalName(pyclass);
723 addSetAttributes(pyclass);
724 } catch (OpalException& exc) {
725 std::cerr << "Failed to initialise class because '" << exc.what()
726 << "'" << std::endl;
727 throw exc;
728 } catch (std::exception& exc) {
729 std::cerr << "Failed to initialise class because '" << exc.what()
730 << "'" << std::endl;
731 throw exc;
732 }
733 if (gmsg == nullptr) {
734 std::cerr <<
735 "Failed to initialise class because gmsg was not initialised.\n"
736 "PyOpal::Globals::Initialise() must be called before attempting to\n"
737 "initialise classes" << std::endl;
738 throw OpalException("PyOpalObject::make_generic_class",
739 "Globals not initialised");
740 }
741 return pyclass;
742}
743
744template <class C>
745boost::python::class_<PyOpalObject<C> > PyOpalObject<C>::make_class(const char* className) {
746 auto pyclass = make_generic_class(className);
747 addSetOpalName(pyclass);
748 return pyclass;
749}
750
751template <class C>
752boost::python::class_<PyOpalObject<C> > PyOpalObject<C>::make_element_class(const char* className) {
753 auto pyclass = make_generic_class(className);
754 addSetOpalElementName(pyclass);
755 addGetOpalElement(pyclass);
756 return pyclass;
757}
758
759template <class C>
760template <class PYCLASS>
761void PyOpalObject<C>::addExecute(PYCLASS& pyclass) {
762 pyclass.def("execute", &PyOpalObject<C>::execute);
763}
764
765template <class C>
766template <class PYCLASS>
767void PyOpalObject<C>::addRegister(PYCLASS& pyclass) {
768 pyclass.def("register", &PyOpalObject<C>::registerObject);
769}
770
771template <class C>
772template <class PYCLASS>
773void PyOpalObject<C>::addGetOpalName(PYCLASS& pyclass) {
774 pyclass.def("get_opal_name", &PyOpalObject<C>::getOpalName);
775}
776
777template <class C>
778template <class PYCLASS>
779void PyOpalObject<C>::addSetAttributes(PYCLASS& pyclass) {
780 pyclass.def("set_attributes",
781 boost::python::raw_function(&PyOpalObject<C>::setAttributes, 0)
782 );
783}
784
785template <class C>
786template <class PYCLASS>
787void PyOpalObject<C>::addSetOpalName(PYCLASS& pyclass) {
788 pyclass.def("set_opal_name", &PyOpalObject<C>::setOpalName);
789}
790
791template <class C>
792template <class PYCLASS>
794 pyclass.def("set_opal_name", &PyOpalObject<C>::setOpalElementName);
795}
796
797template <class C>
798template <class PYCLASS>
800 pyclass.def("get_opal_element", &PyOpalObject<C>::getPyOpalElement);
801}
802
803template <class C>
804template <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());
816}
817
818template <class C>
819template <class PYCLASS>
820void PyOpalObject<C>::addAttributes(PYCLASS& pyclass) {
821 for (std::vector<AttributeDef>::iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
822 pyNameToAttribute[iter->pyName_m] = *iter;
823 PyOpalObjectGetProperty<C> getProp(iter->type_m, iter->opalName_m);
824 PyOpalObjectSetProperty<C> setProp(iter->type_m, iter->opalName_m);
825 std::string docString = getDocString(*iter);
826 std::string pyname = iter->pyName_m.c_str();
827 switch (iter->type_m) {
828 case DOUBLE:
829 {
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),
833 docString.c_str()
834 );
835 break;
836 }
837 case INT:
838 {
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),
842 docString.c_str()
843 );
844 break;
845 }
846 case STRING:
849 {
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),
853 docString.c_str()
854 );
855 break;
856 }
857 case BOOL:
858 {
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),
862 docString.c_str()
863 );
864 break;
865 }
866 case FLOAT_LIST:
867 case STRING_LIST:
868 {
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),
872 docString.c_str()
873 );
874 break;
875 }
876 default:
877 {
878 // Looks like exception handling doesn't work properly at module
879 // import time so this may not be handled politely - thrown as an
880 // unrecognised SystemError
881 throw OpalException("PyOpalObject<C>::addAttributes", "Type not implemented");
882 }
883 }
884 }
885}
886
887template <class C> double PyOpalObject<C>::distanceUnits_m = 1;
888template <class C> double PyOpalObject<C>::timeUnits_m = 1;
889template <class C> double PyOpalObject<C>::bfieldUnits_m = 1;
890template <class C> double PyOpalObject<C>::efieldUnits_m = 1;
891
892template <class C> const std::string PyOpalObject<C>::getFieldValueDocString =
893 "Get the field value at a point in the field map.\n"
894 "\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"
898 "\n"
899 "Parameters\n"
900 "----------\n"
901 "x : float\n"
902 " x position [m]\n"
903 "y : float\n"
904 " y position [m]\n"
905 "z : float\n"
906 " z position [m]\n"
907 "t: float\n"
908 " time [ns]\n"
909 "\n"
910 "Returns\n"
911 "-------\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"
915 "Bx : float\n"
916 " x magnetic field [T]\n"
917 "By : float\n"
918 " y magnetic field [T]\n"
919 "Bz : float\n"
920 " z magnetic field [T]\n"
921 "Ex : float\n"
922 " x electric field [MV/m]\n"
923 "Ey : float\n"
924 " y electric field [MV/m]\n"
925 "Ez : float\n"
926 " z electric field [MV/m]\n";
927
928
930
931template <class C>
932template <class ArgumentPackage>
933PyObject* PyOpalObjectGetProperty<C>::postcall(ArgumentPackage const&, PyObject* result) {
934 Py_DECREF(result);
935 result = object_m->getAttribute(type_m, opalName_m);
936 return result;
937}
938
939template <class C>
941
943
944template <class C>
945template <class ArgumentPackage>
946PyObject* PyOpalObjectSetProperty<C>::postcall(ArgumentPackage const& args, PyObject* result) {
947 PyObject* value;
948 PyObject* pyObject; // this is a direct pointer to the C but I don't know how to unwrap it...
949 if (!PyArg_ParseTuple(args, "OO", &pyObject, &value)) {
950 return nullptr; // ParseTuple sets the error message
951 }
952 Py_DECREF(result);
953 object_m->setAttribute(type_m, opalName_m, value);
954 object_m = nullptr;
955 Py_RETURN_NONE;
956}
957
958template <class C>
960
961} // PyOpalObject
962} // PyOpal
963
964#endif // PyOpalObject_H
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
Inform * gmsg
Definition Main.cpp:70
const std::string name
double getReal(const Attribute &attr)
Return real value.
void setRealArray(Attribute &attr, const std::vector< double > &value)
Set array value.
void setBool(Attribute &attr, bool val)
Set logical value.
void setUpperCaseString(Attribute &attr, const std::string &val)
Set uppercase string value.
void setString(Attribute &attr, const std::string &val)
Set string value.
bool getBool(const Attribute &attr)
Return logical value.
void setReal(Attribute &attr, double val)
Set real value.
void setStringArray(Attribute &attr, const std::vector< std::string > &value)
Set string array value.
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
std::vector< std::string > getStringArray(const Attribute &attr)
Get string array value.
void setPredefinedString(Attribute &attr, const std::string &val)
Set predefined string value.
std::string getString(const Attribute &attr)
Get string value.
std::map< AttributeType, std::string > attributeName
void update(PyOpalObjectNS::PyOpalObject< C > pyelement)
A representation of an Object attribute.
Definition Attribute.h:52
const std::string & getHelp() const
Return the help string.
Definition Attribute.cpp:82
The base class for all OPAL objects.
Definition Object.h:48
static OpalData * getInstance()
Definition OpalData.cpp:196
void define(Object *newObject)
Define a new object.
Definition OpalData.cpp:489
Interface for a single beam element.
Definition Component.h:50
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B)
Definition Component.cpp:99
void addRegister(PYCLASS &pyclass)
void addGetOpalName(PYCLASS &pyclass)
static std::string getOpalName(const PyOpalObject< C > &pyobject)
void addSetOpalName(PYCLASS &pyclass)
static std::vector< AttributeDef > attributes
static void registerObject(PyOpalObject< C > &pyobject)
static std::map< std::string, AttributeDef > pyNameToAttribute
void addAttributes(PYCLASS &pyclass)
void addGetOpalElement(PYCLASS &pyclass)
static boost::python::object setAttributes(boost::python::tuple args, boost::python::dict kwargs)
void addSetOpalElementName(PYCLASS &pyclass)
boost::python::class_< PyC > make_generic_class(const char *className)
void addGetFieldValue(PYCLASS &pyclass, double distanceUnits, double timeUnits, double bfieldUnits, double efieldUnits)
std::string getDocString(AttributeDef &def)
PyOpalObject(std::shared_ptr< C > object)
static boost::python::object getFieldValue(PyOpalObjectNS::PyOpalObject< C > &pyobject, double x, double y, double z, double t)
static boost::python::object getPyOpalElement(PyOpalObject< C > &pyobject)
static void setOpalElementName(PyOpalObject< C > &pyobject, std::string name)
void addSetAttributes(PYCLASS &pyclass)
std::shared_ptr< C > getOpalShared()
PyObject * getAttribute(AttributeType type, std::string opalName) const
boost::python::class_< PyC > make_class(const char *className)
static void execute(PyOpalObject< C > &pyobject)
boost::python::class_< PyC > make_element_class(const char *className)
void addExecute(PYCLASS &pyclass)
static const std::string getFieldValueDocString
std::shared_ptr< C > getOpalShared() const
static void setOpalName(PyOpalObject< C > &pyobject, std::string name)
void setAttribute(AttributeType type, std::string opalName, PyObject *value)
static void setObject(const PyOpalObject< C > *object)
static const PyOpalObject< C > * object_m
PyObject * postcall(ArgumentPackage const &, PyObject *result)
PyOpalObjectGetProperty(AttributeType type, std::string opalName)
static void setObject(PyOpalObject< C > *object)
PyObject * postcall(ArgumentPackage const &args, PyObject *result)
PyOpalObjectSetProperty(AttributeType type, std::string opalName)
The base class for all OPAL exceptions.
virtual const std::string & what() const
Return the message string for the exception.
Vektor< double, 3 > Vector_t