Project
Loading...
Searching...
No Matches
digi2raw.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#include <boost/program_options.hpp>
16#include <TTree.h>
17#include <TChain.h>
18#include <TFile.h>
19#include <TStopwatch.h>
20#include "Framework/Logger.h"
21#include <vector>
22#include <string>
23#include <iomanip>
24#include <filesystem>
36
39namespace bpo = boost::program_options;
40
41constexpr int DefRDHVersion = o2::raw::RDHUtils::getVersion<o2::header::RAWDataHeader>();
42
43void setupLinks(o2::itsmft::MC2RawEncoder<MAP>& m2r, std::string_view outDir, std::string_view outPrefix, std::string_view fileFor);
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);
46
47int main(int argc, char** argv)
48{
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;
55
56 try {
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");
67 add_option("hbfutils-config,u", bpo::value<std::string>()->default_value(std::string(o2::base::NameConf::DIGITIZATIONCONFIGFILE)), "config file for HBFUtils (or none)");
68 add_option("configKeyValues", bpo::value<std::string>()->default_value(""), "comma-separated configKeyValues");
69
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);
72
73 if (vm.count("help")) {
74 std::cout << opt_general << std::endl;
75 exit(0);
76 }
77
78 bpo::notify(vm);
79 } catch (bpo::error& e) {
80 std::cerr << "ERROR: " << e.what() << std::endl
81 << std::endl;
82 std::cerr << opt_general << std::endl;
83 exit(1);
84 } catch (std::exception& e) {
85 std::cerr << e.what() << ", application will now exit" << std::endl;
86 exit(2);
87 }
88
89 std::string confDig = vm["hbfutils-config"].as<std::string>();
90 if (!confDig.empty() && confDig != "none") {
92 }
93 o2::conf::ConfigurableParam::updateFromString(vm["configKeyValues"].as<std::string>());
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:";
103
105
106 return 0;
107}
108
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)
110{
111 TStopwatch swTot;
112 swTot.Start();
113 using ROFR = o2::itsmft::ROFRecord;
114 using ROFRVEC = std::vector<o2::itsmft::ROFRecord>;
115 const uint8_t ruSWMin = 0, ruSWMax = 0xff; // seq.ID of 1st and last RU (stave) to convert
116 if (rdhV < 7 && !enablePadding) {
117 enablePadding = true;
118 LOG(info) << "padding is always ON for RDH version " << rdhV;
119 }
120
121 LOG(info) << "HBFUtil settings:";
123
124 // if needed, create output directory
125 if (!std::filesystem::exists(outDir)) {
126 if (!std::filesystem::create_directories(outDir)) {
127 LOG(fatal) << "could not create output directory " << outDir;
128 } else {
129 LOG(info) << "created output directory " << outDir;
130 }
131 }
132
134 std::string digTreeName{o2::base::NameConf::MCTTREENAME.data()};
135 TChain digTree(digTreeName.c_str());
136 digTree.AddFile(inpName.data());
137 digTree.SetBranchStatus("*MCTruth*", 0); // ignore MC info
138
139 std::vector<o2::itsmft::Digit> digiVec, *digiVecP = &digiVec;
140 std::string digBranchName = o2::utils::Str::concat_string(MAP::getName(), "Digit");
141 if (!digTree.GetBranch(digBranchName.c_str())) {
142 LOG(fatal) << "Failed to find the branch " << digBranchName << " in the tree " << digTreeName;
143 }
144 digTree.SetBranchAddress(digBranchName.c_str(), &digiVecP);
145
146 // ROF record entries in the digit tree
147 ROFRVEC rofRecVec, *rofRecVecP = &rofRecVec;
148 std::string rofRecName = o2::utils::Str::concat_string(MAP::getName(), "DigitROF");
149 if (!digTree.GetBranch(rofRecName.c_str())) {
150 LOG(fatal) << "Failed to find the branch " << rofRecName << " in the tree " << digTreeName;
151 }
152 digTree.SetBranchAddress(rofRecName.c_str(), &rofRecVecP);
154 std::string inputGRP = o2::base::NameConf::getGRPFileName();
155 const auto grp = o2::parameters::GRPObject::loadFrom(inputGRP);
156
159 m2r.setContinuousReadout(grp->isDetContinuousReadOut(MAP::getDetID())); // must be set explicitly
161 m2r.setMinMaxRUSW(ruSWMin, ruSWMax);
162 m2r.getWriter().setSuperPageSize(superPageSizeInB);
163 m2r.getWriter().useRDHVersion(rdhV);
164 m2r.getWriter().useRDHDataFormat(enablePadding ? 0 : 2);
165 if (!enablePadding) { // CRU page alignment padding is used only if no GBT word padding is used
168 }
169 m2r.getWriter().setDontFillEmptyHBF(noEmptyHBF);
170
172 setupLinks(m2r, outDir, MAP::getName(), fileFor);
173 //-------------------------------------------------------------------------------<<<<
174 long nEntProc = 0;
175 for (int i = 0; i < digTree.GetEntries(); i++) {
176 digTree.GetEntry(i);
177 for (const auto& rofRec : rofRecVec) {
178 int nDigROF = rofRec.getNEntries();
179 if (verbosity) {
180 LOG(info) << "Processing ROF:" << rofRec.getROFrame() << " with " << nDigROF << " entries";
181 rofRec.print();
182 }
183 if (!nDigROF && noEmptyROF) {
184 if (verbosity) {
185 LOG(info) << "Frame is empty";
186 }
187 continue;
188 }
189 nEntProc++;
190 auto dgs = nDigROF ? gsl::span<const o2::itsmft::Digit>(&digiVec[rofRec.getFirstEntry()], nDigROF) : gsl::span<const o2::itsmft::Digit>();
191 m2r.digits2raw(dgs, rofRec.getBCData());
192 }
193 } // loop over multiple ROFvectors (in case of chaining)
194
195 m2r.getWriter().writeConfFile(MAP::getName(), "RAWDATA", o2::utils::Str::concat_string(outDir, '/', MAP::getName(), "raw.cfg"));
196 m2r.finalize(); // finish TF and flush data
197 //
198 swTot.Stop();
199 swTot.Print();
200}
201
203 std::string flp{};
204 int feeID;
205 int cruHWID = 0;
206 int idInCRU = 0;
207 int endpoint = 0;
208};
209
210// FLP_Name, FEEId, CRU_HW, idInCRU, endpoint
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}};
292
293void setupLinks(o2::itsmft::MC2RawEncoder<MAP>& m2r, std::string_view outDir, std::string_view outPrefix, std::string_view fileFor)
294{
295 // see the same file from ITS
296 const auto& mp = m2r.getMapping();
297 std::string outFileLink;
299
300 for (int ruID = 0; ruID < mftMapping.getNRUs(); ruID++) {
301
302 if (ruID < m2r.getRUSWMin() || ruID > m2r.getRUSWMax()) { // ignored RUs ?
303 continue;
304 }
305
306 auto FEEId = mftMapping.RUSW2FEEId(ruID);
307 uint16_t layer, ruOnLayer, linkId, zone = FEEId & 0x3;
308 mftMapping.expandFEEId(FEEId, layer, ruOnLayer, linkId);
309
310 m2r.getCreateRUDecode(ruID); // create RU container
311
312 auto& ru = *m2r.getRUDecode(ruID);
313 ru.links[0] = m2r.addGBTLink();
314 uint32_t lanes = mp.getCablesOnRUType(mp.getRUType(zone, layer)); // lanes pattern of this RU
315 auto link = m2r.getGBTLink(ru.links[0]);
316 link->lanes = lanes;
317 link->feeID = mftHWMap[ruID].feeID;
318 link->idInCRU = mftHWMap[ruID].idInCRU; // linkID
319 link->cruID = mftHWMap[ruID].cruHWID; // CRU Serial Number
320 link->endPointID = mftHWMap[ruID].endpoint; // endpoint = face
322 outFileLink = o2::utils::Str::concat_string(outDir, "/", outPrefix);
323 if (fileFor != "all") { // single file for all links
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");
331 }
332 }
333 }
334 }
335 outFileLink += ".raw";
336 m2r.getWriter().registerLink(link->feeID, link->cruID, link->idInCRU, link->endPointID, outFileLink);
337 if (m2r.getVerbosity()) {
338 LOG(info) << "RU" << ruID << '(' << mftHWMap[ruID].cruHWID << " on idInCRU " << mftHWMap[ruID].idInCRU << ") " << link->describe()
339 << " -> " << outFileLink;
340 }
341 }
342}
#define verbosity
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)
Definition digi2raw.cxx:99
Definition of the ITSMFT digit.
int32_t i
Header of the General Run Parameters object.
constexpr int DefRDHVersion
Definition digi2raw.cxx:41
void setupLinks(o2::itsmft::MC2RawEncoder< MAP > &m2r, std::string_view outDir, std::string_view outPrefix, std::string_view fileFor)
Definition digi2raw.cxx:407
const MFTRUMapping mftHWMap[o2::itsmft::ChipMappingMFT::getNRUs()]
Definition digi2raw.cxx:211
Definition of the ITSMFT ROFrame (trigger) record.
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)
Definition NameConf.cxx:58
static constexpr std::string_view DIGITIZATIONCONFIGFILE
Definition NameConf.h:89
static constexpr std::string_view MCTTREENAME
Definition NameConf.h:86
static void updateFromFile(std::string const &, std::string const &paramsList="", 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 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
Definition glcorearb.h:1310
constexpr int GBTPaddedWordLength
Definition GBTWord.h:56
constexpr int GBTWordLength
Definition GBTWord.h:55
std::string flp
Definition digi2raw.cxx:203
std::array< int, MaxLinksPerRU > links
void print() const
Definition HBFUtils.h:134
static std::string concat_string(Ts const &... ts)
#define main
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"