diff --git a/python/helicalscan.py b/python/helicalscan.py index 26e8209..afc31e4 100755 --- a/python/helicalscan.py +++ b/python/helicalscan.py @@ -169,25 +169,30 @@ class HelicalScanGui(): self.manip=manip self.ax=ax=plt3d.Axes3D(fig,[0.02, 0.15, 0.96, 0.83]) ax.set_xlabel('Z');ax.set_ylabel('X');ax.set_zlabel('Y') - ax.view_init(elev=14., azim=-170) + ax.view_init(elev=10, azim=-170) # param[i]=(z_i, y_i, x_i, r_i,phi_i) - ctr=param[:,0:3].mean(0)[::-1] l=max(2*param[:,3].max(),param[:,1].ptp()) #max of diameter and y peaktopeak self.scale=l #scale is the length of a cube were the pltCrist object fits into - self.axSetCenter((0,0,0),l) axCx=plt.axes([0.1, 0.01, 0.8, 0.02]) axCz=plt.axes([0.1, 0.04, 0.8, 0.02]) axW =plt.axes([0.1, 0.07, 0.8, 0.02]) axFy=plt.axes([0.1, 0.10, 0.8, 0.02]) - #lz=ax.get_xlim() - #lx=ax.get_ylim() #x-450 -> center==0 - #ly=ax.get_zlim() - ly = param[::-1,1] - x0=param[:, 2].mean() - lx=(-l/2+x0,l/2+x0) - z0=param[:, 0].mean() - lz=(-l/2+z0,l/2+z0) + if manip: + y0=param[:, 1].mean() + ly=sorted(param[:,1]) + x0=param[:, 2].mean() + lx=(-l/2+x0,l/2+x0) + z0=param[:, 0].mean() + lz=(-l/2+z0,l/2+z0) + self.axSetCenter((x0,y0,z0),l) + else: + self.axSetCenter((0, 0, 0), l) + ly=sorted(param[:,1]) + x0=param[:, 2].mean() + lx=(-l/2+x0,l/2+x0) + z0=param[:, 0].mean() + lz=(-l/2+z0,l/2+z0) self.sldCx=sCx=Slider(axCx, 'cx', lx[0], lx[1], valinit=(lx[0]+lx[1])/2.) self.sldCz=sCz=Slider(axCz, 'cz', lz[0], lz[1], valinit=(lz[0]+lz[1])/2.) @@ -198,21 +203,12 @@ class HelicalScanGui(): sW.on_changed(self.update_cx_cz_w_fy) sFy.on_changed(self.update_cx_cz_w_fy) + if manip: + #self.pltCrist(-x0, -z0, 0, -param[:,1].mean()) + self.pltCrist(0,0,0,0) + else: + self.pltOrig(Trf.trans(0, 0, 0)) self.update_cx_cz_w_fy() - #self.pltCrist(0,0,0,0) - - # param[i]=(z_i, y_i, x_i, r_i,phi_i) - p=np.ndarray((param.shape[0], 3)) - for i in range(2): - (z_i, y_i, x_i, r_i, phi_i)=param[i] - p[i,0]=x_i+r_i*np.sin(phi_i) # x= x_i+r_i*cos(phi_i+w)+cx - p[i,1]=y_i # y= y_i - p[i,2]=z_i+r_i*np.cos(phi_i) # z= z_i+r_i*sin(phi_i*w) - print(p) - ofs=(p[1]+p[0])/2. # = center of the cristal - - ofs=(0,0,0) - m=Trf.trans(*ofs); self.pltOrig(m) plt.show() def update_cx_cz_w_fy(self,val=None): @@ -226,16 +222,18 @@ class HelicalScanGui(): p = np.ndarray((param.shape[0], 3)) for i in range(2): (z_i, y_i, x_i, r_i, phi_i) = param[i] - p[i, 0] = x_i + r_i * np.cos(phi_i) # x= x_i+r_i*cos(phi_i+w)+cx + p[i, 0] = x_i + r_i * np.sin(phi_i) # x= x_i+r_i*cos(phi_i+w)+cx p[i, 1] = y_i # y= y_i - p[i, 2] = z_i + r_i * np.sin(phi_i) # z= z_i+r_i*sin(phi_i*w) - print(p) + p[i, 2] = z_i + r_i * np.cos(phi_i) # z= z_i+r_i*sin(phi_i*w) m = Trf.trans(cx,fy,cz) m= m.dot(Trf.rotY(w*d2r)) + #TODO: THE MODES WITH manip=True are totally wrong... + #m=Trf.rotY(w*d2r) + #m=m.dot(Trf.trans(cx,fy,cz)) self.pltOrig(m) else: w=w*d2r - self.pltCrist(-cx, -cz, w, -fy) + self.pltCrist(-cx, -cz, -w, -fy) #self.pltCrist(cx,cz,w*d2r,fy) self.fig.canvas.draw_idle() @@ -244,13 +242,12 @@ class HelicalScanGui(): self.fig=fig=plt.figure() self.ax=ax=plt3d.Axes3D(fig,[0.02, 0.15, 0.96, 0.83]) ax.set_xlabel('Z');ax.set_ylabel('X');ax.set_zlabel('Y') - ax.view_init(elev=14., azim=10) + ax.view_init(elev=10, azim=-170) # param[i]=(z_i, y_i, x_i, r_i,phi_i) l=max(2*param[:,3].max(),param[:,1].ptp()) #max of diameter and y peaktopeak self.scale=l #scale is the length of a cube were the pltCrist object fits into - ctr=(0,0,0) - self.axSetCenter(ctr,param[0,3]+param[1,3]) + self.axSetCenter((0,0,0),l) axDx=plt.axes([0.1, 0.01, 0.8, 0.02]) axDz=plt.axes([0.1, 0.04, 0.8, 0.02]) @@ -259,7 +256,7 @@ class HelicalScanGui(): lz=ax.get_xlim() lx=ax.get_ylim() - ly = param[::-1,1] + ly=sorted(param[:,1]) self.sldDx=sDx=Slider(axDx, 'dx', lx[0], lx[1], valinit=(lx[0]+lx[1])/2.) self.sldDz=sDz=Slider(axDz, 'dz', lz[0], lz[1], valinit=(lz[0]+lz[1])/2.) self.sldW =sW =Slider(axW, 'ang', -180., 180.0, valinit=0) @@ -269,23 +266,25 @@ class HelicalScanGui(): sW.on_changed(self.update_dx_dz_w_y) sY.on_changed(self.update_dx_dz_w_y) - - # param[i]=(z_i, y_i, x_i, r_i,phi_i) - p=np.ndarray((param.shape[0], 3)) - for i in range(2): - (z_i, y_i, x_i, r_i, phi_i)=param[i] - p[i,0]=x_i+r_i*np.sin(phi_i) # x= x_i+r_i*cos(phi_i+w)+cx - p[i,1]=y_i # y= y_i - p[i,2]=z_i+r_i*np.cos(phi_i) # z= z_i+r_i*sin(phi_i*w) - ofs=(p[1]+p[0])/2. # = center of the cristal - print('p, ofs',p,ofs) - - m=Trf.trans(0,0,0); self.pltOrig(m) - self.pltCrist(cx=-ofs[0],cz=-ofs[2],w=0,fy=-ofs[1]) + self.pltOrig(Trf.trans(0, 0, 0)) + self.update_dx_dz_w_y() plt.show() + # # param[i]=(z_i, y_i, x_i, r_i,phi_i) + # p=np.ndarray((param.shape[0], 3)) + # for i in range(2): + # (z_i, y_i, x_i, r_i, phi_i)=param[i] + # p[i,0]=x_i+r_i*np.sin(phi_i) # x= x_i+r_i*cos(phi_i+w)+cx + # p[i,1]=y_i # y= y_i + # p[i,2]=z_i+r_i*np.cos(phi_i) # z= z_i+r_i*sin(phi_i*w) + # ofs=(p[1]+p[0])/2. # = center of the cristal + # print('p, ofs',p,ofs) + # + # m=Trf.trans(0,0,0); self.pltOrig(m) + # self.pltCrist(cx=-ofs[0],cz=-ofs[2],w=0,fy=-ofs[1]) + #plt.show() + def update_dx_dz_w_y(self,val=None): - print(val) helScn=self.helScn dx = self.sldDx.val dz = self.sldDz.val @@ -293,7 +292,6 @@ class HelicalScanGui(): y = self.sldY.val w=w*d2r (cx,cz,w,fy)=helScn.inv_transform(dx,dz,w,y) - #print (cx,cz,w,fy) self.pltCrist(-cx,-cz,w,-fy) self.fig.canvas.draw_idle() @@ -303,11 +301,12 @@ class HelicalScanGui(): fig = plt.figure() self.ax=ax=plt3d.Axes3D(fig,[0.02, 0.15, 0.96, 0.83]) ax.set_xlabel('Z');ax.set_ylabel('X');ax.set_zlabel('Y') - ax.view_init(elev=14., azim=10) + ax.view_init(elev=10, azim=-170) # param[i]=(z_i, y_i, x_i, r_i,phi_i) - ctr=(0,0,0) - self.axSetCenter(ctr,param[0,3]+param[1,3]) + l=max(2*param[:,3].max(),param[:,1].ptp()) #max of diameter and y peaktopeak + self.scale=l #scale is the length of a cube were the pltCrist object fits into + self.axSetCenter((0,0,0),l) axFrm=plt.axes([0.1, 0.01, 0.8, 0.02]) @@ -315,25 +314,24 @@ class HelicalScanGui(): ly = param[:,1] self.sldFrm=sFrm=Slider(axFrm, 'frm', 0, rec.shape[0]-1, valinit=0) sFrm.on_changed(self.update_anim) - m=Trf.trans(0,0,0); self.pltOrig(m) - self.hCrist=None self.fig=fig - animCnt=100 - self.step=rec.shape[0]/animCnt - #a = anim.FuncAnimation(fig, self.anim_gather_data, animCnt, fargs=(), interval=20, repeat=False, blit=False) + self.pltOrig(Trf.trans(0,0,0)) self.update_anim(0) + + #following lines make an animation + #animCnt=100 + #self.step=rec.shape[0]/animCnt + #a = anim.FuncAnimation(fig, self.anim_gather_data, animCnt, fargs=(), interval=20, repeat=False, blit=False) plt.show() pass def update_anim(self,frm): - print(frm) rec=self.helScn.rec (cx, cz, w, fy)=rec[int(frm),:] #data/=. #scale from um to mm w*=d2r/1000 # scale from deg to rad - #print (cx,cz,w,fy) - self.hCrist,pt=self.pltCrist(-cx,-cz,w,-fy,self.hCrist) + self.pltCrist(-cx,-cz,w,-fy) self.fig.canvas.draw_idle() def anim_gather_data(self,idx): @@ -354,7 +352,7 @@ class HelicalScanGui(): r=m[idx,0]*self.scale/3.#1st g=m[idx,1]*self.scale/3.#2nd b=m[idx,2]*self.scale/3.#3rd - o=m[idx,3]*self.scale/3.#origin + o=m[idx,3] #origin !do not scale orogin lines = np.ndarray((3, 2, 3)) # numlines, points, xyz lines[:, 0, :] = o lines[0, 1, :] = o + r @@ -387,7 +385,7 @@ class HelicalScanGui(): x+=cx;y+=fy;z+=cz;phi+=w pt[i] = (z, x, y) pt[i + 2] = (z + r * np.cos(phi), x + r * np.sin(phi), y) - obj = mpl.patches.Circle((z, x), r, facecolor=mpl.colors.colorConverter.to_rgba('y', alpha=0.2)) + obj = mpl.patches.Circle((z, x), r, facecolor=mpl.colors.colorConverter.to_rgba('y' if i==0 else 'r', alpha=0.2)) h1=ax.add_patch(obj) h2=plt3d.art3d.pathpatch_2d_to_3d(obj, z=y, zdir="z") #print h1._segment3d @@ -403,7 +401,7 @@ class HelicalScanGui(): ax.add_artist(hl);h.append(hl) lseg=tuple(lines) - col=(mpl.colors.colorConverter.to_rgba('r'),)*len(lseg) + col=(mpl.colors.colorConverter.to_rgba('k'),)*len(lseg) hlc=plt3d.art3d.Line3DCollection(lseg,colors=col)#, *args[argi:], **kwargs) ax.add_collection(hlc);h.append(hlc) self.hCrist=h @@ -414,7 +412,7 @@ class HelicalScanGui(): pt[i] = (z, x, y) pt[i + 2] = (z + r * np.cos(phi), x + r * np.sin(phi), y) h[i].remove() - obj = mpl.patches.Circle((z, x), r, facecolor=mpl.colors.colorConverter.to_rgba('y', alpha=0.2)) + obj = mpl.patches.Circle((z, x), r, facecolor=mpl.colors.colorConverter.to_rgba('y' if i==0 else 'r', alpha=0.2)) ax.add_patch(obj) plt3d.art3d.pathpatch_2d_to_3d(obj, z=y, zdir="z") h[i]=obj @@ -436,7 +434,9 @@ class HelicalScanGui(): return (h,pt) - def get_meas_lines(self,pt,cx,cz,fy,w): + def get_meas_lines(self,pt,cx,cz,fy,w,arwLen=None): + if arwLen is None: + arwLen=self.scale*.05 # default arrow length=0.01 of crystal size param = self.helScn.param pts = self.helScn.points dx_ = pts[:, 0] # add 0.2 to test @@ -453,8 +453,8 @@ class HelicalScanGui(): lines[:, 0, 0] = pt[2, 0] + (pt[3, 0] - pt[2, 0]) * f +ofx # z data lines[:, 0, 1] = pt[2, 1] + (pt[3, 1] - pt[2, 1]) * f +ofy # x data lines[:, 0, 2] = pts[:, 3] + fy # y data - lines[:, 1, 0] = lines[:, 0, 0] + np.cos(w-w_)*.1 - lines[:, 1, 1] = lines[:, 0, 1] + np.sin(w-w_)*.1 + lines[:, 1, 0] = lines[:, 0, 0] + np.cos(w-w_)*arwLen + lines[:, 1, 1] = lines[:, 0, 1] + np.sin(w-w_)*arwLen lines[:, 1, 2] = lines[:, 0, 2] return lines @@ -549,25 +549,32 @@ class HelicalScanTests(): plt.legend(handels=h) pass - def calcParamSim(helScn): + @staticmethod + def calcParamSim(): #simulated test values n = 3.; per = 1.; w = 2 * np.pi * per / n * np.arange(n) - #p = ((2.3, .71, 4.12, 10.6 * d2r),(6.2, .45, 3.2, 45.28 * d2r)) # (y, bias, ampl, phi) - p = ((2.3, -100., 10, 10. * d2r),(6.2, 100., 10., -10. * d2r)) # (y, bias, ampl, phi) - helScn.param = param = np.ndarray((len(p), 5)) - z = 14.5 # fix z position - for i in range(2): - (y, bias, ampl, phi) = p[i] - x = ampl * np.cos(w + phi) + bias - print('yMeas_%d=' % i + str(y) + ' xMeas_%d=' % i + str(x)) + #(z_i, y_i, x_i, r_i, phi_i)=param[i] + #paramSim = ((14.5, 2.3, .71, 4.12, 10.6 * d2r),(14.5, 6.2, .45, 3.2, 45.28 * d2r)) # (y, bias, ampl, phi) + #paramSim = ((14.5, 2.3, -100., 10, 10. * d2r),(14.5, 6.2, 100., 10., -10. * d2r)) # (y, bias, ampl, phi) + paramSim = ((14.5, 2.3, -100., 10, 0. * d2r),(14.5, 6.2, 100., 10., 90. * d2r)) # (y, bias, ampl, phi) + paramSim=np.array(paramSim) + param = np.ndarray(paramSim.shape) + for i in range(param.shape[0]): + (z,y,bias,ampl,phi) = paramSim[i] + measX = ampl * np.sin(w + phi) + bias + measZ = ampl * np.cos(w + phi) + bias + print('xMeas_%d=' % i + str(measX) + ' zMeas_%d=' % i + str(measZ)) # param[i]=(z_i, y_i, x_i, r_i,phi_i) param[i, 0] = z param[i, 1] = y - param[i, 2:] = HelicalScan.meas_rot_ctr(x) # (bias,ampl,phase) + param[i, 2:] = HelicalScan.meas_rot_ctr(measX) # (bias,ampl,phase) (bias, ampl, phase) = param[i][2:] print(param) + print(paramSim) + assert((paramSim-param).max()<1E-10) + return param class HelicalScan(MotionBase): @@ -597,9 +604,9 @@ class HelicalScan(MotionBase): p=np.ndarray((param.shape[0], 3)) for i in range(2): (z_i, y_i, x_i, r_i, phi_i)=param[i] - p[i,0]=x_i+r_i*np.cos(phi_i+w) # x= x_i+r_i*cos(phi_i+w)+cx + p[i,0]=x_i+r_i*np.sin(phi_i+w) # x= x_i+r_i*cos(phi_i+w)+cx p[i,1]=y_i # y= y_i - p[i,2]=z_i-r_i*np.sin(phi_i+w) # z= z_i+r_i*sin(phi_i*w) + p[i,2]=z_i+r_i*np.cos(phi_i+w) # z= z_i+r_i*sin(phi_i*w) v=p[1]-p[0] #for y = 0..1: #v=v*y @@ -621,9 +628,9 @@ class HelicalScan(MotionBase): p=np.ndarray((param.shape[0], 3)) for i in range(2): (z_i, y_i, x_i, r_i, phi_i)=param[i] - p[i,0]=x_i+r_i*np.cos(phi_i+w) # x= x_i+r_i*cos(phi_i+w)+cx + p[i,0]=x_i+r_i*np.sin(phi_i+w) # x= x_i+r_i*cos(phi_i+w)+cx p[i,1]=y_i # y= y_i - p[i,2]=z_i-r_i*np.sin(phi_i+w) # z= z_i+r_i*sin(phi_i*w) + p[i,2]=z_i+r_i*np.cos(phi_i+w) # z= z_i+r_i*sin(phi_i*w) v=p[1]-p[0] #for y = 0..1: #v=v*y @@ -695,7 +702,8 @@ class HelicalScan(MotionBase): #bias=np.absolute(f[0]/n) assert(np.imag(f[0])==0.) bias=np.real(f[0]/n) - phase=np.angle(f[idx]) + #phase=np.angle(f[idx]) #f(w)=bias+ampl*cos(w+phase) + phase=np.angle(f[idx]*1j) #f(w)=bias+ampl*sin(w+phase) ampl=np.absolute(f[idx])*2/n return (bias,ampl,phase) @@ -757,12 +765,12 @@ open forward {W}={qW} {qW}={qW}*{d2r} //scale from 1000*deg to rad - {p0_x}={x_0}+{r_0}*cos({phi_0}+{qW}) - {p1_x}={x_1}+{r_1}*cos({phi_1}+{qW}) + {p0_x}={x_0}+{r_0}*sin({phi_0}+{qW}) + {p1_x}={x_1}+{r_1}*sin({phi_1}+{qW}) {p0_y}={y_0} {p1_y}={y_1} - {p0_z}={z_0}-{r_0}*sin({phi_0}+{qW}) - {p1_z}={z_1}-{r_1}*sin({phi_1}+{qW}) + {p0_z}={z_0}+{r_0}*cos({phi_0}+{qW}) + {p1_z}={z_1}+{r_1}*cos({phi_1}+{qW}) {scale}=({qFY}-({y_0}))/({y_1}-({y_0})) {p0_x}={p0_x}+{scale}*({p1_x}-{p0_x}) @@ -801,12 +809,12 @@ open inverse {qW}={W} {W}={W}*{d2r} //scale from 1000*deg to rad - {p0_x}={x_0}+{r_0}*cos({phi_0}+{W}) - {p1_x}={x_1}+{r_1}*cos({phi_1}+{W}) + {p0_x}={x_0}+{r_0}*sin({phi_0}+{W}) + {p1_x}={x_1}+{r_1}*sin({phi_1}+{W}) {p0_y}={y_0} {p1_y}={y_1} - {p0_z}={z_0}-{r_0}*sin({phi_0}+{W}) - {p1_z}={z_1}-{r_1}*sin({phi_1}+{W}) + {p0_z}={z_0}+{r_0}*cos({phi_0}+{W}) + {p1_z}={z_1}+{r_1}*cos({phi_1}+{W}) {sclY}=({Y}-({y_0}))/({y_1}-({y_0})) {p_x}={p0_x}+{sclY}*({p1_x}-{p0_x}) @@ -1057,27 +1065,29 @@ if __name__=='__main__': comm = PPComm(host=args.host) gather = Gather(comm) gpascii = comm.gpascii + #HelicalScanTests.calcParamSim() hs=HelicalScan(comm, gather, args.verbose) - hsg=HelicalScanGui(hs) #hs.test_find_rot_ctr() #hs.test_find_rot_ctr(n=5. ,per=1.,bias=2.31,ampl=4.12,phi=24.6) fn='/tmp/helicalscan' hs.load_rec(fn+'.npz') - #hsg.interactive_anim() - + hs.param[:4]+=np.pi/2.#add 90 deg + hsg=HelicalScanGui(hs);hsg.interactive_anim() + #while True:hsg.update_anim(0) #hs.param = np.ndarray((2,5)) #hs.param[0]=(15,2,0,3,0)#(z_i, y_i, x_i, r_i,phi_i) - #hs.param[1]=(15,4,0,3,0)#(z_i, y_i, x_i, r_i,phi_i) + #hs.param[1]=(15,4,0,2,np.pi/4)#(z_i, y_i, x_i, r_i,phi_i) - #hsg.interactive_cx_cz_w_fy() + hsg=HelicalScanGui(hs);hsg.interactive_cx_cz_w_fy() + #hsg=HelicalScanGui(hs);hsg.interactive_cx_cz_w_fy(manip=True) #while True: hsg.update_cx_cz_w_fy() #for debug purpose - hsg.interactive_dx_dz_w_y() - while True: hsg.update_dx_dz_w_y() #for debug purpose + hsg=HelicalScanGui(hs);hsg.interactive_dx_dz_w_y() + #while True: hsg.update_dx_dz_w_y() #for debug purpose - return + #return #TODO: FE Digitizers PBPS117 timing not working!