Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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);
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<ME4IdsKey>& listLayers) {
0130   std::sort(listLayers.begin(), listLayers.end(), [](ME4IdsKey key1, ME4IdsKey key2) {
0131     Int_t re1 = std::get<0>(key1), re2 = std::get<0>(key2);
0132     Int_t st1 = std::get<1>(key1), st2 = std::get<1>(key2);
0133     Int_t la1 = std::get<2>(key1), la2 = std::get<2>(key2);
0134     Int_t mo1 = std::get<3>(key1), mo2 = std::get<3>(key2);
0135     if (re1 < 0 && re2 > 0)
0136       return false;
0137     if (re1 > 0 && re2 < 0)
0138       return true;
0139     Bool_t bRes = (re1 < 0);  // == re2 < 0
0140     Int_t sum1 = 4096 * std::abs(re1) + 256 * st1 + 16 * la1 + mo1;
0141     Int_t sum2 = 4096 * std::abs(re2) + 256 * st2 + 16 * la2 + mo2;
0142     if (sum1 <= sum2)
0143       return bRes;
0144     return !bRes;
0145   });
0146 
0147   return 0;
0148 }
0149 
0150 dqm::impl::MonitorElement* GEMDQMBase::CreateSummaryHist(DQMStore::IBooker& ibooker, TString strName) {
0151   std::vector<ME4IdsKey> listLayers;
0152   for (auto const& [key3, stationInfo] : mapStationInfo_) {
0153     for (int module_number = 1; module_number <= stationInfo.nNumModules_; module_number++) {
0154       ME4IdsKey key4{keyToRegion(key3), keyToStation(key3), keyToLayer(key3), module_number};
0155       listLayers.push_back(key4);  // Note: Not only count layers but also modules
0156     }
0157   }
0158   SortingLayers(listLayers);
0159   for (Int_t i = 0; i < (Int_t)listLayers.size(); i++)
0160     mapStationToIdx_[listLayers[i]] = i + 1;
0161 
0162   auto h2Res =
0163       ibooker.book2D(strName, "", nMaxNumCh_, 0.5, nMaxNumCh_ + 0.5, listLayers.size(), 0.5, listLayers.size() + 0.5);
0164   h2Res->setXTitle("Chamber");
0165   h2Res->setYTitle("Layer");
0166 
0167   if (h2Res == nullptr)
0168     return nullptr;
0169 
0170   for (Int_t i = 1; i <= nMaxNumCh_; i++)
0171     h2Res->setBinLabel(i, Form("%i", i), 1);
0172   for (Int_t i = 1; i <= (Int_t)listLayers.size(); i++) {
0173     auto key = listLayers[i - 1];
0174     ME3IdsKey key3 = key4Tokey3(key);
0175 
0176     auto region = keyToRegion(key);
0177     auto strInfo = GEMUtils::getSuffixName(key3);  // NOTE: It starts with '_'
0178     if (mapStationInfo_[key3].nNumModules_ > 1) {
0179       strInfo += Form("-M%i", keyToModule(key));
0180     }
0181     auto label = Form("GE%+i1-%cL%i-M%i;%s",
0182                       region * keyToStation(key),
0183                       (region > 0 ? 'P' : 'M'),
0184                       keyToLayer(key),
0185                       keyToModule(key),
0186                       strInfo.Data());
0187     h2Res->setBinLabel(i, label, 2);
0188     Int_t nNumCh = mapStationInfo_[key3].nNumChambers_;
0189     h2Res->setBinContent(0, i, nNumCh);
0190   }
0191 
0192   return h2Res;
0193 }
0194 
0195 int GEMDQMBase::GenerateMEPerChamber(DQMStore::IBooker& ibooker) {
0196   MEMap2Check_.clear();
0197   MEMap3Check_.clear();
0198   MEMap4Check_.clear();
0199   MEMap5Check_.clear();
0200   MEMap2WithEtaCheck_.clear();
0201   MEMap2AbsReWithEtaCheck_.clear();
0202   MEMap4WithChCheck_.clear();
0203   MEMap5WithChCheck_.clear();
0204   for (auto gid : listChamberId_) {
0205     ME2IdsKey key2{gid.region(), gid.station()};
0206     ME3IdsKey key3{gid.region(), gid.station(), gid.layer()};
0207     const auto num_mod = mapStationInfo_[key3].nNumModules_;
0208     for (int module_number = 1; module_number <= num_mod; module_number++) {
0209       ME4IdsKey key4{gid.region(), gid.station(), gid.layer(), module_number};
0210       ME4IdsKey key4WithChamber{gid.region(), gid.station(), gid.layer(), gid.chamber()};
0211       ME5IdsKey key5WithChamber{gid.region(), gid.station(), gid.layer(), module_number, gid.chamber()};
0212       if (!MEMap2Check_[key2]) {
0213         auto strSuffixName = GEMUtils::getSuffixName(key2);
0214         auto strSuffixTitle = GEMUtils::getSuffixTitle(key2);
0215         BookingHelper bh2(ibooker, strSuffixName, strSuffixTitle);
0216         ProcessWithMEMap2(bh2, key2);
0217         MEMap2Check_[key2] = true;
0218       }
0219       if (!MEMap3Check_[key3]) {
0220         auto strSuffixName = GEMUtils::getSuffixName(key3);
0221         auto strSuffixTitle = GEMUtils::getSuffixTitle(key3);
0222         BookingHelper bh3(ibooker, strSuffixName, strSuffixTitle);
0223         ProcessWithMEMap3(bh3, key3);
0224         MEMap3Check_[key3] = true;
0225       }
0226       if (!MEMap4Check_[key4]) {
0227         Int_t nLa = gid.layer();
0228         TString strSuffixCh = Form("-L%i", nLa);
0229         if (mapStationInfo_[key3].nNumModules_ > 1)
0230           strSuffixCh = Form("-L%i-M%i", nLa, module_number);
0231         auto strSuffixName = GEMUtils::getSuffixName(key2) + strSuffixCh;
0232         auto strSuffixTitle = GEMUtils::getSuffixTitle(key2) + strSuffixCh;
0233         BookingHelper bh4(ibooker, strSuffixName, strSuffixTitle);
0234         ProcessWithMEMap4(bh4, key4);
0235         MEMap4Check_[key4] = true;
0236       }
0237       if (!MEMap4WithChCheck_[key4WithChamber]) {
0238         Int_t nCh = gid.chamber();
0239         Int_t nLa = gid.layer();
0240         char cLS = (nCh % 2 == 0 ? 'L' : 'S');  // FIXME: Is it general enough?
0241         TString strSuffixCh = Form("-%02iL%i-%c", nCh, nLa, cLS);
0242         auto strSuffixName = GEMUtils::getSuffixName(key2) + strSuffixCh;
0243         auto strSuffixTitle = GEMUtils::getSuffixTitle(key2) + strSuffixCh;
0244         BookingHelper bh4Ch(ibooker, strSuffixName, strSuffixTitle);
0245         ProcessWithMEMap4WithChamber(bh4Ch, key4WithChamber);
0246         MEMap4WithChCheck_[key4WithChamber] = true;
0247       }
0248       if (!MEMap5WithChCheck_[key5WithChamber]) {
0249         Int_t nCh = gid.chamber();
0250         Int_t nLa = gid.layer();
0251         char cLS = (nCh % 2 == 0 ? 'L' : 'S');  // FIXME: Is it general enough?
0252         TString strSuffixCh = Form("-%02iL%i-%c", nCh, nLa, cLS);
0253         if (mapStationInfo_[key3].nNumModules_ > 1)
0254           strSuffixCh = Form("-%02iL%i-M%i-%c", nCh, nLa, module_number, cLS);
0255         auto strSuffixName = GEMUtils::getSuffixName(key2) + strSuffixCh;
0256         auto strSuffixTitle = GEMUtils::getSuffixTitle(key2) + strSuffixCh;
0257         BookingHelper bh5Ch(ibooker, strSuffixName, strSuffixTitle);
0258         ProcessWithMEMap5WithChamber(bh5Ch, key5WithChamber);
0259         MEMap5WithChCheck_[key5WithChamber] = true;
0260       }
0261       for (auto iEta : mapEtaPartition_[gid]) {
0262         GEMDetId eId = iEta->id();
0263         ME5IdsKey key5{gid.region(), gid.station(), gid.layer(), module_number, eId.ieta()};
0264         ME3IdsKey key2WithEta{gid.region(), gid.station(), eId.ieta()};
0265         ME3IdsKey key2AbsReWithEta{std::abs(gid.region()), gid.station(), eId.ieta()};
0266         if (!MEMap5Check_[key5]) {
0267           auto strSuffixName = GEMUtils::getSuffixName(key3) + Form("-E%02i", eId.ieta());
0268           auto strSuffixTitle = GEMUtils::getSuffixTitle(key3) + Form("-E%02i", eId.ieta());
0269           BookingHelper bh5(ibooker, strSuffixName, strSuffixTitle);
0270           ProcessWithMEMap5(bh5, key5);
0271           MEMap5Check_[key5] = true;
0272         }
0273         if (!MEMap2WithEtaCheck_[key2WithEta]) {
0274           auto strSuffixName = GEMUtils::getSuffixName(key2) + Form("-E%02i", eId.ieta());
0275           auto strSuffixTitle = GEMUtils::getSuffixTitle(key2) + Form("-E%02i", eId.ieta());
0276           BookingHelper bh3(ibooker, strSuffixName, strSuffixTitle);
0277           ProcessWithMEMap2WithEta(bh3, key2WithEta);
0278           MEMap2WithEtaCheck_[key2WithEta] = true;
0279         }
0280         if (!MEMap2AbsReWithEtaCheck_[key2AbsReWithEta]) {
0281           auto strSuffixName = Form("_GE%d1-E%02i", gid.station(), eId.ieta());
0282           auto strSuffixTitle = Form(" GE%d1-E%02i", gid.station(), eId.ieta());
0283           BookingHelper bh3(ibooker, strSuffixName, strSuffixTitle);
0284           ProcessWithMEMap2AbsReWithEta(bh3, key2AbsReWithEta);
0285           MEMap2AbsReWithEtaCheck_[key2AbsReWithEta] = true;
0286         }
0287       }
0288     }
0289   }
0290   return 0;
0291 }
0292 
0293 int GEMDQMBase::readGeometryRadiusInfoChamber(const GEMStation* station, MEStationInfo& stationInfo) {
0294   auto listSuperChambers = station->superChambers();
0295 
0296   Bool_t bDoneEven = false, bDoneOdd = false;
0297 
0298   // Obtaining radius intervals of even/odd chambers
0299   for (auto superchamber : listSuperChambers) {
0300     Int_t chamberNo = superchamber->id().chamber();
0301     if (chamberNo % 2 == 0 && bDoneEven)
0302       continue;
0303     if (chamberNo % 2 != 0 && bDoneOdd)
0304       continue;
0305 
0306     auto& etaPartitions = superchamber->chambers().front()->etaPartitions();
0307 
0308     // A little of additional procedures to list up the radius intervals
0309     // It would be independent to local direction of chambers and the order of eta partitions
0310     //   1. Obtain the radius of the middle top/bottom points of the trapezoid
0311     //   2. Sort these two values and determine which one is the lower/upper one
0312     //   3. Keep them all and then sort them
0313     //   4. The intermediate radii are set as the mean of the corresponding values of upper/lowers.
0314     std::vector<Float_t> listRadiusLower, listRadiusUpper;
0315     for (auto iEta : etaPartitions) {
0316       const GEMStripTopology& stripTopology = dynamic_cast<const GEMStripTopology&>(iEta->specificTopology());
0317       Float_t fHeight = stripTopology.stripLength();
0318       LocalPoint lp1(0.0, -0.5 * fHeight), lp2(0.0, 0.5 * fHeight);
0319       auto& surface = iEta->surface();
0320       GlobalPoint gp1 = surface.toGlobal(lp1), gp2 = surface.toGlobal(lp2);
0321       Float_t fR1 = gp1.perp(), fR2 = gp2.perp();
0322       Float_t fRL = std::min(fR1, fR2), fRH = std::max(fR1, fR2);
0323       listRadiusLower.push_back(fRL);
0324       listRadiusUpper.push_back(fRH);
0325       // For a future usage
0326       //std::cout << "GEO_RADIUS: " << iEta->id().chamber() << " " << iEta->id().ieta() << " "
0327       //  << fRL << " " << fRH << std::endl;
0328     }
0329 
0330     std::sort(listRadiusLower.begin(), listRadiusLower.end());
0331     std::sort(listRadiusUpper.begin(), listRadiusUpper.end());
0332 
0333     std::vector<Float_t>& listR =
0334         (chamberNo % 2 == 0 ? stationInfo.listRadiusEvenChamber_ : stationInfo.listRadiusOddChamber_);
0335     listR.clear();
0336     listR.push_back(listRadiusLower.front());
0337     for (int i = 1; i < (int)listRadiusLower.size(); i++) {
0338       listR.push_back(0.5 * (listRadiusLower[i] + listRadiusUpper[i - 1]));
0339     }
0340     listR.push_back(listRadiusUpper.back());
0341 
0342     if (chamberNo % 2 == 0)
0343       bDoneEven = true;
0344     if (chamberNo % 2 != 0)
0345       bDoneOdd = true;
0346 
0347     if (bDoneEven && bDoneOdd)
0348       break;
0349   }
0350 
0351   return 0;
0352 }
0353 
0354 int GEMDQMBase::readGeometryPhiInfoChamber(const GEMStation* station, MEStationInfo& stationInfo) {
0355   auto listSuperChambers = station->superChambers();
0356   Int_t nNumStripEta = stationInfo.nNumDigi_ * (stationInfo.nMaxVFAT_ / stationInfo.nNumEtaPartitions_);
0357 
0358   std::vector<std::pair<Int_t, std::pair<std::pair<Float_t, Float_t>, Bool_t>>> listDivPhi;
0359 
0360   // Obtaining phi intervals of chambers
0361   for (auto superchamber : listSuperChambers) {
0362     auto iEta = superchamber->chambers().front()->etaPartitions().front();
0363 
0364     // What is the index of the first strip? Rather than to ask to someone, let's calculate it!
0365     Float_t fWidthStrip = std::abs(iEta->centreOfStrip((Int_t)1).x() - iEta->centreOfStrip((Int_t)0).x());
0366     LocalPoint lpRef(-fWidthStrip / 3.0, 0.0);
0367     Int_t nStripMid = (Int_t)iEta->strip(lpRef);
0368     Int_t nFirstStrip = 1 - ((nNumStripEta / 2) - nStripMid);
0369     Int_t nLastStrip = nFirstStrip + nNumStripEta - 1;
0370 
0371     auto& surface = iEta->surface();
0372     LocalPoint lpF = iEta->centreOfStrip((Float_t)(nFirstStrip - 0.5));  // To avoid the round error(?)
0373     LocalPoint lpL = iEta->centreOfStrip((Float_t)(nLastStrip + 0.5));   // To avoid the round error(?)
0374     GlobalPoint gpF = surface.toGlobal(lpF);
0375     GlobalPoint gpL = surface.toGlobal(lpL);
0376 
0377     Float_t fPhiF = gpF.phi();
0378     Float_t fPhiL = gpL.phi();
0379     if (fPhiF * fPhiL < 0 && std::abs(fPhiF) > 0.5 * 3.14159265359) {
0380       if (fPhiF < 0)
0381         fPhiF += 2 * 3.14159265359;
0382       if (fPhiL < 0)
0383         fPhiL += 2 * 3.14159265359;
0384     }
0385     Bool_t bFlipped = fPhiF > fPhiL;
0386     Float_t fPhiMin = std::min(fPhiF, fPhiL);
0387     Float_t fPhiMax = std::max(fPhiF, fPhiL);
0388 
0389     listDivPhi.emplace_back();
0390     listDivPhi.back().first = iEta->id().chamber();
0391     listDivPhi.back().second.first.first = fPhiMin;
0392     listDivPhi.back().second.first.second = fPhiMax;
0393     listDivPhi.back().second.second = bFlipped;
0394   }
0395 
0396   stationInfo.fMinPhi_ = 0.0;
0397   for (auto p : listDivPhi) {
0398     if (p.first == 1) {
0399       stationInfo.fMinPhi_ = p.second.first.first;
0400       break;
0401     }
0402   }
0403 
0404   // For a future usage
0405   //for ( auto p : listDivPhi ) {
0406   //  std::cout << "GEO_PHI: " << p.first << " "
0407   //    << p.second.first.first << " " << p.second.first.second << " " << p.second.second << std::endl;
0408   //}
0409 
0410   return 0;
0411 }