@@ -27,13 +27,16 @@ class DetectorStateFilter : public edm::stream::EDFilter<> {
2727 uint64_t nEvents_, nSelectedEvents_;
2828 bool detectorOn_;
2929 const std::string detectorType_;
30+ const std::vector<std::string> combinations_; // Vector of strings specifying accepted combinations
3031 const edm::EDGetTokenT<DcsStatusCollection> dcsStatusLabel_;
3132 const edm::EDGetTokenT<DCSRecord> dcsRecordToken_;
3233
3334 template <typename T>
3435 bool checkSubdet (const T& DCS, const int index);
3536 template <typename T>
3637 bool checkDCS (const T& DCS);
38+ template <typename T>
39+ bool checkDCSCombinations (const T& DCS, const std::vector<std::string>& combinations);
3740
3841 bool checkDCSStatus (const DcsStatusCollection& dcsStatus);
3942 bool checkDCSRecord (const DCSRecord& dcsRecord);
@@ -44,14 +47,51 @@ class DetectorStateFilter : public edm::stream::EDFilter<> {
4447//
4548namespace DetStateFilter {
4649 enum parts { BPix = 0 , FPix = 1 , TIBTID = 2 , TOB = 3 , TECp = 4 , TECm = 5 , Invalid };
47- }
50+
51+ // Map from string to enum
52+ parts partNameToEnum (const std::string& partName) {
53+ if (partName == " BPix" )
54+ return BPix;
55+ if (partName == " FPix" )
56+ return FPix;
57+ if (partName == " TIBTID" )
58+ return TIBTID;
59+ if (partName == " TOB" )
60+ return TOB;
61+ if (partName == " TECp" )
62+ return TECp;
63+ if (partName == " TECm" )
64+ return TECm;
65+ return Invalid;
66+ }
67+
68+ // Single function to parse and split the vector of strings
69+ std::vector<std::vector<std::string>> parseAndSplit (const std::vector<std::string>& input, char delimiter) {
70+ std::vector<std::vector<std::string>> parsedResult;
71+
72+ for (const auto & str : input) {
73+ std::vector<std::string> splitStrings;
74+ std::stringstream ss (str);
75+ std::string item;
76+
77+ while (std::getline (ss, item, delimiter)) {
78+ splitStrings.push_back (item);
79+ }
80+
81+ parsedResult.push_back (splitStrings);
82+ }
83+
84+ return parsedResult;
85+ }
86+ } // namespace DetStateFilter
4887
4988//
5089// -- Constructor
5190//
5291DetectorStateFilter::DetectorStateFilter (const edm::ParameterSet& pset)
5392 : verbose_(pset.getUntrackedParameter<bool >(" DebugOn" , false )),
5493 detectorType_(pset.getUntrackedParameter<std::string>(" DetectorType" , " sistrip" )),
94+ combinations_(pset.getUntrackedParameter<std::vector<std::string>>(" acceptedCombinations" )),
5595 dcsStatusLabel_(consumes<DcsStatusCollection>(
5696 pset.getUntrackedParameter<edm::InputTag>(" DcsStatusLabel" , edm::InputTag(" scalersRawToDigi" )))),
5797 dcsRecordToken_(consumes<DCSRecord>(
@@ -136,6 +176,104 @@ DetectorStateFilter::checkDCS(const T& DCS)
136176 return accepted;
137177}
138178
179+ template <typename T>
180+ bool
181+ // *********************************************************************//
182+ DetectorStateFilter::checkDCSCombinations (const T& DCS, const std::vector<std::string>& combinations)
183+ // *********************************************************************//
184+ {
185+ // check that the configuration is sound
186+ if (detectorType_ != " pixel" && detectorType_ != " sistrip" ) {
187+ throw cms::Exception (" Wrong Configuration" )
188+ << " Stated DetectorType '" << detectorType_
189+ << " ' is neither 'pixel' or 'sistrip', please check your configuration!" ;
190+ }
191+
192+ bool accepted = false ;
193+
194+ // first get the combinations to check
195+ std::vector<std::vector<std::string>> vec_to_check = DetStateFilter::parseAndSplit (combinations, ' +' );
196+
197+ if (verbose_) {
198+ edm::LogInfo (" DetectorStatusFilter" ) << " Debug Mode: Printing all possible combinations" ;
199+ for (const auto & combination : vec_to_check) {
200+ std::string combinationStr;
201+ for (const auto & part : combination) {
202+ if (!combinationStr.empty ()) {
203+ combinationStr += " + " ;
204+ }
205+ combinationStr += part;
206+ }
207+ edm::LogInfo (" DetectorStatusFilter" ) << " Combination: " << combinationStr;
208+ }
209+ }
210+
211+ // Initialize a vector<bool> to store the pass results
212+ std::vector<bool > bitset (vec_to_check.size (), false );
213+ for (size_t i = 0 ; i < vec_to_check.size (); ++i) {
214+ const auto & subdetectors = vec_to_check[i];
215+ std::vector<DetStateFilter::parts> partsToCheck;
216+ partsToCheck.reserve (subdetectors.size ());
217+
218+ // fill vector of parts to check
219+ for (const auto & sub : subdetectors) {
220+ DetStateFilter::parts partEnum = DetStateFilter::partNameToEnum (sub);
221+ if (partEnum == DetStateFilter::Invalid) {
222+ throw cms::Exception (" InvalidSubdetector" , " Subdetector name '" + sub + " ' is invalid." );
223+ }
224+ partsToCheck.push_back (partEnum);
225+ }
226+
227+ if (detectorType_ == " pixel" ) {
228+ for (const auto & part : partsToCheck) {
229+ if (part >= DetStateFilter::TIBTID) {
230+ throw cms::Exception (" InvalidSubdetector" , " Detector type 'pixel' cannot have partitions TIBTID or larger" );
231+ }
232+ }
233+ } else if (detectorType_ == " sistrip" ) {
234+ for (const auto & part : partsToCheck) {
235+ if (part < DetStateFilter::TIBTID) {
236+ throw cms::Exception (" InvalidSubdetector" ,
237+ " Detector type 'strip' cannot have partitions smaller than TIBTID" );
238+ }
239+ }
240+ }
241+
242+ // Use std::all_of to compute the logical AND of checkSubdet(DCS, part)
243+ bool passes = std::all_of (partsToCheck.begin (), partsToCheck.end (), [this , &DCS](DetStateFilter::parts part) {
244+ return checkSubdet (DCS, part);
245+ });
246+
247+ // Set the corresponding bit in bitset
248+ bitset[i] = passes;
249+ }
250+
251+ // Set the value of accepted to the OR of all the bits in the bitset
252+ accepted = std::any_of (bitset.begin (), bitset.end (), [](bool bit) { return bit; });
253+
254+ if (accepted)
255+ nSelectedEvents_++;
256+
257+ if (detectorType_ == " pixel" ) {
258+ if (verbose_) {
259+ edm::LogInfo (" DetectorStatusFilter" )
260+ << " Total Events " << nEvents_ << " Selected Events " << nSelectedEvents_ << " DCS States : "
261+ << " BPix " << checkSubdet (DCS, DetStateFilter::BPix) << " FPix " << checkSubdet (DCS, DetStateFilter::FPix)
262+ << " Detector State " << accepted << std::endl;
263+ }
264+ } else if (detectorType_ == " sistrip" ) {
265+ if (verbose_) {
266+ edm::LogInfo (" DetectorStatusFilter" )
267+ << " Total Events " << nEvents_ << " Selected Events " << nSelectedEvents_ << " DCS States : "
268+ << " TEC- " << checkSubdet (DCS, DetStateFilter::TECm) << " TEC+ " << checkSubdet (DCS, DetStateFilter::TECp)
269+ << " TIB/TID " << checkSubdet (DCS, DetStateFilter::TIBTID) << " TOB " << checkSubdet (DCS, DetStateFilter::TOB)
270+ << " Detector States " << accepted << std::endl;
271+ }
272+ }
273+
274+ return accepted;
275+ }
276+
139277// *********************************************************************//
140278bool DetectorStateFilter::filter (edm::Event& evt, edm::EventSetup const & es)
141279// *********************************************************************//
@@ -150,10 +288,18 @@ bool DetectorStateFilter::filter(edm::Event& evt, edm::EventSetup const& es)
150288
151289 if (dcsStatus.isValid () && !dcsStatus->empty ()) {
152290 // if the old style DCS status is valid (Run1 + Run2)
153- detectorOn_ = checkDCS (*dcsStatus);
291+ if (combinations_.empty ()) {
292+ detectorOn_ = checkDCS (*dcsStatus);
293+ } else {
294+ detectorOn_ = checkDCSCombinations (*dcsStatus, combinations_);
295+ }
154296 } else if (dcsRecord.isValid ()) {
155297 // in case of real data check for DCSRecord content (Run >=3)
156- detectorOn_ = checkDCS (*dcsRecord);
298+ if (combinations_.empty ()) {
299+ detectorOn_ = checkDCS (*dcsRecord);
300+ } else {
301+ detectorOn_ = checkDCSCombinations (*dcsRecord, combinations_);
302+ }
157303 } else {
158304 edm::LogError (" DetectorStatusFilter" )
159305 << " Error! can't get the products, neither DCSRecord, nor scalersRawToDigi: accept in any case!" ;
@@ -176,6 +322,7 @@ void DetectorStateFilter::fillDescriptions(edm::ConfigurationDescriptions& descr
176322 desc.setComment (" filters on the HV status of the Tracker (either pixels or strips)" );
177323 desc.addUntracked <bool >(" DebugOn" , false )->setComment (" activates debugging" );
178324 desc.addUntracked <std::string>(" DetectorType" , " sistrip" )->setComment (" either strips or pixels" );
325+ desc.addUntracked <std::vector<std::string>>(" acceptedCombinations" , {});
179326 desc.addUntracked <edm::InputTag>(" DcsStatusLabel" , edm::InputTag (" scalersRawToDigi" ))
180327 ->setComment (" event data for DCS (Run2)" );
181328 desc.addUntracked <edm::InputTag>(" DCSRecordLabel" , edm::InputTag (" onlineMetaDataDigis" ))
0 commit comments