552 lines
19 KiB
Python
552 lines
19 KiB
Python
#!/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 os
|
|
import numpy as np
|
|
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
|
|
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar
|
|
import pylab as plt #used for the colormaps
|
|
|
|
|
|
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,0)
|
|
|
|
|
|
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
|
|
|
|
|
|
#class ShiftedLogNorm(mpl.colors.Normalize):
|
|
class ShiftedLogNorm(mpl.colors.LogNorm):
|
|
#copied and modified from LogNorm
|
|
def __call__(self, value, clip=None):
|
|
#print value.shape,self.vmin,self.vmax,self.clip,clip
|
|
if clip is None:
|
|
clip = self.clip
|
|
ofs0=1-self.vmin
|
|
ofs1=1./(np.log(self.vmax+1-self.vmin))
|
|
result=np.log(value+ofs0)*ofs1
|
|
result = np.ma.masked_less_equal(result, 0, copy=False)
|
|
return result
|
|
def inverse(self, value):
|
|
if not self.scaled():
|
|
raise ValueError("Not invertible until scaled")
|
|
vmin, vmax = self.vmin, self.vmax
|
|
ofs0=1-vmin
|
|
if mpl.cbook.iterable(value):
|
|
val = np.ma.asarray(value)
|
|
return vmin * np.ma.power((vmax/vmin), val)-ofs0
|
|
else:
|
|
return vmin * pow((vmax/vmin), value)-ofs0
|
|
def autoscale_None(self, A):
|
|
if self.vmin is None:
|
|
self.vmin = np.ma.min(A)
|
|
if self.vmax is None:
|
|
self.vmax = np.ma.max(A)
|
|
pass
|
|
def autoscale(self, A):
|
|
pass
|
|
|
|
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.1,0.75,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,data):
|
|
if data.dtype==np.complex128:
|
|
self.dataRaw=data
|
|
#data=np.angle(data)
|
|
data=np.absolute(data)
|
|
|
|
fig=self.fig
|
|
ax=self.ax
|
|
|
|
msk=~np.isnan(data);msk=data[msk]
|
|
avg=np.average(msk); std=np.std(msk)
|
|
vmin=np.min(msk);vmax=np.max(msk)
|
|
vmin=max(vmin,avg-3*std);vmax=min(vmax,avg+3*std)
|
|
if vmin==0:vmin=1
|
|
if vmax<=vmin:
|
|
vmax=vmin+1
|
|
|
|
#norm=ShiftedLogNorm()
|
|
norm=mpl.colors.Normalize()
|
|
#img = ax.imshow(data,interpolation='nearest',cmap=mpl.cm.jet, norm=ShiftedLogNorm(vmin=vmin, vmax=vmax))
|
|
|
|
img = ax.imshow(data,interpolation='nearest',cmap=mpl.cm.jet, vmin=vmin, vmax=vmax)
|
|
colBar=fig.colorbar(img,orientation='vertical',norm=norm)
|
|
#colBar.norm=ShiftedLogNorm(vmin=vmin, vmax=vmax)
|
|
colBar.norm=mpl.colors.Normalize(vmin=vmin, vmax=vmax)
|
|
img.set_norm(colBar.norm)
|
|
img.cmap._init();bg=img.cmap._lut[0].copy();bg[:-1]/=4
|
|
ax.set_axis_bgcolor(bg)
|
|
|
|
|
|
self.colBar=colBar
|
|
self.colCycle = sorted([i for i in dir(plt.cm) if hasattr(getattr(plt.cm,i),'N')])
|
|
self.colIndex = self.colCycle.index(colBar.get_cmap().name)
|
|
self.img=img
|
|
|
|
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))
|
|
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)
|
|
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)
|
|
try: del self.colBarPressed
|
|
except AttributeError: pass
|
|
|
|
def OnBtnScroll(self, event):
|
|
#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):
|
|
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):
|
|
for k in dir(event):
|
|
if k[0]!='_':
|
|
print k,getattr(event,k)
|
|
|
|
|
|
class DlgColBarSetup(wx.Dialog):
|
|
def __init__(self,parent):
|
|
wx.Dialog.__init__(self,parent,-1,'Colormap Setup')
|
|
colBar=parent.canvas.colBar
|
|
cmap=colBar.cmap
|
|
nrm=colBar.norm
|
|
|
|
txtVMin=wx.StaticText(self,-1,'vmin')
|
|
txtVMax=wx.StaticText(self,-1,'vmax')
|
|
txtColMap=wx.StaticText(self,-1,'colormap')
|
|
self.edVMin=edVMin=wx.TextCtrl(self,-1,'%g'%nrm.vmin,style=wx.TE_PROCESS_ENTER)
|
|
self.edVMax=edVMax=wx.TextCtrl(self,-1,'%g'%nrm.vmax,style=wx.TE_PROCESS_ENTER)
|
|
|
|
txtTxrFunc=wx.StaticText(self,-1,'function')
|
|
self.cbtxrFunc=cbtxrFunc=wx.ComboBox(self, -1, choices=('linear','logarithmic'), style=wx.CB_READONLY)
|
|
cbtxrFunc.SetSelection(0 if nrm.__class__==mpl.colors.Normalize else 1)
|
|
|
|
#colMapLst=('Accent', 'Blues', 'BrBG', 'BuGn', 'BuPu', 'Dark2', 'GnBu', 'Greens', 'Greys', 'OrRd', 'Oranges', 'PRGn', 'Paired',
|
|
#'Pastel1', 'Pastel2', 'PiYG', 'PuBu', 'PuBuGn', 'PuOr', 'PuRd', 'Purples', 'RdBu', 'RdGy', 'RdPu', 'RdYlBu', 'RdYlGn', 'Reds',
|
|
#'Set1', 'Set2', 'Set3', 'Spectral', 'YlGn', 'YlGnBu', 'YlOrBr', 'YlOrRd', 'afmhot', 'autumn', 'binary', 'bone', 'brg', 'bwr',
|
|
#'cool', 'coolwarm', 'copper', 'cubehelix', 'flag', 'gist_earth', 'gist_gray', 'gist_heat', 'gist_ncar', 'gist_rainbow', 'gist_stern',
|
|
#'gist_yarg', 'gnuplot', 'gnuplot2', 'gray', 'hot', 'hsv', 'jet', 'ocean', 'pink', 'prism', 'rainbow', 'seismic', 'spectral',
|
|
#'spring', 'summer', 'terrain', 'winter')
|
|
|
|
colMapLst=('hot','spectral','jet','gray','RdYlBu','hsv','gist_stern','gist_ncar','BrBG','RdYlBu','brg','gnuplot2',
|
|
'prism','rainbow',)
|
|
|
|
self.cbColMap=cbColMap=wx.ComboBox(self, -1, choices=colMapLst, style=wx.CB_READONLY)
|
|
cbColMap.Value=cmap.name
|
|
|
|
sizer=wx.BoxSizer(wx.VERTICAL)
|
|
fgs=wx.FlexGridSizer(4,2,5,5)
|
|
fgs.Add(txtVMin,0,wx.ALIGN_RIGHT)
|
|
fgs.Add(edVMin,0,wx.EXPAND)
|
|
fgs.Add(txtVMax,0,wx.ALIGN_RIGHT)
|
|
fgs.Add(edVMax,0,wx.EXPAND)
|
|
fgs.Add(txtTxrFunc,0,wx.ALIGN_RIGHT)
|
|
fgs.Add(cbtxrFunc,0,wx.EXPAND)
|
|
fgs.Add(txtColMap,0,wx.ALIGN_RIGHT)
|
|
fgs.Add(cbColMap,0,wx.EXPAND)
|
|
sizer.Add(fgs,0,wx.EXPAND|wx.ALL,5)
|
|
|
|
edVMin.SetFocus()
|
|
|
|
btns = self.CreateButtonSizer(wx.OK|wx.CANCEL)
|
|
btnApply=wx.Button(self, -1, 'Apply')
|
|
btns.Add(btnApply, 0, wx.ALL, 5)
|
|
sizer.Add(btns,0,wx.EXPAND|wx.ALL,5)
|
|
self.Bind(wx.EVT_BUTTON, self.OnModify, id=wx.ID_OK)
|
|
self.Bind(wx.EVT_BUTTON, self.OnModify, btnApply)
|
|
#self.Bind(wx.EVT_TEXT_ENTER, self.OnModify, edVMin)
|
|
#self.Bind(wx.EVT_TEXT_ENTER, self.OnModify, edVMax)
|
|
self.Bind(wx.EVT_TEXT, self.OnModify, edVMin)
|
|
self.Bind(wx.EVT_TEXT, self.OnModify, edVMax)
|
|
self.Bind(wx.EVT_COMBOBOX, self.OnModify, cbtxrFunc)
|
|
self.Bind(wx.EVT_COMBOBOX, self.OnModify, cbColMap)
|
|
|
|
self.SetSizer(sizer)
|
|
sizer.Fit(self)
|
|
|
|
def OnModify(self, event):
|
|
#print 'OnModify'
|
|
parent=self.GetParent()
|
|
canvas=parent.canvas
|
|
colBar=canvas.colBar
|
|
cmap=colBar.cmap
|
|
nrm=colBar.norm
|
|
img=canvas._goImg
|
|
ax=img.get_axes()
|
|
data=img.get_array()
|
|
|
|
v=self.cbColMap.Value
|
|
if v!=cmap.name:
|
|
cmap=getattr(mpl.cm,v)
|
|
colBar.set_cmap(cmap)
|
|
colBar.draw_all()
|
|
img.set_cmap(cmap)
|
|
ax.set_title(cmap.name)
|
|
colBar.patch.figure.canvas.draw()
|
|
|
|
vmin,vmax=(float(self.edVMin.Value),float(self.edVMax.Value))
|
|
nrm.vmin=vmin; nrm.vmax=vmax
|
|
v=self.cbtxrFunc.GetCurrentSelection()
|
|
func=(mpl.colors.Normalize,ShiftedLogNorm)
|
|
if nrm.__class__!=func[v]:
|
|
if v==0: #linear mapping
|
|
colBar.norm = mpl.colors.Normalize(vmin, vmax)
|
|
elif v==1: #log mapping
|
|
img.cmap._init();bg=img.cmap._lut[0].copy();bg[:-1]/=4
|
|
ax.set_axis_bgcolor(bg)
|
|
vmin=1
|
|
colBar.norm = mpl.colors.LogNorm(vmin,vmax)
|
|
img.set_norm(colBar.norm)
|
|
colBar.patch.figure.canvas.draw()
|
|
parent.Refresh(False)
|
|
if event.GetId()==wx.ID_OK:
|
|
event.Skip()#do not consume (use event to close the window and sent return code)
|
|
|
|
class HdfImageFrame(wx.Frame):
|
|
def __init__(self, parent,lbl,ims):
|
|
wx.Frame.__init__(self, parent, title=lbl, size=wx.Size(850, 650))
|
|
|
|
canvas = MPLCanvasImg(self,self.SetStatusCB)
|
|
|
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
|
sizer.Add(canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
|
|
self.SetSizer(sizer)
|
|
|
|
toolbar=AddToolbar(canvas,sizer)
|
|
|
|
l=len(ims)
|
|
wxAxCtrl=SliderGroup(self, label='Axis:%d'%0,range=(0,l-1))
|
|
sizer.Add(wxAxCtrl.sizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5)
|
|
wxAxCtrl.SetCallback(HdfImageFrame.OnSetView,wxAxCtrl)
|
|
|
|
idx=wxAxCtrl.value
|
|
data=ims[idx]
|
|
canvas.InitChild(data)
|
|
|
|
#self.Fit()
|
|
self.Centre()
|
|
|
|
self.BuildMenu(data.dtype)
|
|
self.canvas=canvas
|
|
self.sizer=sizer
|
|
self.toolbar=toolbar
|
|
self.ims=ims
|
|
self.wxAxCtrl=wxAxCtrl
|
|
|
|
def BuildMenu(self,dtype):
|
|
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, '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
|
|
|
|
if dtype==np.complex128:
|
|
mnItem=mn.Append(wx.ID_ANY, 'Complex: Phase', kind=wx.ITEM_CHECK);self.Bind(wx.EVT_MENU, self.OnSetComplexData, 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 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')
|
|
|
|
@staticmethod
|
|
def OnSetView(usrData,value,msg):
|
|
'called when a slice is selected with the slider controls'
|
|
imgFrm=usrData.slider.Parent
|
|
#imgFrm.img.set_array(imgFrm.data[usrData.value,...])
|
|
idx=imgFrm.wxAxCtrl.value
|
|
data=imgFrm.ims[idx]
|
|
try:
|
|
tomoNorm=imgFrm.tomoNorm
|
|
except AttributeError:
|
|
imgFrm.canvas._goImg.set_array(data)
|
|
else:
|
|
data=data*tomoNorm
|
|
imgFrm.canvas._goImg.set_array(data)
|
|
|
|
imgFrm.canvas.draw()
|
|
pass
|
|
|
|
|
|
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
|
|
|
|
class ImgStackApp(wx.App):
|
|
def OnInit(self):
|
|
#parser=GetParser(False) # debug with exampleCmd
|
|
return True
|
|
|
|
def OnExit(self):
|
|
pass
|
|
|
|
def Run(ims):
|
|
app=ImgStackApp()
|
|
frame=HdfImageFrame(None, 'Title', ims)
|
|
frame.Show()
|
|
app.SetTopWindow(frame)
|
|
app.MainLoop()
|