File indexing completed on 2024-04-06 12:21:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
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
0054
0055
0056 std::pair<int, int> areConnected(RPCStripsRing::TIdToRindMap::iterator ref,
0057 RPCStripsRing::TIdToRindMap::iterator other,
0058 L1RPCConeDefinition const*);
0059
0060
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
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
0086
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
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
0118 for (auto& it : ringsMap) {
0119 it.second.filterOverlapingChambers();
0120 it.second.fillWithVirtualStrips();
0121 }
0122
0123
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
0135
0136
0137 if (key != 2000 && key != 3014 && key != 4014) {
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) {
0150
0151 RPCStripsRing::TOtherConnStructVec ringsToConnect;
0152
0153 if (!itRef->second.isReferenceRing())
0154 continue;
0155
0156 RPCStripsRing::TIdToRindMap::iterator itOther = ringsMap.begin();
0157 for (; itOther != ringsMap.end(); ++itOther) {
0158
0159 if (itOther->second.isReferenceRing())
0160 continue;
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 }
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 }
0180 }
0181
0182
0183
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
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)
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)
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
0248 if (lpSize == -1) {
0249
0250 }
0251 }
0252 return std::make_pair(logplane, lpSize);
0253 }
0254
0255 DEFINE_FWK_EVENTSETUP_MODULE(RPCConeBuilder);