source: sasview/guiframe/local_perspectives/plotting/boxSum.py @ 7292e8a

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 7292e8a was 18eba35, checked in by Gervaise Alina <gervyh@…>, 16 years ago

small bugs fixed: clearing slicer improved

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