Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-06-28 02:36:14

0001 #include "DataFormats/Common/interface/Handle.h"
0002 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0003 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0004 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0005 #include "DataFormats/Scalers/interface/DcsStatus.h"
0006 #include "DataFormats/OnlineMetaData/interface/DCSRecord.h"
0007 #include "FWCore/Framework/interface/Event.h"
0008 #include "FWCore/Framework/interface/stream/EDFilter.h"
0009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0013 
0014 #include <type_traits>  // for std::is_same
0015 
0016 class DetectorStateFilter : public edm::stream::EDFilter<> {
0017 public:
0018   DetectorStateFilter(const edm::ParameterSet&);
0019   ~DetectorStateFilter() override;
0020 
0021   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0022 
0023 private:
0024   bool filter(edm::Event&, edm::EventSetup const&) override;
0025 
0026   const bool verbose_;
0027   uint64_t nEvents_, nSelectedEvents_;
0028   bool detectorOn_;
0029   const std::string detectorType_;
0030   const std::vector<std::string> combinations_;  // Vector of strings specifying accepted combinations
0031   const edm::EDGetTokenT<DcsStatusCollection> dcsStatusLabel_;
0032   const edm::EDGetTokenT<DCSRecord> dcsRecordToken_;
0033 
0034   template <typename T>
0035   bool checkSubdet(const T& DCS, const int index);
0036   template <typename T>
0037   bool checkDCS(const T& DCS);
0038   template <typename T>
0039   bool checkDCSCombinations(const T& DCS, const std::vector<std::string>& combinations);
0040 
0041   bool checkDCSStatus(const DcsStatusCollection& dcsStatus);
0042   bool checkDCSRecord(const DCSRecord& dcsRecord);
0043 };
0044 
0045 //
0046 // auxilliary enum
0047 //
0048 namespace DetStateFilter {
0049   enum parts { BPix = 0, FPix = 1, TIBTID = 2, TOB = 3, TECp = 4, TECm = 5, Invalid };
0050 
0051   // Map from string to enum
0052   parts partNameToEnum(const std::string& partName) {
0053     if (partName == "BPix")
0054       return BPix;
0055     if (partName == "FPix")
0056       return FPix;
0057     if (partName == "TIBTID")
0058       return TIBTID;
0059     if (partName == "TOB")
0060       return TOB;
0061     if (partName == "TECp")
0062       return TECp;
0063     if (partName == "TECm")
0064       return TECm;
0065     return Invalid;
0066   }
0067 
0068   // Single function to parse and split the vector of strings
0069   std::vector<std::vector<std::string>> parseAndSplit(const std::vector<std::string>& input, char delimiter) {
0070     std::vector<std::vector<std::string>> parsedResult;
0071 
0072     for (const auto& str : input) {
0073       std::vector<std::string> splitStrings;
0074       std::stringstream ss(str);
0075       std::string item;
0076 
0077       while (std::getline(ss, item, delimiter)) {
0078         splitStrings.push_back(item);
0079       }
0080 
0081       parsedResult.push_back(splitStrings);
0082     }
0083 
0084     return parsedResult;
0085   }
0086 }  // namespace DetStateFilter
0087 
0088 //
0089 // -- Constructor
0090 //
0091 DetectorStateFilter::DetectorStateFilter(const edm::ParameterSet& pset)
0092     : verbose_(pset.getUntrackedParameter<bool>("DebugOn", false)),
0093       detectorType_(pset.getUntrackedParameter<std::string>("DetectorType", "sistrip")),
0094       combinations_(pset.getUntrackedParameter<std::vector<std::string>>("acceptedCombinations")),
0095       dcsStatusLabel_(consumes<DcsStatusCollection>(
0096           pset.getUntrackedParameter<edm::InputTag>("DcsStatusLabel", edm::InputTag("scalersRawToDigi")))),
0097       dcsRecordToken_(consumes<DCSRecord>(
0098           pset.getUntrackedParameter<edm::InputTag>("DCSRecordLabel", edm::InputTag("onlineMetaDataDigis")))) {
0099   nEvents_ = 0;
0100   nSelectedEvents_ = 0;
0101   detectorOn_ = false;
0102 }
0103 
0104 //
0105 // -- Destructor
0106 //
0107 DetectorStateFilter::~DetectorStateFilter() = default;
0108 
0109 template <typename T>
0110 //*********************************************************************//
0111 bool DetectorStateFilter::checkSubdet(const T& DCS, const int index)
0112 //*********************************************************************//
0113 {
0114   std::vector<int> dcsStatusParts = {
0115       DcsStatus::BPIX, DcsStatus::FPIX, DcsStatus::TIBTID, DcsStatus::TOB, DcsStatus::TECp, DcsStatus::TECm};
0116 
0117   std::vector<DCSRecord::Partition> dcsRecordParts = {DCSRecord::Partition::BPIX,
0118                                                       DCSRecord::Partition::FPIX,
0119                                                       DCSRecord::Partition::TIBTID,
0120                                                       DCSRecord::Partition::TOB,
0121                                                       DCSRecord::Partition::TECp,
0122                                                       DCSRecord::Partition::TECm};
0123 
0124   if constexpr (std::is_same_v<T, DcsStatusCollection>) {
0125     return (DCS)[0].ready(dcsStatusParts[index]);
0126   } else if constexpr (std::is_same_v<T, DCSRecord>) {
0127     return DCS.highVoltageReady(dcsRecordParts[index]);
0128   } else {
0129     edm::LogError("DetectorStatusFilter")
0130         << __FILE__ << " " << __LINE__ << " passed a wrong object type, cannot deduce DCS information.\n"
0131         << " returning true" << std::endl;
0132     return true;
0133   }
0134 }
0135 
0136 template <typename T>
0137 bool
0138 //*********************************************************************//
0139 DetectorStateFilter::checkDCS(const T& DCS)
0140 //*********************************************************************//
0141 {
0142   bool accepted = false;
0143   if (detectorType_ == "pixel") {
0144     if (checkSubdet(DCS, DetStateFilter::BPix) && checkSubdet(DCS, DetStateFilter::FPix)) {
0145       accepted = true;
0146       nSelectedEvents_++;
0147     } else {
0148       accepted = false;
0149     }
0150     if (verbose_) {
0151       edm::LogInfo("DetectorStatusFilter")
0152           << " Total Events " << nEvents_ << " Selected Events " << nSelectedEvents_ << " DCS States : "
0153           << " BPix " << checkSubdet(DCS, DetStateFilter::BPix) << " FPix " << checkSubdet(DCS, DetStateFilter::FPix)
0154           << " Detector State " << accepted << std::endl;
0155     }
0156   } else if (detectorType_ == "sistrip") {
0157     if (checkSubdet(DCS, DetStateFilter::TIBTID) && checkSubdet(DCS, DetStateFilter::TOB) &&
0158         checkSubdet(DCS, DetStateFilter::TECp) && checkSubdet(DCS, DetStateFilter::TECm)) {
0159       accepted = true;
0160       nSelectedEvents_++;
0161     } else {
0162       accepted = false;
0163     }
0164     if (verbose_) {
0165       edm::LogInfo("DetectorStatusFilter")
0166           << " Total Events " << nEvents_ << " Selected Events " << nSelectedEvents_ << " DCS States : "
0167           << " TEC- " << checkSubdet(DCS, DetStateFilter::TECm) << " TEC+ " << checkSubdet(DCS, DetStateFilter::TECp)
0168           << " TIB/TID " << checkSubdet(DCS, DetStateFilter::TIBTID) << " TOB " << checkSubdet(DCS, DetStateFilter::TOB)
0169           << " Detector States " << accepted << std::endl;
0170     }
0171   } else {
0172     throw cms::Exception("Wrong Configuration")
0173         << "Stated DetectorType '" << detectorType_
0174         << "' is neither 'pixel' or 'sistrip', please check your configuration!";
0175   }
0176   return accepted;
0177 }
0178 
0179 template <typename T>
0180 bool
0181 //*********************************************************************//
0182 DetectorStateFilter::checkDCSCombinations(const T& DCS, const std::vector<std::string>& combinations)
0183 //*********************************************************************//
0184 {
0185   // check that the configuration is sound
0186   if (detectorType_ != "pixel" && detectorType_ != "sistrip") {
0187     throw cms::Exception("Wrong Configuration")
0188         << "Stated DetectorType '" << detectorType_
0189         << "' is neither 'pixel' or 'sistrip', please check your configuration!";
0190   }
0191 
0192   bool accepted = false;
0193 
0194   // first get the combinations to check
0195   std::vector<std::vector<std::string>> vec_to_check = DetStateFilter::parseAndSplit(combinations, '+');
0196 
0197   if (verbose_) {
0198     edm::LogInfo("DetectorStatusFilter") << "Debug Mode: Printing all possible combinations";
0199     for (const auto& combination : vec_to_check) {
0200       std::string combinationStr;
0201       for (const auto& part : combination) {
0202         if (!combinationStr.empty()) {
0203           combinationStr += " + ";
0204         }
0205         combinationStr += part;
0206       }
0207       edm::LogInfo("DetectorStatusFilter") << "Combination: " << combinationStr;
0208     }
0209   }
0210 
0211   // Initialize a vector<bool> to store the pass results
0212   std::vector<bool> bitset(vec_to_check.size(), false);
0213   for (size_t i = 0; i < vec_to_check.size(); ++i) {
0214     const auto& subdetectors = vec_to_check[i];
0215     std::vector<DetStateFilter::parts> partsToCheck;
0216     partsToCheck.reserve(subdetectors.size());
0217 
0218     // fill vector of parts to check
0219     for (const auto& sub : subdetectors) {
0220       DetStateFilter::parts partEnum = DetStateFilter::partNameToEnum(sub);
0221       if (partEnum == DetStateFilter::Invalid) {
0222         throw cms::Exception("InvalidSubdetector", "Subdetector name '" + sub + "' is invalid.");
0223       }
0224       partsToCheck.push_back(partEnum);
0225     }
0226 
0227     if (detectorType_ == "pixel") {
0228       for (const auto& part : partsToCheck) {
0229         if (part >= DetStateFilter::TIBTID) {
0230           throw cms::Exception("InvalidSubdetector", "Detector type 'pixel' cannot have partitions TIBTID or larger");
0231         }
0232       }
0233     } else if (detectorType_ == "sistrip") {
0234       for (const auto& part : partsToCheck) {
0235         if (part < DetStateFilter::TIBTID) {
0236           throw cms::Exception("InvalidSubdetector",
0237                                "Detector type 'strip' cannot have partitions smaller than TIBTID");
0238         }
0239       }
0240     }
0241 
0242     // Use std::all_of to compute the logical AND of checkSubdet(DCS, part)
0243     bool passes = std::all_of(partsToCheck.begin(), partsToCheck.end(), [this, &DCS](DetStateFilter::parts part) {
0244       return checkSubdet(DCS, part);
0245     });
0246 
0247     // Set the corresponding bit in bitset
0248     bitset[i] = passes;
0249   }
0250 
0251   // Set the value of accepted to the OR of all the bits in the bitset
0252   accepted = std::any_of(bitset.begin(), bitset.end(), [](bool bit) { return bit; });
0253 
0254   if (accepted)
0255     nSelectedEvents_++;
0256 
0257   if (detectorType_ == "pixel") {
0258     if (verbose_) {
0259       edm::LogInfo("DetectorStatusFilter")
0260           << " Total Events " << nEvents_ << " Selected Events " << nSelectedEvents_ << " DCS States : "
0261           << " BPix " << checkSubdet(DCS, DetStateFilter::BPix) << " FPix " << checkSubdet(DCS, DetStateFilter::FPix)
0262           << " Detector State " << accepted << std::endl;
0263     }
0264   } else if (detectorType_ == "sistrip") {
0265     if (verbose_) {
0266       edm::LogInfo("DetectorStatusFilter")
0267           << " Total Events " << nEvents_ << " Selected Events " << nSelectedEvents_ << " DCS States : "
0268           << " TEC- " << checkSubdet(DCS, DetStateFilter::TECm) << " TEC+ " << checkSubdet(DCS, DetStateFilter::TECp)
0269           << " TIB/TID " << checkSubdet(DCS, DetStateFilter::TIBTID) << " TOB " << checkSubdet(DCS, DetStateFilter::TOB)
0270           << " Detector States " << accepted << std::endl;
0271     }
0272   }
0273 
0274   return accepted;
0275 }
0276 
0277 //*********************************************************************//
0278 bool DetectorStateFilter::filter(edm::Event& evt, edm::EventSetup const& es)
0279 //*********************************************************************//
0280 {
0281   nEvents_++;
0282   // Check Detector state Only for Real Data and return true for MC
0283   if (evt.isRealData()) {
0284     edm::Handle<DcsStatusCollection> dcsStatus;
0285     evt.getByToken(dcsStatusLabel_, dcsStatus);
0286     edm::Handle<DCSRecord> dcsRecord;
0287     evt.getByToken(dcsRecordToken_, dcsRecord);
0288 
0289     if (dcsStatus.isValid() && !dcsStatus->empty()) {
0290       // if the old style DCS status is valid (Run1 + Run2)
0291       if (combinations_.empty()) {
0292         detectorOn_ = checkDCS(*dcsStatus);
0293       } else {
0294         detectorOn_ = checkDCSCombinations(*dcsStatus, combinations_);
0295       }
0296     } else if (dcsRecord.isValid()) {
0297       // in case of real data check for DCSRecord content (Run >=3)
0298       if (combinations_.empty()) {
0299         detectorOn_ = checkDCS(*dcsRecord);
0300       } else {
0301         detectorOn_ = checkDCSCombinations(*dcsRecord, combinations_);
0302       }
0303     } else {
0304       edm::LogError("DetectorStatusFilter")
0305           << "Error! can't get the products, neither DCSRecord, nor scalersRawToDigi: accept in any case!";
0306       detectorOn_ = true;
0307     }
0308   } else {
0309     detectorOn_ = true;
0310     nSelectedEvents_++;
0311     if (verbose_) {
0312       edm::LogInfo("DetectorStatusFilter") << "Total MC Events " << nEvents_ << " Selected Events " << nSelectedEvents_
0313                                            << " Detector States " << detectorOn_ << std::endl;
0314     }
0315   }
0316   return detectorOn_;
0317 }
0318 
0319 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0320 void DetectorStateFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0321   edm::ParameterSetDescription desc;
0322   desc.setComment("filters on the HV status of the Tracker (either pixels or strips)");
0323   desc.addUntracked<bool>("DebugOn", false)->setComment("activates debugging");
0324   desc.addUntracked<std::string>("DetectorType", "sistrip")->setComment("either strips or pixels");
0325   desc.addUntracked<std::vector<std::string>>("acceptedCombinations", {});
0326   desc.addUntracked<edm::InputTag>("DcsStatusLabel", edm::InputTag("scalersRawToDigi"))
0327       ->setComment("event data for DCS (Run2)");
0328   desc.addUntracked<edm::InputTag>("DCSRecordLabel", edm::InputTag("onlineMetaDataDigis"))
0329       ->setComment("event data for DCS (Run3)");
0330   descriptions.add("_detectorStateFilter", desc);
0331 }
0332 
0333 #include "FWCore/Framework/interface/MakerMacros.h"
0334 DEFINE_FWK_MODULE(DetectorStateFilter);