#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 sas.guiframe.events import NewPlotEvent
from sas.guiframe.events import StatusEvent
from sas.guiframe.events import SlicerParameterEvent
from sas.guiframe.events import EVT_SLICER_PARS
[docs]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()
[docs] def set_layer(self, n):
"""
"""
self.layernum = n
self.update()
[docs] 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)
[docs] 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())
[docs] 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
[docs] 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 sas.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 sas.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
self.base.parent.update_theory(data_id=self.base.data2D.id, \
theory=new_plot)
wx.PostEvent(self.base.parent,
NewPlotEvent(plot=new_plot, title=str(new_sector.__name__)))
[docs] 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
[docs] 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()
[docs] def move(self, x, y, ev):
"""
Process move to a new position, making sure that the move is allowed.
"""
pass
[docs] def set_cursor(self, x, y):
"""
"""
pass
[docs] 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
[docs] 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()
[docs] def freeze_axes(self):
"""
"""
self.base.freeze_axes()
[docs] def thaw_axes(self):
"""
"""
self.base.thaw_axes()
[docs] def draw(self):
"""
"""
self.base.draw()
[docs]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 sas.dataloader.manipulations import SectorQ
self.post_data(SectorQ)
[docs]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 sas.dataloader.manipulations import SectorPhi
self.post_data(SectorPhi )