Package qubx :: Module notebook_qtiplot
[hide private]
[frames] | no frames]

Source Code for Module qubx.notebook_qtiplot

  1  """Notebook plugin to send figures to QtiPlot 
  2   
  3  Copyright 2008-2012 Research Foundation State University of New York  
  4  This file is part of QUB Express.                               
  5   
  6  QUB Express 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  QUB Express 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  named LICENSE.txt, in the QUB Express program directory.  If not, see         
 18  <http://www.gnu.org/licenses/>.                                       
 19   
 20   
 21  """ 
 22   
 23  import os 
 24  import shutil 
 25  import tempfile 
 26  import time 
 27  import traceback 
 28   
 29  import numpy 
 30   
 31  import qubx.GTK 
 32  import qubx.notebook 
 33  import qubx.pyenv 
 34  import qubx.remote_ctl 
 35   
 36  from Queue import Empty 
 37   
 38  SOCKID_PATH = os.path.join(tempfile.gettempdir(), 'qtiplot.sockid') 
 39  WIN32 = SOCKID_PATH.find('\\') >= 0 
 40  if WIN32: 
 41      from _winreg import * 
 42   
 43  TIMEOUT = 5.0 
 44   
45 -class NbTarget_QtiPlot(qubx.notebook.NbTarget):
46 - def __init__(self):
47 self.qtiplot = None 48 self.supports = [qubx.notebook.NbTable, 49 qubx.notebook.NbChart, 50 qubx.notebook.NbTrace]
51 - def nb_init(self):
52 try: 53 self.qtiplot.reval('1', timeout=TIMEOUT) 54 except: 55 self.qtiplot = None 56 if self.qtiplot is None: 57 try: 58 self.qtiplot = qubx.remote_ctl.RemoteProxy(sockid_path=SOCKID_PATH) 59 except: 60 if self.start_qtiplot(): 61 try: 62 self.qtiplot = qubx.remote_ctl.RemoteProxy(sockid_path=SOCKID_PATH) 63 except: 64 print "Can't connect to QtiPlot; is it running?" 65 return self.qtiplot
66 - def start_qtiplot(self):
67 qtipath, qtistartup = self.find_qtiplot() 68 if not qtipath: 69 return False 70 self.copy_scripts(qtipath, qtistartup) 71 self.exec_qtiplot(qtipath) 72 return True
73 - def find_qtiplot(self):
74 qtipath = qtistartup = "" 75 if WIN32: 76 # win: ensure python2.6 and numpy 77 try: 78 k = OpenKey(HKEY_LOCAL_MACHINE, r'SOFTWARE\Python\PythonCore\2.6\InstallPath') 79 pypath, typ = QueryValueEx(k, '') 80 if not pypath: raise Exception() 81 except: 82 traceback.print_exc() 83 try: 84 k = OpenKey(HKEY_CURRENT_USER, r'SOFTWARE\Python\PythonCore\2.6\InstallPath') 85 pypath, typ = QueryValueEx(k, '') 86 if not pypath: raise Exception() 87 except: 88 traceback.print_exc() 89 qubx.GTK.ShowMessage('Please install Python 2.6 (32-bit) from\nhttp://www.python.org/download/releases/2.6.6') 90 return "", "" 91 numpypath = os.path.join(pypath, 'lib', 'site-packages', 'numpy') 92 if not os.path.exists(numpypath): 93 qubx.GTK.ShowMessage('Please install numpy (for Python 2.6, 32-bit) from\nhttp://sourceforge.net/projects/numpy/files/') 94 return "", "" 95 # find qtiplot 96 try: 97 k = OpenKey(HKEY_CURRENT_USER, r'SOFTWARE\ProIndependent\QtiPlot\General\Paths') 98 qtipath, typ = QueryValueEx(k, 'ScriptsDir') 99 qtipath = os.path.join(qtipath.replace("/", "\\"), "QtiPlot.exe") 100 if not os.path.exists(qtipath): 101 raise Exception() 102 qtistartup, typ = QueryValueEx(k, 'StartupScripts') 103 qtistartup = qtistartup.replace("/", "\\") 104 except: 105 traceback.print_exc() 106 qubx.GTK.ShowMessage('QtiPlot is available from http://soft.proindependent.com/qtiplot.html') 107 return "", "" 108 else: 109 ## TODO: find qtipath, qtistartup in linux (via QT?) 110 qubx.GTK.ShowMessage("""One-time setup: 111 * get QtiPlot from 112 http://soft.proindependent.com/qtiplot.html 113 * look in the folder %s 114 * copy these files into the QtiPlot folder: 115 remote_ctl.py 116 qtiplot_remote_ctl.py 117 * copy this file into qtiplot's startup script folder: 118 qtiplot_start_remote_ctl.py 119 * in QtiPlot preferences, set def. scripting language to Python 120 * close and re-open QtiPlot 121 122 Before sending a figure: 123 * open QtiPlot"""%os.path.join(qubx.pyenv.env.globals['app_path'], 'QtiPlot')) 124 return qtipath, qtistartup
125 - def copy_scripts(self, qtipath, qtistartup):
126 app_path = qubx.pyenv.env.globals['app_path'] 127 from_path = os.path.join(app_path, 'QtiPlot') 128 qtiroot = os.path.split(qtipath)[0] 129 try: 130 ## TODO: linux file permissions (gksu? kdesu? ...?) 131 shutil.copy(os.path.join(from_path, 'remote_ctl.py'), 132 os.path.join(qtiroot, 'remote_ctl.py')) 133 shutil.copy(os.path.join(from_path, 'qtiplot_remote_ctl.py'), 134 os.path.join(qtiroot, 'qtiplot_remote_ctl.py')) 135 shutil.copy(os.path.join(from_path, 'qtiplot_start_remote_ctl.py'), 136 os.path.join(qtistartup, 'qtiplot_start_remote_ctl.py')) 137 except: 138 traceback.print_exc() 139 # set qtiplot def scripting lang to python 140 if WIN32: 141 try: 142 k = OpenKey(HKEY_CURRENT_USER, 'SOFTWARE\ProIndependent\QtiPlot\General') 143 SetValue(k, 'ScriptingLang', REG_SZ, 'Python') 144 except: 145 traceback.print_exc() 146 else: 147 ## TODO: set it for linux (via QT?) 148 print "If Python is not chosen as the default scripting language," 149 print "you'll have to fix that, then close QtiPlot and try again."
150 - def exec_qtiplot(self, qtipath):
151 print 'running',qtipath,'...' 152 os.chdir(os.path.split(qtipath)[0]) 153 if WIN32: 154 os.startfile(qtipath) 155 else: 156 #? 157 os.system("'%s'"%qtipath) 158 time.sleep(TIMEOUT)
159 - def send_table(self, qtiplot, item, show=True):
160 Nr, Nc = item.get_shape() 161 arr = numpy.zeros(shape=(Nr,Nc)) 162 for c in xrange(Nc): 163 try: 164 col = item.get_col(c) 165 arr[:len(col),c] = item.get_col(c) 166 except: 167 pass 168 qtiplot.set_array(arr, 'qub_express_table', timeout=TIMEOUT) 169 print arr 170 app_path = qubx.pyenv.env.globals['app_path'] 171 qtiplot.rexec(open(os.path.join(app_path, 'QtiPlot', 'table.py'), 'r').read(), timeout=TIMEOUT) 172 if show: 173 qtiplot.rexec('qubx_qti_table = add_table("%s", qub_express_table)' % item.get_caption())
174 - def nb_send(self, item):
175 qtiplot = self.nb_init() 176 app_path = qubx.pyenv.env.globals['app_path'] 177 if not qtiplot: 178 return 179 if isinstance(item, qubx.notebook.NbItems): 180 for it in item: 181 self.nb_send(it) 182 return 183 if isinstance(item, qubx.notebook.NbTrace): 184 self.send_table(qtiplot, item) 185 qtiplot.rexec(open(os.path.join(app_path, 'QtiPlot', 'trace.py'), 'r').read(), timeout=TIMEOUT) 186 qtiplot.rexec("""add_trace_plot("%s", "%s", "%s", qubx_qti_table, %s)""" % 187 (item.get_caption(), item.get_xlabel(), item.get_ylabel(), 188 ', '.join([str(series.ycol) for series in item.get_trace_series()]))) 189 return 190 if isinstance(item, qubx.notebook.NbChart): 191 self.send_table(qtiplot, item, show=False) 192 series = item.get_series() 193 lines = [s for s in series if s.ser_type == qubx.notebook.LINES] 194 if series and series[0].ser_type == qubx.notebook.HISTOGRAM: 195 self.send_table(qtiplot, item) 196 qtiplot.rexec(open(os.path.join(app_path, 'QtiPlot', 'histogram.py'), 'r').read(), timeout=TIMEOUT) 197 qtiplot.rexec("""add_hist(qubx_qti_table, "%s", "%s", "%s", 2, []%s)""" % 198 (item.get_caption(), item.get_xlabel(), item.get_ylabel(), 199 lines and (", %s"%", ".join([str(ser.ycol+1) for ser in lines])) 200 or "")) 201 elif series and series[0].ser_type == qubx.notebook.DOTS: 202 qtiplot.rexec(open(os.path.join(app_path, 'QtiPlot', 'scatter.py'), 'r').read(), timeout=TIMEOUT) 203 ser = series[0] 204 nrow = ser.nrow 205 if nrow < 0: nrow = item.get_shape()[0] 206 line = lines and lines[0] or ser 207 line_nrow = line.nrow 208 if line_nrow < 0: line_nrow = nrow 209 qtiplot.rexec("""t,g,l = add_scatter("%s", "%s", "%s", qub_express_table[%d:%d,%d].flatten(), qub_express_table[%d:%d,%d].flatten(), 210 %s, [], qub_express_table[%d:%d,%d].flatten()%s)"""% 211 (item.get_caption(), item.get_xlabel(), item.get_ylabel(), 212 ser.first_row, ser.first_row+nrow, ser.xcol, 213 ser.first_row, ser.first_row+nrow, ser.ycol, 214 item.get_color_indices() or [0]*nrow, 215 line.first_row, line.first_row + line_nrow, line.xcol, 216 lines and (", %s"%", ".join(["qub_express_table[%d:%d,%d].flatten()" % 217 (line.first_row, line.first_row+line_nrow, line.ycol) 218 for line in lines])) 219 or "")) 220 hseries = [s for s in series if s.ser_type == qubx.notebook.HISTOGRAM] 221 if hseries: 222 hser = hseries[0] # assuming only one 223 nrow = hser.nrow 224 if nrow < 0: nrow = item.get_shape()[0] 225 qtiplot.rexec("""add_hist_to_scatter(t, g, l, qub_express_table[%d:%d,%d].flatten(), qub_express_table[%d:%d,%d].flatten())""" % 226 (hser.first_row, hser.first_row+nrow, hser.xcol, 227 hser.first_row, hser.first_row+nrow, hser.ycol)) 228 elif series: 229 self.send_table(qtiplot, item) 230 pass ## TODO: line chart, should any exist 231 return 232 if isinstance(item, qubx.notebook.NbTable): 233 self.send_table(qtiplot, item) 234 return
235
236 -def Init():
237 qubx.notebook.Notebook.register_target(NbTarget_QtiPlot(), 'QtiPlot', 'QtiPlot', 'Send to QtiPlot', None)
238 239 240 241 # table: headers? 242