Changeset 3bdbfcc in sasview for src/sas/sasgui/guiframe/local_perspectives/plotting/AnnulusSlicer.py
- Timestamp:
- Feb 2, 2017 8:29:07 AM (7 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:
- 965fbd8
- Parents:
- 5d89f43
- git-author:
- Piotr Rozyczko <rozyczko@…> (01/23/17 09:21:03)
- git-committer:
- Piotr Rozyczko <rozyczko@…> (02/02/17 08:29:07)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/guiframe/local_perspectives/plotting/AnnulusSlicer.py
rd85c194 r3bdbfcc 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 152 if self.update_model: 153 self.setModelFromParams() 154 self.draw() 155 175 156 176 157 def moveend(self, ev): 177 158 """ 178 159 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) 160 Redraw the plot with new parameters. 161 """ 162 self._post_data(self.nbins) 189 163 190 164 def restore(self): … … 204 178 pass 205 179 206 def get _params(self):180 def getParams(self): 207 181 """ 208 182 Store a copy of values of parameters of the slicer into a dictionary. 209 210 183 :return params: the dictionary created 211 212 184 """ 213 185 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)186 params["inner_radius"] = numpy.fabs(self.inner_circle._inner_mouse_x) 187 params["outer_radius"] = numpy.fabs(self.outer_circle._inner_mouse_x) 216 188 params["nbins"] = self.nbins 217 189 return params 218 190 219 def set _params(self, params):191 def setParams(self, params): 220 192 """ 221 193 Receive a dictionary and reset the slicer with values contained … … 224 196 :param params: a dictionary containing name of slicer parameters and 225 197 values the user assigned to the slicer. 226 227 """ 228 inner = math.fabs(params["inner_radius"]) 229 outer = math.fabs(params["outer_radius"]) 198 """ 199 inner = numpy.fabs(params["inner_radius"]) 200 outer = numpy.fabs(params["outer_radius"]) 230 201 self.nbins = int(params["nbins"]) 231 # #Update the picture202 # Update the picture 232 203 self.inner_circle.set_cursor(inner, self.inner_circle._inner_mouse_y) 233 204 self.outer_circle.set_cursor(outer, self.outer_circle._inner_mouse_y) 234 # #Post the data given the nbins entered by the user205 # Post the data given the nbins entered by the user 235 206 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 207 247 208 def draw(self): … … 278 239 self.sign = sign 279 240 # # 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 241 # Inner circle marker 242 x_value = [self.sign * numpy.fabs(self._inner_mouse_x)] 243 self.inner_marker = self.axes.plot(x_value, [0], linestyle='', 244 marker='s', markersize=10, 245 color=self.color, alpha=0.6, 246 pickradius=5, label="pick", 247 zorder=zorder, 248 visible=True)[0] 304 249 # Draw a circle 305 250 [self.inner_circle] = self.axes.plot([], [], linestyle='-', marker='', color=self.color) 306 # the number of points that make the ring line251 # The number of points that make the ring line 307 252 self.npts = 40 308 253 … … 325 270 """ 326 271 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] 272 self.inner_marker.remove() 273 self.inner_circle.remove() 334 274 335 275 def get_radius(self): … … 347 287 y = [] 348 288 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)289 phi = 2.0 * numpy.pi / (self.npts - 1) * i 290 291 xval = 1.0 * self._inner_mouse_x * numpy.cos(phi) 292 yval = 1.0 * self._inner_mouse_x * numpy.sin(phi) 353 293 354 294 x.append(xval) 355 295 y.append(yval) 356 296 357 self.inner_marker.set(xdata=[self.sign * math.fabs(self._inner_mouse_x)],297 self.inner_marker.set(xdata=[self.sign * numpy.fabs(self._inner_mouse_x)], 358 298 ydata=[0]) 359 299 self.inner_circle.set_data(x, y) … … 366 306 self._inner_save_x = self._inner_mouse_x 367 307 self._inner_save_y = self._inner_mouse_y 368 self.base.freeze_axes()369 308 370 309 def moveend(self, ev): … … 396 335 self.update() 397 336 398 399 def get_params(self): 337 def getParams(self): 400 338 """ 401 339 Store a copy of values of parameters of the slicer into a dictionary. 402 403 340 :return params: the dictionary created 404 405 341 """ 406 342 params = {} 407 params["radius"] = math.fabs(self._inner_mouse_x)343 params["radius"] = numpy.fabs(self._inner_mouse_x) 408 344 return params 409 345 410 def set _params(self, params):346 def setParams(self, params): 411 347 """ 412 348 Receive a dictionary and reset the slicer with values contained … … 435 371 self.base = base 436 372 self.is_inside = side 437 self.qmax = min( math.fabs(self.base.data.xmax),438 math.fabs(self.base.data.xmin)) # must be positive373 self.qmax = min(numpy.fabs(self.base.data.xmax), 374 numpy.fabs(self.base.data.xmin)) # must be positive 439 375 self.connect = self.base.connect 440 376 … … 448 384 self.sign = -1 449 385 # Inner circle 450 self.outer_circle = RingInteractor(self, self. base.subplot, 'blue',386 self.outer_circle = RingInteractor(self, self.axes, 'blue', 451 387 zorder=zorder + 1, r=self.qmax / 1.8, 452 388 sign=self.sign) … … 455 391 self._post_data() 456 392 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 393 def set_layer(self, n): 475 394 """ 476 395 Allow adding plot to the same panel 477 478 396 :param n: the number of layer 479 480 397 """ 481 398 self.layernum = n … … 489 406 self.outer_circle.clear() 490 407 self.base.connect.clearall() 491 # self.base.Unbind(EVT_SLICER_PARS)492 408 493 409 def update(self): … … 498 414 # Update locations 499 415 self.outer_circle.update() 500 # if self.is_inside != None:416 self._post_data() 501 417 out = self._post_data() 502 418 return out … … 507 423 can restore on Esc. 508 424 """ 509 self.base.freeze_axes()510 425 self.outer_circle.save(ev) 511 426 … … 521 436 522 437 # If we have no data, just return 523 if data ==None:438 if data is None: 524 439 return 525 440 mask = data.mask … … 527 442 528 443 rmin = 0 529 rmax = math.fabs(self.outer_circle.get_radius())530 531 # # create the data1D Q average of data2D444 rmax = numpy.fabs(self.outer_circle.get_radius()) 445 446 # Create the data1D Q average of data2D 532 447 mask = Ringcut(r_min=rmin, r_max=rmax) 533 448 … … 536 451 else: 537 452 out = (mask(data)) 538 # self.base.data.mask=out539 453 return out 540 454 … … 566 480 pass 567 481 568 def get _params(self):482 def getParams(self): 569 483 """ 570 484 Store a copy of values of parameters of the slicer into a dictionary. … … 574 488 """ 575 489 params = {} 576 params["outer_radius"] = math.fabs(self.outer_circle._inner_mouse_x)490 params["outer_radius"] = numpy.fabs(self.outer_circle._inner_mouse_x) 577 491 return params 578 492 579 def set _params(self, params):493 def setParams(self, params): 580 494 """ 581 495 Receive a dictionary and reset the slicer with values contained … … 585 499 values the user assigned to the slicer. 586 500 """ 587 outer = math.fabs(params["outer_radius"])588 # #Update the picture501 outer = numpy.fabs(params["outer_radius"]) 502 # Update the picture 589 503 self.outer_circle.set_cursor(outer, self.outer_circle._inner_mouse_y) 590 # #Post the data given the nbins entered by the user504 # Post the data given the nbins entered by the user 591 505 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 506 599 507 def draw(self):
Note: See TracChangeset
for help on using the changeset viewer.