first full functional MAxyPlot

This commit is contained in:
2016-12-23 15:49:40 +01:00
parent 6e31c7e705
commit 36a11a5657
7 changed files with 1417 additions and 27 deletions

442
python/MAError.py Normal file
View 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
View 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()

View File

@@ -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

Binary file not shown.

418
python/data/shapepath.prg Normal file
View 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

View File

@@ -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
View 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