CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ParticleTowerProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: ParticleTowerProducer
4 // Class: ParticleTowerProducer
5 //
13 //
14 // Original Author: Yetkin Yilmaz,32 4-A08,+41227673039,
15 // Created: Thu Jan 20 19:53:58 CET 2011
16 //
17 //
18 
19 
20 // system include files
21 #include <memory>
22 
23 
24 // user include files
27 
30 
32 
34 
36 
41 
46 
47 #include "TMath.h"
48 #include "TRandom.h"
49 
50 
51 
52 
53 //
54 // constants, enums and typedefs
55 //
56 
57 
58 //
59 // static data member definitions
60 //
61 
62 //
63 // constructors and destructor
64 //
66  geo_(0)
67 {
68  //register your products
69  src_ = consumes<reco::PFCandidateCollection>(iConfig.getParameter<edm::InputTag>("src"));
70  useHF_ = iConfig.getParameter<bool>("useHF");
71 
72  produces<CaloTowerCollection>();
73 
74  //now do what ever other initialization is needed
75  random_ = new TRandom();
76  PI = TMath::Pi();
77 
78 
79 
80 }
81 
82 
84 {
85 
86  // do anything here that needs to be done at desctruction time
87  // (e.g. close files, deallocate resources etc.)
88 
89 }
90 
91 
92 //
93 // member functions
94 //
95 
96 // ------------ method called to produce the data ------------
97 void
99 {
100  using namespace edm;
101 
102  if(!geo_){
104  iSetup.get<CaloGeometryRecord>().get(pG);
105  geo_ = pG.product();
106  }
107 
108 
109  resetTowers(iEvent, iSetup);
110 
111 
113  iEvent.getByToken(src_, inputsHandle);
114 
115  for(reco::PFCandidateCollection::const_iterator ci = inputsHandle->begin(); ci!=inputsHandle->end(); ++ci) {
116 
117  const reco::PFCandidate& particle = *ci;
118 
119  // put a cutoff if you want
120  //if(particle.et() < 0.3) continue;
121 
122  double eta = particle.eta();
123 
124  if(!useHF_ && fabs(eta) > 3. ) continue;
125 
126  int ieta = eta2ieta(eta);
127  if(eta<0) ieta *= -1;
128 
129  int iphi = phi2iphi(particle.phi(),ieta);
130 
132  if(abs(ieta)<=16) sd = HcalBarrel;
133  else if(fabs(eta)< 3.) sd = HcalEndcap; // Use the endcap until eta =3
134  else sd = HcalForward;
135 
136  HcalDetId hid = HcalDetId(sd,ieta,iphi,1); // assume depth=1
137 
138  // check against the old method (boundaries slightly shifted in the endcaps
139  /*
140  HcalDetId hid_orig = getNearestTower(particle);
141 
142  if(hid != hid_orig)
143  {
144  if(abs((hid).ieta()-(hid_orig).ieta())>1 || abs((hid).iphi()-(hid_orig).iphi()) >1 ){
145 
146  int phi_diff = 1;
147  if(abs((hid).ieta())>39 || abs((hid_orig).ieta())>39) phi_diff = 4;
148  else if(abs((hid).ieta())>20 || abs((hid_orig).ieta())>20) phi_diff = 2;
149 
150  if(abs((hid).ieta()-(hid_orig).ieta()) > 1 || abs((hid).iphi()-(hid_orig).iphi()) > phi_diff ){
151  std::cout<<" eta "<<eta<<std::endl;
152  std::cout<<" hid "<<hid<<std::endl;
153  std::cout<<" old method "<<hid_orig<<std::endl;
154  }
155  }
156  }
157  */
158  towers_[hid] += particle.et();
159  }
160 
161 
162  std::auto_ptr<CaloTowerCollection> prod(new CaloTowerCollection());
163 
164  for ( std::map< DetId, double >::const_iterator iter = towers_.begin();
165  iter != towers_.end(); ++iter ){
166 
167  CaloTowerDetId newTowerId(iter->first.rawId());
168  double et = iter->second;
169 
170  if(et>0){
171 
172  GlobalPoint pos =geo_->getGeometry(newTowerId)->getPosition();
173 
174  if(!useHF_ && fabs(pos.eta()) > 3. ) continue;
175 
176  // currently sets et = pt, mass to zero
177  // pt, eta , phi, mass
178  reco::Particle::PolarLorentzVector p4(et,pos.eta(),pos.phi(),0.);
179 
180  CaloTower newTower(newTowerId,et,0,0,0,0,p4,pos,pos);
181  prod->push_back(newTower);
182  }
183  }
184 
185 
186  //For reference, Calo Tower Constructors
187 
188  /*
189  CaloTower(const CaloTowerDetId& id,
190  double emE, double hadE, double outerE,
191  int ecal_tp, int hcal_tp,
192  const PolarLorentzVector p4,
193  GlobalPoint emPosition, GlobalPoint hadPosition);
194 
195  CaloTower(const CaloTowerDetId& id,
196  double emE, double hadE, double outerE,
197  int ecal_tp, int hcal_tp,
198  const LorentzVector p4,
199  GlobalPoint emPosition, GlobalPoint hadPosition);
200  */
201 
202 
203  iEvent.put(prod);
204 
205 
206 }
207 
208 // ------------ method called once each job just before starting event loop ------------
209 void
211 {
212  // tower edges from fast sim, used starting at index 30 for the HF
213  const double etatow[42] = {0.000, 0.087, 0.174, 0.261, 0.348, 0.435, 0.522, 0.609, 0.696, 0.783, 0.870, 0.957, 1.044, 1.131, 1.218, 1.305, 1.392, 1.479, 1.566, 1.653, 1.740, 1.830, 1.930, 2.043, 2.172, 2.322, 2.500, 2.650, 2.853, 3.000, 3.139, 3.314, 3.489, 3.664, 3.839, 4.013, 4.191, 4.363, 4.538, 4.716, 4.889, 5.191};
214 
215  // tower centers derived directly from by looping over HCAL towers and printing out the values, used up until eta = 3 where the HF/Endcap interface becomes problematic
216  const double etacent[40] = {
217  0.0435, // 1
218  0.1305, // 2
219  0.2175, // 3
220  0.3045, // 4
221  0.3915, // 5
222  0.4785, // 6
223  0.5655, // 7
224  0.6525, // 8
225  0.7395, // 9
226  0.8265, // 10
227  0.9135, // 11
228  1.0005, // 12
229  1.0875, // 13
230  1.1745, // 14
231  1.2615, // 15
232  1.3485, // 16
233  1.4355, // 17
234  1.5225, // 18
235  1.6095, // 19
236  1.6965, // 20
237  1.785 , // 21
238  1.88 , // 22
239  1.9865, // 23
240  2.1075, // 24
241  2.247 , // 25
242  2.411 , // 26
243  2.575 , // 27
244  2.759 , // 28
245  2.934 , // 29
246  2.90138,// 29
247  3.04448,// 30
248  3.21932,// 31
249  3.39462,// 32
250  3.56966,// 33
251  3.74485,// 34
252  3.91956,// 35
253  4.09497,// 36
254  4.27007,// 37
255  4.44417,// 38
256  4.62046 // 39
257  };
258 
259  // Use the real towers centrers for the barrel and endcap up to eta=3
260  etaedge[0] = 0.;
261  for(int i=1;i<30;i++){
262  etaedge[i] = (etacent[i-1]-etaedge[i-1])*2.0 + etaedge[i-1];
263  //std::cout<<" i "<<i<<" etaedge "<<etaedge[i]<<std::endl;
264  }
265  // beyond eta = 3 just use the fast sim values
266  if(useHF_){
267  for(int i=30;i<42;i++){
268  etaedge[i]=etatow[i];
269  //std::cout<<" i "<<i<<" etaedge "<<etaedge[i]<<std::endl;
270  }
271  }
272 }
273 
274 // ------------ method called once each job just after ending the event loop ------------
275 void
277 }
278 
279 
281 {
282 
283  std::vector<DetId> alldid = geo_->getValidDetIds();
284 
285  for(std::vector<DetId>::const_iterator did=alldid.begin(); did != alldid.end(); did++){
286  if( (*did).det() == DetId::Hcal ){
287  HcalDetId hid = HcalDetId(*did);
288  if( hid.depth() == 1 ) {
289 
290  if(!useHF_){
291  GlobalPoint pos =geo_->getGeometry(hid)->getPosition();
292  //if((hid).iphi()==1)std::cout<<" ieta "<<(hid).ieta()<<" eta "<<pos.eta()<<" iphi "<<(hid).iphi()<<" phi "<<pos.phi()<<std::endl;
293  if(fabs(pos.eta())>3.) continue;
294  }
295  towers_[(*did)] = 0.;
296  }
297 
298  }
299  }
300 
301 
302 
303 
304  //print out tower eta boundaries
305  /*
306  int current_ieta=0;
307  float testphi =0.;
308  for(double testeta=1.7; testeta<=5.4;testeta+=0.00001){
309  HcalDetId hid = getNearestTower(testeta,testphi);
310  if((hid).ieta()!=current_ieta) {
311  std::cout<<" new ieta "<<current_ieta<<" testeta "<<testeta<<std::endl;
312  current_ieta = (hid).ieta();
313  }
314  }
315  */
316 
317 }
318 
319 
320 
321 
323 
324  double eta = in.eta();
325  double phi = in.phi();
326 
327  double minDeltaR = 9999;
328 
329  std::vector<DetId> alldid = geo_->getValidDetIds();
330 
331  DetId returnId;
332 
333  //int nclosetowers=0;
334 
335  for(std::vector<DetId>::const_iterator did=alldid.begin(); did != alldid.end(); did++){
336  if( (*did).det() == DetId::Hcal ){
337 
338  HcalDetId hid(*did);
339 
340  // which layer is irrelevant for an eta-phi map, no?
341 
342  if( hid.depth() != 1 ) continue;
343 
344  GlobalPoint pos =geo_->getGeometry(hid)->getPosition();
345 
346  double hcalEta = pos.eta();
347  double hcalPhi = pos.phi();
348 
349  //std::cout<<" transverse distance = "<<sqrt(pos.x()*pos.x()+pos.y()*pos.y())<<std::endl;
350 
351  //std::cout<<" ieta "<<(hid).ieta()<<" iphi "<<(hid).iphi()<<" hcalEta "<<hcalEta<<" hcalPhi "<<hcalPhi<<std::endl;
352 
353  double deltaR = reco::deltaR(eta,phi,hcalEta,hcalPhi);
354 
355  // need to factor in the size of the tower
356  double towersize = 0.087;
357 
358  int ieta = (hid).ieta();
359 
360  if(abs(ieta)>21){
361  if(abs(ieta)>29) towersize=0.175;
362  else{
363  if(abs(ieta)==22) towersize=0.1;
364  else if(abs(ieta)==23) towersize=0.113;
365  else if(abs(ieta)==24) towersize=0.129;
366  else if(abs(ieta)==25) towersize=0.16;
367  else if(abs(ieta)==26) towersize=0.168;
368  else if(abs(ieta)==27) towersize=0.15;
369  else if(abs(ieta)==28) towersize=0.218;
370  else if(abs(ieta)==29) towersize=0.132;
371  }
372  }
373 
374  deltaR /= towersize;
375  //if(deltaR<1/3.) nclosetowers++;
376 
377  if(deltaR<minDeltaR){
378  returnId = DetId(*did);
379  minDeltaR = deltaR;
380  }
381 
382  //if(abs(eta-hcalEta)<towersize/2. && abs(phi-hcalPhi)<towersize/2.) break;
383  }
384  }
385  //if(nclosetowers>1)std::cout<<"eta "<<eta<<" phi "<<phi<<" minDeltaR "<<minDeltaR<<" nclosetowers "<<nclosetowers<<std::endl;
386  return returnId;
387 
388 
389 }
390 
391 
393 
394  // get closest tower by delta R matching
395  // Now obsolute, instead use faster premade eta-phi grid
396 
397  double minDeltaR = 9999;
398 
399  std::vector<DetId> alldid = geo_->getValidDetIds();
400 
401  DetId returnId;
402 
403  //int nclosetowers=0;
404 
405  for(std::vector<DetId>::const_iterator did=alldid.begin(); did != alldid.end(); did++){
406  if( (*did).det() == DetId::Hcal ){
407 
408  HcalDetId hid(*did);
409 
410  // which layer is irrelevant for an eta-phi map, no?
411 
412  if( hid.depth() != 1 ) continue;
413 
414  GlobalPoint pos =geo_->getGeometry(hid)->getPosition();
415 
416  double hcalEta = pos.eta();
417  double hcalPhi = pos.phi();
418 
419  //std::cout<<" transverse distance = "<<sqrt(pos.x()*pos.x()+pos.y()*pos.y())<<std::endl;
420 
421  //std::cout<<" ieta "<<(hid).ieta()<<" iphi "<<(hid).iphi()<<" hcalEta "<<hcalEta<<" hcalPhi "<<hcalPhi<<std::endl;
422 
423  double deltaR = reco::deltaR(eta,phi,hcalEta,hcalPhi);
424 
425  // need to factor in the size of the tower
426  double towersize = 0.087;
427 
428  int ieta = (hid).ieta();
429 
430  if(abs(ieta)>21){
431  if(abs(ieta)>29) towersize=0.175;
432  else{
433  if(abs(ieta)==22) towersize=0.1;
434  else if(abs(ieta)==23) towersize=0.113;
435  else if(abs(ieta)==24) towersize=0.129;
436  else if(abs(ieta)==25) towersize=0.16;
437  else if(abs(ieta)==26) towersize=0.168;
438  else if(abs(ieta)==27) towersize=0.15;
439  else if(abs(ieta)==28) towersize=0.218;
440  else if(abs(ieta)==29) towersize=0.132;
441  }
442  }
443 
444  deltaR /= towersize;
445  //if(deltaR<1/3.) nclosetowers++;
446 
447  if(deltaR<minDeltaR){
448  returnId = DetId(*did);
449  minDeltaR = deltaR;
450  }
451 
452  //if(abs(eta-hcalEta)<towersize/2. && abs(phi-hcalPhi)<towersize/2.) break;
453  }
454  }
455  //if(nclosetowers>1)std::cout<<"eta "<<eta<<" phi "<<phi<<" minDeltaR "<<minDeltaR<<" nclosetowers "<<nclosetowers<<std::endl;
456  return returnId;
457 
458 
459 }
460 
461 
462 
463 
464 // Taken from FastSimulation/CalorimeterProperties/src/HCALProperties.cc
465 // Note this returns an abs(ieta)
467  // binary search in the array of towers eta edges
468 
469  if(fabs(eta)>etaedge[41]) return 41;
470  int size = 42;
471  if(!useHF_) size = 30;
472 
473  double x = fabs(eta);
474  int curr = size / 2;
475  int step = size / 4;
476  int iter;
477  int prevdir = 0;
478  int actudir = 0;
479 
480  for (iter = 0; iter < size ; iter++) {
481 
482  if( curr >= size || curr < 1 )
483  std::cout << " ParticleTowerProducer::eta2ieta - wrong current index = "
484  << curr << " !!!" << std::endl;
485 
486  if ((x <= etaedge[curr]) && (x > etaedge[curr-1])) break;
487  prevdir = actudir;
488  if(x > etaedge[curr]) {actudir = 1;}
489  else {actudir = -1;}
490  if(prevdir * actudir < 0) { if(step > 1) step /= 2;}
491  curr += actudir * step;
492  if(curr > size) curr = size;
493  else { if(curr < 1) {curr = 1;}}
494 
495  /*
496  std::cout << " HCALProperties::eta2ieta end of iter." << iter
497  << " curr, etaedge[curr-1], etaedge[curr] = "
498  << curr << " " << etaedge[curr-1] << " " << etaedge[curr] << std::endl;
499  */
500 
501  }
502 
503  /*
504  std::cout << " HCALProperties::eta2ieta for input x = " << x
505  << " found index = " << curr-1
506  << std::endl;
507  */
508 
509  return curr;
510 }
511 
512 int ParticleTowerProducer::phi2iphi(double phi, int ieta) const {
513 
514  if(phi<0) phi += 2.*PI;
515  else if(phi> 2.*PI) phi -= 2.*PI;
516 
517  int iphi = (int) TMath::Ceil(phi/2.0/PI*72.);
518  // take into account larger granularity in endcap (x2) and at the end of the HF (x4)
519  if(abs(ieta)>20){
520  if(abs(ieta)<40) iphi -= (iphi+1)%2;
521  else {
522  iphi -= (iphi+1)%4;
523  if(iphi==-1) iphi=71;
524  }
525  }
526 
527  return iphi;
528 
529 }
530 
531  //define this as a plug-in
const double Pi
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
static const double etatow[]
int phi2iphi(double phi, int ieta) const
virtual double et() const
transverse energy
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:449
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
double deltaR(const T1 &t1, const T2 &t2)
Definition: deltaR.h:48
T eta() const
virtual double eta() const
momentum pseudorapidity
ParticleTowerProducer(const edm::ParameterSet &)
void resetTowers(edm::Event &iEvent, const edm::EventSetup &iSetup)
int depth() const
get the tower depth
Definition: HcalDetId.h:40
int iEvent
Definition: GenABIO.cc:230
std::map< DetId, double > towers_
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:113
double p4[4]
Definition: TauolaWrapper.h:92
HcalSubdetector
Definition: HcalAssistant.h:31
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static const double etacent[]
double deltaR(double eta1, double eta2, double phi1, double phi2)
Definition: TreeUtility.cc:17
Definition: DetId.h:18
int eta2ieta(double eta) const
double sd
const T & get() const
Definition: EventSetup.h:55
edm::EDGetTokenT< reco::PFCandidateCollection > src_
T const * product() const
Definition: ESHandle.h:86
std::vector< DetId > getValidDetIds() const
Get the list of all valid detector ids.
Definition: CaloGeometry.cc:90
T eta() const
Definition: PV3DBase.h:76
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:39
edm::SortedCollection< CaloTower > CaloTowerCollection
Definition: CaloTowerFwd.h:15
const CaloCellGeometry * getGeometry(const DetId &id) const
Get the cell geometry of a given detector id.
Definition: CaloGeometry.cc:76
math::PtEtaPhiMLorentzVector PolarLorentzVector
Lorentz vector.
Definition: Particle.h:23
CaloGeometry const * geo_
DetId getNearestTower(const reco::PFCandidate &in) const
tuple cout
Definition: gather_cfg.py:121
virtual void produce(edm::Event &, const edm::EventSetup &)
Definition: DDAxes.h:10
const GlobalPoint & getPosition() const
Returns the position of reference for this cell.
virtual double phi() const
momentum azimuthal angle
tuple size
Write out results.
Definition: DDAxes.h:10