void estimateEfficiencyAndPurity(TH1* fraction,double cut,double& efficiency, double& purity, double& efferror, double& purerror, TFitResultPtr fitRes) { // efficiency loss is defined as the estimated signal below the cut over the estimated total signal double rangeLow, rangeHigh; TF1* expo = fraction->GetFunction("expo"); expo->GetRange(rangeLow, rangeHigh); double signalLoss = expo->Integral(0,cut)/fraction->GetBinWidth(1); double signalLossError = expo->IntegralError(0,cut,fitRes->GetParams(),fitRes->GetCovarianceMatrix().GetMatrixArray())/fraction->GetBinWidth(1); double signal_expopart = expo->Integral(cut,fraction->GetBinLowEdge(fraction->FindBin(rangeHigh)+1))/fraction->GetBinWidth(1); double signal_expopartError = expo->IntegralError(cut, fraction->GetBinLowEdge(fraction->FindBin(rangeHigh)+1),fitRes->GetParams(),fitRes->GetCovarianceMatrix().GetMatrixArray())/fraction->GetBinWidth(1); double signal_toppoart = fraction->Integral(fraction->FindBin(rangeHigh)+1,fraction->FindBin(1.)+1); efficiency = (signal_expopart+signal_toppoart)/(signal_expopart+signal_toppoart+signalLoss); efferror = TMath::Sqrt( pow(signalLoss,2)*pow(signal_expopartError,2) + pow(signal_toppoart+signal_expopart,2)*pow(signalLossError,2) )/pow(signal_expopart+signal_toppoart+signalLoss,2); // purity is defined as the signal above the cut (signal_expopart+signal_toppoart) // over the total data above that cut double data_kept = fraction->Integral(fraction->FindBin(cut),fraction->FindBin(1.)+1); double allBeforeRangeHigh = fraction->Integral(fraction->FindBin(cut),fraction->FindBin(rangeHigh)); purity = (signal_expopart+signal_toppoart)/data_kept; purerror = signal_expopartError/data_kept; if(purity > 1.){ std::cout << "#################################################"<<std::endl; std::cout << "cut: "<<cut<<" purity:" << purity <<std::endl; std::cout << "signalLoss: " << signalLoss << " signalExtrapolated: " << signal_expopart << " signalTop: " << signal_toppoart << std::endl; std::cout << "all b.r.h.: " << allBeforeRangeHigh << std::endl; std::cout << "total signal with expo: "<< (signal_expopart+signal_toppoart)<< std::endl; std::cout << "total signal integrating: "<< (allBeforeRangeHigh+signal_toppoart)<< std::endl; std::cout << "data kept: " << data_kept << std::endl; std::cout << "ratio: " << allBeforeRangeHigh/signal_expopart << std::endl; std::cout << "#################################################"<<std::endl; } // std::cout << "estimateEfficiencyAndPurity for cut=" << cut << std::endl; // std::cout << "signal: " << signalLoss << " " << signal_expopart << " " << signal_toppoart << std::endl; // std::cout << "data kept: " << data_kept << std::endl; // std::cout << "eff: " << efficiency << "+/- " << efferror << " pur: " << purity << " +/- " << purerror << std::endl; }
double extractLimitAtQuantile(TString inFileName, TString plotName, double d_quantile ){ TFile *f = TFile::Open(inFileName); TF1 *expoFit = new TF1("expoFit","[0]*exp([1]*(x-[2]))", rMin, rMax); TGraphErrors *limitPlot_ = new TGraphErrors(); /* bool done = false; */ if (_debug > 0) std::cout << "Search for upper limit using pre-computed grid of p-values" << std::endl; readAllToysFromFile(limitPlot_, f, d_quantile ); f->Close(); limitPlot_->Sort(); double minDist=1e3; int n= limitPlot_->GetN(); cout<<" Number of points in limitPlot_ : "<<n<<endl; if(n<=0) return 0; clsMin.first=0; clsMin.second=0; clsMax.first=0; clsMax.second=0; limit = 0; limitErr = 0; for (int i = 0; i < n; ++i) { double x = limitPlot_->GetX()[i], y = limitPlot_->GetY()[i]; //, ey = limitPlot_->GetErrorY(i); if (fabs(y-clsTarget) < minDist) { limit = x; minDist = fabs(y-clsTarget); } } int ntmp =0; for (int j = 0; j < n; ++j) { int i = n-j-1; double x = limitPlot_->GetX()[i], y = limitPlot_->GetY()[i], ey = limitPlot_->GetErrorY(i); if (y-3*ey >= clsTarget && ntmp<=2) { rMin = x; clsMin = CLs_t(y,ey); ntmp ++ ; } } ntmp =0; for (int i = 0; i < n; ++i) { double x = limitPlot_->GetX()[i], y = limitPlot_->GetY()[i], ey = limitPlot_->GetErrorY(i); if (y+3*ey <= clsTarget && ntmp<=2) { rMax = x; clsMax = CLs_t(y,ey); ntmp ++ ; } } if((clsMin.first==0 and clsMin.second==0) ) { rMin = limitPlot_->GetX()[0]; clsMin=CLs_t(limitPlot_->GetY()[0], limitPlot_->GetErrorY(0)); } if((clsMax.first==0 and clsMax.second==0)) { rMax = limitPlot_->GetX()[n-1]; clsMax=CLs_t(limitPlot_->GetY()[n-1], limitPlot_->GetErrorY(n-1)); } if (_debug > 0) std::cout << " after scan x ~ " << limit << ", bounds [ " << rMin << ", " << rMax << "]" << std::endl; limitErr = std::max(limit-rMin, rMax-limit); expoFit->SetRange(rMin,rMax); //expoFit.SetRange(limitPlot_->GetXaxis()->GetXmin(),limitPlot_->GetXaxis()->GetXmax()); //expoFit->SetRange(1.7,2.25); if (limitErr < std::max(rAbsAccuracy_, rRelAccuracy_ * limit)) { if (_debug > 1) std::cout << " reached accuracy " << limitErr << " below " << std::max(rAbsAccuracy_, rRelAccuracy_ * limit) << std::endl; /* done = true; */ } //if (!done) { // didn't reach accuracy with scan, now do fit if (1) { // didn't reach accuracy with scan, now do fit if (_debug) { std::cout << "\n -- HybridNew, before fit -- \n"; std::cout << "Limit: r" << " < " << limit << " +/- " << limitErr << " [" << rMin << ", " << rMax << "]\n"; std::cout<<"rMin="<<rMin<<" clsMin="<<clsMin.first<<", rMax="<<rMax<<" clsMax="<<clsMax.first<<endl; } expoFit->FixParameter(0,clsTarget); expoFit->SetParameter(1,log(clsMax.first/clsMin.first)/(rMax-rMin)); expoFit->SetParameter(2,limit); double rMinBound, rMaxBound; expoFit->GetRange(rMinBound, rMaxBound); limitErr = std::max(fabs(rMinBound-limit), fabs(rMaxBound-limit)); int npoints = 0; for (int j = 0; j < limitPlot_->GetN(); ++j) { if (limitPlot_->GetX()[j] >= rMinBound && limitPlot_->GetX()[j] <= rMaxBound) npoints++; } for (int i = 0, imax = 0; i <= imax; ++i, ++npoints) { limitPlot_->Sort(); limitPlot_->Fit(expoFit,(_debug <= 1 ? "QNR EX0" : "NR EXO")); if (_debug) { std::cout << "Fit to " << npoints << " points: " << expoFit->GetParameter(2) << " +/- " << expoFit->GetParError(2) << std::endl; } // only when both "cls+3e<0.05 and cls-3e>0.05" are satisfied, we require below ... // if ((rMin < expoFit->GetParameter(2)) && (expoFit->GetParameter(2) < rMax) && (expoFit->GetParError(2) < 0.5*(rMaxBound-rMinBound))) { // sanity check fit result limit = expoFit->GetParameter(2); limitErr = expoFit->GetParError(2); if (limitErr < std::max(rAbsAccuracy_, rRelAccuracy_ * limit)) break; // } } } if (limitPlot_) { TCanvas *c1 = new TCanvas("c1","c1"); limitPlot_->Sort(); limitPlot_->SetLineWidth(2); double rMinBound, rMaxBound; expoFit->GetRange(rMinBound, rMaxBound); if(bPlotInFittedRange){ limitPlot_->GetXaxis()->SetRangeUser(rMinBound, rMaxBound); limitPlot_->GetYaxis()->SetRangeUser(0.5*clsTarget, 1.5*clsTarget); } limitPlot_->Draw("AP"); expoFit->Draw("SAME"); TLine line(limitPlot_->GetX()[0], clsTarget, limitPlot_->GetX()[limitPlot_->GetN()-1], clsTarget); line.SetLineColor(kRed); line.SetLineWidth(2); line.Draw(); line.DrawLine(limit, 0, limit, limitPlot_->GetY()[0]); line.SetLineWidth(1); line.SetLineStyle(2); line.DrawLine(limit-limitErr, 0, limit-limitErr, limitPlot_->GetY()[0]); line.DrawLine(limit+limitErr, 0, limit+limitErr, limitPlot_->GetY()[0]); limitPlot_->SetTitle(";#mu;CLs"); c1->Print(plotName+".gif"); c1->Print(plotName+".root"); if(_debug)limitPlot_->Print("v"); } std::cout << "\n -- Hybrid New -- \n"; if(limit<0) { limit=0; cout<<" WARNING: fitted limit <0, need more toys and more points of signal strength"<<endl; } std::cout << "Limit: r" << " < " << limit << " +/- " << limitErr << " @ " << (1-clsTarget) * 100 << "% CL\n"; return limit; }