ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/VHbb/python/Ratio.C
Revision: 1.1
Committed: Fri May 25 12:59:11 2012 UTC (12 years, 11 months ago) by peller
Content type: text/plain
Branch: MAIN
CVS Tags: hcpApproval, HCP_unblinding, hcpPreApp, hcpPreAppFreeze, ICHEP8TeV, ichep8TeV, AN-12-181-7TeV_patch1, AN-12-181-7TeV
Log Message:
added plotting tool

File Contents

# User Rev Content
1 peller 1.1 #ifndef GENERIC_PLOTTER_H
2     #define GENERIC_PLOTTER_H
3    
4     #include <stdio.h>
5     #include <iostream>
6     #include <vector>
7     #include <string>
8     #include <TLegend.h>
9     #include <TAxis.h>
10     #include <TH1.h>
11     #include <math.h>
12    
13     struct coolRatio {
14     //coolRatio() :
15    
16     // User must clean up the created ratio histograms.
17     //TH1 make_rebinned_ratios(TH1* theHist, TH1* theReference, double maxUncertainty);
18     //static double ratioError2(double numerator, double numeratorError2, double denominator, double denominatorError2);
19    
20    
21    
22     TH1* make_rebinned_ratios(TH1* theHist, TH1* theReference, double maxUncertainty, bool useReferenceError = false, const int number = 0)
23     {
24     std::vector<TH1*> hist;
25     std::vector<TH1*> ratios;
26     hist.push_back(theHist);
27     hist.push_back(theReference);
28     const int reference = 1;
29    
30     const int numHistograms = int(hist.size());
31     assert(numHistograms >= 2);
32     ratios.clear();
33    
34     // Find nonzero range
35     const TH1* denominator = hist[reference];
36     const TAxis* rebinAxis = denominator->GetXaxis();
37     const int binBound = rebinAxis->GetNbins() + 1; // overflow
38     int firstBin = 0;
39     for (bool allEmpty = true; allEmpty && ++firstBin < binBound;)
40     for (int i = 0; allEmpty && i < numHistograms; ++i)
41     allEmpty &= (hist[i] == 0 || hist[i]->GetBinContent(firstBin) == 0);
42     int lastBin = binBound;
43     for (bool allEmpty = true; allEmpty && --lastBin > 0;)
44     for (int i = 0; allEmpty && i < numHistograms; ++i)
45     allEmpty &= (hist[i] == 0 || hist[i]->GetBinContent(lastBin) == 0);
46     if (lastBin <= firstBin) return theHist; // no content
47    
48    
49     // Partition bins in range
50     std::vector<double> binEdges;
51     if (firstBin > 1) binEdges.push_back(rebinAxis->GetBinLowEdge(1));
52     double previousEdge = rebinAxis->GetBinLowEdge(firstBin);
53     std::vector<double> zeros (numHistograms,0);
54     std::vector<std::vector<double> > sumNum (1, zeros);
55     std::vector<std::vector<double> > sumNumErr2(1, zeros);
56     std::vector<double> sumDen (1, 0);
57     std::vector<double> sumDenErr2(1, 0);
58    
59     ////std::cout << std::endl << rebinAxis->GetXmin() << " ( " << rebinAxis->GetBinLowEdge(firstBin) << " , ";
60     ////std::cout << rebinAxis->GetBinUpEdge(lastBin) << " ) " << rebinAxis->GetXmax() << std::endl;
61     for (int bin = firstBin; bin <= lastBin; ++bin) {
62     // Find a filled block
63     sumDen .back() += denominator->GetBinContent(bin);
64     sumDenErr2.back() += pow(denominator->GetBinError(bin), 2);
65     bool aboveThreshold = (sumDen.back() != 0); // denominator must not vanish
66    
67     for (int iHist = 0; iHist < numHistograms; ++iHist) {
68     if (iHist == reference) continue;
69     if (hist[iHist] == 0) continue;
70     double num = hist[iHist]->GetBinContent(bin);
71     double numErr2 = pow(hist[iHist]->GetBinError(bin), 2);
72     sumNum .back()[iHist] += num;
73     sumNumErr2.back()[iHist] += numErr2;
74    
75     const double error2 = ratioError2(sumNum.back()[iHist],sumNumErr2.back()[iHist],sumDen.back(),sumDenErr2.back(),useReferenceError);
76     aboveThreshold &= (sqrt(error2) * sumDen.back() < maxUncertainty * sumNum.back()[iHist]);
77     if (maxUncertainty > 100.) aboveThreshold = true;
78     } // end loop over histograms
79    
80     if (aboveThreshold && bin < lastBin) {
81     //std::cout << " + [" << previousEdge << " , " << rebinAxis->GetBinUpEdge(bin) << "] = " << sumDen.back() << std::endl;
82     binEdges.push_back(previousEdge);
83     sumNum .push_back(zeros); sumNumErr2.push_back(zeros);
84     sumDen .push_back(0); sumDenErr2.push_back(0);
85     previousEdge = rebinAxis->GetBinUpEdge(bin);
86     }
87     } // end loop over bins in reference
88    
89     if (binEdges.empty() || binEdges.back()!=previousEdge) binEdges.push_back(previousEdge);
90     binEdges.push_back(rebinAxis->GetBinUpEdge (lastBin ));
91     if (lastBin < binBound - 1) binEdges.push_back(rebinAxis->GetBinLowEdge(binBound));
92    
93     ////for (unsigned i=0; i<binEdges.size(); ++i) std::cout << " " << binEdges[i]; std::cout << std::endl;
94     ////for (unsigned i=0; i<sumDen.size(); ++i) std::cout << " " << sumDen[i]; std::cout << std::endl;
95    
96    
97     // Make ratios according to new bin edges
98     ratios.reserve(numHistograms - 1);
99     const unsigned numBins = binEdges.size() - 1u;
100     const unsigned numContent = sumNum.size();
101     assert(numBins >= numContent);
102    
103    
104     for (int iHist = 0; iHist < numHistograms; ++iHist) {
105     if (iHist == reference) continue;
106     if (hist[iHist] == 0) continue;
107     TH1* ratio = static_cast<TH1*>(hist[iHist]->Clone("Ratio"));
108     TH1* refError = static_cast<TH1*>(hist[iHist]->Clone("RefError"));
109     ratio->Reset ();
110     ratio->SetBins (numBins, &(binEdges[0]));
111     refError->Reset ();
112     refError->SetBins (numBins, &(binEdges[0]));
113     if (ratio->GetSumw2N() == 0) ratio->Sumw2();
114     if (refError->GetSumw2N() == 0) refError->Sumw2();
115     TArrayD* error2 = ratio->GetSumw2();
116     TArrayD* refError2 = refError->GetSumw2();
117     for (unsigned index = 0, bin = 1 + (firstBin > 1); index < numContent; ++index, ++bin) {
118     if (sumDen[index] == 0) continue;
119     ratio ->SetBinContent(bin, sumNum[index][iHist] / sumDen[index]);
120     error2->SetAt(ratioError2(sumNum[index][iHist],sumNumErr2[index][iHist],sumDen[index],sumDenErr2[index],useReferenceError), bin);
121     if (sumNum[index][iHist] == 0 && sumDen[index] == 0){
122     refError ->SetBinContent(bin, 0.);
123     refError2->SetAt(0., bin);
124     }
125     else{
126     refError ->SetBinContent(bin, 1.);
127     refError2->SetAt(ratio1Error2(sumDen[index],sumDenErr2[index]), bin);
128     }
129     } // end loop over bins
130     ratios.push_back(ratio);
131     ratios.push_back(refError);
132     } // end loop over histograms
133     return ratios[number];
134     }
135    
136     private:
137     double ratio1Error2(double denominator, double denominatorError2)
138     {
139     if (denominator == 0) return 0;
140     return (denominatorError2/denominator/denominator );
141     }
142     double ratioError2(double numerator, double numeratorError2, double denominator, double denominatorError2,bool useDenominatorError=true)
143     {
144     if (numerator == 0) return 0;
145     if (denominator == 0) return 0;
146     if (!useDenominatorError) denominatorError2 = 0;
147     const double ratio = numerator / denominator;
148     return ratio*ratio*( numeratorError2/numerator/numerator + denominatorError2/denominator/denominator );
149     }
150    
151     };
152    
153     #endif