Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:07:27

0001 #include "DQM/GEM/interface/GEMDQMEfficiencySourceBase.h"
0002 
0003 #include "FWCore/Utilities/interface/Likely.h"
0004 
0005 #include "TPRegexp.h"
0006 
0007 GEMDQMEfficiencySourceBase::GEMDQMEfficiencySourceBase(const edm::ParameterSet& ps)
0008     : kGEMOHStatusCollectionToken_(
0009           consumes<GEMOHStatusCollection>(ps.getUntrackedParameter<edm::InputTag>("ohStatusTag"))),
0010       kGEMVFATStatusCollectionToken_(
0011           consumes<GEMVFATStatusCollection>(ps.getUntrackedParameter<edm::InputTag>("vfatStatusTag"))),
0012       kMonitorGE11_(ps.getUntrackedParameter<bool>("monitorGE11")),
0013       kMonitorGE21_(ps.getUntrackedParameter<bool>("monitorGE21")),
0014       kMonitorGE0_(ps.getUntrackedParameter<bool>("monitorGE0")),
0015       kMaskChamberWithError_(ps.getUntrackedParameter<bool>("maskChamberWithError")),
0016       kLogCategory_(ps.getUntrackedParameter<std::string>("logCategory")) {}
0017 
0018 // NOTE GEMDQMEfficiencyClientBase::parseEfficiencySourceName
0019 std::string GEMDQMEfficiencySourceBase::nameNumerator(const std::string& denominator) {
0020   const bool success = TPRegexp("\\w+_GE\\d1-(P|M)[0-9\\-]*").MatchB(denominator);
0021   if (not success) {
0022     edm::LogError(kLogCategory_) << "denominator name not understood: " << denominator;
0023     return std::string{};
0024   }
0025 
0026   const std::string delimiter = "_";
0027   const std::string::size_type delimiter_pos = denominator.find_last_of(delimiter);
0028   const std::string var_name = denominator.substr(0, delimiter_pos);
0029   const std::string gem_name = denominator.substr(delimiter_pos + 1);
0030 
0031   const std::string numerator = var_name + "_match" + delimiter + gem_name;
0032   // e.g. denominator_name = "prop_GE11-P-L1"
0033   // tokens = {"prop", "11-P-L1"}
0034 
0035   return numerator;
0036 }
0037 
0038 // TODO doc
0039 dqm::impl::MonitorElement* GEMDQMEfficiencySourceBase::bookNumerator1D(DQMStore::IBooker& ibooker,
0040                                                                        MonitorElement* denominator) {
0041   if (denominator == nullptr) {
0042     edm::LogError(kLogCategory_) << "denominator is nullptr";
0043     return nullptr;
0044   }
0045 
0046   const std::string name = nameNumerator(denominator->getName());
0047   if (name.empty()) {
0048     edm::LogError(kLogCategory_) << "denominator's name is " << denominator->getName()
0049                                  << " but nameNumerator returns an empty string";
0050     return nullptr;
0051   }
0052   TH1F* hist = dynamic_cast<TH1F*>(denominator->getTH1F()->Clone(name.c_str()));
0053   return ibooker.book1D(name, hist);
0054 }
0055 
0056 // TODO doc
0057 dqm::impl::MonitorElement* GEMDQMEfficiencySourceBase::bookNumerator2D(DQMStore::IBooker& ibooker,
0058                                                                        MonitorElement* denominator) {
0059   if (denominator == nullptr) {
0060     edm::LogError(kLogCategory_) << "denominator is nullptr";
0061     return nullptr;
0062   }
0063 
0064   const std::string name = nameNumerator(denominator->getName());
0065   if (name.empty()) {
0066     edm::LogError(kLogCategory_) << "denominator's name is " << denominator->getName()
0067                                  << " but nameNumerator returns an empty string";
0068     return nullptr;
0069   }
0070 
0071   // TODO check if getTH2F is not None
0072   TH2F* hist = dynamic_cast<TH2F*>(denominator->getTH2F()->Clone(name.c_str()));
0073   return ibooker.book2D(name, hist);
0074 }
0075 
0076 // TODO docs
0077 std::tuple<bool, int, int> GEMDQMEfficiencySourceBase::getChamberRange(const GEMStation* station) {
0078   if (station == nullptr) {
0079     return std::make_tuple(false, 0, 0);
0080   }
0081 
0082   const std::vector<const GEMSuperChamber*> superchamber_vec = station->superChambers();
0083   if (not checkRefs(superchamber_vec)) {
0084     edm::LogError(kLogCategory_) << "GEMStation::superChambers";  // FIXME
0085     return std::make_tuple(false, 0, 0);
0086   }
0087 
0088   std::vector<int> id_vec;
0089   std::transform(superchamber_vec.begin(),
0090                  superchamber_vec.end(),
0091                  std::back_inserter(id_vec),
0092                  [](const GEMSuperChamber* superchamber) -> int { return superchamber->id().chamber(); });
0093   const auto [first_chamber, last_chamber] = std::minmax_element(id_vec.begin(), id_vec.end());
0094   if ((first_chamber == id_vec.end()) or (last_chamber == id_vec.end())) {
0095     edm::LogError(kLogCategory_) << "";  // TODO
0096     return std::make_tuple(false, 0, 0);
0097   }
0098 
0099   return std::make_tuple(true, *first_chamber, *last_chamber);
0100 }
0101 
0102 // TODO docs
0103 std::tuple<bool, int, int> GEMDQMEfficiencySourceBase::getEtaPartitionRange(const GEMStation* station) {
0104   if (station == nullptr) {
0105     return std::make_tuple(false, 0, 0);
0106   }
0107 
0108   const std::vector<const GEMSuperChamber*> superchamber_vec = station->superChambers();
0109   if (not checkRefs(superchamber_vec)) {
0110     edm::LogError(kLogCategory_) << "GEMStation::superChambers";  // FIXME
0111     return std::make_tuple(false, 0, 0);
0112   }
0113 
0114   const std::vector<const GEMChamber*> chamber_vec = superchamber_vec.front()->chambers();
0115   if (not checkRefs(chamber_vec)) {
0116     edm::LogError(kLogCategory_) << "";  // TODO
0117     return std::make_tuple(false, 0, 0);
0118   }
0119   const std::vector<const GEMEtaPartition*> eta_partition_vec = chamber_vec.front()->etaPartitions();
0120   if (not checkRefs(eta_partition_vec)) {
0121     edm::LogError(kLogCategory_) << "";  // TODO
0122     return std::make_tuple(false, 0, 0);
0123   }
0124 
0125   std::vector<int> ieta_vec;
0126   std::transform(eta_partition_vec.begin(),
0127                  eta_partition_vec.end(),
0128                  std::back_inserter(ieta_vec),
0129                  [](const GEMEtaPartition* each) -> int { return each->id().ieta(); });
0130   const auto [first_ieta, last_ieta] = std::minmax_element(ieta_vec.begin(), ieta_vec.end());
0131   if ((first_ieta == ieta_vec.end()) or (last_ieta == ieta_vec.end())) {
0132     edm::LogError(kLogCategory_) << "failed to find minmax";
0133     return std::make_tuple(false, 0, 0);
0134   }
0135 
0136   return std::make_tuple(true, *first_ieta, *last_ieta);
0137 }
0138 
0139 // TODO docs
0140 dqm::impl::MonitorElement* GEMDQMEfficiencySourceBase::bookChamber(DQMStore::IBooker& ibooker,
0141                                                                    const TString& name,
0142                                                                    const TString& title,
0143                                                                    const GEMStation* station) {
0144   if (station == nullptr) {
0145     edm::LogError(kLogCategory_) << "";  // TODO
0146     return nullptr;
0147   }
0148 
0149   auto [success, first_chamber, last_chamber] = getChamberRange(station);
0150   if (not success) {
0151     edm::LogError(kLogCategory_) << "failed to get chambers: " << station->getName();
0152     return nullptr;
0153   }
0154 
0155   const double xlow = first_chamber - 0.5;
0156   const double xup = last_chamber + 0.5;
0157   const int nbinsx = last_chamber - first_chamber + 1;
0158 
0159   MonitorElement* me = ibooker.book1D(name, title, nbinsx, xlow, xup);
0160   me->setAxisTitle("Chamber", 1);
0161 
0162   for (int chamber = first_chamber; chamber <= last_chamber; chamber++) {
0163     const std::string label = std::to_string(chamber);
0164     me->setBinLabel(chamber, label, 1);
0165   }
0166 
0167   return me;
0168 }
0169 
0170 // TODO docs
0171 dqm::impl::MonitorElement* GEMDQMEfficiencySourceBase::bookChamberEtaPartition(DQMStore::IBooker& ibooker,
0172                                                                                const TString& name,
0173                                                                                const TString& title,
0174                                                                                const GEMStation* station) {
0175   if (station == nullptr) {
0176     edm::LogError(kLogCategory_) << "station is nullptr";
0177     return nullptr;
0178   }
0179 
0180   auto [chamber_success, first_chamber, last_chamber] = getChamberRange(station);
0181   if (not chamber_success) {
0182     edm::LogError(kLogCategory_) << "getChamberRange failed";
0183     return nullptr;
0184   }
0185 
0186   auto [ieta_success, first_ieta, last_ieta] = getEtaPartitionRange(station);
0187   if (not ieta_success) {
0188     edm::LogError(kLogCategory_) << "getEtaPartitionRange failed";
0189     return nullptr;
0190   }
0191 
0192   const double xlow = first_chamber - 0.5;
0193   const double xup = last_chamber + 0.5;
0194   const int nbinsx = last_chamber - first_chamber + 1;
0195 
0196   const double ylow = first_ieta - 0.5;
0197   const double yup = last_ieta + 0.5;
0198   const int nbinsy = last_ieta - first_ieta + 1;
0199 
0200   MonitorElement* me = ibooker.book2D(name, title, nbinsx, xlow, xup, nbinsy, ylow, yup);
0201   me->setAxisTitle("Chamber", 1);
0202   me->setAxisTitle("i#eta", 2);
0203 
0204   for (int chamber = first_chamber; chamber <= last_chamber; chamber++) {
0205     const std::string label = std::to_string(chamber);
0206     me->setBinLabel(chamber, label, 1);
0207   }
0208 
0209   for (int ieta = first_ieta; ieta <= last_ieta; ieta++) {
0210     const std::string label = std::to_string(ieta);
0211     me->setBinLabel(ieta, label, 2);
0212   }
0213 
0214   return me;
0215 }
0216 
0217 // TODO docs
0218 bool GEMDQMEfficiencySourceBase::skipGEMStation(const int station) {
0219   bool skip = false;
0220 
0221   if (station == 0) {
0222     skip = not kMonitorGE0_;
0223 
0224   } else if (station == 1) {
0225     skip = not kMonitorGE11_;
0226 
0227   } else if (station == 2) {
0228     skip = not kMonitorGE21_;
0229 
0230   } else {
0231     edm::LogError(kLogCategory_) << "got an unexpected GEM station " << station << ". skip this station.";
0232     skip = true;
0233   }
0234 
0235   return skip;
0236 }
0237 
0238 bool GEMDQMEfficiencySourceBase::maskChamberWithError(const GEMDetId& chamber_id,
0239                                                       const GEMOHStatusCollection* oh_status_collection,
0240                                                       const GEMVFATStatusCollection* vfat_status_collection) {
0241   const bool mask = true;
0242 
0243   for (auto iter = oh_status_collection->begin(); iter != oh_status_collection->end(); iter++) {
0244     const auto [oh_id, range] = (*iter);
0245     if (chamber_id != oh_id) {
0246       continue;
0247     }
0248 
0249     for (auto oh_status = range.first; oh_status != range.second; oh_status++) {
0250       if (oh_status->isBad()) {
0251         // GEMOHStatus is bad. Mask this chamber.
0252         return mask;
0253       }  // isBad
0254     }    // range
0255   }      // collection
0256 
0257   for (auto iter = vfat_status_collection->begin(); iter != vfat_status_collection->end(); iter++) {
0258     const auto [vfat_id, range] = (*iter);
0259     if (chamber_id != vfat_id.chamberId()) {
0260       continue;
0261     }
0262     for (auto vfat_status = range.first; vfat_status != range.second; vfat_status++) {
0263       if (vfat_status->isBad()) {
0264         return mask;
0265       }
0266     }  // range
0267   }    // collection
0268 
0269   return not mask;
0270 }
0271 
0272 // TODO docs
0273 bool GEMDQMEfficiencySourceBase::hasMEKey(const MEMap& me_map, const GEMDetId& key) {
0274   const bool has_key = me_map.find(key) != me_map.end();
0275 
0276   if UNLIKELY (not has_key) {
0277     const std::string hint = me_map.empty() ? "empty" : me_map.begin()->second->getName();
0278     edm::LogError(kLogCategory_) << "got an invalid key: " << key << ", hint=" << hint;
0279   }
0280   return has_key;
0281 }
0282 
0283 void GEMDQMEfficiencySourceBase::fillME(MEMap& me_map, const GEMDetId& key, const double x) {
0284   if (hasMEKey(me_map, key)) {
0285     me_map[key]->Fill(x);
0286   }
0287 }
0288 
0289 void GEMDQMEfficiencySourceBase::fillME(MEMap& me_map, const GEMDetId& key, const double x, const double y) {
0290   if (hasMEKey(me_map, key)) {
0291     me_map[key]->Fill(x, y);
0292   }
0293 }
0294 
0295 double GEMDQMEfficiencySourceBase::clampWithAxis(const double value, const TAxis* axis) {
0296   const double first_bin_center = axis->GetBinCenter(1);
0297   const double last_bin_center = axis->GetBinCenter(axis->GetNbins());
0298   return std::clamp(value, first_bin_center, last_bin_center);
0299 }
0300 
0301 // https://github.com/cms-sw/cmssw/blob/CMSSW_12_0_0_pre3/DQMOffline/L1Trigger/src/L1TFillWithinLimits.cc
0302 void GEMDQMEfficiencySourceBase::fillMEWithinLimits(MonitorElement* me, const double x) {
0303   if (me == nullptr) {
0304     edm::LogError(kLogCategory_) << "MonitorElement is nullptr";
0305     return;
0306   }
0307   // FIXME assume that GEMDQMEfficiencySourceBase uses only TH1F fo 1d histograms
0308   const TAxis* x_axis = me->getTH1F()->GetXaxis();
0309   me->Fill(clampWithAxis(x, x_axis));
0310 }
0311 
0312 // https://github.com/cms-sw/cmssw/blob/CMSSW_12_0_0_pre3/DQMOffline/L1Trigger/src/L1TFillWithinLimits.cc
0313 void GEMDQMEfficiencySourceBase::fillMEWithinLimits(MonitorElement* me, const double x, const double y) {
0314   if (me == nullptr) {
0315     edm::LogError(kLogCategory_) << "MonitorElement is nullptr";
0316     return;
0317   }
0318   // FIXME assume that GEMDQMEfficiencySourceBase uses only TH2F fo 2d histograms
0319   const TH2F* hist = me->getTH2F();
0320   const TAxis* x_axis = hist->GetXaxis();
0321   const TAxis* y_axis = hist->GetYaxis();
0322 
0323   me->Fill(clampWithAxis(x, x_axis), clampWithAxis(y, y_axis));
0324 }
0325 
0326 void GEMDQMEfficiencySourceBase::fillMEWithinLimits(MEMap& me_map, const GEMDetId& key, const double x) {
0327   if (hasMEKey(me_map, key)) {
0328     fillMEWithinLimits(me_map[key], x);
0329   }
0330 }
0331 
0332 void GEMDQMEfficiencySourceBase::fillMEWithinLimits(MEMap& me_map, const GEMDetId& key, const double x, const double y) {
0333   if (hasMEKey(me_map, key)) {
0334     fillMEWithinLimits(me_map[key], x, y);
0335   }
0336 }