OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
PyOpalObject.h
Go to the documentation of this file.
1#ifndef PyOpalObject_H
2
3#include <Python.h>
4#include <structmember.h>
5
6#include <memory>
7#include <exception>
8#include <iostream>
9#include <boost/python.hpp>
10#include <boost/noncopyable.hpp>
11#include <boost/mpl/front.hpp>
12
20
21namespace PyOpal {
22
47namespace PyOpalObjectNS {
48
49// forward declarations
50template <class C> class PyOpalObject;
51template <class C> struct PyOpalObjectGetProperty;
52template <class C> struct PyOpalObjectSetProperty;
53
63
65extern std::map<AttributeType, std::string> attributeName; // defined in PyOpalObject.cpp
66
75struct AttributeDef {
76 std::string opalName_m;
77 std::string pyName_m;
78 std::string docString_m;
80 // could also add a "read only" flag as some attributes are read only
81};
82
118template <class C>
120public:
121 typedef PyOpalObject<C> PyC; // for convenience
123 inline PyOpalObject();
125 PyOpalObject(std::shared_ptr<C> object) : object_m(object) {}
130
137 inline boost::python::class_<PyC> make_class(const char* className);
138
141 template <class PYCLASS>
142 void addAttributes(PYCLASS& pyclass);
143
146 template <class PYCLASS>
147 void addExecute(PYCLASS& pyclass);
148
152 template <class PYCLASS>
153 void addRegister(PYCLASS& pyclass);
154
158 template <class PYCLASS>
159 void addGetOpalName(PYCLASS& pyclass);
160
164 template <class PYCLASS>
165 void addSetOpalName(PYCLASS& pyclass);
166
175 template <class PYCLASS>
176 void addGetOpalElement(PYCLASS& pyclass);
177
196 template <class PYCLASS>
197 void addGetFieldValue(PYCLASS& pyclass,
198 double distanceUnits, double timeUnits,
199 double bfieldUnits, double efieldUnits);
200
204 template <class ValueType>
205 ValueType dummyGet() const {PyOpalObjectGetProperty<C>::setObject(this); return ValueType();}
206
210 template <class ValueType>
211 inline void dummySet(ValueType test);
212
221 PyObject* getAttribute(AttributeType type, std::string opalName) const;
222
230 void setAttribute(AttributeType type, std::string opalName, PyObject* value);
231
233 std::shared_ptr<C> getOpalShared() {return object_m;}
234
236 std::shared_ptr<C> getOpalShared() const {return object_m;}
237
238
239protected:
240 static std::vector<AttributeDef> attributes;
241 static std::string classDocstring;
242 static bool converterRegistered;
243 std::shared_ptr<C> object_m;
246 std::string getDocString(AttributeDef& def);
247 static boost::python::object getFieldValue(
249 double x, double y, double z, double t);
250 static std::string getOpalName(const PyOpalObject<C>& pyobject);
251 static void setOpalName(PyOpalObject<C>& pyobject, std::string name);
252 static void execute(PyOpalObject<C>& pyobject);
253 static void registerObject(PyOpalObject<C>& pyobject);
254 static boost::python::object getPyOpalElement(PyOpalObject<C>& pyobject);
255 // unit definitions for getFieldValue method
256 static double distanceUnits_m;
257 static double timeUnits_m;
258 static double bfieldUnits_m;
259 static double efieldUnits_m;
260 static const std::string getFieldValueDocString;
261};
262
263template <class C>
264template <class ValueType>
265void PyOpalObject<C>::dummySet(ValueType test) {
266 (void)test; // disable Wunused-parameter
268}
269
270template <class C>
271boost::python::object PyOpalObject<C>::getFieldValue(
273 double x, double y, double z, double t) {
274 std::shared_ptr<C> objectPtr = pyobject.getOpalShared();
275 objectPtr->update();
276 ElementBase* element = objectPtr->getElement();
277 Component* component = dynamic_cast<Component*>(element);
278 if (component == nullptr) {
279 throw OpalException("PyElement<C>::getFieldValue",
280 "Failed to deduce Component from ElementBase.");
281 }
282 Vector_t R(x*distanceUnits_m, y*distanceUnits_m, z*distanceUnits_m);
283 Vector_t P(0.0, 0.0, 0.0);
284 Vector_t B;
285 Vector_t E;
286 t *= timeUnits_m;
287 bool outOfBounds = component->apply(R, P, t, E, B);
288 return boost::python::make_tuple(outOfBounds,
289 B[0]*bfieldUnits_m, B[1]*bfieldUnits_m, B[2]*bfieldUnits_m,
290 E[0]*efieldUnits_m, E[1]*efieldUnits_m, E[2]*efieldUnits_m);
291}
292
294template <class C>
295struct PyOpalObjectGetProperty : boost::python::default_call_policies {
296public:
301 PyOpalObjectGetProperty(AttributeType type, std::string opalName): type_m(type), opalName_m(opalName) {}
304
312 template <class ArgumentPackage>
313 PyObject* postcall(ArgumentPackage const&, PyObject* result);
314
316 static void setObject(const PyOpalObject<C>* object) {object_m = object;}
317
318private:
320 std::string opalName_m;
321 static const PyOpalObject<C>* object_m;
322};
323
325template <class C>
326struct PyOpalObjectSetProperty : boost::python::default_call_policies {
327public:
332 PyOpalObjectSetProperty(AttributeType type, std::string opalName): type_m(type), opalName_m(opalName) {}
335
343 template <class ArgumentPackage>
344 PyObject* postcall(ArgumentPackage const& args, PyObject* result);
345
347 static void setObject(PyOpalObject<C>* object) {object_m = object;}
348
349private:
351 std::string opalName_m;
353};
354
356
357
358template <class C>
359void PyOpalObject<C>::execute(PyOpalObject<C>& pyobject) {
360 std::shared_ptr<C> objectPtr = pyobject.getOpalShared();
361 objectPtr->execute();
362}
363
364template <class C>
365void PyOpalObject<C>::registerObject(PyOpalObjectNS::PyOpalObject<C>& pyobject) {
366 C* wrappedC = pyobject.getOpalShared().get();
367 Object* objectPtr = dynamic_cast<Object*>(wrappedC);
368 if (objectPtr == nullptr) {
369 throw OpalException("PyOpalObject<C>::registerObject",
370 "Trying to register something that was not a Opal Object");
371 }
372 //Object* objectPtr = &(*pyobject.getOpalShared());
373 OpalData::getInstance()->define(objectPtr);
374}
375
376template <class C>
377std::string PyOpalObject<C>::getOpalName(const PyOpalObject<C>& pyobject) {
378 std::shared_ptr<C> objectPtr = pyobject.getOpalShared();
379 return objectPtr->getOpalName();
380}
381
382template <class C>
384 std::shared_ptr<C> objectPtr = pyobject.getOpalShared();
385 objectPtr->setOpalName(name);
386}
387
388template <class C>
390 std::shared_ptr<OpalElement> elementPtr =
391 std::dynamic_pointer_cast<OpalElement, C>(pyobject.getOpalShared());
392 if (elementPtr.get() == nullptr) {
393 throw OpalException("PyOpalObject<C>::getPyOpalElement",
394 "Wrapped object was not an OpalElement");
395 }
396 PyOpalObject<OpalElement> element(elementPtr);
397 boost::python::object pyelement(element);
398 return pyelement;
399}
400
401
402// defined in PyOpalElement
403template <>
405
406template <class C>
407PyOpalObject<C>::PyOpalObject() : object_m(new C) {}
408
409template <class C>
410PyObject* PyOpalObject<C>::getAttribute(AttributeType type, std::string opalName) const {
411 if (!object_m) {
412 throw OpalException("PyOpalObject<C>::getRealAttribute",
413 "Object was not initialised");
414 }
415 Attribute* attribute = object_m->findAttribute(opalName);
416 if (attribute == nullptr) {
417 throw OpalException("PyOpalObject<C>::getRealAttribute",
418 "Failed to parse attribute "+opalName);
419 }
420 PyObject* pyvalue;
421 // I spent quite a bit of time trying to get this type unwinding to work
422 // using templates (so it is done at compile time). In the end I couldn't
423 // fight the template syntax and had to do it at runtime using an enum; it's
424 // not so bad - the memory footprint is smaller and, tbh, template syntax is
425 // horrible so might be easier to use.
426 switch (type) {
427 case DOUBLE:
428 {
429 double value = Attributes::getReal(*attribute);
430 pyvalue = PyFloat_FromDouble(value);
431 break;
432 }
433 case INT:
434 {
435 double value = Attributes::getReal(*attribute);
436 pyvalue = PyLong_FromDouble(value);
437 break;
438 }
439 case STRING:
442 {
443 std::string value = Attributes::getString(*attribute);
444 pyvalue = PyUnicode_FromString(value.c_str());
445 break;
446 }
447 case BOOL:
448 {
449 bool value = Attributes::getBool(*attribute);
450 if (value) {
451 pyvalue = Py_True;
452 } else {
453 pyvalue = Py_False;
454 }
455 break;
456 }
457 case FLOAT_LIST:
458 {
459 std::vector<double> value = Attributes::getRealArray(*attribute);
460 pyvalue = PyList_New(value.size());
461 for (size_t i = 0; i < value.size(); ++i) {
462 PyList_SetItem(pyvalue, i, PyFloat_FromDouble(value[i]));
463 }
464 break;
465 }
466 case STRING_LIST:
467 {
468 std::vector<std::string> value = Attributes::getStringArray(*attribute);
469 pyvalue = PyList_New(value.size());
470 for (size_t i = 0; i < value.size(); ++i) {
471 PyList_SetItem(pyvalue, i, PyUnicode_FromString(value[i].c_str()));
472 }
473 break;
474 }
475 default:
476 {
477 throw OpalException("PyOpalObject<C>::getAttribute",
478 "Attribute type "+attributeName[type]+" not implemented");
479 }
480 }
481 Py_INCREF(pyvalue);
482 return pyvalue;
483}
484
485
486template <class C>
487void PyOpalObject<C>::setAttribute(AttributeType type, std::string opalName, PyObject* pyvalue) {
488 if (!object_m) {
489 throw OpalException("PyOpalObject<C>::setAttribute",
490 "Element was not initialised");
491 }
492 Attribute* attribute = object_m->findAttribute(opalName);
493 if (attribute == nullptr) {
494 throw OpalException("PyOpalObject<C>::setAttribute",
495 "Failed to parse attribute "+opalName);
496 }
497 switch (type) {
498 case DOUBLE:
499 {
500 double value = PyFloat_AsDouble(pyvalue);
501 Attributes::setReal(*attribute, value);
502 break;
503 }
504 case INT:
505 {
506 double value = PyLong_AsDouble(pyvalue);
507 Attributes::setReal(*attribute, value);
508 break;
509 }
510 case STRING:
511 {
512 std::string value = PyUnicode_AsUTF8(pyvalue);
513 Attributes::setString(*attribute, value);
514 break;
515 }
517 {
518 // predefined string is a string with a list of options
519 // note that value checking never happens - method exists in
520 // src/Attributes/PredefinedString.h but requires a Statement object
521 // which seems hard to construct (Classic/Parser/Statement.h)
522 std::string value = PyUnicode_AsUTF8(pyvalue);
523 Attributes::setPredefinedString(*attribute, value);
524 break;
525 }
527 {
528 std::string value = PyUnicode_AsUTF8(pyvalue);
529 Attributes::setUpperCaseString(*attribute, value);
530 break;
531 }
532 case BOOL:
533 {
534 bool value = PyObject_IsTrue(pyvalue);
535 Attributes::setBool(*attribute, value);
536 break;
537 }
538 case FLOAT_LIST:
539 {
540 Py_ssize_t listSize = PyList_Size(pyvalue);
541 std::vector<double> value(listSize);
542 for (Py_ssize_t i = 0; i < listSize; ++i) {
543 double value_i = PyFloat_AsDouble(PyList_GetItem(pyvalue, i));
544 value[i] = value_i;
545 }
546 Attributes::setRealArray(*attribute, value);
547 break;
548 }
549 case STRING_LIST:
550 {
551 Py_ssize_t listSize = PyList_Size(pyvalue);
552 std::vector<std::string> value(listSize);
553 for (Py_ssize_t i = 0; i < listSize; ++i) {
554 PyObject* pyvalue_i = PyList_GetItem(pyvalue, i);
555 std::string value_i = PyUnicode_AsUTF8(pyvalue_i);
556 value[i] = value_i;
557 }
558 Attributes::setStringArray(*attribute, value);
559 break;
560 }
561 default:
562 {
563 throw OpalException("PyOpalObject<C>::setAttribute",
564 "Attribute type "+attributeName[type]+" not implemented");
565 }
566 }
567}
568
569template <class C>
570PyOpalObject<C>::PyOpalObject(const PyOpalObject<C>& rhs) : object_m(rhs.object_m) {
571}
572
573template <class C>
574std::string PyOpalObject<C>::getDocString(AttributeDef& def) {
575 Attribute* attribute = object_m->findAttribute(def.opalName_m);
576 if (attribute == nullptr) {
577 throw OpalException("PyOpalObject<C>::getRealAttribute",
578 "Failed to parse attribute "+def.opalName_m);
579 }
580 std::string docString = def.pyName_m+" ("+attributeName[def.type_m]+"): "+attribute->getHelp();
581 if (def.docString_m != "") {
582 docString = def.pyName_m+" ("+attributeName[def.type_m]+"): "+def.docString_m;
583 }
584 return docString;
585}
586
587template <class C>
588boost::python::class_<PyOpalObject<C> > PyOpalObject<C>::make_class(const char* className) {
589 // WARNING - boost::python is bugged so that in module initialisation,
590 // errors are not handled correctly
591 // https://github.com/boostorg/python/issues/280
592 // so if you get the attribute name wrong you get a bad error
593 // hence I do some local error handling
594 typedef boost::python::class_<PyOpalObject<C> > PyClass;
595 boost::python::docstring_options docop(true, true, false); // user_def, py_sig, cpp_sig
596 PyClass pyclass = PyClass(className);
597 try {
598 addAttributes(pyclass);
599 addGetOpalName(pyclass);
600 addSetOpalName(pyclass);
601 } catch (OpalException& exc) {
602 std::cerr << "Failed to initialise class because '" << exc.what()
603 << "'" << std::endl;
604 throw exc;
605 }
606 return pyclass;
607}
608
609
610template <class C>
611template <class PYCLASS>
612void PyOpalObject<C>::addExecute(PYCLASS& pyclass) {
613 pyclass.def("execute", &PyOpalObject<C>::execute);
614}
615
616template <class C>
617template <class PYCLASS>
618void PyOpalObject<C>::addRegister(PYCLASS& pyclass) {
619 pyclass.def("register", &PyOpalObject<C>::registerObject);
620}
621
622
623template <class C>
624template <class PYCLASS>
625void PyOpalObject<C>::addGetOpalName(PYCLASS& pyclass) {
626 pyclass.def("get_opal_name", &PyOpalObject<C>::getOpalName);
627}
628
629template <class C>
630template <class PYCLASS>
631void PyOpalObject<C>::addSetOpalName(PYCLASS& pyclass) {
632 pyclass.def("set_opal_name", &PyOpalObject<C>::setOpalName);
633}
634
635template <class C>
636template <class PYCLASS>
637void PyOpalObject<C>::addGetOpalElement(PYCLASS& pyclass) {
638 pyclass.def("get_opal_element", &PyOpalObject<C>::getPyOpalElement);
639}
640
641template <class C>
642template <class PYCLASS>
644 double distanceUnits, double timeUnits,
645 double efieldUnits, double bfieldUnits) {
646 distanceUnits_m = distanceUnits;
647 timeUnits_m = timeUnits;
648 bfieldUnits_m = bfieldUnits;
649 efieldUnits_m = efieldUnits;
650 pyclass.def("get_field_value",
652 boost::python::args("x", "y", "z", "t"),
653 getFieldValueDocString.c_str());
654}
655
656template <class C>
657template <class PYCLASS>
658void PyOpalObject<C>::addAttributes(PYCLASS& pyclass) {
659 for (std::vector<AttributeDef>::iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
660 PyOpalObjectGetProperty<C> getProp(iter->type_m, iter->opalName_m);
661 PyOpalObjectSetProperty<C> setProp(iter->type_m, iter->opalName_m);
662 std::string docString = getDocString(*iter);
663 std::string pyname = iter->pyName_m.c_str();
664 switch (iter->type_m) {
665 case DOUBLE:
666 {
667 pyclass.add_property(pyname.c_str(),
668 boost::python::make_function(&PyC::dummyGet<double>, getProp),
669 boost::python::make_function(&PyC::dummySet<double>, setProp),
670 docString.c_str()
671 );
672 break;
673 }
674 case INT:
675 {
676 pyclass.add_property(pyname.c_str(),
677 boost::python::make_function(&PyC::dummyGet<int>, getProp),
678 boost::python::make_function(&PyC::dummySet<int>, setProp),
679 docString.c_str()
680 );
681 break;
682 }
683 case STRING:
686 {
687 pyclass.add_property(pyname.c_str(),
688 boost::python::make_function(&PyC::dummyGet<std::string>, getProp),
689 boost::python::make_function(&PyC::dummySet<std::string>, setProp),
690 docString.c_str()
691 );
692 break;
693 }
694 case BOOL:
695 {
696 pyclass.add_property(pyname.c_str(),
697 boost::python::make_function(&PyC::dummyGet<bool>, getProp),
698 boost::python::make_function(&PyC::dummySet<bool>, setProp),
699 docString.c_str()
700 );
701 break;
702 }
703 case FLOAT_LIST:
704 case STRING_LIST:
705 {
706 pyclass.add_property(pyname.c_str(),
707 boost::python::make_function(&PyC::dummyGet<boost::python::list>, getProp),
708 boost::python::make_function(&PyC::dummySet<boost::python::list>, setProp),
709 docString.c_str()
710 );
711 break;
712 }
713 default:
714 {
715 // Looks like exception handling doesn't work properly at module
716 // import time so this may not be handled politely - thrown as an
717 // unrecognised SystemError
718 throw OpalException("PyOpalObject<C>::addAttributes", "Type not implemented");
719 }
720 }
721 }
722}
723
724template <class C> double PyOpalObject<C>::distanceUnits_m = 1;
725template <class C> double PyOpalObject<C>::timeUnits_m = 1;
726template <class C> double PyOpalObject<C>::bfieldUnits_m = 1;
727template <class C> double PyOpalObject<C>::efieldUnits_m = 1;
728
729template <class C> const std::string PyOpalObject<C>::getFieldValueDocString =
730 "Get the field value at a point in the field map.\n"
731 "\n"
732 "The field lookup is performed against the last RINGDEFINITION that was\n"
733 "instantiated. This should be instantiated by calling\n"
734 "pyopal.parser.initialise_from_opal_file\n"
735 "\n"
736 "Parameters\n"
737 "----------\n"
738 "x : float\n"
739 " x position [m]\n"
740 "y : float\n"
741 " y position [m]\n"
742 "z : float\n"
743 " z position [m]\n"
744 "t: float\n"
745 " time [ns]\n"
746 "\n"
747 "Returns\n"
748 "-------\n"
749 "The function returns a tuple containing 7 values:\n"
750 "out of bounds : int\n"
751 " 1 if the event was out of the field map boundary, else 0.\n"
752 "Bx : float\n"
753 " x magnetic field [T]\n"
754 "By : float\n"
755 " y magnetic field [T]\n"
756 "Bz : float\n"
757 " z magnetic field [T]\n"
758 "Ex : float\n"
759 " x electric field [MV/m]\n"
760 "Ey : float\n"
761 " y electric field [MV/m]\n"
762 "Ez : float\n"
763 " z electric field [MV/m]\n";
764
765
767
768template <class C>
769template <class ArgumentPackage>
770PyObject* PyOpalObjectGetProperty<C>::postcall(ArgumentPackage const&, PyObject* result) {
771 Py_DECREF(result);
772 result = object_m->getAttribute(type_m, opalName_m);
773 return result;
774}
775
776template <class C>
777const PyOpalObject<C>* PyOpalObjectGetProperty<C>::object_m = nullptr;
778
780
781template <class C>
782template <class ArgumentPackage>
783PyObject* PyOpalObjectSetProperty<C>::postcall(ArgumentPackage const& args, PyObject* result) {
784 PyObject* value;
785 PyObject* pyObject; // this is a direct pointer to the C but I don't know how to unwrap it...
786 if (!PyArg_ParseTuple(args, "OO", &pyObject, &value)) {
787 return nullptr; // ParseTuple sets the error message
788 }
789 Py_DECREF(result);
790 object_m->setAttribute(type_m, opalName_m, value);
791 object_m = nullptr;
792 Py_RETURN_NONE;
793}
794
795template <class C>
796PyOpalObject<C>* PyOpalObjectSetProperty<C>::object_m = nullptr;
797
798} // PyOpalObject
799} // PyOpal
800
801#endif // PyOpalObject_H
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
const std::string name
std::map< AttributeType, std::string > attributeName
Definition: PyOpalObject.cpp:7
double getReal(const Attribute &attr)
Return real value.
Definition: Attributes.cpp:252
void setRealArray(Attribute &attr, const std::vector< double > &value)
Set array value.
Definition: Attributes.cpp:309
void setBool(Attribute &attr, bool val)
Set logical value.
Definition: Attributes.cpp:119
void setUpperCaseString(Attribute &attr, const std::string &val)
Set uppercase string value.
Definition: Attributes.cpp:456
void setString(Attribute &attr, const std::string &val)
Set string value.
Definition: Attributes.cpp:391
bool getBool(const Attribute &attr)
Return logical value.
Definition: Attributes.cpp:100
void setReal(Attribute &attr, double val)
Set real value.
Definition: Attributes.cpp:271
void setStringArray(Attribute &attr, const std::vector< std::string > &value)
Set string array value.
Definition: Attributes.cpp:524
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
Definition: Attributes.cpp:294
std::vector< std::string > getStringArray(const Attribute &attr)
Get string array value.
Definition: Attributes.cpp:478
void setPredefinedString(Attribute &attr, const std::string &val)
Set predefined string value.
Definition: Attributes.cpp:426
std::string getString(const Attribute &attr)
Get string value.
Definition: Attributes.cpp:343
std::string::iterator iterator
Definition: MSLang.h:16
boost::function< boost::tuple< double, bool >(arguments_t)> type
Definition: function.hpp:21
void addRegister(PYCLASS &pyclass)
void addGetOpalName(PYCLASS &pyclass)
Definition: PyOpalObject.h:625
static std::string getOpalName(const PyOpalObject< C > &pyobject)
Definition: PyOpalObject.h:377
void addSetOpalName(PYCLASS &pyclass)
Definition: PyOpalObject.h:631
static void registerObject(PyOpalObject< C > &pyobject)
Definition: PyOpalObject.h:302
static std::vector< AttributeDef > attributes
Definition: PyOpalObject.h:193
void addAttributes(PYCLASS &pyclass)
void addGetOpalElement(PYCLASS &pyclass)
PyOpalObject(const PyOpalObject< C > &rhs)
void addGetFieldValue(PYCLASS &pyclass, double distanceUnits, double timeUnits, double bfieldUnits, double efieldUnits)
Definition: PyOpalObject.h:643
std::string getDocString(AttributeDef &def)
PyOpalObject(std::shared_ptr< C > object)
Definition: PyOpalObject.h:125
static boost::python::object getFieldValue(PyOpalObjectNS::PyOpalObject< C > &pyobject, double x, double y, double z, double t)
Definition: PyOpalObject.h:271
static boost::python::object getPyOpalElement(PyOpalObject< C > &pyobject)
Definition: PyOpalObject.h:315
std::shared_ptr< C > getOpalShared()
Definition: PyOpalObject.h:233
PyObject * getAttribute(AttributeType type, std::string opalName) const
boost::python::class_< PyC > make_class(const char *className)
Definition: PyOpalObject.h:439
static void execute(PyOpalObject< C > &pyobject)
Definition: PyOpalObject.h:296
void addExecute(PYCLASS &pyclass)
static const std::string getFieldValueDocString
Definition: PyOpalObject.h:260
static void execute(PyOpalObject< C > &pyobject)
static boost::python::object getPyOpalElement(PyOpalObject< C > &pyobject)
static void registerObject(PyOpalObject< C > &pyobject)
std::shared_ptr< C > getOpalShared() const
Definition: PyOpalObject.h:236
static void setOpalName(PyOpalObject< C > &pyobject, std::string name)
Definition: PyOpalObject.h:383
void setAttribute(AttributeType type, std::string opalName, PyObject *value)
boost::python::class_< PyC > make_class(const char *className)
static void setObject(const PyOpalObject< C > *object)
Definition: PyOpalObject.h:253
static const PyOpalObject< C > * object_m
Definition: PyOpalObject.h:258
PyObject * postcall(ArgumentPackage const &, PyObject *result)
PyOpalObjectGetProperty(AttributeType type, std::string opalName)
Definition: PyOpalObject.h:301
static void setObject(PyOpalObject< C > *object)
Definition: PyOpalObject.h:284
PyObject * postcall(ArgumentPackage const &args, PyObject *result)
PyOpalObjectSetProperty(AttributeType type, std::string opalName)
Definition: PyOpalObject.h:332
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
The base class for all OPAL exceptions.
Definition: OpalException.h:28
virtual const std::string & what() const
Return the message string for the exception.