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