source: sasview/guiframe/local_perspectives/plotting/boxSlicer.py @ 116da060

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 116da060 was 030873e, checked in by Gervaise Alina <gervyh@…>, 16 years ago

working on boxslicer translation

  • Property mode set to 100644
File size: 24.0 KB
Line 
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
9# Debug printout
10#from config import printEVT
11from BaseInteractor import _BaseInteractor
12from copy import deepcopy
13import math
14
15#from Plotter1D import AddPlotEvent
16import SlicerParameters
17import wx
18
19class BoxInteractor(_BaseInteractor):
20    """
21         Select an annulus through a 2D plot
22    """
23    def __init__(self,base,axes,color='black', zorder=3,
24                  x_min=0.0025, x_max=0.0025, y_min=0.0025, y_max=0.0025):
25       
26        _BaseInteractor.__init__(self, base, axes, color=color)
27        self.markers = []
28        self.axes = axes
29        self.qmax = self.base.qmax
30        self.connect = self.base.connect
31        self.xmin= -1* x_min
32        self.ymin= -1* y_min
33       
34        self.xmax= x_max
35        self.ymax=  y_max
36       
37        self.theta2= math.pi/4
38        ## Number of points on the plot
39        self.nbins = 20
40        self.count=0
41        self.error=0
42        self.main_line = LineInteractor(self, self.base.subplot,color='orange',
43                                         zorder=zorder, ymin=y_min ,ymax=y_max,
44                                           theta= self.theta2)
45        self.main_line.qmax = self.base.qmax
46       
47        self.left_line = VerticalLine(self, self.base.subplot,color='blue', 
48                                      zorder=zorder,
49                                      mline= self.main_line, 
50                                        ymin= self.ymin , 
51                                        ymax= self.ymax ,
52                                        xmin=self.xmin,
53                                        xmax=self.xmin,
54                                        theta2= self.theta2)
55        self.left_line.qmax = self.base.qmax
56       
57        self.right_line= VerticalLine(self, self.base.subplot,color='black', 
58                                      zorder=zorder,
59                                      mline= self.main_line, 
60                                     ymin= self.ymin , 
61                                     ymax= self.ymax,
62                                    xmin= self.xmax,
63                                    xmax= self.xmax,
64                                    theta2= self.theta2)
65        self.right_line.qmax = self.base.qmax
66       
67        self.top_line= HorizontalLine(self, self.base.subplot,color='green', 
68                                      zorder=zorder,
69                                      mline= self.main_line,
70                                      xmin=self.right_line.x1,
71                                      xmax=self.left_line.x1,
72                                      ymin=self.right_line.y1,
73                                      ymax=self.left_line.y1)
74        self.top_line.qmax= self.base.qmax
75       
76        self.bottom_line= HorizontalLine(self, self.base.subplot,color='grey', 
77                                      zorder=zorder,
78                                      mline= self.main_line,
79                                      xmin=self.right_line.x2,
80                                      xmax=self.left_line.x2,
81                                      ymin=self.right_line.y2,
82                                      ymax=self.left_line.y2)
83        self.bottom_line.qmax= self.base.qmax
84        self.update()
85        #self._post_data()
86       
87        # Bind to slice parameter events
88        self.base.parent.Bind(SlicerParameters.EVT_SLICER_PARS, self._onEVT_SLICER_PARS)
89
90
91    def _onEVT_SLICER_PARS(self, event):
92        #printEVT("AnnulusSlicer._onEVT_SLICER_PARS")
93        event.Skip()
94        if event.type == self.__class__.__name__:
95            #self.set_params(event.params)
96            self.base.update()
97
98    def update_and_post(self):
99        self.update()
100        self._post_data()
101
102    def save_data(self, path, image, x, y):
103        output = open(path, 'w')
104       
105        data_x, data_y = self.get_data(image, x, y)
106       
107        output.write("<phi>  <average>\n")
108        for i in range(len(data_x)):
109            output.write("%g  %g\n" % (data_x[i], data_y[i]))
110        output.close()
111
112    def set_layer(self, n):
113        self.layernum = n
114        self.update()
115       
116    def clear(self):
117        self.clear_markers()
118        self.left_line.clear()
119        self.right_line.clear()
120        self.top_line.clear()
121        self.bottom_line.clear()
122        self.main_line.clear()
123        #self.base.connect.disconnect()
124        self.base.parent.Unbind(SlicerParameters.EVT_SLICER_PARS)
125       
126    def update(self):
127        """
128        Respond to changes in the model by recalculating the profiles and
129        resetting the widgets.
130        """
131       
132        if self.main_line.has_move:
133           
134            self.main_line.update()
135            self.left_line.update(
136                                  xmin= self.xmin,
137                                  xmax= self.xmin,
138                                  ymin= self.ymin,
139                                  ymax=self.ymax,
140                                  translation=True)
141            self.right_line.update(
142                                   xmin= self.xmax,
143                                  xmax= self.xmax,
144                                  ymin= self.ymin,
145                                  ymax=self.ymax,
146                                  translation=True)
147            self.top_line.update(xmin= self.right_line.x1,
148                                 xmax= self.left_line.x1,
149                                 ymin= self.right_line.y1,
150                                 ymax= self.left_line.y1)
151            self.bottom_line.update(xmin= self.right_line.x2,
152                                 xmax= self.left_line.x2,
153                                 ymin= self.right_line.y2,
154                                 ymax= self.left_line.y2)
155        if self.left_line.has_move:
156            print "left has moved"
157            self.left_line.update()
158            self.right_line.update(opline= self.left_line )
159           
160            self.top_line.update(xmin= self.right_line.x2,
161                                 xmax= self.left_line.x1,
162                                 ymin= self.right_line.y2,
163                                 ymax= self.left_line.y1)
164           
165           
166            self.bottom_line.update(xmin= self.right_line.x1,
167                                 xmax= self.left_line.x2,
168                                 ymin= self.right_line.y1,
169                                 ymax= self.left_line.y2)
170           
171        if self.right_line.has_move:
172            print "right has moved"
173            self.right_line.update()
174            self.left_line.update(opline= self.right_line )
175           
176            self.top_line.update(xmin= self.right_line.x1,
177                                 xmax= self.left_line.x2,
178                                 ymin= self.right_line.y1,
179                                 ymax= self.left_line.y2)
180           
181            self.bottom_line.update(xmin= self.right_line.x2,
182                                 xmax= self.left_line.x1,
183                                 ymin= self.right_line.y2,
184                                 ymax= self.left_line.y1)
185        if self.top_line.has_move:
186            self.top_line.update(translation=True)
187    def save(self, ev):
188        """
189        Remember the roughness for this layer and the next so that we
190        can restore on Esc.
191        """
192        self.base.freeze_axes()
193        self.inner_circle.save(ev)
194        self.outer_circle.save(ev)
195
196    def _post_data(self):
197        # Compute data
198        #data = self.base.data2D
199        #from DataLoader.manipulations import  Boxavg
200        #radius = math.sqrt(math.pow(self.qmax,2)+math.pow(self.qmax,2))
201        #x_min= self.left_line.xmin
202        #x_max= self.right_line.xmax
203        #y_min= self.bottom_line.y
204        #y_max= self.top_line.y
205        #box =  Boxavg (x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max)
206       
207        #self.count, self.error= box(self.base.data2D)
208       
209        print "post data"
210             
211                                       
212    def moveend(self, ev):
213        self.base.thaw_axes()
214       
215        # Post paramters
216        event = SlicerParameters.SlicerParameterEvent()
217        event.type = self.__class__.__name__
218        #event.params = self.get_params()
219        wx.PostEvent(self.base.parent, event)
220
221        self._post_data()
222           
223    def restore(self):
224        """
225        Restore the roughness for this layer.
226        """
227        self.inner_circle.restore()
228        self.outer_circle.restore()
229
230    def move(self, x, y, ev):
231        """
232        Process move to a new position, making sure that the move is allowed.
233        """
234        pass
235       
236    def set_cursor(self, x, y):
237        pass
238       
239    def get_params(self):
240        params = {}
241        params["x_min"] = self.left_line.L_width
242        params["x_max"] = self.right_line.R_width
243        #params["y_min"] = self.bottom_line.y
244        #params["y_max"] = self.top_line.y
245        params["count"] = self.count
246        params["error"] = self.error
247        params["phi"] = self.main_line.theta
248        return params
249   
250    def set_params(self, params):
251       
252        x_min = params["x_min"] 
253        x_max = params["x_max"] 
254        #y_min = params["y_min"]
255        #y_max = params["y_max"]
256        theta = params["theta"]
257       
258        self.left_line.update(ymin= y_min ,ymax= y_max)
259        self.right_line.update(ymin= y_min ,ymax= y_max)
260        #self.top_line.update( xmin= x_min ,xmax= xmax)
261        #self.bottom_line.update(xmin= xmin ,xmax= xmax)
262        self.main_line.update(theta)
263       
264        self._post_data()
265    def freeze_axes(self):
266        self.base.freeze_axes()
267       
268    def thaw_axes(self):
269        self.base.thaw_axes()
270
271    def draw(self):
272        self.base.draw()
273
274class HorizontalLine(_BaseInteractor):
275    """
276         Select an annulus through a 2D plot
277    """
278    def __init__(self,base,axes,color='black', zorder=5,mline=None,ymin=None, ymax=None, y=0.5,
279                 xmin=0.0,xmax=0.5,
280                 theta2= math.pi/3 ):
281       
282        _BaseInteractor.__init__(self, base, axes, color=color)
283        self.markers = []
284        self.axes = axes
285       
286        self.ymin= ymin
287        self.save_ymin = ymin
288        self.mline = mline
289        self.ymax= ymax
290        self.save_ymax = ymax
291        self.xmin = xmin
292        self.save_xmin = xmin
293        self.xmax = xmax
294        self.save_xmax = xmax
295        self.top_hight= self.ymax
296       
297        self.theta2 = theta2
298       
299        self.line = self.axes.plot([self.xmax,self.xmin],
300                                   [self.ymax,self.ymin],
301                                      linestyle='-', marker='',
302                                      color=self.color,
303                                      visible=True)[0]
304 
305       
306       
307        self.npts = 20
308        self.has_move=False
309        self.connect_markers([self.line])
310        self.update(xmin= self.xmin,
311                    xmax= self.xmax,
312                    ymin= self.ymin,
313                    ymax=  self.ymax)
314
315    def set_layer(self, n):
316        self.layernum = n
317        self.update()
318       
319    def clear(self):
320        self.clear_markers()
321        try:
322           
323            self.line.remove()
324        except:
325            # Old version of matplotlib
326            for item in range(len(self.axes.lines)):
327                del self.axes.lines[0]
328   
329    def get_radius(self):
330       
331        return 0
332   
333    def update(self,xmin=None, xmax=None,ymin=None,ymax=None, mline=None,translation=False):
334        """
335        Draw the new roughness on the graph.
336        """
337        if translation :
338            print "translation ",self.top_hight
339            self.x1= self.xmax + self.top_hight*math.sin(math.pi/2 + self.mline.theta)
340            self.x2= self.xmin + self.top_hight*math.sin(math.pi/2 + self.mline.theta)
341            self.y1= self.ymin - self.top_hight*math.cos(math.pi/2 + self.mline.theta)
342            self.y2= self.ymax -self.top_hight*math.cos(math.pi/2 + self.mline.theta)
343            self.line.set(xdata=[self.x1,self.x2],
344                       ydata=[self.y1,self.y2])
345            return
346        #print "update main line", self.has_move
347        self.xmin=xmin
348        self.xmax=xmax
349        self.ymin=ymin
350        self.ymax=ymax
351        self.line.set(xdata=[self.xmin,self.xmax],
352                       ydata=[self.ymin,self.ymax])
353   
354       
355       
356    def save(self, ev):
357        """
358        Remember the roughness for this layer and the next so that we
359        can restore on Esc.
360        """
361        self.save_xmin= self.xmin
362        self.save_xmax= self.xmax
363       
364        self.save_ymin= self.ymin
365        self.save_ymax= self.ymax
366        self.top_hight= self.ymax
367        self.base.freeze_axes()
368
369    def moveend(self, ev):
370       
371        self.has_move=False
372        self.base.moveend(ev)
373           
374    def restore(self):
375        """
376        Restore the roughness for this layer.
377        """
378        self.xmin = self.save_xmin
379        self.xmax = self.save_xmax
380        self.ymin = self.save_ymin
381        self.ymax = self.save_ymax
382
383    def move(self, x, y, ev):
384        """
385        Process move to a new position, making sure that the move is allowed.
386        """
387       
388        self.top_hight= y
389        self.has_move=True
390        self.base.base.update()
391       
392    def set_cursor(self, x, y):
393        self.move(x, y, None)
394        self.update()
395       
396       
397    def get_params(self):
398        params = {}
399        params["radius"] = self.xmin
400        params["theta"] = self.xmax
401        return params
402   
403    def set_params(self, params):
404
405        x = params["radius"] 
406        self.set_cursor(x, self._inner_mouse_y)
407       
408
409
410
411class VerticalLine(_BaseInteractor):
412    """
413         Select an annulus through a 2D plot
414    """
415    def __init__(self,base,axes,color='black', zorder=5, mline=None, ymin=0.0, 
416                 ymax=0.5,xmin=-0.5,xmax=0.5,
417                 theta2= math.pi/3 ):
418       
419        _BaseInteractor.__init__(self, base, axes, color=color)
420        self.markers = []
421        self.axes = axes
422       
423        self.L_width=xmin
424        self.save_L_width=xmin
425       
426        self.save_xmin= xmin
427        self.R_width=xmax
428        self.save_xmax=xmax
429        self.ymin=ymin
430        self.save_ymin= ymin
431        self.ymax=ymax
432        self.save_ymax= ymax
433       
434        self.theta2= theta2
435       
436        self.mline= mline
437     
438        self.detax=0
439        self.deltay=0
440       
441       
442        self.clickxf=0
443        self.clickyf=0
444        self.x1= mline.x1 + xmin*math.cos(math.pi/2 - self.theta2)
445        self.x2= mline.x2 + xmin*math.cos(math.pi/2 - self.theta2)
446        self.y1= mline.y1 - xmin*math.sin(math.pi/2 - self.theta2)
447        self.y2= mline.y2 - xmin*math.sin(math.pi/2 - self.theta2)
448       
449        self.line = self.axes.plot([self.x1,self.x2],[self.y1,self.y2],
450                                      linestyle='-', marker='',
451                                      color=self.color,
452                                      visible=True)[0]
453     
454        self.npts = 20
455        # Check vertical line motion
456        self.has_move=False
457        self.connect_markers([self.line])
458        self.update()
459
460    def set_layer(self, n):
461        self.layernum = n
462        self.update()
463       
464    def clear(self):
465        self.clear_markers()
466        try:
467           
468            self.line.remove()
469        except:
470            # Old version of matplotlib
471            for item in range(len(self.axes.lines)):
472                del self.axes.lines[0]
473   
474   
475    def get_radius(self):
476        return 0
477   
478    def update(self,xmin=None,xmax=None,ymin=None, ymax=None, opline=None,translation=False):
479        """
480        Draw the new roughness on the graph.
481        """
482        if opline !=None:
483            self.x1= -1*opline.x1
484            self.x2= -1*opline.x2
485            self.y1= -1*opline.y1
486            self.y2= -1*opline.y2
487            self.line.set(xdata=[self.x1,self.x2],
488                           ydata=[self.y1,self.y2]) 
489            return
490        if xmin== None:
491            xmin= self.L_width
492        if xmax== None:
493            xmax= self.R_width
494        #print "vertical line: xmin, xmax , ymin , ymax", xmin, self.mline.theta
495        self.x1= self.mline.x1 + xmin*math.cos(math.pi/2 - self.mline.theta)
496        self.x2= self.mline.x2 + xmin*math.cos(math.pi/2 - self.mline.theta)
497        self.y1= self.mline.y1 - xmin*math.sin(math.pi/2 - self.mline.theta)
498        self.y2= self.mline.y2 - xmin*math.sin(math.pi/2 - self.mline.theta)
499        #print "vertical line: main line  value ", self.mline.x1, self.mline.x2, self.mline.y1,self.mline.y2
500        #print "vertical line: new value ", self.x1, self.x2, self.y1,self.y2
501
502        self.line.set(xdata=[self.x1,self.x2], ydata=[self.y1,self.y2]) 
503        if opline !=None:
504            self.line.set(xdata=[-1*self.opline.x1,-1*self.opline.x2],
505                           ydata=[self.opline.y1,self.opline.y2]) 
506            return
507        if translation:
508            print "xmin L_width", xmin, self.L_width
509            self.x1= self.mline.x1 + self.L_width*math.cos(math.pi/2 - self.mline.theta)
510            self.x2= self.mline.x2 + self.L_width*math.cos(math.pi/2 - self.mline.theta)
511            self.y1= self.mline.y1 - self.L_width*math.sin(math.pi/2 - self.mline.theta)
512            self.y2= self.mline.y2 - self.L_width*math.sin(math.pi/2 - self.mline.theta)
513           
514            print"translation x1, x2,y1,y2",self.x1, self.x2,self.y1,self.y2
515            self.line.set(xdata=[self.x1,self.x2], ydata=[self.y1,self.y2]) 
516           
517           
518    def save(self, ev):
519        """
520        Remember the roughness for this layer and the next so that we
521        can restore on Esc.
522        """
523        self.save_L_width= self.L_width
524        self.save_xmin= self.x1
525        self.save_xmax= self.x2
526        self.save_ymin= self.y1
527        self.save_ymax= self.y2
528       
529        self.base.freeze_axes()
530
531    def moveend(self, ev):
532       
533        self.has_move=False
534        self.base.moveend(ev)
535           
536    def restore(self):
537        """
538        Restore the roughness for this layer.
539        """
540        self.xmin = self.save_xmin
541        self.xmax = self.save_xmax
542        self.ymin = self.save_ymin
543        self.ymax = self.save_ymax
544        self.L_width= self.save_L_width
545       
546    def move(self, x, y, ev):
547        """
548        Process move to a new position, making sure that the move is allowed.
549        """
550        self.has_move=True
551        self.L_width = x
552        print "move L_width", self.L_width
553        self.base.base.update()
554       
555       
556    def set_cursor(self, x, y):
557        self.move(x, y, None)
558        self.update()
559       
560       
561    def get_params(self):
562        params = {}
563        params["x"] = self.xmin
564        params["ymin"] = self.ymin
565        params["ymax"] = self.ymax
566        return params
567   
568    def set_params(self, params):
569        """
570            Draw a vertical line given some value of params
571            @param params: a dictionary containing value for x, ymin , ymax to draw
572            a vertical line
573        """
574        x = params["x"] 
575        ymin = params["ymin"] 
576        ymax = params["ymax"] 
577        #self.set_cursor(x, self._inner_mouse_y)
578        self.update(self,x =x,ymin =ymin, ymax =ymax)
579       
580
581       
582class LineInteractor(_BaseInteractor):
583    """
584         Select an annulus through a 2D plot
585    """
586    def __init__(self,base,axes,color='black', zorder=5, ymin=1.0,ymax=1.0,theta=math.pi/4):
587       
588        _BaseInteractor.__init__(self, base, axes, color=color)
589        self.markers = []
590        self.axes = axes
591       
592        self.save_theta = theta
593        self.theta= theta
594       
595        self.radius1 = ymax
596        self.radius2 = ymin
597        self.scale = 10.0
598           
599        # Inner circle
600        self.x1= self.radius1*math.cos(self.theta)
601        self.y1= self.radius1*math.sin(self.theta)
602        self.x2= -1*self.radius2*math.cos(self.theta)
603        self.y2= -1*self.radius2*math.sin(self.theta)
604       
605        self.line = self.axes.plot([self.x1,self.x2],[self.y1,self.y2],
606                                      linestyle='-', marker='',
607                                      color=self.color,
608                                      visible=True)[0]
609     
610        self.npts = 20
611        self.has_move=False
612        self.connect_markers([self.line])
613        self.update()
614
615    def set_layer(self, n):
616       
617        self.layernum = n
618        self.update()
619       
620    def clear(self):
621        """
622            Remove the line of the plot
623        """
624        self.clear_markers()
625        try:
626            self.line.remove()
627        except:
628            # Old version of matplotlib
629            for item in range(len(self.axes.lines)):
630                del self.axes.lines[0]
631       
632       
633       
634    def get_delta_angle(self):
635        """
636            return difference between initial angle and the final angle during
637            rotation
638        """
639        return self.theta - self.save_theta
640       
641    def update(self, theta=None,radius1=None,radius2=None):
642        """
643            Draw a line given and angle relative to the x-axis and a radius
644            @param  theta: the angle realtive to the x-axis
645            @param radius: the distance between the center and one end of the line
646        """
647       
648        if theta !=None:
649            self.theta= theta
650        if radius1 !=None:
651            self.radius1 =radius1
652        if radius2 !=None:
653            self.radius2 =radius2
654        print "update main line", math.degrees(self.theta),self.radius1, self.radius2
655        self.x1= self.radius1*math.cos(self.theta)
656        self.y1= self.radius1*math.sin(self.theta)
657        self.x2= -1*self.radius2*math.cos(self.theta)
658        self.y2= -1*self.radius2*math.sin(self.theta)
659     
660        self.line.set(xdata=[self.x1,self.x2], ydata=[self.y1,self.y2]) 
661     
662       
663       
664    def save(self, ev):
665        """
666        Remember the roughness for this layer and the next so that we
667        can restore on Esc.
668        """
669        self.save_theta= self.theta
670        self.base.freeze_axes()
671
672    def moveend(self, ev):
673       
674        self.has_move=False
675        self.base.moveend(ev)
676           
677    def restore(self):
678        """
679        Restore the roughness for this layer.
680        """
681        self.theta = self.save_theta
682
683    def move(self, x, y, ev):
684        """
685        Process move to a new position, making sure that the move is allowed.
686        """
687        self.theta= math.atan2(y,x)
688        #print "main_line previous theta --- next theta ",math.degrees(self.save_theta),math.degrees(self.theta)
689        self.has_move=True
690        self.base.base.update()
691       
692       
693    def set_cursor(self, x, y):
694       
695        self.move(x, y, None)
696        self.update()
697       
698       
699    def get_params(self):
700        """
701            return params a dictionary containing values of paramters necessary to draw
702            this line
703        """
704        params = {}
705        params["ymax"] = self.radius1
706        params["ymin"] = self.radius2
707        params["theta"] = self.theta
708        return params
709   
710    def set_params(self, params):
711        """
712            Draw the line given value contains by params
713            @param params: dictionary containing name of parameters and their values
714        """
715        radius1 = params["ymax"]
716        radius2 = params["ymin"]
717        theta = params["theta"]
718        self.update(x, theta= theta , radius1 = radius1 ,radius2 = radius2)
719       
720
721
722
723       
Note: See TracBrowser for help on using the repository browser.