| Trees | Indices | Help |
|
|---|
|
|
1 """Components for the managing and visualizing L{qubx.trialset.TrialSet}s.
2
3 Copyright 2012-2014 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 traceback
25
26 import gtk
27 import gobject
28
29 import qubx.global_namespace
30 import qubx.GTK
31 import qubx.model
32 import qubx.modelGTK
33 import qubx.pyenv
34 import qubx.tableGTK
35 from qubx.GTK import build_menuitem, pack_item, pack_label
36 from qubx.table import COPY_ROWS_ALL, COPY_ROWS_CHECKED, COPY_ROWS_GROUP, COPY_ROWS_CRITERIA
37 from qubx.toolspace import ColorInfo
38 from qubx.util_types import WeakEvent, Reffer, bind
39
40 COLOR_TRIALS_BG = ('trials.model.bg', (.92, .96, 1, 1))
41 ColorInfo[COLOR_TRIALS_BG[0]].label = 'Trials model background'
42
43
46 self.model = model
47 self.trialsets = []
48 self.trialset_names = []
49 self.__recent_by_datapath = {}
50 self.num_indep = 0
51 self.__save_path = ""
52 self.__ref = Reffer()
53 self.__data = None
54 self.__trialset = None
55 self.__table = None
56 self.OnSwitch = WeakEvent()
57 self.OnChangeNames = WeakEvent()
58 Data.OnSwitch += self.__ref(self.__onSwitchData)
59 Data.OnClosing += self.__ref(self.__onClosingData)
60 self.__onSwitchData(Data, Data.file)
61 trialset = property(lambda self: self.__trialset, lambda self, x: self.set_trialset(x))
62 trialset_by_name = property(lambda self: self.__trialset and self.__trialset.trialset_name or "", lambda self, x: self.set_trialset_by_name(x))
64 if self.__data:
65 if self.trialset in self.__data.trials.trialsets:
66 self.trialset = self.trialsets[self.num_indep-1] if self.num_indep else None
67 self.__data.trials.OnInsert -= self.__ref(self.__onInsertTrialset)
68 self.__data.trials.OnRemoving -= self.__ref(self.__onRemovingTrialset)
69 del self.trialsets[self.num_indep:]
70 del self.trialset_names[self.num_indep:]
71 self.__data = file
72 if self.__data:
73 self.__data.trials.OnInsert += self.__ref(self.__onInsertTrialset)
74 self.__data.trials.OnRemoving += self.__ref(self.__onRemovingTrialset)
75 self.trialsets.extend(file.trials.trialsets)
76 self.trialset_names.extend(file.trials.trialset_names)
77 self.OnChangeNames()
78 if self.__data:
79 try: # restore last trialset for data if possible
80 self.trialset = self.trialsets[self.trialset_names.index(self.__recent_by_datapath[self.__data.path])]
81 except:
82 pass
83 if (self.__trialset is None) and self.trialsets:
84 self.trialset = self.trialsets[0]
86 data = qubx.global_namespace.QubX.Data.views[ix].file
87 for ts in data.trials.trialsets:
88 if not ts.in_qsf:
89 self.prompt_save(ts, data, can_cancel=False)
91 self.trialsets.insert(self.num_indep+ix, trialset)
92 self.trialset_names.insert(self.num_indep+ix, trialset.trialset_name)
93 self.OnChangeNames()
94 if len(self.trialsets) == 1:
95 self.trialset = trialset
97 if trialset == self.__trialset:
98 self.__adjust_ts_closing()
99 del self.trialsets[self.num_indep+ix]
100 del self.trialset_names[self.num_indep+ix]
101 self.OnChangeNames()
105 if ts == self.__trialset: return
106 if not (self.__trialset is None):
107 self.__trialset.OnSelect -= self.__ref(self.__onSelectTrial)
108 self.__trialset.OnDoubleClick -= self.__ref(self.__onDoubleClickTrial)
109 self.__trialset.OnSetInQSF -= self.__ref(self.__onSetInQSF)
110 self.__trialset = ts
111 if not (self.__trialset is None):
112 self.__recent_by_datapath[self.__data.path] = ts.trialset_name
113 self.__trialset.OnSelect += self.__ref(self.__onSelectTrial)
114 self.__trialset.OnDoubleClick += self.__ref(self.__onDoubleClickTrial)
115 self.__trialset.OnSetInQSF += self.__ref(self.__onSetInQSF)
116 qubx.pyenv.env.OnScriptable('QubX.Trials.trialset_by_name = %s' % repr(ts.trialset_name))
117 if self.__trialset.size:
118 self.__trialset.select(0)
119 self.show_trialset_table(ts)
120 self.OnSwitch(ts)
122 try:
123 return self.trialsets[self.trialset_names.index(name)]
124 except ValueError:
125 return self.__data.trials.get_trialset(name, in_qsf)
127 try:
128 ix = self.trialset_names.index(name)
129 if ix >= self.num_indep:
130 if force or self.prompt_save(self.trialsets[ix], self.__data):
131 self.__data.trials.remove_trialset(name)
132 else:
133 if (not (self.__trialset is None)) and (name == self.__trialset.trialset_name):
134 self.__adjust_ts_closing()
135 self.trialsets[ix].dispose()
136 del self.trialsets[ix]
137 del self.trialset_names[ix]
138 self.num_indep -= 1
139 self.OnChangeNames()
140 except ValueError:
141 pass
143 if len(self.trialsets) == 1:
144 self.trialset = None
145 else:
146 ix = self.trialsets.index(self.__trialset)
147 if ix == 0:
148 self.trialset = self.trialsets[1]
149 else:
150 self.trialset = self.trialsets[ix-1]
152 if path is None:
153 return qubx.GTK.Open('Open Trials...', self.__save_path, self.open)
154 qubx.pyenv.env.OnScriptable('QubX.Trials.open(%s)' % repr(path))
155 base = os.path.splitext(path)[0]
156 self.__save_path, name = os.path.split(base)
157 ts_name = '/%s' % name # to distinguish from per-file trialsets
158 ts = qubx.trialset.TrialSet(ts_name)
159 ts.from_text(open(path, 'r').read(), keep_fields=True)
160 files = "%s_files" % base
161 for i in xrange(ts.size):
162 try:
163 ts.models[i] = qubx.tree.Open(os.path.join(files, "model_%i.qmf" % i), readOnly=True)
164 ts.models[i].close()
165 except:
166 traceback.print_exc() ### pass
167 ix = self.num_indep
168 self.trialsets.insert(ix, ts)
169 self.trialset_names.insert(ix, ts_name)
170 self.num_indep += 1
171 self.OnChangeNames()
172 self.trialset = ts
173 qubx.global_namespace.QubX.Models.index = 0 # request_show()
175 ts = self.__trialset if (trialset is None) else trialset
176 if ts is None: return
177 if not path:
178 name = ts.trialset_name
179 if name and (name[0] == '/'):
180 name = name[1:]
181 qubx.GTK.SaveAs('Save Trials...', self.__save_path, name, self.save)
182 return
183 if ts == self.__trialset:
184 qubx.pyenv.env.OnScriptable('QubX.Trials.save(%s)' % repr(path))
185 self.__save_path = os.path.split(path)[0]
186 base = os.path.splitext(path)[0]
187 files = "%s_files" % base
188 self.__save_path, name = os.path.split(base)
189 open(path, 'w').write(ts.to_text())
190 if not os.path.exists(files):
191 os.makedirs(files)
192 for i in xrange(ts.size):
193 try:
194 ts.models[i].saveAs(os.path.join(files, "model_%i.qmf" % i), as_copy=True)
195 except:
196 traceback.print_exc()
198 if can_cancel:
199 choice_i = qubx.GTK.PromptChoices('Save Trials "%s" of %s?' % (trialset.trialset_name, os.path.split(data.path)[1]),
200 ['Discard', 'Cancel', 'Save...'])
201 else:
202 #choice_i = 0
203 choice_i = qubx.GTK.PromptChoices('Save Trials "%s" of %s?' % (trialset.trialset_name, os.path.split(data.path)[1]),
204 ['Discard', 'Save...'])
205 if choice_i: choice_i = 2
206 if choice_i == 1:
207 return False
208 if choice_i == 2:
209 self.save(trialset=trialset)
210 return True
218 in_qsf = chk.get_active()
219 qubx.pyenv.env.OnScriptable('QubX.Trials.trialset.in_qsf = %s' % repr(in_qsf))
220 self.__table.in_qsf = in_qsf
222 if not (self.__table is None):
223 qubx.global_namespace.QubX.Tables.remove_table(self.__table)
224 self.__table = None
225 if not (ts is None):
226 mnuFile = gtk.Menu()
227 build_menuitem('Open Trials...', self.__ref(self.__onClickOpen), menu=mnuFile)
228 build_menuitem('Save Trials as...', self.__ref(self.__onClickSave), menu=mnuFile)
229 build_menuitem('Close', self.__ref(self.__onClickClose), menu=mnuFile)
230 btnFile = qubx.toolspace.Button_Popup(mnuFile, qubx.tableGTK.COLOR_TABLE_FILE_MENU, "File menu")
231 mnuTrials = qubx.GTK.DynamicComboBox()
232 mnuTrials.OnPopulate += self.__ref(self.__onPopulateTrials)
233 mnuTrials.OnChanged += self.__ref(self.__onChooseTrials)
234 mnuTrials.active_text = ts.trialset_name
235 self.chkInQSF = gtk.CheckButton('keep with data')
236 self.chkInQSF.set_tooltip_text('When checked, the Trials are saved in the QSF (session) file')
237 self.chkInQSF.set_active(ts.in_qsf)
238 self.chkInQSF.connect('toggled', self.__onToggleInQSF)
239 self.chkInQSF.show()
240 controls = qubx.tableGTK.TableViewCtrls(ts, None,
241 btnFile, 'Trials:', mnuTrials, self.chkInQSF,
242 ('Show in Models', bind(qubx.global_namespace.QubX.Models.set_index, 0)),
243 qubx.tableGTK.TableViewCtrls.REMOVE,
244 ('Copy row(s) to...', self.copy_rows),
245 qubx.tableGTK.TableViewCtrls.CALCULATE,
246 qubx.tableGTK.TableViewCtrls.PLOT,
247 qubx.tableGTK.TableViewCtrls.CLOSE)
248 controls.OnClickClose += self.__ref(self.__onClickClose)
249 Tables = qubx.global_namespace.QubX.Tables
250 Tables.add_table(ts, None, controls)
251 self.__table = ts
252 Tables.show_table(ts)
254 self.open()
256 self.save()
258 qubx.pyenv.env.OnScriptable('QubX.Trials.remove_trialset(%s)' % repr(self.trialset.trialset_name))
259 self.remove_trialset(self.trialset.trialset_name, force=False)
265 - def copy_rows(self, out_name=None, copy_rows_type=None, group=None, inverse=False, criteria=None):
266 tbn, crt, grp, inv, cta = qubx.tableGTK.prompt_copy_rows(self.trialset, self.trialset.trialset_name, self.trialset_names,
267 out_name, copy_rows_type, group, inverse, criteria)
268 if crt is None: # dialog cancel
269 return
270 if crt == COPY_ROWS_ALL:
271 qubx.pyenv.env.OnScriptable('QubX.Trials.copy_rows(out_name=%s, copy_rows_type=COPY_ROWS_ALL)'
272 % repr(tbn))
273 elif crt == COPY_ROWS_GROUP:
274 qubx.pyenv.env.OnScriptable('QubX.Trials.copy_rows(out_name=%s, copy_rows_type=COPY_ROWS_GROUP, group=%s, inverse=%s)'
275 % (repr(tbn),
276 repr(grp), repr(inv)))
277 elif crt == COPY_ROWS_CRITERIA:
278 qubx.pyenv.env.OnScriptable('QubX.Trials.copy_rows(out_name=%s, copy_rows_type=COPY_ROWS_CRITERIA, criteria=%s)'
279 % (repr(tbn), repr(cta)))
280 elif crt == COPY_ROWS_CHECKED:
281 qubx.pyenv.env.OnScriptable('QubX.Trials.copy_rows(out_name=%s, copy_rows_type=COPY_ROWS_CHECKED)'
282 % repr(tbn))
283 from_ts = self.trialset
284 ts = self.trialset = self.get_trialset(tbn)
285 gobject.idle_add(qubx.global_namespace.QubX.Tables.show_table, ts)
286 ts.copy_rows_from(from_ts, copy_rows_type=crt, group=grp, inverse=inv, criteria=cta, on_copy=self.__onCopyRow)
287 return ts
289 to_list.models[to_i] = from_list.models[from_i].clone()
290
298
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Fri Dec 15 19:07:38 2017 | http://epydoc.sourceforge.net |