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