File indexing completed on 2024-09-11 04:32:30
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
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
0033
0034
0035 return numerator;
0036 }
0037
0038
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
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
0072 TH2F* hist = dynamic_cast<TH2F*>(denominator->getTH2F()->Clone(name.c_str()));
0073 return ibooker.book2D(name, hist);
0074 }
0075
0076
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";
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_) << "";
0096 return std::make_tuple(false, 0, 0);
0097 }
0098
0099 return std::make_tuple(true, *first_chamber, *last_chamber);
0100 }
0101
0102
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";
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_) << "";
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_) << "";
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
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_) << "";
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
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
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
0252 return mask;
0253 }
0254 }
0255 }
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 }
0267 }
0268
0269 return not mask;
0270 }
0271
0272
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
0302 void GEMDQMEfficiencySourceBase::fillMEWithinLimits(MonitorElement* me, const double x) {
0303 if (me == nullptr) {
0304 edm::LogError(kLogCategory_) << "MonitorElement is nullptr";
0305 return;
0306 }
0307
0308 const TAxis* x_axis = me->getTH1F()->GetXaxis();
0309 me->Fill(clampWithAxis(x, x_axis));
0310 }
0311
0312
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
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 }