33#include <TChain.h>
44#include <TFile.h>
55#include <TStopwatch.h>
6- #include <FairLogger.h>
6+ #include "Framework/Logger.h"
77#include <vector>
88#include <string>
99#include <iomanip>
1616#endif
1717
1818// demo macro the MC->raw conversion with new (variable page size) format
19+ void setupLinks (o2 ::itsmft ::MC2RawEncoder < o2 ::itsmft ::ChipMappingITS > & m2r , const std ::string & outPrefix );
1920
20- void run_digi2rawVarPage_its (std ::string outName = "rawits.bin" , // name of the output binary file
21- std ::string inpName = "itsdigits.root" , // name of the input ITS digits
21+ void run_digi2rawVarPage_its (std ::string outPrefix = "rawits" , // prefix of the output binary file
22+ std ::string inpName = "itsdigits.root" , // name of the input ITS digits
23+ int verbosity = 0 ,
2224 std ::string digTreeName = "o2sim" , // name of the digits tree
2325 std ::string digBranchName = "ITSDigit" , // name of the digits branch
2426 std ::string rofRecName = "ITSDigitROF" , // name of the ROF records branch
@@ -46,83 +48,40 @@ void run_digi2rawVarPage_its(std::string outName = "rawits.bin", // nam
4648 // ROF record entries in the digit tree
4749 ROFRVEC rofRecVec , * rofRecVecP = & rofRecVec ;
4850 if (!digTree .GetBranch (rofRecName .c_str ())) {
49- LOG (FATAL ) << "Failed to find the branch " << rofRecName << " in the tree " << rofRecName ;
51+ LOG (FATAL ) << "Failed to find the branch " << rofRecName << " in the tree " << digTreeName ;
5052 }
5153 digTree .SetBranchAddress (rofRecName .c_str (), & rofRecVecP );
5254 ///-------< input
5355
54- ///-------> output
55- if (outName .empty ()) {
56- outName = "raw" + digBranchName + ".raw" ;
57- LOG (INFO ) << "Output file name is not provided, set to " << outName ;
58- }
59- auto outFl = fopen (outName .c_str (), "wb" );
60- if (!outFl ) {
61- LOG (FATAL ) << "failed to open raw data output file " << outName ;
62- ;
63- } else {
64- LOG (INFO ) << "opened raw data output file " << outName ;
65- }
66- ///-------< output
67-
6856 const auto grp = o2 ::parameters ::GRPObject ::loadFrom (inputGRP );
6957
7058 o2 ::itsmft ::MC2RawEncoder < o2 ::itsmft ::ChipMappingITS > m2r ;
71- m2r .setVerbosity (2 );
72- m2r .setOutFile (outFl );
59+ m2r .setVerbosity (verbosity );
7360 m2r .setContinuousReadout (grp -> isDetContinuousReadOut (o2 ::detectors ::DetID ::ITS )); // must be set explicitly
74-
61+ m2r . setDefaultSinkName ( outPrefix + ".raw" );
7562 m2r .setMinMaxRUSW (ruSWMin , ruSWMax );
7663
77- //------------------------------------------------------------------------------->>>>
78- // just as an example, we require here that the staves are read via 3 links, with partitioning according to lnkXB below
79- // while OB staves use only 1 link.
80- // Note, that if the RU container is not defined, it will be created automatically
81- // during encoding.
82- // If the links of the container are not defined, a single link readout will be assigned
83- const auto& mp = m2r .getMapping ();
84- int lnkAssign [3 ][3 ] = {
85- /* // uncomment this to have 1 link per RU
86- {9, 0, 0}, // IB
87- {16, 0, 0}, // MB
88- {28, 0, 0} // OB
89- */
90- {3 , 3 , 3 }, // IB
91- {5 , 5 , 6 }, // MB
92- {9 , 9 , 10 } // OB
93- };
94- for (int ir = m2r .getRUSWMin (); ir <= m2r .getRUSWMax (); ir ++ ) {
95-
96- auto& ru = m2r .getCreateRUDecode (ir ); // create RU container
97- uint32_t lanes = mp .getCablesOnRUType (ru .ruInfo -> ruType ); // lanes patter of this RU
98- int * lnkAs = lnkAssign [ru .ruInfo -> ruType ];
99- int accL = 0 ;
100- for (int il = 0 ; il < 3 ; il ++ ) { // create links
101- if (lnkAs [il ]) {
102- ru .links [il ] = std ::make_unique < o2 ::itsmft ::GBTLink > ( );
103- ru .links [il ]-> lanes = lanes & ((0x1 << lnkAs [il ]) - 1 ) << (accL );
104- ru .links [il ]-> id = il ;
105- ru .links [il ]-> cruID = ir ;
106- ru .links [il ]-> feeID = mp .RUSW2FEEId (ir , il );
107- accL += lnkAs [il ];
108- LOG (INFO ) << "RU " << std ::setw (3 ) << ir << " on lr" << int (ru .ruInfo -> layer )
109- << " : FEEId 0x" << std ::hex << std ::setfill ('0' ) << std ::setw (6 ) << ru .links [il ]-> feeID
110- << " reads lanes " << std ::bitset < 28 > (ru .links [il ]-> lanes );
111- }
112- }
113- }
64+ m2r .getWriter ().setSuperPageSize (1024 * 1024 ); // this is default anyway
65+ m2r .getWriter ().getHBFUtils ().setNOrbitsPerTF (256 ); // this is default anyway
66+
67+ m2r .setVerbosity (0 );
11468
69+ setupLinks (m2r , outPrefix );
11570 //-------------------------------------------------------------------------------<<<<
11671 int lastTreeID = -1 ;
11772 long offs = 0 , nEntProc = 0 ;
11873 for (int i = 0 ; i < digTree .GetEntries (); i ++ ) {
11974 digTree .GetEntry (i );
12075 for (const auto& rofRec : rofRecVec ) {
12176 int nDigROF = rofRec .getNEntries ();
122- LOG (INFO ) << "Processing ROF:" << rofRec .getROFrame () << " with " << nDigROF << " entries" ;
123- rofRec .print ();
77+ if (verbosity ) {
78+ LOG (INFO ) << "Processing ROF:" << rofRec .getROFrame () << " with " << nDigROF << " entries" ;
79+ rofRec .print ();
80+ }
12481 if (!nDigROF ) {
125- LOG (INFO ) << "Frame is empty" ; // ??
82+ if (verbosity ) {
83+ LOG (INFO ) << "Frame is empty" ; // ??
84+ }
12685 continue ;
12786 }
12887 nEntProc ++ ;
@@ -133,9 +92,92 @@ void run_digi2rawVarPage_its(std::string outName = "rawits.bin", // nam
13392
13493 m2r .finalize (); // finish TF and flush data
13594 //
136- fclose (outFl );
137- m2r .setOutFile (nullptr );
138- //
13995 swTot .Stop ();
14096 swTot .Print ();
14197}
98+
99+ void setupLinks (o2 ::itsmft ::MC2RawEncoder < o2 ::itsmft ::ChipMappingITS > & m2r , const std ::string & outPrefix )
100+ {
101+ //------------------------------------------------------------------------------->>>>
102+ // just as an example, we require here that the staves are read via 3 links, with partitioning according to lnkXB below
103+ // while OB staves use only 1 link.
104+ // Note, that if the RU container is not defined, it will be created automatically
105+ // during encoding.
106+ // If the links of the container are not defined, a single link readout will be assigned
107+
108+ constexpr int MaxLinksPerRU = 3 ;
109+ constexpr int MaxLinksPerCRU = 16 ;
110+ const auto& mp = m2r .getMapping ();
111+ int lnkAssign [3 ][MaxLinksPerRU ] = {
112+ // requested link cabling for IB, MB and OB
113+ /* // uncomment this to have 1 link per RU
114+ {9, 0, 0}, // IB
115+ {16, 0, 0}, // MB
116+ {28, 0, 0} // OB
117+ */
118+ {3 , 3 , 3 }, // IB
119+ {5 , 5 , 6 }, // MB
120+ {9 , 9 , 10 } // OB
121+ };
122+
123+ // this is an arbitrary mapping
124+ int nCRU = 0 , nRUtot = 0 , nRU = 0 , nLinks = 0 ;
125+ int linkID = 0 , cruIDprev = -1 , cruID = o2 ::detectors ::DetID ::ITS << 10 ; // this will be the lowest CRUID
126+ std ::string outFileLink ;
127+
128+ for (int ilr = 0 ; ilr < mp .NLayers ; ilr ++ ) {
129+ int nruLr = mp .getNStavesOnLr (ilr );
130+ int ruType = mp .getRUType (nRUtot ); // IB, MB or OB
131+ int * lnkAs = lnkAssign [ruType ];
132+ // count requested number of links per RU
133+ int nlk = 0 ;
134+ for (int i = 3 ; i -- ;) {
135+ nlk += lnkAs [i ] ? 1 : 0 ;
136+ }
137+ outFileLink = outPrefix + "_lr" + std ::to_string (ilr ) + ".raw" ;
138+ for (int ir = 0 ; ir < nruLr ; ir ++ ) {
139+ int ruID = nRUtot ++ ;
140+ bool accept = !(ruID < m2r .getRUSWMin () || ruID > m2r .getRUSWMax ()); // ignored RUs ?
141+ if (accept ) {
142+ m2r .getCreateRUDecode (ruID ); // create RU container
143+ nRU ++ ;
144+ }
145+ int accL = 0 ;
146+ for (int il = 0 ; il < MaxLinksPerRU ; il ++ ) { // create links
147+ if (accept ) {
148+ nLinks ++ ;
149+ auto& ru = * m2r .getRUDecode (ruID );
150+ uint32_t lanes = mp .getCablesOnRUType (ru .ruInfo -> ruType ); // lanes patter of this RU
151+ ru .links [il ] = std ::make_unique < o2 ::itsmft ::GBTLink > ( );
152+ ru .links [il ]-> lanes = lanes & ((0x1 << lnkAs [il ]) - 1 ) << (accL );
153+ ru .links [il ]-> id = linkID ;
154+ ru .links [il ]-> cruID = cruID ;
155+ ru .links [il ]-> feeID = mp .RUSW2FEEId (ir , il );
156+ ru .links [il ]-> endPointID = 0 ; // 0 or 1
157+ accL += lnkAs [il ];
158+ if (m2r .getVerbosity ()) {
159+ LOG (INFO ) << "RU" << ruID << '(' << ir << " on lr " << ilr << ") " << ru .links [il ]-> describe ()
160+ << " -> " << outFileLink ;
161+ }
162+ // register the link in the writer, if not done here, its data will be dumped to common default file
163+ m2r .getWriter ().registerLink (ru .links [il ]-> feeID , ru .links [il ]-> cruID , ru .links [il ]-> id ,
164+ ru .links [il ]-> endPointID , outFileLink );
165+ //
166+ if (cruIDprev != cruID ) { // just to count used CRUs
167+ cruIDprev = cruID ;
168+ nCRU ++ ;
169+ }
170+ }
171+ if ((++ linkID ) >= MaxLinksPerCRU ) {
172+ linkID = 0 ;
173+ ++ cruID ;
174+ }
175+ }
176+ }
177+ if (linkID ) {
178+ linkID = 0 ; // we don't want to put links of different layers on the same CRU
179+ ++ cruID ;
180+ }
181+ }
182+ LOG (INFO ) << "Distributed " << nLinks << " links on " << nRU << " RUs in " << nCRU << " CRUs" ;
183+ }
0 commit comments