source: sasview/guiframe/local_perspectives/plotting/boxSum.py @ 3b909b7

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 3b909b7 was 3b909b7, checked in by Gervaise Alina <gervyh@…>, 15 years ago

allow annulus to plot no matter the order of the circle
boxslicer draw given data boundaries

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