CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HFClusterAlgo.cc
Go to the documentation of this file.
2 #include <sstream>
3 #include <iostream>
4 #include <algorithm>
5 #include <list>
8 
9 using namespace std;
10 using namespace reco;
20 {
21  m_isMC=true; // safest
22 
23 }
24 
26 public:
28  return h1.et>h2.et;
29  }
30 };
31 
33 public:
34  bool operator()(const double c1,const double c2) const {
35  return c1>c2;
36  }
37 };
38 
39 static int indexByEta(HcalDetId id) {
40  return (id.zside()>0)?(id.ietaAbs()-29+13):(41-id.ietaAbs());
41 }
42 
43 static const double MCMaterialCorrections[] = { 1.000,1.000,1.105,0.970,0.965,0.975,0.956,0.958,0.981,1.005,0.986,1.086,1.000,
44  1.000,1.086,0.986,1.005,0.981,0.958,0.956,0.975,0.965,0.970,1.105,1.000,1.000 };
45 
46 static const double ZplusMC2010Corrections[] = { 1.0, 1.0, 1.075, 0.902, 0.983, 0.992, 0.948, 0.941, 0.975, 0.990, 0.988, 1.086, 1.0,
47  1.0, 1.126, 0.959, 0.979, 0.989, 0.959, 0.901, 0.937, 0.962, 0.967, 1.006, 1.0, 1.0};
48 
49 
50 
51 void HFClusterAlgo::setup(double minTowerEnergy, double seedThreshold,double maximumSL,double maximumRenergy,
52  bool usePMTflag,bool usePulseflag, bool forcePulseFlagMC, int correctionSet){
53  m_seedThreshold=seedThreshold;
54  m_minTowerEnergy=minTowerEnergy;
55  m_maximumSL=maximumSL;
56  m_usePMTFlag=usePMTflag;
57  m_usePulseFlag=usePulseflag;
58  m_forcePulseFlagMC=forcePulseFlagMC;
59  m_maximumRenergy=maximumRenergy;
60  m_correctionSet = correctionSet;
61 
62  for(int ii=0;ii<13;ii++){
63  m_cutByEta.push_back(-1);
64  }
65 
66  // always set all the corrections to one...
67  for (int ii=0; ii<13*2; ii++)
68  m_correctionByEta.push_back(1.0);
69 
70  if (m_correctionSet==1) { // corrections for material from MC
71  for (int ii=0; ii<13*2; ii++)
72  m_correctionByEta[ii]=MCMaterialCorrections[ii];
73  }
74  if (m_correctionSet==2) { // corrections for material from MC + 2010 Z-based ccalibration
75  for (int ii=0; ii<13*2; ii++)
76  m_correctionByEta[ii]=ZplusMC2010Corrections[ii];
77  }
78 
79 }
80 
83  const CaloGeometry& geom,
84  HFEMClusterShapeCollection& clusterShapes,
85  SuperClusterCollection& SuperClusters) {
86 
87  std::vector<HFCompleteHit> protoseeds, seeds;
89  std::vector<HFCompleteHit>::iterator i;
90  std::vector<HFCompleteHit>::iterator k;
91  int dP, dE, PWrap;
92  bool isok=true;
93  HFEMClusterShape clusShp;
94 
95  SuperCluster Sclus;
96  bool doCluster=false;
97 
98  for (j=hf.begin(); j!= hf.end(); j++) {
99  const int aieta=j->id().ietaAbs();
100  int iz=(aieta-29);
101  // only long fibers and not 29,40,41 allowed to be considered as seeds
102  if (j->id().depth()!=1) continue;
103  if (aieta==40 || aieta==41 || aieta==29) continue;
104 
105 
106  if (iz<0 || iz>12) {
107  edm::LogWarning("HFClusterAlgo") << "Strange invalid HF hit: " << j->id();
108  continue;
109  }
110 
111  if (m_cutByEta[iz]<0) {
112  double eta=geom.getPosition(j->id()).eta();
113  m_cutByEta[iz]=m_seedThreshold*cosh(eta); // convert ET to E for this ring
114  }
115  double elong=j->energy()*m_correctionByEta[indexByEta(j->id())];
116  if (elong>m_cutByEta[iz]) {
117  j2=hf.find(HcalDetId(HcalForward,j->id().ieta(),j->id().iphi(),2));
118  double eshort=(j2==hf.end())?(0):(j2->energy());
119  if (j2!=hf.end())
120  eshort*=m_correctionByEta[indexByEta(j2->id())];
121  if (((elong-eshort)/(elong+eshort))>m_maximumSL) continue;
122  //if ((m_usePMTFlag)&&(j->flagField(4,1))) continue;
123  //if ((m_usePulseFlag)&&(j->flagField(1,1))) continue;
124  if(isPMTHit(*j)) continue;
125 
126  HFCompleteHit ahit;
127  double eta=geom.getPosition(j->id()).eta();
128  ahit.id=j->id();
129  ahit.energy=elong;
130  ahit.et=ahit.energy/cosh(eta);
131  protoseeds.push_back(ahit);
132  }
133  }
134 
135  if(!protoseeds.empty()){
136  std::sort(protoseeds.begin(), protoseeds.end(), CompareHFCompleteHitET());
137  for (i=protoseeds.begin(); i!= protoseeds.end(); i++) {
138  isok=true;
139  doCluster=false;
140 
141  if ( (i==protoseeds.begin()) && (isok) ) {
142  doCluster=true;
143  }else {
144  // check for overlap with existing clusters
145  for (k=seeds.begin(); isok && k!=seeds.end(); k++) { //i->hits, k->seeds
146 
147  for (dE=-2; dE<=2; dE++)
148  for (dP=-4;dP<=4; dP+=2) {
149  PWrap=k->id.iphi()+dP;
150  if (PWrap<0)
151  PWrap+=72;
152  if (PWrap>72)
153  PWrap-=72;
154 
155  if ( (i->id.iphi()==PWrap) && (i->id.ieta()==k->id.ieta()+dE))
156  isok = false;
157  }
158  }
159  if (isok) {
160  doCluster=true;
161  }
162  }
163  if (doCluster) {
164  seeds.push_back(*i);
165 
166  bool clusterOk=makeCluster( i->id(),hf, geom,clusShp,Sclus);
167  if (clusterOk) { // cluster is _not_ ok if seed is rejected due to other cuts
168  clusterShapes.push_back(clusShp);
169  SuperClusters.push_back(Sclus);
170  }
171 
172  }
173  }//end protoseed loop
174  }//end if seeCount
175 }
176 
177 
179  const HFRecHitCollection& hf,
180  const CaloGeometry& geom,
181  HFEMClusterShape& clusShp,
182  SuperCluster& Sclus) {
183 
184 
185  double w=0;//sum over all log E's
186  double wgt=0;
187  double w_e=0;//sum over ieat*energy
188  double w_x=0;
189  double w_y=0;
190  double w_z=0;
191  double wp_e=0;//sum over iphi*energy
192  double e_e=0;//nonwieghted eta sum
193  double e_ep=0; //nonweighted phi sum
194 
195  double l_3=0;//sum for enenergy in 3x3 long fibers etc.
196  double s_3=0;
197  double l_5=0;
198  double s_5=0;
199  double l_1=0;
200  double s_1=0;
201  int de, dp, phiWrap;
202  double l_1e=0;
203  GlobalPoint sp=geom.getPosition(seedid);
204  std::vector<double> coreCanid;
205  std::vector<double>::const_iterator ci;
207  std::vector<DetId> usedHits;
208 
210  HcalDetId sid(HcalForward,seedid.ieta(),seedid.iphi(),1);
211  si=hf.find(sid);
212 
213  bool clusterOk=true; // assume the best to start...
214 
215  // lots happens here
216  // edge type 1 has 40/41 in 3x3 and 5x5
217  bool edge_type1=seedid.ietaAbs()==39 && (seedid.iphi()%4)==3;
218 
219  double e_seed=si->energy()*m_correctionByEta[indexByEta(si->id())];
220 
221  for (de=-2; de<=2; de++)
222  for (dp=-4;dp<=4; dp+=2) {
223  phiWrap=seedid.iphi()+dp;
224  if (phiWrap<0)
225  phiWrap+=72;
226  if (phiWrap>72)
227  phiWrap-=72;
228 
229 
230  /* Handling of phi-width change problems */
231  if (edge_type1 && de==seedid.zside()) {
232  if (dp==-2) { // we want it in the 3x3
233  phiWrap-=2;
234  if (phiWrap<0)
235  phiWrap+=72;
236  }
237  else if (dp==-4) {
238  continue; // but not double counted in 5x5
239  }
240  }
241 
242  HcalDetId idl(HcalForward,seedid.ieta()+de,phiWrap,1);
243  HcalDetId ids(HcalForward,seedid.ieta()+de,phiWrap,2);
244 
245 
246  il=hf.find(idl);
247  is=hf.find(ids);
248 
249 
250 
251 
252  double e_long=1.0;
253  double e_short=0.0;
254  if (il!=hf.end()) e_long=il->energy()*m_correctionByEta[indexByEta(il->id())];
255  if (e_long <= m_minTowerEnergy) e_long=0.0;
256  if (is!=hf.end()) e_short=is->energy()*m_correctionByEta[indexByEta(is->id())];
257  if (e_short <= m_minTowerEnergy) e_short=0.0;
258  double eRatio=(e_long-e_short)/std::max(1.0,(e_long+e_short));
259 
260  // require S/L > a minimum amount for inclusion
261  if ((abs(eRatio) > m_maximumSL)&&(std::max(e_long,e_short) > m_maximumRenergy)) {
262  if (dp==0 && de==0) clusterOk=false; // somehow, the seed is hosed
263  continue;
264  }
265 
266  if((il!=hf.end())&&(isPMTHit(*il))){
267  if (dp==0 && de==0) clusterOk=false; // somehow, the seed is hosed
268  continue;//continue to next hit, do not include this one in cluster
269  }
270 
271 
272  /*
273 
274  old pmt code
275  // cut on "PMT HIT" flag
276  if ((il!=hf.end())&&(il->flagField(4,1))&&(m_usePMTFlag)) {//HFPET flag for lone/short doil->flagField(0,1)
277  if (dp==0 && de==0) clusterOk=false; // somehow, the seed is hosed
278  continue;//continue to next hit, do not include this one in cluster
279  }
280 
281  // cut on "Pulse shape HIT" flag
282  if ((il!=hf.end())&&(il->flagField(1,1))&&(m_usePulseFlag)) {//HF DIGI TIME flag
283  if (dp==0 && de==0) clusterOk=false; // somehow, the seed is hosed
284  continue;//continue to next hit, do not include this one in cluster
285  }
286  */
287 
288 
289 
290 
291  if (e_long > m_minTowerEnergy && il!=hf.end()) {
292 
293  // record usage
294  usedHits.push_back(idl.rawId());
295  // always in the 5x5
296  l_5+=e_long;
297  // maybe in the 3x3
298  if ((de>-2)&&(de<2)&&(dp>-4)&&(dp<4)) {
299  l_3+=e_long;
300  }
301  // sometimes in the 1x1
302  if ((dp==0)&&(de==0)) {
303  l_1=e_long;
304  }
305 
306  // maybe in the core?
307  if ((de>-2)&&(de<2)&&(dp>-4)&&(dp<4)&&(e_long>(.5*e_seed))) {
308  coreCanid.push_back(e_long);
309  }
310 
311  // position calculation
312  GlobalPoint p=geom.getPosition(idl);
313 
314  double d_p = p.phi()-sp.phi();
315  while (d_p < -M_PI)
316  d_p+=2*M_PI;
317  while (d_p > M_PI)
318  d_p-=2*M_PI;
319  double d_e = p.eta()-sp.eta();
320 
321  wgt=log((e_long));
322  if (wgt>0){
323  w+=wgt;
324  w_e+=(d_e)*wgt;
325  wp_e+=(d_p)*wgt;
326  e_e+=d_e;
327  e_ep+=d_p;
328 
329  w_x+=(p.x())*wgt;//(p.x()-sp.x())*wgt;
330  w_y+=(p.y())*wgt;
331  w_z+=(p.z())*wgt;
332  }
333  } else {
334  if (dp==0 && de==0) clusterOk=false; // somehow, the seed is hosed
335  }
336 
337  if (e_short > m_minTowerEnergy && is!=hf.end()) {
338  // record usage
339  usedHits.push_back(ids.rawId());
340  // always in the 5x5
341  s_5+=e_short;
342  // maybe in the 3x3
343  if ((de>-2)&&(de<2)&&(dp>-4)&&(dp<4)) {
344  s_3+=e_short;
345  }
346  // sometimes in the 1x1
347  if ((dp==0)&&(de==0)) {
348  s_1=e_short;
349  }
350  }
351  }
352 
353 
354  if (!clusterOk) return false;
355 
356  //Core sorting done here
357  std::sort(coreCanid.begin(), coreCanid.end(), CompareHFCore());
358  for (ci=coreCanid.begin();ci!=coreCanid.end();ci++){
359  if(ci==coreCanid.begin()){
360  l_1e=*ci;
361  }else if (*ci>.5*l_1e){
362  l_1e+=*ci;
363  }
364  }//core sorting end
365 
366  double z_=w_z/w;
367  double x_=w_x/w;
368  double y_=w_y/w;
369 
370  //calcualte position, final
371  double eta=w_e/w+sp.eta();
372 
373  double phi=(wp_e/w)+sp.phi();
374 
375  while (phi < -M_PI)
376  phi+=2*M_PI;
377  while (phi > M_PI)
378  phi-=2*M_PI;
379 
380  //calculate cell phi and cell eta
381  static const double HFEtaBounds[14] = {2.853, 2.964, 3.139, 3.314, 3.489, 3.664, 3.839, 4.013, 4.191, 4.363, 4.538, 4.716, 4.889, 5.191};
382  double RcellEta = fabs(eta);
383  double Cphi = (phi>0.)?(fmod((phi),0.087*2)/(0.087*2)):((fmod((phi),0.087*2)/(0.087*2))+1.0);
384  double Rbin = -1.0;
385  for (int icell = 0; icell < 12; icell++ ){
386  if ( (RcellEta>HFEtaBounds[icell]) && (RcellEta<HFEtaBounds[icell+1]) )
387  Rbin = (RcellEta - HFEtaBounds[icell])/(HFEtaBounds[icell+1] - HFEtaBounds[icell]);
388  }
389  double Ceta=Rbin;
390 
391  while (phi< -M_PI)
392  phi+=2*M_PI;
393  while (phi > M_PI)
394  phi-=2*M_PI;
395 
396 
397  math::XYZPoint xyzclus(x_,y_,z_);
398 
399  //return HFEMClusterShape, SuperCluster
400  HFEMClusterShape myClusShp(l_1, s_1, l_3, s_3, l_5,s_5, l_1e,Ceta, Cphi,seedid);
401  clusShp = myClusShp;
402 
403  SuperCluster MySclus(l_3,xyzclus);
404  Sclus=MySclus;
405 
406  return clusterOk;
407 
408 }
410 
411  bool pmthit=false;
412 
413  if((hfr.flagField(HcalCaloFlagLabels::HFLongShort))&&(m_usePMTFlag)) pmthit=true;
414  if (!(m_isMC && !m_forcePulseFlagMC))
415  if((hfr.flagField(HcalCaloFlagLabels::HFDigiTime))&&(m_usePulseFlag)) pmthit=true;
416 
417  return pmthit;
418 
419 
420 }
int i
Definition: DBlmapReader.cc:9
void clusterize(const HFRecHitCollection &hf, const CaloGeometry &geom, reco::HFEMClusterShapeCollection &clusters, reco::SuperClusterCollection &SuperClusters)
int zside() const
get the z-side of the cell (1/-1)
Definition: HcalDetId.h:34
Geom::Phi< T > phi() const
Definition: PV3DBase.h:68
std::vector< T >::const_iterator const_iterator
T y() const
Definition: PV3DBase.h:62
#define abs(x)
Definition: mlp_lapack.h:159
T eta() const
std::vector< HFEMClusterShape > HFEMClusterShapeCollection
static const double MCMaterialCorrections[]
bool makeCluster(const HcalDetId &seedid, const HFRecHitCollection &hf, const CaloGeometry &geom, reco::HFEMClusterShape &clusShp, reco::SuperCluster &SClus)
bool operator()(const HFClusterAlgo::HFCompleteHit &h1, const HFClusterAlgo::HFCompleteHit &h2) const
const T & max(const T &a, const T &b)
std::vector< SuperCluster > SuperClusterCollection
collection of SuperCluser objectr
T z() const
Definition: PV3DBase.h:63
int ieta() const
get the cell ieta
Definition: HcalDetId.h:38
int j
Definition: DBlmapReader.cc:9
const GlobalPoint & getPosition(const DetId &id) const
Get the position of a given detector id.
Definition: CaloGeometry.cc:68
int k[5][pyjets_maxn]
int ietaAbs() const
get the absolute value of the cell ieta
Definition: HcalDetId.h:36
const_iterator end() const
static int indexByEta(HcalDetId id)
static const double ZplusMC2010Corrections[]
int iphi() const
get the cell iphi
Definition: HcalDetId.h:40
#define M_PI
Definition: BFit3D.cc:3
bool operator()(const double c1, const double c2) const
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:13
T eta() const
Definition: PV3DBase.h:75
iterator find(key_type k)
T x() const
Definition: PV3DBase.h:61
bool isPMTHit(const HFRecHit &hfr)
void setup(double minTowerEnergy, double seedThreshold, double maximumSL, double m_maximumRenergy, bool usePMTflag, bool usePulseflag, bool forcePulseFlagMC, int correctionSet)
uint32_t flagField(int base, int width=1) const
Definition: CaloRecHit.cc:31
const_iterator begin() const
T w() const
Definition: DDAxes.h:10