15#include <boost/program_options.hpp>
19#include <TStopwatch.h>
41constexpr int DefRDHVersion = o2::raw::RDHUtils::getVersion<o2::header::RAWDataHeader>();
44void digi2raw(std::string_view inpName, std::string_view outDir, std::string_view fileFor,
int verbosity, uint32_t rdhV =
DefRDHVersion,
bool enablePadding =
false,
45 bool noEmptyHBF =
false,
bool noEmptyROF =
false,
int superPageSizeInB = 1024 * 1024);
47int main(
int argc,
char** argv)
49 bpo::variables_map vm;
50 bpo::options_description opt_general(
"Usage:\n " + std::string(argv[0]) +
51 "Convert MFT digits to CRU raw data\n");
52 bpo::options_description opt_hidden(
"");
53 bpo::options_description opt_all;
54 bpo::positional_options_description opt_pos;
57 auto add_option = opt_general.add_options();
58 add_option(
"help,h",
"Print this help message");
59 add_option(
"verbosity,v", bpo::value<uint32_t>()->default_value(0),
"verbosity level [0 = no output]");
60 add_option(
"input-file,i", bpo::value<std::string>()->default_value(
"mftdigits.root"),
"input digits file");
61 add_option(
"file-for,f", bpo::value<std::string>()->default_value(
"layer"),
"single file per: all,layer,cruendpoint,link");
62 add_option(
"output-dir,o", bpo::value<std::string>()->default_value(
"./"),
"output directory for raw data");
63 add_option(
"rdh-version,r", bpo::value<uint32_t>()->default_value(
DefRDHVersion),
"RDH version to use");
64 add_option(
"enable-padding", bpo::value<bool>()->default_value(
false)->implicit_value(
true),
"enable GBT word padding to 128 bits even for RDH V7");
65 add_option(
"no-empty-hbf,e", bpo::value<bool>()->default_value(
false)->implicit_value(
true),
"do not create empty HBF pages (except for HBF starting TF)");
66 add_option(
"no-empty-rof", bpo::value<bool>()->default_value(
false)->implicit_value(
true),
"do not create empty ROF blocks");
68 add_option(
"configKeyValues", bpo::value<std::string>()->default_value(
""),
"comma-separated configKeyValues");
70 opt_all.add(opt_general).add(opt_hidden);
71 bpo::store(bpo::command_line_parser(argc, argv).options(opt_all).positional(opt_pos).run(), vm);
73 if (vm.count(
"help")) {
74 std::cout << opt_general << std::endl;
79 }
catch (bpo::error& e) {
80 std::cerr <<
"ERROR: " << e.what() << std::endl
82 std::cerr << opt_general << std::endl;
84 }
catch (std::exception& e) {
85 std::cerr << e.what() <<
", application will now exit" << std::endl;
89 std::string confDig = vm[
"hbfutils-config"].as<std::string>();
90 if (!confDig.empty() && confDig !=
"none") {
94 digi2raw(vm[
"input-file"].as<std::string>(),
95 vm[
"output-dir"].as<std::string>(),
96 vm[
"file-for"].as<std::string>(),
97 vm[
"verbosity"].as<uint32_t>(),
98 vm[
"rdh-version"].as<uint32_t>(),
99 vm[
"enable-padding"].as<bool>(),
100 vm[
"no-empty-hbf"].as<bool>(),
101 vm[
"no-empty-rof"].as<bool>());
102 LOG(info) <<
"HBFUtils settings used for conversion:";
109void digi2raw(std::string_view inpName, std::string_view outDir, std::string_view fileFor,
int verbosity, uint32_t rdhV,
bool enablePadding,
bool noEmptyHBF,
bool noEmptyROF,
int superPageSizeInB)
114 using ROFRVEC = std::vector<o2::itsmft::ROFRecord>;
115 const uint8_t ruSWMin = 0, ruSWMax = 0xff;
116 if (rdhV < 7 && !enablePadding) {
117 enablePadding =
true;
118 LOG(info) <<
"padding is always ON for RDH version " << rdhV;
121 LOG(info) <<
"HBFUtil settings:";
125 if (!std::filesystem::exists(outDir)) {
126 if (!std::filesystem::create_directories(outDir)) {
127 LOG(fatal) <<
"could not create output directory " << outDir;
129 LOG(info) <<
"created output directory " << outDir;
135 TChain digTree(digTreeName.c_str());
136 digTree.AddFile(inpName.data());
137 digTree.SetBranchStatus(
"*MCTruth*", 0);
139 std::vector<o2::itsmft::Digit> digiVec, *digiVecP = &digiVec;
141 if (!digTree.GetBranch(digBranchName.c_str())) {
142 LOG(fatal) <<
"Failed to find the branch " << digBranchName <<
" in the tree " << digTreeName;
144 digTree.SetBranchAddress(digBranchName.c_str(), &digiVecP);
147 ROFRVEC rofRecVec, *rofRecVecP = &rofRecVec;
149 if (!digTree.GetBranch(rofRecName.c_str())) {
150 LOG(fatal) <<
"Failed to find the branch " << rofRecName <<
" in the tree " << digTreeName;
152 digTree.SetBranchAddress(rofRecName.c_str(), &rofRecVecP);
165 if (!enablePadding) {
175 for (
int i = 0;
i < digTree.GetEntries();
i++) {
177 for (
const auto& rofRec : rofRecVec) {
178 int nDigROF = rofRec.getNEntries();
180 LOG(info) <<
"Processing ROF:" << rofRec.getROFrame() <<
" with " << nDigROF <<
" entries";
183 if (!nDigROF && noEmptyROF) {
185 LOG(info) <<
"Frame is empty";
190 auto dgs = nDigROF ? gsl::span<const o2::itsmft::Digit>(&digiVec[rofRec.getFirstEntry()], nDigROF) : gsl::span<const o2::itsmft::Digit>();
212 {
"alio2-cr1-flp182", 0, 570, 0, 0},
213 {
"alio2-cr1-flp182", 1, 570, 1, 0},
214 {
"alio2-cr1-flp182", 2, 570, 2, 0},
215 {
"alio2-cr1-flp182", 3, 570, 3, 0},
216 {
"alio2-cr1-flp186", 64, 542, 4, 0},
217 {
"alio2-cr1-flp186", 65, 542, 5, 0},
218 {
"alio2-cr1-flp186", 66, 542, 6, 0},
219 {
"alio2-cr1-flp186", 67, 542, 7, 0},
220 {
"alio2-cr1-flp182", 4, 570, 4, 1},
221 {
"alio2-cr1-flp182", 5, 570, 5, 1},
222 {
"alio2-cr1-flp182", 6, 570, 6, 1},
223 {
"alio2-cr1-flp182", 7, 570, 7, 1},
224 {
"alio2-cr1-flp186", 68, 542, 8, 1},
225 {
"alio2-cr1-flp186", 69, 542, 9, 1},
226 {
"alio2-cr1-flp186", 70, 542, 10, 1},
227 {
"alio2-cr1-flp186", 71, 542, 11, 1},
228 {
"alio2-cr1-flp183", 8, 548, 0, 0},
229 {
"alio2-cr1-flp183", 9, 548, 1, 0},
230 {
"alio2-cr1-flp183", 10, 548, 2, 0},
231 {
"alio2-cr1-flp183", 11, 548, 3, 0},
232 {
"alio2-cr1-flp185", 72, 541, 4, 0},
233 {
"alio2-cr1-flp185", 73, 541, 5, 0},
234 {
"alio2-cr1-flp185", 74, 541, 6, 0},
235 {
"alio2-cr1-flp185", 75, 541, 7, 0},
236 {
"alio2-cr1-flp183", 12, 548, 4, 1},
237 {
"alio2-cr1-flp183", 13, 548, 5, 1},
238 {
"alio2-cr1-flp183", 14, 548, 6, 1},
239 {
"alio2-cr1-flp183", 15, 548, 7, 1},
240 {
"alio2-cr1-flp185", 76, 541, 8, 1},
241 {
"alio2-cr1-flp185", 77, 541, 9, 1},
242 {
"alio2-cr1-flp185", 78, 541, 10, 1},
243 {
"alio2-cr1-flp185", 79, 541, 11, 1},
244 {
"alio2-cr1-flp184", 16, 569, 0, 0},
245 {
"alio2-cr1-flp184", 17, 569, 1, 0},
246 {
"alio2-cr1-flp184", 18, 569, 2, 0},
247 {
"alio2-cr1-flp184", 19, 569, 3, 0},
248 {
"alio2-cr1-flp184", 80, 543, 4, 0},
249 {
"alio2-cr1-flp184", 81, 543, 5, 0},
250 {
"alio2-cr1-flp184", 82, 543, 6, 0},
251 {
"alio2-cr1-flp184", 83, 543, 7, 0},
252 {
"alio2-cr1-flp184", 20, 569, 4, 1},
253 {
"alio2-cr1-flp184", 21, 569, 5, 1},
254 {
"alio2-cr1-flp184", 22, 569, 6, 1},
255 {
"alio2-cr1-flp184", 23, 569, 7, 1},
256 {
"alio2-cr1-flp184", 84, 543, 8, 1},
257 {
"alio2-cr1-flp184", 85, 543, 9, 1},
258 {
"alio2-cr1-flp184", 86, 543, 10, 1},
259 {
"alio2-cr1-flp184", 87, 543, 11, 1},
260 {
"alio2-cr1-flp185", 24, 552, 0, 0},
261 {
"alio2-cr1-flp185", 25, 552, 1, 0},
262 {
"alio2-cr1-flp185", 26, 552, 2, 0},
263 {
"alio2-cr1-flp185", 27, 552, 3, 0},
264 {
"alio2-cr1-flp183", 88, 554, 4, 0},
265 {
"alio2-cr1-flp183", 89, 554, 5, 0},
266 {
"alio2-cr1-flp183", 90, 554, 6, 0},
267 {
"alio2-cr1-flp183", 91, 554, 7, 0},
268 {
"alio2-cr1-flp185", 28, 552, 4, 1},
269 {
"alio2-cr1-flp185", 29, 552, 5, 1},
270 {
"alio2-cr1-flp185", 30, 552, 6, 1},
271 {
"alio2-cr1-flp185", 31, 552, 7, 1},
272 {
"alio2-cr1-flp183", 92, 554, 8, 1},
273 {
"alio2-cr1-flp183", 93, 554, 9, 1},
274 {
"alio2-cr1-flp183", 94, 554, 10, 1},
275 {
"alio2-cr1-flp183", 95, 554, 11, 1},
276 {
"alio2-cr1-flp186", 32, 547, 0, 0},
277 {
"alio2-cr1-flp186", 33, 547, 1, 0},
278 {
"alio2-cr1-flp186", 34, 547, 2, 0},
279 {
"alio2-cr1-flp186", 35, 547, 3, 0},
280 {
"alio2-cr1-flp182", 96, 567, 4, 0},
281 {
"alio2-cr1-flp182", 97, 567, 5, 0},
282 {
"alio2-cr1-flp182", 98, 567, 6, 0},
283 {
"alio2-cr1-flp182", 99, 567, 7, 0},
284 {
"alio2-cr1-flp186", 36, 547, 4, 1},
285 {
"alio2-cr1-flp186", 37, 547, 5, 1},
286 {
"alio2-cr1-flp186", 38, 547, 6, 1},
287 {
"alio2-cr1-flp186", 39, 547, 7, 1},
288 {
"alio2-cr1-flp182", 100, 567, 8, 1},
289 {
"alio2-cr1-flp182", 101, 567, 9, 1},
290 {
"alio2-cr1-flp182", 102, 567, 10, 1},
291 {
"alio2-cr1-flp182", 103, 567, 11, 1}};
297 std::string outFileLink;
300 for (
int ruID = 0; ruID < mftMapping.
getNRUs(); ruID++) {
307 uint16_t
layer, ruOnLayer, linkId, zone = FEEId & 0x3;
314 uint32_t lanes = mp.getCablesOnRUType(mp.getRUType(zone,
layer));
323 if (fileFor !=
"all") {
324 outFileLink += fmt::format(
"_{}",
mftHWMap[ruID].flp);
325 if (fileFor !=
"flp") {
326 outFileLink += fmt::format(
"_cru{}_{}",
mftHWMap[ruID].cruHWID, link->endPointID);
327 if (fileFor !=
"cruendpoint") {
328 outFileLink += fmt::format(
"_lnk{}_feeid{}", link->idInCRU, link->feeID);
329 if (fileFor !=
"link") {
330 throw std::runtime_error(
"invalid option provided for file grouping");
335 outFileLink +=
".raw";
336 m2r.
getWriter().
registerLink(link->feeID, link->cruID, link->idInCRU, link->endPointID, outFileLink);
339 <<
" -> " << outFileLink;
void digi2raw(const std::string &inpName, const std::string &outDir, int verbosity, const std::string &fileForLink, uint32_t rdhV=4, bool noEmptyHBF=false, bool zsIR=true, bool zsClass=true, bool enablePadding=true, int cruPageAlignment=16, int superPageSizeInB=1024 *1024)
Header of the General Run Parameters object.
constexpr int DefRDHVersion
void setupLinks(o2::itsmft::MC2RawEncoder< MAP > &m2r, std::string_view outDir, std::string_view outPrefix, std::string_view fileFor)
const MFTRUMapping mftHWMap[o2::itsmft::ChipMappingMFT::getNRUs()]
Definition of the ITS/MFT Alpide pixel MC->raw converter.
Definition of the Names Generator class.
static std::string getGRPFileName(const std::string_view prefix=STANDARDSIMPREFIX)
static constexpr std::string_view DIGITIZATIONCONFIGFILE
static constexpr std::string_view MCTTREENAME
static const HBFUtils & Instance()
static void updateFromFile(std::string const &, std::string const ¶msList="", bool unchangedOnly=false)
static void updateFromString(std::string const &)
static constexpr o2::detectors::DetID::ID getDetID()
static constexpr std::string_view getName()
void expandFEEId(uint16_t feeID, uint16_t &layer, uint16_t &ruOnLayer, uint16_t &link) const
decompose FEEid to face, disk, half
uint16_t RUSW2FEEId(uint16_t sw, uint16_t linkID=0) const
compose FEEid for given stave (ru) relative to layer and link, see documentation in the constructor
static constexpr Int_t getNRUs()
< total number of RUs
GBTLink * getGBTLink(int i)
void setContinuousReadout(bool v)
RUDecodeData & getCreateRUDecode(int ruSW)
o2::raw::RawFileWriter & getWriter()
void setDefaultSinkName(const std::string &nm)
void setMinMaxRUSW(uint8_t ruMin, uint8_t ruMax)
void digits2raw(gsl::span< const Digit > digits, const o2::InteractionRecord &bcData)
RUDecodeData * getRUDecode(int ruSW)
static GRPObject * loadFrom(const std::string &grpFileName="")
void useRDHVersion(int v)
void setAlignmentSize(unsigned char v)
void useRDHDataFormat(unsigned char v)
unsigned char getUsedRDHDataFormat() const
void setSuperPageSize(int nbytes)
void setAlignmentPaddingFiller(unsigned char v)
void setDontFillEmptyHBF(bool v)
LinkData & registerLink(uint16_t fee, uint16_t cru, uint8_t link, uint8_t endpoint, std::string_view outFileName)
void writeConfFile(std::string_view origin="FLP", std::string_view description="RAWDATA", std::string_view cfgname="raw.cfg", bool fullPath=true) const
GLenum GLuint GLint GLint layer
constexpr int GBTPaddedWordLength
constexpr int GBTWordLength
static constexpr int CRUPageAlignment
std::array< int, MaxLinksPerRU > links
static std::string concat_string(Ts const &... ts)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"