diff --git a/python/MAError.py b/python/MAError.py index d1b0417..2e6ca76 100644 --- a/python/MAError.py +++ b/python/MAError.py @@ -45,136 +45,75 @@ class MPLCanvasErr(FigureCanvas): self.fig=fig self.ax=ax - def InitChild(self,pts,rec): + def InitChild(self,err): fig=self.fig ax=self.ax - - err=np.sqrt((rec[:,1]-rec[:,4])**2+(rec[:,1]-rec[:,4])**2) - hl = ax.plot(err, 'r-') + errx,erry,err=err + hl = [] + hl = ax.plot(errx, 'g-',label='x-error') + hl = ax.plot(erry, 'y-',label='y-error') + hl = ax.plot(err, 'r-',label='error') ax.xaxis.set_label_text('time (10x servo cycle)') ax.yaxis.set_label_text('pos-error um') + legend = ax.legend(loc='upper right', shadow=True) 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) + def OnMotion(self, event): + # print event,event.x,event.y,event.inaxes,event.xdata,event.ydata - 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() + if event.inaxes == self.ax: + + x = int(round(event.xdata)) + #y = int(round(event.ydata)) + y = 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]) + s.append('%s=%.2f' % (lbl, arr[1][idx])) + else: + s += str(h) + str(c[1]) + s=', '.join(s) + + self.SetStatusCB(self.Parent, 0, (x, y, s)) 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""" + print dir(event.guiEvent) #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 __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)) + wx.Frame.__init__(self, parent, title='error-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) @@ -187,7 +126,16 @@ class MAErrorFrame(wx.Frame): self.SetSizer(sizer) toolbar=ut.AddToolbar(canvas,sizer) - canvas.InitChild(doc.fh['pts'],doc.fh['rec']) + + try: + err=doc.err + except AttributeError: + rec=doc.fh['rec'] + errx = abs(rec[:, 1] - rec[:, 4]) + erry = abs(rec[:, 2] - rec[:, 5]) + errxy = np.sqrt(errx ** 2 + erry ** 2) + doc.err = err = (errx, erry, errxy) + canvas.InitChild(err) self.Centre() @@ -201,15 +149,14 @@ class MAErrorFrame(wx.Frame): #-------- 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 - + #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() @@ -222,147 +169,33 @@ class MAErrorFrame(wx.Frame): 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) + # for message description s.a. class MADoc + if msg == 0: + canvas = self.canvas + ax = canvas.ax + len = usrData + err = self.doc.err + hl = canvas.hl + #hl[0].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(len-x, len + x,emit=True) + #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=%g"%v,0) - elif mode==1: - obj.SetStatusText( "Colormap Value %d (drag to scale)"%v,0) + #obj.SetStatusText( "x= %d y=%d val=%s"%v,0) + obj.SetStatusText("x(%d,%.2f): %s" % 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 @@ -378,22 +211,6 @@ use cursor up and down to use a different colormap''' 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):