ATLAS Offline Software
Loading...
Searching...
No Matches
RootFitTEff.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
10
13#include <TH1.h>
14#include <TF1.h>
15#include <TEfficiency.h>
16#include <TGraphAsymmErrors.h>
17#include <TClass.h>
18#include <ers/ers.h>
19#include <TROOT.h>
20#include <dqm_core/AlgorithmManager.h>
21#include <cmath>
22
23namespace
24{
25 dqm_algorithms::RootFitTEff fermi_fit( "fermi" );
26 dqm_algorithms::RootFitTEff erf_fit( "erf" );
27 dqm_algorithms::RootFitTEff flat_fit( "flat" );
28}
29
31 : m_name( name )
32{
33
34 if (m_name == "fermi"){
35 m_func = std::make_unique<TF1> ( "fermi","[0]/(1+exp(([1]-x)/[2]))" );
36 }
37 if (m_name == "erf"){
38 m_func = std::make_unique<TF1> ( "erf","[0]*TMath::Erf((x-[1])/(sqrt(2.)*[2]))" );
39 }
40 if (m_name == "flat"){
41 m_func = std::make_unique<TF1> ( "flat","[0]" );
42 }
43 dqm_core::AlgorithmManager::instance().registerAlgorithm( "Simple_"+name +"_Fit_TEff", this );
44}
45
47{
48 // totally defeats the purpose of unique_ptr, but fixes a segfault in 5.34 ...
49 (void)m_func.release();
50}
51
57
58
59dqm_core::Result *
60dqm_algorithms::RootFitTEff::execute( const std::string & name,
61 const TObject & object,
62 const dqm_core::AlgorithmConfig & config )
63{
64
65 //std::cout<<"ROOTFITTEFF = calling rootfit with name "<<name<<std::endl;
66 const TEfficiency * eff;
67 if(object.IsA()->InheritsFrom( "TEfficiency" ))
68 {
69 eff = static_cast<const TEfficiency*>(&object);
70 }
71 else {
72 throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TEfficiency" );
73 }
74
75 //std::cout<<"ROOTFITTEFF = trying to get parameters"<<std::endl;
76 Axis_t xmin = dqm_algorithms::tools::GetFirstFromMap( "xmin", config.getParameters(), eff->GetTotalHistogram()->GetXaxis()->GetXmin());
77 Axis_t xmax = dqm_algorithms::tools::GetFirstFromMap( "xmax", config.getParameters(), eff->GetTotalHistogram()->GetXaxis()->GetXmax());
78
79 Axis_t ymin = dqm_algorithms::tools::GetFirstFromMap( "ymin", config.getParameters(), eff->GetTotalHistogram()->GetYaxis()->GetXmin());
80 Axis_t ymax = dqm_algorithms::tools::GetFirstFromMap( "ymax", config.getParameters(), eff->GetTotalHistogram()->GetYaxis()->GetXmax());
81
82 double xaxismean = (xmax + xmin)/2.;
83 double xdiff = xmax - xmin;
84 double ydiff = ymax - ymin;
85
86
87 const double minpoint = dqm_algorithms::tools::GetFirstFromMap( "MinPoint", config.getParameters(), -1);
88 const bool verbose = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap( "Verbose", config.getParameters(), 0));
89 const double minSig = dqm_algorithms::tools::GetFirstFromMap( "MinSignificance", config.getParameters(), 0);
90 const bool improve = static_cast<bool>(dqm_algorithms::tools::GetFirstFromMap( "ImproveFit", config.getParameters(), 0));
91
92 //std::cout << "verbose " << verbose
93 //<< " draw " << draw
94 //<< " lf " << lf << std::endl;
95 //std::cout<<"ROOTFITTEFF = trying to get num points"<<std::endl;
96 const TH1* eff_hist = eff->GetTotalHistogram();
97 const Int_t eff_points = eff_hist->GetNbinsX();
98 if (eff_points < minpoint || eff_points==0) {
99 if(verbose)std::cout << name << " number of points are too small " << eff_points << std::endl;
100 dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined);
101 result->tags_["InsufficientN"] = eff_points;
102 return result;
103 }
104 if(verbose)std::cout << name << " enough number of points " << eff_points << std::endl;
105 //std::cout<<"ROOTFITTEFF = trying to get axes"<<std::endl;
106 const TAxis *x = eff_hist->GetXaxis();
107 int nbins = x->GetNbins();
108 double high = x->GetBinUpEdge(nbins);
109 double low = x->GetBinUpEdge(0);
110
111
112 if ( xmin>high || xmin<low || xmax>high || xmax<low) {
113 throw dqm_core::BadConfig( ERS_HERE, name, "xmin and/or xmax value not in eff bin range" );
114 }
115
116 std::string option;
117 //Always set option end to avoid making graphics object and drawing it.
118 //draw fit curve if DrawFitCurve == 1.0
119 if (verbose){
120 //if( draw == 1.0 ) option = "";
121 //else option="N";
122 option="N";
123 } else {
124 //if( draw == 1.0 ) option = "Q";
125 //else option = "QN";
126 option = "QN";
127 }
128
129 //Use Minos technique as recommended for better error calculation, if errors are important:
130 // if both minos and improve are specified ("EM"), minos is used by ROOT automatically
131 if ( minSig != 0 ) option += "E";
132 if ( improve ) option += "M";
133 //show histo name and fit option for verbose mode
134 if( verbose ){
135 std::cout <<" eff name " << eff->GetName() << std::endl;
136 std::cout <<" fit option " << option << std::endl;
137 }
138 //std::cout<<"ROOTFITTEFF = trying to do fits"<<std::endl;
139 if (m_name == "fermi") {
140 if(verbose)std::cout << "set "<<name<< " parameters" << std::endl;
141 m_func->SetParameter(0,ymax*0.9);
142 m_func->SetParameter(1,xaxismean);
143 m_func->SetParameter(2,xdiff/50.);
144 m_func->SetParNames("Plateau","Threshold","Resolution");
145
146 m_func->SetParLimits(0, ymin - 0.1 * ydiff, ymax + 0.1 * ydiff );
147 m_func->SetParLimits(1, xmin, xmax );
148 m_func->SetParLimits(2, 0., xdiff/4. );
149 }
150 else if(m_name == "erf") {
151 if(verbose)std::cout << "set "<<name<< " parameters" << std::endl;
152 m_func->SetParameter(0,ymax*0.9);
153 m_func->SetParameter(1,xaxismean);
154 m_func->SetParameter(2,xdiff/50.);
155 m_func->SetParNames("Plateau","Threshold","Resolution");
156
157 m_func->SetParLimits(0, ymin - 0.1 * ydiff, ymax + 0.1 * ydiff );
158 m_func->SetParLimits(1, xmin, xmax );
159 m_func->SetParLimits(2, 0., xdiff/4. );
160 }
161 else if(m_name == "flat") {
162 if(verbose)std::cout << "set "<<name<< " parameters" << std::endl;
163 m_func->SetParNames("Height");
164 }
165/*
166 const int numsig = m_func->GetParNumber("Sigma");
167
168 if (numsig != -1 ){
169 double sigmaup = dqm_algorithms::tools::GetFirstFromMap( "Sigma_upperLimit", config.getParameters(), 1000000);
170 m_func->SetParLimits(numsig, 0., sigmaup);
171 }
172 */
173
174 option += "R"; // we need to specify the fit range to fit the TEfficiency (alternative would have been to use TEfficiency::CreateGraph())
175 m_func->SetRange(xmin, xmax);
176
177 if(verbose)std::cout << "fit "<<name<< " with interval cut " << xmin << " - " << xmax << std::endl;
178 std::shared_ptr<TGraphAsymmErrors> graph(eff->CreateGraph()); // we own this!
179 graph->Fit( m_func.get(), option.c_str());
180
181 const int numsig = m_func->GetParNumber("Sigma");
182 if (numsig != -1 ){
183 double sigma=m_func->GetParameter(numsig);
184 m_func->SetParameter(numsig,std::abs(sigma));
185 }
186
187 try {
188 dqm_core::Result *result= dqm_algorithms::tools::GetFitResult (m_func.get() , config, minSig );
189 return result;
190 }
191 catch ( dqm_core::Exception & ex ) {
192 throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
193 }
194}
195
196void
198{
199 out<<"Simple_"+m_name+"_Fit_TEff: Does simple "+m_name+" fit to eff and checks fit parameters against thresholds\n"<<std::endl;
200 if (m_name == "fermi" ) {
201 out<<"The following fit Parameters can be checked with Red and Green Thresholds; only one parameter is needed to get back real result"<<std::endl;
202 out<<"Green/Red Threshold: Plateau : Plateau fit value to give Green/Red Result"<<std::endl;
203 out<<"Green/Red Threshold: Threshold : Fermi energy fit value to give Green/Red Result"<<std::endl;
204 out<<"Green/Red Threshold: Resolution : Templature fit value to give Green/Red Result\n"<<std::endl;
205 }else if (m_name == "erf" ) {
206 out<<"The following fit Parameters can be checked with Red and Green Thresholds; only one parameter is needed to get back real result"<<std::endl;
207 out<<"Green/Red Threshold: Plateau : Plateau fit value to give Green/Red Result"<<std::endl;
208 out<<"Green/Red Threshold: Threshold : mean of gaussian fit value to give Green/Red Result"<<std::endl;
209 out<<"Green/Red Threshold: Resolution : sigma of gaussian fit value to give Green/Red Result\n"<<std::endl;
210 }
211 out<<"Optional Parameter: Verbose: Write out fit results to log file (set to 1)"<<std::endl;
212 out<<"Optional Parameter: MinPoint: Minimum eff point needed to perform Algorithm"<<std::endl;
213 out<<"Optional Parameter: MinSignificance : Minimum multiple of the error in fit paramenter by which the parameter must exceed the thresholds"<<std::endl;
214 out<<"Optional Parameter: ImproveFit : IMPROVE is used to avoid local minima"<<std::endl;
215 out<<"Optional Parameter: xmin: minimum x range"<<std::endl;
216 out<<"Optional Parameter: xmax: maximum x range"<<std::endl;
217 out<<"Optional Parameter: SubtractFromMean: value subtracted from XMean before test is applied: allows using AbsXMean for non-zero expected mean"<<std::endl;
218// out<<"Optional Parameter: Sigma_upperLimit: Upper limit on Sigma- lower limit set to 0. and default upper value is 1e^6\n"<<std::endl;
219
220}
221
file declares the dqm_algorithms::RootFitTEff class.
#define x
bool verbose
Definition hcg.cxx:73
double xmax
Definition listroot.cxx:61
double ymin
Definition listroot.cxx:63
double xmin
Definition listroot.cxx:60
double ymax
Definition listroot.cxx:64
double GetFirstFromMap(const std::string &paramName, const std::map< std::string, double > &params)
dqm_core::Result * GetFitResult(const TF1 *func, const dqm_core::AlgorithmConfig &config, double minSig=0)
void printDescription(std::ostream &out)
std::unique_ptr< TF1 > m_func
Definition RootFitTEff.h:36
dqm_core::Result * execute(const std::string &, const TObject &, const dqm_core::AlgorithmConfig &)
RootFitTEff(const std::string &name)
#define IsA
Declare the TObject style functions.