| Trees | Indices | Help |
|
|---|
|
|
1 """Panel to modify idealized data.
2
3 Copyright 2008-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 import gobject
23 import gtk
24 from gtk import gdk
25 import numpy
26 import os
27 import qubx.chop
28 import qubx.data_types
29 import qubx.faces
30 import qubx.GTK
31 import qubx.notebook
32 import qubx.pyenv
33 import traceback
34 from itertools import izip, count
35 from qubx.accept import *
36 from qubx.GTK import pack_item, pack_space, pack_hsep, pack_vsep, pack_label, pack_button, pack_check, pack_radio, pack_scrolled
37 from qubx.settings import Property, Propertied
38 from qubx.util_types import WeakEvent, Reffer, bind, bind_with_args_before
39 from qubx.ulp_diff import fulpdiff
40
41 MAX_ULP_DIFF = 4
42
43
44 @Propertied(Property('stab_window', 50, 'number of events per chunk'),
45 Property('stab_overlap', 25, 'number of events overlapping in consecutive chunks'),
46 Property('stab_listname', 'Stability', 'name of output List'),
47 Property('list_events_class', 1, 'class index to be listed'),
48 Property('list_events_name', 'Events', 'output selection list name'),
49 Property('list_trans_from', 0, 'class index to be listed'),
50 Property('list_trans_to', 1, 'class index to be listed'),
51 Property('list_trans_pre', 5.0, 'msec of prior event to include in list sel'),
52 Property('list_trans_name', 'Transitions', 'output selection list name'),
53 # bw_ properties are used by menu in qubx.dataGTK for Baum-Welch (AMP)
54 Property('bw_auto_init', 0, 'True to spread initial amps evenly across [min(data)..max(data)]'),
55 Property('bw_auto_init_up', 1, 'False to auto-init classes from max to min'),
56 Property('bw_update_model', 1, 'True to update Classes:Amp and Std'),
57 Property('bw_show_ideal', 1, 'True to show results as idealized data'))
59 __explore_featured = ['calc_stability', 'save_dwt', 'save_sampled', 'clear', 'apply_dead_time', 'change_class', 'fill_blanks',
60 'join_class', 'set_amp', 'list_events', 'list_transitions', 'get_segmentation_idl']
62 qubx.faces.Face.__init__(self, name, global_name)
63 self.propertied_connect_settings('IdlTools')
64 self.__ref = Reffer()
65 self.QubX = qubx.pyenv.env.globals['QubX']
66
67 v = gtk.VBox()
68 self.scroll = pack_scrolled(v, self, with_vp=True, expand=True)
69
70 vh = pack_item(gtk.HBox(), v)
71 pack_label('Apply dead time:', vh)
72 self.txtDeadTime = pack_item(qubx.GTK.NumEntry(1.0, acceptFloatGreaterThan(0.0), '%.3g', width_chars=7), vh)
73 pack_label('ms', vh)
74 self.btnDeadTime = pack_button('Apply', vh, at_end=True, on_click=self.__onClickDeadTime)
75
76 vh = pack_item(gtk.HBox(), v)
77 pack_label('Change class', vh)
78 self.txtChangeFrom = pack_item(qubx.GTK.NumEntry(2, acceptIntGreaterThanOrEqualTo(0), width_chars=4), vh)
79 pack_label('events to class', vh)
80 self.txtChangeTo = pack_item(qubx.GTK.NumEntry(1, acceptIntGreaterThanOrEqualTo(0), width_chars=4), vh)
81 self.btnChangeClass = pack_button('Change', vh, at_end=True, on_click=self.__onClickChangeClass)
82
83 vh = pack_item(gtk.HBox(), v)
84 pack_label('Fill blanks with class', vh)
85 self.txtFillClass = pack_item(qubx.GTK.NumEntry(0, acceptIntGreaterThanOrEqualTo(0), width_chars=5), vh)
86 self.btnFillBlanks = pack_button('Fill blanks', vh, at_end=True, on_click=self.__onClickFillBlanks)
87
88 vh = pack_item(gtk.HBox(), v)
89 pack_label('Join class', vh)
90 self.txtJoinClass = pack_item(qubx.GTK.NumEntry(2, acceptIntGreaterThanOrEqualTo(0), width_chars=4), vh)
91 pack_label('events to the prior event', vh)
92 self.btnJoinClass = pack_button('Join', vh, at_end=True, on_click=self.__onClickJoinClass)
93
94 vh = pack_item(gtk.HBox(), v)
95 pack_label('Set amp of class', vh)
96 self.txtSetAmpClass = pack_item(qubx.GTK.NumEntry(2, acceptIntGreaterThanOrEqualTo(0), width_chars=4), vh)
97 pack_label('to', vh)
98 self.txtSetAmpTo = pack_item(qubx.GTK.NumEntry(0.0, acceptFloat, '%.4g', width_chars=8), vh)
99 self.btnSetAmp = pack_button('Set amp', vh, at_end=True, on_click=self.__onClickSetAmp)
100
101 vh = pack_item(gtk.HBox(), v)
102 pack_label('Calculate stats (e.g. occupancy):', vh)
103 self.btnIdlStatSeg = pack_button('of Segments', vh, at_end=True, on_click=self.__onClickIdlStatSeg)
104 self.btnIdlStatList = pack_button('of List', vh, at_end=True, on_click=self.__onClickIdlStatList)
105
106 vh = pack_item(gtk.HBox(), v)
107 pack_label('Calculate stability (stats over time):', vh)
108 self.btnStability = pack_button('Stability...', vh, at_end=True, on_click=self.onClickStability)
109
110 vh = pack_item(gtk.HBox(), v)
111 pack_label('Save as DWT:', vh)
112 self.btnSaveDWTStats = pack_button('With event stats...', vh, at_end=True, on_click=bind_with_args_before(self.onClickSaveDWT, True))
113 self.btnSaveDWT = pack_button('Standard...', vh, at_end=True, on_click=bind_with_args_before(self.onClickSaveDWT, False))
114
115 vh = pack_item(gtk.HBox(), v)
116 pack_label('Save as sampled text:', vh)
117 self.btnSaveSampledAmp = pack_button('by class amp...', vh, at_end=True, on_click=bind_with_args_before(self.onClickSaveSampled, True))
118 self.btnSaveSampledIndex = pack_button('by class index...', vh, at_end=True, on_click=bind_with_args_before(self.onClickSaveSampled, False))
119
120 vh = pack_item(gtk.HBox(), v)
121 pack_label('Clear idealization:', vh)
122 self.btnClearFile = pack_button('Whole file', vh, at_end=True, on_click=bind_with_args_before(self.onClickClear, True))
123 self.btnClearScreen = pack_button('On-screen', vh, at_end=True, on_click=bind_with_args_before(self.onClickClear, False))
124
125 vh = pack_item(gtk.HBox(), v)
126 pack_label('Make List:', vh)
127 self.btnChop = pack_button('of Bursts (Chop)', vh, at_end=True, on_click=self.onClickChop)
128 self.btnChop = pack_button('of Transitions', vh, at_end=True, on_click=self.onClickListTransitions)
129 self.btnChop = pack_button('of Events', vh, at_end=True, on_click=self.onClickListEvents)
130
131 qubx.notebook.Notebook.register_auto('IdealStat.Segments', 'Segments table, on idealize/get stats', True)
132 qubx.notebook.Notebook.register_auto('IdealStat.List', 'List table, on idealize/get stats', True)
133
135 qubx.pyenv.env.OnScriptable('QubX.Data.view.measure_segments(QubX.DataSource.get_segmentation_file(), script_name="Idealized.py")')
136 self.QubX.Data.view.measure_segments(self.QubX.DataSource.get_segmentation(), script_name='Idealized.py')
137 self.QubX.Tables.show_table(self.QubX.Data.file.segments, show_tables=True)
139 qubx.pyenv.env.OnScriptable('QubX.Data.view.measure_list(QubX.Data.file.list, script_name="Idealized.py")')
140 self.QubX.Data.view.measure_list(self.QubX.Data.file.list, script_name='Idealized.py', wait=False,
141 receiver=lambda tbl, off, ct: self.QubX.Tables.show_table(tbl, show_tables=True))
143 dlg = gtk.Dialog('Calculate stability...', self.parent_window, gtk.DIALOG_MODAL)
144 line = pack_item(gtk.HBox(), dlg.vbox)
145 pack_label('Builds a list of overlapping selections and measures them.', line)
146 line = pack_item(gtk.HBox(), dlg.vbox)
147 pack_label('Window size:', line)
148 txtWindow = pack_item(qubx.GTK.NumEntry(self.stab_window, acceptIntGreaterThan(0), width_chars=6), line)
149 pack_label('events', line)
150 line = pack_item(gtk.HBox(), dlg.vbox)
151 pack_label('Overlap:', line)
152 txtOverlap = pack_item(qubx.GTK.NumEntry(self.stab_overlap, acceptIntGreaterThan(0), width_chars=6), line)
153 pack_label('events', line)
154 line = pack_item(gtk.HBox(), dlg.vbox)
155 pack_label('Output list name:', line)
156 txtListName = pack_item(qubx.GTK.NumEntry(self.stab_listname), line, expand=True)
157 dlg.add_button('Cancel', gtk.RESPONSE_REJECT)
158 dlg.add_button('Run', gtk.RESPONSE_ACCEPT)
159 response = dlg.run()
160 window_size = txtWindow.value
161 overlap = txtOverlap.value
162 listname = txtListName.value or self.stab_listname
163 dlg.destroy()
164
165 if window_size != self.stab_window:
166 self.propertied_on_user_set('stab_window', window_size)
167 if overlap != self.stab_overlap:
168 self.propertied_on_user_set('stab_overlap', overlap)
169 if listname != self.stab_listname:
170 self.propertied_on_user_set('stab_listname', listname)
171
172 qubx.pyenv.env.OnScriptable('%s.calc_stability(window_size=%i, overlap=%i, listname=%s)' % (self.global_name, window_size, overlap, repr(listname)))
173 self.calc_stability(window_size, overlap, listname, wait=False)
174 - def calc_stability(self, window_size=None, overlap=None, listname=None, wait=True, receiver=lambda: None):
175 if wait:
176 return qubx.pyenv.call_async_wait(lambda rcv: self.calc_stability(window_size, overlap, listname, wait=False, receiver=rcv))
177 self.btnStability.set_sensitive(False)
178 ws = self.stab_window if (window_size is None) else window_size
179 ol = self.stab_overlap if (overlap is None) else overlap
180 ln = self.stab_listname if (listname is None) else listname
181 QubX = qubx.global_namespace.QubX
182 segs = QubX.DataSource.get_segmentation()
183 idl = [seg.get_idealization(get_fragments=True) for seg in segs] # (ff, ll, cc)
184 lst = QubX.Data.file.lists.show_list(ln)
185 lst.clear()
186 task = StabilityTask(segs, idl, ws, ol, lst, receiver)
187 task.OnException += task_exception_to_console
188 task.start()
190 qubx.GTK.SaveAs('Save DWT as...', self.QubX.Data.path, os.path.splitext(os.path.split(self.QubX.Data.file.path)[1])[0],
191 lambda fname: self.save_dwt_clicked(fname, with_stats),
192 filters=[('DWT files', '.dwt')], parent=self.parent_window)
194 if not fname: return
195 self.QubX.Data.path = os.path.split(fname)[0]
196 if not os.path.splitext(fname)[1]:
197 fname = fname + '.dwt'
198 qubx.pyenv.env.OnScriptable('QubX.Tools.Idealization.save_dwt(%s, with_stats=%s)' % (repr(fname), repr(with_stats)))
199 self.save_dwt(fname, with_stats)
201 self.busy_dwt_fname = fname
202 self.busy_dwt_stats = with_stats
203 dlg = qubx.GTK.BusyDialog('Saving %s...'%os.path.split(fname)[1], self.busy_save_dwt)
204 dlg.set_size_request(300, 75)
205 try:
206 dlg.run()
207 except Exception, e:
208 traceback.print_exc()
209 mdlg = gtk.MessageDialog(qubx.GTK.get_active_window(), buttons=gtk.BUTTONS_OK, flags=gtk.DIALOG_MODAL,
210 message_format=str(e))
211 mdlg.run()
212 mdlg.destroy()
213 dlg.destroy()
215 fname = self.busy_dwt_fname
216 with_stats = self.busy_dwt_stats
217 signal = self.QubX.DataSource.signal
218 segs = self.get_segmentation_idl(self.QubX.Data.view.get_segmentation_file())
219 if not segs: return
220 fi = open(fname, "w")
221 points_f = segs[0].f
222 points_n = segs[-1].l - points_f + 1
223 for s, seg in enumerate(segs):
224 if not progress((seg.f - points_f) * 1.0 / points_n):
225 break
226 Nclass = numpy.max(seg.classes) + 1
227 amp = seg.file.ideal[signal].seg[seg.index].amp
228 std = seg.file.ideal[signal].seg[seg.index].std
229 fi.write("Segment: %d Dwells: %d Sampling(ms): %.10g Start(ms): %.10g ClassCount: %d" % (s+1, len(seg.firsts), seg.file.sampling*1e3, seg.start, Nclass))
230 for c in xrange(Nclass):
231 a = amp[c] if c < len(amp) else 0.0
232 s = std[c] if c < len(std) else 0.0
233 fi.write(" %.10g %.10g" % (a, s))
234 fi.write("\n")
235 if with_stats:
236 samples = seg.get_samples().samples
237 means = [samples[seg.firsts[i]-seg.f:seg.lasts[i]+1-seg.f].mean() for i in xrange(len(seg.firsts))]
238 stds = [samples[seg.firsts[i]-seg.f:seg.lasts[i]+1-seg.f].std() for i in xrange(len(seg.firsts))]
239 for i in xrange(len(seg.firsts)):
240 stats = with_stats and ("\t%.10g\t%.10g" % (means[i], stds[i])) or ""
241 fi.write("%d\t%.10g%s\n" % (seg.classes[i], seg.durations[i], stats))
242 # complain on zero events?
244 qubx.GTK.SaveAs('Save Sampled idl as...', self.QubX.Data.path, os.path.splitext(os.path.split(self.QubX.Data.file.path)[1])[0],
245 lambda fname: self.save_sampled_clicked(fname, lookup_amps),
246 filters=[('Text files', '.txt')], parent=self.parent_window)
248 if not fname: return
249 if not os.path.splitext(fname)[1]:
250 fname = fname + '.txt'
251 self.QubX.Data.path = os.path.split(fname)[0]
252 qubx.pyenv.env.OnScriptable('QubX.Tools.Idealization.save_sampled(%s, lookup_amps=%s)' % (repr(fname), repr(lookup_amps)))
253 self.save_sampled(fname, lookup_amps)
255 self.busy_sam_fname = fname
256 self.busy_sam_amps = lookup_amps
257 dlg = qubx.GTK.BusyDialog('Saving %s...'%os.path.split(fname)[1], self.busy_save_sampled)
258 dlg.set_size_request(300, 75)
259 try:
260 dlg.run()
261 except Exception, e:
262 traceback.print_exc()
263 mdlg = gtk.MessageDialog(qubx.GTK.get_active_window(), buttons=gtk.BUTTONS_OK, flags=gtk.DIALOG_MODAL,
264 message_format=str(e))
265 mdlg.run()
266 mdlg.destroy()
267 dlg.destroy()
269 fname = self.busy_sam_fname
270 lookup_amps = self.busy_sam_amps
271 signal = self.QubX.DataSource.signal
272 segs = self.get_segmentation_idl(self.QubX.Data.view.get_segmentation_file())
273 if not segs: return
274 sampling = segs[0].file.sampling
275 fi = open(fname, "w")
276 points_f = segs[0].f
277 points_n = segs[-1].l - points_f + 1
278 for s, seg in enumerate(segs):
279 if not progress((seg.f - points_f) * 1.0 / points_n):
280 break
281 if s:
282 fi.write('\n')
283 if lookup_amps:
284 amps = numpy.array(seg.file.ideal[signal].seg[seg.index].amp)
285 classes = amps[seg.classes]
286 else:
287 classes = seg.classes
288 t = seg.start * 1e-3
289 for i in xrange(len(seg.firsts)):
290 x = classes[i]
291 for j in xrange(seg.lasts[i] - seg.firsts[i] + 1):
292 fi.write("%f\t%s\n" % (t, x))
293 t += sampling
295 qubx.pyenv.env.OnScriptable('QubX.Tools.Idealization.clear(whole_file=%s)' % repr(whole_file))
296 self.clear(whole_file)
298 signal = self.QubX.DataSource.signal
299 file = self.QubX.Data.file
300 if whole_file:
301 file.ideal[signal].idl.clear()
302 else:
303 for seg in self.QubX.Data.view.get_segmentation_hires():
304 file.ideal[signal].idl.set_dwell(seg.f, seg.l, -1)
305 file.OnChangeIdealization(file, signal)
307 qubx.pyenv.env.OnScriptable('QubX.Tools.Idealization.apply_dead_time(td_ms=%s)' % repr(self.txtDeadTime.value))
308 self.apply_dead_time(self.txtDeadTime.value)
310 dlg = qubx.GTK.BusyDialog('Applying dead time', lambda progress: self.busy_dead_time(progress, td_ms))
311 dlg.set_size_request(300, 75)
312 try:
313 dlg.run()
314 except Exception, e:
315 traceback.print_exc()
316 mdlg = gtk.MessageDialog(qubx.GTK.get_active_window(), buttons=gtk.BUTTONS_OK, flags=gtk.DIALOG_MODAL,
317 message_format=str(e))
318 mdlg.run()
319 mdlg.destroy()
320 dlg.destroy()
322 segs = self.get_segmentation_idl(self.QubX.DataSource.get_segmentation())
323 if not segs: return
324 td_samples = td_ms / (1e3 * segs[0].file.sampling)
325 points_f = segs[0].f
326 points_n = segs[-1].l - points_f + 1
327 for seg in segs:
328 if not progress((seg.f - points_f) * 1.0 / points_n):
329 break
330 ff, ll, cc = seg.firsts, seg.lasts, seg.classes
331 n = len(ff)
332 i_in = 0
333 while i_in < n:
334 n_here = (ll[i_in] - ff[i_in] + 1)
335 if (n_here > td_samples) or (fulpdiff(n_here, td_samples) < MAX_ULP_DIFF):
336 break
337 i_in += 1
338 if i_in:
339 ll[0] = ll[i_in-1]
340 cc[0] = -1
341 i_out = 1
342 else:
343 i_out = 0
344 while i_in < n:
345 cls = cc[i_in]
346 dur = (ll[i_in] - ff[i_in] + 1)
347 if (cc[i_out] == cls) or ((dur < td_samples) and (fulpdiff(dur, td_samples) > MAX_ULP_DIFF)):
348 ll[i_out] = ll[i_in]
349 else:
350 i_out += 1
351 if i_out < n:
352 ff[i_out] = ff[i_in]
353 ll[i_out] = ll[i_in]
354 cc[i_out] = cls
355 i_in += 1
356 n = i_out + 1
357 seg.file.ideal[seg.signal].idl.set_dwells(n, ff, ll, cc)
358 segs[0].file.OnChangeIdealization(segs[0].file, segs[0].signal)
360 cls_from = self.txtChangeFrom.value
361 cls_to = self.txtChangeTo.value
362 qubx.pyenv.env.OnScriptable('QubX.Tools.Idealization.change_class(cls_from=%i, cls_to=%i)' % (cls_from, cls_to))
363 self.change_class(cls_from, cls_to)
365 dlg = qubx.GTK.BusyDialog('Changing class of events', lambda progress: self.busy_change_class(progress, cls_from, cls_to))
366 dlg.set_size_request(300, 75)
367 try:
368 dlg.run()
369 except Exception, e:
370 traceback.print_exc()
371 mdlg = gtk.MessageDialog(qubx.GTK.get_active_window(), buttons=gtk.BUTTONS_OK, flags=gtk.DIALOG_MODAL,
372 message_format=str(e))
373 mdlg.run()
374 mdlg.destroy()
375 dlg.destroy()
377 segs = self.get_segmentation_idl(self.QubX.DataSource.get_segmentation())
378 if not segs: return
379 points_f = segs[0].f
380 points_n = segs[-1].l - points_f + 1
381 for seg in segs:
382 if not progress((seg.f - points_f) * 1.0 / points_n):
383 break
384 ff, ll, cc = seg.firsts, seg.lasts, seg.classes
385 n = len(ff)
386 for i in xrange(n):
387 if cc[i] == cls_from:
388 cc[i] = cls_to
389 seg.file.ideal[seg.signal].idl.set_dwells(n, ff, ll, cc)
390 segs[0].file.OnChangeIdealization(segs[0].file, segs[0].signal)
392 cls_fill = self.txtFillClass.value
393 qubx.pyenv.env.OnScriptable('QubX.Tools.Idealization.fill_blanks(cls_fill=%i)' % cls_fill)
394 self.fill_blanks(cls_fill)
396 dlg = qubx.GTK.BusyDialog('Filling blanks', lambda progress: self.busy_fill_blanks(progress, cls_fill))
397 dlg.set_size_request(300, 75)
398 try:
399 dlg.run()
400 except Exception, e:
401 traceback.print_exc()
402 mdlg = gtk.MessageDialog(qubx.GTK.get_active_window(), buttons=gtk.BUTTONS_OK, flags=gtk.DIALOG_MODAL,
403 message_format=str(e))
404 mdlg.run()
405 mdlg.destroy()
406 dlg.destroy()
408 segs = self.QubX.DataSource.get_segmentation()
409 if not segs: return
410 points_f = segs[0].f
411 points_n = segs[-1].l - points_f + 1
412 for seg in segs:
413 if not progress((seg.f - points_f) * 1.0 / points_n):
414 break
415 ff, ll, cc = seg.get_idealization(get_fragments=True)
416 n = len(ff)
417 for i in xrange(n):
418 if cc[i] < 0:
419 cc[i] = cls_fill
420 seg.file.ideal[seg.signal].idl.set_dwells(n, ff, ll, cc)
421 segs[0].file.OnChangeIdealization(segs[0].file, segs[0].signal)
423 cls_join = self.txtJoinClass.value
424 qubx.pyenv.env.OnScriptable('QubX.Tools.Idealization.join_class(cls_join=%i)' % cls_join)
425 self.join_class(cls_join)
427 dlg = qubx.GTK.BusyDialog('Joining events', lambda progress: self.busy_join_class(progress, cls_join))
428 dlg.set_size_request(300, 75)
429 try:
430 dlg.run()
431 except Exception, e:
432 traceback.print_exc()
433 mdlg = gtk.MessageDialog(qubx.GTK.get_active_window(), buttons=gtk.BUTTONS_OK, flags=gtk.DIALOG_MODAL,
434 message_format=str(e))
435 mdlg.run()
436 mdlg.destroy()
437 dlg.destroy()
439 segs = self.get_segmentation_idl(self.QubX.DataSource.get_segmentation())
440 if not segs: return
441 points_f = segs[0].f
442 points_n = segs[-1].l - points_f + 1
443 for seg in segs:
444 if not progress((seg.f - points_f) * 1.0 / points_n):
445 break
446 ff, ll, cc = seg.firsts, seg.lasts, seg.classes
447 cls_last = seg.f and seg.file.ideal[seg.signal].idl[seg.f-1] or -1
448 n = len(ff)
449 for i in xrange(n):
450 if cc[i] == cls_join:
451 cc[i] = cls_last
452 else:
453 cls_last = cc[i]
454 seg.file.ideal[seg.signal].idl.set_dwells(n, ff, ll, cc)
455 segs[0].file.OnChangeIdealization(segs[0].file, segs[0].signal)
457 cls = self.txtSetAmpClass.value
458 amp = self.txtSetAmpTo.value
459 qubx.pyenv.env.OnScriptable('QubX.Tools.Idealization.set_amp(cls=%i, amp=%s)' % (cls, repr(amp)))
460 self.set_amp(cls, amp)
462 segs = self.QubX.DataSource.get_segmentation()
463 if not segs: return
464 for seg in segs:
465 amps = seg.file.ideal[seg.signal].seg[seg.index].amp
466 if (not (amps is None)) and (len(amps) > cls):
467 amps[cls] = amp
468 segs[0].file.OnChangeIdealization(segs[0].file, segs[0].signal)
472 response = qubx.GTK.PromptEntries([('List events in class:', self.list_events_class, acceptIntGreaterThanOrEqualTo(0), str),
473 ('Output list name:', self.list_events_name, str, str)],
474 'Make List of Events', self.parent_window)
475 if response and response[1]:
476 self.list_events_class = response[0]
477 self.list_events_name = response[1]
478 qubx.pyenv.env.OnScriptable('QubX.Tools.Idealization.list_events(class_index=%s, output_list_name=%s)' % (self.list_events_class, repr(self.list_events_name)))
479 self.list_events()
481 cls = class_index
482 if cls is None:
483 cls = self.list_events_class
484 list_name = output_list_name or self.list_events_name
485 dlg = qubx.GTK.BusyDialog('Listing events...', lambda progress: self.busy_list_events(cls, list_name, progress))
486 dlg.set_size_request(300, 75)
487 try:
488 dlg.run()
489 except Exception, e:
490 traceback.print_exc()
491 mdlg = gtk.MessageDialog(qubx.GTK.get_active_window(), buttons=gtk.BUTTONS_OK, flags=gtk.DIALOG_MODAL,
492 message_format=str(e))
493 mdlg.run()
494 mdlg.destroy()
495 dlg.destroy()
497 lst = self.QubX.Data.file.lists.show_list(list_name)
498 lst.clear()
499 segs = self.QubX.DataSource.get_segmentation()
500 for s, seg in enumerate(segs):
501 if not progress( s * 1.0 / len(segs) ): return
502 for c, chunk in enumerate(seg.chunks):
503 if chunk.included:
504 ff, ll, cc = chunk.get_idealization(get_fragments=True, get_durations=False)
505 for i, f, l, c in izip(count(), ff, ll, cc):
506 if c == cls:
507 lst.insert_selection(f, l)
509 response = qubx.GTK.PromptEntries([('List transitions from class:', self.list_trans_from, acceptIntGreaterThanOrEqualTo(0), str),
510 ('to class:', self.list_trans_to, acceptIntGreaterThanOrEqualTo(0), str),
511 ('msec before each transition:', self.list_trans_pre, acceptFloatGreaterThanOrEqualTo(0.0), '%.3g'),
512 ('Output list name:', self.list_trans_name, str, str)],
513 'Make List of Events', self.parent_window)
514 if response and response[3]:
515 self.list_trans_from, self.list_trans_to, self.list_trans_pre, self.list_trans_name = response
516 qubx.pyenv.env.OnScriptable('QubX.Tools.Idealization.list_transitions(class_from=%s, class_to=%s, msec_before=%s, output_list_name=%s)' % (self.list_trans_from, self.list_trans_to, self.list_trans_pre, repr(self.list_trans_name)))
517 self.list_transitions()
518 - def list_transitions(self, class_from=None, class_to=None, msec_before=None, output_list_name=None):
519 cls_from = class_from
520 if cls_from is None:
521 cls_from = self.list_trans_from
522 cls_to = class_to
523 if cls_to is None:
524 cls_to = self.list_trans_to
525 samples_pre = msec_before
526 if samples_pre is None:
527 samples_pre = self.list_trans_pre
528 samples_pre = int(round(samples_pre * 1e-3 / self.QubX.Data.file.sampling))
529 list_name = output_list_name or self.list_trans_name
530 dlg = qubx.GTK.BusyDialog('Listing transitions...', lambda progress: self.busy_list_transitions(cls_from, cls_to, samples_pre, list_name, progress))
531 dlg.set_size_request(300, 75)
532 try:
533 dlg.run()
534 except Exception, e:
535 traceback.print_exc()
536 mdlg = gtk.MessageDialog(qubx.GTK.get_active_window(), buttons=gtk.BUTTONS_OK, flags=gtk.DIALOG_MODAL,
537 message_format=str(e))
538 mdlg.run()
539 mdlg.destroy()
540 dlg.destroy()
542 lst = self.QubX.Data.file.lists.show_list(list_name)
543 lst.clear()
544 segs = self.QubX.DataSource.get_segmentation()
545 for s, seg in enumerate(segs):
546 if not progress( s * 1.0 / len(segs) ): return
547 for c, chunk in enumerate(seg.chunks):
548 if chunk.included:
549 ff, ll, cc = chunk.get_idealization(get_fragments=True, get_durations=False)
550 for i, f, l, c in izip(count(), ff, ll, cc):
551 if i == 0: continue
552 if (c == cls_to) and (cc[i-1] == cls_from):
553 lst.insert_selection(max(ff[i-1], f-samples_pre), l)
555 if not segs: return []
556 # split into regions of cls >= 0
557 idlsegs = []
558 for seg in segs:
559 seg.firsts, seg.lasts, seg.classes, seg.durations = seg.get_idealization(get_fragments=True, get_durations=True)
560 if numpy.any(seg.classes < 0):
561 ndwell = len(seg.lasts)
562 inext = 0
563 while inext < ndwell:
564 ifirst = inext
565 while (ifirst < ndwell) and (seg.classes[ifirst] < 0):
566 ifirst += 1
567 inext = ifirst + 1
568 while (inext < ndwell) and (seg.classes[inext] >= 0):
569 inext += 1
570 if ifirst < ndwell:
571 idlseg = qubx.data_types.SourceSeg(file=seg.file, signal=seg.signal, f=seg.firsts[ifirst],
572 l=seg.lasts[inext-1], index=seg.index, offset=seg.offset,
573 start=seg.start+(seg.firsts[ifirst]-seg.f)*1e3*seg.file.sampling,
574 latency=seg.latency, filter_Hz=seg.filter_Hz)
575 idlseg.firsts = numpy.array(seg.firsts[ifirst:inext])
576 idlseg.lasts = numpy.array(seg.lasts[ifirst:inext])
577 idlseg.classes = numpy.array(seg.classes[ifirst:inext])
578 idlseg.durations = numpy.array(seg.durations[ifirst:inext])
579 idlsegs.append(idlseg)
580 else:
581 idlsegs.append(seg)
582 return idlsegs
583
585 traceback.print_exception(typ, val, tb)
586
589 qubx.task.Task.__init__(self, 'Stability')
590 self.segs = segs
591 self.idl = idl
592 self.window_size = window_size
593 self.overlap = overlap
594 self.lst = lst
595 self.receiver = receiver
597 QubX = qubx.global_namespace.QubX
598 window_size = self.window_size
599 overlap = self.overlap
600 qubx.task.Tasks.add_task(self)
601 self.status = 'Running...'
602 try:
603 n = 0
604 done = 0
605 sels = []
606 for ff, ll, cc in self.idl:
607 n += len(ff)
608 for ff, ll, cc in self.idl:
609 n_in_seg = len(ff)
610 for i in xrange(0, n_in_seg-window_size, overlap):
611 sels.append((ff[i], ll[min(n_in_seg, i+window_size)-1]))
612 if not (i % 20*overlap):
613 self.progress = (done + i) * 50.0 / n
614 done += n_in_seg
615 rcv = self.receiver
616 self.receiver = None # fill_and_measure will call it; avoid double-invocation in finally
617 gobject.idle_add(fill_and_measure_list, self.lst, sels, rcv)
618 finally:
619 try:
620 QubX.Tools.Idealization.btnStability.set_sensitive(True)
621 except:
622 pass
623 if self.receiver:
624 gobject.idle_add(self.receiver)
625 qubx.task.Tasks.remove_task(self)
626
628 QubX = qubx.global_namespace.QubX
629 try:
630 for f, l in sels:
631 lst.insert_selection(f, l)
632 QubX.Data.view.measure_list(lst, script_name='Idealized.py')
633 QubX.Data.file.lists.show_list(lst.list_name)
634 finally:
635 gobject.idle_add(receiver)
636
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Fri Dec 15 19:07:38 2017 | http://epydoc.sourceforge.net |