00001
00002
00003 #ifndef __TPILEUPREWEIGHTING__
00004 #define __TPILEUPREWEIGHTING__
00005
00016
00017
00018
00019
00020
00021
00022 #include "TNamed.h"
00023 #include <TFile.h>
00024 #include <TString.h>
00025 #include "TVectorD.h"
00026 #include <map>
00027 #include <vector>
00028 #include <TRandom3.h>
00029
00030
00031 #include <iostream>
00032 #include <stdexcept>
00033
00034 #include "TH1.h"
00035
00036
00037 class TH1;
00038 class TH1D;
00039 class TH2D;
00040 class TTree;
00041 class TFile;
00042
00043
00044
00045 namespace CP {
00046 class TPileupReweighting : public TNamed {
00047
00048 public:
00050 TPileupReweighting(const char* name="TPileupReweighting");
00051
00053 ~TPileupReweighting();
00054
00055
00056 public:
00057
00059 Int_t UsePeriodConfig(const TString& configName);
00061 Int_t SetBinning(Int_t nbinsx, Double_t* xbins, Int_t nbinsy=0, Double_t* ybins=0);
00062 Int_t SetUniformBinning(Int_t nbinsx, Double_t xlow, Double_t xup, Int_t nbinsy=0, Double_t ylow=0, Double_t yup=0);
00063 Int_t SetBinning(TH1* hist);
00064
00067 void SetDefaultChannel(Int_t channel, Int_t mcRunNumber=-1);
00068 Int_t GetDefaultChannel(Int_t mcRunNumber=-1);
00069
00071 Double_t GetIntegratedLumi(const TString& trigger="");
00073 inline Double_t GetNumberOfEvents(Int_t channel) {
00074 Period* global = m_periods[-1];
00075 if(!global) return 0;
00076 if(global->numberOfEntries.find(channel)==global->numberOfEntries.end()) {
00077 Error("GetNumberOfEvents", "Unknown channel: %d",channel);
00078 return 0;
00079 }
00080 return global->numberOfEntries[channel];
00081 }
00082 inline Double_t GetSumOfEventWeights(Int_t channel) {
00083 Period* global = m_periods[-1];
00084 if(!global) return 0;
00085 if(global->sumOfWeights.find(channel)==global->sumOfWeights.end()) {
00086 Error("GetSumOfEventWeights", "Unknown channel: %d",channel);
00087 return 0;
00088 }
00089 return global->sumOfWeights[channel];
00090 }
00091
00093 void RemapPeriod(Int_t periodNumber1, Int_t periodNumber2);
00094
00095
00097 Double_t GetIntegratedLumiFraction(Int_t periodNumber, UInt_t start, UInt_t end);
00099 Double_t GetIntegratedLumiFraction(Int_t periodNumber, Double_t mu, UInt_t start, UInt_t end);
00100
00102 inline Double_t GetIntegratedLumi(UInt_t start, UInt_t end) { return GetIntegratedLumi(-1,start,end); }
00104 Double_t GetIntegratedLumi(Int_t periodNumber, UInt_t start, UInt_t end);
00105
00107 Double_t GetLumiBlockIntegratedLumi(Int_t runNumber, UInt_t lb);
00108
00110 Float_t GetLumiBlockMu(Int_t runNumber, UInt_t lb);
00111
00112
00113
00114
00116 inline void DisableWarnings(Bool_t in) { m_SetWarnings = !in;}
00118 inline void EnableDebugging(Bool_t in) { m_debugging = in;}
00119
00122 inline void SetUnrepresentedDataAction(Int_t action, Double_t tolerance=0.05) {
00123 if(action<0 || action>3) {
00124 Fatal("SetUnrepresentedDataAction","Set action=%d - I'm afraid I can't let you do that, Dave",action);
00125 throw std::runtime_error("Throwing 2001");
00126 }
00127 m_unrepresentedDataAction=action;
00128 m_unrepDataTolerance=tolerance;
00129 }
00131 Double_t GetUnrepresentedDataFraction(Int_t periodNumber,Int_t channel);
00132 inline Float_t GetUnrepresentedDataWeight(Int_t periodNumber,Int_t channel) {
00133 if(m_unrepresentedDataAction!=2) {
00134 Warning("GetUnrepresentedDataWeight","You should not be applying this weight unless the UnrepresentedDataAction=2");
00135 }
00136 return 1./(1. - GetUnrepresentedDataFraction(periodNumber,channel));
00137 }
00138
00139
00140
00141 Bool_t IsUnrepresentedData(Int_t runNumber, Float_t x, Float_t y=0.);
00142
00144 inline void IgnoreConfigFilePeriods(Bool_t in) { m_ignoreFilePeriods=in; }
00145
00147 Int_t AddPeriod(Int_t periodNumber, UInt_t start, UInt_t end);
00149 Int_t GetFirstFoundPeriodNumber(UInt_t runNumber);
00150
00151
00152
00154 inline void SetDataScaleFactors(Float_t x,Float_t y=1.) { m_dataScaleFactorX=x;m_dataScaleFactorY=y; }
00155 inline void SetMCScaleFactors(Float_t x,Float_t y=1.) { m_mcScaleFactorX=x;m_mcScaleFactorY=y;}
00156
00157
00158
00159
00160
00161
00162 Int_t AddConfigFile(const TString& fileName);
00163 Int_t AddLumiCalcFile(const TString& fileName, const TString& trigger="None");
00164 Int_t AddMetaDataFile(const TString& fileName,const TString& channelBranchName="mc_channel_number");
00165
00167 Bool_t RemoveChannel(int chanNum);
00168
00172 Int_t Initialize();
00173
00174
00175
00176
00177
00178 Float_t GetCombinedWeight(Int_t periodNumber, Int_t channelNumber,Float_t x,Float_t y=0.);
00179 Float_t GetPeriodWeight(Int_t periodNumber, Int_t channelNumber);
00180 Float_t GetPrimaryWeight(Int_t periodNumber, Int_t channelNumber,Float_t x);
00181 Float_t GetSecondaryWeight(Int_t periodNumber, Int_t channelNumber,Float_t x,Float_t y);
00182
00183
00184
00185
00186 Double_t GetMetaData(const TString& metadataName,Int_t channelNumber) {
00187 if(m_metadata.find(metadataName)==m_metadata.end()) {
00188 Error("GetMetaData","Metadata %s not known",metadataName.Data());
00189 return 0;
00190 }
00191 if(m_metadata[metadataName].find(channelNumber)==m_metadata[metadataName].end()) {
00192 Error("GetMetaData","Metadata %s not known in channel %d",metadataName.Data(), channelNumber);
00193 return 0;
00194 }
00195 return m_metadata[metadataName][channelNumber];
00196 }
00198 TTree* GetMetaDataTree();
00199 Int_t GenerateMetaDataFile(const TString& fileName,const TString& channelBranchName="mc_channel_number");
00200
00201
00202
00203
00204
00205 Int_t Fill(Int_t runNumber,Int_t channelNumber,Float_t w,Float_t x, Float_t y=0.);
00206 Int_t WriteToFile(const TString& filename="");
00207 Int_t WriteToFile(TFile* outFile);
00208
00209
00210
00211
00212
00213 ULong64_t GetPRWHash(Int_t periodNumber, Int_t channelNumber, Float_t x, Float_t y=0.);
00214 Bool_t MakeWeightTree(TString channelNumbers, TString outFile, TString hashBranch="PRWHash", TString weightBranch="PileupWeight");
00215
00216
00217
00218
00219
00220 void SetRandomSeed(int seed) {m_random3->SetSeed(seed);}
00221 int GetRandomSeed() {return m_random3->GetSeed();}
00224 UInt_t GetRandomRunNumber(Int_t mcRunNumber);
00226 UInt_t GetRandomRunNumber(Int_t mcRunNumber, Double_t mu);
00228 Int_t GetRandomPeriodNumber(Int_t mcRunNumber);
00230 UInt_t GetRandomLumiBlockNumber(UInt_t runNumber);
00231
00232
00233
00234
00235
00236 Int_t Merge(TCollection *coll);
00237
00238
00239
00240
00241
00242
00243 TH1* GetInputHistogram(Int_t channelNumber, Int_t periodNumber) {
00244 if(m_periods.find(periodNumber)==m_periods.end()||
00245 m_periods[periodNumber]->inputHists.find(channelNumber)==m_periods[periodNumber]->inputHists.end()) {
00246 return 0;
00247 }
00248 return m_periods[periodNumber]->inputHists[channelNumber];
00249 }
00250
00251 TH1D* GetPrimaryDistribution(Int_t channelNumber, Int_t periodNumber) {
00252 if(m_periods.find(periodNumber)==m_periods.end()||
00253 m_periods[periodNumber]->primaryHists.find(channelNumber)==m_periods[periodNumber]->primaryHists.end()) {
00254 return 0;
00255 }
00256 return m_periods[periodNumber]->primaryHists[channelNumber];
00257 }
00258
00259 TH1D* GetPrimaryTriggerDistribution(const TString& trigger, Int_t periodNumber, long triggerBits) {
00260 if(m_triggerObjs.find(trigger)==m_triggerObjs.end() || m_triggerObjs[trigger]->triggerHists.find(periodNumber) ==m_triggerObjs[trigger]->triggerHists.end() ||
00261 m_triggerObjs[trigger]->triggerHists[periodNumber].find(triggerBits) == m_triggerObjs[trigger]->triggerHists[periodNumber].end()) return 0;
00262
00263
00264
00265
00266
00267 return m_triggerObjs[trigger]->triggerHists[periodNumber][triggerBits];
00268 }
00269
00271 Double_t GetDataWeight(Int_t runNumber, TString trigger, Double_t x);
00272 Double_t GetDataWeight(Int_t runNumber, TString trigger);
00273
00274
00275
00276 Bool_t IsInitialized() { return m_isInitialized; }
00277
00278 Int_t AddDistribution(TH1* hist, Int_t runNumber, Int_t channelNumber);
00279
00281 void ResetCountingMode() { m_countingMode=true; }
00282
00283
00284 void SetParentTool(TPileupReweighting* tool) { m_parentTool = tool; }
00285
00286 Float_t GetDataScaleFactor() const { return m_dataScaleFactorX; }
00287
00288 void SetTriggerBit(const TString& trigger, bool in=true) { m_triggerPassBits[trigger]=in; }
00289 void ResetTriggerBits() { m_triggerPassBits.clear(); }
00290
00291 double GetRunAverageMu(int run) { return m_runs[run].inputHists["None"]->GetMean(); }
00292
00293 protected:
00294 virtual bool runLbnOK(Int_t , Int_t ) { return true; }
00295 virtual bool passTriggerBeforePrescale(const TString& trigger) const {
00296 if(m_triggerPassBits.size()==0) return true;
00297 try {
00298 return m_triggerPassBits.at(trigger);
00299 } catch(...) { return true; }
00300 }
00301 std::map<TString, bool> m_triggerPassBits;
00302
00303
00304 Int_t GetNearestGoodBin(Int_t thisMCRunNumber, Int_t bin);
00305 Int_t IsBadBin(Int_t thisMCRunNumber, Int_t bin);
00306
00307
00308 TH1* CloneEmptyHistogram(Int_t runNumber, Int_t channelNumber);
00310 void normalizeHistogram(TH1* histo);
00311 void AddDistributionTree(TTree *tree, TFile *file);
00312
00313
00314 void CalculatePrescaledLuminosityHistograms(const TString& trigger);
00315
00316
00317 TPileupReweighting* m_parentTool;
00318 Bool_t m_SetWarnings;
00319 Bool_t m_debugging;
00320 Bool_t m_countingMode;
00321 Int_t m_unrepresentedDataAction;
00322 Bool_t m_isInitialized;Bool_t m_lumiVectorIsLoaded;
00323 Float_t m_dataScaleFactorX;Float_t m_dataScaleFactorY;
00324 Float_t m_mcScaleFactorX;Float_t m_mcScaleFactorY;
00325 Int_t m_nextPeriodNumber;
00326 Bool_t m_ignoreFilePeriods;
00327 TTree *m_metadatatree;
00328 Double_t m_unrepDataTolerance;
00329 Bool_t m_doGlobalDataWeight;
00330 Int_t m_lumicalcRunNumberOffset;
00331
00333 std::map<TString,std::vector<TString> > m_lumicalcFiles;
00334
00335
00336
00337
00338
00339
00340
00342 TH1* m_emptyHistogram;
00343
00344
00345
00347 std::map<TString, std::map<Int_t, Double_t> > m_metadata;
00348
00349 public:
00350 struct CompositeTrigger {
00351 int op;
00352 CompositeTrigger* trig1;
00353 CompositeTrigger* trig2;
00354 TString val;
00355 std::vector<TString> subTriggers;
00356 CompositeTrigger() : op(0),trig1(0),trig2(0),val("") { }
00357 ~CompositeTrigger() { if(trig1) delete trig1; if(trig2) delete trig2; }
00358 double eval(std::map<TString, std::map<Int_t, std::map<Int_t, Float_t> > >& m, int run, int lbn, const TPileupReweighting* tool) {
00359 switch(op) {
00360 case 0: if(m[val][run].find(lbn)==m[val][run].end() || !m[val][run][lbn] || !tool->passTriggerBeforePrescale(val)) return 0;
00361 return 1./m[val][run][lbn];
00362 case 1: return 1. - (1. - trig1->eval(m,run,lbn,tool))*(1.-trig2->eval(m,run,lbn,tool));
00363 case 2: return trig1->eval(m,run,lbn,tool)*trig2->eval(m,run,lbn,tool);
00364 default: return 1;
00365 }
00366 }
00367 void getTriggers(std::vector<TString>& s) {
00368 if(trig1==0&&trig2==0&&val.Length()>0) s.push_back(val);
00369 else { trig1->getTriggers(s); trig2->getTriggers(s); }
00370 }
00371
00372 long getBits(const TPileupReweighting* tool) {
00373 long out(0);
00374 for(uint i=0;i<subTriggers.size();i++) out += (tool->passTriggerBeforePrescale(subTriggers[i]) << i);
00375 return out;
00376 }
00377
00378 std::map<int, std::map<long, TH1D*> > triggerHists;
00379
00380 };
00381 protected:
00382
00383 std::map<TString, CompositeTrigger*> m_triggerObjs;
00384
00385 CompositeTrigger* makeTrigger(const TString& s);
00386 void calculateHistograms(CompositeTrigger* trigger);
00387
00388 public:
00389 inline void PrintPeriods() { for(auto p : m_periods) {std::cout << p.first << " -> "; p.second->print("");} }
00390 struct Period {
00391 Period(Int_t _id, UInt_t _start, UInt_t _end, Int_t _defaultChannel) : id(_id),start(_start),end(_end),defaultChannel(_defaultChannel) {};
00392 Int_t id;
00393 UInt_t start;
00394 UInt_t end;
00395 Int_t defaultChannel;
00396 std::map<Int_t, Int_t> inputBinRedirect;
00397 std::map<Int_t, Double_t> unrepData;
00398 std::vector<Period*> subPeriods;
00399 std::vector<UInt_t> runNumbers;
00400 std::map<Int_t, TH1*> inputHists;
00401 std::map<Int_t, Double_t> sumOfWeights;
00402 std::map<Int_t, Int_t> numberOfEntries;
00403 std::map<Int_t, TH1D*> primaryHists;
00404 std::map<Int_t, TH2D*> secondaryHists;
00405
00406 bool contains(unsigned int runNumber) {
00407 if(runNumber >= start && runNumber <= end) return true;
00408 for(auto p : subPeriods) if(p->contains(runNumber)) return true;
00409 return false;
00410 };
00411 void SetDefaultChannel(Int_t channel) {
00412 defaultChannel=channel;
00413 for(auto p : subPeriods) p->SetDefaultChannel(channel);
00414 };
00415 void print(const char* prefix) {
00416 std::cout << prefix << id << "[" << start << "," << end << "] : ";
00417 for(auto hist : inputHists) std::cout << hist.first << " , ";
00418 std::cout << std::endl;
00419 for(auto p : subPeriods) p->print(TString::Format(" %s",prefix).Data()); };
00420 };
00421 struct Run {
00422 std::map<TString,TH1*> inputHists;
00423 std::map<Int_t,Double_t> badBins;
00424 Double_t lumi;
00425 std::map<UInt_t, std::pair<Double_t,Double_t> > lumiByLbn;
00426 TH1D* muDist;
00427 };
00428 protected:
00429 std::map<Int_t, Period*> m_periods;
00430 std::map<UInt_t, Run> m_runs;
00431
00432 std::map<Int_t, Double_t> unrepDataByChannel;
00433
00434 std::string m_prwFilesPathPrefix;
00435
00436
00437
00438
00439
00440 TRandom3 *m_random3;
00441
00442 Bool_t m_ignoreBadChannels;
00443 Bool_t m_useMultiPeriods = true;
00444
00445 public:
00446
00447 inline void CopyProperties(const TPileupReweighting* in) {
00448 m_prwFilesPathPrefix = in->m_prwFilesPathPrefix;
00449 m_ignoreBadChannels = in->m_ignoreBadChannels;
00450 m_unrepresentedDataAction = in->m_unrepresentedDataAction;
00451 m_unrepDataTolerance= in->m_unrepDataTolerance;
00452 }
00453
00454 ClassDef(TPileupReweighting,0)
00455
00456
00457 };
00458
00459 }
00460
00461 #endif