Back to home page

Project CMSSW displayed by LXR

 
 

    


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 // Borrowed from DQM/GEM/src/GEMOfflineDQMBase.cc
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   // Borrwed from DQM/GEM/src/GEMOfflineMonitor.cc
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());  // the number of VFATs per GEMEtaPartition
0087       const int num_etas = getNumEtaPartitions(station);    // the number of eta partitions per GEMChamber
0088       const int num_vfat = num_etas * max_vfat;             // the number of VFATs per GEMChamber
0089       const int strip1st = (station_number == 2 ? 1 : 0);   // the index of the first strip
0090       const int num_digi = GEMeMap::maxChan_;               // the number of digis (channels) per VFAT
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);  // == re2 < 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);  // NOTE: It starts with '_'
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');  // FIXME: Is it general enough?
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   // Obtaining radius intervals of even/odd chambers
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     // A little of additional procedures to list up the radius intervals
0263     // It would be independent to local direction of chambers and the order of eta partitions
0264     //   1. Obtain the radius of the middle top/bottom points of the trapezoid
0265     //   2. Sort these two values and determine which one is the lower/upper one
0266     //   3. Keep them all and then sort them
0267     //   4. The intermediate radii are set as the mean of the corresponding values of upper/lowers.
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       // For a future usage
0280       //std::cout << "GEO_RADIUS: " << iEta->id().chamber() << " " << iEta->id().ieta() << " "
0281       //  << fRL << " " << fRH << std::endl;
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   // Obtaining phi intervals of chambers
0315   for (auto superchamber : listSuperChambers) {
0316     auto iEta = superchamber->chambers().front()->etaPartitions().front();
0317 
0318     // What is the index of the first strip? Rather than to ask to someone, let's calculate it!
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));  // To avoid the round error(?)
0327     LocalPoint lpL = iEta->centreOfStrip((Float_t)(nLastStrip + 0.5));   // To avoid the round error(?)
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   // For a future usage
0359   //for ( auto p : listDivPhi ) {
0360   //  std::cout << "GEO_PHI: " << p.first << " "
0361   //    << p.second.first.first << " " << p.second.first.second << " " << p.second.second << std::endl;
0362   //}
0363 
0364   return 0;
0365 }