21#include <fmt/format.h>
23#include <fairmq/Tools.h>
24#include <fairlogger/Logger.h>
40static constexpr int sBcInOneADCclock = 4;
54 if (!mInputDigits.empty()) {
55 mOrderedDigits.resize(mInputDigits.size());
57 std::iota(mOrderedDigits.begin(), mOrderedDigits.end(), 0);
58 mOutputROFs.emplace_back(
digitTime2IR(mInputDigits[0]), 0, mInputDigits.size());
65 bool ok =
id < mInputDigits.size();
67 LOG(error) <<
"Invalid digit ID " <<
id <<
" (digits vector size is " << mInputDigits.size() <<
")\n";
74 return mInputDigits[
id];
78 auto startNewROF = [&](
const RawDigit& digit,
int id) {
89 for (
size_t id = 0;
id < mOrderedDigits.size();
id++) {
95 if (!checkDigitId(inputId)) {
99 auto& rofSeed = getDigit(inputId);
100 startNewROF(rofSeed,
id);
103 std::cout << fmt::format(
"starting new ROF from {} -> {}\n",
id, inputId);
106 for (
size_t id2 =
id + 1; id2 < mOrderedDigits.size(); id2++) {
111 if (!checkDigitId(inputId2)) {
114 auto& digit = getDigit(inputId2);
117 std::cout << fmt::format(
" checking digit {} -> {}\n", id2, inputId2);
120 auto tdiff = digit.
getTime() - rofSeed.getTime();
121 if (std::abs(tdiff) < sBcInOneADCclock) {
124 std::cout << fmt::format(
" digit {} -> {} added to current ROF\n", id2, inputId2);
142void ROFFinder::sortDigits()
144 mOrderedDigits.reserve(mInputDigits.size());
145 for (
size_t i = 0;
i < mInputDigits.size();
i++) {
146 auto& digit = mInputDigits[
i];
147 if (!digit.timeValid()) {
149 LOG(error) <<
"Digit with invalid time, DS " << digit.info.solar <<
"," << digit.info.ds <<
"," << digit.info.chip
150 <<
" pad " << digit.getDetID() <<
"," << digit.getPadID() <<
" "
151 << digit.getOrbit() <<
" (" << mFirstTForbit <<
") time "
152 << digit.getTime() <<
" SAMPA time " << digit.getBXTime();
157 auto orbit = digit.getOrbit();
158 if (
orbit < mFirstTForbit) {
163 std::cout <<
"Inserting digit: "
164 <<
"pad " << digit.getDetID() <<
"," << digit.getPadID() <<
" "
165 << digit.getOrbit() <<
" " << digit.getTime() <<
" " << digit.getBXTime() << std::endl;
168 mOrderedDigits.emplace_back(
i);
172 const RawDigit& d1 = mInputDigits[id1];
173 const RawDigit& d2 = mInputDigits[id2];
176 std::sort(mOrderedDigits.begin(), mOrderedDigits.end(), rawDigitIdComp);
184 auto firstOrbit = mFirstTForbit;
198void ROFFinder::storeROF()
201 mOutputROFs.emplace_back(mIR, mFirstIdx, mEntries, sBcInOneADCclock);
214 bufSize = mOrderedDigits.size() * sizeOfDigit;
222 for (
auto&
id : mOrderedDigits) {
223 const auto& d = mInputDigits[
id];
224 memcpy(p, &(d.digit), sizeOfDigit);
228 return reinterpret_cast<char*
>(
buf);
240 bufSize = mOutputROFs.size() * sizeOfROFRecord;
248 for (
size_t i = 0;
i < mOutputROFs.size();
i++) {
249 auto& rof = mOutputROFs[
i];
250 memcpy(p, &(rof), sizeOfROFRecord);
254 return reinterpret_cast<char*
>(
buf);
264 for (
size_t i = 1;
i < mOutputROFs.size();
i++) {
265 const auto& rof = mOutputROFs[
i];
266 const auto& rofPrev = mOutputROFs[
i - 1];
267 int64_t delta = rof.getBCData().differenceInBC(rofPrev.getBCData());
268 if (rof.getBCData() < rofPrev.getBCData()) {
269 LOG(error) <<
"Non-monotonic ROFs encountered:";
270 LOG(error) << fmt::format(
"ROF1 {}-{} {},{} ", rofPrev.getFirstIdx(), rofPrev.getLastIdx(),
271 rofPrev.getBCData().orbit, rofPrev.getBCData().bc)
272 << fmt::format(
"ROF2 {}-{} {},{}", rof.getFirstIdx(), rof.getLastIdx(),
273 rof.getBCData().orbit, rof.getBCData().bc);
276 if ((delta % 4) != 0) {
277 LOG(error) <<
"Mis-aligned ROFs encountered:";
278 LOG(error) << fmt::format(
"ROF1 {}-{} {},{} ", rofPrev.getFirstIdx(), rofPrev.getLastIdx(),
279 rofPrev.getBCData().orbit, rofPrev.getBCData().bc)
280 << fmt::format(
"ROF2 {}-{} {},{}", rof.getFirstIdx(), rof.getLastIdx(),
281 rof.getBCData().orbit, rof.getBCData().bc);
291 for (
size_t i = 0;
i < mOutputROFs.size();
i++) {
292 auto& rof = mOutputROFs[
i];
293 for (
int j = rof.getFirstIdx() + 1;
j <= rof.getLastIdx();
j++) {
294 auto id = mOrderedDigits[
j];
295 auto idPrev = mOrderedDigits[
j - 1];
296 const auto& digit = mInputDigits[
id];
297 const auto& digitPrev = mInputDigits[idPrev];
298 if (digit.getTime() != digitPrev.getTime()) {
299 LOG(error) <<
"Mis-aligned digits encountered:";
300 LOG(error) << fmt::format(
"TIME1 {} ", digitPrev.getTime()) << fmt::format(
"TIME2 {}", digit.getTime());
311 if (i < 0 || i >= mOrderedDigits.size()) {
315 auto id = mOrderedDigits[
i];
316 if (
id >= mInputDigits.size()) {
320 return mInputDigits[
id];
326 std::cout <<
"OUTPUT DIGITS:\n";
327 for (
size_t i = 0;
i < mOrderedDigits.size();
i++) {
328 const auto id = mOrderedDigits[
i];
329 const auto& digit = mInputDigits[
id];
330 const auto& d = digit.digit;
331 const auto& t = digit.info;
333 if (d.getPadID() < 0) {
337 bool bending =
segment.isBendingPad(d.getPadID());
338 float X =
segment.padPositionX(d.getPadID());
339 float Y =
segment.padPositionY(d.getPadID());
340 uint32_t
orbit = t.orbit;
341 uint32_t bunchCrossing = t.bunchCrossing;
342 uint32_t sampaTime = t.sampaTime;
343 auto tfTime = digit.getTime();
346 for (
size_t j = 0;
j < mOutputROFs.size();
j++) {
347 const auto& rof = mOutputROFs[
j];
348 if (rof.getFirstIdx() <=
i && rof.getLastIdx() >=
i) {
352 std::cout << fmt::format(
" DIGIT [{} -> {}] ROF {} DE {:4d} PAD {:5d} ADC {:6d} TIME {} ({} {} {:4d} {})",
353 i,
id, iROF, d.getDetID(), d.getPadID(), d.getADC(), tfTime,
orbit, bunchCrossing, sampaTime, t.getBXTime());
354 std::cout << fmt::format(
"\tC {} PAD_XY {:+2.2f} , {:+2.2f}\n", (bending ? (
int)0 : (
int)1), X, Y);
361 std::cout <<
"OUTPUT ROFs:\n";
362 for (
size_t i = 0;
i < mOutputROFs.size();
i++) {
363 auto& rof = mOutputROFs[
i];
364 std::cout << fmt::format(
" ROF {} {}-{} {},{}\n",
i, rof.getFirstIdx(), rof.getLastIdx(),
365 rof.getBCData().orbit, rof.getBCData().bc);
Header to collect LHC related constants.
Class to group the fired pads according to their time stamp.
MCH digit implementation.
A Segmentation lets you find pads of a detection element and then inspect those pads.
std::vector< RawDigit > RawDigitVector
ROFFinder(const DataDecoder::RawDigitVector &digits, uint32_t firstTForbit)
std::optional< DataDecoder::RawDigit > getOrderedDigit(int i)
char * saveROFRsToBuffer(size_t &bufSize)
char * saveDigitsToBuffer(size_t &bufSize)
bool isDigitsTimeAligned()
void process(bool dummyROFs=false)
o2::InteractionRecord digitTime2IR(const RawDigit &digit)
bool isRofTimeMonotonic()
GLenum GLuint GLenum GLsizei const GLchar * buf
constexpr int LHCMaxBunches
O2MCHMAPPINGIMPL3_EXPORT const Segmentation & segmentation(int detElemId)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits