File indexing completed on 2024-04-06 12:25:11
0001
0002
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004 #include "DataFormats/HGCalReco/interface/Common.h"
0005 #include "PatternRecognitionbyCA.h"
0006 #include "HGCDoublet.h"
0007 #include "HGCGraph.h"
0008 #include "DataFormats/Common/interface/ValueMap.h"
0009 #include "DataFormats/Math/interface/deltaR.h"
0010
0011 template <typename TILES>
0012 void HGCGraphT<TILES>::makeAndConnectDoublets(const TILES &histo,
0013 const std::vector<TICLSeedingRegion> ®ions,
0014 int nEtaBins,
0015 int nPhiBins,
0016 const std::vector<reco::CaloCluster> &layerClusters,
0017 const std::vector<float> &mask,
0018 const edm::ValueMap<std::pair<float, float>> &layerClustersTime,
0019 int deltaIEta,
0020 int deltaIPhi,
0021 float minCosTheta,
0022 float minCosPointing,
0023 float root_doublet_max_distance_from_seed_squared,
0024 float etaLimitIncreaseWindow,
0025 int skip_layers,
0026 int maxNumberOfLayers,
0027 float maxDeltaTime,
0028 int lastLayerEE,
0029 int lastLayerFH,
0030 const std::vector<double> &siblings_maxRSquared) {
0031 isOuterClusterOfDoublets_.clear();
0032 isOuterClusterOfDoublets_.resize(layerClusters.size());
0033 allDoublets_.clear();
0034 theRootDoublets_.clear();
0035 bool checkDistanceRootDoubletVsSeed = root_doublet_max_distance_from_seed_squared < 9999;
0036 float origin_eta;
0037 float origin_phi;
0038 float maxRSquared;
0039 for (const auto &r : regions) {
0040 bool isGlobal = (r.index == -1);
0041 auto zSide = r.zSide;
0042 int startEtaBin, endEtaBin, startPhiBin, endPhiBin;
0043
0044 if (isGlobal) {
0045 startEtaBin = 0;
0046 startPhiBin = 0;
0047 endEtaBin = nEtaBins;
0048 endPhiBin = nPhiBins;
0049 origin_eta = 0;
0050 origin_phi = 0;
0051 } else {
0052 auto firstLayerOnZSide = maxNumberOfLayers * zSide;
0053 const auto &firstLayerHisto = histo[firstLayerOnZSide];
0054 origin_eta = r.origin.eta();
0055 origin_phi = r.origin.phi();
0056 int entryEtaBin = firstLayerHisto.etaBin(origin_eta);
0057 int entryPhiBin = firstLayerHisto.phiBin(origin_phi);
0058
0059
0060
0061
0062 auto etaWindow = deltaIEta;
0063 auto phiWindow = deltaIPhi;
0064 if (std::abs(origin_eta) > etaLimitIncreaseWindow) {
0065 etaWindow++;
0066 phiWindow++;
0067 LogDebug("HGCGraph") << "Limit of Eta for increase: " << etaLimitIncreaseWindow
0068 << " reached! Increasing inner search window" << std::endl;
0069 }
0070 startEtaBin = std::max(entryEtaBin - etaWindow, 0);
0071 endEtaBin = std::min(entryEtaBin + etaWindow + 1, nEtaBins);
0072 startPhiBin = entryPhiBin - phiWindow;
0073 endPhiBin = entryPhiBin + phiWindow + 1;
0074 if (verbosity_ > ticl::VerbosityLevel::Guru) {
0075 LogDebug("HGCGraph") << " Entrance eta, phi: " << origin_eta << ", " << origin_phi
0076 << " entryEtaBin: " << entryEtaBin << " entryPhiBin: " << entryPhiBin
0077 << " globalBin: " << firstLayerHisto.globalBin(origin_eta, origin_phi)
0078 << " on layer: " << firstLayerOnZSide << " startEtaBin: " << startEtaBin
0079 << " endEtaBin: " << endEtaBin << " startPhiBin: " << startPhiBin
0080 << " endPhiBin: " << endPhiBin << " phiBin(0): " << firstLayerHisto.phiBin(0.)
0081 << " phiBin(" << M_PI / 2. << "): " << firstLayerHisto.phiBin(M_PI / 2.) << " phiBin("
0082 << M_PI << "): " << firstLayerHisto.phiBin(M_PI) << " phiBin(" << -M_PI / 2.
0083 << "): " << firstLayerHisto.phiBin(-M_PI / 2.) << " phiBin(" << -M_PI
0084 << "): " << firstLayerHisto.phiBin(-M_PI) << " phiBin(" << 2. * M_PI
0085 << "): " << firstLayerHisto.phiBin(2. * M_PI) << std::endl;
0086 }
0087 }
0088
0089 for (int il = 0; il < maxNumberOfLayers - 1; ++il) {
0090 for (int outer_layer = 0; outer_layer < std::min(1 + skip_layers, maxNumberOfLayers - 1 - il); ++outer_layer) {
0091 int currentInnerLayerId = il + maxNumberOfLayers * zSide;
0092 int currentOuterLayerId = currentInnerLayerId + 1 + outer_layer;
0093 auto const &outerLayerHisto = histo[currentOuterLayerId];
0094 auto const &innerLayerHisto = histo[currentInnerLayerId];
0095 maxRSquared = (il <= lastLayerEE) ? siblings_maxRSquared[0]
0096 : (il <= lastLayerFH) ? siblings_maxRSquared[1]
0097 : siblings_maxRSquared[2];
0098 const int etaLimitIncreaseWindowBin = innerLayerHisto.etaBin(etaLimitIncreaseWindow);
0099 if (verbosity_ > ticl::VerbosityLevel::Advanced) {
0100 LogDebug("HGCGraph") << "Limit of Eta for increase: " << etaLimitIncreaseWindow
0101 << " at etaBin: " << etaLimitIncreaseWindowBin << std::endl;
0102 }
0103
0104 for (int ieta = startEtaBin; ieta < endEtaBin; ++ieta) {
0105 auto offset = ieta * nPhiBins;
0106 for (int iphi_it = startPhiBin; iphi_it < endPhiBin; ++iphi_it) {
0107 int iphi = ((iphi_it % nPhiBins + nPhiBins) % nPhiBins);
0108 if (verbosity_ > ticl::VerbosityLevel::Advanced) {
0109 LogDebug("HGCGraph") << "Inner Global Bin: " << (offset + iphi)
0110 << " on layers I/O: " << currentInnerLayerId << "/" << currentOuterLayerId
0111 << " with clusters: " << innerLayerHisto[offset + iphi].size() << std::endl;
0112 }
0113 for (auto innerClusterId : innerLayerHisto[offset + iphi]) {
0114
0115 if (mask[innerClusterId] == 0.) {
0116 if (verbosity_ > ticl::VerbosityLevel::Advanced)
0117 LogDebug("HGCGraph") << "Skipping inner masked cluster " << innerClusterId << std::endl;
0118 continue;
0119 }
0120
0121
0122
0123
0124
0125
0126 auto etaWindow = deltaIEta;
0127 auto phiWindow = deltaIPhi;
0128 if (isGlobal && ieta > etaLimitIncreaseWindowBin) {
0129 etaWindow++;
0130 phiWindow++;
0131 if (verbosity_ > ticl::VerbosityLevel::Advanced) {
0132 LogDebug("HGCGraph") << "Eta and Phi window increased by one" << std::endl;
0133 }
0134 }
0135 const auto etaRangeMin = std::max(0, ieta - etaWindow);
0136 const auto etaRangeMax = std::min(ieta + etaWindow + 1, nEtaBins);
0137
0138 for (int oeta = etaRangeMin; oeta < etaRangeMax; ++oeta) {
0139
0140 for (int phiRange = 0; phiRange < 2 * phiWindow + 1; ++phiRange) {
0141
0142
0143
0144
0145
0146 auto ophi = ((iphi + phiRange - phiWindow) % nPhiBins + nPhiBins) % nPhiBins;
0147 if (verbosity_ > ticl::VerbosityLevel::Guru) {
0148 LogDebug("HGCGraph") << "Outer Global Bin: " << (oeta * nPhiBins + ophi)
0149 << " on layers I/O: " << currentInnerLayerId << "/" << currentOuterLayerId
0150 << " with clusters: " << innerLayerHisto[oeta * nPhiBins + ophi].size()
0151 << std::endl;
0152 }
0153 for (auto outerClusterId : outerLayerHisto[oeta * nPhiBins + ophi]) {
0154
0155 if (mask[outerClusterId] == 0.) {
0156 if (verbosity_ > ticl::VerbosityLevel::Advanced)
0157 LogDebug("HGCGraph") << "Skipping outer masked cluster " << outerClusterId << std::endl;
0158 continue;
0159 }
0160 auto doubletId = allDoublets_.size();
0161 if (maxDeltaTime != -1 &&
0162 !areTimeCompatible(innerClusterId, outerClusterId, layerClustersTime, maxDeltaTime)) {
0163 if (verbosity_ > ticl::VerbosityLevel::Advanced)
0164 LogDebug("HGCGraph") << "Rejecting doublets due to timing!" << std::endl;
0165 continue;
0166 }
0167 if (currentOuterLayerId - currentInnerLayerId == 1) {
0168 if (areOverlappingOnSiblingLayers(innerClusterId, outerClusterId, layerClusters, maxRSquared)) {
0169 allDoublets_.emplace_back(
0170 innerClusterId, outerClusterId, doubletId, &layerClusters, r.index, true);
0171 } else {
0172 continue;
0173 }
0174 } else {
0175 allDoublets_.emplace_back(
0176 innerClusterId, outerClusterId, doubletId, &layerClusters, r.index, false);
0177 }
0178 if (verbosity_ > ticl::VerbosityLevel::Advanced) {
0179 LogDebug("HGCGraph")
0180 << "Creating doubletsId: " << doubletId << " layerLink in-out: [" << currentInnerLayerId
0181 << ", " << currentOuterLayerId << "] clusterLink in-out: [" << innerClusterId << ", "
0182 << outerClusterId << "]" << std::endl;
0183 }
0184 isOuterClusterOfDoublets_[outerClusterId].push_back(doubletId);
0185 auto &neigDoublets = isOuterClusterOfDoublets_[innerClusterId];
0186 auto &thisDoublet = allDoublets_[doubletId];
0187 if (verbosity_ > ticl::VerbosityLevel::Expert) {
0188 LogDebug("HGCGraph")
0189 << "Checking compatibility of doubletId: " << doubletId
0190 << " with all possible inners doublets link by the innerClusterId: " << innerClusterId
0191 << std::endl;
0192 }
0193 bool isRootDoublet =
0194 thisDoublet.checkCompatibilityAndTag(allDoublets_,
0195 neigDoublets,
0196 r.directionAtOrigin,
0197 minCosTheta,
0198 minCosPointing,
0199 verbosity_ > ticl::VerbosityLevel::Advanced);
0200 if (isRootDoublet and checkDistanceRootDoubletVsSeed) {
0201 if (reco::deltaR2(layerClusters[innerClusterId].eta(),
0202 layerClusters[innerClusterId].phi(),
0203 origin_eta,
0204 origin_phi) > root_doublet_max_distance_from_seed_squared) {
0205 isRootDoublet = false;
0206 }
0207 }
0208 if (isRootDoublet) {
0209 theRootDoublets_.push_back(doubletId);
0210 }
0211 }
0212 }
0213 }
0214 }
0215 }
0216 }
0217 }
0218 }
0219 }
0220
0221 if (verbosity_ > ticl::VerbosityLevel::None) {
0222 LogDebug("HGCGraph") << "number of Root doublets " << theRootDoublets_.size() << " over a total number of doublets "
0223 << allDoublets_.size() << std::endl;
0224 }
0225
0226 }
0227
0228 template <typename TILES>
0229 bool HGCGraphT<TILES>::areTimeCompatible(int innerIdx,
0230 int outerIdx,
0231 const edm::ValueMap<std::pair<float, float>> &layerClustersTime,
0232 float maxDeltaTime) {
0233 float timeIn = layerClustersTime.get(innerIdx).first;
0234 float timeInE = layerClustersTime.get(innerIdx).second;
0235 float timeOut = layerClustersTime.get(outerIdx).first;
0236 float timeOutE = layerClustersTime.get(outerIdx).second;
0237
0238 return (timeIn == -99. || timeOut == -99. ||
0239 std::abs(timeIn - timeOut) < maxDeltaTime * sqrt(timeInE * timeInE + timeOutE * timeOutE));
0240 }
0241
0242 template <typename TILES>
0243 bool HGCGraphT<TILES>::areOverlappingOnSiblingLayers(int innerIdx,
0244 int outerIdx,
0245 const std::vector<reco::CaloCluster> &layerClusters,
0246 float maxRSquared) {
0247 return reco::deltaR2(layerClusters[outerIdx].eta(),
0248 layerClusters[outerIdx].phi(),
0249 layerClusters[innerIdx].eta(),
0250 layerClusters[innerIdx].phi()) < maxRSquared;
0251 }
0252
0253
0254 template <typename TILES>
0255 void HGCGraphT<TILES>::findNtuplets(std::vector<HGCDoublet::HGCntuplet> &foundNtuplets,
0256 std::vector<int> &seedIndices,
0257 const unsigned int minClustersPerNtuplet,
0258 const bool outInDFS,
0259 unsigned int maxOutInHops) {
0260 HGCDoublet::HGCntuplet tmpNtuplet;
0261 tmpNtuplet.reserve(minClustersPerNtuplet);
0262 std::vector<std::pair<unsigned int, unsigned int>> outInToVisit;
0263 for (auto rootDoublet : theRootDoublets_) {
0264 tmpNtuplet.clear();
0265 outInToVisit.clear();
0266 int seedIndex = allDoublets_[rootDoublet].seedIndex();
0267 int outInHops = 0;
0268 allDoublets_[rootDoublet].findNtuplets(
0269 allDoublets_, tmpNtuplet, seedIndex, outInDFS, outInHops, maxOutInHops, outInToVisit);
0270 while (!outInToVisit.empty()) {
0271 allDoublets_[outInToVisit.back().first].findNtuplets(
0272 allDoublets_, tmpNtuplet, seedIndex, outInDFS, outInToVisit.back().second, maxOutInHops, outInToVisit);
0273 outInToVisit.pop_back();
0274 }
0275
0276 if (tmpNtuplet.size() > minClustersPerNtuplet) {
0277 foundNtuplets.push_back(tmpNtuplet);
0278 seedIndices.push_back(seedIndex);
0279 }
0280 }
0281 }
0282
0283 template class HGCGraphT<TICLLayerTiles>;
0284 template class HGCGraphT<TICLLayerTilesHFNose>;