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_;
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
0047
0048 namespace DetStateFilter {
0049 enum parts { BPix = 0, FPix = 1, TIBTID = 2, TOB = 3, TECp = 4, TECm = 5, Invalid };
0050
0051
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
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 }
0087
0088
0089
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
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
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
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
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
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
0243 bool passes = std::all_of(partsToCheck.begin(), partsToCheck.end(), [this, &DCS](DetStateFilter::parts part) {
0244 return checkSubdet(DCS, part);
0245 });
0246
0247
0248 bitset[i] = passes;
0249 }
0250
0251
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
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
0291 if (combinations_.empty()) {
0292 detectorOn_ = checkDCS(*dcsStatus);
0293 } else {
0294 detectorOn_ = checkDCSCombinations(*dcsStatus, combinations_);
0295 }
0296 } else if (dcsRecord.isValid()) {
0297
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
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);