11 template <
typename TILES>
13 const std::vector<TICLSeedingRegion> &
regions,
16 const std::vector<reco::CaloCluster> &layerClusters,
17 const std::vector<float> &mask,
18 const edm::ValueMap<std::pair<float, float>> &layerClustersTime,
23 float root_doublet_max_distance_from_seed_squared,
24 float etaLimitIncreaseWindow,
30 const std::vector<double> &siblings_maxRSquared) {
31 isOuterClusterOfDoublets_.clear();
32 isOuterClusterOfDoublets_.resize(layerClusters.size());
34 theRootDoublets_.clear();
35 bool checkDistanceRootDoubletVsSeed = root_doublet_max_distance_from_seed_squared < 9999;
39 for (
const auto &
r : regions) {
40 bool isGlobal = (
r.index == -1);
42 int startEtaBin, endEtaBin, startPhiBin, endPhiBin;
52 auto firstLayerOnZSide = maxNumberOfLayers * zSide;
53 const auto &firstLayerHisto = histo[firstLayerOnZSide];
54 origin_eta =
r.origin.eta();
55 origin_phi =
r.origin.phi();
56 int entryEtaBin = firstLayerHisto.etaBin(origin_eta);
57 int entryPhiBin = firstLayerHisto.phiBin(origin_phi);
62 auto etaWindow = deltaIEta;
63 auto phiWindow = deltaIPhi;
64 if (
std::abs(origin_eta) > etaLimitIncreaseWindow) {
67 LogDebug(
"HGCGraph") <<
"Limit of Eta for increase: " << etaLimitIncreaseWindow
68 <<
" reached! Increasing inner search window" << std::endl;
70 startEtaBin =
std::max(entryEtaBin - etaWindow, 0);
71 endEtaBin =
std::min(entryEtaBin + etaWindow + 1, nEtaBins);
72 startPhiBin = entryPhiBin - phiWindow;
73 endPhiBin = entryPhiBin + phiWindow + 1;
74 if (verbosity_ > Guru) {
75 LogDebug(
"HGCGraph") <<
" Entrance eta, phi: " << origin_eta <<
", " << origin_phi
76 <<
" entryEtaBin: " << entryEtaBin <<
" entryPhiBin: " << entryPhiBin
77 <<
" globalBin: " << firstLayerHisto.globalBin(origin_eta, origin_phi)
78 <<
" on layer: " << firstLayerOnZSide <<
" startEtaBin: " << startEtaBin
79 <<
" endEtaBin: " << endEtaBin <<
" startPhiBin: " << startPhiBin
80 <<
" endPhiBin: " << endPhiBin <<
" phiBin(0): " << firstLayerHisto.phiBin(0.)
81 <<
" phiBin(" <<
M_PI / 2. <<
"): " << firstLayerHisto.phiBin(
M_PI / 2.) <<
" phiBin("
82 <<
M_PI <<
"): " << firstLayerHisto.phiBin(
M_PI) <<
" phiBin(" << -
M_PI / 2.
83 <<
"): " << firstLayerHisto.phiBin(-
M_PI / 2.) <<
" phiBin(" << -
M_PI
84 <<
"): " << firstLayerHisto.phiBin(-
M_PI) <<
" phiBin(" << 2. *
M_PI
85 <<
"): " << firstLayerHisto.phiBin(2. *
M_PI) << std::endl;
89 for (
int il = 0; il < maxNumberOfLayers - 1; ++il) {
90 for (
int outer_layer = 0; outer_layer <
std::min(1 + skip_layers, maxNumberOfLayers - 1 - il); ++outer_layer) {
91 int currentInnerLayerId = il + maxNumberOfLayers * zSide;
92 int currentOuterLayerId = currentInnerLayerId + 1 + outer_layer;
93 auto const &outerLayerHisto = histo[currentOuterLayerId];
94 auto const &innerLayerHisto = histo[currentInnerLayerId];
95 maxRSquared = (il <= lastLayerEE) ? siblings_maxRSquared[0]
96 : (il <= lastLayerFH) ? siblings_maxRSquared[1]
97 : siblings_maxRSquared[2];
98 const int etaLimitIncreaseWindowBin = innerLayerHisto.etaBin(etaLimitIncreaseWindow);
99 if (verbosity_ > Advanced) {
100 LogDebug(
"HGCGraph") <<
"Limit of Eta for increase: " << etaLimitIncreaseWindow
101 <<
" at etaBin: " << etaLimitIncreaseWindowBin << std::endl;
104 for (
int ieta = startEtaBin; ieta < endEtaBin; ++ieta) {
106 for (
int iphi_it = startPhiBin; iphi_it < endPhiBin; ++iphi_it) {
107 int iphi = ((iphi_it % nPhiBins +
nPhiBins) % nPhiBins);
108 if (verbosity_ > Guru) {
110 <<
" on layers I/O: " << currentInnerLayerId <<
"/" << currentOuterLayerId
111 <<
" with clusters: " << innerLayerHisto[
offset + iphi].
size() << std::endl;
113 for (
auto innerClusterId : innerLayerHisto[
offset + iphi]) {
115 if (mask[innerClusterId] == 0.) {
116 if (verbosity_ > Advanced)
117 LogDebug(
"HGCGraph") <<
"Skipping inner masked cluster " << innerClusterId << std::endl;
126 auto etaWindow = deltaIEta;
127 auto phiWindow = deltaIPhi;
128 if (isGlobal && ieta > etaLimitIncreaseWindowBin) {
131 if (verbosity_ > Advanced) {
132 LogDebug(
"HGCGraph") <<
"Eta and Phi window increased by one" << std::endl;
135 const auto etaRangeMin =
std::max(0, ieta - etaWindow);
136 const auto etaRangeMax =
std::min(ieta + etaWindow + 1, nEtaBins);
138 for (
int oeta = etaRangeMin; oeta < etaRangeMax; ++oeta) {
140 for (
int phiRange = 0; phiRange < 2 * phiWindow + 1; ++phiRange) {
146 auto ophi = ((iphi + phiRange - phiWindow) % nPhiBins + nPhiBins) %
nPhiBins;
147 if (verbosity_ > Guru) {
148 LogDebug(
"HGCGraph") <<
"Outer Global Bin: " << (oeta * nPhiBins + ophi)
149 <<
" on layers I/O: " << currentInnerLayerId <<
"/" << currentOuterLayerId
150 <<
" with clusters: " << innerLayerHisto[oeta * nPhiBins + ophi].
size()
153 for (
auto outerClusterId : outerLayerHisto[oeta * nPhiBins + ophi]) {
155 if (mask[outerClusterId] == 0.) {
156 if (verbosity_ > Advanced)
157 LogDebug(
"HGCGraph") <<
"Skipping outer masked cluster " << outerClusterId << std::endl;
160 auto doubletId = allDoublets_.size();
161 if (maxDeltaTime != -1 &&
162 !areTimeCompatible(innerClusterId, outerClusterId, layerClustersTime, maxDeltaTime)) {
163 if (verbosity_ > Advanced)
164 LogDebug(
"HGCGraph") <<
"Rejecting doublets due to timing!" << std::endl;
167 if (currentOuterLayerId - currentInnerLayerId == 1) {
168 if (areOverlappingOnSiblingLayers(innerClusterId, outerClusterId, layerClusters, maxRSquared)) {
169 allDoublets_.emplace_back(
170 innerClusterId, outerClusterId, doubletId, &layerClusters,
r.index,
true);
175 allDoublets_.emplace_back(
176 innerClusterId, outerClusterId, doubletId, &layerClusters,
r.index,
false);
178 if (verbosity_ > Advanced) {
180 <<
"Creating doubletsId: " << doubletId <<
" layerLink in-out: [" << currentInnerLayerId
181 <<
", " << currentOuterLayerId <<
"] clusterLink in-out: [" << innerClusterId <<
", "
182 << outerClusterId <<
"]" << std::endl;
184 isOuterClusterOfDoublets_[outerClusterId].push_back(doubletId);
185 auto &neigDoublets = isOuterClusterOfDoublets_[innerClusterId];
186 auto &thisDoublet = allDoublets_[doubletId];
187 if (verbosity_ > Expert) {
189 <<
"Checking compatibility of doubletId: " << doubletId
190 <<
" with all possible inners doublets link by the innerClusterId: " << innerClusterId
193 bool isRootDoublet = thisDoublet.checkCompatibilityAndTag(allDoublets_,
198 verbosity_ > Advanced);
199 if (isRootDoublet and checkDistanceRootDoubletVsSeed) {
201 layerClusters[innerClusterId].
phi(),
203 origin_phi) > root_doublet_max_distance_from_seed_squared) {
204 isRootDoublet =
false;
208 theRootDoublets_.push_back(doubletId);
220 if (verbosity_ >
None) {
221 LogDebug(
"HGCGraph") <<
"number of Root doublets " << theRootDoublets_.size() <<
" over a total number of doublets "
222 << allDoublets_.size() << std::endl;
227 template <
typename TILES>
230 const edm::ValueMap<std::pair<float, float>> &layerClustersTime,
231 float maxDeltaTime) {
232 float timeIn = layerClustersTime.get(innerIdx).first;
233 float timeInE = layerClustersTime.get(innerIdx).second;
234 float timeOut = layerClustersTime.get(outerIdx).first;
235 float timeOutE = layerClustersTime.get(outerIdx).second;
237 return (timeIn == -99. || timeOut == -99. ||
238 std::abs(timeIn - timeOut) < maxDeltaTime *
sqrt(timeInE * timeInE + timeOutE * timeOutE));
241 template <
typename TILES>
244 const std::vector<reco::CaloCluster> &layerClusters,
247 layerClusters[outerIdx].
phi(),
248 layerClusters[innerIdx].
eta(),
249 layerClusters[innerIdx].
phi()) < maxRSquared;
253 template <
typename TILES>
255 std::vector<int> &seedIndices,
256 const unsigned int minClustersPerNtuplet,
258 unsigned int maxOutInHops) {
260 tmpNtuplet.reserve(minClustersPerNtuplet);
261 std::vector<std::pair<unsigned int, unsigned int>> outInToVisit;
262 for (
auto rootDoublet : theRootDoublets_) {
264 outInToVisit.clear();
265 int seedIndex = allDoublets_[rootDoublet].seedIndex();
267 allDoublets_[rootDoublet].findNtuplets(
268 allDoublets_, tmpNtuplet, seedIndex, outInDFS, outInHops, maxOutInHops, outInToVisit);
269 while (!outInToVisit.empty()) {
270 allDoublets_[outInToVisit.back().first].findNtuplets(
271 allDoublets_, tmpNtuplet, seedIndex, outInDFS, outInToVisit.back().second, maxOutInHops, outInToVisit);
272 outInToVisit.pop_back();
275 if (tmpNtuplet.size() > minClustersPerNtuplet) {
276 foundNtuplets.push_back(tmpNtuplet);
277 seedIndices.push_back(seedIndex);
std::vector< unsigned int > HGCntuplet
void makeAndConnectDoublets(const TILES &h, const std::vector< TICLSeedingRegion > ®ions, int nEtaBins, int nPhiBins, const std::vector< reco::CaloCluster > &layerClusters, const std::vector< float > &mask, const edm::ValueMap< std::pair< float, float >> &layerClustersTime, int deltaIEta, int deltaIPhi, float minCosThetai, float maxCosPointing, float root_doublet_max_distance_from_seed_squared, float etaLimitIncreaseWindow, int skip_layers, int maxNumberOfLayers, float maxDeltaTime, int lastLayerEE, int lastLayerFH, const std::vector< double > &siblings_maxRSquared)
constexpr uint32_t maxNumberOfLayers
auto const & foundNtuplets
bool areOverlappingOnSiblingLayers(int innerIdx, int outerIdx, const std::vector< reco::CaloCluster > &layerClusters, float maxRSquared)
Abs< T >::type abs(const T &t)
bool areTimeCompatible(int innerIdx, int outerIdx, const edm::ValueMap< std::pair< float, float >> &layerClustersTime, float maxDeltaTime)
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
void findNtuplets(std::vector< HGCDoublet::HGCntuplet > &foundNtuplets, std::vector< int > &seedIndices, const unsigned int minClustersPerNtuplet, const bool outInDFS, const unsigned int maxOutInHops)
tuple size
Write out results.