Changeset 9687d58 in sasview for src/sas/sasgui/guiframe/local_perspectives
- Timestamp:
- Apr 10, 2017 4:01:46 AM (8 years ago)
- Branches:
- ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
- Children:
- 6c8fb2c
- Parents:
- 9208346 (diff), c6f3aec (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - Location:
- src/sas/sasgui/guiframe/local_perspectives/plotting
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter1D.py
r5bcb6a9 r9687d58 65 65 # context menu 66 66 self._slicerpop = None 67 68 67 self._available_data = [] 69 68 self._symbol_labels = self.get_symbol_label() … … 95 94 self.parent.SetFocus() 96 95 96 # If true, there are 3 qrange bars 97 self.is_corfunc = False 98 97 99 98 100 def get_symbol_label(self): … … 214 216 if active_ctrl == None: 215 217 return 218 if hasattr(event, 'is_corfunc'): 219 self.is_corfunc = event.is_corfunc 216 220 if event.id in self.plots.keys(): 217 221 ctrl = event.ctrl … … 222 226 values = [max(x_data.min(), float(ctrl[0].GetValue())), 223 227 min(x_data.max(), float(ctrl[1].GetValue()))] 228 if len(ctrl) == 3: 229 colors.append('purple') 230 values.append(min(x_data.max(), float(ctrl[2].GetValue()))) 224 231 if self.ly == None: 225 232 self.ly = [] … … 232 239 xval = float(active_ctrl.GetValue()) 233 240 position = self.get_data_xy_vals(xval) 234 if position != None :241 if position != None and not self.is_corfunc: 235 242 wx.PostEvent(self.parent, StatusEvent(status=position)) 236 243 except: … … 293 300 ly0x = ly[0].get_xdata() 294 301 ly1x = ly[1].get_xdata() 302 ly2x = None 303 if self.is_corfunc: ly2x = ly[2].get_xdata() 295 304 self.q_ctrl[0].SetBackgroundColour('white') 296 305 self.q_ctrl[1].SetBackgroundColour('white') … … 306 315 self.q_ctrl[0].SetValue(str(pos_x)) 307 316 self.q_ctrl[1].SetBackgroundColour('pink') 317 elif ly2x is not None and ly1x >= ly2x: 318 if self.vl_ind == 1: 319 ly[2].set_xdata(posx) 320 ly[2].set_zorder(nop) 321 self.q_ctrl[2].SetValue(str(pos_x)) 322 elif self.vl_ind == 2: 323 ly[1].set_xdata(posx) 324 ly[1].set_zorder(nop) 325 self.q_ctrl[1].SetValue(str(pos_x)) 326 308 327 309 328 def _get_cusor_lines(self, event): … … 325 344 dqmin = math.fabs(event.xdata - self.ly[0].get_xdata()) 326 345 dqmax = math.fabs(event.xdata - self.ly[1].get_xdata()) 327 is_qmax = dqmin > dqmax 328 if is_qmax: 329 self.vl_ind = 1 346 if not self.is_corfunc: 347 is_qmax = dqmin > dqmax 348 if is_qmax: 349 self.vl_ind = 1 350 else: 351 self.vl_ind = 0 330 352 else: 331 self.vl_ind = 0 353 dqmax2 = math.fabs(event.xdata - self.ly[2].get_xdata()) 354 closest = min(dqmin, dqmax, dqmax2) 355 self.vl_ind = { dqmin: 0, dqmax: 1, dqmax2: 2 }.get(closest) 332 356 333 357 def cusor_line(self, event): -
src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter2D.py
r2d647cf rb2b36932 316 316 317 317 slicerpop.AppendSeparator() 318 if len(self.data2D.detector) == 1:318 if len(self.data2D.detector) <= 1: 319 319 item_list = self.parent.get_current_context_menu(self) 320 320 if (not item_list == None) and (not len(item_list) == 0) and\ -
src/sas/sasgui/guiframe/local_perspectives/plotting/plotting.py
rd85c194 r6ffa0dd 16 16 from sas.sasgui.guiframe.events import EVT_NEW_PLOT 17 17 from sas.sasgui.guiframe.events import EVT_PLOT_QRANGE 18 from sas.sasgui.guiframe.events import EVT_PLOT_LIM 18 19 from sas.sasgui.guiframe.events import DeletePlotPanelEvent 19 20 from sas.sasgui.guiframe.plugin_base import PluginBase … … 79 80 self.parent.Bind(EVT_NEW_PLOT, self._on_plot_event) 80 81 self.parent.Bind(EVT_PLOT_QRANGE, self._on_plot_qrange) 82 self.parent.Bind(EVT_PLOT_LIM, self._on_plot_lim) 81 83 # We have no initial panels for this plug-in 82 84 return [] … … 95 97 return 96 98 panel.on_plot_qrange(event) 99 100 def _on_plot_lim(self, event=None): 101 if event == None: 102 return 103 if event.id in self.plot_panels.keys(): 104 panel = self.plot_panels[event.id] 105 elif event.group_id in self.plot_panels.keys(): 106 panel = self.plot_panels[event.group_id] 107 else: 108 return 109 if hasattr(event, 'xlim'): 110 panel.subplot.set_xlim(event.xlim) 111 if hasattr(event, 'ylim'): 112 panel.subplot.set_ylim(event.ylim) 113 97 114 98 115 def _on_show_panel(self, event): … … 312 329 new_panel = self.create_2d_panel(data, group_id) 313 330 self.create_panel_helper(new_panel, data, group_id, title) 331 if hasattr(event, 'xlim'): 332 new_panel.subplot.set_xlim(event.xlim) 333 if hasattr(event, 'ylim'): 334 new_panel.subplot.set_ylim(event.ylim) 314 335 return -
src/sas/sasgui/guiframe/local_perspectives/plotting/AnnulusSlicer.py
rd85c194 r116260a 1 # TODO: the line slicer should listen to all 2DREFRESH events, get the data and slice it 2 # before pushing a new 1D data update. 3 4 # 5 # TODO: NEED MAJOR REFACTOR 6 # 7 8 import math 9 import wx 10 # from copy import deepcopy 11 # Debug printout 12 from sas.sasgui.guiframe.events import NewPlotEvent 13 from sas.sasgui.guiframe.events import StatusEvent 14 from sas.sasgui.guiframe.events import SlicerParameterEvent 15 from sas.sasgui.guiframe.events import EVT_SLICER_PARS 1 import numpy 2 from PyQt4 import QtGui 3 from PyQt4 import QtCore 4 16 5 from BaseInteractor import _BaseInteractor 17 6 from sas.sasgui.guiframe.dataFitting import Data1D 18 19 class AnnulusInteractor(_BaseInteractor): 7 import sas.qtgui.GuiUtils as GuiUtils 8 from sas.qtgui.GuiUtils import formatNumber 9 from sas.qtgui.SlicerModel import SlicerModel 10 11 class AnnulusInteractor(_BaseInteractor, SlicerModel): 20 12 """ 21 13 Select an annulus through a 2D plot. … … 24 16 this class is defined by 2 Ringinterators. 25 17 """ 26 def __init__(self, base, axes, color='black', zorder=3):18 def __init__(self, base, axes, item=None, color='black', zorder=3): 27 19 28 20 _BaseInteractor.__init__(self, base, axes, color=color) 21 SlicerModel.__init__(self) 22 29 23 self.markers = [] 30 24 self.axes = axes 31 25 self.base = base 32 self.qmax = min(math.fabs(self.base.data2D.xmax), 33 math.fabs(self.base.data2D.xmin)) # must be positive 26 self._item = item 27 self.qmax = min(numpy.fabs(self.base.data.xmax), 28 numpy.fabs(self.base.data.xmin)) # must be positive 34 29 self.connect = self.base.connect 35 30 36 # #Number of points on the plot31 # Number of points on the plot 37 32 self.nbins = 36 38 33 # Cursor position of Rings (Left(-1) or Right(1)) 39 self.xmaxd = self.base.data 2D.xmax40 self.xmind = self.base.data 2D.xmin34 self.xmaxd = self.base.data.xmax 35 self.xmind = self.base.data.xmin 41 36 42 37 if (self.xmaxd + self.xmind) > 0: … … 45 40 self.sign = -1 46 41 # Inner circle 47 self.inner_circle = RingInteractor(self, self. base.subplot,42 self.inner_circle = RingInteractor(self, self.axes, 48 43 zorder=zorder, 49 44 r=self.qmax / 2.0, sign=self.sign) 50 45 self.inner_circle.qmax = self.qmax 51 self.outer_circle = RingInteractor(self, self. base.subplot,46 self.outer_circle = RingInteractor(self, self.axes, 52 47 zorder=zorder + 1, r=self.qmax / 1.8, 53 48 sign=self.sign) … … 56 51 self._post_data() 57 52 58 # Bind to slice parameter events 59 self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) 60 61 def _onEVT_SLICER_PARS(self, event): 62 """ 63 receive an event containing parameters values to reset the slicer 64 65 :param event: event of type SlicerParameterEvent with params as 66 attribute 67 68 """ 69 wx.PostEvent(self.base, 70 StatusEvent(status="AnnulusSlicer._onEVT_SLICER_PARS")) 71 event.Skip() 72 if event.type == self.__class__.__name__: 73 self.set_params(event.params) 74 self.base.update() 53 self.setModelFromParams() 75 54 76 55 def set_layer(self, n): … … 92 71 self.inner_circle.clear() 93 72 self.base.connect.clearall() 94 self.base.Unbind(EVT_SLICER_PARS)95 73 96 74 def update(self): … … 108 86 can restore on Esc. 109 87 """ 110 self.base.freeze_axes()111 88 self.inner_circle.save(ev) 112 89 self.outer_circle.save(ev) … … 120 97 """ 121 98 # Data to average 122 data = self.base.data2D 123 # If we have no data, just return 124 if data == None: 99 data = self.base.data 100 if data is None: 125 101 return 126 102 127 103 from sas.sascalc.dataloader.manipulations import Ring 128 rmin = min( math.fabs(self.inner_circle.get_radius()),129 math.fabs(self.outer_circle.get_radius()))130 rmax = max( math.fabs(self.inner_circle.get_radius()),131 math.fabs(self.outer_circle.get_radius()))132 # if the user does not specify the numbers of points to plot104 rmin = min(numpy.fabs(self.inner_circle.get_radius()), 105 numpy.fabs(self.outer_circle.get_radius())) 106 rmax = max(numpy.fabs(self.inner_circle.get_radius()), 107 numpy.fabs(self.outer_circle.get_radius())) 108 # If the user does not specify the numbers of points to plot 133 109 # the default number will be nbins= 36 134 if nbins ==None:110 if nbins is None: 135 111 self.nbins = 36 136 112 else: 137 113 self.nbins = nbins 138 # # create the data1D Q average of data2D114 # Create the data1D Q average of data2D 139 115 sect = Ring(r_min=rmin, r_max=rmax, nbins=self.nbins) 140 sector = sect(self.base.data 2D)116 sector = sect(self.base.data) 141 117 142 118 if hasattr(sector, "dxl"): … … 148 124 else: 149 125 dxw = None 150 new_plot = Data1D(x=(sector.x - math.pi) * 180 / math.pi,126 new_plot = Data1D(x=(sector.x - numpy.pi) * 180 / numpy.pi, 151 127 y=sector.y, dy=sector.dy) 152 128 new_plot.dxl = dxl 153 129 new_plot.dxw = dxw 154 new_plot.name = "AnnulusPhi" + "(" + self.base.data 2D.name + ")"155 156 new_plot.source = self.base.data2D.source 157 # new_plot.info=self.base.data2D.info130 new_plot.name = "AnnulusPhi" + "(" + self.base.data.name + ")" 131 new_plot.title = "AnnulusPhi" + "(" + self.base.data.name + ")" 132 133 new_plot.source = self.base.data.source 158 134 new_plot.interactive = True 159 new_plot.detector = self.base.data 2D.detector135 new_plot.detector = self.base.data.detector 160 136 # If the data file does not tell us what the axes are, just assume... 161 137 new_plot.xaxis("\\rm{\phi}", 'degrees') 162 138 new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}") 163 139 if hasattr(data, "scale") and data.scale == 'linear' and \ 164 self.base.data 2D.name.count("Residuals") > 0:140 self.base.data.name.count("Residuals") > 0: 165 141 new_plot.ytransform = 'y' 166 142 new_plot.yaxis("\\rm{Residuals} ", "/") 167 143 168 new_plot.group_id = "AnnulusPhi" + self.base.data 2D.name169 new_plot.id = "AnnulusPhi" + self.base.data 2D.name144 new_plot.group_id = "AnnulusPhi" + self.base.data.name 145 new_plot.id = "AnnulusPhi" + self.base.data.name 170 146 new_plot.is_data = True 171 147 new_plot.xtransform = "x" 172 148 new_plot.ytransform = "y" 173 self.base.parent.update_theory(data_id=data.id, theory=new_plot) 174 wx.PostEvent(self.base.parent, NewPlotEvent(plot=new_plot, title="AnnulusPhi")) 149 variant_plot = QtCore.QVariant(new_plot) 150 GuiUtils.updateModelItemWithPlot(self._item, variant_plot, new_plot.id) 151 self.base.manager.communicator.plotUpdateSignal.emit([new_plot]) 152 153 if self.update_model: 154 self.setModelFromParams() 155 self.draw() 156 157 def validate(self, param_name, param_value): 158 """ 159 Test the proposed new value "value" for row "row" of parameters 160 """ 161 MIN_DIFFERENCE = 0.01 162 isValid = True 163 164 if param_name == 'inner_radius': 165 # First, check the closeness 166 if numpy.fabs(param_value - self.getParams()['outer_radius']) < MIN_DIFFERENCE: 167 print("Inner and outer radii too close. Please adjust.") 168 isValid = False 169 elif param_value > self.qmax: 170 print("Inner radius exceeds maximum range. Please adjust.") 171 isValid = False 172 elif param_name == 'outer_radius': 173 # First, check the closeness 174 if numpy.fabs(param_value - self.getParams()['inner_radius']) < MIN_DIFFERENCE: 175 print("Inner and outer radii too close. Please adjust.") 176 isValid = False 177 elif param_value > self.qmax: 178 print("Outer radius exceeds maximum range. Please adjust.") 179 isValid = False 180 elif param_name == 'nbins': 181 # Can't be 0 182 if param_value < 1: 183 print("Number of bins cannot be less than or equal to 0. Please adjust.") 184 isValid = False 185 186 return isValid 175 187 176 188 def moveend(self, ev): 177 189 """ 178 190 Called when any dragging motion ends. 179 Post an event (type =SlicerParameterEvent) 180 to plotter 2D with a copy slicer parameters 181 Call _post_data method 182 """ 183 self.base.thaw_axes() 184 # Post parameters to plotter 2D 185 event = SlicerParameterEvent() 186 event.type = self.__class__.__name__ 187 event.params = self.get_params() 188 wx.PostEvent(self.base, event) 191 Redraw the plot with new parameters. 192 """ 193 self._post_data(self.nbins) 189 194 190 195 def restore(self): … … 204 209 pass 205 210 206 def get _params(self):211 def getParams(self): 207 212 """ 208 213 Store a copy of values of parameters of the slicer into a dictionary. 209 210 214 :return params: the dictionary created 211 212 215 """ 213 216 params = {} 214 params["inner_radius"] = math.fabs(self.inner_circle._inner_mouse_x)215 params["outer_radius"] = math.fabs(self.outer_circle._inner_mouse_x)217 params["inner_radius"] = numpy.fabs(self.inner_circle._inner_mouse_x) 218 params["outer_radius"] = numpy.fabs(self.outer_circle._inner_mouse_x) 216 219 params["nbins"] = self.nbins 217 220 return params 218 221 219 def set _params(self, params):222 def setParams(self, params): 220 223 """ 221 224 Receive a dictionary and reset the slicer with values contained … … 224 227 :param params: a dictionary containing name of slicer parameters and 225 228 values the user assigned to the slicer. 226 227 """ 228 inner = math.fabs(params["inner_radius"]) 229 outer = math.fabs(params["outer_radius"]) 229 """ 230 inner = numpy.fabs(params["inner_radius"]) 231 outer = numpy.fabs(params["outer_radius"]) 230 232 self.nbins = int(params["nbins"]) 231 # #Update the picture233 # Update the picture 232 234 self.inner_circle.set_cursor(inner, self.inner_circle._inner_mouse_y) 233 235 self.outer_circle.set_cursor(outer, self.outer_circle._inner_mouse_y) 234 # #Post the data given the nbins entered by the user236 # Post the data given the nbins entered by the user 235 237 self._post_data(self.nbins) 236 237 def freeze_axes(self):238 """239 """240 self.base.freeze_axes()241 242 def thaw_axes(self):243 """244 """245 self.base.thaw_axes()246 238 247 239 def draw(self): … … 278 270 self.sign = sign 279 271 # # Create a marker 280 try: 281 # Inner circle marker 282 x_value = [self.sign * math.fabs(self._inner_mouse_x)] 283 self.inner_marker = self.axes.plot(x_value, [0], linestyle='', 284 marker='s', markersize=10, 285 color=self.color, alpha=0.6, 286 pickradius=5, label="pick", 287 zorder=zorder, 288 visible=True)[0] 289 except: 290 x_value = [self.sign * math.fabs(self._inner_mouse_x)] 291 self.inner_marker = self.axes.plot(x_value, [0], linestyle='', 292 marker='s', markersize=10, 293 color=self.color, alpha=0.6, 294 label="pick", 295 visible=True)[0] 296 message = "\nTHIS PROTOTYPE NEEDS THE LATEST" 297 message += " VERSION OF MATPLOTLIB\n" 298 message += "Get the SVN version that is at " 299 message += " least as recent as June 1, 2007" 300 301 owner = self.base.base.parent 302 wx.PostEvent(owner, StatusEvent(status="AnnulusSlicer: %s" % message)) 303 272 # Inner circle marker 273 x_value = [self.sign * numpy.fabs(self._inner_mouse_x)] 274 self.inner_marker = self.axes.plot(x_value, [0], linestyle='', 275 marker='s', markersize=10, 276 color=self.color, alpha=0.6, 277 pickradius=5, label="pick", 278 zorder=zorder, 279 visible=True)[0] 304 280 # Draw a circle 305 281 [self.inner_circle] = self.axes.plot([], [], linestyle='-', marker='', color=self.color) 306 # the number of points that make the ring line282 # The number of points that make the ring line 307 283 self.npts = 40 308 284 … … 325 301 """ 326 302 self.clear_markers() 327 try: 328 self.inner_marker.remove() 329 self.inner_circle.remove() 330 except: 331 # Old version of matplotlib 332 for item in range(len(self.axes.lines)): 333 del self.axes.lines[0] 303 self.inner_marker.remove() 304 self.inner_circle.remove() 334 305 335 306 def get_radius(self): … … 347 318 y = [] 348 319 for i in range(self.npts): 349 phi = 2.0 * math.pi / (self.npts - 1) * i350 351 xval = 1.0 * self._inner_mouse_x * math.cos(phi)352 yval = 1.0 * self._inner_mouse_x * math.sin(phi)320 phi = 2.0 * numpy.pi / (self.npts - 1) * i 321 322 xval = 1.0 * self._inner_mouse_x * numpy.cos(phi) 323 yval = 1.0 * self._inner_mouse_x * numpy.sin(phi) 353 324 354 325 x.append(xval) 355 326 y.append(yval) 356 327 357 self.inner_marker.set(xdata=[self.sign * math.fabs(self._inner_mouse_x)],328 self.inner_marker.set(xdata=[self.sign * numpy.fabs(self._inner_mouse_x)], 358 329 ydata=[0]) 359 330 self.inner_circle.set_data(x, y) … … 366 337 self._inner_save_x = self._inner_mouse_x 367 338 self._inner_save_y = self._inner_mouse_y 368 self.base.freeze_axes()369 339 370 340 def moveend(self, ev): … … 396 366 self.update() 397 367 398 399 def get_params(self): 368 def getParams(self): 400 369 """ 401 370 Store a copy of values of parameters of the slicer into a dictionary. 402 403 371 :return params: the dictionary created 404 405 372 """ 406 373 params = {} 407 params["radius"] = math.fabs(self._inner_mouse_x)374 params["radius"] = numpy.fabs(self._inner_mouse_x) 408 375 return params 409 376 410 def set _params(self, params):377 def setParams(self, params): 411 378 """ 412 379 Receive a dictionary and reset the slicer with values contained … … 435 402 self.base = base 436 403 self.is_inside = side 437 self.qmax = min( math.fabs(self.base.data.xmax),438 math.fabs(self.base.data.xmin)) # must be positive404 self.qmax = min(numpy.fabs(self.base.data.xmax), 405 numpy.fabs(self.base.data.xmin)) # must be positive 439 406 self.connect = self.base.connect 440 407 … … 448 415 self.sign = -1 449 416 # Inner circle 450 self.outer_circle = RingInteractor(self, self. base.subplot, 'blue',417 self.outer_circle = RingInteractor(self, self.axes, 'blue', 451 418 zorder=zorder + 1, r=self.qmax / 1.8, 452 419 sign=self.sign) … … 455 422 self._post_data() 456 423 457 # Bind to slice parameter events458 # self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS)459 460 def _onEVT_SLICER_PARS(self, event):461 """462 receive an event containing parameters values to reset the slicer463 464 :param event: event of type SlicerParameterEvent with params as465 attribute466 """467 wx.PostEvent(self.base,468 StatusEvent(status="AnnulusSlicer._onEVT_SLICER_PARS"))469 event.Skip()470 if event.type == self.__class__.__name__:471 self.set_params(event.params)472 self.base.update()473 474 424 def set_layer(self, n): 475 425 """ 476 426 Allow adding plot to the same panel 477 478 427 :param n: the number of layer 479 480 428 """ 481 429 self.layernum = n … … 489 437 self.outer_circle.clear() 490 438 self.base.connect.clearall() 491 # self.base.Unbind(EVT_SLICER_PARS)492 439 493 440 def update(self): … … 498 445 # Update locations 499 446 self.outer_circle.update() 500 # if self.is_inside != None:447 self._post_data() 501 448 out = self._post_data() 502 449 return out … … 507 454 can restore on Esc. 508 455 """ 509 self.base.freeze_axes()510 456 self.outer_circle.save(ev) 511 457 … … 521 467 522 468 # If we have no data, just return 523 if data ==None:469 if data is None: 524 470 return 525 471 mask = data.mask … … 527 473 528 474 rmin = 0 529 rmax = math.fabs(self.outer_circle.get_radius())530 531 # # create the data1D Q average of data2D475 rmax = numpy.fabs(self.outer_circle.get_radius()) 476 477 # Create the data1D Q average of data2D 532 478 mask = Ringcut(r_min=rmin, r_max=rmax) 533 479 … … 536 482 else: 537 483 out = (mask(data)) 538 # self.base.data.mask=out539 484 return out 540 485 … … 566 511 pass 567 512 568 def get _params(self):513 def getParams(self): 569 514 """ 570 515 Store a copy of values of parameters of the slicer into a dictionary. … … 574 519 """ 575 520 params = {} 576 params["outer_radius"] = math.fabs(self.outer_circle._inner_mouse_x)521 params["outer_radius"] = numpy.fabs(self.outer_circle._inner_mouse_x) 577 522 return params 578 523 579 def set _params(self, params):524 def setParams(self, params): 580 525 """ 581 526 Receive a dictionary and reset the slicer with values contained … … 585 530 values the user assigned to the slicer. 586 531 """ 587 outer = math.fabs(params["outer_radius"])588 # #Update the picture532 outer = numpy.fabs(params["outer_radius"]) 533 # Update the picture 589 534 self.outer_circle.set_cursor(outer, self.outer_circle._inner_mouse_y) 590 # #Post the data given the nbins entered by the user535 # Post the data given the nbins entered by the user 591 536 self._post_data() 592 593 def freeze_axes(self):594 self.base.freeze_axes()595 596 def thaw_axes(self):597 self.base.thaw_axes()598 537 599 538 def draw(self): -
src/sas/sasgui/guiframe/local_perspectives/plotting/AzimutSlicer.py
rd85c194 r161713c 182 182 NewPlotEvent(plot=new_plot, title=str(new_sector.__name__))) 183 183 184 185 def validate(self, param_name, param_value): 186 """ 187 Test the proposed new value "value" for row "row" of parameters 188 """ 189 # Here, always return true 190 return True 191 184 192 def moveend(self, ev): 185 193 #TODO: why is this empty? -
src/sas/sasgui/guiframe/local_perspectives/plotting/SectorSlicer.py
rd85c194 r116260a 2 2 Sector interactor 3 3 """ 4 import math 5 import wx 4 import numpy 5 from PyQt4 import QtGui 6 from PyQt4 import QtCore 7 6 8 from BaseInteractor import _BaseInteractor 7 from sas.sasgui.guiframe.events import NewPlotEvent8 from sas.sasgui.guiframe.events import StatusEvent9 from sas.sasgui.guiframe.events import SlicerParameterEvent10 from sas.sasgui.guiframe.events import EVT_SLICER_PARS11 9 from sas.sasgui.guiframe.dataFitting import Data1D 12 13 14 class SectorInteractor(_BaseInteractor): 10 import sas.qtgui.GuiUtils as GuiUtils 11 from sas.qtgui.SlicerModel import SlicerModel 12 13 MIN_PHI = 0.05 14 15 class SectorInteractor(_BaseInteractor, SlicerModel): 15 16 """ 16 17 Draw a sector slicer.Allow to performQ averaging on data 2D 17 18 """ 18 def __init__(self, base, axes, color='black', zorder=3):19 def __init__(self, base, axes, item=None, color='black', zorder=3): 19 20 20 21 _BaseInteractor.__init__(self, base, axes, color=color) 21 ## Class initialization 22 SlicerModel.__init__(self) 23 # Class initialization 22 24 self.markers = [] 23 25 self.axes = axes 24 ## connect the plot to event 26 self._item = item 27 # Connect the plot to event 25 28 self.connect = self.base.connect 26 29 27 # # compute qmax limit to reset the graph28 x = math.pow(max(self.base.data2D.xmax,29 math.fabs(self.base.data2D.xmin)), 2)30 y = math.pow(max(self.base.data2D.ymax,31 math.fabs(self.base.data2D.ymin)), 2)32 self.qmax = math.sqrt(x + y)33 # #Number of points on the plot30 # Compute qmax limit to reset the graph 31 x = numpy.power(max(self.base.data.xmax, 32 numpy.fabs(self.base.data.xmin)), 2) 33 y = numpy.power(max(self.base.data.ymax, 34 numpy.fabs(self.base.data.ymin)), 2) 35 self.qmax = numpy.sqrt(x + y) 36 # Number of points on the plot 34 37 self.nbins = 20 35 # #Angle of the middle line36 self.theta2 = math.pi / 337 # #Absolute value of the Angle between the middle line and any side line38 self.phi = math.pi / 1239 # #Middle line40 self.main_line = LineInteractor(self, self. base.subplot, color='blue',38 # Angle of the middle line 39 self.theta2 = numpy.pi / 3 40 # Absolute value of the Angle between the middle line and any side line 41 self.phi = numpy.pi / 12 42 # Middle line 43 self.main_line = LineInteractor(self, self.axes, color='blue', 41 44 zorder=zorder, r=self.qmax, 42 45 theta=self.theta2) 43 46 self.main_line.qmax = self.qmax 44 # #Right Side line45 self.right_line = SideInteractor(self, self. base.subplot, color='black',47 # Right Side line 48 self.right_line = SideInteractor(self, self.axes, color='black', 46 49 zorder=zorder, r=self.qmax, 47 50 phi=-1 * self.phi, theta2=self.theta2) 48 51 self.right_line.qmax = self.qmax 49 # #Left Side line50 self.left_line = SideInteractor(self, self. base.subplot, color='black',52 # Left Side line 53 self.left_line = SideInteractor(self, self.axes, color='black', 51 54 zorder=zorder, r=self.qmax, 52 55 phi=self.phi, theta2=self.theta2) 53 56 self.left_line.qmax = self.qmax 54 # #draw the sector57 # draw the sector 55 58 self.update() 56 59 self._post_data() 57 ## Bind to slice parameter events 58 self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) 59 60 def _onEVT_SLICER_PARS(self, event): 61 """ 62 receive an event containing parameters values to reset the slicer 63 64 :param event: event of type SlicerParameterEvent with params as 65 attribute 66 67 """ 68 wx.PostEvent(self.base.parent, 69 StatusEvent(status="SectorSlicer._onEVT_SLICER_PARS")) 70 event.Skip() 71 if event.type == self.__class__.__name__: 72 self.set_params(event.params) 73 self.base.update() 60 self.setModelFromParams() 74 61 75 62 def set_layer(self, n): 76 63 """ 77 64 Allow adding plot to the same panel 78 79 65 :param n: the number of layer 80 81 66 """ 82 67 self.layernum = n … … 92 77 self.right_line.clear() 93 78 self.base.connect.clearall() 94 self.base.Unbind(EVT_SLICER_PARS)95 79 96 80 def update(self): … … 100 84 """ 101 85 # Update locations 102 # #Check if the middle line was dragged and103 # update the picture accordingly86 # Check if the middle line was dragged and 87 # update the picture accordingly 104 88 if self.main_line.has_move: 105 89 self.main_line.update() … … 108 92 self.left_line.update(delta=self.left_line.phi / 2, 109 93 mline=self.main_line.theta) 110 # #Check if the left side has moved and update the slicer accordingly94 # Check if the left side has moved and update the slicer accordingly 111 95 if self.left_line.has_move: 112 96 self.main_line.update() … … 116 100 mline=self.main_line, side=True, 117 101 left=False, right=True) 118 ## Check if the right side line has moved and 119 #update the slicer accordingly 102 # Check if the right side line has moved and update the slicer accordingly 120 103 if self.right_line.has_move: 121 104 self.main_line.update() … … 130 113 can restore on Esc. 131 114 """ 132 self.base.freeze_axes()133 115 self.main_line.save(ev) 134 116 self.right_line.save(ev) … … 141 123 :param nbins: the number of point to plot for the average 1D data 142 124 """ 143 # # get the data2D to average144 data = self.base.data 2D125 # Get the data2D to average 126 data = self.base.data 145 127 # If we have no data, just return 146 128 if data == None: 147 129 return 148 # #Averaging130 # Averaging 149 131 from sas.sascalc.dataloader.manipulations import SectorQ 150 132 radius = self.qmax … … 154 136 nbins = 20 155 137 sect = SectorQ(r_min=0.0, r_max=radius, 156 phi_min=phimin + math.pi,157 phi_max=phimax + math.pi, nbins=nbins)158 159 sector = sect(self.base.data 2D)160 # #Create 1D data resulting from average138 phi_min=phimin + numpy.pi, 139 phi_max=phimax + numpy.pi, nbins=nbins) 140 141 sector = sect(self.base.data) 142 # Create 1D data resulting from average 161 143 162 144 if hasattr(sector, "dxl"): … … 171 153 new_plot.dxl = dxl 172 154 new_plot.dxw = dxw 173 new_plot.name = "SectorQ" + "(" + self.base.data 2D.name + ")"174 new_plot. source = self.base.data2D.source175 #new_plot.info=self.base.data2D.info155 new_plot.name = "SectorQ" + "(" + self.base.data.name + ")" 156 new_plot.title = "SectorQ" + "(" + self.base.data.name + ")" 157 new_plot.source = self.base.data.source 176 158 new_plot.interactive = True 177 new_plot.detector = self.base.data 2D.detector178 # # If the data file does not tell us what the axes are, just assume...159 new_plot.detector = self.base.data.detector 160 # If the data file does not tell us what the axes are, just assume them. 179 161 new_plot.xaxis("\\rm{Q}", "A^{-1}") 180 162 new_plot.yaxis("\\rm{Intensity}", "cm^{-1}") 181 163 if hasattr(data, "scale") and data.scale == 'linear' and \ 182 self.base.data 2D.name.count("Residuals") > 0:164 self.base.data.name.count("Residuals") > 0: 183 165 new_plot.ytransform = 'y' 184 166 new_plot.yaxis("\\rm{Residuals} ", "/") 185 167 186 new_plot.group_id = "2daverage" + self.base.data 2D.name187 new_plot.id = "SectorQ" + self.base.data 2D.name168 new_plot.group_id = "2daverage" + self.base.data.name 169 new_plot.id = "SectorQ" + self.base.data.name 188 170 new_plot.is_data = True 189 self.base.parent.update_theory(data_id=data.id, theory=new_plot) 190 wx.PostEvent(self.base.parent, 191 NewPlotEvent(plot=new_plot, title="SectorQ" + self.base.data2D.name)) 171 variant_plot = QtCore.QVariant(new_plot) 172 GuiUtils.updateModelItemWithPlot(self._item, variant_plot, new_plot.id) 173 self.base.manager.communicator.plotUpdateSignal.emit([new_plot]) 174 175 if self.update_model: 176 self.setModelFromParams() 177 self.draw() 178 179 def validate(self, param_name, param_value): 180 """ 181 Test the proposed new value "value" for row "row" of parameters 182 """ 183 MIN_DIFFERENCE = 0.01 184 isValid = True 185 186 if param_name == 'Delta_Phi [deg]': 187 # First, check the closeness 188 if numpy.fabs(param_value) < MIN_DIFFERENCE: 189 print("Sector angles too close. Please adjust.") 190 isValid = False 191 elif param_name == 'nbins': 192 # Can't be 0 193 if param_value < 1: 194 print("Number of bins cannot be less than or equal to 0. Please adjust.") 195 isValid = False 196 return isValid 192 197 193 198 def moveend(self, ev): … … 195 200 Called a dragging motion ends.Get slicer event 196 201 """ 197 self.base.thaw_axes() 198 ## Post parameters 199 event = SlicerParameterEvent() 200 event.type = self.__class__.__name__ 201 event.params = self.get_params() 202 ## Send slicer paramers to plotter2D 203 wx.PostEvent(self.base, event) 202 # Post parameters 203 self._post_data(self.nbins) 204 204 205 205 def restore(self): … … 222 222 pass 223 223 224 def get _params(self):224 def getParams(self): 225 225 """ 226 226 Store a copy of values of parameters of the slicer into a dictionary. 227 228 227 :return params: the dictionary created 229 230 228 """ 231 229 params = {} 232 # #Always make sure that the left and the right line are at phi233 # #angle of the middle line234 if math.fabs(self.left_line.phi) != math.fabs(self.right_line.phi):230 # Always make sure that the left and the right line are at phi 231 # angle of the middle line 232 if numpy.fabs(self.left_line.phi) != numpy.fabs(self.right_line.phi): 235 233 msg = "Phi left and phi right are different" 236 234 msg += " %f, %f" % (self.left_line.phi, self.right_line.phi) 237 235 raise ValueError, msg 238 params["Phi [deg]"] = self.main_line.theta * 180 / math.pi239 params["Delta_Phi [deg]"] = math.fabs(self.left_line.phi * 180 / math.pi)236 params["Phi [deg]"] = self.main_line.theta * 180 / numpy.pi 237 params["Delta_Phi [deg]"] = numpy.fabs(self.left_line.phi * 180 / numpy.pi) 240 238 params["nbins"] = self.nbins 241 239 return params 242 240 243 def set _params(self, params):241 def setParams(self, params): 244 242 """ 245 243 Receive a dictionary and reset the slicer with values contained … … 249 247 values the user assigned to the slicer. 250 248 """ 251 main = params["Phi [deg]"] * math.pi / 180 252 phi = math.fabs(params["Delta_Phi [deg]"] * math.pi / 180) 249 main = params["Phi [deg]"] * numpy.pi / 180 250 phi = numpy.fabs(params["Delta_Phi [deg]"] * numpy.pi / 180) 251 252 # phi should not be too close. 253 if numpy.fabs(phi) < MIN_PHI: 254 phi = MIN_PHI 255 params["Delta_Phi [deg]"] = MIN_PHI 256 253 257 self.nbins = int(params["nbins"]) 254 258 self.main_line.theta = main 255 # #Reset the slicer parameters259 # Reset the slicer parameters 256 260 self.main_line.update() 257 261 self.right_line.update(phi=phi, delta=None, mline=self.main_line, … … 259 263 self.left_line.update(phi=phi, delta=None, 260 264 mline=self.main_line, side=True) 261 # # post the new corresponding data265 # Post the new corresponding data 262 266 self._post_data(nbins=self.nbins) 263 267 264 def freeze_axes(self):265 """266 """267 self.base.freeze_axes()268 269 def thaw_axes(self):270 """271 """272 self.base.thaw_axes()273 274 268 def draw(self): 275 269 """ 270 Redraw canvas 276 271 """ 277 272 self.base.draw() … … 287 282 """ 288 283 def __init__(self, base, axes, color='black', zorder=5, r=1.0, 289 phi= math.pi / 4, theta2=math.pi / 3):284 phi=numpy.pi / 4, theta2=numpy.pi / 3): 290 285 """ 291 286 """ 292 287 _BaseInteractor.__init__(self, base, axes, color=color) 293 # #Initialize the class288 # Initialize the class 294 289 self.markers = [] 295 290 self.axes = axes 296 # #compute the value of the angle between the current line and297 # #the x-axis291 # compute the value of the angle between the current line and 292 # the x-axis 298 293 self.save_theta = theta2 + phi 299 294 self.theta = theta2 + phi 300 # #the value of the middle line angle with respect to the x-axis295 # the value of the middle line angle with respect to the x-axis 301 296 self.theta2 = theta2 302 # #Radius to find polar coordinates this line's endpoints297 # Radius to find polar coordinates this line's endpoints 303 298 self.radius = r 304 # #phi is the phase between the current line and the middle line299 # phi is the phase between the current line and the middle line 305 300 self.phi = phi 306 # #End points polar coordinates307 x1 = self.radius * math.cos(self.theta)308 y1 = self.radius * math.sin(self.theta)309 x2 = -1 * self.radius * math.cos(self.theta)310 y2 = -1 * self.radius * math.sin(self.theta)311 # # defining a new marker301 # End points polar coordinates 302 x1 = self.radius * numpy.cos(self.theta) 303 y1 = self.radius * numpy.sin(self.theta) 304 x2 = -1 * self.radius * numpy.cos(self.theta) 305 y2 = -1 * self.radius * numpy.sin(self.theta) 306 # Defining a new marker 312 307 self.inner_marker = self.axes.plot([x1 / 2.5], [y1 / 2.5], linestyle='', 313 308 marker='s', markersize=10, … … 316 311 zorder=zorder, visible=True)[0] 317 312 318 # #Defining the current line313 # Defining the current line 319 314 self.line = self.axes.plot([x1, x2], [y1, y2], 320 315 linestyle='-', marker='', 321 316 color=self.color, visible=True)[0] 322 # #Flag to differentiate the left line from the right line motion317 # Flag to differentiate the left line from the right line motion 323 318 self.left_moving = False 324 # #Flag to define a motion319 # Flag to define a motion 325 320 self.has_move = False 326 # #connecting markers and draw the picture321 # connecting markers and draw the picture 327 322 self.connect_markers([self.inner_marker, self.line]) 328 323 … … 330 325 """ 331 326 Allow adding plot to the same panel 332 333 327 :param n: the number of layer 334 335 328 """ 336 329 self.layernum = n … … 359 352 360 353 """ 361 #print "update left or right ", self.has_move362 354 self.left_moving = left 363 355 theta3 = 0 … … 367 359 delta = 0 368 360 if right: 369 self.phi = -1 * math.fabs(self.phi)361 self.phi = -1 * numpy.fabs(self.phi) 370 362 #delta=-delta 371 363 else: 372 self.phi = math.fabs(self.phi)364 self.phi = numpy.fabs(self.phi) 373 365 if side: 374 366 self.theta = mline.theta + self.phi … … 383 375 else: 384 376 theta3 = self.theta2 + delta 385 x1 = self.radius * math.cos(theta3)386 y1 = self.radius * math.sin(theta3)387 x2 = -1 * self.radius * math.cos(theta3)388 y2 = -1 * self.radius * math.sin(theta3)377 x1 = self.radius * numpy.cos(theta3) 378 y1 = self.radius * numpy.sin(theta3) 379 x2 = -1 * self.radius * numpy.cos(theta3) 380 y2 = -1 * self.radius * numpy.sin(theta3) 389 381 self.inner_marker.set(xdata=[x1 / 2.5], ydata=[y1 / 2.5]) 390 382 self.line.set(xdata=[x1, x2], ydata=[y1, y2]) … … 396 388 """ 397 389 self.save_theta = self.theta 398 self.base.freeze_axes()399 390 400 391 def moveend(self, ev): … … 414 405 Process move to a new position, making sure that the move is allowed. 415 406 """ 416 self.theta = math.atan2(y, x)407 self.theta = numpy.arctan2(y, x) 417 408 self.has_move = True 418 #ToDo: Simplify below419 409 if not self.left_moving: 420 410 if self.theta2 - self.theta <= 0 and self.theta2 > 0: … … 426 416 return 427 417 elif self.theta2 < 0 and self.theta > 0 and \ 428 (self.theta2 + 2 * math.pi - self.theta) >= math.pi / 2:418 (self.theta2 + 2 * numpy.pi - self.theta) >= numpy.pi / 2: 429 419 self.restore() 430 420 return 431 421 elif self.theta2 < 0 and self.theta < 0 and \ 432 (self.theta2 - self.theta) >= math.pi / 2:433 self.restore() 434 return 435 elif self.theta2 > 0 and (self.theta2 - self.theta >= math.pi / 2 or \436 (self.theta2 - self.theta >= math.pi / 2)):422 (self.theta2 - self.theta) >= numpy.pi / 2: 423 self.restore() 424 return 425 elif self.theta2 > 0 and (self.theta2 - self.theta >= numpy.pi / 2 or \ 426 (self.theta2 - self.theta >= numpy.pi / 2)): 437 427 self.restore() 438 428 return 439 429 else: 440 if self.theta < 0 and (self.theta + math.pi * 2 - self.theta2) <= 0:430 if self.theta < 0 and (self.theta + numpy.pi * 2 - self.theta2) <= 0: 441 431 self.restore() 442 432 return … … 447 437 self.restore() 448 438 return 449 elif self.theta - self.theta2 >= math.pi / 2 or \450 ((self.theta + math.pi * 2 - self.theta2) >= math.pi / 2 and \439 elif self.theta - self.theta2 >= numpy.pi / 2 or \ 440 ((self.theta + numpy.pi * 2 - self.theta2) >= numpy.pi / 2 and \ 451 441 self.theta < 0 and self.theta2 > 0): 452 442 self.restore() 453 443 return 454 444 455 self.phi = math.fabs(self.theta2 - self.theta)456 if self.phi > math.pi:457 self.phi = 2 * math.pi - math.fabs(self.theta2 - self.theta)445 self.phi = numpy.fabs(self.theta2 - self.theta) 446 if self.phi > numpy.pi: 447 self.phi = 2 * numpy.pi - numpy.fabs(self.theta2 - self.theta) 458 448 self.base.base.update() 459 449 … … 464 454 self.update() 465 455 466 def get _params(self):456 def getParams(self): 467 457 """ 468 458 """ … … 472 462 return params 473 463 474 def set _params(self, params):464 def setParams(self, params): 475 465 """ 476 466 """ … … 484 474 """ 485 475 def __init__(self, base, axes, color='black', 486 zorder=5, r=1.0, theta= math.pi / 4):476 zorder=5, r=1.0, theta=numpy.pi / 4): 487 477 """ 488 478 """ … … 496 486 self.scale = 10.0 497 487 # Inner circle 498 x1 = self.radius * math.cos(self.theta)499 y1 = self.radius * math.sin(self.theta)500 x2 = -1 * self.radius * math.cos(self.theta)501 y2 = -1 * self.radius * math.sin(self.theta)488 x1 = self.radius * numpy.cos(self.theta) 489 y1 = self.radius * numpy.sin(self.theta) 490 x2 = -1 * self.radius * numpy.cos(self.theta) 491 y2 = -1 * self.radius * numpy.sin(self.theta) 502 492 # Inner circle marker 503 493 self.inner_marker = self.axes.plot([x1 / 2.5], [y1 / 2.5], linestyle='', … … 540 530 if theta != None: 541 531 self.theta = theta 542 x1 = self.radius * math.cos(self.theta)543 y1 = self.radius * math.sin(self.theta)544 x2 = -1 * self.radius * math.cos(self.theta)545 y2 = -1 * self.radius * math.sin(self.theta)532 x1 = self.radius * numpy.cos(self.theta) 533 y1 = self.radius * numpy.sin(self.theta) 534 x2 = -1 * self.radius * numpy.cos(self.theta) 535 y2 = -1 * self.radius * numpy.sin(self.theta) 546 536 547 537 self.inner_marker.set(xdata=[x1 / 2.5], ydata=[y1 / 2.5]) … … 554 544 """ 555 545 self.save_theta = self.theta 556 self.base.freeze_axes()557 546 558 547 def moveend(self, ev): … … 572 561 Process move to a new position, making sure that the move is allowed. 573 562 """ 574 self.theta = math.atan2(y, x)563 self.theta = numpy.arctan2(y, x) 575 564 self.has_move = True 576 565 self.base.base.update() … … 582 571 self.update() 583 572 584 def get _params(self):573 def getParams(self): 585 574 """ 586 575 """ … … 590 579 return params 591 580 592 def set _params(self, params):581 def setParams(self, params): 593 582 """ 594 583 """ -
src/sas/sasgui/guiframe/local_perspectives/plotting/boxSlicer.py
rd85c194 r3bdbfcc 1 import wx2 import math3 1 import numpy 4 from sas.sasgui.guiframe.events import NewPlotEvent 5 from sas.sasgui.guiframe.events import StatusEvent 6 from sas.sasgui.guiframe.events import SlicerParameterEvent 7 from sas.sasgui.guiframe.events import EVT_SLICER_PARS 2 from PyQt4 import QtGui 3 from PyQt4 import QtCore 4 8 5 from BaseInteractor import _BaseInteractor 9 6 from sas.sasgui.guiframe.dataFitting import Data1D 10 11 12 class BoxInteractor(_BaseInteractor): 7 import sas.qtgui.GuiUtils as GuiUtils 8 from sas.qtgui.SlicerModel import SlicerModel 9 10 11 class BoxInteractor(_BaseInteractor, SlicerModel): 13 12 """ 14 13 BoxInteractor define a rectangle that return data1D average of Data2D 15 14 in a rectangle area defined by -x, x ,y, -y 16 15 """ 17 def __init__(self, base, axes, color='black', zorder=3):16 def __init__(self, base, axes, item=None, color='black', zorder=3): 18 17 _BaseInteractor.__init__(self, base, axes, color=color) 19 # # Class initialization 18 SlicerModel.__init__(self) 19 # Class initialization 20 20 self.markers = [] 21 21 self.axes = axes 22 # #connecting artist 22 self._item = item 23 #connecting artist 23 24 self.connect = self.base.connect 24 # #which direction is the preferred interaction direction25 # which direction is the preferred interaction direction 25 26 self.direction = None 26 # #determine x y values27 self.x = 0.5 * min( math.fabs(self.base.data2D.xmax),28 math.fabs(self.base.data2D.xmin))29 self.y = 0.5 * min( math.fabs(self.base.data2D.xmax),30 math.fabs(self.base.data2D.xmin))31 # #when reach qmax reset the graph32 self.qmax = max(self.base.data 2D.xmax, self.base.data2D.xmin,33 self.base.data 2D.ymax, self.base.data2D.ymin)34 # #Number of points on the plot27 # determine x y values 28 self.x = 0.5 * min(numpy.fabs(self.base.data.xmax), 29 numpy.fabs(self.base.data.xmin)) 30 self.y = 0.5 * min(numpy.fabs(self.base.data.xmax), 31 numpy.fabs(self.base.data.xmin)) 32 # when reach qmax reset the graph 33 self.qmax = max(self.base.data.xmax, self.base.data.xmin, 34 self.base.data.ymax, self.base.data.ymin) 35 # Number of points on the plot 35 36 self.nbins = 30 36 # #If True, I(|Q|) will be return, otherwise,37 # If True, I(|Q|) will be return, otherwise, 37 38 # negative q-values are allowed 38 39 self.fold = True 39 # #reference of the current Slab averaging40 # reference of the current Slab averaging 40 41 self.averager = None 41 # #Create vertical and horizaontal lines for the rectangle42 # Create vertical and horizaontal lines for the rectangle 42 43 self.vertical_lines = VerticalLines(self, 43 self. base.subplot,44 self.axes, 44 45 color='blue', 45 46 zorder=zorder, … … 49 50 50 51 self.horizontal_lines = HorizontalLines(self, 51 self. base.subplot,52 self.axes, 52 53 color='green', 53 54 zorder=zorder, … … 55 56 y=self.y) 56 57 self.horizontal_lines.qmax = self.qmax 57 # #draw the rectangle and plost the data 1D resulting58 # #of averaging data2D58 # draw the rectangle and plost the data 1D resulting 59 # of averaging data2D 59 60 self.update() 60 61 self._post_data() 61 # # Bind to slice parameter events 62 self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) 63 64 def _onEVT_SLICER_PARS(self, event): 65 """ 66 receive an event containing parameters values to reset the slicer 67 68 :param event: event of type SlicerParameterEvent with params as 69 attribute 70 """ 71 wx.PostEvent(self.base.parent, 72 StatusEvent(status="BoxSlicer._onEVT_SLICER_PARS")) 73 event.Skip() 74 if event.type == self.__class__.__name__: 75 self.set_params(event.params) 76 self.base.update() 62 self.setModelFromParams() 77 63 78 64 def update_and_post(self): … … 102 88 self.vertical_lines.clear() 103 89 self.base.connect.clearall() 104 self.base.Unbind(EVT_SLICER_PARS)105 90 106 91 def update(self): … … 123 108 can restore on Esc. 124 109 """ 125 self.base.freeze_axes()126 110 self.vertical_lines.save(ev) 127 111 self.horizontal_lines.save(ev) … … 139 123 140 124 """ 141 if self.direction ==None:125 if self.direction is None: 142 126 self.direction = direction 143 127 144 x_min = -1 * math.fabs(self.vertical_lines.x)145 x_max = math.fabs(self.vertical_lines.x)146 y_min = -1 * math.fabs(self.horizontal_lines.y)147 y_max = math.fabs(self.horizontal_lines.y)148 149 if nbins !=None:128 x_min = -1 * numpy.fabs(self.vertical_lines.x) 129 x_max = numpy.fabs(self.vertical_lines.x) 130 y_min = -1 * numpy.fabs(self.horizontal_lines.y) 131 y_max = numpy.fabs(self.horizontal_lines.y) 132 133 if nbins is not None: 150 134 self.nbins = nbins 151 if self.averager ==None:152 if new_slab ==None:135 if self.averager is None: 136 if new_slab is None: 153 137 msg = "post data:cannot average , averager is empty" 154 138 raise ValueError, msg … … 158 142 x_low = 0 159 143 else: 160 x_low = math.fabs(x_min)144 x_low = numpy.fabs(x_min) 161 145 bin_width = (x_max + x_low) / self.nbins 162 146 elif self.direction == "Y": … … 164 148 y_low = 0 165 149 else: 166 y_low = math.fabs(y_min)150 y_low = numpy.fabs(y_min) 167 151 bin_width = (y_max + y_low) / self.nbins 168 152 else: … … 173 157 bin_width=bin_width) 174 158 box.fold = self.fold 175 boxavg = box(self.base.data 2D)159 boxavg = box(self.base.data) 176 160 # 3 Create Data1D to plot 177 161 if hasattr(boxavg, "dxl"): … … 187 171 new_plot.dxw = dxw 188 172 new_plot.name = str(self.averager.__name__) + \ 189 "(" + self.base.data2D.name + ")" 190 new_plot.source = self.base.data2D.source 173 "(" + self.base.data.name + ")" 174 new_plot.title = str(self.averager.__name__) + \ 175 "(" + self.base.data.name + ")" 176 new_plot.source = self.base.data.source 191 177 new_plot.interactive = True 192 new_plot.detector = self.base.data 2D.detector178 new_plot.detector = self.base.data.detector 193 179 # # If the data file does not tell us what the axes are, just assume... 194 180 new_plot.xaxis("\\rm{Q}", "A^{-1}") 195 181 new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}") 196 182 197 data = self.base.data 2D183 data = self.base.data 198 184 if hasattr(data, "scale") and data.scale == 'linear' and \ 199 self.base.data 2D.name.count("Residuals") > 0:185 self.base.data.name.count("Residuals") > 0: 200 186 new_plot.ytransform = 'y' 201 187 new_plot.yaxis("\\rm{Residuals} ", "/") 202 188 203 new_plot.group_id = "2daverage" + self.base.data 2D.name204 new_plot.id = (self.averager.__name__) + self.base.data 2D.name189 new_plot.group_id = "2daverage" + self.base.data.name 190 new_plot.id = (self.averager.__name__) + self.base.data.name 205 191 new_plot.is_data = True 206 self.base.parent.update_theory(data_id=self.base.data2D.id, \ 207 theory=new_plot) 208 wx.PostEvent(self.base.parent, 209 NewPlotEvent(plot=new_plot, title=str(self.averager.__name__))) 192 variant_plot = QtCore.QVariant(new_plot) 193 GuiUtils.updateModelItemWithPlot(self._item, variant_plot, new_plot.id) 194 195 if self.update_model: 196 self.setModelFromParams() 197 self.draw() 210 198 211 199 def moveend(self, ev): … … 215 203 corresponding to the new average 216 204 """ 217 self.base.thaw_axes()218 # Post paramters219 event = SlicerParameterEvent()220 event.type = self.__class__.__name__221 event.params = self.get_params()222 wx.PostEvent(self.base.parent, event)223 # create the new data1D224 205 self._post_data() 225 206 … … 240 221 pass 241 222 242 def get _params(self):223 def getParams(self): 243 224 """ 244 225 Store a copy of values of parameters of the slicer into a dictionary. … … 248 229 """ 249 230 params = {} 250 params["x_max"] = math.fabs(self.vertical_lines.x)251 params["y_max"] = math.fabs(self.horizontal_lines.y)231 params["x_max"] = numpy.fabs(self.vertical_lines.x) 232 params["y_max"] = numpy.fabs(self.horizontal_lines.y) 252 233 params["nbins"] = self.nbins 253 234 return params 254 235 255 def set _params(self, params):236 def setParams(self, params): 256 237 """ 257 238 Receive a dictionary and reset the slicer with values contained … … 261 242 values the user assigned to the slicer. 262 243 """ 263 self.x = float( math.fabs(params["x_max"]))264 self.y = float( math.fabs(params["y_max"]))244 self.x = float(numpy.fabs(params["x_max"])) 245 self.y = float(numpy.fabs(params["y_max"])) 265 246 self.nbins = params["nbins"] 266 247 … … 269 250 self.post_data(nbins=None) 270 251 271 def freeze_axes(self):272 """273 """274 self.base.freeze_axes()275 276 def thaw_axes(self):277 """278 """279 self.base.thaw_axes()280 281 252 def draw(self): 282 253 """ … … 294 265 """ 295 266 _BaseInteractor.__init__(self, base, axes, color=color) 296 # #Class initialization267 # Class initialization 297 268 self.markers = [] 298 269 self.axes = axes 299 # #Saving the end points of two lines270 # Saving the end points of two lines 300 271 self.x = x 301 272 self.save_x = x … … 303 274 self.y = y 304 275 self.save_y = y 305 # #Creating a marker276 # Creating a marker 306 277 # Inner circle marker 307 278 self.inner_marker = self.axes.plot([0], [self.y], linestyle='', … … 311 282 zorder=zorder, 312 283 visible=True)[0] 313 # #Define 2 horizontal lines284 # Define 2 horizontal lines 314 285 self.top_line = self.axes.plot([self.x, -self.x], [self.y, self.y], 315 286 linestyle='-', marker='', … … 318 289 linestyle='-', marker='', 319 290 color=self.color, visible=True)[0] 320 # #Flag to check the motion of the lines291 # Flag to check the motion of the lines 321 292 self.has_move = False 322 # #Connecting markers to mouse events and draw293 # Connecting markers to mouse events and draw 323 294 self.connect_markers([self.top_line, self.inner_marker]) 324 295 self.update() … … 339 310 """ 340 311 self.clear_markers() 341 try: 342 self.inner_marker.remove() 343 self.top_line.remove() 344 self.bottom_line.remove() 345 except: 346 # Old version of matplotlib 347 for item in range(len(self.axes.lines)): 348 del self.axes.lines[0] 312 self.inner_marker.remove() 313 self.top_line.remove() 314 self.bottom_line.remove() 349 315 350 316 def update(self, x=None, y=None): … … 356 322 357 323 """ 358 # #Reset x, y- coordinates if send as parameters359 if x !=None:360 self.x = numpy.sign(self.x) * math.fabs(x)361 if y !=None:362 self.y = numpy.sign(self.y) * math.fabs(y)363 # #Draw lines and markers324 # Reset x, y- coordinates if send as parameters 325 if x is not None: 326 self.x = numpy.sign(self.x) * numpy.fabs(x) 327 if y is not None: 328 self.y = numpy.sign(self.y) * numpy.fabs(y) 329 # Draw lines and markers 364 330 self.inner_marker.set(xdata=[0], ydata=[self.y]) 365 331 self.top_line.set(xdata=[self.x, -self.x], ydata=[self.y, self.y]) … … 373 339 self.save_x = self.x 374 340 self.save_y = self.y 375 self.base.freeze_axes()376 341 377 342 def moveend(self, ev): … … 409 374 self.markers = [] 410 375 self.axes = axes 411 self.x = math.fabs(x)376 self.x = numpy.fabs(x) 412 377 self.save_x = self.x 413 self.y = math.fabs(y)378 self.y = numpy.fabs(y) 414 379 self.save_y = y 415 380 # Inner circle marker … … 446 411 """ 447 412 self.clear_markers() 448 try: 449 self.inner_marker.remove() 450 self.left_line.remove() 451 self.right_line.remove() 452 except: 453 # Old version of matplotlib 454 for item in range(len(self.axes.lines)): 455 del self.axes.lines[0] 413 self.inner_marker.remove() 414 self.left_line.remove() 415 self.right_line.remove() 456 416 457 417 def update(self, x=None, y=None): … … 463 423 464 424 """ 465 # # reset x, y -coordinates if given as parameters466 if x !=None:467 self.x = numpy.sign(self.x) * math.fabs(x)468 if y !=None:469 self.y = numpy.sign(self.y) * math.fabs(y)470 # # draw lines and markers425 # Reset x, y -coordinates if given as parameters 426 if x is not None: 427 self.x = numpy.sign(self.x) * numpy.fabs(x) 428 if y is not None: 429 self.y = numpy.sign(self.y) * numpy.fabs(y) 430 # Draw lines and markers 471 431 self.inner_marker.set(xdata=[self.x], ydata=[0]) 472 432 self.left_line.set(xdata=[-self.x, -self.x], ydata=[self.y, -self.y]) … … 480 440 self.save_x = self.x 481 441 self.save_y = self.y 482 self.base.freeze_axes()483 442 484 443 def moveend(self, ev): … … 510 469 Average in Qx direction 511 470 """ 512 def __init__(self, base, axes, color='black', zorder=3):513 BoxInteractor.__init__(self, base, axes, color=color)471 def __init__(self, base, axes, item=None, color='black', zorder=3): 472 BoxInteractor.__init__(self, base, axes, item=item, color=color) 514 473 self.base = base 515 474 self._post_data() … … 527 486 Average in Qy direction 528 487 """ 529 def __init__(self, base, axes, color='black', zorder=3):530 BoxInteractor.__init__(self, base, axes, color=color)488 def __init__(self, base, axes, item=None, color='black', zorder=3): 489 BoxInteractor.__init__(self, base, axes, item=item, color=color) 531 490 self.base = base 532 491 self._post_data() -
src/sas/sasgui/guiframe/local_perspectives/plotting/boxSum.py
rd85c194 r3bdbfcc 1 1 """ 2 Boxsum Class: determine 2 rectangular area to compute 3 the sum of pixel of a Data. 4 """ 5 import numpy 6 from PyQt4 import QtGui 7 from PyQt4 import QtCore 8 from sas.qtgui.GuiUtils import formatNumber 9 10 from BaseInteractor import _BaseInteractor 11 from sas.sascalc.dataloader.manipulations import Boxavg 12 from sas.sascalc.dataloader.manipulations import Boxsum 13 14 from sas.qtgui.SlicerModel import SlicerModel 15 16 17 class BoxSumCalculator(_BaseInteractor): 18 """ 2 19 Boxsum Class: determine 2 rectangular area to compute 3 20 the sum of pixel of a Data. 4 """ 5 import math 6 import wx 7 from BaseInteractor import _BaseInteractor 8 from sas.sasgui.guiframe.events import SlicerParamUpdateEvent 9 from sas.sasgui.guiframe.events import EVT_SLICER_PARS 10 from sas.sasgui.guiframe.events import StatusEvent 11 12 13 class BoxSum(_BaseInteractor): 21 Uses PointerInteractor , VerticalDoubleLine,HorizontalDoubleLine. 22 @param zorder: Artists with lower zorder values are drawn first. 23 @param x_min: the minimum value of the x coordinate 24 @param x_max: the maximum value of the x coordinate 25 @param y_min: the minimum value of the y coordinate 26 @param y_max: the maximum value of the y coordinate 27 14 28 """ 15 Boxsum Class: determine 2 rectangular area to compute 16 the sum of pixel of a Data. 17 Uses PointerInteractor , VerticalDoubleLine,HorizontalDoubleLine. 18 @param zorder: Artists with lower zorder values are drawn first. 19 @param x_min: the minimum value of the x coordinate 20 @param x_max: the maximum value of the x coordinate 21 @param y_min: the minimum value of the y coordinate 22 @param y_max: the maximum value of the y coordinate 23 24 """ 25 def __init__(self, base, axes, color='black', zorder=3, x_min=0.008, 26 x_max=0.008, y_min=0.0025, y_max=0.0025): 27 """ 28 """ 29 def __init__(self, base, axes, color='black', zorder=3): 29 30 _BaseInteractor.__init__(self, base, axes, color=color) 30 # # class initialization 31 # #list of Boxsmun markers31 32 # list of Boxsmun markers 32 33 self.markers = [] 33 34 self.axes = axes 34 # # connect the artist for the motion 35 self._model = None 36 self.update_model = False 37 38 # connect the artist for the motion 35 39 self.connect = self.base.connect 36 # # when qmax is reached the selected line is reset the its previous value 37 self.qmax = min(self.base.data2D.xmax, self.base.data2D.xmin) 38 # # Define the boxsum limits 39 self.xmin = -1 * 0.5 * min(math.fabs(self.base.data2D.xmax), 40 math.fabs(self.base.data2D.xmin)) 41 self.ymin = -1 * 0.5 * min(math.fabs(self.base.data2D.xmax), 42 math.fabs(self.base.data2D.xmin)) 43 self.xmax = 0.5 * min(math.fabs(self.base.data2D.xmax), 44 math.fabs(self.base.data2D.xmin)) 45 self.ymax = 0.5 * min(math.fabs(self.base.data2D.xmax), 46 math.fabs(self.base.data2D.xmin)) 47 # # center of the boxSum 40 41 # when qmax is reached the selected line is reset the its previous value 42 self.qmax = min(self.base.data.xmax, self.base.data.xmin) 43 44 # Define the boxsum limits 45 self.xmin = -1 * 0.5 * min(numpy.fabs(self.base.data.xmax), 46 numpy.fabs(self.base.data.xmin)) 47 self.ymin = -1 * 0.5 * min(numpy.fabs(self.base.data.xmax), 48 numpy.fabs(self.base.data.xmin)) 49 self.xmax = 0.5 * min(numpy.fabs(self.base.data.xmax), 50 numpy.fabs(self.base.data.xmin)) 51 self.ymax = 0.5 * min(numpy.fabs(self.base.data.xmax), 52 numpy.fabs(self.base.data.xmin)) 53 # center of the boxSum 48 54 self.center_x = 0.0002 49 55 self.center_y = 0.0003 50 # #Number of points on the plot56 # Number of points on the plot 51 57 self.nbins = 20 52 # #Define initial result the summation58 # Define initial result the summation 53 59 self.count = 0 54 60 self.error = 0 … … 56 62 self.totalerror = 0 57 63 self.points = 0 58 # #Flag to determine if the current figure has moved59 # #set to False == no motion , set to True== motion64 # Flag to determine if the current figure has moved 65 # set to False == no motion , set to True== motion 60 66 self.has_move = False 61 # #Create Boxsum edges67 # Create Boxsum edges 62 68 self.horizontal_lines = HorizontalDoubleLine(self, 63 self. base.subplot,69 self.axes, 64 70 color='blue', 65 71 zorder=zorder, … … 71 77 72 78 self.vertical_lines = VerticalDoubleLine(self, 73 self. base.subplot,79 self.axes, 74 80 color='black', 75 81 zorder=zorder, … … 81 87 82 88 self.center = PointInteractor(self, 83 self. base.subplot, color='grey',89 self.axes, color='grey', 84 90 zorder=zorder, 85 91 center_x=self.center_x, 86 92 center_y=self.center_y) 87 # #Save the name of the slicer panel associate with this slicer93 # Save the name of the slicer panel associate with this slicer 88 94 self.panel_name = "" 89 # # Update and post slicer parameters 90 self.update() 91 self._post_data() 92 # # Bind to slice parameter events 93 self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) 94 95 def set_panel_name(self, name): 96 """ 97 Store the name of the panel associated to this slicer 98 @param name: the name of this panel 95 # Update and post slicer parameters 96 self.update_model = False 97 self.update() 98 self.postData() 99 100 # set up the model 101 self._model = QtGui.QStandardItemModel(1, 9) 102 self.setModelFromParams() 103 self.update_model = True 104 self._model.itemChanged.connect(self.setParamsFromModel) 105 106 def setModelFromParams(self): 107 """ 108 Set up the Qt model for data handling between controls 109 """ 110 parameters = self.getParams() 111 # Crete/overwrite model items 112 self._model.setData(self._model.index(0, 0), 113 QtCore.QVariant(formatNumber(parameters['Height']))) 114 self._model.setData(self._model.index(0, 1), 115 QtCore.QVariant(formatNumber(parameters['Width']))) 116 self._model.setData(self._model.index(0, 2), 117 QtCore.QVariant(formatNumber(parameters['center_x']))) 118 self._model.setData(self._model.index(0, 3), 119 QtCore.QVariant(formatNumber(parameters['center_y']))) 120 121 self.setReadOnlyParametersFromModel() 122 123 def model(self): 124 ''' model accessor ''' 125 return self._model 126 127 def setReadOnlyParametersFromModel(self): 128 """ 129 Cast model content onto "read-only" subset of parameters 130 """ 131 parameters = self.getParams() 132 self._model.setData(self._model.index(0, 4), 133 QtCore.QVariant(formatNumber(parameters['avg']))) 134 self._model.setData(self._model.index(0, 5), 135 QtCore.QVariant(formatNumber(parameters['avg_error']))) 136 self._model.setData(self._model.index(0, 6), 137 QtCore.QVariant(formatNumber(parameters['sum']))) 138 self._model.setData(self._model.index(0, 7), 139 QtCore.QVariant(formatNumber(parameters['sum_error']))) 140 self._model.setData(self._model.index(0, 8), 141 QtCore.QVariant(formatNumber(parameters['num_points']))) 142 143 def setParamsFromModel(self): 144 """ 145 Cast model content onto params dict 146 """ 147 params = {} 148 params["Height"] = float(self.model().item(0, 0).text()) 149 params["Width"] = float(self.model().item(0, 1).text()) 150 params["center_x"] = float(self.model().item(0, 2).text()) 151 params["center_y"] = float(self.model().item(0, 3).text()) 152 self.update_model = False 153 self.setParams(params) 154 self.setReadOnlyParametersFromModel() 155 self.update_model = True 156 157 def setPanelName(self, name): 158 """ 159 Store the name of the panel associated to this slicer 160 @param name: the name of this panel 99 161 """ 100 162 self.panel_name = name 101 163 102 def _onEVT_SLICER_PARS(self, event): 103 """ 104 receive an event containing parameters values to reset the slicer 105 @param event: event of type SlicerParameterEvent with params as 106 attribute 107 """ 108 # # Post e message to declare what kind of event has being received 109 wx.PostEvent(self.base.parent, 110 StatusEvent(status="Boxsum._onEVT_SLICER_PARS")) 111 event.Skip() 112 # # reset the slicer with the values contains the event.params dictionary 113 if event.type == self.__class__.__name__: 114 self.set_params(event.params) 115 self.base.update() 116 117 def set_layer(self, n): 164 def setLayer(self, n): 118 165 """ 119 166 Allow adding plot to the same panel … … 132 179 self.center.clear() 133 180 self.base.connect.clearall() 134 self.base.Unbind(EVT_SLICER_PARS)135 181 136 182 def update(self): … … 139 185 resetting the widgets. 140 186 """ 141 # #check if the center point has moved and update the figure accordingly187 # check if the center point has moved and update the figure accordingly 142 188 if self.center.has_move: 143 189 self.center.update() 144 190 self.horizontal_lines.update(center=self.center) 145 191 self.vertical_lines.update(center=self.center) 146 # #check if the horizontal lines have moved and192 # check if the horizontal lines have moved and 147 193 # update the figure accordingly 148 194 if self.horizontal_lines.has_move: … … 151 197 y2=self.horizontal_lines.y2, 152 198 height=self.horizontal_lines.half_height) 153 # #check if the vertical lines have moved and199 # check if the vertical lines have moved and 154 200 # update the figure accordingly 155 201 if self.vertical_lines.has_move: … … 164 210 can restore on Esc. 165 211 """ 166 self.base.freeze_axes()167 212 self.horizontal_lines.save(ev) 168 213 self.vertical_lines.save(ev) 169 214 self.center.save(ev) 170 215 171 def _post_data(self):216 def postData(self): 172 217 """ 173 218 Get the limits of the boxsum and compute the sum of the pixel 174 219 contained in that region and the error on that sum 175 220 """ 176 # #the region of the summation221 # the region of the summation 177 222 x_min = self.horizontal_lines.x2 178 223 x_max = self.horizontal_lines.x1 179 224 y_min = self.vertical_lines.y2 180 225 y_max = self.vertical_lines.y1 181 # #computation of the sum and its error 182 from sas.sascalc.dataloader.manipulations import Boxavg 226 #computation of the sum and its error 183 227 box = Boxavg(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max) 184 self.count, self.error = box(self.base.data 2D)228 self.count, self.error = box(self.base.data) 185 229 # Dig out number of points summed, SMK & PDB, 04/03/2013 186 from sas.sascalc.dataloader.manipulations import Boxsum187 230 boxtotal = Boxsum(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max) 188 self.total, self.totalerror, self.points = boxtotal(self.base.data2D) 231 self.total, self.totalerror, self.points = boxtotal(self.base.data) 232 if self.update_model: 233 self.setModelFromParams() 234 self.draw() 189 235 190 236 def moveend(self, ev): 191 237 """ 192 After a dragging motion this function is called to compute 193 the error and the sum of pixel of a given data 2D 194 """ 195 self.base.thaw_axes() 196 # # compute error an d sum of data's pixel 197 self._post_data() 198 # # Create and event ( posted to guiframe)that set the 199 # #current slicer parameter to a panel of name self.panel_name 200 self.type = self.__class__.__name__ 201 params = self.get_params() 202 event = SlicerParamUpdateEvent(type=self.type, 203 params=params, 204 panel_name=self.panel_name) 205 wx.PostEvent(self.base.parent, event) 238 After a dragging motion this function is called to compute 239 the error and the sum of pixel of a given data 2D 240 """ 241 # compute error an d sum of data's pixel 242 self.postData() 206 243 207 244 def restore(self): … … 213 250 self.center.restore() 214 251 215 def move(self, x, y, ev): 216 """ 217 Process move to a new position, making sure that the move is allowed. 218 """ 219 pass 220 221 def set_cursor(self, x, y): 222 """ 223 """ 224 pass 225 226 def get_params(self): 252 def getParams(self): 227 253 """ 228 254 Store a copy of values of parameters of the slicer into a dictionary. … … 230 256 """ 231 257 params = {} 232 params["Width"] = math.fabs(self.vertical_lines.half_width) * 2233 params["Height"] = math.fabs(self.horizontal_lines.half_height) * 2258 params["Width"] = numpy.fabs(self.vertical_lines.half_width) * 2 259 params["Height"] = numpy.fabs(self.horizontal_lines.half_height) * 2 234 260 params["center_x"] = self.center.x 235 261 params["center_y"] = self.center.y … … 241 267 return params 242 268 243 def get _result(self):244 """ 245 return the result of box summation269 def getResult(self): 270 """ 271 Return the result of box summation 246 272 """ 247 273 result = {} … … 253 279 return result 254 280 255 def set _params(self, params):281 def setParams(self, params): 256 282 """ 257 283 Receive a dictionary and reset the slicer with values contained 258 284 in the values of the dictionary. 259 :param params: a dictionary containing name of slicer parameters and values the user assigned to the slicer. 260 """ 261 x_max = math.fabs(params["Width"]) / 2 262 y_max = math.fabs(params["Height"]) / 2 285 :param params: a dictionary containing name of slicer parameters 286 and values the user assigned to the slicer. 287 """ 288 x_max = numpy.fabs(params["Width"]) / 2 289 y_max = numpy.fabs(params["Height"]) / 2 263 290 264 291 self.center_x = params["center_x"] … … 271 298 width=x_max, height=y_max) 272 299 # compute the new error and sum given values of params 273 self._post_data() 274 275 def freeze_axes(self): 276 """ 277 """ 278 self.base.freeze_axes() 279 280 def thaw_axes(self): 281 """ 282 """ 283 self.base.thaw_axes() 300 self.postData() 284 301 285 302 def draw(self): 286 """ 287 """ 303 """ Redraw canvas""" 288 304 self.base.draw() 289 305 … … 297 313 def __init__(self, base, axes, color='black', zorder=5, center_x=0.0, 298 314 center_y=0.0): 299 """300 """301 315 _BaseInteractor.__init__(self, base, axes, color=color) 302 # #Initialization the class316 # Initialization the class 303 317 self.markers = [] 304 318 self.axes = axes … … 306 320 self.x = center_x 307 321 self.y = center_y 308 # #saved value of the center coordinates322 # saved value of the center coordinates 309 323 self.save_x = center_x 310 324 self.save_y = center_y 311 # #Create a marker325 # Create a marker 312 326 self.center_marker = self.axes.plot([self.x], [self.y], linestyle='', 313 327 marker='s', markersize=10, … … 316 330 zorder=zorder, 317 331 visible=True)[0] 318 # #Draw a point332 # Draw a point 319 333 self.center = self.axes.plot([self.x], [self.y], 320 334 linestyle='-', marker='', 321 335 color=self.color, 322 336 visible=True)[0] 323 # #Flag to determine the motion this point337 # Flag to determine the motion this point 324 338 self.has_move = False 325 # #connecting the marker to allow them to move339 # connecting the marker to allow them to move 326 340 self.connect_markers([self.center_marker]) 327 # #Update the figure328 self.update() 329 330 def set _layer(self, n):331 """ 332 333 341 # Update the figure 342 self.update() 343 344 def setLayer(self, n): 345 """ 346 Allow adding plot to the same panel 347 @param n: the number of layer 334 348 """ 335 349 self.layernum = n … … 338 352 def clear(self): 339 353 """ 340 354 Clear this figure and its markers 341 355 """ 342 356 self.clear_markers() 343 try: 344 self.center.remove() 345 self.center_marker.remove() 346 except: 347 # Old version of matplotlib 348 for item in range(len(self.axes.lines)): 349 del self.axes.lines[0] 357 self.center.remove() 358 self.center_marker.remove() 350 359 351 360 def update(self, center_x=None, center_y=None): 352 361 """ 353 362 Draw the new roughness on the graph. 354 363 """ 355 364 if center_x != None: … … 367 376 self.save_x = self.x 368 377 self.save_y = self.y 369 self.base.freeze_axes()370 378 371 379 def moveend(self, ev): … … 391 399 self.base.base.update() 392 400 393 def set _cursor(self, x, y):401 def setCursor(self, x, y): 394 402 """ 395 403 """ … … 399 407 class VerticalDoubleLine(_BaseInteractor): 400 408 """ 401 402 409 Draw 2 vertical lines moving in opposite direction and centered on 410 a point (PointInteractor) 403 411 """ 404 412 def __init__(self, base, axes, color='black', zorder=5, x=0.5, y=0.5, 405 413 center_x=0.0, center_y=0.0): 406 """407 """408 414 _BaseInteractor.__init__(self, base, axes, color=color) 409 # #Initialization the class415 # Initialization the class 410 416 self.markers = [] 411 417 self.axes = axes 412 # #Center coordinates418 # Center coordinates 413 419 self.center_x = center_x 414 420 self.center_y = center_y 415 # #defined end points vertical lignes and their saved values421 # defined end points vertical lignes and their saved values 416 422 self.y1 = y + self.center_y 417 423 self.save_y1 = self.y1 … … 429 435 # # save the color of the line 430 436 self.color = color 431 # #the height of the rectangle432 self.half_height = math.fabs(y)433 self.save_half_height = math.fabs(y)434 # #the with of the rectangle435 self.half_width = math.fabs(self.x1 - self.x2) / 2436 self.save_half_width = math.fabs(self.x1 - self.x2) / 2437 # #Create marker437 # the height of the rectangle 438 self.half_height = numpy.fabs(y) 439 self.save_half_height = numpy.fabs(y) 440 # the with of the rectangle 441 self.half_width = numpy.fabs(self.x1 - self.x2) / 2 442 self.save_half_width = numpy.fabs(self.x1 - self.x2) / 2 443 # Create marker 438 444 self.right_marker = self.axes.plot([self.x1], [0], linestyle='', 439 445 marker='s', markersize=10, … … 442 448 zorder=zorder, visible=True)[0] 443 449 444 # # define the left and right lines of the rectangle450 # Define the left and right lines of the rectangle 445 451 self.right_line = self.axes.plot([self.x1, self.x1], [self.y1, self.y2], 446 452 linestyle='-', marker='', … … 449 455 linestyle='-', marker='', 450 456 color=self.color, visible=True)[0] 451 # #Flag to determine if the lines have moved457 # Flag to determine if the lines have moved 452 458 self.has_move = False 453 # # connection the marker and draw the pictures459 # Connection the marker and draw the pictures 454 460 self.connect_markers([self.right_marker]) 455 461 self.update() 456 462 457 def set _layer(self, n):463 def setLayer(self, n): 458 464 """ 459 465 Allow adding plot to the same panel … … 468 474 """ 469 475 self.clear_markers() 470 try: 471 self.right_marker.remove() 472 self.right_line.remove() 473 self.left_line.remove() 474 except: 475 # Old version of matplotlib 476 for item in range(len(self.axes.lines)): 477 del self.axes.lines[0] 476 self.right_marker.remove() 477 self.right_line.remove() 478 self.left_line.remove() 478 479 479 480 def update(self, x1=None, x2=None, y1=None, y2=None, width=None, … … 489 490 :param center: provided x, y coordinates of the center point 490 491 """ 491 # # save the new height, witdh of the rectangle if given as a param492 if width !=None:492 # Save the new height, witdh of the rectangle if given as a param 493 if width is not None: 493 494 self.half_width = width 494 if height !=None:495 if height is not None: 495 496 self.half_height = height 496 # #If new center coordinates are given draw the rectangle497 # #given these value498 if center !=None:497 # If new center coordinates are given draw the rectangle 498 # given these value 499 if center is not None: 499 500 self.center_x = center.x 500 501 self.center_y = center.y … … 510 511 ydata=[self.y1, self.y2]) 511 512 return 512 # #if x1, y1, y2, y3 are given draw the rectangle with this value513 if x1 !=None:513 # if x1, y1, y2, y3 are given draw the rectangle with this value 514 if x1 is not None: 514 515 self.x1 = x1 515 if x2 !=None:516 if x2 is not None: 516 517 self.x2 = x2 517 if y1 !=None:518 if y1 is not None: 518 519 self.y1 = y1 519 if y2 !=None:520 if y2 is not None: 520 521 self.y2 = y2 521 # #Draw 2 vertical lines and a marker522 # Draw 2 vertical lines and a marker 522 523 self.right_marker.set(xdata=[self.x1], ydata=[self.center_y]) 523 524 self.right_line.set(xdata=[self.x1, self.x1], ydata=[self.y1, self.y2]) … … 535 536 self.save_half_height = self.half_height 536 537 self.save_half_width = self.half_width 537 self.base.freeze_axes()538 538 539 539 def moveend(self, ev): 540 540 """ 541 541 After a dragging motion reset the flag self.has_move to False 542 542 """ 543 543 self.has_move = False … … 562 562 delta = self.x1 - self.center_x 563 563 self.x2 = self.center_x - delta 564 self.half_width = math.fabs(self.x1 - self.x2) / 2564 self.half_width = numpy.fabs(self.x1 - self.x2) / 2 565 565 self.has_move = True 566 566 self.base.base.update() 567 567 568 def set _cursor(self, x, y):569 """ 570 568 def setCursor(self, x, y): 569 """ 570 Update the figure given x and y 571 571 """ 572 572 self.move(x, y, None) … … 575 575 class HorizontalDoubleLine(_BaseInteractor): 576 576 """ 577 577 Select an annulus through a 2D plot 578 578 """ 579 579 def __init__(self, base, axes, color='black', zorder=5, x=0.5, y=0.5, … … 581 581 582 582 _BaseInteractor.__init__(self, base, axes, color=color) 583 # #Initialization the class583 # Initialization the class 584 584 self.markers = [] 585 585 self.axes = axes 586 # #Center coordinates586 # Center coordinates 587 587 self.center_x = center_x 588 588 self.center_y = center_y … … 598 598 self.save_x2 = self.x2 599 599 self.color = color 600 self.half_height = math.fabs(y)601 self.save_half_height = math.fabs(y)602 self.half_width = math.fabs(x)603 self.save_half_width = math.fabs(x)600 self.half_height = numpy.fabs(y) 601 self.save_half_height = numpy.fabs(y) 602 self.half_width = numpy.fabs(x) 603 self.save_half_width = numpy.fabs(x) 604 604 self.top_marker = self.axes.plot([0], [self.y1], linestyle='', 605 605 marker='s', markersize=10, … … 616 616 linestyle='-', marker='', 617 617 color=self.color, visible=True)[0] 618 # #Flag to determine if the lines have moved618 # Flag to determine if the lines have moved 619 619 self.has_move = False 620 # #connection the marker and draw the pictures620 # connection the marker and draw the pictures 621 621 self.connect_markers([self.top_marker]) 622 622 self.update() 623 623 624 def set _layer(self, n):625 """ 626 627 624 def setLayer(self, n): 625 """ 626 Allow adding plot to the same panel 627 @param n: the number of layer 628 628 """ 629 629 self.layernum = n … … 632 632 def clear(self): 633 633 """ 634 634 Clear this figure and its markers 635 635 """ 636 636 self.clear_markers() 637 try: 638 self.top_marker.remove() 639 self.bottom_line.remove() 640 self.top_line.remove() 641 except: 642 # Old version of matplotlib 643 for item in range(len(self.axes.lines)): 644 del self.axes.lines[0] 637 self.top_marker.remove() 638 self.bottom_line.remove() 639 self.top_line.remove() 645 640 646 641 def update(self, x1=None, x2=None, y1=None, y2=None, … … 656 651 :param center: provided x, y coordinates of the center point 657 652 """ 658 # # save the new height, witdh of the rectangle if given as a param659 if width !=None:653 # Save the new height, witdh of the rectangle if given as a param 654 if width is not None: 660 655 self.half_width = width 661 if height !=None:656 if height is not None: 662 657 self.half_height = height 663 # #If new center coordinates are given draw the rectangle664 # #given these value665 if center !=None:658 # If new center coordinates are given draw the rectangle 659 # given these value 660 if center is not None: 666 661 self.center_x = center.x 667 662 self.center_y = center.y … … 678 673 ydata=[self.y2, self.y2]) 679 674 return 680 # #if x1, y1, y2, y3 are given draw the rectangle with this value681 if x1 !=None:675 # if x1, y1, y2, y3 are given draw the rectangle with this value 676 if x1 is not None: 682 677 self.x1 = x1 683 if x2 !=None:678 if x2 is not None: 684 679 self.x2 = x2 685 if y1 !=None:680 if y1 is not None: 686 681 self.y1 = y1 687 if y2 !=None:682 if y2 is not None: 688 683 self.y2 = y2 689 # #Draw 2 vertical lines and a marker684 # Draw 2 vertical lines and a marker 690 685 self.top_marker.set(xdata=[self.center_x], ydata=[self.y1]) 691 686 self.top_line.set(xdata=[self.x1, self.x2], ydata=[self.y1, self.y1]) … … 703 698 self.save_half_height = self.half_height 704 699 self.save_half_width = self.half_width 705 self.base.freeze_axes()706 700 707 701 def moveend(self, ev): … … 730 724 delta = self.y1 - self.center_y 731 725 self.y2 = self.center_y - delta 732 self.half_height = math.fabs(self.y1) - self.center_y726 self.half_height = numpy.fabs(self.y1) - self.center_y 733 727 self.has_move = True 734 728 self.base.base.update() 735 729 736 def set _cursor(self, x, y):737 """ 738 730 def setCursor(self, x, y): 731 """ 732 Update the figure given x and y 739 733 """ 740 734 self.move(x, y, None)
Note: See TracChangeset
for help on using the changeset viewer.