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 
4 
8 
12 
17 
19  SOUTH,
20  SOUTHEAST,
21  WEST,
22  EAST,
23  NORTHWEST,
24  NORTH,
25  NORTHEAST};
26 
27 
29  public:
30 
31 
32 
34 
35  }
36 
37 
38 
40  PFRecHitNavigatorBase(iConfig){
41 
43  iConfig.getParameter<bool>("crossBarrelEndcapBorder");
44 
46 
47  }
48 
49  void beginEvent(const edm::EventSetup& iSetup) override {
51  iSetup.get<CaloGeometryRecord>().get(geoHandle);
52 
53  const CaloSubdetectorGeometry *ebTmp =
55  const CaloSubdetectorGeometry *eeTmp =
57 
58  barrelGeometry_ = dynamic_cast< const EcalBarrelGeometry* > (ebTmp);
59  endcapGeometry_ = dynamic_cast < const EcalEndcapGeometry* > (eeTmp);
60 
61  // get the ecalBarrel topology
62  barrelTopology_ = std::make_unique<EcalBarrelTopology>(*geoHandle);
63  endcapTopology_ = std::make_unique<EcalEndcapTopology>(*geoHandle);
64 
66 
67  }
68 
69  void associateNeighbours(reco::PFRecHit& rh,std::unique_ptr<reco::PFRecHitCollection>& hits,edm::RefProd<reco::PFRecHitCollection>& refprod) override {
70 
71 
72 
73  DetId center( rh.detId() );
74 
75 
76  DetId north = move( center, NORTH );
77  DetId northeast = move( center, NORTHEAST );
78  DetId northwest = move( center, NORTHWEST );
79  DetId south = move( center, SOUTH );
80  DetId southeast = move( center, SOUTHEAST );
81  DetId southwest = move( center, SOUTHWEST );
82  DetId east = move( center, EAST );
83  DetId west = move( center, WEST );
84 
85 
86  associateNeighbour(north,rh,hits,refprod,0,1,0);
87  associateNeighbour(northeast,rh,hits,refprod,1,1,0);
88  associateNeighbour(south,rh,hits,refprod,0,-1,0);
89  associateNeighbour(southwest,rh,hits,refprod,-1,-1,0);
90  associateNeighbour(east,rh,hits,refprod,1,0,0);
91  associateNeighbour(southeast,rh,hits,refprod,1,-1,0);
92  associateNeighbour(west,rh,hits,refprod,-1,0,0);
93  associateNeighbour(northwest,rh,hits,refprod,-1,1,0);
94 
95  }
96 
97 
98 
99 
100 
101 
102 
103 
104  protected:
105 
106 
107  void ecalNeighbArray(const EcalBarrelGeometry& barrelGeom,
108  const CaloSubdetectorTopology& barrelTopo,
109  const EcalEndcapGeometry& endcapGeom,
110  const CaloSubdetectorTopology& endcapTopo ){
111 
112 
113 
114  const unsigned nbarrel = 62000;
115  // Barrel first. The hashed index runs from 0 to 61199
116  neighboursEB_.resize(nbarrel);
117 
118  //std::cout << " Building the array of neighbours (barrel) " ;
119 
120  const std::vector<DetId>& vec(barrelGeom.getValidDetIds(DetId::Ecal,
121  EcalBarrel));
122  unsigned size=vec.size();
123  for(unsigned ic=0; ic<size; ++ic)
124  {
125  // We get the 9 cells in a square.
126  std::vector<DetId> neighbours(barrelTopo.getWindow(vec[ic],3,3));
127  // std::cout << " Cell " << EBDetId(vec[ic]) << std::endl;
128  unsigned nneighbours=neighbours.size();
129 
130  unsigned hashedindex=EBDetId(vec[ic]).hashedIndex();
131  if(hashedindex>=nbarrel)
132  {
133  LogDebug("CaloGeometryTools") << " Array overflow " << std::endl;
134  }
135 
136 
137  // If there are 9 cells, it is easy, and this order is know:
138  // 6 7 8
139  // 3 4 5
140  // 0 1 2 (0 = SOUTHWEST)
141 
142  if(nneighbours==9)
143  {
144  neighboursEB_[hashedindex].reserve(8);
145  for(unsigned in=0;in<nneighbours;++in)
146  {
147  // remove the centre
148  if(neighbours[in]!=vec[ic])
149  {
150  neighboursEB_[hashedindex].push_back(neighbours[in]);
151  // std::cout << " Neighbour " << in << " " << EBDetId(neighbours[in]) << std::endl;
152  }
153  }
154  }
155  else
156  {
157  DetId central(vec[ic]);
158  neighboursEB_[hashedindex].resize(8,DetId(0));
159  for(unsigned idir=0;idir<8;++idir)
160  {
161  DetId testid=central;
162  bool status=stdmove(testid,orderedDir[idir],
163  barrelTopo, endcapTopo,
164  barrelGeom, endcapGeom);
165  if(status) neighboursEB_[hashedindex][idir]=testid;
166  }
167 
168  }
169  }
170 
171  // Moved to the endcap
172 
173  // std::cout << " done " << size << std::endl;
174  // std::cout << " Building the array of neighbours (endcap) " ;
175 
176  // vec.clear();
177  const std::vector<DetId>& vecee=endcapGeom.getValidDetIds(DetId::Ecal,EcalEndcap);
178  size=vecee.size();
179  // There are some holes in the hashedIndex for the EE. Hence the array is bigger than the number
180  // of crystals
181  const unsigned nendcap=19960;
182 
183  neighboursEE_.resize(nendcap);
184  for(unsigned ic=0; ic<size; ++ic)
185  {
186  // We get the 9 cells in a square.
187  std::vector<DetId> neighbours(endcapTopo.getWindow(vecee[ic],3,3));
188  unsigned nneighbours=neighbours.size();
189  // remove the centre
190  unsigned hashedindex=EEDetId(vecee[ic]).hashedIndex();
191 
192  if(hashedindex>=nendcap)
193  {
194  LogDebug("CaloGeometryTools") << " Array overflow " << std::endl;
195  }
196 
197  if(nneighbours==9)
198  {
199  neighboursEE_[hashedindex].reserve(8);
200  for(unsigned in=0;in<nneighbours;++in)
201  {
202  // remove the centre
203  if(neighbours[in]!=vecee[ic])
204  {
205  neighboursEE_[hashedindex].push_back(neighbours[in]);
206  }
207  }
208  }
209  else
210  {
211  DetId central(vecee[ic]);
212  neighboursEE_[hashedindex].resize(8,DetId(0));
213  for(unsigned idir=0;idir<8;++idir)
214  {
215  DetId testid=central;
216  bool status=stdmove(testid,orderedDir[idir],
217  barrelTopo, endcapTopo,
218  barrelGeom, endcapGeom);
219 
220  if(status) neighboursEE_[hashedindex][idir]=testid;
221  }
222 
223  }
224  }
225  // std::cout << " done " << size <<std::endl;
227  }
228 
229 
230 
231 bool stdsimplemove(DetId& cell,
232  const CaloDirection& dir,
233  const CaloSubdetectorTopology& barrelTopo,
234  const CaloSubdetectorTopology& endcapTopo,
235  const EcalBarrelGeometry& barrelGeom,
236  const EcalEndcapGeometry& endcapGeom )
237  const {
238 
239  std::vector<DetId> neighbours;
240 
241  // BARREL CASE
242  if(cell.subdetId()==EcalBarrel) {
243  EBDetId ebDetId = cell;
244 
245  neighbours = barrelTopo.getNeighbours(ebDetId,dir);
246 
247  // first try to move according to the standard navigation
248  if(!neighbours.empty() && !neighbours[0].null()) {
249  cell = neighbours[0];
250  return true;
251  }
252 
253  // failed.
254 
256  // are we on the outer ring ?
257  const int ietaAbs ( ebDetId.ietaAbs() ) ; // abs value of ieta
258  if( EBDetId::MAX_IETA == ietaAbs ) {
259  // get ee nbrs for for end of barrel crystals
260 
261  // yes we are
263  ol( * barrelGeom.getClosestEndcapCells( ebDetId ) ) ;
264 
265  // take closest neighbour on the other side, that is in the barrel.
266  cell = *(ol.begin() );
267  return true;
268  }
269  }
270  }
271 
272  // ENDCAP CASE
273  else if(cell.subdetId()==EcalEndcap) {
274 
275  EEDetId eeDetId = cell;
276 
277  neighbours= endcapTopo.getNeighbours(eeDetId,dir);
278 
279  if(!neighbours.empty() && !neighbours[0].null()) {
280  cell = neighbours[0];
281  return true;
282  }
283 
284  // failed.
285 
287  // are we on the outer ring ?
288  const int iphi ( eeDetId.iPhiOuterRing() ) ;
289  if( iphi!= 0) {
290  // yes we are
292  ol( * endcapGeom.getClosestBarrelCells( eeDetId ) ) ;
293 
294  // take closest neighbour on the other side, that is in the barrel.
295  cell = *(ol.begin() );
296  return true;
297  }
298  }
299  }
300 
301  // everything failed
302  cell = DetId(0);
303  return false;
304 }
305 
306 
307 
308 bool stdmove(DetId& cell,
309  const CaloDirection& dir,
310  const CaloSubdetectorTopology& barrelTopo,
311  const CaloSubdetectorTopology& endcapTopo,
312  const EcalBarrelGeometry& barrelGeom,
313  const EcalEndcapGeometry& endcapGeom )
314 
315  const {
316 
317 
318  bool result;
319 
320  if(dir==NORTH) {
321  result = stdsimplemove(cell,NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
322  return result;
323  }
324  else if(dir==SOUTH) {
325  result = stdsimplemove(cell,SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
326  return result;
327  }
328  else if(dir==EAST) {
329  result = stdsimplemove(cell,EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
330  return result;
331  }
332  else if(dir==WEST) {
333  result = stdsimplemove(cell,WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
334  return result;
335  }
336 
337 
338  // One has to try both paths
339  else if(dir==NORTHEAST)
340  {
341  result = stdsimplemove(cell,NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
342  if(result)
343  return stdsimplemove(cell,EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
344  else
345  {
346  result = stdsimplemove(cell,EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
347  if(result)
348  return stdsimplemove(cell,NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
349  else
350  return false;
351  }
352  }
353  else if(dir==NORTHWEST)
354  {
355  result = stdsimplemove(cell,NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
356  if(result)
357  return stdsimplemove(cell,WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
358  else
359  {
360  result = stdsimplemove(cell,WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
361  if(result)
362  return stdsimplemove(cell,NORTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
363  else
364  return false;
365  }
366  }
367  else if(dir == SOUTHEAST)
368  {
369  result = stdsimplemove(cell,SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
370  if(result)
371  return stdsimplemove(cell,EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
372  else
373  {
374  result = stdsimplemove(cell,EAST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
375  if(result)
376  return stdsimplemove(cell,SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
377  else
378  return false;
379  }
380  }
381  else if(dir == SOUTHWEST)
382  {
383  result = stdsimplemove(cell,SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
384  if(result)
385  return stdsimplemove(cell,WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
386  else
387  {
388  result = stdsimplemove(cell,SOUTH, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
389  if(result)
390  return stdsimplemove(cell,WEST, barrelTopo, endcapTopo, barrelGeom, endcapGeom );
391  else
392  return false;
393  }
394  }
395  cell = DetId(0);
396  return false;
397 }
398 
399 
400 
402  const CaloDirection&dir ) const
403 {
404  DetId originalcell = cell;
405  if(dir==NONE || cell==DetId(0)) return false;
406 
407  // Conversion CaloDirection and index in the table
408  // CaloDirection :NONE,SOUTH,SOUTHEAST,SOUTHWEST,EAST,WEST, NORTHEAST,NORTHWEST,NORTH
409  // Table : SOUTHWEST,SOUTH,SOUTHEAST,WEST,EAST,NORTHWEST,NORTH, NORTHEAST
410  static const int calodirections[9]={-1,1,2,0,4,3,7,5,6};
411 
412  assert(neighbourmapcalculated_);
413 
414  DetId result = (originalcell.subdetId()==EcalBarrel) ?
415  neighboursEB_[EBDetId(originalcell).hashedIndex()][calodirections[dir]]:
416  neighboursEE_[EEDetId(originalcell).hashedIndex()][calodirections[dir]];
417  return result;
418 }
419 
420 
421  std::unique_ptr<EcalEndcapTopology> endcapTopology_;
422  std::unique_ptr<EcalBarrelTopology> barrelTopology_;
423 
426 
428  std::vector<std::vector<DetId> > neighboursEB_;
429 
431  std::vector<std::vector<DetId> > neighboursEE_;
432 
435 
438 
439 
440 };
441 
442 
443 
444 
445 
446 #endif
447 
448 
#define LogDebug(id)
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)
T getParameter(std::string const &) const
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:49
std::vector< std::vector< DetId > > neighboursEB_
for each ecal barrel rechit, keep track of the neighbours
PFECALHashNavigator(const edm::ParameterSet &iConfig)
const OrderedListOfEEDetId * getClosestEndcapCells(EBDetId id) const
int hashedIndex() const
get a compact index for arrays
Definition: EBDetId.h:82
virtual std::vector< DetId > getNeighbours(const DetId &id, const CaloDirection &dir) const
std::unique_ptr< EcalEndcapTopology > endcapTopology_
bool stdmove(DetId &cell, const CaloDirection &dir, const CaloSubdetectorTopology &barrelTopo, const CaloSubdetectorTopology &endcapTopo, const EcalBarrelGeometry &barrelGeom, const EcalEndcapGeometry &endcapGeom) const
unsigned detId() const
rechit detId
Definition: PFRecHit.h:93
bool crossBarrelEndcapBorder_
if true, navigation will cross the barrel-endcap border
std::vector< std::vector< DetId > > neighboursEE_
for each ecal endcap rechit, keep track of the neighbours
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)
std::unique_ptr< EcalBarrelTopology > barrelTopology_
static const CaloDirection orderedDir[8]
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
Definition: PFRecHit.h:31
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:41
int iPhiOuterRing() const
Definition: EEDetId.cc:295
const OrderedListOfEBDetId * getClosestBarrelCells(EEDetId id) const
void beginEvent(const edm::EventSetup &iSetup) override
DetId move(DetId cell, const CaloDirection &dir) const
const EcalEndcapGeometry * endcapGeometry_
Definition: DetId.h:18
int hashedIndex() const
Definition: EEDetId.h:183
virtual std::vector< DetId > getWindow(const DetId &id, const int &northSouthSize, const int &eastWestSize) const
void associateNeighbours(reco::PFRecHit &rh, std::unique_ptr< reco::PFRecHitCollection > &hits, edm::RefProd< reco::PFRecHitCollection > &refprod) override
bool stdsimplemove(DetId &cell, const CaloDirection &dir, const CaloSubdetectorTopology &barrelTopo, const CaloSubdetectorTopology &endcapTopo, const EcalBarrelGeometry &barrelGeom, const EcalEndcapGeometry &endcapGeom) const
const EcalBarrelGeometry * barrelGeometry_
static const int MAX_IETA
Definition: EBDetId.h:136
T get() const
Definition: EventSetup.h:71
dbl *** dir
Definition: mlp_gen.cc:35
CaloDirection
Codes the local directions in the cell lattice.
Definition: CaloDirection.h:9
int ietaAbs() const
get the absolute value of the crystal ieta
Definition: EBDetId.h:47
bool neighbourmapcalculated_
set to true in ecalNeighbArray