casa
$Rev:20696$
|
00001 //# CasaPyInterpreter.h: Maintain and manage different flag versions. 00002 //# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2002,2003 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have receied a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id$ 00027 //# 00028 //# ---------------------------------------------------------------------------- 00029 //# Change Log 00030 //# ---------------------------------------------------------------------------- 00031 //# Date Name Comments 00032 //# Aug 20 Urvashi R.V. Created this class. 00033 00034 00035 #ifndef CASAPYINTERPRETER_H 00036 #define CASAPYINTERPRETER_H 00037 00038 //# Includes 00039 00040 #include <casa/aips.h> 00041 #include <casa/iostream.h> 00042 #include <casa/OS/Timer.h> 00043 #include <casa/OS/File.h> 00044 00045 #include <casa/Arrays/Vector.h> 00046 #include <casa/Arrays/Array.h> 00047 00048 #include <tableplot/TablePlot/SLog.h> 00049 #include <Python.h> 00050 00051 namespace casa { //# NAMESPACE CASA - BEGIN 00052 00053 // <summary> 00054 // Class that grabs a handle onto the currently running 00055 // casapy Python interpreter shell. 00056 // </summary> 00057 00058 // <reviewed reviewer="" date="" tests=""> 00059 // </reviewed> 00060 00061 // <prerequisite> 00062 // <li> Extending/Embedding Python with C++ 00063 // <li> python - matplotlib/pylab 00064 // </prerequisite> 00065 00066 // <etymology> 00067 // A link between Casa and a Python-Interpreter. 00068 // </etymology> 00069 00070 // <synopsis> 00071 // This class creates and maintains a link between C++ and the 00072 // current instance of the python interpreter. 00073 // ( Wes Young wrote the first part of the constructor, that creates 00074 // a local python interpreter, and loads "pylab" into it. ) 00075 // 00076 // All python commands that TPPlotter runs, are sent into this class 00077 // for transmission to the python interpreter. 00078 // </synopsis> 00079 00080 // <motivation> 00081 // To isolate the process of connecting between C++ and Python. 00082 // </motivation> 00083 00084 // <thrown> 00085 // <li> 00086 // <li> 00087 // </thrown> 00088 00089 00090 // <todo asof="$DATE:$"> 00091 // <li> 00092 // </todo> 00093 00094 00095 class CasaPyInterpreter 00096 { 00097 public: 00098 // Default Constructor 00099 CasaPyInterpreter(Bool usegui=True); 00100 // Copy Constructor 00101 CasaPyInterpreter( CasaPyInterpreter const& ); 00102 // Assignment 00103 CasaPyInterpreter& operator=(CasaPyInterpreter const&); 00104 // Destructor 00105 ~CasaPyInterpreter(); 00106 00107 // Send in a python command string. 00108 // Be very wary of newlines and blank spaces 00109 void pyrunString( String cmd ); 00110 // Periodically check if the internal interpreter has thrown 00111 // an exception. If so, grab the message and create an AipsError 00112 // exception. 00113 void CheckPlotError( String cmd ); 00114 // Add Gui buttons and bind them. 00115 // Usually called immediately after construction, and only once. 00116 void setupCustomGuiFeatures(); 00117 00118 private: 00119 00120 // Exception generator. 00121 void CasaPyInterpreterError(String msg); 00122 00123 // Handle to the internal python interpreter. 00124 PyObject *interp; 00125 00126 SLog* log; 00127 static String clname; 00128 }; 00129 00130 /* Documentation for PlotterGlobals. */ 00131 00132 // <summary> 00133 // Description for PlotterGlobals.cc : 00134 // Implements the connection between GUI events and C++ callbacks. 00135 // </summary> 00136 00137 // <use visibility=export> 00138 00139 // <reviewed reviewer="" date="" tests=""> 00140 // </reviewed> 00141 00142 // <prerequisite> 00143 // <li> Extending/Embedding Python and the C/Python API 00144 // <li> TPGuiBinder 00145 // </prerequisite> 00146 00147 // <etymology> 00148 // Global functions to handle Gui callback binding between Python and C++. 00149 // </etymology> 00150 00151 // <synopsis> 00152 00153 // 00154 // Description : Implements the connection between GUI events and C++ callbacks. 00155 // -------------------------------------------------------------------------------------- 00156 // Flow of control is as follows. 00157 // 00158 // -> Button-press event ( in Tkinter - matplotlib/python ) 00159 // -> PlotFlag::flag() ( in internal python interpreter ) 00160 // -> PyBind::flagdata() ( python/C++ callback ) 00161 // -> TPGuiBinder::flagdata() ( link to casa::application function ) 00162 // -> TablePlot::flagData(); ( the actual flagging ! ) 00163 // 00164 // -------------------------------------------------------------------------------------- 00165 // 00166 // (1) CREATE A NEW PYTHON MODULE - PyBind 00167 // 00168 // A set of global callback functions are defined. It uses the Python-C API described 00169 // in "http://docs.python.org/api/api.html" and "http://docs.python.org/ext/ext.html". 00170 // 00171 // These functions are initialized as a Python module (in C++), when its constructor is called. 00172 // - Py_Initialize(); // Startup the internal python interpreter 00173 // - initPyBind(); // constructor to create and bind this new module 00174 // - Py_Run_Simple_String("import PyBind"); // import this module into python namespace. 00175 // The equivalent of this is done in TPPlotter::initPlot(). 00176 // 00177 // These functions are then accessible from within the internal python interpreter 00178 // created via Py_Initialize(). 00179 // 00180 // (2) DEFINE A C++ GUIBINDER CLASS - (example) MSPlotGuiBinder 00181 // 00182 // See the definition of class TPGuiBinder in TablePlot.h. 00183 // A global instance of this TPGuiBinder pointer is 00184 // maintained, and the callbacks implemented in the PyBind module use it and call 00185 // its member functions. This way, TablePlot, can connect the 00186 // global generic PyBind callback functions to its member functions. 00187 // 00188 // (3) IMPLEMENT THE METHODS OF THE PYTHON MODULE - PyBind.flag(), PyBind.unflag(),... 00189 // 00190 // Call member functions of TPGuiBinder from a global instance. This is needed 00191 // to give applications control over what functions are bound to. 00192 // This connects steps (1) and (2). 00193 // 00194 // (4) PYTHON EVENT CAPTURE AND BINDING - PlotFlag. 00195 // 00196 // The binding of the actual matplotlib-backend events to these callbacks is done in the 00197 // TablePlotTkAgg.py script. Buttons are added, and matplotlib callbacks are defined that 00198 // use the PyBind module (remember - PyBind is visible in the namespace of the internal 00199 // python interpreter ! ). 00200 // 00201 // -------------------------------------------------------------------------------------- 00202 // Example : A simplified example based on TablePlot 00203 // 00204 // In TablePlot.h ---> Implement a derived class of TPGuiBinder that calls the 00205 // application-specific function. 00206 // 00207 // - class TPGuiBinder 00208 // - { 00209 // - public : 00210 // - TPGuiBinder( casa::TablePlot* intp ){itsTablePlot = intp;} 00211 // - Bool flagdata(){ return itsTablePlot->flagData(FLAG); } 00212 // - private : 00213 // - casa::TablePlot* itsTablePlot; 00214 // - }; 00215 // 00216 // In TablePlot.cc ---> A Global instance of TPGuiBinder is created. 00217 // 00218 // - GBB = new TPGuiBinder(this); 00219 // 00220 // 00221 // In PyBind ( PlotterGlobals.cc ) ---> Define the PyBind method that calls 00222 // MSPlotGuiBinder::flagdata(); 00223 // GBB is the global instance of TPGuiBinder *. 00224 // 00225 // - static PyObject * 00226 // - PyBind_flagdata(PyObject *self, PyObject* args) 00227 // - { 00228 // - if(GBB != NULL) GBB->flagdata(); 00229 // - else cout << "Binder is NULL" << endl; 00230 // - return Py_BuildValue("i", 1); 00231 // - } 00232 // 00233 // In TablePlotTkAgg.py ---> Bind the python Tk event to the PyBind callback in a 00234 // python class called PlotFlag. 00235 // 00236 // - class PlotFlag: 00237 // - # bind the Button "bFlag" to the command "self.flag". 00238 // - self.toolbar.bFlag.config(command=self.flag); 00239 // - def flag(self, *args): 00240 // - self.PyBind.flagdata(); 00241 // - 00242 // 00243 // -------------------------------------------------------------------------------------- 00244 // Again... Flow of control is as follows. 00245 // 00246 // -> Button-press event ( in Tkinter - matplotlib/python ) 00247 // -> PlotFlag::flag() ( in internal python interpreter ) 00248 // -> PyBind::flagdata() ( python/C++ callback ) 00249 // -> TPGuiBinder::flagdata() ( link to casa::application function ) 00250 // -> TablePlot::flagData(); ( the actual flagging ! ) 00251 // 00252 // </synopsis> 00253 00254 // <example> 00255 // 00256 // <srcblock> 00257 // 00258 // </srcblock> 00259 // </example> 00260 00261 // <motivation> 00262 // To generate callbacks from the matplotlib GUI to C++. 00263 // </motivation> 00264 00265 // <templating arg=T> 00266 // <li> 00267 // </templating> 00268 00269 // <thrown> 00270 // <li> 00271 // <li> 00272 // </thrown> 00273 00274 00275 // <todo asof="$DATE:$"> 00276 // <li> 00277 // </todo> 00278 00279 // See tables/TablePlot/PlotterGlobals.cc 00280 00281 00282 } //# NAMESPACE CASA - END 00283 00284 //#ifndef AIPS_NO_TEMPLATE_SRC 00285 //#include <tableplot/TablePlot/CasaPyInterpreter.tcc> 00286 //#endif //# AIPS_NO_TEMPLATE_SRC 00287 #endif 00288