diff --git a/cfg/MX1_setup.cfg b/cfg/MX1_setup.cfg index 1243832..6b6105c 100644 --- a/cfg/MX1_setup.cfg +++ b/cfg/MX1_setup.cfg @@ -29,7 +29,7 @@ //Mot 4: Stage X Stada Stepper 670mA 200 poles 1 rev = 100*2048 phase_step (2 stepper motor) //Enc 4: Renishaw absolute BiSS -//Mot 5: Stage Y Stada Stepper 670mA 200 poles 1 rev = 100*2048 phase_step (2 stepper motor) +//Mot 5: Stage Z Stada Stepper 670mA 200 poles 1 rev = 100*2048 phase_step (2 stepper motor) //Enc 5: Renishaw absolute BiSS //Enc 6: Interferometer Y diff --git a/python/helicalscan.py b/python/helicalscan.py index 986636d..26e8209 100755 --- a/python/helicalscan.py +++ b/python/helicalscan.py @@ -8,16 +8,23 @@ ''' tools to setup and execute a helical scan of a cristal +Gather motor order +"Motor[4].ActPos","Motor[5].ActPos","Motor[3].ActPos","Motor[1].ActPos motors CX CZ RY FY - 7 8 1 2 -Mot 1: Rotation stage LS Mecapion MDM-DC06DNC0H 32 poles = 1 rev = 16*2048=32768 phase_step -Mot 2: Stage Y Parker MX80L D11 25mm one pole cycle = 13mm = 2048 phase_step -Mot 3: Stage X Parker MX80L D11 25mm one pole cycle = 13mm = 2048 phase_step -Mot/Enc 4: camera base plate X -Mot/Enc 5: camera base plate Y -Mot 6: Backlight 2.3A -Mot 7: Stada Stepper: 670mA 200 poles 1 rev = 100*2048 phase_step (2 stepper motor) -Mot 8: Stada Stepper: 670mA 200 poles 1 rev = 100*2048 phase_step (2 stepper motor) + 4 5 3 1 +Mot 1: Stage Y Parker MX80L D11 25mm one pole cycle = 13mm = 2048 phase_step +Mot 2: Stage X Parker MX80L D11 25mm one pole cycle = 13mm = 2048 phase_step +Mot 3: Rotation stage LS Mecapion MDM-DC06DNC0H 32 poles = 1 rev = 16*2048=32768 phase_step +Mot 4: Stage X Stada Stepper 670mA 200 poles 1 rev = 100*2048 phase_step (2 stepper motor) +Mot 5: Stage Z Stada Stepper 670mA 200 poles 1 rev = 100*2048 phase_step (2 stepper motor) +Enc 6: Interferometer Y +Enc 7: Interferometer X + + + + + + verbose bits: #1 basic info @@ -147,27 +154,41 @@ class HelicalScanGui(): #print msg event.canvas.toolbar.set_message(msg) - def interactive_cx_cz_w_fy(self): + def interactive_cx_cz_w_fy(self,manip=False): + '''interactive shows a cristal with sliders for cx,cz,w,fy + self.helScn.param is used a cristal parameters + THE AXES ARE RELABELED ! + The generated members are: + self.fig : handle to figure + self.hCrist : handle to cristal object + self.hOrig : handle to xyz-origin cross (xyz-length= 1/5 height of cristal + self.manip : True: moves the origin cross, False moves the Cristal + ''' param=self.helScn.param - fig = plt.figure() - self.manip=False#True#False + self.fig=fig=plt.figure() + 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=10) + ax.view_init(elev=14., azim=-170) # param[i]=(z_i, y_i, x_i, r_i,phi_i) ctr=param[:,0:3].mean(0)[::-1] - 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) 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]) - if self.manip: - lz=ax.get_xlim() - lx=ax.get_ylim() - ly=ax.get_zlim() - else: - lx = ly=lz=[-5,5] + #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) + 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.) self.sldW =sW =Slider(axW, 'ang', -180., 180.0, valinit=0) @@ -177,9 +198,9 @@ class HelicalScanGui(): sW.on_changed(self.update_cx_cz_w_fy) sFy.on_changed(self.update_cx_cz_w_fy) - hCrist,pt=self.pltCrist() + self.update_cx_cz_w_fy() + #self.pltCrist(0,0,0,0) - self.hCrist=hCrist;self.fig=fig # param[i]=(z_i, y_i, x_i, r_i,phi_i) p=np.ndarray((param.shape[0], 3)) for i in range(2): @@ -190,11 +211,11 @@ class HelicalScanGui(): print(p) ofs=(p[1]+p[0])/2. # = center of the cristal - m=Trf.trans(*ofs); self.hOrig=self.pltOrig(m) - + ofs=(0,0,0) + m=Trf.trans(*ofs); self.pltOrig(m) plt.show() - def update_cx_cz_w_fy(self,val): + def update_cx_cz_w_fy(self,val=None): cx = self.sldCx.val cz = self.sldCz.val w = self.sldW.val @@ -209,24 +230,25 @@ class HelicalScanGui(): 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) - ofs = (p[1] + p[0]) / 2. # = center of the cristal - m = Trf.trans(cx,fy,cz) m= m.dot(Trf.rotY(w*d2r)) - self.hOrig = self.pltOrig(m,self.hOrig) + self.pltOrig(m) else: - self.hCrist,pt=self.pltCrist(cx,cz,w*d2r,fy,self.hCrist) - #l.set_ydata(amp * np.sin(2 * np.pi * freq * t)) + w=w*d2r + self.pltCrist(-cx, -cz, w, -fy) + #self.pltCrist(cx,cz,w*d2r,fy) self.fig.canvas.draw_idle() def interactive_dx_dz_w_y(self): param=self.helScn.param - fig = plt.figure() + 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) # 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]) @@ -235,8 +257,9 @@ class HelicalScanGui(): axW =plt.axes([0.1, 0.07, 0.8, 0.02]) axY =plt.axes([0.1, 0.10, 0.8, 0.02]) - lx=[-1,1];ly=[0,1];lz=[-1,1] - ly = param[:,1] + lz=ax.get_xlim() + lx=ax.get_ylim() + ly = param[::-1,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) @@ -257,13 +280,12 @@ class HelicalScanGui(): ofs=(p[1]+p[0])/2. # = center of the cristal print('p, ofs',p,ofs) - m=Trf.trans(0,0,0); self.hOrig=self.pltOrig(m) - hCrist,pt=self.pltCrist(cx=-ofs[0],fy=-ofs[1],cz=-ofs[2]) - - self.hCrist=hCrist;self.fig=fig + 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): + def update_dx_dz_w_y(self,val=None): + print(val) helScn=self.helScn dx = self.sldDx.val dz = self.sldDz.val @@ -272,7 +294,7 @@ class HelicalScanGui(): w=w*d2r (cx,cz,w,fy)=helScn.inv_transform(dx,dz,w,y) #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 interactive_anim(self): @@ -293,7 +315,7 @@ 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.hOrig=self.pltOrig(m) + m=Trf.trans(0,0,0); self.pltOrig(m) self.hCrist=None self.fig=fig @@ -322,36 +344,43 @@ class HelicalScanGui(): #data=self.rec[int(idx*self.step),:] #self.hCrist,pt=self.pltCrist(*data,h=self.hCrist) - def pltOrig(self,m,h=None): + def pltOrig(self,m): + '''plots a xyz axes in rgb colors that shows the transformation matrix m + if h is not none, the handles are the existing object and is modified + m is a 4x4 matrix. the transformed matrix + ''' ax=self.ax - # m is a 4x4 matrix. the transformed matrix idx=(2,0,1) - r=m[idx,0] #1st - g=m[idx,1] #2nd - b=m[idx,2] #3rd - o=m[idx,3] #origin + 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 lines = np.ndarray((3, 2, 3)) # numlines, points, xyz lines[:, 0, :] = o lines[0, 1, :] = o + r lines[1, 1, :] = o + g lines[2, 1, :] = o + b - if h is None: + + try: + h=self.hOrig + except AttributeError: lseg = tuple(lines) col=('r','g','b') - hlc = plt3d.art3d.Line3DCollection(lseg, colors=col, linewidths=2) # , *args[argi:], **kwargs) - ax.add_collection(hlc) - return hlc + h = plt3d.art3d.Line3DCollection(lseg, colors=col, linewidths=2) # , *args[argi:], **kwargs) + ax.add_collection(h) + self.hOrig=h else: h.set_segments(lines) - return h - def pltCrist(self,cx=0,cz=0,w=0,fy=0,h=None): + def pltCrist(self,cx,cz,w,fy): #h are the handles ax = self.ax helScn = self.helScn param = helScn.param pt = np.ndarray((4, 3)) - if h is None: + try: + h=self.hCrist + except AttributeError: h=[] #handels for i in range(2): (z, y, x, r, phi) = param[i] @@ -377,6 +406,7 @@ class HelicalScanGui(): col=(mpl.colors.colorConverter.to_rgba('r'),)*len(lseg) hlc=plt3d.art3d.Line3DCollection(lseg,colors=col)#, *args[argi:], **kwargs) ax.add_collection(hlc);h.append(hlc) + self.hCrist=h else: for i in range(2): (z, y, x, r, phi) = param[i] @@ -403,6 +433,7 @@ class HelicalScanGui(): hlc=h[5] hlc.set_segments(lines) + return (h,pt) def get_meas_lines(self,pt,cx,cz,fy,w): @@ -1019,6 +1050,7 @@ close if __name__=='__main__': def run_test(args): + args.host=None if args.host is None: comm=gather=None else: @@ -1031,8 +1063,22 @@ if __name__=='__main__': #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 = 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) + + #hsg.interactive_cx_cz_w_fy() + #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 + + return - #TODO: move the graphic part in a separate class #TODO: FE Digitizers PBPS117 timing not working! #hs.calcParam() @@ -1105,7 +1151,7 @@ if __name__=='__main__': #hs.gen_prog(mode=0,cntHor=3,cntVert=10,hRng=(-5,5),wRng=(0,120000)) #hs.gen_prog(mode=0,cntHor=3,cntVert=25,hRng=(-5,5),wRng=(0,120000)) #hs.gen_prog(mode=1,cntHor=3,cntVert=25,hRng=(-5,5),wRng=(0,120000),smt=0,pt2pt_time=300) - hs.setup_motion(mode=1,cntHor=5,cntVert=25,hRng=(-10,10),wRng=(0,120000),smt=0,pt2pt_time=300) + hs.setup_motion(mode=1,cntHor=5,cntVert=15,hRng=(-150,150),wRng=(0,120000),smt=0,pt2pt_time=300) #hs.gen_prog(mode=1,cntHor=5,cntVert=25,hRng=(-100,100),wRng=(0,120000),smt=0,pt2pt_time=40) #hs.gen_prog(mode=1,cntHor=3,cntVert=20,hRng=(-5,5),wRng=(0,1200),smt=0,pt2pt_time=200) #hs.gen_prog(mode=1, cntHor=2, cntVert=2, wRng=(0, 360000), smt=0) diff --git a/python/shapepath.py b/python/shapepath.py index 0111a71..ef8cc5c 100755 --- a/python/shapepath.py +++ b/python/shapepath.py @@ -15,39 +15,22 @@ verbose bits: 4 upload progress 8 plot gather path -#config file example: -{ - "points": [ - [100,523],[635,632],[756,213], - "sequencer":[ - 'gen_grid_points(w=10,h=10,pitch=100,rnd=.2)', - 'sort_points()', - 'gen_prog(file="'+fn+'.prg")', - 'plot_gather("'+fn+'.npz")'] -} - -Sequencer functions are: - - generate points (if not in the 'points' configuration) - gen_rand_points(self,n=107,scale=1000) - gen_grid_points(w=10,h=10,pitch=100,rnd=.2) - - sorting points: - sort_points(self) - - generate/download/execute motion progran, upload trace of motors (gather data) - gen_prog(self,prgId=2,file=None,host=None) - if host=None nothing will be downloaded/executed and trace of motors will not be uploaded - if file=None the program will not be saved and nothing will be executed - gen_prog modes: - -1 jog a 10mm square - 0 linear motion - 1 pvt motion - 2 spline motion +Gather motor order +"Motor[3].ActPos","Motor[2].ActPos","Motor[1].ActPos","Motor[3].DesPos","Motor[2].DesPos","Motor[1].DesPos") + ACT DES +motors RY FX FY RY FX FY + 3 2 1 3 2 1 +Mot 1: Stage Y Parker MX80L D11 25mm one pole cycle = 13mm = 2048 phase_step +Mot 2: Stage X Parker MX80L D11 25mm one pole cycle = 13mm = 2048 phase_step +Mot 3: Rotation stage LS Mecapion MDM-DC06DNC0H 32 poles = 1 rev = 16*2048=32768 phase_step +Mot 4: Stage X Stada Stepper 670mA 200 poles 1 rev = 100*2048 phase_step (2 stepper motor) +Mot 5: Stage Z Stada Stepper 670mA 200 poles 1 rev = 100*2048 phase_step (2 stepper motor) +Enc 6: Interferometer Y +Enc 7: Interferometer X + - - plot gathered data - plot_gather("'+fn+'.npz") - this makes only sence, if motion has been executed and data can be gathered from the powerbrick -Acquired time is:MaxSamples*Period*.2 ''' from __future__ import print_function import os, sys, time