3131#include " DetectorsRaw/RDHUtils.h"
3232#include " EMCALBase/Geometry.h"
3333#include " EMCALBase/Mapper.h"
34+ #include " EMCALCalib/FeeDCS.h"
3435#include " EMCALReconstruction/CaloFitResults.h"
3536#include " EMCALReconstruction/Bunch.h"
3637#include " EMCALReconstruction/CaloRawFitterStandard.h"
@@ -93,8 +94,11 @@ void RawToCellConverterSpec::init(framework::InitContext& ctx)
9394
9495 mMergeLGHG = !ctx.options ().get <bool >(" no-mergeHGLG" );
9596 mDisablePedestalEvaluation = ctx.options ().get <bool >(" no-evalpedestal" );
97+ mActiveLinkCheck = !ctx.options ().get <bool >(" no-checkactivelinks" );
9698
9799 LOG (info) << " Running gain merging mode: " << (mMergeLGHG ? " yes" : " no" );
100+ LOG (info) << " Checking for active links: " << (mActiveLinkCheck ? " yes" : " no" );
101+ LOG (info) << " Calculate pedestals: " << (mDisablePedestalEvaluation ? " no" : " yes" );
98102 LOG (info) << " Using L0LM delay: " << o2::ctp::TriggerOffsetsParam::Instance ().LM_L0 << " BCs" ;
99103
100104 mRawFitter ->setAmpCut (mNoiseThreshold );
@@ -107,6 +111,9 @@ void RawToCellConverterSpec::run(framework::ProcessingContext& ctx)
107111 mCalibHandler ->checkUpdates (ctx);
108112 updateCalibrationObjects ();
109113
114+ // container with BCid and feeID
115+ std::unordered_map<int64_t , std::bitset<46 >> bcFreq;
116+
110117 double timeshift = RecoParam::Instance ().getCellTimeShiftNanoSec (); // subtract offset in ns in order to center the time peak around the nominal delay
111118 constexpr auto originEMC = o2::header::gDataOriginEMC ;
112119 constexpr auto descRaw = o2::header::gDataDescriptionRawData ;
@@ -181,6 +188,9 @@ void RawToCellConverterSpec::run(framework::ProcessingContext& ctx)
181188 continue ;
182189 }
183190 }
191+
192+ bcFreq[currentIR.toLong ()].set (feeID, true );
193+
184194 // Correct the cell time for the bc mod 4 (LHC: 40 MHz clock - ALTRO: 10 MHz clock)
185195 // Convention: All times shifted with respect to BC % 4 = 0 for trigger BC
186196 // Attention: Correction only works for the permutation (0 1 2 3) of the BC % 4, if the permutation is
@@ -315,6 +325,29 @@ void RawToCellConverterSpec::run(framework::ProcessingContext& ctx)
315325 }
316326 }
317327
328+ if (mActiveLinkCheck ) {
329+ // build expected active mask from DCS
330+ FeeDCS* feedcs = mCalibHandler ->getFEEDCS ();
331+ auto list0 = feedcs->getDDLlist0 ();
332+ auto list1 = feedcs->getDDLlist1 ();
333+ // links 21 and 39 do not exist, but they are set active in DCS
334+ list0.set (21 , false );
335+ list1.set (7 , false );
336+ // must be 0x307FFFDFFFFF if all links are active
337+ std::bitset<46 > bitSetActiveLinks ((list1.to_ullong () << 32 ) + list0.to_ullong ());
338+
339+ // Check if we have received pages from all active links
340+ // If not we cannot trust the timeframe and must send
341+ // empty containers
342+ for (const auto & [globalBC, activelinks] : bcFreq) {
343+ if (activelinks != bitSetActiveLinks) {
344+ LOG (error) << " Not all EMC active links contributed in global BCid=" << globalBC << " : mask=" << (activelinks ^ bitSetActiveLinks);
345+ sendData (ctx, mOutputCells , mOutputTriggerRecords , mOutputDecoderErrors );
346+ return ;
347+ }
348+ }
349+ }
350+
318351 // Loop over BCs, sort cells with increasing tower ID and write to output containers
319352 RecoContainerReader eventIterator (mCellHandler );
320353 while (eventIterator.hasNext ()) {
@@ -355,9 +388,9 @@ void RawToCellConverterSpec::updateCalibrationObjects()
355388 LOG (info) << " RecoParams updated" ;
356389 o2::emcal::RecoParam::Instance ().printKeyValues (true , true );
357390 }
358- // if (mCalibHandler->hasUpdateFEEDCS()) {
359- // LOG(info) << "DCS params updated";
360- // }
391+ if (mCalibHandler ->hasUpdateFEEDCS ()) {
392+ LOG (info) << " DCS params updated" ;
393+ }
361394}
362395
363396bool RawToCellConverterSpec::isLostTimeframe (framework::ProcessingContext& ctx) const
@@ -677,17 +710,19 @@ o2::framework::DataProcessorSpec o2::emcal::reco_workflow::getRawToCellConverter
677710 // CCDB objects
678711 auto calibhandler = std::make_shared<o2::emcal::CalibLoader>();
679712 calibhandler->enableRecoParams (true );
680- // calibhandler->enableFEEDCS(true);
713+ calibhandler->enableFEEDCS (true );
681714 calibhandler->defineInputSpecs (inputs);
682715
683- return o2::framework::DataProcessorSpec{" EMCALRawToCellConverterSpec" ,
684- inputs,
685- outputs,
686- o2::framework::adaptFromTask<o2::emcal::reco_workflow::RawToCellConverterSpec>(subspecification, !disableDecodingErrors, calibhandler),
687- o2::framework::Options{
688- {" fitmethod" , o2::framework::VariantType::String, " gamma2" , {" Fit method (standard or gamma2)" }},
689- {" maxmessage" , o2::framework::VariantType::Int, 100 , {" Max. amout of error messages to be displayed" }},
690- {" printtrailer" , o2::framework::VariantType::Bool, false , {" Print RCU trailer (for debugging)" }},
691- {" no-mergeHGLG" , o2::framework::VariantType::Bool, false , {" Do not merge HG and LG channels for same tower" }},
692- {" no-evalpedestal" , o2::framework::VariantType::Bool, false , {" Disable pedestal evaluation" }}}};
716+ return o2::framework::DataProcessorSpec{
717+ " EMCALRawToCellConverterSpec" ,
718+ inputs,
719+ outputs,
720+ o2::framework::adaptFromTask<o2::emcal::reco_workflow::RawToCellConverterSpec>(subspecification, !disableDecodingErrors, calibhandler),
721+ o2::framework::Options{
722+ {" fitmethod" , o2::framework::VariantType::String, " gamma2" , {" Fit method (standard or gamma2)" }},
723+ {" maxmessage" , o2::framework::VariantType::Int, 100 , {" Max. amout of error messages to be displayed" }},
724+ {" printtrailer" , o2::framework::VariantType::Bool, false , {" Print RCU trailer (for debugging)" }},
725+ {" no-mergeHGLG" , o2::framework::VariantType::Bool, false , {" Do not merge HG and LG channels for same tower" }},
726+ {" no-checkactivelinks" , o2::framework::VariantType::Bool, false , {" Do not check for active links per BC" }},
727+ {" no-evalpedestal" , o2::framework::VariantType::Bool, false , {" Disable pedestal evaluation" }}}};
693728}
0 commit comments