Gyoto
GyotoPython.h
Go to the documentation of this file.
1/*
2 Copyright 2015-2016, 2022 Thibaut Paumard
3
4 This file is part of Gyoto.
5
6 Gyoto is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Gyoto is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Gyoto. If not, see <http://www.gnu.org/licenses/>.
18 */
19
89#ifndef __GyotoPython_H_
90#define __GyotoPython_H_
91#include <GyotoSpectrum.h>
92#include <GyotoMetric.h>
94#include <GyotoThinDisk.h>
95#include <GyotoProperty.h>
96#include <GyotoValue.h>
97#include <GyotoScreen.h>
99#include <Python.h>
100
101namespace Gyoto {
107 namespace Python {
108 class Base;
109 template <class O> class Object;
112
114 PyObject * PyInstance_GetMethod(PyObject* pInstance, const char *name);
115
117 PyObject * PyImport_Gyoto();
118
120 void PyInstance_SetThis(PyObject * pInstance,
121 PyObject * pNew,
122 void * ptr);
123
125 bool PyCallable_HasVarArg(PyObject * pMethod);
126
128 PyObject * PyModule_NewFromPythonCode(const char * code);
129
131 PyObject * pGyotoSpectrum() ;
133 PyObject * pGyotoMetric() ;
137 PyObject * pGyotoThinDisk() ;
138 }
139 namespace Spectrum {
140 class Python;
141 }
142 namespace Metric {
143 class Python;
144 }
145 namespace Astrobj {
150 namespace Python {
151 class Standard;
152 class ThinDisk;
153 }
154 }
155}
156
193 protected:
200 std::string module_;
201
206 std::string inline_module_;
207
213 std::string class_;
214
222 std::vector<double> parameters_;
223
227 PyObject * pModule_;
228
232 PyObject * pInstance_;
233
237 PyObject * pProperties_;
238
242 PyObject * pSet_;
243
247 PyObject * pGet_;
248
249 public:
250 Base();
251 Base(const Base&);
252 ~Base();
253
254 virtual std::string module() const ;
255 virtual std::string inlineModule() const ;
256
265 virtual void module(const std::string&);
266
275 virtual void inlineModule(const std::string&);
276
278 virtual std::string klass() const ;
279
293 virtual void klass(const std::string& c);
294
296 virtual std::vector<double> parameters() const;
303 virtual void parameters(const std::vector<double>&);
304
305 virtual bool hasPythonProperty(std::string const &key) const ;
306 virtual void setPythonProperty(std::string const &key, Value val);
307 virtual Value getPythonProperty(std::string const &key) const;
308 virtual int pythonPropertyType(std::string const &key) const;
309
310};
311
318template <class O>
320 : public O, public Gyoto::Python::Base
321{
322public:
323 Object() : O(), Gyoto::Python::Base() {}
324 Object(const Object& o) : O(o), Base(o) {}
325 virtual ~Object() {};
326
327 using O::set;
328
329 virtual void set(std::string const &key, Value val) {
330 GYOTO_DEBUG_EXPR(key);
332 if (hasPythonProperty(key)) {
333 GYOTO_DEBUG << "Python key " << key << " exists" << std::endl;
334 setPythonProperty(key, val);
335 } else {
336 GYOTO_DEBUG << "Python key " << key << " does not exist" << std::endl;
337 O::set(key, val);
338 }
339 }
340
341 virtual void set(Property const &p, Value val){
342 std::string key=p.name;
343 GYOTO_DEBUG_EXPR(key);
344 if (!hasPythonProperty(key)) {
345 GYOTO_DEBUG << "calling Generic::set" << std::endl;
346 O::set(p, val);
347 return;
348 }
349 setPythonProperty(key, val);
350 }
351
352 virtual void set(Property const &p, Value val, std::string const &unit) {
354 if (hasPythonProperty(p.name)) {
355 GYOTO_DEBUG << "Python key " << p.name << " exists" << std::endl;
356 if (unit!="") GYOTO_ERROR("units not implemented");
357 setPythonProperty(p.name, val);
358 } else {
359 GYOTO_DEBUG << "Python key " << p.name << " does not exist" << std::endl;
360 O::set(p, val, unit);
361 }
362 }
363
364 using O::get;
365
366 virtual Value get(std::string const &key) const {
367 GYOTO_DEBUG_EXPR(key);
368 if (!hasPythonProperty(key)) {
369 GYOTO_DEBUG << "calling Generic::get" << std::endl;
370 return O::get(key);
371 }
372 return getPythonProperty(key);
373 }
374
375 Value get(Property const &p,
376 std::string const &unit) const {
377 if (!hasPythonProperty(p.name)) {
378 GYOTO_DEBUG << "calling Generic::get" << std::endl;
379 return O::get(p, unit);
380 }
381 return getPythonProperty(p.name);
382 }
383
384 Value get(Property const &p) const {
385 if (!hasPythonProperty(p.name)) {
386 GYOTO_DEBUG << "calling Generic::get" << std::endl;
387 return O::get(p);
388 }
389 return getPythonProperty(p.name);
390 }
391
392 using O::setParameter;
393
394 virtual int setParameter(std::string name, std::string content, std::string unit) {
395 GYOTO_DEBUG_EXPR(name);
396 GYOTO_DEBUG_EXPR(content);
397 GYOTO_DEBUG_EXPR(unit);
398 if (hasPythonProperty(name)) {
399 Property p(NULL);
400 p.name=name;
401 p.type=pythonPropertyType(name);
402 GYOTO_DEBUG << "Calling setParameter(p, name, content, unit)" << std::endl;
403 setParameter(p, name, content, unit);
404 return 0;
405 }
406 return O::setParameter(name, content, unit);
407 }
408
409 virtual void fillElement(Gyoto::FactoryMessenger *fmp) const {
410 O::fillElement(fmp);
411 if (pProperties_) {
412 Py_ssize_t pos=0;
413 PyObject *pKey, *pVal;
414 while (PyDict_Next(pProperties_, &pos, &pKey, &pVal)) {
415 std::string key=PyUnicode_AsUTF8(pKey);
416 std::string stype=PyUnicode_AsUTF8(pVal);
418 const Property p (key, type);
419 this->fillProperty(fmp, p);
420 }
421 }
422 }
423
424
425 void setParameters(Gyoto::FactoryMessenger *fmp) {
426 std::string name="", content="", unit="";
427 FactoryMessenger * child = NULL;
428 if (fmp)
429 while (fmp->getNextParameter(&name, &content, &unit)) {
430 GYOTO_DEBUG << "Setting '" << name << "' to '" << content
431 << "' (unit='"<<unit<<"')" << std::endl;
432 const Property * prop =NULL;
433 bool need_delete= false;
434 if (hasPythonProperty(name)) {
435 need_delete=true;
436 prop = new Property(name, pythonPropertyType(name));
437 } else {
438 need_delete=false;
439 prop = this->property(name);
440 }
441 if (!prop) {;
442 GYOTO_DEBUG << "'" << name << "' not found, calling setParameter()"
443 << std::endl;
444 // The specific setParameter() implementation may well know
445 // this entity
446 setParameter(name, content, unit);
447 } else {
448 GYOTO_DEBUG << "'" << name << "' found "<< std::endl;
449 std::vector<std::string> plugins;
450 switch (prop->type) {
452 set(*prop, fmp->metric());
453 break;
455 set(*prop, fmp->astrobj());
456 break;
458 set(*prop, fmp->screen());
459 break;
461 content = fmp -> getAttribute("kind");
462 child = fmp -> getChild();
463 plugins = Gyoto::split(fmp -> getAttribute("plugin"), ",");
464 set(*prop, (*Spectrum::getSubcontractor(content, plugins))(child, plugins) );
465 delete child;
466 break;
468 content = fmp -> getAttribute("kind");
469 child = fmp -> getChild();
470 plugins = Gyoto::split(fmp -> getAttribute("plugin"), ",");
471 set(*prop, (*Spectrometer::getSubcontractor(content, plugins))(child, plugins) );
472 delete child;
473 break;
475 content = fmp->fullPath(content);
476 // no 'break;' here, we need to proceed
477 default:
478 setParameter(*prop, name, content, unit);
479 break;
480 }
481 }
482 if (need_delete) delete prop;
483 }
484 GYOTO_DEBUG << "Done processing parameters" << std::endl;
485 }
486};
487
502 : public Gyoto::Python::Object<Gyoto::Spectrum::Generic>
503{
505 protected:
506
513 PyObject * pCall_;
514
518 PyObject * pIntegrate_;
519
538
539 public:
542
543 Python();
544
545 Python(const Python&);
546
547 virtual Python * clone() const;
548
549 ~Python();
550
551 // For some reason we need to implement the bunch although only one
552 // is non-trivial
553 virtual std::string module() const ;
554 virtual void module(const std::string&);
555 virtual std::string inlineModule() const ;
556 virtual void inlineModule(const std::string&);
557 virtual std::string klass() const ;
558 virtual void klass(const std::string&);
559 virtual std::vector<double> parameters() const;
560 virtual void parameters(const std::vector<double>&);
561
562 virtual double operator()(double nu) const;
563 virtual double operator()(double nu, double opacity, double ds) const;
564
565 virtual double integrate(double nu1, double nu2) ;
566
567};
568
569
589 : public Gyoto::Python::Object<Gyoto::Metric::Generic>
590{
592
593 private:
594 // Variables to cache Python objects:
598 PyObject * pGmunu_;
599
603 PyObject * pChristoffel_;
604
608 PyObject * pGetRmb_;
609
613 PyObject * pGetRms_;
614
618 PyObject * pGetSpecificAngularMomentum_;
619
623 PyObject * pGetPotential_;
624
628 PyObject * pIsStopCondition_;
629
633 PyObject * pCircularVelocity_;
634
635 public:
638 Python();
639 Python(const Python&);
640 ~Python();
641 virtual Python* clone() const ;
642
643 // Accessors for the Gyoto::Property members:
644 // Those are mere wrappers arround Generic::coordKind(), useful for
645 // declaring a boolen property using the macro GYOTO_PROPERTY_BOOL:
646 void spherical(bool);
647 bool spherical() const;
648 virtual std::string module() const ;
649 virtual void module(const std::string&);
650 virtual std::string inlineModule() const ;
651 virtual void inlineModule(const std::string&);
652 virtual std::string klass() const ;
653 virtual void klass(const std::string&);
654 virtual std::vector<double> parameters() const;
655 virtual void parameters(const std::vector<double>&);
657 virtual void mass(double m);
658
659 // The minimal Gyoto::Metric API:
660 void gmunu(double g[4][4], const double * x) const ;
661 int christoffel(double dst[4][4][4], const double * x) const ;
662
663 // Little more
664 double getRmb() const;
665 double getRms() const;
666 double getSpecificAngularMomentum(double rr) const;
667 double getPotential(double const pos[4], double l_cst) const;
668 int isStopCondition(double const coord[8]) const;
669 void circularVelocity(double const pos[4], double vel[4],
670 double dir=1.) const ;
671
672};
673
684 : public Gyoto::Python::Object<Gyoto::Astrobj::Standard>
685{
687
688 private:
689 PyObject *pEmission_, *pIntegrateEmission_, *pTransmission_, *pCall_,
690 *pGetVelocity_, *pGiveDelta_;
691 bool pEmission_overloaded_, pIntegrateEmission_overloaded_;
692
693 public:
696
697 /* Birth and Death*/
698 Standard();
699 Standard(const Standard&);
701 Standard* clone() const;
702
703 /* Astrobj::Generic API */
704 virtual double emission(double nu_em, double dsem, state_t const &coord_ph,
705 double const coord_obj[8]=NULL) const ;
706
707 virtual void emission(double Inu[], double const nu_em[], size_t nbnu,
708 double dsem, state_t const &coord_ph,
709 double const coord_obj[8]=NULL) const ;
710
711 virtual double integrateEmission(double nu1, double nu2, double dsem,
712 state_t const &c_ph, double const c_obj[8]=NULL) const;
713
714 virtual void integrateEmission(double * I, double const * boundaries,
715 size_t const * chaninds, size_t nbnu,
716 double dsem, state_t const &cph, double const *co) const;
717
718 virtual double transmission(double nuem, double dsem, state_t const &cph, double const *co) const ;
719
720 /* Astrobj::Standard API */
721 virtual double operator()(double const coord[4]) ;
722 virtual void getVelocity(double const pos[4], double vel[4]) ;
723 virtual double giveDelta(double coord[8]);
724
725 /* Python::Base */
726 virtual std::string module() const ;
727 virtual void module(const std::string&);
728 virtual std::string inlineModule() const ;
729 virtual void inlineModule(const std::string&);
730 virtual std::string klass() const ;
731 virtual void klass(const std::string&);
732 virtual std::vector<double> parameters() const;
733 virtual void parameters(const std::vector<double>&);
734 virtual double criticalValue() const ;
735 virtual void criticalValue(double) ;
736
737};
738
749 : public Gyoto::Python::Object<Gyoto::Astrobj::ThinDisk>
750{
752
753 private:
754 PyObject *pEmission_, *pIntegrateEmission_, *pTransmission_, *pCall_,
755 *pGetVelocity_, *pGiveDelta_;
756 bool pEmission_overloaded_, pIntegrateEmission_overloaded_;
757
758 public:
761
762 /* Birth and Death*/
763 ThinDisk();
764 ThinDisk(const ThinDisk&);
766 ThinDisk* clone() const;
767
768 /* Astrobj::Generic API */
769 virtual double emission(double nu_em, double dsem, state_t const &coord_ph,
770 double const coord_obj[8]=NULL) const ;
771
772 virtual void emission(double Inu[], double const nu_em[], size_t nbnu,
773 double dsem, state_t const &coord_ph,
774 double const coord_obj[8]=NULL) const ;
775
776 virtual double integrateEmission(double nu1, double nu2, double dsem,
777 state_t const &c_ph, double const c_obj[8]=NULL) const;
778
779 virtual void integrateEmission(double * I, double const * boundaries,
780 size_t const * chaninds, size_t nbnu,
781 double dsem, state_t const &cph, double const *co) const;
782
783 virtual double transmission(double nuem, double dsem, state_t const &cph ,double const *co) const ;
784
785 /* Astrobj::ThinDisk API */
786 virtual double operator()(double const coord[4]) ;
787 virtual void getVelocity(double const pos[4], double vel[4]) ;
788
789 /* Python::Base */
790 virtual std::string module() const ;
791 virtual void module(const std::string&);
792 virtual std::string inlineModule() const ;
793 virtual void inlineModule(const std::string&);
794 virtual std::string klass() const ;
795 virtual void klass(const std::string&);
796 virtual std::vector<double> parameters() const;
797 virtual void parameters(const std::vector<double>&);
798
799};
800
801
802#endif
#define GYOTO_DEBUG
Display debug message (in debug mode)
Definition GyotoDefs.h:341
#define GYOTO_DEBUG_EXPR(a)
Output expression value in debug mode.
Definition GyotoDefs.h:280
#define GYOTO_ERROR(msg)
Throw a Gyoto::Error nicely.
Definition GyotoError.h:196
Factory / SmartPointee::Subcontractor_t interface.
Base class for metric description.
#define GYOTO_OBJECT_THREAD_SAFETY
Declare virtual bool isThreadSafe() const.
Definition GyotoObject.h:99
#define GYOTO_OBJECT
Declare class::properties and class::getProperties()
Definition GyotoObject.h:84
Introspectable properties.
Description of the observer screen.
Spectrum of a simple object (e.g. Star)
Astronomical objects defined bya a potential/distance.
Geometrically thin disks and rings.
Introspectable value.
Coding a Gyoto::Astrobj::Standard in Python.
Definition GyotoPython.h:685
Coding a Gyoto::Astrobj::ThinDisk in Python.
Definition GyotoPython.h:750
Factory / SmartPointee::Subcontractor_t interface.
Definition GyotoFactoryMessenger.h:92
std::string fullPath(std::string relpath)
Transform path into full path specification.
SmartPointer< Astrobj::Generic > astrobj()
Build and get the Astrobj described in this XML file.
int getNextParameter(std::string *name, std::string *content, std::string *unit=NULL)
Get name and value of next parameter.
SmartPointer< Metric::Generic > metric()
Build and get the Metric described in this XML file.
SmartPointer< Screen > screen()
Build and get the Screen described in this XML file.
double mass() const
Get mass used in unitLength()
Metric coded in Python.
Definition GyotoPython.h:590
Property that can be set and got using standard methods.
Definition GyotoProperty.h:608
static type_e typeFromString(std::string stype)
Get Property::type_e value from name.
type_e
Possible type of a Property instance.
Definition GyotoProperty.h:616
@ metric_t
Type is Gyoto::SmartPointer<Gyoto::Metric::Generic>
Definition GyotoProperty.h:644
@ astrobj_t
Type is Gyoto::SmartPointer<Gyoto::Astrobj::Generic>
Definition GyotoProperty.h:648
@ filename_t
Type is std::string and holds a file name.
Definition GyotoProperty.h:638
@ spectrometer_t
Type is Gyoto::SmartPointer<Gyoto::Spectrometer::Generic>
Definition GyotoProperty.h:652
@ spectrum_t
Type is Gyoto::SmartPointer<Gyoto::Spectrum::Generic>
Definition GyotoProperty.h:650
@ screen_t
Type is Gyoto::SmartPointer<Gyoto::Screen::Generic>
Definition GyotoProperty.h:646
std::string name
Name of this instance.
Definition GyotoProperty.h:663
int type
Type of this instance.
Definition GyotoProperty.h:670
Base class for classes in the Python plug-in.
Definition GyotoPython.h:192
virtual void inlineModule(const std::string &)
Set inline_module_ and import the Python module.
virtual void module(const std::string &)
Set module_ and import the Python module.
std::string class_
Name of the Python class that we want to expose.
Definition GyotoPython.h:213
PyObject * pGet_
Reference to the (optional) Get method.
Definition GyotoPython.h:247
virtual std::string inlineModule() const
Return inline_module_.
PyObject * pProperties_
Reference to the properties member.
Definition GyotoPython.h:237
std::string module_
Name of the Python module that holds the class.
Definition GyotoPython.h:200
virtual std::string klass() const
Retrieve class_.
PyObject * pSet_
Reference to the (optional) Set method.
Definition GyotoPython.h:242
virtual std::string module() const
Return module_.
std::vector< double > parameters_
Parameters that this class needs.
Definition GyotoPython.h:222
PyObject * pInstance_
Reference to the python instance once it has been instantiated.
Definition GyotoPython.h:232
virtual void klass(const std::string &c)
Set class_ and instantiate the Python class.
virtual void parameters(const std::vector< double > &)
Set parameters_ and send them to pInstance_.
std::string inline_module_
Python source code for module that holds the class.
Definition GyotoPython.h:206
virtual std::vector< double > parameters() const
Retrieve parameters_.
PyObject * pModule_
Reference to the python module once it has been loaded.
Definition GyotoPython.h:227
Class template to implement parts of the Gyoto::Object API.
Definition GyotoPython.h:321
Pointers performing reference counting.
Definition GyotoSmartPointer.h:135
Loader for Python classes implementing the Spectrum interface.
Definition GyotoPython.h:503
PyObject * pCall_
Reference to ___call__.
Definition GyotoPython.h:513
virtual std::string inlineModule() const
Return inline_module_.
bool pCall_overloaded_
Whether call is overloaded.
Definition GyotoPython.h:537
virtual Python * clone() const
Cloner.
virtual std::vector< double > parameters() const
Retrieve parameters_.
virtual std::string klass() const
Retrieve class_.
virtual std::string module() const
Return module_.
virtual double integrate(double nu1, double nu2)
Integrate optically thick I_nu.
PyObject * pIntegrate_
Reference to the (optional) integrate method.
Definition GyotoPython.h:518
Container for the value of a Property.
Definition GyotoValue.h:60
int type
Type of this instance.
Definition GyotoValue.h:72
PyObject * pGyotoThinDisk()
Get reference to the ThinDisk constructor in the gyoto Python extension.
PyObject * pGyotoSpectrum()
Get reference to the Spectrum constructor in the gyoto Python extension.
PyObject * PyImport_Gyoto()
Return refernce to the gyoto module, or NULL.
PyObject * PyInstance_GetMethod(PyObject *pInstance, const char *name)
Return new reference to method, or NULL if method not found.
PyObject * PyModule_NewFromPythonCode(const char *code)
Create module from Python source code in a C string.
PyObject * pGyotoMetric()
Get reference to the Metric constructor in the gyoto Python extension.
void PyInstance_SetThis(PyObject *pInstance, PyObject *pNew, void *ptr)
Set "this" attribute in instance.
PyObject * PyObject_FromGyotoValue(const Gyoto::Value &)
Convert Gyoto Value to Python Object.
PyObject * pGyotoStandardAstrobj()
Get reference to the StandardAstrobj constructor in the gyoto Python extension.
bool PyCallable_HasVarArg(PyObject *pMethod)
Check whether method accepts the varargs argument.
Gyoto::Spectrometer::Subcontractor_t * getSubcontractor(std::string name, std::vector< std::string > &plugins, int errmode=0)
Query the Spectrometer register.
Gyoto::Spectrum::Subcontractor_t * getSubcontractor(std::string name, std::vector< std::string > &plugins, int errmode=0)
Query the Spectrum register.
Namespace for the Gyoto library.
Definition GyotoAstrobj.h:44
std::vector< std::string > split(std::string const &src, std::string const &delim)
Split string.