From ba9a0c7917de2cc5bbeacbf8abcde2153cfba7bf Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 30 Oct 2019 18:20:16 +0100 Subject: [PATCH] removed unused multi functions --- .../bin/ctbDetectorServer_developer | Bin 177572 -> 177572 bytes .../bin/eigerDetectorServer_developer | Bin 322961 -> 322961 bytes .../bin/gotthard2DetectorServer_developer | Bin 124892 -> 124892 bytes .../bin/gotthardDetectorServer_developer | Bin 130684 -> 130684 bytes .../bin/jungfrauDetectorServer_developer | Bin 143460 -> 143492 bytes .../src/slsDetectorServer_funcs.c | 19 +- .../include/multiSlsDetector.h | 1550 +----------- slsDetectorSoftware/include/slsDetector.h | 16 +- .../include/slsDetectorCommand.h | 12 - slsDetectorSoftware/src/Detector.cpp | 28 +- slsDetectorSoftware/src/multiSlsDetector.cpp | 2069 +---------------- slsDetectorSoftware/src/slsDetector.cpp | 43 +- .../src/slsDetectorCommand.cpp | 131 +- .../tests/test-multiSlsDetectorClient.cpp | 16 +- slsSupportLib/include/versionAPI.h | 10 +- 15 files changed, 157 insertions(+), 3737 deletions(-) diff --git a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer index 18ab1ea3b9172d94a13736549ff247e4ba92f5c8..702b5bae66ca06a8d598988c4494177bef960ae2 100755 GIT binary patch delta 43 zcmV+`0M!4a>k6dn3XmxSxy9d?K`#Oru|%8-0Wh=S3Li!RFoOY6hXGLmw*gTCqhx!Z B4=w-z delta 43 zcmZ4Tnrq2xt_hmVJF?TKJL)q@Y;>8!#i+UYA(y-xqh>Q>U^`|y Wqa*DOrx<~l35c1uJDg$(R0aSQF%{eZ delta 68 zcmbPuTX^Da;SJ}-7&V(Oh;6?h#%SNjsJUHW2BWl*sI22$1|LfW2F3aZ!qh@oj_4ZzC#`lK+S#=NH diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index aafccc72c6076e0472a53e46137db4875460fa98..b8f1a6ebdc977d65cf8cb2ac58e09b0b0676950b 100755 GIT binary patch delta 52624 zcmbS!eOy$<_y1jBalthg0Rcf>6a++c@!=z;CHRn}n5dLwmTOX4lA>8+X}c;J6&g4s zR9K6dSyDk#f@_6kMn#EbrG?4$DydPTnPHLpd!M;`cQ3Zq_x1Z@VBTkD&YU@O=6UYy z$!1-is2gv4ogy}!=n5D5oN(G(5cGo#X`)ZF9xhqbH4AVV zrm14{3B!zTVsp{1A-;ML_02`62Z!jJQ^b=e2x;*DZsBHeP_~~qh$U!7SOm#m6eL5D z<}{ZMe`_lDR3wY5S_C))n=E#m@P~875OTD_>4Abm7t9n#=0biYrN-P(gq)K3c|l5B zAxO!&g0yF$P9JYjVx)-HY|SnB^VB>+ig`X+tj-qTQjo2NvX}O0toAjvf?1GSG}c-{ zI{2cJsZNzC`L{<-7L!qsWH!Vr@)lY26mf612CkntK@g-f&;67CI!&Ryi1Xi}DFpu_ zkNnw-UORk+2fB#D11!xubyQcx;(0-7f?gM@6rSV|jmhHj#R54=6e{giwXu-iS5pb@ z=hzqCArlnYY>PFbZSfwI+z82Jsvx~D)YPh0tg}#2J+djbQY+XGZV(jG3!2%30zo<}A5T<6Ud2T3Y38YOCyG zy3Qm>M>e?GnuKP%$l2a1G=uGp9@&y6f}x4lC4$(>rfUQJ`y-xgB5bj?kLEeHK^x{( zwt-b14)WFIXhdBOdoy`}Wx`THoUl}rZWubFXoiq1rsfE6mu-SHVM8Vunt{z6kJ*q8 zyb5>~$HOTz4+kre{wP+Om#;wf zyy%{~Tbk|7wW0c;P_Y&^gLKQ62KO>Mq{)sp`+2C?AuVyVLB*NuFW+!W1tL@|bx0-$ z)oUz5Z*@?;-dHA>>+A-w9C=Try|Ok%Y^u@OUEIV7g9MS!IgV7&;7bG9r)L=XS;L{GcFTE<1&YI=87W2bzFu&*n3@u zX+B`*yM$;CGCy5-*L_(A6O@7YCN@MDJa*R$I&-1Du2z>t=3QC4M)zU3tyTl6^Ro(T z1-$`%LIz@IEUT(@Nb9eV21wSOS4acJY@KeDHW%T!Y@aSrvxt48i`Q-g-o~_k^E5`b zz%O3okH3+A)HT|`_jmT5Ur6wo`N`v*iWiiS5(lThXVAhzET2?tmwXAj| zi*?{xw=6|$Tc&}7=|A0UA1Jn8DVcqucAP0vbO?f!#YlhmJuTBy#EXb~aoIRDl+`6| zc7qZ0ze{GHM|?pVv{?zKN`C<1D3AVJAjO$AJ0(bLN8{Wo@xK4$(M zWrB43e4W0B0d)!SGaiHmcPO@8+(F{3eoluBj=bQmldeLtSb*3Ch@IJ?*y!pGD%!oz zO%`L(smDq*t_adNc1}Me=DHj~x{yPHKI3mNw^i!QrYfVjRuJd;gBGwrkVe2wV-veY z`ekMd(nh%du_fL5$Gm@^QQRYt)t#A#mVsRNBG;e)A{h;^HUpROGOO*DqS?d#>h?@@ zJL0q>&clC^WEAIxzeuvYQo-D2PZp0L{0MvNx_DomgicIi&DTw~1T7cDpydu}0B1~Q zJmoJc{P0qv_@W?4gXif?ODD^I{XF@96w%UTzt=psdVHWB6Zo0H@5-M_v*^$H>7D$1 zk#@S1-$}F4!ZYbGgXm=Vz1b-G-C&v~NFO|}bVI~A8H|&`_$wFVKmH^^n@eOtz6X!n zos4V1gM@D+nv?IFX1Aa;Yp`<6Vh#H6Ot8*eUTbqmwm+3h{rFE(-J5KhAwg?JxRtFj zg!Fx~7}^8;@V9yQls3Nv|`3|V^bE?!+tE7Jw3FU1)@2y?BxHI&&Zo>@Yt%p#Ck zgflaHyUkwC1#fP*A+JxLmGe5sB7=JO&qiJuYig=4SINcs(p8)W6i2)Z(=i^e>0y{Q z&u@^2{DvdH;jBC;#BZgO`%64k1i1UCxSw!wZwB`waJTSy1>k-!ro3LtsZ}!<}mnSReN? zQAe|jCy1+iNRUE#DQMDAft)HHS_#w1{6py4=*C@Vwe(7*a1^ z;&uhI>hlMgRhQyAqj6p$68A#lfjsd&Ba!$SXW|?r&T%F_cuBF7i3Q=aK^5=Bu{%C(y>dGh<$)rjKaJC#6CI)JugcL?LGR^azVPqnNu~=Ry)&f zyhQT@YD&8<)gf&eyVYnE(}YOz7AW=&q<@dnTRubje$MnKk^ZDJ{oR+8naLBE8j(JS z#UcF!q`wL2*Epq(f_|e`$cnl7l2X%)FHud;VpK!vh>^bHvJJDPOG*vhb%| zWszaGYsRrh!+L8!Kx=!IZ3&yC>Bey{NVbf1=@qH@nJw+rTe}e9>1;}`Xw4@aAAS(C z0>*kpdcE=()mV>yh~WQNZdGknZh37v`Uy_fzJPeYF>Uy$uo}oxv%(=o{H{ov@;ga7 zkj)C8u8ccxh8q>{;qU=Y@1}^!+Ki+AVg{QQ(cfZPiD6`=VpVeYSU8)y&Gv&zx0yX# zrssj4EH)wMCggnIMa6hFUL@mLQFIzwrEWLps`P2j^jV;5Fmh0waWc&;&E`yXxtKxc zI;61|6{E_!NJcfa=zS;Co33Ko&&l+9(EXfDL!C4e=Q##E$FS+W11u zyDW|Ybdx#dHW~fmq-r^zh2XOgvYq`+F~jZ`$qd^I?{jiJe|u+zec?=h3iNrCG4@i4 zKXMX(05MrC2Ge3Nt@}-}%~QXTZGKre*2(mftC+s*OmF9O!K4UV;-tUD`PPGPJ@^*? zrr1U8Z{5i-wiX7$ggX%2!It(3PS{k~KHqBhH%=D0F&wS2(PXNNV6|IomFWPDw&6DY)mj2H`Piy#BWn6dH@dM5wh zlm<5BH)>#^g_C_{LD{;#iIc+a74-cKHMR>_*~oJ&!!)wt9<0VT%B<4`8QN`DeL$#D ztbzC^GS?okdC!~nrwx;V?p_(BIih1W*Ef8kI{l2Iv-Tdw_W5o08e3=1hN5XE5i`gq z=eO0;63sow@dl?%c84+2&->|Qu@prpWse&_(bmCN$EHUP>uq_eZeF3C+K4`r%o|d4 z(PYrNj7ISC$jGoOE9>ls?8)M^WDNSrZIxc;x>~H$r5D)`k@1$$oB)%~G+wl>^oH}o z55<8r$>jU_wh&}tMr<=; zx3-b;D0TqP;Li;d=l9zXJB@sYZ|j`j^T@B|Hb3*4X}SzS?-Pn;hTYq!GqL`7;2?GmG=YAp3&SO18JrtAMx-&DfV4CQKIRpwFLk z)bMgrOOr!E=|IO^s1WE!7it7L?m~w0>E*(nfIZHXmZOE`hsuq65*5Nx!`A6rllM$_ z;lizlwwm`Wbzwu1)#XpO6}tR|Hk-@eXsg_lEH>55pm~>8n4on4&HGrVT*pkB&Nd1X+CftI;0Gv-s^-BeG~>zr{pq z=RE2q&S7D({WZJU4Y6~zdBAzBJT@*e2VF`X($_t@re-Y)I^)-L`*fau#joi|Z)QKo zMrxZ8znKNZ_1BDMBjV=z>Q;G)x>fA?xY$J(pMp56AkM1tnyp~)?Jvr*U~uv& zbs3XU91NOV^dERpOu!~59(D2u?1+5Ni=MSgBf_ER-=m1x$RV303=GliViN~OYI7k# zE?YFPzh)zQX5d_{4cNwh8yFWk3Gy@{cGIe&noW==?iXcHz2%oW$TO1N5Fe@SK>Q9i zKfb?LkEd9E{9W3p)m~y0`#C<&@AD_of>)yjv)+S3H1=I11|@1NgV19Qk_@b{b~65x zKfTiI@)uU-xcrTknAu=EmGaWgz?9s3%`|gu-MEz7h|)Zr{$8HGZ=AVSqw@~cnQc5~ z8z|OV>ohsm7d%$WbfjK~!BXeVP9=07dz3J^<+!+2^LSq%ZB8d{`#~vmaVzJs_OM}t z``=+j!K|wtQsK|k!;iqFzz+6g8NiC%CT zDNiHi?z77H(sY)z@i9`;2>$_6uEh94{w+K&9}C7X3%X%fULTz${Zu$pY^M|$!ze`_ z@}mD`Y>6pkR1{K1A!V*B=(^;2cOL`?CN)p%zTuz!GL~}W>Th9uI8AmTf@InMjr%5ad)^V}UKb{F4+YoBA z{%NBb##g5mIsQ0Jax}A_heZ$5OkacELf&D->DCOJ9a`pl(G5u30M6S_D|Y(%X|kPa zHhy^Y?eUpbcREa^XK57ib$tGXLm`90m*$xvM%pb@C;>%Aae=0-GO=ossd+(8m0*q( zUlP2amDkw5;j=WWS=fk3O*R`nVu)rS8}h%9*xC2etPsa3kg63@UHVCpDx6E@^LV>W zkh4%vN+WiZpjQrFnR&l`S;|vc~^iXGsFrB+hk;i)#+&db^YB zOmMxNR%2^Nmo4Wr*vaRnsqMEY6+`o@W{n_?q1fmq$lnX`PT>DgCyo3D&`#oitW2|T z;0t04h<%(9$=`vVL*7#r*URj>Qz)p!`WO5sc3LNm{1Rxy`mZ!O9{G=gM%>OjY2-hc zrU>mXu%?lHv{}$W7ITaY_WOLD+=@SDy_5P{o=Zcu>w6iJ#XQ8wTjP*QTa@bV{#fay(kd>r4Q`|%; zoH<81a~{Knj0(5t*Wv(stwZX`^P&N9G|ww)okMCqD-Tc+NKMO(7m?qeQ{?|Whz3qX zYnx&;3z8ow$zl}vMS()XvRkVa(eI7Nj# zy;f#=Vv4*mK^fE`(=7bo{-!+e9DHNV-)`ZwMAhw_RNxmYY z*oBB)h}dIKDHE8iQ)EF?*BTLf0AhnHY_kIKDiAN8E04IQ59Hb#g_7oA4W2CSMU=g~ zXklC%)RW)HwGqSa9381S!7QW4PisP~rnUQOzk&*moTQqdcz>U4My4%mx`U5y9k!NW z44sqQbgz*~tDm!gF)KBV?CCK$1ze{Q2dxvN_{Ri&xB+KP(07=C z*|33pN#L5aE=9~ltju*i!0!`{Jhd03R*eyO?i!(aajy*!*?UugD24!2oxGG(tc znrhb`FsyC2>9A{IC`u8tz$Xj2U0f~bdqP1u7G#hELYXGno`M-a-Frv|+u>^_i-pJh z;pq75$$v1)2cvwXYjiRy1RpplS0k?+FcH$EgO34x8CkqY5Of0HfOs zrdn8RR*h|qE)dmR4W@9?EgG|Z9zXbhP-6zu7IyrG@CApF^6 zpgP?~9)su+FuH2w1}7y5%@fd)=>EVAexc)Ii~8C^axUiehzciNv|{22Kb+J2H!ZvC{y$0mawGQoJ==d;uBRR%mSTBf%^~%mOYVC2<+T)jP*aKZc zGqpj$gE&60Bpo;vIF;k~m!tyE0iMJ0yGxRRbAWR=esf6@a2{|T$J>{ffJ=c(Ieu|T zEZyp;0HJ~tHZL(ELLG1&#~YV~0v`rG%<=jqv^8}a_%z3lEumF@2XF_+4=+)xXUz&_ zobVB__(n0|r0ckH&=E+(xN>}2AJduHT}?f`?t6?YD0>N4Q0{sSmd=smVl359pf;Xx zE2svXYSxp2g1CYjfg3s2a|N{mw{q;m6(k_N@C3#0SWF5E0uJK%;$l)zEO0Ext&2%P zV}QqSd~z{YP&x?doY1tG6qE&=#qr_Aq@Y~jT#g$SlY$C>3pn1tm=t6KwsE|7v06c& zJgg|l8~ajnXGX2pH`E~|9Ct|1o%A+h67u57WHId*0S?#Hp1>8gCze5b53HOlPC&z& zz>ohGMqMz)R+<_0XDMQaq=Cck92TVgkZx)UEnJ0eJ_en+(LM>SCj(qEa9hi&_s4B5 z1x1Q01)X2-(8(4jiF&GwD9Obqu)*lM2NTQh!HBD|&XtSxibpOyEf zXB5@g?nZf?eSxc2m{IgSrq@bAyj(HZgbDwfV#vpKRldg5X77*9s~{japa`G{AUL34 zpg}-zK-U2c2Z96Y0yG9_4EuOOv}M(k7|owlYzp@~5CVsIIf$151P62<&_W7E>I9hByJQC9Ks-Oe=!LV z4v^$c2Z944dFKGld5Sep3}Q7m=`Br=wMivwF@oU`nItF!f&(H6wgJHbkpvY$a6lx% zULZIiQdk2J91sa`7zhr?Wh=ZApfL8+#BMBoQV&a6F~*@{x6ay;1`cU%>yNTOjj}&Y zXc|xi5FAh{P!bRvPzq2Q5FF6;K$$>rK*N9*0>J?d0$L6P2Nc~Oc4GyE1MGvqVjwu6 z5TI>9a6ks2Y9KfuKcM|Ua6n!_hk@XL{_2P71cC#)2qY9}$N~KV6a)kZ)BCduazG}aC?GhXIG`~bH5U2<*bgubfp9?KKxQB~pdg?eAUL3IK>0v$K)yhwKyW~g zNHh;1IG}c*Iv_Zp^FT*{;DF8ood&Yt51<6t4hRR-1f+Wgmj4W)Z-9b;;DEja8UzFf z^a)Th5FAh)P&yDCP%V%d2oC6NpyfbtKs$j7fC?-eZUZa>ghSvKph_S(pv^!vKyX0M z05t%?0p$ZV1Hl2U0lEkT2lNP#z7WbUB=jIq6c8LxHc%2!QlW+5J%DL|a6oqfEd+uC zngz592o5M6s1yhe=w_g5AUL3LKy^THK%;>gfZ%|J1Dytf14;n$DT2usX)J&P07C)c zfcgRr0)hhy1sVec2NVF50R#u+50niA2jmTu2LuPyf$pyi2oC6Xph_S(pkIOZ1HqXr zZT6o4n*iYu*bHp~rwC zfZ%{u0GWW`fM_}}0SFGrLi2%4KsZ2}4`c(u0nvQG3Iqp4^MPU@I3Su2Q~<#N(fGO_ z2o8wG*CRl1Kzw`!YUPMVH=kk%T1;UBEr1b#aDX(tnSkJcXn30d1P4UJn;8fWh=#Z2 zKyW}byyXMI0nvOw-pjKKb_{v-{Fjltxe*?<-VMYVOCP z<9tk1Ln@<%X6J6|DfY0?sLMa#zlTmEW8OJ5bu zfMYAeV}=%^ina>0RiH(xXlKAX1bvzMn$W}c5L+;LrbiaW}&7Lu@+ibYiNm6MdZ7OpwWjvO6zDuyhhOC zRkR3f^+c>Qvf;{spbb^gE`oLuG`ba`2rVy$4K2e}w2N3QU3}8eGD5)ihZ50@8M*l>L(BhE z5!0W>LiuS!%SaV%FKBx~OH$D~KfZbgH{dN4JumkGq_pyjG^U56>WbJPKApMEn`(QpG{EpCPPcIik1Uf4rnPV zS~F;tW)R1zh}LJZPxY*!WxR^k09pfR6I3+QX0+|ihL(vcS}th0pxvaRjVZz2Ly4hf zl8TlGS{`Vr0@mV+`rANk1My~6#5twd2`V+TOjgl$Jdb*R-q12dMaz2u3|}y`q^W4S zGV}{&hL))+S~_Uypxxr4S+E-f;$aY{xrnHeEvS+$hL&^{%?6qcwCO6EPdQXwZfKdI zqBXvTR`QymWu}T|dmU+CH?(A^Xzif2TR^;3MXcY6cD&Qja+``)_zE_9Uoo`IQqfYk zW6x~6p(RsAvw>yQ4vsftz)T0LmXR5Zi87>M3Av^=Py zm4a3Z+Hw``HlN+F;N6Cnhg8HG&}u+?SVfDi!JcA`p=E`NRt#D(Xt^p{L@ioQEi0Wh z&?4`L>9A?%-Z^tfwSUmJV#@Yk-e%0$Hw)7JSqjY|UARcQ&2-um@;mJ|H$Lc`&+!Ag zn##*pZ3w3Qf~CtZ>RoakXx?P2N|$Ra%OcJS)JZIy1WLNwcAWp^xa1w4ibc{KukrIScVcW z(NOZwSij776_)*$84y0xS-^$3(5DmVZup;=C-U4`-`k^AimchH(}x=9=J=oGqqj~% zPF>(`5{H-g!mZv)*9?|b?W&?LIfEh3*7+gEf5tW=w%J4Mr`>W%fi7(&`EqrgXP@3~ z4|hD!Zd1PWz5GB@dF*xcEnhzR?tJ#r>|o2I%V^*9`o%g^4NkzY-BE(=j*_9+rmcQJ zy;FSVek>mlR#8In^XJ>_y^Zbg^+rmg_>;G8Mk79qX{^=wcL`ln+iv>`6*hfw58Rb% zw{3!d%3>>SP0`(wHy^Op7S(PA?XUXpJjnYMfhsOs%Dluf-PN_Rn|UM+ecYGz}&9heOBsCQNdjg=*-RbZmv2Hm3O82 zhtLB?$otY40u}S`femNH@b{ze`%47r&bt+wg9XkBuza)>$BLB#K60zEg_-G^$na5a z^Zze-4F4j}k>OX%V<>V+cl@qyjvW?=)d8{eZn31|3rc&ey+93T**`>-l9UzKpBnde zJso2zg;Nw(mpxDn?I@W|--?gppUmtA#ni4)5_pw5BgxvFj4!J2m8Z0FxK;0Kz$Y3P zl3Kc6>2Jih6KvX@y|r>XS$b!f<|+2{onZ^*R_iJAyR&gJx*lJRuQwF6+37k?Tcwd} z+K+46tP}$^@25I<@Wg9OHf!71)5~`_i@IyT(1A&HxK8M3#d8=v*?Z<2BAdXl3Bo@0m!ehbu^SAPP?;7g z+rh%;g=1~-Rv6X@g6vc2HOi({ViHsMbR&nU6V%hc5rg0A>} zRVEkCDfbyd+Ne8fWL@tLa~g8o-7!w_$#7zf>a3>My0gi9&RfiT?vtx>iBRRTjo%-q zPVZBGe|+s?)bzcw$+z45cuijzk!(-q^~3K=oc1Tf9qt_YJXvnTeFA#C_W6zWX{LP( z+^2AxnfLsW0rKSBA>IF{Q*1V6eq`cvBRU&_{y&W1LAGUnxMg&r+&KRFwa`As?!k2Eya;zEe@_(&Tr+Q|k_77=eKuWiPa+?YdbB4wV=|5_5n zLW0;A`ibKNLF%cJ;p8t$lkxkt8T>v(U#`?U=4SCY{KeUT$AS3V5dIy0w+n%{81XpA zaAv-DU_dsOjM*m|~0(Pm8{gTh#uTcx4_M@af9p!0XVVsh-MMp7BkJdovs6Eg|EK!7Wr4eXB7RW@=#*dD zpqoDzc|*&UuKM|SL82vNm|9<5L#LVM-AhxiIVKmK9y&m6k#;{?L{j*WEYf?6TrreK zV=z8;{SWKAZUOZX?epujN!Rf5_iTTo$(NwQ#~rR9+hhS!znWBdtb2S2rBSMrwZJpgwtak=rqW1 zV{u1e(^sydV$I?N8Ox#XGqSG&Y1&MA|Nz}hpse;s2sshcTNhYgo3Q3sB$(`-e zq3(WAIPLo%8cbt9-xqF48|t1_sAqqk`sUbsam#h6pr3)(U3SzTjxHueU8Ai>mEkz3 zY@BF2>IElAad#+%bVybFBLoZ`7U^656~Z(3#~K~d?4Mj(xu$;7z&5SyENa?*kDK9> z{3`?+i{9j404%uQJye1jsNB{bNN{aui;K}UVqTZI9UGe{G(l`Kx z4n?8=|Ef1;w!1do;$KxzZ5+1n&nhy=7EBL1q z_uS{=1Pj#TlBKeykt_S4snM=AQvbvJALyx??xFGug0$Hr=)0l?!W7_?37tdI z|8zCm7ff<(R9_Egwa>piKixi$z4Sm|P13Fp9*EQg1ZUYWr}S~n zEZ<}27tbFfcLg-tQv}3;6KpEKY#BO&yH)FElk3}sTjg&T7P7)6p*P28Tt9!Dn3Qq> zUx4C!h%}*F=P8O(s_|k?nKvAjj8cRO8q6PYIV#hcF+0B`Q1dm@=Jc26i@OqXG@8IR z$kJ9eP%OpONBQF8K9;idap#os^QB?kl-X%J*tfIuO9Ok)ou!n;A^r4|(xK}42NNH& z$Yta2bC-H+?XFr=ZAz_s$3fmh7${~T#|xFis&cBT_^tz83k_6peu3ZPC(Eeg_xM-d zJIQ3mB$SpLx#jY5;|%*^S@;w=H%}E+H;+EtrOLv*3FC>Vns?^M$+N4}pDOJpWwOkM zJvdSuy9GN|Y{`QmLkkjA{qFx^ZFlcHTAgW3?BIjJn(^$^gVEYCTfA}6s{8Wb-sxbQ zzQrN^etwdv?yA9l2uoQW7=P`8_|NM+X~tN%ysxI7y|g@1bB^s>{%;e7&)B);!3(|^ zq*yd{?SUA^)syhtSdvL+ip+9P%ooSHQ#kvw)8YRy^c1i~5B1f|U{61^KvTeed&p^P zEd1f#&M8voreNNJbJ;Ch(G=QL>yP*O6>zG0iQfP(%W_L1=<^MAXlVXeytT2XAD-V` zHsM*Oar})TiT(X>--)s&J9kDV!&23Bz8LjVyk($R4Ku8BP3g%9-^ox~%)AwWnsD~e ziiEk3#nF60cnNG20Vg}<(#aQmh5GBPVlYlSV--^e~2xY8iVs6Oox6h}$^G(1_D04QyJ5LLb zB7S#%GRmyv;>v+}8}ZiDK(}0V*gUabW&5wP=_>;hu5J5k?{e|O<_pb{X0oD{!Io76 z-SyG!KkPE|uJ-wrc6tE~(^r)i`#H6ELbBRz_{zVLb|MA}`UlXB;}tJ&o!_WVlOWaI zR1048!@FBBU^r7Dze>;!1P4S9tSP&>!i!#_@S?m5pe@LuGu{2?9!cpxk4rQmExnui zBKHMYbsn}(d33ee-^R?<_##d%*jtYTKk(q)ZavjO0J?L&vM(;Sn#@;e{79T)pVSwG z(3hFgiT>(K;NDRRYOJMJB-=$D_w$-!iI0Zd>}+MK!A%)`3-7$z#-EL&Tzmz0ovBvA ztmx5@B*iNEW}}pRLo@11-A6@7Q|-%EfBr(xDw@# z_8F)REM`^j@SjxFU7)^$ukirkU0(phv`N zY~#>iYgMryN9-q9)vDeBTUFG>pysgSpgygl&I0vz)@^m~faNM`GN|L&=+(U~cdDpy zpvD^=(y*_uR>Wjgte%J!3X5?!{H`$Ae>Oy=!ebRJ1#X9V+ z)3bv~u(G5V9g-;0YK1<|@jXE;@dNliVSbOr1pK4@vXsZ-{5FY=xN(E^5qt2lI1h2& zcr4K`Q>^51GTBca<3w5#{rWiL^kH{cJn?zfGRm*HxsdZ|X5V>?6JQepUvOJg0vWhja9twYIO`Kod z@kVSuV2;B=)<(ztLy5mA4a#da&0?@|i`D+~Z2sD45B#268|Qbgli$7UbB}Q}>w-1O zEM%Rh^i$WxY4mKxx)cw*KV28+_vMdrWq!&2TIZ?IBk~gbHvd@1%d?p+%JY;*IpUa| zam?&Hk8!#^9_=^yM>-vGNQ2qv$35{``golGpT}g~{dt;gdpzo2ls6{Rt-QnRoJWSy z>l5&t#?1ATJZ=G}p$kuY@$1@lbOFkdU2B@V8()4*S;aqhjM~MFIXd2MtY|k@v>WSb zr2*2Y+r!X|w_NZsQ^Mxu z-*AI72D>_Sb3b)zIuL9{Sz1w+2b+|g!&3G`{>}GpAQpvor>-J7WL>t{RjVt+juHtE`R*z-0)()APc z!RWEwBR+ld!qCbcb@a)L&pw6M9Zz{`2SrcCS?>R#&OROc!}5v7dy#^EEDX#cC4D9D z7LOOLFL}dp^Wx{t4(WCGiXHV9gZQ+ANCWD@Z*aA0q_tY_EXMYp~dyud9hPV+?C}(crWq}(#rJlMmZbZRRwKT{3D$>{*6=`z8FSirF2DZ~9 zzf&9IFm`l*ruSUA_Bt=+RJ$6g`K{@wqVHRelD@CYl=XeKPSJNE@-OU^{~Y%8Gw~j@ z`^htLmV-x(_H&(P$eCy_rFhzBpusAJ@21B~*UffF&wz5RlY$*KT$8r-6Ym%BLFf#( zZM<_t{&dwLeSZW!hs0*7`-~{;MVTx#o4yy7S)(kVB7e#1 zkSdSlfa!gmm|6|VwbN^@_9D9p?dP)HX0Ni-?CPSOCY@EaI5+a^hWDBAUpEv-RP5J6 zgR@5=?YnnXg35ixpz^h~tkzarb=AAv?@m%g!{^dRl=a4ZHnAu^%w3aiUU}e^$DS+- z50ne!khDjXS{%rB7bW~l>m5A9A$`WYH+gEkBR0kPm3}981Ep-iCQmk7zA4e~uJ0=O z*nb!MVUwpmFM!>tF|Z{pE(9;FitXj}430zcL#ir1H66^}Vv)X~Tk&DQR`xA3-r97+ zh8H{N#bKpF)uua8jJ;Sgo1Qnmd-`iw;SSo0uS~Z(q>sO)A&9#5v)|UC=3c&apqSi7 z4=AUCbt;=u+`IeBClp#HXqjw9aqrj-Cx#nkp7e!qpIMD|C5{zwtXse0FFvaJ;zpxZ6P^kL$1iKb4n+MyUr_VoChJNV&`@WgfGX zc#`s+k~qI3hh;N9!hS08WX6%DaeiB!akjFVrJlO8XG-JxE;?+m|LuIo$qJoYq4S3h zE3f%H&%P_|t(uQ2rNNgTFQW^4`FTv&9=k=M;y~lDGF@AGxDw_uaAqx@S15uGQ}!yB z-+50=y+Pjuo=q>G1&wiG}%1mt1VQL0~YK|r7pG2>yG1KF&*g!b@{=x^OD=77bVZT-Zl=)$i| zRp<_>0gGiE@1vH_f6WFyKTy?IQs0OtSyemH72ABpifx^L!=USUH#7FN((Bc*7oJaW zR)nVwy1i3rfk9n1ZExWzDdhz9SZ8&6*1`%^0VcW%aR1lT!u!wY$F%?@4Ch)M6nnl+i`(L**Ac~koA$jRU<^Dcx6x3Hxz23i#U zMToO2p6*JhDYwO2VPnl`X>p%i`|x`eBv|!I4@mH$N`mY|O7~E7h`NW#={+EU{0L+~ z`HXUn$#9#%ykF`+)`s-9SK2CR0IN>MMmLmM^NM^*G#RVYq(jOo?9M~fR(qy9PmshW zq-+ZM{apk~x*V^U{zQIh?}epL?jQjWg@~z7NNPg!^>eo3L&+QfYbXRWc<%Hu4?2EL`KABY7T` zS~a|kS+E8DCXVUh@EIPM7H_|R1@U1limFkJ>g_2AL3JNRw{?)-pwq!bKRRdy`&GB- z%sKWbmyr|_I~BJYaI4wg3ug9)2W~44(pxJ!Gv0$MJ6H&Iw{muWD^_sSWpkaFHi2o= z_CF!wIuA^z9;8-8A}%{fttg)J{MyZP>x`}3j@>*hD0c^#c5LqlNpJVSwEsbB7{oO7 zU?rGpIMdgR4#`kw(7%jXqin3{SC!xRszx-vN}>+-z_tBL8aR3RdmpR=TfCkIbw1{j zwec!;$zYfKDhb)e1G__CQkx?oFMZhvZf|jJvs~PY%D<9Zu)E|ac-E`mt$*jBvyHq^NiY!#E0Pf-NvC}_%hPzqDx(J`z z)0iyo$JZqLU&WpwFBCoNG?N!fKXr13^I8iH-oYqc8NcKruL7EptQpAyU2-RJxzD@a zSG&gj3byZ+=;*^=G}`~iFXwfSC0*iC6@07`w8J6&@P*PT39Re(un^gX0x(0>=={(L zC>`AB?Fs*~ciB3LMm;6&GusnA%)t+BkB&}r$?-&tEXQ!jF&uKtbjgv+!e3S7nEnqr zro8%Za%6Rqq7TOaS&j_IkpVeAZ&38n*1!hs2z4r?=pTaIvE$za zX}U?RkhgYt66E}j=;$#nK~^{g$%P=f5M;bdkcDjYYl=b+{X>pLul<`G8J*<#;5AQj zXkL%I;qA|@_7vy1Q3eUhAi>_x6;+6zQxkc9vLLkw2>SlGm9*zCLEl&Da@c~`W1J%s zd)?F4+M(Bjo#8)w43FCx*SC*Kg1wMnFC>U{NidZy-5KWO@yt#oH~Y?nA=h5W4VtKI zs4HC~-hO81UJqe|D|&b^(CHO%@S^=}(m& z_*>E}`}KZKL8S^$%7}bJQO4*uJcX}(Bd+hIPu*e&ui@j|*Bp}I5+j=JdqYvi@i!D@ zbbT|ybZuq$O!$W~@X$4Dd%Y)n>`hPFD1S40YSyQ8ai6-2SO^gdA(niq=%V;j(#6zN zjPKoPcNk07%L4Xf6ekLTleO1@}kA3mTSGH z%HW}S9IcA(Q~!xlv<4Kd0Y&@z6QyYFpRkCxBWB6D(4eI*Lo3SAiZb+5mErYIsKTfW z2S1@QLP4q&%7P?FD2NYBA4LZ8eW37w>_00U{`d^pih+br15p! zNq8O4wR173a^`R`f^VXIq&s)T{7ZIsIkRg&#CGh8@}R6^$m+lWC95&WY7DYEbU-oD zO9!aLZ%xD#&@8U{-0>(9msc{y$g3E6m3^$}Z{NqHzekYQTE;x``1IX4zgr+J9qix2{(9Hb2E&Nm z2{U?rY{iPHuC@^K)^d7jP2UBJhZ^Kq^LnM-*N9Wc*Kz9jdKFI7_Jg|r^{U$QmGns- zu4uaCN#ydJ9gojD53=gro=oD*?gYQR`{h&ny{vDICxLFSiSt{(Ulw{jd)i~1k89%M z(!obj&S?mB8p@fyUr~-_KPe{(!eAGo){}y#*2ekio%!gQr8Z8rf5$(oFk9`TUYRVG zV&PwkZ3K;O7&>d8+|8%QQ9?vnPCtXa0sx{0*J>&jJ5APX6?kX;+0m+py=3Yw$C6;%Dr{FAx0k zoc#KMU(Habylj{~I&hBUFV5jVlNtgOX=p_c$QIcXv<5WnwyT1aJh$I}%fY zO~59OZHe?o;{@Od9G5000cQeda$J~5Z!~5DXLFpN7;8+<5Un6sIl-DpZ!{JI7jvAO z7z(@tcn8NhiS$O}Uf{hPFHF<{Hv%_uY)*6@uCtx*C5%dI6~wewJkCUQ(%Mh73b-sV zCRr>Mkl$uAUbM~Gqv#*^%J4QUzBy~fy$KfZ{>W6f#{ID5(?coxora;;|8yL`9Wfd9 z?GHB@KaWAbFCw>%5IkZUYNEGrai8J_Jf-yp+QA#F@cp6MG>DMKK6yXd={x^^nA6w& zgZP>5tU5KOJzY?^AY>ebjQt_1oJ~)#FCStUO4)6}f6DH=F?cT#*$sbVoS5~77hcug z@WI3-QFvS+>P>ge=HZotyf+-uxGVG{AvD@9xMF~1>>qo5B-Db?QiKk>LXQAbXyz3o zLf;u1k5C&zZ3vCJV#3!#6ngU&6GFF-jX-E6LMvHHU6{58z8W?czB>5o*lPId;j3pa z)P-3Z;cEn!qkk(u9&qJvE4bV-_7KW?1ffR|`q|&K5kq;L`@0aKX=6V`=t+d0M5z65 zWnZ%SZyQ2y7`qFhZ3t~cXvN>kp5dXtD-k+)>^6jUAhhER2OG98#McK}@p+S_?+f+S z!>fOjErvG;-k>*G!M>-$G9{dhNwk&NwM%17>@A@trwy?oABK$lXS}3fb^>uSe_@^vN zAJe`--N*2s>)loI(J`-UWGCMiQ9ABqWY>u78d>>)=)r0Mm4<+y;DmsRbrQnS9iE=h zRkDi*Vy}^jxl@_UNRo^s$?WD&hILBe&SYt)OqSa5NLM92()HRW=b-9_-t%c!!&IJd<|>^d~NWxF|i@u*YGyprFfh5 z_#$090p1C0!51-FGkj*ozKHjC&yCrb#zE+}Qs*z)KzHY??%WzX*+L_1 z!3NdX*w}+H&QCcO9bBz#ecKCB$r<`xm|^Uq8@cxkZ?lKtx(a3uqYP-7280-R zh=6Yb%nND}r|U4xNq7o+tT+uR5MSRCNa1*a45;_Ke=a!7E|Z8jxV zkD{5j?&epgU7xP}Lh3ki;Vv&cfggN0u74p?!bwI!UX5WxUTB6?n@7-X_#Ft{!R8&F z?^_Qo)bHXyPVVy#dc=3!Z~2G|d3gfzvrI zj;0wv7H}5F1<^DEke_@ZetFR}11Lav0S{jljTwMNw1HsbgyqpR1E>bB<~Tc=W&riT z^&DqK(+r>qxQXLA(KG{S18(CuBU*jEZf=6}kO5z|DcU0)D@PCV*Hi4*Z-#1zzk|_p zSM;}|HNIK!X1&8TW5Yu-ws+l{*#=E*dxuJLR}^VxFYsQDZ;K+$905MU@hwrLnO5Ld zj&F)0%?RKpyi4hCj3Uhh0S9sXzbMj7EO0ExgQK9C3~>wyV>n?z6lo?MIGy7@QKXqH z;4F@NMv-Q6fpa;&E{Zf$09?SaFK)=oAHB43{!g80GB^@f{4l_63Rl_Bxv~#_ z=pScA468(sM<=19P|#Vdyo}fNHHftV(=c+Q03EDr(=cr#e2r{;(>!0pZZ!Gbyn@nd zFvqKLS5P`0^hw`M3f>z@6|@j|A;;B`R6%*bc^p?nQU#R)mvX!N1JCZ6W z2{?)4tVm_@`tq@L+Et*hV(~x52WQq|=&5xVu@E7JY|)S5+8X$3*wgSe!`IAq{uu77 zLu_3wYxuF3)&#GK{rqE`maCS99go*$gO<&1J|3PRS65F|oLo`C@X3`=-`~hp-vd5g z@vP{0LL~Y&(T1gN`W2eI(XFqCu2|8td^-e-WQ5hQX{ zyF-$3wCa%Z9hk}?&Pf*29OM-T3q+Lv8|Y;<%#^8FD*tJI5FMkRj`l zUT>%Pt$oOljlf2ZPxc{09u7R5}o93SojL$-)>K$yb`4SmRvbAWR=-rt7| zIS)9GzkV}C}Ij-(QhFk$$!Er?&bsxNYfV;yWMYkay-M^U0-=U|ywp>SBExS?j zjhB_%S!ID-WpXXc{RdY$TOtJ~c#8kqC8`!Be%<&Kx<^g6z^bJF56G5dC>m8xKg29o z)^mt2b0Tw>?IWP5-4<$kI=L&tWa~lR8D6O3QfI2iT&X(CyN&11Es>?14DRbm#-~(q z9y%HC8?+arz+SffWTw^xuZek|vS?HH(w)60PAz3gzs$g|Z0toL_Oj_Mf$Ze3L0;>A zXMg@Wh;47l=w5?>8vfCo9L4Xa1SgHkBhx1SG%3M`cs7X|{5JTuNz~wXz_){^t$?pW zq7;?zRkGTjhV^%+xOTkmr-x{(kpe#;c6zikMW8DW(#=(AS^4P=|EGA<&nTQ9Ka;3k z2*oU9_A{$}tx$}0FK;w^-^1|xp1aZ1AyVC5Y6KU0QKLBme1zk(y{OS#1ir}eiC)xb zbV#pzkK%vdiyBP?a0JI+^`b^&0yc5{Subid6M!dh{9!LNnhY@$giKD@(~BBSHgGn_ zZ}*}`V+FQy{CY2HG{wNh9B=JKjb;b%4vwGirS$$Ie=h0IHHvzvvE}P}VNxz*Ly^Js z=K{a>-y6KIGZpbAQv^^1N0?K5zl6-FL*3Om`_=vM?|1gA_3+m_`_%^c8=U=WBm9lde)TZ?hn@ZE5%`brewBU@ zgxP*E`Q{_L{P%f9?f(G1*$3{5sz?6y?~~#Ogi%E`12=QrCyXkp1Gt0Zo?%o`2BbH9 zK=H2&ql$_Gj^fxij4CP#IEmvcp;S?6z-b&`3gs1L2Eoh;zlKspEeBrCaZ4ywR6cM% z$3KQrMU?@Uar|v4Ra7N#CC6W)I`}+_9sD(Tq^v$NbJ<5D!}#;m1xoX(y-7o)uhnJ%(@ z=fV;dDVl3duAHfP%lT5HmaC8&Ca*x&wQb1wCgjkB90Yv=RvfxIw1qlB`X&}813#Q} z5dKv7;iOODUk*Q<^b!0v_-$-;TZoqPVb8Tq@vW}I6X|uR@fgcK^z!@M6@C%1FV;~7 zmW5D->k+QsN4PkIDm)fAmg9mDs_-$uV>r$Wp$bn2PUm=42vv9%a2ChQL#V=Yfpa;| z4nc*BmI4q8I3X*9D%=Ka<9JR8Rd_XUHOCntRN?i&^&F>#P=z-EH*q{6L_M5M>+4)R zVD^hq_Ct)aAL2@9jFXCQ?uninfq+y5Tu=q@X$I&yEdIij80&}V#y%V;HcR;7TfW=m z7cx-nxKc8kcAj>{ptC^SVz%YNh{$d5ZTk>UjU&wwaLo;&pEwtAz6U`OhM(ZQFv8dH z5gN%yZ18VUlbR*8CrM+TVaA19?9a&X|W$CtpcZP(6c|nWBk}8YnB|+!Yj(nx(!zv5$DTjd;{cg=a>iX zc^?T@6+IN`lDH< zwF^kj9lh%y-5?JcnfyNd24?1 z)i%K2ushgav!aKu{$qbp|MBik5gMbHHme23RI8 zYpvTRb}?bdEcvaECVt|!iQ~kEV-$@dc)?GB)f4X)a1a3cwuy*35tHC!lvH=p9}XKQ zSq7GdSY1qhX1!QlGQY1TQN>DTLkzFYN)J|gCo9UHSRr=F(Y~6|VaB7rBAjum*zagJ zxQEaYY{QYwwvq&+COj_c=%vaordv&T2d3m8qp zK8>tdVisab=K57@c4a?Jysr-m2tKd((?nPX;o8>lqj*T<=miYggK*(*I9~5bg79Yy zM$sZ*BdEucp%a&oPAAGbotPz9vGDkzqf55|p|{skmJ?CnZ4;lVydSryWl=&*lX2s_ z+NowL39nkz-tD;HBujwW+C8zq=24C1#>z2+XBhp%X6Y?MD0QnvW2M#?*>P!)i!2idlUOeGy_{?u8nw zL@uFkPX(7QI@3(%XYPhNo)oQ#(VjlmO*~!lV6klk`n`9&Q*t+VH@a9DQ z8T5f%wvvW;iiiCyUW?%EE`39sI znV@0XLhvjsIhde%LYo9{Qpp{IHDT~#E>N;^uqMWmd%#c3J)koQLh5rG-S8l+YY{K^ zK){5XP5EYxpEd$d$fUL{(D~jhW+QI)fylQnFY(JpY`?!l@cV3FHRnL+P;71>T{hA^ zIeR8`nFmszMW=bdZ>Zt6qS@1*)n(iauK2Yc{M8yMy`Vo3vaqD@5KTgG>4C0d>48P2 zkF#zPD-Q?@wZnbI%H8vZXc9FuD^c^6$9#3M5j}_Ax>c(W4!Y4a=^l4;xkg6>YxPAx zn4(ECY4z6yO+s6D>AU2VNt1ZPzxHEDuEo#Z-U=2qVBxFxyNbokL`~f7|Hb0>y~HE~ zOuW22FhM4;B5b^ELpSrgmO2=EWtO^_ZxS_$P8*^oU|kU6>_A=3v84Y{O@Fryl}sC| z39+~vo7LGVUESEIp;3dQrsV2)^*5p3mA+HxHa1jN?>K53PCnJgJT=4VMcReyMU(aJ zp~1#A^K}2OweydwvdZ`UcWobZ>!6WC4jD(0kV}TN-EzHXgd9R*9CVNvLnDX0Uexjon; zc*5p~YW#4;&V#`;KFe+1_!WOG$E{n`GW#?~or@N=jDEC3j~Gpc9sjYu*j5#rqb3>F zo5mIv+l*ztjx8*<-x7YmYTHM~ws5dwjC~zmkw=WFC6+NbvyLgmZ^sfS^TBkhwqJ)@n6g-63`vk$3Kng zvw2N=E=+ea+^}=$PUK@XU7j#3F-(~9Q->AZ{^(q zEtcOutzOYh^8WrI1J@qrtIw!UmX>$^^}AKxX>&qZr|mZ^aRTd!aTeS8sqIeFLXlcze~w{grj<93=aEmco0F2m%qPTN4d z_ryl)A;%RIFcr<)6=0b1OT2L@Y^dV-ETiOq&#o4uzD;VO}?@cAO6T=mi_+fGxf+{zugafxy?HQ)az3RyPOQQ zhm8gg<78IxXQI@j7O!X3OvP#w(B0fMzK+?(x{lEO9fvLc{*I%$%Qo+V>5<^Ruw4Q6 z6P%e9GCuHZ>1|(~^|svssmkW!67#-5^^#pE8A8nymZ@J)v$t~mu=0Jgas;uO|@uj z`{&&o%`XM1pM_cRg|$n+i|M^<+1Rg2>L;eZ>sPz=yME6Mdd!}wN=$E;?RQz)mI0m1 zuP8jCFJZr}We&T4L0f-3OYnEr9Q_oMF zWNmS%VasoRXN6i}H{7D{9yWisLj89hCwC89o>-}Vt+Tt*BHdTaZ-uHgc7r?)n!gR@ zgFGHPd6jzh-s7rO>ZALyVQT+B*iQWKFtvE{V3*Xz9n(|fPo7tw*bR2s9>08E{bl^o zaxq-}PCf9!Sh1RA!S^hONXyRE>QQCqe|B=Wzxm(`>TSC~9s|u!N2q_|kqaI3OA%`B zvWT-gKAPMeaaKfEsn2_u{lWrJW&+7QT>+>eCKUhv^3VJwj zm67j1ZxhU)MyNHjQ_nV5azlOgQRDWtKG(kZVb9eceh9XIf;B6bH7nP=bd7qd8mlgMQ82U)9>eLzxmr2)f~G6joea*Uq@Y!m*+C#?e;)EaX5-`hh@`WH3HZlYKxcZ=2R7^{{%8od06 zE1f^sCfN8Ph70+hkA*C+#;QI3^Uu|bbfTN+E}C{+WES#5erP3Hhc=;YmIWWEpDL4o zqe$$@AFHonJlqVY-+Sl!pQL**-#Xssqr`uZ?!i1foBpoyze(`_^}XS58X9|&L)C*7 zuKc?MKYssU+W+dg=KtY=3xE60>2E63?j;zud{wD_VK=|8P2@J3_@&4U%CW3EqFz<=w_g;=LdEDXI)%=o9yEk>?Q|=0MMm?Dqw1;YqnAXq4iS6gh@3kt zUKYj2|1^OMs1Myn6E9;2az~3$5L%5kpe^RS8rAi1NGCo+>8KpFSa#N`7j*L%^^hE` zMjOx;l!9_lDLRTyqYJ3dGPRzss@K}Eh)z>IrxhWEp^XIs22yz&7pu{`mK+U@j6|79f}ol0WR{pWu3=a*Tn z9D0>FTtzlMAX{>s`CONJY_5Y6;lJ@@efN^vvfPuc)bXU|)K29;p}tF5y1!D>mHBd) zdi>Fluaw-E^;0EdIs?s*TGf*}=iBBWtD2{x%>QatkL#TNk2%MxW~o&35v!W5V$EOL z;BWr3RsAFCf z2%M(hp-WL~`E5gQYx^gN3vsPvN;In;s&t-VcJHCeGV?Nms^0vY9*P<;?;&Itzfnof zSY1Yhm_|iCCz@I|!Z~MDQ-R5%0#h~hM4PB5+BG%ngs539knpUp zH8q>xxi@<{bcgd`BFumVut-yLaPypL&;`0_$~91wYY1Emqu>x6(bVHJL_O}TDU(~X zD7Ooma_ff!@Q$dtdQHvkh1WIZo*~M;0G7Z*nlfaIG8Dr@unOK4wZL9e3moB07!5bW ztuP7Rgts+i)I=Glz?Co(Zh~7hlQQP>P@<`YF`^d6!z7pt%V9OdL*6<~`Q?c6%ZGLF zl%|&IL@k{N7ePNrg-f@=qmcLh+eP`O;ZXw~<$Yi%4A)c`4G5zFVKgAD%A~1RQboOz z0}COBY={%Jfr2)qz;s-H3fDK|;%T@Tm(31<%V9Fif;F&FQ*-pVd`uxVu0~*E9`?eExF&QKTNe_7QO9hcKUa<+r($+kL{YI zGw_@ysZ}DW)tcDc~cX4Q?E(-7QP`{VI4f7iRrCSk+;G%d5aCuTLYS8B#C4sYw~s!Hb!fb=`51z z0`I`Pn(T@d*%hbBZqn^0-R>G#uSqrrWn)mb7i0iuV|X@(^RoxZJ`HJLHVw?CVc9fn zkCVtAXU!yg{CEf;f)?zd1v!I!6oxg)Ef>kHf`oGk=LL%71w-QVh|j+(vR6l#4^G~Y zCVTw}2NEB_$03q%3*lBx3UWmX3N(2qTI8J=O$uE^3f&-{EUY$Z^6oT|cc*Jos*b3L4=eP4{|^nY#)XdV^}eU6%$`fd~p#hfx~b_ll_#lpK|sW z!eTf82Q?|d;1UxSmt^yhONJ~m}XH*#6kq{)$V zkt3O!99_qEe!V7^C=p9EjAg58iQ{1l5nDB>=@F^v)1;O`Q_G;K^I=!w3u$>BEk8CQ za%@zS6MiBm0yJqbh%|U>a*9E9ia~XHBfFhVupTyQ^67MuPiMf*aEm6N=|w)Xr~FpR zZ=>8GwyJfsypBGpqfhE5iqub`f|XPdMg>&VKt&%jeLiOToKB$NM96eJ&2;?Kg@WB+ z5=^Fo8B{Qn3i_zvI^{BU>KHr6bQnI7@|jKbE|4y-r_1Y2SW=HA^;XymacMm+JuV{0 zHRu2xAr&2`qT>eW4gFyt429t^3P!^?7!Q+RGUYW=UK0(%11Io6Lktayg`{gBovDGA zG|-ZUemI~>BOYkP1C4Ib0|vk#NCk~l(6|k5hXt?**1;379dT1nc-RUV zTxS_vpSjY9?ywcMY0|om-OGBI39}&vv|>Q(Ay}cw7gY2G6@B3YePI|}4Xa=^q}(qk zx6Pex(>xdmgJC%|Rq=r9+i-mw3EN2crC#Jqd*}q6p$GJYRPZGgd>ITwU<8bWF)$V; zz(kk|(_tEcP3ph*WU@1W(EZi-wQB21Td(4`&C%>RxS z9%UFEb2|7a$=m~wGFQg@xLtq4qgfTD{Ccs3>siB;DO**G> zhMx|Z)}3LHLD;z&W-$Ldvv{b0hv7MR9y0GcnfG0uB3%Yp3J*aRrY;tyu0D8O6YCTa z>ojP9-Y^_SK&GFS>1Qp0Wg0(65^j*-C?`hIq=#@1;T{t$=%EEY5ikN8 zDolsDumG09a##cFVKZ!j?XUy(!vW|4JvF)Fz;&UcCcUX5z3C9cdold#Mv<$VnE&4t zihNV7$#tgDb*9nvNEiiUVH`|^NsvCfPM=*bfJLwzR>6AM2wPw)?0{A{00-fy$hV@& zxAxG1a0v0Cgxd(WGyexzSO!>F2I!Lk`ea}$+y-&=0It5lAiKdJyFrU@(Bd1za72@v z#NQ(Up^o8XAp8VfO zKvN_SF+9Y=1egd@VLHr(1+Wa3!x~smMI%%+O1P774`j*xo+Wo^8pq%1kOgaq1#5^w zIK&_vVyPWsi5|kELwIzU_+eW-E3IjWrS=ws7PI3P z72cx4TU2<93Wr%Khgm6yF?<-qhs$9VY=X_2{CT3tpQmVYJDGb94r&wF)lXnoKY2vd zpZ*wQz6F_FHQkoY}UPo;T=uQKWq{;|EQ*(@)q@!5A=t@np%uO zi!tbFDtMX-R%{csf`e8l=bg}aH~LK7861oE&Ek{}`pQc*-Y%!C}YA~?51Z~}{{(9{~es5R4| zD|Ck(u-0%Kc@Yo2h=*RpfEO{~MOygc2o2#JvzT+tdh)M73_1U-zs*66lcEdfos}*e zl3h4!x)|URPGA+B!0I&>K*oR#gbx#LB)pFBM#3B!U7HB6C(Oa>i6Rc)C3KMkUF2wv z(sUo0I@noT*+6e+1DygH$L}(Z-(`Zl%LIA%CLCfzox_GYA2Mu;7&b*#*vtOci~X+= zGW?1ee#K|tIrhJ^*#EjhR*3zq5c`{93;W+0?0;uM*0d7anpSGhhS!0OFBwY7P|D_~ zbc-ejokb41Kq@#$1qU(kAO@CsvN1M5KNtYBU=AB)UpC7Aa3u_b#juo(^K$N>R>CcC zD?A6!vyY~p_c^D_`-MCd6Tw7zpNUeQ&&IkCo`z@GU}M+^81}&_cpBb>Lu|N%*l;h0 zy^tlSg8UWaucX3CDy$^FlK4vED~YcnzKZzY+~r13r%9}iTf&K~X$Mxb^jl zJxJh50$LhNON(h)F)b@z3)jIkm;qU8idkxkJ7EtT#l?cFjc^eRh2bz2ro&Qr2ws3+ z!(sUH2z@b+zVL#frz6Uw0~i9;1@(>t`NkQNoj z!Z=9&Lh|oR=Y6I*Zj#REm*&dZ)}5m&H%s?ix1T)Llp2b*-?C&G&US-#6I< z8`uMTv-KojgS)wCRLz@qZj;El&6=FM1Mga#^tzu+FvW8wPtfF#nJ`Qj|ziG^E}n>V4f`F zSjVNoL@o_jhf`Bv8Z3sTToNqel3)o8h2bz47BGHy()~Moh@gTrDoFE#0Wb!}LMlq5 zqBkSBRfvR5u$fy0javmh#1rXwBAwxo&S-dxUVAH(%LQ7RK}$36NCqBx+mW7gf`zb{ zO9nlc4EBuQOj?>rOEWjXjj#X~!9IAMTL>!NMa8>XV5=rscq|K#W#O?bJeJiD2e_S} z>vz-jds4Yvz`8wcu$@Z=A1)buVG>M+G$@A#nFB@4reGeh*o?*I5je^%1cu~dNNxwT za_c}#@@Pq(7c@e~Q6A$ck9>LL%gcfJupM@AE8)wngg>O~^69#KJe-e*^D#6ZL-#Uf z_cCVplHatK0ty_sws3?IFcMO60TsVP#qUt@J7ut(i9yQ?X?YsburSPbJ~ zGi+fI#AWZ{viI6y2a6vW50UYGVXf0(D{Nz}^I)y>gd=d2HI9ltprQ&F)-*Sm025iu zNLNX^O2Ueoy8JZ~YC^NPR}d$l6iz^CoC9ui4!Fa1dnViMS!{9-v&lWmp7At$#xt672@~ZK!M$iT_o96E zUHFWrWLW6O1u0vxg=gS7O})gv z;UzX4Zg4XUcm`yHGusQYA)1{E zxo4eS!X3C<3s=HlQ$a5rq~OyOOvOf8VvK?t;bsbC%e9al)xtzb0d8faXREicpYQ-T zy1v|%`;(s=;JItLD=*=$yqr66Jh0RWxk@22;2nO z6Z&OQKp|v@W@W4`bR!fbLoz>DUFa;ily!YQmKEi?QAp`MXU`$kq!3!me}mJfx}T>5Av+3jVd53a8+;Y|YlPb$f9;dq66P zauOBgrm2_PMZMgsDW7wqeDL7<3ig7y{B^)Z32b9G3*Q{+2^38ygO6sDcR zv{vR|D|7JkDI%XwgQWYMbf(X@@UWF@9X;1N_Andf!Xj7#$@m2szre6BFzm|{%*<0< zelT+{F>^0r$R!N9#LT_K%S7tXj<5o9}IxOFoX(w zsj#2)^`vhkJV>;xV8b1FlfP6)NaPs}Mj-LQ#NQ>XBfb~*6CX-^IN_UwhX_X!jv{O_60wK} z#=v)sfg7~&1}*$9gm5T~g3&MmCURNg%4LZ=OoT~XdeC)4blt5b++p~^IX`Hs!eM9rDb2XKxv4}2F~mv9jF<42Xkk1911coA zPrBJG@3VdQF7X{QCh`4oN$6QJU)-_4j)LrR=zVud}mm@{U`FB;XCBd z7uDY#@_F#*^RTRgHQovnU?SyYQ%*kNRKn?mDKCifmYpWd2Xcsu_8%vumf5(d7VM^I)mzUta%-4wi`IH zdBa4Q1R1T{8Le*+{|51Il*1|xY)%~5oGCXsnTJ#&2H`L#ws1~v5fJnL)X0fV&xy?* zX22|10S|L>^XKFi2$@zpm{vR5VFw2<(x;I=EgmMoQ4U_h0gMXYq{26&VGL}AZG0@! z9XNqGauVAFH^WSr&52Ank!dg&7H}dna3Z4x8MHKmmcH%6iOdZyf=eL%_cr~P>Bs@h z33@^U#E?u3$)x`>lOg?@Nx$xz$-!(Ee%^&eyRc|iI?RN$WEU;rf0!j%Se%82vhYyW zFdX5;cAFF19ZqW5oYZom74~vM3*>|r3@Imva&r3N00*>*9MGn~P#6wrkeLRNRdQ{8 zoV%HaEszYkWXNSg=dse{`9gol$jM{me zFrO~W$KZSn-fPbZ&H?&BUr2h>UNY>(qP9X2R z*aPptyWBX1bK?{N<6u1Vzm6Amyf`+4Wo;%uj&M7vtAiLLLHn@5=xc2Zo zya0P(pQfH+?R}<2ul_X<1)~rYio#I@ibPQ;8pWVk6sK34OHi5Kq&C;^P>$+R6{^;& z|7AtJs2>fWLA~1Ih}?J{Mk8pHupkZTkv(!iPRJR#=+$ePC>Ir=B1EOHl_BbRje1_o zHt`3Q|K5Q7Q6LINAt)4iBOm0eS1Aq%BT}d!g$h!rAO(X`Jdh`%j1Ir=B2fRirudN!<)nJ|*WBvqMI7<4G8180MWFs^RY|5w0|5`@iEPi_$QK2pP!x_L zP$Y^%(J00o?Wy~N8Z>u!>Yg?~HecsrB3UKLDoIvJvPzOw#vtmij6(@15hbByl#0?( zHp)c>s0fvyGE|PL_3DU*^vE7LAV=hcoRJH1Lmql%I^xL#_8+B?qZD$KLXJ|%(JDki zM{7_$YD7(_8MUBMy|M_RA`2B+sHi3cg`#j2fg({9ibgRg7R8}>l%Q9&5zOgY64jEZ zmPEBAIz~musOT6K9iyUSt*8yPqYh+6y{I1z=+*IhM4sd1IZmGA> zPM+iBIZmDi(lwB-fpiV6%;^RaHjuD^gbgHYAYp?oA%!;#>eWe`hS3Nb)vHs2G^9uN z$N@PbC*-VGO`#|j#i4K%iK0;|3PFh|2_+*_6o15{2o!@7P$nuzRVW)3pc2%K>QN(V zLPe+=<)SiFgVIq8>P3Tk^@$#iLO~kO?WiA(pbq-K$;!h38b+{Oc$vQaf^Lln^MfkIFMqQdS*WYw!43hg0Z50&Uv#K5(yeZ^kT|`l8 z?@5Mif60)2v3!iw9kK4&gDWgj#t4DJsk*Iy>L*Ior#d1;JSQ~z3xct~m?oV*X+*F{ zjVA?!4D%$Z=9DXD<~mqWWX;yyia$@z5#-S4EmCo|fRF;QIubAM*V&ybs|2ec zyL9#{L3X~R3N>hiQvB7J36e<;mP~A*U(BtF>M7FZY#l;xDOC{Uub=xT|JAxeXA$SW zT~`SHkG0F6z2vt&upzsH)R4{6{KpUb{Y8%~Su7Hah6uItq=#fen=L|{EfQo&D0fy= zB|!T?T{*aa$3FKDPgQlZFVac&Mf*^5BQ#T}g8ZIPEl~MZQKq-CkFO~jP z=87d1{^sWL4(4mjf_z|ukF8l~a7vu*G@$`(`?kxLbPa3izdvJLu3zx)lXrn+lj<6@oExR||Zxz-lDM37>a=+ebOQ;Vhw7AYY|K)B=(Wb=kh zFth+$I8NA*4m=ZhCdZ}?Cf%4IAG>uz<+6WqKXj@ULOdbm$x@JRnHI18(_;E2<9H za2;g!Zim6To$Nw~aGjF{8KOGAktLd84CEKtKttH5E#Ok)fouD#0jXOc;XPLmsH8a?6ijAq$YMJFk!h>}<7Rm_8HfnQXryR5yctZRn?81H6Xm zgXZXrY<^Hbzu)Gv1wp1D8XFy8EU|Zk!o$9vYZ>FQyr8Ch#(oIuMT!Q;*dm@4tU7D5 zYq@)v>oK=Qa)7DhffT9s0UZK-e|>|quhe>F(;cU(Mw??Kw;;&rj0`w!y+Tis>X5hY zfzjwG3pX`8MHA?MZMx$E@(XgrvuZlE`t3+Zg^cGzDbI{MQo2gVQ25vbeWhj;Nik1F zk=^Xw;6H5*P^3Ylh@LA_(?*e^jiku4Pxh6Fo+8CQs6!yJJDzQJ_A-&}7QY~x)$|0U zC-C&qPmVL2?osFykblB6YH3n){j<&2aXlNLC$XMvj=6`}PJBjXWd5sxsGR8Ri_l) ztL)ECPsbfYo@2=K@Smg^<$2*x(k!P$ur@m_QYF$W*<0823v4`vQS20JxMqT_1;iE< zx|TC0Kc4s}Ro+x$l3o%7x%(W0dC3GN-fC6;i$qIP;y+t`<_Um##9Z{FT(^AX54B(P z;rv=RDfxe~8q8BX{A#Tx8yC_@L=VG*5E3-fJXw%;KCg~L#MlJJCNTce%lP*{NYTR{ z#s|UUb`Rri9!0B(=HdIiMp2qJ*g0kiqA@BNtdn!A9B$e1huWwg{XwRCo=p}9=&eY% zvXx?ZuZK1rtujfE!!A=b>^cYvEsO0H-yd#AZae4ZzNFe9maBT{S!z;2zBt=pHc9U0 zlnezQnXUXk%PK;`gWmU`Z`sk1D7^#R9PC0!xb9sR)TNhSKPwCF(o+}3Zt2p)uW2@0 z&}F=><{>-?9#Wq~t)+Hjw}{qK!RRkm;;%(I1RjTSt4jYUb<0yO(KLnH`Qb};)Ntan zL^nyF3eDv@bFjI$bO;(gGTZ80;%tf`USr$vY5=bW53hcgXiAdM1n&DK-SyOD6+m|Fn2+&% zhaQG&b9w#Sk=GT5?8-{Jh6l~_a9__$8Nj{S?&E&S%N?_1`7v<6kLSw+_gXvErrz|= zX6O&@{aH#_czD<|ik1hxd=7w5Dq9>DsUMGAN|*V8y%Clav}cxr4zsgi zi7Y?N*uCO+)mgv!ot$-Nv0{;74l!bg5n{iEeK@{dp0vnI=& zDJWb&QxTPo+}WPomA@(TUAKJVw{qm(#cU>FP6%>;G!r8(8xYZB_^Dh$zR@G87-fq+ zWuN+uCI-}ncK=p`viWS9$t0x-G19Ft>~kppI+eG*gYwsS${#@a1D^7C|E5k!p7^a6 z6T8Rhc5__w zAZ7!Mb&v5YT0t$=7S*Y;TF9w}6}{(SI_PgqukkRw7W5zw(*O@Gn)8g#6QpQ1rAMf(b5XH}i{Wov zPT#JmbNP0I*=$XjuAt){>IG0O(s=M0pXZj(T~yt$a|^lQ>B5B`t|yRBYp^O$`JhB#UF=Mb@l;_bT(};|^=wJcumLLyTj$!H!KMikcZTDY4w^)D5bRESl{yWe z=Papy58K^yqD{#cfyvg5-crdxgT2TC)ZdH71I2k!I#5q9$^;7cA`_m0v^OvW&NyV* zQH)H%7u60n@FI1vfWirZilS_FucUGMdjw-|vC{DimNd%TN}NnS+=W#-hFJ}Uu41dh zZVZVqNtICli_BFA9sYAB|KY$SptD~FS&rzK#r29Bt1UmZ=$x~Qsda9%v(nL)vsg6Q zEMeyO(A?%KTATSMVgBHh%I-A91f74+k` zm-!?3VeK7a_BVGnyXChos1u&L3uLC(pHj*VT}JvP>#?DPl}!L=`=j{K8HsSWR+MN(i3t}}Z(MwVoH5l?;wCDA&PyetXV4fcK7#S+5z^1h z^`oWkG_GIYu21=l9stjzLOt1-J_BqCD3tJsTlVK-Xd<4##r(B_)N7q?Ft40Iv2Uk` zLxcsnEy&%}OvaEAnVG>h77?N5P{`|)8AyUHna16 zdgw7B!U{AbHuSc)IG-KhvySsw$EDhlZim#Dyiz}GZibW+o|{o_uHyq5ss5-XNnOL1 z#*WiH$=;8R(Y?D{ik+mhZ3nyUk4We$FP~R^;Lv$u_+mjr)xNUyy{ht7Y{(53CP*VN z=8rfozMSl;cdIBJ=!6#)0)6jAwLmAmNGzRFD(nl{=P7ABURZjx)U+>2B^(#GPT6YN zH^qw!w;tVU-M7Sx#Ui^mp6)30#tR(|Z@kt~zRx1nplUU+)D7pG_g$!@_L+IUxl)jm z3f%IHD>eJv^42T1T4bz4#=1xLSGwii=LM&Z&k)9)7hr?vg4#;K7!-j%{0LTFkLb+F zu5aB2Q;O6KjKDGc6C7F}Ia+z+>2KX`+5NNV4B=d2&x_!4X?;zlXpD$Zd5MqeBm|T_ zKAtm+1_6Nx?&Q-5u4ABEq}WHXQ}w99JPa7q1|ajJ!%iQAh%bINIb*npi$9wn;t;zS zAEO`fsGl@~MJDvoz05`?%+_ZCXR*?R#F&}uEs_J}9gnW8T!o5G{W;w^g_mFYb2`eW zu^$s+^fky|!$K1K=;GPX#Myz3z>SZx=Mxj|YrvQkyBz8)FRk1P2H*UoE=T_S$qoj! zPipIEL3QxZLs{apFOoN0pHlS~~ZVMaRH%6bi z+z*}MzP^2QkFclv&eq$3?d)RT#F)X*ry9AdmlsuTgg%KssSnj#f2x5#eb~r;G5UJs zuV-`n_3^v1j^+2eOCRu!>t^YLNB)sJlCsi z@O6Few4!3x$J}z^k2J!P>%aYDEi`&EKgP7OYGai}T8Qji{7k+m8*%u`Hiv zt`=z<(zhXf@sH}@R{SH43JY1qb)o%?vH;t7MutYcV3BH(zZUt^d48H>Kg9D-VCS!! zI4*FCvIgoog`~C4aZJ`_G~nr1JE?XuQIyn+={}D1q)9dojli?S*gXQyyMmsAD+h*7 z{{0D)RE@#xLb@{MQ~XGJB)ZEUrEuTK8j$}bxhwnWlj!_9bSE$50>B|2vm^?6U z{vnh+gpzyDsn3`Cb7YMQl%yy8PLy1R=L^NxaapHP;xtOUdbn?xk99dusKPQ-4`Hr0aCC0 zpiYtdoO2+x^>J35G&(XL$@xgG{Xt!5{rW>Wl0RkVlg8Lyooq0-&b3HK+$kA3RWt#j z=ZbBz@_!RjEz)*y*bWYbKd4>u?H_8u;mOBS(9mm;e?Icle;dz#0QnCff8G!3bl}Aw zYLWke$EP6wF65hx{PchRKwh8$1sYJm`h(h9Yk#2Dy5n*5Hme}t1b@7YJeO^(VNlo5 zagVER73g^mj$j=IFYX>;7o-R~cB8qTG(m{tdj7GN6%IBHACKhmNR}H(ElM_UwN9+f zgpKV;wcG!2&^#|H9iKQRPeX%y1L!5~`GtB9k;<*Ib@dG0xmD zKc_;l#zQG)9-nh7TR6>&6CNAD(dYJv1xCdlYDO7+U>yR@Ews zYt_7_)gj2gFJ?Q2MlUR02nSuke-UHst7b|%JNHzWGd4l{sn|OWPq!uXGVkcv-@~ZdR zSu)!4HHwsnA%#5iifv^ECaG`~gVl~BD zhjSh4;W`RjFQrvFS}|lRa=Lr?44Tw>tJ*L$ziQA4asuVXFhTJ^Ztu=_KO6j9>G@t@dT@X#oJ1T2TBI!G$Xe-^OI&Jy ze%D3)d7~$P0od<{C>jawO{0N0A0_fp!sb$Y^fni@{4!682dMmUunNQcD!2Ue8C8=|u1Vu6ybQvk3QH>f;EYDT=v8i;{J%3)NfQLS z&rl`nRw)9$06W^4AOU3%nuY%x*DAP%(ohXbdx;C*+eUb~SNPXw$P7C)!i@qcyJeys z>&1Xok)-WPECV*3Q6C!BX9`iIh|Re%GJXiO9D>@cI71H&vd+tA97xSuC0cWw^GtZ? zAjf!CdSj?<{;CAfGEDZWm6BkmHBJ{iz-JW98L>=P&DM{Iu^CtEB;#s94qqV{qeQ%8g1sXJ zOyxz2MXbgUv^qsfMy}-5UBK^Soieo-A-^pY)vaCNI55h z5ug%V_YX!3z-R%=ReKoafDeM4r&CrASRm@s!RNAFJ*Yr0a5N={Eh#EIxCod$xe=pn!g7n_pI(KRk}CbK`$+h%gBP@ zkmaj$NRdUV1Q!I^q|0$G;atY*a=>Mq{nFfFt~&QMF;b;PYCtXoxf4I{L53K_&wIeZ zZ|XJRr$<$D(0PmT5mcfDB@pDZg3=|R0YAZUAA94b9$^t{bW+5czETFXYc5w_tA5W; z-V|jsA;t8!l!G}+PI|+cvr@!_&?1dkBT$eX-ZLB@3FXi`){aeET|;HfXzXu}oFGMG zB@&HQ$pk4E4VH^{{RX36Y@M5ox-B;ea#jbe?xF#PwSqO?e2ogV{ch_G=UonrAZPIt z8&vsq{KQ71E!5-{fFlH#ZxWnBmC(r$fxq%m9b69o=cY7Q#z@I-gCQ`2VmVg~hBKks za*yyFM308k6+;?=JV0njMNguG15^1)jtZOhyh8sxi{wC71i8VEi6i0&au-1vG6net zp&8ew}UXDSd=rmmE6Jq2B`=?_qCP;%&`q1*v(hy7P=y1DBRHmmJswT}(4I zBhrm)3GZ5*4x9j-!10d7bev-Z@Cc5#E~eug>A>k6KfgE`I14z73Lmc0`m{$4q!1Wy8y;y6W`6~RT+A(&`M3^i z>6p>+w&EwyJWu#6Rsz-~kCTN2Zn1LUa*kUUk;M)JALh7u5m~GOxPjxwMP#uS;1-S> z7Lmma;BR<>_#InB7K;Xs=D2ndx0o3OGbbEcL>5a0PUW~}5m_t~IFsYbMP#vT;B1b| z7m>y6z;=$eFVb3U_rt2i`~_{72#j#c15Uc-=T7^ZFe`cKv_6lsX8L%?<&R;ayEZdeMfWQ9%vqQP409Ea{S z1YCyT+?L%KjB{HmijkHHhM*o16Koz54PAApN!=6JarB;uN#G}9K7R}gU%9@cDw>Wu z`B-6?KZjxdoU&OxwW!i@H|pyd9K6HC)S~}kzO7co&zpm#rd~g>8TCdmH#_@aH>(8* z0Vo>iG7th#7?3d^&#!z!*8p_|LICOj6b%&3K1z+V&0L4a`#RO9aL@xO2*{U%d_#Z` zfEEIc2SNb48z>V90q9PkY#;=n44~ye2tbp7@_`V5ZU)*6ga9Be5C? z0VoNm4hR9LFVJZq1R!2@pcam(>f$vtps!Q|gaAb99tJ`HB6aJ55P(SCMj!+rt}ajuN2G4R zlR64WgSvgB2tWit($@@x07UwZ02=WmYZ%*=Ro-m0RYTWmjjp*!MnGoLU^x&15NWUm z2my#RC;&nLA`LbJApnuV%774nNP#^-2tZz6;f996*x9k2So*jww&lfmFctf3b_`_@ zP-c1`)Ex)`Xfn`cAOxWCKoRRv+4Y1{fcgU=0Nn_b41@qQ7-&2Y0#JXT3?KxcxIXY3 zDe}0QLs#k3X`nJ71fYDN8XyFql|Xes2tbbjH31<2JqQ#~2;&zL$_9!6iYT-Z zoCnw+5CP~epz%NmKr?`50wDmU1LXlB0Nnyq41@qQ8pr{J05lw^3e2+$!Q1fT&x zr-2Y`fY$=H0wMtQ0x}lCz(s^2fTDpAfI@(V03iSc1Em2W0Qm!D0U-cg#_+cs2m$C< zph6%7pr3)Z0U?-e&Cauc)qn^{YyheQLI64r)ChzC^d-<`AOxV#fW(b>Tx}$D04Np+ z0q9+zWFQ2fcYxA>5P;qSvH~HPn{CeRfVqGONGt`)2SNaP9%wTV0uTe*1B3un0CX4# z0cb7IX&?lk6+oAP5P+5fi42M|LNpzS1wsI_(R?5o5CM?p18G1AKr|n)0wDm=d>|JH z0f^=U1waTu^nBe0gaAa(*GeD+ApU#>I?NG0-A)4`Ag!+r@G>9*AU)p1VrW`Sh#qgT zKnOtec(VW@0MX+u0|)_#9&ZbP5P)btpzQDHFy~4=7mR>a!Az_QX3`=~rOccqNVb`? z(lNhON!vl%KC4heiMR{<19#PGD2G8ge3w|^E0sMP)8pCc8VZ&Nl3*>=Q1b7_mfYR7 z8cOn99G;Yv@R-uN{bPx8)?y1#K0v2HJXo0xf$0vUwge^?h zP-;P`U0A50RNjk4`@ObW4JqwD%%AQPU82Tp1)vpx7NVimfmR1v7Y*%LHqOvyi>^=& z&3r$W8TX5>t{R$h_F8m>DKr~zn+%+#&3I6Bb<<=t;s~QLS9FDIXa%4ZfEJ;l8F1Xr z@Q~<=)XTS~yM?jeoHqq5bL#qU>60}$i z&1{ER?V>AALvw)U0PR{0O~j6>xKeb*YiI?a6@ZrDq1mWww1C(GVxlIaWffk{t`c4J z36QsUfVLg9ei~W}Xf2@i*U*%$D$zASL#xMLPW@`pb)AMbevM$0#;*}w12x1w*gn_; znps1OzzRKLt>{Y9(CnbuK^vr@9R}?%Xmm_MRa(FbPk2If4bjjJW3hC2o#+}WU_V67 zn2Z^D@{^+LdQHZJ_1LReFS>5f(27AT1}#}bs{^eLv|$?Bfdaf%D-c~bYG^YzV3oE( zbPZQ&HZnhmEg+6iiJ%ocg?4&MbdA)|vY*B<^R(!?NkiLQgw53=(KSj#s|T$fG>e8d zej|2=H;S$l4XqM1TP292HN?zku=IaMbdAx_wt=<{v{Vhv@GQFBv!ZLPhL#RmI%qd* zXk9nqWbh`@HBLjD3EE81#tT@BtL8rh;vo=k(PSJ_f?e+t(KSIsvpPJxiszI+X7*_L;DO*H6RtV=vpL7GjI{4w<1ICFz|*sz@hZ zQX(!nDjhn*NbDT?Dv(!dFm@HOO7e(01W|{c9bQ@qVXY2x1$_V#iZ=^Qb3-u|RdY2X zS93eLj?eX0mR-yYi5lgp-~ycRGYE88{140%xpda+_Bf3pE4Lbq5h5KW|D$yH)^U*3 z0pVthuz?7VZKZPu4^-@~pl>?EpwClt!%hFpZ9#5JJGqzo^pZop)=CcK<~qSXx!oD{ z=Ex_2lfNi-W%r^f4+Bdy+k-=PvS7O-i*o5tlO@pva>$qRL zQ~dS4SUw=FU=!ufo$GM+Fts8UgpwxdtiNGuExwSct)mG5X-YXc4--kL7J;#RM8QHH8Y87s}2y`}^**+HR@|CfskZHaI(Z+dM+qmFBzu zU4|tSq~)6mfae9rV@sX#Ne&%b=KBRmuR~q@GNQH7DTHDtenTZ;0I(DB_!q zUy@xNukPnOJz)IH4B&x%~2^xF1>-AZsL{> z;+9TRtAUme(!6(Qk5@uAvlevo`(-eTz3bXR-I8l?zR=fBbW%tiKiVtZd>>2S&~4(r z!FIezbjwd&sC5p)mz>G?P#7Ow-9X2bVCgKwHG2HV31`V*x`0E0cFc$DB{;Zr*)3mx zssW?qsj4wjL5V+>;V15j!3%HqU13pIH^8%O;Or>fU2Nj)VLdj3*Jkh!@VS{CnH?2&jYs=a&E?J*Q*BkVlRm+8&yLh@2k-5yhc$dq%nfur zUNKA_hPN(4>%SW2&wJTD)}FfkY^`;$zTi1bg4w&)kulX^SPf;L{8P0mjo639a+pjH zlNGb5IZ^sUB^Z_2@HsJ>5z{vs*CVyQgjJPSq1B}WLB3Htf41tTZaKDDJ#BVNb1j_x z=S3q;7*UL7G}F|R1~Yxu+*ee!pog1Vz8Un<=-GY`q@H2Nbhhr$7 zt`YLfdG&xpcry)0)vV*)kse1*ygS~bJ~>XjNh@kfl}}98bN*7+b07aria{e~8$VD^ zgWf0nK>4CYXz6#m@ zeQ)7bG5@(Ygyds#p8vdCzV{E0+HB(7n54Bs+d6^qKb&ATdvR`*Ej~%<9Dn{?=$v3G zuc}24Yk-Rl8!8xY5NoS&LPTD2g99h;6o)5|=qHv|HQZ+u_8wL_Z3hVk5|#W7>GIT6b(1KaUOL=RbwCj0GwcLk%?F&nIMe{#*n7 zh5P-{CvsHFv!Z!%w(AGc!9jehgFZ`jGQ7}R8Z8L2pGJq%KdD_N=;sFTdlO^1+U}T}^~1|wyc=luLHyl7{y~1HUqWv+ z2{J}(>pgu#(y%;Cd%-P#(CVotd*PnJw|O|CPyg^;p)(0nj4@K?3;qc7R90qrZrR!D zt7D3$j>EI@!M*00Lanxw#mxV=q4aS!d4A-qP50HJeI7YS?Nj@IYM&eD``Rb^C-niH z@>4Txz#=FN1e)oXj!P3!)?=6yx8wtj+t zOF<0F__q{O7J50s1C8R}8{28Fb?Qwt{;=TtyJ_Y-s*dVion2TocZ4z&&}>gt5HFnIQwugffPvsv&AQp_{g`2z@-f4FR=7Cgmhg-l=Z=<= zQ+~lGp}5Z{P3Y8iilWwPj8wAOAAxE{B_aeJ=8rfWmFW@8E-Vh!z0dSHeU$m)?g2SE zU1%+IsomUHD#2Mu`B&y@1BC6S%f+37K`KgKRB3GFd)hFTZ5eDp&z3vQ z>SUP>e((mp;YIATvBeLD56T;$8F&8=YrCm)XmzHGW=9?j(+y;29*omRzvz#HR-JRh zdYHl1{Gwa_^};xF&EFpOQ7k1lwBOY$@|(5oq#4h`++MmpY)fv8?mMu3&i)?`2=yimp(vS%198&xBLc%lt@qewI%Y!I&@BprZw2@m9~) zKRmay;=(h`qxoe+N7!Ev_Zq8Mvh84G7MEzI^SNl3+!y;wd*FsO-YGpfVQGfiW9BRk z)pcMGEgdlX-hMUvYASsrIz4ABQVCkL1TET`A5S+y-y!^X`tiA{zU?{X^|Q635B2Kd zOqZu_D7IIk8%of!3DY6(Z0OXriu=BEI>)&hlQz3?F_tc|{1_z7O}YXl042yFMH8g{ zi1o+8MxB8!q*LgW>o&|_Jf#@RyCGaHG0rUDQ}-A8VP=FnZf8rD zEeo?P=<92bPXFPTsdu%`EqBsgXqdigtay#bil=0|(}B@v1_wqk7xJS7$AA!k=&Ch!H@D$MKdIqGWfeeMkUeknjdJ^Bb^JUj z(}Z-*-82>{$NQ;)v@#rRWOQ^mcVXr#yoBv__SPd|_s_oDXQvt{K!?!h^}@kcv-NKl zKai;UCyfQ+^r@!&MIY^{@bg|&TSdJ{@rxQB=PkvO9u2?6)5|muH}&beeAeH6d}Sg@ z2^4&7rdb8EqDR9;)hqdCquhTaYj`wzz=c!gI9by=*DaeqZ9wB`2d%$i$sLq#a02;o zPGosl$TK&>&Zb{@>6#}ebuNj2Csr+Wn>;5-p8 z;gKZKB7{D|>3)hj*!zfm$C6gWhy0^kvV|)WgI<+tagYYviR^_HiS6Y1dPP!Dwp7mZ zWV6n;_VV0fO9~p~$uo$pZa2@nwqZdn4TYRf3v;)dXPA9xP-TOI=c!~%?d{2`un!2b zH`MSvc6PSiJTWT=1daFP8P8^{Y>!XT%3;C59({s;WOXYO+Npe}Rf$1$Cu^~%fLSsd zwJI+DA4dF1?I(VB(BuUBu~@{v$=0umYlq){@O#9=?-6$KU-@mn-N!G3jauCvzlT;Q z>P&3Q>Xde5U09tMbn1JhaZj;6YuYoytTh9Ic6?vM>$iikHSNjx1bK2jd2*S%-8@6r z#s!W3o?e2u<B~O8t6lLuK9r-UK`tv(z?gPaE?3t@%9)@dVGLx7kl*a zaqaHx_J0XGuP=R7)ry|&eG`}F8=dn{sEhMAPEfy?I@7@WjTQaIihfhvsP;Y@tGkE| zxUFg$q*YYWrKhAOEeVf0x=t>4m0kF0mH8D50A_cEi`B1B z=yi3k9W>1?W3(uUX@}9Yf<#?8vlVDxt;iZZ>!D};7Q5uWXrJKI_Rm{<+HU%v+6k-w zM-4dV_AaoTTfU`EwUyD~FBu(LTYY$@?KU`O*{s)wuy*ttyCD%*Gc4W^-eX0b`d%yn z{1V#m%VRHZXm2b$u_1A2)A3qoEPn?_FO>S3Xds|>Z`odc7VxvQ;n$xHf2uux4?UHr zbFeK>h4KEBwv8>WS-0@RU6y+@yc}#7Ko7l;s0sqqD zuAAz{{R;gyw%6lkZA=U*`&Q|?W$fvV?fKa!827t)$G@Rx360NJzNvxzU!K-ivNY3$#R*$6x^G>@Z%U56nTgMI z?Y#GtnwX5lWVWTahpv>pTO6sk0$bU4#XUN&{#%|7&-55}KWHRA{W)QbVEi}~-_=6= za){6RMt#7n`vxPbe4ST(H8@tYSP0zkGIvQ2%@k0r4ZfLp8Dq`M&tuB8;#QT4 z3u@}rDbw1za(G4G+p2JLK@n^?ty*>Nw!2H(t?p{@tbX|%cxGsLUT>>YXH9q3k*5oq z`H)~-hv7?SrF&Dc6^9Y*&Z`KD!t6+WrF0pBE^|R9jUYdm>nNY^#n;tB&f%$d^8L-^ zVC;g6MP>|)J{BXk;p4Pzy`@PQYp+aF>2A5_e6=JtBV>zm`^^SzQzL(*wTVqQs=Uy`I*khF~b`md5+ zO;aRcHTYtCk{)_7E}^$qQUFd22fTuBuDz0`a!J3ZV|IIjeemM7|57Q7N7T=(<4bY2 z1-S8G0o*N_{{}`jP&P+bd+3{9!PjuF{12VRHPPoehmKMgrkUzbM;)m0#`HU4CV;QP zyAVTQ#Rmp+VbviEPAph+5bW?GNV9QqMJTenA00SQ6(Gv=es*-S26VEKA7A|q@=Pc+ z^OY`8=p~Ip_M_^^@XApd878E6fkMjFiXo*_OLb;(x?o%`vg@{(M%lr_{z`K>-5s&V zf(>Jsx8xP&ZOa5K2h)zK>!l?}si$^J_q>Ubs!_6zR{s*z=J8hboxdR(`2NE5ESf zDC9S2>8^5aU|+bfz?nmDn4Z4JImK8gcpxUJ?@xYw&V7vhzBCzmT=Qg~N4!5Avy z)S^HuK-!k}v@%W?c$$wLElt!7VSkoJYKC%J3e5acdls?(t2(LwtJruRMvNU)?sN`K6{-?*(mLf4iMxAG%};5LnO z`%7*1;~}Ls)zP#%R)cBvtA9Yp)$K5ybA);lF@5|9^`w5B=~q6cTc>VSoL9@U9z5$` z?F~h5*YdP^>V3lz>J7wn<`L=*I?nWU6OO~xh{l&O5meka{crUbUeig!YozLRTDBgp z#v}BgB(6zEYQXiINo36xUR7&fwzX{?6WEzvBP~0$!|u!%)XRun@Db`|Z*g`ryzGif zzw~rlZOv1`Gxaq;@H{d8A5CPHonO%Nk(f4o(Ez4vInx0?rdz*k$DCPUn)O;=Fx~x6 zrgG62HNkIqi#PFumZtrR*w)64(!~#7%4byw-U=Khf4Xfy{{SX27on{LX)_j!0cO zzp6CcztojBT(DC3OTadV>QW(?py~`kICZ3scynJJ@Go1fP2=c6sOH`KYEnB>@Jp}8 zO|yD+dm>)Ztt-Ah>AD?;@#zDn{HWcbo=>Y_?g|A;&}!whgQp>Rqbc0#eQW=c0_ufqfhUM_r#n#1`NFV0<31Ny3wxsBko6L zqsqeBbvwJX<5^R7CXO7W(PA^S*bFU3c(s`G8QCUq0snBA&%3% z(yV%CZ%=Ipzu8`Gm%OQ3V|}~npS&5@BkvPBJWr#K;dPw&c-<|p{zSFKcGmH&$Z+N1 zRpj{lNHhGcfAdQF7;TSv`mOes5}&*k*Q522D!)JE_lJCculxkov0RmZ^q=y}|4qKo zR(^TA^2<^GLp9FZ`0+>OQ##cD5REDccnF~W6+JS2Yd$)2tgbq9U&mbNbwPgb29<^b zeuv0%^l-5qqUMVoCz{;yxK;sYxbUd}?vAU)XdM_q+YkX&%wCc3FAE9lXl2b3!9J^K zZ_T3H6=$peSXI6Z#w&yI&VH;aZ#+a#_s zQK{aVO1<~7S}FNss#N~XRH>c6qf%W^tKTcNwR(r`-Ie$+l{%23RO(aazq`Fk4ci?T zZ~0hVTnanzT7L(wH{~i&i{x+>!fvJwq_w-_W3S#P@A618e#vTgxA($Kzb7vKe+N}j z(GV34QD+XS&L7N0y*1V?f5xWl`L}g!t3|04UIg!HuTn=LDc3708IqDA$>x=`?I79p z7D$@Mdc6H_k~VrIS=juy+mrO-+i~&NcqL^*QYIutdL`Y&CCRC{q?7&duaf$EB>j&K zey2T23*SjheDx!Gg{~}Wav>`hvdTYF?f3OZRI5iI>sjV(m&b*75`*skNZI+ioAue- zUKgFUcfi!XAK9^Zs;Mf(1h$keD>HV$qND^8OLmky15LQ)V+UUO?Wn*juWg`i+fh+< zp`5;I!+{B}K4ZB)=f=3@z*<(nw>_5#sT>egdq8p9(Dopu&1Ci48~K^_d1Tw%rwC)2xfu58EgSU07`zv_loTD4nOJg4rP;ipsf9dLy;UdT+|7d5ec{$d;cVjKP=cH&b1oeKXh;NMZ@&)(j5=T-Qb+VC^A z;g15`d|>&2klzu zdb7DrmCRSI(jZi+pSMa6RnHF0--*51o$Sg_@wPHtiBP6qHinPRcfzf9(nW=pNtsy1 zGypenT%JT1A6^E&%<=Z5@xUU=i)EDGkwh0C#sbH3T#}RwoD7`IabXf&e3%BD#&Ld9 z0`P5C5UiYFPoj$tbAfX?&P$2_&IiutI46lNKHLnvnd1dX2HfaY#;mK_n zRrjbFvnm5!h3C8B{eA;{;@fnueH~D_7AVsKWrFv4M6;*gkL=X-4O}?*#%L+^4L{sd z{r3A~!vgRne!!c)R?Nbc09mYaO{6{#u{<^aF*{;*HnAqsR)|>P8*Vx5iUs%I($wO{ zD;D_3rcs?@Fa{#E1gU{n=vG@w?RO;|srjR>KqCiI9Z3ECFZGRK^c5>omyJ4))a^*! zj?~7#)K`CmCOyj4j^`b_1GV&uSKku4c{MWtw*dL zd|v!Z-Pr%&uNv^_HR>7gIgQlQNPX%rbvu6dU$saTM?H?zCZskY)%F+7T1fwGe_?!= zb)%LdwFRjyZ?HZ4pR^^*c+n-(4r0d+wUr6CMwr!ptM=)m-bQP`Pb(f3QdC>n;ebI< zd$Y)DD)ED>XfmzG;gD-k_b#=S^gA%gr@wdW*t;LZ^ijqMRbG{&t&{Lnru#7dDo)bS zW&miwqiQp*TG-5{eb{T_|ABK;d*f5vifw79T?F!iNyMW|;2=eN>|QFq`y6j7_N!?RC*btiB_V{&bcA1DrDX#iQSI zUsnel+@T9}lkw}D(J0|-(=hLhpU%2o1LWh~!IuWp`M5UN+MG0X%j^I2B^r!3@*mYg z8~hZEkj`Hzcfy=Q*>sEGr$p(?bNmL&pR`x+Q${;<*0%AMT6l{c#Dl%68BBBgZ~Yp(6BPlf-avhbsWJ+aA0lRUAtYHYXj=myIGW?laWu~`1DiQ6j-z=-DsU>t z1#vXb$OO*hcugG5GqQoRIbI%zd4^50gJ9=`+&G$N6ayD?oE=B=jP1bNInIisc}6vG zHODjKXr56ET+4Aroc8S9>;Y<55d_sxWM=i-Nnceb=|~+}=Iuo8h{^R76wX z=D)pe$8|6EcYKyv^EOT=zD<_6E0!#?8F(|t(__gpmB5u8-x^DnIShQ5tbP<3@I9fXim5`mMmiiHgnuFmMoJBoXT;xSh7qe za3;ss#FAyQfwMUdjP+P%_Y=n?KU*4nE=^W`>@FSgbh*_*qd^AZ8FF$d#WNAll=FCe zCgL;YO2if8(d`8OFsi~Q90Rrzqf0U_{9!Op07v4AOa7;;T$MQI%Fce*C(()=R+;X7 zPKHmb=p0sjrfYhMQdP)gyu3pN>e=A>!TNH<%GrJOa{`;+L9c&@H&Fjd%p@y)4P?e$ zJm$S*!0H%kpz*-tIo=aP4U`3(#c^2-HBcUK9>?2asDTQA3pm~!Lk;8rc5qxALk+YC zcn`+~F}#5efpCZu*2GW))dSaaygY^)s2RAKU)4#i-zK9k0Z`RK-$0EHE>5V-7vn!aTb>j@0uQY(c6mwT( z5TTIBLQf{@d6Th}ll}B*prx@TC!+=^ZqN-5p*TPoVv1AICpn5sbwP|f6stNpAjXce zc2p<*3cXIGQ)drd0Zsm9AS#2j64s%im%a?KGS&~V1Be}9lN(|J8xd=)Vh=a;)CcT? zUDi`iTZ;QqyFIjo%(~qllnjhGhXZbZj!`! zd~}ec=4@N$jIRtkD^1g9?ZZ1XmU1fI=5WF#oj!lq2HD&8kw*peBA2fQuIBi1PjdNV zz{fal=}9i%1l+`NQ%`bv{DJ}kl|S8+T)r!CSB~p@lFKImCvaTX6E1I)Mu0Ga6At$z zmrn;y=lDQRa``OaERL&tlFR1-=W)EJC%Jq9Z~@0cQ)R4aYxA?eDK`HctxIeeo%~fv8NxDAYQ`z!31eD;+y5XHhqGg42mrBY9)rA5G$|# zl}xONR+>l=t;D%#_MvNbXGH*w7@R#zIy=BaBU3B1`_GOWps=RVM&U`Ljlz-2DpjEp zydq3GJGhUp#MSfN&^S=ftIO_d9PTL*>XkuN`deA{N#ln9Q@&+CsGQ&UAxS?TO*Ed# zKRgy_MH5-8`6F%fyO>kF>+9bRWO7tf|NNyp_3ujHN{-KUr~X|BT*vXL?$o~Z?4AZ10{se$ zlfLT`stH5~Vh zBs13o*K^!0lFZx;+|2Pck!0oo@C$gK$_GZ0nInKBIKC1=X6_H%pX1*mVCFj|3kViY z_&I{ioB^D{u`7biya0Fs$KOYgnU@1E=lGilGIJqtA;(|9n0zw;+rl{gU}7s=z5T{q zU|U`N*{$beC+?nL1QCV&!ab^T65Fh*k5A+yPhtH9`V{{B;7Fx&}>MgP)8;JOOb8`4hx55J!+d zMBI)zf*i`5o_;SVnK%71=)*a){mm2g#WlEmorPS8x7F^)qh-IZ@#|2&u7(4A{V30dLP_;z4B$1}sJ@r!|rInD^D#@`OSo#V7{YW!;8YK~LGwT(Zym%8Hd7w~BR z0FU+$aKtrUUGdPQ-6Hi!KmvmNizb23V?a-5xBW6P-ueLsqz^_*HL@Q9ZNvqI_mwVR z*>nfRcgLgKBX2JI=$D}}YYf+GAX2hC5VAC(g zj;oQ;w`84lDjI49wlx)u>&rjH_2nPZ^@o#U`brHDhW!Q5`hQ45rQZD4#5r5@hcGzX zf3a7TQnm>Fd^tF!fu8muuKCCQVGaB9V$>9scNX|$eJIGSVf)HNhJbArdS|czB^Ib9 zWVf73lU}|xxscC!cf=X2$*#R_`fauXpxB?QwX$?te4goo(akM~z=PK0Ax ze3M%oG})}Xr?+GgXy8gUnk(?L3&(#e?_i#0#%(*t1sNB5V6*FO{+*gX|FtOcb_42W z-}IbG_u3Gu_+gnOTjwiPKMakOiW6O}_+j~O;TGw%9E7k5_eUfLQ3*xYw_|i4#UGYC zfYCT}3W^XrVis<;aHDI@UD{jM&vqIzPRrAZI^f*qy=CbRw=Dd1f6-XurSM1IppOZ$ z2ZZC3U612NlHsftEqvUGC87 z+KAinWx{f#kQz^y--~1Cih|+h3DpyNp^#EZsvvg*wDj#b6Q(G(_uf9b6*}926D5w4 zienWK6`2*m(g8djGIvEhvtay9(M!#b&nN!mG^9ZwmqYChH-H}GG?S3t34xquo?tU~ z@RTS%;U^Wty+||4S$qOR6>?ybg{Ccpl!#rEz@>x1d>ae0c7ii3j?? zBlNpg7t^EZqeZ(&H)4;yw+;i|9BcdmLnPO2)52?Y^Zuhd{dlcz0DQx)_{QFtc-IUi$U5my4rpUg!8}zZD#%`L{SNE1a;2>rKdxQGv zQvAYd@ddld!kPSq7erLVc~P>&*68q zyLQUfn}V~k$7=j795V^+ZOXM%9DkpTW3#FldlCz37f9&loap z0W17e5SR@gs2diRcd(bVm*FbcN#|fN?o!!&=}Np9L5Z9b8LDvNtgH^LiZ=>BKvqt zfFs-iW5_m)A;0Qr^q_lcY5e#L>UemOFWcvbdxlJJr`j}ekgkvIpS);1YQY9rM?o1c z)NW+=3_*YIM%0Crx-qP)i(Q5RnptN*q8!5Q!2)U}}&7L>LJ%l!BQWVz`PhAR@8E zjLK$RA8PLB72TTd?%n4;_j&rw=RM~=e}CuCdwvI`Kd>IQ&@53)>o2+ZGAAY$tY(j& z^IJ+j141ry%k|J1RN^vh?t&f-Fd29L+g71%5SpnTGOk;7caP8(A4~7<9-;lE@%vS4 z9~Ny7VDaDmBCHpW22AWX1$PUW*g>?9)5Pwf<(*ie4+qM}pJ-zv(Y7mhx2aygF}|>V z!ZLTQYkodZE`Izk38r}cpo`Xb0_CsO)SiApM@4|-v({sNVzFF2*?IY)0q14&n#Iz~ z#b=m*>Sg}TV(IOY*QISx?=5Btmz?I8N~{+a%Tv;&iq%qOJ@^y3UiXm4^@ojIiI}H` z$WKG_`u_4w$?Ma4kkhCAi6vZ~KK@jt2r_a^xSNKfLZ2(PVFJ2^GSq>?t^3vK!Lg_=#F@_(%OOEJ$5egC~y-#T&mAGORY?iQu}9o1%`XQ1!a zJ0yr*6fhOd+q2Z@`ZKJ- z4ykdpHECbPC~!AaG5kb8pP|MyXEP;wDN-q2b;T=$;D5E z4Qrn?ewBp2YyS_`+7B%68|}#m`Iw7=S`6mrBIJL2%8zV*!?zA;Dee|AT+j290n-EK z1w;-QhxN4K^$6)5Yol+re*GSn8OILo&mOfC)87B{efmAW<`?asa9cjmMoe43_ID|@ z<)}0KoI-H`QwEag&>&xAK7+#PwJzcQJ)PPsTfArSNC1n=ZrRJZ$Am>cj z!}`k?F(4IbekWGmj9i{DFfZsmC^DSI+ss6#lR=#<1upe zQ+6Khot2jLDJzYxN!#7rJPZRC;kz&Y`3;t^fr*3*R?6q^<@xnW`SHES1+ntbf3f>t zkClt3*!x9e>Ipqx+J!I5PhIT&+T)*Jlz*Ohw0<8a|CfB=!}L$9SpHsJ_;l9at&)#R z7em(+hUD{?aNEFwyz1g^2PV>T>k$1NVlimR}7@HWuz;x@*)$$2>ufIpu{M)nnvzO&_4`)(DW|s>G^EY{V)BNKE`J~GZ^6juLPLQwO z`@~z{dqpV}5zPeDi_P{8h3Hy_aL+_^xdSKlGWplI3c0gxx#jJ^T0aA(zRH{wV{F zesge&T=ICra{j6L_uBTT{e_H4f`16O{BFqn$Y=DwEJbF8%|F~EL>)Sf&Y@xS9h!Vn zh#6=uT7)9dD(lLR;C)y zgr@(O#Q)!E^?%jT@KZQG54LRXzf17L_YbE1&z|%DFBYi&>vx`iRblTvGk045wMPD( z%lzhUA)4mj97V<|SC>pIro2hk3vv1T8lQJZD=wa#mn=jHs4Z|Ebsif$v(q21P3TII7k)8KbB26dpEf0^Lsd(^_(J55@g7LIv9XSIBj zq;Tq_NPw+KgkoUwJ&pZHiu+;hS&P@gb05%j z>)(DV_jx|reo+d2pA?bk{&Tze`bD-Z=OyYNLK+{CmRx7P)-Ru!<1U5Ze-p_r-%GA# zxhJjEiKOPrJ{dNtq+ePYqUqB7=YILr<9`2Jiusk$L6@EnT8{U_g35+3O)iItjw3>38a~)YzkBw--VPNq2XlY>+__NX~x zkSa6H>j}yN^R7XPYBL`vK|3~#}4C1-mH zIok&Yz#!NG?eH2LQ_|#9CZtcbl0G)r2G2r=l5?7boYSi0++-o=rojxjT}fjKf2npW z+zxZ#IXDDI;SD7h1Pi%fIgEwz@H9LFd*Psx0ds{62!s(ZTA5_PW*#z>To@+g!YCLI z6JQq1gIH+cc_l+O2^q2(?uEthJnU04befQ%Gawa)u7bNE@59yz8MY3K>ai&A!+oKj zlCg9kmJYFu7ScaY^3oN3CQ7{%Z!_(IKujOy1x-hZd zR_368k^A`VZ}GZCiR?{6WN(It;Zb-7o>gLJfDk(u!E$(5iJTm^y*xMsN0ivLNQhla z;5N7&=D~be2uqa6E#Y%j2Klt)I+VzZ79uYe?uGl6Fulc!e#=jZw`{OYiQVz+#R*Eh z9Yh<0;TXK7ME+SJ^3N%;CtQd~9xhf2R_KSwa-%K*EKDi@by=GC<;s zh%Y|JNBBJ9(}X*eIN&M70Wac>#0L_tAY7?LNvaSfX-d2sEX2EE@D?0bq7+M(=9zdH z=HaRm@7)&Sy*q^Yij>|aY#{8TL|LE^WkJvtPE+FGJRuJHLmGCFhLzK>avD}nd^z#u z=`aI!Lc0=&DCZF69NGf6!Zz5hL6tb>iD zry&(Iq+%^x2N{|QhUR_Jzfb!2BViP*hfPWxrlE&v=#d^Fj`S)~IU+>ms1hI0QPT(X z^ut*~d^lT)st7jRG=t}5GT5oXr94oW~LG?dLdfelxSsAwKAzrFXfyb0SjOuyb7-= z@!4`AK8sf3jDrK$5am}=eih};;;7n4&l?$&M#khs9~BHz!CWesM+H>WLPf1CpH`O7 z=@<%(gDl6>EXUKg;5Ze;Q$Ye1T%&>;RKO56v{Ei}r;)kScpmmqKC9^jtEq`0Z(_)s zOthqlmNeDFCWuL!Flkc{?1dw66jD(W6`j-zancQXLNDkG{a_FbhLJD|#=`{i6_T%n z4q<_2EYK20hr%K0T1aPVp(ic$q{Rl?AQouB0xjc0*n|?cnQ#`Q0vi?BR>3te4W`4r za6h!bTF6k?7z*1cbSiO*$$E;(dWwdgqM@glW2cy7E#zz2ugp@fd)oAS%<_B8(t&w9 zFmDHIx1$o?g5yg3Axelp#K1CG0ZIP{(s$B}PI}Q<0?Qy1uak+_HCu?TxiA_suez8w zUCf&^w;7&0N_<`^#OGB?*cWjyS;8h{-@ro(5j4O~1MJ&jwi0Kl=qwd|;V#4%9&jG? zhdD40Qt%fP{KXw1x^+r)vln!;7j$RA9EerBv1&Kzx=GjVfJ4v;$CSXq5ML@bp)aZ6 zODg!%0DYhl2Es5H4r5>(OoT}=6{b;;g@S4cI|x(oSLFYS{9h%&M94(@DivnHOqd7r zAr|`zi+xoEO%@)Sc(6fC_>~>@LI)g$PB<<^k5Hn=4Z0JKB0ffm3-r8~o?kdE#Dxwe zdRgne8(wI7L3ii@4bTS~VIT~H;V=fq zkujeF3J4DqzN$puTpTHuY#$S>j|tY73^&4Tm*=rt7$MDX2Bd-01IIStc10& z9=5@D*bRH&5FCL%&{v5+RSEGYixQ*k8Kc240x~3{v2Yc{(xX^?{k{+%8?coJcNK9GW)6zrr2PI}#rY*iOOSgzE@5LblWEY^T?U;Z-GWEE3|z z638UHkpTBXw%;3=^ads!BYsSauO@s9GDmJOM{crl-DKms83LEWI2aGJp^4>jlL~KA z;Y}*MNrg9WL$=B>T0Tb0$Fg7!EP-XP4-P8vT>{r(IAJ^e^DQ|v-c=~mKVGyi`&9Dq|!uQXE z6y$#tR>MSy>*3D{-=BlHespL!i;O!;c z%a^``x0Q^i!gw#Z6!JbEXDyz3;*;P8hz}KyOA^1`#6va@4mb>N!#hf@#(7$etMM`> zdKnA7Oaoq~0WZ_Tm+kZfA7wE<$~wHWb-Azup25k&3-rd9@y7r4#*H-Sg)~gZsmjKw zDo}DM`Id$d#zM0T3C~$X#8M(~2WOWMv4k*A)6?lV)){aFj+!%-?qd^MKq*_mduuox zuZ2wH_tGE>acd!4WDrLIaP` zK-wfK^>7B92{*z`9DY57_`nm+h4bK6xJ`+pv$@xs3!`ByJPeO=My8$*@xjH1TX@(? z1PkRu7E0A-4$WI&DJ+LHtcr$xRLmi|6rP419HwV+n4S&UgR0qss>xqX{u(N*p~4#C zYlyEQzJ_=U@fPC$;SQH-IwewcLZnP)t9aj^o(I5S7^cKVUlRC{fITaPJ*%9amD98G z0JsRQgUOJ+raTMQ!A95(doZypCY}Z<=Md!_N`&lDhql4(uo@nNo$ysVV?j$QCPM@C zfveyem;C-dfQ=1oH$2kLwd($w8Z-Hny7iUV~k2kO(DZ}psS-5~jz$=7P*z~06I zJ&*%>5X^?TuopTwuw%T>Fy5I6PK3+hS$Ix~P>dJqsjNTM>vWS$(KzR^O1!=Sra&hg zQ({{Jcb18e&3aomlah{@=!l6*O;nm0Bt&K~q>-64@(oWR-tdA2un>-OhbffU9toqM z1=d31-z5IcbeKVTZw~P=qC{2nyH z%#(f0lXnuiWk`Zm(86tlJGTuUFdimAI<%h-nZ1NCn+!bAVlyo^+hI4?5j3Qbh7{Jq zdPq--=tP9-;}R|-e2|_V zq^Ad+aE#SS4=do8>BZs&G3m$_^%^I#l|hp8|PX248Hxo0T% zbJBfIx(4z!kZ;C`qZCxlt`^9y7KGD08>e}$+5WKZ8EhkVVVsl6IQkov_#{?{Pgdaw zlJ`sU_RPdjn}vI{7WZf!&cYd-g|nQ|Z*WHcjw5j{N8;TaEK509mMdwPC#1p11!*1^ zq#P2w`R03bKJ#&M1ItbBoLbIn^^gnFxq{1ZV=OnVtGF@E=jN0Q3puwf>Yc%5xK9NI9;4tU*iONv6imed^dx|TT>$5$_ z&%tn^jc^-RyBC~M8FJr|E@SZH~p3oQi!9{QhB!4^k&rGIBSGW!)n|mnQbdHOp z^CaQ;($4Xvi;c94jr4>kYsL#^!(6x*?q`7nvp~XNB#a`yg!nQRP%{gtl@kN`TFKW+ z6Iy9PYY+_PDu^{`XARm1;jj{aB;6lLXZm9_53$@4Ik+Pl;tnWN?cO>#*`jTgVXsqUt)AFF*^Kq7k`EYRzV9KgqZ5m zD0Ff$F@uYVna}`zsIZ9&ZM-kweIem?!kvVfC6|~bm)1h|EC&sA(7;RMzY$)!eaO6s{OX;NYs z3l3w!VN5-Ysjox{aU}*;L5mV2A^d*GQg{vCAYU6F=gaM6;KeX6uB;;A8WJ$3BaGeJ|-9q^G=L%DaN;uVDHs zHrPh`1kxvx-i?pr*Y0E(A;TyM(nydFJK!1O$B4g0_zoF#WC){zaIR){b2YOUmcnvK zx<8R_SWuyYjj$Ph2X8|+NIk>!c$f}fA>9?yjo#t|G)fPzRq!3Dgw^mES1ZL_t(0=r zqPS|&6W>gHEAf@YR}t?{ya(|#^coHQ_89SX#Cs8MApRWj=ZSA3-bTDH@qUC)6Yd}! zNH~bF$(4v{JTM2oWe$8p55J*@-}(^tg{+QmgJBGegSX)wZdl^DVTtEvgrU2^(A}KQ zMaK*{8_tF4Fau(#n^@{59lJ@#Zql%ue8&vELK?2}0W^#W`6SNDRHebxANaxM=?(NQZiSJNAJRF65Ulu0w9ooqI?Yz$>ejV}2&;f_prAZe= zy2aCQ_xXH;FXHpSrL|mkgT0y0KsY~I3~yyGc4sg4fOmv^LC1Heg6~cx-x>DqQ1PnQ$WEBuIG?l((#uFdx`ioB1+tF({eD z2QFzZEQBR+6C`6&Cd{&0X6k;TOoeQ(C2X^u(9Th2J4cyp$kJ+NX*DwsnwbYD=CU2n zgYhr{ronXbm65N4pBr3dyT8V^Jeh6T6>foBVF4^;TW6wv!bJUK9`sk@d8Wtn(>Swj z^wwS1nJDdbN_%}Ak4@mYZGb7T7dqI?nItAAiHTO4Xk})&5Sfv%7S=2A29xRyCe<6X z<_%i2U604+2IF8nWVUX%;kgn2Ch>1(!5rv>W0aeffajK|L{>ZO#AEZrV>3dUzk}xQ zaKIrvw`4rGjW8SL;<0(+v3Wt3)lQbxP7AEXAtU`R(&t9ufW^RW*aN9BmkNIyi~|-1 zD`6EMi{Fm$Fp4J@fhV>cZh$GU2lnETrQ(^T;fd+-#OT3pdb*pQ?!E=b@yMp(kxhq; z-`kAe+oRBlBc^b~^pJ++(~$gl$oS{tfsYAB#P-Xb&yglLR+Fda{R}?4iYb zXz^Ywv=R!Aa;G%39(EmQ@)fbUz!QC;C@()hsXOe-XA3YLGmAD4jg0-RABlFOkXhq zN8uPBiwY`ypPs!>&khIT;srq}I!r}J!twATVF@h5!;8bii-%Rvf`^BxKfu%4wm#nY?D!*j#KbBDdqfrm#uA5l*=^G{Ukc}ReXxOgP2Az=;S8p0OB z7Qz<77A=e^Ett|W2#4|TqVVuyU;!+|!^0xSu*k8Qa2CvhIj|Gj@%Uo!_~Kw8EWy(= zdEx3Ac%Ub>^rRNk)MA?BMqIr>NDq$FgX80PdIFD+0_!NS4ind5VrvDSUnQQN2Ogg% zWGLzxiUx+Pfgx+CgN^VkJjeBvAJ*(L!$#Pw1#QNdS0WR*V0V|Z!dFka2C!!HMs9*;bWK%&l4a(LdH$)lP zq|YXOHtBa#!OlWdg33?@szg=Df@+bep8qr`Z9pj~6{Vqclz}o)7Ro_+ zh)Q>Hwwj|I24a4Htz9z z6;N3Ll@(A~0hJX{Q2`Ye6k3OTbsaLcm{t{&pqPZk)KW~Q;xxT1B5_d#B0~`wifCC; z2`WRCs0vw7EviRNh=vrk?SDr1ta;%xIxp#Aj(SG-f+>*_lMwALPC==p8q>?FHbj%F zI*}c9qaM_Y9B2rQpi$)1%W4Di)XSQD=!X=FLUAaDcvzE)Xlb<%B2SIGUItX_3AiBw z)gH(T`643iv)r1+x6=X@5QKuMb1vC=x}X7!-%%^|FC94WwxxO#^8fNOOXU zPEgSaDmp<$CoHHI)uSe4Lv5%Xb?W8G5=5Sp)^XYav~WmX5+(?0R`hQ#a~Cy~u%v&e%z zGa^$I|A|3?C>VvK4ag5AphT2}!cZIvLXjvQrJ_8PkJ3;E%0iW>1eKu*l!*#ZI?6$X zCO~GTgz8Z{>OoD&hB{F?hn$-hSfxN!L%Be#+}7-$fd8 zk;*R8xQjI4VjiN7i&=Wv=Zmy=cKvJeA{j4I@kJ`WNW~W^tj`^JA}?e>KFC8a9SRvy k97;n4s1}ibK#%-TJfgyZGGs%PIY_=iDjg)>U^*)KKX+|FOaK4? diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 7df2acc7e..a11a7ae72 100755 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -1167,12 +1167,12 @@ int set_dac(int file_des) { if (val != -1) { //changing dac changes settings to undefined switch(serverDacIndex) { - case VCMP_LL: - case VCMP_LR: - case VCMP_RL: - case VCMP_RR: - case VRF: - case VCP: + case E_VCMP_LL: + case E_VCMP_LR: + case E_VCMP_RL: + case E_VCMP_RR: + case E_VRF: + case E_VCP: setSettings(UNDEFINED); FILE_LOG(logERROR, ("Settings has been changed " "to undefined (changed specific dacs)\n")); @@ -2495,6 +2495,13 @@ int send_update(int file_des) { if (n < 0) return printSocketReadError(); #endif + // num udp interfaces +#ifdef JUNGFRAUD + i32 = getNumberofUDPInterfaces(); + n = sendData(file_des,&i32,sizeof(i32),INT32); + if (n < 0) return printSocketReadError(); +#endif + if (lockStatus == 0) { lastClientIP = thisClientIP; } diff --git a/slsDetectorSoftware/include/multiSlsDetector.h b/slsDetectorSoftware/include/multiSlsDetector.h index c493f933b..2e880fd2c 100755 --- a/slsDetectorSoftware/include/multiSlsDetector.h +++ b/slsDetectorSoftware/include/multiSlsDetector.h @@ -221,93 +221,24 @@ class multiSlsDetector : public virtual slsDetectorDefs { void parallelCall(void (slsDetector::*somefunc)(CT...) const, typename NonDeduced::type... Args) const; - /** - * Set acquiring flag in shared memory - * @param b acquiring flag - */ - void setAcquiringFlag(bool flag); // + /** set acquiring flag in shared memory */ + void setAcquiringFlag(bool flag); - /** - * Get acquiring flag from shared memory - * @returns acquiring flag - */ - bool getAcquiringFlag() const; // + /** return multi detector shared memory ID */ + int getMultiId() const; - /** - * Check version compatibility with detector software - * (if hostname/rx_hostname has been set/ sockets created) - * @param p port type control port or receiver port - * @param detPos -1 for all detectors in list or specific detector position - */ - void checkDetectorVersionCompatibility(int detPos = -1); // - - /** - * Check version compatibility with receiver software - * (if hostname/rx_hostname has been set/ sockets created) - * @param p port type control port or receiver port - * @param detPos -1 for all detectors in list or specific detector position - */ - void checkReceiverVersionCompatibility(int detPos = -1); // - - /** - * Get ID or version numbers - * @param mode version type - * @param detPos -1 for all detectors in list or specific detector position - * @returns Id or version number of that type - */ - int64_t getId(idMode mode, - int detPos = -1); // not needed anymore (later remove - // this_software_version from enum) - - int getMultiId() const { return multiId; } // part of multi also - - /** - * Get package version (git branch) - * @returns package version - */ std::string getPackageVersion() const; - /** - * Get Client Software version - * @returns client software version - */ - int64_t getClientSoftwareVersion() const; // + int64_t getClientSoftwareVersion() const; - /** - * Get Receiver software version - * @return receiver software version - */ - int64_t getReceiverSoftwareVersion(int detPos = -1); // + /** Free specific shared memory from the command line without creating object */ + static void freeSharedMemory(int multiId, int detPos = -1); - /** - * Get Detector Number - * @returns vector of detector number - */ - std::vector - getDetectorNumber(); // renamed to getDetectorSerialNumber - /** - * Free shared memory from the command line - * avoiding creating the constructor classes and mapping - * @param multiId multi detector Id - * @param detPos -1 for all detectors in list or specific detector position - */ - static void freeSharedMemory(int multiId, - int detPos = -1); // private or not needed + /** Free all modules from current multi Id shared memory and delete members */ + void freeSharedMemory(); - /** - * Free shared memory and delete shared memory structure - * occupied by the sharedMultiSlsDetector structure - * Clears all the vectors and bring - * object back to state before object creation amap - * @param detPos -1 for all detectors in list or specific detector position - */ - void freeSharedMemory(int detPos = -1); // - - /** - * Get user details of shared memory - * @returns string with user details - */ - std::string getUserDetails(); // part of multi + /** Get user details of shared memory */ + std::string getUserDetails(); /** * Connect to Virtual Detector Servers at local host @@ -316,1248 +247,27 @@ class multiSlsDetector : public virtual slsDetectorDefs { */ void setVirtualDetectorServers(const int numdet, const int port); - /** - * Sets the hostname of all sls detectors in shared memory and updates local - * cache - * @param name hostname of all the sls detectors - */ - void setHostname( - const std::vector &name); // cannot set individually + /** Sets the hostname of all sls detectors in shared memory and updates local cache */ + void setHostname(const std::vector &name); - /** - * Sets the hostname of all sls detectors in shared memory - * Connects to them - * @param name concatenated hostname of all the sls detectors - * @param detPos -1 for all detectors in list or specific detector position - */ - void setHostname(const char *name, int detPos = -1); // not needed + /** Gets the total number of detectors */ + int size() const; - /** - * Gets the hostname of detector at particular position - * or concatenated hostnames of all the sls detectors - * @param detPos -1 for all detectors in list or specific detector position - * @returns concatenated hostnames of all detectors or hostname of specific - * one - */ - std::string getHostname(int detPos = -1) const; // + slsDetectorDefs::xy getNumberOfDetectors() const; - /** - * Get Detector type as an enum - * @returns detector type - */ - detectorType getDetectorTypeAsEnum() const; // + slsDetectorDefs::xy getNumberOfChannels() const; - /** - * Get Detector type for a particular sls detector or get the first one - * @param detPos -1 for all detectors in list or specific detector position - * @returns detector type of sls detector in position pos, if -1, returns - * the first det type - */ - detectorType getDetectorTypeAsEnum(int detPos); // + /** Must be set before setting hostname + * Sets maximum number of channels of all sls detectors */ + void setNumberOfChannels(const slsDetectorDefs::xy c); - /** - * Concatenates string types of all sls detectors or - * returns the detector type of the first sls detector - * @param detPos -1 for all detectors in list or specific detector position - * @returns detector type of sls detector in position pos, if -1, - * concatenates - */ - std::string getDetectorTypeAsString(int detPos = -1); // - - /** - * Returns the number of detectors in the multidetector structure - * @returns number of detectors - */ - size_t size() const; // - - /** - * Returns the number of detectors in each direction - */ - slsDetectorDefs::xy getNumberOfDetectors() const; // - - /** - * Returns the total number of channels of all sls detectors including gap - * pixels - * @param detPos -1 for all detectors in list or specific detector position - * @returns the total number of channels of all sls detectors including gap - * pixels - */ - slsDetectorDefs::xy getNumberOfChannels(int detPos = -1) const; // - - /** - * Must be set before setting hostname - * Sets maximum number of channels of all sls detectors in each - * dimension d from shared memory - * @param c maximum number of channels of all sls detectors - */ - void setNumberOfChannels(const slsDetectorDefs::xy c); // - - /** - * Get Quad Type (Only for Eiger Quad detector hardware) - * @param detPos -1 for all detectors in list or specific detector position - * @returns quad type - */ - int getQuad(int detPos = -1); // - - /** - * Set Quad Type (Only for Eiger Quad detector hardware) - * @param enable true if quad type set, else false - * @param detPos -1 for all detectors in list or specific detector position - */ - void setQuad(const bool enable, int detPos = -1); // - - /** - * Set number of rows to read out (Only for Eiger) - * @param value number of lines - * @param detPos -1 for all detectors in list or specific detector position - */ - void setReadNLines(const int value, int detPos = -1); // - - /** - * Get number of rows to read out (Only for Eiger) - * @param detPos -1 for all detectors in list or specific detector position - * @returns number of lines - */ - int getReadNLines(int detPos = -1); // - - /** - * Set/Gets TCP Port of the detector - * @param port_number (-1 gets) - * @param detPos -1 for all detectors in list or specific detector position - * @returns port number - */ - int setControlPort(int port_number = -1, int detPos = -1); // - - /** - * Set/Gets TCP STOP Port of the detector - * @param port_number (-1 gets) - * @param detPos -1 for all detectors in list or specific detector position - * @returns port number - */ - int setStopPort(int port_number = -1, int detPos = -1); // - - /** - * Set/Gets TCP Port of the receiver - * @param port_number (-1 gets) - * @param detPos -1 for all detectors in list or specific detector position - * @returns port number - */ - int setReceiverPort(int port_number = -1, int detPos = -1); // - - /** - * Get Receiver port - * @param detPos -1 for all detectors in list or specific detector position - * @returns vector of receiver port - */ - int getReceiverPort(int detPos = -1) const; // - - /** - * Lock server for this client IP - * @param p 0 to unlock, 1 to lock - * @param detPos -1 for all detectors in list or specific detector position - * @returns 1 for locked or 0 for unlocked - */ - int lockServer(int p = -1, int detPos = -1); // - - /** - * Exit detector server - * @param detPos -1 for all detectors in list or specific detector position - */ - void exitServer(int detPos = -1); // - - /** - * Execute a command on the detector server - * @param cmd command - * @param detPos -1 for all detectors in list or specific detector position - */ - void execCommand(const std::string &cmd, int detPos); // - - /** - * Load configuration from a configuration File - * @param fname configuration file name - */ - void readConfigurationFile(const std::string &fname); // - - /** - * Write current configuration to a file - * @param fname configuration file name - */ - void writeConfigurationFile(const std::string &fname); // - - /** - * Get detector settings - * @param detPos -1 for all detectors in list or specific detector position - * @returns current settings - */ - detectorSettings getSettings(int detPos = -1); // - - /** - * Load detector settings from the settings file picked from the - * trimdir/settingsdir Eiger only stores in shared memory ( a get will - * overwrite this) For Eiger, one must use threshold - * @param isettings settings - * @param detPos -1 for all detectors in list or specific detector position - * @returns current settings - */ - detectorSettings setSettings(detectorSettings isettings, - int detPos = -1); // - - /** - * Get threshold energy (Eiger) - * @param detPos -1 for all detectors in list or specific detector position - * @returns current threshold value for imod in ev (-1 failed) - */ - int getThresholdEnergy(int detPos = -1); // - - /** - * Set threshold energy (Eiger) - * @param e_eV threshold in eV - * @param isettings ev. change settings - * @param tb 1 to include trimbits, 0 to exclude - * @param detPos -1 for all detectors in list or specific detector position - * @returns current threshold value for imod in ev (-1 failed) - */ - int setThresholdEnergy(int e_eV, detectorSettings isettings = GET_SETTINGS, - int tb = 1, int detPos = -1); // - - /** - * Returns the detector trimbit/settings directory - * @param detPos -1 for all detectors in list or specific detector position - * @returns the trimbit/settings directory - */ - std::string getSettingsDir(int detPos = -1); // - - /** - * Sets the detector trimbit/settings directory - * @param s trimbits/settings directory - * @param detPos -1 for all detectors in list or specific detector position - * @returns the trimbit/settings directory - */ - std::string setSettingsDir(const std::string &directory, - int detPos = -1); // - - /** - * Loads the modules settings/trimbits reading from a specific file - * file name extension is automatically generated. - * @param fname specific settings/trimbits file - * @param detPos -1 for all detectors in list or specific detector position - */ - void loadSettingsFile(const std::string &fname, int detPos = -1); // - - /** - * Saves the modules settings/trimbits to a specific file - * file name extension is automatically generated. - * @param fname specific settings/trimbits file - * @param detPos -1 for all detectors in list or specific detector position - */ - void saveSettingsFile(const std::string &fname, int detPos = -1); // - - /** - * Configures in detector the destination for UDP packets - * @param detPos -1 for all detectors in list or specific detector position - */ - //void configureMAC(int detPos = -1); //TODO - - /** - * Set starting frame number for the next acquisition - * @param val starting frame number - * @param detPos -1 for all detectors in list or specific detector position - */ - void setStartingFrameNumber(const uint64_t value, int detPos = -1); // - - /** - * Get starting frame number for the next acquisition - * @param detPos -1 for all detectors in list or specific detector position - * @returns starting frame number - */ - uint64_t getStartingFrameNumber(int detPos = -1); // - - /** - * Set/get timer value (not all implemented for all detectors) - * @param index timer index - * @param t time in ns or number of...(e.g. frames, probes) - * @param detPos -1 for all detectors in list or specific detector position - * @returns timer set value in ns or number of...(e.g. frames, - * probes) - */ - int64_t setTimer(timerIndex index, int64_t t = -1, int detPos = -1); // - - /** - * Set/get exposure time - * @param t time (-1 gets) - * @param inseconds true if the value is in s, else ns - * @param detPos -1 for all detectors in list or specific detector position - * @returns exposure time in ns, or s if specified - */ - double setExposureTime(double t = -1, bool inseconds = false, - int detPos = -1); // - - /** - * Set/get exposure period - * @param t time (-1 gets) - * @param inseconds true if the value is in s, else ns - * @param detPos -1 for all detectors in list or specific detector position - * @returns exposure period in ns, or s if specified - */ - double setExposurePeriod(double t = -1, bool inseconds = false, - int detPos = -1); // - - /** - * Set/get delay after trigger (Gotthard, Jungfrau(not for this release)) - * @param t time (-1 gets) - * @param inseconds true if the value is in s, else ns - * @param detPos -1 for all detectors in list or specific detector position - * @returns delay after trigger in ns, or s if specified - */ - double setDelayAfterTrigger(double t = -1, bool inseconds = false, - int detPos = -1); // - - /** - * (Advanced users) - * Set/get sub frame exposure time (Eiger in 32 bit mode) - * @param t time (-1 gets) - * @param inseconds true if the value is in s, else ns - * @param detPos -1 for all detectors in list or specific detector position - * @returns sub frame exposure time in ns, or s if specified - */ - double setSubFrameExposureTime(double t = -1, bool inseconds = false, - int detPos = -1); // - - /** - * (Advanced users) - * Set/get sub frame dead time (Eiger in 32 bit mode) - * @param t time (-1 gets) - * @param inseconds true if the value is in s, else ns - * @param detPos -1 for all detectors in list or specific detector position - * @returns sub frame dead time in ns, or s if specified - */ - double setSubFrameExposureDeadTime(double t = -1, bool inseconds = false, - int detPos = -1); // - - /** - * Set/get number of frames - * @param t number of frames (-1 gets) - * @param detPos -1 for all detectors in list or specific detector position - * @returns number of frames - */ - int64_t setNumberOfFrames(int64_t t = -1, int detPos = -1); // - - /** - * Set/get number of triggers - * @param t number of triggers (-1 gets) - * @param detPos -1 for all detectors in list or specific detector position - * @returns number of triggers - */ - int64_t setNumberOfTriggers(int64_t t = -1, int detPos = -1); // - - /** - * Set/get number of additional storage cells (Jungfrau) - * @param t number of additional storage cells. Default is 0. (-1 gets) - * @param detPos -1 for all detectors in list or specific detector position - * @returns number of additional storage cells - */ - int64_t setNumberOfStorageCells(int64_t t = -1, int detPos = -1); // - - /** - * Get measured period between previous two frames (EIGER) - * @param t time (-1 gets) - * @param inseconds true if the value is in s, else ns - * @param detPos -1 for all detectors in list or specific detector position - * @returns sub frame dead time in ns, or s if specified - */ - double getMeasuredPeriod(bool inseconds = false, int detPos = -1); // - - /** - * Get sub period between previous two sub frames in 32 bit mode (EIGER) - * @param t time (-1 gets) - * @param inseconds true if the value is in s, else ns - * @param detPos -1 for all detectors in list or specific detector position - * @returns sub frame dead time in ns, or s if specified - */ - double getMeasuredSubFramePeriod(bool inseconds = false, - int detPos = -1); // - - /** - * Set/get timer value left in acquisition (not all implemented for all - * detectors) - * @param index timer index - * @param t time in ns or number of...(e.g. frames, probes) - * @param detPos -1 for all detectors in list or specific detector position - * @returns timer set value in ns or number of...(e.g. frames, - * probes) - */ - int64_t getTimeLeft(timerIndex index, int detPos = -1); // - - /** - * Set speed - * @param sp speed type (clkdivider option for Jungfrau and Eiger, - * adcphase for Gotthard, others for CTB & Moench) - * @param value (clkdivider 0,1,2 for full, half and quarter speed). Other - * values check manual - * @param mode 0 for shift, 1 for degrees. relevant only for speed type - * adcphase and dbit phase - * @param detPos -1 for all detectors in list or specific detector position - * @returns value of speed set - */ - int setSpeed(speedVariable index, int value = -1, int mode = 0, - int detPos = -1); // - - /** - * Set/get dynamic range and updates the number of dataBytes - * (Eiger: If i is 32, also sets clkdivider to 2, if 16, sets clkdivider to - * 1) - * @param i dynamic range (-1 get) - * @param detPos -1 for all detectors in list or specific detector position - * @returns current dynamic range - */ - int setDynamicRange(int dr = -1, int detPos = -1); // - - /** - * Set/get dacs value - * @param val value (in V) - * @param index DAC index - * @param mV 0 in dac units or 1 in mV - * @param detPos -1 for all detectors in list or specific detector position - * @returns current DAC value - */ - int setDAC(int val, dacIndex index, int mV, int detPos = -1); // - - /** - * Get adc value - * @param index adc(DAC) index - * @param detPos -1 for all detectors in list or specific detector position - * @returns current adc value (temperature for eiger and jungfrau in - * millidegrees) - */ - int getADC(dacIndex index, int detPos = -1); // - - /** - * Set/get timing mode - * @param pol timing mode (-1 gets) - * @param detPos -1 for all detectors in list or specific detector position - * @returns current timing mode - */ - timingMode setTimingMode(timingMode pol = GET_TIMING_MODE, - int detPos = -1); // - - /** - * Set/get external signal flags (to specify triggerinrising edge etc) - * (Gotthard, Mythen) - * @param pol external signal flag (-1 gets) - * @param detPos -1 for all detectors in list or specific detector position - * @returns current timing mode - */ - externalSignalFlag - setExternalSignalFlags(externalSignalFlag pol = GET_EXTERNAL_SIGNAL_FLAG, - int detPos = -1); // - - /** - * Set readout mode (Only for CTB and Moench) - * @param mode readout mode Options: ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL - * @param detPos -1 for all detectors in list or specific detector position - */ - void setReadoutMode(const readoutMode mode, int detPos = -1); - - /** - * Get readout mode(Only for CTB and Moench) - * @param detPos -1 for all detectors in list or specific detector position - * @returns readout mode - */ - readoutMode getReadoutMode(int detPos = -1); - - /** - * Set Interrupt last sub frame (Only for Eiger) - * @param enable true if interrupt last subframe set, else false - * @param detPos -1 for all detectors in list or specific detector position - */ - void setInterruptSubframe(const bool enable, int detPos = -1); - - /** - * Get Interrupt last sub frame (Only for Eiger) - * @param detPos -1 for all detectors in list or specific detector position - * @returns 1 if interrupt last subframe set, else 0, -1 different values - */ - int getInterruptSubframe(int detPos = -1); - - /** - * Write in a register. For Advanced users - * @param addr address of register - * @param val value to write into register - * @param detPos -1 for all detectors in list or specific detector position - * @returns value read after writing - */ - uint32_t writeRegister(uint32_t addr, uint32_t val, int detPos = -1); // - - /** - * Read from a register. For Advanced users - * @param addr address of register - * @param detPos -1 for all detectors in list or specific detector position - * @returns value read from register - */ - uint32_t readRegister(uint32_t addr, int detPos = -1); // - - /** - * Set bit in a register. For Advanced users - * @param addr address of register - * @param n nth bit - * @param detPos -1 for all detectors in list or specific detector position - * @returns value read from register - */ - uint32_t setBit(uint32_t addr, int n, int detPos = -1); // - - /** - * Clear bit in a register. For Advanced users - * @param addr address of register - * @param n nth bit - * @param detPos -1 for all detectors in list or specific detector position - * @returns value read from register - */ - uint32_t clearBit(uint32_t addr, int n, int detPos = -1); // - - /** - * Validates and sets the receiver. - * Also updates the receiver with all the shared memory parameters - * significant for the receiver Also configures the detector to the receiver - * as UDP destination - * @param receiver receiver hostname or IP address - * @param detPos -1 for all detectors in list or specific detector position - * @returns the receiver IP address from shared memory - */ - std::string setReceiverHostname(const std::string &receiver, - int detPos = -1); // - - /** - * Returns the receiver IP address - * @param detPos -1 for all detectors in list or specific detector position - * @returns the receiver IP address - */ - std::string getReceiverHostname(int detPos = -1) const; // - - /** - * ets the number of UDP interfaces to stream data from detector (Jungfrau - * only) - * @param n number of interfaces. Options 1 or 2. - * @param detPos -1 for all detectors in list or specific detector position - */ - void setNumberofUDPInterfaces(int n, int detPos = -1); // - - /** - * Returns the number of UDP interfaces to stream data from detector - * (Jungfrau only) - * @param detPos -1 for all detectors in list or specific detector position - * @returns the number of interfaces - */ - int getNumberofUDPInterfaces(int detPos = -1) ; // - - /** - * Selects the UDP interfaces to stream data from detector. Effective only - * when number of interfaces is 1. (Jungfrau only) - * @param n selected interface. Options 1 or 2. - * @param detPos -1 for all detectors in list or specific detector position - */ - void selectUDPInterface(int n, int detPos = -1); - - /** - * Returns the UDP interfaces to stream data from detector. Effective only - * when number of interfaces is 1. (Jungfrau only) - * @param detPos -1 for all detectors in list or specific detector position - * @returns the interface selected - */ - int getSelectedUDPInterface(int detPos = -1) ; // - - /** - * (advanced users) - * Set/Get client streaming in ZMQ port and restarts client sockets - * @param i sets, -1 gets - * If detPos is -1(multi module), port calculated (increments) for all the - * individual detectors using i - * @param detPos -1 for all detectors in list or specific detector position - */ - void setClientDataStreamingInPort(int i = -1, int detPos = -1); - - /** - * Returns the client zmq port - * If detPos is -1(multi module), port returns client streaming port of - * first module - * @param detPos -1 for all detectors in list or specific detector position - * @returns the client zmq port - */ - int getClientStreamingPort(int detPos = -1); // - - /** - * (advanced users) - * Set/Get receiver streaming out ZMQ port and restarts receiver sockets - * @param i sets, -1 gets - * If detPos is -1(multi module), port calculated (increments) for all the - * individual detectors using i - * @param detPos -1 for all detectors in list or specific detector position - */ - void setReceiverDataStreamingOutPort(int i = -1, int detPos = -1); // - - /** - * Returns the receiver zmq port - * If detPos is -1(multi module), port returns receiver streaming port of - * first module - * @param detPos -1 for all detectors in list or specific detector position - * @returns the receiver zmq port - */ - int getReceiverStreamingPort(int detPos = -1); // - - /** - * Sets the transmission delay for left, right or entire frame - * (Eiger, Jungfrau(only entire frame)) - * @param index type of delay - * @param delay delay - * @param detPos -1 for all detectors in list or specific detector position - * @returns transmission delay - */ - int setDetectorNetworkParameter(networkParameter index, int delay, - int detPos = -1); // maybe not needed in API - - /** - * Sets the additional json header - * @param jsonheader additional json header - * @param detPos -1 for all detectors in list or specific detector position - * @returns additional json header, default is empty - */ - std::string setAdditionalJsonHeader(const std::string &jsonheader, - int detPos = -1); // - - /** - * Returns the additional json header - * @param detPos -1 for all detectors in list or specific detector position - * @returns the additional json header, default is empty - */ - std::string getAdditionalJsonHeader(int detPos = -1); // - - /** - * Sets the value for the additional json header parameter if found, else - * append it - * @param key additional json header parameter - * @param value additional json header parameter value (cannot be empty) - * @param detPos -1 for all detectors in list or specific detector position - * @returns the additional json header parameter value, - * empty if no parameter found in additional json header - */ - std::string setAdditionalJsonParameter(const std::string &key, - const std::string &value, - int detPos = -1); // - - /** - * Returns the additional json header parameter value - * @param key additional json header parameter - * @param detPos -1 for all detectors in list or specific detector position - * @returns the additional json header parameter value, - * empty if no parameter found in additional json header - */ - std::string getAdditionalJsonParameter(const std::string &key, - int detPos = -1); // - - /** - * Sets the detector minimum/maximum energy threshold in processor (for - * Moench only) - * @param index 0 for emin, antyhing else for emax - * @param v value to set (-1 gets) - * @returns detector minimum/maximum energy threshold (-1 for not found or - * error in computing json parameter value) - */ - int setDetectorMinMaxEnergyThreshold(const int index, int value, - int detPos = -1); // - - /** - * Sets the frame mode in processor (Moench only) - * @param value frameModeType (-1 gets) - * @param detPos -1 for all detectors in list or specific detector position - * @returns frame mode (-1 for not found or error in computing json - * parameter value) - */ - int setFrameMode(frameModeType value, int detPos = -1); - - /** - * Sets the detector mode in processor (Moench only) - * @param value detectorModetype (-1 gets) - * @param detPos -1 for all detectors in list or specific detector position - * @returns detector mode (-1 for not found or error in computing json - * parameter value) - */ - int setDetectorMode(detectorModeType value, int detPos = -1); - - /** - * Sets the receiver UDP socket buffer size - * @param udpsockbufsize additional json header - * @param detPos -1 for all detectors in list or specific detector position - * @returns receiver udp socket buffer size - */ - int64_t setReceiverUDPSocketBufferSize(int64_t udpsockbufsize = -1, - int detPos = -1); // - - /** - * Returns the receiver UDP socket buffer size - * @param detPos -1 for all detectors in list or specific detector position - * @returns the receiver UDP socket buffer size - */ - int64_t getReceiverUDPSocketBufferSize(int detPos = -1); // - - /** - * Returns the receiver real UDP socket buffer size - * @param detPos -1 for all detectors in list or specific detector position - * @returns the receiver real UDP socket buffer size - */ - int64_t getReceiverRealUDPSocketBufferSize(int detPos = -1); // - - /** (users only) - * Set 10GbE Flow Control (Eiger) - * @param enable 1 to set, 0 to unset, -1 gets - * @param detPos -1 for all detectors in list or specific detector position - * @returns 10GbE flow Control - */ - int setFlowControl10G(int enable = -1, int detPos = -1); // - - /** - * Execute a digital test (Gotthard, Jungfrau, CTB) - * @param mode testmode type - * @param value 1 to set or 0 to clear the image test bit (Gotthard) - * @param detPos -1 for all detectors in list or specific detector position - * @returns result of test - */ - int digitalTest(digitalTestMode mode, int ival = -1, int detPos = -1); - - /** - * Set/get counter bit in detector (Eiger) - * @param i is -1 to get, 0 to reset and any other value to set the counter - * bit - * @param detPos -1 for all detectors in list or specific detector position - * @returns the counter bit in detector - */ - int setCounterBit(int i = -1, int detPos = -1); // - - /** - * Clear ROI (Gotthard) - * @param detPos -1 for all detectors in list or specific detector position - */ - void clearROI(int detPos = -1); - - /** - * Set ROI (Gotthard) - * At the moment only one set allowed per module - * Only allowed to set one ROI per module - * @param arg roi - * @param detPos specific detector position - */ - void setROI(slsDetectorDefs::ROI arg, int detPos = -1); - - /** - * Get ROI (Gotthard) - * Only allowed to set one ROI per module - * @param detPos specific detector position - * @returns roi - */ - slsDetectorDefs::ROI getROI(int detPos) const; - - /** - * Set ADC Enable Mask (CTB, Moench) - * @param mask ADC Enable mask - * @param detPos -1 for all detectors in list or specific detector position - */ - void setADCEnableMask(uint32_t mask, int detPos = -1); // - - /** - * Get ADC Enable Mask (CTB, Moench) - * @param detPos -1 for all detectors in list or specific detector position - * @returns ADC Enable mask - */ - uint32_t getADCEnableMask(int detPos = -1); // - - /** - * Set ADC invert register (CTB, Moench) - * @param value ADC invert value - * @param detPos -1 for all detectors in list or specific detector position - */ - void setADCInvert(uint32_t value, int detPos = -1); // - - /** - * Get ADC invert register (CTB, Moench) - * @param detPos -1 for all detectors in list or specific detector position - * @returns ADC invert value - */ - uint32_t getADCInvert(int detPos = -1); // - - /** - * Set external sampling source (CTB only) - * @param value external sampling source (Option: 0-63) - * @param detPos -1 for all detectors in list or specific detector position - */ - void setExternalSamplingSource(int value, int detPos = -1); // - - /** - * Get external sampling source (CTB only) - * @param detPos -1 for all detectors in list or specific detector position - * @returns external sampling source - */ - int getExternalSamplingSource(int detPos = -1); // - - /** - * Set external sampling enable (CTB only) - * @param value external sampling source (Option: 0-63) - * @param detPos -1 for all detectors in list or specific detector position - */ - void setExternalSampling(bool value, int detPos = -1); // - - /** - * Get external sampling source (CTB only) - * @param detPos -1 for all detectors in list or specific detector position - * @returns external sampling enable - */ - int getExternalSampling(int detPos = -1); // - - /** - * Set external sampling enable (CTB only) - * @param list external sampling source (Option: 0-63) - * @param detPos -1 for all detectors in list or specific detector position - */ - void setReceiverDbitList(std::vector list, int detPos = -1); // - - /** - * Get external sampling source (CTB only) - * @param detPos -1 for all detectors in list or specific detector position - * @returns external sampling enable - */ - std::vector getReceiverDbitList(int detPos = -1); // - - /** - * Set digital data offset in bytes (CTB only) - * @param value digital data offset in bytes - * @param detPos -1 for all detectors in list or specific detector position - */ - void setReceiverDbitOffset(int value, int detPos = -1); // - - /** - * Get digital data offset in bytes (CTB only) - * @param detPos -1 for all detectors in list or specific detector position - * @returns digital data offset in bytes - */ - int getReceiverDbitOffset(int detPos = -1); // - - /** - * Write to ADC register (Gotthard, Jungfrau, ChipTestBoard). For expert - * users - * @param addr address of adc register - * @param val value - * @param detPos -1 for all detectors in list or specific detector position - */ - void writeAdcRegister(uint32_t addr, uint32_t val, int detPos = -1); // - - /** - * Activates/Deactivates the detector (Eiger only) - * @param enable active (1) or inactive (0), -1 gets - * @param detPos -1 for all detectors in list or specific detector position - * @returns 0 (inactive) or 1 (active)for activate mode - */ - int activate(int const enable = -1, int detPos = -1); // - - /** - * Set deactivated Receiver padding mode (Eiger only) - * @param padding padding option for deactivated receiver. Can be 1 - * (padding), 0 (no padding), -1 (gets) - * @param detPos -1 for all detectors in list or specific detector position - * @returns 1 (padding), 0 (no padding), -1 (inconsistent values) for - * padding option - */ - int setDeactivatedRxrPaddingMode(int padding = -1, int detPos = -1); - - /** - * Returns the enable if data will be flipped across x axis (Eiger) - * @param detPos -1 for all detectors in list or specific detector position - * @returns 1 for flipped, else 0 - */ - int getFlippedDataX(int detPos = -1); // - - /** - * Sets the enable which determines if - * data will be flipped across x axis (Eiger) - * @param value 0 or 1 to reset/set or -1 to get value - * @param detPos -1 for all detectors in list or specific detector position - * @returns enable flipped data across x or y axis - */ - int setFlippedDataX(int value = -1, int detPos = -1); // - - /** - * Sets all the trimbits to a particular value (Eiger) - * @param val trimbit value - * @param detPos -1 for all detectors in list or specific detector position - * @returns OK or FAIL - */ - int setAllTrimbits(int val, int detPos = -1); // + void readConfigurationFile(const std::string &fname); /** * Enable gap pixels, only for Eiger and for 8,16 and 32 bit mode. (Eiger) * 4 bit mode gap pixels only in gui call back - * @param val 1 sets, 0 unsets, -1 gets - * @returns gap pixel enable or -1 for error */ - int enableGapPixels(int val = -1, int detPos = -1); // - - void setGapPixelsEnable(bool enable, sls::Positions pos = {}); - /** - * Sets the number of trim energies and their value (Eiger) - * - * @param nen number of energies - * @param en array of energies - * @param detPos -1 for all detectors in list or specific detector position - * @returns number of trim energies - */ - int setTrimEn(std::vector energies, int detPos = -1); // - - /** - * Returns the number of trim energies and their value (Eiger) - * - * @param detPos -1 for all detectors in list or specific detector position - * @returns vector of trim energies - */ - std::vector getTrimEn(int detPos = -1); // - - /** - * Pulse Pixel (Eiger) - * @param n is number of times to pulse - * @param x is x coordinate - * @param y is y coordinate - * @param detPos -1 for all detectors in list or specific detector position - */ - void pulsePixel(int n = 0, int x = 0, int y = 0, int detPos = -1); // - - /** - * Pulse Pixel and move by a relative value (Eiger) - * @param n is number of times to pulse - * @param x is relative x value - * @param y is relative y value - * @param detPos -1 for all detectors in list or specific detector position - */ - void pulsePixelNMove(int n = 0, int x = 0, int y = 0, int detPos = -1); // - - /** - * Pulse Chip (Eiger) - * @param n is number of times to pulse - * @param detPos -1 for all detectors in list or specific detector position - */ - void pulseChip(int n = 0, int detPos = -1); // - - /** - * Set/gets threshold temperature (Jungfrau) - * @param val value in millidegrees, -1 gets - * @param detPos -1 for all detectors in list or specific detector position - * @returns threshold temperature in millidegrees - */ - int setThresholdTemperature(int val = -1, int detPos = -1); // - - /** - * Enables/disables temperature control (Jungfrau) - * @param val value, -1 gets - * @param detPos -1 for all detectors in list or specific detector position - * @returns temperature control enable - */ - int setTemperatureControl(int val = -1, int detPos = -1); // - - /** - * Resets/ gets over-temperature event (Jungfrau) - * @param val value, -1 gets - * @param detPos -1 for all detectors in list or specific detector position - * @returns over-temperature event - */ - int setTemperatureEvent(int val = -1, int detPos = -1); // - - /** - * Set storage cell that stores first acquisition of the series (Jungfrau) - * @param value storage cell index. Value can be 0 to 15. (-1 gets) - * @param detPos -1 for all detectors in list or specific detector position - * @returns the storage cell that stores the first acquisition of the series - */ - int setStoragecellStart(int pos = -1, int detPos = -1); // - - /** - * Programs FPGA with pof file (Jungfrau, CTB, Moench) - * @param fname file name - * @param detPos -1 for all detectors in list or specific detector position - */ - void programFPGA(const std::string &fname, int detPos = -1); // - - /** - * Resets FPGA (Jungfrau, CTB, Moench) - * @param detPos -1 for all detectors in list or specific detector position - */ - void resetFPGA(int detPos = -1); // - - /** - * Copies detector server from tftp and changes respawn server (Not Eiger) - * @param fname name of detector server binary - * @param hostname name of pc to tftp from - * @param detPos -1 for all detectors in list or specific detector position - */ - void copyDetectorServer(const std::string &fname, - const std::string &hostname, int detPos = -1); // - - /** - * Reboot detector controller (Not Eiger) - * @param detPos -1 for all detectors in list or specific detector position - */ - void rebootController(int detPos = -1); // - - /** - * Updates the firmware, detector server and then reboots detector - * controller blackfin. (Not Eiger) - * @param sname name of detector server binary - * @param hostname name of pc to tftp from - * @param fname programming file name - * @param detPos -1 for all detectors in list or specific detector position - */ - void update(const std::string &sname, const std::string &hostname, - const std::string &fname, int detPos = -1); // - - /** - * Power on/off Chip (Jungfrau) - * @param ival on is 1, off is 0, -1 to get - * @param detPos -1 for all detectors in list or specific detector position - * @returns OK or FAIL - */ - int powerChip(int ival = -1, int detPos = -1); // - - /** - * Automatic comparator disable (Jungfrau) - * @param ival on is 1, off is 0, -1 to get - * @param detPos -1 for all detectors in list or specific detector position - * @returns OK or FAIL - */ - int setAutoComparatorDisableMode(int ival = -1, int detPos = -1); // - - /** - * Set Default Rate correction from trimbit file ( Eiger) - * @param detPos -1 for all detectors in list or specific detector position - */ - void setDefaultRateCorrection(int detPos = -1); // - - /** - * Set Rate correction ( Eiger) - * @param t dead time in ns - if 0 disable correction, - * if >0 set dead time to t, cannot be < 0 - * @param detPos -1 for all detectors in list or specific detector position - */ - void setRateCorrection(int64_t t = 0, int detPos = -1); // - - /** - * Get rate correction ( Eiger) - * @param detPos -1 for all detectors in list or specific detector position - * @returns 0 if rate correction disabled, > 0 otherwise (ns) - */ - int64_t getRateCorrection(int detPos = -1); // - - /** - * Prints receiver configuration - * @param detPos -1 for all detectors in list or specific detector position - * @returns receiver configuration - */ - std::string printReceiverConfiguration(int detPos = -1); // - - /** - * Get receiver online status - * @param detPos -1 for all detectors in list or specific detector position - * @returns use receiver flag - */ - bool getUseReceiverFlag(int detPos = -1); // - - /** - * Locks/Unlocks the connection to the receiver - * @param lock sets (1), usets (0), gets (-1) the lock - * @param detPos -1 for all detectors in list or specific detector position - * @returns lock status of the receiver - */ - int lockReceiver(int lock = -1, int detPos = -1); // - - /** - * Turns off the receiver server! - * @param detPos -1 for all detectors in list or specific detector position - */ - void exitReceiver(int detPos = -1); - - /** - * Executes a system command on the receiver server - * e.g. mount an nfs disk, reboot and returns answer etc. - * @param cmd command to be executed - * @param detPos -1 for all detectors in list or specific detector position - */ - void execReceiverCommand(const std::string &cmd, int detPos = -1); - - /** - * Returns output file directory - * @param detPos -1 for all detectors in list or specific detector position - * @returns output file directory - */ - std::string getFilePath(int detPos = -1); // - - /** - * Sets up the file directory - * @param detPos -1 for all detectors in list or specific detector position - * @param s file directory - * @returns file dir - */ - std::string setFilePath(const std::string &path, int detPos = -1); // - - /** - * Returns file name prefix - * @param detPos -1 for all detectors in list or specific detector position - * @returns file name prefix - */ - std::string getFileName(int detPos = -1); // - - /** - * Sets up the file name prefix - * @param detPos -1 for all detectors in list or specific detector position - * @param s file name prefix - * @returns file name prefix - */ - std::string setFileName(const std::string &fname, int detPos = -1); // - - /** - * Sets the max frames per file in receiver - * @param f max frames per file - * @param detPos -1 for all detectors in list or specific detector position - * @returns max frames per file in receiver - */ - int setFramesPerFile(int f = -1, int detPos = -1); // - - /** - * Gets the max frames per file in receiver - * @param detPos -1 for all detectors in list or specific detector position - * @returns max frames per file in receiver - */ - int getFramesPerFile(int detPos = -1) const; // - - /** - * Sets the frames discard policy in receiver - * @param f frames discard policy - * @param detPos -1 for all detectors in list or specific detector position - * @returns frames discard policy set in receiver - */ - frameDiscardPolicy setReceiverFramesDiscardPolicy( - frameDiscardPolicy f = GET_FRAME_DISCARD_POLICY, int detPos = -1); // - - /** - * Sets the partial frames padding enable in receiver - * @param f partial frames padding enable - * @param detPos -1 for all detectors in list or specific detector position - * @returns partial frames padding enable in receiver - */ - int setPartialFramesPadding(bool padding, int detPos = -1); // - - int getPartialFramesPadding(int detPos = -1) const; // - - /** - * Returns file format - * @param detPos -1 for all detectors in list or specific detector position - * @returns file name - */ - fileFormat getFileFormat(int detPos = -1); // - - /** - * Sets up the file format - * @param f file format - * @param detPos -1 for all detectors in list or specific detector position - * @returns file format - */ - fileFormat setFileFormat(fileFormat f, int detPos = -1); // - - /** - * Sets up the file index - * @param i file index - * @param detPos -1 for all detectors in list or specific detector position - * @returns file index - */ - int64_t setFileIndex(int64_t i, int detPos = -1); // - - /** - * Get File index - * @param detPos -1 for all detectors in list or specific detector - * position - * @returns file index - */ - int64_t getFileIndex(int detPos = -1) const; // - - /** - * Gets the number of frames caught by receiver - * @param detPos -1 for all detectors in list or specific detector position - * @returns number of frames caught by receiver - */ - int getFramesCaughtByReceiver(int detPos = -1); // - - /** - * Gets the current frame index of receiver - * @param detPos -1 for all detectors in list or specific detector position - * @returns average of all current frame index of receiver - */ - uint64_t getReceiverCurrentFrameIndex(int detPos = -1); // - - /** - * Sets/Gets receiver file write enable - * @param value 1 or 0 to set/reset file write enable - * @param detPos -1 for all detectors in list or specific detector position - * @returns file write enable - */ - int setFileWrite(bool value, int detPos = -1); // - - /** - * Gets file write enable - * @returns file write enable - */ - int getFileWrite(int detPos = -1) const; // - - /** - * Sets/Gets receiver master file write enable - * @param value 1 or 0 to set/reset master file write enable - * @param detPos -1 for all detectors in list or specific detector position - * @returns master file write enable - */ - int setMasterFileWrite(bool value, int detPos = -1); // - - /** - * Gets master file write enable - * @param detPos -1 for all detectors in list or specific detector position - * @returns master file write enable - */ - int getMasterFileWrite(int detPos = -1) const; // - - /** - * Sets/Gets file overwrite enable - * @param enable 1 or 0 to set/reset file overwrite enable - * @param detPos -1 for all detectors in list or specific detector position - * @returns file overwrite enable - */ - int setFileOverWrite(bool enable, int detPos = -1); // - - /** - * Gets file over write enable - * @param detPos -1 for all detectors in list or specific detector position - * @returns file over write enable - */ - int getFileOverWrite(int detPos = -1) const; // - - /** - * (previously setReadReceiverFrequency) - * Sets the receiver streaming frequency - * @param freq nth frame streamed out, if 0, streamed out at a timer of 200 - * ms - * @param detPos -1 for all detectors in list or specific detector position - * @returns receiver streaming frequency - */ - int setReceiverStreamingFrequency(int freq = -1, int detPos = -1); - - /** - * (previously setReceiverReadTimer) - * Sets the receiver streaming timer - * If receiver streaming frequency is 0, then this timer between each - * data stream is set. Default is 200 ms. - * @param time_in_ms timer between frames - * @param detPos -1 for all detectors in list or specific detector position - * @returns receiver streaming timer in ms - */ - int setReceiverStreamingTimer(int time_in_ms = 200, int detPos = -1); // + void setGapPixelsinReceiver(bool enable); /** * Enable data streaming to client @@ -1566,145 +276,8 @@ class multiSlsDetector : public virtual slsDetectorDefs { */ bool enableDataStreamingToClient(int enable = -1); - /** - * Enable or disable streaming data from receiver to client - * @param enable 0 to disable 1 to enable -1 to only get the value - * @param detPos -1 for all detectors in list or specific detector position - * @returns data streaming from receiver enable - */ - int enableDataStreamingFromReceiver(int enable = -1, int detPos = -1); + void savePattern(const std::string &fname); - /** - * Enable/disable or 10Gbe - * @param i is -1 to get, 0 to disable and 1 to enable - * @param detPos -1 for all detectors in list or specific detector position - * @returns if 10Gbe is enabled - */ - int enableTenGigabitEthernet(int i = -1, int detPos = -1); // - - /** - * Set/get receiver fifo depth - * @param i is -1 to get, any other value to set the fifo deph - * @param detPos -1 for all detectors in list or specific detector position - * @returns the receiver fifo depth - */ - int setReceiverFifoDepth(int i = -1, int detPos = -1); // - - /** - * Set/get receiver silent mode - * @param i is -1 to get, 0 unsets silent mode, 1 sets silent mode - * @param detPos -1 for all detectors in list or specific detector position - * @returns the receiver silent mode enable - */ - int setReceiverSilentMode(int i = -1, int detPos = -1); // - - /** - * Opens pattern file and sends pattern (CTB/ Moench) - * @param fname pattern file to open - * @param detPos -1 for all detectors in list or specific detector position - */ - void setPattern(const std::string &fname, int detPos = -1); // - - /** - * Executes and saves pattern to file (CTB/ Moench) - * @param fname pattern file to save to - */ - void savePattern(const std::string &fname); // - - /** - * Sets pattern IO control (CTB/ Moench) - * @param word 64bit word to be written, -1 gets - * @param detPos -1 for all detectors in list or specific detector position - * @returns actual value - */ - uint64_t setPatternIOControl(uint64_t word = -1, int detPos = -1); // - - /** - * Sets pattern clock control (CTB/ Moench) - * @param word 64bit word to be written, -1 gets - * @param detPos -1 for all detectors in list or specific detector position - * @returns actual value - */ - uint64_t setPatternClockControl(uint64_t word = -1, int detPos = -1); // - - /** - * Writes a pattern word (CTB/ Moench) - * @param addr address of the word - * @param word 64bit word to be written, -1 reads the addr (same as - * executing the pattern) - * @param detPos -1 for all detectors in list or specific detector position - * @returns actual value - */ - uint64_t setPatternWord(int addr, uint64_t word, int detPos = -1); // - - /** - * Sets the wait address (CTB/ Moench) - * @param level 0,1,2, wait level - * @param addr wait address, -1 gets - * @param detPos -1 for all detectors in list or specific detector position - * @returns actual value - */ - int setPatternWaitAddr(int level, int addr = -1, int detPos = -1); // - - /** - * Sets the wait time (CTB/ Moench) - * @param level 0,1,2, wait level - * @param t wait time, -1 gets - * @param detPos -1 for all detectors in list or specific detector position - * @returns actual value - */ - uint64_t setPatternWaitTime(int level, uint64_t t = -1, int detPos = -1); // - - /** - * Sets the mask applied to every pattern (CTB/ Moench) - * @param mask mask to be applied - * @param detPos -1 for all detectors in list or specific detector position - */ - void setPatternMask(uint64_t mask, int detPos = -1); // - - /** - * Gets the mask applied to every pattern (CTB/ Moench) - * @param detPos -1 for all detectors in list or specific detector position - * @returns mask set - */ - uint64_t getPatternMask(int detPos = -1); // - - /** - * Selects the bits that the mask will be applied to for every pattern (CTB/ - * Moench) - * @param mask mask to select bits - * @param detPos -1 for all detectors in list or specific detector position - */ - void setPatternBitMask(uint64_t mask, int detPos = -1); // - - /** - * Gets the bits that the mask will be applied to for every pattern (CTB/ - * Moench) - * @param detPos -1 for all detectors in list or specific detector position - * @returns mask of bits selected - */ - uint64_t getPatternBitMask(int detPos = -1); // - - /** - * Set LED Enable (Moench, CTB only) - * @param enable 1 to switch on, 0 to switch off, -1 gets - * @param detPos -1 for all detectors in list or specific detector position - * @returns LED enable - */ - int setLEDEnable(int enable = -1, int detPos = -1); // - - /** - * Set Digital IO Delay (Moench, CTB only) - * @param digital IO mask to select the pins - * @param delay delay in ps(1 bit=25ps, max of 775 ps) - * @param detPos -1 for all detectors in list or specific detector position - */ - void setDigitalIODelay(uint64_t pinMask, int delay, int detPos = -1); // - - /** - * Loads the detector setup from file - * @param fname file to read from - */ void loadParameters(const std::string &fname); /** @@ -1736,7 +309,7 @@ class multiSlsDetector : public virtual slsDetectorDefs { * index, loops for measurements, calls required call backs. * @returns OK or FAIL depending on if it already started */ - int acquire(); // + int acquire(); /** * Combines data from all readouts and gives it to the gui @@ -1763,72 +336,33 @@ class multiSlsDetector : public virtual slsDetectorDefs { void setupMultiDetector(bool verify = true, bool update = true); /** - * Initialize (open/create) shared memory for the sharedMultiDetector - * structure + * Creates shm and initializes shm structure OR + * Open shm and maps to structure * @param verify true to verify if shm size matches existing one * @param update true to update last user pid, date etc - * @returns true if shared memory was created in this call, else false */ void initSharedMemory(bool verify = true); - /** - * Initialize detector structure for the shared memory just created - */ + /** Initialize detector structure for the shared memory just created */ void initializeDetectorStructure(); - /** - * Initialize class members (and from parent classes) + /** Initialize members (eg. slsDetectors from shm, zmqsockets) * @param verify true to verify if shm size matches existing one */ void initializeMembers(bool verify = true); - /** - * Update user details in detector structure - */ + /** Update in shm */ void updateUserdetails(); - /** - * Check if acquiring flag is set, set error if set - * @returns FAIL if not ready, OK if ready - */ bool isAcquireReady(); - /** - * Execute in command line and return result - * @param cmd command - * @returns result - */ + /** Execute command in terminal and return result */ std::string exec(const char *cmd); - /** - * Add sls detector - * @param s hostname of the single detector - */ void addSlsDetector(const std::string &hostname); - /** - * Updates the channel size in X and Y dimension for all the sls - * detectors - */ void updateDetectorSize(); - /** - * increments file index - * @param detPos -1 for all detectors in list or specific detector position - * @returns the file index - */ - int64_t incrementFileIndex(int detPos = -1); - - /** - * add gap pixels to the image (only for Eiger in 4 bit mode) - * @param image pointer to image without gap pixels - * @param gpImage poiner to image with gap pixels, if NULL, allocated - * inside function - * quadEnable quad enabled - * @returns number of data bytes of image with gap pixels - */ - int processImageWithGapPixels(char *image, char *&gpImage, bool quadEnable); - /** * Create Receiving Data Sockets * @param destroy is true to destroy all the sockets @@ -1843,31 +377,23 @@ class multiSlsDetector : public virtual slsDetectorDefs { void readFrameFromReceiver(); /** - * Set total progress (total number of frames/images in an acquisition) - * @returns total progress + * add gap pixels to the image (only for Eiger in 4 bit mode) + * @param image pointer to image without gap pixels + * @param gpImage poiner to image with gap pixels, if NULL, allocated + * inside function + * quadEnable quad enabled + * @returns number of data bytes of image with gap pixels */ + int processImageWithGapPixels(char *image, char *&gpImage, bool quadEnable); + int setTotalProgress(); - /** - * Get progress in current acquisition - * @returns current progress - */ double getCurrentProgress(); - /** - * Increment progress by one - */ void incrementProgress(); - /** - * Set current progress to argument - * @param i current progress - */ void setCurrentProgress(int i = 0); - /** - * Start data processing thread - */ void startProcessingThread(); /** diff --git a/slsDetectorSoftware/include/slsDetector.h b/slsDetectorSoftware/include/slsDetector.h index 5faf2806b..01a7c74b2 100755 --- a/slsDetectorSoftware/include/slsDetector.h +++ b/slsDetectorSoftware/include/slsDetector.h @@ -169,6 +169,9 @@ struct sharedSlsDetector { /** reciever dbit offset */ int rxDbitOffset; + + /** num udp interfaces */ + int numUDPInterfaces; }; class slsDetector : public virtual slsDetectorDefs { @@ -258,13 +261,7 @@ class slsDetector : public virtual slsDetectorDefs { * Get Detector type from shared memory variable * @returns detector type from shared memory variable */ - detectorType getDetectorTypeAsEnum() const; - - /** - * Gets string version of detector type from shared memory variable - * @returns string version of detector type from shared memory variable - */ - std::string getDetectorTypeAsString() const; + detectorType getDetectorType() const; /** * Gets detector type from detector and set it in receiver @@ -554,8 +551,6 @@ class slsDetector : public virtual slsDetectorDefs { */ int setDynamicRange(int n = -1); - int getDynamicRangeFromShm(); - /** * Set/get dacs value * @param val value (in V) @@ -848,6 +843,9 @@ class slsDetector : public virtual slsDetectorDefs { */ void setNumberofUDPInterfaces(int n); + /** Returns the number of udp interfaces from shared memory */ + int getNumberofUDPInterfacesFromShm(); + /** * Returns the number of UDP interfaces to stream data from detector * (Jungfrau only) diff --git a/slsDetectorSoftware/include/slsDetectorCommand.h b/slsDetectorSoftware/include/slsDetectorCommand.h index 396ed1666..450b4006c 100755 --- a/slsDetectorSoftware/include/slsDetectorCommand.h +++ b/slsDetectorSoftware/include/slsDetectorCommand.h @@ -33,16 +33,7 @@ class slsDetectorCommand : public virtual slsDetectorDefs { std::vector getAllCommands(); - - /* /\** */ - /* returns the help for the executeLine command */ - /* \param os output stream to return the help to */ - /* \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) */ - /* *\/ */ - std::string helpLine(int narg, const char * const args[], int action=HELP_ACTION, int detPos = -1); static std::string helpAcquire(int action); - static std::string helpFree(int action); - static std::string helpSN(int action); static std::string helpConfiguration(int action); @@ -51,9 +42,6 @@ class slsDetectorCommand : public virtual slsDetectorDefs { std::string cmdUnknown(int narg, const char * const args[], int action, int detPos = -1); std::string cmdAcquire(int narg, const char * const args[], int action, int detPos = -1); - std::string cmdFree(int narg, const char * const args[], int action, int detPos = -1); - std::string cmdHelp(int narg, const char * const args[], int action, int detPos = -1); - std::string cmdSN(int narg, const char * const args[], int action, int detPos = -1); std::string cmdConfiguration(int narg, const char * const args[], int action, int detPos = -1); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 74b957000..d91ba39fd 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -67,7 +67,7 @@ Result Detector::getReceiverVersion(Positions pos) const { } Result Detector::getDetectorType(Positions pos) const { - return pimpl->Parallel(&slsDetector::getDetectorTypeAsEnum, pos); + return pimpl->Parallel(&slsDetector::getDetectorType, pos); } int Detector::size() const { return pimpl->size(); } @@ -173,7 +173,7 @@ Result Detector::getSpeed(Positions pos) const { auto res = pimpl->Parallel(&slsDetector::setSpeed, pos, defs::CLOCK_DIVIDER, -1, 0); Result speedResult(res.size()); - for (size_t i = 0; i < res.size(); ++i) { + for (unsigned int i = 0; i < res.size(); ++i) { speedResult[i] = static_cast(res[i]); } return speedResult; @@ -314,7 +314,7 @@ void Detector::stopReceiver() { } void Detector::startDetector() { - if (getDetectorType({}).squash() == defs::EIGER) { + if (getDetectorType().squash() == defs::EIGER) { pimpl->Parallel(&slsDetector::prepareAcquisition, {}); } pimpl->Parallel(&slsDetector::startAcquisition, {}); @@ -782,7 +782,9 @@ Result Detector::getDynamicRange(Positions pos) const { return pimpl->Parallel(&slsDetector::setDynamicRange, pos, -1); } -void Detector::setDynamicRange(int value) { pimpl->setDynamicRange(value); } +void Detector::setDynamicRange(int value) { + pimpl->Parallel(&slsDetector::setDynamicRange, {}, value); +} Result Detector::getSubExptime(Positions pos) const { return pimpl->Parallel(&slsDetector::setTimer, pos, @@ -832,7 +834,7 @@ Result Detector::getRxAddGapPixels(Positions pos) const { } void Detector::setRxAddGapPixels(bool enable) { - pimpl->setGapPixelsEnable(enable, {}); + pimpl->setGapPixelsinReceiver(enable); } Result Detector::getParallelMode(Positions pos) const { @@ -968,7 +970,13 @@ Result Detector::getQuad(Positions pos) const { return pimpl->Parallel(&slsDetector::getQuad, pos); } -void Detector::setQuad(const bool value) { pimpl->setQuad(value); } +void Detector::setQuad(const bool value) { + if (value && size() > 1) { + throw RuntimeError("Cannot set Quad type as it is available only for 1 " + "Eiger Quad Half module."); + } + pimpl->Parallel(&slsDetector::setQuad, {}, value); +} // Jungfrau Specific @@ -1007,8 +1015,8 @@ Result Detector::getPowerChip(Positions pos) const { void Detector::setPowerChip(bool on, Positions pos) { if ((pos.empty() || pos[0] == -1) && on && pimpl->size() > 3) { - for (unsigned int i = 0; i != pimpl->size(); ++i) { - pimpl->powerChip(static_cast(on), i); + for (int i = 0; i != pimpl->size(); ++i) { + pimpl->Parallel(&slsDetector::powerChip, {i}, static_cast(on)); usleep(1000 * 1000); } } else { @@ -1618,12 +1626,12 @@ Result Detector::getRxCurrentFrameIndex(Positions pos) const { std::vector Detector::getPortNumbers(int start_port) { int num_sockets_per_detector = 1; - switch (getDetectorType({}).squash()) { + switch (getDetectorType().squash()) { case defs::EIGER: num_sockets_per_detector *= 2; break; case defs::JUNGFRAU: - if (getNumberofUDPInterfaces({}).squash() == 2) { + if (getNumberofUDPInterfaces().squash() == 2) { num_sockets_per_detector *= 2; } break; diff --git a/slsDetectorSoftware/src/multiSlsDetector.cpp b/slsDetectorSoftware/src/multiSlsDetector.cpp index f1f7288e7..8f6a40994 100755 --- a/slsDetectorSoftware/src/multiSlsDetector.cpp +++ b/slsDetectorSoftware/src/multiSlsDetector.cpp @@ -136,53 +136,12 @@ void multiSlsDetector::setAcquiringFlag(bool flag) { multi_shm()->acquiringFlag = flag; } -bool multiSlsDetector::getAcquiringFlag() const { - return multi_shm()->acquiringFlag; -} - -void multiSlsDetector::checkDetectorVersionCompatibility(int detPos) { - if (detPos >= 0) { - detectors[detPos]->checkDetectorVersionCompatibility(); - } - - parallelCall(&slsDetector::checkDetectorVersionCompatibility); -} - -void multiSlsDetector::checkReceiverVersionCompatibility(int detPos) { - if (detPos >= 0) { - detectors[detPos]->checkReceiverVersionCompatibility(); - } - - parallelCall(&slsDetector::checkReceiverVersionCompatibility); -} - -int64_t multiSlsDetector::getId(idMode mode, int detPos) { - if (detPos >= 0) { - return detectors[detPos]->getId(mode); - } - - auto r = parallelCall(&slsDetector::getId, mode); - return sls::minusOneIfDifferent(r); -} +int multiSlsDetector::getMultiId() const { return multiId; } std::string multiSlsDetector::getPackageVersion() const { return GITBRANCH; } int64_t multiSlsDetector::getClientSoftwareVersion() const { return APILIB; } -int64_t multiSlsDetector::getReceiverSoftwareVersion(int detPos) { - if (detPos >= 0) { - return detectors[detPos]->getReceiverSoftwareVersion(); - } - - auto r = parallelCall(&slsDetector::getReceiverSoftwareVersion); - return sls::minusOneIfDifferent(r); -} - -std::vector multiSlsDetector::getDetectorNumber() { - return parallelCall(&slsDetector::getId, - slsDetectorDefs::DETECTOR_SERIAL_NUMBER); -} - void multiSlsDetector::freeSharedMemory(int multiId, int detPos) { // single if (detPos >= 0) { @@ -209,14 +168,7 @@ void multiSlsDetector::freeSharedMemory(int multiId, int detPos) { } } -void multiSlsDetector::freeSharedMemory(int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->freeSharedMemory(); - return; - } - - // multi +void multiSlsDetector::freeSharedMemory() { zmqSocket.clear(); for (auto &d : detectors) { d->freeSharedMemory(); @@ -243,13 +195,13 @@ std::string multiSlsDetector::getUserDetails() { sstream << "\nType: "; // get type from multi shm if (multi_shm()->shmversion >= MULTI_SHMAPIVERSION) { - sstream << ToString(getDetectorTypeAsEnum()); + sstream << ToString(multi_shm()->multiDetectorType); } // get type from slsdet shm else { for (auto &d : detectors) { sstream << (d->isFixedPatternSharedMemoryCompatible() - ? d->getDetectorTypeAsString() + ? ToString(d->getDetectorType()) : "Unknown") << "+"; } @@ -327,10 +279,10 @@ bool multiSlsDetector::isAcquireReady() { << "Acquire has already started. " "If previous acquisition terminated unexpectedly, " "reset busy flag to restart.(sls_detector_put busy 0)"; - return FAIL != 0u; + return false; } multi_shm()->acquiringFlag = true; - return OK != 0u; + return true; } std::string multiSlsDetector::exec(const char *cmd) { @@ -382,40 +334,6 @@ void multiSlsDetector::setHostname(const std::vector &name) { updateDetectorSize(); } -void multiSlsDetector::setHostname(const char *name, int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->setHostname(name); - return; - } - - // multi - // this check is there only to allow the previous detsizechan command - if (multi_shm()->numberOfDetectors != 0) { - FILE_LOG(logWARNING) - << "There are already detector(s) in shared memory." - "Freeing Shared memory now."; - freeSharedMemory(); - setupMultiDetector(); - } - for (const auto &hostname : sls::split(name, '+')) { - addSlsDetector(hostname); - } - updateDetectorSize(); -} - -std::string multiSlsDetector::getHostname(int detPos) const { - // single - if (detPos >= 0) { - return detectors[detPos]->getHostname(); - } - - // multi - auto r = serialCall(&slsDetector::getHostname); - return sls::concatenateNonEmptyStrings(r); -} - - void multiSlsDetector::addSlsDetector(const std::string &hostname) { FILE_LOG(logINFO) << "Adding detector " << hostname; @@ -448,8 +366,8 @@ void multiSlsDetector::addSlsDetector(const std::string &hostname) { detectors[pos]->setControlPort(port); detectors[pos]->setStopPort(port + 1); detectors[pos]->setHostname(host); - multi_shm()->multiDetectorType = - getDetectorTypeAsEnum(-1); // -1 needed here + // detector type updated by now + multi_shm()->multiDetectorType = Parallel(&slsDetector::getDetectorType, {}).tsquash("Inconsistent detector types."); } void multiSlsDetector::updateDetectorSize() { @@ -487,46 +405,13 @@ void multiSlsDetector::updateDetectorSize() { } } -slsDetectorDefs::detectorType multiSlsDetector::getDetectorTypeAsEnum() const { - return multi_shm()->multiDetectorType; -} - -slsDetectorDefs::detectorType -multiSlsDetector::getDetectorTypeAsEnum(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getDetectorTypeAsEnum(); - } - - // multi - auto r = serialCall(&slsDetector::getDetectorTypeAsEnum); - return (detectorType)sls::minusOneIfDifferent(r); -} - -std::string multiSlsDetector::getDetectorTypeAsString(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getDetectorTypeAsString(); - } - - // multi - auto r = serialCall(&slsDetector::getDetectorTypeAsString); - return sls::concatenateIfDifferent(r); -} - -size_t multiSlsDetector::size() const { return detectors.size(); } +int multiSlsDetector::size() const { return detectors.size(); } slsDetectorDefs::xy multiSlsDetector::getNumberOfDetectors() const { return multi_shm()->numberOfDetector; } -slsDetectorDefs::xy multiSlsDetector::getNumberOfChannels(int detPos) const { - // single - if (detPos >= 0) { - return detectors[detPos]->getNumberOfChannels(); - } - - // multi +slsDetectorDefs::xy multiSlsDetector::getNumberOfChannels() const { return multi_shm()->numberOfChannels; } @@ -538,104 +423,6 @@ void multiSlsDetector::setNumberOfChannels(const slsDetectorDefs::xy c) { multi_shm()->numberOfChannels = c; } -int multiSlsDetector::getQuad(int detPos) { - int retval = detectors[0]->getQuad(); - if (retval && size() > 1) { - throw RuntimeError("Quad type is available only for 1 Eiger Quad Half " - "module, but Quad is enabled for 1st readout"); - } - return retval; -} - -void multiSlsDetector::setQuad(const bool enable, int detPos) { - if (enable && size() > 1) { - throw RuntimeError("Cannot set Quad type as it is available only for 1 " - "Eiger Quad Half module."); - } - - detectors[0]->setQuad(enable); -} - -void multiSlsDetector::setReadNLines(const int value, int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->setReadNLines(value); - } - - // multi - parallelCall(&slsDetector::setReadNLines, value); -} - -int multiSlsDetector::getReadNLines(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getReadNLines(); - } - - // multi - auto r = parallelCall(&slsDetector::getReadNLines); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setControlPort(int port_number, int detPos) { - if (detPos >= 0) { - return detectors[detPos]->setControlPort(port_number); - } - - auto r = serialCall(&slsDetector::setControlPort, port_number); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setStopPort(int port_number, int detPos) { - if (detPos >= 0) { - return detectors[detPos]->setStopPort(port_number); - } - - auto r = serialCall(&slsDetector::setStopPort, port_number); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setReceiverPort(int port_number, int detPos) { - if (detPos >= 0) { - return detectors[detPos]->setReceiverPort(port_number); - } - - auto r = serialCall(&slsDetector::setReceiverPort, port_number); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::getReceiverPort(int detPos) const { - if (detPos >= 0) { - return detectors[detPos]->getReceiverPort(); - } - - auto r = serialCall(&slsDetector::getReceiverPort); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::lockServer(int p, int detPos) { - if (detPos >= 0) { - return detectors[detPos]->lockServer(p); - } - auto r = parallelCall(&slsDetector::lockServer, p); - return sls::minusOneIfDifferent(r); -} - - -void multiSlsDetector::exitServer(int detPos) { - if (detPos >= 0) { - detectors[detPos]->exitServer(); - } - parallelCall(&slsDetector::exitServer); -} - -void multiSlsDetector::execCommand(const std::string &cmd, int detPos) { - if (detPos >= 0) { - detectors[detPos]->execCommand(cmd); - } - parallelCall(&slsDetector::execCommand, cmd); -} - void multiSlsDetector::readConfigurationFile(const std::string &fname) { freeSharedMemory(); setupMultiDetector(); @@ -662,1089 +449,9 @@ void multiSlsDetector::readConfigurationFile(const std::string &fname) { input_file.close(); } -void multiSlsDetector::writeConfigurationFile(const std::string &fname) { - // TODO! make exception safe! - const std::vector header{"detsizechan", "hostname"}; - std::ofstream outfile; - - outfile.open(fname.c_str(), std::ios_base::out); - if (outfile.is_open()) { - for (const auto &cmd : header) - multiSlsDetectorClient(cmd, GET_ACTION, this, outfile); - - // single detector configuration - for (auto &detector : detectors) { - outfile << '\n'; - auto det_commands = detector->getConfigFileCommands(); - for (const auto &cmd : det_commands) - multiSlsDetectorClient(cmd, GET_ACTION, this, outfile); - } - } else { - throw RuntimeError("Could not open configuration file " + fname + - " for writing"); - } -} - -slsDetectorDefs::detectorSettings multiSlsDetector::getSettings(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getSettings(); - } - - // multi - auto r = parallelCall(&slsDetector::getSettings); - return (detectorSettings)sls::minusOneIfDifferent(r); -} - -slsDetectorDefs::detectorSettings -multiSlsDetector::setSettings(detectorSettings isettings, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setSettings(isettings); - } - - // multi - auto r = parallelCall(&slsDetector::setSettings, isettings); - return (detectorSettings)sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::getThresholdEnergy(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getThresholdEnergy(); - } - - // multi - auto r = parallelCall(&slsDetector::getThresholdEnergy); - if (sls::allEqualWithTol(r, 200)) { - return r.front(); - } - return -1; -} - -int multiSlsDetector::setThresholdEnergy(int e_eV, detectorSettings isettings, - int tb, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setThresholdEnergy(e_eV, isettings, tb); - } - - // multi - auto r = - parallelCall(&slsDetector::setThresholdEnergy, e_eV, isettings, tb); - if (sls::allEqualWithTol(r, 200)) { - return r.front(); - } - return -1; -} - -std::string multiSlsDetector::getSettingsDir(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getSettingsDir(); - } - - // multi - auto r = serialCall(&slsDetector::getSettingsDir); - return sls::concatenateIfDifferent(r); -} - -std::string multiSlsDetector::setSettingsDir(const std::string &directory, - int detPos) { - if (detPos >= 0) { - return detectors[detPos]->setSettingsDir(directory); - } - - auto r = parallelCall(&slsDetector::setSettingsDir, directory); - return sls::concatenateIfDifferent(r); -} - -void multiSlsDetector::loadSettingsFile(const std::string &fname, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->loadSettingsFile(fname); - } - - // multi - parallelCall(&slsDetector::loadSettingsFile, fname); -} - -void multiSlsDetector::saveSettingsFile(const std::string &fname, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->saveSettingsFile(fname); - } - - // multi - parallelCall(&slsDetector::saveSettingsFile, fname); -} - - -void multiSlsDetector::setStartingFrameNumber(const uint64_t value, - int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setStartingFrameNumber(value); - } - - // multi - parallelCall(&slsDetector::setStartingFrameNumber, value); -} - -uint64_t multiSlsDetector::getStartingFrameNumber(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getStartingFrameNumber(); - } - - // multi - auto r = parallelCall(&slsDetector::getStartingFrameNumber); - if (sls::allEqual(r)) { - return r.front(); - } - - // can't have different values for next acquisition - std::ostringstream ss; - ss << "Error: Different Values for starting frame number"; - throw RuntimeError(ss.str()); -} - -int64_t multiSlsDetector::setTimer(timerIndex index, int64_t t, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setTimer(index, t); - } - - // multi - auto r = parallelCall(&slsDetector::setTimer, index, t); - return sls::minusOneIfDifferent(r); -} - -int64_t multiSlsDetector::secondsToNanoSeconds(double t) { - int64_t ns = lround(t * 1E9); - return (ns < 0) ? -1 : ns; -} - -double multiSlsDetector::setExposureTime(double t, bool inseconds, int detPos) { - if (!inseconds) { - return setTimer(ACQUISITION_TIME, (int64_t)t, detPos); - } - auto t_ns = setTimer(ACQUISITION_TIME, secondsToNanoSeconds(t), detPos); - return (t_ns < 0) ? -1 : 1E-9 * t_ns; -} - -double multiSlsDetector::setExposurePeriod(double t, bool inseconds, - int detPos) { - if (!inseconds) { - return setTimer(FRAME_PERIOD, (int64_t)t, detPos); - } - auto t_ns = setTimer(FRAME_PERIOD, secondsToNanoSeconds(t), detPos); - return (t_ns < 0) ? -1 : 1E-9 * t_ns; -} - -double multiSlsDetector::setDelayAfterTrigger(double t, bool inseconds, - int detPos) { - if (!inseconds) { - return setTimer(DELAY_AFTER_TRIGGER, (int64_t)t, detPos); - } - auto t_ns = setTimer(DELAY_AFTER_TRIGGER, secondsToNanoSeconds(t), detPos); - return (t_ns < 0) ? -1 : 1E-9 * t_ns; -} - -double multiSlsDetector::setSubFrameExposureTime(double t, bool inseconds, - int detPos) { - if (!inseconds) { - return setTimer(SUBFRAME_ACQUISITION_TIME, (int64_t)t, detPos); - } - auto t_ns = - setTimer(SUBFRAME_ACQUISITION_TIME, secondsToNanoSeconds(t), detPos); - return (t_ns < 0) ? -1 : 1E-9 * t_ns; -} - -double multiSlsDetector::setSubFrameExposureDeadTime(double t, bool inseconds, - int detPos) { - if (!inseconds) { - return setTimer(SUBFRAME_DEADTIME, (int64_t)t, detPos); - } - auto t_ns = setTimer(SUBFRAME_DEADTIME, secondsToNanoSeconds(t), detPos); - return (t_ns < 0) ? -1 : 1E-9 * t_ns; -} - -int64_t multiSlsDetector::setNumberOfFrames(int64_t t, int detPos) { - return setTimer(FRAME_NUMBER, t, detPos); -} - -int64_t multiSlsDetector::setNumberOfTriggers(int64_t t, int detPos) { - return setTimer(TRIGGER_NUMBER, t, detPos); -} - -int64_t multiSlsDetector::setNumberOfStorageCells(int64_t t, int detPos) { - return setTimer(STORAGE_CELL_NUMBER, t, detPos); -} - -double multiSlsDetector::getMeasuredPeriod(bool inseconds, int detPos) { - if (!inseconds) { - return getTimeLeft(MEASURED_PERIOD, detPos); - } else { - int64_t tms = getTimeLeft(MEASURED_PERIOD, detPos); - if (tms < 0) { - return -1; - } - return ((1E-9) * (double)tms); - } -} - -double multiSlsDetector::getMeasuredSubFramePeriod(bool inseconds, int detPos) { - if (!inseconds) { - return getTimeLeft(MEASURED_SUBPERIOD, detPos); - } else { - int64_t tms = getTimeLeft(MEASURED_SUBPERIOD, detPos); - if (tms < 0) { - return -1; - } - return ((1E-9) * (double)tms); - } -} - -int64_t multiSlsDetector::getTimeLeft(timerIndex index, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getTimeLeft(index); - } - - // multi - auto r = parallelCall(&slsDetector::getTimeLeft, index); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setSpeed(speedVariable index, int value, int mode, - int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setSpeed(index, value, mode); - } - - // multi - auto r = parallelCall(&slsDetector::setSpeed, index, value, mode); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setDynamicRange(int dr, int detPos) { - // single - if (detPos >= 0) { - throw RuntimeError("Dynamic Range cannot be set individually"); - } - - // multi - int prevValue = -1; - auto temp = Parallel(&slsDetector::getDynamicRangeFromShm, {}); - if (temp.equal()) { - prevValue = temp.squash(); - } - - auto r = parallelCall(&slsDetector::setDynamicRange, dr); - int ret = sls::minusOneIfDifferent(r); - - // change in dr - if (dr != -1 && dr != prevValue) { - - // update speed, check ratecorrection - if (getDetectorTypeAsEnum() == EIGER) { - - // rate correction before speed for consistency - // (else exception at speed makes ratecorr inconsistent) - parallelCall(&slsDetector::updateRateCorrection); - - // speed(usability) - switch (dr) { - case 32: - FILE_LOG(logINFO) - << "Setting Clock to Quarter Speed to cope with " - "Dynamic Range of 32"; - setSpeed(CLOCK_DIVIDER, 2); - break; - case 16: - FILE_LOG(logINFO) - << "Setting Clock to Half Speed for Dynamic Range of 16"; - setSpeed(CLOCK_DIVIDER, 1); - break; - default: - break; - } - } - } - - return ret; -} - -int multiSlsDetector::setDAC(int val, dacIndex index, int mV, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setDAC(val, index, mV); - } - - // multi - auto r = parallelCall(&slsDetector::setDAC, val, index, mV); - if (getDetectorTypeAsEnum() != EIGER && index != HIGH_VOLTAGE) { - return sls::minusOneIfDifferent(r); - } - - // ignore slave values for hv (-999) - int firstValue = r.front(); - for (const auto &value : r) { - if ((value != -999) && (value != firstValue)) { - return -1; - } - } - - return firstValue; -} - -int multiSlsDetector::getADC(dacIndex index, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getADC(index); - } - - // multi - auto r = parallelCall(&slsDetector::getADC, index); - return sls::minusOneIfDifferent(r); -} - -slsDetectorDefs::timingMode multiSlsDetector::setTimingMode(timingMode pol, - int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setTimingMode(pol); - } - - // multi - auto r = parallelCall(&slsDetector::setTimingMode, pol); - return sls::minusOneIfDifferent(r); -} - -slsDetectorDefs::externalSignalFlag -multiSlsDetector::setExternalSignalFlags(externalSignalFlag pol, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setExternalSignalFlags(pol); - } - - // multi - auto r = parallelCall(&slsDetector::setExternalSignalFlags, pol); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::setReadoutMode(const slsDetectorDefs::readoutMode mode, int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->setReadoutMode(mode); - } - - // multi - parallelCall(&slsDetector::setReadoutMode, mode); -} - -slsDetectorDefs::readoutMode multiSlsDetector::getReadoutMode(int detPos) { - // single - if (detPos >= 0) { - return (detectors[detPos]->getReadoutMode()); - } - - // multi - auto r = parallelCall(&slsDetector::getReadoutMode); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::setInterruptSubframe(const bool enable, int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->setInterruptSubframe(enable); - } - - // multi - parallelCall(&slsDetector::setInterruptSubframe, enable); -} - -int multiSlsDetector::getInterruptSubframe(int detPos) { - // single - if (detPos >= 0) { - return static_cast(detectors[detPos]->getInterruptSubframe()); - } - - // multi - auto r = parallelCall(&slsDetector::getInterruptSubframe); - return sls::minusOneIfDifferent(r); -} - -uint32_t multiSlsDetector::writeRegister(uint32_t addr, uint32_t val, - int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->writeRegister(addr, val); - } - - // multi - auto r = parallelCall(&slsDetector::writeRegister, addr, val); - if (sls::allEqual(r)) { - return r.front(); - } - - // can't have different values - std::ostringstream ss; - ss << "Error: Different Values for function writeRegister (write 0x" - << std::hex << val << " to addr 0x" << std::hex << addr << std::dec - << ")"; - throw RuntimeError(ss.str()); -} - -uint32_t multiSlsDetector::readRegister(uint32_t addr, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->readRegister(addr); - } - - // multi - auto r = parallelCall(&slsDetector::readRegister, addr); - if (sls::allEqual(r)) { - return r.front(); - } - - // can't have different values - std::ostringstream ss; - ss << "Error: Different Values for function readRegister (read from 0x" - << std::hex << addr << std::dec << ")"; - throw RuntimeError(ss.str()); -} - -uint32_t multiSlsDetector::setBit(uint32_t addr, int n, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setBit(addr, n); - } - - // multi - auto r = parallelCall(&slsDetector::setBit, addr, n); - if (sls::allEqual(r)) { - return r.front(); - } - - // can't have different values - std::ostringstream ss; - ss << "Error: Different Values for function setBit " - "(set bit " - << n << " to addr 0x" << std::hex << addr << std::dec << ")"; - throw RuntimeError(ss.str()); -} - -uint32_t multiSlsDetector::clearBit(uint32_t addr, int n, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->clearBit(addr, n); - } - - // multi - auto r = parallelCall(&slsDetector::clearBit, addr, n); - if (sls::allEqual(r)) { - return r.front(); - } - - // can't have different values - std::ostringstream ss; - ss << "Error: Different Values for function clearBit (clear bit " << n - << " to addr 0x" << std::hex << addr << std::dec << ")"; - throw RuntimeError(ss.str()); -} - -std::string multiSlsDetector::setReceiverHostname(const std::string &receiver, - int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setReceiverHostname(receiver); - } - - // multi - auto r = parallelCall(&slsDetector::setReceiverHostname, receiver); - return sls::concatenateIfDifferent(r); -} - -std::string multiSlsDetector::getReceiverHostname(int detPos) const { - // single - if (detPos >= 0) { - return detectors[detPos]->getReceiverHostname(); - } - - // multi - auto r = parallelCall(&slsDetector::getReceiverHostname); - return sls::concatenateIfDifferent(r); -} - - -void multiSlsDetector::setNumberofUDPInterfaces(int n, int detPos) { - - bool previouslyClientStreaming = enableDataStreamingToClient(); - int previouslyReceiverStreaming = enableDataStreamingFromReceiver(); - - // single - if (detPos >= 0) { - detectors[detPos]->setNumberofUDPInterfaces(n); - } - - // multi - parallelCall(&slsDetector::setNumberofUDPInterfaces, n); - - // redo the zmq sockets - if (previouslyClientStreaming) { - enableDataStreamingToClient(0); - enableDataStreamingToClient(1); - } - if (previouslyReceiverStreaming != 0) { - enableDataStreamingFromReceiver(0); - enableDataStreamingFromReceiver(1); - } -} - -int multiSlsDetector::getNumberofUDPInterfaces(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getNumberofUDPInterfaces(); - } - - // multi - auto r = parallelCall(&slsDetector::getNumberofUDPInterfaces); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::selectUDPInterface(int n, int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->selectUDPInterface(n); - } - - // multi - parallelCall(&slsDetector::selectUDPInterface, n); -} - -int multiSlsDetector::getSelectedUDPInterface(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getSelectedUDPInterface(); - } - - // multi - auto r = parallelCall(&slsDetector::getSelectedUDPInterface); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::setClientDataStreamingInPort(int i, int detPos) { - if (i >= 0) { - bool prev_streaming = enableDataStreamingToClient(); - - // single - if (detPos >= 0) { - detectors[detPos]->setClientStreamingPort(i); - } - // multi - else { - // calculate ports individually - int firstPort = i; - int numSockets = (getDetectorTypeAsEnum() == EIGER) ? 2 : 1; - if (getNumberofUDPInterfaces() == 2) - numSockets *= 2; - - for (size_t idet = 0; idet < detectors.size(); ++idet) { - auto port = firstPort + (idet * numSockets); - detectors[idet]->setClientStreamingPort(port); - } - } - - if (prev_streaming) { - enableDataStreamingToClient(0); - enableDataStreamingToClient(1); - } - } -} - -int multiSlsDetector::getClientStreamingPort(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getClientStreamingPort(); - } - - // multi - auto r = serialCall(&slsDetector::getClientStreamingPort); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::setReceiverDataStreamingOutPort(int i, int detPos) { - if (i >= 0) { - int prev_streaming = enableDataStreamingFromReceiver(-1, detPos); - - // single - if (detPos >= 0) { - detectors[detPos]->setReceiverStreamingPort(i); - } - // multi - else { - // calculate ports individually - int firstPort = i; - int numSockets = (getDetectorTypeAsEnum() == EIGER) ? 2 : 1; - if (getNumberofUDPInterfaces() == 2) - numSockets *= 2; - - for (size_t idet = 0; idet < detectors.size(); ++idet) { - auto port = firstPort + (idet * numSockets); - detectors[idet]->setReceiverStreamingPort(port); - } - } - - if (prev_streaming != 0) { - enableDataStreamingFromReceiver(0, detPos); - enableDataStreamingFromReceiver(1, detPos); - } - } -} - -int multiSlsDetector::getReceiverStreamingPort(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getReceiverStreamingPort(); - } - - // multi - auto r = serialCall(&slsDetector::getReceiverStreamingPort); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setDetectorNetworkParameter(networkParameter index, - int value, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setDetectorNetworkParameter(index, value); - } - - // multi - auto r = - parallelCall(&slsDetector::setDetectorNetworkParameter, index, value); - return sls::minusOneIfDifferent(r); -} - -std::string -multiSlsDetector::setAdditionalJsonHeader(const std::string &jsonheader, - int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setAdditionalJsonHeader(jsonheader); - } - - // multi - auto r = parallelCall(&slsDetector::setAdditionalJsonHeader, jsonheader); - return sls::concatenateIfDifferent(r); -} - -std::string multiSlsDetector::getAdditionalJsonHeader(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getAdditionalJsonHeader(); - } - - // multi - auto r = serialCall(&slsDetector::getAdditionalJsonHeader); - return sls::concatenateIfDifferent(r); -} - -std::string multiSlsDetector::setAdditionalJsonParameter( - const std::string &key, const std::string &value, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setAdditionalJsonParameter(key, value); - } - - // multi - auto r = parallelCall(&slsDetector::setAdditionalJsonParameter, key, value); - return sls::concatenateIfDifferent(r); -} - -std::string multiSlsDetector::getAdditionalJsonParameter(const std::string &key, - int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getAdditionalJsonParameter(key); - } - - // multi - auto r = serialCall(&slsDetector::getAdditionalJsonParameter, key); - return sls::concatenateIfDifferent(r); -} - -int multiSlsDetector::setDetectorMinMaxEnergyThreshold(const int index, - int value, int detPos) { - std::string parameter = (index != 0 ? "emax" : "emin"); - - std::string result; - if (value < 0) { - result = getAdditionalJsonParameter(parameter, detPos); - } else { - result = setAdditionalJsonParameter(parameter, std::to_string(value), - detPos); - } - - // convert to integer - try { - return stoi(result); - } - // not found or cannot scan integer - catch (...) { - return -1; - } -} - -int multiSlsDetector::setFrameMode(frameModeType value, int detPos) { - std::string parameter = "frameMode"; - std::string result; - - if (value == GET_FRAME_MODE) { - result = getAdditionalJsonParameter(parameter, detPos); - } else { - result = setAdditionalJsonParameter(parameter, sls::ToString(value), - detPos); - } - - return sls::StringTo(result); -} - -int multiSlsDetector::setDetectorMode(detectorModeType value, int detPos) { - std::string parameter = "detectorMode"; - std::string result; - - if (value == GET_DETECTOR_MODE) { - result = getAdditionalJsonParameter(parameter, detPos); - } else { - result = setAdditionalJsonParameter(parameter, - sls::ToString(value), detPos); - } - - return sls::StringTo(result); -} - -int64_t multiSlsDetector::setReceiverUDPSocketBufferSize(int64_t udpsockbufsize, - int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setReceiverUDPSocketBufferSize( - udpsockbufsize); - } - - // multi - auto r = parallelCall(&slsDetector::setReceiverUDPSocketBufferSize, - udpsockbufsize); - return sls::minusOneIfDifferent(r); -} - -int64_t multiSlsDetector::getReceiverUDPSocketBufferSize(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getReceiverUDPSocketBufferSize(); - } - - // multi - auto r = serialCall(&slsDetector::getReceiverUDPSocketBufferSize); - return sls::minusOneIfDifferent(r); -} - -int64_t multiSlsDetector::getReceiverRealUDPSocketBufferSize(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getReceiverRealUDPSocketBufferSize(); - } - - // multi - auto r = serialCall(&slsDetector::getReceiverRealUDPSocketBufferSize); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setFlowControl10G(int enable, int detPos) { - if (enable != -1) { - enable = ((enable >= 1) ? 1 : 0); - } - return setDetectorNetworkParameter(FLOW_CONTROL_10G, enable, detPos); -} - -int multiSlsDetector::digitalTest(digitalTestMode mode, int ival, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->digitalTest(mode, ival); - } - - // multi - auto r = parallelCall(&slsDetector::digitalTest, mode, ival); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setCounterBit(int i, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setCounterBit(i); - } - - // multi - auto r = parallelCall(&slsDetector::setCounterBit, i); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::clearROI(int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->clearROI(); - } - - // multi - parallelCall(&slsDetector::clearROI); -} - -void multiSlsDetector::setROI(slsDetectorDefs::ROI arg, int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->setROI(arg); - } - - // multi - if (detPos < 0 && size() > 1) { - throw RuntimeError("Cannot set ROI for all modules simultaneously"); - } - detectors[0]->setROI(arg); -} - -slsDetectorDefs::ROI multiSlsDetector::getROI(int detPos) const { - // single - if (detPos >= 0) { - return detectors[detPos]->getROI(); - } - - // multi - if (detPos < 0 && size() > 1) { - throw RuntimeError("Cannot get ROI for all modules simultaneously"); - } - return detectors[0]->getROI(); -} - -void multiSlsDetector::setADCEnableMask(uint32_t mask, int detPos) { - if (detPos >= 0) { - detectors[detPos]->setADCEnableMask(mask); - } - - parallelCall(&slsDetector::setADCEnableMask, mask); -} - -uint32_t multiSlsDetector::getADCEnableMask(int detPos) { - if (detPos >= 0) { - return detectors[detPos]->getADCEnableMask(); - } - - auto r = parallelCall(&slsDetector::getADCEnableMask); - if (sls::allEqual(r)) { - return r.front(); - } - - // can't have different values - throw RuntimeError("Error: Different Values for function getADCEnableMask"); -} - -void multiSlsDetector::setADCInvert(uint32_t value, int detPos) { - if (detPos >= 0) { - detectors[detPos]->setADCInvert(value); - } - - parallelCall(&slsDetector::setADCInvert, value); -} - -uint32_t multiSlsDetector::getADCInvert(int detPos) { - if (detPos >= 0) { - return detectors[detPos]->getADCInvert(); - } - - auto r = parallelCall(&slsDetector::getADCInvert); - if (sls::allEqual(r)) { - return r.front(); - } - - // can't have different values - throw RuntimeError("Error: Different Values for function getADCInvert"); -} - -void multiSlsDetector::setExternalSamplingSource(int value, int detPos) { - if (detPos >= 0) { - detectors[detPos]->setExternalSamplingSource(value); - } - - parallelCall(&slsDetector::setExternalSamplingSource, value); -} - -int multiSlsDetector::getExternalSamplingSource(int detPos) { - if (detPos >= 0) { - return detectors[detPos]->getExternalSamplingSource(); - } - - auto r = parallelCall(&slsDetector::getExternalSamplingSource); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::setExternalSampling(bool value, int detPos) { - if (detPos >= 0) { - detectors[detPos]->setExternalSampling(static_cast(value)); - } - - parallelCall(&slsDetector::setExternalSampling, static_cast(value)); -} - -int multiSlsDetector::getExternalSampling(int detPos) { - if (detPos >= 0) { - return detectors[detPos]->getExternalSampling(); - } - - auto r = parallelCall(&slsDetector::getExternalSampling); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::setReceiverDbitList(std::vector list, int detPos) { - if (detPos >= 0) { - detectors[detPos]->setReceiverDbitList(list); - } - - parallelCall(&slsDetector::setReceiverDbitList, list); -} - -std::vector multiSlsDetector::getReceiverDbitList(int detPos) { - if (detPos >= 0) { - return detectors[detPos]->getReceiverDbitList(); - } - - auto r = parallelCall(&slsDetector::getReceiverDbitList); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::setReceiverDbitOffset(int value, int detPos) { - if (detPos >= 0) { - detectors[detPos]->setReceiverDbitOffset(value); - } - - parallelCall(&slsDetector::setReceiverDbitOffset, value); -} - -int multiSlsDetector::getReceiverDbitOffset(int detPos) { - if (detPos >= 0) { - return detectors[detPos]->getReceiverDbitOffset(); - } - - auto r = parallelCall(&slsDetector::getReceiverDbitOffset); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::writeAdcRegister(uint32_t addr, uint32_t val, - int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->writeAdcRegister(addr, val); - } - - // multi - parallelCall(&slsDetector::writeAdcRegister, addr, val); -} - -int multiSlsDetector::activate(int const enable, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->activate(enable); - } - - // multi - auto r = parallelCall(&slsDetector::activate, enable); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setDeactivatedRxrPaddingMode(int padding, int detPos) { - // single - if (detPos >= 0) { - return static_cast( - detectors[detPos]->setDeactivatedRxrPaddingMode(padding)); - } - - // multi - auto r = parallelCall(&slsDetector::setDeactivatedRxrPaddingMode, padding); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::getFlippedDataX(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getFlippedDataX(); - } - - // multi - auto r = serialCall(&slsDetector::getFlippedDataX); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setFlippedDataX(int value, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setFlippedDataX(value); - } - - // multi - auto r = parallelCall(&slsDetector::setFlippedDataX, value); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setAllTrimbits(int val, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setAllTrimbits(val); - } - - // multi - auto r = parallelCall(&slsDetector::setAllTrimbits, val); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::enableGapPixels(int val, int detPos) { - if (getDetectorTypeAsEnum() != EIGER) { - if (val >= 0) { - throw NotImplementedError( - "Function (enableGapPixels) not implemented for this detector"); - } - return 0; - } - - // single - if (detPos >= 0) { - if (val >= 0) { - throw RuntimeError("Function (enableGapPixels) must be called from " - "a multi detector level."); - } - return detectors[detPos]->enableGapPixels(val); - } - - // multi - auto r = parallelCall(&slsDetector::enableGapPixels, val); - int ret = sls::minusOneIfDifferent(r); - - if (val != -1) { - Parallel(&slsDetector::enableGapPixels, {}, val); - Result res = - Parallel(&slsDetector::getNumberOfChannels, {}); - multi_shm()->numberOfChannels.x = 0; - multi_shm()->numberOfChannels.y = 0; - for (auto &it : res) { - multi_shm()->numberOfChannels.x += it.x; - multi_shm()->numberOfChannels.y += it.y; - } - } - return ret; -} - -void multiSlsDetector::setGapPixelsEnable(bool enable, Positions pos) { - Parallel(&slsDetector::enableGapPixels, pos, static_cast(enable)); +void multiSlsDetector::setGapPixelsinReceiver(bool enable) { + Parallel(&slsDetector::enableGapPixels, {}, static_cast(enable)); + // update number of channels Result res = Parallel(&slsDetector::getNumberOfChannels, {}); multi_shm()->numberOfChannels.x = 0; @@ -1755,481 +462,6 @@ void multiSlsDetector::setGapPixelsEnable(bool enable, Positions pos) { } } -int multiSlsDetector::setTrimEn(std::vector energies, int detPos) { - if (detPos >= 0) { - return detectors[detPos]->setTrimEn(energies); - } - auto r = parallelCall(&slsDetector::setTrimEn, energies); - return sls::minusOneIfDifferent(r); -} - -std::vector multiSlsDetector::getTrimEn(int detPos) { - if (detPos >= 0) { - return detectors[detPos]->getTrimEn(); - } - auto r = parallelCall(&slsDetector::getTrimEn); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::pulsePixel(int n, int x, int y, int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->pulsePixel(n, x, y); - } - - // multi - parallelCall(&slsDetector::pulsePixel, n, x, y); -} - -void multiSlsDetector::pulsePixelNMove(int n, int x, int y, int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->pulsePixelNMove(n, x, y); - } - - // multi - parallelCall(&slsDetector::pulsePixelNMove, n, x, y); -} - -void multiSlsDetector::pulseChip(int n, int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->pulseChip(n); - } - - // multi - parallelCall(&slsDetector::pulseChip, n); -} - -int multiSlsDetector::setThresholdTemperature(int val, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setThresholdTemperature(val); - } - - // multi - auto r = parallelCall(&slsDetector::setThresholdTemperature, val); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setTemperatureControl(int val, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setTemperatureControl(val); - } - - // multi - auto r = parallelCall(&slsDetector::setTemperatureControl, val); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setTemperatureEvent(int val, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setTemperatureEvent(val); - } - - // multi - auto r = parallelCall(&slsDetector::setTemperatureEvent, val); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setStoragecellStart(int pos, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setStoragecellStart(pos); - } - - // multi - auto r = parallelCall(&slsDetector::setStoragecellStart, pos); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::programFPGA(const std::string &fname, int detPos) { - FILE_LOG(logINFO) << "This can take awhile. Please be patient..."; - // read pof file - std::vector buffer = readPofFile(fname); - - // single - if (detPos >= 0) { - detectors[detPos]->programFPGA(buffer); - } - - // multi - parallelCall(&slsDetector::programFPGA, buffer); -} - -void multiSlsDetector::resetFPGA(int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->resetFPGA(); - } - - // multi - parallelCall(&slsDetector::resetFPGA); -} - -void multiSlsDetector::copyDetectorServer(const std::string &fname, - const std::string &hostname, - int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->copyDetectorServer(fname, hostname); - detectors[detPos]->rebootController(); - // reboot and copy should be independant for - // update command - } - - // multi - parallelCall(&slsDetector::copyDetectorServer, fname, hostname); - parallelCall(&slsDetector::rebootController); -} - -void multiSlsDetector::rebootController(int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->rebootController(); - } - - // multi - parallelCall(&slsDetector::rebootController); -} - -void multiSlsDetector::update(const std::string &sname, - const std::string &hostname, - const std::string &fname, int detPos) { - FILE_LOG(logINFO) << "This can take awhile. Please be patient..."; - // read pof file - std::vector buffer = readPofFile(fname); - - // single - if (detPos >= 0) { - detectors[detPos]->copyDetectorServer(sname, hostname); - detectors[detPos]->programFPGA(buffer); - } - - // multi - parallelCall(&slsDetector::copyDetectorServer, sname, hostname); - parallelCall(&slsDetector::programFPGA, buffer); -} - -int multiSlsDetector::powerChip(int ival, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->powerChip(ival); - } - - // multi delayed call for safety - if (ival >= 0 && size() > 3) { - std::vector r; - r.reserve(detectors.size()); - for (auto &d : detectors) { - r.push_back(d->powerChip(ival)); - usleep(1000 * 1000); - } - return sls::minusOneIfDifferent(r); - } - // multi parallel - auto r = parallelCall(&slsDetector::powerChip, ival); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setAutoComparatorDisableMode(int ival, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setAutoComparatorDisableMode(ival); - } - - // multi - auto r = parallelCall(&slsDetector::setAutoComparatorDisableMode, ival); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::setDefaultRateCorrection(int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->setDefaultRateCorrection(); - } - - // multi - parallelCall(&slsDetector::setDefaultRateCorrection); -} - -void multiSlsDetector::setRateCorrection(int64_t t, int detPos) { - if (t < 0) { - throw sls::RuntimeError("Dead time has to be greater or equal to 0"); - } - // single - if (detPos >= 0) { - detectors[detPos]->setRateCorrection(t); - } - - // multi - parallelCall(&slsDetector::setRateCorrection, t); -} - -int64_t multiSlsDetector::getRateCorrection(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getRateCorrection(); - } - - // multi - auto r = parallelCall(&slsDetector::getRateCorrection); - return sls::minusOneIfDifferent(r); -} - -std::string multiSlsDetector::printReceiverConfiguration(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->printReceiverConfiguration(); - } - - // multi - auto r = parallelCall(&slsDetector::printReceiverConfiguration); - // concatenate without '+' - std::string ret; - for (const auto &s : r) - if (!s.empty()) - ret += s; - return ret; -} - -bool multiSlsDetector::getUseReceiverFlag(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getUseReceiverFlag(); - } - - // multi - auto r = parallelCall(&slsDetector::getUseReceiverFlag); - if (sls::allEqual(r)) { - return r.front(); - } else { - throw RuntimeError("Inconsistent Use receiver flags"); - } -} - -int multiSlsDetector::lockReceiver(int lock, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->lockReceiver(lock); - } - - // multi - auto r = parallelCall(&slsDetector::lockReceiver, lock); - return sls::minusOneIfDifferent(r); -} - - - -void multiSlsDetector::exitReceiver(int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->exitReceiver(); - } - - // multi - parallelCall(&slsDetector::exitReceiver); -} - -void multiSlsDetector::execReceiverCommand(const std::string &cmd, int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->execReceiverCommand(cmd); - } - - // multi - parallelCall(&slsDetector::execReceiverCommand, cmd); -} - -std::string multiSlsDetector::getFilePath(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getFilePath(); - } - - // multi - auto r = serialCall(&slsDetector::getFilePath); - return sls::concatenateIfDifferent(r); -} - -std::string multiSlsDetector::setFilePath(const std::string &path, int detPos) { - if (path.empty()) { - return getFilePath(detPos); - } - - // single - if (detPos >= 0) { - return detectors[detPos]->setFilePath(path); - } - - // multi - auto r = parallelCall(&slsDetector::setFilePath, path); - return sls::concatenateIfDifferent(r); -} - -std::string multiSlsDetector::getFileName(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getFileName(); - } - - // multi - auto r = serialCall(&slsDetector::getFileName); - return sls::concatenateIfDifferent(r); -} - -std::string multiSlsDetector::setFileName(const std::string &fname, - int detPos) { - if (fname.empty()) { - return getFileName(detPos); - } - - // single - if (detPos >= 0) { - return detectors[detPos]->setFileName(fname); - } - - // multi - auto r = parallelCall(&slsDetector::setFileName, fname); - return sls::concatenateIfDifferent(r); -} - -int multiSlsDetector::setFramesPerFile(int f, int detPos) { - if (detPos >= 0) { - return detectors[detPos]->setFramesPerFile(f); - } - auto r = parallelCall(&slsDetector::setFramesPerFile, f); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::getFramesPerFile(int detPos) const { - if (detPos >= 0) { - return detectors[detPos]->getFramesPerFile(); - } - auto r = parallelCall(&slsDetector::getFramesPerFile); - return sls::minusOneIfDifferent(r); -} - -slsDetectorDefs::frameDiscardPolicy -multiSlsDetector::setReceiverFramesDiscardPolicy(frameDiscardPolicy f, - int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setReceiverFramesDiscardPolicy(f); - } - - // multi - auto r = parallelCall(&slsDetector::setReceiverFramesDiscardPolicy, f); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setPartialFramesPadding(bool padding, int detPos) { - if (detPos >= 0) - return static_cast( - detectors[detPos]->setPartialFramesPadding(padding)); - auto r = parallelCall(&slsDetector::setPartialFramesPadding, padding); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::getPartialFramesPadding(int detPos) const { - if (detPos >= 0) - return static_cast(detectors[detPos]->getPartialFramesPadding()); - auto r = parallelCall(&slsDetector::getPartialFramesPadding); - return sls::minusOneIfDifferent(r); -} - -slsDetectorDefs::fileFormat multiSlsDetector::getFileFormat(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getFileFormat(); - } - - // multi - auto r = serialCall(&slsDetector::getFileFormat); - return sls::minusOneIfDifferent(r); -} - -slsDetectorDefs::fileFormat multiSlsDetector::setFileFormat(fileFormat f, - int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setFileFormat(f); - } - - // multi - auto r = parallelCall(&slsDetector::setFileFormat, f); - return sls::minusOneIfDifferent(r); -} - -int64_t multiSlsDetector::incrementFileIndex(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->incrementFileIndex(); - } - - // multi - auto r = parallelCall(&slsDetector::incrementFileIndex); - return sls::minusOneIfDifferent(r); -} - -int64_t multiSlsDetector::setFileIndex(int64_t i, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setFileIndex(i); - } - - // multi - auto r = parallelCall(&slsDetector::setFileIndex, i); - return sls::minusOneIfDifferent(r); -} - -int64_t multiSlsDetector::getFileIndex(int detPos) const { - if (detPos >= 0) - return detectors[detPos]->getFileIndex(); - auto r = parallelCall(&slsDetector::getFileIndex); - return sls::minusOneIfDifferent(r); -} - - -int multiSlsDetector::getFramesCaughtByReceiver(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getFramesCaughtByReceiver(); - } - - // multi - auto r = parallelCall(&slsDetector::getFramesCaughtByReceiver); - - // prevent divide by all or do not take avg when -1 for "did not connect" - if ((detectors.empty()) || (sls::anyEqualTo(r, -1))) { - return -1; - } - - // return average - return ((sls::sum(r)) / (int)detectors.size()); -} - -uint64_t multiSlsDetector::getReceiverCurrentFrameIndex(int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->getReceiverCurrentFrameIndex(); - } - - // multi - auto r = parallelCall(&slsDetector::getReceiverCurrentFrameIndex); - - // prevent divide by all or do not take avg when -1 for "did not connect" - if ((detectors.empty()) || - (sls::anyEqualTo(r, static_cast(-1)))) { - return -1; - } - - // return average - return ((sls::sum(r)) / (int)detectors.size()); -} - int multiSlsDetector::createReceivingDataSockets(const bool destroy) { if (destroy) { FILE_LOG(logINFO) << "Going to destroy data sockets"; @@ -2245,10 +477,10 @@ int multiSlsDetector::createReceivingDataSockets(const bool destroy) { size_t numSockets = detectors.size(); size_t numSocketsPerDetector = 1; - if (getDetectorTypeAsEnum() == EIGER) { + if (multi_shm()->multiDetectorType == EIGER) { numSocketsPerDetector = 2; } - if (getNumberofUDPInterfaces() == 2) { + if (Parallel(&slsDetector::getNumberofUDPInterfacesFromShm, {}).squash() == 2) { numSocketsPerDetector = 2; } numSockets *= numSocketsPerDetector; @@ -2287,7 +519,7 @@ void multiSlsDetector::readFrameFromReceiver() { bool gappixelsenable = false; bool quadEnable = false; bool eiger = false; - bool numInterfaces = getNumberofUDPInterfaces(); // cannot pick up from zmq + bool numInterfaces = Parallel(&slsDetector::getNumberofUDPInterfacesFromShm, {}).squash(); // cannot pick up from zmq bool runningList[zmqSocket.size()], connectList[zmqSocket.size()]; int numRunning = 0; @@ -2429,7 +661,7 @@ void multiSlsDetector::readFrameFromReceiver() { uint32_t yoffset = coordY * nPixelsY; uint32_t singledetrowoffset = nPixelsX * bytesPerPixel; uint32_t rowoffset = nX * singledetrowoffset; - if (getDetectorTypeAsEnum() == CHIPTESTBOARD) { + if (multi_shm()->multiDetectorType == CHIPTESTBOARD) { singledetrowoffset = size; } FILE_LOG(logDEBUG1) @@ -2673,76 +905,6 @@ int multiSlsDetector::processImageWithGapPixels(char *image, char *&gpImage, return gapdatabytes; } -int multiSlsDetector::setFileWrite(bool value, int detPos) { - if (detPos >= 0) { - return static_cast(detectors[detPos]->setFileWrite(value)); - } - auto r = parallelCall(&slsDetector::setFileWrite, value); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::getFileWrite(int detPos) const { - if (detPos >= 0) { - return static_cast(detectors[detPos]->getFileWrite()); - } - auto r = parallelCall(&slsDetector::getFileWrite); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setMasterFileWrite(bool value, int detPos) { - if (detPos >= 0) { - return static_cast(detectors[detPos]->setMasterFileWrite(value)); - } - auto r = parallelCall(&slsDetector::setMasterFileWrite, value); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::getMasterFileWrite(int detPos) const { - if (detPos >= 0) { - return static_cast(detectors[detPos]->getMasterFileWrite()); - } - auto r = parallelCall(&slsDetector::getMasterFileWrite); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setFileOverWrite(bool enable, int detPos) { - if (detPos >= 0) { - return static_cast(detectors[detPos]->setFileOverWrite(enable)); - } - auto r = parallelCall(&slsDetector::setFileOverWrite, enable); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::getFileOverWrite(int detPos) const { - if (detPos >= 0) { - return static_cast(detectors[detPos]->getFileOverWrite()); - } - auto r = parallelCall(&slsDetector::getFileOverWrite); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setReceiverStreamingFrequency(int freq, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setReceiverStreamingFrequency(freq); - } - - // multi - auto r = parallelCall(&slsDetector::setReceiverStreamingFrequency, freq); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setReceiverStreamingTimer(int time_in_ms, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setReceiverStreamingTimer(time_in_ms); - } - - // multi - auto r = parallelCall(&slsDetector::setReceiverStreamingTimer, time_in_ms); - return sls::minusOneIfDifferent(r); -} - bool multiSlsDetector::enableDataStreamingToClient(int enable) { if (enable >= 0) { // destroy data threads @@ -2758,61 +920,6 @@ bool multiSlsDetector::enableDataStreamingToClient(int enable) { return client_downstream; } -int multiSlsDetector::enableDataStreamingFromReceiver(int enable, int detPos) { - // single - if (detPos >= 0) { - return static_cast( - detectors[detPos]->enableDataStreamingFromReceiver(enable)); - } - - // multi - auto r = - parallelCall(&slsDetector::enableDataStreamingFromReceiver, enable); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::enableTenGigabitEthernet(int i, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->enableTenGigabitEthernet(i); - } - - // multi - auto r = parallelCall(&slsDetector::enableTenGigabitEthernet, i); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setReceiverFifoDepth(int i, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setReceiverFifoDepth(i); - } - - // multi - auto r = parallelCall(&slsDetector::setReceiverFifoDepth, i); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setReceiverSilentMode(int i, int detPos) { - // single - if (detPos >= 0) { - return static_cast(detectors[detPos]->setReceiverSilentMode(i)); - } - - // multi - auto r = parallelCall(&slsDetector::setReceiverSilentMode, i); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::setPattern(const std::string &fname, int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->setPattern(fname); - } - - // multi - parallelCall(&slsDetector::setPattern, fname); -} void multiSlsDetector::savePattern(const std::string &fname) { std::ofstream outfile; @@ -2854,128 +961,6 @@ void multiSlsDetector::savePattern(const std::string &fname) { multiSlsDetectorClient(cmd, GET_ACTION, this, outfile); } -uint64_t multiSlsDetector::setPatternIOControl(uint64_t word, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setPatternIOControl(word); - } - - // multi - auto r = parallelCall(&slsDetector::setPatternIOControl, word); - return sls::minusOneIfDifferent(r); -} - -uint64_t multiSlsDetector::setPatternClockControl(uint64_t word, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setPatternClockControl(word); - } - - // multi - auto r = parallelCall(&slsDetector::setPatternClockControl, word); - return sls::minusOneIfDifferent(r); -} - -uint64_t multiSlsDetector::setPatternWord(int addr, uint64_t word, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setPatternWord(addr, word); - } - - // multi - auto r = parallelCall(&slsDetector::setPatternWord, addr, word); - return sls::minusOneIfDifferent(r); -} - -int multiSlsDetector::setPatternWaitAddr(int level, int addr, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setPatternWaitAddr(level, addr); - } - - // multi - auto r = parallelCall(&slsDetector::setPatternWaitAddr, level, addr); - return sls::minusOneIfDifferent(r); -} - -uint64_t multiSlsDetector::setPatternWaitTime(int level, uint64_t t, - int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setPatternWaitTime(level, t); - } - - // multi - auto r = parallelCall(&slsDetector::setPatternWaitTime, level, t); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::setPatternMask(uint64_t mask, int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->setPatternMask(mask); - } - - // multi - parallelCall(&slsDetector::setPatternMask, mask); -} - -uint64_t multiSlsDetector::getPatternMask(int detPos) { - if (detPos >= 0) - return detectors[detPos]->getPatternMask(); - auto r = parallelCall(&slsDetector::getPatternMask); - if (sls::allEqual(r)) { - return r.front(); - } else { - - throw RuntimeError("multiSlsDetector::getPatternMask: Error: Different " - "Values returned)"); - } -} - -void multiSlsDetector::setPatternBitMask(uint64_t mask, int detPos) { - if (detPos >= 0) { - detectors[detPos]->setPatternBitMask(mask); - } - parallelCall(&slsDetector::setPatternBitMask, mask); -} - -uint64_t multiSlsDetector::getPatternBitMask(int detPos) { - if (detPos >= 0) { - return detectors[detPos]->getPatternBitMask(); - } - auto r = parallelCall(&slsDetector::getPatternBitMask); - if (sls::allEqual(r)) { - return r.front(); - } - - // should not have different values - throw RuntimeError( - "multiSlsDetector::getPatternBitMask Different Values returned)"); -} - -int multiSlsDetector::setLEDEnable(int enable, int detPos) { - // single - if (detPos >= 0) { - return detectors[detPos]->setLEDEnable(enable); - } - - // multi - auto r = parallelCall(&slsDetector::setLEDEnable, enable); - return sls::minusOneIfDifferent(r); -} - -void multiSlsDetector::setDigitalIODelay(uint64_t pinMask, int delay, - int detPos) { - // single - if (detPos >= 0) { - detectors[detPos]->setDigitalIODelay(pinMask, delay); - } - - // multi - parallelCall(&slsDetector::setDigitalIODelay, pinMask, delay); -} - void multiSlsDetector::loadParameters(const std::string &fname) { std::ifstream input_file; input_file.open(fname.c_str(), std::ios_base::in); @@ -3010,13 +995,13 @@ void multiSlsDetector::registerDataCallback( void *pArg) { dataReady = userCallback; pCallbackArg = pArg; - if (getUseReceiverFlag()) { + if (Parallel(&slsDetector::getUseReceiverFlag, {}).squash(false)) { if (dataReady == nullptr) { enableDataStreamingToClient(0); - enableDataStreamingFromReceiver(0); + Parallel(&slsDetector::enableDataStreamingFromReceiver, {}, 0); } else { enableDataStreamingToClient(1); - enableDataStreamingFromReceiver(1); + Parallel(&slsDetector::enableDataStreamingFromReceiver, {}, 1); } } } @@ -3031,7 +1016,7 @@ int multiSlsDetector::setTotalProgress() { } int ns = 1; - if (getDetectorTypeAsEnum() == JUNGFRAU) { + if (multi_shm()->multiDetectorType == JUNGFRAU) { ns = Parallel(&slsDetector::setTimer, {}, STORAGE_CELL_NUMBER, -1) .tsquash("Inconsistent number of additional storage cells"); ++ns; @@ -3068,7 +1053,7 @@ void multiSlsDetector::setCurrentProgress(int i) { int multiSlsDetector::acquire() { // ensure acquire isnt started multiple times by same client - if (static_cast(isAcquireReady()) == FAIL) { + if (!isAcquireReady()) { return FAIL; } @@ -3083,7 +1068,7 @@ int multiSlsDetector::acquire() { // process) sem_init(&sem_endRTAcquisition, 1, 0); - bool receiver = getUseReceiverFlag(); + bool receiver = Parallel(&slsDetector::getUseReceiverFlag, {}).squash(false); progressIndex = 0; setJoinThreadFlag(false); @@ -3105,7 +1090,7 @@ int multiSlsDetector::acquire() { } // start and read all - if (getDetectorTypeAsEnum() == EIGER) { + if (multi_shm()->multiDetectorType == EIGER) { Parallel(&slsDetector::prepareAcquisition, {}); } Parallel(&slsDetector::startAndReadAll, {}); @@ -3119,7 +1104,7 @@ int multiSlsDetector::acquire() { // external process to be // done sending data to gui - incrementFileIndex(); + Parallel(&slsDetector::incrementFileIndex, {}); } // waiting for the data processing thread to finish! @@ -3157,7 +1142,7 @@ void multiSlsDetector::startProcessingThread() { } void multiSlsDetector::processData() { - if (getUseReceiverFlag()) { + if (Parallel(&slsDetector::getUseReceiverFlag, {}).squash(false)) { if (dataReady != nullptr) { readFrameFromReceiver(); } @@ -3174,7 +1159,7 @@ void multiSlsDetector::processData() { } } // get progress - caught = getFramesCaughtByReceiver(0); + caught = Parallel(&slsDetector::getFramesCaughtByReceiver, {0}).squash(); // updating progress if (caught != -1) { diff --git a/slsDetectorSoftware/src/slsDetector.cpp b/slsDetectorSoftware/src/slsDetector.cpp index f66f21895..4a39c1e1d 100755 --- a/slsDetectorSoftware/src/slsDetector.cpp +++ b/slsDetectorSoftware/src/slsDetector.cpp @@ -391,6 +391,7 @@ void slsDetector::initializeDetectorStructure(detectorType type) { shm()->rxMasterFileWrite = true; shm()->rxFileOverWrite = true; shm()->rxDbitOffset = 0; + shm()->numUDPInterfaces = 1; // get the detector parameters based on type detParameters parameters{type}; @@ -545,14 +546,10 @@ int slsDetector::setDetectorType(detectorType const type) { return retval; } -slsDetectorDefs::detectorType slsDetector::getDetectorTypeAsEnum() const { +slsDetectorDefs::detectorType slsDetector::getDetectorType() const { return shm()->myDetectorType; } -std::string slsDetector::getDetectorTypeAsString() const { - return ToString(getDetectorTypeAsEnum()); -} - void slsDetector::updateNumberOfChannels() { if (shm()->myDetectorType == CHIPTESTBOARD || shm()->myDetectorType == MOENCH) { @@ -832,6 +829,12 @@ void slsDetector::updateCachedDetectorVariables() { updateNumberOfChannels(); } + // num udp interfaces + if (shm()->myDetectorType == JUNGFRAU) { + n += client.Receive(&i32, sizeof(i32)); + shm()->numUDPInterfaces = i32; + } + if (n == 0) { FILE_LOG(logERROR) << "Could not update detector, received 0 bytes"; } @@ -1312,6 +1315,8 @@ int slsDetector::setSpeed(speedVariable sp, int value, int mode) { int slsDetector::setDynamicRange(int n) { // TODO! Properly handle fail + int prevDr = shm()->dynamicRange; + int retval = -1; FILE_LOG(logDEBUG1) << "Setting dynamic range to " << n; sendToDetector(F_SET_DYNAMIC_RANGE, n, retval); @@ -1325,11 +1330,22 @@ int slsDetector::setDynamicRange(int n) { sendToReceiver(F_SET_RECEIVER_DYNAMIC_RANGE, n, retval); FILE_LOG(logDEBUG1) << "Receiver Dynamic range: " << retval; } + + // changes in dr + int dr = shm()->dynamicRange; + if (prevDr != dr && shm()->myDetectorType == EIGER) { + updateRateCorrection(); + // update speed for usability + if (dr == 32) { + FILE_LOG(logINFO) << "Setting Clock to Quarter Speed to cope with Dynamic Range of 32"; setSpeed(CLOCK_DIVIDER, 2); + } else if (dr == 16) { + FILE_LOG(logINFO) << "Setting Clock to Half Speed to cope with Dynamic Range of 16"; setSpeed(CLOCK_DIVIDER, 1); + } + } + return shm()->dynamicRange; } -int slsDetector::getDynamicRangeFromShm() { return shm()->dynamicRange; } - int slsDetector::setDAC(int val, dacIndex index, int mV) { int args[]{static_cast(index), mV, val}; int retval = -1; @@ -1857,17 +1873,24 @@ int slsDetector::getDestinationUDPPort2() { void slsDetector::setNumberofUDPInterfaces(int n) { FILE_LOG(logDEBUG1) << "Setting number of udp interfaces to " << n; sendToDetector(F_SET_NUM_INTERFACES, n, nullptr); + shm()->numUDPInterfaces = n; if (shm()->useReceiverFlag) { sendToReceiver(F_SET_RECEIVER_NUM_INTERFACES, n, nullptr); } } +int slsDetector::getNumberofUDPInterfacesFromShm() { + return shm()->numUDPInterfaces; +} + + int slsDetector::getNumberofUDPInterfaces() { int retval = -1; FILE_LOG(logDEBUG1) << "Getting number of udp interfaces"; sendToDetector(F_GET_NUM_INTERFACES, nullptr, retval); FILE_LOG(logDEBUG1) << "Number of udp interfaces: " << retval; - return retval; + shm()->numUDPInterfaces = retval; + return shm()->numUDPInterfaces; } void slsDetector::selectUDPInterface(int n) { @@ -2380,6 +2403,10 @@ int slsDetector::setAllTrimbits(int val) { int slsDetector::enableGapPixels(int val) { if (val >= 0) { + if (shm()->myDetectorType != EIGER) { + throw NotImplementedError( + "Function (enableGapPixels) not implemented for this detector"); + } int fnum = F_ENABLE_GAPPIXELS_IN_RECEIVER; int retval = -1; FILE_LOG(logDEBUG1) << "Sending gap pixels enable to receiver: " << val; diff --git a/slsDetectorSoftware/src/slsDetectorCommand.cpp b/slsDetectorSoftware/src/slsDetectorCommand.cpp index 1f35a1110..ab7b4f09c 100755 --- a/slsDetectorSoftware/src/slsDetectorCommand.cpp +++ b/slsDetectorSoftware/src/slsDetectorCommand.cpp @@ -1,5 +1,6 @@ #include "slsDetectorCommand.h" #include "multiSlsDetector.h" +#include "slsDetector.h" #include "string_utils.h" #include @@ -80,16 +81,6 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { - /*! \page test - - help Returns a list of possible commands. - */ - descrToFuncMap[i].m_pFuncName = "help"; - descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdHelp; - ++i; - - - - /* Acquisition and status commands */ /*! \page acquisition Acquition commands Commands to control the acquisition @@ -103,28 +94,6 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { ++i; - /*! \page config - - \b free Free shared memory on the control PC - */ - descrToFuncMap[i].m_pFuncName = "free"; - descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdFree; - ++i; - - - /*! \page config - - checkdetversion Checks the version compatibility with detector server (if hostname is in shared memory). Only get! Only for Eiger, Jungfrau & Gotthard. \c Returns \c ("compatible", "incompatible") - */ - descrToFuncMap[i].m_pFuncName = "checkdetversion"; - descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdSN; - ++i; - - /*! \page config - - rx_checkversion Checks the version compatibility with receiver server (if rx_hostname is in shared memory). Only get! Only for Eiger, Jungfrau & Gotthard. \c Returns \c ("compatible", "incompatible") - */ - descrToFuncMap[i].m_pFuncName = "rx_checkversion"; - descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdSN; - ++i; - /* settings dump/retrieve */ @@ -182,40 +151,6 @@ std::vector slsDetectorCommand::getAllCommands(){ return commands; } -std::string slsDetectorCommand::helpLine(int narg, const char * const args[], int action, int detPos) { - - std::ostringstream os; - - if (action == READOUT_ACTION) { - return helpAcquire(HELP_ACTION); - } - - if (narg == 0) { - os << "Command can be: " << std::endl; - for (int i = 0; i < numberOfCommands; ++i) { - os << descrToFuncMap[i].m_pFuncName << "\n"; - } - os << std::endl; - return os.str(); - } - return executeLine(narg, args, HELP_ACTION, detPos); -} - - -std::string slsDetectorCommand::cmdHelp(int narg, const char * const args[], int action, int detPos) { -#ifdef VERBOSE - std::cout << std::string("Executing command ") + std::string(args[0]) + std::string(" ( ") + cmd + std::string(" )\n"); -#endif - - std::cout << narg << std::endl; - - if (narg >= 1) - return helpLine(narg - 1, args, action, detPos); - else - return helpLine(0, args, action, detPos); -} - - std::string slsDetectorCommand::cmdAcquire(int narg, const char * const args[], int action, int detPos) { @@ -237,10 +172,11 @@ std::string slsDetectorCommand::cmdAcquire(int narg, const char * const args[], if (myDet->acquire() == FAIL) return std::string("acquire failed"); - if (myDet->getUseReceiverFlag(detPos)) { - char answer[100]; - sprintf(answer, "\nAcquired %d", myDet->getFramesCaughtByReceiver(detPos)); - return std::string(answer); + if (myDet->Parallel(&slsDetector::getUseReceiverFlag, {}).squash(false)) { + std::ostringstream os; + os << "\nAcquired "; + os << sls::ToString(myDet->Parallel(&slsDetector::getFramesCaughtByReceiver, {})); + return os.str(); } return std::string(); @@ -260,61 +196,6 @@ std::string slsDetectorCommand::helpAcquire(int action) { -std::string slsDetectorCommand::cmdFree(int narg, const char * const args[], int action, int detPos) { - -#ifdef VERBOSE - std::cout << std::string("Executing command ") + std::string(args[0]) + std::string(" ( ") + cmd + std::string(" )\n"); -#endif - if (action == HELP_ACTION) { - return helpFree(HELP_ACTION); - } - - return ("Error: Should have been freed before creating constructor\n"); -} - -std::string slsDetectorCommand::helpFree(int action) { - return std::string("free \t frees the shared memory\n"); -} - - - - -std::string slsDetectorCommand::cmdSN(int narg, const char * const args[], int action, int detPos) { - - if (action == PUT_ACTION) - return std::string("cannot set"); - - if (action == HELP_ACTION) - return helpSN(action); - - - if (cmd == "checkdetversion") { - myDet->checkDetectorVersionCompatibility(detPos); - return std::string("compatible"); - } - - if (cmd == "rx_checkversion") { - myDet->checkReceiverVersionCompatibility(detPos); - return std::string("compatible"); - } - - return std::string("unknown id mode ") + cmd; -} - -std::string slsDetectorCommand::helpSN(int action) { - - std::ostringstream os; - if (action == GET_ACTION || action == HELP_ACTION) { - os << "checkdetversion \n gets the version compatibility with detector server (if hostname is in shared memory). Only for Eiger, Jungfrau & Gotthard. Prints compatible/ incompatible." << std::endl; - os << "rx_checkversion \n gets the version compatibility with receiver server (if rx_hostname is in shared memory). Only for Eiger, Jungfrau & Gotthard. Prints compatible/ incompatible." << std::endl; - } - return os.str(); -} - - - - - std::string slsDetectorCommand::cmdConfiguration(int narg, const char * const args[], int action, int detPos) { diff --git a/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp b/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp index f16946907..c068cab2b 100644 --- a/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp +++ b/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp @@ -3076,14 +3076,14 @@ TEST_CASE("zmqport", "[.cmd]") { } int port = 3500; REQUIRE_NOTHROW(multiSlsDetectorClient("zmqport " + std::to_string(port), PUT)); - for (size_t i = 0; i != d.size(); ++i) { + for (int i = 0; i != d.size(); ++i) { std::ostringstream oss; REQUIRE_NOTHROW(multiSlsDetectorClient(std::to_string(i) + ":zmqport", GET, nullptr, oss)); REQUIRE(oss.str() == "zmqport " + std::to_string(port + i * socketsperdetector) + '\n'); } port = 1954; REQUIRE_NOTHROW(multiSlsDetectorClient("zmqport " + std::to_string(port), PUT)); - for (size_t i = 0; i != d.size(); ++i) { + for (int i = 0; i != d.size(); ++i) { std::ostringstream oss; REQUIRE_NOTHROW(multiSlsDetectorClient(std::to_string(i) + ":zmqport", GET, nullptr, oss)); REQUIRE(oss.str() == "zmqport " + std::to_string(port + i * socketsperdetector) + '\n'); @@ -3104,14 +3104,14 @@ TEST_CASE("rx_zmqport", "[.cmd]") { } int port = 3500; REQUIRE_NOTHROW(multiSlsDetectorClient("rx_zmqport " + std::to_string(port), PUT)); - for (size_t i = 0; i != d.size(); ++i) { + for (int i = 0; i != d.size(); ++i) { std::ostringstream oss; REQUIRE_NOTHROW(multiSlsDetectorClient(std::to_string(i) + ":rx_zmqport", GET, nullptr, oss)); REQUIRE(oss.str() == "rx_zmqport " + std::to_string(port + i * socketsperdetector) + '\n'); } port = 30001; REQUIRE_NOTHROW(multiSlsDetectorClient("rx_zmqport " + std::to_string(port), PUT)); - for (size_t i = 0; i != d.size(); ++i) { + for (int i = 0; i != d.size(); ++i) { std::ostringstream oss; REQUIRE_NOTHROW(multiSlsDetectorClient(std::to_string(i) + ":rx_zmqport", GET, nullptr, oss)); REQUIRE(oss.str() == "rx_zmqport " + std::to_string(port + i * socketsperdetector) + '\n'); @@ -3337,14 +3337,14 @@ TEST_CASE("network", "[.cmd]") { } int port = 5500; REQUIRE_NOTHROW(multiSlsDetectorClient("udp_dstport " + std::to_string(port), PUT)); - for (size_t i = 0; i != d.size(); ++i) { + for (int i = 0; i != d.size(); ++i) { std::ostringstream oss; REQUIRE_NOTHROW(multiSlsDetectorClient(std::to_string(i) + ":udp_dstport", GET, nullptr, oss)); REQUIRE(oss.str() == "udp_dstport " + std::to_string(port + i * socketsperdetector) + '\n'); } port = 50001; REQUIRE_NOTHROW(multiSlsDetectorClient("udp_dstport " + std::to_string(port), PUT)); - for (size_t i = 0; i != d.size(); ++i) { + for (int i = 0; i != d.size(); ++i) { std::ostringstream oss; REQUIRE_NOTHROW(multiSlsDetectorClient(std::to_string(i) + ":udp_dstport", GET, nullptr, oss)); REQUIRE(oss.str() == "udp_dstport " + std::to_string(port + i * socketsperdetector) + '\n'); @@ -4235,7 +4235,7 @@ TEST_CASE("rx_tcpport", "[.cmd]") { multiSlsDetector d; int port = 3500; REQUIRE_NOTHROW(multiSlsDetectorClient("rx_tcpport " + std::to_string(port), PUT)); - for (size_t i = 0; i != d.size(); ++i) { + for (int i = 0; i != d.size(); ++i) { std::ostringstream oss; REQUIRE_NOTHROW(multiSlsDetectorClient(std::to_string(i) + ":rx_tcpport", GET, nullptr, oss)); REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n'); @@ -4243,7 +4243,7 @@ TEST_CASE("rx_tcpport", "[.cmd]") { REQUIRE_THROWS(multiSlsDetectorClient("rx_tcpport 15", PUT)); port = 1954; REQUIRE_NOTHROW(multiSlsDetectorClient("rx_tcpport " + std::to_string(port), PUT)); - for (size_t i = 0; i != d.size(); ++i) { + for (int i = 0; i != d.size(); ++i) { std::ostringstream oss; REQUIRE_NOTHROW(multiSlsDetectorClient(std::to_string(i) + ":rx_tcpport", GET, nullptr, oss)); REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n'); diff --git a/slsSupportLib/include/versionAPI.h b/slsSupportLib/include/versionAPI.h index 548e6d87e..4d0aaa8b6 100644 --- a/slsSupportLib/include/versionAPI.h +++ b/slsSupportLib/include/versionAPI.h @@ -4,9 +4,9 @@ #define APIRECEIVER 0x190722 #define APIGUI 0x190723 #define APIMOENCH 0x190820 -#define APICTB 0x191029 -#define APIGOTTHARD 0x191029 -#define APIGOTTHARD2 0x191029 -#define APIEIGER 0x191029 -#define APIMYTHEN3 0x191030 #define APIJUNGFRAU 0x191030 +#define APIEIGER 0x191030 +#define APIGOTTHARD 0x191030 +#define APIGOTTHARD2 0x191030 +#define APIMYTHEN3 0x191030 +#define APICTB 0x191030