00001 #include "OpeTool.h"
00002 #include "SctData/RawScanResult.h"
00003 #include "Sct/LogicErrors.h"
00004 #include <boost/shared_ptr.hpp>
00005
00006 #include "TH2.h"
00007 #include "TH1.h"
00008 #include "TMath.h"
00009 #include "TFile.h"
00010
00011 using namespace SctData;
00012 using namespace Sct;
00013 using boost::shared_ptr;
00014
00015 namespace SctAnalysis {
00016
00017 OpeTool::OpeTool(){}
00018
00019 OpeTool::~OpeTool(){}
00020
00021 boost::shared_ptr<SctData::OpeResult> OpeTool::analyzeModule(const RawScanResult& raw){
00022
00023 unsigned nOPE = raw.nOccupancyPerEvent();
00024
00025 shared_ptr<OpeResult> result;
00026 if (nOPE==0) return result;
00027
00028 result = shared_ptr<OpeResult>(new OpeResult(raw.getUniqueID()));
00029
00030
00031 for (unsigned int ichip=0; ichip<nOPE; ++ichip) {
00032 const TH2D& chipHist = raw.getOccupancyPerEvent(ichip);
00033 const int biny = chipHist.GetNbinsY();
00034
00035 std::ostringstream newhistname;
00036 newhistname << raw.getClassName() << "." << raw.getUniqueID()
00037 << "_Chip" << ichip << "_Ope_Badness";
00038
00039 std::ostringstream newtitle;
00040 newtitle << "Chip" << ichip << "_Ope_Badness";
00041
00042 const char* c_name=newhistname.str().c_str();
00043 const char* c_title=newtitle.str().c_str();
00044
00045 int stupidBloomingNonConstBinY=biny;
00046 shared_ptr<TH1> badnessHist(new TH1D(c_name, c_title, stupidBloomingNonConstBinY, chipHist.GetYaxis()->GetXbins()->GetArray()));
00047
00048
00049 for(unsigned int iy=1; iy<biny+1; ++iy){
00050 std::ostringstream projectionName;
00051 projectionName << raw.getClassName() << "." << raw.getUniqueID()
00052 << "_Chip" << ichip << "_bin" << iy;
00053 shared_ptr<TH1D> proj(chipHist.ProjectionX(projectionName.str().c_str(),iy,iy,""));
00054
00055
00056
00057 badnessHist->SetBinContent(iy, fractionVariance(*proj));
00058 }
00059
00060 SctData::ChipOpeResult& chipResult=result->getChipResult(ichip);
00061
00062
00063 chipResult.hist=badnessHist;
00064 chipResult.badmax= badnessHist->GetMaximum();
00065 int badbin = badnessHist->GetMaximumBin();
00066 chipResult.threshold= badnessHist->GetBinCenter(badbin);
00067 }
00068
00069 return result;
00070 }
00071
00072 double OpeTool::fractionVariance(const TH1& data) {
00073
00074 double range = data.GetXaxis()->GetXmax() - data.GetXaxis()->GetXmin();
00075 double prob = (data.GetMean())/range;
00076
00077 double calcRMS = sqrt(range*prob*(1-prob));
00078
00079 double measRMS = data.GetRMS();
00080
00081
00082 if (calcRMS ==0) return 1;
00083 else return measRMS/calcRMS;
00084 }
00085
00086 double OpeTool::findChi2Binomial(const TH1& data) {
00087
00088 const unsigned int binx = data.GetNbinsX();
00089 unsigned int dof = 0;
00090 double trials = data.GetSumOfWeights();
00091 double range = data.GetXaxis()->GetXmax() - data.GetXaxis()->GetXmin();
00092 if (range==0.) throw Sct::LogicError("Range of histogram x axis was zero!",__FILE__,__LINE__);
00093 double prob = (data.GetMean())/range;
00094 std::cout << "OPE: Mean:" << data.GetMean()<< std::endl;
00095
00096 double chisq =0;
00097 double delta =0;
00098
00099 if (prob == 0) return 0;
00100 else {
00101
00102
00103
00104
00105 for (unsigned int ix=1; ix<binx+1; ix++){
00106
00107
00108 if (data.GetBinContent(ix) > 0) {
00109
00110
00111
00112 int start = static_cast<int>(ceil(data.GetBinLowEdge(ix)));
00113 int w = int(data.GetBinWidth(ix));
00114 if (w ==0) throw Sct::LogicError("Error- bin size truncates to zero!", __FILE__, __LINE__);
00115 std::cout << "Giving BinomialI " << prob << "range: " << start << " to " << start+w << std::endl;
00116 int irange=static_cast<int>(floor(range+0.5));
00117 double expect = (BinomialI(prob,irange,start) -
00118 BinomialI(prob,irange,start+w))*trials;
00119
00120 if (expect ==0) delta = data.GetBinContent(ix);
00121 else delta = (data.GetBinContent(ix)-expect)/sqrt(expect);
00122
00123 chisq += delta*delta;
00124 std::cout << "OPE: expect:" << expect<< " get: "<<data.GetBinContent(ix) << " delta:" << delta << std::endl;
00125 dof += 1;
00126 }
00127 }
00128
00129 dof = dof -1;
00130 if (dof == 0 ) return 0;
00131 else return sqrt(chisq)/(dof-1);
00132 }
00133 }
00134
00135
00136 double OpeTool::BinomialI(Double_t p, Int_t n, Int_t k)
00137 {
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 Double_t P = BetaIncomplete(p, Double_t(k), Double_t(n-k+1));
00150 return P;
00151 }
00152
00153 Double_t OpeTool::BetaIncomplete(Double_t x, Double_t a, Double_t b)
00154 {
00155
00156
00157
00158 Double_t bt;
00159 if ((x<0.0)||(x>1.0)) {
00160 throw Sct::LogicError("OpeTool::BetaIncomplete: X must between 0 and 1", __FILE__, __LINE__);
00161 return 0.0;
00162 }
00163 if ((x==0.0)||(x==1.0)) {
00164 bt=0.0;
00165 } else {
00166 bt = TMath::Power(x, a)*TMath::Power(1-x, b)/Beta(a, b);
00167 }
00168 if (x<(a+1)/(a+b+2)) {
00169 return bt*BetaCf(x, a, b)/a;
00170 }
00171 else {
00172 return (1 - bt*BetaCf(1-x, b, a)/b);
00173 }
00174 }
00175
00176 Double_t OpeTool::Beta(Double_t p, Double_t q)
00177 {
00178
00179
00180 return TMath::Exp(TMath::LnGamma(p)+TMath::LnGamma(q)-TMath::LnGamma(p+q));
00181 }
00182
00183 Double_t OpeTool::BetaCf(Double_t x, Double_t a, Double_t b)
00184 {
00185
00186
00187
00188 Int_t itmax = 500;
00189 Double_t eps = 3.e-14;
00190 Double_t fpmin = 1.e-30;
00191
00192 Int_t m, m2;
00193 Double_t aa, c, d, del, qab, qam, qap;
00194 Double_t h;
00195 qab = a+b;
00196 qap = a+1.0;
00197 qam = a-1.0;
00198 c = 1.0;
00199 d = 1.0 - qab*x/qap;
00200 if (TMath::Abs(d)<fpmin) d=fpmin;
00201 d=1.0/d;
00202 h=d;
00203 for (m=1; m<=itmax; m++) {
00204 m2=m*2;
00205 aa = m*(b-m)*x/((qam+ m2)*(a+m2));
00206 d = 1.0 +aa*d;
00207 if(TMath::Abs(d)<fpmin) d = fpmin;
00208 c = 1 +aa/c;
00209 if (TMath::Abs(c)<fpmin) c = fpmin;
00210 d=1.0/d;
00211 h*=d*c;
00212 aa = -(a+m)*(qab +m)*x/((a+m2)*(qap+m2));
00213 d=1.0+aa*d;
00214 if(TMath::Abs(d)<fpmin) d = fpmin;
00215 c = 1.0 +aa/c;
00216 if (TMath::Abs(c)<fpmin) c = fpmin;
00217 d=1.0/d;
00218 del = d*c;
00219 h*=del;
00220 if (TMath::Abs(del-1)<=eps) break;
00221 }
00222 if (m>itmax) {
00223 throw Sct::LogicError("OpeTool::BetaCf: a or b too big, or itmax too small", __FILE__, __LINE__);
00224 }
00225 return h;
00226 }
00227 }