CMS 3D CMS Logo

PFECALHashNavigator.h
Go to the documentation of this file.
1 #ifndef RecoParticleFlow_PFClusterProducer_PFECALHashNavigator_h
2 #define RecoParticleFlow_PFClusterProducer_PFECALHashNavigator_h
3 
8 
12 
17 
19 
21 public:
23 
25  : PFRecHitNavigatorBase(iConfig, cc),
27  crossBarrelEndcapBorder_(iConfig.getParameter<bool>("crossBarrelEndcapBorder")),
28  geomToken_(cc.esConsumes<edm::Transition::BeginRun>()) {}
29 
30  void init(const edm::EventSetup& iSetup) override {
32 
35 
36  barrelGeometry_ = dynamic_cast<const EcalBarrelGeometry*>(ebTmp);
37  endcapGeometry_ = dynamic_cast<const EcalEndcapGeometry*>(eeTmp);
38 
39  // get the ecalBarrel topology
40  barrelTopology_ = std::make_unique<EcalBarrelTopology>(*geoHandle);
41  endcapTopology_ = std::make_unique<EcalEndcapTopology>(*geoHandle);
42 
44  }
45 
47  std::unique_ptr<reco::PFRecHitCollection>& hits,
48  edm::RefProd<reco::PFRecHitCollection>& refprod) override {
49  DetId center(rh.detId());
50 
51  DetId north = move(center, NORTH);
52  DetId northeast = move(center, NORTHEAST);
53  DetId northwest = move(center, NORTHWEST);
54  DetId south = move(center, SOUTH);
55  DetId southeast = move(center, SOUTHEAST);
56  DetId southwest = move(center, SOUTHWEST);
57  DetId east = move(center, EAST);
58  DetId west = move(center, WEST);
59 
60  associateNeighbour(north, rh, hits, refprod, 0, 1, 0);
61  associateNeighbour(northeast, rh, hits, refprod, 1, 1, 0);
62  associateNeighbour(south, rh, hits, refprod, 0, -1, 0);
63  associateNeighbour(southwest, rh, hits, refprod, -1, -1, 0);
64  associateNeighbour(east, rh, hits, refprod, 1, 0, 0);
65  associateNeighbour(southeast, rh, hits, refprod, 1, -1, 0);
66  associateNeighbour(west, rh, hits, refprod, -1, 0, 0);
67  associateNeighbour(northwest, rh, hits, refprod, -1, 1, 0);
68  }
69 
70 protected:
71  void ecalNeighbArray(const EcalBarrelGeometry& barrelGeom,
72  const CaloSubdetectorTopology& barrelTopo,
73  const EcalEndcapGeometry& endcapGeom,
74  const CaloSubdetectorTopology& endcapTopo) {
75  const unsigned nbarrel = 62000;
76  // Barrel first. The hashed index runs from 0 to 61199
77  neighboursEB_.resize(nbarrel);
78 
79  //std::cout << " Building the array of neighbours (barrel) " ;
80 
81  const std::vector<DetId>& vec(barrelGeom.getValidDetIds(DetId::Ecal, EcalBarrel));
82  unsigned size = vec.size();
83  for (unsigned ic = 0; ic < size; ++ic) {
84  // We get the 9 cells in a square.
85  std::vector<DetId> neighbours(barrelTopo.getWindow(vec[ic], 3, 3));
86  // std::cout << " Cell " << EBDetId(vec[ic]) << std::endl;
87  unsigned nneighbours = neighbours.size();
88 
89  unsigned hashedindex = EBDetId(vec[ic]).hashedIndex();
90  if (hashedindex >= nbarrel) {
91  LogDebug("CaloGeometryTools") << " Array overflow " << std::endl;
92  }
93 
94  // If there are 9 cells, it is easy, and this order is know:
95  // 6 7 8
96  // 3 4 5
97  // 0 1 2 (0 = SOUTHWEST)
98 
99  if (nneighbours == 9) {
100  neighboursEB_[hashedindex].reserve(8);
101  for (unsigned in = 0; in < nneighbours; ++in) {
102  // remove the centre
103  if (neighbours[in] != vec[ic]) {
104  neighboursEB_[hashedindex].push_back(neighbours[in]);
105  // std::cout << " Neighbour " << in << " " << EBDetId(neighbours[in]) << std::endl;
106  }
107  }
108  } else {
109  DetId central(vec[ic]);
110  neighboursEB_[hashedindex].resize(8, DetId(0));
111  for (unsigned idir = 0; idir < 8; ++idir) {
112  DetId testid = central;
113  bool status = stdmove(testid, orderedDir[idir], barrelTopo, endcapTopo, barrelGeom, endcapGeom);
114  if (status)
115  neighboursEB_[hashedindex][idir] = testid;
116  }
117  }
118  }
119 
120  // Moved to the endcap
121 
122  // std::cout << " done " << size << std::endl;
123  // std::cout << " Building the array of neighbours (endcap) " ;
124 
125  // vec.clear();
126  const std::vector<DetId>& vecee = endcapGeom.getValidDetIds(DetId::Ecal, EcalEndcap);
127  size = vecee.size();
128  // There are some holes in the hashedIndex for the EE. Hence the array is bigger than the number
129  // of crystals
130  const unsigned nendcap = 19960;
131 
132  neighboursEE_.resize(nendcap);
133  for (unsigned ic = 0; ic < size; ++ic) {
134  // We get the 9 cells in a square.
135  std::vector<DetId> neighbours(endcapTopo.getWindow(vecee[ic], 3, 3));
136  unsigned nneighbours = neighbours.size();
137  // remove the centre
138  unsigned hashedindex = EEDetId(vecee[ic]).hashedIndex();
139 
140  if (hashedindex >= nendcap) {
141  LogDebug("CaloGeometryTools") << " Array overflow " << std::endl;
142  }
143 
144  if (nneighbours == 9) {
145  neighboursEE_[hashedindex].reserve(8);
146  for (unsigned in = 0; in < nneighbours; ++in) {
147  // remove the centre
148  if (neighbours[in] != vecee[ic]) {
149  neighboursEE_[hashedindex].push_back(neighbours[in]);
150  }
151  }
152  } else {
153  DetId central(vecee[ic]);
154  neighboursEE_[hashedindex].resize(8, DetId(0));
155  for (unsigned idir = 0; idir < 8; ++idir) {
156  DetId testid = central;
157  bool status = stdmove(testid, orderedDir[idir], barrelTopo, endcapTopo, barrelGeom, endcapGeom);
158 
159  if (status)
160  neighboursEE_[hashedindex][idir] = testid;
161  }
162  }
163  }
164  // std::cout << " done " << size <<std::endl;
166  }
167 
168  bool stdsimplemove(DetId& cell,
169  const CaloDirection& dir,
170  const CaloSubdetectorTopology& barrelTopo,
171  const CaloSubdetectorTopology& endcapTopo,
172  const EcalBarrelGeometry& barrelGeom,
173  const EcalEndcapGeometry& endcapGeom) const {
174  std::vector<DetId> neighbours;
175 
176  // BARREL CASE
177  if (cell.subdetId() == EcalBarrel) {
178  EBDetId ebDetId = cell;
179 
180  neighbours = barrelTopo.getNeighbours(ebDetId, dir);
181 
182  // first try to move according to the standard navigation
183  if (!neighbours.empty() && !neighbours[0].null()) {
184  cell = neighbours[0];
185  return true;
186  }
187 
188  // failed.
189 
191  // are we on the outer ring ?
192  const int ietaAbs(ebDetId.ietaAbs()); // abs value of ieta
193  if (EBDetId::MAX_IETA == ietaAbs) {
194  // get ee nbrs for for end of barrel crystals
195 
196  // yes we are
197  const EcalBarrelGeometry::OrderedListOfEEDetId& ol(*barrelGeom.getClosestEndcapCells(ebDetId));
198 
199  // take closest neighbour on the other side, that is in the barrel.
200  cell = *(ol.begin());
201  return true;
202  }
203  }
204  }
205 
206  // ENDCAP CASE
207  else if (cell.subdetId() == EcalEndcap) {
208  EEDetId eeDetId = cell;
209 
210  neighbours = endcapTopo.getNeighbours(eeDetId, dir);
211 
212  if (!neighbours.empty() && !neighbours[0].null()) {
213  cell = neighbours[0];
214  return true;
215  }
216 
217  // failed.
218 
220  // are we on the outer ring ?
221  const int iphi(eeDetId.iPhiOuterRing());
222  if (iphi != 0) {
223  // yes we are
224  const EcalEndcapGeometry::OrderedListOfEBDetId& ol(*endcapGeom.getClosestBarrelCells(eeDetId));
225 
226  // take closest neighbour on the other side, that is in the barrel.
227  cell = *(ol.begin());
228  return true;
229  }
230  }
231  }
232 
233  // everything failed
234  cell = DetId(0);
235  return false;
236  }
237 
238  bool stdmove(DetId& cell,
239  const CaloDirection& dir,
240  const CaloSubdetectorTopology& barrelTopo,
241  const CaloSubdetectorTopology& endcapTopo,
242  const EcalBarrelGeometry& barrelGeom,
243  const EcalEndcapGeometry& endcapGeom)
244 
245  const {
246  bool result;
247 
248  if (dir == NORTH) {
249  result = stdsimplemove(cell, NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
250  return result;
251  } else if (dir == SOUTH) {
252  result = stdsimplemove(cell, SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
253  return result;
254  } else if (dir == EAST) {
255  result = stdsimplemove(cell, EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
256  return result;
257  } else if (dir == WEST) {
258  result = stdsimplemove(cell, WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
259  return result;
260  }
261 
262  // One has to try both paths
263  else if (dir == NORTHEAST) {
264  result = stdsimplemove(cell, NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
265  if (result)
266  return stdsimplemove(cell, EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
267  else {
268  result = stdsimplemove(cell, EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
269  if (result)
270  return stdsimplemove(cell, NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
271  else
272  return false;
273  }
274  } else if (dir == NORTHWEST) {
275  result = stdsimplemove(cell, NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
276  if (result)
277  return stdsimplemove(cell, WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
278  else {
279  result = stdsimplemove(cell, WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
280  if (result)
281  return stdsimplemove(cell, NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
282  else
283  return false;
284  }
285  } else if (dir == SOUTHEAST) {
286  result = stdsimplemove(cell, SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
287  if (result)
288  return stdsimplemove(cell, EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
289  else {
290  result = stdsimplemove(cell, EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
291  if (result)
292  return stdsimplemove(cell, SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
293  else
294  return false;
295  }
296  } else if (dir == SOUTHWEST) {
297  result = stdsimplemove(cell, SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
298  if (result)
299  return stdsimplemove(cell, WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
300  else {
301  result = stdsimplemove(cell, SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
302  if (result)
303  return stdsimplemove(cell, WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom);
304  else
305  return false;
306  }
307  }
308  cell = DetId(0);
309  return false;
310  }
311 
312  DetId move(DetId cell, const CaloDirection& dir) const {
313  DetId originalcell = cell;
314  if (dir == NONE || cell == DetId(0))
315  return false;
316 
317  // Conversion CaloDirection and index in the table
318  // CaloDirection :NONE,SOUTH,SOUTHEAST,SOUTHWEST,EAST,WEST, NORTHEAST,NORTHWEST,NORTH
319  // Table : SOUTHWEST,SOUTH,SOUTHEAST,WEST,EAST,NORTHWEST,NORTH, NORTHEAST
320  static const int calodirections[9] = {-1, 1, 2, 0, 4, 3, 7, 5, 6};
321 
323 
324  DetId result = (originalcell.subdetId() == EcalBarrel)
325  ? neighboursEB_[EBDetId(originalcell).hashedIndex()][calodirections[dir]]
326  : neighboursEE_[EEDetId(originalcell).hashedIndex()][calodirections[dir]];
327  return result;
328  }
329 
330  std::unique_ptr<EcalEndcapTopology> endcapTopology_;
331  std::unique_ptr<EcalBarrelTopology> barrelTopology_;
332 
335 
337  std::vector<std::vector<DetId> > neighboursEB_;
338 
340  std::vector<std::vector<DetId> > neighboursEE_;
341 
344 
347 
348 private:
350 };
351 
352 #endif
size
Write out results.
void ecalNeighbArray(const EcalBarrelGeometry &barrelGeom, const CaloSubdetectorTopology &barrelTopo, const EcalEndcapGeometry &endcapGeom, const CaloSubdetectorTopology &endcapTopo)
void associateNeighbour(const DetId &id, reco::PFRecHit &hit, std::unique_ptr< reco::PFRecHitCollection > &hits, edm::RefProd< reco::PFRecHitCollection > &refProd, short eta, short phi, short depth)
std::vector< std::vector< DetId > > neighboursEB_
for each ecal barrel rechit, keep track of the neighbours
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
int ietaAbs() const
get the absolute value of the crystal ieta
Definition: EBDetId.h:47
std::unique_ptr< EcalEndcapTopology > endcapTopology_
uint32_t cc[maxCellsPerHit]
Definition: gpuFishbone.h:49
const OrderedListOfEEDetId * getClosestEndcapCells(EBDetId id) const
bool stdmove(DetId &cell, const CaloDirection &dir, const CaloSubdetectorTopology &barrelTopo, const CaloSubdetectorTopology &endcapTopo, const EcalBarrelGeometry &barrelGeom, const EcalEndcapGeometry &endcapGeom) const
bool crossBarrelEndcapBorder_
if true, navigation will cross the barrel-endcap border
assert(be >=bs)
std::vector< std::vector< DetId > > neighboursEE_
for each ecal endcap rechit, keep track of the neighbours
std::unique_ptr< EcalBarrelTopology > barrelTopology_
unsigned detId() const
rechit detId
Definition: PFRecHit.h:93
static const CaloDirection orderedDir[8]
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
Definition: PFRecHit.h:31
edm::ESGetToken< CaloGeometry, CaloGeometryRecord > geomToken_
Transition
Definition: Transition.h:12
virtual const std::vector< DetId > & getValidDetIds(DetId::Detector det=DetId::Detector(0), int subdet=0) const
Get a list of valid detector ids (for the given subdetector)
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
virtual std::vector< DetId > getWindow(const DetId &id, const int &northSouthSize, const int &eastWestSize) const
virtual std::vector< DetId > getNeighbours(const DetId &id, const CaloDirection &dir) const
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:130
const EcalEndcapGeometry * endcapGeometry_
Definition: DetId.h:17
void associateNeighbours(reco::PFRecHit &rh, std::unique_ptr< reco::PFRecHitCollection > &hits, edm::RefProd< reco::PFRecHitCollection > &refprod) override
const EcalBarrelGeometry * barrelGeometry_
static const int MAX_IETA
Definition: EBDetId.h:136
DetId move(DetId cell, const CaloDirection &dir) const
HLT enums.
PFECALHashNavigator(const edm::ParameterSet &iConfig, edm::ConsumesCollector &cc)
int hashedIndex() const
get a compact index for arrays
Definition: EBDetId.h:82
void init(const edm::EventSetup &iSetup) override
const OrderedListOfEBDetId * getClosestBarrelCells(EEDetId id) const
CaloDirection
Codes the local directions in the cell lattice.
Definition: CaloDirection.h:9
bool stdsimplemove(DetId &cell, const CaloDirection &dir, const CaloSubdetectorTopology &barrelTopo, const CaloSubdetectorTopology &endcapTopo, const EcalBarrelGeometry &barrelGeom, const EcalEndcapGeometry &endcapGeom) const
int hashedIndex() const
Definition: EEDetId.h:183
Definition: TkAlStyle.h:43
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:34
bool neighbourmapcalculated_
set to true in ecalNeighbArray
int iPhiOuterRing() const
Definition: EEDetId.cc:295
#define LogDebug(id)