From 6e97710f0fdb96ac386f8f645cccba7f128c4e50 Mon Sep 17 00:00:00 2001 From: "Ryan@iMac" Date: Wed, 8 Feb 2023 12:00:30 -0500 Subject: [PATCH] for MUSIC by Chloe --- Analysis/EventBuilder_raw | Bin 0 -> 50136 bytes Analysis/TimSyncComp.C | 128 ++++++++ Analysis/TimeSync.C | 138 ++++++++ Analysis/timeshift.C | 302 ++++++++++++++++++ DAQ/Acquisition.cpp | 295 +++++++++++++++++ DAQ/ClassData.h | 18 +- DAQ/ClassDigitizer.cpp | 8 +- DAQ/ClassDigitizer.h | 1 + DAQ/EventBuilder.cpp | 529 ++++++++++++++++++------------- DAQ/EventBuilder_raw.cpp | 446 ++++++++++++++++++++++++++ DAQ/Makefile | 29 +- DAQ/Plotting.cpp | 177 +++++++++++ DAQ/RegisterAddress.h | 3 +- DAQ/macro.h | 4 +- DAQ/testStartAtSameTime.cpp | 79 +++++ MUSIC_Topology/Board0.dat | 17 + MUSIC_Topology/Board1.dat | 16 + MUSIC_Topology/Board2.dat | 16 + MUSIC_Topology/Board3.dat | 16 + README/README.md | 112 +++++++ README/Register_inputs_readme.md | 50 +++ README/Topology_MUSIC_read_me.md | 21 ++ 22 files changed, 2158 insertions(+), 247 deletions(-) create mode 100755 Analysis/EventBuilder_raw create mode 100755 Analysis/TimSyncComp.C create mode 100755 Analysis/TimeSync.C create mode 100644 Analysis/timeshift.C create mode 100644 DAQ/Acquisition.cpp create mode 100644 DAQ/EventBuilder_raw.cpp create mode 100644 DAQ/Plotting.cpp create mode 100644 DAQ/testStartAtSameTime.cpp create mode 100644 MUSIC_Topology/Board0.dat create mode 100644 MUSIC_Topology/Board1.dat create mode 100644 MUSIC_Topology/Board2.dat create mode 100644 MUSIC_Topology/Board3.dat create mode 100644 README/README.md create mode 100644 README/Register_inputs_readme.md create mode 100644 README/Topology_MUSIC_read_me.md diff --git a/Analysis/EventBuilder_raw b/Analysis/EventBuilder_raw new file mode 100755 index 0000000000000000000000000000000000000000..cdb81db0a58f445195bf656ba4e0f6099736d111 GIT binary patch literal 50136 zcmeFadtg-6wLg9)4+sx)qJoVTb9=_-k0T}2#{ClZ!CC0-EZNx9Mp{Cl2s zt~3nsBnIQ@c|1TWfBFPzBTNzSM1+(tH-Q5NhvNjE5gHs)m@LwU3YOf(p++c4W(J^q z#B292SQMd|y%=F3F@q<2G!Kn@#2)4A6Z!f?J|oN%{2QTBKO#qe#Ug!hXhRx3Mo75y z6u$2(r}wQv7Cj~W7Y9p5Xyp45@)4ik^+^+mi$rD7@^S)ld8O>)2B|VD!;tS zTjOuKyeW73<l-D82XLqn+o?-f-`x>lQq; z_!F1%pmJ-dtGo6ui!TP-M z*QQ8GN&jiumnWs=eQ?1YBbK(APs>Z4U?N&q;%_GY=$VDTtJs?)%|@6f-mM7p@n;ut z2SOMA7T~WCe?P(>J=8s@W>-@L&yVqU4gRjh-*x!A9)CCB??(K&@mGSsGW>b)w+w%k z_#63Hg7m@_|N2SYifg3#_*?x}-7V}a)7d}zed(s@pS^tE;)_q_ zHI4Y^h7szeAJ6}7?S0au>h+^;TK)6e&b(mL^zlFbYtxD*^FI#Vyky+i3;+D}lkeVh z+avSeZJSd1+DC7vukEY8`DeEk*kAf^>g(q%o}co@$chAO(=6nFChOz*zbneV=fQ%L ze;yy2_RGKPpQcuw_EFYLn;yIkRf+rjAz6~n7$S8q^lB*hGjZ@!sV70jIJDKRuvx!C)ZbI}(QGM~_pkhCD;@e{UT8%Ykpk-{5C!9Q-@b z`G%suKMsChoc1b+Q?EDU(4qb^RJn)Z;J3#q_m6Sluf~CIjZ^N=!T(V0SQ3Yy`{K}l zB#s=YpAS{v=i|UXi~~Ozr(Am+K5vOb=Rf1%Z;u1dh@&T|arpT%jvUs-=|>3|w1$$; zC2{Cn5{FN+>t_57er}0_-yDa2NgO`^5C`5BhtBRe<*thZ--AK!bm?qq=|g5#g}tI8 z9}Opak}7pqalqN&gPu{KL-={WHM6*Zze>?soTyO#6#X@Y(= zYZqBcS}hPo;7FnNN|jnyaezm_{}hMLX3$BK(j{rLSzz+uO~9#MX@X9ZNSy{cOb!Ac z#j$4z>P7gQD|y^1`1}fVP6z$;LHNH0+&o0NvyqSJ^m;iR?wv@|Q$lXaugomLD7OrB zsJ@brgCVy}=s(ffdMl@sCHR?v{z7o6hQm7%r)MjppDvjP@p%mjBK*ReI3D#|dZr8c zbP4!z4wn8Q_+Pq`1FV9f{Q`e$Ifp+e%54z*cNcSb^=Uj@BkH^KS7rv-%fXT?@Ov-d zfLF75ID@rIx|BAE|NDSX?Imq7Gekpfb45Eg3w(qAIlxZ?ezt&f>XP&mA&0J;Ib<>9 zOV1?&KTXi*P)Q0h{?nv1(JlgA`mNyKn7>>mGTaC`4b|?)1^>OjGc!zs|1qrG^i%kJ z1n{BS>pt*9dXgvPFPcqCG5W=zcD#l0kN*2>UancR*X=?MgWK_>fOiXT%h0#qARqCQ z-N-ANE$G~Xa*3b9QVtJ6Z|Erkoin6SQtSCVZv6WcURb>!qS^OWxnz%dtoC1EXB4GUrF)GI?okz zJw6KUi{=;kEIz!sy)_lJK$<$Iw!Ru9Z;7Q@=QK*0Zxoy}#oEx|srT8dJk_2WpWRFN zIg^W7eHyIw^(8BFrsl7#D`{u|r=F5(Prbb~mL~XYl$I5(gczz>-YLabd+Hm!wKWBm zp0edgW+aPz(;HET+Iojka#4w+DBEqf+lauag-$7`t!ePp`^$Wuax3@};>pP_wt4Fr zrIk6;3;gx<;5q`~l#CKkHsr!&7{Bd`uf^>-r;IWpt>xVr=~n65A_C~r?jNp&3X^(#YMh> zETOpwUbDg=Q}1EfsDYQ2mAMpV45h0jw}1*TwN%a#+|T~Xq#l3*-+wN+Aur?!ILQ5C^>iOC9?x>A+EZOt zw^FJotEz4ANEPV#<ily1fy`E#L30 z!bsz;FIiDoIF&5F_omX)o1|L5Z&7Wnk9r)KAYKeEzPTsZgh64XMDt8-SW!|J;m_V! zSWIS3@-#YZQe6o&!dL6IS%381YeZ%E>S5y|*~@BcIK;_xY#^z@k^x(=3DY45pO>{m zJ*3m%V*>^ZSPq$53+$5*>9sY5-XeFQLBc!8MZl6?Ij-UdL)Iw-@IZT(o!Bb8eaI@cAw!Eme-ZxkS44tj_*GMJg z!xS@JoLf-fo|2U<&2>8R3zjUw`&0>`HQ(XR$(q8!?#WpMW+-@%zU4$;CudC~hcN+b zx=CVvJ{d6%<14>#oEap6rBfQcB?|1}BBUIN_>WR~euB^&CcJDlnBqLuB>nIFSA?R| zP^KAwg%__JB}v1jPWZ+2n7~^QlMhO#sgf`A9(dTv(hEo@*nvMUNA5)FwFrKaR43>m zS@NCjMM{cvSm2NGdND&ACLI;=`+oW}2rfzbO2qv?B>V(v_(;l4`x#~yqEPm9iFsaV z5Pa(eJiT`iyj9?*i20a7$A}M}?@0kpXYhP`Zji$V&u_B@e%mk241u%&)sH-TW8k7n zEUhaB4uMCWLoslYukm!pz|S>+2tzUO*eOqM44l?Zji)aLPVH$t6NG$d8udd1h_LWM zGmBxm1zm_fOJd+rJ(i@UF>ocV&GV?V&IuE@TD>EOJm@bF>qtehLY=I;1gr;n_}QuG4SRX_@o&4`WSdl47@c4 zJ~;-yF$O**2EI84J~aluB?iuhLXoyL20lFo|M3|36)|un@L`IgCC_R$OG>cKm(bs( z1a_zFieU6l`^hS^)PK>P_*XtZ4{sE&r1WriKc0*3pg5VLa2Jc;LUA%d;Wiepr#P9O z@KzSTiQ;5(!kbyVl;UKf!>ufSEyc<7gqvA>5yeTp!*wh^kK$x%!b@2^pWb|85AcI6Yf0;z(pe| zPD4Sso5d3-PNpW@#o{M!N1RMdxQ)e+Qk+ancq@y4KyflD;ms`m4#mlogj-qsRf>}d z2{*I&ixel*5w2tLXDCi4BfONwcT${8MYxc~pP)Dm8R0w@|0~7GWQ4O>{9%fZqqv#H ze@$^3!oq1R{&R|-M{$Y8@1gkl6z~0->i-jpnusG(WlKIus(JQVxhy36fiFV=pWKq!+^d!C44%_wJuiF_pLv+UTs}$Ew-vBixl-U zZGXly*X`)`p{Nn4)rs#)A|hToVL)19JB+VoHj-x z^a?=Mz{y1U?%xmveOhk}{!@gnoeAiP80c>~l}R`;z-WN*y&U9>0X1__Nerl(gBoK% z*8=o7tBc0CR-E+ftT$TSH|$chTT^n5Jwbgm^Z@FK zc$$bSYOoa$HP}t{U(FNKqlu*Ap-KX)!Sx8N`kb%S-~{4oqoUUlcnL+8x1}rUw)J>* zsGkG4k+KBZ&Qb#1y-Mb8MYm-PSK32~N}$8!P&*YpX%D!8_=8=*bf|lL<0|CyZIa|v zKM6H`2~glelOwPv-4Xbz-~T~i2Nfy#EGYj=McYQ1l)x@Cm5TzMdeyLWo?p?XIMpMe z_Zf-Z=|DE@D6#a%)BcuA3qHbyfiO^Le?rlA5Vg#mf2TUh%6_$jQ47rm7f$UF#;rc>9W-LJ z6sqV8U!jyG$#_-Y4E+_z`NxvJCR1y2==Kr5lzCdx*JSyWve%3z(PyTI4gnL|e;??n z9Z;oQifgP!irS%o{j2ktVm1MTqH_^FX5WbF6pipDDca)As93C;4FemZuMpMw!)@w2PW59$!~cSu*1&EP z+92IF;~}E%??S;hUlZ*GI&icNq=HCDixwR6QJwT@_88m}0%=^|^rRq}d_%p|hgjdq z+$|IZ9l8m{$t~kxhy>@vFR70`=a?FNoJtI|f%RY|5G%6e^IJd<`ll~Hj&i4>^A2pQ z3sE}Ph;*LDG=f@j1X65zlL_xub+=7D89MSse?J$@ruCq%sE0^C1;brs{h}S`=`(Zf z`fVA>p;0H0TRn-);H3`Oq2EVx519=j9T9p7I8bM*By#4fNsrmo!=YM{(>IDr13gx{ zwu1s!*?Wc#p*@_YBcY!H+uIg`tB}YF20fA@5p$rMIxX8sG;%PEe{I?}CNgakDRa&~ zQ8qN6ve?yL1*+0DLy|-T$Svn#h_I=>PJNo|IudKy2&Z02@}@fGyk^MTdd!y5Z&F`% zsc-v|U78bSLJJa2r+SPjk~VrHAXHJCmb4Mtel1l!unX2V|W zoxxt@p(e#^U-Xrn3S8`n#RJUzR0zqVbom*_Gbc4(_o95Ys>$t?{qNlLKamnJkMG`tU3 zNLB)!Fuw@39V9j=m7=XkQD&?_ro}ANF;YdQhMJ@fgY{2RRA7i2@%n`ocK)FDLRH61nQf@9Cs?JuJGntiXil69+MhT2<0CmGOX;UlSrDK zLCP#ztts+qZzhnI9(wz8X053`oiiSxwp8>&@XNBP7~d8*E9wTyD7Rb$hshQENNypM z51yA0_GOzGlmGa`!~Ah{+KIG;kc>KoWX)lc51|C`8Dho4^xglKOZA}rf>hgdP)Vl>%-BSFF1JjCd#D6olUwcvw@&S$CP1B+J;Y?s z4?HNH1*}R4S(Th>H)$rT&eN3pAIL(_Y*wA|s19+m>NAw0wmVGEDk`{}pW;-@s5Vpp znw$!7sJk7RpCgwqRZ(AXs_%rZ;hCJKw0=lYq14(YVGJ|S%%$K01a%E(hp}(wd(DCHZGgO?mgXzK z&-sW9Ycq(`pqGZs@F24Dwb2vi=}8wH%S(X=P{=%h!ZZ~6`r>GzNsL`yU_^nLmED7y z@5X>}YPlVjUANsou#Q%JAq;aTj1Q};rCq-Bhg1hGdB)9V_@(FGMuCIssC^))-S{b^_H+~RI(91y zPJ0%pkQS}HS|68gM}!>6^w1h!^gX~5aQ(Ec40mh|%Q@{&6r;*gO;J7=Esw?C$g!JN zn5lrDpNc&_7W;ONeN!XDUVSQdN-TCM$G+aru%9~>`&E=0;k$rir`9v<1*c;FF&29= z$Cg-=PMb9dJFue=eMI86@##VcIJB0@b=nVr2`8I|9U<^dT;K~p9iGDdbulb`S_CY8 z?31;OrLQQa(%7s%Wld<`z^A-u~iGr)qz9MqiG zoch!~WM_Mp8U9j*{7KtUMZUBR{Vp3l>!^H9^5ZCRo;Lc@W7ZTC#kY{G^dGT~{v+z> zoeMEjXlG2ZnPccIaK-HL$0V9vDGtkBy5gTpLiWi#{_ONni!=fqV#K6xKJ)~ z!%PF0xW`E2R5Q}$784dRK=cX7UdlNZN)Tl{^ASmI8&wX&gQ6y#C#%!RCZGY-cB+rE z|AWBWCS}AkRI!~$ z{N%1Gw2pr6_-X_L8_5wk((BCpDmqIDF_FK?YffGyY$#0>cmvQhmBbGpfQlrS-l;bn zcToR-i(L9!heIZJ{RlG2fU*%cAn|nHb3Zw4o|=>uy8A<7zZ0?wWnfVf0;BSf$MiSP8_aTrs1fM4M)ZktO8k^;l zdqPL`5?L1b2~1zrO=*-(+eAgH!S^Va9^6PUHJHLFZf3Df*&HY#VDo#(h#_b@2o$;; z67mKKH!ok7Y}!M_kGd;y(-wq~7nNfVzK8jG9~Gjd`!dKaYV4ti&S01~x=@pyMo+zx zq@v#r@A?(yCH{k)ztDTg!JWp=4h+^{^sUfRU}}rEs$K1&ae=;(a&S2elTF)1Jgj*K zNU}}O*nr%U9W&sw&~68vG^u&pDCz}pZ&weKdfJF1Q6i=;tkw5~Y5=uq8;D?lNzkOR zz#e?jHx~33Q^$;O-c0I(L0{BaOLwZv(`;(lXt|{tovJfXi3TNha@yeJwa^>1XrIz) z3z+G>!lvGtXomT~%r-#@^qKu{=d?xqfm_qy!^6pNY6uISxXJU4EVw8VaXQGC(ZF*iJl;&qt*&NJ(S>>QU zW&nE5kJN9?iScK!1v_o=<75dY;K9|E9m;uy*E}6GRm23s~C{wBXH6 zvgu=DYkF|#n%aZ=ol33_1yD@ARig48bm1|dH|XGYOzPF=p^VKDlcoK}{Sv+t;! zcJ7P?$j+=QOxlY*E|HJy+h=62D*`7?pUKzk{!G5M?Wla?uEy~da@J1y=WSNm-qzCQ zI|G;?bm zoisW{+eCK4vZ)XeIrup(n#hlBBa6d(95hPX&`r^86Id}j$huh7S8VF1p|Rs|B=|Ks z_)iR=JRM?qnkK-+ThBQWebEa{7G}9ttsqlQ^I&duom$2rhjv>=S}1&kbu+SL)=pan z+YO|b(VzquG2;-8j4g*zlQ#cWdQV{)_y{&5=}q~bHu9V0|_Awy9)3@ zKJ}Psc$-{-VBqkk=*dYnW_0VE7jurWG&r8kkPs3+qtQ^GcEo|0a7ib?r~ver7*@U} zHudDkIP!scf=Ns{u=3K4#29Ct<`Q!7AX)@Ob{nX`dz{H@2Q7MpoY_>~jxF@wHi^CW zQtPs*mK#DwB6^F{T`r4xfVYIHdetOoB!#flxLUo0QC>O8W;i``NGj z9a>Az`O5fbl;tm`WAee=lSFdV13l^eX$}jdj&**%VjkWHfk*6OL&RPj^IfLTjG7De z1ndp0;#mW%BC{1IhoQ5pZCF4IFM}du9%t3-U^#Xsk?hq+$x7PPE&xCvY50L|7)aAj zvX5av*Srm8SF0No2%tA?UI${1IJ>A(a3&0sP3qO9IYRkd`;Ef-=0rWJ(53burhpr|~D z_9)d%nepgGR;dhuHd5Zs%BoW$S^r(G6^-z0`Pze@~~Jzz41A#i-O{_T{qOPd%#ZUdwI&i;0pIGMdelGno zL$X5Y$S=VBCC{Nh)lvD}Vv}NeE4Xjvg&}PMOjjiRQR<%&v>m@p1X_r8dx5fzNVvT3 zNh4+vrN`85Bo~L?vb*w;aI#`L#5SAw)&UnF>mbjd;ozIs0T=y;)Lgrl^c!7^glyxT zU(r^Yo!Z%awNG#Q- zjNhq@=yL?GLW99F&vvLu8UFp)_(;KW7koO(<$ngw169PSE=^OF^zg@+ItcxX>inlz zuxF-<*{MPHzULUT?#bva33AITK;^a={V03@)L?@(o!WANK4!kl`wBU6c6s}+ne0vP zI@Pxq=;N-du)^!S=ySuaAdi+@<+QQ z2%y3mxP!b$yr@4R!t(+x|J)3bn!;6({ahXX5ymYs zu3*?8ITd7W#HpsX~Ea$?k@kq!f%x`T{P zydm!$*qot4$(JBA$ZnCUgf zJ7#d>jCYu@#vkvlfXO2^*?<@2bO{>9+TP8EJe%6d$K{z<9XLY1LmwNL|62pzMo1C^ z-ev@H%Pxo;6H;o1ZyND1Kb6&=f+5zU^HPR3vx9~_t3V@*OQn66A@6eJVMAV3@?h&~ z*hUO_uM;P6hrG9t3adinlcF`G4bp(%7O)a`)O(erLi=yreZg`^u!LBT><6QFk}7IX z8pGd(*uaJqgWvDs4Sv&ML*X^i1Xos* zu|^uc4gb)2FxDW$q15rly?;WGly+(>{MW|41E9lN<_ye>|6AkUD+UEx@=oui)Ewr5}HRO3B%9lI$~HtSHakqOx=_( zp4f9<3?F1850BngjYjprJIPpMg==TU)UG|0=4kIeKODw(8n-J9k0ikG zk{RBM*7gs8_s;p@Ha2^N{pn0x501izu>{ESDf*n0PBuXT7z@zMkqUSIJK}%9QHf1w z^NFx0nm%Oyt=LZ!{>zZ*0Sx!wls-EmFYKNUQT`jKj>xZV*h}3(f0BID(BcbFiGkxq z@D1#rwPMl83_${qJkikQzze^L1Y>W_1L=Ep|x2?+eHg#Rnx zi&iLs1!jMj(M`vw@4@ZFHQQ6J(xMlQ3EZp=CPWHWpfwNYgJ0lq|K3OSxe^sZn| zSqrgA<)y@=e`G#|-eIV4l%A?DAt!FIJPC+;6(R`jV?4!?=Vh#Hl4ldAGf$0|5wZ~Xe}d)R!Q~b z`Af{Co6k-ju+-{@Ov7h}A!WTPW425E*wOy+FbAFgz+O{s7aRAXoTME>S6rqyaT<04 z_5qlBn7W+m-$kNa5j7IB~omScm^tKtP$6;cjL6*MzW(=g|O`MIfq^&zH9??$^MJ$ z#DTs2;mu5^7jF)aM;jPpt2K);rU>X4#e`)u;H^0lBGEoZhZxIabI`|afs6s+H+7A%VA%YLmLL=!vYD` z(|bNrR2(bk&F6(tG@9=XT%5prwE1p(p2WkK__yL6r^%?@oQV%n(>Q0az&8fRz0+xV z2HP#59tyog*|0@h&B9%wZ3rFO?X=X0BU+abH1^EaSsXx;4xPY;1iPw2djKHubEG-d zcf&4JUx3yL(3Me;Pk=4~2&9>D#_^)BQTyvk!Ug+qssOL)Q#^(gjg+QP@-riAhU=c_{w zwU2?ju|rKqj4Qwf_p5R~a;W=nRMdBrzhtNWtk^0T06wLYx_2?gaY`$6g zT=pP7bJXVV;kw$z@aNhr`^!s9rX`x*hRC4XdEQNgoxwo2o@`u zCy`%iKZ(lVENW=BV(L)#pY)-6$*LeYng|->^3Eq5yHjt4ptG>{hZH*+L$B!=w!|@^fH%z2i@VS zXvKuIrJhYn%1&0GHS$~a_G0sn20^h6Df-23q{U< z0aGrUrMEFzO~lHO)AE87Fm}UYO`9}rH0C)c)BF$GgU7IGKvPG47C*^ud0)PpIK-iD zsVMd{!bjbOIFmqMjl)uG0oG*OhoIDh3iPlkUG#jwBiTs&y~R2xNGt(-8I2E^M}aX z5sJg~zQA%?LjKRSO;mO4CEvAoBwRBV!=OdA$=T=RqnA_Di6y-O&3v2$3J(mson~uC zQi@bzSI0Rb`i-fq;JJ|V%r@;UpZcHG>`%ckFgi(jkXITg;s`fRIN$|LqV~8vgLl?X zg@Qq|=}2Zo3P=S~q`y{N=0)1w;q9^ArG)oTc3VAyYG^|R(`LGIg zW&tuZxy(?=BTD;`Bm&9^^EhhY3$aYQP6p>E5@ z`G=XS=4rl;6ky*?E9ig-1U1Km6Kn+Rf#3_2T9JRfo+P4^0SMBRD zzp<~!)|<6s7!^Dr=QWr5DGpimSdDdcw9d5^mS^O(N3m*VZMI;KOo8~YhMz0TYiBV@ z`nPlpGjY4ZPB=j3z6+GH1J1G@dHa2Z)Z7)p7yXY?A~H(ojbEnu-*lN@#sm2gU zM^Yknd33}M|LYZj6N%W)mhZQ3R_z;cpr6R;$t7q;I_GF_m4kjr8lW2iik?)+rpoEb zRsfA73b_yhMAk}&LvGlppeh#LWA)^bKtp3ot4228z8O+_0&5f8N>d*?Ova!0A#h1e z2dTsPU^+-vP4^|@wCI=&oPa`qiuC7vdHbCsxd8Y1Zk;1QonRb*W(|8k6oK=ubUE8;TC^bA+I%{>={c4MqKD_yoyZpSBN^dqwS1E*mDVpGB%@ z99gBash>}P(X~GX*giV#iIYy(B!>VqLL7?PE8hWwO`32CTmWo_U7e&P-o6>#b>TcS z>*MnFYzI2FQr2NrKZ6d8u_AF1>;Ra*pGn`QP9)fk)W1dgWX9GQ^#1#K@1K=tL#jGv zF6z&;#lF?57iXYzqu1oCV=BSHLnsjh(hD$5FJNkckp?qm|Hg{IFktRRC+bYMS-MwE zbd-Gst4;%SaYu@R4HR|(DUvY;clE!VICkjNNU}Xn&A!oz>EINoFZSPAceQqyOyLV? zt*sS%tZYc#|8bxjXSF&=XdUc`?4RIrRU4@g=8}i9SvNah+`*DhL*$A z0=s@==AbT?0Uj z8ADf0^TU7Xmx0# zGpItO0OZi)+_D9y-gd#5U!!O;UY}Rr?Efjgh(Zc*F-q6x!?Nr$QJbruq2Enyv^>B1 zahpcP^71rR9yp{T$iOe7PSw-uQa^;_wM9{H*vKUKr2~f!XrD(*jEZSy zhD|+2Q|hBuv_4GKm^z$-hpe9IZ{?Dj_SIZ7&LGWUc3s|%t256)RHGMK+E;JG1>uco zq1Nztl!@VVKTs7d1yWgdK8^vku_?K{{mhVrs(|0WAiW}xEBP9LTm=;PWfA*`^nG)X zALr?D+Y?h=mK!XMUW%mWAA63nyS^Clh^c(EcF{eAYZ`CrT zY!}JY%C_B%Lk9P?|tvYjZdY!foC`QwfYkK19N0SSszb zZ$uxF!pHkqt=FC_>J_>VWNBg{d|NF@++$LK9mu4sm%!;>bwfH;le=4xO}#+_ z%q;+wa3SW7JU_Zu&*(2-6K+kH~E#LJKUX-%uP!XNVz)_4Tb}hkf39ZI7 zwHj?6b5D#W}KPU6ibps#w{QHIOtGq-Un<7Qa388*u& zt8$dU$3$huS3M}anNpqV^V*dT^<^vFbI*Lsp&q~-D#@uY=tqXtZxeghK=zD1@>ybQ z+-Ro>-<9Bia-+hi^cV+KK6EZyN<+mRrp`#ce}Jl6_E=Tfs-7j^ITFUPeR>;9;N5?>o;I#VkA6@Vr`apZ^Hz2cS=mzgXZ^6{eH5;RxDWDU5WEZ z*5buQPBrSEkz=9XL)KgPzkI6U zfZZZ~II#ize0O^O9c*&CZZir~^!sU}Q|Vksn@_y-bRI@+cX z>02W}TJ{&fw&?5LNP1Tkcqjtwjsimla4uS?IS<~HJE?QH29h1?^1vfaZ z8EC^IN0%S>$Nxac2SMrLI`HJKCD>Pea zCR9uuNIsn{FOe5c4;W~K&PJz(F>A+_*|rG_)$3DI zoZ5ecK5-;0R3Au5>2)O7w7hPow&aja&Fi&k&E0o*VP$?v$f<2Sgjbu|+{+*vLkN^L zC&*Ej**#)qO%LfG?&`p;-_4fl*X&`7HETNZPD{kP)t6G*V_(a`3#prGtRWTcerh8{ zUDrf`wvO6SQSYZVLK-y%(pnK{tO=1sEupTXrqk9@1F7q%MRM9&v0TwCnaa-hF9FtkcE)8|As{}eBU00#5`yB7gSnR53U0eidLHG*3tAgH7Crz+|b38QW zaoW|u!T7}~_%en+T|Kz}B=vOMiBZ%~uDby{{y9Kt)%>G-jzp(Rt;Tr52NR-bIq7pb zak<>7O{Y(LXt;MUH_fSj?achQGc%;9VYpw){x8s#>aSF^)hOYFGZPm$y9jP+U*X3n zEeG!d?@rT4in<&Z5QvRK18ff39H))<`F^0_NbUMZfebD~Z#_l>?PVC-L4)oebK`X+ zbPx%2wh;G~KMDPQJFraeJJkz8J+0>frne4#>RC9O;h*h5&b3Y)G0Z#~`X#a{iI;^N z(Uw9V4Vs^X?huJ&=A!~Z0kEVY4<+KWE#St5OAFxtq%-qlN8;2B(3e{-K%SnThh$(y zvob!&LVpEeYI8A5!R6~d-=&J~#*uhjImhQ$^s3JEp5bJ7=q@;%;WWk4gLP@FwP`am zXmvf6AN1b8HE*L?*;Tz;In zaeaBDV+X`U&-sc989LR88O}`HQx7FNaP{6fK7{#NUZPXKZ4Vi9VSly7s2?^OEGK-q zPQ5mrbPF3u$Z=4)a7+f)$`(P4<6iC=!P_0*s8O^Z^q+xGQK0Q`w}UdXU5Yi^Xy@cB zC)T$|z{^eV`3=>Jyb?v50KM~_1I@%-3%$b_iNh}BVRR`e3a7G&=^Kf@!CyBXAc_RAlfvy#$ zP>0Y<7_P;42P{YE(*yL`0Ziw78HOHXw;b*BF(LPXX@%qfopM+{^uG&a*6U&_VDOJg zPS5W{SA#q@Q=&UMi~mM|w?enGuro9k2u{mqzSM!cPN5wveOKrqggtN?B`%L+Tppj3 z75N&qN0Tgsl+o^c;iQrBMlX zpp{%HxE-!weF(ccBM(#Fu!+V4jFhG#|BOebLnIL1@8wo4TEEsO$|9R+gvF5 zt{@ZMyN;(3($mZ*T|IM*_O=Fk-~=AEVHh~@4t8981=c_qkY1a*4~OR++NBCRKd+1r zDm%Pvv=j+q!etHt!^Ylw6lY$ZOt&`lphugmc zonVAIrSA&3?vnC!AJ2{54%|?Kv$9*U zJ>x{b))%00x@`KY1iIP~_{5|>@59|Q!1z@MhX#}KjB$Q`uOm2uL>o9c+o4MSomj2J zagsKCZH%(A2C*`Y^*;p^bQrlM5v4n@`hX63{Gc-adEP?fB+Zo$N*y4B6`VBOR)lWq zGuxe+Z^4?bTE?%$^^Bob!_~~$K85aSQYpUqxXtebISniycB$=91;+t=E96sL%TUI* zD0NhwH;!3`T5JgwACiBvVfxWRw5gPKKi8 zdD1|ADokK6>FES{?O0l1e>`IUJ3D)!iKJx{Li-=#Z)Rs=d4^eTc@j0ox(e*-Vkydk zqZ8{0cpOk^Hq6iq^XIX+sbn6Y0f>L>hO z7^lyLZcl_s1;D{A)!jr$JrEg>KBDpHO>*NZsoBWC!I(r}h{AY8+2Bu-TZx&j<)lOX zx7=a@1*cwt!Qy(dfk(+XfH8VJa@DXsOcxCIDsWucgA0c3;KhOAbIdMOO!z6b$m~&^ z6BCn4rB?pp58!%O{M=Gx0cSS*JK7oq3a_R^u@rh8G2n zF{+}?M0+^kN3r1@epH@QUkyL%gt)LtD?=9&3GPZwe7PqzYENl7UHDUQg!{=aHTcI^OwS0vjiq^_#hYhIx*WU_{k7+3Okcxyp=@G{ z^@eaR#b{goI>?d0W-u#-w-5;&ubKET!oY2S;t&&Tx;ZotjD}vKf3hhJI4KlDM=>|* z@nstaNoZz8GgKPId!V?xLakIq^rKvabZ@!$GcfhHkjlWjLN_Bcy!__QipbpB#=7@aVDs=1b zX~^1xxtZK@4s_iP(pad|9MA{16JN4|x@!Q1Klv)eZwu00Y6l=SAW%TzbXwfxpdxnPfHz!I{~w zw11N5(68@H?@4au{nf(z*xit$!}69>{etFsd_I{RS_vrjP8(ej1FqZlz?@^4806)W zKhGBJv8&a{`tfr{KaO@sM@)Cb6eavHP@)RVq*09?`3ZVt_*PPGW(San?-FPsj2!yCM&l7oXw6bQc1LW+Y`)w7M`gMOL;} zn~fS!`_Y*`=Zu*d{&(2CM_-ZdRHtSrmREes6}-HPlV4(W*B_ZXPa(^ z-8jP6D;$}xQ!xwl@*}b930SYd)C)Gw{|ULfFE~ zXt485GumV=0rOdWA7RM(?3=%#+!$bD=Cets&SzHuZP0wS1?7I1`7G=1#+FHVPNcs^ z3@YqaD*PloQt$&q+?t05>guVW9nI7{fb_hTm30}eJd1Zl>}zw)QNut47r&m z(Yr!lGORtM-fe`4Ua$pWWIcdwB{6&H)GxXU_dBrDbNL*EMOO7|>@GPo-v?(YO8eJ| zp%*rT02a#3(eK5wX)UgxePZn&^EwO)P8_}A{{Y3u?kTlKJJn~q&_9SCFz_nT@43)3 zE6!tPzd&UcKS5>25kdY8MmL-32ei!iHMC_O^Ofd{s;d0v%ULkd+<;%qtMW9UN0s0o zN*X!1JaaYuW)@{EH%~Ns8U=}w(nV9sCz?y~S5`@|$#~=c`0+x82#yBv!;7*v60xSr z5E!SW$skqo=+UKSzc)Zw>vP zSI!M)<8|^4<}5sdaVjxN2O{y-n5(^I^~j9h*MfA)JryO8rFoV)hq4fQv?RiB;D82m z1AeB^V+e%k;t_lR?<#Y)xuUin^h*89%!b$`LR#qe)%ktq3h-&hufutWCJGln)o8A$ zudN1KtQwJg7yg%?krJVs3rcEgYJFz<%{N{eG@v2NY%RqPK4tNSgj{dqX$|Q5MF2#?!`4|pUVxe();u$0@k;(%zeq)Z* ztE#rPE+XFn7_kx5u%^LV=_%&|n^aj_?U__s(pXaOEvadkG^c1We%8(H!X|dXB>dne z6o7uYbJC)c75F-lBz+_PB7Y4-0$zbs$|MHq@cv1iZKULu@+J30*;D*dR()-)&k(~^ zq(fZxOo6CfQ5ExoNZ%pt;f(?~D58})N->!k-ixR)$N->Bq)uo5PKjVrr!gLCG}Z@! z2d>ah@w0zEkNANxY7e)=HmQpL+#NGT^z(g_8e)FRueAKSNWu+B!B3KvRSpD|RZ5WVxuK-dQ*QRv@@Du(wUGGlyv{7G zt*yH1$}0!_(kJOu^hwLxaPZ>LsI1ekB3N@vmX)U!(n7Z6dG0x@>72wF|H3=2K}pij z`}=8ww)X)HgXE)b>hJ$oGQM<#ux%J@9qxM28H4N>5J&pv*ZceFdl#*5_V?Ezl-}y^ zUrO+I`up!AItY6a=DpY7KNG{?W`sV3=J)&iw^Dexzn^|zIQs~WG9fGs_4hxE(EK5M zlO*tqwZR7v(k7k&Qq%MVM{4?=iPlu}+9Yf0gg|oQ z?TM*oB{e-iH7!3iMVbKoR{SNsjfHfCk~KALZGts5J&@>1HJ6M`O`n^ZW=%~|MoH2{ zBtM0}O4Nt_7B|B!IBl46cj8@1dh(saY=Pm4KO8<1^`8TL1-KvLudf^X=V%)VW!{~T zpPGJGVt%SwPs&f7aA&eLHGAzaYie#__}tXIgsVrU=Gs!T!6`6+$+@(RlBObiE@*rO zJ{RMiXx*7$OHE%(bqgfj22Q~asx)sDxaY5w2Y+?QmjV5_h4L++e85ksBRNF$vHp?vyn`=s-sm{A_=5g9^aLWb8shArUX)WRI2SbN+Cz1s3_ zfB)H__bs&MqCR_uq&07pbQ`kMXQyvNKV!=-QNE&W8|BNET9-K1G$b))RMC*|`J)mq zNfaZS1mojJ;ba|qeY0}rzjhoop7Mf6%h@AV#TCz9j=^rEt! zACa{ywJ>qP&>Y$ry>8HZ>SO3WOI$DkJ+T1N9mQD4eMJ)eS|V!xmM z&9uI;?TA(jXl=&L-Tx^qvPE5>m2p45hmUt@erj4R>hP|Sspd$3wQ?Ob!_N8+Vs&Aljt-?)i&K{-ZW&r;yiKb>EB#P^|4qajOqsAhL&@Kn zn&%&?=O{1*&prQwB+Uegzd+81}2)w23kiYUT|7g+JY=98;=ct zUxA-Pkh_NfL$#qo`lXOPbfxCi55*7rZB84Ffsiev8hQGEagk|UMe;Ky>0VRvyC%~f z6TQD_LXjs;$$71nix0#YZO*X9^mfSi_(uUFdFNOguNQ3sdrm@ukG@Fw3B-5{xlK+w< zJ(U!}=Xbj-<`Q-&iWWms%gX zQTkd=-n~?MA}#sQQtA2AlaDTy?mZ*Ake6+L(fR{=l95NAo|Ihal_+A3v zOW=D6d@q6TCGfojzL&uF68K&M-%H?o3H&cgfPR&Xo~;+~uvNs3x#r-I&U?~h!0QLa zgIK4CO)tWnFE(B$;-fiOYCWI7u**VtOK?dy4Go73s!0 zUy6YL`(%GDy>1kfcTudAo5~SrYEO?M_~pA(l60nc!SWY-*m+&NjTLbt5Y?7)A2c(N zu|`lR=+T-DJ!1J)ukrcKS7c4g%D#MxpT%-k<>Y2%PtD{|1OJ=C zL|B>Jgi|pRr39&XNO+<|`%#0RL@6m^2V&C_rQ}He9|#{7u@eK~!zH8t41}jhM!y>f zA0Zk2dmwzIWY~d$@KF(aI1oNs+A8|TK=^6W<{{cSQA&;2^MUws#J&!Mr%7q6VNpPv~DJ|<$vV^b4hRSo++5Pp_4l>JDA6*cVbKztZA zLqB5@5~Z`HydmMn=n+Lu!)ucCX@3;L-%JP+V&pknAY6pd1o|Vkm>God=%F=vf~O3E z{}}M0=$8Uc^d&LwBFdg}{7dk>LGTp(B0}MXto|$O~eW1(U zCh1iDna}8-s?Rqv{B$W|-$Vh+1$@G0GlLl8?mECvhnz#d<8Z^=(50v|&|bZwKhoX> zJ@nCvGx+O(f49Vecf^6e5(nN7_ys7pi*3G0(s5DB=@|HlpROVfxJlhsRFYFJZ?72S<{_g-kUEst9e+K-5 zSb%u{XB;|jGI*-gE&3PRYeyd1>>>F`qW>E0J__P!30#80o6W3uxAcnt$?HZsSAeSi+bnU`Yl z8y|^-|BpEE7Xc?d8Ek)!#lcS-!SM&%pK}2ps=ia>z!wTST{m+9&^Z%&cE!PeL*RGc z#_^1PeFf(2#Q)|>4rgbf@LCM`Q2aE-f!`ko{wUyNC;NV9W(7bj?0HvE zVFwKPU&`LmBIMLuV)+wHCO)_8r0E||J#;lkovM~%-@UsF=$%$c(6YJMQNpwd&e+%A>X`x<=y zii)fax4- z3v6yTkc(Xfk@o?}McaIaL$|}d$GINn(wrOitU;OR+pmyIp!`{?6xbS z48^txpz?-VcV$UUd6h@9{Wz=MQ<3F%FKcRY*Fjvh5S`bz(%qOHbAGtG#9Jd(cxo&1 z^5!}n`33IDS(CG-fl^shiMte%tZ|o>_{u8t@(PwLvF1D6IayPrYEN}p-O6Z=oT;qM za;|W@eUgB8$el$I5(ga%a$F+c?%xmyO)h~_CNvM-ungtoahXZm1`E-ajC zEAf?hZz?UlNviex7U8@(og$~k0^H5py29tFsv68=X+wiZ27i`fB2&Dw&U3|FkB>qs z(`WJF4Z2fNOO+TPTrZ^Qld)NX_23z=Ez*<3~qmBE_z$t;c;Kw-<(`1l&0ay*ZbfUhtqP!%gTQE%M4w!i|Py=O*TNdnA1YsKmGc#srEUqFAxE?WpTO)_jhtMU8d^yu; zOz<+>Q}3?ApvJ5ux_u7Wnn*D~UdXJEr4Hi;a@5v9JKco_Q7=<|BUb06-uBH3P%!yB z6dyG)KI`$Yi&2b;fo1>=HOLGw zr^WC<2f8foI=DK%3L1N(r3=!a7V+-;(+JjI<4 z-_#hqO6i)I$6Z162bP>O1()rh=KeCc#a47TVJeKW!5Q~-91AhFm%}@xJB36i(qpGN zYRWxLq@-T&f+Ba$WP1UuW&wQdl6sFFsFs`k-m>LIxGXu?N*SiI-VdL&!Q+XM6Lqx; zx^Wp59f6o*UQD;qBq^(5Wwo!Q6d}4P3oDH`$lX(4CuQNr(Bq-6o~MXghyx;Sq}6+>N+^SPtE=)!SHXLVpD#i4nvK&N=7^s((xjju~o;sf!^?<9$i1C>Pr(wLK%o1F)1(!6w zXTf2VvM{S5OBpjs`yag0Haac&h~=-yKB2K+Xq*QyiXhzB=R!oVloQEcEC?B)ITji3 z#=O-4=intazfa^h!VCjZgoE?j0LS&WT7!S%oPrV3ohW*edB8XM#XAN6U*TrR(?AeJ z;R^-{2?E>Ta19FCfI%S;7zn}hClClQCYb0hrU>`L#W3ha{?0WRs>p_V*< z2WoVV0es@3;9HRKpMKzx+MTmNeGqvIU>khkN?Gk_m!-6h98y4c| zwQ(&N=1&Xo+RvWxTL>(yjC@K;lR_qEi>-YqTV{je=~>cy4# qduUA;{`2|a=L6qW?B(me6!&yaSqpa2Id=0GfAg{QSWJXeZGHjZd-9Y3 literal 0 HcmV?d00001 diff --git a/Analysis/TimSyncComp.C b/Analysis/TimSyncComp.C new file mode 100755 index 0000000..7cc4ed5 --- /dev/null +++ b/Analysis/TimSyncComp.C @@ -0,0 +1,128 @@ +#include +#include +#include "TFile.h" +void quicksort( Double_t* arr1, Int_t* arr2, int left, int right) +{ + auto i = left; + auto j = right; + auto tmp = arr1[0]; + auto pivot = arr1[(int)((left + right)/2)]; + + // Partition + while (i <= j) { + while (arr1[i] < pivot) + i++; + while (arr1[j] > pivot) + j--; + if (i <= j) { + // swap arr1 elements + tmp = arr1[i]; + arr1[i] = arr1[j]; + arr1[j] = tmp; + // swap arr2 elements + tmp = arr2[i]; + arr2[i] = arr2[j]; + arr2[j] = tmp; + i++; + j--; + } + }; + + // Recursion + if (left < j) + quicksort(arr1, arr2, left, j); + if (i < right) + quicksort(arr1, arr2, i, right); + + return; +} +void TimSyncComp() +{ + Char_t* f; TChain* MUSICdata = new TChain("Data_R"); + f ="/home/bavarians/exp/test0/DAQ/run/RAW/DataR_run.root"; + std::cout<Add(f); + double run_portion=0.01; + + //""""""""""""""""""""" + //TIME synchronization of the digital board + //""""""""""""""""""""" + // Double_t shiftTime[4] ={0.30026482, 0.200206944, 0.100003416, 0.0};//pulser + // Double_t shiftTime[4] ={0.192828788, 0.137373792 , 0.058816296, 0.0};//run28 + Double_t shiftTime[4] ={0, 0 ,0., 0.0}; + //""""""""""""""""""""" + //MAP + //""""""""""""""""""""" + //Left 0->15 + //Right 16->31 + //Individual{32=Grid, 33=S0, 34=cathode, 35=S17}, + //100=empty + int Map_DAQCha_to_MUSICStrip[4][16]={{34,100, 1, 100, 33, 100, 5, 100, 0, 100, 9, 100, 17, 13, 100, 32}, + {2, 100, 16, 100, 21, 100, 20, 100, 8, 100, 24, 100, 27, 28, 100, 14}, + {19, 100, 3, 100, 6, 100, 7, 100, 25, 100, 11, 100, 12, 15, 100, 31}, + {4, 100, 18, 36, 23, 100, 22, 100, 10, 100, 26, 100, 29, 30, 100, 35}}; + + + //""""""""""""""""""""" + //Data tree structure + //""""""""""""""""""""" + MUSICdata->SetBranchStatus("*", 0); + + UShort_t Channel; + ULong64_t Timestamp; + UShort_t Board; + UShort_t Energy; + + MUSICdata->SetBranchStatus("Channel", 1);MUSICdata->SetBranchAddress("Channel", &Channel); + MUSICdata->SetBranchStatus("Timestamp", 1);MUSICdata->SetBranchAddress("Timestamp", &Timestamp); + MUSICdata->SetBranchStatus("Board", 1);MUSICdata->SetBranchAddress("Board", &Board); + MUSICdata->SetBranchStatus("Energy", 1);MUSICdata->SetBranchAddress("Energy", &Energy); + + + double Ibeam = 30000.; + int nStat = MUSICdata->GetEntries(); + std::cout<LR16)",5000, 0,0+0.5,80,0,80); + Double_t* timestampVec = new Double_t[nStat]; Int_t* entryVec = new Int_t[nStat]; + for(int j=0;jGetEntry(j); + ChTimeBefore->Fill((Timestamp*1e-12)*1000. , Board*16+Channel); + timestampVec[j]= (Timestamp - shiftTime[Board]*1e+12); + entryVec[j]=j; + } + quicksort(timestampVec, entryVec,0,nStat-1); + std::cout<<"sorted "<=0){ + PositiveTime=j; + break; + } + } + + //""""""""""""""""""""" + //checking synchronization + //""""""""""""""""""""" + Double_t TimeEv = timestampVec[PositiveTime]*1e-12; + + //""""""""""""""""""""" + //Plot definition + //""""""""""""""""""""" + TH2F* ChTimeAfter = new TH2F("ChTimeAfter", ";time(ms);channel(S0->LR16)",5000, 0, 0+0.5,80,0,80); + + for(int i=0;iGetEntry(entryVec[i]); + ChTimeAfter->Fill((timestampVec[i]*1e-12)*1e+3, Board*16+Channel); + } + TCanvas* c= new TCanvas("c","c",800,800);c->Divide(1,2); + gStyle->SetPalette(kThermometer); + c->cd(1);ChTimeBefore->Draw("colz"); +c->cd(2);ChTimeAfter->Draw("colz"); + +} diff --git a/Analysis/TimeSync.C b/Analysis/TimeSync.C new file mode 100755 index 0000000..16f23da --- /dev/null +++ b/Analysis/TimeSync.C @@ -0,0 +1,138 @@ +#include +#include +#include "TFile.h" +void quicksort( Double_t* arr1, Int_t* arr2, int left, int right) +{ + auto i = left; + auto j = right; + auto tmp = arr1[0]; + auto pivot = arr1[(int)((left + right)/2)]; + + // Partition + while (i <= j) { + while (arr1[i] < pivot) + i++; + while (arr1[j] > pivot) + j--; + if (i <= j) { + // swap arr1 elements + tmp = arr1[i]; + arr1[i] = arr1[j]; + arr1[j] = tmp; + // swap arr2 elements + tmp = arr2[i]; + arr2[i] = arr2[j]; + arr2[j] = tmp; + i++; + j--; + } + }; + + // Recursion + if (left < j) + quicksort(arr1, arr2, left, j); + if (i < right) + quicksort(arr1, arr2, i, right); + + return; +} +void TimeSync() +{ + Char_t* f; TChain* MUSICdata = new TChain("tree"); + f ="/fs2data/bavarians/MUSIC_Devel/FSUDAQ/Run_001_B0.root"; + std::cout<Add(f); + f ="/fs2data/bavarians/MUSIC_Devel/FSUDAQ/Run_001_B1.root"; + std::cout<Add(f); + f ="/fs2data/bavarians/MUSIC_Devel/FSUDAQ/Run_001_B2.root"; + std::cout<Add(f); + f ="/fs2data/bavarians/MUSIC_Devel/FSUDAQ/Run_001_B3.root"; + std::cout<Add(f); + double run_portion=0.01; + + //""""""""""""""""""""" + //TIME synchronization of the digital board + //""""""""""""""""""""" + + Double_t shiftTime[4] ={0.0, 0.0 , 0.0, 0.0}; + //""""""""""""""""""""" + //MAP + //""""""""""""""""""""" + //Left 0->15 + //Right 16->31 + //Individual{32=Grid, 33=S0, 34=cathode, 35=S17, 40-43 pulser}, + //100=empty + int Map_DAQCha_to_MUSICStrip[4][16]={{34,100, 1, 100, 33, 40, 5, 100, 0, 100, 9, 100, 17, 13, 100, 32}, + {2, 100, 16, 100, 21, 41, 20, 100, 8, 100, 24, 100, 27, 28, 100, 14}, + {19, 100, 3, 100, 6, 42, 7, 100, 25, 100, 11, 100, 12, 15, 100, 31}, + {4, 100, 18, 36, 23, 43, 22, 100, 10, 100, 26, 100, 29, 30, 100, 35}}; + + + //""""""""""""""""""""" + //Data tree structure + //""""""""""""""""""""" + MUSICdata->SetBranchStatus("*", 0); + + int MAX_MULTI =100; + + + unsigned short bd[MAX_MULTI] ; + unsigned short ch[MAX_MULTI] ; + unsigned long long e_t[MAX_MULTI] ; + + + MUSICdata->SetBranchStatus("ch", 1);MUSICdata->SetBranchAddress("ch", &ch); + MUSICdata->SetBranchStatus("bd", 1);MUSICdata->SetBranchAddress("bd", &bd); + MUSICdata->SetBranchStatus("e_t", 1);MUSICdata->SetBranchAddress("e_t", &e_t); + + + double Ibeam = 30000.; + int nStat = MUSICdata->GetEntries(); + std::cout<LR16)",5000, 1000,1000+1,80,0,80); + Double_t* timestampVec = new Double_t[nStat]; Int_t* entryVec = new Int_t[nStat]; + for(int j=0;jGetEntry(j); + ChTimeBefore->Fill((e_t[0]*1e-9)*1e+4 , bd[0]*16+ch[0]); + timestampVec[j]= (e_t[0] - shiftTime[bd[0]]*1e+9); + entryVec[j]=j; + } + quicksort(timestampVec, entryVec,0,nStat-1); + std::cout<<"sorted "<=0){ + PositiveTime=j; + break; + } + } + + //""""""""""""""""""""" + //checking synchronization + //""""""""""""""""""""" + Double_t TimeEv = timestampVec[PositiveTime]*1e-9; + + //""""""""""""""""""""" + //Plot definition + //""""""""""""""""""""" + TH2F* ChTimeAfter = new TH2F("ChTimeAfter", ";time(0.1 ms);channel(S0->LR16)",5000, 1000, 1000+1,80,0,80); + + for(int i=0;iGetEntry(entryVec[i]); + ChTimeAfter->Fill((timestampVec[i]*1e-9)*1e+4, bd[0]*16+ch[0]); + } + TCanvas* c= new TCanvas("c","c",800,800);c->Divide(1,2); + gStyle->SetPalette(kThermometer); + c->cd(1);ChTimeBefore->Draw("colz"); +c->cd(2);ChTimeAfter->Draw("colz"); + +} diff --git a/Analysis/timeshift.C b/Analysis/timeshift.C new file mode 100644 index 0000000..c7c6c90 --- /dev/null +++ b/Analysis/timeshift.C @@ -0,0 +1,302 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +TCanvas* cGraphs; +TCanvas* cProb; + + +void computeNSD2(TGraph* ref, TGraph* gr, + Double_t threshDT/*microsec*/, + Double_t OverlapTMin/*sec*/, + Double_t OverlapTMax/*sec*/, + Int_t& npts, + Double_t& NSD2) +{ + NSD2 = 0; + npts = 0; + for (Long64_t p=0; pGetN(); p++) { + Double_t tref, dtref, dt; + ref->GetPoint(p, tref, dtref); + if (tref>=OverlapTMin && tref<=OverlapTMax && dtref>threshDT) { + dt = gr->Eval(tref); + // cout << i << " (" << tref << "," << yref << "," << y << ")" << endl; + NSD2 += pow(dt-dtref,2); + npts++; + } + } + if (NSD2>0) { + NSD2 = sqrt(NSD2); + NSD2 /= npts; + } + else + NSD2 = 1.0; + return; +} + + + + + +Double_t findshift(TGraph* ref, TGraph* gr, + Double_t OverlapTMin/*sec*/, + Double_t OverlapTMax/*sec*/, + Double_t threshDT/*microsec*/) +{ + Double_t shift = 0; + Int_t iterations = 0; + TGraph* grShifted = (TGraph*)gr->Clone("grShifted"); + TRandom3 rdm; + Int_t npts = 0; + Double_t NSD2 = 0; // normalized sum of differences squared (NSD2) + Double_t prevNSD2 = 0; + Double_t NSD2min = 1; + Double_t tmin, tmax, aux; + Double_t tini; + TGraph* gInvNSD2 = new TGraph(); + + ref->GetPoint(0, tini, aux); + + // First get a coarse distribution of the 1/NSD2 + for (Int_t p=0; pGetN(); p++) { + npts = 0; + NSD2 = 0; + gr->GetPoint(p, shift, aux); + shift -= tini; + + // shift the graph time + for (Long64_t ps=0; psGetN(); ps++) { + Double_t tsec, dt; + gr->GetPoint(ps, tsec, dt); + grShifted->SetPoint(ps, tsec-shift, dt); + } + + // check that the min/max times are within the overlap limits + grShifted->GetPoint(0, tmin, aux); + grShifted->GetPoint(grShifted->GetN()-1, tmax, aux); + if (tminOverlapTMax) { + // compute NSD2 of grShifted with respect to ref + computeNSD2(ref, grShifted, threshDT, OverlapTMin, OverlapTMax, npts, NSD2); + // cout << p << " "; + // cout.precision(10); + // cout << shift; + // cout << " " << npts << " " << NSD2 << endl; + // Fill histogram with inverse NSD2 whose GetRandom() method + // will serve guide the search for a precise time shift. + gInvNSD2->SetPoint(gInvNSD2->GetN(), shift, 1/NSD2); + } + // cout << shift << " " << tmin1 << " " << tmax1 << "\n" << npts << " " << NSD2 << endl; + } + + // Retreive time shift with largest 1/NSD2 + Double_t bestshift = 0; // return value + Double_t maxInvNSD2 = 0; + Double_t invNSD2 = 0; + for (Int_t i=0; iGetN(); i++) { + gInvNSD2->GetPoint(i, shift, invNSD2); + if (invNSD2>maxInvNSD2) { + bestshift = shift; + maxInvNSD2 = invNSD2; + } + } + + cProb = new TCanvas("cPorb","Prob"); + gInvNSD2->Draw("al*"); + + return bestshift; +} + + + +//////////////////////////////////////////////////////////////////////////////// +// _______ _ _ _ __ _ // +// |__ __(_) | | (_)/ _| | // +// | | _ _ __ ___ ___ ___| |__ _| |_| |_ // +// | | | | '_ ` _ \ / _ \/ __| '_ \| | _| __| // +// | | | | | | | | | __/\__ \ | | | | | | |_ // +// |_| |_|_| |_| |_|\___||___/_| |_|_|_| \__| // +// // +// Main function of this code. +//////////////////////////////////////////////////////////////////////////////// + +int timeshift( + UShort_t Board=0, UShort_t Chan=5, + UShort_t minE=400, UShort_t maxE=600, +// UShort_t minE= 1800, UShort_t maxE=2300, + // UShort_t Board=1, UShort_t Chan=4, + // UShort_t minE= 1700, UShort_t maxE=2200, + // UShort_t Board=2, UShort_t Chan=4, + // UShort_t minE= 1500, UShort_t maxE=1900, + UShort_t refBoard=3, UShort_t refChan=5, + UShort_t refMinE= 400, UShort_t refMaxE=600, + Double_t OverlapTMin= 0.3/*sec*/, + Double_t OverlapTMax= 10,/*sec*/// + Double_t threshDT= 100/*microsec*/, //80 + Int_t MaxEntry=5000000, Int_t FindShift=1) +{ + + + TString infile = "/home/bavarians/exp/test0/DAQ/run/RAW/DataR_run.root"; + + TFile* myFile = new TFile(infile); + TTree* tree = (TTree*)myFile->Get("Data_R"); + tree->Print(); + + // Simple progress monitor + TStopwatch StpWatch; + Long64_t numEntries = tree->GetEntries();; + long double Frac[6]; + int fIndex = 0; + Frac[0] = 0.01; + Frac[1] = 0.25; + Frac[2] = 0.5; + Frac[3] = 0.75; + Frac[4] = 0.9; + Frac[5] = 1.0; + + + TTreeReader theReader("Data_R", myFile); + TTreeReaderValue rvTimestamp(theReader, "Timestamp"); + TTreeReaderValue rvBoard = {theReader, "Board"}; + TTreeReaderValue rvChannel = {theReader, "Channel"}; + TTreeReaderValue rvEnergy = {theReader, "Energy"}; + TTreeReaderValue rvFlags = {theReader, "Flags"}; + + + Long64_t nentries = theReader.GetEntries(); + + ULong64_t* ts0 = new ULong64_t[nentries]; // reference channel + ULong64_t* ts1 = new ULong64_t[nentries]; + + cout << "Extracting data from " << infile << " ..." << endl; + + Long64_t entry = 0; + Long64_t e0 = 0; + Long64_t e1 = 0; + + + // Save the timestamps in arrays for selected channels using beam related events (energy cut) + while(theReader.Next() && entryrefMinE && *rvEnergyminE && *rvEnergySetLineColor(kRed); + TGraph* Delta1 = new TGraph(); + Delta1->SetLineColor(kBlue); + + + Double_t MaxDeltaT = 0; + for (Long64_t i=0; ithreshDT) { + Delta0->SetPoint(Delta0->GetN(), ts0[i]/1e12/*sec*/, DTus); + if (DTus>MaxDeltaT) + MaxDeltaT = DTus; + } + } + + for (Long64_t i=0; ithreshDT) { + Delta1->SetPoint(Delta1->GetN(), ts1[i]/1e12-tshift, DTus); + if (DTus>MaxDeltaT) + MaxDeltaT = DTus; + } + } + + + Double_t tref, yref, y; + Double_t NSD2 = 0; // normalized sum of differences squared (NSD2) + Double_t NSD2min = 1; + Double_t tmin0, tmax0, tmin1, tmax1, tmin2, tmax2; + tmin0 = ts0[0]/1e12; + tmax0 = ts0[e0-1]/1e12; + tmin1 = ts1[0]/1e12; + tmax1 = ts1[e1-1]/1e12; + + if (tmin0<=OverlapTMin && tmax0>=OverlapTMax && tmin1<=OverlapTMin && tmax1>=OverlapTMax) { + if (FindShift) { + cout << "executing findshift() ..." << endl; + tshift = findshift(Delta0, Delta1, + OverlapTMin, OverlapTMax, threshDT); + cout.precision(10); + cout << "best timeshift: " << tshift << " sec" << endl; + } + else { + // Just compute the + Int_t npts = 0; + computeNSD2(Delta0, Delta1, threshDT, OverlapTMin, OverlapTMax, npts, NSD2); + cout << tshift << " " << npts << " " << NSD2 << endl; + } + } + else + cout << "Need more entries for channel 0 or 2" << endl; + + + // Draw the graphs + cGraphs = new TCanvas("cGraphs","graphs"); + TH2F* hbk = new TH2F("hbk","",10000,OverlapTMin, OverlapTMax, 20,0,1.2*MaxDeltaT); + hbk->GetXaxis()->SetTitle("Time [s]"); + hbk->GetXaxis()->CenterTitle(); + hbk->GetYaxis()->SetTitle("#DeltaT [#mus]"); + hbk->GetYaxis()->CenterTitle(); + TH2F* hba; + if (FindShift) { + cGraphs->Divide(1,2); + hbk->SetTitle("Before"); + hba = new TH2F("hba","After",10000,OverlapTMin, OverlapTMax, 20,0,1.2*MaxDeltaT); + hba->GetXaxis()->SetTitle("Time [s]"); + hba->GetXaxis()->CenterTitle(); + hba->GetYaxis()->SetTitle("#DeltaT [#mus]"); + hba->GetYaxis()->CenterTitle(); + cGraphs->cd(1); + hbk->Draw(); + Delta0->Draw("lp same"); + TGraph* Delta1clone = (TGraph*)Delta1->Clone();Delta1clone->Draw("lp same"); + + cGraphs->cd(2); + hba->Draw(); + Delta0->Draw("lp same"); + for (Int_t i=0; iGetN(); i++) { + Double_t tsec, DTus; + Delta1->GetPoint(i, tsec, DTus); + Delta1->SetPoint(i, tsec-tshift, DTus); + } + Delta1->Draw("lp same"); + } + else { + hbk->Draw(); + Delta0->Draw("lp same"); + Delta1->Draw("lp same"); + } + + + return 0; +} diff --git a/DAQ/Acquisition.cpp b/DAQ/Acquisition.cpp new file mode 100644 index 0000000..2660cdc --- /dev/null +++ b/DAQ/Acquisition.cpp @@ -0,0 +1,295 @@ +#include "macro.h" +#include "ClassData.h" +#include "ClassDigitizer.h" +#include "influxdb.h" +#include +#include +#include /** struct timeval, select() */ +#include /** tcgetattr(), tcsetattr() */ +#include +#include +#include "TString.h" +#include "TSystem.h" +#include +#include +#define nDig 4 +Digitizer * dig[4]; +std::mutex mtx[nDig]; +std::condition_variable cv; +bool ready = false; +bool stop_acquisition = false; + +timespec ts[nDig]; +static struct termios g_old_kbd_mode; +char* path_to_run="/home/bavarians/FSUDAQ_MUSIC/Run/"; +char* path_to_DAQ="/home/bavarians/FSUDAQ_MUSIC/"; + +static void cooked(void){ + tcsetattr(0, TCSANOW, &g_old_kbd_mode); +} + +static void uncooked(void){ + struct termios new_kbd_mode; + /** put keyboard (stdin, actually) in raw, unbuffered mode */ + tcgetattr(0, &g_old_kbd_mode); + memcpy(&new_kbd_mode, &g_old_kbd_mode, sizeof(struct termios)); + new_kbd_mode.c_lflag &= ~(ICANON | ECHO); + new_kbd_mode.c_cc[VTIME] = 0; + new_kbd_mode.c_cc[VMIN] = 1; + tcsetattr(0, TCSANOW, &new_kbd_mode); +} + +static void raw(void){ + + static char init; + if(init) return; + /** put keyboard (stdin, actually) in raw, unbuffered mode */ + uncooked(); + /** when we exit, go back to normal, "cooked" mode */ + atexit(cooked); + + init = 1; +} + +int keyboardhit(){ + + struct timeval timeout; + fd_set read_handles; + int status; + + raw(); + /** check stdin (fd 0) for activity */ + FD_ZERO(&read_handles); + FD_SET(0, &read_handles); + timeout.tv_sec = timeout.tv_usec = 0; + status = select(0 + 1, &read_handles, NULL, NULL, &timeout); + if(status < 0){ + printf("select() failed in keyboardhit()\n"); + exit(1); + } + return (status); +} + +int getch(void){ + unsigned char temp; + raw(); + /** stdin = fd 0 */ + if(read(0, &temp, 1) != 1) return 0; + return temp; +} + +void go() { + ready = true; + cv.notify_all(); +} + +void func(Digitizer * dig, double RunTime, int Rid, int Bid){ + std::unique_lock lck(mtx[Bid]); + while (!ready ){ + printf("waiting for unlock %d\n", Bid); + cv.wait(lck); + } + cv.notify_all(); + clock_gettime(CLOCK_REALTIME, &ts[Bid]); + printf("----thread %d ready. %ld ns\n", Bid, ts[Bid].tv_nsec); + + dig->StartACQ(); + if(RunTime>0){ + unsigned long time; + unsigned long time0 = get_time(); + do{ + usleep(5*1000); + dig->ReadData(); + dig->GetData()->DecodeBuffer(true,0); + //dig->GetData()->PrintStat(); + //dig->GetData()->PrintData(); + gSystem->cd(path_to_run); + dig->GetData()->SaveBuffer(Form("Run_%03u_B%01u",Rid, Bid)); + time = get_time(); + //printf("********************* time : %lu usec\n", time-time0); + } + while((time-time0)*1e-6<=(RunTime)); + time = get_time(); + //printf("********************* end time : %lu usec\n", time-time0); + dig->StopACQ(); + } + if(RunTime<=0){ + do{ + usleep(5*1000); + dig->ReadData(); + unsigned long time1 = get_time(); + dig->GetData()->DecodeBuffer(true,0); + unsigned long time2 = get_time(); + //dig->GetData()->PrintStat(); + //dig->GetData()->PrintData(); + gSystem->cd(path_to_run); + dig->GetData()->SaveBuffer(Form("Run_%03u_B%01u",Rid, Bid)); + } + while(RunTime<=0 && !stop_acquisition); + dig->StopACQ(); + } + printf("thread %d finished.\n", Bid); +} + +void boardSetParameters(int BI, Digitizer * dig, double BoardConfigurationval, double DPPAlgoCtrl, double DPPAlgoCtrl_10A0,double DPPAlgoCtrl_10AC, double ShapedTriggerWidthVal, double InputSec[7], double DiscriSec[4], double TrapSec[7]){ + //ALL channels + //GENERAL + dig->WriteRegister(Register::DPP::BoardConfiguration, BoardConfigurationval); //Reg=0x8000 + dig->WriteRegister(Register::DPP::DPPAlgorithmControl, DPPAlgoCtrl);//Reg=0x1080 + dig->WriteRegister(Register::DPP::PHA::DPPAlgorithmControl2_G, DPPAlgoCtrl_10A0); //Reg=0x10A0 + dig->WriteRegister(Register::DPP::PHA::DPPAlgorithmControl22_G, DPPAlgoCtrl_10AC); //Reg=0x10AC + //Input Section + dig->WriteRegister(Register::DPP::RecordLength_G, InputSec[1]); //Reg=0x1020 + //Syncrhonization Section + //Trigger/Veto/coinc Section + dig->WriteRegister(Register::DPP::PHA::ShapedTriggerWidth, ShapedTriggerWidthVal); //Reg=0x1084 + //Miscellaneaous Section + //per channel + for(int i=0;i<16;i++){ + //GENERAL + //Input Section + dig->WriteRegister(Register::DPP::PreTrigger, InputSec[2], i);//Reg=0x1038 + dig->WriteRegister(Register::DPP::ChannelDCOffset, InputSec[5], i);//Reg=0x1098 + dig->WriteRegister(Register::DPP::InputDynamicRange, InputSec[6], i);//Reg=0x1028 + //Discriminator Section + dig->WriteRegister(Register::DPP::PHA::TriggerThreshold,DiscriSec[0], i);//Reg=0x106C + dig->WriteRegister(Register::DPP::PHA::TriggerHoldOffWidth, DiscriSec[1], i);//Reg=0x1074 + dig->WriteRegister(Register::DPP::PHA::RCCR2SmoothingFactor,DiscriSec[2], i);//Reg=0x1054 + dig->WriteRegister(Register::DPP::PHA::InputRiseTime, DiscriSec[3], i);//Reg=0x1058 + //Trapezoid Section + dig->WriteRegister(Register::DPP::PHA::TrapezoidRiseTime,TrapSec[0], i);//Reg=0x105C + dig->WriteRegister(Register::DPP::PHA::TrapezoidFlatTop, TrapSec[1], i);//Reg=0x1060 + dig->WriteRegister(Register::DPP::PHA::DecayTime, TrapSec[2], i);//Reg=0x1068 + dig->WriteRegister(Register::DPP::PHA::PeakingTime,TrapSec[3], i);//Reg=0x1064 + dig->WriteRegister(Register::DPP::PHA::PeakHoldOff,TrapSec[5], i);//Reg=0x1078 + dig->WriteRegister(Register::DPP::PHA::FineGain,TrapSec[6], i);//Reg=0x10C4 + } + } + +void boardCommonParameters(Digitizer * dig){ + //all channels + dig->WriteRegister(Register::DPP::TriggerValidationMask_G , 0x00000000);//Reg=0x8100 + //per channels + for(int i=0;i<16;i++){ + dig->WriteRegister(Register::DPP::PHA::RiseTimeValidationWindow, 0x00000000, i);//Reg=0x1070 + dig->WriteRegister(Register::DPP::VetoWidth, 0x0000000A, i);//Reg=0x10D4 + dig->WriteRegister(Register::DPP::Scratch, 0xAAAAAAAA, i);//Reg=0xEF20 + dig->WriteRegister(Register::DPP::InterruptEventNumber, 0x00000000,i);//Reg=0xEF18 + dig->WriteRegister(Register::DPP::InterruptStatusID, 0x000000DD,i);//Reg=0xEF14 + dig->WriteRegister(Register::DPP::RelocationAddress, 0x00000000,i);//Reg=0xEF10 + dig->WriteRegister(Register::DPP::MCSTBaseAddressAndControl , 0x000000AA, i);//Reg=0xEF0C + dig->WriteRegister(Register::DPP::ReadoutControl, 0x00000010, i);//Reg=0xEF00 + dig->WriteRegister(Register::DPP::ExtendedVetoDelay, 0x12340014,i);//Reg=0x81C4 + dig->WriteRegister(Register::DPP::BufferOccupancyGain , 0x00000000, i);//Reg=0x81B4 + dig->WriteRegister(Register::DPP::FrontPanelLVDSIONewFeatures , 0x00001111, i);//Reg=0x81A0 + dig->WriteRegister(Register::DPP::RunStartStopDelay , 0x00000000, i);//Reg=0x8170 + dig->WriteRegister(Register::DPP::DisableExternalTrigger, 0x00000000,i);//Reg=0x817C + dig->WriteRegister(Register::DPP::FanSpeedControl, 0x00000020, i);//Reg=0x8168 + dig->WriteRegister(Register::MemoryBufferAlmostFullLevel, 0x00000000, i);//Reg=0x816C + dig->WriteRegister(Register::DPP::AcquisitionControl, 00000000,i);//Reg=0x8100 + dig->WriteRegister(Register::DPP::GlobalTriggerMask, 0x80000000,i);//Reg=0x810C + dig->WriteRegister(Register::DPP::FrontPanelTRGOUTEnableMask, 0x00000000, i);//Reg=0x8110 + dig->WriteRegister(Register::DPP::LVDSIOData, 0x0000FFFF, i);//Reg=0x8118 + dig->WriteRegister(Register::DPP::FrontPanelIOControl, 0x00008100, i);//Reg=0x811C + dig->WriteRegister(Register::DPP::ChannelEnableMask, 0x0000FFFF, i);//Reg=0x8120 + dig->WriteRegister(Register::DPP::VoltageLevelModeConfig, 0x00000000, i);//Reg=0x8138 + dig->WriteRegister(Register::DPP::AnalogMonitorMode, 0x00000000, i);//Reg=0x8144 + } + } + +int main(int argc, char* argv[]){ + + printf("=====================================\n"); + printf("=== FSU DAQ ===\n"); + printf("=====================================\n"); + if (argc < 2) { + printf("Incorrect number of arguments:\n"); + printf("%s [RunTime] [RunId] \n", argv[0]); + printf(" RunTime in sec, default = -1 if unstoppped \n"); + return 1; + } + double RunTime = atoi(argv[1]); + int Rid= atoi(argv[2]); + + //"""""""""""""""""""""""""""""" + //Opening digitizers + //"""""""""""""""""""""""""""""" + for(int d=0;dProgramPHABoard(); + dig[i]->ReadAllSettingsFromBoard(); + dig[i]->WriteRegister(Register::DPP::SoftwareClear_W, 1); + dig[i]->WriteRegister(Register::DPP::MaxAggregatePerBlockTransfer, 40);//80 Reg=0xEF1C + dig[i]->WriteRegister(Register::DPP::NumberEventsPerAggregate_G, 511);//1023-->forced in WriteRegisterFromFile Reg=0x1034 + printf("========== %d \n", dig[i]->ReadSettingFromFile(Register::DPP::MaxAggregatePerBlockTransfer)); + boardSetParameters(i, dig[i], BoardConfigurationval[i],DPPAlgoCtrl[i], DPPAlgoCtrl_10A0[i],DPPAlgoCtrl_10AC[i], ShapedTriggerWidthVal, InputSec[i], DiscriSec[i], TrapSec[i] ); + boardCommonParameters(dig[i]); + dig[i]-> SaveAllSettingsAsText(Form("reg_Board%i.txt",i)); + dig[i]->GetData()->SetSaveWaveToMemory(false); + } + + //"""""""""""""""""""""""""""""" + //Parallel digitizer data taking + //"""""""""""""""""""""""""""""" + std::thread fdig[nDig]; + for (int i = 0; i < nDig; ++i){ + fdig[i] = std::thread(func, dig[i],RunTime , Rid, i); + } + printf("%d threads ready to race...\n", nDig); + usleep(1000*1000); + if(RunTime<=0){ + printf("Enter to stop ..\n"); + if(getchar()){stop_acquisition=true;} + } + go(); + for (auto& f : fdig) f.join(); + printf("=========== finsihed.\n"); + long avg = 0; + for( int i =0; i < nDig ; i++) avg += ts[i].tv_nsec; + avg = avg/nDig; + long min , max; + for( int i =0; i < nDig; i++) { + if( i == 0 ){ + min = ts[i].tv_nsec; + max = ts[i].tv_nsec; + continue; + } + if( min > ts[i].tv_nsec) min = ts[i].tv_nsec; + if( max < ts[i].tv_nsec) max = ts[i].tv_nsec; + } + printf(" avg : %ld\n", avg); + printf(" min : %ld, %ld\n", min, avg - min); + printf(" max : %ld, %ld\n", max, max - avg); + printf(" diff : %ld\n", max-min); + for(int i=0;i (unsigned int)MaxSaveFileSize ) { /// 2 GB + if( inFileSize > (unsigned int)MaxSaveFileSize ) { /// 1 GB fclose(haha); saveFileIndex ++; sprintf(saveFileName, "%s_%03u.fsu", fileName , saveFileIndex); @@ -212,7 +213,7 @@ inline void Data::PrintBuffer() const{ inline void Data::PrintData() const{ printf("============================= Print Data\n"); for( int ch = 0; ch < MaxNChannels ; ch++){ - if( NumEvents[ch] == 0 ) continue; + if(NumEvents[ch] == 0 ) continue; printf("------------ ch : %d, %d \n", ch, NumEvents[ch]); for( int ev = 0; ev < NumEvents[ch] ; ev++){ printf("%4d, %5u, %15llu, %5u \n", ev, Energy[ch][ev], Timestamp[ch][ev], fineTime[ch][ev]); @@ -277,7 +278,6 @@ inline void Data::DecodeBuffer(bool fastDecode, int verbose){ nw = nw + 1; unsigned int bdAggCounter = ReadBuffer(nw, verbose); if( verbose >= 1 ) printf("Board Agg Counter : %u \n", bdAggCounter & 0x7FFFFF); - nw = nw + 1; unsigned int bdAggTimeTag = ReadBuffer(nw, verbose); if( verbose >= 2 ) printf("Agg Counter : %u \n", bdAggTimeTag); @@ -285,7 +285,6 @@ inline void Data::DecodeBuffer(bool fastDecode, int verbose){ for( int chMask = 0; chMask < MaxNChannels/2 ; chMask ++ ){ if( ((ChannelMask >> chMask) & 0x1 ) == 0 ) continue; if( verbose >= 2 ) printf("==================== Dual Channel Block, ch Mask : %d, nw : %d\n", chMask *2, nw); - if( DPPType == V1730_DPP_PHA_CODE ) { if ( DecodePHADualChannelBlock(chMask, fastDecode, verbose) < 0 ) break; } @@ -298,9 +297,8 @@ inline void Data::DecodeBuffer(bool fastDecode, int verbose){ break; } nw++; - ///printf("nw : %d ,x 4 = %d, nByte : %d \n", nw, 4*nw, nByte); + //printf("nw : %d ,x 4 = %d, nByte : %d \n", nw, 4*nw, nByte); }while(4*nw < nByte); - ///Calculate trigger rate and first and last Timestamp for(int ch = 0; ch < MaxNChannels; ch++){ if( NumEventsDecoded[ch] > 0 ) IsNotRollOverFakeAgg = true; diff --git a/DAQ/ClassDigitizer.cpp b/DAQ/ClassDigitizer.cpp index 22b5020..1e83677 100644 --- a/DAQ/ClassDigitizer.cpp +++ b/DAQ/ClassDigitizer.cpp @@ -328,8 +328,8 @@ void Digitizer::StartACQ(){ if ( AcqRun ) return; unsigned int bufferSize = CalByteForBuffer(); - if( bufferSize > 80 * 1024 * 1024 ){ - printf("============= buffer size bigger than 80 MB"); + if( bufferSize > 800 * 1024 * 1024 ){ + printf("============= buffer size bigger than 800 MB"); return; } @@ -341,7 +341,7 @@ void Digitizer::StartACQ(){ return; } - printf("\e[1m\e[33m======= Acquisition Started for Board %d\e[0m\n", boardID); + printf("\e[1m\e[33m======= Acquisition Started for Board %d - %d \e[0m\n", boardID,portID); AcqRun = true; data->ClearTriggerRate(); } @@ -351,7 +351,7 @@ void Digitizer::StopACQ(){ int ret = CAEN_DGTZ_SWStopAcquisition(handle); ret |= CAEN_DGTZ_ClearData(handle); if( ret != 0 ) ErrorMsg("something wrong when try to stop ACQ and clear buffer"); - printf("\n\e[1m\e[33m====== Acquisition STOPPED for Board %d\e[0m\n", boardID); + printf("\n\e[1m\e[33m====== Acquisition STOPPED for Board %d - %d \e[0m\n", boardID,portID); AcqRun = false; data->ClearTriggerRate(); } diff --git a/DAQ/ClassDigitizer.h b/DAQ/ClassDigitizer.h index 151b607..30204b4 100644 --- a/DAQ/ClassDigitizer.h +++ b/DAQ/ClassDigitizer.h @@ -91,6 +91,7 @@ class Digitizer{ /// ONLY WriteRegister can have ch = -1, for writting all channels /// for board setting, ignore ch void WriteRegister (Reg registerAddress, uint32_t value, int ch = -1, bool isSave2MemAndFile = true); + /// read value from digitizer and memory, and save to memory, and settingFile(if exist), /// for board setting, ignore ch uint32_t ReadRegister (Reg registerAddress, unsigned short ch = 0, bool isSave2MemAndFile = true, std::string str = "" ); diff --git a/DAQ/EventBuilder.cpp b/DAQ/EventBuilder.cpp index 141d9de..428be5e 100644 --- a/DAQ/EventBuilder.cpp +++ b/DAQ/EventBuilder.cpp @@ -1,25 +1,38 @@ #include "macro.h" #include "ClassData.h" - +#include +#include #include "TROOT.h" #include "TSystem.h" #include "TClonesArray.h" #include "TGraph.h" #include "TFile.h" #include "TTree.h" +#include "TSystem.h" #define MAX_MULTI 100 +#define MAX_File 100 #define NTimeWinForBuffer 3 +char* path_to_run="/home/bavarians/FSUDAQ_MUSIC/Run/"; +char* path_to_DAQ="/home/bavarians/FSUDAQ_MUSIC/"; +char* path_to_con="/home/bavarians/FSUDAQ_MUSIC/Conversion/"; +char* path_to_top="/home/bavarians/FSUDAQ_MUSIC/MUSIC_Topology/"; + TFile * outRootFile = NULL; TTree * tree = NULL; unsigned long long evID = 0; -unsigned short multi = 0; -unsigned short bd[MAX_MULTI] = {0}; /// boardID -unsigned short ch[MAX_MULTI] = {0}; /// chID -unsigned short e[MAX_MULTI] = {0}; /// 15 bit -unsigned long long e_t[MAX_MULTI] = {0}; /// timestamp 47 bit +unsigned short multi_evt=0; +unsigned short multi_hit=0; +unsigned short stp0[MAX_MULTI] = {0}; /// 15 bit +unsigned short stp17[MAX_MULTI] = {0}; /// 15 bit +unsigned short grid[MAX_MULTI] = {0}; /// 15 bit +unsigned short cath[MAX_MULTI] = {0}; /// 15 bit +unsigned short de_l[MAX_MULTI][16] = {{0}}; /// 15 bit +unsigned short de_r[MAX_MULTI][16] = {{0}}; /// 15 bit +unsigned short puls[MAX_MULTI][4] = {{0}}; /// 15 bit +unsigned long long e_t[MAX_MULTI] = {0}; /// timestamp 47 bit --> to get en sec *2e-9 unsigned short e_f[MAX_MULTI] = {0}; /// fine time 10 bit /// using TClonesArray to hold the trace in TGraph @@ -30,7 +43,8 @@ TGraph * trace = NULL; template void swap(T * a, T *b ); int partition(int arr[], int kaka[], TString file[], int start, int end); void quickSort(int arr[], int kaka[], TString file[], int start, int end); -void EventBuilder(Data * data, const unsigned int timeWin, bool traceOn = false, bool isLastData = false, unsigned int verbose = 0); +void extraction_map(int map[4][16]); +void EventBuilder(Data * data[],int nFile, const unsigned int timeWin, bool traceOn = false, bool isLastData = false, unsigned int verbose = 0); int main(int argc, char **argv) { @@ -40,19 +54,17 @@ int main(int argc, char **argv) { if (argc <= 3) { printf("Incorrect number of arguments:\n"); printf("%s [timeWindow] [traceOn/Off] [verbose] [inFile1] [inFile2] .... \n", argv[0]); - printf(" timeWindow : number of tick, 1 tick. default = 100 \n"); + printf(" timeWindow : in microsecond, default = 1 \n"); printf(" traceOn/Off : is traces stored \n"); printf(" verbose : > 0 for debug \n"); printf(" Output file name is contructed from inFile1 \n"); return 1; } - /// File format must be YYY...Y_runXXX_AAA_BBB_CCC.fsu - /// YYY...Y = prefix - /// XXX = runID, 3 digits - /// AAA = board Serial Number, 3 digits - /// BBB = DPPtype, 3 digits - /// CCC = over size index, 3 digits + /// File format must be Run_XXX_BB_YYY.fsu + /// XXX = 3 digits, run number + /// BB = board number, 2 digits + /// YYY = over size index, 3 digits ///============= read input unsigned int timeWindow = atoi(argv[1]); @@ -68,7 +80,8 @@ int main(int argc, char **argv) { TString outFileName = inFileName[0]; int pos = outFileName.Index("_"); pos = outFileName.Index("_", pos+1); - outFileName.Remove(pos); + outFileName.Remove(pos); + outFileName += Form("_%03u",atoi(&inFileName[0][inFileName[0].Index("B")+5])); outFileName += ".root"; printf("-------> Out file name : %s \n", outFileName.Data()); @@ -125,16 +138,27 @@ int main(int argc, char **argv) { } ///============= Set Root Tree + gSystem->cd(path_to_con); outRootFile = new TFile(outFileName, "recreate"); + // gSystem->cd(path_to_DAQ); tree = new TTree("tree", outFileName); tree->Branch("evID", &evID, "event_ID/l"); - tree->Branch("multi", &multi, "multi/s"); - tree->Branch("bd", bd, "bd[multi]/s"); - tree->Branch("ch", ch, "ch[multi]/s"); - tree->Branch("e", e, "e[multi]/s"); - tree->Branch("e_t", e_t, "e_timestamp[multi]/l"); - tree->Branch("e_f", e_f, "e_timestamp[multi]/s"); - + tree->Branch("multi_evt", &multi_evt, "multi_evt/s"); + tree->Branch("multi_hit", &multi_hit, "multi_hit/s"); + tree->Branch("de_l", de_l, "de_l[multi_evt][16]/s"); + tree->Branch("de_r", de_r, "de_r[multi_evt][16]/s"); + tree->Branch("stp0", stp0, "stp0[multi_evt]/s"); + tree->Branch("stp17", stp17, "stp17[multi_evt]/s"); + tree->Branch("grid", grid, "grid[multi_evt]/s"); + tree->Branch("cath", cath, "cath[multi_evt]/s"); + tree->Branch("puls", puls, "puls[multi_evt][4]/s"); + tree->Branch("e_t", e_t, "e_timestamp[multi_evt]/l"); + tree->Branch("e_f", e_f, "e_timestamp[multi_evt]/s"); + for(int ev=0;evBranch("traceLength", traceLength, "traceLength[multi]/s"); @@ -142,235 +166,283 @@ int main(int argc, char **argv) { arrayTrace->BypassStreamer(); } - ///============= Open input Files + + ///============= Open input Files printf("##############################################\n"); - FILE * haha = fopen(fileCat[0][0], "r"); - if( haha == NULL ){ - printf("#### Cannot open file : %s. Abort.\n", fileCat[0][0].Data()); - return -1; - } - fseek(haha, 0L, SEEK_END); - const size_t inFileSize = ftell(haha); - printf("%s | file size : %d Byte = %.2f MB\n", fileCat[0][0].Data(), (int) inFileSize, inFileSize/1024./1024.); - fclose(haha); + gSystem->cd(path_to_run); - - Data * data = new Data(); - data->DPPType = typeCat[0][0]; - data->boardSN = idCat[0]; - data->SetSaveWaveToMemory(true); + printf("#### number of files: %i \n", nFile); + FILE * haha[nFile]; + size_t inFileSize[nFile]; + for( int i = 0; i < nFile; i++){ + haha[i]= fopen(fileCat[i][0], "r"); + if( haha[i] == NULL ){ + printf("#### Cannot open file : %s. Abort.\n", fileCat[i][0].Data()); + return -1; + } + fseek(haha[i], 0L, SEEK_END); + inFileSize[i] = ftell(haha[i]); + printf("%s | file size : %d Byte = %.2f MB\n", fileCat[i][0].Data(), (int) inFileSize[i], inFileSize[i]/1024./1024.); + fclose(haha[i]); + } ///============= Main Loop - haha = fopen(inFileName[0], "r"); + gSystem->cd(path_to_run); int countBdAgg = 0; - unsigned long currentTime = 0; unsigned long oldTime = 0; - char * buffer = NULL; + Data * data[nFile]; + for( int i = 0; i < nFile; i++){ + haha[i] = fopen(inFileName[i], "r"); + data[i] = new Data(); + data[i]->DPPType ; + data[i]->boardSN = atoi(&inFileName[i][inFileName[i].Index("B")+1]); + data[i]->SetSaveWaveToMemory(true); + } + int end_of_loop=1; + + do{ + for( int i = 0; i < nFile; i++){ + // haha[i] = fopen(inFileName[i], "r"); + ///========== Get 1 aggreration for each file + oldTime = get_time(); + if( debug) printf("*********************** file pos : %d, %lu\n", (int) ftell(haha[i]), oldTime); + unsigned int word[1]; /// 4 bytes + size_t dump = fread(word, 4, 1, haha[i]); + fseek(haha[i], -4, SEEK_CUR); - ///========== Get 1 aggreration - oldTime = get_time(); - if( debug) printf("*********************** file pos : %d, %lu\n", (int) ftell(haha), oldTime); - unsigned int word[1]; /// 4 bytes - size_t dump = fread(word, 4, 1, haha); - fseek(haha, -4, SEEK_CUR); + short header = ((word[0] >> 28 ) & 0xF); + if( header != 0xA ) break; - short header = ((word[0] >> 28 ) & 0xF); - if( header != 0xA ) break; + unsigned int aggSize = (word[0] & 0x0FFFFFFF) * 4; ///byte - unsigned int aggSize = (word[0] & 0x0FFFFFFF) * 4; ///byte - - if( debug) printf("Board Agg. has %d word = %d bytes\n", aggSize/4, aggSize); + if( debug) printf("Board Agg. has %d word = %d bytes\n", aggSize/4, aggSize); - buffer = new char[aggSize]; - dump = fread(buffer, aggSize, 1, haha); - countBdAgg ++; - if( debug) printf("==================== %d Agg\n", countBdAgg); + buffer = new char[aggSize]; + dump = fread(buffer, aggSize, 1, haha[i]); + countBdAgg ++; + if( debug) printf("==================== %d Agg\n", countBdAgg); + data[i]->DecodeBuffer(buffer, aggSize,false, 0);//false + if(!data[i]->IsNotRollOverFakeAgg ) continue; + currentTime = get_time(); + if( debug) { + printf("~~~~~~~~~~~~~~~~ time used : %lu usec\n", currentTime - oldTime); + } + } + EventBuilder(data, nFile, timeWindow, traceOn, false, debug); - data->DecodeBuffer(buffer, aggSize, false, 0); - data->ClearBuffer(); - if( !data->IsNotRollOverFakeAgg ) continue; - - currentTime = get_time(); - - if( debug) { - printf("~~~~~~~~~~~~~~~~ time used : %lu usec\n", currentTime - oldTime); - data->PrintStat(); - } - - EventBuilder(data, timeWindow, traceOn, false, debug); - if( debug) printf("---------- event built : %llu \n", evID); - - //if( countBdAgg > 74) break; - }while(!feof(haha) && ftell(haha) < inFileSize); - - fclose(haha); - + for( int i = 0; i < nFile; i++){ + data[i]->ClearBuffer(); + //if( countBdAgg > 74) break; + end_of_loop= end_of_loop*(!feof(haha[i]) && ftell(haha[i]) < inFileSize[i]); + } + }while(end_of_loop==1); + for( int i = 0; i < nFile; i++){ fclose(haha[i]);} + printf("=======@@@@@@@@###############============= end of loop \n"); - EventBuilder(data, timeWindow, traceOn, true, debug); + EventBuilder(data, nFile,timeWindow, traceOn, true, debug); - + gSystem->cd(path_to_con); tree->Write(); outRootFile->Close(); - printf("========================= finsihed.\n"); printf("total events built = %llu \n", evID); printf("=======> saved to %s \n", outFileName.Data()); } -void EventBuilder(Data * data, const unsigned int timeWin, bool traceOn, bool isLastData, unsigned int verbose){ - +void EventBuilder(Data * data[],int nFile, const unsigned int timeWin, bool traceOn, bool isLastData, unsigned int verbose){ if( verbose) { printf("======================== Event Builder \n"); - data->PrintData(); } - + ///============= Set MUSIC DAQ Topology + int map[4][16]; + extraction_map(map); + int temp_index=0;double tempEn; /// find the last event timestamp; - unsigned long long firstTimeStamp = -1; - unsigned long long lastTimeStamp = 0; - unsigned long long smallestLastTimeStamp = -1; - unsigned int maxNumEvent = 0; - for( int chI = 0; chI < MaxNChannels ; chI ++){ - if( data->NumEvents[chI] == 0 ) continue; - - if( data->Timestamp[chI][0] < firstTimeStamp ) { - firstTimeStamp = data->Timestamp[chI][0]; - } - unsigned short ev = data->NumEvents[chI]-1; - if( data->Timestamp[chI][ev] > lastTimeStamp ) { - lastTimeStamp = data->Timestamp[chI][ev]; - } - if( ev + 1 > maxNumEvent ) maxNumEvent = ev + 1; - if( data->Timestamp[chI][ev] < smallestLastTimeStamp ){ - smallestLastTimeStamp = data->Timestamp[chI][ev]; - } - } - - if( maxNumEvent == 0 ) return; - - if( verbose) printf("================ time range : %llu - %llu, smallest Last %llu\n", firstTimeStamp, lastTimeStamp, smallestLastTimeStamp ); - unsigned short lastEv[MaxNChannels] = {0}; /// store the last event number for each ch - unsigned short exhaustedCh = 0; /// when exhaustedCh == MaxNChannels ==> stop - bool singleChannelExhaustedFlag = false; /// when a single ch has data but exhaused ==> stop - - do { - - /// find the 1st event - int ch1st = -1; - unsigned long long time1st = -1; - for( int chI = 0; chI < MaxNChannels ; chI ++){ - if( data->NumEvents[chI] == 0 ) continue; - if( data->NumEvents[chI] <= lastEv[chI] ) continue; - if( data->Timestamp[chI][lastEv[chI]] < time1st ) { - time1st = data->Timestamp[chI][lastEv[chI]]; - ch1st = chI; - } - } - if( !isLastData && ((smallestLastTimeStamp - time1st) < NTimeWinForBuffer * timeWin) && maxNumEvent < MaxNData * 0.6 ) break; - if( ch1st > MaxNChannels ) break; - - multi ++; - bd[multi-1] = data->boardSN; - ch[multi-1] = ch1st; - e[multi-1] = data->Energy[ch1st][lastEv[ch1st]]; - e_t[multi-1] = data->Timestamp[ch1st][lastEv[ch1st]]; - e_f[multi-1] = data->fineTime[ch1st][lastEv[ch1st]]; - if( traceOn ){ - arrayTrace->Clear("C"); - traceLength[multi-1] = (unsigned short) data->Waveform1[ch1st][lastEv[ch1st]].size(); - ///if( verbose )printf("------- trace Length : %u \n", traceLength[multi-1]); - trace = (TGraph *) arrayTrace->ConstructedAt(multi-1, "C"); - trace->Clear(); - for( int hh = 0; hh < traceLength[multi-1]; hh++){ - trace->SetPoint(hh, hh, data->Waveform1[ch1st][lastEv[ch1st]][hh]); - ///if( verbose )if( hh % 200 == 0 ) printf("%3d | %u \n", hh, data->Waveform1[ch1st][lastEv[ch1st]][hh]); - } - } - lastEv[ch1st] ++; + long long firstTimeStamp = -1; + unsigned long long lastTimeStamp = 0; + long long smallestLastTimeStamp = -1; + unsigned int maxNumEvent[nFile] ; + for( int b = 0; b < nFile ; b++){ + maxNumEvent[b] = 0; + for( int chI = 0; chI < MaxNChannels ; chI ++){ + if(data[b]->NumEvents[chI] == 0 ) continue; + if(data[b]->Timestamp[chI][0] < firstTimeStamp ) { + firstTimeStamp = data[b]->Timestamp[chI][0]; + } + unsigned short ev = data[b]->NumEvents[chI]-1; + if( data[b]->Timestamp[chI][ev] > lastTimeStamp ) { + lastTimeStamp = data[b]->Timestamp[chI][ev]; + } + if( ev + 1 > maxNumEvent[b] ) maxNumEvent[b] = ev + 1; + if( data[b]->Timestamp[chI][ev] < smallestLastTimeStamp ){ + smallestLastTimeStamp = data[b]->Timestamp[chI][ev]; + } + } + if( maxNumEvent[b] == 0 ) return; + } + if( verbose) printf("================ time range : %llu - %llu, smallest Last %llu\n", firstTimeStamp, lastTimeStamp, smallestLastTimeStamp); + unsigned short lastEv[nFile][MaxNChannels] = {0}; /// store the last event number for each ch + unsigned short exhaustedCh[nFile] = {0}; /// when exhaustedCh == MaxNChannels ==> stop + bool singleChannelExhaustedFlag[nFile] = {false}; /// when a single ch has data but exhaused ==> stop + unsigned short exhaustedBd = 0; + bool BoardExhaustedFlag[nFile] = {false}; + for( int b = 0; b < nFile ; b++){ + singleChannelExhaustedFlag[b]=false; + exhaustedCh[b]=0; + for( int c = 0; c < MaxNChannels; c++){ + lastEv[b][c]=0; + } + } + do { + /// find the 1st event + unsigned long long time1st=-1; + int ch1st=-1; int b1st=-1; + for( int b = 0; b < nFile ; b++){ + for( int chI = 0; chI < MaxNChannels ; chI ++){ + if( data[b]->NumEvents[chI] == 0 ) continue; + if( data[b]->NumEvents[chI] <= lastEv[b][chI] ) continue; + if( data[b]->Timestamp[chI][lastEv[b][chI]] < time1st ) { + time1st= data[b]->Timestamp[chI][lastEv[b][chI]]; + ch1st = chI; b1st=b; + } + } + } +//&& maxNumEvent[b] < MaxNData * 0.6 + if( !isLastData && ((smallestLastTimeStamp - time1st) < NTimeWinForBuffer * timeWin) ) break; + if( ch1st > MaxNChannels ) break; + if( b1st < 0 ) break; + + temp_index= map[b1st][ch1st]; + if(temp_index>=0){ + e_t[multi_evt]= data[b1st]->Timestamp[ch1st][lastEv[b1st][ch1st]]; + e_f[multi_evt]= data[b1st]->fineTime[ch1st][lastEv[b1st][ch1st]]; + tempEn=data[b1st]->Energy[ch1st][lastEv[b1st][ch1st]]; + if(temp_index<16){de_l[multi_evt][temp_index] = tempEn;} + if(temp_index<32 && temp_index>15){ de_r[multi_evt][temp_index] = tempEn; } + if(temp_index==500){stp0[multi_evt]= tempEn;} + if(temp_index==501){stp17[multi_evt]= tempEn;} + if(temp_index==502){grid[multi_evt]= tempEn;} + if(temp_index==503){cath[multi_evt]= tempEn;} + if(temp_index==504){puls[multi_evt][b1st]= tempEn;} + multi_hit++; + } + if( traceOn ){ + arrayTrace->Clear("C"); + traceLength[multi_evt] = (unsigned short) data[b1st]->Waveform1[ch1st][lastEv[b1st][ch1st]].size(); + trace = (TGraph *) arrayTrace->ConstructedAt(multi_evt, "C"); + trace->Clear(); + for( int hh = 0; hh < traceLength[multi_evt]; hh++){ + trace->SetPoint(hh, hh, data[b1st]->Waveform1[ch1st][lastEv[b1st][ch1st]][hh]); + } + } + lastEv[b1st][ch1st] ++; - /// build the rest of the event - exhaustedCh = 0; - singleChannelExhaustedFlag = false; - for( int chI = ch1st; chI < ch1st + MaxNChannels; chI ++){ - unsigned short chX = chI % MaxNChannels; - if( data->NumEvents[chX] == 0 ) { - exhaustedCh ++; - continue; - } - if( data->NumEvents[chX] <= lastEv[chX] ) { - exhaustedCh ++; - singleChannelExhaustedFlag = true; - continue; - } - if( timeWin == 0 ) continue; - for( int ev = lastEv[chX]; ev < data->NumEvents[chX] ; ev++){ - if( data->Timestamp[chX][ev] > 0 && (data->Timestamp[chX][ev] - e_t[0] ) < timeWin ) { - multi ++; - bd[multi-1] = data->boardSN; - ch[multi-1] = chX; - e[multi-1] = data->Energy[chX][ev]; - e_t[multi-1] = data->Timestamp[chX][ev]; - e_f[multi-1] = data->fineTime[chX][ev]; - if( traceOn ){ - traceLength[multi-1] = (unsigned short) data->Waveform1[chX][ev].size(); - trace = (TGraph *) arrayTrace->ConstructedAt(multi-1, "C"); - trace->Clear(); - for( int hh = 0; hh < traceLength[multi-1]; hh++){ - trace->SetPoint(hh, hh, data->Waveform1[chX][ev][hh]); - } - } - lastEv[chX] = ev + 1; - if( lastEv[chX] == data->NumEvents[chX] ) exhaustedCh ++; - } - } - } - - if( verbose) { - printf("=============== multi : %d , ev : %llu\n", multi, evID); - for( int ev = 0; ev < multi; ev++){ - printf("%3d, ch : %2d, %u, %llu \n", ev, ch[ev], e[ev], e_t[ev]); - } - - printf("=============== Last Ev , exhaustedCh %d \n", exhaustedCh); - for( int chI = 0; chI < MaxNChannels ; chI++){ - if( lastEv[chI] == 0 ) continue; - printf("%2d, %d %d\n", chI, lastEv[chI], data->NumEvents[chI]); - } - } - - /// fill Tree - outRootFile->cd(); - tree->Fill(); - evID++; - multi = 0; - - }while( !singleChannelExhaustedFlag || (exhaustedCh < MaxNChannels) ); - + /// build the rest of the event + exhaustedBd=0; + for( int b = 0; b < nFile ; b++){ + exhaustedCh[b] = 0; + singleChannelExhaustedFlag[b] = false; + //for( int chI = ch1st[b]; chI < ch1st[b] + MaxNChannels; chI ++){ + //unsigned short chX = chI % MaxNChannels; + for( int chI = 0; chI < MaxNChannels; chI ++){ + if( data[b]->NumEvents[chI] == 0 ) { + exhaustedCh[b] ++; + continue; + } + if(data[b]->NumEvents[chI] <= lastEv[b][chI] ) { + exhaustedCh[b] ++; + singleChannelExhaustedFlag[b] = true; + continue; + } + + if(singleChannelExhaustedFlag[b] && exhaustedCh[b] >= MaxNChannels){BoardExhaustedFlag[b]=true;} + if( timeWin == 0 ) continue; + if( BoardExhaustedFlag[b]) continue; + for( int ev = lastEv[b][chI]; ev < data[b]->NumEvents[chI] ; ev++){ + if( data[b]->Timestamp[chI][ev] > 0 && ((data[b]->Timestamp[chI][ev] - e_t[0] )*ch2ns_value*1e-9)*1e6 < timeWin ) { + temp_index= map[data[b]->boardSN][chI]; + if(temp_index>=0){ + tempEn=data[b]->Energy[chI][ev]; + if(temp_index<16 && de_l[multi_evt][temp_index]>0){multi_evt ++; de_l[multi_evt][temp_index] = tempEn;} + if(temp_index<16 && de_l[multi_evt][temp_index]==0){de_l[multi_evt][temp_index] = tempEn;} + if(temp_index<32 && temp_index>15 && de_r[multi_evt][temp_index]>0){multi_evt ++;de_r[multi_evt][temp_index] = tempEn;} + if(temp_index<32 && temp_index>15 && de_r[multi_evt][temp_index]==0){de_r[multi_evt][temp_index] = tempEn;} + if(temp_index==500 && stp0[multi_evt]>0){multi_evt ++;stp0[multi_evt]= tempEn;} + if(temp_index==500 && stp0[multi_evt]==0){stp0[multi_evt]= tempEn;} + if(temp_index==501 && stp17[multi_evt]>0){multi_evt ++;stp17[multi_evt]= tempEn;} + if(temp_index==501 && stp17[multi_evt]==0){stp17[multi_evt]= tempEn;} + if(temp_index==502 && grid[multi_evt]>0){multi_evt ++;grid[multi_evt]= tempEn;} + if(temp_index==502 && grid[multi_evt]==0){grid[multi_evt]= tempEn;} + if(temp_index==503 &&cath[multi_evt]>0){multi_evt ++;cath[multi_evt]= tempEn;} + if(temp_index==503 &&cath[multi_evt]==0){cath[multi_evt]= tempEn;} + if(temp_index==504 && puls[multi_evt][b]>0){multi_evt ++;puls[multi_evt][b]= tempEn;} + if(temp_index==504 && puls[multi_evt][b]==0){ puls[multi_evt][b] = tempEn;} + e_t[multi_evt] = data[b]->Timestamp[chI][ev]; + e_f[multi_evt] = data[b]->fineTime[chI][ev]; + multi_hit++; + } + if( traceOn ){ + traceLength[multi_evt] = (unsigned short) data[b]->Waveform1[chI][ev].size(); + trace = (TGraph *) arrayTrace->ConstructedAt(multi_evt, "C"); + trace->Clear(); + for( int hh = 0; hh < traceLength[multi_evt]; hh++){ + trace->SetPoint(hh, hh, data[b]->Waveform1[chI][ev][hh]); + } + } + lastEv[b][chI] = ev + 1; + if(lastEv[b][chI] == data[b]->NumEvents[chI] ) exhaustedCh[b] ++; + } + } + } + } + for(int b=0;b= MaxNChannels){BoardExhaustedFlag[b]=true;exhaustedBd ++;};} + multi_evt++; + if( verbose) { + printf("=============== multi : %d , ev : %llu\n", multi_evt, evID); + for( int ev = 0; ev < multi_evt; ev++){ + printf("%3d, grid time : %u, %llu \n", ev, grid[ev], e_t[ev]); + } + printf("=============== Last Ev , exhaustedBd %d \n", exhaustedBd); + for( int chI = 0; chI < MaxNChannels ; chI++){ + for( int b = 0; b < nFile ; b++){ + if(lastEv[b][chI] == 0 ) continue; + printf("board %d %2d, %d %d\n", b+1, chI, lastEv[b][chI], data[b]->NumEvents[chI]); + } + } + } + /// fill Tree + outRootFile->cd(); + tree->Fill(); + evID++; + for(int ev=0;evNumEvents[chI] == 0 ) continue; - int count = 0; - for( int ev = lastEv[chI] ; ev < data->NumEvents[chI] ; ev++){ - data->Energy[chI][count] = data->Energy[chI][ev]; - data->Timestamp[chI][count] = data->Timestamp[chI][ev]; - data->fineTime[chI][count] = data->fineTime[chI][ev]; - count++; - } - int lala = data->NumEvents[chI] - lastEv[chI]; - data->NumEvents[chI] = (lala >= 0 ? lala: 0); - } - - if( verbose > 0 ) { - printf("&&&&&&&&&&&&&&&&&&&&&&&&&& end of one event build loop\n"); - data->PrintData(); - } - + for(int b=0;bNumEvents[chI] == 0 ) continue; + int count = 0; + for( int ev = lastEv[b][chI] ; ev < data[b]->NumEvents[chI] ; ev++){ + data[b]->Energy[chI][count] = data[b]->Energy[chI][ev]; + data[b]->Timestamp[chI][count] = data[b]->Timestamp[chI][ev]; + data[b]->fineTime[chI][count] = data[b]->fineTime[chI][ev]; + count++; + } + int lala = data[b]->NumEvents[chI] - lastEv[b][chI]; + data[b]->NumEvents[chI] = (lala >= 0 ? lala: 0); + } + } } template void swap(T * a, T *b ){ @@ -378,7 +450,6 @@ template void swap(T * a, T *b ){ *b = *a; *a = temp; } - int partition(int arr[], int kaka[], TString file[], int start, int end){ int pivot = arr[start]; int count = 0; @@ -406,8 +477,26 @@ int partition(int arr[], int kaka[], TString file[], int start, int end){ } return pivotIndex; } - +void extraction_map(int map[4][16]) { + std::ifstream in; + char* file; int nlines =0; + Double_t DAQmap[4][16]; + gSystem->cd(path_to_top); + for(int b=0;b<4;b++){ + in.open(Form("Board%i.dat",b)); + nlines =0 ; + while (1) { + in >> DAQmap[b][nlines] >> map[b][nlines] ; // MeV/a.u. + if (!in.good()) break; + nlines++; + } + in.close(); + } + gSystem->cd(path_to_run); + //return 1; +} void quickSort(int arr[], int kaka[], TString file[], int start, int end){ + /// base case if (start >= end) return; /// partitioning the array diff --git a/DAQ/EventBuilder_raw.cpp b/DAQ/EventBuilder_raw.cpp new file mode 100644 index 0000000..6b8d704 --- /dev/null +++ b/DAQ/EventBuilder_raw.cpp @@ -0,0 +1,446 @@ +#include "macro.h" +#include "ClassData.h" +#include "TROOT.h" +#include "TSystem.h" +#include "TClonesArray.h" +#include "TGraph.h" +#include "TFile.h" +#include "TTree.h" +#include "TCanvas.h" +#include "TSystem.h" + +#define MAX_MULTI 100 +#define MAX_File 100 +#define NTimeWinForBuffer 3 + +char* path_to_run="/home/bavarians/FSUDAQ_MUSIC/Run/"; +char* path_to_DAQ="/home/bavarians/FSUDAQ_MUSIC/"; +char* path_to_con="/home/bavarians/FSUDAQ_MUSIC/Conversion/Raw/"; + +TFile * outRootFile = NULL; +TTree * tree = NULL; + +unsigned long long evID = 0; +unsigned short multi_evt=0; +unsigned short bd[MAX_MULTI] = {0}; /// boardPort +unsigned short ch[MAX_MULTI] = {0}; /// chID +unsigned short e[MAX_MULTI] = {0}; /// 15 bit +unsigned long long e_t[MAX_MULTI] = {0}; /// timestamp 47 bit --> to get en sec *4e-9 +unsigned short e_f[MAX_MULTI] = {0}; /// fine time 10 bit + +/// using TClonesArray to hold the trace in TGraph +TClonesArray * arrayTrace = NULL; +unsigned short traceLength[MAX_MULTI] = {0}; +TGraph * trace = NULL; + +template void swap(T * a, T *b ); +int partition(int arr[], int kaka[], TString file[], int start, int end); +void quickSort(int arr[], int kaka[], TString file[], int start, int end); +void EventBuilder_raw(Data * data[],int nFile, const unsigned int timeWin, bool traceOn = false, bool isLastData = false, unsigned int verbose = 0); + +int main(int argc, char **argv) { + + printf("=====================================\n"); + printf("=== *.fsu Events Builder ===\n"); + printf("=====================================\n"); + if (argc <= 3) { + printf("Incorrect number of arguments:\n"); + printf("%s [timeWindow] [traceOn/Off] [verbose] [inFile1] [inFile2] .... \n", argv[0]); + printf(" timeWindow : in microsecond, default = 1 \n"); + printf(" traceOn/Off : is traces stored \n"); + printf(" verbose : > 0 for debug \n"); + printf(" Output file name is contructed from inFile1 \n"); + return 1; + } + + /// File format must be Run_XXX_BB_YYY.fsu + /// XXX = 3 digits, run number + /// BB = board number, 2 digits + /// YYY = over size index, 3 digits + + ///============= read input + unsigned int timeWindow = atoi(argv[1]); + bool traceOn = atoi(argv[2]); + unsigned int debug = atoi(argv[3]); + int nFile = argc - 4; + TString inFileName[nFile]; + for( int i = 0 ; i < nFile ; i++){ + inFileName[i] = argv[i+4]; + } + + /// Form outFileName; + TString outFileName = inFileName[0]; + int pos = outFileName.Index("_"); + pos = outFileName.Index("_", pos+1); + outFileName.Remove(pos); + outFileName += Form("_%03u",atoi(&inFileName[0][inFileName[0].Index("B")+5])); + outFileName += ".root"; + printf("-------> Out file name : %s \n", outFileName.Data()); + + + printf(" Number of Files : %d \n", nFile); + for( int i = 0; i < nFile; i++) printf("%2d | %s \n", i, inFileName[i].Data()); + printf("=====================================\n"); + printf(" Time Window = %u \n", timeWindow); + printf("=====================================\n"); + + ///============= sorting file by the serial number & order + int ID[nFile]; /// serial+ order*1000; + int type[nFile]; + for( int i = 0; i < nFile; i++){ + int snPos = inFileName[i].Index("_"); + snPos = inFileName[i].Index("_", snPos+1); + int sn = atoi(&inFileName[i][snPos+1]); + type[i] = atoi(&inFileName[i][snPos+5]); + int order = atoi(&inFileName[i][snPos+9]); + ID[i] = sn + order * 1000; + } + quickSort(&(ID[0]), &(type[0]), &(inFileName[0]), 0, nFile-1); + for( int i = 0 ; i < nFile; i++){ + printf("%d | %6d | %3d | %s \n", i, ID[i], type[i], inFileName[i].Data()); + } + + ///=============== Separate files + std::vector idCat; + std::vector> typeCat; + std::vector> fileCat; + for( int i = 0; i < nFile; i++){ + if( ID[i] / 1000 == 0 ) { + std::vector temp = {inFileName[i]}; + std::vector temp2 = {type[i]}; + fileCat.push_back(temp); + typeCat.push_back(temp2); + idCat.push_back(ID[i]%1000); + }else{ + for( int p = 0; p < (int) idCat.size(); p++){ + if( (ID[i] % 1000) == idCat[p] ) { + fileCat[p].push_back(inFileName[i]); + typeCat[p].push_back(type[i]); + } + } + } + } + + printf("=====================================\n"); + for( int i = 0; i < (int) idCat.size(); i++){ + printf("............ %d \n", idCat[i]); + for( int j = 0; j< (int) fileCat[i].size(); j++){ + printf("%s | %d\n", fileCat[i][j].Data(), typeCat[i][j]); + } + } + + ///============= Set Root Tree + gSystem->cd(path_to_con); + outRootFile = new TFile(outFileName, "recreate"); + // gSystem->cd(path_to_DAQ); + tree = new TTree("tree", outFileName); + tree->Branch("evID", &evID, "event_ID/l"); + tree->Branch("multi_evt", &multi_evt, "multi_evt/s"); + tree->Branch("bd", bd, "bd[multi_evt]/s"); + tree->Branch("ch", ch, "ch[multi_evt]/s"); + tree->Branch("e", e, "e[multi_evt]/s"); + tree->Branch("e_t", e_t, "e_timestamp[multi_evt]/l"); + tree->Branch("e_f", e_f, "e_timestamp[multi_evt]/s"); + + if( traceOn ) { + arrayTrace = new TClonesArray("TGraph"); + tree->Branch("traceLength", traceLength, "traceLength[multi_evt]/s"); + tree->Branch("trace", arrayTrace, 2560000); + arrayTrace->BypassStreamer(); + } + + + ///============= Open input Files + printf("##############################################\n"); + gSystem->cd(path_to_run); + + printf("#### number of files: %i \n", nFile); + FILE * haha[nFile]; + size_t inFileSize[nFile]; + for( int i = 0; i < nFile; i++){ + haha[i]= fopen(fileCat[i][0], "r"); + if( haha[i] == NULL ){ + printf("#### Cannot open file : %s. Abort.\n", fileCat[i][0].Data()); + return -1; + } + fseek(haha[i], 0L, SEEK_END); + inFileSize[i] = ftell(haha[i]); + printf("%s | file size : %d Byte = %.2f MB\n", fileCat[i][0].Data(), (int) inFileSize[i], inFileSize[i]/1024./1024.); + fclose(haha[i]); + } + + ///============= Main Loop + gSystem->cd(path_to_run); + int countBdAgg = 0; + unsigned long currentTime = 0; + unsigned long oldTime = 0; + char * buffer = NULL; + Data * data[nFile]; + for( int i = 0; i < nFile; i++){ + haha[i] = fopen(inFileName[i], "r"); + data[i] = new Data(); + data[i]->DPPType ;//typeCat[0][0]; + // data->boardSN = atoi(&inFileName[0][inFileName[0].Index("_")+1]); //idCat[0]; + data[i]->boardSN = atoi(&inFileName[i][inFileName[i].Index("B")+1]); //idCat[0]; + data[i]->SetSaveWaveToMemory(true); + // fclose(haha[i]); + } + int end_of_loop=1; + + do{ + for( int i = 0; i < nFile; i++){ + ///========== Get 1 aggreration for each file + oldTime = get_time(); + if( debug) printf("*********************** file pos : %d, %lu\n", (int) ftell(haha[i]), oldTime); + unsigned int word[1]; /// 4 bytes + size_t dump = fread(word, 4, 1, haha[i]); + fseek(haha[i], -4, SEEK_CUR); + + short header = ((word[0] >> 28 ) & 0xF); + if( header != 0xA ) break; + + unsigned int aggSize = (word[0] & 0x0FFFFFFF) * 4; ///byte + + if( debug) printf("Board Agg. has %d word = %d bytes\n", aggSize/4, aggSize); + + buffer = new char[aggSize]; + dump = fread(buffer, aggSize, 1, haha[i]); + countBdAgg ++; + if( debug) printf("==================== %d Agg\n", countBdAgg); + data[i]->DecodeBuffer(buffer, aggSize,false, 0);//false + if(!data[i]->IsNotRollOverFakeAgg ) continue; + currentTime = get_time(); + if( debug) { + printf("~~~~~~~~~~~~~~~~ time used : %lu usec\n", currentTime - oldTime); + } + } + EventBuilder_raw(data, nFile, timeWindow, traceOn, false, debug); + + if( debug) printf("---------- event built : %llu \n", evID); + + for( int i = 0; i < nFile; i++){ + data[i]->ClearBuffer(); + //if( countBdAgg > 74) break; + end_of_loop= end_of_loop*(!feof(haha[i]) && ftell(haha[i]) < inFileSize[i]); + } + }while(end_of_loop==1); + for( int i = 0; i < nFile; i++){ fclose(haha[i]);} + + printf("=======@@@@@@@@###############============= end of loop \n"); + EventBuilder_raw(data, nFile,timeWindow, traceOn, true, debug); + + gSystem->cd(path_to_con); + tree->Write(); + outRootFile->Close(); + printf("========================= finsihed.\n"); + printf("total events built = %llu \n", evID); + printf("=======> saved to %s \n", outFileName.Data()); +} + +void EventBuilder_raw(Data * data[], int nFile, const unsigned int timeWin, bool traceOn, bool isLastData, unsigned int verbose){ + if( verbose) { + printf("======================== Event Builder \n"); + } + + /// find the last event timestamp; + long long firstTimeStamp = -1; + unsigned long long lastTimeStamp = 0; + long long smallestLastTimeStamp = -1; + unsigned int maxNumEvent[nFile] ; + for( int b = 0; b < nFile ; b++){ + maxNumEvent[b] = 0; + for( int chI = 0; chI < MaxNChannels ; chI ++){ + if(data[b]->NumEvents[chI] == 0 ) continue; + if(data[b]->Timestamp[chI][0] < firstTimeStamp ) { + firstTimeStamp = data[b]->Timestamp[chI][0]; + } + unsigned short ev = data[b]->NumEvents[chI]-1; + if( data[b]->Timestamp[chI][ev] > lastTimeStamp ) { + lastTimeStamp = data[b]->Timestamp[chI][ev]; + } + if( ev + 1 > maxNumEvent[b] ) maxNumEvent[b] = ev + 1; + if( data[b]->Timestamp[chI][ev] < smallestLastTimeStamp ){ + smallestLastTimeStamp = data[b]->Timestamp[chI][ev]; + } + } + if( maxNumEvent[b] == 0 ) return; + } + if( verbose) printf("================ time range : %llu - %llu, smallest Last %llu\n", firstTimeStamp, lastTimeStamp, smallestLastTimeStamp); + unsigned short lastEv[nFile][MaxNChannels] = {0}; /// store the last event number for each ch + unsigned short exhaustedCh[nFile] = {0}; /// when exhaustedCh == MaxNChannels ==> stop + bool singleChannelExhaustedFlag[nFile] = {false}; /// when a single ch has data but exhaused ==> stop + unsigned short exhaustedBd = 0; + bool BoardExhaustedFlag[nFile] = {false}; + for( int b = 0; b < nFile ; b++){ + singleChannelExhaustedFlag[b]=false; + exhaustedCh[b]=0; + for( int c = 0; c < MaxNChannels; c++){ + lastEv[b][c]=0; + } + } + do { + /// find the 1st event + unsigned long long time1st=-1; + int ch1st=-1; int b1st=-1; + for( int b = 0; b < nFile ; b++){ + for( int chI = 0; chI < MaxNChannels ; chI ++){ + if( data[b]->NumEvents[chI] == 0 ) continue; + if( data[b]->NumEvents[chI] <= lastEv[b][chI] ) continue; + if( data[b]->Timestamp[chI][lastEv[b][chI]] < time1st ) { + time1st= data[b]->Timestamp[chI][lastEv[b][chI]]; + ch1st = chI; b1st=b; + } + } + } + +//&& maxNumEvent[b] < MaxNData * 0.6 + if( !isLastData && ((smallestLastTimeStamp - time1st) < NTimeWinForBuffer * timeWin) ) break; + if( ch1st > MaxNChannels ) break; + if( b1st < 0 ) break; + bd[multi_evt]= data[b1st]->boardSN; + ch[multi_evt]= ch1st; + e[multi_evt]= data[b1st]->Energy[ch1st][lastEv[b1st][ch1st]]; + e_t[multi_evt]= data[b1st]->Timestamp[ch1st][lastEv[b1st][ch1st]]; + e_f[multi_evt]= data[b1st]->fineTime[ch1st][lastEv[b1st][ch1st]]; + if( traceOn ){ + arrayTrace->Clear("C"); + traceLength[multi_evt] = (unsigned short) data[b1st]->Waveform1[ch1st][lastEv[b1st][ch1st]].size(); + trace = (TGraph *) arrayTrace->ConstructedAt(multi_evt, "C"); + trace->Clear(); + for( int hh = 0; hh < traceLength[multi_evt]; hh++){ + trace->SetPoint(hh, hh, data[b1st]->Waveform1[ch1st][lastEv[b1st][ch1st]][hh]); + } + } + + multi_evt ++; + lastEv[b1st][ch1st] ++; + + /// build the rest of the event + exhaustedBd=0; + for( int b = 0; b < nFile ; b++){ + exhaustedCh[b] = 0; + singleChannelExhaustedFlag[b] = false; + //for( int chI = ch1st[b]; chI < ch1st[b] + MaxNChannels; chI ++){ + //unsigned short chX = chI % MaxNChannels; + for( int chI = 0; chI < MaxNChannels; chI ++){ + if( data[b]->NumEvents[chI] == 0 ) { + exhaustedCh[b] ++; + continue; + } + if(data[b]->NumEvents[chI] <= lastEv[b][chI] ) { + exhaustedCh[b] ++; + singleChannelExhaustedFlag[b] = true; + continue; + } + + if(singleChannelExhaustedFlag[b] && exhaustedCh[b] >= MaxNChannels){BoardExhaustedFlag[b]=true;} + + if( timeWin == 0 ) continue; + if( BoardExhaustedFlag[b]) continue; + for( int ev = lastEv[b][chI]; ev < data[b]->NumEvents[chI] ; ev++){ + if( data[b]->Timestamp[chI][ev] > 0 && ((data[b]->Timestamp[chI][ev] - e_t[0] )*ch2ns_value*1e-9)*1e6 <= timeWin ) { + bd[multi_evt] = data[b]->boardSN; + ch[multi_evt] = chI; + e[multi_evt] = data[b]->Energy[chI][ev]; + e_t[multi_evt] = data[b]->Timestamp[chI][ev]; + e_f[multi_evt] = data[b]->fineTime[chI][ev]; + if( traceOn ){ + traceLength[multi_evt] = (unsigned short) data[b]->Waveform1[chI][ev].size(); + trace = (TGraph *) arrayTrace->ConstructedAt(multi_evt, "C"); + trace->Clear(); + for( int hh = 0; hh < traceLength[multi_evt]; hh++){ + trace->SetPoint(hh, hh, data[b]->Waveform1[chI][ev][hh]); + } + } + lastEv[b][chI] = ev + 1; + multi_evt ++; + if(lastEv[b][chI] == data[b]->NumEvents[chI] ) exhaustedCh[b] ++; + } + } + } + } + for(int b=0;b= MaxNChannels){BoardExhaustedFlag[b]=true;exhaustedBd ++;};} + + if( verbose) { + printf("=============== multi : %d , ev : %llu\n", multi_evt, evID); + for( int ev = 0; ev < multi_evt; ev++){ + printf("%3d, bd, ch : %2d, %2d, %u, %llu \n", ev, bd[ev], ch[ev], e[ev], e_t[ev]); + } + printf("=============== Last Ev , exhaustedBd %d \n", exhaustedBd); + for( int chI = 0; chI < MaxNChannels ; chI++){ + for( int b = 0; b < nFile ; b++){ + if(lastEv[b][chI] == 0 ) continue; + printf("board %d %2d, %d %d\n", b+1, chI, lastEv[b][chI], data[b]->NumEvents[chI]); + } + } + } + /// fill Tree + outRootFile->cd(); + tree->Fill(); + evID++; + multi_evt=0; + }while(exhaustedBd < nFile && exhaustedBdNumEvents[chI] == 0 ) continue; + int count = 0; + for( int ev = lastEv[b][chI] ; ev < data[b]->NumEvents[chI] ; ev++){ + data[b]->Energy[chI][count] = data[b]->Energy[chI][ev]; + data[b]->Timestamp[chI][count] = data[b]->Timestamp[chI][ev]; + data[b]->fineTime[chI][count] = data[b]->fineTime[chI][ev]; + count++; + } + int lala = data[b]->NumEvents[chI] - lastEv[b][chI]; + data[b]->NumEvents[chI] = (lala >= 0 ? lala: 0); + } + } +} + +template void swap(T * a, T *b ){ + T temp = * b; + *b = *a; + *a = temp; +} + +int partition(int arr[], int kaka[], TString file[], int start, int end){ + int pivot = arr[start]; + int count = 0; + for (int i = start + 1; i <= end; i++) { + if (arr[i] <= pivot) count++; + } + /// Giving pivot element its correct position + int pivotIndex = start + count; + swap(&arr[pivotIndex], &arr[start]); + swap(&file[pivotIndex], &file[start]); + swap(&kaka[pivotIndex], &kaka[start]); + + /// Sorting left and right parts of the pivot element + int i = start, j = end; + while (i < pivotIndex && j > pivotIndex) { + while (arr[i] <= pivot) {i++;} + while (arr[j] > pivot) {j--;} + if (i < pivotIndex && j > pivotIndex) { + int ip = i++; + int jm = j--; + swap( &arr[ip], &arr[jm]); + swap(&file[ip], &file[jm]); + swap(&kaka[ip], &kaka[jm]); + } + } + return pivotIndex; +} + +void quickSort(int arr[], int kaka[], TString file[], int start, int end){ + + /// base case + if (start >= end) return; + /// partitioning the array + int p = partition(arr, kaka, file, start, end); + /// Sorting the left part + quickSort(arr, kaka, file, start, p - 1); + /// Sorting the right part + quickSort(arr, kaka, file, p + 1, end); +} diff --git a/DAQ/Makefile b/DAQ/Makefile index 9450db1..f86f6e0 100755 --- a/DAQ/Makefile +++ b/DAQ/Makefile @@ -15,25 +15,31 @@ OBJS = influxdb.o startStopDialog.o programSetting.o triggerSummary.o registerSe ######################################################################### -all : ../test ../FSUDAQ ../test_indep ../Analysis/EventBuilder +all : ../Acquisition ../Analysis ../FSUDAQ /EventBuilder ../Analysis/EventBuilder_raw ../Plotting + ##../testStartAtSameTime clean : - /bin/rm -f $(OBJS) test FSUDAQ test_indep EventBuilder FSUDAQDict.cxx *.pcm + /bin/rm -f $(OBJS) Acquisition FSUDAQ EventBuilder EventBuilder_raw Plotting FSUDAQDict.cxx *.pcm + ##testStartAtSameTime ClassDigitizer.o : ClassDigitizer.cpp ClassDigitizer.h RegisterAddress.h macro.h ClassData.h $(CC) $(COPTS) -c ClassDigitizer.cpp -../test : test.cpp ClassDigitizer.o influxdb.o - @echo "--------- making test" - $(CC) $(COPTS) -o ../test test.cpp ClassDigitizer.o influxdb.o $(CAENLIBS) $(ROOTLIBS) -lcurl +../Acquisition : Acquisition.cpp ClassDigitizer.o influxdb.o + @echo "--------- making Acquisition" + $(CC) $(COPTS) -o ../Acquisition Acquisition.cpp ClassDigitizer.o influxdb.o $(CAENLIBS) $(ROOTLIBS) -lcurl ../Analysis/EventBuilder : EventBuilder.cpp ClassData.h @echo "--------- making EventBuilder" - $(CC) $(COPTS) -o ../Analysis/EventBuilder EventBuilder.cpp $(ROOTLIBS) - -../test_indep : test_indep.cpp RegisterAddress.h macro.h - @echo "--------- making test_indep" - $(CC) $(COPTS) -o ../test_indep test_indep.cpp $(CAENLIBS) + $(CC) $(COPTS) -o ../Analysis/EventBuilder EventBuilder.cpp $(CAENLIBS) $(ROOTLIBS) -lcurl + +../Analysis/EventBuilder_raw : EventBuilder_raw.cpp ClassData.h + @echo "--------- making EventBuilder_raw" + $(CC) $(COPTS) -o ../Analysis/EventBuilder_raw EventBuilder_raw.cpp $(CAENLIBS) $(ROOTLIBS) -lcurl + +../Plotting : Plotting.cpp ClassData.h + @echo "--------- making Plotting" + $(CC) $(COPTS) -o ../Plotting Plotting.cpp $(CAENLIBS) $(ROOTLIBS) -lcurl ../FSUDAQ : FSUDAQDict.cxx $(OBJS) ClassData.h @echo "----------- creating FSUDAQ" @@ -85,4 +91,7 @@ startStopDialog.o: startStopDialog.h startStopDialog.cpp #BoxScore : src/BoxScore.c Class/ClassDigitizer.h Class/FileIO.h Class/GenericPlane.h Class/HelioTarget.h Class/IsoDetect.h Class/HelioArray.h Class/MCPClass.h # g++ -std=c++17 -pthread src/BoxScore.c -o BoxScore $(DEPLIBS) $(ROOTLIBS) +#../testStartAtSameTime : testStartAtSameTime.cpp ClassDigitizer.o influxdb.o +# @echo "--------- making testStartAtSameTime" +# $(CC) $(COPTS) -o ../testStartAtSameTime testStartAtSameTime.cpp ClassDigitizer.o influxdb.o $(CAENLIBS) $(ROOTLIBS) -lcurl diff --git a/DAQ/Plotting.cpp b/DAQ/Plotting.cpp new file mode 100644 index 0000000..e21036f --- /dev/null +++ b/DAQ/Plotting.cpp @@ -0,0 +1,177 @@ +#include "macro.h" +#include "ClassData.h" +#include "TH1.h" +#include "TH2.h" +#include "TStyle.h" +#include "TCanvas.h" +#include "TFile.h" +#include "TChain.h" +#include "TSystem.h" +#include "TTree.h" +#include +#include "TApplication.h" + +char* path_to_con="/home/bavarians/FSUDAQ_MUSIC/Conversion/"; + +TH1I * heleft[MaxNChannels]; +TH1I * heright[MaxNChannels]; +TH1I * MultiEVT; +TH1I * MultiHIT; +TH2F* MapFull ; +TH2F* MapLeft; +TH2F* MapRight; +TH2F* S0A1l; +TH2F* S0grid; +TH2F* S0cath; +TH2F* A1A2; +TH2F* gridcath; +TH2F* MapTime; + +//IF SILICON DETECTOR +/*TH1F* E_histo ; +TH1F* dE_histo; +TH2F* dEE; +TH2F* si_de_time ; +TH2F* si_e_time;*/ + +TCanvas* csegLeft; +TCanvas* csegRight; +TCanvas* c; +TCanvas* cmult; +TCanvas* cmap; +TCanvas* cantime; + +#define MAX_MULTI 100 +unsigned long long evID ; +unsigned short multi_evt; +unsigned short multi_hit; +unsigned short stp0[MAX_MULTI]; /// 15 bit +unsigned short stp17[MAX_MULTI]; /// 15 bit +unsigned short grid[MAX_MULTI]; /// 15 bit +unsigned short cath[MAX_MULTI] ; /// 15 bit +unsigned short de_l[MAX_MULTI][16] ; /// 15 bit +unsigned short de_r[MAX_MULTI][16] ; /// 15 bit +unsigned short puls[MAX_MULTI][4]; /// 15 bit +unsigned long long e_t[MAX_MULTI]; /// timestamp 47 bit --> to get en sec *2e-9 +unsigned short e_f[MAX_MULTI]; /// fine time 10 bit + +int main(int argc, char* argv[]){ + + printf("=====================================\n"); + printf("=== Data Visualization ===\n"); + printf("=====================================\n"); + if (argc < 2) { + printf("Incorrect number of arguments:\n"); + printf("%s [RunId] \n", argv[0]); + printf("%s [Number of subfiles] \n", argv[1]); + return 1; + } + if (argc > 1) { + TApplication theApp("App",&argc, argv); + int Rid= atoi(argv[1]); + int Nfiles = atoi(argv[2]); + //""""""""""""""""""""" + //Accesing run + //""""""""""""""""""""" + gSystem->cd(path_to_con); + //FILE * haha[Nfiles]; TString inFileName; + char* inFileName; + TChain* MusicTree = new TChain("tree"); + for(int f=0;f9 && f<100){inFileName= Form("Run_00%i_0%i.root", Rid, f);} + if(f>99 && f<1000){inFileName= Form("Run_00%i_%i.root", Rid, f);} + printf("input file %s \n", inFileName); + //haha[f] = fopen(inFileName, "r"); + MusicTree->Add(inFileName); + } + MusicTree->SetBranchAddress("evID", &evID); + MusicTree->SetBranchAddress("multi_evt",&multi_evt); MusicTree->SetBranchAddress("multi_hit", &multi_hit); + MusicTree->SetBranchAddress("de_l", de_l); MusicTree->SetBranchAddress("de_r", de_r); + MusicTree->SetBranchAddress("stp0", stp0); MusicTree->SetBranchAddress("stp17", stp17); + MusicTree->SetBranchAddress("grid", grid); MusicTree->SetBranchAddress("cath" ,cath); + MusicTree->SetBranchAddress("puls", puls); + MusicTree->SetBranchAddress("e_t",e_t); MusicTree->SetBranchAddress("e_f", e_f); + int nStat = MusicTree->GetEntries(); + printf("number of Tree entries %i \n", nStat); + + //""""""""""""""""""""" + //Plot definition + //""""""""""""""""""""" + csegLeft= new TCanvas("csegLeft","csegLeft",1600,1600);csegLeft->Divide(4,4); + csegRight= new TCanvas("csegRight","csegRight",1600,1600);csegRight->Divide(4,4); + c= new TCanvas("c","c",1600,1600);c->Divide(2,2); + cmult= new TCanvas("cmult","cmult",1600,1600);cmult->Divide(2,2); + cmap= new TCanvas("cmap","cmap",900,1600);cmap->Divide(1,3); + cantime= new TCanvas("cantime","cantime",400,400); + cantime->cd(); + + double Er[2]={0., 16000}; double Timer[2]={0., 5000}; + double bin_raw=2; double bin_raw_time=0.1; + int Nbins = int((Er[1]-Er[0])/bin_raw); + int NbinsTime = int((Timer[1]-Timer[0])/ bin_raw_time); + S0A1l = new TH2F("S0A1l",";#DeltaE_{0} (a.u.); #DeltaE_{1} left (a.u.)",Nbins, Er[0], Er[1], Nbins, Er[0], Er[1]); + S0cath = new TH2F("S0cath",";cathode (a.u.);#DeltaE_{0} (a.u.)",Nbins, Er[0], Er[1],Nbins, Er[0], Er[1]); + S0grid= new TH2F("S0grid",";grid (a.u.);#DeltaE_{0} (a.u.)", Nbins, Er[0], Er[1],Nbins, Er[0], Er[1]); + A1A2 = new TH2F("A1A2",";#DeltaE_{1} (a.u.);#DeltaE_{2} (a.u.)",Nbins, Er[0], Er[1],Nbins, Er[0], Er[1]); + gridcath= new TH2F("gridcath",";grid (a.u.);cathode (a.u.)", Nbins, Er[0], Er[1],Nbins, Er[0], Er[1]); + MapLeft= new TH2F("MapLeft","Left;Strip;#DeltaE (a.u.)", 18,0,18,Nbins, Er[0], Er[1]); + MapRight = new TH2F("MapRight","Right;Strip;#DeltaE (a.u.)", 18,0,18,Nbins, Er[0], Er[1]); + MapFull = new TH2F("MapFull","Long segments;Strip;#DeltaE (a.u.)", 18,0,17,Nbins, Er[0], Er[1]); + MapTime = new TH2F("MapTime",";Time event (ms); grid = 0 & Pulser = 5+Board*5", NbinsTime,Timer[0],Timer[1],25,0,25); + MultiEVT = new TH1I("MultiEVT",";Event multiplicity", 10, 0, 10); + MultiHIT= new TH1I("MultiHIT",";DAQ Channel Hit multiplicity", 100, 0, 100); + for(int c=0;cDraw("multi_evt>>MultiEVT"); + MusicTree->Draw("multi_hit>>MultiHIT"); + for(int i = 0;iGetEntry(i); + if(multi_evt*multi_hit>0){ + for(int ev=0;evFill(grid[ev],stp0[ev]); S0cath->Fill(cath[ev],stp0[ev]); + gridcath->Fill(grid[ev],cath[ev]); + MapRight->Fill(0.,stp0[ev]); MapLeft->Fill(0.,stp0[ev]); + MapRight->Fill(17,stp17[ev]); MapLeft->Fill(17,stp17[ev]); + A1A2->Fill(de_l[ev][0],de_r[ev][1]); S0A1l->Fill(stp0[ev], de_l[ev][0]); + for( int c = 0; c Fill(de_l[ev][c]); heright[c]->Fill(de_r[ev][c]); + MapRight->Fill(c+1,de_r[ev][c]); MapLeft->Fill(c+1,de_l[ev][c]); + if(c%2==0){MapFull->Fill(c+1, de_l[ev][c]);} + if(c%2==1){MapFull->Fill(c+1, de_r[ev][c]);} + } + if(e_t[ev]*ch2ns_value*1e-90){MapTime->Fill(e_t[ev]*ch2ns_value*1e-6,0);} + for(int b = 0; b 0){MapTime->Fill(e_t[ev]*ch2ns_value*1e-6,5+b*5);} + } + } + } + } + } + printf("Enter Ctrl+C to stop ..."); + //""""""""""""""""""""" + //Plotting + //""""""""""""""""""""" + gStyle->SetPalette(kThermometer); + c->cd(1);S0grid->Draw("colz");S0grid->GetXaxis()->CenterTitle();S0grid->GetYaxis()->CenterTitle(); + c->cd(2);S0cath->Draw("colz");S0cath->GetXaxis()->CenterTitle();S0cath->GetYaxis()->CenterTitle(); + c->cd(3); S0A1l->Draw("colz"); S0A1l->GetXaxis()->CenterTitle(); S0A1l->GetYaxis()->CenterTitle(); + c->cd(4);A1A2->Draw("colz");A1A2->GetXaxis()->CenterTitle();A1A2->GetYaxis()->CenterTitle(); + cmult->cd(1);gridcath->Draw("colz");gridcath->GetXaxis()->CenterTitle();gridcath->GetYaxis()->CenterTitle(); + cantime->cd();MapTime->Draw("colz");MapTime->GetXaxis()->CenterTitle();MapTime->GetYaxis()->CenterTitle(); + cmap->cd(1);MapLeft->Draw("colz");MapLeft->GetXaxis()->CenterTitle();MapLeft->GetYaxis()->CenterTitle(); + cmap->cd(2);MapRight->Draw("colz");MapRight->GetXaxis()->CenterTitle();MapRight->GetYaxis()->CenterTitle(); + cmap->cd(3);MapFull->Draw("colz");MapFull->GetXaxis()->CenterTitle();MapFull->GetYaxis()->CenterTitle(); + for( int i = 0; i cd(i+1); heleft[i]->Draw("h");heleft[i]->GetXaxis()->CenterTitle(); + csegRight->cd(i+1); heright[i]->Draw("h");heright[i]->GetXaxis()->CenterTitle(); + } + cmult->cd(3);MultiEVT->Draw("h");MultiEVT->GetXaxis()->CenterTitle(); + cmult->cd(4);MultiHIT->Draw("h");MultiHIT->GetXaxis()->CenterTitle(); + theApp.Run(); + return 1; + } +} diff --git a/DAQ/RegisterAddress.h b/DAQ/RegisterAddress.h index 508febd..e23306e 100644 --- a/DAQ/RegisterAddress.h +++ b/DAQ/RegisterAddress.h @@ -264,7 +264,8 @@ namespace Register { const Reg TriggerHoldOffWidth ("TriggerHoldOffWidth" , 0x1074); /// R/W OK const Reg PeakHoldOff ("PeakHoldOff" , 0x1078); /// R/W OK const Reg ShapedTriggerWidth ("ShapedTriggerWidth" , 0x1084); /// R/W not sure - const Reg DPPAlgorithmControl2_G ("DPPAlgorithmControl2_G" , 0x10A0, 0, 1); /// R/W OK + const Reg DPPAlgorithmControl2_G ("DPPAlgorithmControl2_G" , 0x10A0, 0); /// R/W OK + const Reg DPPAlgorithmControl22_G ("DPPAlgorithmControl22_G" , 0x10AC); /// R/W OK const Reg FineGain ("FineGain" , 0x10C4); /// R/W OK } diff --git a/DAQ/macro.h b/DAQ/macro.h index 19ad7b6..6043700 100644 --- a/DAQ/macro.h +++ b/DAQ/macro.h @@ -2,10 +2,10 @@ #define MACRO_H #define MaxNPorts 4 -#define MaxNBoards 22 +#define MaxNBoards 4 #define MaxNChannels 16 #define MaxRecordLength 0x3fff * 8 -#define MaxSaveFileSize 1024 * 1024 * 1024 * 2 +#define MaxSaveFileSize 1024 * 1024 * 1024 * 1.0 #define SETTINGSIZE 2048 diff --git a/DAQ/testStartAtSameTime.cpp b/DAQ/testStartAtSameTime.cpp new file mode 100644 index 0000000..0baeabd --- /dev/null +++ b/DAQ/testStartAtSameTime.cpp @@ -0,0 +1,79 @@ + +#include // std::cout +#include // std::thread +#include // std::mutex, std::unique_lock +#include // std::condition_variable +#include // time in nano-sec +#include // usleep + +#define nTh 5 + +std::mutex mtx[nTh]; +std::condition_variable cv; +bool ready = false; + +timespec ts[nTh]; + +void print_id(int id) { + std::unique_lock lck(mtx[id]); + while (!ready ){ + printf("waiting for unlock %d\n", id); + cv.wait(lck); + } + cv.notify_all(); + + clock_gettime(CLOCK_REALTIME, &ts[id]); + printf("----thread %d ready. %ld ns\n", id, ts[id].tv_nsec); + + usleep(2000*2000); + + printf("thread %d finished.\n", id); + +} + +void go() { + ready = true; + cv.notify_all(); +} + +int main(){ + + std::thread threads[nTh]; + + for (int i = 0; i < nTh; ++i){ + threads[i] = std::thread(print_id, i); + } + + printf("%d threads ready to race...\n", nTh); + + usleep(1000*1000); + + go(); // go! + + for (auto& th : threads) th.join(); + + printf("=========== finsihed.\n"); + + long avg = 0; + for( int i =0; i < nTh ; i++) avg += ts[i].tv_nsec; + avg = avg/nTh; + + long min , max; + + for( int i =0; i < nTh; i++) { + if( i == 0 ){ + min = ts[i].tv_nsec; + max = ts[i].tv_nsec; + continue; + } + if( min > ts[i].tv_nsec) min = ts[i].tv_nsec; + if( max < ts[i].tv_nsec) max = ts[i].tv_nsec; + } + + printf(" avg : %ld\n", avg); + printf(" min : %ld, %ld\n", min, avg - min); + printf(" max : %ld, %ld\n", max, max - avg); + printf(" diff : %ld\n", max-min); + + return 0; +} diff --git a/MUSIC_Topology/Board0.dat b/MUSIC_Topology/Board0.dat new file mode 100644 index 0000000..61822e4 --- /dev/null +++ b/MUSIC_Topology/Board0.dat @@ -0,0 +1,17 @@ +0 503 +1 -1 +2 1 +3 -1 +4 500 +5 504 +6 5 +7 -1 +8 0 +9 -1 +10 9 +11 -1 +12 17 +13 13 +14 -1 +15 502 + diff --git a/MUSIC_Topology/Board1.dat b/MUSIC_Topology/Board1.dat new file mode 100644 index 0000000..4453723 --- /dev/null +++ b/MUSIC_Topology/Board1.dat @@ -0,0 +1,16 @@ +0 2 +1 -1 +2 16 +3 -1 +4 21 +5 504 +6 20 +7 -1 +8 8 +9 -1 +10 24 +11 -1 +12 27 +13 28 +14 -1 +15 14 diff --git a/MUSIC_Topology/Board2.dat b/MUSIC_Topology/Board2.dat new file mode 100644 index 0000000..59cbffb --- /dev/null +++ b/MUSIC_Topology/Board2.dat @@ -0,0 +1,16 @@ +0 19 +1 -1 +2 3 +3 -1 +4 6 +5 504 +6 7 +7 -1 +8 25 +9 -1 +10 11 +11 -1 +12 12 +13 15 +14 -1 +15 10 diff --git a/MUSIC_Topology/Board3.dat b/MUSIC_Topology/Board3.dat new file mode 100644 index 0000000..a56cc1a --- /dev/null +++ b/MUSIC_Topology/Board3.dat @@ -0,0 +1,16 @@ +0 4 +1 -1 +2 18 +3 -1 +4 23 +5 504 +6 22 +7 -1 +8 29 +9 -1 +10 26 +11 -1 +12 31 +13 30 +14 -1 +15 501 diff --git a/README/README.md b/README/README.md new file mode 100644 index 0000000..61b3e5b --- /dev/null +++ b/README/README.md @@ -0,0 +1,112 @@ +## Introduction (First Version) + +The FSUDAQ_MUSIC is an ONGOING online and offline aquisition for CAEN x725 digitizers with DPP-PHA firmware for MUSIC set-up at ATLAS/Argonne National Laboratory. +It is based on CERN_ROOT/C++. The x730 digitizer and the DPP-PSD firmware are also possible. + +Additional inforamtion in https://fsunuc.physics.fsu.edu/wiki/index.php/CAEN_digitizer#FSU_DAQ + +## Required Library +1. CAENComm 1.4+ +2. CAENVMELib 2.5+ +3. CAENDigitizer 2.12+ +4. CAEN A3818 Driver 1.61+ (for optical link) +5. CERN ROOT 6 +6. libcurl4-nss-dev (for the libcurl, used in InfluxDB class) +7. InfluxDB 1.8 (recommanded for trigger rate, optional for database) + +## Folder Structure +FSUDAQ_MUSIC \ + ├── Analysis \ + ├── Conversion \ + | └── Raw \ + ├── DAQ \ + ├── MUSIC_Topology\ + ├── README \ + └── Run \ + +The parent folder FSUDAQ_MUSIC should be placed on the Home directory. +Information available in README/ folder. + +All source codes are in DAQ/ folder. +The key codes are +1. ClassData.h +2. RegisterAddress.h +3. ClassDigitizer.h/cpp +4. Acquisition.cpp +5. EventBuilder.cpp EventBuilder_raw.cpp +6. Plotting.cpp + +4. The Acquisition.cpp is the main code for online acquisition. It controls, readouts digitizers and stores the data in Run/ folder. + +5. The EventBuilder_raw.cpp and EventBuilder.cpp are the codes for online /offline event building with the raw DAQ topology and the MUSIC setup toplogy, respectively. +Saved raw run .fsu files (in Run/) are converted in TTree .root run files in Conversion/Raw/ and Conversion/ for EventBuilder_raw.cpp and EventBuilder.cpp, respectively. +Compiled scripts are stored in Analysis/ folder. + +6. The Plotting.cpp is a code for online or offline data visualization from the converted .root run files in Conversion/, requiring the MUSIC setup toplogy. + + +The MUSIC setup toplogy is defined in MUSIC_Topology/. +--> see description in README/Topology_MUSIC_read_me.md + + +## To Compile (--> according to DAQ/Makefile) +> cd DAQ/; make ../Acquisition;cd ../; +> cd DAQ/; make ../Analysis/EventBuilder_raw;cd ../; +> cd DAQ/; make ../Analysis/EventBuilder;cd ../; +> cd DAQ/; make ../Plotting;cd ../; + +Executables produced for each code. + + + +######## +# Usages +######## + + +## Acquisition +--> Input = [Run Time in second, 0 for infinite one] [Run number] + +Number of available digitizers defined at start +--> nDig +Data taking done in parallel with the function: +--> func(Digitizer * dig, double RunTime, int Rid, int Bid) +All digitizers start at close time (~dT tens of microseconds) + +Assignement of registers value done through 2 functions +--> boardSetParameters //Parameters usually tuned at the start of a MUSIC experiment with the help of CoMPASS software +--> boardCommonParameters //Standard parameters for MUSIC setup +Details on how to assign the registers values are given in +--> README/Register_inputs_readme.md + +Raw data are stored in Run/, with the path defined at start +--> path_to_run +A file per board and files size limit is 1 GB (defined with MaxSaveFileSize in DAQ/macro.h ) +--> Run_00#_B#_###.fsu + + +## EventBuilder_raw and EventBuilder +--> Input = [Time window in microsecond] [Trace ==0, off] [verbose 0/1] [list of raw run .fsu filenames ...] + +Building of events in readable format, i.e. oot TTree 'tree' (see defined tree structures). + +Raw conversion stores within the time window the lists of energy/time/board/channel. The number of DAQ channel hits corresponds to +-->multi_evt + +Final conversion stores within the time window the physical events with MUSIC inputs (energies of left/right segments, grid, cathode, strip0, strip17,..., and times, pulsers...). +The number of events within the time window is +-->multi_evt +The number of MUSIC signals hits for each event (e.g. std value is 16+4(+4puls)) is +-->multi_hit + +MUSIC setup toplogy path is defined at start +--> path_to_top +Converted root files are stored in Conversion/, with the path defined at start +--> path_to_con + + +## Plotting +--> Input = [Run number] [number of run_subfiles] + +Standard MUSIC histograms for PID, beam trajectory and segment maps (2x16), event built multiplicities and time structure (if pulser input per board). +Additional (like Silicon PID..) histograms to be defined at the start of the script. diff --git a/README/Register_inputs_readme.md b/README/Register_inputs_readme.md new file mode 100644 index 0000000..fd7fe7c --- /dev/null +++ b/README/Register_inputs_readme.md @@ -0,0 +1,50 @@ +## Introduction +Assignement of registers value done in DAQ/Acquisition.cpp, +parameters are usually tuned at the start of a MUSIC experiment with the help of CoMPASS software. + +Assigned registers saved in +--> reg_Board%i.txt + +## Usage +Digitizer class function +--> dig->WriteRegister(Register::#DPP::#PHA::#name, #value_in_hexadecimal, #channel_index) + +To access registers values, looked in CoMPASS software (or if saved in reg_Board%i.txt) with register address "Reg" defined by +--> 0x#### + +Aggregate registers +--> MaxAggregatePerBlockTransfer //Reg=0xEF1C +--> NumberEventsPerAggregate_G //Reg=0x1034 + +Standard registers defined and assigned in +--> boardCommonParameters(Digitizer * dig) + +Specific registers per MUSIC experiment defined and assigned in +--> boardSetParameters(...) +where inputs defined in main function +--> double BoardConfigurationval //Reg=0x8000 +--> double DPPAlgoCtrl //Reg=0x1080 +--> double DPPAlgoCtrl_10A0 //Reg=0x10A0 +--> double DPPAlgoCtrl_10AC //Reg=0x10AC +--> double ShapedTriggerWidthVal //Reg=0x1084 in steps of 16ns, 96=6*16 +--> double InputSec[7] // Corresponding to CoMPASS Inputs Section + 0. Not used + 1. //Reg=0x1020 RecordLength input N such length (ns) == N*8*4 + 2. //Reg=0x1038 PreTrigger in steps of 16ns, input N such length (ns) == N*4*4 + 3. Not used + 4. Not used + 5. //Reg=0x1098 DCoffset DC% = 1 - input/65535 (ChannelDCOffset) + 6. //Reg=0x1028 CoarseGain 0=x1 or 1=x4 (InputDynamicRange) +--> double DiscriSec[4] // Corresponding to CoMPASS Discriminator Section + 0. //Reg=0x106C TriggerThreshold in lsb + 1. //Reg=0x1074 TriggerHoldOffWidth in steps of 16ns + 2. //Reg=0x1054 FastDiscriSmooth, e.g. 20=64samp, 63=128samp, (RCCR2SmoothingFactor) + 3. //Reg=0x1058 InputRiseTime in steps of 16ns +--> double TrapSec[7] // Corresponding to CoMPASS Trapezoid Section + 0. //Reg=0x105C RiseTime in steps of 16ns + 1. //Reg=0x1060 FlatTop in steps of 16ns + 2. //Reg=0x1068 PoleZero in steps of 16ns (DecayTime) + 3. //Reg=0x1064 PeakingTime in steps of 16ns + 4. Not used + 5. //Reg=0x1078 PeakHoldOff in steps of 16ns + 6. //Reg=0x10C4 fine gain, eg 1==0x00006C3A (FineGain) diff --git a/README/Topology_MUSIC_read_me.md b/README/Topology_MUSIC_read_me.md new file mode 100644 index 0000000..6e08793 --- /dev/null +++ b/README/Topology_MUSIC_read_me.md @@ -0,0 +1,21 @@ +## Introduction +The topology of the DAQ w.r.t detection inputs (MUSIC signals, pulser, additional Silicon signals...) is given in a file per board +--> Board#.dat +Files and associated topology information are extracted and used by DAQ/EventBuilder.cpp to build back events from DAQ channels to physics signals. +Used function in DAQ/EventBuilder.cpp +--> extraction_map(int map[4][16]) + +## Path to files +FSUDAQ_MUSIC/MUSIC_Topology/Board#.dat + +## File Structure --> 2 columns +DAQ channel (0->15) | MUSIC Segment + +## Correspondance MUSIC Segment to physics inputs +500 == Strip 0 +501 == Strip 17 +502 == Grid +503 == Cathode +504 == Pulse +0->15 == left side +16->31 == right side