File indexing completed on 2023-05-26 22:38:00
0001 #include "DQM/GEM/interface/GEMDQMBase.h"
0002 #include "Geometry/CommonTopologies/interface/GEMStripTopology.h"
0003
0004 using namespace std;
0005 using namespace edm;
0006
0007 GEMDQMBase::GEMDQMBase(const edm::ParameterSet& cfg) : geomToken_(esConsumes<edm::Transition::BeginRun>()) {
0008 std::string strRunType = cfg.getUntrackedParameter<std::string>("runType");
0009
0010 nRunType_ = GEMDQM_RUNTYPE_ONLINE;
0011
0012 if (strRunType == "online") {
0013 nRunType_ = GEMDQM_RUNTYPE_ONLINE;
0014 } else if (strRunType == "offline") {
0015 nRunType_ = GEMDQM_RUNTYPE_OFFLINE;
0016 } else if (strRunType == "relval") {
0017 nRunType_ = GEMDQM_RUNTYPE_RELVAL;
0018 } else if (strRunType == "allplots") {
0019 nRunType_ = GEMDQM_RUNTYPE_ALLPLOTS;
0020 } else {
0021 edm::LogError(log_category_) << "+++ Error : GEM geometry is unavailable on event loop. +++\n";
0022 }
0023
0024 log_category_ = cfg.getUntrackedParameter<std::string>("logCategory");
0025 }
0026
0027 int GEMDQMBase::initGeometry(edm::EventSetup const& iSetup) {
0028 GEMGeometry_ = nullptr;
0029 if (auto handle = iSetup.getHandle(geomToken_)) {
0030 GEMGeometry_ = handle.product();
0031 } else {
0032 edm::LogError(log_category_) << "+++ Error : GEM geometry is unavailable on event loop. +++\n";
0033 return -1;
0034 }
0035
0036 return 0;
0037 }
0038
0039
0040 int GEMDQMBase::getNumEtaPartitions(const GEMStation* station) {
0041 const auto&& superchambers = station->superChambers();
0042 if (not checkRefs(superchambers)) {
0043 edm::LogError(log_category_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl;
0044 return 0;
0045 }
0046
0047 const auto& chambers = superchambers.front()->chambers();
0048 if (not checkRefs(chambers)) {
0049 edm::LogError(log_category_) << "failed to get a valid vector of GEMChamber ptrs" << std::endl;
0050 return 0;
0051 }
0052
0053 return chambers.front()->nEtaPartitions();
0054 }
0055
0056 int GEMDQMBase::loadChambers() {
0057 if (GEMGeometry_ == nullptr)
0058 return -1;
0059 listChamberId_.clear();
0060 mapEtaPartition_.clear();
0061 for (const GEMRegion* region : GEMGeometry_->regions()) {
0062 for (const GEMStation* station : region->stations()) {
0063 for (auto sch : station->superChambers()) {
0064 for (auto pchamber : sch->chambers()) {
0065 GEMDetId gid = pchamber->id();
0066 listChamberId_.push_back(pchamber->id());
0067 for (auto iEta : pchamber->etaPartitions()) {
0068 mapEtaPartition_[gid].push_back(iEta);
0069 }
0070 }
0071 }
0072 }
0073 }
0074
0075
0076 nMaxNumCh_ = 0;
0077 for (const GEMRegion* region : GEMGeometry_->regions()) {
0078 const int region_number = region->region();
0079
0080 for (const GEMStation* station : region->stations()) {
0081 const auto&& superchambers = station->superChambers();
0082
0083 const int station_number = station->station();
0084 const int num_superchambers = (station_number == 1 ? 36 : 18);
0085 const int num_mod = getNumModule(station->station());
0086 const int max_vfat = getMaxVFAT(station->station());
0087 const int num_etas = getNumEtaPartitions(station);
0088 const int num_vfat = num_etas * max_vfat;
0089 const int strip1st = (station_number == 2 ? 1 : 0);
0090 const int num_digi = GEMeMap::maxChan_;
0091
0092 nMaxNumCh_ = std::max(nMaxNumCh_, num_superchambers * num_mod);
0093
0094 Int_t nMinIdxChamber = 1048576;
0095 Int_t nMaxIdxChamber = -1048576;
0096 for (auto sch : superchambers) {
0097 auto nIdxChamber = sch->chambers().front()->id().chamber();
0098 if (nMinIdxChamber > nIdxChamber)
0099 nMinIdxChamber = nIdxChamber;
0100 if (nMaxIdxChamber < nIdxChamber)
0101 nMaxIdxChamber = nIdxChamber;
0102 }
0103
0104 const auto& chambers = superchambers.front()->chambers();
0105
0106 for (auto pchamber : chambers) {
0107 int layer_number = pchamber->id().layer();
0108 ME3IdsKey key3(region_number, station_number, layer_number);
0109 mapStationInfo_[key3] = MEStationInfo(region_number,
0110 station_number,
0111 layer_number,
0112 num_superchambers,
0113 num_mod,
0114 num_etas,
0115 num_vfat,
0116 strip1st,
0117 num_digi,
0118 nMinIdxChamber,
0119 nMaxIdxChamber);
0120 readGeometryRadiusInfoChamber(station, mapStationInfo_[key3]);
0121 readGeometryPhiInfoChamber(station, mapStationInfo_[key3]);
0122 }
0123 }
0124 }
0125
0126 return 0;
0127 }
0128
0129 int GEMDQMBase::SortingLayers(std::vector<ME3IdsKey>& listLayers) {
0130 std::sort(listLayers.begin(), listLayers.end(), [](ME3IdsKey key1, ME3IdsKey key2) {
0131 Int_t re1 = std::get<0>(key1), st1 = std::get<1>(key1), la1 = std::get<2>(key1);
0132 Int_t re2 = std::get<0>(key2), st2 = std::get<1>(key2), la2 = std::get<2>(key2);
0133 if (re1 < 0 && re2 > 0)
0134 return false;
0135 if (re1 > 0 && re2 < 0)
0136 return true;
0137 Bool_t bRes = (re1 < 0);
0138 Int_t sum1 = 256 * std::abs(re1) + 16 * st1 + 1 * la1;
0139 Int_t sum2 = 256 * std::abs(re2) + 16 * st2 + 1 * la2;
0140 if (sum1 <= sum2)
0141 return bRes;
0142 return !bRes;
0143 });
0144
0145 return 0;
0146 }
0147
0148 dqm::impl::MonitorElement* GEMDQMBase::CreateSummaryHist(DQMStore::IBooker& ibooker, TString strName) {
0149 std::vector<ME3IdsKey> listLayers;
0150 listLayers.reserve(mapStationInfo_.size());
0151 for (auto const& [key, stationInfo] : mapStationInfo_)
0152 listLayers.push_back(key);
0153 SortingLayers(listLayers);
0154 for (Int_t i = 0; i < (Int_t)listLayers.size(); i++)
0155 mapStationToIdx_[listLayers[i]] = i + 1;
0156
0157 auto h2Res =
0158 ibooker.book2D(strName, "", nMaxNumCh_, 0.5, nMaxNumCh_ + 0.5, listLayers.size(), 0.5, listLayers.size() + 0.5);
0159 h2Res->setXTitle("Chamber");
0160 h2Res->setYTitle("Layer");
0161
0162 if (h2Res == nullptr)
0163 return nullptr;
0164
0165 for (Int_t i = 1; i <= nMaxNumCh_; i++)
0166 h2Res->setBinLabel(i, Form("%i", i), 1);
0167 for (Int_t i = 1; i <= (Int_t)listLayers.size(); i++) {
0168 auto key = listLayers[i - 1];
0169 auto strInfo = GEMUtils::getSuffixName(key);
0170 auto region = keyToRegion(key);
0171 auto label =
0172 Form("GE%+i1-%cL%i;%s", region * keyToStation(key), (region > 0 ? 'P' : 'M'), keyToLayer(key), strInfo.Data());
0173 h2Res->setBinLabel(i, label, 2);
0174 Int_t nNumCh = mapStationInfo_[key].nNumChambers_ * mapStationInfo_[key].nNumModules_;
0175 h2Res->setBinContent(0, i, nNumCh);
0176 }
0177
0178 return h2Res;
0179 }
0180
0181 int GEMDQMBase::GenerateMEPerChamber(DQMStore::IBooker& ibooker) {
0182 MEMap2Check_.clear();
0183 MEMap2WithEtaCheck_.clear();
0184 MEMap2AbsReWithEtaCheck_.clear();
0185 MEMap3Check_.clear();
0186 MEMap3WithChCheck_.clear();
0187 MEMap4Check_.clear();
0188 for (auto gid : listChamberId_) {
0189 ME2IdsKey key2{gid.region(), gid.station()};
0190 ME3IdsKey key3{gid.region(), gid.station(), gid.layer()};
0191 ME4IdsKey key3WithChamber{gid.region(), gid.station(), gid.layer(), gid.chamber()};
0192 if (!MEMap2Check_[key2]) {
0193 auto strSuffixName = GEMUtils::getSuffixName(key2);
0194 auto strSuffixTitle = GEMUtils::getSuffixTitle(key2);
0195 BookingHelper bh2(ibooker, strSuffixName, strSuffixTitle);
0196 ProcessWithMEMap2(bh2, key2);
0197 MEMap2Check_[key2] = true;
0198 }
0199 if (!MEMap3Check_[key3]) {
0200 auto strSuffixName = GEMUtils::getSuffixName(key3);
0201 auto strSuffixTitle = GEMUtils::getSuffixTitle(key3);
0202 BookingHelper bh3(ibooker, strSuffixName, strSuffixTitle);
0203 ProcessWithMEMap3(bh3, key3);
0204 MEMap3Check_[key3] = true;
0205 }
0206 if (!MEMap3WithChCheck_[key3WithChamber]) {
0207 Int_t nCh = gid.chamber();
0208 Int_t nLa = gid.layer();
0209 char cLS = (nCh % 2 == 0 ? 'L' : 'S');
0210 auto strSuffixName = GEMUtils::getSuffixName(key2) + Form("-%02iL%i-%c", nCh, nLa, cLS);
0211 auto strSuffixTitle = GEMUtils::getSuffixTitle(key2) + Form("-%02iL%i-%c", nCh, nLa, cLS);
0212 BookingHelper bh3Ch(ibooker, strSuffixName, strSuffixTitle);
0213 ProcessWithMEMap3WithChamber(bh3Ch, key3WithChamber);
0214 MEMap3WithChCheck_[key3WithChamber] = true;
0215 }
0216 for (auto iEta : mapEtaPartition_[gid]) {
0217 GEMDetId eId = iEta->id();
0218 ME4IdsKey key4{gid.region(), gid.station(), gid.layer(), eId.ieta()};
0219 ME3IdsKey key2WithEta{gid.region(), gid.station(), eId.ieta()};
0220 ME3IdsKey key2AbsReWithEta{std::abs(gid.region()), gid.station(), eId.ieta()};
0221 if (!MEMap4Check_[key4]) {
0222 auto strSuffixName = GEMUtils::getSuffixName(key3) + Form("-E%02i", eId.ieta());
0223 auto strSuffixTitle = GEMUtils::getSuffixTitle(key3) + Form("-E%02i", eId.ieta());
0224 BookingHelper bh4(ibooker, strSuffixName, strSuffixTitle);
0225 ProcessWithMEMap4(bh4, key4);
0226 MEMap4Check_[key4] = true;
0227 }
0228 if (!MEMap2WithEtaCheck_[key2WithEta]) {
0229 auto strSuffixName = GEMUtils::getSuffixName(key2) + Form("-E%02i", eId.ieta());
0230 auto strSuffixTitle = GEMUtils::getSuffixTitle(key2) + Form("-E%02i", eId.ieta());
0231 BookingHelper bh3(ibooker, strSuffixName, strSuffixTitle);
0232 ProcessWithMEMap2WithEta(bh3, key2WithEta);
0233 MEMap2WithEtaCheck_[key2WithEta] = true;
0234 }
0235 if (!MEMap2AbsReWithEtaCheck_[key2AbsReWithEta]) {
0236 auto strSuffixName = Form("_GE%d1-E%02i", gid.station(), eId.ieta());
0237 auto strSuffixTitle = Form(" GE%d1-E%02i", gid.station(), eId.ieta());
0238 BookingHelper bh3(ibooker, strSuffixName, strSuffixTitle);
0239 ProcessWithMEMap2AbsReWithEta(bh3, key2AbsReWithEta);
0240 MEMap2AbsReWithEtaCheck_[key2AbsReWithEta] = true;
0241 }
0242 }
0243 }
0244 return 0;
0245 }
0246
0247 int GEMDQMBase::readGeometryRadiusInfoChamber(const GEMStation* station, MEStationInfo& stationInfo) {
0248 auto listSuperChambers = station->superChambers();
0249
0250 Bool_t bDoneEven = false, bDoneOdd = false;
0251
0252
0253 for (auto superchamber : listSuperChambers) {
0254 Int_t chamberNo = superchamber->id().chamber();
0255 if (chamberNo % 2 == 0 && bDoneEven)
0256 continue;
0257 if (chamberNo % 2 != 0 && bDoneOdd)
0258 continue;
0259
0260 auto& etaPartitions = superchamber->chambers().front()->etaPartitions();
0261
0262
0263
0264
0265
0266
0267
0268 std::vector<Float_t> listRadiusLower, listRadiusUpper;
0269 for (auto iEta : etaPartitions) {
0270 const GEMStripTopology& stripTopology = dynamic_cast<const GEMStripTopology&>(iEta->specificTopology());
0271 Float_t fHeight = stripTopology.stripLength();
0272 LocalPoint lp1(0.0, -0.5 * fHeight), lp2(0.0, 0.5 * fHeight);
0273 auto& surface = iEta->surface();
0274 GlobalPoint gp1 = surface.toGlobal(lp1), gp2 = surface.toGlobal(lp2);
0275 Float_t fR1 = gp1.perp(), fR2 = gp2.perp();
0276 Float_t fRL = std::min(fR1, fR2), fRH = std::max(fR1, fR2);
0277 listRadiusLower.push_back(fRL);
0278 listRadiusUpper.push_back(fRH);
0279
0280
0281
0282 }
0283
0284 std::sort(listRadiusLower.begin(), listRadiusLower.end());
0285 std::sort(listRadiusUpper.begin(), listRadiusUpper.end());
0286
0287 std::vector<Float_t>& listR =
0288 (chamberNo % 2 == 0 ? stationInfo.listRadiusEvenChamber_ : stationInfo.listRadiusOddChamber_);
0289 listR.clear();
0290 listR.push_back(listRadiusLower.front());
0291 for (int i = 1; i < (int)listRadiusLower.size(); i++) {
0292 listR.push_back(0.5 * (listRadiusLower[i] + listRadiusUpper[i - 1]));
0293 }
0294 listR.push_back(listRadiusUpper.back());
0295
0296 if (chamberNo % 2 == 0)
0297 bDoneEven = true;
0298 if (chamberNo % 2 != 0)
0299 bDoneOdd = true;
0300
0301 if (bDoneEven && bDoneOdd)
0302 break;
0303 }
0304
0305 return 0;
0306 }
0307
0308 int GEMDQMBase::readGeometryPhiInfoChamber(const GEMStation* station, MEStationInfo& stationInfo) {
0309 auto listSuperChambers = station->superChambers();
0310 Int_t nNumStripEta = stationInfo.nNumDigi_ * (stationInfo.nMaxVFAT_ / stationInfo.nNumEtaPartitions_);
0311
0312 std::vector<std::pair<Int_t, std::pair<std::pair<Float_t, Float_t>, Bool_t>>> listDivPhi;
0313
0314
0315 for (auto superchamber : listSuperChambers) {
0316 auto iEta = superchamber->chambers().front()->etaPartitions().front();
0317
0318
0319 Float_t fWidthStrip = std::abs(iEta->centreOfStrip((Int_t)1).x() - iEta->centreOfStrip((Int_t)0).x());
0320 LocalPoint lpRef(-fWidthStrip / 3.0, 0.0);
0321 Int_t nStripMid = (Int_t)iEta->strip(lpRef);
0322 Int_t nFirstStrip = 1 - ((nNumStripEta / 2) - nStripMid);
0323 Int_t nLastStrip = nFirstStrip + nNumStripEta - 1;
0324
0325 auto& surface = iEta->surface();
0326 LocalPoint lpF = iEta->centreOfStrip((Float_t)(nFirstStrip - 0.5));
0327 LocalPoint lpL = iEta->centreOfStrip((Float_t)(nLastStrip + 0.5));
0328 GlobalPoint gpF = surface.toGlobal(lpF);
0329 GlobalPoint gpL = surface.toGlobal(lpL);
0330
0331 Float_t fPhiF = gpF.phi();
0332 Float_t fPhiL = gpL.phi();
0333 if (fPhiF * fPhiL < 0 && std::abs(fPhiF) > 0.5 * 3.14159265359) {
0334 if (fPhiF < 0)
0335 fPhiF += 2 * 3.14159265359;
0336 if (fPhiL < 0)
0337 fPhiL += 2 * 3.14159265359;
0338 }
0339 Bool_t bFlipped = fPhiF > fPhiL;
0340 Float_t fPhiMin = std::min(fPhiF, fPhiL);
0341 Float_t fPhiMax = std::max(fPhiF, fPhiL);
0342
0343 listDivPhi.emplace_back();
0344 listDivPhi.back().first = iEta->id().chamber();
0345 listDivPhi.back().second.first.first = fPhiMin;
0346 listDivPhi.back().second.first.second = fPhiMax;
0347 listDivPhi.back().second.second = bFlipped;
0348 }
0349
0350 stationInfo.fMinPhi_ = 0.0;
0351 for (auto p : listDivPhi) {
0352 if (p.first == 1) {
0353 stationInfo.fMinPhi_ = p.second.first.first;
0354 break;
0355 }
0356 }
0357
0358
0359
0360
0361
0362
0363
0364 return 0;
0365 }