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

Source Code for Module qubx.list_average

  1  """Panel with live average of selections in active List. 
  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 cStringIO 
 23  import itertools 
 24  import os 
 25  import sys 
 26  import time 
 27  import traceback 
 28  import gobject 
 29  import cairo 
 30  import gtk 
 31  import qubx.settings 
 32  import qubx.GTK 
 33  import qubx.pyenv 
 34  import qubx.tree 
 35  import qubx.faces 
 36  import qubx.fit_space 
 37  import qubx.task 
 38  import qubx.dataGTK 
 39  import qubx.extract 
 40  import qubx.notebook 
 41  import qubx.notebookGTK 
 42  import qubx.toolspace 
 43   
 44  from gtk import gdk 
 45  from gtk import keysyms 
 46  from itertools import izip, count 
 47  from qubx.util_types import * 
 48  from qubx.accept import * 
 49  from qubx.GTK import pack_item, pack_space, pack_hsep, pack_vsep, pack_label, pack_button, pack_check, pack_radio, pack_scrolled, build_menuitem 
 50  from qubx.settings import Property, Propertied 
 51  from numpy import arange, array, zeros 
 52  from qubx.task import Tasks 
 53   
 54  GROUPS_IN_MENU = 16 
55 56 @Propertied(Property('max_n', 2048, 'if there are more datapoints, they will be resampled to this many onscreen')) 57 -class ListAverageFace(qubx.faces.Face):
58 """ 59 60 Panel showing live average of front List. 61 62 @ivar limit_group: None to use all selections, or integer group index to use only matching sels 63 64 """ 65 66 __explore_featured = ['plot', 'sync', 'nbChart', 'nbPicture', 'subNotebook', 'nbParams', 'limit_group', 'update', 'robot_update'] 67
68 - def __init__(self, name, global_name=""):
69 """@param name: caption for this panel's tab""" 70 qubx.faces.Face.__init__(self, name, global_name) 71 self.__ref = Reffer() 72 self.set_size_request(100, 70) 73 self.QubX = qubx.pyenv.env.globals['QubX'] 74 self.QubX.OnQuit += self.__ref(lambda: self.plot.controls.robot.stop()) 75 self.plot = pack_item(qubx.fit_space.FitSpace(label=name, global_name=global_name and ("%s.plot" % global_name)), self, expand=True) 76 self.plot.layerset = self.plot.controlsHidden 77 self.plot.caption = 'Average of all traces in List' 78 self.plot.controls.robot.OnException += self.__ref(self.__onException) 79 self.plot.data_rad = 0.0 80 self.subMaxN = qubx.toolspace.SubLayer_Label('Max N: %i' % self.max_n, -1, 1, x=-20, y=0, w=10, h=qubx.fit_space.LINE_EMS, 81 color=self.plot.controls.cText, action=self.__ref(self.__onClickMaxN)) 82 self.plot.layBottomHidden.add_sublayer(self.subMaxN) 83 self.subExtract = qubx.toolspace.SubLayer_Label('Extract...', 0, 1, x=-30, y=0, w=10, h=qubx.fit_space.LINE_EMS, 84 color=self.plot.controls.cButton, action=self.__ref(self.__onClickExtract)) 85 self.plot.layBottomHidden.add_sublayer(self.subExtract) 86 self.subGroup = qubx.toolspace.SubLayer_Label('Group: All', -1, 1, x=-40, y=0, w=10, h=qubx.fit_space.LINE_EMS, 87 color=self.plot.controls.cText, action=self.__ref(self.__onClickGroup)) 88 self.plot.layBottomHidden.add_sublayer(self.subGroup) 89 self.mnuGroup = gtk.Menu() 90 self.itemGroupAll = build_menuitem('All', self.__ref(bind(self.__onClickGroupItem, None)), item_class=gtk.CheckMenuItem, active=True, menu=self.mnuGroup) 91 self.group_items = [build_menuitem(str(i), self.__ref(bind(self.__onClickGroupItem, i)), item_class=gtk.CheckMenuItem, menu=self.mnuGroup) for i in xrange(GROUPS_IN_MENU)] 92 build_menuitem('Other...', self.__ref(self.__onClickGroupOther), menu=self.mnuGroup) 93 self.__limit_group = None 94 self.__ignore_group_event = False 95 self.sync = self.plot.controls.robot.sync 96 self.serial = 0 97 98 self.propertied_connect_settings('ListAverage') 99 100 self.__datafile = None 101 self.QubX.Data.OnSwitch += self.__ref(self.__onSwitchData) 102 self.QubX.DataSource.OnChangeSignal += self.__ref(self.__onChangeSignal) 103 104 self.plot.controls.robot.OnStats += self.__ref(self.__onStats) 105 self.plot.controls.robot.OnEndFit += self.__ref(self.__onEndFit) 106 self.layNotebook = qubx.toolspace.Layer(x=1, y=-5.5-qubx.fit_space.LINE_EMS, w=2, h=2, cBG=qubx.toolspace.COLOR_CLEAR) 107 self.subNotebook = qubx.notebookGTK.SubLayer_Notebook(x=0, y=0, w=2, h=2) 108 self.layNotebook.add_sublayer(self.subNotebook) 109 self.plot.add_layer(self.layNotebook) 110 self.nbChart = qubx.notebook.NbChart('Chart', '%s.nbChart' % global_name, lambda: self.plot.caption, 111 self.plot.controls.nb_get_shape, self.plot.controls.nb_get_headers, 112 get_col=self.plot.controls.nb_get_col, get_type=lambda: float, 113 get_series=self.plot.nb_get_series) 114 self.subNotebook.items.append(self.nbChart) 115 self.nbPicture = qubx.notebookGTK.NbPicture('Picture', '%s.nbPicture' % global_name, self.plot.nb_picture_get_shape, 116 self.plot.nb_picture_draw) 117 self.subNotebook.items.append(self.nbPicture) 118 self.nbParams = qubx.notebook.NbDynText('Parameters', '%s.nbParams' % global_name, self.plot.controls.nb_get_param_text) 119 self.nbParams.std_err_est = None 120 self.subNotebook.items.append(self.nbParams) 121 qubx.notebook.Notebook.register_auto('%s.Parameters'%name, '%s Parameters, on Fit'%name, True) 122 qubx.notebook.Notebook.register_auto('%s.Results'%name, '%s Results, on Fit'%name, True) 123 qubx.notebook.Notebook.register_auto('%s.Chart'%name, '%s Chart, on Fit'%name) 124 qubx.notebook.Notebook.register_auto('%s.Picture'%name, '%s Picture, on Fit'%name, True) 125 self.__nb_next_stats = False 126 self.__onSwitchData(self.QubX.Data, self.QubX.Data.file)
127 - def propertied_set(self, value, name):
128 super(ListAverageFace, self).propertied_set(value, name) 129 if name == 'max_n': 130 self.subMaxN.label = 'Max N: %i' % value 131 self.update()
132 - def set_limit_group(self, x):
133 if x == self.__limit_group: 134 return 135 self.__limit_group = x 136 if x is None: 137 self.subGroup.label = 'Group: All' 138 else: 139 self.subGroup.label = 'Group: %i' % x 140 self.update()
141 limit_group = property(lambda self: self.__limit_group, lambda self, x: self.set_limit_group(x))
142 - def __onClickMaxN(self, x, y, e):
143 new_val = qubx.pyenvGTK.prompt_entry('Max N (larger data will be resampled):', self.max_n, acceptIntGreaterThan(0)) 144 if not (new_val is None): 145 self.propertied_on_user_set('max_n', new_val)
146 - def __onClickExtract(self, x, y, e):
147 Extract = self.QubX.Tools.Extract 148 Extract.source = qubx.extract.SOURCE_LIST 149 Extract.subtract_fit = qubx.extract.SUBTRACT_FIT_NONE 150 Extract.resample = False 151 Extract.process = qubx.extract.PROC_AVG 152 if not (self.__limit_group is None): 153 Extract.limit_to_group = True 154 Extract.limit_group = self.__limit_group 155 else: 156 Extract.limit_to_group = False 157 Extract.request_show()
158 - def __onClickGroup(self, x, y, e):
159 self.__ignore_group_event = True 160 g = self.__limit_group 161 self.itemGroupAll.set_active(g is None) 162 for i, item in enumerate(self.group_items): 163 item.set_active(g == i) 164 self.__ignore_group_event = False 165 self.mnuGroup.popup(None, None, None, 0, e.time)
166 - def __onClickGroupItem(self, g):
167 if self.__ignore_group_event: 168 return 169 qubx.pyenv.env.OnScriptable('%s.limit_group = %s' % (self.global_name, g)) 170 self.limit_group = g
171 - def __onClickGroupOther(self, item):
172 g = self.__limit_group 173 if g is None: 174 g = 0 175 new_val = qubx.pyenvGTK.prompt_entry('Group:', g, acceptIntGreaterThan(0)) 176 if not (new_val is None): 177 qubx.pyenv.env.OnScriptable('%s.limit_group = %s' % (self.global_name, new_val)) 178 self.limit_group = new_val
179 - def onShow(self, showing):
180 if showing: 181 self.update()
182 - def __onSwitchData(self, Data, file):
183 if self.__datafile: 184 self.__datafile.lists.OnChangeList -= self.__ref(self.__onChangeList) 185 self.__datafile.lists.OnSwitchList -= self.__ref(self.__onChangeList) 186 self.__datafile.OnChangeSamples -= self.__ref(self.__onChangeList) 187 self.__datafile = file 188 if self.__datafile: 189 self.__datafile.lists.OnChangeList += self.__ref(self.__onChangeList) 190 self.__datafile.lists.OnSwitchList += self.__ref(self.__onChangeList) 191 self.__datafile.OnChangeSamples += self.__ref(self.__onChangeList) 192 self.update()
193 - def __onChangeSignal(self, signal):
194 self.update()
195 - def __onChangeList(self, *args, **kw):
196 self.update()
197 - def __onEndFit(self):
198 self.__nb_next_stats = True
199 - def __onStats(self, correlation, is_pseudo, std_err_est, ssr, r2, runs_prob):
200 if self.__nb_next_stats: 201 self.__nb_next_stats = False 202 label = self.face_name 203 n = len(self.plot.controls.xx) 204 qubx.notebook.Notebook.send(qubx.notebook.NbText("""%(label)s fitting finished. 205 \tN: %(n)i 206 \tSSR: %(ssr).6g 207 \tR^2: %(r2).6g 208 \tWald-Wolfowitz runs probability: %(runs_prob).6g 209 \tCorrelation: 210 %(correlation)s 211 """ % locals()), auto_id='%s.Results'%self.face_name) 212 self.nbParams.std_err_est = std_err_est 213 qubx.notebook.Notebook.send(self.nbParams, auto_id='%s.Parameters'%self.face_name) 214 qubx.notebook.Notebook.send(self.nbChart, auto_id='%s.Chart'%self.face_name) 215 qubx.notebook.Notebook.send(self.nbPicture, auto_id='%s.Picture'%self.face_name) 216 self.nbParams.std_err_est = None
217
218 - def __onException(self, robot, typ, val, trace):
219 traceback.print_exception(typ, val, trace)
220 - def update(self, force=False):
221 """Requests that robot_update() be called in the robot thread.""" 222 self.serial += 1 223 if self.showing or force: 224 self.plot.controls.robot.do(self.robot_try_update, self.serial)
225 - def robot_try_update(self, serial):
226 """In robot thread, filters out duplicate (stale serial) requests and calls robot_update()""" 227 # if there's a newer update, wait for that request to come around and proc all at once 228 if serial == self.serial: 229 self.robot_update()
230 - def robot_update(self):
231 if (not self.__datafile) or (not self.__datafile.list): return 232 with self.plot.controls.robot.main_hold: 233 segs = self.__datafile.get_segmentation_list(signal=self.QubX.DataSource.signal, group=self.__limit_group) 234 max_n = self.max_n 235 if not segs: 236 self.plot.controls.robot.robot_set_data([], []) 237 return 238 seg = qubx.extract.SourceSegAvg(segs) 239 if not seg.n: return 240 if seg.n > max_n: 241 factor = max_n * 1.0 / seg.n 242 sampling_kHz = (1e-3 / seg.sampling) * factor 243 seg = qubx.extract.SourceSegResampled(seg, sampling_kHz) 244 xx = arange(seg.n, dtype='float32') 245 xx *= seg.sampling 246 yy = seg.get_samples().samples 247 self.plot.controls.robot.robot_set_data(xx, yy)
248