CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MuonCaloCompatibility.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: MuonIdentification
4 // Class: MuonCaloCompatibility
5 //
6 /*
7 
8  Description: test track muon hypothesis using energy deposition in ECAL,HCAL,HO
9 
10 */
11 //
12 // Original Author: Ingo Bloch
13 // $Id: MuonCaloCompatibility.cc,v 1.8 2010/06/02 15:50:51 andersj Exp $
14 //
15 //
19 
21 {
22  MuonfileName_ = (iConfig.getParameter<edm::FileInPath>("MuonTemplateFileName")).fullPath();
23  PionfileName_ = (iConfig.getParameter<edm::FileInPath>("PionTemplateFileName")).fullPath();
24  muon_templates.reset( new TFile(MuonfileName_.c_str(),"READ") );
25  pion_templates.reset( new TFile(PionfileName_.c_str(),"READ") );
26 
27  pion_em_etaEmi = (TH2D*) pion_templates->Get("em_etaEmi");
28  pion_had_etaEmi = (TH2D*) pion_templates->Get("had_etaEmi");
29 
30  pion_em_etaTmi = (TH2D*) pion_templates->Get("em_etaTmi");
31  pion_had_etaTmi = (TH2D*) pion_templates->Get("had_etaTmi");
32 
33  pion_em_etaB = (TH2D*) pion_templates->Get("em_etaB");
34  pion_had_etaB = (TH2D*) pion_templates->Get("had_etaB");
35  pion_ho_etaB = (TH2D*) pion_templates->Get("ho_etaB");
36 
37  pion_em_etaTpl = (TH2D*) pion_templates->Get("em_etaTpl");
38  pion_had_etaTpl = (TH2D*) pion_templates->Get("had_etaTpl");
39 
40  pion_em_etaEpl = (TH2D*) pion_templates->Get("em_etaEpl");
41  pion_had_etaEpl = (TH2D*) pion_templates->Get("had_etaEpl");
42 
43  muon_em_etaEmi = (TH2D*) muon_templates->Get("em_etaEmi");
44  muon_had_etaEmi = (TH2D*) muon_templates->Get("had_etaEmi");
45 
46  muon_em_etaTmi = (TH2D*) muon_templates->Get("em_etaTmi");
47  muon_had_etaTmi = (TH2D*) muon_templates->Get("had_etaTmi");
48 
49  muon_em_etaB = (TH2D*) muon_templates->Get("em_etaB");
50  muon_had_etaB = (TH2D*) muon_templates->Get("had_etaB");
51  muon_ho_etaB = (TH2D*) muon_templates->Get("ho_etaB");
52 
53  muon_em_etaTpl = (TH2D*) muon_templates->Get("em_etaTpl");
54  muon_had_etaTpl = (TH2D*) muon_templates->Get("had_etaTpl");
55 
56  muon_em_etaEpl = (TH2D*) muon_templates->Get("em_etaEpl");
57  muon_had_etaEpl = (TH2D*) muon_templates->Get("had_etaEpl");
58 
59  pbx = -1;
60  pby = -1;
61  pbz = -1;
62 
63  psx = -1;
64  psy = -1;
65  psz = -1;
66 
67  muon_compatibility = -1;
68 
69  use_corrected_hcal = true;
70  use_em_special = true;
71  isConfigured_ = true;
72 }
73 
74 bool MuonCaloCompatibility::accessing_overflow( TH2D* histo, double x, double y ) {
75  bool access = false;
76 
77  if( histo->GetXaxis()->FindBin(x) == 0 ||
78  histo->GetXaxis()->FindBin(x) > histo->GetXaxis()->GetNbins() ) {
79  access = true;
80  }
81  if( histo->GetYaxis()->FindBin(y) == 0 ||
82  histo->GetYaxis()->FindBin(y) > histo->GetYaxis()->GetNbins() ) {
83  access = true;
84  }
85  return access;
86 }
87 
89  if (! isConfigured_) {
90  edm::LogWarning("MuonIdentification") << "MuonCaloCompatibility is not configured! Nothing is calculated.";
91  return -9999;
92  }
93 
94  double eta = 0.;
95  double p = 0.;
96  double em = 0.;
97  double had = 0.;
98  double ho = 0.;
99 
100  // had forgotten this reset in previous versions 070409
101  pbx = 1.;
102  pby = 1.;
103  pbz = 1.;
104 
105  psx = 1.;
106  psy = 1.;
107  psz = 1.;
108 
109  muon_compatibility = -1.;
110 
113 
116 
119 
120  // 071002: Get either tracker track, or SAmuon track.
121  // CaloCompatibility templates may have to be specialized for
122  // the use with SAmuons, currently just using the ones produced
123  // using tracker tracks.
124  const reco::Track* track = 0;
125  if ( ! amuon.track().isNull() ) {
126  track = amuon.track().get();
127  }
128  else {
129  if ( ! amuon.standAloneMuon().isNull() ) {
130  track = amuon.standAloneMuon().get();
131  }
132  else {
133  throw cms::Exception("FatalError") << "Failed to fill muon id calo_compatibility information for a muon with undefined references to tracks";
134  }
135  }
136 
137  if( !use_corrected_hcal ) { // old eta regions, uncorrected energy
138  eta = track->eta();
139  p = track->p();
140 
141  // new 070904: Set lookup momentum to 1999.9 if larger than 2 TeV.
142  // Though the templates were produced with p<2TeV, we believe that
143  // this approximation should be roughly valid. A special treatment
144  // for >1 TeV muons is advisable anyway :)
145  if( p>=2000. ) p = 1999.9;
146 
147  // p = 10./sin(track->theta()); // use this for templates < 1_5
148  if( use_em_special ) {
149  if( amuon.calEnergy().em == 0. ) em = -5.;
150  else em = amuon.calEnergy().em;
151  }
152  else {
153  em = amuon.calEnergy().em;
154  }
155  had = amuon.calEnergy().had;
156  ho = amuon.calEnergy().ho;
157  }
158  else {
159  eta = track->eta();
160  p = track->p();
161 
162  // new 070904: Set lookup momentum to 1999.9 if larger than 2 TeV.
163  // Though the templates were produced with p<2TeV, we believe that
164  // this approximation should be roughly valid. A special treatment
165  // for >1 TeV muons is advisable anyway :)
166  if( p>=2000. ) p = 1999.9;
167 
168  // p = 10./sin(track->theta()); // use this for templates < 1_5
169  // hcal energy is now done where we get the template histograms (to use corrected cal energy)!
170  // had = amuon.calEnergy().had;
171  if( use_em_special ) {
172  if( amuon.calEnergy().em == 0. ) em = -5.;
173  else em = amuon.calEnergy().em;
174  }
175  else {
176  em = amuon.calEnergy().em;
177  }
178  ho = amuon.calEnergy().ho;
179  }
180 
181 
182  // Skip everyting and return "I don't know" (i.e. 0.5) for uncovered regions:
183  // if( p < 0. || p > 500.) return 0.5; // removed 500 GeV cutoff 070817 after updating the tempates (v2_0) to have valid entried beyond 500 GeV
184  if( p < 0. ) return 0.5; // return "unknown" for unphysical momentum input.
185  if( fabs(eta) > 2.5 ) return 0.5;
186  // temporary fix for low association efficiency:
187  // set caloCompatibility to 0.12345 for tracks
188  // which have 0 energy in BOTH ecal and hcal
189  if( amuon.calEnergy().had == 0.0 && amuon.calEnergy().em == 0.0 ) return 0.12345;
190 
191  // std::cout<<std::endl<<"Input values are: "<<eta <<" "<< p <<" "<< em <<" "<< had <<" "<< ho;
192 
193  // depending on the eta, choose correct histogram: (now all for barrel):
194  // bad! eta range has to be syncronised with choice for histogram... should be read out from the histo file somehow... 070322
195  if(42 != 42) { // old eta ranges and uncorrected hcal energy
196  if(eta <= -1.4) {
197  // std::cout<<"Emi"<<std::endl;
202  }
203  else if(eta > -1.4 && eta <= -1.31) {
204  // std::cout<<"Tmi"<<std::endl;
209  }
210  else if(eta > -1.31 && eta <= 1.31) {
211  // std::cout<<"B"<<std::endl;
218  }
219  else if(eta > 1.31 && eta <= 1.4) {
220  // std::cout<<"Tpl"<<std::endl;
225  }
226  else if(eta > 1.4) {
227  // std::cout<<"Epl"<<std::endl;
232  }
233  else {
234  LogTrace("MuonIdentification")<<"Some very weird thing happened in MuonCaloCompatibility::evaluate - go figure ;) ";
235  return -999;
236  }
237  }
238  else if( 42 == 42 ) { // new eta bins, corrected hcal energy
239  if( track->eta() > 1.27 ) {
240  // had_etaEpl ->Fill(muon->track().get()->p(),1.8/2.2*muon->calEnergy().had );
241  if(use_corrected_hcal) had = 1.8/2.2*amuon.calEnergy().had;
242  else had = amuon.calEnergy().had;
245  }
246  if( track->eta() <= 1.27 && track->eta() > 1.1 ) {
247  // had_etaTpl ->Fill(muon->track().get()->p(),(1.8/(-2.2*muon->track().get()->eta()+5.5))*muon->calEnergy().had );
248  if(use_corrected_hcal) had = (1.8/(-2.2*track->eta()+5.5))*amuon.calEnergy().had;
249  else had = amuon.calEnergy().had;
252  }
253  if( track->eta() <= 1.1 && track->eta() > -1.1 ) {
254  // had_etaB ->Fill(muon->track().get()->p(),sin(muon->track().get()->theta())*muon->calEnergy().had );
255  if(use_corrected_hcal) had = sin(track->theta())*amuon.calEnergy().had;
256  else had = amuon.calEnergy().had;
259  }
260  if( track->eta() <= -1.1 && track->eta() > -1.27 ) {
261  // had_etaTmi ->Fill(muon->track().get()->p(),(1.8/(-2.2*muon->track().get()->eta()+5.5))*muon->calEnergy().had );
262  if(use_corrected_hcal) had = (1.8/(2.2*track->eta()+5.5))*amuon.calEnergy().had;
263  else had = amuon.calEnergy().had;
266  }
267  if( track->eta() <= -1.27 ) {
268  // had_etaEmi ->Fill(muon->track().get()->p(),1.8/2.2*muon->calEnergy().had );
269  if(use_corrected_hcal) had = 1.8/2.2*amuon.calEnergy().had;
270  else had = amuon.calEnergy().had;
273  }
274 
275  // just two eta regions for Ecal (+- 1.479 for barrel, else for rest), no correction:
276 
277  // std::cout<<"We have a muon with an eta of: "<<track->eta()<<std::endl;
278 
279  if( track->eta() > 1.479 ) {
280  // em_etaEpl ->Fill(muon->track().get()->p(),muon->calEnergy().em );
281  // // em_etaTpl ->Fill(muon->track().get()->p(),muon->calEnergy().em );
285  }
286  if( track->eta() <= 1.479 && track->eta() > -1.479 ) {
287  // em_etaB ->Fill(muon->track().get()->p(),muon->calEnergy().em );
291  }
292  if( track->eta() <= -1.479 ) {
293  // // em_etaTmi ->Fill(muon->track().get()->p(),muon->calEnergy().em );
294  // em_etaEmi ->Fill(muon->track().get()->p(),muon->calEnergy().em );
298  }
299 
300  // just one barrel eta region for the HO, no correction
301  // if( track->eta() < 1.4 && track->eta() > -1.4 ) { // experimenting now...
302  if( track->eta() < 1.28 && track->eta() > -1.28 ) {
303  // ho_etaB ->Fill(muon->track().get()->p(),muon->calEnergy().ho );
307  }
308 
309 
310  }
311 
312 
313  if( 42 != 42 ) { // check validity of input template histos and input variables"
314  pion_template_em ->ls();
315  pion_template_had->ls();
317  muon_template_em ->ls();
318  muon_template_had->ls();
320 
321  LogTrace("MuonIdentification")<<"Input variables: eta p em had ho "<<"\n"
322  <<eta<<" "<<p<<" "<<em<<" "<<had<<" "<<ho<<" "<<"\n"
323  <<"cal uncorr: em had ho "<<"\n"
324  <<eta<<" "<<p<<" "<<amuon.calEnergy().em<<" "<<amuon.calEnergy().had<<" "<<amuon.calEnergy().ho;
325  }
326 
327 
328  // Look up Compatibility by, where x is p and y the energy.
329  // We have a set of different histograms for different regions of eta.
330 
331  // need error meassage in case the template histos are missing / the template file is not present!!! 070412
332 
333  if( pion_template_em ) { // access ecal background template
334  if( accessing_overflow( pion_template_em, p, em ) ) {
335  pbx = 1.;
336  psx = 1.;
337  LogTrace("MuonIdentification")<<" // Message: trying to access overflow bin in MuonCompatibility template for ecal - defaulting signal and background ";
338  LogTrace("MuonIdentification")<<" // template value to 1. "<<pion_template_em->GetName()<<" e: "<<em<<" p: "<<p;
339  }
340  else pbx = pion_template_em->GetBinContent( pion_template_em->GetXaxis()->FindBin(p), pion_template_em->GetYaxis()->FindBin(em) );
341  }
342  if( pion_template_had ) { // access hcal background template
343  if( accessing_overflow( pion_template_had, p, had ) ) {
344  pby = 1.;
345  psy = 1.;
346  LogTrace("MuonIdentification")<<" // Message: trying to access overflow bin in MuonCompatibility template for hcal - defaulting signal and background ";
347  LogTrace("MuonIdentification")<<" // template value to 1. "<<pion_template_had->GetName()<<" e: "<<had<<" p: "<<p;
348  }
349  else pby = pion_template_had->GetBinContent( pion_template_had->GetXaxis()->FindBin(p), pion_template_had->GetYaxis()->FindBin(had) );
350  }
351  if(pion_template_ho) { // access ho background template
352  if( accessing_overflow( pion_template_ho, p, ho ) ) {
353  pbz = 1.;
354  psz = 1.;
355  LogTrace("MuonIdentification")<<" // Message: trying to access overflow bin in MuonCompatibility template for ho - defaulting signal and background ";
356  LogTrace("MuonIdentification")<<" // template value to 1. "<<pion_template_ho->GetName()<<" e: "<<em<<" p: "<<p;
357  }
358  else pbz = pion_template_ho->GetBinContent( pion_template_ho->GetXaxis()->FindBin(p), pion_template_ho->GetYaxis()->FindBin(ho) );
359  }
360 
361 
362  if( muon_template_em ) { // access ecal background template
363  if( accessing_overflow( muon_template_em, p, em ) ) {
364  psx = 1.;
365  pbx = 1.;
366  LogTrace("MuonIdentification")<<" // Message: trying to access overflow bin in MuonCompatibility template for ecal - defaulting signal and background ";
367  LogTrace("MuonIdentification")<<" // template value to 1. "<<muon_template_em->GetName()<<" e: "<<em<<" p: "<<p;
368  }
369  else psx = muon_template_em->GetBinContent( muon_template_em->GetXaxis()->FindBin(p), muon_template_em->GetYaxis()->FindBin(em) );
370  }
371  if( muon_template_had ) { // access hcal background template
372  if( accessing_overflow( muon_template_had, p, had ) ) {
373  psy = 1.;
374  pby = 1.;
375  LogTrace("MuonIdentification")<<" // Message: trying to access overflow bin in MuonCompatibility template for hcal - defaulting signal and background ";
376  LogTrace("MuonIdentification")<<" // template value to 1. "<<muon_template_had->GetName()<<" e: "<<had<<" p: "<<p;
377  }
378  else psy = muon_template_had->GetBinContent( muon_template_had->GetXaxis()->FindBin(p), muon_template_had->GetYaxis()->FindBin(had) );
379  }
380  if(muon_template_ho) { // access ho background template
381  if( accessing_overflow( muon_template_ho, p, ho ) ) {
382  psz = 1.;
383  pbz = 1.;
384  LogTrace("MuonIdentification")<<" // Message: trying to access overflow bin in MuonCompatibility template for ho - defaulting signal and background ";
385  LogTrace("MuonIdentification")<<" // template value to 1. "<<muon_template_ho->GetName()<<" e: "<<ho<<" p: "<<p;
386  }
387  else psz = muon_template_ho->GetBinContent( muon_template_ho->GetXaxis()->FindBin(p), muon_template_ho->GetYaxis()->FindBin(ho) );
388  }
389 
390  // erm - what is this?!?! How could the HO probability be less than 0????? Do we want this line!?!?
391  if(psz <= 0.) psz = 1.;
392  if(pbz <= 0.) pbz = 1.;
393 
394  // Protection agains empty bins - set cal part to neutral if the bin of the template is empty
395  // (temporary fix, a proper extrapolation would be better)
396  if (psx == 0. || pbx == 0.) {
397  psx = 1.;
398  pbx = 1.;
399  }
400  if (psy == 0. || pby == 0.) {
401  psy = 1.;
402  pby = 1.;
403  }
404  if (psz == 0. || pbz == 0.) {
405  psz = 1.;
406  pbz = 1.;
407  }
408 
409  // There are two classes of events that deliver 0 for the hcal or ho energy:
410  // 1) the track momentum is so low that the extrapolation tells us it should not have reached the cal
411  // 2) the crossed cell had an reading below the readout cuts.
412  // The 2nd case discriminates between muons and hadrons, the 1st not. Thus for the time being,
413  // we set the returned ps and pb to 0 for these cases.
414  // We need to have a return value different from 0 for the 1st case in the long run.
415  if ( had == 0.0 ) {
416  psy = 1.;
417  pby = 1.;
418  }
419  if ( ho == 0.0 ) {
420  psz = 1.;
421  pbz = 1.;
422  }
423 
424 
425  // Set em to neutral if no energy in em or negative energy measured.
426  // (These cases might indicate problems in the ecal association or readout?! The only
427  // hint so far: for critical eta region (eta in [1.52, 1.64]) have negative em values.)
428  if( em <= 0. && !use_em_special ) {
429  pbx = 1.;
430  psx = 1.;
431  }
432 
433  if( (psx*psy*psz+pbx*pby*pbz) > 0. ) muon_compatibility = psx*psy*psz / (psx*psy*psz+pbx*pby*pbz);
434  else {
435  LogTrace("MuonIdentification")<<"Divide by 0 - defaulting consistency to 0.5 (neutral)!!";
436  muon_compatibility = 0.5;
437  LogTrace("MuonIdentification")<<"Input variables: eta p em had ho "<<"\n"
438  <<eta<<" "<<p<<" "<<em<<" "<<had<<" "<<ho<<" "<<"\n"
439  <<"cal uncorr: em had ho "<<"\n"
440  <<eta<<" "<<p<<" "<<amuon.calEnergy().em<<" "<<amuon.calEnergy().had<<" "<<amuon.calEnergy().ho;
441  }
442  return muon_compatibility;
443 }
double p() const
momentum vector magnitude
Definition: TrackBase.h:129
T getParameter(std::string const &) const
double theta() const
polar angle
Definition: TrackBase.h:117
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
virtual TrackRef track() const
reference to a Track
Definition: Muon.h:50
double evaluate(const reco::Muon &)
#define NULL
Definition: scimark2.h:8
T eta() const
boost::shared_ptr< TFile > pion_templates
float ho
energy deposited in crossed HO towers
Definition: MuonEnergy.h:32
bool isNull() const
Checks for null.
Definition: Ref.h:247
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:141
#define LogTrace(id)
MuonEnergy calEnergy() const
get energy deposition information
Definition: Muon.h:112
void configure(const edm::ParameterSet &)
bool accessing_overflow(TH2D *histo, double x, double y)
Definition: DDAxes.h:10
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:242
boost::shared_ptr< TFile > muon_templates
virtual TrackRef standAloneMuon() const
reference to a stand-alone muon Track
Definition: Muon.h:53