CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MuonRadiationCorrWeightProducer.cc
Go to the documentation of this file.
2 
4 
6 
8 
10 
11 #include <vector>
12 #include <algorithm>
13 #include <math.h>
14 
16  : numOthers_(0),
17  numWarnings_(0)
18 {
19  srcMuonsBeforeRad_ = cfg.getParameter<edm::InputTag>("srcMuonsBeforeRad");
20  srcMuonsAfterRad_ = cfg.getParameter<edm::InputTag>("srcMuonsAfterRad");
21 
23  if ( inputFileName.location() == edm::FileInPath::Unknown)
24  throw cms::Exception("MuonRadiationCorrWeightProducer")
25  << " Failed to find File = " << inputFileName << " !!\n";
26  std::auto_ptr<TFile> inputFile(new TFile(inputFileName.fullPath().data()));
27 
28  typedef std::vector<double> vdouble;
29  vdouble binningMuonEn = cfg.getParameter<vdouble>("binningMuonEn");
30  int numBinsMuonEn = binningMuonEn.size() - 1;
31  if ( !(numBinsMuonEn >= 1) ) throw cms::Exception("Configuration")
32  << " Invalid Configuration Parameter 'binningMuonEn', must define at least one bin !!\n";
33 
34  lutDirectoryRef_ = cfg.getParameter<std::string>("lutDirectoryRef");
35  for ( int iBinMuPlusEn = 0; iBinMuPlusEn < numBinsMuonEn; ++iBinMuPlusEn ) {
36  double minMuPlusEn = binningMuonEn[iBinMuPlusEn];
37  double maxMuPlusEn = binningMuonEn[iBinMuPlusEn + 1];
38  for ( int iBinMuMinusEn = 0; iBinMuMinusEn < numBinsMuonEn; ++iBinMuMinusEn ) {
39  double minMuMinusEn = binningMuonEn[iBinMuMinusEn];
40  double maxMuMinusEn = binningMuonEn[iBinMuMinusEn + 1];
41  lutEntryType* lutEntry =
42  new lutEntryType(*inputFile, lutDirectoryRef_, minMuPlusEn, maxMuPlusEn, minMuMinusEn, maxMuMinusEn);
43  lutEntriesRef_.push_back(lutEntry);
44  }
45  }
46 
47  edm::ParameterSet cfgNameOthers = cfg.getParameter<edm::ParameterSet>("lutDirectoryOthers");
48  std::vector<std::string> names_others = cfgNameOthers.getParameterNamesForType<std::string>();
49  for ( std::vector<std::string>::const_iterator name_others = names_others.begin();
50  name_others != names_others.end(); ++name_others ) {
51  std::string lutDirectoryOther = cfgNameOthers.getParameter<std::string>(*name_others);
52  lutDirectoriesOthers_[*name_others] = lutDirectoryOther;
53  for ( int iBinMuPlusEn = 0; iBinMuPlusEn < numBinsMuonEn; ++iBinMuPlusEn ) {
54  double minMuPlusEn = binningMuonEn[iBinMuPlusEn];
55  double maxMuPlusEn = binningMuonEn[iBinMuPlusEn + 1];
56  for ( int iBinMuMinusEn = 0; iBinMuMinusEn < numBinsMuonEn; ++iBinMuMinusEn ) {
57  double minMuMinusEn = binningMuonEn[iBinMuMinusEn];
58  double maxMuMinusEn = binningMuonEn[iBinMuMinusEn + 1];
59  lutEntryType* lutEntry =
60  new lutEntryType(*inputFile, lutDirectoryOther, minMuPlusEn, maxMuPlusEn, minMuMinusEn, maxMuMinusEn);
61  lutEntriesOthers_[*name_others].push_back(lutEntry);
62  }
63  }
64  ++numOthers_;
65  }
66  if ( !(numOthers_ >= 1) )
67  throw cms::Exception("MuonRadiationCorrWeightProducer")
68  << " Invalid Configuration Parameter 'lutNameOthers': No alternative models defined !!\n";
69 
70  minWeight_ = cfg.getParameter<double>("minWeight");
71  maxWeight_ = cfg.getParameter<double>("maxWeight");
72 
73  verbosity_ = ( cfg.exists("verbosity") ) ?
74  cfg.getParameter<int>("verbosity") : 0;
75 
76  maxWarnings_ = 10;
77 
78  produces<double>("weight");
79  produces<double>("weightUp");
80  produces<double>("weightDown");
81 }
82 
84 {
85  for ( vlutEntryType::iterator it = lutEntriesRef_.begin();
86  it != lutEntriesRef_.end(); ++it ) {
87  delete (*it);
88  }
89 
90  for ( std::map<std::string, vlutEntryType>::iterator it1 = lutEntriesOthers_.begin();
91  it1 != lutEntriesOthers_.end(); ++it1 ) {
92  for ( vlutEntryType::iterator it2 = it1->second.begin();
93  it2 != it1->second.end(); ++it2 ) {
94  delete (*it2);
95  }
96  }
97 }
98 
99 namespace
100 {
101  double square(double x)
102  {
103  return x*x;
104  }
105 }
106 
108 {
109  if ( verbosity_ ) {
110  std::cout << "<MuonRadiationCorrWeightProducer::produce>:" << std::endl;
111  std::cout << " srcMuonsBeforeRad = " << srcMuonsBeforeRad_ << std::endl;
112  std::cout << " srcMuonsAfterRad = " << srcMuonsAfterRad_ << std::endl;
113  }
114 
115  reco::Candidate::LorentzVector genMuonPlusP4_beforeRad;
116  bool genMuonPlus_beforeRad_found = false;
117  reco::Candidate::LorentzVector genMuonMinusP4_beforeRad;
118  bool genMuonMinus_beforeRad_found = false;
119  findMuons(evt, srcMuonsBeforeRad_, genMuonPlusP4_beforeRad, genMuonPlus_beforeRad_found, genMuonMinusP4_beforeRad, genMuonMinus_beforeRad_found);
120 
121  reco::Candidate::LorentzVector genMuonPlusP4_afterRad;
122  bool genMuonPlus_afterRad_found = false;
123  reco::Candidate::LorentzVector genMuonMinusP4_afterRad;
124  bool genMuonMinus_afterRad_found = false;
125  findMuons(evt, srcMuonsAfterRad_, genMuonPlusP4_afterRad, genMuonPlus_afterRad_found, genMuonMinusP4_afterRad, genMuonMinus_afterRad_found);
126 
127  bool genMuonPlus_found = (genMuonPlus_beforeRad_found && genMuonPlus_afterRad_found);
128  bool genMuonMinus_found = (genMuonMinus_beforeRad_found && genMuonMinus_afterRad_found);
129 
130  double weight = 1.;
131  double weightErr = 1.;
132  if ( genMuonPlus_found && genMuonMinus_found ) {
133  if ( verbosity_ ) {
134  std::cout << " muon+: En = " << genMuonPlusP4_afterRad.E() << ", dEn = " << (genMuonPlusP4_beforeRad.E() - genMuonPlusP4_afterRad.E()) << std::endl;
135  std::cout << " muon-: En = " << genMuonMinusP4_afterRad.E() << ", dEn = " << (genMuonMinusP4_beforeRad.E() - genMuonMinusP4_afterRad.E()) << std::endl;
136  }
137 
138  int error = 0;
139 
140  double pRef = 0;
141  bool pRef_found = false;
142  for ( vlutEntryType::iterator lutEntry = lutEntriesRef_.begin();
143  lutEntry != lutEntriesRef_.end(); ++lutEntry ) {
144  if ( (*lutEntry)->isWithinBounds(genMuonPlusP4_afterRad.E(), genMuonMinusP4_afterRad.E()) ) {
145  pRef = (*lutEntry)->getP(genMuonPlusP4_beforeRad, genMuonPlusP4_afterRad, genMuonMinusP4_beforeRad, genMuonMinusP4_afterRad);
146  if ( verbosity_ ) std::cout << "pRef = " << pRef << std::endl;
147  pRef_found = true;
148  }
149  }
150  if ( !pRef_found ) {
151  if ( numWarnings_ < maxWarnings_ ) {
152  edm::LogWarning ("<MuonRadiationCorrWeightProducer>")
153  << "Failed to find entry in reference LUT for"
154  << " muon+: En = " << genMuonPlusP4_afterRad.E() << ", dEn = " << (genMuonPlusP4_beforeRad.E() - genMuonPlusP4_afterRad.E()) << ";"
155  << " muon-: En = " << genMuonMinusP4_afterRad.E() << ", dEn = " << (genMuonMinusP4_beforeRad.E() - genMuonMinusP4_afterRad.E()) << " !!" << std::endl;
156  ++numWarnings_;
157  }
158  error = 1;
159  }
160 
161  std::map<std::string, double> pOthers; // key = model name
162  for ( std::map<std::string, vlutEntryType>::iterator lutEntriesOther = lutEntriesOthers_.begin();
163  lutEntriesOther != lutEntriesOthers_.end(); ++lutEntriesOther ) {
164  bool pOther_found = false;
165  for ( vlutEntryType::iterator lutEntry = lutEntriesOther->second.begin();
166  lutEntry != lutEntriesOther->second.end(); ++lutEntry ) {
167  if ( (*lutEntry)->isWithinBounds(genMuonPlusP4_afterRad.E(), genMuonMinusP4_afterRad.E()) ) {
168  pOthers[lutEntriesOther->first] = (*lutEntry)->getP(genMuonPlusP4_beforeRad, genMuonPlusP4_afterRad, genMuonMinusP4_beforeRad, genMuonMinusP4_afterRad);
169  if ( verbosity_ ) std::cout << "pOthers[" << lutEntriesOther->first << "] = " << pOthers[lutEntriesOther->first] << std::endl;
170  pOther_found = true;
171  }
172  }
173  if ( !pOther_found ) {
174  if ( numWarnings_ < maxWarnings_ ) {
175  edm::LogWarning ("<MuonRadiationCorrWeightProducer>")
176  << "Failed to find entry in LUT = " << lutEntriesOther->first << " for"
177  << " muon+: En = " << genMuonPlusP4_afterRad.E() << ", dEn = " << (genMuonPlusP4_beforeRad.E() - genMuonPlusP4_afterRad.E()) << ";"
178  << " muon-: En = " << genMuonMinusP4_afterRad.E() << ", dEn = " << (genMuonMinusP4_beforeRad.E() - genMuonMinusP4_afterRad.E()) << " !!" << std::endl;
179  ++numWarnings_;
180  }
181  error = 1;
182  }
183  }
184 
185  if ( !error ) {
186  double pMean = pRef;
187  for ( std::map<std::string, double>::const_iterator pOther = pOthers.begin();
188  pOther != pOthers.end(); ++pOther ) {
189  pMean += pOther->second;
190  }
191  pMean /= (1 + numOthers_);
192  if ( verbosity_ ) std::cout << "pMean = " << pMean << std::endl;
193 
194  double pErr2 = square(pRef - pMean);
195  for ( std::map<std::string, double>::const_iterator pOther = pOthers.begin();
196  pOther != pOthers.end(); ++pOther ) {
197  pErr2 += square(pOther->second - pMean);
198  }
199  pErr2 /= numOthers_;
200  if ( verbosity_ ) std::cout << "pErr = " << sqrt(pErr2) << std::endl;
201 
202  if ( pRef > 0. ) {
203  weight = pMean/pRef;
204  weightErr = sqrt(pErr2)/pRef;
205  } else {
206  weight = maxWeight_;
207  weightErr = maxWeight_;
208  }
209  }
210  } else {
211  if ( numWarnings_ < maxWarnings_ ) {
212  edm::LogWarning ("<MuonRadiationCorrWeightProducer>")
213  << "Failed to find generator level taus matching reconstructed muons !!" << std::endl;
214  ++numWarnings_;
215  }
216  }
217 
218  if ( weight < minWeight_ ) weight = minWeight_;
219  if ( weight > maxWeight_ ) weight = maxWeight_;
220  double weightUp = weight + weightErr;
221  if ( weightUp > (2.*maxWeight_) ) weightUp = 2.*maxWeight_;
222  double weightDown = std::max(weight - weightErr, 0.);
223 
224  if ( verbosity_ ) {
225  std::cout << "--> weight = " << weight << " + " << (weightUp - weight) << " - " << (weight - weightDown) << std::endl;
226  }
227 
228  std::auto_ptr<double> weightPtr(new double(weight));
229  evt.put(weightPtr, "weight");
230  std::auto_ptr<double> weightUpPtr(new double(weightUp));
231  evt.put(weightUpPtr, "weightUp");
232  std::auto_ptr<double> weightDownPtr(new double(weightDown));
233  evt.put(weightDownPtr, "weightDown");
234 }
235 
237 
239 
240 
T getParameter(std::string const &) const
tuple cfg
Definition: looper.py:293
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
std::map< std::string, std::string > lutDirectoriesOthers_
bool exists(std::string const &parameterName) const
checks if a parameter exists
MuonRadiationCorrWeightProducer(const edm::ParameterSet &)
void produce(edm::Event &, const edm::EventSetup &)
std::map< std::string, vlutEntryType > lutEntriesOthers_
std::vector< std::string > getParameterNamesForType(bool trackiness=true) const
Definition: ParameterSet.h:194
T x() const
Cartesian x coordinate.
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:120
T sqrt(T t)
Definition: SSEVec.h:48
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
double square(const double a)
tuple cout
Definition: gather_cfg.py:121
void findMuons(const edm::Event &, const edm::InputTag &, reco::Candidate::LorentzVector &, bool &, reco::Candidate::LorentzVector &, bool &)