@@ -145,6 +145,17 @@ ReadoutEquipment::ReadoutEquipment(ConfigFile& cfg, std::string cfgEntryPoint, b
145145 cfg.getOptionalValue <int >(cfgEntryPoint + " .rdhCheckDetectorField" , cfgRdhCheckDetectorField);
146146 theLog.log (LogInfoDevel_ (3002 ), " RDH settings: rdhCheckEnabled=%d rdhDumpEnabled=%d rdhDumpErrorEnabled=%d rdhDumpWarningEnabled=%d rdhUseFirstInPageEnabled=%d rdhCheckFirstOrbit=%d rdhCheckDetectorField=%d" , cfgRdhCheckEnabled, cfgRdhDumpEnabled, cfgRdhDumpErrorEnabled, cfgRdhDumpWarningEnabled, cfgRdhUseFirstInPageEnabled, cfgRdhCheckFirstOrbit, cfgRdhCheckDetectorField);
147147
148+ // configuration parameter: | equipment-* | ctpMode | int | 0 | If set, the detector field (CTP run mask) is checked. Incoming data is discarded until a new bit is set, and discarded again after this bit is unset. Automatically implies rdhCheckDetectorField=1 and rdhCheckDetectorField=1. |
149+ cfg.getOptionalValue <int >(cfgEntryPoint + " .ctpMode" , cfgCtpMode);
150+ if (cfgCtpMode) {
151+ theLog.log (LogInfoDevel_ (3002 ), " CTP mode enabled, data will be discarded until CTP run mask changes" );
152+ cfgRdhUseFirstInPageEnabled = 1 ;
153+ cfgRdhCheckDetectorField = 1 ;
154+ }
155+
156+ // configuration parameter: | equipment-* | verbose | int | 0 | If set, extra debug messages may be logged. |
157+ cfg.getOptionalValue <int >(cfgEntryPoint + " .verbose" , cfgVerbose);
158+
148159 if (!cfgDisableTimeframes) {
149160 // configuration parameter: | equipment-* | TFperiod | int | 128 | Duration of a timeframe, in number of LHC orbits. |
150161 int cfgTFperiod = 128 ;
@@ -403,6 +414,12 @@ Thread::CallbackResult ReadoutEquipment::threadCallback(void* arg)
403414 if (ptr->cfgRdhUseFirstInPageEnabled ) {
404415 ptr->processRdh (nextBlock);
405416 }
417+
418+ // discard data immediately if configured to do so
419+ if (ptr->discardData ) {
420+ nextBlock = nullptr ;
421+ continue ;
422+ }
406423
407424 // tag data with equipment Id, if set (will overwrite field if was already set by equipment)
408425 if (ptr->id != undefinedEquipmentId) {
@@ -574,6 +591,12 @@ void ReadoutEquipment::initCounters()
574591 isDefinedLastDetectorField[i] = 0 ;
575592 lastDetectorField[i] = 0 ;
576593 }
594+
595+ ctpRunBit = -1 ;
596+ discardData = 0 ;
597+ if (cfgCtpMode) {
598+ discardData = 1 ;
599+ }
577600};
578601
579602void ReadoutEquipment::finalCounters ()
@@ -692,11 +715,44 @@ int ReadoutEquipment::processRdh(DataBlockContainerReference& block)
692715 if (cfgRdhCheckDetectorField) {
693716 if (isDefinedLastDetectorField[lid]) {
694717 if (h.getDetectorField () != lastDetectorField[lid]) {
695- theLog.log (LogInfoDevel_ (3011 ), " Equipment %s Link %d: change in detector field detected: 0x%X -> 0x%X (orbit 0x%X page offset 0x%X)" , name.c_str (), (int )lid, (int )lastDetectorField[lid], (int )h.getDetectorField (), (int )h.getHbOrbit (), (int )pageOffset);
718+ if (cfgVerbose) {
719+ theLog.log (LogInfoDevel_ (3011 ), " Equipment %s Link %d: change in detector field detected: 0x%X -> 0x%X (orbit 0x%X page offset 0x%X)" ,
720+ name.c_str (), (int )lid, (int )lastDetectorField[lid], (int )h.getDetectorField (), (int )h.getHbOrbit (), (int )pageOffset);
721+ }
696722 hasChanged = 1 ;
723+
724+ if (cfgCtpMode) {
725+ // check how many bits have changed
726+ try {
727+ auto bitsChanged = std::bitset<sizeof (uint32_t )>(h.getDetectorField () ^ lastDetectorField[lid]);
728+ uint32_t nChanged = bitsChanged.count ();
729+ if (nChanged == 1 ) {
730+ int bitChanged = bitsChanged._Find_first ();
731+ bool isSet = std::bitset<sizeof (uint32_t )>(h.getDetectorField ()).test (bitChanged);
732+
733+ // theLog.log(LogInfoDevel_(3011), "bitChanged=%d isSet=%d ctpRunBit=%d discardData=%d", (int)bitChanged, (int)isSet, (int)ctpRunBit, (int)discardData);
734+
735+ if ((ctpRunBit == -1 ) && (isSet) && (discardData == 1 )) {
736+ // start of run detected
737+ ctpRunBit = bitChanged;
738+ discardData = 0 ;
739+ theLog.log (LogInfoDevel_ (3011 ), " Start of run detected (pattern 0x%X bit %d), enabling data" , (int )h.getDetectorField (), (int )bitChanged);
740+ } else if ((ctpRunBit != -1 ) && (!isSet) && (ctpRunBit == bitChanged)) {
741+ // end of run detected
742+ ctpRunBit = -1 ;
743+ discardData = 2 ; // no data on next other run
744+ theLog.log (LogInfoDevel_ (3011 ), " End of run detected (pattern 0x%X bit %d), disabling data" , (int )h.getDetectorField (), (int )bitChanged);
745+ }
746+ }
747+ }
748+ catch (...) {
749+ }
750+ }
697751 }
698752 } else {
699- theLog.log (LogInfoDevel_ (3011 ), " Equipment %s link %d: first detector field : 0x%X" , name.c_str (), (int )lid, (int )h.getDetectorField ());
753+ if (cfgVerbose) {
754+ theLog.log (LogInfoDevel_ (3011 ), " Equipment %s link %d: first detector field : 0x%X" , name.c_str (), (int )lid, (int )h.getDetectorField ());
755+ }
700756 }
701757 lastDetectorField[lid] = h.getDetectorField ();
702758 isDefinedLastDetectorField[lid] = 1 ;
@@ -707,6 +763,13 @@ int ReadoutEquipment::processRdh(DataBlockContainerReference& block)
707763 // retrieve metadata from RDH, if configured to do so
708764 if ((cfgRdhUseFirstInPageEnabled) || (cfgRdhCheckEnabled)) {
709765 RdhHandle h (blockData);
766+
767+ // check detector field first (might enable/disable data discard)
768+ checkChangesInDetectorField (h,0 );
769+ if (discardData) {
770+ return 0 ;
771+ }
772+
710773 if (tagDatablockFromRdh (h, blockHeader) == 0 ) {
711774 blockHeader.isRdhFormat = 1 ;
712775 }
@@ -728,8 +791,6 @@ int ReadoutEquipment::processRdh(DataBlockContainerReference& block)
728791 equipmentLinksData[h.getLinkId ()] += blockHeader.dataSize ;
729792 }
730793
731- // check detector field
732- checkChangesInDetectorField (h,0 );
733794 }
734795
735796 // Dump RDH if configured to do so
0 commit comments