Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions macro/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ install(FILES CheckClusters_mft.C
run_collect_calib_tof.C
run_digi.C
run_digi2raw_its.C
run_digi2raw_mft.C
run_digi_mft.C
run_digi_tof.C
run_match_TPCITS.C
run_match_tof.C
run_primary_vertexer_ITS.C
run_rawdecoding_its.C
run_rawdecoding_mft.C
run_sim.C
run_sim_emcal.C
run_sim_mft.C
Expand Down Expand Up @@ -227,6 +229,14 @@ o2_add_test_root_macro(run_digi2raw_its.C
O2::ITSMFTReconstruction
LABELS its)

# FIXME: move to subsystem dir
o2_add_test_root_macro(run_digi2raw_mft.C
PUBLIC_LINK_LIBRARIES O2::ITSMFTReconstruction
O2::DataFormatsITSMFT
O2::ITSMFTBase
O2::ITSMFTReconstruction
LABELS mft)

# FIXME: move to subsystem dir
o2_add_test_root_macro(run_digi_mft.C
PUBLIC_LINK_LIBRARIES O2::DataFormatsParameters
Expand Down Expand Up @@ -270,6 +280,13 @@ o2_add_test_root_macro(run_rawdecoding_its.C
O2::CommonDataFormat
LABELS its)

# FIXME: move to subsystem dir
o2_add_test_root_macro(run_rawdecoding_mft.C
PUBLIC_LINK_LIBRARIES O2::ITSMFTReconstruction
O2::DataFormatsITSMFT
O2::CommonDataFormat
LABELS mft)

# FIXME: move to subsystem dir + check compilation o2_add_test_root_macro(
# run_rec_ca.C PUBLIC_LINK_LIBRARIES O2::DetectorsCommonDataFormats
# O2::DataFormatsITSMFT O2::DataFormatsParameters O2::DetectorsBase O2::Field
Expand Down
148 changes: 148 additions & 0 deletions macro/run_digi2raw_mft.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#if !defined(__CLING__) || defined(__ROOTCLING__)
#include <TTree.h>
#include <TChain.h>
#include <TFile.h>
#include <TStopwatch.h>
#include <FairLogger.h>
#include <vector>
#include <string>
#include <iomanip>
#include "ITSMFTReconstruction/ChipMappingMFT.h"
#include "ITSMFTReconstruction/GBTWord.h"
#include "ITSMFTReconstruction/PayLoadCont.h"
#include "DataFormatsITSMFT/ROFRecord.h"
#include "ITSMFTBase/Digit.h"
#endif

#include "ITSMFTReconstruction/RawPixelReader.h"

void run_digi2raw_mft(std::string outName = "rawmft.bin", // name of the output binary file
std::string inpName = "mftdigits.root", // name of the input MFT digits
std::string digTreeName = "o2sim", // name of the digits tree
std::string digBranchName = "MFTDigit", // name of the digits branch
std::string rofRecName = "MFTDigitROF", // name of the ROF records tree and its branch
uint8_t ruSWMin = 0, uint8_t ruSWMax = 0xff, // seq.ID of 1st and last RU (stave) to convert
uint8_t superPageSize = o2::itsmft::NCRUPagesPerSuperpage / 2 // CRU superpage size, max = 256
)
{
TStopwatch swTot;
swTot.Start();
using ROFR = o2::itsmft::ROFRecord;
using ROFRVEC = std::vector<o2::itsmft::ROFRecord>;

///-------> input
TChain digTree(digTreeName.c_str());
TChain rofTree(rofRecName.c_str());

digTree.AddFile(inpName.c_str());
rofTree.AddFile(inpName.c_str());

std::vector<o2::itsmft::Digit> digiVec, *digiVecP = &digiVec;
if (!digTree.GetBranch(digBranchName.c_str())) {
LOG(FATAL) << "Failed to find the branch " << digBranchName << " in the tree " << digTreeName;
}
digTree.SetBranchAddress(digBranchName.c_str(), &digiVecP);

// ROF record entries in the digit tree
ROFRVEC rofRecVec, *rofRecVecP = &rofRecVec;
if (!rofTree.GetBranch(rofRecName.c_str())) {
LOG(FATAL) << "Failed to find the branch " << rofRecName << " in the tree " << rofRecName;
}
rofTree.SetBranchAddress(rofRecName.c_str(), &rofRecVecP);
///-------< input

///-------> output
if (outName.empty()) {
outName = "raw" + digBranchName + ".raw";
LOG(INFO) << "Output file name is not provided, set to " << outName << FairLogger::endl;
}
auto outFl = fopen(outName.c_str(), "wb");
if (!outFl) {
LOG(FATAL) << "failed to open raw data output file " << outName;
;
} else {
LOG(INFO) << "opened raw data output file " << outName;
}
o2::itsmft::PayLoadCont outBuffer;
///-------< output

o2::itsmft::RawPixelReader<o2::itsmft::ChipMappingMFT> rawReader;
rawReader.setPadding128(true);
rawReader.setVerbosity(0);

//------------------------------------------------------------------------------->>>>
// just as an example, we require here that the IB staves are read via 3 links,
// while OB staves use only 1 link.
// Note, that if the RU container is not defined, it will be created automatically
// during encoding.
// If the links of the container are not defined, a single link readout will be assigned
const auto& mp = rawReader.getMapping();
LOG(INFO) << "Number of RUs = " << mp.getNRUs();
for (int ir = 0; ir < mp.getNRUs(); ir++) {
auto& ru = rawReader.getCreateRUDecode(ir); // create RU container
uint32_t lanes = mp.getCablesOnRUType(ru.ruInfo->ruType); // lanes patter of this RU
ru.links[0] = std::make_unique<o2::itsmft::GBTLink>();
ru.links[0]->lanes = lanes; // single link reads all lanes
LOG(INFO) << "RU " << std::setw(3) << ir << " type " << int(ru.ruInfo->ruType) << " on lr" << int(ru.ruInfo->layer)
<< " : FEEId 0x" << std::hex << std::setfill('0') << std::setw(6) << mp.RUSW2FEEId(ir, int(ru.ruInfo->layer))
<< " reads lanes " << std::bitset<25>(ru.links[0]->lanes);
}

//-------------------------------------------------------------------------------<<<<
int lastTreeID = -1;
long offs = 0, nEntProc = 0;
for (int i = 0; i < rofTree.GetEntries(); i++) {
rofTree.GetEntry(i);
if (rofTree.GetTreeNumber() > lastTreeID) { // this part is needed for chained input
if (lastTreeID > 0) { // new chunk, increase the offset
offs += digTree.GetTree()->GetEntries();
}
lastTreeID = rofTree.GetTreeNumber();
}

for (const auto& rofRec : rofRecVec) {
auto rofEntry = rofRec.getROFEntry();
int nDigROF = rofRec.getNROFEntries();
LOG(INFO) << "Processing ROF:" << rofRec.getROFrame() << " with " << nDigROF << " entries";
if (!nDigROF) {
LOG(INFO) << "Frame is empty"; // ??
continue;
}
if (rofEntry.getEvent() != digTree.GetReadEntry() + offs || !nEntProc) {
digTree.GetEntry(rofEntry.getEvent() + offs); // read tree entry containing needed ROF data
nEntProc++;
}
int digIndex = rofEntry.getIndex(); // needed ROF digits start from this one
int maxDigIndex = digIndex + nDigROF;
LOG(INFO) << "BV===== digIndex " << digIndex << " maxDigIndex " << maxDigIndex << "\n";

int nPagesCached = rawReader.digits2raw(digiVec, rofEntry.getIndex(), nDigROF, rofRec.getBCData(),
ruSWMin, ruSWMax);

if (nPagesCached >= superPageSize) {
int nPagesFlushed = rawReader.flushSuperPages(superPageSize, outBuffer);
fwrite(outBuffer.data(), 1, outBuffer.getSize(), outFl); //write to file
outBuffer.clear();
LOG(INFO) << "Flushed " << nPagesFlushed << " CRU pages";
}
//printf("BV===== stop after the first ROF!\n");
//break;
}
} // loop over multiple ROFvectors (in case of chaining)

// flush the rest
int flushed = 0;
do {
flushed = rawReader.flushSuperPages(o2::itsmft::NCRUPagesPerSuperpage, outBuffer);
fwrite(outBuffer.data(), 1, outBuffer.getSize(), outFl); //write to file
if (flushed) {
LOG(INFO) << "Flushed final " << flushed << " CRU pages";
}
outBuffer.clear();
} while (flushed);

fclose(outFl);
//
swTot.Stop();
swTot.Print();
}
124 changes: 124 additions & 0 deletions macro/run_rawdecoding_mft.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#if !defined(__CLING__) || defined(__ROOTCLING__)

#include <TTree.h>
#include <TFile.h>
#include <TStopwatch.h>
#include <FairLogger.h>
#include <vector>
#include <string>

#include "ITSMFTReconstruction/ChipMappingMFT.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 MFT raw data decoding
// Data can be prepared from the MC digits using run_digi2raw_mft.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_mft(std::string inpName = "06282019_1854_output.bin", // input binary data file name
std::string outDigName = "raw2mftdigits.root", // name for optinal digits tree
bool outDigPerROF = false, // in case digits are requested, create separate tree entry for each ROF
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<o2::itsmft::ChipMappingMFT> 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 irHB, irTrig;
std::vector<o2::itsmft::Digit> digits, *digitsPtr = &digits;
std::vector<o2::itsmft::ROFRecord> rofRecVec, *rofRecVecPtr = &rofRecVec;
std::size_t rofEntry = 0, nrofdig = 0;
std::unique_ptr<TFile> outFileDig;
std::unique_ptr<TTree> outTreeDig; // output tree with digits
std::unique_ptr<TTree> outTreeROF; // output tree with ROF records

if (!outDigName.empty()) { // output to digit is requested
outFileDig = std::make_unique<TFile>(outDigName.c_str(), "recreate");
outTreeDig = std::make_unique<TTree>("o2sim", "Digits tree");
outTreeDig->Branch("MFTDigit", &digitsPtr);
outTreeROF = std::make_unique<TTree>("MFTDigitROF", "ROF records tree");
outTreeROF->Branch("MFTDigitROF", &rofRecVecPtr);
}

while (rawReader.getNextChipData(chipData)) {
if (verbose >= 10) {
chipData.print();
}

if (outTreeDig) { // >> store digits
if (irHB != rawReader.getInteractionRecordHB() || irTrig != rawReader.getInteractionRecord()) {
if (!irTrig.isDummy()) {
o2::dataformats::EvIndex<int, int> evId(outTreeDig->GetEntries(), rofEntry);
rofRecVec.emplace_back(irHB, roFrame, evId, nrofdig); // registed finished ROF
if (outDigPerROF) {
outTreeDig->Fill();
digits.clear();
}
roFrame++;
}
irHB = rawReader.getInteractionRecordHB();
irTrig = rawReader.getInteractionRecord();
rofEntry = digits.size();
nrofdig = 0;
}
const auto& pixdata = chipData.getData();
for (const auto& pix : pixdata) {
digits.emplace_back(chipData.getChipID(), roFrame, pix.getRowDirect(), pix.getCol());
nrofdig++;
}

printf("ROF %7d ch: %5d IR: ", roFrame, chipData.getChipID());
irHB.print();

} // << store digits
//
}

if (outTreeDig) {
// register last ROF
o2::dataformats::EvIndex<int, int> evId(outTreeDig->GetEntries(), rofEntry);
rofRecVec.emplace_back(irHB, roFrame, evId, nrofdig); // registed finished ROF

// fill last (and the only one?) entry
outTreeDig->Fill();
outTreeROF->Fill();

// and store trees
outTreeDig->Write();
outTreeROF->Write();
}

sw.Stop();

const auto& MAP = rawReader.getMapping();
for (int ir = 0; ir < MAP.getNRUs(); ir++) {
for (int il = 0; il < o2::itsmft::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();
}