Project
Loading...
Searching...
No Matches
testHBFUtils.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
12#define BOOST_TEST_MODULE Test HBFUtils class
13#define BOOST_TEST_MAIN
14#define BOOST_TEST_DYN_LINK
15#include <algorithm>
16#include <bitset>
17#include <boost/test/unit_test.hpp>
21#include <TRandom.h>
22#include <fairlogger/Logger.h>
23
24// @brief test and demo for HBF sampling for simulated IRs
25// @author ruben.shahoyan@cern.ch
26
27namespace o2
28{
30{
33
34 const bool useContinuous = true;
35
37
38 // default sampler with BC filling like in TPC TDR
40 irSampler.setInteractionRate(12000); // ~1.5 interactions per orbit
41 irSampler.setFirstIR(sampler.getFirstIR());
42 irSampler.init();
43
44 int nIRs = 500;
45 std::vector<o2::InteractionTimeRecord> irs(nIRs);
46 irSampler.generateCollisionTimes(irs);
47
48 LOG(info) << "Emulate RDHs for raw data between IRs " << irs.front() << " and " << irs.back();
49
50 uint8_t packetCounter = 0;
51 std::vector<o2::InteractionRecord> HBIRVec;
52 auto irFrom = sampler.getFirstIR(); // TFs are counted from this IR
53 int nHBF = 0, nHBFEmpty = 0, nTF = 0;
54 int nHBFOpen = 0, nHBFClose = 0;
55 RDH rdh;
56 IR rdhIR;
57 auto flushRDH = [&]() {
58 bool empty = rdh.offsetToNext == sizeof(RDH);
59 std::bitset<32> trig(rdh.triggerType);
60 int hbfID = sampler.getHBF(rdhIR);
61 auto tfhb = sampler.getTFandHBinTF(rdhIR);
62 static bool firstCall = true;
63
64 printf("%s HBF%4d (TF%3d/HB%3d) Sz:%4d| HB Orbit/BC :%4d/%4d Trigger:(0x%08x) %s Packet: %3d Page: %3d Stop: %d\n",
65 rdh.stop ? "Close" : "Open ", hbfID, tfhb.first, tfhb.second, rdh.memorySize, rdhIR.orbit, rdhIR.bc,
66 int(rdh.triggerType), trig.to_string().c_str(), rdh.packetCounter, int(rdh.pageCnt), int(rdh.stop));
67 bool sox = (rdh.triggerType & o2::trigger::SOC || rdh.triggerType & o2::trigger::SOT);
68
69 if (rdh.stop) {
70 nHBFClose++;
71 } else {
72 nHBFOpen++;
73 if (rdh.triggerType & o2::trigger::TF) {
74 nTF++;
75 }
77 nHBF++;
78 }
79 if (empty) {
80 nHBFEmpty++;
81 }
82 BOOST_CHECK(firstCall == sox);
83 firstCall = false;
84 }
85 };
86
87 bool flagSOX = true; // the 1st RDH must provide readout mode: SOT or SOC
88
89 for (int i = 0; i < nIRs; i++) {
90 int nHBF = sampler.fillHBIRvector(HBIRVec, irFrom, irs[i]);
91 irFrom = irs[i] + 1;
92
93 // nHBF-1 HBframes don't have data, we need to create empty HBFs for them
94 if (nHBF) {
95 if (rdh.stop) { // do we need to close previous HBF?
96 flushRDH();
97 }
98 for (int j = 0; j < nHBF - 1; j++) {
99 rdhIR = HBIRVec[j];
100 rdh = sampler.createRDH<RDH>(rdhIR);
101 // dress rdh with cruID/FEE/Link ID ...
102 rdh.packetCounter = packetCounter++;
103 rdh.memorySize = sizeof(rdh);
104 rdh.offsetToNext = sizeof(rdh);
105
106 if (flagSOX) {
107 rdh.triggerType |= useContinuous ? o2::trigger::SOC : o2::trigger::SOT;
108 flagSOX = false;
109 }
110 flushRDH(); // open empty HBH
111 rdh.packetCounter = packetCounter++;
112 rdh.stop = 0x1;
113 rdh.pageCnt++;
114 flushRDH(); // close empty HBF
115 }
116
117 rdhIR = HBIRVec.back();
118 rdh = sampler.createRDH<RDH>(rdhIR);
119 if (flagSOX) {
120 rdh.triggerType |= useContinuous ? o2::trigger::SOC : o2::trigger::SOT;
121 flagSOX = false;
122 }
123 rdh.packetCounter = packetCounter++;
124 rdh.memorySize = sizeof(rdh) + 16 + gRandom->Integer(8192 - sizeof(rdh) - 16); // random payload
125 rdh.offsetToNext = rdh.memorySize;
126 flushRDH(); // open non-empty HBH
127 rdh.packetCounter = packetCounter++;
128 rdh.stop = 0x1; // flag that it should be closed
129 rdh.pageCnt++;
130 }
131 // flush payload
132 printf("Flush payload for Orbit/BC %4d/%d\n", irs[i].orbit, irs[i].bc);
133 }
134 // close last packet
135 if (rdh.stop) { // do we need to close previous HBF?
136 flushRDH();
137 } else {
138 BOOST_CHECK(false); // lost closing RDH?
139 }
140
141 // the TF must be completed, generate HBF till the end of the current TF
142 int tf = sampler.getTF(irs.back());
143 auto lastHBIR = sampler.getIRTF(tf + 1) - 1; // last IR of the current TF
144 sampler.fillHBIRvector(HBIRVec, irs.back(), lastHBIR);
145 for (const auto& ir : HBIRVec) {
146 rdh = sampler.createRDH<RDH>(rdhIR);
147 // dress rdh with cruID/FEE/Link ID ...
148 rdh.packetCounter = packetCounter++;
149 rdh.memorySize = sizeof(rdh);
150 rdh.offsetToNext = sizeof(rdh);
151
152 flushRDH(); // open empty HBH
153 rdh.stop = 0x1;
154 rdh.pageCnt++;
155 flushRDH(); // close empty HBF
156 }
157
158 printf("\nN_TF=%d, N_HBF=%d (%d empty), Opened %d / Closed %d\n", nTF, nHBF, nHBFEmpty, nHBFOpen, nHBFClose);
159 BOOST_CHECK(nHBF > nHBFEmpty);
160 BOOST_CHECK(nTF > 0);
161 BOOST_CHECK(nHBFOpen == nHBFClose);
162 BOOST_CHECK(nHBF == nTF * sampler.getNOrbitsPerTF()); // make sure all TFs are complete
163}
164} // namespace o2
uint64_t orbit
Definition RawEventData.h:6
uint64_t bc
Definition RawEventData.h:5
int32_t i
Definition of the RAW Data Header.
uint32_t j
Definition RawData.h:0
void generateCollisionTimes(std::vector< o2::InteractionTimeRecord > &dest)
void setFirstIR(const o2::InteractionRecord &ir)
void setInteractionRate(float rateHz)
GLuint sampler
Definition glcorearb.h:1630
constexpr uint32_t SOT
Definition Triggers.h:33
constexpr uint32_t TF
Definition Triggers.h:37
constexpr uint32_t ORBIT
Definition Triggers.h:26
constexpr uint32_t SOC
Definition Triggers.h:35
constexpr uint32_t HB
Definition Triggers.h:27
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
BOOST_AUTO_TEST_CASE(FlatHisto)
void empty(int)
std::unique_ptr< GPUReconstructionTimeframe > tf
uint32_t orbit
LHC orbit.
uint16_t bc
bunch crossing ID of interaction
uint32_t packetCounter
bit 96 to 103: link id
uint64_t stop
bit 32 to 47: pages counter
uint32_t memorySize
bit 64 to 79: offset to next packet in memory
uint64_t pageCnt
bit 0 to 31: trigger type
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
BOOST_CHECK(tree)
o2::InteractionRecord ir(0, 0)