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
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
74 qtipath = qtistartup = ""
75 if WIN32:
76
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
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
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
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
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
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
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."
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)
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())
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]
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
231 return
232 if isinstance(item, qubx.notebook.NbTable):
233 self.send_table(qtiplot, item)
234 return
235
238
239
240
241
242