CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
L1ExtraMEtMixerPlugin.cc
Go to the documentation of this file.
3 
5 
9 
10 #include <TMath.h>
11 
12 #include <vector>
13 #include <set>
14 #include <algorithm>
15 
18  srcMuons_(cfg.getParameter<edm::InputTag>("srcMuons")),
19  srcDistanceMapMuPlus_(cfg.getParameter<edm::InputTag>("distanceMapMuPlus")),
20  srcDistanceMapMuMinus_(cfg.getParameter<edm::InputTag>("distanceMapMuMinus")),
21  sfAbsEtaLt12_(cfg.getParameter<double>("H_Calo_AbsEtaLt12")),
22  sfAbsEta12to17_(cfg.getParameter<double>("H_Calo_AbsEta12to17")),
23  sfAbsEtaGt17_(cfg.getParameter<double>("H_Calo_AbsEtaGt17"))
24 {}
25 
27 {
29 }
30 
32 {
33  //std::cout << "<L1ExtraMEtMixerPlugin::produce>:" << std::endl;
34  //std::cout << " src1 = " << src1_ << std::endl;
35  //std::cout << " src2 = " << src2_ << std::endl;
36  //std::cout << " instanceLabel = " << instanceLabel_ << std::endl;
37 
39  evt.getByLabel(src1_, met1);
40 
42  evt.getByLabel(src2_, met2);
43 
45  evt.getByLabel(srcMuons_, muons);
46 
47  edm::Handle<detIdToFloatMap> distanceMapMuPlus;
48  evt.getByLabel(srcDistanceMapMuPlus_, distanceMapMuPlus);
49  edm::Handle<detIdToFloatMap> distanceMapMuMinus;
50  evt.getByLabel(srcDistanceMapMuMinus_, distanceMapMuMinus);
51 
52  std::auto_ptr<l1extra::L1EtMissParticleCollection> metSum(new l1extra::L1EtMissParticleCollection());
53 
54  // CV: entries in MET collections refer to different bunch-crossings.
55  // The number of entries in the two MET collections is not necessarily the same
56  // --> match entries by bunch-crossing number
57  std::set<int> bx_set;
58  for ( l1extra::L1EtMissParticleCollection::const_iterator met1_i = met1->begin();
59  met1_i != met1->end(); ++met1_i ) {
60  bx_set.insert(met1_i->bx());
61  }
62  for ( l1extra::L1EtMissParticleCollection::const_iterator met2_i = met2->begin();
63  met2_i != met2->end(); ++met2_i ) {
64  bx_set.insert(met2_i->bx());
65  }
66 
67  std::vector<int> bx_vector;
68  for ( std::set<int>::const_iterator bx = bx_set.begin();
69  bx != bx_set.end(); ++bx ) {
70  bx_vector.push_back(*bx);
71  }
72  std::sort(bx_vector.begin(), bx_vector.end());
73 
74  for ( std::vector<int>::const_iterator bx = bx_vector.begin();
75  bx != bx_vector.end(); ++bx ) {
76  bool errorFlag = false;
77 
78  const l1extra::L1EtMissParticle* met1_bx = 0;
79  for ( l1extra::L1EtMissParticleCollection::const_iterator met1_i = met1->begin();
80  met1_i != met1->end(); ++met1_i ) {
81  if ( met1_i->bx() == (*bx) ) {
82  if ( met1_bx ) errorFlag = true;
83  met1_bx = &(*met1_i);
84  }
85  }
86 
87  const l1extra::L1EtMissParticle* met2_bx = 0;
88  for ( l1extra::L1EtMissParticleCollection::const_iterator met2_i = met2->begin();
89  met2_i != met2->end(); ++met2_i ) {
90  if ( met2_i->bx() == (*bx) ) {
91  if ( met2_bx ) errorFlag = true;
92  met2_bx = &(*met2_i);
93  }
94  }
95 
96  if ( errorFlag )
97  throw cms::Exception("L1ExtraMEtMixer::produce")
98  << " Failed to find unique match of MET objects for BX = " << (*bx) << " !!\n";
99  assert(met1_bx || met2_bx);
100 
101  // CV: check that both MET objects are of the same type
102  if ( met1_bx && met2_bx && met1_bx->type() != met2_bx->type() )
103  throw cms::Exception("L1ExtraMEtMixer::produce")
104  << " Mismatch in type between MET objects stored in collections 'src1' and 'src2' !!\n";
105 
106  double metSumPx = 0.;
107  double metSumPy = 0.;
108  double metSumEt = 0.;
109  int type = -1;
110  if ( met1_bx ) {
111  //std::cout << "met1 (BX = " << (*bx) << "): Px = " << met1_bx->px() << ", Py = " << met1_bx->py()
112  // << " (Et = " << met1_bx->etMiss() << ", Pt = " << met1_bx->pt() << ", phi = " << met1_bx->phi() << ", sumEt = " << met1_bx->etTotal() << ")" << std::endl;
113  metSumPx += met1_bx->px();
114  metSumPy += met1_bx->py();
115  metSumEt += met1_bx->etTotal();
116  type = met1_bx->type();
117  }
118  if ( met2_bx ) {
119  //std::cout << "met2 (BX = " << (*bx) << "): Px = " << met2_bx->px() << ", Py = " << met2_bx->py()
120  // << " (Et = " << met2_bx->etMiss() << ", Pt = " << met2_bx->pt() << ", phi = " << met2_bx->phi() << ", sumEt = " << met2_bx->etTotal() << ")" << std::endl;
121  metSumPx += met2_bx->px();
122  metSumPy += met2_bx->py();
123  metSumEt += met2_bx->etTotal();
124  type = met2_bx->type();
125  }
126 
127  // Subtract contribution of muons that were replaced by simulated taus
128  if ( (*bx) == 0 ) {
129  for ( reco::CandidateCollection::const_iterator muon = muons->begin();
130  muon != muons->end(); ++muon ) {
131  //std::cout << "muon: Pt = " << muon->pt() << ", eta = " << muon->eta() << ", phi = " << muon->phi()
132  // << " (Px = " << muon->px() << ", Py = " << muon->py() << ")" << std::endl;
133 
134  double distance_ecal = 0.;
135  double distance_hcal = 0.;
136  const detIdToFloatMap& distanceMap = ( muon->charge() > 0 ) ?
137  (*distanceMapMuPlus) : (*distanceMapMuMinus);
138  for ( detIdToFloatMap::const_iterator dist_iter = distanceMap.begin();
139  dist_iter != distanceMap.end(); ++dist_iter ) {
140  const DetId& id = dist_iter->first;
141  if ( id.det() == DetId::Ecal ) distance_ecal += dist_iter->second;
142  if ( id.det() == DetId::Hcal && id.subdetId() != HcalOuter) distance_hcal += dist_iter->second;
143  }
144  //std::cout << "distance_ecal = " << distance_ecal << std::endl;
145  //std::cout << "distance_hcal = " << distance_hcal << std::endl;
146 
147  // This is what we would expect from theory:
148  double dedx = getDeDxForPbWO4(muon->p());
149  //std::cout << "dedx = " << dedx << std::endl;
150  double muonEnLoss_theory = dedx*(distance_ecal*DENSITY_PBWO4 + distance_hcal*DENSITY_BRASS);
151 
152  // We correct the muon energy loss computed from theory
153  // by the ratio of average reconstructed L1Extra MET (projected in direction of the muon)
154  // in single muon gun Monte Carlo events to the theory expecation.
155  // The ratio depends on eta:
156  double muonEnLoss = muonEnLoss_theory;
157  //std::cout << "muonEnLoss (before eta-correction) = " << muonEnLoss << std::endl;
158  if ( fabs(muon->eta()) < 1.2 ) muonEnLoss *= sfAbsEtaLt12_;
159  else if ( fabs(muon->eta()) < 1.7 ) muonEnLoss *= sfAbsEta12to17_;
160  else muonEnLoss *= sfAbsEtaGt17_;
161  //std::cout << "muonEnLoss (after eta-correction) = " << muonEnLoss << std::endl;
162 
163  double muonEnLoss_transverse = muonEnLoss*sin(muon->theta());
164  if ( muonEnLoss_transverse > metSumEt ) muonEnLoss_transverse = metSumEt;
165  //std::cout << "muonEnLoss_transverse = " << muonEnLoss_transverse << std::endl;
166 
167  // The direction is given by the muon direction
168  double muonMetCorrPx = muonEnLoss_transverse*cos(muon->phi());
169  double muonMetCorrPy = muonEnLoss_transverse*sin(muon->phi());
170  double muonMetCorrSumEt = muonEnLoss_transverse;
171  //std::cout << "muonMetCorr: Px = " << muonMetCorrPx << ", Py = " << muonMetCorrPy << " (sumEt = " << muonMetCorrSumEt << ")" << std::endl;
172  metSumPx += muonMetCorrPx;
173  metSumPy += muonMetCorrPy;
174  metSumEt -= muonMetCorrSumEt;
175  }
176  }
177 
178  const double metSumPt = TMath::Sqrt(metSumPx*metSumPx + metSumPy*metSumPy);
179  // CV: setting edm::Refs to L1Gct objects not implemented yet
180  l1extra::L1EtMissParticle metSum_bx(
181  reco::Candidate::LorentzVector(metSumPx, metSumPy, 0., metSumPt),
183  metSumEt,
188  (*bx));
189  //std::cout << "metSum (BX = " << (*bx) << "): Px = " << metSum_bx.px() << ", Py = " << metSum_bx.py()
190  // << " (Et = " << metSum_bx.etMiss() << ", Pt = " << metSum_bx.pt() << ", phi = " << metSum_bx.phi() << ")" << std::endl;
191  metSum->push_back(metSum_bx);
192  }
193 
194  evt.put(metSum, instanceLabel_);
195 }
196 
198 
200 
const double DENSITY_PBWO4
type
Definition: HCALResponse.h:21
tuple cfg
Definition: looper.py:293
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
assert(m_qm.get())
EtMissType type() const
virtual void produce(edm::Event &, const edm::EventSetup &)
const double DENSITY_BRASS
std::map< uint32_t, float > detIdToFloatMap
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:120
double getDeDxForPbWO4(double)
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
if(c.getParameter< edm::InputTag >("puppiValueMap").label().size()!=0)
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:420
Definition: DetId.h:18
virtual double px() const
x coordinate of momentum vector
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
tuple muons
Definition: patZpeak.py:38
const double & etTotal() const
edm::InputTag srcDistanceMapMuMinus_
#define DEFINE_EDM_PLUGIN(factory, type, name)
std::vector< L1EtMissParticle > L1EtMissParticleCollection
L1ExtraMEtMixerPlugin(const edm::ParameterSet &)
edm::InputTag srcDistanceMapMuPlus_
virtual double py() const
y coordinate of momentum vector
virtual void registerProducts(edm::EDProducer &)