// Copyright 2019-2026 CERN and copyright holders of ALICE O2. // See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. // All rights not expressly granted are reserved. // // This software is distributed under the terms of the GNU General Public // License v3 (GPL Version 3), copied verbatim in the file "COPYING". // // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. #if !defined(__CLING__) || defined(__ROOTCLING__) #include #include #include #include #include #include #include "ITSMFTReconstruction/ChipMappingITS.h" #include "ITSMFTReconstruction/RUDecodeData.h" #include "ITSMFTReconstruction/GBTWord.h" #include "ITSMFTReconstruction/PayLoadCont.h" #include "ITSMFTReconstruction/PixelData.h" #include "DataFormatsITSMFT/ROFRecord.h" #include "ITSMFTReconstruction/RawPixelReader.h" #include "CommonDataFormat/InteractionRecord.h" #endif // example of ITS raw data decoding // Data can be prepared from the MC digits using run_digi2raw_its.C // The padding parameter should be set to "true" for CRU data and to "false" for // the data obtained by the removing the 128 bit padding from GBT words void run_rawdecoding_its(std::string inpName = "rawits.bin", // input binary data file name std::string outDigName = "", // name for optinal digits tree bool padding = true, // payload in raw data comes in 128 bit CRU words bool page8kb = true, // full 8KB CRU pages are provided (no skimming applied) int nTriggersToCache = 1025, // number of triggers per link to cache (> N 8KB CRU pages per superpage) int verbose = 0) { o2::itsmft::RawPixelReader rawReader; rawReader.openInput(inpName); rawReader.setPadding128(padding); // payload GBT words are padded to 16B rawReader.imposeMaxPage(page8kb); // pages are 8kB in size (no skimming) rawReader.setMinTriggersToCache(nTriggersToCache); rawReader.setVerbosity(verbose); o2::itsmft::ChipPixelData chipData; TStopwatch sw; sw.Start(); uint32_t roFrame = 0; o2::InteractionRecord irTrig; std::vector digits, *digitsPtr = &digits; std::vector rofRecVec, *rofRecVecPtr = &rofRecVec; std::size_t rofEntry = 0, nrofdig = 0; std::unique_ptr outFileDig; std::unique_ptr outTreeDig; // output tree with digits if (!outDigName.empty()) { // output to digit is requested outFileDig = std::make_unique(outDigName.c_str(), "recreate"); outTreeDig = std::make_unique("o2sim", "Digits tree"); outTreeDig->Branch("ITSDigit", &digitsPtr); outTreeDig->Branch("ITSDigitROF", &rofRecVecPtr); } while (rawReader.getNextChipData(chipData)) { if (verbose >= 10) { chipData.print(); } if (outTreeDig) { // >> store digits if (irTrig != rawReader.getInteractionRecord()) { if (!irTrig.isDummy()) { rofRecVec.emplace_back(irTrig, roFrame, rofEntry, nrofdig); // registed finished ROF roFrame++; } irTrig = rawReader.getInteractionRecord(); rofEntry = digits.size(); nrofdig = 0; } const auto& pixdata = chipData.getData(); for (const auto& pix : pixdata) { digits.emplace_back(chipData.getChipID(), pix.getRowDirect(), pix.getCol()); nrofdig++; } printf("ROF %7d ch: %5d IR: ", roFrame, chipData.getChipID()); } // << store digits // } if (outTreeDig) { // register last ROF rofRecVec.emplace_back(irTrig, roFrame, rofEntry, nrofdig); // registed finished ROF // fill last (and the only one?) entry outTreeDig->Fill(); // and store tree outTreeDig->Write(); } sw.Stop(); const auto& MAP = rawReader.getMapping(); for (int ir = 0; ir < MAP.getNRUs(); ir++) { for (int il = 0; il < o2::itsmft::RUDecodeData::MaxLinksPerRU; il++) { const auto ruStat = rawReader.getRUDecodingStatSW(ir, il); if (ruStat && ruStat->nPackets) { printf("\nStatistics for RU%3d (HWID:0x%4x) GBTLink%d\n", ir, MAP.RUSW2FEEId(ir, il), il); ruStat->print(); } } } rawReader.getDecodingStat().print(); sw.Print(); }