Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-01-28 00:23:08

0001 // -*- C++ -*-
0002 //
0003 // Package:    RPCConeBuilder
0004 // Class:      RPCConeBuilder
0005 //
0006 /**\class RPCConeBuilder RPCConeBuilder.h L1Trigger/RPCTriggerConfig/src/RPCConeBuilder.cc
0007 
0008  Description: The RPCConeBuilder class is the emulator of the Run 1 RPC PAC Trigger. 
0009               It is not used in the L1 Trigger decision since 2016.
0010           It might be needed just for the re-emulation of the Run 1 data.
0011 
0012  Implementation:
0013      <Notes on implementation>
0014 */
0015 //
0016 // Original Author:  Tomasz Maciej Frueboes
0017 //         Created:  Fri Feb 22 13:57:06 CET 2008
0018 //
0019 //
0020 
0021 #include "CondFormats/DataRecord/interface/L1RPCConeBuilderRcd.h"
0022 #include "CondFormats/L1TObjects/interface/L1RPCConeDefinition.h"
0023 #include "CondFormats/RPCObjects/interface/L1RPCConeBuilder.h"
0024 #include "CondFormats/DataRecord/interface/L1RPCConeDefinitionRcd.h"
0025 #include "FWCore/Framework/interface/ModuleFactory.h"
0026 #include "FWCore/Framework/interface/ESProducer.h"
0027 #include "FWCore/Framework/interface/ModuleFactory.h"
0028 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0029 #include "FWCore/Utilities/interface/Exception.h"
0030 #include "Geometry/Records/interface/MuonGeometryRecord.h"
0031 #include "Geometry/RPCGeometry/interface/RPCGeometry.h"
0032 #include "L1Trigger/RPCTrigger/interface/RPCStripsRing.h"
0033 
0034 #include <cmath>
0035 #include <vector>
0036 #include <map>
0037 #include <memory>
0038 #include <utility>
0039 
0040 class RPCConeBuilder : public edm::ESProducer {
0041 public:
0042   RPCConeBuilder(const edm::ParameterSet&);
0043 
0044   using ReturnType = std::unique_ptr<L1RPCConeBuilder>;
0045 
0046   ReturnType produce(const L1RPCConeBuilderRcd&);
0047 
0048 private:
0049   void buildCones(RPCGeometry const*, L1RPCConeDefinition const*, RPCStripsRing::TIdToRindMap&);
0050 
0051   void buildConnections(L1RPCConeDefinition const*, RPCStripsRing::TIdToRindMap&);
0052 
0053   /// In the pair that is returned, the first element is the logplane number
0054   /// for this connection (if not connected returns -1) and the second element
0055   /// is lpSize.
0056   std::pair<int, int> areConnected(RPCStripsRing::TIdToRindMap::iterator ref,
0057                                    RPCStripsRing::TIdToRindMap::iterator other,
0058                                    L1RPCConeDefinition const*);
0059 
0060   // ----------member data ---------------------------
0061   edm::ESGetToken<RPCGeometry, MuonGeometryRecord> m_rpcGeometryToken;
0062   edm::ESGetToken<L1RPCConeDefinition, L1RPCConeDefinitionRcd> m_l1RPCConeDefinitionToken;
0063   int m_towerBeg;
0064   int m_towerEnd;
0065 };
0066 
0067 RPCConeBuilder::RPCConeBuilder(const edm::ParameterSet& iConfig)
0068     : m_towerBeg(iConfig.getParameter<int>("towerBeg")), m_towerEnd(iConfig.getParameter<int>("towerEnd")) {
0069   auto cc = setWhatProduced(this);
0070   m_rpcGeometryToken = cc.consumes();
0071   m_l1RPCConeDefinitionToken = cc.consumes();
0072 }
0073 
0074 // ------------ method called to produce the data  ------------
0075 RPCConeBuilder::ReturnType RPCConeBuilder::produce(const L1RPCConeBuilderRcd& iRecord) {
0076   auto pL1RPCConeBuilder = std::make_unique<L1RPCConeBuilder>();
0077 
0078   pL1RPCConeBuilder->setFirstTower(m_towerBeg);
0079   pL1RPCConeBuilder->setLastTower(m_towerEnd);
0080 
0081   RPCStripsRing::TIdToRindMap ringsMap;
0082 
0083   buildCones(&iRecord.get(m_rpcGeometryToken), &iRecord.get(m_l1RPCConeDefinitionToken), ringsMap);
0084 
0085   // Compress all connections. Since members of this class are shared
0086   // pointers this call will compress all data
0087   ringsMap.begin()->second.compressConnections();
0088 
0089   pL1RPCConeBuilder->setConeConnectionMap(ringsMap.begin()->second.getConnectionsMap());
0090 
0091   pL1RPCConeBuilder->setCompressedConeConnectionMap(ringsMap.begin()->second.getCompressedConnectionsMap());
0092 
0093   return pL1RPCConeBuilder;
0094 }
0095 
0096 void RPCConeBuilder::buildCones(RPCGeometry const* rpcGeom,
0097                                 L1RPCConeDefinition const* l1RPCConeDefinition,
0098                                 RPCStripsRing::TIdToRindMap& ringsMap) {
0099   // fetch geometrical data
0100   auto uncompressedCons = std::make_shared<L1RPCConeBuilder::TConMap>();
0101 
0102   int rolls = 0;
0103   for (auto const& it : rpcGeom->dets()) {
0104     RPCRoll const* roll = dynamic_cast<RPCRoll const*>(it);
0105     if (roll == nullptr) {
0106       continue;
0107     }
0108 
0109     ++rolls;
0110 
0111     int ringId = RPCStripsRing::getRingId(roll);
0112     auto found = ringsMap.find(ringId);
0113     if (found == ringsMap.end()) {
0114       ringsMap[ringId] = RPCStripsRing(roll, uncompressedCons);
0115     } else {
0116       found->second.addRoll(roll);
0117     }
0118   }
0119 
0120   // filtermixed strips, fill gaps with virtual strips
0121   for (auto& it : ringsMap) {
0122     it.second.filterOverlapingChambers();
0123     it.second.fillWithVirtualStrips();
0124   }
0125 
0126   // Xcheck, if rings are symmetrical
0127   for (auto& it : ringsMap) {
0128     int key = it.first;
0129     int sign = key / 100 - (key / 1000) * 10;
0130 
0131     if (sign == 0) {
0132       key += 100;
0133     } else {
0134       key -= 100;
0135     }
0136 
0137     // Check if the geometry has a complete ring:
0138     // note that in the case of demo chambers, the ring is not filled because only 2 sectors are added.
0139     // (3014 and 4014 lack counter-rings)
0140     if (key != 2000 && key != 3014 && key != 4014) {  // Key 2100 has no counter-ring
0141       if (it.second.size() != ringsMap[key].size()) {
0142         throw cms::Exception("RPCInternal") << " Size differs for ring " << key << " +- 100 \n";
0143       }
0144     }
0145   }
0146   buildConnections(l1RPCConeDefinition, ringsMap);
0147 }
0148 
0149 void RPCConeBuilder::buildConnections(L1RPCConeDefinition const* l1RPCConeDefinition,
0150                                       RPCStripsRing::TIdToRindMap& ringsMap) {
0151   RPCStripsRing::TIdToRindMap::iterator itRef = ringsMap.begin();
0152   for (; itRef != ringsMap.end(); ++itRef) {  // iterate over reference rings
0153 
0154     RPCStripsRing::TOtherConnStructVec ringsToConnect;
0155 
0156     if (!itRef->second.isReferenceRing())
0157       continue;  // iterate over reference rings
0158 
0159     RPCStripsRing::TIdToRindMap::iterator itOther = ringsMap.begin();
0160     for (; itOther != ringsMap.end(); ++itOther) {  // iterate over nonreference rings
0161 
0162       if (itOther->second.isReferenceRing())
0163         continue;  // iterate over nonreference rings
0164 
0165       std::pair<int, int> pr = areConnected(itRef, itOther, l1RPCConeDefinition);
0166       if (pr.first != -1) {
0167         RPCStripsRing::TOtherConnStruct newOtherConn;
0168         newOtherConn.m_it = itOther;
0169         newOtherConn.m_logplane = pr.first;
0170         newOtherConn.m_logplaneSize = pr.second;
0171         ringsToConnect.push_back(newOtherConn);
0172       }
0173     }  // OtherRings iteration ends
0174 
0175     std::pair<int, int> prRef = areConnected(itRef, itRef, l1RPCConeDefinition);
0176     if (prRef.first == -1) {
0177       throw cms::Exception("RPCConfig") << " Cannot determine logplane for reference ring " << itRef->first << "\n ";
0178     }
0179 
0180     itRef->second.createRefConnections(ringsToConnect, prRef.first, prRef.second);
0181 
0182   }  // RefRings iteration ends
0183 }
0184 
0185 // first - logplane
0186 // second - logplanesize
0187 std::pair<int, int> RPCConeBuilder::areConnected(RPCStripsRing::TIdToRindMap::iterator ref,
0188                                                  RPCStripsRing::TIdToRindMap::iterator other,
0189                                                  L1RPCConeDefinition const* l1RPCConeDefinition) {
0190   int logplane = -1;
0191 
0192   // Do not connect  rolls lying on the oposite side of detector
0193   if (ref->second.getEtaPartition() * other->second.getEtaPartition() < 0)
0194     return std::make_pair(-1, 0);
0195 
0196   int refTowerCnt = 0;
0197   int index = -1;
0198   int refTower = -1;
0199 
0200   for (auto const& itRef : l1RPCConeDefinition->getRingToTowerVec()) {
0201     if (itRef.m_etaPart != std::abs(ref->second.getEtaPartition()) ||
0202         itRef.m_hwPlane != std::abs(ref->second.getHwPlane() - 1)  // -1?
0203     ) {
0204       continue;
0205     }
0206 
0207     ++refTowerCnt;
0208     refTower = itRef.m_tower;
0209 
0210     for (auto const& itOther : l1RPCConeDefinition->getRingToTowerVec()) {
0211       if (itOther.m_etaPart != std::abs(other->second.getEtaPartition()) ||
0212           itOther.m_hwPlane != std::abs(other->second.getHwPlane() - 1)  // -1?
0213       ) {
0214         continue;
0215       }
0216 
0217       if (itOther.m_tower == refTower) {
0218         index = itOther.m_index;
0219       }
0220     }
0221   }
0222 
0223   if (refTowerCnt > 1) {
0224     throw cms::Exception("RPCConeBuilder") << " Reference(?) ring " << ref->first << " "
0225                                            << "wants to be connected to " << refTowerCnt << " towers \n";
0226   }
0227 
0228   if (refTowerCnt == 0) {
0229     throw cms::Exception("RPCConeBuilder") << " Reference(?) ring " << ref->first << " "
0230                                            << " is not connected anywhere \n";
0231   }
0232 
0233   int lpSize = 0;
0234   if (index != -1) {
0235     for (auto const& it : l1RPCConeDefinition->getRingToLPVec()) {
0236       if (it.m_etaPart != std::abs(other->second.getEtaPartition()) ||
0237           it.m_hwPlane != std::abs(other->second.getHwPlane() - 1) || it.m_index != index) {
0238         continue;
0239       }
0240       logplane = it.m_LP;
0241     }
0242 
0243     for (auto const& it : l1RPCConeDefinition->getLPSizeVec()) {
0244       if (it.m_tower != std::abs(refTower) || it.m_LP != logplane - 1) {
0245         continue;
0246       }
0247       lpSize = it.m_size;
0248     }
0249 
0250     //FIXME
0251     if (lpSize == -1) {
0252       //throw cms::Exception("getLogStrip") << " lpSize==-1\n";
0253     }
0254   }
0255   return std::make_pair(logplane, lpSize);
0256 }
0257 
0258 DEFINE_FWK_EVENTSETUP_MODULE(RPCConeBuilder);