Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-10-06 02:54:09

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() + 6, barrelMin.begin());
0070   std::copy(connectedSectorsStartVec->begin() + 6, connectedSectorsStartVec->begin() + 12, endcap10DegMin.begin());
0071   std::copy(connectedSectorsStartVec->begin() + 12, connectedSectorsStartVec->end(), endcap20DegMin.begin());
0072 
0073   std::copy(connectedSectorsEndVec->begin(), connectedSectorsEndVec->begin() + 6, barrelMax.begin());
0074   std::copy(connectedSectorsEndVec->begin() + 6, connectedSectorsEndVec->begin() + 12, endcap10DegMax.begin());
0075   std::copy(connectedSectorsEndVec->begin() + 12, connectedSectorsEndVec->end(), endcap20DegMax.begin());
0076 
0077   ///Set connections tables
0078   const std::vector<L1TMuonOverlapParams::LayerMapNode> *layerMap = omtfParams->layerMap();
0079 
0080   for (unsigned int iLayer = 0; iLayer < nLayers(); ++iLayer) {
0081     L1TMuonOverlapParams::LayerMapNode aNode = layerMap->at(iLayer);
0082     hwToLogicLayer[aNode.hwNumber] = aNode.logicNumber;
0083     logicToHwLayer[aNode.logicNumber] = aNode.hwNumber;
0084     logicToLogic[aNode.logicNumber] = aNode.connectedToLayer;
0085     if (aNode.bendingLayer)
0086       bendingLayers.insert(aNode.logicNumber);
0087   }
0088   /////
0089   refToLogicNumber.resize(nRefLayers());
0090 
0091   const std::vector<L1TMuonOverlapParams::RefLayerMapNode> *refLayerMap = omtfParams->refLayerMap();
0092   for (unsigned int iRefLayer = 0; iRefLayer < nRefLayers(); ++iRefLayer) {
0093     L1TMuonOverlapParams::RefLayerMapNode aNode = refLayerMap->at(iRefLayer);
0094     refToLogicNumber[aNode.refLayer] = aNode.logicNumber;
0095   }
0096   /////
0097   std::vector<int> vector1D(nRefLayers(), nPhiBins());
0098   processorPhiVsRefLayer.assign(nProcessors(), vector1D);
0099 
0100   ///connections tables for each processor each logic cone
0101   ///Vector of all layers
0102   vector1D_pair aLayer1D(nLayers());
0103   ///Vector of all logic cones
0104   vector2D_pair aLayer2D;
0105   aLayer2D.assign(nLogicRegions(), aLayer1D);
0106   ///Vector of all processors
0107   connections.assign(nProcessors(), aLayer2D);
0108 
0109   ///Starting phis of each region
0110   ///Vector of all regions in one processor
0111   std::vector<std::pair<int, int> > aRefHit1D(nLogicRegions(), std::pair<int, int>(9999, 9999));
0112   ///Vector of all reflayers
0113   std::vector<std::vector<std::pair<int, int> > > aRefHit2D;
0114   aRefHit2D.assign(nRefLayers(), aRefHit1D);
0115   ///Vector of all inputs
0116   regionPhisVsRefLayerVsInput.assign(nInputs(), aRefHit2D);
0117 
0118   //Vector of ref hit definitions
0119   std::vector<RefHitDef> aRefHitsDefs(nRefHits());
0120   ///Vector of all processros
0121   refHitsDefs.assign(nProcessors(), aRefHitsDefs);
0122 
0123   const std::vector<int> *phiStartMap = omtfParams->globalPhiStartMap();
0124   const std::vector<L1TMuonOverlapParams::RefHitNode> *refHitMap = omtfParams->refHitMap();
0125   const std::vector<L1TMuonOverlapParams::LayerInputNode> *layerInputMap = omtfParams->layerInputMap();
0126   unsigned int tmpIndex = 0;
0127   for (unsigned int iProcessor = 0; iProcessor < nProcessors(); ++iProcessor) {
0128     for (unsigned int iRefLayer = 0; iRefLayer < nRefLayers(); ++iRefLayer) {
0129       int iPhiStart = phiStartMap->at(iRefLayer + iProcessor * nRefLayers());
0130       processorPhiVsRefLayer[iProcessor][iRefLayer] = iPhiStart;
0131     }
0132     for (unsigned int iRefHit = 0; iRefHit < nRefHits(); ++iRefHit) {
0133       int iPhiMin = refHitMap->at(iRefHit + iProcessor * nRefHits()).iPhiMin;
0134       int iPhiMax = refHitMap->at(iRefHit + iProcessor * nRefHits()).iPhiMax;
0135       unsigned int iInput = refHitMap->at(iRefHit + iProcessor * nRefHits()).iInput;
0136       unsigned int iRegion = refHitMap->at(iRefHit + iProcessor * nRefHits()).iRegion;
0137       unsigned int iRefLayer = refHitMap->at(iRefHit + iProcessor * nRefHits()).iRefLayer;
0138       regionPhisVsRefLayerVsInput[iInput][iRefLayer][iRegion] = std::pair<int, int>(iPhiMin, iPhiMax);
0139       refHitsDefs[iProcessor][iRefHit] = RefHitDef(iInput, iPhiMin, iPhiMax, iRegion, iRefLayer);
0140     }
0141     for (unsigned int iLogicRegion = 0; iLogicRegion < nLogicRegions(); ++iLogicRegion) {
0142       for (unsigned int iLayer = 0; iLayer < nLayers(); ++iLayer) {
0143         tmpIndex = iLayer + iLogicRegion * nLayers() + iProcessor * nLogicRegions() * nLayers();
0144         unsigned int iFirstInput = layerInputMap->at(tmpIndex).iFirstInput;
0145         unsigned int nInputsInRegion = layerInputMap->at(tmpIndex).nInputs;
0146         connections[iProcessor][iLogicRegion][iLayer] =
0147             std::pair<unsigned int, unsigned int>(iFirstInput, nInputsInRegion);
0148         ///Symetrize connections. Use the same connections for all processors
0149         if (iProcessor != 0)
0150           connections[iProcessor][iLogicRegion][iLayer] = connections[0][iLogicRegion][iLayer];
0151       }
0152     }
0153   }
0154 
0155   initCounterMatrices();
0156 
0157   pdfBins = (1 << rawParams.nPdfAddrBits());
0158   pdfMaxVal = (1 << rawParams.nPdfValBits()) - 1;
0159 
0160   //configuration based on the firmware version parameter
0161   //TODO add next entries for the new firmware
0162   //the default values of the parameters are used, if not set here, so don't mess them!
0163   if (fwVersion() <= 4) {
0164     setMinDtPhiQuality(4);
0165   } else if (fwVersion() == 5) {
0166     setMinDtPhiQuality(2);
0167     setGhostBusterType("GhostBusterPreferRefDt");
0168   } else if (fwVersion() == 6) {
0169     setMinDtPhiQuality(2);
0170     setGhostBusterType("GhostBusterPreferRefDt");
0171   } else if (fwVersion() == 8) {
0172     setMinDtPhiQuality(2);
0173     setMinDtPhiBQuality(2);  //should be 4, but in the fwVersion = 8 was not yet implemented
0174 
0175     setSorterType(1);  //"byLLH"
0176 
0177     setRpcMaxClusterSize(3);
0178     setRpcMaxClusterCnt(2);
0179     setRpcDropAllClustersIfMoreThanMax(true);
0180 
0181     setGoldenPatternResultFinalizeFunction(9);
0182 
0183     setNoHitValueInPdf(true);
0184 
0185     setGhostBusterType("GhostBusterPreferRefDt");
0186   }
0187 }
0188 
0189 void OMTFConfiguration::configureFromEdmParameterSet(const edm::ParameterSet &edmParameterSet) {
0190   edm::LogVerbatim("OMTFReconstruction") << "OMTFConfiguration::configureFromEdmParameterSet: setting the params from "
0191                                             "python config (overwrites the EventSetup (DB) params): "
0192                                          << std::endl;
0193 
0194   ProcConfigurationBase::configureFromEdmParameterSet(edmParameterSet);
0195 
0196   if (edmParameterSet.exists("goldenPatternResultFinalizeFunction")) {
0197     int finalizeFunction = edmParameterSet.getParameter<int>("goldenPatternResultFinalizeFunction");
0198     setGoldenPatternResultFinalizeFunction(finalizeFunction);
0199     edm::LogVerbatim("OMTFReconstruction")
0200         << "GoldenPatternResult::setFinalizeFunction: " << finalizeFunction << std::endl;
0201   }
0202 
0203   if (edmParameterSet.exists("noHitValueInPdf")) {
0204     setNoHitValueInPdf(edmParameterSet.getParameter<bool>("noHitValueInPdf"));
0205     edm::LogVerbatim("OMTFReconstruction")
0206         << "noHitValueInPdf: " << edmParameterSet.getParameter<bool>("noHitValueInPdf") << std::endl;
0207   }
0208 
0209   if (edmParameterSet.exists("sorterType")) {
0210     string sorterTypeStr = edmParameterSet.getParameter<std::string>("sorterType");
0211     if (sorterTypeStr == "byNhitsByLLH")
0212       sorterType = 0;
0213     if (sorterTypeStr == "byLLH")
0214       sorterType = 1;
0215 
0216     edm::LogVerbatim("OMTFReconstruction") << "sorterType: " << sorterType << " = "
0217                                            << edmParameterSet.getParameter<std::string>("sorterType") << std::endl;
0218   }
0219 
0220   if (edmParameterSet.exists("ghostBusterType")) {
0221     setGhostBusterType(edmParameterSet.getParameter<std::string>("ghostBusterType"));
0222 
0223     edm::LogVerbatim("OMTFReconstruction") << "ghostBusterType: " << getGhostBusterType() << std::endl;
0224   }
0225 
0226   setFixCscGeometryOffset(true);  //for the OMTF by default is true, read from python if needed
0227 }
0228 
0229 ///////////////////////////////////////////////
0230 ///////////////////////////////////////////////
0231 std::ostream &operator<<(std::ostream &out, const OMTFConfiguration &aConfig) {
0232   out << "nLayers(): " << aConfig.nLayers() << std::endl
0233       << " nHitsPerLayer(): " << aConfig.nHitsPerLayer() << std::endl
0234       << " nRefLayers(): " << aConfig.nRefLayers() << std::endl
0235       << " nPdfAddrBits: " << aConfig.nPdfAddrBits() << std::endl
0236       << " nPdfValBits: " << aConfig.nPdfValBits() << std::endl
0237       << " nPhiBins(): " << aConfig.nPhiBins() << std::endl
0238       << " nPdfAddrBits(): " << aConfig.nPdfAddrBits() << std::endl
0239       << std::endl;
0240 
0241   for (unsigned int iProcessor = 0; iProcessor < aConfig.nProcessors(); ++iProcessor) {
0242     out << "Processor: " << iProcessor;
0243     for (unsigned int iRefLayer = 0; iRefLayer < aConfig.nRefLayers(); ++iRefLayer) {
0244       out << " " << aConfig.processorPhiVsRefLayer[iProcessor][iRefLayer];
0245     }
0246     out << std::endl;
0247   }
0248 
0249   return out;
0250 }
0251 ///////////////////////////////////////////////
0252 ///////////////////////////////////////////////
0253 bool OMTFConfiguration::isInRegionRange(int iPhiStart, unsigned int coneSize, int iPhi) const {
0254   if (iPhi < 0)
0255     iPhi += nPhiBins();
0256   if (iPhiStart < 0)
0257     iPhiStart += nPhiBins();
0258 
0259   if (iPhiStart + (int)coneSize < (int)nPhiBins()) {
0260     return iPhiStart <= iPhi && iPhiStart + (int)coneSize > iPhi;
0261   } else if (iPhi > (int)nPhiBins() / 2) {
0262     return iPhiStart <= iPhi;
0263   } else if (iPhi < (int)nPhiBins() / 2) {
0264     return iPhi < iPhiStart + (int)coneSize - (int)nPhiBins();
0265   }
0266   return false;
0267 }
0268 ///////////////////////////////////////////////
0269 ///////////////////////////////////////////////
0270 unsigned int OMTFConfiguration::getRegionNumberFromMap(unsigned int iInput, unsigned int iRefLayer, int iPhi) const {
0271   for (unsigned int iRegion = 0; iRegion < nLogicRegions(); ++iRegion) {
0272     if (iPhi >= regionPhisVsRefLayerVsInput[iInput][iRefLayer][iRegion].first &&
0273         iPhi <= regionPhisVsRefLayerVsInput[iInput][iRefLayer][iRegion].second)
0274       return iRegion;
0275   }
0276 
0277   return 99;
0278 }
0279 ///////////////////////////////////////////////
0280 ///////////////////////////////////////////////
0281 int OMTFConfiguration::globalPhiStart(unsigned int iProcessor) const {
0282   return *std::min_element(processorPhiVsRefLayer[iProcessor].begin(), processorPhiVsRefLayer[iProcessor].end());
0283 }
0284 ///////////////////////////////////////////////
0285 ///////////////////////////////////////////////
0286 uint32_t OMTFConfiguration::getLayerNumber(uint32_t rawId) const {
0287   uint32_t aLayer = 0;
0288 
0289   DetId detId(rawId);
0290   if (detId.det() != DetId::Muon) {
0291     std::cout << "PROBLEM: hit in unknown Det, detID: " << detId.det() << std::endl;
0292     return rawId;
0293   }
0294 
0295   switch (detId.subdetId()) {
0296     case MuonSubdetId::RPC: {
0297       RPCDetId aId(rawId);
0298       bool isBarrel = (aId.region() == 0);
0299       if (isBarrel)
0300         aLayer = aId.station() <= 2 ? 2 * (aId.station() - 1) + aId.layer() : aId.station() + 2;
0301       else
0302         aLayer = aId.station();
0303       aLayer += 10 * (!isBarrel);
0304       break;
0305     }
0306     case MuonSubdetId::DT: {
0307       DTChamberId dt(rawId);
0308       aLayer = dt.station();
0309       break;
0310     }
0311     case MuonSubdetId::CSC: {
0312       CSCDetId csc(rawId);
0313       aLayer = csc.station();
0314       if (csc.ring() == 2 && csc.station() == 1)
0315         aLayer = 1811;  //1811 = 2011 - 200, as we want to get 2011 for this chamber.
0316       if (csc.station() == 4)
0317         aLayer = 4;
0318       break;
0319     }
0320   }
0321 
0322   int hwNumber = aLayer + 100 * detId.subdetId();
0323 
0324   return hwNumber;
0325 }
0326 
0327 ///////////////////////////////////////////////
0328 // phiRad should be in the range [-pi,pi]
0329 int OMTFConfiguration::getProcScalePhi(unsigned int iProcessor, double phiRad) const {
0330   double phi15deg =
0331       M_PI / 3. * (iProcessor) + M_PI / 12.;  // "0" is 15degree moved cyclically to each processor, note [0,2pi]
0332 
0333   const double phiUnit = 2 * M_PI / nPhiBins();  //rad/unit
0334 
0335   // adjust [0,2pi] and [-pi,pi] to get deltaPhi difference properly
0336   switch (iProcessor + 1) {
0337     case 1:
0338       break;
0339     case 6: {
0340       phi15deg -= 2 * M_PI;
0341       break;
0342     }
0343     default: {
0344       if (phiRad < 0)
0345         phiRad += 2 * M_PI;
0346       break;
0347     }
0348   }
0349 
0350   // local angle in CSC halfStrip usnits
0351   return lround((phiRad - phi15deg) / phiUnit);  //FIXME lround or floor ???
0352 }
0353 
0354 ///////////////////////////////////////////////
0355 ///////////////////////////////////////////////
0356 double OMTFConfiguration::procHwPhiToGlobalPhi(int procHwPhi, int procHwPhi0) const {
0357   int globalHwPhi = foldPhi(procHwPhi + procHwPhi0);
0358   const double phiUnit = 2 * M_PI / nPhiBins();  //rad/unit
0359   return globalHwPhi * phiUnit;
0360 }
0361 
0362 ///////////////////////////////////////////////
0363 ///////////////////////////////////////////////
0364 OMTFConfiguration::PatternPt OMTFConfiguration::getPatternPtRange(unsigned int patNum) const {
0365   if (patternPts.empty())
0366     throw cms::Exception("OMTFConfiguration::getPatternPtRange: patternPts vector not initialized");
0367 
0368   if (patNum > patternPts.size()) {
0369     throw cms::Exception("OMTFConfiguration::getPatternPtRange: patNum > patternPts.size()");
0370   }
0371   return patternPts[patNum];
0372 }
0373 
0374 unsigned int OMTFConfiguration::getPatternNum(double pt, int charge) const {
0375   //in LUT the charge is in convention 0 is -, 1 is + (so it is not the uGMT convention!!!)
0376   //so we change the charge here
0377   //if(charge == -1)
0378   //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!!!
0379   for (unsigned int iPat = 0; iPat < patternPts.size(); iPat++) {
0380     //std::cout<<"iPAt "<<iPat<<" ptFrom "<<getPatternPtRange(iPat).ptFrom<<" "<<getPatternPtRange(iPat).ptTo<<" "<<rawParams.chargeLUT()->data(iPat)<<std::endl;
0381     PatternPt patternPt = getPatternPtRange(iPat);
0382     if (pt >= patternPt.ptFrom && pt < patternPt.ptTo && charge == patternPt.charge)
0383       return iPat;
0384   }
0385   return 0;  //FIXME in this way if pt < 4GeV, the pattern = 0 is return , regardless of sign!
0386 }
0387 
0388 void OMTFConfiguration::printConfig() const {
0389   edm::LogVerbatim("OMTFReconstruction") << "OMTFConfiguration: " << std::endl;
0390 
0391   edm::LogVerbatim("OMTFReconstruction") << "rpcMaxClusterSize " << getRpcMaxClusterSize() << std::endl;
0392   edm::LogVerbatim("OMTFReconstruction") << "rpcMaxClusterCnt " << getRpcMaxClusterCnt() << std::endl;
0393   edm::LogVerbatim("OMTFReconstruction") << "rpcDropAllClustersIfMoreThanMax " << getRpcDropAllClustersIfMoreThanMax()
0394                                          << std::endl;
0395   edm::LogVerbatim("OMTFReconstruction") << "minDtPhiQuality " << getMinDtPhiQuality() << std::endl;
0396   edm::LogVerbatim("OMTFReconstruction") << "minDtPhiBQuality " << getMinDtPhiBQuality() << std::endl;
0397 
0398   edm::LogVerbatim("OMTFReconstruction") << "cscLctCentralBx_ " << cscLctCentralBx() << std::endl;
0399 
0400   edm::LogVerbatim("OMTFReconstruction") << "goldenPatternResultFinalizeFunction "
0401                                          << goldenPatternResultFinalizeFunction << std::endl;
0402   edm::LogVerbatim("OMTFReconstruction") << "noHitValueInPdf " << noHitValueInPdf << std::endl;
0403   edm::LogVerbatim("OMTFReconstruction") << "sorterType " << sorterType << std::endl;
0404   edm::LogVerbatim("OMTFReconstruction") << "ghostBusterType " << ghostBusterType << std::endl;
0405 }