CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
LumiReWeighting.cc
Go to the documentation of this file.
1 #ifndef PhysicsTools_Utilities_interface_LumiReWeighting_cc
2 #define PhysicsTools_Utilities_interface_LumiReWeighting_cc
3 
4 
20 #include "TRandom1.h"
21 #include "TRandom2.h"
22 #include "TRandom3.h"
23 #include "TStopwatch.h"
24 #include "TH1.h"
25 #include "TFile.h"
26 #include <iostream>
27 #include <string>
28 #include <algorithm>
29 #include <boost/shared_ptr.hpp>
36 
37 using namespace edm;
38 
40  std::string dataFile,
41  std::string GenHistName = "pileup",
42  std::string DataHistName = "pileup" ) :
43  generatedFileName_( generatedFile),
44  dataFileName_ ( dataFile ),
45  GenHistName_ ( GenHistName ),
46  DataHistName_ ( DataHistName )
47  {
48  generatedFile_ = boost::shared_ptr<TFile>( new TFile(generatedFileName_.c_str()) ); //MC distribution
49  dataFile_ = boost::shared_ptr<TFile>( new TFile(dataFileName_.c_str()) ); //Data distribution
50 
51  Data_distr_ = boost::shared_ptr<TH1>( (static_cast<TH1*>(dataFile_->Get( DataHistName_.c_str() )->Clone() )) );
52  MC_distr_ = boost::shared_ptr<TH1>( (static_cast<TH1*>(generatedFile_->Get( GenHistName_.c_str() )->Clone() )) );
53 
54  // MC * data/MC = data, so the weights are data/MC:
55 
56  // normalize both histograms first
57 
58  Data_distr_->Scale( 1.0/ Data_distr_->Integral() );
59  MC_distr_->Scale( 1.0/ MC_distr_->Integral() );
60 
61  weights_ = boost::shared_ptr<TH1>( static_cast<TH1*>(Data_distr_->Clone()) );
62 
63  weights_->SetName("lumiWeights");
64 
65  TH1* den = dynamic_cast<TH1*>(MC_distr_->Clone());
66 
67  //den->Scale(1.0/ den->Integral());
68 
69  weights_->Divide( den ); // so now the average weight should be 1.0
70 
71  std::cout << " Lumi/Pileup Reweighting: Computed Weights per In-Time Nint " << std::endl;
72 
73  int NBins = weights_->GetNbinsX();
74 
75  for(int ibin = 1; ibin<NBins+1; ++ibin){
76  std::cout << " " << ibin-1 << " " << weights_->GetBinContent(ibin) << std::endl;
77  }
78 
79 
80  FirstWarning_ = true;
81  OldLumiSection_ = -1;
82 }
83 
84 LumiReWeighting::LumiReWeighting(const std::vector< float >& MC_distr,const std::vector< float >& Lumi_distr) {
85  // no histograms for input: use vectors
86 
87  // now, make histograms out of them:
88 
89  // first, check they are the same size...
90 
91  if( MC_distr.size() != Lumi_distr.size() ){
92 
93  std::cerr <<"ERROR: LumiReWeighting: input vectors have different sizes. Quitting... \n";
94  return;
95 
96  }
97 
98  Int_t NBins = MC_distr.size();
99 
100  MC_distr_ = boost::shared_ptr<TH1> ( new TH1F("MC_distr","MC dist",NBins,-0.5, float(NBins)-0.5) );
101  Data_distr_ = boost::shared_ptr<TH1> ( new TH1F("Data_distr","Data dist",NBins,-0.5, float(NBins)-0.5) );
102 
103  weights_ = boost::shared_ptr<TH1> ( new TH1F("luminumer","luminumer",NBins,-0.5, float(NBins)-0.5) );
104  TH1* den = new TH1F("lumidenom","lumidenom",NBins,-0.5, float(NBins)-0.5) ;
105 
106  for(int ibin = 1; ibin<NBins+1; ++ibin ) {
107  weights_->SetBinContent(ibin, Lumi_distr[ibin-1]);
108  Data_distr_->SetBinContent(ibin, Lumi_distr[ibin-1]);
109  den->SetBinContent(ibin,MC_distr[ibin-1]);
110  MC_distr_->SetBinContent(ibin,MC_distr[ibin-1]);
111  }
112 
113  // check integrals, make sure things are normalized
114 
115  float deltaH = weights_->Integral();
116  if(fabs(1.0 - deltaH) > 0.02 ) { //*OOPS*...
117  weights_->Scale( 1.0/ weights_->Integral() );
118  Data_distr_->Scale( 1.0/ Data_distr_->Integral() );
119  }
120  float deltaMC = den->Integral();
121  if(fabs(1.0 - deltaMC) > 0.02 ) {
122  den->Scale(1.0/ den->Integral());
123  MC_distr_->Scale(1.0/ MC_distr_->Integral());
124  }
125 
126  weights_->Divide( den ); // so now the average weight should be 1.0
127 
128  std::cout << " Lumi/Pileup Reweighting: Computed Weights per In-Time Nint " << std::endl;
129 
130  for(int ibin = 1; ibin<NBins+1; ++ibin){
131  std::cout << " " << ibin-1 << " " << weights_->GetBinContent(ibin) << std::endl;
132  }
133 
134  FirstWarning_ = true;
135  OldLumiSection_ = -1;
136 }
137 
138 double LumiReWeighting::weight( int npv ) {
139  int bin = weights_->GetXaxis()->FindBin( npv );
140  return weights_->GetBinContent( bin );
141 }
142 
143 double LumiReWeighting::weight( float npv ) {
144  int bin = weights_->GetXaxis()->FindBin( npv );
145  return weights_->GetBinContent( bin );
146 }
147 
148 
149 
150 // This version of weight does all of the work for you, assuming you want to re-weight
151 // using the true number of interactions in the in-time beam crossing.
152 
153 
155 
156  // find provenance of event objects, just to check at the job beginning if there might be an issue
157 
158  if(FirstWarning_) {
159 
161  edm::ProcessHistory::const_iterator PHist_iter = PHist.begin();
162 
163  for(; PHist_iter<PHist.end() ;++PHist_iter) {
164  edm::ProcessConfiguration PConf = *(PHist_iter);
165  edm::ReleaseVersion Release = PConf.releaseVersion() ;
166  const std::string Process = PConf.processName();
167 
168  }
169  // SetFirstFalse();
170  FirstWarning_ = false;
171  }
172 
173  // get pileup summary information
174 
176  e.getByLabel(edm::InputTag("addPileupInfo"), PupInfo);
177 
178  std::vector<PileupSummaryInfo>::const_iterator PVI;
179 
180  int npv = -1;
181  for(PVI = PupInfo->begin(); PVI != PupInfo->end(); ++PVI) {
182 
183  int BX = PVI->getBunchCrossing();
184 
185  if(BX == 0) {
186  npv = PVI->getPU_NumInteractions();
187  continue;
188  }
189 
190  }
191 
192  if(npv < 0) std::cerr << " no in-time beam crossing found\n! " ;
193 
194  return weight(npv);
195 
196 }
197 
198 // Use this routine to re-weight out-of-time pileup to match the in-time distribution
199 // As of May 2011, CMS is only sensitive to a bunch that is 50ns "late", which corresponds to
200 // BunchCrossing +1. So, we use that here for re-weighting.
201 
203 
204 
205  //int Run = e.run();
206  int LumiSection = e.luminosityBlock();
207 
208  // do some caching here, attempt to catch file boundaries
209 
210  if(LumiSection != OldLumiSection_) {
211 
213  edm::ProcessHistory::const_iterator PHist_iter = PHist.begin();
214 
215  for(; PHist_iter<PHist.end() ;++PHist_iter) {
216  edm::ProcessConfiguration PConf = *(PHist_iter);
217  edm::ReleaseVersion Release = PConf.releaseVersion() ;
218  const std::string Process = PConf.processName();
219 
220  }
221  OldLumiSection_ = LumiSection;
222  }
223 
224  // find the pileup summary information
225 
227  e.getByLabel(edm::InputTag("addPileupInfo"), PupInfo);
228 
229  std::vector<PileupSummaryInfo>::const_iterator PVI;
230 
231  int npv = -1;
232  int npv50ns = -1;
233 
234  for(PVI = PupInfo->begin(); PVI != PupInfo->end(); ++PVI) {
235 
236  int BX = PVI->getBunchCrossing();
237 
238  if(BX == 0) {
239  npv = PVI->getPU_NumInteractions();
240  }
241 
242  if(BX == 1) {
243  npv50ns = PVI->getPU_NumInteractions();
244  }
245 
246  }
247 
248  // Note: for the "uncorrelated" out-of-time pileup, reweighting is only done on the 50ns
249  // "late" bunch (BX=+1), since that is basically the only one that matters in terms of
250  // energy deposition.
251 
252  if(npv < 0) {
253  std::cerr << " no in-time beam crossing found\n! " ;
254  std::cerr << " Returning event weight=0\n! ";
255  return 0.;
256  }
257  if(npv50ns < 0) {
258  std::cerr << " no out-of-time beam crossing found\n! " ;
259  std::cerr << " Returning event weight=0\n! ";
260  return 0.;
261  }
262 
263  int bin = weights_->GetXaxis()->FindBin( npv );
264 
265  double inTimeWeight = weights_->GetBinContent( bin );
266 
267  double TotalWeight = 1.0;
268 
269  TotalWeight = inTimeWeight;
270 
271  return TotalWeight;
272 
273 }
274 
275 #endif
collection_type::const_iterator const_iterator
const_iterator begin() const
edm::LuminosityBlockNumber_t luminosityBlock() const
Definition: EventBase.h:63
boost::shared_ptr< TH1 > MC_distr_
std::string const & processName() const
double weight(int npv)
double weightOOT(const edm::EventBase &e)
boost::shared_ptr< TFile > dataFile_
boost::shared_ptr< TFile > generatedFile_
virtual ProcessHistory const & processHistory() const =0
ReleaseVersion const & releaseVersion() const
boost::shared_ptr< TH1 > Data_distr_
std::string ReleaseVersion
Definition: ReleaseVersion.h:7
const_iterator end() const
bool getByLabel(InputTag const &, Handle< T > &) const
Definition: EventBase.h:92
boost::shared_ptr< TH1 > weights_
tuple cout
Definition: gather_cfg.py:121
std::string generatedFileName_