75 std::shared_ptr<base::GRPGeomRequest> request) : mInputSpec(spec),
76 mCcdbRequest(request) {}
86 mCheckROFs = ic.
options().
get<
bool>(
"check-rofs");
87 mDummyROFs = ic.
options().
get<
bool>(
"dummy-rofs");
88 auto mapCRUfile = ic.
options().
get<std::string>(
"cru-map");
89 auto mapFECfile = ic.
options().
get<std::string>(
"fec-map");
91 mErrorLogFrequency = ic.
options().
get<
int>(
"error-log-frequency");
92 auto timeRecoModeString = ic.
options().
get<std::string>(
"time-reco-mode");
95 if (timeRecoModeString ==
"hbpackets") {
97 }
else if (timeRecoModeString ==
"bcreset") {
101 mDecoder =
new DataDecoder(channelHandler, rdhHandler, mapCRUfile, mapFECfile,
ds2manu, mDebug,
108 auto stop = [
this]() {
109 LOG(info) <<
"mch-data-decoder: decoding duration = " << mTimeDecoding.count() * 1000 / mTFcount <<
" us / TF";
110 LOG(info) <<
"mch-data-decoder: ROF finder duration = " << mTimeROFFinder.count() * 1000 / mTFcount <<
" us / TF";
120 LOGP(info,
"Setting number of orbits per TF to {}",
n);
129 mFirstTForbit = tinfo.firstTForbit;
134 LOG(info) <<
"[DataDecoderSpec::run] first TF orbit is " << mFirstTForbit;
138 auto& inputs = pc.
inputs();
141 for (
auto it = parser.
begin(),
end = parser.
end(); it !=
end && abort ==
false; ++it) {
142 auto const* raw = it.raw();
146 size_t payloadSize = it.size();
148 gsl::span<const std::byte>
buffer(
reinterpret_cast<const std::byte*
>(raw),
sizeof(
RDH) + payloadSize);
151 LOG(alarm) <<
"critical decoding error : aborting this TF decoding\n";
161 static int nFrame = 1;
167 auto const* raw = input.
payload;
172 std::cout << nFrame <<
" payloadSize=" << payloadSize << std::endl;
175 if (payloadSize == 0) {
179 const RDH* rdh =
reinterpret_cast<const RDH*
>(raw);
180 mFirstTForbit = o2::raw::RDHUtils::getHeartBeatOrbit(rdh);
183 gsl::span<const std::byte>
buffer(
reinterpret_cast<const std::byte*
>(raw), payloadSize);
189 std::vector<Digit>
digits;
190 std::vector<ROFRecord> rofs;
191 std::vector<OrbitInfo> orbits;
192 std::vector<DecoderError> errors;
193 std::vector<HeartBeatPacket> hbpackets;
209 static size_t contDeadBeef = 0;
213 if (payloadSize == 0) {
214 const auto* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(pc.
inputs().
getFirstValid(
true));
216 if (++contDeadBeef <= maxWarn) {
217 LOGP(alarm,
"Found input [{}/{}/{:#x}] TF#{} 1st_orbit:{} Payload {} : assuming no payload for all links in this TF{}",
218 dh->dataOrigin.str, dh->dataDescription.str, dh->subSpecification, tinfo.tfCounter, tinfo.firstTForbit, payloadSize,
219 contDeadBeef == maxWarn ? fmt::format(
". {} such inputs in row received, stopping reporting", contDeadBeef) :
"");
240 static int32_t deltaMax = 0;
243 size =
vec.empty() ? 0 :
sizeof(*(
vec.begin())) *
vec.size();
249 size_t sizeofElement =
sizeof(*(
vec.begin()));
250 for (
auto& element :
vec) {
251 memcpy(p, &element, sizeofElement);
259 auto tStart = std::chrono::high_resolution_clock::now();
261 for (
auto&& input : pc.
inputs()) {
262 if (input.spec->binding ==
"readout") {
265 if (input.spec->binding ==
"TF") {
270 auto tEnd = std::chrono::high_resolution_clock::now();
271 mTimeDecoding += tEnd - tStart;
278#ifdef MCH_RAW_DATADECODER_DEBUG_DIGIT_TIME
280 int32_t bcMax = mNHBPerTF * 3564 - 1;
282 if (d.getTime() < 0 || d.getTime() > bcMax) {
283 int32_t delta = d.getTime() - bcMax;
284 if (delta > deltaMax) {
286 std::cout <<
"Max digit time exceeded: TF ORBIT " << mDecoder->getFirstOrbitInTF().value() <<
" DE# " << d.getDetID() <<
" PadId " << d.getPadID() <<
" ADC " << d.getADC()
287 <<
" time " << d.getTime() <<
" (" << bcMax <<
", delta=" << delta <<
")" << std::endl;
293 tStart = std::chrono::high_resolution_clock::now();
296 tEnd = std::chrono::high_resolution_clock::now();
297 mTimeROFFinder += tEnd - tStart;
310 size_t digitsSize, rofsSize, orbitsSize, errorsSize, hbSize;
318 LOGP(info,
"digitsSize {} rofsSize {} orbitsSize {} errorsSize {}", digitsSize, rofsSize, orbitsSize, errorsSize);
322 auto freefct = [](
void*
data,
void*) { free(
data); };
330 if (mErrorLogFrequency) {
331 if (mTFcount == 1 || mTFcount % mErrorLogFrequency == 0) {
338 std::string mInputSpec;
339 bool mDebug = {
false};
340 bool mCheckROFs = {
false};
341 bool mDummyROFs = {
false};
342 uint32_t mFirstTForbit{0};
343 DataDecoder* mDecoder = {
nullptr};
345 uint32_t mTFcount{0};
346 uint32_t mErrorLogFrequency;
348 std::chrono::duration<double, std::milli> mTimeDecoding{};
349 std::chrono::duration<double, std::milli> mTimeROFFinder{};
350 std::shared_ptr<base::GRPGeomRequest> mCcdbRequest;
361 inputs.emplace_back(
"stfDist",
"FLP",
"DISTSUBTIMEFRAME", 0, o2::framework::Lifetime::Timeframe);
363 auto ccdbRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
379 AlgorithmSpec{adaptFromTask<DataDecoderTask>(std::move(task))},
380 Options{{
"mch-debug", VariantType::Bool,
false, {
"enable verbose output"}},
381 {
"cru-map", VariantType::String,
"", {
"custom CRU mapping"}},
382 {
"fec-map", VariantType::String,
"", {
"custom FEC mapping"}},
383 {
"dummy-elecmap", VariantType::Bool,
false, {
"use dummy electronic mapping (for debug, temporary)"}},
384 {
"ds2manu", VariantType::Bool,
false, {
"convert channel numbering from Run3 to Run1-2 order"}},
385 {
"time-reco-mode", VariantType::String,
"bcreset", {
"digit time reconstruction method [hbpackets, bcreset]"}},
386 {
"check-rofs", VariantType::Bool,
false, {
"perform consistency checks on the output ROFs"}},
387 {
"dummy-rofs", VariantType::Bool,
false, {
"disable the ROFs finding algorithm"}},
388 {
"error-log-frequency", VariantType::Int, 6000, {
"log the error map at this frequency (in TF unit) (first TF is always logged, unless frequency is zero)"}}}};
A raw page parser for DPL input.
Definition of the decoder for the MCH data.
Helper for geometry and GRP related CCDB requests.
Header to collect LHC related constants.
Class to group the fired pads according to their time stamp.
int ds2manu(int deId, int ch)
void checkUpdates(o2::framework::ProcessingContext &pc)
bool finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj)
static int getNHBFPerTF()
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static const VerbosityConfig & Instance()
T get(const char *key) const
The parser handles transparently input in the format of raw pages.
const_iterator end() const
const_iterator begin() const
void adoptChunk(const Output &, char *, size_t, fair::mq::FreeFn *, void *)
ServiceRegistryRef services()
ConfigParamRegistry const & options()
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
void decodeReadout(const o2::framework::DataRef &input)
void run(framework::ProcessingContext &pc)
DataDecoderTask(std::string spec, std::shared_ptr< base::GRPGeomRequest > request)
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj)
void decodeTF(framework::ProcessingContext &pc)
bool isDroppedTF(framework::ProcessingContext &pc)
void init(framework::InitContext &ic)
void sendEmptyOutput(framework::DataAllocator &output)
void logErrorMap(int tfcount) const
send all messages from our error map to the infologger
void setOrbitsInTF(uint32_t nofOrbitsPerTF)
const std::vector< o2::mch::HeartBeatPacket > & getHBPackets() const
Get the list of heart-beat packets that have been found in the current TimeFrame.
const std::vector< o2::mch::DecoderError > & getErrors() const
Get the list of decoding errors that have been found in the current TimeFrame.
void setFirstOrbitInTF(uint32_t orbit)
const RawDigitVector & getDigits() const
Get the vector of digits that have been decoded in the current TimeFrame.
const std::unordered_set< OrbitInfo, OrbitInfoHash > & getOrbits() const
Get the list of orbits that have been found in the current TimeFrame for each CRU link.
bool decodeBuffer(gsl::span< const std::byte > buf)
char * saveROFRsToBuffer(size_t &bufSize)
char * saveDigitsToBuffer(size_t &bufSize)
bool isDigitsTimeAligned()
void process(bool dummyROFs=false)
bool isRofTimeMonotonic()
GLenum GLuint GLenum GLsizei const GLchar * buf
constexpr o2::header::DataOrigin gDataOriginMCH
constexpr o2::header::DataDescription gDataDescriptionRawData
constexpr int LHCMaxBunches
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > Options
std::vector< InputSpec > select(char const *matcher="")
std::vector< OutputSpec > Outputs
o2::framework::DataProcessorSpec getDecodingSpec(const char *specName="mch-data-decoder", std::string inputSpec="TF:MCH/RAWDATA", bool askDISTSTF=false)
std::function< void(o2::header::RDHAny *)> RdhHandler
std::function< void(DsElecId dsId, DualSampaChannelId channel, SampaCluster)> SampaChannelHandler
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static o2::header::DataHeader::PayloadSizeType getPayloadSize(const DataRef &ref)
const bool useDummyElecMap
std::vector< std::byte > createBuffer(gsl::span< std::string > data, uint32_t orbit=12345, uint16_t bc=678)
std::vector< o2::ctf::BufferType > vec
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits