Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-07-19 01:44:22

0001 #ifndef L1Trigger_CSCTriggerPrimitives_GEMCSCLUTAnalyzer_h
0002 #define L1Trigger_CSCTriggerPrimitives_GEMCSCLUTAnalyzer_h
0003 
0004 /** \class GEMCSCLUTAnalyzer
0005  *
0006  * Makes the lookup tables for the GEM-CSC integrated local trigger
0007  * in simulation and firmware
0008  *
0009  * authors: Sven Dildick (Rice University)
0010  */
0011 
0012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0013 #include "FWCore/Framework/interface/ConsumesCollector.h"
0014 #include "FWCore/Framework/interface/Frameworkfwd.h"
0015 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0016 #include "FWCore/Framework/interface/Event.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0018 #include "DataFormats/Common/interface/Handle.h"
0019 #include "DataFormats/MuonDetId/interface/CSCTriggerNumbering.h"
0020 #include "DataFormats/CSCDigi/interface/CSCConstants.h"
0021 #include "Geometry/Records/interface/MuonGeometryRecord.h"
0022 #include "Geometry/GEMGeometry/interface/GEMGeometry.h"
0023 #include "Geometry/CSCGeometry/interface/CSCGeometry.h"
0024 #include "Geometry/GEMGeometry/interface/GEMEtaPartitionSpecs.h"
0025 #include "Geometry/CommonTopologies/interface/StripTopology.h"
0026 
0027 #include <fstream>
0028 #include <iostream>
0029 #include <vector>
0030 
0031 class GEMCSCLUTAnalyzer : public edm::one::EDAnalyzer<> {
0032 public:
0033   explicit GEMCSCLUTAnalyzer(const edm::ParameterSet&);
0034   ~GEMCSCLUTAnalyzer() override;
0035 
0036   void analyze(const edm::Event&, const edm::EventSetup&) override;
0037 
0038 private:
0039   /// generate and print LUT
0040   void generateLUTs(const CSCDetId& id) const;
0041   void generateLUTsME11(const CSCDetId& id) const;
0042   void generateLUTsME21(const CSCDetId& id) const;
0043   int assignRoll(const std::vector<std::pair<double, double>>&, double eta) const;
0044 
0045   void gemRollToEtaLimitsLUT(const GEMChamber* gemChamber, std::vector<std::pair<double, double>>& lut) const;
0046 
0047   // create LUT: WG->(rollMin,rollMax)
0048   void cscWgToRollLUT(const std::vector<std::pair<double, double>>&,
0049                       const std::vector<std::pair<double, double>>&,
0050                       std::vector<std::pair<int, int>>&) const;
0051 
0052   // create LUT: WG->(etaMin,etaMax)
0053   void cscWgToEtaLimitsLUT(const CSCLayer*, std::vector<std::pair<double, double>>&) const;
0054 
0055   // create LUT: ES->pad
0056   void cscEsToGemPadLUT(
0057       const CSCLayer*, const GEMEtaPartition*, int minH, int maxH, std::vector<std::pair<int, int>>&) const;
0058 
0059   // create LUT: pad->HS
0060   void gemPadToCscHsLUT(const CSCLayer*, const GEMEtaPartition*, std::vector<int>&) const;
0061 
0062   // create LUT: pad->ES
0063   void gemPadToCscEsLUT(const CSCLayer*, const GEMEtaPartition*, std::vector<int>&) const;
0064 
0065   // create LUT: roll-> center wg
0066   void gemRollToCscWgLUT(const CSCLayer*, const GEMChamber*, std::vector<std::pair<int, int>>&) const;
0067 
0068   edm::ESGetToken<GEMGeometry, MuonGeometryRecord> gemToken_;
0069   edm::ESGetToken<CSCGeometry, MuonGeometryRecord> cscToken_;
0070 
0071   const GEMGeometry* gemGeometry_;
0072   const CSCGeometry* cscGeometry_;
0073 };
0074 
0075 #endif
0076 
0077 GEMCSCLUTAnalyzer::GEMCSCLUTAnalyzer(const edm::ParameterSet& conf) {
0078   gemToken_ = esConsumes<GEMGeometry, MuonGeometryRecord>();
0079   cscToken_ = esConsumes<CSCGeometry, MuonGeometryRecord>();
0080 }
0081 
0082 GEMCSCLUTAnalyzer::~GEMCSCLUTAnalyzer() {}
0083 
0084 void GEMCSCLUTAnalyzer::analyze(const edm::Event& ev, const edm::EventSetup& setup) {
0085   edm::ESHandle<GEMGeometry> h_gem = setup.getHandle(gemToken_);
0086   edm::ESHandle<CSCGeometry> h_csc = setup.getHandle(cscToken_);
0087 
0088   gemGeometry_ = &*h_gem;
0089   cscGeometry_ = &*h_csc;
0090 
0091   // LUTs are made for ME1/1 and ME2/1, for even/odd
0092 
0093   // ME+1/1/1 (odd)
0094   generateLUTs(CSCDetId(1, 1, 1, 1));
0095 
0096   // ME+1/1/2 (even)
0097   generateLUTs(CSCDetId(1, 1, 1, 2));
0098 
0099   // ME+2/1/1 (odd)
0100   generateLUTs(CSCDetId(1, 2, 1, 1));
0101 
0102   // ME+2/1/2 (even)
0103   generateLUTs(CSCDetId(1, 2, 1, 2));
0104 }
0105 
0106 void GEMCSCLUTAnalyzer::generateLUTs(const CSCDetId& id) const {
0107   if (id.station() == 1)
0108     generateLUTsME11(id);
0109   if (id.station() == 2)
0110     generateLUTsME21(id);
0111 }
0112 
0113 void GEMCSCLUTAnalyzer::generateLUTsME11(const CSCDetId& id) const {
0114   // CSC trigger geometry
0115   const CSCDetId me1bId(id);
0116   const CSCDetId me1aId(id.endcap(), 1, 4, id.chamber());
0117   const CSCChamber* cscChamberME1b(cscGeometry_->chamber(me1bId));
0118   const CSCChamber* cscChamberME1a(cscGeometry_->chamber(me1aId));
0119   const CSCLayer* keyLayerME1b(cscChamberME1b->layer(3));
0120   const CSCLayer* keyLayerME1a(cscChamberME1a->layer(3));
0121 
0122   // GEM trigger geometry
0123   const GEMDetId gem_id_l1(id.zendcap(), 1, 1, 1, me1bId.chamber(), 0);
0124   const GEMDetId gem_id_l2(id.zendcap(), 1, 1, 2, me1bId.chamber(), 0);
0125   const GEMChamber* gemChamber_l1(gemGeometry_->chamber(gem_id_l1));
0126   const GEMChamber* gemChamber_l2(gemGeometry_->chamber(gem_id_l2));
0127   const GEMEtaPartition* randRoll(gemChamber_l1->etaPartition(4));
0128 
0129   // LUTs
0130   std::vector<std::pair<double, double>> gemRollEtaLimits_l1;
0131   std::vector<std::pair<double, double>> gemRollEtaLimits_l2;
0132   std::vector<std::pair<double, double>> cscWGToEtaLimits;
0133   std::vector<std::pair<int, int>> cscWgToGemRoll_l1;
0134   std::vector<std::pair<int, int>> cscWgToGemRoll_l2;
0135   std::vector<std::pair<int, int>> cscEsToGemPadME1a;
0136   std::vector<std::pair<int, int>> cscEsToGemPadME1b;
0137   std::vector<int> gemPadToCscEsME1a;
0138   std::vector<int> gemPadToCscEsME1b;
0139   std::vector<int> gemPadToCscHsME1a;
0140   std::vector<int> gemPadToCscHsME1b;
0141   std::vector<std::pair<int, int>> gemRollL1ToCscWg;
0142   std::vector<std::pair<int, int>> gemRollL2ToCscWg;
0143 
0144   gemRollToEtaLimitsLUT(gemChamber_l1, gemRollEtaLimits_l1);
0145   gemRollToEtaLimitsLUT(gemChamber_l2, gemRollEtaLimits_l2);
0146   cscWgToEtaLimitsLUT(keyLayerME1b, cscWGToEtaLimits);
0147   cscWgToRollLUT(cscWGToEtaLimits, gemRollEtaLimits_l1, cscWgToGemRoll_l1);
0148   cscWgToRollLUT(cscWGToEtaLimits, gemRollEtaLimits_l2, cscWgToGemRoll_l2);
0149   cscEsToGemPadLUT(keyLayerME1a, randRoll, 2, 94, cscEsToGemPadME1a);
0150   cscEsToGemPadLUT(keyLayerME1b, randRoll, 4, 124, cscEsToGemPadME1b);
0151   gemPadToCscHsLUT(keyLayerME1a, randRoll, gemPadToCscHsME1a);
0152   gemPadToCscHsLUT(keyLayerME1b, randRoll, gemPadToCscHsME1b);
0153   gemPadToCscEsLUT(keyLayerME1a, randRoll, gemPadToCscEsME1a);
0154   gemPadToCscEsLUT(keyLayerME1b, randRoll, gemPadToCscEsME1b);
0155   gemRollToCscWgLUT(keyLayerME1b, gemChamber_l1, gemRollL1ToCscWg);
0156   gemRollToCscWgLUT(keyLayerME1b, gemChamber_l2, gemRollL2ToCscWg);
0157 
0158   const std::string oddeven(id.chamber() % 2 == 0 ? "_even" : "_odd");
0159 
0160   unsigned i = 0;
0161   std::ofstream ofos;
0162   // simulation LUTs
0163   ofos.open("GEMCSCLUT_pad_hs_ME1a" + oddeven + ".txt");
0164   ofos << "#<header> v1.0 8 32 </header>\n";
0165   for (const auto& p : gemPadToCscHsME1a) {
0166     ofos << i << " " << p << std::endl;
0167     i++;
0168   }
0169   ofos.close();
0170 
0171   ofos.open("GEMCSCLUT_pad_hs_ME1b" + oddeven + ".txt");
0172   ofos << "#<header> v1.0 8 32 </header>\n";
0173   i = 0;
0174   for (const auto& p : gemPadToCscHsME1b) {
0175     ofos << i << " " << p << std::endl;
0176     i++;
0177   }
0178   ofos.close();
0179 
0180   ofos.open("GEMCSCLUT_pad_es_ME1a" + oddeven + ".txt");
0181   ofos << "#<header> v1.0 8 32 </header>\n";
0182   i = 0;
0183   for (const auto& p : gemPadToCscEsME1a) {
0184     ofos << i << " " << p << std::endl;
0185     i++;
0186   }
0187   ofos.close();
0188 
0189   ofos.open("GEMCSCLUT_pad_es_ME1b" + oddeven + ".txt");
0190   ofos << "#<header> v1.0 8 32 </header>\n";
0191   i = 0;
0192   for (const auto& p : gemPadToCscEsME1b) {
0193     ofos << i << " " << p << std::endl;
0194     i++;
0195   }
0196   ofos.close();
0197 
0198   ofos.open("GEMCSCLUT_roll_l1_min_wg_ME11" + oddeven + ".txt");
0199   ofos << "#<header> v1.0 3 32 </header>\n";
0200   i = 0;
0201   for (const auto& p : gemRollL1ToCscWg) {
0202     ofos << i << " " << p.first << std::endl;
0203     i++;
0204   }
0205   ofos.close();
0206 
0207   ofos.open("GEMCSCLUT_roll_l1_max_wg_ME11" + oddeven + ".txt");
0208   ofos << "#<header> v1.0 3 32 </header>\n";
0209   i = 0;
0210   for (const auto& p : gemRollL1ToCscWg) {
0211     ofos << i << " " << p.second << std::endl;
0212     i++;
0213   }
0214   ofos.close();
0215 
0216   ofos.open("GEMCSCLUT_roll_l2_min_wg_ME11" + oddeven + ".txt");
0217   ofos << "#<header> v1.0 3 32 </header>\n";
0218   i = 0;
0219   for (const auto& p : gemRollL2ToCscWg) {
0220     ofos << i << " " << p.first << std::endl;
0221     i++;
0222   }
0223   ofos.close();
0224 
0225   ofos.open("GEMCSCLUT_roll_l2_max_wg_ME11" + oddeven + ".txt");
0226   ofos << "#<header> v1.0 3 32 </header>\n";
0227   i = 0;
0228   for (const auto& p : gemRollL2ToCscWg) {
0229     ofos << i << " " << p.second << std::endl;
0230     i++;
0231   }
0232   ofos.close();
0233 
0234   // firmware LUTs
0235   ofos.open("GEMCSCLUT_pad_hs_ME1a" + oddeven + ".mem");
0236   for (const auto& p : gemPadToCscHsME1a)
0237     ofos << std::hex << p << std::endl;
0238   ofos.close();
0239 
0240   ofos.open("GEMCSCLUT_pad_hs_ME1b" + oddeven + ".mem");
0241   for (const auto& p : gemPadToCscHsME1b)
0242     ofos << std::hex << p << std::endl;
0243   ofos.close();
0244 
0245   ofos.open("GEMCSCLUT_pad_es_ME1a" + oddeven + ".mem");
0246   for (const auto& p : gemPadToCscEsME1a)
0247     ofos << std::hex << p << std::endl;
0248   ofos.close();
0249 
0250   ofos.open("GEMCSCLUT_pad_es_ME1b" + oddeven + ".mem");
0251   for (const auto& p : gemPadToCscEsME1b)
0252     ofos << std::hex << p << std::endl;
0253   ofos.close();
0254 
0255   ofos.open("GEMCSCLUT_roll_l1_min_wg_ME11" + oddeven + ".mem");
0256   for (const auto& p : gemRollL1ToCscWg)
0257     ofos << std::hex << p.first << std::endl;
0258   ofos.close();
0259 
0260   ofos.open("GEMCSCLUT_roll_l1_max_wg_ME11" + oddeven + ".mem");
0261   for (const auto& p : gemRollL1ToCscWg)
0262     ofos << std::hex << p.second << std::endl;
0263   ofos.close();
0264 
0265   ofos.open("GEMCSCLUT_roll_l2_min_wg_ME11" + oddeven + ".mem");
0266   for (const auto& p : gemRollL2ToCscWg)
0267     ofos << std::hex << p.first << std::endl;
0268   ofos.close();
0269 
0270   ofos.open("GEMCSCLUT_roll_l2_max_wg_ME11" + oddeven + ".mem");
0271   for (const auto& p : gemRollL2ToCscWg)
0272     ofos << std::hex << p.second << std::endl;
0273   ofos.close();
0274 }
0275 
0276 void GEMCSCLUTAnalyzer::generateLUTsME21(const CSCDetId& csc_id) const {
0277   const CSCChamber* cscChamber(cscGeometry_->chamber(csc_id));
0278   const CSCLayer* keyLayer(cscChamber->layer(3));
0279 
0280   // GEM trigger geometry
0281   const GEMDetId gem_id_l1(csc_id.zendcap(), 1, 2, 1, csc_id.chamber(), 0);
0282   const GEMDetId gem_id_l2(csc_id.zendcap(), 1, 2, 2, csc_id.chamber(), 0);
0283   const GEMChamber* gemChamber_l1(gemGeometry_->chamber(gem_id_l1));
0284   const GEMChamber* gemChamber_l2(gemGeometry_->chamber(gem_id_l2));
0285   const GEMEtaPartition* randRoll(gemChamber_l1->etaPartition(4));
0286 
0287   // LUTs
0288   std::vector<std::pair<double, double>> gemRollEtaLimits_l1;
0289   std::vector<std::pair<double, double>> gemRollEtaLimits_l2;
0290   std::vector<std::pair<double, double>> cscWGToEtaLimits;
0291   std::vector<std::pair<int, int>> cscWgToGemRoll_l1;
0292   std::vector<std::pair<int, int>> cscWgToGemRoll_l2;
0293   std::vector<std::pair<int, int>> cscEsToGemPad;
0294   std::vector<int> gemPadToCscHs;
0295   std::vector<int> gemPadToCscEs;
0296   std::vector<std::pair<int, int>> gemRollL1ToCscWg;
0297   std::vector<std::pair<int, int>> gemRollL2ToCscWg;
0298 
0299   gemRollToEtaLimitsLUT(gemChamber_l1, gemRollEtaLimits_l1);
0300   gemRollToEtaLimitsLUT(gemChamber_l2, gemRollEtaLimits_l2);
0301   cscWgToEtaLimitsLUT(keyLayer, cscWGToEtaLimits);
0302   cscWgToRollLUT(cscWGToEtaLimits, gemRollEtaLimits_l1, cscWgToGemRoll_l1);
0303   cscWgToRollLUT(cscWGToEtaLimits, gemRollEtaLimits_l2, cscWgToGemRoll_l2);
0304   cscEsToGemPadLUT(keyLayer, randRoll, 4, 155, cscEsToGemPad);
0305   gemPadToCscHsLUT(keyLayer, randRoll, gemPadToCscHs);
0306   gemPadToCscEsLUT(keyLayer, randRoll, gemPadToCscEs);
0307   gemRollToCscWgLUT(keyLayer, gemChamber_l1, gemRollL1ToCscWg);
0308   gemRollToCscWgLUT(keyLayer, gemChamber_l2, gemRollL2ToCscWg);
0309 
0310   const std::string oddeven(csc_id.chamber() % 2 == 0 ? "_even" : "_odd");
0311 
0312   unsigned i = 0;
0313   std::ofstream ofos;
0314   // simulation LUTs
0315   ofos.open("GEMCSCLUT_pad_hs_ME21" + oddeven + ".txt");
0316   ofos << "#<header> v1.0 9 32 </header>\n";
0317   for (const auto& p : gemPadToCscHs) {
0318     ofos << i << " " << p << std::endl;
0319     i++;
0320   }
0321   ofos.close();
0322 
0323   ofos.open("GEMCSCLUT_pad_es_ME21" + oddeven + ".txt");
0324   ofos << "#<header> v1.0 9 32 </header>\n";
0325   i = 0;
0326   for (const auto& p : gemPadToCscEs) {
0327     ofos << i << " " << p << std::endl;
0328     i++;
0329   }
0330   ofos.close();
0331 
0332   ofos.open("GEMCSCLUT_roll_l1_min_wg_ME21" + oddeven + ".txt");
0333   ofos << "#<header> v1.0 4 32 </header>\n";
0334   i = 0;
0335   for (const auto& p : gemRollL1ToCscWg) {
0336     ofos << i << " " << p.first << std::endl;
0337     i++;
0338   }
0339   ofos.close();
0340 
0341   ofos.open("GEMCSCLUT_roll_l2_min_wg_ME21" + oddeven + ".txt");
0342   ofos << "#<header> v1.0 4 32 </header>\n";
0343   i = 0;
0344   for (const auto& p : gemRollL2ToCscWg) {
0345     ofos << i << " " << p.first << std::endl;
0346     i++;
0347   }
0348   ofos.close();
0349 
0350   ofos.open("GEMCSCLUT_roll_l1_max_wg_ME21" + oddeven + ".txt");
0351   ofos << "#<header> v1.0 4 32 </header>\n";
0352   i = 0;
0353   for (const auto& p : gemRollL1ToCscWg) {
0354     ofos << i << " " << p.second << std::endl;
0355     i++;
0356   }
0357   ofos.close();
0358 
0359   ofos.open("GEMCSCLUT_roll_l2_max_wg_ME21" + oddeven + ".txt");
0360   ofos << "#<header> v1.0 4 32 </header>\n";
0361   i = 0;
0362   for (const auto& p : gemRollL2ToCscWg) {
0363     ofos << i << " " << p.second << std::endl;
0364     i++;
0365   }
0366   ofos.close();
0367 
0368   // firmware LUTs
0369   ofos.open("GEMCSCLUT_pad_hs_ME21" + oddeven + ".mem");
0370   for (const auto& p : gemPadToCscHs)
0371     ofos << std::hex << p << std::endl;
0372   ofos.close();
0373 
0374   ofos.open("GEMCSCLUT_pad_es_ME21" + oddeven + ".mem");
0375   for (const auto& p : gemPadToCscEs)
0376     ofos << std::hex << p << std::endl;
0377   ofos.close();
0378 
0379   ofos.open("GEMCSCLUT_roll_l1_min_wg_ME21" + oddeven + ".mem");
0380   for (const auto& p : gemRollL1ToCscWg)
0381     ofos << std::hex << p.first << std::endl;
0382   ofos.close();
0383 
0384   ofos.open("GEMCSCLUT_roll_l2_min_wg_ME21" + oddeven + ".mem");
0385   for (const auto& p : gemRollL2ToCscWg)
0386     ofos << std::hex << p.first << std::endl;
0387   ofos.close();
0388 
0389   ofos.open("GEMCSCLUT_roll_l1_max_wg_ME21" + oddeven + ".mem");
0390   for (const auto& p : gemRollL1ToCscWg)
0391     ofos << std::hex << p.second << std::endl;
0392   ofos.close();
0393 
0394   ofos.open("GEMCSCLUT_roll_l2_max_wg_ME21" + oddeven + ".mem");
0395   for (const auto& p : gemRollL2ToCscWg)
0396     ofos << std::hex << p.second << std::endl;
0397   ofos.close();
0398 }
0399 
0400 int GEMCSCLUTAnalyzer::assignRoll(const std::vector<std::pair<double, double>>& lut, double eta) const {
0401   int result = -99;
0402   int iRoll = 0;
0403   for (const auto& p : lut) {
0404     iRoll++;
0405     const float minEta(p.first);
0406     const float maxEta(p.second);
0407     if (minEta <= std::abs(eta) and std::abs(eta) < maxEta) {
0408       result = iRoll;
0409       break;
0410     }
0411   }
0412   return result;
0413 }
0414 
0415 void GEMCSCLUTAnalyzer::gemRollToEtaLimitsLUT(const GEMChamber* gemChamber,
0416                                               std::vector<std::pair<double, double>>& lut) const {
0417   for (const auto& roll : gemChamber->etaPartitions()) {
0418     const float half_striplength(roll->specs()->specificTopology().stripLength() / 2.);
0419     const LocalPoint lp_top(0., half_striplength, 0.);
0420     const LocalPoint lp_bottom(0., -half_striplength, 0.);
0421     const GlobalPoint& gp_top(roll->toGlobal(lp_top));
0422     const GlobalPoint& gp_bottom(roll->toGlobal(lp_bottom));
0423     const double bottom_eta(std::abs(gp_bottom.eta()));
0424     const double top_eta(std::abs(gp_top.eta()));
0425     lut.emplace_back(std::min(bottom_eta, top_eta), std::max(bottom_eta, top_eta));
0426   }
0427 }
0428 
0429 void GEMCSCLUTAnalyzer::cscWgToRollLUT(const std::vector<std::pair<double, double>>& inLUT1,
0430                                        const std::vector<std::pair<double, double>>& inLUT2,
0431                                        std::vector<std::pair<int, int>>& outLUT) const {
0432   for (const auto& p : inLUT1) {
0433     double etaMin(p.first);
0434     double etaMax(p.second);
0435     outLUT.emplace_back(assignRoll(inLUT2, etaMin), assignRoll(inLUT2, etaMax));
0436   }
0437 }
0438 
0439 void GEMCSCLUTAnalyzer::cscWgToEtaLimitsLUT(const CSCLayer* keyLayer,
0440                                             std::vector<std::pair<double, double>>& lut) const {
0441   const CSCLayerGeometry* keyLayerGeometry(keyLayer->geometry());
0442   const int numberOfWG(keyLayerGeometry->numberOfWireGroups());
0443   for (int i = 0; i < numberOfWG; ++i) {
0444     const float middle_wire(keyLayerGeometry->middleWireOfGroup(i));
0445     const std::pair<LocalPoint, LocalPoint> wire_ends(keyLayerGeometry->wireTopology()->wireEnds(middle_wire));
0446     const GlobalPoint& gp_top(keyLayer->toGlobal(wire_ends.first));
0447     const GlobalPoint& gp_bottom(keyLayer->toGlobal(wire_ends.second));
0448     const double bottom_eta(std::abs(gp_bottom.eta()));
0449     const double top_eta(std::abs(gp_top.eta()));
0450     lut.emplace_back(std::min(bottom_eta, top_eta), std::max(bottom_eta, top_eta));
0451   }
0452 }
0453 
0454 void GEMCSCLUTAnalyzer::cscEsToGemPadLUT(const CSCLayer* keyLayer,
0455                                          const GEMEtaPartition* randRoll,
0456                                          int minH,
0457                                          int maxH,
0458                                          std::vector<std::pair<int, int>>& lut) const {
0459   const CSCLayerGeometry* keyLayerGeometry(keyLayer->geometry());
0460   auto nStrips(keyLayerGeometry->numberOfStrips());
0461   for (float i = 0; i < nStrips; i = i + 0.125) {
0462     const LocalPoint& lpCSC(keyLayerGeometry->topology()->localPosition(i));
0463     const GlobalPoint& gp(keyLayer->toGlobal(lpCSC));
0464     const LocalPoint& lpGEM(randRoll->toLocal(gp));
0465     const float pad(randRoll->pad(lpGEM));
0466     lut.emplace_back(std::floor(pad), std::ceil(pad));
0467   }
0468 }
0469 
0470 void GEMCSCLUTAnalyzer::gemPadToCscHsLUT(const CSCLayer* keyLayer,
0471                                          const GEMEtaPartition* randRoll,
0472                                          std::vector<int>& lut) const {
0473   int offset(0);
0474   if (keyLayer->id().ring() == 4)
0475     offset = 64;
0476   const int nGEMPads(randRoll->npads());
0477   const CSCLayerGeometry* keyLayerGeometry(keyLayer->geometry());
0478   for (int i = 0; i < nGEMPads; ++i) {
0479     const LocalPoint& lpGEM(randRoll->centreOfPad(i));
0480     const GlobalPoint& gp(randRoll->toGlobal(lpGEM));
0481     const LocalPoint& lpCSC(keyLayer->toLocal(gp));
0482     const float strip(keyLayerGeometry->strip(lpCSC));
0483     lut.push_back(int((strip + offset) * 2));
0484   }
0485 }
0486 
0487 void GEMCSCLUTAnalyzer::gemPadToCscEsLUT(const CSCLayer* keyLayer,
0488                                          const GEMEtaPartition* randRoll,
0489                                          std::vector<int>& lut) const {
0490   int offset(0);
0491   if (keyLayer->id().ring() == 4)
0492     offset = CSCConstants::NUM_STRIPS_ME1B;
0493   const int nGEMPads(randRoll->npads());
0494   const CSCLayerGeometry* keyLayerGeometry(keyLayer->geometry());
0495   for (int i = 0; i < nGEMPads; ++i) {
0496     const LocalPoint& lpGEM(randRoll->centreOfPad(i));
0497     const GlobalPoint& gp(randRoll->toGlobal(lpGEM));
0498     const LocalPoint& lpCSC(keyLayer->toLocal(gp));
0499     const float strip(keyLayerGeometry->strip(lpCSC));
0500     lut.push_back(int((strip + offset) * 8));
0501   }
0502 }
0503 
0504 void GEMCSCLUTAnalyzer::gemRollToCscWgLUT(const CSCLayer* keyLayer,
0505                                           const GEMChamber* gemChamber,
0506                                           std::vector<std::pair<int, int>>& lut) const {
0507   const CSCLayerGeometry* keyLayerGeometry(keyLayer->geometry());
0508   for (const auto& roll : gemChamber->etaPartitions()) {
0509     const float half_striplength(roll->specs()->specificTopology().stripLength() / 2.);
0510     const LocalPoint lp_top(0., half_striplength, 0.);
0511     const LocalPoint lp_bottom(0., -half_striplength, 0.);
0512 
0513     const GlobalPoint& gp_top(roll->toGlobal(lp_top));
0514     const GlobalPoint& gp_bottom(roll->toGlobal(lp_bottom));
0515 
0516     const LocalPoint& lp_csc_top(keyLayer->toLocal(gp_top));
0517     const LocalPoint& lp_csc_bottom(keyLayer->toLocal(gp_bottom));
0518 
0519     const int wire_top(keyLayerGeometry->nearestWire(lp_csc_top));
0520     const int wire_bottom(keyLayerGeometry->nearestWire(lp_csc_bottom));
0521 
0522     int wg_top(keyLayerGeometry->wireGroup(wire_top));
0523     int wg_bottom(keyLayerGeometry->wireGroup(wire_bottom));
0524 
0525     // override for cases when the function "wireGroup" fails to provide the
0526     // wiregroup number
0527     const int GEM_layer = roll->id().layer();
0528     const int GEM_roll = roll->id().roll();
0529     if (roll->isGE21() and GEM_layer == 1) {
0530       // L1 - max
0531       if (GEM_roll == 10)
0532         wg_top = 45;
0533       // L1 - min
0534       if (GEM_roll == 4)
0535         wg_bottom = 80;
0536       if (GEM_roll == 9)
0537         wg_bottom = 46;
0538     }
0539     lut.emplace_back(wg_bottom, wg_top);
0540   }
0541 }
0542 //define this as a plug-in
0543 #include "FWCore/Framework/interface/MakerMacros.h"
0544 DEFINE_FWK_MODULE(GEMCSCLUTAnalyzer);