From 362daa7846285dfad6c02fc98d3dd250764ae0c3 Mon Sep 17 00:00:00 2001 From: Vonka Jakub Date: Fri, 23 Sep 2022 09:36:33 +0200 Subject: [PATCH] Added attocube module --- __pycache__/PSSS_motion.cpython-39.pyc | Bin 0 -> 7624 bytes __pycache__/attocube.cpython-39.pyc | Bin 0 -> 12247 bytes .../attocube_assignment.cpython-39.pyc | Bin 0 -> 338 bytes .../attocube_device_def.cpython-39.pyc | Bin 0 -> 307 bytes __pycache__/channels.cpython-39.pyc | Bin 0 -> 4598 bytes __pycache__/cool_motor.cpython-39.pyc | Bin 0 -> 824 bytes __pycache__/knife_edge.cpython-39.pyc | Bin 0 -> 410 bytes __pycache__/our_attocube.cpython-39.pyc | Bin 0 -> 300 bytes __pycache__/smaract.cpython-39.pyc | Bin 0 -> 8219 bytes __pycache__/smaract_device_def.cpython-39.pyc | Bin 0 -> 409 bytes __pycache__/spreadsheet.cpython-39.pyc | Bin 0 -> 3681 bytes __pycache__/undulator.cpython-39.pyc | Bin 0 -> 7319 bytes attocube.py | 354 ++++++++++++++++++ attocube_device_def.py | 6 + cristallina.py | 14 +- 15 files changed, 371 insertions(+), 3 deletions(-) create mode 100644 __pycache__/PSSS_motion.cpython-39.pyc create mode 100644 __pycache__/attocube.cpython-39.pyc create mode 100644 __pycache__/attocube_assignment.cpython-39.pyc create mode 100644 __pycache__/attocube_device_def.cpython-39.pyc create mode 100644 __pycache__/channels.cpython-39.pyc create mode 100644 __pycache__/cool_motor.cpython-39.pyc create mode 100644 __pycache__/knife_edge.cpython-39.pyc create mode 100644 __pycache__/our_attocube.cpython-39.pyc create mode 100644 __pycache__/smaract.cpython-39.pyc create mode 100644 __pycache__/smaract_device_def.cpython-39.pyc create mode 100644 __pycache__/spreadsheet.cpython-39.pyc create mode 100644 __pycache__/undulator.cpython-39.pyc create mode 100644 attocube.py create mode 100644 attocube_device_def.py diff --git a/__pycache__/PSSS_motion.cpython-39.pyc b/__pycache__/PSSS_motion.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3048456be5cd4cdf708b439b2de0c3fdb7dd9527 GIT binary patch literal 7624 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 literal 0 HcmV?d00001 diff --git a/__pycache__/attocube_assignment.cpython-39.pyc b/__pycache__/attocube_assignment.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2578e143a29aa5d90736b330dfe9eea37daf40d GIT binary patch literal 338 zcmZuqO-sZu5Y43fQN)7aS?@iVtauX%o9nnMX;V%sa)ZF`6NGUh~y00?;|Lpz>*3I0HQ%r6{&$5K1Bsp zqnxDUSG*x9^hp*%ExUW22T|(fPM+ON^P|Z@Hk(~t+@4RDyMLAAZ1SIYn9?4K9_}vF zsMzz?NT&3Ik=nCTJKYM)#3rhxnBB+UbWPe33SaPc&C7-0tg1T~Jok&aY>f}XTH^#4 tO@n_$FttMuSN_Z0yq^p2P3bD_0&5=o_@t^;XZ0yyh>sDrqXAH$?;q+uU0DDC literal 0 HcmV?d00001 diff --git a/__pycache__/attocube_device_def.cpython-39.pyc b/__pycache__/attocube_device_def.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a0fc4c2cecddbacefa184c35772d64bee0f5ae64 GIT binary patch literal 307 zcmYe~<>g`kf~R{mlY4>mV-N=!umU*_KwK;bBvKes7;_kM8KW2(8B!Tjm{OQiSW;Mf znWGp|*n$}}*7*eN`=9Lud7pKK1 z7iAWgB4*-NkQC|Q6 literal 0 HcmV?d00001 diff --git a/__pycache__/channels.cpython-39.pyc b/__pycache__/channels.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab9b05220be9855a6b4874092343c31cfa336999 GIT binary patch literal 4598 zcma)A>u%~s5QYsQCJ84wRoe7+dXp*@RV0|36jW6u!~|L{mTd_5k7a=&sN7^bY4GEm ze|>>IO#b#2Dz!ar&*^v#4z_n8M9bp&z8QOFc0D^$6ne*a*IlJV~F_VIey2$48 zNxsx%3uV4ql3D_n*s(rZGa{yPnS!fto%o>+-xPz=E=UtGY^cd+SUU_N%dQ*x6bz9e zrS&6r!-LkQKVOt?A)dU_F4h$OD)kHw`wUL{8Jx^BI9VJ7&ojHB@knuKn6)H|BEyBHqb5&O-nyKkV;^o?c;Dx%qAVyPDn;Ii?VSNEMoIow12c@S0sw=aB zGEof!yY6EQMy8@p=Hroh*Vk~|2!x5IPO)bMY&IAenrVF#yt!@KFx6>a)%!|cyC13M zXg0;0(r@RN+ey%~2L*yK7>zaS{h)DuVgwytY;|~{Y;o8jkR5g~n!^tI9EX8Pba+8` zc%gv9f%L;`k(Pddwxl03HbuiF5TfB?#Avwa)@V4)U^K9toPG=i(+}b;>Bo#M4pYos={N;ee@s|VO z5Xu2am*wC~ct_xxT$8Hx6zi1qt5&_O_m#C zp;So~?7Dl+N!BOsqhh!uR7I)CVhT$K(*+j4BLhz2b4w!sR9u=xzLm;m3w1a#2~Z8) zs^bN^G~k8?RMr7WvJW=SJ)FnJWwBZG0B6Ewo2He<&JwiJo3t`Ct;{B^EKMuBNh?Rw z%5Boh)3owf%RQ~GLgk!ktq);Yc!D7b#fGSeJPi>pab$5Z1zSZH-W02R*f}QvX_`ic z24rbKjt1m|hal&vx|uWB0=R5@PEZaiG$p0uFajqqhtbJleH!ZMJ~{r=Wt)W+dZTpQ zWH}LWfi4E@xcdOXQ6V989ofyU$J%9!BEKR(megfwz|+3)+(ClCuC|#M=+I1cf~G2L zE=vs75(qlJ1PH-eA#|N!u&@pxSdKgxEG#DlYY9+1Bn8XSSjOZSmP4yiD04Nt<%GSd zhoNo8TiOXOyj@wSJIghRm!$nhCxVccL=^8|{Mzn_b=al(LdVv&Q)aI)57MO~@(Qt= zOOKAQphFLI$XY^;#LLH69~z9FInxdKq<5=Mr`p(1hN_`VX44UfoE@y5S(5X&>lzjwuQ zY<_Pj26Q!s9Jha}b4@qzbj^^DjS2KqJ=5hr?f~J}kiH99#$Ru^^Wi`}Kby?%rlxUj z43wTef|KlcJesQK>KvM-9&Tj-gP-T?=;~?C=8H$>yUDD7H`cyq?Ek&g;48Ar9H4iR zXe7cg%n|b*a|(ZP<^+Y&JA}|%w1fUb5%e$GMgO2EdV}`R--tnfp&0rT7)Q)?WDmG+ IBT**yKYTeJo&W#< literal 0 HcmV?d00001 diff --git a/__pycache__/cool_motor.cpython-39.pyc b/__pycache__/cool_motor.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..192ea1e219dbdc2dc99f9ea4b76cd943c2c6f054 GIT binary patch literal 824 zcmZ`%v2NQi5Iu^LExU1$00q*m8LLJ5fuKkcpqZ-0owN|FNV^JX$t9%}DZDj5;}6Qh zwNrkfQ|}}sP~7%_JCeuay?1w%i^UvJ9xl$xlmYyr!&pK*T%x*jGzt_muweyba1AO@ z{2mn7>?bb*6)qu(9x)0M=I0;OP3Kzq#pse;V+rtZiR#{=(NHi2_?#7dNLYj_RM9;Y zk(#I}t`ikw>X|?ObeHSzS50F+f351ZMY>Ruc@o-_UZJ`PnjPH0680?LGtak;!zFau ztoC4Mc>Vi2Td!o6Zkn!cUFKGzv=x#zrmAHow_8({vaOmL?{J%qZ%d>hHci{ubbIGd z*SZyDXRWSVaVt%yW8y%S0{e0Pl6d-8aM=e^FbeHS`zmNSJGKLXy68mFb&Ek{E{9rY&; q!XV}`@4b1#{c9RzS~gav^7)5aYIh& literal 0 HcmV?d00001 diff --git a/__pycache__/knife_edge.cpython-39.pyc b/__pycache__/knife_edge.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a47aecefe7dcd8c40fcf7f4fb1017622b137bdd8 GIT binary patch literal 410 zcmZWkO-sW-5Zy@{8?^<&n;`U>g9&&nA_}b@q$<`!%_S_^X;|ERu$xL-ym|JAc=q4y z)sx^a@Z==D6dc%j^LD=8@P2=fk-dHf=?~#oL$=K$azW1w$q6Pvu^eK6CU%sQyRi!l zUE#h#+#&1`dI-Y94tiqe-Hmrdcgh0)oBCM*wl|e|rEr8VGDYIvq^wK5KA2uUoQ!Ap zli6@`_n2JG{{1|y4^Kyfn?lZUfFi?zsdwd4JY|bNUTNJg4%sff8 xBsogSf=9fnNC&TFSx}C`XgmAd9FQ~zgw@LWXL%_W3eSON8=qVcdX5ji^9KXJbe8}C literal 0 HcmV?d00001 diff --git a/__pycache__/our_attocube.cpython-39.pyc b/__pycache__/our_attocube.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ad8da51b7e386ca55706606062d13282b16e467 GIT binary patch literal 300 zcmYe~<>g`kg3Jk;$$dcjF^Gc@R_87&IAg@j8~2CRtckv zSUDPC6ExIhy2TiEi!s6v$lyqXnp(sJv}Pqk5gU*K6Tdw5)6)|5^>Xt|^Gb^Ki__wh zi!zH#5_57g^AhzF3kq^FlM_oa^YegmK&C#jY<_7`Jj`Idg34PQHo5sJr8%i~j6ldf literal 0 HcmV?d00001 diff --git a/__pycache__/smaract.cpython-39.pyc b/__pycache__/smaract.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..35d4feac48247e62fc0314b68cc2e97b111407ff GIT binary patch literal 8219 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 literal 0 HcmV?d00001 diff --git a/__pycache__/smaract_device_def.cpython-39.pyc b/__pycache__/smaract_device_def.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2843c3cd438ee3cbdda2f6537c3c913edb7ccf7b GIT binary patch literal 409 zcmYe~<>g`k0-Ft*$*N2Y439w^WWWjJH~?|68jwg~NMX!j$YqRTWMoKXOkql4PGL!5 zO<_x6PvJ=6>}8K)NZ|@*(ByszRLh{rc#9`EH?hbuxg@wGF+H`4KiDzIHQ3ldHzL^A z(a_YaN)S!JDgsj|5>qIuN(fzJP$d?z3M^t(nryciBW^K9-eQc3VhXAR;tC+H^3!Cx z#a;|_ZDMjs5ilGWRx%W^11T`^%U?e|Em2=DH@`Hmq*%W=Ek3y@v$!NNCnqy6Q9rSu zASW|9u_QA;4=4v@>LbfS&5Tb;Ez3+!1yX5x1(mlrY;yBcN^?@}KvoqC00|ye7Dgrn G`~?8&Mrj5B literal 0 HcmV?d00001 diff --git a/__pycache__/spreadsheet.cpython-39.pyc b/__pycache__/spreadsheet.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca7c365a328903c719114df3f094b1e4e6756b2c GIT binary patch literal 3681 zcma)8&2!tv6~_W3MNyPQ%O8y#$7NF2He-VykSyDZ>zEd)kB&rf2#Sp{lfl5mN`e9c z^a4~OjC`_Z(j3y69&$=EV|RM#wdedLnBIEQxi_Es9!RceeRxXE{_xvL%YwI zoJVwJ|sB6!IR#uD=aXEU5#mpQw_*>5=eh_hMFu5$J< zXV*CUgtP0M{g$&VXP;`AQ=j`TyjhVMNyWMAI?r*bn{2$~mM4N#1{T$Xe zO%vuF^X_Zm711Vv%Vs{}Q)WRGa-}2O*PIxp>#ef6*YkYixlO}Ny;XI3o#U1q3Dc_8 z>DshH_pLUC`h?->-mc61cF%94m(iaHl_yZVO8`{Rh$(2INlfvzph>0#kz?UZy`}oh za(0fxwBbDQA94xG5|qf#p|B_Hk-f;zkK~Q?RscUztqEerQB33v982AOFHACOn9q&& zH=(pc{V@B#$U+dampjOMP6p~h1_@=d<W?a&Kk7_V zf0T0mC?&YsS6Gxc%C)t6Bz&`>m-4Oh`Z+e`1Gc$QTS;zh$gQSQREmrBMpad}8r7lC zfo-l>`hX1%8XtEDbS_s*MY&$BuN3DO7V-RT)?_$>jg@E6+K}s8>uOalw^o9Tx-2i% zm)7Ox+QuT3YH$UHZ`Dfk^2XCzrBo~~uE~vRxe{DH-43TUxIT=wS#CCq3-fpulxCw` zQ*nZollFTj?77)61!tMjZo}|tI9)eP)22(iM&~(YrSDEQ9Gq+jv5(Gj4xX@&Eka^OhKe<8$x9Z+2-c5mVgV~F%2!DLKK^_d(fXP;GhWz z?87zgLD*nQ19k|WCAk+NT&9+_JWnT97vqCMW zjrFHf(xyf)u~KnpP)-;gviqpwA;K+$MT9Q^w6PTiqMV&D?lP0IFs9m;A6%?}sJ8F2 zY}fTHe1fuHoz?g(m_6O|w&Cp9G^dHxZ=iJ9A23dA!v**ANF`V?Rzd{|!W_a~gginK z;SPd~P(ZkikVE(!U^vT#A-O*!4~FESmK-cmk+TwK3TJbi&2x5-vjxuXbM}BU9z)?V z6dprS&df=oTmqjwU+~E*f*C605TphfP`nGdh#w~1!3#99;XUH~qcvDZmotU!kL60+kr(xLDcm>)ZY zmVv@V?ab5&pJ(qHz@hMGVP9Y$`S3jyW`#H8Eeuv6HHYbmwGdN02~r@24?jH6!~ziA z{r)7Q>;WwY=nwM+fh0+W1h@Lrg>;DO+b+{blb%Pm+cs?PF(xwaiNl;H1|<@Qxx)@f z`a1oRfHYY1zltwn>PP|u%EWw;;m+hpr0-Z%n0jPGLe_RW-N!GX!+)U&LH_?ybv*DL zxtoi#FJUC6SEkkWA*ITUOhw1}g|R)?a@b?&21_Hs6&K0KiG4{GXzw3^tLI1GhfW@@ zqaY?oIyOU6gl#~r1{1pp-`sR~2@}bD+hsIw@O+!$k}*6d;U~v-Gs?8{UX*tCD-72) zOhtWqzGZtXjw5l$w1lJg9MjXL0DHCpcZY5{uxYrk(d^kDkv%~`QD>g-edf$@%Q?ZvoO%BwFaL<~aX#@_cTQbb_#~fttnew{+Si=Z=uh(*^k@7r^v|F_ z%jeLa+gF{l=$+v6=*^?|5)ZEpIa zqGi@9-|j@Q_aN}I^6mR0y{X&x*TPP7ID+@ekGw|g)?32$f*_gMSiN(v`kj^K*Sib% zZd9)=e{=bTh7Z1&LbXYsre~eL=ZC)7+^eyCNY=!1Dpye=2UQHV?-R?_E{j=;c2`Z+ zZ8Zh!x&BOLN~|5|n+i96%nn&siw$nl`c&ICd0|Hr)wpm_Mg(Vdn;?zwL8~8xC?&h#K($}neDxJ zs}&~SSc>XP?X6baT8cz%iC%D<=!vC=@u1geg^TUIL|upyZK3%_GI?zO7b=)2h{cKh z{_36Tjq3FkNr{~wq3MUQUH2M+&li(Z>y5AxZTY-6*{6E3S}A2lTQtI0kSsH;-H9_R z>O5$RR?Uy1OcR|@(5Es>_;E*swHEg?4H}gd9(jVeThYZB7C5u=AUT`e+xOkjYx>T_ z(LwCz$IlgU5-)tVzO-5QmKK|>P8dhviCYs5C}$8fLT|}yw}VE_i@^uXp}90VI}jdt zlubr{?2dfrC2Stepi=ZA(^-*Cs1s^YwOCmdr!iWisnN&mb)vV>@D+z~#ZftPG+*Z` zsUwH-)y*eLo$&%MJ}x;1pW+rDd(0e@m-#qsu)rtyBz}uepyy5rYB-%)_xd^(CEHTP zU`%%Cf_hi@^*^Y#Lf^i?{kqo);>ty-br|=BAJ%+(a7Me<5g3YtJ-ZV@h7b1S%BEM_ zYG8v$jUcceU_IvKN2+(7>D4={w{C2>_o~jwtcQuT)l*V6)O<5Po-H8!QOv$&A5T}6Cft}|m=ff3Zjd|k>8igAJ7z>aK}i67%D zCAptP>ps=x7g?&f7)1?v@bY6NW!IE_rYjg3>lWkk!FZ}3=KYCoNqSu+Ez%mSm`pX) zQ}OgZt)EGi?a8!sTIpKxY--6Bb6kNeC#w}T(@CQagwwIcYiFWUD)a;0KJl=N|OZC|wJ%XQ|$XRMM~^zPNS zZd|o5B(KN~8=>4UfEn7Yy6x5C#_otBMk{u5?xO95e4uoV&9EhWz9jr+YuD$=>0d|B zh2+%%&Hwjjj>HafKL*MMspUMXO$h6w3B(QM0FmR6{i*s;-^iT`#8igTyVccOYwr53 zyO{}-YkD!p)y3tEh0^up)hTS1S(oUvwN|rznfCuL6eW3OXe5iS3*Q;L?&77ORr7-A zG8+9izMRZPkIWQ=lFt9x2$?J^4ZcxP#aHlEL4ND=-lBQ&4F6hjZuSQvE zxJ3yLOFI2X{1)wC(+=hSpbOq*I$~3lnTX2>OWD}fR=Dd6gx9s3S)rD9vf>8K(vTt7 zRmL(s@`Jiqq)nHo`X=qH-nf=?>>PT|^yiKwmT4*ApOP`}Ir#0mwZMxa*BweROi@~I%Q%Ff=Mzv5MVS=lJy$-&i+Gjg+Pz= zr+wW)Lw0>Kmr>ri>BfO*yJ}Y>7N`0trEA2R3|=f3TB<{IT56!yKP{5*D9oig#9Z&KG(JVhWXi*Npk6c8 zIZ*90wQHuzK_N9M>^+>1iz$SRcS}6q!;1c#f*_3n^NvAT(2@ZPqEg|V_0q!SQlgeF zi1VO7Id4ZhjdmNDA!-n$$k}A~Wx5Wt(6?Fve?jgwITf~Y1WB%3;zvKERDoB@nU*x# z;&rUbj7ID?BQZ&BHEg3Fgb$r7e%bhA!JE{v|I1qUz0ejQpk+hi*};i zj!Ei{vEzas`U(9T8QrLOVZ;__m};3VvwUnOWQN!cBhTje>`HtcWHUmG#dpNgMujAn24UA^&rdY$TSf`5k zlQYbe#6{9;iQlD#CE&iu4H`Q>9J5D9iFPWcJc_8&d#kjH?PTT_%*7YtT^c0JEN)Rn zb|$W)@=+oim4dUCaW)HhcSfC4P5e&bbQ5q?raH5noc)qB9x-Ur1oBr`QKE~efQb~C zGvPo6WCVOi#?S?B+U|L-*nk1(DMIjbR>e8U=gOmt%hbwwvnFn%Q!(;WzDyI+%V2TU`EI znw7q56kH769&uXzHvm~QFWi%ye9m&dNga@t)PWDM=}%E2qFQ0e+z4+5TUXe6#Ucbi z@YQuQ%LT>AeW_h`UGjsynS$%`Rt>|ZjQATeJW55&B}t#l#(QzJ<_AGPmP(3#AG5h? zow0lo(0C2y$fNgq(KpZ-Bwu;5h2#s#7NucG!5%|mjv>=46LKqv zuj7S(`PK9P_{UohuDp39@RAaf+mV7KHA@+1CrN4Hv3p4k{5Ap|QVUA)o|*8n)YeZT zoUhRv} z3zD&w^|g0yzxD22+zM2f*aS&Pn_t0C&SOFfnFVy@=6U~Dl+*4b_i>kqvS`eHhu|C0;Xn$%_90CD%qZnHqk#cPb`G{1Dwo^!guDeI zwTs05cPJ4tt*A~|DwC=}TOWBqvvLI`BIG>KETr|gn$x+4BwqKmImOpejI#<-c>`(u zj08i>!L=Q?kkFU%w9>Ki)X^Esuj`yLp9XJc#ka8e=ImcA|K;g}|GdkGI3uzKya<>i&z3wPF5uhoe6{fF9A zuA)d;==kz5>0{q7a zA|L9?D1BtDR3v>bqXE1E$0*Z&b`~0gP@u)YORy~P_7EQSxmJBaDkix>myqPO>o69i z8fzE_yniTSm;;4!Df^7oGq!u2*!M8~3lu5$Jm4kcqXgeP!bzf%G(b{nqtU07Bam@* z7IuCXU>rUHl%6Ht61;?Qw&*9P#wqONm{L5%pb%6IRZ_C>k1+O2lmS&!>?l=hpR=_A zRef6nWw17~wLGk-nSpEwnU{pfn_jc&xe@#{5^eEChDQ|t8`01cSvmv+vhhxeB z#>nl+(Dgf5bVOT86a#S(;vpfp65IEohSmu=eDJq1>5QXISBUvl;mA4U5$L@CgVNWB z>3&K*u<7cNa7m7o=$E?iHX6PAJ-QE*s@YXz^#F!~d=-IlTiMnrl%_Cv!hN}xP=KAw z9e{z=MvB`$D0Bzg0TX@)KY8SkCSUL(PYAE)>f8C6{A9Vl^x(Zyx;X&-6TO*U%IK7P zeLX zlgq)CfhMGQ(HT4>+9HbN@Le?We}9nKcgZoqT^_RN47vFHE|m~B+?4V?6_{H|%CSzV zU{`rx3Fma=?|W4SEXtG*q>3zK59pOvO~&PaX;$v6tuNrt#xZ0U{4d~}Viy%|_mMfp z5&a(o_xOI8X>|Kf;EMn!Oj*24YljDwDpkSQ58%b6RVXsopquqFa;Y-@icHXo%K1!> z8%;k?_YC|)slAu`c*AcuYEd4y3i$6q;^U@?_$6pm|bG zNxpM#xCq&Nh<`FI(l1>n4D!rrS}m`iD0dOBqRI?GxuEc9fRYe#Lyp#imKV!JR030p zA*5|f@yYXyaA6?stavGh&zC8vMZb-T&RY1tUDkr99CcZlH IUFFpO0_VBKjsO4v literal 0 HcmV?d00001 diff --git a/attocube.py b/attocube.py new file mode 100644 index 0000000..43cf9f8 --- /dev/null +++ b/attocube.py @@ -0,0 +1,354 @@ +from re import S +import time +import subprocess +from types import SimpleNamespace +from enum import IntEnum +from epics import ca + + +# import slic +from slic.core.adjustable import Adjustable, AdjustableError +from slic.utils import typename +from slic.utils.printing import printable_dict +from slic.utils.hastyepics import get_pv as PV +# from ..basedevice import BaseDevice +from slic.core.device.basedevice import BaseDevice + + +class AttocubeStage(BaseDevice): + + def __init__(self, name=None, **axis_ids): + self.name = name + self.axis_ids = axis_ids + + self.axes = {} + for ax_name, ax_id in axis_ids.items(): + record_name = f"{name}: {ax_name}" + ax = AttocubeAxis(ax_id, name=record_name) + setattr(self, ax_name, ax) + self.axes[ax_name] = ax + + + def __repr__(self): + tname = typename(self) + name = self.name + head = f"{tname} \"{name}\"" + + to_print = {ax_name: ax.get_current_value() for ax_name, ax in self.axes.items()} + return printable_dict(to_print, head) + + + +class AttocubeAxis(Adjustable): + + def __init__(self, ID, name=None, units=None, internal=False): + super().__init__(ID, name=name, units=units, internal=internal) + + self.wait_time = 0.1 + self.timeout = 60 + self._move_requested = False + + self.pvs = SimpleNamespace( + drive = PV(ID + "-SET_TARGET"), + readback = PV(ID + "-POS"), + amplitude = PV(ID + "-AMPL_SET"), + amplitude_rb = PV(ID + "-AMPL_RB"), + frequency = PV(ID + "-FREQ_SET"), + frequency_rb = PV(ID + "-FREQ_RB"), + moving_status = PV(ID + "-MOVING"), + hlm = PV(ID + ":HLM"), + llm = PV(ID + ":LLM"), + set_pos = PV(ID + ":SET_POS"), + stop = PV(ID + "-STOP_AUTO_CMD"), + move = PV(ID + "-MV_ABS_SET"), + stop_auto_cmd = PV(ID + "-STOP_AUTO_CMD"), + target_tol_rb = PV(ID + "-TARGET_RANGE"), + target_tol_set = PV(ID + "-SET_TARGET_RANGE"), + target_reached = PV(ID + "-TARGET_REACHED_RB"), + target_ground = PV(ID + "-TARGET_GND_SET"), + output_enabled = PV(ID + "-ENABLE_SET"), + twv = PV(ID + ":TWV"), + units = PV(ID + "-UNIT"), + output_RB = PV(ID + "-ENABLE_RB"), + ) + + @property + def units(self): + units = self._units + if units is not None: + return units + return self.pvs.units.get() + + @units.setter + def units(self, value): + self._units = value + + def disable_output(self,verbose=True): + old_value = self.pvs.output_RB.value + self.pvs.output_enabled.put(0) + if verbose: + if old_value == 1: + print("Output has been disabled") + else: + print("Output has been off and stays that way") + + def enable_output(self,verbose=True): + old_value = self.pvs.output_RB.value + self.pvs.output_enabled.put(1) + if verbose: + if old_value == 0: + print("Output has been enabled") + else: + print("Output has been on and stays that way") + + def get_ground_on_targert(self): + return self.pvs.target_ground.value + + def get_amplitude(self,verbose=False): + amplitude = self.pvs.amplitude_rb.value + if verbose: + print(f'Drive amplitude is {amplitude/1000} V') + return amplitude/1000 + + def set_amplitude(self,value,verbose=False,check=False): + """Set drive amplitude for the axis in Volts. Add check=True for checking if it happened (takes 2s).""" + self.pvs.amplitude.put(value*1000) + if check: + time.sleep(2) + assert self.pvs.amplitude_rb.value == value*1000, 'drive amplitude readback does not match set value' + if verbose: + print(f'Drive amplitude is set to {value} V') + + def get_frequency(self,verbose=False): + frequency = self.pvs.frequency_rb.value + if verbose: + print(f'Drive frequency is {frequency} V') + return frequency + + def set_frequency(self,value,verbose=False,check=False): + """Set drive frequency for the axis in Hz. Add check=True for checking if it happened (takes 2s).""" + self.pvs.frequency.put(value) + if check: + time.sleep(2) + assert self.pvs.frequency_rb.value == value, 'drive frequency readback does not match set value' + if verbose: + print(f'Drive frequency is set to {value} Hz') + + def set_ground_on_target(self,value,verbose=True): + if value == True or value == 1: + self.pvs.target_ground.put(1) + if verbose: + print("grounding upon target arrival is now active") + elif value == False or value == 0: + self.pvs.target_ground.put(0) + if verbose: + print("grounding upon target arrival has been deactivated") + else: + raise AttocubeError(f"only true/false and 0/1 values are allowed, you entered value {value}") + + def get_target_tolerance(self): + return self.pvs.target_tol_rb.value + + def set_target_tolerance(self,value): + self.pvs.target_tol_set.put(value) + print(f"target tolerance set to {value} {self.pvs.units.char_value}") + + def get_current_value(self, readback=True): + if readback: + return self.pvs.readback.get() + else: + return self.pvs.drive.get() + + def set_target_value(self, value): + print(f"moving to {value}") + wait_time = self.wait_time + timeout = self.timeout + time.time() + + self._move_requested = True + self.pvs.drive.put(value, wait=True) + + # Move button must be pressed to make the move + self.set_move_allowed(True) + + # wait for start + while self._move_requested and not self.is_moving(): + time.sleep(wait_time) + if time.time() >= timeout: + tname = typename(self) + self.stop() + raise AttocubeError(f"starting to move {tname} \"{self.name}\" to {value} {self.pvs.units.char_value} timed out") + + # wait for move done + while self._move_requested and self.is_moving(): + if self.is_at_target(): # holding == arrived at target! + break + time.sleep(wait_time) + + self._move_requested = False + print("move done") + + + def stop(self): + self._move_requested = False + self.pvs.stop.put(1, wait=True) + + def is_output_on(self): + return self.pvs.output_RB.value == 1 + + def is_moving(self): + return self.pvs.moving_status.value == 1 + + def is_at_target(self): + return self.pvs.target_reached.value == 1 + + def allow_move(self): + self.pvs.move.put(1, wait=True) + + def forbid_move(self): + self.pvs.move.put(0, wait=True) + + def set_move_allowed(self,value): + if value == True or value == 1: + self.pvs.move.put(1) + elif value == False or value == 0: + self.pvs.move.put(0) + else: + raise AttocubeError(f"only true/false and 0/1 values are allowed, you entered value {value}") + + def within_epics_limits(self, val): + low, high = self.get_epics_limits() + return low <= val <= high + + def get_epics_limits(self): + low = self.pvs.llm.get() + high = self.pvs.hlm.get() + return low, high + + def set_epics_limits(self, low, high, relative_to_current=False): + low = -np.inf if low is None else low + high = +np.inf if high is None else high + if relative_to_current: + val = self.get_current_value() + low += val + high += val + self.pvs.llm.put(low) + self.pvs.hlm.put(high) + + ### + # Things to be desired from the epics module: + # 1. Set SET_TARGET_RANGE as a float or somehow alow decimals to be entered + # 2. Soft epics limits + + + def move(self, val, relative=False, wait=True, ignore_limits=False, confirm_move=True, timeout=300.0, pos_check_delay=0.15, target_gnd=None): + """ + moves Attocube drive to position (emulating pyepics Motor class) + + arguments: + ========== + val value to move to (float) [Must be provided] + relative move relative to current position (T/F) [F] + wait whether to wait for move to complete (T/F) [F] + ignore_limits try move without regard to limits (T/F) [F] + confirm_move try to confirm that move has begun (T/F) [F] + timeout max time for move to complete (in seconds) [300] + pos_check_delay delay before checkig motor in position (in seconds) [0.1] + + return values: + ============== + -13 : invalid value (cannot convert to float). Move not attempted. + -12 : target value outside soft limits. Move not attempted. + -11 : drive PV is not connected. Move not attempted. + -8 : move started, but timed-out. + # -7 : move started, timed-out, but appears done. + -5 : move started, unexpected return value from PV.put(). + # -4 : move-with-wait finished, soft limit violation seen. + # -3 : move-with-wait finished, hard limit violation seen. + 0 : move-with-wait finished OK. + 0 : move-without-wait executed, move not confirmed. + 1 : move-without-wait executed, move confirmed. + # 3 : move-without-wait finished, hard limit violation seen. + # 4 : move-without-wait finished, soft limit violation seen. + + """ + INVALID_VALUE = -13 + OUTSIDE_LIMITS = -12 + NOT_CONNECTED = -11 + TIMEOUT = -8 + UNKNOWN_ERROR = -5 + SUCCESS = 0 + EXECUTED = 0 + CONFIRMED = 1 + + PUT_SUCCESS = 1 + PUT_TIMEOUT = -1 + + try: + val = float(val) + except Exception: + return INVALID_VALUE + + if relative: + val += self.pvs.drive.get() + + if not ignore_limits: + if not self.within_epics_limits(val): + return OUTSIDE_LIMITS + + put_stat = self.pvs.drive.put(val, wait=wait, timeout=timeout) + + if not self.is_output_on(): + self.enable_output(verbose=False) + + if target_gnd == True or target_gnd == 1: + self.set_ground_on_target(True,verbose=False) + elif target_gnd == False or target_gnd == 0: + self.set_ground_on_target(False,verbose=False) + + self.allow_move() + + if put_stat is None: + return NOT_CONNECTED + + if wait and put_stat == PUT_TIMEOUT: + return TIMEOUT + + if put_stat != PUT_SUCCESS: + return UNKNOWN_ERROR + + t0 = time.time() + tstart = t0 + min(timeout, 10) + tout = t0 + timeout + + if not wait and not confirm_move: + return EXECUTED + + if not wait: + return CONFIRMED + + if time.time() > tout: + return TIMEOUT + + time.sleep(pos_check_delay) # Wait before checking if target value reached. It's necessary as sometimes this PV takes a while to set for the new target value. + while self.is_at_target() == False and time.time() <= tout: + ca.poll(evt=1.0e-2) + + if self.is_at_target(): + return SUCCESS + + + + return UNKNOWN_ERROR + + def gui(self): + device, motor = self.ID.split(":") + cmd = f'caqtdm -macro "DEVICE={device}" S_ANC350.ui' + return subprocess.Popen(cmd, shell=True) + + + +class AttocubeError(AdjustableError): + pass + + + diff --git a/attocube_device_def.py b/attocube_device_def.py new file mode 100644 index 0000000..29c28d4 --- /dev/null +++ b/attocube_device_def.py @@ -0,0 +1,6 @@ +from attocube import AttocubeStage + +attocube = AttocubeStage("SARES30-ATTOCUBE", + Z='SARES30-ATTOCUBE:A0', + X='SARES30-ATTOCUBE:A1', + ) \ No newline at end of file diff --git a/cristallina.py b/cristallina.py index b88deff..09591cc 100644 --- a/cristallina.py +++ b/cristallina.py @@ -73,13 +73,21 @@ from slic.devices.xoptics import slits ## Smaract stage from smaract_device_def import smaract -# from attocube_assignment import attocube +from attocube_device_def import attocube ########################################### instrument = "cristallina" -# pgroup = "p19739" # commissioning March 2022 -- July 2022 -pgroup = "p20443" # commissioning Wavefront Sensor August 2022 +# pgroup = "p19739" # commissioning March 2022 -- July 2022 +pgroup = "p20443" # commissioning Wavefront Sensor August 2022 (active) + +# pgroup = "p20558" # SwissMX commissioning 3 +# pgroup = "p20557" # CrQ PMS commisioning 1 +# pgroup = "p20509" # CrQ commissoing DilSc1 (active) +# pgroup = "p20519" # beamline commissioning 2 + +# pgroup = "p19150" # Scratch +# pgroup = "p19152" # Scratch daq = SFAcquisition( instrument,