#TODO: the line slicer should listen to all 2DREFRESH events, get the data and slice it # before pushing a new 1D data update. # #TODO: NEED MAJOR REFACTOR # # Debug printout import math import wx from copy import deepcopy from BaseInteractor import _BaseInteractor from sans.guiframe.events import NewPlotEvent from sans.guiframe.events import StatusEvent from sans.guiframe.events import SlicerParameterEvent from sans.guiframe.events import EVT_SLICER_PARS class SectorInteractor(_BaseInteractor): """ Select an annulus through a 2D plot """ def __init__(self, base, axes, color='black', zorder=3): """ """ _BaseInteractor.__init__(self, base, axes, color=color) self.markers = [] self.axes = axes self.qmax = self.base.data2D.xmax self.connect = self.base.connect ## Number of points on the plot self.nbins = 20 theta1 = math.pi/8 theta2 = math.pi/2 theta1 = 2 * math.pi/3 theta2 = -2 * math.pi/3 r1 = self.qmax/2.0 r2 = self.qmax/1.8 # Inner circle from Arc import ArcInteractor self.inner_circle = ArcInteractor(self, self.base.subplot, zorder=zorder, r=self.qmax/2.0, theta1=theta1, theta2=theta2) self.inner_circle.qmax = self.qmax self.outer_circle = ArcInteractor(self, self.base.subplot, zorder=zorder+1, r=self.qmax/1.8, theta1=theta1, theta2=theta2) self.outer_circle.qmax = self.qmax * 1.2 #self.outer_circle.set_cursor(self.base.qmax/1.8, 0) from Edge import RadiusInteractor self.right_edge= RadiusInteractor(self, self.base.subplot, zorder=zorder+1, arc1=self.inner_circle, arc2=self.outer_circle, theta=theta1) self.left_edge= RadiusInteractor(self, self.base.subplot, zorder=zorder+1, arc1=self.inner_circle, arc2=self.outer_circle, theta=theta2) self.update() self._post_data() # Bind to slice parameter events self.base.parent.Bind(EVT_SLICER_PARS, self._onEVT_SLICER_PARS) def _onEVT_SLICER_PARS(self, event): """ """ #printEVT("AnnulusSlicer._onEVT_SLICER_PARS") event.Skip() if event.type == self.__class__.__name__: self.set_params(event.params) self.base.update() def save_data(self, path, image, x, y): """ """ output = open(path, 'w') data_x, data_y = self.get_data(image, x, y) output.write(" \n") for i in range(len(data_x)): output.write("%g %g\n" % (data_x[i], data_y[i])) output.close() def set_layer(self, n): """ """ self.layernum = n self.update() def clear(self): """ """ self.clear_markers() self.outer_circle.clear() self.inner_circle.clear() self.right_edge.clear() self.left_edge.clear() #self.base.connect.disconnect() self.base.parent.Unbind(EVT_SLICER_PARS) def update(self): """ Respond to changes in the model by recalculating the profiles and resetting the widgets. """ # Update locations if self.inner_circle.has_move: #print "inner circle has moved" self.inner_circle.update() r1 = self.inner_circle.get_radius() r2 = self.outer_circle.get_radius() self.right_edge.update(r1, r2) self.left_edge.update(r1, r2) if self.outer_circle.has_move: #print "outer circle has moved" self.outer_circle.update() r1 = self.inner_circle.get_radius() r2 = self.outer_circle.get_radius() self.left_edge.update(r1, r2) self.right_edge.update(r1, r2) if self.right_edge.has_move: #print "right edge has moved" self.right_edge.update() self.inner_circle.update(theta1=self.right_edge.get_angle(), theta2=None) self.outer_circle.update(theta1=self.right_edge.get_angle(), theta2=None) if self.left_edge.has_move: #print "left Edge has moved" self.left_edge.update() self.inner_circle.update(theta1=None, theta2=self.left_edge.get_angle()) self.outer_circle.update(theta1=None, theta2=self.left_edge.get_angle()) def save(self, ev): """ Remember the roughness for this layer and the next so that we can restore on Esc. """ self.base.freeze_axes() self.inner_circle.save(ev) self.outer_circle.save(ev) self.right_edge.save(ev) self.left_edge.save(ev) def _post_data(self): pass def post_data(self,new_sector ): """ post data averaging in Q""" if self.inner_circle.get_radius() < self.outer_circle.get_radius(): rmin = self.inner_circle.get_radius() rmax = self.outer_circle.get_radius() else: rmin = self.outer_circle.get_radius() rmax = self.inner_circle.get_radius() if self.right_edge.get_angle() < self.left_edge.get_angle(): phimin = self.right_edge.get_angle() phimax = self.left_edge.get_angle() else: phimin = self.left_edge.get_angle() phimax = self.right_edge.get_angle() #print "phimin, phimax, rmin ,rmax",math.degrees(phimin), # math.degrees(phimax), rmin ,rmax #from DataLoader.manipulations import SectorQ sect = new_sector(r_min=rmin, r_max=rmax, phi_min=phimin, phi_max=phimax) sector = sect(self.base.data2D) from sans.guiframe.dataFitting import Data1D if hasattr(sector, "dxl"): dxl = sector.dxl else: dxl = None if hasattr(sector, "dxw"): dxw = sector.dxw else: dxw = None new_plot = Data1D(x=sector.x, y=sector.y, dy=sector.dy, dxl=dxl, dxw=dxw) new_plot.name = str(new_sector.__name__) + \ "("+ self.base.data2D.name+")" new_plot.source = self.base.data2D.source new_plot.interactive = True #print "loader output.detector",output.source new_plot.detector = self.base.data2D.detector # If the data file does not tell us what the axes are, just assume... new_plot.xaxis("\\rm{Q}", 'rad') new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}") new_plot.group_id = str(new_sector.__name__) + self.base.data2D.name wx.PostEvent(self.base.parent, NewPlotEvent(plot=new_plot, title=str(new_sector.__name__))) def moveend(self, ev): #self.base.thaw_axes() # Post paramters #event = SlicerParameterEvent() #event.type = self.__class__.__name__ #event.params = self.get_params() #print "main moveend ", event.params #wx.PostEvent(self.base.parent, event) #self._post_data() pass def restore(self): """ Restore the roughness for this layer. """ self.inner_circle.restore() self.outer_circle.restore() self.right_edge.restore() self.left_edge.restore() def move(self, x, y, ev): """ Process move to a new position, making sure that the move is allowed. """ pass def set_cursor(self, x, y): """ """ pass def get_params(self): """ """ params = {} params["r_min"] = self.inner_circle.get_radius() params["r_max"] = self.outer_circle.get_radius() params["phi_min"] = self.right_edge.get_angle() params["phi_max"] = self.left_edge.get_angle() params["nbins"] = self.nbins return params def set_params(self, params): """ """ #print "setparams on main slicer ",params inner = params["r_min"] outer = params["r_max"] phi_min= params["phi_min"] phi_max=params["phi_max"] self.nbins = int(params["nbins"]) self.inner_circle.set_cursor(inner, phi_min, phi_max,self.nbins) self.outer_circle.set_cursor(outer, phi_min, phi_max, self.nbins) self.right_edge.set_cursor(inner, outer, phi_min) self.left_edge.set_cursor(inner, outer, phi_max) self._post_data() def freeze_axes(self): """ """ self.base.freeze_axes() def thaw_axes(self): """ """ self.base.thaw_axes() def draw(self): """ """ self.base.draw() class SectorInteractorQ(SectorInteractor): """ """ def __init__(self, base, axes, color='black', zorder=3): """ """ SectorInteractor.__init__(self, base, axes, color=color) self.base=base self._post_data() def _post_data(self): """ """ from DataLoader.manipulations import SectorQ self.post_data(SectorQ) class SectorInteractorPhi(SectorInteractor): """ """ def __init__(self, base, axes, color='black', zorder=3): """ """ SectorInteractor.__init__(self, base, axes, color=color) self.base=base self._post_data() def _post_data(self): """ """ from DataLoader.manipulations import SectorPhi self.post_data(SectorPhi )