source: sasview/guiframe/local_perspectives/plotting/last_boxSlicer.py @ 86340d4

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 86340d4 was 6d920cd, checked in by Gervaise Alina <gervyh@…>, 16 years ago

print statement removed

  • Property mode set to 100644
File size: 20.5 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
15from sans.guicomm.events import NewPlotEvent, StatusEvent,SlicerParameterEvent,EVT_SLICER_PARS
16import SlicerParameters
17import wx
18
19
20class BoxInteractor(_BaseInteractor):
21    """
22         Select an annulus through a 2D plot
23    """
24    def __init__(self,base,axes,color='black', zorder=3,
25                  x_min=0.0025, x_max=0.0025, y_min=0.0025, y_max=0.0025):
26       
27        _BaseInteractor.__init__(self, base, axes, color=color)
28        self.markers = []
29        self.axes = axes
30        self.qmax = self.base.data2D.xmax
31        self.connect = self.base.connect
32        self.x= 0.5*min(math.fabs(self.base.data2D.xmax),math.fabs( self.base.data2D.xmin))
33        self.y= 0.5*min(math.fabs(self.base.data2D.xmax),math.fabs( self.base.data2D.xmin))       
34         
35        self.theta2= math.pi/3
36        ## Number of points on the plot
37        self.nbins = 30
38        self.count=0
39        self.error=0
40        self.averager=None
41        self.left_line = VerticalLine(self, self.base.subplot,color='blue', 
42                                      zorder=zorder,
43                                        ymin= -self.y , 
44                                        ymax= self.y ,
45                                        xmin= -self.x,
46                                        xmax= -self.x)
47        self.left_line.qmax = self.qmax
48       
49        self.right_line= VerticalLine(self, self.base.subplot,color='black', 
50                                      zorder=zorder,
51                                     ymin= -self.y , 
52                                     ymax= self.y,
53                                     xmin= self.x,
54                                     xmax= self.x)
55        self.right_line.qmax = self.qmax
56       
57        self.top_line= HorizontalLine(self, self.base.subplot,color='green', 
58                                      zorder=zorder,
59                                      xmin= -self.x,
60                                      xmax= self.x,
61                                      ymin= self.y,
62                                      ymax= self.y)
63        self.top_line.qmax= self.qmax
64       
65        self.bottom_line= HorizontalLine(self, self.base.subplot,color='gray', 
66                                      zorder=zorder,
67                                      xmin= -self.x,
68                                      xmax= self.x,
69                                      ymin= -self.y,
70                                      ymax= -self.y)
71        self.bottom_line.qmax= self.qmax
72       
73        self.update()
74        self._post_data()
75       
76        # Bind to slice parameter events
77        self.base.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS)
78
79
80    def _onEVT_SLICER_PARS(self, event):
81        wx.PostEvent(self.base, StatusEvent(status="BoxSlicer._onEVT_SLICER_PARS"))
82        event.Skip()
83        if event.type == self.__class__.__name__:
84            self.set_params(event.params)
85            self.base.update()
86
87    def update_and_post(self):
88        self.update()
89        self._post_data()
90
91    def save_data(self, path, image, x, y):
92        output = open(path, 'w')
93       
94        data_x, data_y = self.get_data(image, x, y)
95       
96        output.write("<phi>  <average>\n")
97        for i in range(len(data_x)):
98            output.write("%g  %g\n" % (data_x[i], data_y[i]))
99        output.close()
100
101    def set_layer(self, n):
102        self.layernum = n
103        self.update()
104       
105    def clear(self):
106        self.averager=None
107        self.clear_markers()
108        self.left_line.clear()
109        self.right_line.clear()
110        self.top_line.clear()
111        self.bottom_line.clear()
112        #self.base.connect.disconnect()
113        self.base.Unbind(EVT_SLICER_PARS)
114       
115    def update(self):
116        """
117        Respond to changes in the model by recalculating the profiles and
118        resetting the widgets.
119        """
120       
121        if self.top_line.has_move:
122            #print"top has moved"
123            self.top_line.update()
124            self.bottom_line.update(ymin= -self.top_line.y1,
125                                    ymax= -self.top_line.y2)
126            self.left_line.update(ymin= -self.top_line.y1,
127                                    ymax= -self.top_line.y2)
128            self.right_line.update(ymin= -self.top_line.y1,
129                                    ymax= -self.top_line.y2)
130           
131        if self.bottom_line.has_move:
132            #print "bottom has move"
133            self.bottom_line.update()
134            self.top_line.update(ymin= -self.bottom_line.y1,
135                                    ymax= -self.bottom_line.y2)
136            self.left_line.update(ymin= self.bottom_line.y1,
137                                    ymax= self.top_line.y1)
138            self.right_line.update(ymin= self.bottom_line.y1,
139                                    ymax=self.top_line.y1)
140           
141        if self.left_line.has_move:
142           
143            self.left_line.update()
144            self.right_line.update(xmin = - self.left_line.x1,
145                                   xmax = - self.left_line.x1)
146            self.bottom_line.update(xmin=  self.left_line.x1,
147                                     xmax= self.right_line.x1)
148            self.top_line.update(xmin= self.left_line.x1,
149                                    xmax= self.right_line.x1)
150           
151        if self.right_line.has_move:
152           
153            self.right_line.update()
154            self.left_line.update(xmin = -self.right_line.x1,
155                                   xmax = -self.right_line.x1)
156           
157            self.bottom_line.update(xmin= self.left_line.x1,
158                                 xmax= self.right_line.x1)
159           
160            self.top_line.update(xmin= self.left_line.x1,
161                                    xmax= self.right_line.x1)
162               
163           
164    def save(self, ev):
165        """
166        Remember the roughness for this layer and the next so that we
167        can restore on Esc.
168        """
169        self.base.freeze_axes()
170        self.left_line.save(ev)
171        self.right_line.save(ev)
172        self.top_line.save(ev)
173        self.bottom_line.save(ev)
174    def _post_data(self):
175        pass
176       
177   
178    def post_data(self,new_slab=None , nbins=None):
179        """ post data averaging in Q"""
180        x_min= min(self.left_line.x1, self.right_line.x1)
181        x_max= max(self.left_line.x1, self.right_line.x1)
182       
183        y_min= min(self.top_line.y1, self.bottom_line.y1)
184        y_max= max(self.top_line.y1, self.bottom_line.y1) 
185       
186        if nbins !=None:
187            self.nbins
188        if self.averager==None:
189            if new_slab ==None:
190                raise ValueError,"post data:cannot average , averager is empty"
191            self.averager= new_slab
192        bin_width= (x_max + math.fabs(x_min))/self.nbins
193       
194        box = self.averager( x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max,
195                         bin_width=bin_width)
196       
197        boxavg = box(self.base.data2D)
198       
199        from sans.guiframe.dataFitting import Data1D
200        if hasattr(boxavg,"dxl"):
201            dxl= boxavg.dxl
202        else:
203            dxl= None
204        if hasattr(boxavg,"dxw"):
205            dxw=boxavg.dxw
206        else:
207            dxw= None
208       
209        new_plot = Data1D(x=boxavg.x,y=boxavg.y,dy=boxavg.dy,dxl=dxl,dxw=dxw)
210        new_plot.name = str(self.averager.__name__) +"("+ self.base.data2D.name+")"
211       
212       
213
214        new_plot.source=self.base.data2D.source
215        new_plot.interactive = True
216        #print "loader output.detector",output.source
217        new_plot.detector =self.base.data2D.detector
218        # If the data file does not tell us what the axes are, just assume...
219        new_plot.xaxis("\\rm{Q}", 'rad')
220        new_plot.yaxis("\\rm{Intensity} ","cm^{-1}")
221        new_plot.group_id = str(self.averager.__name__)+self.base.data2D.name
222        new_plot.id = str(self.averager.__name__)
223        wx.PostEvent(self.base.parent, NewPlotEvent(plot=new_plot,
224                                                 title=str(self.averager.__name__) ))
225       
226       
227    def _post_data(self):
228        # Compute data
229        data = self.base.data2D
230        from DataLoader.manipulations import  Boxavg
231        radius = math.sqrt(math.pow(self.qmax,2)+math.pow(self.qmax,2))
232        self.x= math.fabs(self.right_line.x1)
233        self.y= math.fabs(self.top_line.y1 )
234       
235        box =  Boxavg (x_min=-self.x, x_max=self.x, y_min=-self.y, y_max=self.y)
236       
237        self.count, self.error= box(self.base.data2D)
238       
239        #print "post data"
240             
241                                       
242    def moveend(self, ev):
243        self.base.thaw_axes()
244       
245        # Post paramters
246        event = SlicerParameterEvent()
247        event.type = self.__class__.__name__
248        event.params = self.get_params()
249        wx.PostEvent(self.base.parent, event)
250
251        self._post_data()
252           
253    def restore(self):
254        """
255        Restore the roughness for this layer.
256        """
257        self.left_line.restore()
258        self.right_line.restore()
259        self.top_line.restore()
260        self.bottom_line.restore()
261
262    def move(self, x, y, ev):
263        """
264        Process move to a new position, making sure that the move is allowed.
265        """
266        pass
267       
268    def set_cursor(self, x, y):
269        pass
270       
271    def get_params(self):
272        params = {}
273        params["x_max"]= math.fabs(self.right_line.x1)
274        params["y_max"]= math.fabs(self.top_line.y1)
275        params["nbins"]= self.nbins
276        params["errors"] = self.error
277        params["count"]= self.count
278        return params
279   
280    def set_params(self, params):
281       
282        self.x = float(math.fabs(params["x_max"]))
283        self.y = float(math.fabs(params["y_max"] ))
284        self.nbins=params["nbins"]
285        self.left_line.update(xmin= -1*self.x,
286                              xmax = -1*self.x,
287                              ymin= -self.y,
288                              ymax=  self.y, 
289                              )
290        self.right_line.update(xmin= self.x,
291                              xmax = self.x,
292                              ymin= -self.y,
293                              ymax=  self.y, 
294                              )
295        self.top_line.update(xmin= -1*self.x,
296                             xmax= self.x,
297                             ymin= self.y,
298                             ymax= self.y)
299        self.bottom_line.update(xmin= -1*self.x,
300                                 xmax= self.x,
301                                 ymin= -1*self.y,
302                                 ymax= -1*self.y)
303       
304        self.post_data( nbins=None)
305    def freeze_axes(self):
306        self.base.freeze_axes()
307       
308    def thaw_axes(self):
309        self.base.thaw_axes()
310
311    def draw(self):
312        self.base.draw()
313
314class HorizontalLine(_BaseInteractor):
315    """
316         Select an annulus through a 2D plot
317    """
318    def __init__(self,base,axes,color='black', zorder=5,mline=None,ymin=None, ymax=None, y=0.5,
319                 xmin=0.0,xmax=0.5):
320       
321        _BaseInteractor.__init__(self, base, axes, color=color)
322        self.markers = []
323        self.axes = axes
324        self.x1= xmax
325        self.save_x1= xmax
326       
327        self.x2= xmin
328        self.save_x2= xmin
329       
330        self.y1= ymax
331        self.save_y1= ymax
332       
333        self.y2= ymin
334        self.save_y2= ymin
335        self.mline= mline
336        try:
337            # Inner circle marker
338            self.inner_marker = self.axes.plot([0],[self.y1], linestyle='',
339                                          marker='s', markersize=10,
340                                          color=self.color, alpha=0.6,
341                                          pickradius=5, label="pick", 
342                                          zorder=zorder, # Prefer this to other lines
343                                          visible=True)[0]
344        except:
345            self.inner_marker = self.axes.plot([0],[self.y1], linestyle='',
346                                          marker='s', markersize=10,
347                                          color=self.color, alpha=0.6,
348                                          label="pick", 
349                                          visible=True)[0]
350            message  = "\nTHIS PROTOTYPE NEEDS THE LATEST VERSION OF MATPLOTLIB\n"
351            message += "Get the SVN version that is at least as recent as June 1, 2007"
352           
353        self.line = self.axes.plot([self.x1,-self.x1],
354                                   [self.y1,self.y2],
355                                      linestyle='-', marker='',
356                                      color=self.color,
357                                      visible=True)[0]
358       
359        self.npts = 20
360        self.has_move=False
361        self.connect_markers([self.line, self.inner_marker])
362        self.update()
363
364    def set_layer(self, n):
365        self.layernum = n
366        self.update()
367       
368    def clear(self):
369        self.clear_markers()
370        try:
371           
372            self.line.remove()
373        except:
374            # Old version of matplotlib
375            for item in range(len(self.axes.lines)):
376                del self.axes.lines[0]
377   
378    def get_radius(self):
379       
380        return 0
381   
382    def update(self,xmin=None, xmax=None,ymin=None,ymax=None, mline=None,translation=False):
383        """
384        Draw the new roughness on the graph.
385        """
386        if xmin !=None:
387            self.x1 = xmin
388        if ymin !=None:
389            self.y1 = ymin
390        self.inner_marker.set(xdata=[0],ydata=[self.y1])
391        self.line.set(xdata=[self.x1,-self.x1],
392                       ydata=[self.y1,self.y1])
393   
394       
395       
396    def save(self, ev):
397        """
398        Remember the roughness for this layer and the next so that we
399        can restore on Esc.
400        """
401        self.save_x1= self.x1
402        self.save_x2= self.x2
403       
404        self.save_y1= self.y1
405        self.save_y2= self.y2
406   
407       
408        self.base.freeze_axes()
409
410    def moveend(self, ev):
411       
412        self.has_move=False
413        self.base.moveend(ev)
414           
415    def restore(self):
416        """
417        Restore the roughness for this layer.
418        """
419        self.x1 = self.save_x1
420        self.x2 = self.save_x2
421        self.y1 = self.save_y1
422        self.y2 = self.save_y2
423       
424
425    def move(self, x, y, ev):
426        """
427        Process move to a new position, making sure that the move is allowed.
428        """
429        #print "horizontal move x y "
430        self.y1= y
431        self.has_move=True
432        self.base.base.update()
433       
434    def set_cursor(self, x, y):
435        self.move(x, y, None)
436        self.update()
437       
438       
439    def get_params(self):
440        params = {}
441        params["radius"] = self.x1
442        #params["theta"] = self.xmax
443        return params
444   
445    def set_params(self, params):
446
447        x = params["radius"] 
448        self.set_cursor(x, self._inner_mouse_y)
449       
450
451
452
453class VerticalLine(_BaseInteractor):
454    """
455         Select an annulus through a 2D plot
456    """
457    def __init__(self,base,axes,color='black', zorder=5, mline=None, ymin=0.0, 
458                 ymax=0.5,xmin=-0.5,xmax=0.5
459                 ):
460       
461        _BaseInteractor.__init__(self, base, axes, color=color)
462        self.markers = []
463        self.axes = axes
464       
465        self.x1= xmax
466        self.x2= xmin
467        self.y1= ymax
468        self.y2= ymin
469        try:
470            # Inner circle marker
471            self.inner_marker = self.axes.plot([self.x1],[0], linestyle='',
472                                          marker='s', markersize=10,
473                                          color=self.color, alpha=0.6,
474                                          pickradius=5, label="pick", 
475                                          zorder=zorder, # Prefer this to other lines
476                                          visible=True)[0]
477        except:
478            self.inner_marker = self.axes.plot([self.x1],[0], linestyle='',
479                                          marker='s', markersize=10,
480                                          color=self.color, alpha=0.6,
481                                          label="pick", 
482                                          visible=True)[0]
483            message  = "\nTHIS PROTOTYPE NEEDS THE LATEST VERSION OF MATPLOTLIB\n"
484            message += "Get the SVN version that is at least as recent as June 1, 2007"
485           
486        self.line = self.axes.plot([self.x1,self.x2],[self.y1,self.y2],
487                                      linestyle='-', marker='',
488                                      color=self.color,
489                                      visible=True)[0]
490     
491        self.has_move=False
492        self.connect_markers([self.line, self.inner_marker])
493        self.update()
494
495    def set_layer(self, n):
496        self.layernum = n
497        self.update()
498       
499    def clear(self):
500        self.clear_markers()
501        try:
502           
503            self.line.remove()
504        except:
505            # Old version of matplotlib
506            for item in range(len(self.axes.lines)):
507                del self.axes.lines[0]
508   
509   
510    def get_radius(self):
511        return 0
512   
513    def update(self,xmin=None,xmax=None,ymin=None, ymax=None, opline=None,translation=False):
514        """
515        Draw the new roughness on the graph.
516        """
517
518   
519        if xmin!=None:
520            self.x1=xmin
521        if ymin!=None:
522            self.y1=ymin
523        self.inner_marker.set(xdata=[self.x1],ydata=[0]) 
524        self.line.set(xdata=[self.x1,self.x1],
525                       ydata=[self.y1,-self.y1]) 
526       
527   
528       
529    def save(self, ev):
530        """
531        Remember the roughness for this layer and the next so that we
532        can restore on Esc.
533        """
534        self.save_x1= self.x1
535        self.save_x2= self.x2
536        self.save_y1= self.y1
537        self.save_y2= self.y2
538       
539        self.base.freeze_axes()
540
541    def moveend(self, ev):
542       
543        self.has_move=False
544        self.base.moveend(ev)
545           
546    def restore(self):
547        """
548        Restore the roughness for this layer.
549        """
550        self.x1 = self.save_x1
551        self.x2 = self.save_x2
552        self.y1 = self.save_y1
553        self.y2= self.save_y2
554     
555       
556    def move(self, x, y, ev):
557        """
558        Process move to a new position, making sure that the move is allowed.
559        """
560        self.has_move=True
561       
562        # compute the b intercept of the vertical line
563        self.x1= x
564       
565       
566        self.base.base.update()
567       
568       
569    def set_cursor(self, x, y):
570        self.move(x, y, None)
571        self.update()
572       
573       
574    def get_params(self):
575        params = {}
576        params["x"] = self.xmin
577        params["ymin"] = self.ymin
578        params["ymax"] = self.ymax
579        return params
580   
581    def set_params(self, params):
582        """
583            Draw a vertical line given some value of params
584            @param params: a dictionary containing value for x, ymin , ymax to draw
585            a vertical line
586        """
587        x = params["x"] 
588        ymin = params["ymin"] 
589        ymax = params["ymax"] 
590        #self.set_cursor(x, self._inner_mouse_y)
591        self.update(self,x =x,ymin =ymin, ymax =ymax)
592       
593
594class BoxInteractorX(BoxInteractor):
595    def __init__(self,base,axes,color='black', zorder=3):
596        BoxInteractor.__init__(self, base, axes, color=color)
597        self.base=base
598        self._post_data()
599    def _post_data(self):
600        from DataLoader.manipulations import SlabX
601        self.post_data(SlabX )   
602       
603
604class BoxInteractorY(BoxInteractor):
605    def __init__(self,base,axes,color='black', zorder=3):
606        BoxInteractor.__init__(self, base, axes, color=color)
607        self.base=base
608        self._post_data()
609    def _post_data(self):
610        from DataLoader.manipulations import SlabY
611        self.post_data(SlabY )   
612       
613       
Note: See TracBrowser for help on using the repository browser.