CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFRecHitProducerHO.cc
Go to the documentation of this file.
2 
3 #include <memory>
4 
6 
10 
14 
18 
24 
27 
30 
33 
34 // Necessary includes for identify severity of flagged problems in HO rechits
39 
40 using namespace std;
41 using namespace edm;
42 
44  : PFRecHitProducer(iConfig) {
45 
46  // access to the collections of rechits
48  iConfig.getParameter<InputTag>("recHitsHO");
49 
50  HOMaxAllowedSev_ = iConfig.getParameter<int>("HOMaxAllowedSev");
52 }
53 
54 
55 
57 
58 void
60  vector<reco::PFRecHit>& rechitsCleaned,
62  const edm::EventSetup& iSetup ) {
63 
64 
65 
66  // this map is necessary to find the rechit neighbours efficiently
67  //C but I should think about using Florian's hashed index to do this.
68  //C in which case the map might not be necessary anymore
69  //
70  // the key of this map is detId.
71  // the value is the index in the rechits vector
72  map<unsigned, unsigned > idSortedRecHits;
73  // typedef map<unsigned, unsigned >::iterator IDH;
74 
76  iSetup.get<CaloGeometryRecord>().get(geoHandle);
77 
78  // get the HO geometry
79  const CaloSubdetectorGeometry *hcalBarrelGeometry =
80  geoHandle->getSubdetectorGeometry(DetId::Hcal, HcalOuter);
81 
82  // get the HO topology
83  HcalTopology hcalBarrelTopology; // (geoHandle);
84 
86  hoNeighbArray( *hcalBarrelGeometry,
87  hcalBarrelTopology);
88 
89  // Get Hcal Severity Level Computer, so that the severity of each rechit flag/status may be determined
90  edm::ESHandle<HcalSeverityLevelComputer> hcalSevLvlComputerHndl;
91  iSetup.get<HcalSeverityLevelComputerRcd>().get(hcalSevLvlComputerHndl);
92  const HcalSeverityLevelComputer* hcalSevLvlComputer = hcalSevLvlComputerHndl.product();
93 
94 
95  // get the HO rechits
96 
98 
99 
100  bool found = iEvent.getByLabel(inputTagHORecHits_,
101  rhcHandle);
102 
103  if(!found) {
104 
105  ostringstream err;
106  err<<"could not find rechits "<<inputTagHORecHits_;
107  LogError("PFRecHitProducerHO")<<err.str()<<endl;
108 
109  throw cms::Exception( "MissingProduct", err.str());
110  }
111  else {
112  assert( rhcHandle.isValid() );
113 
114  // process HO rechits
115  for(unsigned i=0; i<rhcHandle->size(); i++) {
116 
117  const HORecHit& erh = (*rhcHandle)[i];
118  const HcalDetId& detid = (HcalDetId)erh.detid();
119 
120  double energy = erh.energy();
121  // uint32_t flag = erh.recoFlag();
122  double time = erh.time();
123 
125 
126  if (esd != 3) continue;
127 
128  int hoeta=detid.ieta();
129  if ( (abs(hoeta)<=4 && energy < thresh_Barrel_) ||
130  (abs(hoeta)> 4 && energy < thresh_Endcap_) ) continue;
131 
132 
133  // Get Channel Quality information for the given detID
134  const HcalChannelStatus* theStatus = theHcalChStatus->getValues(detid);
135  unsigned theStatusValue = theStatus->getValue();
136  // Now get severity of problems for the given detID, based on the rechit flag word and the channel quality status value
137  int hitSeverity=hcalSevLvlComputer->getSeverityLevel(detid, erh.flags(),theStatusValue);
138 
139  // Skip hits whose problems are more severe than max accept level. In the future, allow for cleaning of such hits?
140  // Note: As of April 2012, by default, all HO hits in rings +/-1, +/-2 should be identified as either "remove from calotowers" or "remove from rechit collections" in the channel quality database, and thus should be rejected by this conditional statement.
141  if (hitSeverity>HOMaxAllowedSev_)
142  {
143  //std::cout <<"Rejecting HO hit HO("<<hoeta<<", "<<detid.iphi()<<", "<<detid.depth()<<std::endl;
144  continue;
145  }
146 
147 
148 
149  reco::PFRecHit *pfrh = createHORecHit(detid, energy,
150  PFLayer::HCAL_BARREL2, // HO,
151  hcalBarrelGeometry);
152 
153  if( !pfrh ) continue; // problem with this rechit. skip it
154 
155  pfrh->setRescale(time);
156 
157  rechits.push_back( *pfrh );
158  delete pfrh;
159  idSortedRecHits.insert( make_pair(detid.rawId(), rechits.size()-1 ) );
160  }
161  }
162 
163  // do navigation
164  for(unsigned i=0; i<rechits.size(); i++ ) {
165  findRecHitNeighboursHO( rechits[i], idSortedRecHits );
166  }
167 
168 }
169 
170 
173  double energy,
174  PFLayer::Layer layer,
175  const CaloSubdetectorGeometry* geom ) {
176 
178  math::XYZVector axis;
179 
180  const CaloCellGeometry *thisCell
181  = geom->getGeometry(detid);
182 
183  // find rechit geometry
184  if(!thisCell) {
185  LogError("PFRecHitProducerHO")
186  <<"warning detid "<<detid.rawId()
187  <<" not found in geometry"<<endl;
188  return 0;
189  }
190 
191  double sclel0l1r=0.946; //384.8/406.6
192 
193  if (abs(thisCell->getPosition().z())>130) {
194  position.SetCoordinates ( sclel0l1r*thisCell->getPosition().x(),
195  sclel0l1r*thisCell->getPosition().y(),
196  sclel0l1r*thisCell->getPosition().z() );
197 
198  } else {
199  position.SetCoordinates ( thisCell->getPosition().x(),
200  thisCell->getPosition().y(),
201  thisCell->getPosition().z() );
202  }
203 
204  // the axis vector is the difference
205 
206  // const TruncatedPyramid* pyr
207  // = dynamic_cast< const TruncatedPyramid* > (thisCell);
208  // if( pyr ) {
209  // axis.SetCoordinates( pyr->getPosition(1).x(),
210  // pyr->getPosition(1).y(),
211  // pyr->getPosition(1).z() );
212 
213  // math::XYZVector axis0( pyr->getPosition(0).x(),
214  // pyr->getPosition(0).y(),
215  // pyr->getPosition(0).z() );
216 
217  // axis -= axis0;
218  // }
219  // else return 0;
220 
221  axis = math::XYZVector(0,0,0);
222 
223  // if( !geomfound ) {
224  // LogError("PFRecHitProducerHO")<<"cannor find geometry for detid "
225  // <<detid.rawId()<<" in layer "<<layer<<endl;
226  // return 0; // geometry not found, skip rechit
227  // }
228 
229 
230  reco::PFRecHit *rh
231  = new reco::PFRecHit( detid.rawId(), layer,
232  energy,
233  position.x(), position.y(), position.z(),
234  axis.x(), axis.y(), axis.z() );
235 
236  const CaloCellGeometry::CornersVec& corners = thisCell->getCorners();
237  assert( corners.size() == 8 );
238 
239  if (abs(corners[0].z())>130.0) {
240  rh->setNECorner( sclel0l1r*corners[0].x(), sclel0l1r*corners[0].y(), sclel0l1r*corners[0].z() );
241  rh->setSECorner( sclel0l1r*corners[1].x(), sclel0l1r*corners[1].y(), sclel0l1r*corners[1].z() );
242  rh->setSWCorner( sclel0l1r*corners[2].x(), sclel0l1r*corners[2].y(), sclel0l1r*corners[2].z() );
243  rh->setNWCorner( sclel0l1r*corners[3].x(), sclel0l1r*corners[3].y(), sclel0l1r*corners[3].z() );
244 
245  } else {
246  rh->setNECorner( corners[0].x(), corners[0].y(), corners[0].z() );
247  rh->setSECorner( corners[1].x(), corners[1].y(), corners[1].z() );
248  rh->setSWCorner( corners[2].x(), corners[2].y(), corners[2].z() );
249  rh->setNWCorner( corners[3].x(), corners[3].y(), corners[3].z() );
250  }
251 
252  return rh;
253 }
254 
255 
256 bool
260  math::XYZVector& axis ) {
261 
262 
263  const CaloCellGeometry *thisCell
264  = geom->getGeometry(detid);
265 
266  // find rechit geometry
267  if(!thisCell) {
268  LogError("PFRecHitProducerHO")
269  <<"warning detid "<<detid.rawId()
270  <<" not found in geometry"<<endl;
271  return false;
272  }
273 
274  position.SetCoordinates ( thisCell->getPosition().x(),
275  thisCell->getPosition().y(),
276  thisCell->getPosition().z() );
277 
278 
279 
280  // the axis vector is the difference
281  // const TruncatedPyramid* pyr
282  // = dynamic_cast< const TruncatedPyramid* > (thisCell);
283  // if( pyr ) {
284  // axis.SetCoordinates( pyr->getPosition(1).x(),
285  // pyr->getPosition(1).y(),
286  // pyr->getPosition(1).z() );
287 
288  // math::XYZVector axis0( pyr->getPosition(0).x(),
289  // pyr->getPosition(0).y(),
290  // pyr->getPosition(0).z() );
291 
292  // axis -= axis0;
293 
294 
295  // return true;
296  // }
297 
298  axis = math::XYZVector(0,0,0);
299  return true;
300 
301  // else return false;
302 }
303 
304 
305 
306 void
309  const map<unsigned,unsigned >& sortedHits ) {
310 
311  DetId center( rh.detId() );
312 
313 
314  DetId north = move( center, NORTH );
315  DetId northeast = move( center, NORTHEAST );
316  DetId northwest = move( center, NORTHWEST );
317  DetId south = move( center, SOUTH );
318  DetId southeast = move( center, SOUTHEAST );
319  DetId southwest = move( center, SOUTHWEST );
320  DetId east = move( center, EAST );
321  DetId west = move( center, WEST );
322 
323  IDH i = sortedHits.find( north.rawId() );
324  if(i != sortedHits.end() )
325  rh.add4Neighbour( i->second );
326 
327  i = sortedHits.find( northeast.rawId() );
328  if(i != sortedHits.end() )
329  rh.add8Neighbour( i->second );
330 
331  i = sortedHits.find( south.rawId() );
332  if(i != sortedHits.end() )
333  rh.add4Neighbour( i->second );
334 
335  i = sortedHits.find( southwest.rawId() );
336  if(i != sortedHits.end() )
337  rh.add8Neighbour( i->second );
338 
339  i = sortedHits.find( east.rawId() );
340  if(i != sortedHits.end() )
341  rh.add4Neighbour( i->second );
342 
343  i = sortedHits.find( southeast.rawId() );
344  if(i != sortedHits.end() )
345  rh.add8Neighbour( i->second );
346 
347  i = sortedHits.find( west.rawId() );
348  if(i != sortedHits.end() )
349  rh.add4Neighbour( i->second );
350 
351  i = sortedHits.find( northwest.rawId() );
352  if(i != sortedHits.end() )
353  rh.add8Neighbour( i->second );
354 }
355 
356 
357 // Build the array of (max)8 neighbors
358 void
360  const CaloSubdetectorGeometry& barrelGeom,
361  const CaloSubdetectorTopology& barrelTopo){
362 
363  static const CaloDirection orderedDir[8]={SOUTHWEST,
364  SOUTH,
365  SOUTHEAST,
366  WEST,
367  EAST,
368  NORTHWEST,
369  NORTH,
370  NORTHEAST};
371 
372  const unsigned nbarrel = 2160; //62000;
373  // Barrel first. The hashed index runs from 0 to 2199 61199
374  neighboursHO_.resize(nbarrel);
375 
376  //std::cout << " Building the array of neighbours (barrel) " ;
377 
378  const std::vector<DetId>& vec(barrelGeom.getValidDetIds(DetId::Hcal,
379  HcalOuter));
380  unsigned size=vec.size();
381  for(unsigned ic=0; ic<size; ++ic)
382  {
383  // We get the 9 cells in a square.
384  std::vector<DetId> neighbours(barrelTopo.getWindow(vec[ic],3,3));
385  unsigned nneighbours=neighbours.size();
386 
387  unsigned hashedindex=HcalDetId(vec[ic]).hashed_index()-5184; //2*( kHBhalf + kHEhalf )
388  // std::cout << " Cell " << ic<<" "<<vec[ic].rawId()<<" "<<HcalDetId(vec[ic]) <<" "<<hashedindex<<" "<<nneighbours<< std::endl;
389  if(hashedindex>=nbarrel)
390  {
391  LogDebug("CaloGeometryTools") << " Array overflow " << std::endl;
392  }
393 
394 
395  // If there are 9 cells, it is easy, and this order is know:
396  // 6 7 8
397  // 3 4 5
398  // 0 1 2 (0 = SOUTHWEST)
399 
400  if(nneighbours==9)
401  {
402  neighboursHO_[hashedindex].reserve(8);
403  for(unsigned in=0;in<nneighbours;++in)
404  {
405  // remove the centre
406  // cout<<"ic "<<ic<<" "<<in<<" "<<neighbours[in].rawId()<<" "<<vec[ic].rawId()<<" "<<hashedindex<<endl;
407  if(neighbours[in]!=vec[ic])
408  {
409  neighboursHO_[hashedindex].push_back(neighbours[in]);
410  // std::cout << " Neighbour " << ic<<" "<<size<<" "<<in << " " <<hashedindex<<" "<< HcalDetId(neighbours[in]) << std::endl;
411  }
412  }
413  }
414  else
415  {
416  DetId central(vec[ic]);
417  neighboursHO_[hashedindex].resize(8,DetId(0));
418  for(unsigned idir=0;idir<8;++idir)
419  {
420  DetId testid=central;
421  bool status=stdmove(testid,orderedDir[idir],
422  barrelTopo, barrelGeom);
423  if(status) neighboursHO_[hashedindex][idir]=testid;
424  }
425 
426  }
427  }
428 
429  // std::cout << " done " << size <<std::endl;
431 }
432 
433 bool
435  const CaloDirection& dir,
436  const CaloSubdetectorTopology& barrelTopo,
437  const CaloSubdetectorGeometry& barrelGeom)
438  const {
439 
440  std::vector<DetId> neighbours;
441 
442  // BARREL CASE
443  if(cell.subdetId()==HcalOuter) {
444  HcalDetId hoDetId = cell;
445 
446  neighbours = barrelTopo.getNeighbours(hoDetId,dir);
447 
448  // first try to move according to the standard navigation
449  if(neighbours.size()>0 && !neighbours[0].null()) {
450  cell = neighbours[0];
451  return true;
452  }
453 
454  // failed.
455 
456 
457  }
458 
459  // everything failed
460  cell = DetId(0);
461  return false;
462 }
463 
464 
465 
466 bool
468  const CaloDirection& dir,
469  const CaloSubdetectorTopology& barrelTopo,
470  const CaloSubdetectorGeometry& barrelGeom)
471 
472  const {
473 
474 
475  bool result;
476 
477  if(dir==NORTH) {
478  result = stdsimplemove(cell,NORTH, barrelTopo, barrelGeom);
479  return result;
480  }
481  else if(dir==SOUTH) {
482  result = stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom);
483  return result;
484  }
485  else if(dir==EAST) {
486  result = stdsimplemove(cell,EAST, barrelTopo, barrelGeom);
487  return result;
488  }
489  else if(dir==WEST) {
490  result = stdsimplemove(cell,WEST, barrelTopo, barrelGeom);
491  return result;
492  }
493 
494 
495  // One has to try both paths
496  else if(dir==NORTHEAST)
497  {
498  result = stdsimplemove(cell,NORTH, barrelTopo, barrelGeom);
499  if(result)
500  return stdsimplemove(cell,EAST, barrelTopo, barrelGeom);
501  else
502  {
503  result = stdsimplemove(cell,EAST, barrelTopo, barrelGeom);
504  if(result)
505  return stdsimplemove(cell,NORTH, barrelTopo, barrelGeom);
506  else
507  return false;
508  }
509  }
510  else if(dir==NORTHWEST)
511  {
512  result = stdsimplemove(cell,NORTH, barrelTopo, barrelGeom );
513  if(result)
514  return stdsimplemove(cell,WEST, barrelTopo, barrelGeom );
515  else
516  {
517  result = stdsimplemove(cell,WEST, barrelTopo, barrelGeom );
518  if(result)
519  return stdsimplemove(cell,NORTH, barrelTopo, barrelGeom );
520  else
521  return false;
522  }
523  }
524  else if(dir == SOUTHEAST)
525  {
526  result = stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom );
527  if(result)
528  return stdsimplemove(cell,EAST, barrelTopo, barrelGeom );
529  else
530  {
531  result = stdsimplemove(cell,EAST, barrelTopo, barrelGeom );
532  if(result)
533  return stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom );
534  else
535  return false;
536  }
537  }
538  else if(dir == SOUTHWEST)
539  {
540  result = stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom );
541  if(result)
542  return stdsimplemove(cell,WEST, barrelTopo, barrelGeom );
543  else
544  {
545  result = stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom );
546  if(result)
547  return stdsimplemove(cell,WEST, barrelTopo, barrelGeom );
548  else
549  return false;
550  }
551  }
552  cell = DetId(0);
553  return false;
554 }
555 
557  const CaloDirection&dir ) const
558 {
559  DetId originalcell = cell;
560  if(dir==NONE || cell==DetId(0)) return false;
561 
562  // Conversion CaloDirection and index in the table
563  // CaloDirection :NONE,SOUTH,SOUTHEAST,SOUTHWEST,EAST,WEST, NORTHEAST,NORTHWEST,NORTH
564  // Table : SOUTHWEST,SOUTH,SOUTHEAST,WEST,EAST,NORTHWEST,NORTH, NORTHEAST
565  static const int calodirections[9]={-1,1,2,0,4,3,7,5,6};
566 
567  assert(neighbourmapcalculated_);
568 
569  DetId result = neighboursHO_[HcalDetId(originalcell).hashed_index()-5184][calodirections[dir]];
570  return result;
571 }
572 
#define LogDebug(id)
void setSECorner(double posx, double posy, double posz)
Definition: PFRecHit.cc:226
T getParameter(std::string const &) const
void add4Neighbour(unsigned index)
Definition: PFRecHit.cc:176
int i
Definition: DBlmapReader.cc:9
reco::PFRecHit * createHORecHit(const DetId &detid, double energy, PFLayer::Layer layer, const CaloSubdetectorGeometry *geom)
virtual std::vector< DetId > getNeighbours(const DetId &id, const CaloDirection &dir) const
void add8Neighbour(unsigned index)
Definition: PFRecHit.cc:181
void setNECorner(double posx, double posy, double posz)
Definition: PFRecHit.cc:231
std::vector< std::vector< DetId > > neighboursHO_
for each HO barrel rechit, keep track of the neighbours
const DetId & detid() const
Definition: CaloRecHit.h:22
unsigned detId() const
rechit detId
Definition: PFRecHit.h:99
void hoNeighbArray(const CaloSubdetectorGeometry &barrelGeom, const CaloSubdetectorTopology &barrelTopo)
bool stdsimplemove(DetId &cell, const CaloDirection &dir, const CaloSubdetectorTopology &barrelTopo, const CaloSubdetectorGeometry &barrelGeom) const
T y() const
Definition: PV3DBase.h:62
#define abs(x)
Definition: mlp_lapack.h:159
const GlobalPoint & getPosition() const
Returns the position of reference for this cell.
float time() const
Definition: CaloRecHit.h:21
double double double z
static int position[TOTALCHAMBERS][3]
Definition: ReadPGInfo.cc:509
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)
virtual const CaloCellGeometry * getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
uint32_t rawId() const
get the raw id
Definition: DetId.h:45
void setSWCorner(double posx, double posy, double posz)
Definition: PFRecHit.cc:221
void createRecHits(std::vector< reco::PFRecHit > &rechits, std::vector< reco::PFRecHit > &rechitsCleaned, edm::Event &, const edm::EventSetup &)
int iEvent
Definition: GenABIO.cc:243
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
Definition: PFRecHit.h:31
Base producer for particle flow rechits (PFRecHit)
float energy() const
Definition: CaloRecHit.h:19
T z() const
Definition: PV3DBase.h:63
tuple result
Definition: query.py:137
uint32_t flags() const
Definition: CaloRecHit.h:23
int ieta() const
get the cell ieta
Definition: HcalDetId.h:38
HcalSubdetector
Definition: HcalAssistant.h:32
void setRescale(double factor)
Definition: PFRecHit.h:74
bool isValid() const
Definition: HandleBase.h:76
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:39
void setNWCorner(double posx, double posy, double posz)
search for pointers to neighbours, using neighbours&#39; DetId.
Definition: PFRecHit.cc:216
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:356
Layer
layer definition
Definition: PFLayer.h:31
Definition: DetId.h:20
edm::InputTag inputTagHORecHits_
virtual std::vector< DetId > getWindow(const DetId &id, const int &northSouthSize, const int &eastWestSize) const
DetId move(DetId cell, const CaloDirection &dir) const
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
const HcalChannelQuality * theHcalChStatus
void findRecHitNeighboursHO(reco::PFRecHit &rh, const std::map< unsigned, unsigned > &sortedHits)
find rechit neighbours, using the hashed index
const T & get() const
Definition: EventSetup.h:55
T const * product() const
Definition: ESHandle.h:62
int getSeverityLevel(const DetId &myid, const uint32_t &myflag, const uint32_t &mystatus) const
std::map< unsigned, unsigned >::const_iterator IDH
bool findHORecHitGeometry(const DetId &detid, const CaloSubdetectorGeometry *geom, math::XYZVector &position, math::XYZVector &axis)
find the position and the axis of the cell for a given rechit
double thresh_Barrel_
rechits with E &lt; threshold will not give rise to a PFRecHit
dbl *** dir
Definition: mlp_gen.cc:35
CaloDirection
Codes the local directions in the cell lattice.
Definition: CaloDirection.h:9
Definition: DDAxes.h:10
tuple status
Definition: ntuplemaker.py:245
uint32_t getValue() const
bool stdmove(DetId &cell, const CaloDirection &dir, const CaloSubdetectorTopology &barrelTopo, const CaloSubdetectorGeometry &barrelGeom) const
const Item * getValues(DetId fId) const
T x() const
Definition: PV3DBase.h:61
tuple size
Write out results.
virtual const CornersVec & getCorners() const =0
Returns the corner points of this cell&#39;s volume.
int hashed_index() const
Definition: HcalDetId.cc:119
PFRecHitProducerHO(const edm::ParameterSet &)
bool neighbourmapcalculated_
set to true in hoNeighbArray