Changeset b40ad40 in sasview for src/sas/guiframe/local_perspectives/plotting/SectorSlicer.py
- Timestamp:
- Mar 5, 2015 4:53:03 PM (9 years ago)
- Branches:
- master, 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, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- c4f6851
- Parents:
- c039589
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/guiframe/local_perspectives/plotting/SectorSlicer.py
r79492222 rb40ad40 1 1 """ 2 Sector interactor 3 """ 2 4 import math 3 5 import wx 4 #from copy import deepcopy5 6 from BaseInteractor import _BaseInteractor 6 7 from sas.guiframe.events import NewPlotEvent … … 16 17 """ 17 18 def __init__(self, base, axes, color='black', zorder=3): 18 19 19 20 _BaseInteractor.__init__(self, base, axes, color=color) 20 21 ## Class initialization 21 22 self.markers = [] 22 self.axes = axes 23 ## connect the plot to event 23 self.axes = axes 24 ## connect the plot to event 24 25 self.connect = self.base.connect 25 26 ## compute qmax limit to reset the graph 27 x = math.pow(max(self.base.data2D.xmax, 26 27 ## compute qmax limit to reset the graph 28 x = math.pow(max(self.base.data2D.xmax, 28 29 math.fabs(self.base.data2D.xmin)), 2) 29 y = math.pow(max(self.base.data2D.ymax, 30 y = math.pow(max(self.base.data2D.ymax, 30 31 math.fabs(self.base.data2D.ymin)), 2) 31 32 self.qmax = math.sqrt(x + y) … … 33 34 self.nbins = 20 34 35 ## Angle of the middle line 35 self.theta2 = math.pi /336 self.theta2 = math.pi / 3 36 37 ## Absolute value of the Angle between the middle line and any side line 37 self.phi = math.pi /1238 self.phi = math.pi / 12 38 39 ## Middle line 39 self.main_line = LineInteractor(self, self.base.subplot, color='blue', 40 self.main_line = LineInteractor(self, self.base.subplot, color='blue', 40 41 zorder=zorder, r=self.qmax, 41 theta=self.theta2)42 theta=self.theta2) 42 43 self.main_line.qmax = self.qmax 43 44 ## Right Side line 44 45 self.right_line = SideInteractor(self, self.base.subplot, color='black', 45 46 phi=-1*self.phi, theta2=self.theta2)46 zorder=zorder, r=self.qmax, 47 phi=-1 * self.phi, theta2=self.theta2) 47 48 self.right_line.qmax = self.qmax 48 ## Left Side line 49 ## Left Side line 49 50 self.left_line = SideInteractor(self, self.base.subplot, color='black', 50 51 zorder=zorder, r=self.qmax, 51 52 phi=self.phi, theta2=self.theta2) 52 53 self.left_line.qmax = self.qmax 53 ## draw the sector 54 ## draw the sector 54 55 self.update() 55 56 self._post_data() … … 60 61 """ 61 62 receive an event containing parameters values to reset the slicer 62 63 :param event: event of type SlicerParameterEvent with params as 63 64 :param event: event of type SlicerParameterEvent with params as 64 65 attribute 65 66 66 67 """ 67 68 wx.PostEvent(self.base.parent, … … 71 72 self.set_params(event.params) 72 73 self.base.update() 73 74 74 75 def set_layer(self, n): 75 76 """ 76 77 Allow adding plot to the same panel 77 78 78 79 :param n: the number of layer 79 80 80 81 """ 81 82 self.layernum = n 82 83 self.update() 83 84 84 85 def clear(self): 85 86 """ … … 92 93 self.base.connect.clearall() 93 94 self.base.Unbind(EVT_SLICER_PARS) 94 95 95 96 def update(self): 96 97 """ … … 98 99 resetting the widgets. 99 100 """ 100 # Update locations 101 ## Check if the middle line was dragged and 102 #update the picture accordingly 101 # Update locations 102 ## Check if the middle line was dragged and 103 #update the picture accordingly 103 104 if self.main_line.has_move: 104 105 self.main_line.update() 105 self.right_line.update(delta=-self.left_line.phi/2, 106 mline=self.main_line.theta) 107 self.left_line.update(delta=self.left_line.phi/2, 106 self.right_line.update(delta=-self.left_line.phi / 2, 108 107 mline=self.main_line.theta) 109 ## Check if the left side has moved and update the slicer accordingly 108 self.left_line.update(delta=self.left_line.phi / 2, 109 mline=self.main_line.theta) 110 ## Check if the left side has moved and update the slicer accordingly 110 111 if self.left_line.has_move: 111 112 self.main_line.update() … … 113 114 side=True, left=True) 114 115 self.right_line.update(phi=self.left_line.phi, delta=None, 115 116 117 ## Check if the right side line has moved and 116 mline=self.main_line, side=True, 117 left=False, right=True) 118 ## Check if the right side line has moved and 118 119 #update the slicer accordingly 119 120 if self.right_line.has_move: … … 122 123 side=True, left=False, right=True) 123 124 self.left_line.update(phi=self.right_line.phi, delta=None, 124 125 125 mline=self.main_line, side=True, left=False) 126 126 127 def save(self, ev): 127 128 """ … … 137 138 """ 138 139 compute sector averaging of data2D into data1D 139 140 140 141 :param nbins: the number of point to plot for the average 1D data 141 142 """ … … 147 148 ## Averaging 148 149 from sas.dataloader.manipulations import SectorQ 149 radius = self.qmax 150 phimin = 150 radius = self.qmax 151 phimin = -self.left_line.phi + self.main_line.theta 151 152 phimax = self.left_line.phi + self.main_line.theta 152 153 if nbins == None: 153 154 nbins = 20 154 155 sect = SectorQ(r_min=0.0, r_max=radius, 155 156 157 156 phi_min=phimin + math.pi, 157 phi_max=phimax + math.pi, nbins=nbins) 158 158 159 sector = sect(self.base.data2D) 159 160 ##Create 1D data resulting from average 160 161 161 162 if hasattr(sector, "dxl"): 162 163 dxl = sector.dxl … … 186 187 new_plot.id = "SectorQ" + self.base.data2D.name 187 188 new_plot.is_data = True 188 self.base.parent.update_theory(data_id=data.id, \ 189 theory=new_plot) 190 wx.PostEvent(self.base.parent, NewPlotEvent(plot=new_plot, 191 title="SectorQ" + self.base.data2D.name)) 192 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)) 192 193 193 def moveend(self, ev): 194 194 """ 195 Called a dragging motion ends.Get slicer event 195 Called a dragging motion ends.Get slicer event 196 196 """ 197 197 self.base.thaw_axes() … … 202 202 ## Send slicer paramers to plotter2D 203 203 wx.PostEvent(self.base, event) 204 204 205 205 def restore(self): 206 206 """ … … 216 216 """ 217 217 pass 218 218 219 219 def set_cursor(self, x, y): 220 220 """ 221 221 """ 222 222 pass 223 223 224 224 def get_params(self): 225 225 """ 226 226 Store a copy of values of parameters of the slicer into a dictionary. 227 227 228 228 :return params: the dictionary created 229 229 230 230 """ 231 231 params = {} 232 ## Always make sure that the left and the right line are at phi 232 ## Always make sure that the left and the right line are at phi 233 233 ## angle of the middle line 234 234 if math.fabs(self.left_line.phi) != math.fabs(self.right_line.phi): … … 236 236 msg += " %f, %f" % (self.left_line.phi, self.right_line.phi) 237 237 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)238 params["Phi [deg]"] = self.main_line.theta * 180 / math.pi 239 params["Delta_Phi [deg]"] = math.fabs(self.left_line.phi * 180 / math.pi) 240 240 params["nbins"] = self.nbins 241 241 return params 242 242 243 243 def set_params(self, params): 244 244 """ 245 Receive a dictionary and reset the slicer with values contained 245 Receive a dictionary and reset the slicer with values contained 246 246 in the values of the dictionary. 247 248 :param params: a dictionary containing name of slicer parameters and 247 248 :param params: a dictionary containing name of slicer parameters and 249 249 values the user assigned to the slicer. 250 250 """ 251 main = params["Phi [deg]"] * math.pi/180252 phi = math.fabs(params["Delta_Phi [deg]"] * math.pi /180)251 main = params["Phi [deg]"] * math.pi / 180 252 phi = math.fabs(params["Delta_Phi [deg]"] * math.pi / 180) 253 253 self.nbins = int(params["nbins"]) 254 254 self.main_line.theta = main … … 257 257 self.right_line.update(phi=phi, delta=None, mline=self.main_line, 258 258 side=True, right=True) 259 self.left_line.update(phi=phi, delta=None, 259 self.left_line.update(phi=phi, delta=None, 260 260 mline=self.main_line, side=True) 261 261 ## post the new corresponding data 262 262 self._post_data(nbins=self.nbins) 263 263 264 264 def freeze_axes(self): 265 265 """ 266 266 """ 267 267 self.base.freeze_axes() 268 268 269 269 def thaw_axes(self): 270 270 """ … … 277 277 self.base.draw() 278 278 279 279 280 280 class SideInteractor(_BaseInteractor): 281 281 """ 282 282 Draw an oblique line 283 283 284 284 :param phi: the phase between the middle line and one side line 285 285 :param theta2: the angle between the middle line and x- axis 286 286 287 287 """ 288 288 def __init__(self, base, axes, color='black', zorder=5, r=1.0, 289 phi=math.pi /4, theta2= math.pi/3):289 phi=math.pi / 4, theta2=math.pi / 3): 290 290 """ 291 291 """ … … 295 295 self.axes = axes 296 296 ## compute the value of the angle between the current line and 297 ## the x-axis 297 ## the x-axis 298 298 self.save_theta = theta2 + phi 299 299 self.theta = theta2 + phi … … 309 309 x2 = -1 * self.radius * math.cos(self.theta) 310 310 y2 = -1 * self.radius * math.sin(self.theta) 311 ## defining a new marker 312 try: 313 self.inner_marker = self.axes.plot([x1/2.5], [y1/2.5], linestyle='', 314 marker='s', markersize=10, 315 color=self.color, alpha=0.6, 316 pickradius=5, label="pick", 317 # Prefer this to other lines 318 zorder=zorder, visible=True)[0] 319 except: 320 self.inner_marker = self.axes.plot([x1/2.5],[y1/2.5], linestyle='', 321 marker='s', markersize=10, 322 color=self.color, alpha=0.6, 323 label="pick", visible=True)[0] 324 message = "\nTHIS PROTOTYPE NEEDS THE LATEST" 325 message += " VERSION OF MATPLOTLIB\n Get the SVN version that" 326 message += " is at least as recent as June 1, 2007" 327 owner = self.base.base.parent 328 wx.PostEvent(owner, 329 StatusEvent(status="sectorSlicer: %s" % message)) 330 311 ## defining a new marker 312 self.inner_marker = self.axes.plot([x1 / 2.5], [y1 / 2.5], linestyle='', 313 marker='s', markersize=10, 314 color=self.color, alpha=0.6, 315 pickradius=5, label="pick", 316 zorder=zorder, visible=True)[0] 317 331 318 ## Defining the current line 332 319 self.line = self.axes.plot([x1, x2], [y1, y2], 333 334 320 linestyle='-', marker='', 321 color=self.color, visible=True)[0] 335 322 ## Flag to differentiate the left line from the right line motion 336 323 self.left_moving = False … … 339 326 ## connecting markers and draw the picture 340 327 self.connect_markers([self.inner_marker, self.line]) 341 328 342 329 def set_layer(self, n): 343 330 """ 344 331 Allow adding plot to the same panel 345 332 346 333 :param n: the number of layer 347 334 348 335 """ 349 336 self.layernum = n 350 337 self.update() 351 338 352 339 def clear(self): 353 340 """ … … 362 349 for item in range(len(self.axes.lines)): 363 350 del self.axes.lines[0] 364 351 365 352 def update(self, phi=None, delta=None, mline=None, 366 side=False, left= 353 side=False, left=False, right=False): 367 354 """ 368 355 Draw oblique line 369 356 370 357 :param phi: the phase between the middle line and the current line 371 358 :param delta: phi/2 applied only when the mline was moved 372 359 373 360 """ 374 361 #print "update left or right ", self.has_move … … 386 373 if side: 387 374 self.theta = mline.theta + self.phi 388 389 if mline != None 375 376 if mline != None: 390 377 if delta != 0: 391 378 self.theta2 = mline + delta … … 400 387 x2 = -1 * self.radius * math.cos(theta3) 401 388 y2 = -1 * self.radius * math.sin(theta3) 402 self.inner_marker.set(xdata=[x1 /2.5], ydata=[y1/2.5])403 self.line.set(xdata=[x1, x2], ydata=[y1, y2]) 404 389 self.inner_marker.set(xdata=[x1 / 2.5], ydata=[y1 / 2.5]) 390 self.line.set(xdata=[x1, x2], ydata=[y1, y2]) 391 405 392 def save(self, ev): 406 393 """ … … 416 403 self.has_move = False 417 404 self.base.moveend(ev) 418 405 419 406 def restore(self): 420 407 """ … … 433 420 if self.theta2 - self.theta <= 0 and self.theta2 > 0: 434 421 self.restore() 435 return 422 return 436 423 elif self.theta2 < 0 and self.theta < 0 and \ 437 self.theta -self.theta2 >= 0:438 self.restore() 439 return 424 self.theta - self.theta2 >= 0: 425 self.restore() 426 return 440 427 elif self.theta2 < 0 and self.theta > 0 and \ 441 (self.theta2 + 2 * math.pi - self.theta) >= math.pi/2: 442 #print "my theta", self.theta 443 self.restore() 444 return 428 (self.theta2 + 2 * math.pi - self.theta) >= math.pi / 2: 429 self.restore() 430 return 445 431 elif self.theta2 < 0 and self.theta < 0 and \ 446 (self.theta2 - self.theta) >= math.pi/2: 447 #print "my theta", self.theta 448 self.restore() 449 return 450 elif self.theta2 > 0 and (self.theta2-self.theta >= math.pi/2 or \ 451 (self.theta2-self.theta >= math.pi/2)): 452 #print "self theta encore" 453 self.restore() 454 return 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)): 437 self.restore() 438 return 455 439 else: 456 #print "left move" 457 if self.theta < 0 and (self.theta + math.pi*2-self.theta2) <= 0: 458 self.restore() 459 return 460 elif self.theta2 < 0 and (self.theta-self.theta2) <= 0: 461 self.restore() 462 return 463 elif self.theta > 0 and self.theta-self.theta2 <= 0: 464 #print "my theta", self.theta 465 self.restore() 466 return 467 elif self.theta-self.theta2 >= math.pi/2 or \ 468 ((self.theta + math.pi * 2 - self.theta2) >= math.pi/2 and \ 440 if self.theta < 0 and (self.theta + math.pi * 2 - self.theta2) <= 0: 441 self.restore() 442 return 443 elif self.theta2 < 0 and (self.theta - self.theta2) <= 0: 444 self.restore() 445 return 446 elif self.theta > 0 and self.theta - self.theta2 <= 0: 447 self.restore() 448 return 449 elif self.theta - self.theta2 >= math.pi / 2 or \ 450 ((self.theta + math.pi * 2 - self.theta2) >= math.pi / 2 and \ 469 451 self.theta < 0 and self.theta2 > 0): 470 #print "self theta encore" 471 self.restore() 472 return 473 452 self.restore() 453 return 454 474 455 self.phi = math.fabs(self.theta2 - self.theta) 475 456 if self.phi > math.pi: 476 457 self.phi = 2 * math.pi - math.fabs(self.theta2 - self.theta) 477 458 self.base.base.update() 478 459 479 460 def set_cursor(self, x, y): 480 461 """ … … 482 463 self.move(x, y, None) 483 464 self.update() 484 465 485 466 def get_params(self): 486 467 """ … … 490 471 params["theta"] = self.theta 491 472 return params 492 473 493 474 def set_params(self, params): 494 475 """ 495 476 """ 496 x = params["radius"] 477 x = params["radius"] 497 478 self.set_cursor(x, None) 498 479 499 480 500 481 class LineInteractor(_BaseInteractor): … … 503 484 """ 504 485 def __init__(self, base, axes, color='black', 505 zorder=5, r=1.0, theta=math.pi /4):486 zorder=5, r=1.0, theta=math.pi / 4): 506 487 """ 507 488 """ 508 489 _BaseInteractor.__init__(self, base, axes, color=color) 509 490 510 491 self.markers = [] 511 492 self.axes = axes 512 self.save_theta = theta 513 self.theta = theta493 self.save_theta = theta 494 self.theta = theta 514 495 self.radius = r 515 496 self.scale = 10.0 … … 517 498 x1 = self.radius * math.cos(self.theta) 518 499 y1 = self.radius * math.sin(self.theta) 519 x2 = -1*self.radius * math.cos(self.theta) 520 y2 = -1*self.radius * math.sin(self.theta) 521 try: 522 # Inner circle marker 523 self.inner_marker = self.axes.plot([x1/2.5], [y1/2.5], linestyle='', 524 marker='s', markersize=10, 525 color=self.color, alpha=0.6, 526 pickradius=5, label="pick", 527 # Prefer this to other lines 528 zorder=zorder, 529 visible=True)[0] 530 except: 531 self.inner_marker = self.axes.plot([x1/2.5], [y1/2.5], linestyle='', 532 marker='s', markersize=10, 533 color=self.color, alpha=0.6, 534 label="pick", 535 visible=True)[0] 536 message = "\nTHIS PROTOTYPE NEEDS THE LATEST VERSION" 537 message += " OF MATPLOTLIB\n Get the SVN version that is at" 538 message += " least as recent as June 1, 2007" 500 x2 = -1 * self.radius * math.cos(self.theta) 501 y2 = -1 * self.radius * math.sin(self.theta) 502 # Inner circle marker 503 self.inner_marker = self.axes.plot([x1 / 2.5], [y1 / 2.5], linestyle='', 504 marker='s', markersize=10, 505 color=self.color, alpha=0.6, 506 pickradius=5, label="pick", 507 zorder=zorder, 508 visible=True)[0] 539 509 self.line = self.axes.plot([x1, x2], [y1, y2], 540 541 510 linestyle='-', marker='', 511 color=self.color, visible=True)[0] 542 512 self.npts = 20 543 513 self.has_move = False … … 550 520 self.layernum = n 551 521 self.update() 552 522 553 523 def clear(self): 554 524 """ … … 562 532 for item in range(len(self.axes.lines)): 563 533 del self.axes.lines[0] 564 534 565 535 def update(self, theta=None): 566 536 """ 567 537 Draw the new roughness on the graph. 568 538 """ 569 539 570 540 if theta != None: 571 541 self.theta = theta … … 574 544 x2 = -1 * self.radius * math.cos(self.theta) 575 545 y2 = -1 * self.radius * math.sin(self.theta) 576 577 self.inner_marker.set(xdata=[x1 /2.5], ydata=[y1/2.5])578 self.line.set(xdata=[x1, x2], ydata=[y1, y2]) 579 546 547 self.inner_marker.set(xdata=[x1 / 2.5], ydata=[y1 / 2.5]) 548 self.line.set(xdata=[x1, x2], ydata=[y1, y2]) 549 580 550 def save(self, ev): 581 551 """ … … 583 553 can restore on Esc. 584 554 """ 585 self.save_theta = self.theta555 self.save_theta = self.theta 586 556 self.base.freeze_axes() 587 557 … … 591 561 self.has_move = False 592 562 self.base.moveend(ev) 593 563 594 564 def restore(self): 595 565 """ … … 605 575 self.has_move = True 606 576 self.base.base.update() 607 577 608 578 def set_cursor(self, x, y): 609 579 """ … … 611 581 self.move(x, y, None) 612 582 self.update() 613 583 614 584 def get_params(self): 615 585 """ … … 619 589 params["theta"] = self.theta 620 590 return params 621 591 622 592 def set_params(self, params): 623 593 """ 624 594 """ 625 x = params["radius"] 595 x = params["radius"] 626 596 self.set_cursor(x, None) 627
Note: See TracChangeset
for help on using the changeset viewer.