ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/VHbb/python/myutils/Ratio.C
Revision: 1.1
Committed: Wed Jan 16 16:35:40 2013 UTC (12 years, 4 months ago) by peller
Content type: text/plain
Branch: MAIN
CVS Tags: lhcp_UnblindFix, hcp_Unblind, lhcp_11April, LHCP_PreAppFixAfterFreeze, LHCP_PreAppFreeze, workingVersionAfterHCP, HEAD
Log Message:
reorganized the whole repository. Macros im myutils, config files in subdirectories. Config file split in parts. Path config file restructured. Moved all path options to the path config. Changed the code accordingly.

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