source: sasview/guiframe/local_perspectives/plotting/boxSlicer.py @ d468daa

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

print stament removed

  • Property mode set to 100644
File size: 18.2 KB
RevLine 
[2d107b8]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
[38224f10]10#from config import printEVT
[2d107b8]11from BaseInteractor import _BaseInteractor
12from copy import deepcopy
13import math
14
[0d9dae8]15from sans.guicomm.events import NewPlotEvent, StatusEvent,SlicerParameterEvent,EVT_SLICER_PARS
[2d107b8]16import SlicerParameters
17import wx
18
[0f6d05f8]19
[38224f10]20class BoxInteractor(_BaseInteractor):
[2d107b8]21    """
22         Select an annulus through a 2D plot
23    """
[c73d871]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):
[2d107b8]26       
27        _BaseInteractor.__init__(self, base, axes, color=color)
28        self.markers = []
29        self.axes = axes
[ffd23b5]30        self.qmax = self.base.data2D.xmax
[2d107b8]31        self.connect = self.base.connect
[0f6d05f8]32        self.x= x_max
33        self.y= y_max
34               
[3554b99a]35        self.theta2= math.pi/3
[2d107b8]36        ## Number of points on the plot
[ffd23b5]37        self.nbins = 30
[38224f10]38        self.count=0
39        self.error=0
[ffd23b5]40        self.averager=None
[c73d871]41        self.left_line = VerticalLine(self, self.base.subplot,color='blue', 
42                                      zorder=zorder,
[0f6d05f8]43                                        ymin= -self.y , 
44                                        ymax= self.y ,
45                                        xmin= -self.x,
46                                        xmax= -self.x)
[ffd23b5]47        self.left_line.qmax = self.qmax
[dd40217]48       
49        self.right_line= VerticalLine(self, self.base.subplot,color='black', 
50                                      zorder=zorder,
[0f6d05f8]51                                     ymin= -self.y , 
52                                     ymax= self.y,
53                                     xmin= self.x,
54                                     xmax= self.x)
[ffd23b5]55        self.right_line.qmax = self.qmax
[dd40217]56       
57        self.top_line= HorizontalLine(self, self.base.subplot,color='green', 
58                                      zorder=zorder,
[0f6d05f8]59                                      xmin= -self.x,
60                                      xmax= self.x,
61                                      ymin= self.y,
62                                      ymax= self.y)
[ffd23b5]63        self.top_line.qmax= self.qmax
[dd40217]64       
65        self.bottom_line= HorizontalLine(self, self.base.subplot,color='gray', 
66                                      zorder=zorder,
[0f6d05f8]67                                      xmin= -self.x,
68                                      xmax= self.x,
69                                      ymin= -self.y,
70                                      ymax= -self.y)
[ffd23b5]71        self.bottom_line.qmax= self.qmax
[dd40217]72       
[38224f10]73        self.update()
[0f6d05f8]74        self._post_data()
[2d107b8]75       
76        # Bind to slice parameter events
[0d9dae8]77        self.base.parent.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS)
[2d107b8]78
79
80    def _onEVT_SLICER_PARS(self, event):
[38224f10]81        #printEVT("AnnulusSlicer._onEVT_SLICER_PARS")
[2d107b8]82        event.Skip()
83        if event.type == self.__class__.__name__:
[0f6d05f8]84            self.set_params(event.params)
[2d107b8]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):
[ffd23b5]106        self.averager=None
[2d107b8]107        self.clear_markers()
[0f6d05f8]108        self.left_line.clear()
109        self.right_line.clear()
110        self.top_line.clear()
111        self.bottom_line.clear()
[2d107b8]112        #self.base.connect.disconnect()
[0d9dae8]113        self.base.parent.Unbind(EVT_SLICER_PARS)
[2d107b8]114       
115    def update(self):
116        """
117        Respond to changes in the model by recalculating the profiles and
118        resetting the widgets.
119        """
[8ff3ec1]120       
[dd40217]121        if self.top_line.has_move:
[d468daa]122            #print"top has moved"
[0f6d05f8]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           
[dd40217]131        if self.bottom_line.has_move:
[d468daa]132            #print "bottom has move"
[0f6d05f8]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           
[dd40217]141        if self.left_line.has_move:
[0f6d05f8]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           
[dd40217]151        if self.right_line.has_move:
[0f6d05f8]152           
153            self.right_line.update()
154            self.left_line.update(xmin = -self.right_line.x1,
155                                   xmax = -self.right_line.x1)
[dd40217]156           
[0f6d05f8]157            self.bottom_line.update(xmin= self.left_line.x1,
158                                 xmax= self.right_line.x1)
[dd40217]159           
[0f6d05f8]160            self.top_line.update(xmin= self.left_line.x1,
161                                    xmax= self.right_line.x1)
[dd40217]162               
[0f6d05f8]163           
[2d107b8]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()
[0f6d05f8]170        self.left_line.save(ev)
171        self.right_line.save(ev)
172        self.top_line.save(ev)
173        self.bottom_line.save(ev)
[ffd23b5]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       
[2d107b8]213
[ffd23b5]214        new_plot.source=self.base.data2D.source
215        new_plot.info=self.base.data2D.info
216        new_plot.interactive = True
217        #print "loader output.detector",output.source
218        new_plot.detector =self.base.data2D.detector
219        # If the data file does not tell us what the axes are, just assume...
220        new_plot.xaxis("\\rm{Q}", 'rad')
221        new_plot.yaxis("\\rm{Intensity} ","cm^{-1}")
222        new_plot.group_id = str(self.averager.__name__)+self.base.data2D.name
223        new_plot.id = str(self.averager.__name__)
224        wx.PostEvent(self.base.parent, NewPlotEvent(plot=new_plot,
225                                                 title=str(self.averager.__name__) ))
226       
227       
[2d107b8]228    def _post_data(self):
229        # Compute data
[0f6d05f8]230        data = self.base.data2D
231        from DataLoader.manipulations import  Boxavg
232        radius = math.sqrt(math.pow(self.qmax,2)+math.pow(self.qmax,2))
[aa1b747]233        self.x= math.fabs(self.right_line.x1)
234        self.y= math.fabs(self.top_line.y1 )
235       
236        box =  Boxavg (x_min=-self.x, x_max=self.x, y_min=-self.y, y_max=self.y)
[38224f10]237       
[0f6d05f8]238        self.count, self.error= box(self.base.data2D)
[b319def8]239       
[0f6d05f8]240        #print "post data"
[b319def8]241             
[38224f10]242                                       
[2d107b8]243    def moveend(self, ev):
244        self.base.thaw_axes()
245       
246        # Post paramters
[0d9dae8]247        event = SlicerParameterEvent()
[2d107b8]248        event.type = self.__class__.__name__
[0f6d05f8]249        event.params = self.get_params()
[2d107b8]250        wx.PostEvent(self.base.parent, event)
251
252        self._post_data()
253           
254    def restore(self):
255        """
256        Restore the roughness for this layer.
257        """
[0f6d05f8]258        self.left_line.restore()
259        self.right_line.restore()
260        self.top_line.restore()
261        self.bottom_line.restore()
[2d107b8]262
263    def move(self, x, y, ev):
264        """
265        Process move to a new position, making sure that the move is allowed.
266        """
267        pass
268       
269    def set_cursor(self, x, y):
270        pass
271       
272    def get_params(self):
273        params = {}
[0f6d05f8]274        params["x_max"]= math.fabs(self.right_line.x1)
[aa1b747]275        params["y_max"]= math.fabs(self.top_line.y1)
[ffd23b5]276        params["nbins"]= self.nbins
[0f6d05f8]277        params["errors"] = self.error
278        params["count"]= self.count
[2d107b8]279        return params
280   
281    def set_params(self, params):
[aa1b747]282       
[0f6d05f8]283        self.x = float(math.fabs(params["x_max"]))
284        self.y = float(math.fabs(params["y_max"] ))
[ffd23b5]285        self.nbins=params["nbins"]
[0f6d05f8]286        self.left_line.update(xmin= -1*self.x,
287                              xmax = -1*self.x,
288                              ymin= -self.y,
289                              ymax=  self.y, 
290                              )
291        self.right_line.update(xmin= self.x,
292                              xmax = self.x,
293                              ymin= -self.y,
294                              ymax=  self.y, 
295                              )
296        self.top_line.update(xmin= -1*self.x,
297                             xmax= self.x,
298                             ymin= self.y,
299                             ymax= self.y)
300        self.bottom_line.update(xmin= -1*self.x,
301                                 xmax= self.x,
302                                 ymin= -1*self.y,
303                                 ymax= -1*self.y)
[aa1b747]304       
[ffd23b5]305        self.post_data( nbins=None)
[2d107b8]306    def freeze_axes(self):
307        self.base.freeze_axes()
308       
309    def thaw_axes(self):
310        self.base.thaw_axes()
311
312    def draw(self):
313        self.base.draw()
314
315class HorizontalLine(_BaseInteractor):
316    """
317         Select an annulus through a 2D plot
318    """
[030873e]319    def __init__(self,base,axes,color='black', zorder=5,mline=None,ymin=None, ymax=None, y=0.5,
[0f6d05f8]320                 xmin=0.0,xmax=0.5):
[2d107b8]321       
322        _BaseInteractor.__init__(self, base, axes, color=color)
323        self.markers = []
324        self.axes = axes
[dd40217]325        self.x1= xmax
326        self.save_x1= xmax
[2d107b8]327       
[dd40217]328        self.x2= xmin
329        self.save_x2= xmin
[3554b99a]330       
[dd40217]331        self.y1= ymax
332        self.save_y1= ymax
[3554b99a]333       
[dd40217]334        self.y2= ymin
335        self.save_y2= ymin
[3554b99a]336        self.mline= mline
[0f6d05f8]337        self.line = self.axes.plot([self.x1,-self.x1],
[3554b99a]338                                   [self.y1,self.y2],
[2d107b8]339                                      linestyle='-', marker='',
340                                      color=self.color,
341                                      visible=True)[0]
[c73d871]342       
[2d107b8]343        self.npts = 20
344        self.has_move=False
345        self.connect_markers([self.line])
[3554b99a]346        self.update()
[2d107b8]347
348    def set_layer(self, n):
349        self.layernum = n
350        self.update()
351       
352    def clear(self):
353        self.clear_markers()
354        try:
355           
356            self.line.remove()
357        except:
358            # Old version of matplotlib
359            for item in range(len(self.axes.lines)):
360                del self.axes.lines[0]
[030873e]361   
[2d107b8]362    def get_radius(self):
363       
364        return 0
[8ff3ec1]365   
[b6b1669]366    def update(self,xmin=None, xmax=None,ymin=None,ymax=None, mline=None,translation=False):
[2d107b8]367        """
368        Draw the new roughness on the graph.
369        """
[3554b99a]370        if xmin !=None:
[0f6d05f8]371            self.x1 = xmin
[3554b99a]372        if ymin !=None:
[0f6d05f8]373            self.y1 = ymin
374        self.line.set(xdata=[self.x1,-self.x1],
375                       ydata=[self.y1,self.y1])
[030873e]376   
[2d107b8]377       
378       
379    def save(self, ev):
380        """
381        Remember the roughness for this layer and the next so that we
382        can restore on Esc.
383        """
[3554b99a]384        self.save_x1= self.x1
385        self.save_x2= self.x2
[2d107b8]386       
[3554b99a]387        self.save_y1= self.y1
388        self.save_y2= self.y2
[0f6d05f8]389   
[3554b99a]390       
[2d107b8]391        self.base.freeze_axes()
392
393    def moveend(self, ev):
[030873e]394       
[2d107b8]395        self.has_move=False
396        self.base.moveend(ev)
397           
398    def restore(self):
399        """
400        Restore the roughness for this layer.
401        """
[3554b99a]402        self.x1 = self.save_x1
403        self.x2 = self.save_x2
404        self.y1 = self.save_y1
405        self.y2 = self.save_y2
[0f6d05f8]406       
[2d107b8]407
408    def move(self, x, y, ev):
409        """
410        Process move to a new position, making sure that the move is allowed.
411        """
[d468daa]412        #print "horizontal move x y "
[0f6d05f8]413        self.y1= y
[2d107b8]414        self.has_move=True
415        self.base.base.update()
416       
417    def set_cursor(self, x, y):
418        self.move(x, y, None)
419        self.update()
420       
421       
422    def get_params(self):
423        params = {}
[3554b99a]424        params["radius"] = self.x1
425        #params["theta"] = self.xmax
[2d107b8]426        return params
427   
428    def set_params(self, params):
429
430        x = params["radius"] 
431        self.set_cursor(x, self._inner_mouse_y)
432       
433
434
435
436class VerticalLine(_BaseInteractor):
437    """
438         Select an annulus through a 2D plot
439    """
[c73d871]440    def __init__(self,base,axes,color='black', zorder=5, mline=None, ymin=0.0, 
[0f6d05f8]441                 ymax=0.5,xmin=-0.5,xmax=0.5
442                 ):
[2d107b8]443       
444        _BaseInteractor.__init__(self, base, axes, color=color)
445        self.markers = []
446        self.axes = axes
[030873e]447       
[0f6d05f8]448        self.x1= xmax
449        self.x2= xmin
450        self.y1= ymax
451        self.y2= ymin
[c73d871]452        self.line = self.axes.plot([self.x1,self.x2],[self.y1,self.y2],
[2d107b8]453                                      linestyle='-', marker='',
454                                      color=self.color,
455                                      visible=True)[0]
456     
457        self.has_move=False
458        self.connect_markers([self.line])
459        self.update()
460
461    def set_layer(self, n):
462        self.layernum = n
463        self.update()
464       
465    def clear(self):
466        self.clear_markers()
467        try:
468           
469            self.line.remove()
470        except:
471            # Old version of matplotlib
472            for item in range(len(self.axes.lines)):
473                del self.axes.lines[0]
[c73d871]474   
475   
[2d107b8]476    def get_radius(self):
477        return 0
[8ff3ec1]478   
[d5a792a]479    def update(self,xmin=None,xmax=None,ymin=None, ymax=None, opline=None,translation=False):
[2d107b8]480        """
481        Draw the new roughness on the graph.
482        """
[0f6d05f8]483
484   
485        if xmin!=None:
486            self.x1=xmin
487        if ymin!=None:
488            self.y1=ymin
489        self.line.set(xdata=[self.x1,self.x1],
490                       ydata=[self.y1,-self.y1]) 
[dd40217]491       
[0f6d05f8]492   
[3554b99a]493       
[2d107b8]494    def save(self, ev):
495        """
496        Remember the roughness for this layer and the next so that we
497        can restore on Esc.
498        """
[dd40217]499        self.save_x1= self.x1
500        self.save_x2= self.x2
501        self.save_y1= self.y1
502        self.save_y2= self.y2
[8ff3ec1]503       
[2d107b8]504        self.base.freeze_axes()
505
506    def moveend(self, ev):
[030873e]507       
[2d107b8]508        self.has_move=False
509        self.base.moveend(ev)
510           
511    def restore(self):
512        """
513        Restore the roughness for this layer.
514        """
[3554b99a]515        self.x1 = self.save_x1
516        self.x2 = self.save_x2
517        self.y1 = self.save_y1
518        self.y2= self.save_y2
519     
[78ed1ad]520       
[2d107b8]521    def move(self, x, y, ev):
522        """
523        Process move to a new position, making sure that the move is allowed.
524        """
[8ff3ec1]525        self.has_move=True
[3554b99a]526       
527        # compute the b intercept of the vertical line
[0f6d05f8]528        self.x1= x
[3554b99a]529       
530       
[8ff3ec1]531        self.base.base.update()
532       
533       
534    def set_cursor(self, x, y):
535        self.move(x, y, None)
536        self.update()
537       
538       
539    def get_params(self):
540        params = {}
541        params["x"] = self.xmin
542        params["ymin"] = self.ymin
543        params["ymax"] = self.ymax
544        return params
545   
546    def set_params(self, params):
547        """
548            Draw a vertical line given some value of params
549            @param params: a dictionary containing value for x, ymin , ymax to draw
550            a vertical line
551        """
552        x = params["x"] 
553        ymin = params["ymin"] 
554        ymax = params["ymax"] 
555        #self.set_cursor(x, self._inner_mouse_y)
556        self.update(self,x =x,ymin =ymin, ymax =ymax)
[2d107b8]557       
[8ff3ec1]558
[ffd23b5]559class BoxInteractorX(BoxInteractor):
560    def __init__(self,base,axes,color='black', zorder=3):
561        BoxInteractor.__init__(self, base, axes, color=color)
562        self.base=base
563        self._post_data()
564    def _post_data(self):
565        from DataLoader.manipulations import SlabX
566        self.post_data(SlabX )   
567       
568
569class BoxInteractorY(BoxInteractor):
570    def __init__(self,base,axes,color='black', zorder=3):
571        BoxInteractor.__init__(self, base, axes, color=color)
572        self.base=base
573        self._post_data()
574    def _post_data(self):
575        from DataLoader.manipulations import SlabY
576        self.post_data(SlabY )   
577       
[2d107b8]578       
Note: See TracBrowser for help on using the repository browser.