17#include <InfoLogger/InfoLogger.hxx>
53 if (mErrorMessagesSuppressed) {
54 LOG(warning) <<
"Suppressed further " << mErrorMessagesSuppressed <<
" error messages";
60 if (ctx.
services().
active<AliceO2::InfoLogger::InfoLoggerContext>()) {
61 auto& ilctx = ctx.
services().
get<AliceO2::InfoLogger::InfoLoggerContext>();
62 ilctx.setField(AliceO2::InfoLogger::InfoLoggerContext::FieldName::Detector,
"EMC");
65 LOG(
debug) <<
"[EMCALRawToCellConverter - init] Initialize converter ";
70 LOG(error) <<
"Failure accessing geometry";
77 LOG(error) <<
"Failed to initialize mapper";
80 if (!mTriggerMapping) {
81 mTriggerMapping = std::make_unique<TriggerMappingV2>(mGeometry);
84 auto fitmethod = ctx.
options().
get<std::string>(
"fitmethod");
85 if (fitmethod ==
"standard") {
86 LOG(info) <<
"Using standard raw fitter";
88 }
else if (fitmethod ==
"gamma2") {
89 LOG(info) <<
"Using gamma2 raw fitter";
92 LOG(fatal) <<
"Unknown fit method" << fitmethod;
94 LOG(info) <<
"Creating decoding errors: " << (mCreateRawDataErrors ?
"yes" :
"no");
96 mPrintTrailer = ctx.
options().
get<
bool>(
"printtrailer");
98 mMaxErrorMessages = ctx.
options().
get<
int>(
"maxmessage");
99 LOG(info) <<
"Suppressing error messages after " << mMaxErrorMessages <<
" messages";
101 mMergeLGHG = !ctx.
options().
get<
bool>(
"no-mergeHGLG");
102 mDisablePedestalEvaluation = ctx.
options().
get<
bool>(
"no-evalpedestal");
103 mActiveLinkCheck = !ctx.
options().
get<
bool>(
"no-checkactivelinks");
105 LOG(info) <<
"Running gain merging mode: " << (mMergeLGHG ?
"yes" :
"no");
106 LOG(info) <<
"Checking for active links: " << (mActiveLinkCheck ?
"yes" :
"no");
107 LOG(info) <<
"Calculate pedestals: " << (mDisablePedestalEvaluation ?
"no" :
"yes");
110 mRawFitter->setAmpCut(mNoiseThreshold);
111 mRawFitter->setL1Phase(0.);
116 LOG(
debug) <<
"[EMCALRawToCellConverter - run] called";
117 mCalibHandler->checkUpdates(ctx);
118 updateCalibrationObjects();
121 std::unordered_map<int64_t, std::bitset<46>> bcFreq;
129 auto currenttime = std::chrono::system_clock::now();
130 std::chrono::duration<double> interval = mReferenceTime - currenttime;
131 if (interval.count() > 600) {
133 mNumErrorMessages = 0;
134 mReferenceTime = currenttime;
137 mOutputCells.clear();
138 mOutputTriggerRecords.clear();
139 mOutputDecoderErrors.clear();
141 mOutputTRUTriggerRecords.clear();
142 mOutputPatches.clear();
143 mOutputPatchTriggerRecords.clear();
144 mOutputTimesums.clear();
145 mOutputTimesumTriggerRecords.clear();
147 if (isLostTimeframe(ctx)) {
152 mCellHandler.
reset();
188 handleMinorPageError(e);
193 auto triggerBC = raw::RDHUtils::getTriggerBC(header);
194 auto triggerOrbit = raw::RDHUtils::getTriggerOrbit(header);
195 auto feeID = raw::RDHUtils::getFEEID(header);
196 auto triggerbits = raw::RDHUtils::getTriggerType(header);
198 int correctionShiftBCmod4 = 0;
203 currentIR -= lml0delay;
206 correctionShiftBCmod4 = lml0delay % 4;
213 bcFreq[currentIR.
toLong()].set(feeID,
true);
223 LOG(
debug) <<
"Original BC " << triggerBC <<
", L0LM corrected " << currentIR.
bc;
224 LOG(
debug) <<
"Applying correction for LM delay: " << correctionShiftBCmod4;
225 LOG(
debug) <<
"BC mod original: " << triggerBC % 4 <<
", corrected " << bcmod4;
226 LOG(
debug) <<
"Applying time correction: " << -1 * 25 * bcmod4;
228 if (!currentEvent.getTriggerBits()) {
231 CellTimeCorrection timeCorrector{timeshift, bcmod4};
241 if (maxBunchLengthRP) {
249 handleAltroError(e, feeID);
253 handleMinorAltroError(minorerror, feeID);
263 LOG(debug3) <<
"Zero suppression enabled";
265 LOG(debug3) <<
"Zero suppression disabled";
267 if (mDisablePedestalEvaluation) {
271 mRawFitter->setIsZeroSuppressed(
true);
278 const auto& map = mMapper->getMappingForDDL(feeID);
279 uint16_t iSM = feeID / 2;
282 int nBunchesNotOK = 0;
285 auto iRow = map.getRow(chan.getHardwareAddress());
286 auto iCol = map.getColumn(chan.getHardwareAddress());
287 auto chantype = map.getChannelType(chan.getHardwareAddress());
288 LocalPosition channelPosition{iSM, feeID, iCol, iRow};
292 addFEEChannelToEvent(currentEvent, chan, timeCorrector, channelPosition, chantype);
297 addFEEChannelToEvent(currentEvent, chan, timeCorrector, channelPosition, chantype);
301 addTRUChannelToEvent(currentEvent, chan, channelPosition);
304 LOG(error) <<
"Unknown channel type for HW address " << chan.getHardwareAddress();
308 handleAddressError(ex, feeID, chan.getHardwareAddress());
314 handleDDLError(ddlerror, feeID);
319 std::bitset<46> bitSetActiveLinks;
320 if (mActiveLinkCheck) {
322 FeeDCS* feedcs = mCalibHandler->getFEEDCS();
326 list0.set(21,
false);
329 bitSetActiveLinks = std::bitset<46>((list1.to_ullong() << 32) + list0.to_ullong());
334 while (eventIterator.
hasNext()) {
335 int ncellsEvent = 0, nLEDMONsEvent = 0;
336 int eventstart = mOutputCells.size();
337 auto& currentevent = eventIterator.
nextEvent();
339 if (mActiveLinkCheck) {
342 auto bcfreqFound = bcFreq.find(interaction.toLong());
343 if (bcfreqFound != bcFreq.end()) {
344 const auto& activelinks = bcfreqFound->second;
345 if (activelinks != bitSetActiveLinks) {
346 static int nErrors = 0;
348 LOG(error) <<
"Not all EMC active links contributed in global BCid=" << interaction.
toLong() <<
": mask=" << (activelinks ^ bitSetActiveLinks) << (nErrors == 3 ?
" (not reporting further errors to avoid spamming)" :
"");
350 if (mCreateRawDataErrors) {
351 for (std::size_t ilink = 0; ilink < bitSetActiveLinks.size(); ilink++) {
352 if (!bitSetActiveLinks.test(ilink)) {
355 if (!activelinks.test(ilink)) {
362 mOutputTriggerRecords.emplace_back(interaction, currentevent.getTriggerBits() | o2::emcal::triggerbits::Inc, eventstart, 0);
368 if (currentevent.getNumberOfCells()) {
369 LOG(
debug) <<
"Event has " << currentevent.getNumberOfCells() <<
" cells";
370 currentevent.sortCells(
false);
371 ncellsEvent = bookEventCells(currentevent.getCells(),
false);
374 if (currentevent.getNumberOfLEDMONs()) {
375 LOG(
debug) <<
"Event has " << currentevent.getNumberOfLEDMONs() <<
" LEDMONs";
376 currentevent.sortCells(
true);
377 nLEDMONsEvent = bookEventCells(currentevent.getLEDMons(),
true);
379 LOG(
debug) <<
"Next event [Orbit " << interaction.orbit <<
", BC (" << interaction.bc <<
"]: Accepted " << ncellsEvent <<
" cells and " << nLEDMONsEvent <<
" LEDMONS";
380 mOutputTriggerRecords.emplace_back(interaction, currentevent.getTriggerBits(), eventstart, ncellsEvent + nLEDMONsEvent);
383 if (mDoTriggerReconstruction) {
384 auto [trus, patches] = buildL0Patches(currentevent);
385 LOG(
debug) <<
"Found " << patches.size() <<
" L0 patches from " << trus.size() <<
" TRUs";
386 auto trusstart = mOutputTRUs.size();
387 std::copy(trus.begin(), trus.end(), std::back_inserter(mOutputTRUs));
388 mOutputTRUTriggerRecords.emplace_back(interaction, currentevent.getTriggerBits(), trusstart, trus.size());
389 auto patchesstart = mOutputPatches.size();
390 std::copy(patches.begin(), patches.end(), std::back_inserter(mOutputPatches));
391 mOutputPatchTriggerRecords.emplace_back(interaction, currentevent.getTriggerBits(), patchesstart, patches.size());
394 auto timesumsstart = mOutputTimesums.size();
395 auto timesums = buildL0Timesums(currentevent, 8);
396 std::copy(timesums.begin(), timesums.end(), std::back_inserter(mOutputTimesums));
397 mOutputTimesumTriggerRecords.emplace_back(interaction, currentevent.getTriggerBits(), timesumsstart, timesums.size());
401 LOG(info) <<
"[EMCALRawToCellConverter - run] Writing " << mOutputCells.size() <<
" cells from " << mOutputTriggerRecords.size() <<
" events ...";
402 if (mDoTriggerReconstruction) {
403 LOG(info) <<
"[EMCALRawToCellConverter - run] Writing " << mOutputTRUs.size() <<
" TRU infos and " << mOutputPatches.size() <<
" trigger patches and " << mOutputTimesums.size() <<
" timesums from " << mOutputTRUTriggerRecords.size() <<
" events ...";
410 if (mCalibHandler->finalizeCCDB(matcher, obj)) {
415void RawToCellConverterSpec::updateCalibrationObjects()
417 if (mCalibHandler->hasUpdateRecoParam()) {
418 LOG(info) <<
"RecoParams updated";
421 if (mCalibHandler->hasUpdateFEEDCS()) {
422 LOG(info) <<
"DCS params updated";
433 static size_t contDeadBeef = 0;
435 const auto dh = o2::framework::DataRefUtils::getHeader<o2::header::DataHeader*>(
ref);
437 if (payloadSize == 0) {
439 if (++contDeadBeef <= maxWarn) {
440 LOGP(warning,
"Found input [{}/{}/{:#x}] TF#{} 1st_orbit:{} Payload {} : assuming no payload for all links in this TF{}",
441 dh->dataOrigin.str, dh->dataDescription.str, dh->subSpecification, dh->tfCounter, dh->firstTForbit, payloadSize,
442 contDeadBeef == maxWarn ? fmt::format(
". {} such inputs in row received, stopping reporting", contDeadBeef) :
"");
454 bool isLowGain =
false;
458 CellID = getCellAbsID(position.mSupermoduleID, position.mColumn, position.mRow);
462 CellID = geLEDMONAbsID(position.mSupermoduleID, position.mColumn);
463 isLowGain = position.mRow == 0;
465 }
catch (ModuleIndexException& e) {
466 handleGeometryError(e, position.mSupermoduleID, CellID, currentchannel.
getHardwareAddress(), chantype);
473 fitResults = mRawFitter->evaluate(currentchannel.
getBunches());
475 if (fitResults.
getAmp() < 0) {
478 if (fitResults.
getTime() < 0) {
482 double celltime = timeCorrector.getCorrectedTime(fitResults.
getTime());
483 double amp = fitResults.
getAmp() * o2::emcal::constants::EMCAL_ADCENERGY;
485 amp *= o2::emcal::constants::EMCAL_HGLGFACTOR;
494 handleFitError(fiterror, position.mFeeID, CellID, currentchannel.
getHardwareAddress());
501 auto tru = mTriggerMapping->getTRUIndexFromOnlineHardareAddree(currentchannel.
getHardwareAddress(), position.mFeeID, position.mSupermoduleID);
502 if (position.mColumn >= 96 && position.mColumn <= 105) {
505 for (
auto& bunch : currentchannel.getBunches()) {
506 LOG(
debug) <<
"Found bunch of length " <<
static_cast<int>(bunch.getBunchLength()) <<
" with start time " <<
static_cast<int>(bunch.getStartTime()) <<
" (column " <<
static_cast<int>(position.mColumn) <<
")";
507 auto l0time = bunch.getStartTime();
509 for (
auto&
adc : bunch.getADC()) {
516 if (position.mColumn == 105) {
517 std::bitset<6> patchBits(
adc & 0x3F);
518 std::bitset<4> headerbits((
adc >> 6) & 0xF);
519 for (
auto localindex = 0; localindex < patchBits.size(); localindex++) {
520 if (patchBits.test(localindex)) {
521 auto globalindex = (position.mColumn - 96) * 10 + localindex;
522 LOG(
debug) <<
"Found patch with index " << globalindex <<
" in sample " << isample;
525 trudata.setPatch(globalindex, bunch.getStartTime() - isample);
527 handlePatchError(e, position.mFeeID, tru);
531 if (headerbits.test(2)) {
532 LOG(
debug) <<
"TRU " << tru <<
": Found TRU fired (" << tru <<
") in sample " << isample;
534 trudata.setFired(
true);
535 trudata.setL0time(bunch.getStartTime() - isample);
538 std::bitset<10> patchBits(
adc & 0x3FF);
539 for (
auto localindex = 0; localindex < patchBits.size(); localindex++) {
540 if (patchBits.test(localindex)) {
541 auto globalindex = (position.mColumn - 96) * 10 + localindex;
542 LOG(
debug) <<
"TRU " << tru <<
": Found patch with index " << globalindex <<
" in sample " << isample;
545 trudata.setPatch(globalindex, bunch.getStartTime() - isample);
547 handlePatchError(e, position.mFeeID, tru);
557 auto absFastOR = mTriggerMapping->getAbsFastORIndexFromIndexInTRU(tru, position.mColumn);
558 for (
auto& bunch : currentchannel.getBunches()) {
568 currentEvent.
setFastOR(absFastOR, bunch.getStartTime(), bunch.getADC());
570 handleFastORStartTimeErrors(e, position.mFeeID, tru);
574 handleFastORErrors(e, position.mFeeID, tru);
582std::tuple<RawToCellConverterSpec::TRUContainer, RawToCellConverterSpec::PatchContainer> RawToCellConverterSpec::buildL0Patches(
const EventContainer& currentevent)
const
585 TRUContainer eventTRUs;
586 PatchContainer eventPatches;
588 std::set<uint16_t> foundFastOrs;
589 for (
auto fastor : fastOrs) {
590 foundFastOrs.insert(fastor.first);
594 if (!currenttru.hasAnyPatch()) {
598 LOG(
debug) <<
"Found patches in TRU " << itru <<
", fired: " << (currenttru.isFired() ?
"yes" :
"no") <<
", L0 time " <<
static_cast<int>(l0time);
601 if (currenttru.hasPatch(ipatch)) {
602 auto patchtime = currenttru.getPatchTime(ipatch);
603 LOG(
debug) <<
"Found patch " << ipatch <<
" in TRU " << itru <<
" with time " <<
static_cast<int>(patchtime);
604 auto fastorStart = mTriggerMapping->getAbsFastORIndexFromIndexInTRU(itru, ipatch);
605 auto fastORs = mTriggerMapping->getFastORIndexFromL0Index(itru, ipatch, 4);
606 std::array<const FastORTimeSeries*, 4> fastors;
607 std::fill(fastors.begin(), fastors.end(),
nullptr);
608 int indexFastorInTRU = 0;
609 for (
auto fastor : fastORs) {
610 auto [truID, fastorTRU] = mTriggerMapping->getTRUFromAbsFastORIndex(fastor);
612 auto timeseriesFound = fastOrs.find(fastor);
613 if (timeseriesFound != fastOrs.end()) {
614 LOG(
debug) <<
"Adding FastOR (" << indexFastorInTRU <<
") with index " << fastor <<
" to patch";
615 fastors[indexFastorInTRU] = &(timeseriesFound->second);
619 auto [patchADC, recpatchtime] = reconstructTriggerPatch(fastors);
621 patchADC = patchADC << 2;
622 LOG(
debug) <<
"Reconstructed patch at index " << ipatch <<
" with peak time " <<
static_cast<int>(recpatchtime) <<
" (time sample " <<
static_cast<int>(patchtime) <<
") and energy " << patchADC;
623 eventPatches.push_back({
static_cast<uint8_t>(itru),
static_cast<uint8_t>(ipatch), patchtime, patchADC});
626 eventTRUs.push_back({
static_cast<uint8_t>(itru),
static_cast<uint8_t>(l0time), currenttru.isFired(), npatches});
628 return std::make_tuple(eventTRUs, eventPatches);
631std::vector<o2::emcal::CompressedL0TimeSum> RawToCellConverterSpec::buildL0Timesums(
const o2::emcal::EventContainer& currentevent, uint8_t l0time)
const
633 std::vector<o2::emcal::CompressedL0TimeSum> timesums;
634 for (
const auto& [fastorID, timeseries] : currentevent.getTimeSeriesContainer()) {
635 timesums.push_back({fastorID,
static_cast<uint16_t
>(timeseries.calculateL1TimeSum(l0time) << 2)});
640std::tuple<uint16_t, uint8_t> RawToCellConverterSpec::reconstructTriggerPatch(
const gsl::span<const FastORTimeSeries*> fastors)
const
642 constexpr size_t INTEGRATE_SAMPLES = 4,
644 double maxpatchenergy = 0;
646 for (
size_t itime = 0; itime < MAX_SAMPLES - INTEGRATE_SAMPLES; ++itime) {
647 double currenttimesum = 0;
648 for (
size_t isample = 0; isample < INTEGRATE_SAMPLES; ++isample) {
649 for (
auto ifastor = 0; ifastor < fastors.size(); ++ifastor) {
650 if (fastors[ifastor]) {
651 currenttimesum += fastors[ifastor]->getADCs()[itime + isample];
655 if (currenttimesum > maxpatchenergy) {
656 maxpatchenergy = currenttimesum;
661 return std::make_tuple(maxpatchenergy, foundtime);
664int RawToCellConverterSpec::bookEventCells(
const gsl::span<const o2::emcal::RecCellInfo>&
cells,
bool isLELDMON)
667 int ncellsSelected = 0;
668 for (
const auto& cell :
cells) {
669 if (cell.mIsLGnoHG) {
672 int ampLG = cell.mCellData.getAmplitude() / (o2::emcal::constants::EMCAL_ADCENERGY * o2::emcal::constants::EMCAL_HGLGFACTOR);
674 if (ampLG > noiseThresholLGnoHG) {
679 if (cell.mHGOutOfRange) {
684 mOutputCells.push_back(cell.mCellData);
687 mOutputCells.back().setLEDMon();
690 return ncellsSelected;
693int RawToCellConverterSpec::getCellAbsID(
int supermoduleID,
int column,
int row)
697 if (cellID > 17664 || cellID < 0) {
698 throw ModuleIndexException(cellID, column,
row, etashift, phishift);
703int RawToCellConverterSpec::geLEDMONAbsID(
int supermoduleID,
int moduleID)
706 throw ModuleIndexException(moduleID);
713 if (mNumErrorMessages < mMaxErrorMessages) {
714 LOG(warning) <<
"Mapping error DDL " << feeID <<
": " << error.
what();
716 if (mNumErrorMessages == mMaxErrorMessages) {
717 LOG(warning) <<
"Max. amount of error messages (" << mMaxErrorMessages <<
" reached, further messages will be suppressed";
720 mErrorMessagesSuppressed++;
722 if (mCreateRawDataErrors) {
724 mOutputDecoderErrors.push_back(mappingError);
730 if (mNumErrorMessages < mMaxErrorMessages) {
731 std::string errormessage;
734 case AltroErrType::RCU_TRAILER_ERROR:
735 errormessage =
" RCU Trailer Error ";
737 case AltroErrType::RCU_VERSION_ERROR:
738 errormessage =
" RCU Version Error ";
740 case AltroErrType::RCU_TRAILER_SIZE_ERROR:
741 errormessage =
" RCU Trailer Size Error ";
743 case AltroErrType::ALTRO_BUNCH_HEADER_ERROR:
744 errormessage =
" ALTRO Bunch Header Error ";
746 case AltroErrType::ALTRO_BUNCH_LENGTH_ERROR:
747 errormessage =
" ALTRO Bunch Length Error ";
749 case AltroErrType::ALTRO_PAYLOAD_ERROR:
750 errormessage =
" ALTRO Payload Error ";
752 case AltroErrType::ALTRO_MAPPING_ERROR:
753 errormessage =
" ALTRO Mapping Error ";
755 case AltroErrType::CHANNEL_ERROR:
756 errormessage =
" Channel Error ";
761 LOG(warning) <<
" EMCAL raw task: " << errormessage <<
" in DDL " << ddlID;
763 if (mNumErrorMessages == mMaxErrorMessages) {
764 LOG(warning) <<
"Max. amount of error messages (" << mMaxErrorMessages <<
" reached, further messages will be suppressed";
767 mErrorMessagesSuppressed++;
769 if (mCreateRawDataErrors) {
772 mOutputDecoderErrors.push_back(errornum);
778 if (mNumErrorMessages < mMaxErrorMessages) {
779 LOG(warning) <<
" EMCAL raw task - Minor error in DDL " << ddlID <<
": " << minorerror.
what();
781 if (mNumErrorMessages == mMaxErrorMessages) {
782 LOG(warning) <<
"Max. amount of error messages (" << mMaxErrorMessages <<
" reached, further messages will be suppressed";
785 mErrorMessagesSuppressed++;
787 if (mCreateRawDataErrors) {
788 int fecID = -1, hwaddress = -1;
798 mOutputDecoderErrors.push_back(errornum);
804 if (mNumErrorMessages < mMaxErrorMessages) {
805 LOG(error) <<
"Failed obtaining mapping for DDL " << error.
getDDDL();
807 if (mNumErrorMessages == mMaxErrorMessages) {
808 LOG(error) <<
"Max. amount of error messages (" << mMaxErrorMessages <<
" reached, further messages will be suppressed";
811 if (mCreateRawDataErrors) {
820 if (mNumErrorMessages < mMaxErrorMessages) {
823 if (mNumErrorMessages == mMaxErrorMessages) {
824 LOG(warning) <<
"Max. amount of error messages (" << mMaxErrorMessages <<
" reached, further messages will be suppressed";
827 mErrorMessagesSuppressed++;
830 if (mCreateRawDataErrors) {
841 if (mNumErrorMessages < mMaxErrorMessages) {
844 LOG(warning) <<
"FEC " << fecID <<
": 0x" << std::hex << hwaddress << std::dec <<
" (DDL " << ddlID <<
") has only high-gain out-of-range";
847 LOG(warning) <<
"FEC " << fecID <<
": 0x" << std::hex << hwaddress << std::dec <<
" (DDL " << ddlID <<
") has low gain but no high-gain";
850 LOG(warning) <<
"FEC " << fecID <<
": 0x" << std::hex << hwaddress << std::dec <<
" (DDL " << ddlID <<
") falsely flagged as gain error";
852 if (mNumErrorMessages == mMaxErrorMessages) {
853 LOG(warning) <<
"Max. amount of error messages (" << mMaxErrorMessages <<
" reached, further messages will be suppressed";
856 mErrorMessagesSuppressed++;
858 if (mCreateRawDataErrors) {
863void RawToCellConverterSpec::handleGeometryError(
const ModuleIndexException& error,
int feeID,
int cellID,
int hwaddress,
ChannelType_t chantype)
865 if (mNumErrorMessages < mMaxErrorMessages) {
866 std::string celltypename;
869 celltypename =
"high gain";
872 celltypename =
"low-gain";
875 celltypename =
"TRU";
878 celltypename =
"LEDMON";
881 int supermoduleID = feeID / 2;
882 switch (error.getModuleType()) {
883 case ModuleIndexException::ModuleType_t::CELL_MODULE:
884 LOG(warning) <<
"Sending invalid or negative cell ID " << error.getIndex() <<
" (SM " << supermoduleID <<
", row " << error.getRow() <<
" - shift " << error.getRowShifted() <<
", col " << error.getColumn() <<
" - shift " << error.getColumnShifted() <<
") of type " << celltypename;
886 case ModuleIndexException::ModuleType_t::LEDMON_MODULE:
887 LOG(warning) <<
"Sending invalid or negative LEDMON module ID " << error.getIndex() <<
"( SM" << supermoduleID <<
")";
891 if (mNumErrorMessages == mMaxErrorMessages) {
892 LOG(warning) <<
"Max. amount of error messages (" << mMaxErrorMessages <<
" reached, further messages will be suppressed";
895 mErrorMessagesSuppressed++;
897 if (mCreateRawDataErrors) {
904 if (mCreateRawDataErrors) {
907 if (mNumErrorMessages < mMaxErrorMessages) {
908 LOG(warning) <<
" Page decoding: " << e.
what() <<
" in FEE ID " << e.
getFECID();
910 if (mNumErrorMessages == mMaxErrorMessages) {
911 LOG(warning) <<
"Max. amount of error messages (" << mMaxErrorMessages <<
" reached, further messages will be suppressed";
914 mErrorMessagesSuppressed++;
920 if (mCreateRawDataErrors) {
923 if (mNumErrorMessages < mMaxErrorMessages) {
926 if (mNumErrorMessages == mMaxErrorMessages) {
927 LOG(warning) <<
"Max. amount of error messages (" << mMaxErrorMessages <<
" reached, further messages will be suppressed";
930 mErrorMessagesSuppressed++;
934void RawToCellConverterSpec::handleFastORErrors(
const FastORIndexException& e,
unsigned int linkID,
unsigned int indexTRU)
936 if (mCreateRawDataErrors) {
939 if (mNumErrorMessages < mMaxErrorMessages) {
940 LOG(warning) <<
" TRU decoding: " << e.
what() <<
" in FEE ID " << linkID <<
", TRU " << indexTRU;
942 if (mNumErrorMessages == mMaxErrorMessages) {
943 LOG(warning) <<
"Max. amount of error messages (" << mMaxErrorMessages <<
" reached, further messages will be suppressed";
946 mErrorMessagesSuppressed++;
952 if (mCreateRawDataErrors) {
955 if (mNumErrorMessages < mMaxErrorMessages) {
956 LOG(warning) <<
" TRU decoding: " << e.
what() <<
" in FEE ID " << linkID <<
", TRU " << indexTRU;
958 if (mNumErrorMessages == mMaxErrorMessages) {
959 LOG(warning) <<
"Max. amount of error messages (" << mMaxErrorMessages <<
" reached, further messages will be suppressed";
962 mErrorMessagesSuppressed++;
968 if (mCreateRawDataErrors) {
971 if (mNumErrorMessages < mMaxErrorMessages) {
972 LOG(warning) <<
" TRU decoding: " << e.
what() <<
" in FEE ID " << linkID <<
", TRU " << indexTRU;
974 if (mNumErrorMessages == mMaxErrorMessages) {
975 LOG(warning) <<
"Max. amount of error messages (" << mMaxErrorMessages <<
" reached, further messages will be suppressed";
978 mErrorMessagesSuppressed++;
982void RawToCellConverterSpec::handleTRUIndexError(
const TRUIndexException& e,
unsigned int linkID,
unsigned int hwaddress)
984 if (mCreateRawDataErrors) {
987 if (mNumErrorMessages < mMaxErrorMessages) {
988 LOG(warning) <<
" TRU decoding: " << e.
what() <<
" in FEE ID " << linkID <<
", TRU " << e.
getTRUIndex() <<
"(hardware address: " << hwaddress <<
")";
990 if (mNumErrorMessages == mMaxErrorMessages) {
991 LOG(warning) <<
"Max. amount of error messages (" << mMaxErrorMessages <<
" reached, further messages will be suppressed";
994 mErrorMessagesSuppressed++;
1003 if (mCreateRawDataErrors) {
1004 LOG(
debug) <<
"Sending " << mOutputDecoderErrors.size() <<
" decoding errors";
1007 if (mDoTriggerReconstruction) {
1017RawToCellConverterSpec::ModuleIndexException::ModuleIndexException(
int moduleIndex,
int column,
int row,
int shiftedColumn,
int shiftedRow) : mModuleType(ModuleType_t::CELL_MODULE),
1018 mIndex(moduleIndex),
1021 mColumnShifted(shiftedColumn),
1022 mRowShifted(shiftedRow) {}
1024RawToCellConverterSpec::ModuleIndexException::ModuleIndexException(
int moduleIndex) : mModuleType(ModuleType_t::LEDMON_MODULE), mIndex(moduleIndex) {}
1029 std::vector<o2::framework::OutputSpec> outputs;
1031 outputs.emplace_back(originEMC,
"CELLS", subspecification, o2::framework::Lifetime::Timeframe);
1032 outputs.emplace_back(originEMC,
"CELLSTRGR", subspecification, o2::framework::Lifetime::Timeframe);
1033 if (!disableDecodingErrors) {
1034 outputs.emplace_back(originEMC,
"DECODERERR", subspecification, o2::framework::Lifetime::Timeframe);
1036 if (!disableTriggerReconstruction) {
1037 outputs.emplace_back(originEMC,
"TRUS", subspecification, o2::framework::Lifetime::Timeframe);
1038 outputs.emplace_back(originEMC,
"TRUSTRGR", subspecification, o2::framework::Lifetime::Timeframe);
1039 outputs.emplace_back(originEMC,
"PATCHES", subspecification, o2::framework::Lifetime::Timeframe);
1040 outputs.emplace_back(originEMC,
"PATCHESTRGR", subspecification, o2::framework::Lifetime::Timeframe);
1041 outputs.emplace_back(originEMC,
"FASTORS", subspecification, o2::framework::Lifetime::Timeframe);
1042 outputs.emplace_back(originEMC,
"FASTORSTRGR", subspecification, o2::framework::Lifetime::Timeframe);
1047 inputs.emplace_back(
"stdDist",
"FLP",
"DISTSUBTIMEFRAME", 0, o2::framework::Lifetime::Timeframe);
1050 auto calibhandler = std::make_shared<o2::emcal::CalibLoader>();
1051 calibhandler->enableRecoParams(
true);
1052 calibhandler->enableFEEDCS(
true);
1053 calibhandler->defineInputSpecs(inputs);
1056 "EMCALRawToCellConverterSpec",
1059 o2::framework::adaptFromTask<o2::emcal::reco_workflow::RawToCellConverterSpec>(subspecification, !disableDecodingErrors, !disableTriggerReconstruction, calibhandler),
Definition of the 32 Central Trigger System (CTS) Trigger Types defined in https://twiki....
Definition of a container to keep Monte Carlo truth external to simulation objects.
Errors appearing in geometry access obtaining the tower ID.
static const TriggerOffsetsParam & Instance()
Error handling of the ALTRO Decoder.
ErrorType_t
Error codes connected with the ALTRO decoding.
@ ALTRO_MAPPING_ERROR
Incorrect ALTRO channel mapping.
static int errorTypeToInt(ErrorType_t errortype)
convert the error type from symoblic constant into int
const ErrorType_t getErrorType() const noexcept
Access to the error type connected to the erro.
Decoder of the ALTRO data in the raw page.
void decode()
Decode the ALTRO stream.
const RCUTrailer & getRCUTrailer() const
Get reference to the RCU trailer object.
const std::vector< Channel > & getChannels() const
Get the reference to the channel container.
const std::vector< MinorAltroDecodingError > & getMinorDecodingErrors() const
Get list of minor decoding errors.
void setMaxBunchLength(int maxBunchLength)
Set the max. allowed bunch length.
Container class to hold results from fitting.
Raw data fitting: Gamma-2 function.
Raw data fitting: standard TMinuit fit.
static int getErrorNumber(RawFitterError_t fiterror)
Convert error type to numeric representation.
RawFitterError_t
Error codes for failures in raw fitter procedure.
@ BUNCH_NOT_OK
Bunch selection failed.
static std::string createErrorMessage(RawFitterError_t fiterror)
Create error message for a given error type.
ALTRO channel representation.
static int getFecIndexFromHwAddress(int hwaddress)
Extracting FEC index in branch from the hardware address.
static int getHardwareAddressFromChannelHeader(int channelheader)
Extrcting hardware address from the channel header word.
uint16_t getHardwareAddress() const
Get the full hardware address.
static int getBranchIndexFromHwAddress(int hwaddress)
Extracting branch index from the hardware address.
const std::vector< Bunch > & getBunches() const
Get list of bunches in the channel.
Errors per FEE information.
@ FIT_ERROR
Raw fit failed.
@ LINK_ERROR
Error due to missing DDL links.
@ ALTRO_ERROR
Decoding of the ALTRO payload failed.
@ GEOMETRY_ERROR
Decoded position outside EMCAL.
@ TRU_ERROR
Errors from TRU data.
@ MINOR_ALTRO_ERROR
Non-fatal error in decoding of the ALTRO payload.
@ GAIN_ERROR
Error due to gain type.
@ PAGE_ERROR
Raw page decoding failed.
Containter of cells for a given event.
const std::unordered_map< uint16_t, FastORTimeSeries > & getTimeSeriesContainer() const
Access to container with FastOR time series.
void setTriggerBits(uint64_t triggerbits)
Set trigger bits of the interaction.
void setCell(int tower, double energy, double time, ChannelType_t celltype, int hwaddress, int ddlID, bool doMergeHGLG)
Add cell information to the event container.
void setFastOR(uint16_t fastORAbsID, uint8_t starttime, const gsl::span< const uint16_t > timesamples)
Add bunch of time series to the container.
const TRUDataHandler & readTRUData(std::size_t truIndex) const
Read-only access TRU data of a given TRU.
const o2::InteractionRecord & getInteractionRecord() const
Get interaction record of the event.
TRUDataHandler & getTRUData(std::size_t truIndex)
Read and write access TRU data of a given TRU.
void setLEDMONCell(int tower, double energy, double time, ChannelType_t celltype, int hwaddress, int ddlID, bool doMergeHGLG)
Add LEDMON information to the event container.
Error handling of faulty FastOR indices.
const char * what() const noexcept final
Get error message.
Handling of error if starttime is to large (>=14). This is most likely caused by a corrupted channel ...
const char * what() const noexcept final
Access to error message.
std::bitset< 14 > getDDLlist1() const
std::bitset< 32 > getDDLlist0() const
static Geometry * GetInstanceFromRunNumber(Int_t runNumber, const std::string_view="", const std::string_view mcname="TGeant3", const std::string_view mctitle="")
Instanciate geometry depending on the run number. Mostly used in analysis and MC anchors.
std::tuple< int, int > ShiftOnlineToOfflineCellIndexes(Int_t supermoduleID, Int_t iphi, Int_t ieta) const
Adapt cell indices in supermodule to online indexing.
Int_t GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
Transition from super module number (nSupMod) and cell indexes (ieta,iphi) to cell absolute ID number...
Error handling requests for unknown hardware addresses.
const char * what() const noexcept override
Access to error message.
Error handling for invalid DDL IDs (not in range for EMCAL)
int getDDDL() const
Access to DDL ID responsible for the exception.
Handler providing the correct mapping for the given DDL.
Error handling for the ALTRO decoder for non-crashing errors.
static int errorTypeToInt(ErrorType_t errortype)
convert the error type from symoblic constant into int
ErrorType_t getErrorType() const noexcept
Get the type of the error.
std::string what() const noexcept
Create and return error message for different error types.
uint32_t getChannelHeader() const noexcept
Get the header of the channel raising the error.
bool hasZeroSuppression() const
Check whether zero suppression has been applied.
Error handling of the raw reader.
static const char * getErrorCodeDescription(ErrorType_t errortype)
Get description of error type.
const char * what() const noexcept override
Providing error message of the exception.
@ HEADER_DECODING
Header cannot be decoded (format incorrect)
@ HEADER_INVALID
Header in memory not belonging to requested superpage.
static int ErrorTypeToInt(RawDecodingError::ErrorType_t errortype)
Convert error type to error code number.
int getFECID() const
Get the ID of the frontend electronics responsible for the error.
ErrorType_t getErrorType() const
Get the type identifier of the error handled with this exception.
Minor (non-crashing) raw decoding errors.
RawDecodingError::ErrorType_t getErrorType() const
Get type of the error.
int getFEEID() const
Get ID of the FEE.
Reader for raw data produced by the Readout application in in-memory format.
bool hasNext() const
check if more pages are available in the raw file
const o2::header::RDHAny & getRawHeader() const
access to the raw header of the current page
void setRangeSRUDDLs(uint16_t minDDL, uint16_t maxDDL)
Set range for DDLs from SRU (for RCU trailer merging)
void next()
Read next payload from the stream.
gsl::span< const MinorError > getMinorErrors() const
Get minor (non-crashing) raw decoding errors.
Iterator over reco containers.
EventContainer & nextEvent()
Get the next event in container.
bool hasNext() const
Check whehter there are more events in the container.
EventContainer & getEventContainer(const o2::InteractionRecord ¤tIR)
Get container for trigger.
void reset()
Clear container.
Handler of errors related to invalid trigger patch IDs.
const char * what() const noexcept final
Access Error message.
Error handling of faulty TRU indices.
const char * what() const noexcept final
Get error message.
unsigned int getTRUIndex() const noexcept
Get the index of the TRU raising the exception.
static constexpr unsigned int ALLTRUS
Total number of TRUs in EMCAL.
static constexpr unsigned int PATCHESINTRU
void finaliseCCDB(framework::ConcreteDataMatcher &matcher, void *obj) final
Handle objects obtained from the CCDB.
~RawToCellConverterSpec() override
Destructor.
void run(framework::ProcessingContext &ctx) final
Run conversion of raw data to cells.
void init(framework::InitContext &ctx) final
Initializing the RawToCellConverterSpec.
T get(const char *key) const
void snapshot(const Output &spec, T const &object)
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.
bool active() const
Check if service of type T is currently active.
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
constexpr o2::header::DataDescription gDataDescriptionRawData
constexpr o2::header::DataOrigin gDataOriginEMC
uint8_t itsSharedClusterMap uint8_t
framework::DataProcessorSpec getRawToCellConverterSpec(bool askDISTSTF, bool disableDecodingError, bool disableTriggerReconstruction, int subspecification)
Creating DataProcessorSpec for the EMCAL Cell Converter Spec.
constexpr int getErrorCodeFromGainError(GainError_t errortype)
Convert gain error type into numberic representation.
@ LGNOHG
LG found below HG/LG transition, HG missing.
@ HGNOLG
HG saturated, LG missing.
@ CELL_RANGE_EXCEED
Requested cell value exceeding allowed cell range.
@ CELL_INDEX_NEGATIVE
Requested cell value negative.
constexpr int getErrorCodeFromGeometryError(GeometryError_t errortype)
Convert geometry error type into numberic representation.
constexpr int getErrorCodeFromTRUDecodingError(TRUDecodingError_t error)
Convert TRU decoding error type into numberic representation.
@ TRU_INDEX_INVALID
TRU index invalid.
@ FASTOR_STARTTIME_INVALID
FastOr stattime is larger than 14.
@ PATCH_INDEX_INVALID
Patch index outside range.
@ EMCAL_LEDREFS
Number of LEDs (reference/monitors) per module for EMCAL; one per StripModule.
ChannelType_t
Type of a raw data channel.
@ HIGH_GAIN
High gain channel.
@ LOW_GAIN
Low gain channel.
@ LEDMON
LED monitor channel.
std::vector< ConfigParamSpec > Options
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
uint16_t bc
bunch crossing ID of interaction
int64_t differenceInBC(const InteractionRecord &other) const
static o2::header::DataHeader::PayloadSizeType getPayloadSize(const DataRef &ref)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Cell > cells