Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-15 04:21:50

0001 #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h"
0002 
0003 #include "CondFormats/L1TObjects/interface/LUT.h"
0004 #include "DataFormats/DetId/interface/DetId.h"
0005 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
0006 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
0007 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
0008 #include "DataFormats/MuonDetId/interface/RPCDetId.h"
0009 #include "FWCore/Utilities/interface/Exception.h"
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011 
0012 #include <algorithm>
0013 #include <cmath>
0014 #include <cstdint>
0015 #include <iostream>
0016 #include <iterator>
0017 #include <utility>
0018 
0019 ///////////////////////////////////////////////
0020 ///////////////////////////////////////////////
0021 RefHitDef::RefHitDef(unsigned int aInput, int aPhiMin, int aPhiMax, unsigned int aRegion, unsigned int aRefLayer)
0022     : iInput(aInput), iRegion(aRegion), iRefLayer(aRefLayer), range(std::pair<int, int>(aPhiMin, aPhiMax)) {}
0023 ///////////////////////////////////////////////
0024 ///////////////////////////////////////////////
0025 bool RefHitDef::fitsRange(int iPhi) const { return iPhi >= range.first && iPhi <= range.second; }
0026 ///////////////////////////////////////////////
0027 ///////////////////////////////////////////////
0028 std::ostream &operator<<(std::ostream &out, const RefHitDef &aRefHitDef) {
0029   out << "iRefLayer: " << aRefHitDef.iRefLayer << " iInput: " << aRefHitDef.iInput << " iRegion: " << aRefHitDef.iRegion
0030       << " range: (" << aRefHitDef.range.first << ", " << aRefHitDef.range.second << std::endl;
0031 
0032   return out;
0033 }
0034 ///////////////////////////////////////////////
0035 ///////////////////////////////////////////////
0036 void OMTFConfiguration::initCounterMatrices() {
0037   ///Vector of all inputs
0038   std::vector<int> aLayer1D(nInputs(), 0);
0039 
0040   ///Vector of all layers
0041   vector2D aLayer2D;
0042   aLayer2D.assign(nLayers(), aLayer1D);
0043 
0044   ///Vector of all logic cones
0045   vector3D aLayer3D;
0046   aLayer3D.assign(nLogicRegions(), aLayer2D);
0047 
0048   ///Vector of all processors
0049   measurements4D.assign(nProcessors(), aLayer3D);
0050   measurements4Dref.assign(nProcessors(), aLayer3D);
0051 }
0052 ///////////////////////////////////////////////
0053 ///////////////////////////////////////////////
0054 void OMTFConfiguration::configure(const L1TMuonOverlapParams *omtfParams) {
0055   rawParams = *omtfParams;
0056 
0057   ///Set chamber sectors connections to logic processros.
0058   barrelMin.resize(nProcessors());
0059   endcap10DegMin.resize(nProcessors());
0060   endcap20DegMin.resize(nProcessors());
0061 
0062   barrelMax.resize(nProcessors());
0063   endcap10DegMax.resize(nProcessors());
0064   endcap20DegMax.resize(nProcessors());
0065 
0066   const std::vector<int> *connectedSectorsStartVec = omtfParams->connectedSectorsStart();
0067   const std::vector<int> *connectedSectorsEndVec = omtfParams->connectedSectorsEnd();
0068 
0069   std::copy(connectedSectorsStartVec->begin(), connectedSectorsStartVec->begin() + nProcessors(), barrelMin.begin());
0070   std::copy(connectedSectorsStartVec->begin() + nProcessors(),
0071             connectedSectorsStartVec->begin() + 2 * nProcessors(),
0072             endcap10DegMin.begin());
0073   std::copy(
0074       connectedSectorsStartVec->begin() + 2 * nProcessors(), connectedSectorsStartVec->end(), endcap20DegMin.begin());
0075 
0076   std::copy(connectedSectorsEndVec->begin(), connectedSectorsEndVec->begin() + nProcessors(), barrelMax.begin());
0077   std::copy(connectedSectorsEndVec->begin() + nProcessors(),
0078             connectedSectorsEndVec->begin() + 2 * nProcessors(),
0079             endcap10DegMax.begin());
0080   std::copy(connectedSectorsEndVec->begin() + 2 * nProcessors(), connectedSectorsEndVec->end(), endcap20DegMax.begin());
0081 
0082   ///Set connections tables
0083   const std::vector<L1TMuonOverlapParams::LayerMapNode> *layerMap = omtfParams->layerMap();
0084 
0085   for (unsigned int iLayer = 0; iLayer < nLayers(); ++iLayer) {
0086     L1TMuonOverlapParams::LayerMapNode aNode = layerMap->at(iLayer);
0087     hwToLogicLayer[aNode.hwNumber] = aNode.logicNumber;
0088     logicToHwLayer[aNode.logicNumber] = aNode.hwNumber;
0089     logicToLogic[aNode.logicNumber] = aNode.connectedToLayer;
0090     if (aNode.bendingLayer)
0091       bendingLayers.insert(aNode.logicNumber);
0092   }
0093   /////
0094   refToLogicNumber.resize(nRefLayers());
0095 
0096   const std::vector<L1TMuonOverlapParams::RefLayerMapNode> *refLayerMap = omtfParams->refLayerMap();
0097   for (unsigned int iRefLayer = 0; iRefLayer < nRefLayers(); ++iRefLayer) {
0098     L1TMuonOverlapParams::RefLayerMapNode aNode = refLayerMap->at(iRefLayer);
0099     refToLogicNumber[aNode.refLayer] = aNode.logicNumber;
0100   }
0101   /////
0102   std::vector<int> vector1D(nRefLayers(), nPhiBins());
0103   processorPhiVsRefLayer.assign(nProcessors(), vector1D);
0104 
0105   ///connections tables for each processor each logic cone
0106   ///Vector of all layers
0107   vector1D_pair aLayer1D(nLayers());
0108   ///Vector of all logic cones
0109   vector2D_pair aLayer2D;
0110   aLayer2D.assign(nLogicRegions(), aLayer1D);
0111   ///Vector of all processors
0112   connections.assign(nProcessors(), aLayer2D);
0113 
0114   ///Starting phis of each region
0115   ///Vector of all regions in one processor
0116   std::vector<std::pair<int, int> > aRefHit1D(nLogicRegions(), std::pair<int, int>(9999, 9999));
0117   ///Vector of all reflayers
0118   std::vector<std::vector<std::pair<int, int> > > aRefHit2D;
0119   aRefHit2D.assign(nRefLayers(), aRefHit1D);
0120   ///Vector of all inputs
0121   regionPhisVsRefLayerVsInput.assign(nInputs(), aRefHit2D);
0122 
0123   //Vector of ref hit definitions
0124   std::vector<RefHitDef> aRefHitsDefs(nRefHits());
0125   ///Vector of all processros
0126   refHitsDefs.assign(nProcessors(), aRefHitsDefs);
0127 
0128   const std::vector<int> *phiStartMap = omtfParams->globalPhiStartMap();
0129   const std::vector<L1TMuonOverlapParams::RefHitNode> *refHitMap = omtfParams->refHitMap();
0130   const std::vector<L1TMuonOverlapParams::LayerInputNode> *layerInputMap = omtfParams->layerInputMap();
0131   unsigned int tmpIndex = 0;
0132   for (unsigned int iProcessor = 0; iProcessor < nProcessors(); ++iProcessor) {
0133     for (unsigned int iRefLayer = 0; iRefLayer < nRefLayers(); ++iRefLayer) {
0134       int iPhiStart = phiStartMap->at(iRefLayer + iProcessor * nRefLayers());
0135       processorPhiVsRefLayer[iProcessor][iRefLayer] = iPhiStart;
0136     }
0137     for (unsigned int iRefHit = 0; iRefHit < nRefHits(); ++iRefHit) {
0138       int iPhiMin = refHitMap->at(iRefHit + iProcessor * nRefHits()).iPhiMin;
0139       int iPhiMax = refHitMap->at(iRefHit + iProcessor * nRefHits()).iPhiMax;
0140       unsigned int iInput = refHitMap->at(iRefHit + iProcessor * nRefHits()).iInput;
0141       unsigned int iRegion = refHitMap->at(iRefHit + iProcessor * nRefHits()).iRegion;
0142       unsigned int iRefLayer = refHitMap->at(iRefHit + iProcessor * nRefHits()).iRefLayer;
0143       regionPhisVsRefLayerVsInput[iInput][iRefLayer][iRegion] = std::pair<int, int>(iPhiMin, iPhiMax);
0144       refHitsDefs[iProcessor][iRefHit] = RefHitDef(iInput, iPhiMin, iPhiMax, iRegion, iRefLayer);
0145     }
0146     for (unsigned int iLogicRegion = 0; iLogicRegion < nLogicRegions(); ++iLogicRegion) {
0147       for (unsigned int iLayer = 0; iLayer < nLayers(); ++iLayer) {
0148         tmpIndex = iLayer + iLogicRegion * nLayers() + iProcessor * nLogicRegions() * nLayers();
0149         unsigned int iFirstInput = layerInputMap->at(tmpIndex).iFirstInput;
0150         unsigned int nInputsInRegion = layerInputMap->at(tmpIndex).nInputs;
0151         connections[iProcessor][iLogicRegion][iLayer] =
0152             std::pair<unsigned int, unsigned int>(iFirstInput, nInputsInRegion);
0153         ///Symetrize connections. Use the same connections for all processors
0154         if (iProcessor != 0)
0155           connections[iProcessor][iLogicRegion][iLayer] = connections[0][iLogicRegion][iLayer];
0156       }
0157     }
0158   }
0159 
0160   initCounterMatrices();
0161 
0162   pdfBins = (1 << rawParams.nPdfAddrBits());
0163   pdfMaxVal = (1 << rawParams.nPdfValBits()) - 1;
0164 
0165   //configuration based on the firmware version parameter
0166   //TODO add next entries for the new firmware
0167   //the default values of the parameters are used, if not set here, so don't mess them!
0168   if (fwVersion() <= 4) {
0169     setMinDtPhiQuality(4);
0170     setMinDtPhiBQuality(4);
0171   } else if (fwVersion() == 5) {
0172     setMinDtPhiQuality(2);
0173     setMinDtPhiBQuality(2);
0174     setGhostBusterType("GhostBusterPreferRefDt");
0175   } else if (fwVersion() == 6) {
0176     setMinDtPhiQuality(2);
0177     setMinDtPhiBQuality(2);
0178     setGhostBusterType("GhostBusterPreferRefDt");
0179   } else if (fwVersion() == 8) {
0180     setMinDtPhiQuality(2);
0181     setMinDtPhiBQuality(2);
0182 
0183     setSorterType(1);  //"byLLH"
0184 
0185     setRpcMaxClusterSize(3);
0186     setRpcMaxClusterCnt(2);
0187     setRpcDropAllClustersIfMoreThanMax(true);
0188 
0189     setGoldenPatternResultFinalizeFunction(9);
0190 
0191     setNoHitValueInPdf(true);
0192 
0193     setGhostBusterType("GhostBusterPreferRefDt");
0194   } else if (fwVersion() == 9) {
0195     setMinDtPhiQuality(2);
0196     setMinDtPhiBQuality(4);
0197 
0198     setSorterType(1);  //"byLLH"
0199 
0200     setRpcMaxClusterSize(3);
0201     setRpcMaxClusterCnt(2);
0202     setRpcDropAllClustersIfMoreThanMax(true);
0203 
0204     setGoldenPatternResultFinalizeFunction(10);
0205 
0206     setNoHitValueInPdf(true);
0207 
0208     usePhiBExtrapolationFromMB1_ = true;
0209     usePhiBExtrapolationFromMB2_ = true;
0210     useStubQualInExtr_ = false;
0211     useEndcapStubsRInExtr_ = false;
0212 
0213     dtRefHitMinQuality = 4;
0214 
0215     setGhostBusterType("byRefLayer");
0216   }
0217 }
0218 
0219 void OMTFConfiguration::configureFromEdmParameterSet(const edm::ParameterSet &edmParameterSet) {
0220   edm::LogVerbatim("OMTFReconstruction") << "OMTFConfiguration::configureFromEdmParameterSet: setting the params from "
0221                                             "python config (overwrites the EventSetup (DB) params): "
0222                                          << std::endl;
0223 
0224   ProcConfigurationBase::configureFromEdmParameterSet(edmParameterSet);
0225 
0226   if (edmParameterSet.exists("goldenPatternResultFinalizeFunction")) {
0227     int finalizeFunction = edmParameterSet.getParameter<int>("goldenPatternResultFinalizeFunction");
0228     setGoldenPatternResultFinalizeFunction(finalizeFunction);
0229     edm::LogVerbatim("OMTFReconstruction")
0230         << "GoldenPatternResult::setFinalizeFunction: " << finalizeFunction << std::endl;
0231   }
0232 
0233   if (edmParameterSet.exists("noHitValueInPdf")) {
0234     setNoHitValueInPdf(edmParameterSet.getParameter<bool>("noHitValueInPdf"));
0235     edm::LogVerbatim("OMTFReconstruction")
0236         << "noHitValueInPdf: " << edmParameterSet.getParameter<bool>("noHitValueInPdf") << std::endl;
0237   }
0238 
0239   if (edmParameterSet.exists("sorterType")) {
0240     string sorterTypeStr = edmParameterSet.getParameter<std::string>("sorterType");
0241     if (sorterTypeStr == "byNhitsByLLH")
0242       sorterType = 0;
0243     if (sorterTypeStr == "byLLH")
0244       sorterType = 1;
0245 
0246     edm::LogVerbatim("OMTFReconstruction") << "sorterType: " << sorterType << " = "
0247                                            << edmParameterSet.getParameter<std::string>("sorterType") << std::endl;
0248   }
0249 
0250   if (edmParameterSet.exists("ghostBusterType")) {
0251     setGhostBusterType(edmParameterSet.getParameter<std::string>("ghostBusterType"));
0252 
0253     edm::LogVerbatim("OMTFReconstruction") << "ghostBusterType: " << getGhostBusterType() << std::endl;
0254   }
0255 
0256   setFixCscGeometryOffset(true);  //for the OMTF by default is true, read from python if needed
0257 
0258   if (edmParameterSet.exists("usePhiBExtrapolationFromMB1")) {
0259     usePhiBExtrapolationFromMB1_ = edmParameterSet.getParameter<bool>("usePhiBExtrapolationFromMB1");
0260     edm::LogVerbatim("OMTFReconstruction")
0261         << "usePhiBExtrapolationFromMB1: " << usePhiBExtrapolationFromMB1_ << std::endl;
0262   }
0263 
0264   if (edmParameterSet.exists("usePhiBExtrapolationFromMB2")) {
0265     usePhiBExtrapolationFromMB2_ = edmParameterSet.getParameter<bool>("usePhiBExtrapolationFromMB2");
0266     edm::LogVerbatim("OMTFReconstruction")
0267         << "usePhiBExtrapolationFromMB2: " << usePhiBExtrapolationFromMB2_ << std::endl;
0268   }
0269 
0270   if (edmParameterSet.exists("useStubQualInExtr")) {
0271     useStubQualInExtr_ = edmParameterSet.getParameter<bool>("useStubQualInExtr");
0272     edm::LogVerbatim("OMTFReconstruction") << "useStubQualInExtr: " << useStubQualInExtr_ << std::endl;
0273   }
0274 
0275   if (edmParameterSet.exists("useEndcapStubsRInExtr")) {
0276     useEndcapStubsRInExtr_ = edmParameterSet.getParameter<bool>("useEndcapStubsRInExtr");
0277     edm::LogVerbatim("OMTFReconstruction") << "useEndcapStubsRInExtr: " << useEndcapStubsRInExtr_ << std::endl;
0278   }
0279 
0280   if (edmParameterSet.exists("dtRefHitMinQuality")) {
0281     dtRefHitMinQuality = edmParameterSet.getParameter<int>("dtRefHitMinQuality");
0282     edm::LogVerbatim("OMTFReconstruction") << "dtRefHitMinQuality: " << dtRefHitMinQuality << std::endl;
0283   }
0284 
0285   if (edmParameterSet.exists("dumpResultToXML")) {
0286     dumpResultToXML = edmParameterSet.getParameter<bool>("dumpResultToXML");
0287   }
0288 
0289   if (edmParameterSet.exists("minCSCStubRME12")) {
0290     minCSCStubRME12_ = edmParameterSet.getParameter<int>("minCSCStubRME12");
0291     edm::LogVerbatim("OMTFReconstruction") << "minCSCStubRME12: " << minCSCStubRME12_ << std::endl;
0292   }
0293 
0294   if (edmParameterSet.exists("minCSCStubR")) {
0295     minCSCStubR_ = edmParameterSet.getParameter<int>("minCSCStubR");
0296     edm::LogVerbatim("OMTFReconstruction") << "minCSCStubR: " << minCSCStubR_ << std::endl;
0297   }
0298 
0299   if (edmParameterSet.exists("cleanStubs")) {
0300     cleanStubs_ = edmParameterSet.getParameter<bool>("cleanStubs");
0301   }
0302 }
0303 
0304 ///////////////////////////////////////////////
0305 ///////////////////////////////////////////////
0306 std::ostream &operator<<(std::ostream &out, const OMTFConfiguration &aConfig) {
0307   out << "nLayers(): " << aConfig.nLayers() << std::endl
0308       << " nHitsPerLayer(): " << aConfig.nHitsPerLayer() << std::endl
0309       << " nRefLayers(): " << aConfig.nRefLayers() << std::endl
0310       << " nPdfAddrBits: " << aConfig.nPdfAddrBits() << std::endl
0311       << " nPdfValBits: " << aConfig.nPdfValBits() << std::endl
0312       << " nPhiBins(): " << aConfig.nPhiBins() << std::endl
0313       << " nPdfAddrBits(): " << aConfig.nPdfAddrBits() << std::endl
0314       << std::endl;
0315 
0316   for (unsigned int iProcessor = 0; iProcessor < aConfig.nProcessors(); ++iProcessor) {
0317     out << "Processor: " << iProcessor;
0318     for (unsigned int iRefLayer = 0; iRefLayer < aConfig.nRefLayers(); ++iRefLayer) {
0319       out << " " << aConfig.processorPhiVsRefLayer[iProcessor][iRefLayer];
0320     }
0321     out << std::endl;
0322   }
0323 
0324   return out;
0325 }
0326 ///////////////////////////////////////////////
0327 ///////////////////////////////////////////////
0328 bool OMTFConfiguration::isInRegionRange(int iPhiStart, unsigned int coneSize, int iPhi) const {
0329   if (iPhi < 0)
0330     iPhi += nPhiBins();
0331   if (iPhiStart < 0)
0332     iPhiStart += nPhiBins();
0333 
0334   if (iPhiStart + (int)coneSize < (int)nPhiBins()) {
0335     return iPhiStart <= iPhi && iPhiStart + (int)coneSize > iPhi;
0336   } else if (iPhi > (int)nPhiBins() / 2) {
0337     return iPhiStart <= iPhi;
0338   } else if (iPhi < (int)nPhiBins() / 2) {
0339     return iPhi < iPhiStart + (int)coneSize - (int)nPhiBins();
0340   }
0341   return false;
0342 }
0343 ///////////////////////////////////////////////
0344 ///////////////////////////////////////////////
0345 unsigned int OMTFConfiguration::getRegionNumberFromMap(unsigned int iInput, unsigned int iRefLayer, int iPhi) const {
0346   for (unsigned int iRegion = 0; iRegion < nLogicRegions(); ++iRegion) {
0347     if (iPhi >= regionPhisVsRefLayerVsInput[iInput][iRefLayer][iRegion].first &&
0348         iPhi <= regionPhisVsRefLayerVsInput[iInput][iRefLayer][iRegion].second)
0349       return iRegion;
0350   }
0351 
0352   return 99;
0353 }
0354 ///////////////////////////////////////////////
0355 ///////////////////////////////////////////////
0356 int OMTFConfiguration::globalPhiStart(unsigned int iProcessor) const {
0357   return *std::min_element(processorPhiVsRefLayer[iProcessor].begin(), processorPhiVsRefLayer[iProcessor].end());
0358 }
0359 ///////////////////////////////////////////////
0360 ///////////////////////////////////////////////
0361 uint32_t OMTFConfiguration::getLayerNumber(uint32_t rawId) const {
0362   uint32_t aLayer = 0;
0363 
0364   DetId detId(rawId);
0365   if (detId.det() != DetId::Muon) {
0366     std::cout << "PROBLEM: hit in unknown Det, detID: " << detId.det() << std::endl;
0367     return rawId;
0368   }
0369 
0370   switch (detId.subdetId()) {
0371     case MuonSubdetId::RPC: {
0372       RPCDetId aId(rawId);
0373       bool isBarrel = (aId.region() == 0);
0374       if (isBarrel)
0375         aLayer = aId.station() <= 2 ? 2 * (aId.station() - 1) + aId.layer() : aId.station() + 2;
0376       else
0377         aLayer = aId.station();
0378       aLayer += 10 * (!isBarrel);
0379       break;
0380     }
0381     case MuonSubdetId::DT: {
0382       DTChamberId dt(rawId);
0383       aLayer = dt.station();
0384       break;
0385     }
0386     case MuonSubdetId::CSC: {
0387       CSCDetId csc(rawId);
0388       aLayer = csc.station();
0389       if (csc.ring() == 2 && csc.station() == 1)
0390         aLayer = 1811;  //1811 = 2011 - 200, as we want to get 2011 for this chamber.
0391       if (csc.station() == 4)
0392         aLayer = 4;
0393       break;
0394     }
0395   }
0396 
0397   int hwNumber = aLayer + 100 * detId.subdetId();
0398 
0399   return hwNumber;
0400 }
0401 
0402 int OMTFConfiguration::calcGlobalPhi(int locPhi, int proc) const {
0403   int globPhi = 0;
0404   //60 degree sectors = 96 in int-scale
0405   globPhi = (proc) * 96 * 6 / nProcessors() + locPhi;
0406   // first processor starts at CMS phi = 15 degrees (24 in int)... Handle wrap-around with %. Add 576 to make sure the number is positive
0407   globPhi = (globPhi + 600) % 576;
0408   return globPhi;
0409 }
0410 
0411 unsigned int OMTFConfiguration::eta2Bits(unsigned int eta) {
0412   if (eta == 73)
0413     return 0b100000000;
0414   else if (eta == 78)
0415     return 0b010000000;
0416   else if (eta == 85)
0417     return 0b001000000;
0418   else if (eta == 90)
0419     return 0b000100000;
0420   else if (eta == 94)
0421     return 0b000010000;
0422   else if (eta == 99)
0423     return 0b000001000;
0424   else if (eta == 103)
0425     return 0b000000100;
0426   else if (eta == 110)
0427     return 0b000000010;
0428   else if (eta == 75)
0429     return 0b110000000;
0430   else if (eta == 79)
0431     return 0b011000000;
0432   else if (eta == 92)
0433     return 0b000110000;
0434   else if (eta == 115)
0435     return 0b000000001;
0436   else if (eta == 121)
0437     return 0b000000000;
0438   else
0439     return 0b111111111;
0440   ;
0441 }
0442 
0443 unsigned int OMTFConfiguration::etaBits2HwEta(unsigned int bits) {
0444   if (bits == 0b100000000)
0445     return 73;
0446   else if (bits == 0b010000000)
0447     return 78;
0448   else if (bits == 0b001000000)
0449     return 85;
0450   else if (bits == 0b000100000)
0451     return 90;
0452   else if (bits == 0b000010000)
0453     return 94;
0454   else if (bits == 0b000001000)
0455     return 99;
0456   else if (bits == 0b000000100)
0457     return 103;
0458   else if (bits == 0b000000010)
0459     return 110;
0460   else if (bits == 0b110000000)
0461     return 75;
0462   else if (bits == 0b011000000)
0463     return 79;
0464   else if (bits == 0b000110000)
0465     return 92;
0466   else if (bits == 0b000000001)
0467     return 115;
0468   else if (bits == 0b000000000)
0469     return 121;
0470   else if (bits == 0b111111111)
0471     return 95;
0472   else
0473     return 0b111111111;
0474   ;
0475 }
0476 
0477 int OMTFConfiguration::etaBit2Code(unsigned int bit) {
0478   int code = 73;
0479   switch (bit) {
0480     case 0: {
0481       code = 115;
0482       break;
0483     }
0484     case 1: {
0485       code = 110;
0486       break;
0487     }
0488     case 2: {
0489       code = 103;
0490       break;
0491     }
0492     case 3: {
0493       code = 99;
0494       break;
0495     }
0496     case 4: {
0497       code = 94;
0498       break;
0499     }
0500     case 5: {
0501       code = 90;
0502       break;
0503     }
0504     case 6: {
0505       code = 85;
0506       break;
0507     }
0508     case 7: {
0509       code = 78;
0510       break;
0511     }
0512     case 8: {
0513       code = 73;
0514       break;
0515     }
0516     default: {
0517       code = 95;
0518       break;
0519     }
0520   }
0521   return code;
0522 }
0523 
0524 ///////////////////////////////////////////////
0525 // phiRad should be in the range [-pi,pi]
0526 int OMTFConfiguration::getProcScalePhi(unsigned int iProcessor, double phiRad) const {
0527   double phi15deg =
0528       M_PI / 3. * (iProcessor) + M_PI / 12.;  // "0" is 15degree moved cyclically to each processor, note [0,2pi]
0529 
0530   const double phiUnit = 2 * M_PI / nPhiBins();  //rad/unit
0531 
0532   // adjust [0,2pi] and [-pi,pi] to get deltaPhi difference properly
0533   switch (iProcessor + 1) {
0534     case 1:
0535       break;
0536     case 6: {
0537       phi15deg -= 2 * M_PI;
0538       break;
0539     }
0540     default: {
0541       if (phiRad < 0)
0542         phiRad += 2 * M_PI;
0543       break;
0544     }
0545   }
0546 
0547   // local angle in CSC halfStrip usnits
0548   return lround((phiRad - phi15deg) / phiUnit);  //FIXME lround or floor ???
0549 }
0550 
0551 ///////////////////////////////////////////////
0552 ///////////////////////////////////////////////
0553 double OMTFConfiguration::procHwPhiToGlobalPhi(int procHwPhi, int procHwPhi0) const {
0554   int globalHwPhi = foldPhi(procHwPhi + procHwPhi0);
0555   const double phiUnit = 2 * M_PI / nPhiBins();  //rad/unit
0556   return globalHwPhi * phiUnit;
0557 }
0558 
0559 ///////////////////////////////////////////////
0560 ///////////////////////////////////////////////
0561 OMTFConfiguration::PatternPt OMTFConfiguration::getPatternPtRange(unsigned int patNum) const {
0562   if (patternPts.empty())
0563     throw cms::Exception("OMTFConfiguration::getPatternPtRange: patternPts vector not initialized");
0564 
0565   if (patNum > patternPts.size()) {
0566     throw cms::Exception("OMTFConfiguration::getPatternPtRange: patNum > patternPts.size()");
0567   }
0568   return patternPts[patNum];
0569 }
0570 
0571 unsigned int OMTFConfiguration::getPatternNum(double pt, int charge) const {
0572   //in LUT the charge is in convention 0 is -, 1 is + (so it is not the uGMT convention!!!)
0573   //so we change the charge here
0574   //if(charge == -1)
0575   //charge = 0;  //TODO but in the xml (and in GPs) the charge is +1 and -1, so it is important from where the patternPts is loaded FIXME!!!
0576   for (unsigned int iPat = 0; iPat < patternPts.size(); iPat++) {
0577     //std::cout<<"iPAt "<<iPat<<" ptFrom "<<getPatternPtRange(iPat).ptFrom<<" "<<getPatternPtRange(iPat).ptTo<<" "<<rawParams.chargeLUT()->data(iPat)<<std::endl;
0578     PatternPt patternPt = getPatternPtRange(iPat);
0579     if (pt >= patternPt.ptFrom && pt < patternPt.ptTo && charge == patternPt.charge)
0580       return iPat;
0581   }
0582   return 0;  //FIXME in this way if pt < 4GeV, the pattern = 0 is return , regardless of sign!
0583 }
0584 
0585 void OMTFConfiguration::printConfig() const {
0586   edm::LogVerbatim("OMTFReconstruction") << "OMTFConfiguration: " << std::endl;
0587 
0588   edm::LogVerbatim("OMTFReconstruction") << "rpcMaxClusterSize " << getRpcMaxClusterSize() << std::endl;
0589   edm::LogVerbatim("OMTFReconstruction") << "rpcMaxClusterCnt " << getRpcMaxClusterCnt() << std::endl;
0590   edm::LogVerbatim("OMTFReconstruction") << "rpcDropAllClustersIfMoreThanMax " << getRpcDropAllClustersIfMoreThanMax()
0591                                          << std::endl;
0592   edm::LogVerbatim("OMTFReconstruction") << "minDtPhiQuality " << getMinDtPhiQuality() << std::endl;
0593   edm::LogVerbatim("OMTFReconstruction") << "minDtPhiBQuality " << getMinDtPhiBQuality() << std::endl;
0594 
0595   edm::LogVerbatim("OMTFReconstruction") << "cscLctCentralBx_ " << cscLctCentralBx() << std::endl;
0596 
0597   edm::LogVerbatim("OMTFReconstruction") << "goldenPatternResultFinalizeFunction "
0598                                          << goldenPatternResultFinalizeFunction << std::endl;
0599   edm::LogVerbatim("OMTFReconstruction") << "noHitValueInPdf " << noHitValueInPdf << std::endl;
0600   edm::LogVerbatim("OMTFReconstruction") << "sorterType " << sorterType << std::endl;
0601   edm::LogVerbatim("OMTFReconstruction") << "ghostBusterType " << ghostBusterType << std::endl;
0602 
0603   edm::LogVerbatim("OMTFReconstruction") << "usePhiBExtrapolationFromMB1 " << usePhiBExtrapolationFromMB1_ << std::endl;
0604   edm::LogVerbatim("OMTFReconstruction") << "usePhiBExtrapolationFromMB2 " << usePhiBExtrapolationFromMB2_ << std::endl;
0605   edm::LogVerbatim("OMTFReconstruction") << "useStubQualInExtr " << useStubQualInExtr_ << std::endl;
0606   edm::LogVerbatim("OMTFReconstruction") << "useEndcapStubsRInExtr " << useEndcapStubsRInExtr_ << std::endl;
0607   edm::LogVerbatim("OMTFReconstruction") << "dtRefHitMinQuality " << dtRefHitMinQuality << std::endl;
0608 
0609   edm::LogVerbatim("OMTFReconstruction") << "cleanStubs " << cleanStubs_ << std::endl;
0610 }