casa  $Rev:20696$
CasaPyInterpreter.h
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines