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