first full functional MAxyPlot
This commit is contained in:
442
python/MAError.py
Normal file
442
python/MAError.py
Normal file
@@ -0,0 +1,442 @@
|
||||
#!/usr/bin/env python
|
||||
#*-----------------------------------------------------------------------*
|
||||
#| |
|
||||
#| Copyright (c) 2013 by Paul Scherrer Institute (http://www.psi.ch) |
|
||||
#| |
|
||||
#| Author Thierry Zamofing (thierry.zamofing@psi.ch) |
|
||||
#*-----------------------------------------------------------------------*
|
||||
'''
|
||||
implements an image view to show a colored image of a hdf5 dataset.
|
||||
'''
|
||||
|
||||
if __name__ == '__main__':
|
||||
#Used to guarantee to use at least Wx2.8
|
||||
import wxversion
|
||||
wxversion.ensureMinimal('2.8')
|
||||
import wx
|
||||
import matplotlib as mpl
|
||||
if __name__ == '__main__':
|
||||
mpl.use('WXAgg')
|
||||
#or mpl.use('WX')
|
||||
#matplotlib.get_backend()
|
||||
|
||||
import wxutils as ut
|
||||
import os
|
||||
import numpy as np
|
||||
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
|
||||
import pylab as plt #used for the colormaps
|
||||
|
||||
#or from matplotlib.backends.backend_wx import FigureCanvasWx as FigureCanvas
|
||||
#The source of the DraggableColorbar is from:
|
||||
#http://www.ster.kuleuven.be/~pieterd/python/html/plotting/interactive_colorbar.html
|
||||
|
||||
class MPLCanvasErr(FigureCanvas):
|
||||
def __init__(self,parent,SetStatusCB=None):
|
||||
if SetStatusCB:
|
||||
self.SetStatusCB=SetStatusCB
|
||||
fig = mpl.figure.Figure()
|
||||
ax = fig.add_axes([0.075,0.075,0.85,0.85])
|
||||
FigureCanvas.__init__(self,parent, -1, fig)
|
||||
self.mpl_connect('motion_notify_event', self.OnMotion)
|
||||
self.mpl_connect('button_press_event', self.OnBtnPress)
|
||||
self.mpl_connect('button_release_event', self.OnBtnRelease)
|
||||
self.mpl_connect('scroll_event', self.OnBtnScroll)
|
||||
self.mpl_connect('key_press_event',self.OnKeyPress)
|
||||
self.fig=fig
|
||||
self.ax=ax
|
||||
|
||||
def InitChild(self,pts,rec):
|
||||
|
||||
fig=self.fig
|
||||
ax=self.ax
|
||||
|
||||
err=np.sqrt((rec[:,1]-rec[:,4])**2+(rec[:,1]-rec[:,4])**2)
|
||||
hl = ax.plot(err, 'r-')
|
||||
ax.xaxis.set_label_text('time (10x servo cycle)')
|
||||
ax.yaxis.set_label_text('pos-error um')
|
||||
self.ax = ax
|
||||
self.hl = hl
|
||||
|
||||
def OnMotion(self,event):
|
||||
print event,event.x,event.y,event.inaxes,event.xdata,event.ydata
|
||||
return
|
||||
if event.inaxes==self.ax:
|
||||
x=int(round(event.xdata))
|
||||
y=int(round(event.ydata))
|
||||
try:
|
||||
v=self.img.get_array()[y,x]
|
||||
except IndexError as e:
|
||||
pass
|
||||
else:
|
||||
#print x,y,v
|
||||
self.SetStatusCB(self.Parent,0,(x,y,v))
|
||||
elif event.inaxes==self.colBar.ax:
|
||||
colBar=self.colBar
|
||||
pt=colBar.ax.bbox.get_points()[:,1]
|
||||
nrm=colBar.norm
|
||||
vmin,vmax,p0,p1,pS = (nrm.vmin,nrm.vmax,pt[0],pt[1],event.y)
|
||||
if isinstance(colBar.norm,mpl.colors.LogNorm):#type(colBar.norm)==mpl.colors.LogNorm does not work...
|
||||
vS=0
|
||||
else:#scale around point
|
||||
vS=vmin+(vmax-vmin)/(p1-p0)*(pS-p0)
|
||||
self.SetStatusCB(self.Parent,1,vS)
|
||||
try:
|
||||
vmin,vmax,p0,p1,pS=self.colBarPressed
|
||||
except AttributeError:
|
||||
return
|
||||
#if event.inaxes != self.cbar.ax: return
|
||||
colBar=self.colBar
|
||||
#print vmin,vmax,p0,p1,pS,type(colBar.norm)
|
||||
#print 'x0=%f, xpress=%f, event.xdata=%f, dx=%f, x0+dx=%f'%(x0, xpress, event.xdata, dx, x0+dx)
|
||||
|
||||
if isinstance(colBar.norm,mpl.colors.LogNorm):#type(colBar.norm)==mpl.colors.LogNorm does not work...
|
||||
if event.button==1:
|
||||
#colBar.norm.vmin=.1
|
||||
colBar.norm.vmax=vmax*np.exp((pS-event.y)/100)
|
||||
#scale= np.exp((event.y-pS)/100)
|
||||
elif event.button==1:#move top,bottom,both
|
||||
pD = event.y - pS
|
||||
vD=(vmax-vmin)/(p1-p0)*(pS-event.y)
|
||||
colBar.norm.vmin = vmin+vD
|
||||
colBar.norm.vmax = vmax+vD
|
||||
elif event.button==3:#scale around point
|
||||
scale= np.exp((pS-event.y)/100)
|
||||
vS=vmin+(vmax-vmin)/(p1-p0)*(pS-p0)
|
||||
#print scale,vS
|
||||
colBar.norm.vmin = vS-scale*(vS-vmin)
|
||||
colBar.norm.vmax = vS-scale*(vS-vmax)
|
||||
self.img.set_norm(colBar.norm)#force image to redraw
|
||||
colBar.patch.figure.canvas.draw()
|
||||
|
||||
def OnBtnPress(self, event):
|
||||
"""on button press we will see if the mouse is over us and store some data"""
|
||||
print dir(event.guiEvent)
|
||||
return
|
||||
if event.inaxes == self.colBar.ax:
|
||||
#if event.guiEvent.LeftDClick()==True:
|
||||
# print dlg
|
||||
pt=self.colBar.ax.bbox.get_points()[:,1]
|
||||
nrm=self.colBar.norm
|
||||
self.colBarPressed = (nrm.vmin,nrm.vmax,pt[0],pt[1],event.y)
|
||||
#self.colBarPressed = event.x, event.y
|
||||
#print self.colBarPressed
|
||||
#self.OnMouse(event)
|
||||
pass
|
||||
|
||||
def OnBtnRelease(self, event):
|
||||
"""on release we reset the press data"""
|
||||
#self.OnMouse(event)
|
||||
return
|
||||
try: del self.colBarPressed
|
||||
except AttributeError: pass
|
||||
|
||||
def OnBtnScroll(self, event):
|
||||
return
|
||||
#self.OnMouse(event)
|
||||
colBar=self.colBar
|
||||
if event.inaxes==colBar.ax:
|
||||
pt=colBar.ax.bbox.get_points()[:,1]
|
||||
nrm=colBar.norm
|
||||
vmin,vmax,p0,p1,pS = (nrm.vmin,nrm.vmax,pt[0],pt[1],event.y)
|
||||
if isinstance(colBar.norm,mpl.colors.LogNorm):#type(colBar.norm)==mpl.colors.LogNorm does not work...
|
||||
scale= np.exp((-event.step)/10)
|
||||
colBar.norm.vmax=vmax*scale
|
||||
else:#scale around point
|
||||
scale= np.exp((-event.step)/10)
|
||||
vS=vmin+(vmax-vmin)/(p1-p0)*(pS-p0)
|
||||
#print scale,vS
|
||||
colBar.norm.vmin = vS-scale*(vS-vmin)
|
||||
colBar.norm.vmax = vS-scale*(vS-vmax)
|
||||
self.img.set_norm(colBar.norm)#force image to redraw
|
||||
colBar.patch.figure.canvas.draw()
|
||||
|
||||
def OnKeyPress(self, event):
|
||||
return
|
||||
colCycle=self.colCycle
|
||||
colBar=self.colBar
|
||||
if event.key=='down':
|
||||
self.colIndex += 1
|
||||
elif event.key=='up':
|
||||
self.colIndex -= 1
|
||||
self.colIndex%=len(colCycle)
|
||||
cmap = colCycle[self.colIndex]
|
||||
colBar.set_cmap(cmap)
|
||||
colBar.draw_all()
|
||||
self.img.set_cmap(cmap)
|
||||
self.img.get_axes().set_title(cmap)
|
||||
colBar.patch.figure.canvas.draw()
|
||||
|
||||
def OnMouse(self, event):
|
||||
return
|
||||
for k in dir(event):
|
||||
if k[0]!='_':
|
||||
print k,getattr(event,k)
|
||||
|
||||
class MAErrorFrame(wx.Frame):
|
||||
def __init__(self, parent,doc):
|
||||
wx.Frame.__init__(self, parent, title='xy-Plot', size=wx.Size(850, 650))
|
||||
self.doc=doc;doc.view.append(self)
|
||||
imgDir=ut.Path.GetImage()
|
||||
icon = wx.Icon(os.path.join(imgDir,'PBMA.ico'), wx.BITMAP_TYPE_ICO)
|
||||
self.SetIcon(icon)
|
||||
|
||||
canvas = MPLCanvasErr(self,self.SetStatusCB)
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
toolbar=ut.AddToolbar(canvas,sizer)
|
||||
canvas.InitChild(doc.fh['pts'],doc.fh['rec'])
|
||||
|
||||
self.Centre()
|
||||
|
||||
self.BuildMenu()
|
||||
self.canvas=canvas
|
||||
self.sizer=sizer
|
||||
self.toolbar=toolbar
|
||||
|
||||
def BuildMenu(self):
|
||||
mnBar = wx.MenuBar()
|
||||
|
||||
#-------- Edit Menu --------
|
||||
mn = wx.Menu()
|
||||
mnItem=mn.Append(wx.ID_ANY, 'Setup Colormap', 'Setup the color mapping ');self.Bind(wx.EVT_MENU, self.OnColmapSetup, mnItem)
|
||||
mnItem=mn.Append(wx.ID_ANY, 'Invert X-Axis', kind=wx.ITEM_CHECK);self.Bind(wx.EVT_MENU, self.OnInvertAxis, mnItem)
|
||||
self.mnIDxAxis=mnItem.GetId()
|
||||
mnItem=mn.Append(wx.ID_ANY, 'Invert Y-Axis', kind=wx.ITEM_CHECK);self.Bind(wx.EVT_MENU, self.OnInvertAxis, mnItem)
|
||||
mnItem=mn.Append(wx.ID_ANY, 'Show Moments', 'Show image moments ', kind=wx.ITEM_CHECK);self.Bind(wx.EVT_MENU, self.OnShowMoments, mnItem)
|
||||
self.mnItemShowMoment=mnItem
|
||||
mnItem=mn.Append(wx.ID_ANY, 'Tomo Normalize', 'Multiplies each pixel with a normalization factor. Assumes there exist an array exchange/data_white', kind=wx.ITEM_CHECK);self.Bind(wx.EVT_MENU, self.OnTomoNormalize, mnItem)
|
||||
self.mnItemTomoNormalize=mnItem
|
||||
|
||||
|
||||
mnBar.Append(mn, '&Edit')
|
||||
mn = wx.Menu()
|
||||
mnItem=mn.Append(wx.ID_ANY, 'Help', 'How to use the image viewer');self.Bind(wx.EVT_MENU, self.OnHelp, mnItem)
|
||||
mnBar.Append(mn, '&Help')
|
||||
|
||||
self.SetMenuBar(mnBar)
|
||||
self.CreateStatusBar()
|
||||
|
||||
def OnUpdate(self, msg, usrData):
|
||||
# this is the model-view-control update function
|
||||
print 'OnUpdate',self, msg, usrData
|
||||
|
||||
def SetIdxXY(self,x,y):
|
||||
self.idxXY=(x,y)
|
||||
|
||||
@staticmethod
|
||||
def SetStatusCB(obj,mode,v):
|
||||
if mode==0:
|
||||
obj.SetStatusText( "x= %d y=%d val=%g"%v,0)
|
||||
elif mode==1:
|
||||
obj.SetStatusText( "Colormap Value %d (drag to scale)"%v,0)
|
||||
else:
|
||||
raise KeyError('wrong mode')
|
||||
|
||||
|
||||
def OnShowMoments(self,event):
|
||||
if event.IsChecked():
|
||||
dlg = wx.FileDialog(self, "Choose valid mask file (e.g. pilatus_valid_mask.mat)", os.getcwd(), '','MATLAB files (*.mat)|*.mat|all (*.*)|*.*', wx.OPEN|wx.FD_CHANGE_DIR)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
fnMatMsk = dlg.GetPath()
|
||||
print 'OnOpen',fnMatMsk
|
||||
dlg.Destroy()
|
||||
if not fnMatMsk:
|
||||
return
|
||||
#fnMatMsk='/scratch/detectorData/cSAXS_2013_10_e14608_georgiadis_3D_for_Marianne/analysis/data/pilatus_valid_mask.mat'
|
||||
self.procMoment=pm=ProcMoment()
|
||||
pm.SetMskMat(fnMatMsk,False)
|
||||
#roi=[603, 826, 200, 200]
|
||||
#pm.roi=(slice(roi[1],roi[1]+roi[3]),slice(roi[0],roi[0]+roi[2]))
|
||||
#pm.shape=(roi[3],roi[2])
|
||||
|
||||
#pm.SetProcess('python')
|
||||
#pm.SetProcess('pyFast')
|
||||
pm.SetProcess('c')
|
||||
self.PlotMoments()
|
||||
#self.canvas.img.draw()
|
||||
data=self.canvas.img.get_array()
|
||||
self.canvas.img.set_array(data)
|
||||
fig, ax = plt.subplots(2)
|
||||
v=data.sum(axis=0); x=np.arange(v.size); x0=x.sum(); m0=v.sum(); m1=(v*x).sum(); m2=(v*x*x).sum()
|
||||
ax[0].plot(v);
|
||||
m=m1/m0
|
||||
s=np.sqrt( (m2-(m1**2/m0))/m0)
|
||||
xx=1/(s*np.sqrt(2*np.pi))*np.exp(-.5*((x-m)/s)**2)
|
||||
ax[0].set_title('%g | %g | %g | %g | %g'%(m0,m1,m2,m,s))
|
||||
ax[0].hold(True);ax[0].plot(xx*m0)
|
||||
|
||||
v=data.sum(axis=1);
|
||||
ax[1].plot(v);
|
||||
|
||||
|
||||
plt.show()
|
||||
#print pm.resArr[0:3],pm.resArr[1]/pm.resArr[0],pm.resArr[2]/pm.resArr[0]
|
||||
else:
|
||||
for o in self.goMoment:
|
||||
o.remove()
|
||||
del self.goMoment
|
||||
del self.procMoment
|
||||
self.canvas.draw()
|
||||
|
||||
def PlotMoments(self):
|
||||
data=self.canvas.img.get_array()
|
||||
pm=self.procMoment
|
||||
|
||||
#data=ndi.median_filter(data, 3)
|
||||
try:
|
||||
data.ravel()[pm.mskIdx]=0
|
||||
except AttributeError as e:
|
||||
print e
|
||||
try:
|
||||
data=data[pm.roi]
|
||||
except AttributeError as e:
|
||||
print e
|
||||
#data=np.log(data+1)
|
||||
#data[100:110,500:510]=1000 #y,x
|
||||
#data[650:850,700:850]=0 #y,x
|
||||
#pm.Process(np.log(data+1))
|
||||
pm.Process(data)
|
||||
xbar, ybar, cov=pm.GetIntertialAxis()
|
||||
|
||||
m=pm.resArr
|
||||
m00=m[0];m01=m[1];m10=m[2];m11=m[3];m02=m[4];m20=m[5]
|
||||
|
||||
xm = m10 / m00
|
||||
ym = m01 / m00
|
||||
u11 = (m11 - xm * m01) / m00
|
||||
#u11[u11<0.]=0. #processing rounding error
|
||||
u20 = (m20 - xm * m10) / m00
|
||||
u02 = (m02 - ym * m01) / m00
|
||||
a=(u20+u02)/2
|
||||
b=np.sqrt(4*u11**2+(u20-u02)**2)/2
|
||||
l0=a+b
|
||||
l1=a-b
|
||||
ang=0.5*np.arctan2(2*u11,(u20-u02))/(2*np.pi)*360. #orientation value 0..1
|
||||
exc=np.sqrt(1-l1/l0) #eccentricity :circle=0: http://en.wikipedia.org/wiki/Eccentricity_%28mathematics%29
|
||||
|
||||
print 'xb:%g yb:%g cov:%g %g %g %g ang:%g exc:%g'%((xm, ym)+tuple(cov.ravel())+(ang,exc))
|
||||
#fig, ax = plt.subplots()
|
||||
#ax.imshow(data,vmax=100,interpolation='nearest')
|
||||
#plt.show()
|
||||
ax=self.canvas.img.get_axes()
|
||||
try:
|
||||
for o in self.goMoment:
|
||||
o.remove()
|
||||
except AttributeError: pass
|
||||
|
||||
self.goMoment=ProcMoment.PlotMoments(ax, xbar, ybar, cov)
|
||||
ax.axis('image')
|
||||
|
||||
def OnTomoNormalize(self,event):
|
||||
if event.IsChecked():
|
||||
#try to find white image
|
||||
#calculate average
|
||||
#show white normalize factors
|
||||
white=self.data.parent['data_white']
|
||||
tomoNorm=white[1,:,:]
|
||||
#tomoNorm=white[:,:,:].mean(axis=0)
|
||||
#np.iinfo(tomoNorm.dtype).max
|
||||
#tomoNorm=float(np.iinfo(tomoNorm.dtype).max/2)/tomoNorm
|
||||
tomoNorm=tomoNorm.mean()/tomoNorm
|
||||
#tomoNorm=tomoNorm/float(np.iinfo(tomoNorm.dtype).max)
|
||||
data=self.canvas.img.get_array()
|
||||
data*=tomoNorm
|
||||
#data/=tomoNorm
|
||||
self.tomoNorm=tomoNorm
|
||||
self.canvas.img.set_array(data)
|
||||
else:
|
||||
tomoNorm=self.tomoNorm
|
||||
data=self.canvas.img.get_array()
|
||||
data/=tomoNorm
|
||||
self.canvas.img.set_array(data)
|
||||
del self.tomoNorm
|
||||
self.canvas.draw()
|
||||
|
||||
def OnSetComplexData(self, event):
|
||||
if event.IsChecked():
|
||||
data=np.angle(self.canvas.dataRaw)
|
||||
else:
|
||||
data=np.absolute(self.canvas.dataRaw)
|
||||
self.canvas.img.set_array(data)
|
||||
self.canvas.draw()
|
||||
|
||||
def OnHelp(self,event):
|
||||
msg='''to change the image selection:
|
||||
use the toolbar at the bottom to pan and zoom the image
|
||||
use the scrollbars at the bottom (if present) to select an other slice
|
||||
|
||||
to change the colorscale:
|
||||
drag with left mouse button to move the colorbar up and down
|
||||
drag with right mouse button to zoom in/out the colorbar at a given point
|
||||
use mouse weel to zoom in/out the colorbar at a given point
|
||||
double click left mouse button to set maximum and minimun colorbar values
|
||||
use cursor up and down to use a different colormap'''
|
||||
dlg = wx.MessageDialog(self, msg, 'Help', wx.OK|wx.ICON_INFORMATION)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
|
||||
def OnColmapSetup(self,event):
|
||||
dlg=DlgColBarSetup(self)
|
||||
if dlg.ShowModal()==wx.ID_OK:
|
||||
pass
|
||||
dlg.Destroy()
|
||||
|
||||
def OnInvertAxis(self,event):
|
||||
ax=self.canvas.ax
|
||||
#event.Checked()
|
||||
if self.mnIDxAxis==event.GetId():
|
||||
ax.invert_xaxis()
|
||||
else:
|
||||
ax.invert_yaxis()
|
||||
self.canvas.draw()
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
import os,sys,argparse #since python 2.7
|
||||
def GetParser(required=True):
|
||||
fnHDF='/scratch/detectorData/e14472_00033.hdf5'
|
||||
#lbl='mcs'
|
||||
lbl='pilatus_1'
|
||||
#lbl='spec'
|
||||
elem='/entry/dataScan00033/'+lbl
|
||||
exampleCmd='--hdfFile='+fnHDF+' --elem='+elem
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description=__doc__,
|
||||
epilog='Example:\n'+os.path.basename(sys.argv[0])+' '+exampleCmd+'\n ')
|
||||
parser.add_argument('--hdfFile', required=required, default=fnHDF, help='the hdf5 to show')
|
||||
parser.add_argument('--elem', required=required, default=elem, help='the path to the element in the hdf5 file')
|
||||
return parser
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
class App(wx.App):
|
||||
def OnInit(self):
|
||||
parser=GetParser()
|
||||
#parser=GetParser(False) # debug with exampleCmd
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
self.fid=fid=h5py.h5f.open(args.hdfFile)
|
||||
except IOError as e:
|
||||
sys.stderr.write('Unable to open File: '+args.hdfFile+'\n')
|
||||
parser.print_usage(sys.stderr)
|
||||
return True
|
||||
try:
|
||||
hid = h5py.h5o.open(fid,args.elem)
|
||||
except KeyError as e:
|
||||
sys.stderr.write('Unable to open Object: '+args.elem+'\n')
|
||||
parser.print_usage(sys.stderr)
|
||||
return True
|
||||
frame = HdfImageFrame(None,args.elem,hid)
|
||||
frame.Show()
|
||||
self.SetTopWindow(frame)
|
||||
return True
|
||||
|
||||
def OnExit(self):
|
||||
self.fid.close()
|
||||
|
||||
ut.StopWatch.Start()
|
||||
app = App()
|
||||
app.MainLoop()
|
||||
347
python/MAxyPlot.py
Normal file
347
python/MAxyPlot.py
Normal file
@@ -0,0 +1,347 @@
|
||||
#!/usr/bin/env python
|
||||
#*-----------------------------------------------------------------------*
|
||||
#| |
|
||||
#| Copyright (c) 2013 by Paul Scherrer Institute (http://www.psi.ch) |
|
||||
#| |
|
||||
#| Author Thierry Zamofing (thierry.zamofing@psi.ch) |
|
||||
#*-----------------------------------------------------------------------*
|
||||
'''
|
||||
implements an image view to show a colored image of a hdf5 dataset.
|
||||
'''
|
||||
|
||||
if __name__ == '__main__':
|
||||
#Used to guarantee to use at least Wx2.8
|
||||
import wxversion
|
||||
wxversion.ensureMinimal('2.8')
|
||||
import wx
|
||||
import matplotlib as mpl
|
||||
if __name__ == '__main__':
|
||||
mpl.use('WXAgg')
|
||||
#or mpl.use('WX')
|
||||
#matplotlib.get_backend()
|
||||
|
||||
import wxutils as ut
|
||||
import os
|
||||
import numpy as np
|
||||
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
|
||||
import pylab as plt #used for the colormaps
|
||||
|
||||
#or from matplotlib.backends.backend_wx import FigureCanvasWx as FigureCanvas
|
||||
#The source of the DraggableColorbar is from:
|
||||
#http://www.ster.kuleuven.be/~pieterd/python/html/plotting/interactive_colorbar.html
|
||||
|
||||
class MPLCanvasImg(FigureCanvas):
|
||||
def __init__(self,parent,SetStatusCB=None):
|
||||
if SetStatusCB:
|
||||
self.SetStatusCB=SetStatusCB
|
||||
fig = mpl.figure.Figure()
|
||||
ax = fig.add_axes([0.075,0.075,0.85,0.85])
|
||||
FigureCanvas.__init__(self,parent, -1, fig)
|
||||
self.mpl_connect('motion_notify_event', self.OnMotion)
|
||||
self.mpl_connect('button_press_event', self.OnBtnPress)
|
||||
self.mpl_connect('button_release_event', self.OnBtnRelease)
|
||||
self.mpl_connect('scroll_event', self.OnBtnScroll)
|
||||
self.mpl_connect('key_press_event',self.OnKeyPress)
|
||||
#self.mpl_connect('pick_event',self.OnPick) #works but locks the screed if debugging
|
||||
self.fig=fig
|
||||
self.ax=ax
|
||||
|
||||
def InitChild(self,pts,rec):
|
||||
|
||||
fig=self.fig
|
||||
ax=self.ax
|
||||
|
||||
hl=[]
|
||||
hl+=ax.plot(pts[:,0],pts[:,1],'r.',label='ptsDot') #,picker=5 default value
|
||||
hl+=ax.plot(pts[:,0],pts[:,1],'y--',label='ptsLine')
|
||||
|
||||
ec = mpl.collections.EllipseCollection(1, 1, 0, units='xy', offsets=pts,transOffset=ax.transData,edgecolors='g',facecolors=(1,1,0,0.3))
|
||||
ax.add_collection(ec)
|
||||
|
||||
|
||||
hl+=ax.plot(rec[:, 4], rec[:, 5], 'b-',label='recDesPos')
|
||||
hl+=ax.plot(rec[:,1],rec[:,2],'g-',label='recActPos')
|
||||
ax.xaxis.set_label_text('x-pos um')
|
||||
ax.yaxis.set_label_text('y-pos um')
|
||||
|
||||
fig.obj=self
|
||||
self.ax=ax
|
||||
self.hl=hl
|
||||
|
||||
def OnPick(self,event):
|
||||
thisline = event.artist
|
||||
xdata = thisline.get_xdata()
|
||||
ydata = thisline.get_ydata()
|
||||
ind = event.ind
|
||||
points = tuple(zip(xdata[ind], ydata[ind]))
|
||||
print('onpick points:', points)
|
||||
pass
|
||||
|
||||
|
||||
def OnMotion(self,event):
|
||||
#print event,event.x,event.y,event.inaxes,event.xdata,event.ydata
|
||||
|
||||
if event.inaxes==self.ax:
|
||||
|
||||
x=int(round(event.xdata))
|
||||
y=int(round(event.ydata))
|
||||
s=''
|
||||
for h in self.ax.get_lines(): # to get also the ellipses: self.ax.get_children()
|
||||
c=h.contains(event)
|
||||
if c[0]:
|
||||
#s = str(h)+str(c[1])
|
||||
#print "over %s" % s
|
||||
if type(h)==mpl.lines.Line2D:
|
||||
lbl=h.get_label()
|
||||
arr=h.get_data()
|
||||
idx=c[1]['ind'][0]
|
||||
s += '%s[%d] = [%.2f, %.2f]'%(lbl,idx,arr[0][idx],arr[1][idx])
|
||||
else:
|
||||
s += str(h)+str(c[1])
|
||||
|
||||
self.SetStatusCB(self.Parent, 0, (x, y, s))
|
||||
|
||||
#try:
|
||||
# #v=self.img.get_array()[y,x]
|
||||
# v=0;
|
||||
#except IndexError as e:
|
||||
# pass
|
||||
#else:
|
||||
#print x,y,v
|
||||
|
||||
#if event.button==1:#move top,bottom,both
|
||||
# pD = event.y - pS
|
||||
# vD=(vmax-vmin)/(p1-p0)*(pS-event.y)
|
||||
# colBar.norm.vmin = vmin+vD
|
||||
# colBar.norm.vmax = vmax+vD
|
||||
#elif event.button==3:#scale around point
|
||||
# scale= np.exp((pS-event.y)/100)
|
||||
# vS=vmin+(vmax-vmin)/(p1-p0)*(pS-p0)
|
||||
# #print scale,vS
|
||||
# colBar.norm.vmin = vS-scale*(vS-vmin)
|
||||
# colBar.norm.vmax = vS-scale*(vS-vmax)
|
||||
|
||||
def OnBtnPress(self, event):
|
||||
"""on button press we will see if the mouse is over us and store some data"""
|
||||
print dir(event.guiEvent)
|
||||
return
|
||||
if event.inaxes == self.colBar.ax:
|
||||
#if event.guiEvent.LeftDClick()==True:
|
||||
# print dlg
|
||||
pt=self.colBar.ax.bbox.get_points()[:,1]
|
||||
nrm=self.colBar.norm
|
||||
self.colBarPressed = (nrm.vmin,nrm.vmax,pt[0],pt[1],event.y)
|
||||
#self.colBarPressed = event.x, event.y
|
||||
#print self.colBarPressed
|
||||
#self.OnMouse(event)
|
||||
pass
|
||||
|
||||
def OnBtnRelease(self, event):
|
||||
"""on release we reset the press data"""
|
||||
#self.OnMouse(event)
|
||||
return
|
||||
try: del self.colBarPressed
|
||||
except AttributeError: pass
|
||||
|
||||
def OnBtnScroll(self, event):
|
||||
return
|
||||
#self.OnMouse(event)
|
||||
colBar=self.colBar
|
||||
if event.inaxes==colBar.ax:
|
||||
pt=colBar.ax.bbox.get_points()[:,1]
|
||||
nrm=colBar.norm
|
||||
vmin,vmax,p0,p1,pS = (nrm.vmin,nrm.vmax,pt[0],pt[1],event.y)
|
||||
if isinstance(colBar.norm,mpl.colors.LogNorm):#type(colBar.norm)==mpl.colors.LogNorm does not work...
|
||||
scale= np.exp((-event.step)/10)
|
||||
colBar.norm.vmax=vmax*scale
|
||||
else:#scale around point
|
||||
scale= np.exp((-event.step)/10)
|
||||
vS=vmin+(vmax-vmin)/(p1-p0)*(pS-p0)
|
||||
#print scale,vS
|
||||
colBar.norm.vmin = vS-scale*(vS-vmin)
|
||||
colBar.norm.vmax = vS-scale*(vS-vmax)
|
||||
self.img.set_norm(colBar.norm)#force image to redraw
|
||||
colBar.patch.figure.canvas.draw()
|
||||
|
||||
def OnKeyPress(self, event):
|
||||
return
|
||||
colCycle=self.colCycle
|
||||
colBar=self.colBar
|
||||
if event.key=='down':
|
||||
self.colIndex += 1
|
||||
elif event.key=='up':
|
||||
self.colIndex -= 1
|
||||
self.colIndex%=len(colCycle)
|
||||
cmap = colCycle[self.colIndex]
|
||||
colBar.set_cmap(cmap)
|
||||
colBar.draw_all()
|
||||
self.img.set_cmap(cmap)
|
||||
self.img.get_axes().set_title(cmap)
|
||||
colBar.patch.figure.canvas.draw()
|
||||
|
||||
def OnMouse(self, event):
|
||||
return
|
||||
for k in dir(event):
|
||||
if k[0]!='_':
|
||||
print k,getattr(event,k)
|
||||
|
||||
class MAxyPlotFrame(wx.Frame):
|
||||
def __del__(self):
|
||||
self.doc.view.remove(self)
|
||||
|
||||
def __init__(self, parent,doc):
|
||||
wx.Frame.__init__(self, parent, title='xy-Plot', size=wx.Size(850, 650))
|
||||
self.doc=doc;doc.view.append(self)
|
||||
imgDir=ut.Path.GetImage()
|
||||
icon = wx.Icon(os.path.join(imgDir,'PBMA.ico'), wx.BITMAP_TYPE_ICO)
|
||||
self.SetIcon(icon)
|
||||
|
||||
canvas = MPLCanvasImg(self,self.SetStatusCB)
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
toolbar=ut.AddToolbar(canvas,sizer)
|
||||
|
||||
wxAxCtrlLst=[]
|
||||
#l=len(data.shape)
|
||||
#idxXY=(l-2,l-1)
|
||||
#for idx,l in enumerate(data.shape):
|
||||
# if idx in idxXY:
|
||||
# continue
|
||||
# wxAxCtrl=ut.SliderGroup(self, label='Axis:%d'%idx,range=(0,l-1))
|
||||
# wxAxCtrl.idx=idx
|
||||
# wxAxCtrlLst.append(wxAxCtrl)
|
||||
# sizer.Add(wxAxCtrl.sizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5)
|
||||
# wxAxCtrl.SetCallback(HdfImageFrame.OnSetView,wxAxCtrl)
|
||||
|
||||
#sl=ut.GetSlice(idxXY,data.shape,wxAxCtrlLst)
|
||||
#wxAxCtrl=ut.SliderGroup(self, label='Axis:%d'%1,range=(0,1000))
|
||||
#wxAxCtrl.SetCallback(MAxyPlotFrame.OnSetView,wxAxCtrl)
|
||||
#sizer.Add(wxAxCtrl.sizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5)
|
||||
|
||||
canvas.InitChild(doc.fh['pts'],doc.fh['rec'])
|
||||
|
||||
#self.Fit()
|
||||
self.Centre()
|
||||
|
||||
self.BuildMenu()
|
||||
self.canvas=canvas
|
||||
self.sizer=sizer
|
||||
self.toolbar=toolbar
|
||||
#self.data=data
|
||||
#self.idxXY=idxXY
|
||||
#self.wxAxCtrlLst=wxAxCtrlLst
|
||||
|
||||
def BuildMenu(self):
|
||||
mnBar = wx.MenuBar()
|
||||
|
||||
#-------- Edit Menu --------
|
||||
mn = wx.Menu()
|
||||
#mnItem=mn.Append(wx.ID_ANY, 'Setup Colormap', 'Setup the color mapping ');self.Bind(wx.EVT_MENU, self.OnColmapSetup, mnItem)
|
||||
#mnItem=mn.Append(wx.ID_ANY, 'Invert X-Axis', kind=wx.ITEM_CHECK);self.Bind(wx.EVT_MENU, self.OnInvertAxis, mnItem)
|
||||
#self.mnIDxAxis=mnItem.GetId()
|
||||
#mnItem=mn.Append(wx.ID_ANY, 'Invert Y-Axis', kind=wx.ITEM_CHECK);self.Bind(wx.EVT_MENU, self.OnInvertAxis, mnItem)
|
||||
#mnItem=mn.Append(wx.ID_ANY, 'Show Moments', 'Show image moments ', kind=wx.ITEM_CHECK);self.Bind(wx.EVT_MENU, self.OnShowMoments, mnItem)
|
||||
#self.mnItemShowMoment=mnItem
|
||||
#mnItem=mn.Append(wx.ID_ANY, 'Tomo Normalize', 'Multiplies each pixel with a normalization factor. Assumes there exist an array exchange/data_white', kind=wx.ITEM_CHECK);self.Bind(wx.EVT_MENU, self.OnTomoNormalize, mnItem)
|
||||
#self.mnItemTomoNormalize=mnItem
|
||||
|
||||
mnBar.Append(mn, '&Edit')
|
||||
#mnItem=mn.Append(wx.ID_ANY, 'Animate', 'Animate the motion');self.Bind(wx.EVT_MENU, self.OnAnimate, mnItem)
|
||||
|
||||
mn = wx.Menu()
|
||||
mnItem=mn.Append(wx.ID_ANY, 'Help', 'How to use the image viewer');self.Bind(wx.EVT_MENU, self.OnHelp, mnItem)
|
||||
mnBar.Append(mn, '&Help')
|
||||
|
||||
self.SetMenuBar(mnBar)
|
||||
self.CreateStatusBar()
|
||||
|
||||
def OnUpdate(self, msg, usrData):
|
||||
# this is the model-view-control update function
|
||||
print 'OnUpdate',self, msg, usrData
|
||||
if msg==0:
|
||||
canvas=self.canvas
|
||||
ax=canvas.ax
|
||||
len=usrData
|
||||
rec=self.doc.fh['rec']
|
||||
hl=canvas.hl
|
||||
hl[2].set_data(rec[:len, 4], rec[:len, 5])
|
||||
hl[3].set_data(rec[:len, 1], rec[:len, 2])
|
||||
#ax.draw_artist(hl[2])
|
||||
x=ax.get_xlim();x=(x[1]-x[0])/2;
|
||||
y=ax.get_ylim();y=(y[1]-y[0])/2;
|
||||
ax.set_xlim(rec[len, 1]-x,rec[len, 1]+x)
|
||||
ax.set_ylim(rec[len, 2]-y,rec[len, 2]+y)
|
||||
canvas.draw()
|
||||
|
||||
@staticmethod
|
||||
def SetStatusCB(obj,mode,v):
|
||||
if mode==0:
|
||||
obj.SetStatusText( "x= %d y=%d val=%s"%v,0)
|
||||
else:
|
||||
raise KeyError('wrong mode')
|
||||
|
||||
def OnHelp(self,event):
|
||||
msg='''to change the image selection:
|
||||
use the toolbar at the bottom to pan and zoom the image
|
||||
use the scrollbars at the bottom (if present) to select an other slice
|
||||
|
||||
to change the colorscale:
|
||||
drag with left mouse button to move the colorbar up and down
|
||||
drag with right mouse button to zoom in/out the colorbar at a given point
|
||||
use mouse weel to zoom in/out the colorbar at a given point
|
||||
double click left mouse button to set maximum and minimun colorbar values
|
||||
use cursor up and down to use a different colormap'''
|
||||
dlg = wx.MessageDialog(self, msg, 'Help', wx.OK|wx.ICON_INFORMATION)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import os,sys,argparse #since python 2.7
|
||||
def GetParser(required=True):
|
||||
fnHDF='/scratch/detectorData/e14472_00033.hdf5'
|
||||
#lbl='mcs'
|
||||
lbl='pilatus_1'
|
||||
#lbl='spec'
|
||||
elem='/entry/dataScan00033/'+lbl
|
||||
exampleCmd='--hdfFile='+fnHDF+' --elem='+elem
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description=__doc__,
|
||||
epilog='Example:\n'+os.path.basename(sys.argv[0])+' '+exampleCmd+'\n ')
|
||||
parser.add_argument('--hdfFile', required=required, default=fnHDF, help='the hdf5 to show')
|
||||
parser.add_argument('--elem', required=required, default=elem, help='the path to the element in the hdf5 file')
|
||||
return parser
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
class App(wx.App):
|
||||
def OnInit(self):
|
||||
parser=GetParser()
|
||||
#parser=GetParser(False) # debug with exampleCmd
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
self.fid=fid=h5py.h5f.open(args.hdfFile)
|
||||
except IOError as e:
|
||||
sys.stderr.write('Unable to open File: '+args.hdfFile+'\n')
|
||||
parser.print_usage(sys.stderr)
|
||||
return True
|
||||
try:
|
||||
hid = h5py.h5o.open(fid,args.elem)
|
||||
except KeyError as e:
|
||||
sys.stderr.write('Unable to open Object: '+args.elem+'\n')
|
||||
parser.print_usage(sys.stderr)
|
||||
return True
|
||||
frame = HdfImageFrame(None,args.elem,hid)
|
||||
frame.Show()
|
||||
self.SetTopWindow(frame)
|
||||
return True
|
||||
|
||||
def OnExit(self):
|
||||
self.fid.close()
|
||||
|
||||
ut.StopWatch.Start()
|
||||
app = App()
|
||||
app.MainLoop()
|
||||
@@ -2,30 +2,36 @@ import os,sys
|
||||
import wx
|
||||
import wx.py
|
||||
import numpy as np
|
||||
from MAxyPlot import *
|
||||
from MAError import *
|
||||
#from hdfTree import *
|
||||
#from hdfGrid import *
|
||||
#from hdfAttrib import *
|
||||
#from hdfImage import *
|
||||
|
||||
import utilities as ut
|
||||
import wxutils as ut
|
||||
class MADoc():
|
||||
'''
|
||||
|
||||
class Path():
|
||||
@staticmethod
|
||||
def GetImage():
|
||||
path=__file__
|
||||
try:symPath=os.readlink(path) #follow symbolic link
|
||||
except (AttributeError,OSError) as e:pass
|
||||
else:
|
||||
path=symPath
|
||||
path=os.path.abspath(path)
|
||||
path=os.path.dirname(path)
|
||||
return os.path.join(path,'images')
|
||||
Implemented messages
|
||||
0: The time slider has changed. usrData=index
|
||||
1: The position slider has changed. usrData=index
|
||||
'''
|
||||
|
||||
def __init__(self):
|
||||
self.view=[] #list of object that have view on this document
|
||||
pass
|
||||
|
||||
def Update(self,skipView,msg,usrData):
|
||||
for v in self.view:
|
||||
if v==skipView: continue
|
||||
v.OnUpdate(msg,usrData)
|
||||
|
||||
|
||||
class AboutFrame(wx.Frame):
|
||||
def __init__(self,parent):
|
||||
wx.Frame.__init__(self,parent,-1,'About MotionAnalyzer',size=(300,330))
|
||||
imgDir=Path.GetImage()
|
||||
imgDir=ut.Path.GetImage()
|
||||
icon = wx.Icon(os.path.join(imgDir,'PBMA.ico'), wx.BITMAP_TYPE_ICO)
|
||||
self.SetIcon(icon)
|
||||
self.Centre()
|
||||
@@ -43,8 +49,9 @@ class AboutFrame(wx.Frame):
|
||||
class MAMainFrame(wx.Frame):
|
||||
|
||||
def OpenFile(self,fn_npz):
|
||||
doc=self.doc
|
||||
try:
|
||||
self.fh=fh=np.load(fn_npz)
|
||||
doc.fh=fh=np.load(fn_npz)
|
||||
except IOError as e:
|
||||
sys.stderr.write('Unable to open File: '+fn_npz+'\n')
|
||||
else:
|
||||
@@ -53,7 +60,16 @@ class MAMainFrame(wx.Frame):
|
||||
for k,v in fh.iteritems():
|
||||
s+=' '+k+': '+str(v.dtype)+' '+str(v.shape)+'\n'
|
||||
self.wxTxt.SetLabel(s)
|
||||
#self.wxTree.ShowHirarchy(self.fid)
|
||||
|
||||
lenRec=fh['rec'].shape[0]
|
||||
lenPts=fh['pts'].shape[0]
|
||||
self.wxTimeCtrl.slider.SetRange(0,lenRec-1)
|
||||
self.wxTimeCtrl.slider.SetPageSize(lenRec/lenPts)
|
||||
|
||||
self.xPosCtrl.slider.SetRange(0,lenPts-1)
|
||||
|
||||
#self.wxTimeCtrl.slider.SetPageSize(100)
|
||||
#self.wxTree.ShowHirarchy(self.fid)
|
||||
|
||||
def CloseFile(self):
|
||||
#http://docs.wxwidgets.org/2.8/wx_windowdeletionoverview.html#windowdeletionoverview
|
||||
@@ -64,9 +80,10 @@ class MAMainFrame(wx.Frame):
|
||||
except AttributeError as e:
|
||||
pass
|
||||
|
||||
def __init__(self, parent, title):
|
||||
def __init__(self, parent, title,doc):
|
||||
wx.Frame.__init__(self, parent, title=title, size=wx.Size(650, 350))
|
||||
imgDir=Path.GetImage()
|
||||
self.doc=doc;doc.view.append(self)
|
||||
imgDir=ut.Path.GetImage()
|
||||
icon = wx.Icon(os.path.join(imgDir,'PBMA.ico'), wx.BITMAP_TYPE_ICO)
|
||||
self.SetIcon(icon)
|
||||
#wxSplt = wx.SplitterWindow(self, -1)
|
||||
@@ -75,16 +92,29 @@ class MAMainFrame(wx.Frame):
|
||||
#wxTree.Bind(wx.EVT_TREE_ITEM_MENU, self.OnMenu, id=1)
|
||||
#wx.EVT_TREE_ITEM_MENU(id, func)
|
||||
#wxTxt = wx.StaticText(wxSplt, -1, '',(10,10) )#, style=wx.ALIGN_CENTRE)
|
||||
self.wxTxt = wx.StaticText(self, wx.ID_ANY, "MyLabel", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
|
||||
#wxSplt.SplitVertically(wxTree, wxTxt)
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.SetSizer(sizer)
|
||||
wxTxt = wx.StaticText(self, wx.ID_ANY, "MyLabel", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
|
||||
sizer.Add(wxTxt, 1, wx.LEFT | wx.TOP | wx.GROW)
|
||||
|
||||
wxTimeCtrl=ut.SliderGroup(self, label='Time', range=(0, 1000))
|
||||
wxTimeCtrl.SetCallback(MAMainFrame.OnSetTime, wxTimeCtrl)
|
||||
sizer.Add(wxTimeCtrl.sizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5) #wxSplt.SplitVertically(wxTree, wxTxt)
|
||||
wxPosCtrl=ut.SliderGroup(self, label='Position', range=(0, 1000))
|
||||
wxPosCtrl.SetCallback(MAMainFrame.OnSetPosition, wxPosCtrl)
|
||||
sizer.Add(wxPosCtrl.sizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5) #wxSplt.SplitVertically(wxTree, wxTxt)
|
||||
#wxSplt.SetMinimumPaneSize(320)
|
||||
#wxLstCtrl=HdfAttrListCtrl(wxSplt)
|
||||
#wxSplt.SplitVertically(wxTree, wxLstCtrl)
|
||||
self.BuildMenu()
|
||||
|
||||
self.Centre()
|
||||
|
||||
self.wxTimeCtrl=wxTimeCtrl
|
||||
self.xPosCtrl=wxPosCtrl
|
||||
self.wxTxt=wxTxt
|
||||
#self.wxTree=wxTree
|
||||
#self.display=wxTxt
|
||||
def __del__(self):
|
||||
@@ -146,11 +176,16 @@ class MAMainFrame(wx.Frame):
|
||||
#mn.AppendItem(mnItem)
|
||||
self.SetMenuBar(mnBar)
|
||||
self.CreateStatusBar()
|
||||
self.SetStatusText("This is the status message")
|
||||
|
||||
def OnShowXYPath(self, event):
|
||||
pass
|
||||
frame=MAxyPlotFrame(self,self.doc)
|
||||
frame.Show(True)
|
||||
|
||||
def OnShowError(self, event):
|
||||
pass
|
||||
frame=MAErrorFrame(self,self.doc)
|
||||
frame.Show(True)
|
||||
|
||||
def OnShowVelocity(self, event):
|
||||
pass
|
||||
|
||||
@@ -192,7 +227,43 @@ rec
|
||||
# 'hid=wxTree.GetPyData(wxNode)']:
|
||||
# shell.run(cmd, prompt=False)
|
||||
|
||||
def OnUpdate(self,msg,usrData):
|
||||
#this is the model-view-control update function
|
||||
print self,msg,usrData
|
||||
|
||||
@staticmethod
|
||||
def OnSetTime(usrData, value, msg):
|
||||
'called when the time slider has been changed'
|
||||
print 'OnSetTime', usrData, value, msg
|
||||
view=usrData.slider.Parent
|
||||
doc=view.doc
|
||||
doc.Update(view,0,value)
|
||||
# imgFrm=usrData.slider.Parent
|
||||
# imgFrm.img.set_array(imgFrm.data[usrData.value,...])
|
||||
# data=imgFrm.data
|
||||
# sl=ut.GetSlice(imgFrm.idxXY,data.shape,imgFrm.wxAxCtrlLst)
|
||||
|
||||
# try:
|
||||
# tomoNorm=imgFrm.tomoNorm
|
||||
# except AttributeError:
|
||||
# imgFrm.canvas.img.set_array(data[sl])
|
||||
# else:
|
||||
# data=data[sl]*tomoNorm
|
||||
# imgFrm.canvas.img.set_array(data)
|
||||
|
||||
# if imgFrm.mnItemShowMoment.IsChecked():
|
||||
# imgFrm.PlotMoments()
|
||||
# imgFrm.canvas.draw()
|
||||
pass
|
||||
|
||||
|
||||
@staticmethod
|
||||
def OnSetPosition(usrData, value, msg):
|
||||
'called when the time slider has been changed'
|
||||
print 'OnSetPosition', usrData, value, msg
|
||||
view = usrData.slider.Parent
|
||||
doc = view.doc
|
||||
doc.Update(view, 1, value)
|
||||
|
||||
if __name__ == '__main__':
|
||||
def GetArgs():
|
||||
@@ -211,7 +282,8 @@ if __name__ == '__main__':
|
||||
|
||||
def OnInit(self):
|
||||
args=GetArgs()
|
||||
frame = MAMainFrame(None, 'PBMotionAnalyzer')
|
||||
doc=MADoc()
|
||||
frame = MAMainFrame(None,'PBMotionAnalyzer',doc)
|
||||
if args.npzFile:
|
||||
frame.OpenFile(args.npzFile)
|
||||
frame.Show(True)
|
||||
|
||||
BIN
python/data/shapepath.npz
Normal file
BIN
python/data/shapepath.npz
Normal file
Binary file not shown.
418
python/data/shapepath.prg
Normal file
418
python/data/shapepath.prg
Normal file
@@ -0,0 +1,418 @@
|
||||
Gather.Enable=0
|
||||
Gather.Items=6
|
||||
Gather.MaxSamples=100000
|
||||
Gather.Period=10
|
||||
Gather.Addr[0]=Motor[1].ActPos.a
|
||||
Gather.Addr[1]=Motor[2].ActPos.a
|
||||
Gather.Addr[2]=Motor[3].ActPos.a
|
||||
Gather.Addr[3]=Motor[1].DesPos.a
|
||||
Gather.Addr[4]=Motor[2].DesPos.a
|
||||
Gather.Addr[5]=Motor[3].DesPos.a
|
||||
open prog 2
|
||||
Gather.Enable=2
|
||||
linear abs
|
||||
X(5.488135) Y(7.151894)
|
||||
X(56.027634) Y(5.448832)
|
||||
X(104.236548) Y(6.458941)
|
||||
X(154.375872) Y(8.917730)
|
||||
X(209.636628) Y(3.834415)
|
||||
X(257.917250) Y(5.288949)
|
||||
X(305.680446) Y(9.255966)
|
||||
X(350.710361) Y(0.871293)
|
||||
X(400.202184) Y(8.326198)
|
||||
X(457.781568) Y(8.700121)
|
||||
X(509.786183) Y(7.991586)
|
||||
X(554.614794) Y(7.805292)
|
||||
X(601.182744) Y(6.399210)
|
||||
X(651.433533) Y(9.446689)
|
||||
X(705.218483) Y(4.146619)
|
||||
X(752.645556) Y(7.742337)
|
||||
X(804.561503) Y(5.684339)
|
||||
X(850.187898) Y(6.176355)
|
||||
X(906.120957) Y(6.169340)
|
||||
X(959.437481) Y(6.818203)
|
||||
X(952.961402) Y(51.187277)
|
||||
X(902.828070) Y(51.201966)
|
||||
X(857.392636) Y(50.391878)
|
||||
X(809.767611) Y(56.048455)
|
||||
X(759.764595) Y(54.686512)
|
||||
X(708.379449) Y(50.960984)
|
||||
X(658.209932) Y(50.971013)
|
||||
X(601.965824) Y(53.687252)
|
||||
X(556.563296) Y(51.381830)
|
||||
X(501.589696) Y(51.103751)
|
||||
X(454.663108) Y(52.444256)
|
||||
X(406.531083) Y(52.532916)
|
||||
X(352.088768) Y(51.613095)
|
||||
X(309.883738) Y(51.020448)
|
||||
X(255.701968) Y(54.386015)
|
||||
X(203.154284) Y(53.637108)
|
||||
X(152.103826) Y(51.289263)
|
||||
X(106.667667) Y(56.706379)
|
||||
X(56.976312) Y(50.602255)
|
||||
X(3.595079) Y(54.370320)
|
||||
X(3.179832) Y(104.142630)
|
||||
X(50.641475) Y(106.924721)
|
||||
X(105.666015) Y(102.653895)
|
||||
X(155.232481) Y(100.939405)
|
||||
X(205.759465) Y(109.292962)
|
||||
X(253.185690) Y(106.674104)
|
||||
X(301.317979) Y(107.163272)
|
||||
X(352.894061) Y(101.831914)
|
||||
X(405.865129) Y(100.201075)
|
||||
X(458.289400) Y(100.046955)
|
||||
X(506.778165) Y(102.700080)
|
||||
X(557.351940) Y(109.621885)
|
||||
X(602.487531) Y(105.761573)
|
||||
X(655.920419) Y(105.722519)
|
||||
X(702.230816) Y(109.527490)
|
||||
X(754.471254) Y(108.464087)
|
||||
X(806.994793) Y(102.974370)
|
||||
X(858.137978) Y(103.965057)
|
||||
X(908.811032) Y(105.812729)
|
||||
X(958.817354) Y(106.925316)
|
||||
X(954.071833) Y(150.691670)
|
||||
X(908.073190) Y(155.691007)
|
||||
X(851.238200) Y(158.480082)
|
||||
X(801.624929) Y(156.155596)
|
||||
X(751.494483) Y(158.681261)
|
||||
X(707.142413) Y(159.988470)
|
||||
X(651.002269) Y(159.194826)
|
||||
X(608.061940) Y(157.038886)
|
||||
X(554.358649) Y(158.919234)
|
||||
X(508.965466) Y(153.675619)
|
||||
X(456.521033) Y(154.314184)
|
||||
X(405.743252) Y(156.532008)
|
||||
X(355.699649) Y(155.908728)
|
||||
X(301.354741) Y(152.982823)
|
||||
X(256.180154) Y(154.287687)
|
||||
X(206.601735) Y(152.900776)
|
||||
X(150.191932) Y(153.015748)
|
||||
X(104.238550) Y(156.063932)
|
||||
X(59.560836) Y(156.439902)
|
||||
X(7.252543) Y(155.013244)
|
||||
X(6.974288) Y(204.535427)
|
||||
X(57.220556) Y(208.663823)
|
||||
X(109.755215) Y(208.558033)
|
||||
X(150.117141) Y(203.599781)
|
||||
X(207.299906) Y(201.716297)
|
||||
X(255.210366) Y(200.543380)
|
||||
X(301.999965) Y(200.185218)
|
||||
X(357.936977) Y(202.239247)
|
||||
X(403.453517) Y(209.280813)
|
||||
X(457.044144) Y(200.318389)
|
||||
X(501.646942) Y(206.214784)
|
||||
X(555.772286) Y(202.378928)
|
||||
X(609.342140) Y(206.139660)
|
||||
X(655.356328) Y(205.899100)
|
||||
X(707.301220) Y(203.119450)
|
||||
X(753.982211) Y(202.098437)
|
||||
X(801.861930) Y(209.443724)
|
||||
X(857.395508) Y(204.904588)
|
||||
X(902.274146) Y(202.543565)
|
||||
X(950.580292) Y(204.344166)
|
||||
X(952.776287) Y(255.867843)
|
||||
X(903.741700) Y(254.635754)
|
||||
X(852.074701) Y(254.246855)
|
||||
X(805.182007) Y(250.256627)
|
||||
X(752.539416) Y(252.133120)
|
||||
X(709.473706) Y(257.308558)
|
||||
X(656.874883) Y(252.155077)
|
||||
X(601.856359) Y(259.527917)
|
||||
X(552.735420) Y(257.980468)
|
||||
X(506.289818) Y(258.726507)
|
||||
X(455.883171) Y(258.310485)
|
||||
X(403.200172) Y(253.834639)
|
||||
X(350.206510) Y(257.583787)
|
||||
X(306.630782) Y(252.633224)
|
||||
X(259.903389) Y(252.168970)
|
||||
X(205.365792) Y(258.966713)
|
||||
X(156.793928) Y(254.536968)
|
||||
X(100.246787) Y(250.672496)
|
||||
X(53.777518) Y(251.796037)
|
||||
X(3.117959) Y(256.963435)
|
||||
X(8.638556) Y(301.175319)
|
||||
X(55.173791) Y(301.320681)
|
||||
X(107.168597) Y(303.960597)
|
||||
X(155.654213) Y(301.832798)
|
||||
X(201.448478) Y(304.880563)
|
||||
X(253.556127) Y(309.404319)
|
||||
X(307.653253) Y(307.486636)
|
||||
X(359.037197) Y(300.834224)
|
||||
X(405.521925) Y(305.844761)
|
||||
X(459.619364) Y(302.921475)
|
||||
X(502.408288) Y(301.002939)
|
||||
X(550.164296) Y(309.295293)
|
||||
X(606.699165) Y(307.851529)
|
||||
X(652.817301) Y(305.864102)
|
||||
X(700.639553) Y(304.856276)
|
||||
X(759.774951) Y(308.765052)
|
||||
X(803.381590) Y(309.615702)
|
||||
X(852.317016) Y(309.493188)
|
||||
X(909.413777) Y(307.992026)
|
||||
X(956.304479) Y(308.742880)
|
||||
X(958.605512) Y(357.270443)
|
||||
X(904.205395) Y(355.573688)
|
||||
X(856.720478) Y(352.453672)
|
||||
X(800.795221) Y(350.896030)
|
||||
X(757.705807) Y(351.469466)
|
||||
X(707.255944) Y(350.114275)
|
||||
X(651.324876) Y(350.534272)
|
||||
X(604.072412) Y(352.322341)
|
||||
X(553.331452) Y(350.811014)
|
||||
X(509.065555) Y(357.740473)
|
||||
X(459.729195) Y(359.608347)
|
||||
X(400.978445) Y(358.621915)
|
||||
X(355.113190) Y(352.243170)
|
||||
X(308.221177) Y(351.898479)
|
||||
X(253.685846) Y(351.369003)
|
||||
X(204.973914) Y(356.394725)
|
||||
X(159.818294) Y(354.783703)
|
||||
X(103.472335) Y(351.481409)
|
||||
X(56.178767) Y(350.132369)
|
||||
X(2.930203) Y(358.489436)
|
||||
X(2.703279) Y(401.314828)
|
||||
X(50.553743) Y(403.015986)
|
||||
X(102.621181) Y(404.561406)
|
||||
X(156.832813) Y(406.956254)
|
||||
X(202.835188) Y(403.799270)
|
||||
X(251.811510) Y(407.885455)
|
||||
X(300.568481) Y(406.969972)
|
||||
X(357.786954) Y(407.774076)
|
||||
X(402.594226) Y(403.738131)
|
||||
X(455.875996) Y(402.728219)
|
||||
X(503.708528) Y(401.970543)
|
||||
X(554.598559) Y(400.446123)
|
||||
X(607.997959) Y(400.769564)
|
||||
X(655.188351) Y(403.068101)
|
||||
X(705.775429) Y(409.594333)
|
||||
X(756.455702) Y(400.353624)
|
||||
X(804.304024) Y(405.100169)
|
||||
X(855.361775) Y(406.813925)
|
||||
X(902.775961) Y(401.288606)
|
||||
X(953.926757) Y(409.564057)
|
||||
X(950.163285) Y(451.852323)
|
||||
X(903.553688) Y(453.567069)
|
||||
X(850.333046) Y(459.589827)
|
||||
X(802.586841) Y(458.490383)
|
||||
X(750.627130) Y(454.240323)
|
||||
X(706.288984) Y(453.984343)
|
||||
X(658.155238) Y(451.594145)
|
||||
X(608.207671) Y(459.088437)
|
||||
X(559.518745) Y(455.757512)
|
||||
X(508.577226) Y(454.572235)
|
||||
X(454.581388) Y(455.909842)
|
||||
X(407.963915) Y(459.591666)
|
||||
X(352.400203) Y(451.605388)
|
||||
X(307.567786) Y(456.360611)
|
||||
X(256.996221) Y(453.277204)
|
||||
X(209.040444) Y(456.900250)
|
||||
X(157.241676) Y(453.990253)
|
||||
X(108.820414) Y(454.586040)
|
||||
X(55.438060) Y(454.569114)
|
||||
X(1.871309) Y(459.039840)
|
||||
X(4.012595) Y(509.292914)
|
||||
X(50.996149) Y(509.453015)
|
||||
X(108.694885) Y(504.541624)
|
||||
X(153.267009) Y(502.327441)
|
||||
X(206.144647) Y(500.330746)
|
||||
X(250.156061) Y(504.287957)
|
||||
X(300.680741) Y(502.519410)
|
||||
X(352.211609) Y(502.531912)
|
||||
X(401.310552) Y(500.120362)
|
||||
X(451.154843) Y(506.184803)
|
||||
X(509.742562) Y(509.903450)
|
||||
X(554.090541) Y(501.629544)
|
||||
X(606.387618) Y(504.903053)
|
||||
X(659.894098) Y(500.653042)
|
||||
X(707.832344) Y(502.883985)
|
||||
X(752.414186) Y(506.625046)
|
||||
X(802.460632) Y(506.658591)
|
||||
X(855.173085) Y(504.240890)
|
||||
X(905.546878) Y(502.870515)
|
||||
X(957.065747) Y(504.148569)
|
||||
X(959.944008) Y(554.518217)
|
||||
X(906.995751) Y(559.679656)
|
||||
X(859.402097) Y(557.507649)
|
||||
X(806.339977) Y(558.672894)
|
||||
X(755.023895) Y(559.425836)
|
||||
X(708.391891) Y(552.377418)
|
||||
X(654.492916) Y(553.044684)
|
||||
X(602.378072) Y(551.718531)
|
||||
X(553.742962) Y(557.487883)
|
||||
X(502.724369) Y(553.790569)
|
||||
X(457.307091) Y(558.817202)
|
||||
X(406.897683) Y(550.583564)
|
||||
X(359.509526) Y(552.334203)
|
||||
X(302.494200) Y(551.059062)
|
||||
X(252.965563) Y(559.920112)
|
||||
X(209.689717) Y(559.049483)
|
||||
X(158.149665) Y(559.854914)
|
||||
X(102.326270) Y(553.485194)
|
||||
X(59.249669) Y(550.460073)
|
||||
X(3.605456) Y(558.286569)
|
||||
X(0.708698) Y(602.927940)
|
||||
X(51.523547) Y(604.174864)
|
||||
X(101.312893) Y(606.041178)
|
||||
X(153.828081) Y(608.953859)
|
||||
X(209.677947) Y(605.468849)
|
||||
X(252.748236) Y(605.922304)
|
||||
X(308.967612) Y(604.067333)
|
||||
X(355.520783) Y(602.716528)
|
||||
X(404.554441) Y(604.017135)
|
||||
X(452.484135) Y(605.058664)
|
||||
X(503.103808) Y(603.730349)
|
||||
X(555.249704) Y(607.505950)
|
||||
X(603.335075) Y(609.241588)
|
||||
X(658.623185) Y(600.486903)
|
||||
X(702.536425) Y(604.461355)
|
||||
X(751.046279) Y(603.484760)
|
||||
X(807.400975) Y(606.805145)
|
||||
X(856.223844) Y(607.105284)
|
||||
X(902.049237) Y(603.416981)
|
||||
X(956.762425) Y(608.792348)
|
||||
X(956.232947) Y(658.869608)
|
||||
X(902.277595) Y(654.103016)
|
||||
X(856.939564) Y(650.908857)
|
||||
X(804.420356) Y(655.199524)
|
||||
X(757.908402) Y(650.972429)
|
||||
X(705.098072) Y(653.339649)
|
||||
X(656.964824) Y(658.136786)
|
||||
X(609.627703) Y(650.168717)
|
||||
X(556.003922) Y(655.887396)
|
||||
X(500.027032) Y(656.471967)
|
||||
X(456.719571) Y(659.488610)
|
||||
X(405.771402) Y(656.952700)
|
||||
X(352.097499) Y(651.157032)
|
||||
X(306.222311) Y(652.790679)
|
||||
X(250.243132) Y(653.426110)
|
||||
X(200.894945) Y(654.059423)
|
||||
X(155.305372) Y(659.221115)
|
||||
X(100.078841) Y(653.726791)
|
||||
X(50.302353) Y(657.103368)
|
||||
X(5.436781) Y(652.826997)
|
||||
X(6.188262) Y(701.334615)
|
||||
X(59.805801) Y(708.717857)
|
||||
X(105.027208) Y(709.223480)
|
||||
X(155.413808) Y(709.233061)
|
||||
X(208.298974) Y(709.682864)
|
||||
X(259.197828) Y(700.360338)
|
||||
X(301.747720) Y(703.891347)
|
||||
X(359.521427) Y(703.000289)
|
||||
X(401.604676) Y(708.863047)
|
||||
X(454.463944) Y(709.078756)
|
||||
X(501.602305) Y(706.611175)
|
||||
X(554.402638) Y(700.764868)
|
||||
X(606.964631) Y(702.473988)
|
||||
X(650.396155) Y(700.599443)
|
||||
X(700.610785) Y(709.077330)
|
||||
X(757.398839) Y(708.980624)
|
||||
X(806.725823) Y(705.289399)
|
||||
X(853.044464) Y(709.979623)
|
||||
X(903.621891) Y(704.706489)
|
||||
X(953.782452) Y(709.795269)
|
||||
X(955.896947) Y(757.453981)
|
||||
X(901.173205) Y(751.070041)
|
||||
X(857.730836) Y(759.587409)
|
||||
X(804.322815) Y(755.219963)
|
||||
X(750.626360) Y(752.419017)
|
||||
X(703.354982) Y(751.476856)
|
||||
X(657.645620) Y(756.982485)
|
||||
X(609.762257) Y(758.897937)
|
||||
X(556.375827) Y(758.130539)
|
||||
X(503.518930) Y(757.214067)
|
||||
X(453.972567) Y(759.992780)
|
||||
X(405.910269) Y(756.591765)
|
||||
X(350.968040) Y(753.433917)
|
||||
X(309.704937) Y(751.334394)
|
||||
X(254.565199) Y(753.374774)
|
||||
X(205.145127) Y(753.679276)
|
||||
X(152.840000) Y(752.384133)
|
||||
X(106.072494) Y(754.776465)
|
||||
X(56.803487) Y(750.632076)
|
||||
X(1.746584) Y(753.279880)
|
||||
X(8.481504) Y(809.358321)
|
||||
X(59.834262) Y(803.998017)
|
||||
X(103.803352) Y(801.478087)
|
||||
X(156.849344) Y(806.567620)
|
||||
X(208.620626) Y(800.972580)
|
||||
X(254.977769) Y(805.810819)
|
||||
X(302.415570) Y(801.690254)
|
||||
X(358.595808) Y(800.585349)
|
||||
X(404.706209) Y(801.158340)
|
||||
X(454.570588) Y(809.799623)
|
||||
X(504.237064) Y(808.571249)
|
||||
X(551.173156) Y(802.712521)
|
||||
X(604.037927) Y(803.998121)
|
||||
X(656.713835) Y(803.447181)
|
||||
X(707.137669) Y(806.391869)
|
||||
X(753.991611) Y(804.317601)
|
||||
X(806.145277) Y(800.700422)
|
||||
X(858.224067) Y(806.534212)
|
||||
X(907.263425) Y(805.369230)
|
||||
X(951.104771) Y(804.050356)
|
||||
X(953.494403) Y(857.814796)
|
||||
X(904.329842) Y(855.282341)
|
||||
X(851.533689) Y(851.995961)
|
||||
X(807.734555) Y(854.564096)
|
||||
X(751.621203) Y(855.596824)
|
||||
X(700.656049) Y(858.562762)
|
||||
X(652.650397) Y(850.661495)
|
||||
X(602.213964) Y(851.000141)
|
||||
X(550.805320) Y(850.853109)
|
||||
X(503.732160) Y(852.228638)
|
||||
X(455.181498) Y(858.427769)
|
||||
X(401.905669) Y(850.191229)
|
||||
X(355.241839) Y(853.650999)
|
||||
X(305.349169) Y(854.042436)
|
||||
X(258.671672) Y(850.291902)
|
||||
X(209.591423) Y(851.032982)
|
||||
X(157.032175) Y(856.347863)
|
||||
X(101.097845) Y(856.063081)
|
||||
X(50.299503) Y(857.372542)
|
||||
X(4.053736) Y(853.210430)
|
||||
X(7.510216) Y(909.272118)
|
||||
X(50.289525) Y(908.956913)
|
||||
X(103.925688) Y(908.783725)
|
||||
X(156.907848) Y(909.873488)
|
||||
X(207.592825) Y(903.645446)
|
||||
X(255.010632) Y(903.763892)
|
||||
X(303.649118) Y(902.609045)
|
||||
X(354.959703) Y(906.817399)
|
||||
X(402.773403) Y(905.243798)
|
||||
X(451.173803) Y(901.598453)
|
||||
X(500.468064) Y(909.707314)
|
||||
X(550.038604) Y(901.785800)
|
||||
X(606.128668) Y(900.813696)
|
||||
X(658.818965) Y(907.196202)
|
||||
X(709.663900) Y(905.076355)
|
||||
X(753.004037) Y(905.495006)
|
||||
X(809.308187) Y(905.207614)
|
||||
X(852.672070) Y(908.773988)
|
||||
X(903.719187) Y(900.013833)
|
||||
X(952.476850) Y(903.182335)
|
||||
X(952.503982) Y(954.833935)
|
||||
X(903.917969) Y(952.421786)
|
||||
X(859.758839) Y(959.325612)
|
||||
X(805.964331) Y(951.175256)
|
||||
X(755.682176) Y(952.465569)
|
||||
X(704.246630) Y(951.076177)
|
||||
X(653.041987) Y(950.753591)
|
||||
X(601.024138) Y(951.563833)
|
||||
X(558.428549) Y(958.180333)
|
||||
X(501.390727) Y(954.269044)
|
||||
X(457.781716) Y(958.442350)
|
||||
X(404.530942) Y(954.939578)
|
||||
X(359.227566) Y(952.940767)
|
||||
X(302.164573) Y(951.660478)
|
||||
X(256.756891) Y(952.448895)
|
||||
X(209.661474) Y(957.918796)
|
||||
X(159.918903) Y(953.767413)
|
||||
X(108.806781) Y(959.450268)
|
||||
X(54.445873) Y(953.361023)
|
||||
X(8.587775) Y(954.585032)
|
||||
dwell 100
|
||||
Gather.Enable=0
|
||||
close
|
||||
&1
|
||||
b2r
|
||||
@@ -8,10 +8,9 @@
|
||||
'''
|
||||
utilities classes
|
||||
'''
|
||||
import logging, h5py, re, zlib, zmq, json
|
||||
import json
|
||||
import numpy as np
|
||||
from libDetXR import *
|
||||
import time
|
||||
import time,os
|
||||
|
||||
|
||||
class dotdict(dict):
|
||||
@@ -90,4 +89,3 @@ class GpasciiCommunicator():
|
||||
p.write('gpascii -2\n') # execute gpascii command
|
||||
print p.read_until(self.gpascii_inp)
|
||||
return p
|
||||
|
||||
|
||||
113
python/wxutils.py
Executable file
113
python/wxutils.py
Executable file
@@ -0,0 +1,113 @@
|
||||
if __name__ == '__main__':
|
||||
#Used to guarantee to use at least Wx2.8
|
||||
import wxversion
|
||||
wxversion.ensureMinimal('2.8')
|
||||
import wx
|
||||
import matplotlib as mpl
|
||||
if __name__ == '__main__':
|
||||
mpl.use('WXAgg') #or mpl.use('WX')
|
||||
|
||||
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar
|
||||
import time,os
|
||||
|
||||
class Path():
|
||||
@staticmethod
|
||||
def GetImage():
|
||||
path=__file__
|
||||
try:symPath=os.readlink(path) #follow symbolic link
|
||||
except (AttributeError,OSError) as e:pass
|
||||
else:
|
||||
path=symPath
|
||||
path=os.path.abspath(path)
|
||||
path=os.path.dirname(path)
|
||||
return os.path.join(path,'images')
|
||||
|
||||
class StopWatch():
|
||||
@classmethod
|
||||
def Start(cls):
|
||||
cls.ts=time.time()
|
||||
@classmethod
|
||||
def Log(cls,str=None,restart=True):
|
||||
ts=time.time()
|
||||
print '%.6f'%(ts-cls.ts),str
|
||||
if restart:
|
||||
cls.ts=ts
|
||||
|
||||
class SliderGroup():
|
||||
def __init__(self, parent, label, range=(0,100),val=0):
|
||||
self.sliderLabel = wx.StaticText(parent, label=label)
|
||||
self.sliderText = wx.TextCtrl(parent, -1, style=wx.TE_PROCESS_ENTER)
|
||||
self.slider = wx.Slider(parent, -1)
|
||||
self.slider.SetRange(range[0],range[1])
|
||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
sizer.Add(self.sliderLabel, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=2)
|
||||
sizer.Add(self.sliderText, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=2)
|
||||
sizer.Add(self.slider, 1, wx.EXPAND)
|
||||
self.sizer = sizer
|
||||
self.slider.Bind(wx.EVT_SLIDER, self.sliderHandler)
|
||||
self.sliderText.Bind(wx.EVT_TEXT_ENTER, self.sliderTextHandler)
|
||||
self.SetValue(val)
|
||||
|
||||
def SetValue(self, value):
|
||||
self.value = value
|
||||
self.slider.SetValue(value)
|
||||
self.sliderText.SetValue(str(value))
|
||||
|
||||
def SetCallback(self,funcCB,usrData):
|
||||
self.cbFuncData=(funcCB,usrData)
|
||||
|
||||
def Callback(self,value,msg):
|
||||
try:
|
||||
(funcCB,usrData)=self.cbFuncData
|
||||
except BaseException as e:
|
||||
pass
|
||||
else:
|
||||
funcCB(usrData,value,msg)
|
||||
|
||||
def sliderHandler(self, evt):
|
||||
value = evt.GetInt()
|
||||
self.sliderText.SetValue(str(value))
|
||||
self.value=value
|
||||
self.Callback(value,0)
|
||||
|
||||
def sliderTextHandler(self, evt):
|
||||
value = int(self.sliderText.GetValue())
|
||||
self.slider.SetValue(value)
|
||||
value = self.slider.Value
|
||||
self.sliderText.SetValue(str(value))
|
||||
self.value=value
|
||||
self.Callback(value,1)
|
||||
|
||||
def GetSlice(idxXY,shp,wxAxCtrlLst):
|
||||
'''returns a slice list to select data'''
|
||||
sl=[None]*len(shp)
|
||||
for ax in wxAxCtrlLst:
|
||||
sl[ax.idx]=ax.value
|
||||
for i in idxXY:
|
||||
sl[i]=slice(None)
|
||||
sl=tuple(sl)
|
||||
return sl
|
||||
|
||||
|
||||
def AddToolbar(parent,sizer):
|
||||
toolbar = NavigationToolbar(parent)
|
||||
toolbar.Realize()
|
||||
if wx.Platform == '__WXMAC__':
|
||||
# Mac platform (OSX 10.3, MacPython) does not seem to cope with
|
||||
# having a toolbar in a sizer. This work-around gets the buttons
|
||||
# back, but at the expense of having the toolbar at the top
|
||||
parent.SetToolBar(toolbar)
|
||||
else:
|
||||
# On Windows platform, default window size is incorrect, so set
|
||||
# toolbar width to figure width.
|
||||
tw, th = toolbar.GetSizeTuple()
|
||||
fw, fh = parent.GetSizeTuple()
|
||||
# By adding toolbar in sizer, we are able to put it at the bottom
|
||||
# of the frame - so appearance is closer to GTK version.
|
||||
# As noted above, doesn't work for Mac.
|
||||
toolbar.SetSize(wx.Size(fw, th))
|
||||
sizer.Add(toolbar, 0, wx.LEFT | wx.EXPAND)
|
||||
# update the axes menu on the toolbar
|
||||
toolbar.update()
|
||||
return toolbar
|
||||
|
||||
Reference in New Issue
Block a user