Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:21:40

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   for (auto const& it : rpcGeom->dets()) {
0103     RPCRoll const* roll = dynamic_cast<RPCRoll const*>(it);
0104     if (roll == nullptr) {
0105       continue;
0106     }
0107 
0108     int ringId = RPCStripsRing::getRingId(roll);
0109     auto found = ringsMap.find(ringId);
0110     if (found == ringsMap.end()) {
0111       ringsMap[ringId] = RPCStripsRing(roll, uncompressedCons);
0112     } else {
0113       found->second.addRoll(roll);
0114     }
0115   }
0116 
0117   // filtermixed strips, fill gaps with virtual strips
0118   for (auto& it : ringsMap) {
0119     it.second.filterOverlapingChambers();
0120     it.second.fillWithVirtualStrips();
0121   }
0122 
0123   // Xcheck, if rings are symmetrical
0124   for (auto& it : ringsMap) {
0125     int key = it.first;
0126     int sign = key / 100 - (key / 1000) * 10;
0127 
0128     if (sign == 0) {
0129       key += 100;
0130     } else {
0131       key -= 100;
0132     }
0133 
0134     // Check if the geometry has a complete ring:
0135     // note that in the case of demo chambers, the ring is not filled because only 2 sectors are added.
0136     // (3014 and 4014 lack counter-rings)
0137     if (key != 2000 && key != 3014 && key != 4014) {  // Key 2100 has no counter-ring
0138       if (it.second.size() != ringsMap[key].size()) {
0139         throw cms::Exception("RPCInternal") << " Size differs for ring " << key << " +- 100 \n";
0140       }
0141     }
0142   }
0143   buildConnections(l1RPCConeDefinition, ringsMap);
0144 }
0145 
0146 void RPCConeBuilder::buildConnections(L1RPCConeDefinition const* l1RPCConeDefinition,
0147                                       RPCStripsRing::TIdToRindMap& ringsMap) {
0148   RPCStripsRing::TIdToRindMap::iterator itRef = ringsMap.begin();
0149   for (; itRef != ringsMap.end(); ++itRef) {  // iterate over reference rings
0150 
0151     RPCStripsRing::TOtherConnStructVec ringsToConnect;
0152 
0153     if (!itRef->second.isReferenceRing())
0154       continue;  // iterate over reference rings
0155 
0156     RPCStripsRing::TIdToRindMap::iterator itOther = ringsMap.begin();
0157     for (; itOther != ringsMap.end(); ++itOther) {  // iterate over nonreference rings
0158 
0159       if (itOther->second.isReferenceRing())
0160         continue;  // iterate over nonreference rings
0161 
0162       std::pair<int, int> pr = areConnected(itRef, itOther, l1RPCConeDefinition);
0163       if (pr.first != -1) {
0164         RPCStripsRing::TOtherConnStruct newOtherConn;
0165         newOtherConn.m_it = itOther;
0166         newOtherConn.m_logplane = pr.first;
0167         newOtherConn.m_logplaneSize = pr.second;
0168         ringsToConnect.push_back(newOtherConn);
0169       }
0170     }  // OtherRings iteration ends
0171 
0172     std::pair<int, int> prRef = areConnected(itRef, itRef, l1RPCConeDefinition);
0173     if (prRef.first == -1) {
0174       throw cms::Exception("RPCConfig") << " Cannot determine logplane for reference ring " << itRef->first << "\n ";
0175     }
0176 
0177     itRef->second.createRefConnections(ringsToConnect, prRef.first, prRef.second);
0178 
0179   }  // RefRings iteration ends
0180 }
0181 
0182 // first - logplane
0183 // second - logplanesize
0184 std::pair<int, int> RPCConeBuilder::areConnected(RPCStripsRing::TIdToRindMap::iterator ref,
0185                                                  RPCStripsRing::TIdToRindMap::iterator other,
0186                                                  L1RPCConeDefinition const* l1RPCConeDefinition) {
0187   int logplane = -1;
0188 
0189   // Do not connect  rolls lying on the oposite side of detector
0190   if (ref->second.getEtaPartition() * other->second.getEtaPartition() < 0)
0191     return std::make_pair(-1, 0);
0192 
0193   int refTowerCnt = 0;
0194   int index = -1;
0195   int refTower = -1;
0196 
0197   for (auto const& itRef : l1RPCConeDefinition->getRingToTowerVec()) {
0198     if (itRef.m_etaPart != std::abs(ref->second.getEtaPartition()) ||
0199         itRef.m_hwPlane != std::abs(ref->second.getHwPlane() - 1)  // -1?
0200     ) {
0201       continue;
0202     }
0203 
0204     ++refTowerCnt;
0205     refTower = itRef.m_tower;
0206 
0207     for (auto const& itOther : l1RPCConeDefinition->getRingToTowerVec()) {
0208       if (itOther.m_etaPart != std::abs(other->second.getEtaPartition()) ||
0209           itOther.m_hwPlane != std::abs(other->second.getHwPlane() - 1)  // -1?
0210       ) {
0211         continue;
0212       }
0213 
0214       if (itOther.m_tower == refTower) {
0215         index = itOther.m_index;
0216       }
0217     }
0218   }
0219 
0220   if (refTowerCnt > 1) {
0221     throw cms::Exception("RPCConeBuilder") << " Reference(?) ring " << ref->first << " "
0222                                            << "wants to be connected to " << refTowerCnt << " towers \n";
0223   }
0224 
0225   if (refTowerCnt == 0) {
0226     throw cms::Exception("RPCConeBuilder") << " Reference(?) ring " << ref->first << " "
0227                                            << " is not connected anywhere \n";
0228   }
0229 
0230   int lpSize = 0;
0231   if (index != -1) {
0232     for (auto const& it : l1RPCConeDefinition->getRingToLPVec()) {
0233       if (it.m_etaPart != std::abs(other->second.getEtaPartition()) ||
0234           it.m_hwPlane != std::abs(other->second.getHwPlane() - 1) || it.m_index != index) {
0235         continue;
0236       }
0237       logplane = it.m_LP;
0238     }
0239 
0240     for (auto const& it : l1RPCConeDefinition->getLPSizeVec()) {
0241       if (it.m_tower != std::abs(refTower) || it.m_LP != logplane - 1) {
0242         continue;
0243       }
0244       lpSize = it.m_size;
0245     }
0246 
0247     //FIXME
0248     if (lpSize == -1) {
0249       //throw cms::Exception("getLogStrip") << " lpSize==-1\n";
0250     }
0251   }
0252   return std::make_pair(logplane, lpSize);
0253 }
0254 
0255 DEFINE_FWK_EVENTSETUP_MODULE(RPCConeBuilder);