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, 3 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

# Content
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