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

Source Code for Module qubx.hist

  1  """Histograms panel with amplitude histogram. 
  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  from __future__ import with_statement 
 23   
 24  import cStringIO 
 25  import itertools 
 26  import gc 
 27  import os 
 28  import sys 
 29  import time 
 30  import traceback 
 31  import gobject 
 32  import cairo 
 33  import gtk 
 34  import traceback 
 35  import qubx.settings 
 36  import qubx.GTK 
 37  import qubx.pyenv 
 38  import qubx.tree 
 39  import qubx.faces 
 40  import qubx.fit_space 
 41  import qubx.task 
 42  import qubx.dataGTK 
 43  import qubx.notebook 
 44  import qubx.notebookGTK 
 45  import qubx.toolspace 
 46   
 47  from gtk import gdk 
 48  from gtk import keysyms 
 49  from itertools import izip, count 
 50  from qubx.util_types import * 
 51  from qubx.accept import * 
 52  from qubx.GTK import pack_item, pack_space, pack_hsep, pack_vsep, pack_label, pack_button, pack_check, pack_radio, pack_scrolled 
 53  from qubx.settings import Property, Propertied 
 54  from numpy import arange, array, zeros 
 55  from qubx.task import Tasks 
56 57 -class HistRec(Anon):
58 - def __init__(self, caption, nb_caption, bins, bars, pdf=None, components=[], 59 nb_headers=[], nb_xlabel="", nb_ylabel="", 60 data_colorref=qubx.toolspace.COLOR_BLACK, pdf_color=(0,0,0), global_name="", **kw):
61 Anon.__init__(self, caption=caption, nb_caption=nb_caption, bins=bins, bars=bars, pdf=pdf, components=components, 62 nb_headers=nb_headers, nb_xlabel=nb_xlabel, nb_ylabel=nb_ylabel, 63 data_colorref=data_colorref, pdf_color=pdf_color, **kw) 64 self.nbChart = qubx.notebook.NbChart(caption, global_name=global_name, 65 get_caption=lambda: self.nb_caption, 66 get_shape=self.__nb_get_shape, get_headers=self.__nb_get_headers, 67 get_col=self.__nb_get_col, get_type=lambda: float, 68 get_xlabel=lambda: self.nb_xlabel, get_ylabel=lambda: self.nb_ylabel, 69 get_series=self.__nb_get_series)
70 - def __nb_get_shape(self):
71 return (len(self.bins), 2+((not (self.pdf is None)) and 1 or 0)+len(self.components))
72 - def __nb_get_headers(self):
73 Nr, Nc = self.__nb_get_shape() 74 headers = [""] * Nc 75 if not (self.pdf is None): 76 headers[2] = 'pdf' 77 for i,h in enumerate(self.nb_headers): 78 headers[i] = h 79 return headers
80 - def __nb_get_col(self, c):
81 if c == 0: 82 return self.bins 83 if c == 1: 84 return self.bars 85 if (c == 2) and not (self.pdf is None): 86 return self.pdf 87 return self.components[c - 2 - ((not (self.pdf is None)) and 1 or 0)]
88 - def __nb_get_series(self):
89 series = [qubx.notebook.NbChartSeries(0, 1, 0, len(self.bins), qubx.notebook.HISTOGRAM, qubx.toolspace.Appearance.color(self.data_colorref))] 90 if not (self.pdf is None): 91 series.append(qubx.notebook.NbChartSeries(0, 2, 0, len(self.bins), qubx.notebook.LINES, self.pdf_color)) 92 for c, com in enumerate(self.components): 93 series.append(qubx.notebook.NbChartSeries(0, len(series)+1, 0, len(self.bins), qubx.notebook.LINES, (0,0,0), .3)) 94 return series
95
96 -class HistFace(qubx.faces.Face):
97 """ 98 99 Base class for panel showing one or more pages of histograms which are updated on a background thread (robot). 100 101 When the histograms are outdated, call update(). On the worker thread, it will call robot_update(). 102 Communicate the new histogram(s) back to the GUI via gobject.idle_add(). 103 104 @ivar QubX: the top-level L{qubx.express.Cube} object 105 @ivar robot: a worker thread servicing a queue (L{qubx.task.Robot}) 106 @ivar plots: list of L{HistoPlot} displays 107 @ivar plot_count: number of plots showing 108 @ivar page: index of page showing 109 @ivar page_count: number of pages 110 @ivar OnAddPlot: L{WeakEvent}(index) for subclass customization 111 @ivar OnRemovingPlot: L{WeakEvent}(index) 112 @ivar OnChangePage: L{WeakEvent}(index) 113 """ 114 115 __explore_featured = ['robot', 'plots', 'plot_count', 'page', 'page_count', 'OnAddPlot', 'OnRemovingPlot', 'OnChangePage', 116 'sync', 'update_plots', 'robot_update'] 117
118 - def __init__(self, name, global_name=""):
119 """@param name: caption for this panel's tab""" 120 qubx.faces.Face.__init__(self, name, global_name) 121 self.__ref = Reffer() 122 self.set_size_request(100, 70) 123 self.QubX = qubx.pyenv.env.globals['QubX'] 124 self.QubX.OnQuit += self.__ref(lambda: self.robot.stop()) 125 self.robot = qubx.task.Robot(name, self.__ref(lambda: Tasks.add_task(self.robot)), 126 self.__ref(lambda: Tasks.remove_task(self.robot))) 127 self.robot.OnException += self.__ref(self.__onException) 128 self.sync = self.robot.sync 129 self.serial = 0 130 131 self.OnAddPlot = WeakEvent() 132 self.OnRemovingPlot = WeakEvent() 133 self.plots = [] 134 self.plotBox = pack_item(qubx.GTK.AspectGrid(), self, expand=True) 135 136 self.OnChangePage = WeakEvent() 137 self.__page = 0 138 self.__page_count = 1 139 self.__plot_fit = -1 140 self.adjPage = gtk.Adjustment(value=0, lower=0, upper=0, step_incr=1, page_incr=1, page_size=0) 141 self.scroll = pack_item(gtk.HScrollbar(self.adjPage), self, show=False) 142 self.scroll.connect('value_changed', self.__onChangePage) 143 144 self.histrec = [ [] ] 145 self.nbCharts = qubx.notebook.NbItems("All charts", self.global_name and '%s.nbCharts'%self.global_name or '') 146 self.nbPictures = qubx.notebook.NbItems("All pictures", self.global_name and '%s.nbPictures'%self.global_name or '')
147 - def set_page_count(self, n):
148 if self.__page >= n: 149 self.page = n - 1 150 while self.__page_count > n: 151 self.__page_count -= 1 152 while self.__page_count < n: 153 self.__page_count += 1 154 if len(self.histrec) < self.__page_count: 155 self.histrec.append([]) 156 self.adjPage.upper = n - 1 157 self.adjPage.emit('changed') 158 if n <= 1: 159 self.scroll.hide() 160 else: 161 self.scroll.show()
162 page_count = property(lambda self: self.__page_count, lambda self, x: self.set_page_count(x))
163 - def set_page(self, x):
164 if self.__page == x: 165 return 166 self.__page = x 167 self.adjPage.set_value(self.__page) 168 self.OnChangePage(x) 169 self.update_plots()
170 page = property(lambda self: self.__page, lambda self, x: self.set_page(x))
171 - def set_plot_count(self, x):
172 while x < len(self.plots): 173 self.plots[-1].dispose() 174 self.OnRemovingPlot(len(self.plots)-1) 175 del self.nbPictures.items[len(self.plots)-1] 176 if self.__plot_fit == (len(self.plots)-1): 177 self.plots[-1].layerset = self.plots[-1].controlsHidden 178 self.plots[-1].OnChangeLayerset -= self.__ref(self.__onChangeLayerset) 179 if self.__plot_fit == -1: 180 self.plotBox.remove(self.plots[-1]) 181 del self.plots[-1] 182 if len(self.plots) == 1: 183 self.plots[0].subNotebook.items.remove(self.nbCharts) 184 self.plots[0].subNotebook.items.remove(self.nbPictures) 185 while x > len(self.plots): 186 plot = HistoPlot(label=self.face_name, global_name='%s.plots[%i]'%(self.global_name, len(self.plots))) 187 plot.OnChangeLayerset += self.__ref(self.__onChangeLayerset) 188 if len(self.plots) == 1: 189 self.plots[0].subNotebook.items.append(self.nbCharts) 190 self.plots[0].subNotebook.items.append(self.nbPictures) 191 plot.subNotebook.items.append(self.nbCharts) 192 plot.subNotebook.items.append(self.nbPictures) 193 self.plots.append(plot) 194 plot.show() 195 if (self.__plot_fit == -1): 196 self.plotBox.pack_aspect(plot) 197 self.OnAddPlot(len(self.plots)-1) 198 try: 199 self.nbPictures.items.insert(len(self.plots)-1, plot.nbPicture) 200 except: 201 self.nbPictures.items.insert(len(self.plots)-1, None)
202 plot_count = property(lambda self: len(self.plots), lambda self, x: self.set_plot_count(x))
203 - def __onChangeLayerset(self, plot, layerset):
204 if layerset == plot.controlsHidden: 205 self.plotBox.remove(plot) 206 for p in self.plots: 207 self.plotBox.pack_aspect(p) 208 self.__plot_fit = -1 209 else: 210 for p in self.plots: 211 self.plotBox.remove(p) 212 self.plotBox.pack_aspect(plot) 213 self.__plot_fit = self.plots.index(plot)
214
215 - def update_plots(self):
216 """Re-render all plots from self.histrec[self.page].""" 217 if not self.page_count: return 218 hists = self.histrec[self.page] 219 self.plot_count = len(hists) 220 for h, hist in enumerate(hists): 221 self.plots[h].set_rec(hist) 222 223 # also re-gen list of all charts 224 items = [] 225 for hists in self.histrec: 226 for hist in hists: 227 items.append(hist.nbChart) 228 self.nbCharts.items[:] = items 229 230 self.OnChangePage(self.__page)
231 - def onShow(self, showing):
232 self.update()
233 - def __onChangePage(self, scroll):
234 self.page = int(self.adjPage.value)
235 - def __onException(self, robot, typ, val, trace):
236 traceback.print_exception(typ, val, trace)
237 - def update(self, force=False):
238 """Requests that robot_update() be called in the robot thread.""" 239 self.serial += 1 240 if self.showing or force: 241 self.robot.do(self.robot_try_update, self.serial)
242 - def robot_try_update(self, serial):
243 """In robot thread, filters out duplicate (stale serial) requests and calls robot_update()""" 244 # if there's a newer update, wait for that request to come around and proc all at once 245 if serial == self.serial: 246 self.robot_update()
247 - def robot_update(self):
248 """Override this method to calculate something in the robot thread.""" 249 pass
250
251 -class DataHistFace(HistFace):
252 """Base class for a histogram panel which updates when the sampled data source changes.""" 253 __explore_featured = ['on_change_data']
254 - def __init__(self, name, global_name=""):
255 HistFace.__init__(self, name, global_name) 256 self.__ref = Reffer() 257 self.dataSource = self.QubX.DataSource 258 self.dataSource.OnChangeSamples += self.__ref(self.__onChangeData), 'Histograms.onChangeData' 259 gobject.idle_add(self.__onChangeData)
260 - def __onChangeData(self, *args):
261 self.on_change_data()
262 - def on_change_data(self):
263 """Override this method to do something when the sampled data changes.""" 264 pass
265 266 267 @Propertied(Property('bins', 128, "number of bins"), 268 Property('auto', True, "False to manually set lo and hi bounds"), 269 Property('lo', 0.0, "left bound"), 270 Property('hi', 1.0, 'right bound'), 271 Property('multi_file', False, 'True to work on a Group of files'), 272 Property('multi_file_group', 0, 'multi_file: work on Data table entries with this Group number') 273 )
274 -class AmpHistFace(DataHistFace):
275 """Panel showing the all-points amplitude histogram of one signal. 276 277 @ivar signal: signal (channel) index, 1-based 278 @ivar controls: L{qubx.faces.Face} with settings, to go in QubX.About 279 @ivar path: last save-as location 280 """ 281 282 __explore_featured = ['controls', 'path', 'copy_to_clipboard', 'copy_image_to_clipboard', 'save_to'] 283
284 - def __init__(self, name='AmpHist', global_name=""):
285 DataHistFace.__init__(self, name, global_name) 286 self.propertied_connect_settings('AmpHist') 287 self.controls = qubx.faces.Face("AmpHist", global_name='QubX.About.AmpHist') 288 self.controls.set_size_request(100, 100) 289 self.controls.show() 290 line = pack_item(gtk.HBox(True), self.controls) 291 pack_label('Bins:', line) 292 self.txtBins = pack_item(qubx.GTK.NumEntry(self.bins, acceptIntGreaterThan(1)), line) 293 self.propertied_connect_NumEntry('bins', self.txtBins) 294 line = pack_item(gtk.HBox(), self.controls) 295 self.chkAuto = pack_check('auto', line) 296 self.propertied_connect_check('auto', self.chkAuto) 297 pack_label('lo:', line) 298 self.txtLo = pack_item(qubx.GTK.NumEntry(self.lo, width_chars=4), line) 299 self.propertied_connect_NumEntry('lo', self.txtLo) 300 pack_label('hi:', line) 301 self.txtHi = pack_item(qubx.GTK.NumEntry(self.hi, width_chars=4), line) 302 self.propertied_connect_NumEntry('hi', self.txtHi) 303 line = pack_item(gtk.HBox(), self.controls) 304 self.chkMulti = pack_check('Multi-file: Group', line) 305 self.propertied_connect_check('multi_file', self.chkMulti) 306 self.txtGroup = pack_item(qubx.GTK.NumEntry(self.multi_file_group, acceptInt, width_chars=4), line) 307 self.propertied_connect_NumEntry('multi_file_group', self.txtGroup) 308 line = pack_item(gtk.HBox(), self.controls) 309 self.btnSave = pack_button('Save...', line, on_click=self.__onClickSave) 310 self.btnCopy = pack_button('Copy', line, on_click=self.__onClickCopy) 311 self.btnCopyImage = pack_button('Image...', line, on_click=self.__onClickCopyImage) 312 self.plot_count = 1 313 self.path = None
314 - def propertied_set(self, value, name):
315 super(AmpHistFace, self).propertied_set(value, name) 316 if name in ('bins', 'multi_file'): 317 self.on_change_data() 318 elif name == 'auto': 319 if value: 320 self.update() 321 elif name in ('lo', 'hi'): 322 self.update() 323 elif self.multi_file and (name == 'multi_file_group'): 324 self.on_change_data()
325 - def __onClickSave(self, btn):
326 dlg = gtk.FileChooserDialog('Save as...', None, gtk.FILE_CHOOSER_ACTION_SAVE, 327 buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) 328 dlg.set_default_response(gtk.RESPONSE_OK) 329 filter = gtk.FileFilter() 330 filter.set_name("text files") 331 filter.add_pattern("*.txt") 332 dlg.add_filter(filter) 333 if self.path: dlg.set_current_folder(self.path) 334 dlg.set_filename('AmpHist ') 335 response = dlg.run() 336 if response == gtk.RESPONSE_OK: 337 try: 338 fname = add_ext_if_none(dlg.get_filename(), '.txt') 339 if self.global_name: 340 qubx.pyenv.env.scriptable_if_matching('%s.save_to(open(%s, "w"))' % (self.global_name, repr(fname)), 341 [(self.global_name, self)]) 342 self.save_to(open(fname, 'w')) 343 except Exception, e: 344 print "Saving %s: %s" % (fname, e) 345 self.path = dlg.get_current_folder() 346 dlg.destroy()
347 - def __onClickCopy(self, btn):
348 if self.global_name: 349 qubx.pyenv.env.scriptable_if_matching('%s.copy_to_clipboard()' % self.global_name, 350 [(self.global_name, self)]) 351 self.copy_to_clipboard()
352 - def copy_to_clipboard(self):
353 buf = cStringIO.StringIO() 354 self.save_to(buf) 355 gtk.clipboard_get('CLIPBOARD').set_text(buf.getvalue())
356 - def __onClickCopyImage(self, btn):
357 if gtk.RESPONSE_ACCEPT == TheAmpHistCopyDialog.run(self.plots[0]): 358 w = TheAmpHistCopyDialog.copy_width 359 h = TheAmpHistCopyDialog.copy_height 360 if self.global_name: 361 qubx.pyenv.env.scriptable_if_matching('%s.copy_image_to_clipboard(%s, %s)' % 362 (self.global_name, repr(w), repr(h)), 363 [(self.global_name, self)]) 364 self.copy_image_to_clipboard(w, h)
365 - def copy_image_to_clipboard(self, w, h):
366 pixmap = gdk.Pixmap(self.window, w, h, -1) 367 ctx = pixmap.cairo_create() 368 ctx.set_source_rgb(1,1,1) 369 ctx.paint() 370 self.plots[0].draw_to_context(ctx, w, h) 371 del ctx 372 pixbuf = gdk.Pixbuf(gdk.COLORSPACE_RGB, False, 8, w, h) 373 pixbuf.get_from_drawable(pixmap, gdk.colormap_get_system(), 0, 0, 0, 0, -1, -1) 374 clipboard = gtk.clipboard_get('CLIPBOARD') 375 clipboard.set_image(pixbuf) 376 del pixmap 377 del pixbuf 378 qubx.pyenv.env.gc_collect_on_idle() 379 self.plots[0].redraw_canvas() # re-calculate geometry for mouse
380 - def onShow(self, showing):
381 DataHistFace.onShow(self, showing) 382 if showing: 383 self.QubX.About.append_face(self.controls) 384 self.QubX.About.show_face('AmpHist') 385 else: 386 self.QubX.About.remove_face( self.QubX.About.index('AmpHist') )
387 - def save_to(self, f):
388 """Writes the histogram as tab-separated text to a.file-like object""" 389 f.write(self.plots[0].nbChart.to_txt())
390 - def on_change_data(self):
391 """Determines if update() is needed""" 392 if self.QubX.Data.view: 393 self.update()
394 # self.robot.interrupt() # hangs everything, once in a blue moon
395 - def robot_update(self):
396 """Calculates a new amp hist.""" 397 with self.robot.main_hold: 398 if self.multi_file: 399 segs = [] 400 for v, ss in self.QubX.DataSource.get_segmentation_files(group=self.multi_file_group): 401 segs.extend(ss) 402 else: 403 segs = self.dataSource.get_segmentation() 404 n = sum(seg.n for seg in segs) 405 auto, lo, hi = self.auto, self.lo, self.hi 406 if n == 0: return 407 finished = 0 408 if auto: 409 lo, hi = 1e30, -1e30 410 for seg in segs: 411 for chunk in self.dataSource.gen_samples(seg.chunks, self.robot.main_hold): 412 if chunk.included: 413 lo = min(lo, min(chunk.samples)) 414 hi = max(hi, max(chunk.samples)) 415 finished += len(chunk.samples) 416 self.robot.progress = finished * 50.0 / n 417 if lo != self.lo: 418 gobject.idle_add(self.propertied_set, lo, 'lo') 419 if hi != self.hi: 420 gobject.idle_add(self.propertied_set, hi, 'hi') 421 else: 422 self.robot.progress = 50.0 423 if lo >= hi: return 424 bins, binw = make_bins(lo, hi, self.bins) 425 bars = zeros(shape=(self.bins,)) 426 one = 1.0 / n 427 last = self.bins-1 428 finished = 0 429 for seg in segs: 430 for chunk in self.dataSource.gen_samples(seg.chunks, self.robot.main_hold): 431 if chunk.included: 432 samples = array(chunk.samples[(lo <= chunk.samples) & (chunk.samples <= hi)]) 433 samples -= lo # - binw/2 434 samples /= binw 435 samples = samples.astype('int32') 436 samples[samples == self.bins] = self.bins-1 437 for x in xrange(len(bins)): 438 bars[x] += one * len(samples[samples == x]) 439 finished += chunk.n 440 self.robot.progress = 50.0 + finished * 50.0 / n 441 with self.robot.main_hold: 442 self.histrec[0][:] = [HistRec('All-points amplitude histogram of %s'%segs[0].file.signals.get(segs[0].signal, 'Name'), 443 'AmpHist', bins, bars, nb_headers=['bin_mid', 'count / n'], 444 nb_xlabel='bin_mid', nb_ylabel='count / n')] 445 gobject.idle_add(self.update_plots)
446
447 -def make_bins(lo, hi, n):
448 """Returns (bins, bin_width) as (numpy.array[n], float).""" 449 d = (hi - lo) 450 one = d/n 451 bins = arange(n, dtype='float64') 452 bins *= one 453 bins += lo + one/2 454 return bins, one
455
456 457 -class HistoPlot(qubx.fit_space.FitSpace):
458 """ 459 fit_space for a histogram 460 """
461 - def __init__(self, bins=[], bars=[], caption="", label="Hist", **kw):
462 """ 463 @param bins: array of upper bounds 464 @param bars: array of count/total 465 """ 466 qubx.fit_space.FitSpace.__init__(self, label=label, **kw) 467 self.draw_hist = True 468 self.layerset = self.controlsHidden 469 self.caption = caption 470 self.set_size_request(40, 40) 471 self.lines = [] 472 self.__ref = Reffer() 473 self.OnOverlay += self.__ref(self._onOverlay) 474 self.OnChangeLayerset += self.__ref(self.__onChangeLayerset) 475 self.controls.robot.OnExpr += self.__ref(self.__onExpr) 476 self.controls.robot.OnParam += self.__ref(self.__onParam) 477 self.controls.robot.OnStats += self.__ref(self.__onStats) 478 self.controls.robot.OnIteration += self.__ref(self.__onIteration) 479 self.controls.robot.OnEndFit += self.__ref(self.__onEndFit) 480 self.layNotebook = qubx.toolspace.Layer(x=1, y=-5.5-qubx.fit_space.LINE_EMS, w=2, h=2, cBG=qubx.toolspace.COLOR_CLEAR) 481 self.subNotebook = qubx.notebookGTK.SubLayer_Notebook(x=0, y=0, w=2, h=2) 482 self.layNotebook.add_sublayer(self.subNotebook) 483 self.add_layer(self.layNotebook) 484 self.nbChartGiven = qubx.notebook.NbItems('Chart', '') 485 self.nbChartFit = qubx.notebook.NbChart('Chart', '', lambda: self.caption, 486 self.controls.nb_get_shape, self.controls.nb_get_headers, 487 get_col=self.controls.nb_get_col, get_type=lambda: float, 488 get_series=self.nb_get_series) 489 self.nbChart = self.nbChartGiven 490 self.subNotebook.items.append(self.nbChart) 491 self.nbPicture = qubx.notebookGTK.NbPicture('Picture', '', self.nb_picture_get_shape, 492 self.nb_picture_draw) 493 self.subNotebook.items.append(self.nbPicture) 494 self.nbParams = qubx.notebook.NbDynText('Parameters', '', self.controls.nb_get_param_text) 495 self.nbParams.std_err_est = None 496 self.subNotebook.items.append(self.nbParams) 497 qubx.notebook.Notebook.register_auto('%s.Parameters'%label, '%s Parameters, on Fit'%label, True) 498 qubx.notebook.Notebook.register_auto('%s.Results'%label, '%s Results, on Fit'%label, True) 499 qubx.notebook.Notebook.register_auto('%s.Chart'%label, '%s Chart, on Fit'%label) 500 qubx.notebook.Notebook.register_auto('%s.Picture'%label, '%s Picture, on Fit'%label, True) 501 self.__nb_next_stats = False 502 self.global_name = self.global_name # update nb*.global_name 503 self.set_data(bins, bars)
504 - def set_data(self, bins, bars):
505 self.bins = array(bins, copy=True) 506 self.bars = array(bars, copy=True) 507 self.pdf = None 508 self.components = [] 509 self.controls.robot.set_data(bins, bars)
510 - def set_global_name(self, x):
511 qubx.fit_space.FitSpace.set_global_name(self, x) 512 self.nbChartGiven.global_name = '%s.nbChart'%x 513 self.nbChartFit.global_name = '%s.nbChart'%x 514 self.nbPicture.global_name = '%s.nbPicture'%x 515 self.nbParams.global_name = '%s.nbParams'%x
516 - def _onOverlay(self, context, w, h):
517 self._dim = (w, h) 518 if self.layerset == self.controls: 519 return 520 for c in self.components: 521 context.set_source_rgba(*self.appearance.color(self.cBG)) 522 context.set_line_width(0.2*self.appearance.emsize * self.appearance.line_width + 0.15 * self.appearance.emsize) 523 qubx.fit_space.draw_line(context, self.appearance, self.bins, c, self.t2x, self.d2y, 0.0) 524 context.set_source_rgba(.5,.5,.5,.8) 525 context.set_line_width(0.2*self.appearance.emsize * self.appearance.line_width) 526 qubx.fit_space.draw_line(context, self.appearance, self.bins, c, self.t2x, self.d2y, 0.0) 527 if not (self.pdf is None): 528 context.set_source_rgba(*self.appearance.color(self.cBG)) 529 context.set_line_width(0.6*self.appearance.emsize * self.appearance.line_width + 0.2*self.appearance.emsize) 530 qubx.fit_space.draw_line(context, self.appearance, self.bins, self.pdf, self.t2x, self.d2y, 0.0) 531 context.set_source_rgba(*(list(self.dataColor2)+[.6])) 532 context.set_line_width(0.6*self.appearance.emsize * self.appearance.line_width) 533 qubx.fit_space.draw_line(context, self.appearance, self.bins, self.pdf, self.t2x, self.d2y, 0.0)
534 - def set_pdf(self, pdf, components):
535 """Sets the pdf and its components (fit curves). 536 @param pdf: numpy.array with sum fit curve 537 @param components: list of numpy arrays with partial fit curves 538 """ 539 self.pdf = pdf 540 self.components = components 541 self.draw_fit_when_hidden = False 542 self.redraw_canvas()
543 - def set_rec(self, rec):
544 self.caption = rec.caption 545 self.cData = rec.data_colorref 546 self.dataColor2 = rec.pdf_color 547 self.set_data(rec.bins, rec.bars) 548 self.draw_fit_when_hidden = True 549 if (not (rec.pdf is None)) and (len(rec.pdf)): 550 self.set_pdf(rec.pdf, rec.components) 551 self.nbChartGiven.items[:] = [rec.nbChart] 552 self.__onChangeLayerset(self, self.layerset)
553 - def __onChangeLayerset(self, selfy, layerset):
554 if (layerset == self.controlsHidden) and not (self.pdf is None): 555 self.nbChart = self.nbChartGiven 556 else: 557 self.nbChart = self.nbChartFit 558 self.subNotebook.items[0] = self.nbChart
559 - def __onExpr(self, curve_name, expr, params, param_vals, lo, hi, can_fit):
560 self.__param_names = params 561 self.__param_vals = param_vals 562 self.__param_active = can_fit
563 - def __onParam(self, index, name, value, lo, hi, can_fit):
564 self.__param_names[index] = name # paranoid? 565 self.__param_vals[index] = value 566 self.__param_active[index] = can_fit
567 - def __onIteration(self, param_vals, iteration):
568 self.__param_vals = param_vals
569 - def __onEndFit(self):
570 self.__nb_next_stats = True
571 - def __onStats(self, correlation, is_pseudo, std_err_est, ssr, r2, runs_prob):
572 if self.__nb_next_stats: 573 self.__nb_next_stats = False 574 label = self.label 575 n = len(self.bins) 576 qubx.notebook.Notebook.send(qubx.notebook.NbText("""%(label)s finished. 577 \tN: %(n)i 578 \tSSR: %(ssr).6g 579 \tR^2: %(r2).6g 580 \tWald-Wolfowitz runs probability: %(runs_prob).6g 581 \tCorrelation: 582 %(correlation)s 583 """ % locals()), auto_id='%s.Results'%label) 584 self.nbParams.std_err_est = std_err_est 585 qubx.notebook.Notebook.send(self.nbParams, auto_id='%s.Parameters'%label) 586 qubx.notebook.Notebook.send(self.nbChart, auto_id='%s.Chart'%label) 587 qubx.notebook.Notebook.send(self.nbPicture, auto_id='%s.Picture'%label) 588 self.nbParams.std_err_est = None
589 590 591 TheAmpHistCopyDialog = qubx.GTK.CopyDialog('Copy histogram image') # L{qubx.GTK.CopyDialog} 592