ATLAS Offline Software
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 
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 
23 namespace
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 
54 {
55  return new RootFitTEff( m_name );
56 }
57 
58 
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;
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 {
189  return result;
190  }
191  catch ( dqm_core::Exception & ex ) {
192  throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
193  }
194 }
195 
196 void
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 
RootFitTEff.h
ymin
double ymin
Definition: listroot.cxx:63
Undefined
@ Undefined
Definition: MaterialTypes.h:8
pdg_comparison.sigma
sigma
Definition: pdg_comparison.py:324
get_generator_info.result
result
Definition: get_generator_info.py:21
IsA
#define IsA
Declare the TObject style functions.
Definition: xAODTEventBranch.h:59
dqm_algorithms::RootFitTEff::execute
dqm_core::Result * execute(const std::string &, const TObject &, const dqm_core::AlgorithmConfig &)
Definition: RootFitTEff.cxx:60
dqm_algorithms::RootFitTEff::m_name
std::string m_name
Definition: RootFitTEff.h:35
dqm_algorithms::RootFitTEff::clone
RootFitTEff * clone()
Definition: RootFitTEff.cxx:53
dqm_algorithms::tools::GetFitResult
dqm_core::Result * GetFitResult(const TF1 *func, const dqm_core::AlgorithmConfig &config, double minSig=0)
Definition: AlgorithmHelper.cxx:308
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
dqm_algorithms::RootFitTEff::m_func
std::unique_ptr< TF1 > m_func
Definition: RootFitTEff.h:36
x
#define x
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
xmin
double xmin
Definition: listroot.cxx:60
Result
ICscStripFitter::Result Result
Definition: CalibCscStripFitter.cxx:13
dqm_algorithms::RootFitTEff::~RootFitTEff
~RootFitTEff()
Definition: RootFitTEff.cxx:46
dqm_algorithms::RootFitTEff::RootFitTEff
RootFitTEff(const std::string &name)
Definition: RootFitTEff.cxx:30
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
dqm_algorithms::RootFitTEff
Definition: RootFitTEff.h:26
SCT_CalibAlgs::nbins
@ nbins
Definition: SCT_CalibNumbers.h:10
python.TriggerHandler.verbose
verbose
Definition: TriggerHandler.py:297
xmax
double xmax
Definition: listroot.cxx:61
AlgorithmHelper.h
dqm_algorithms::RootFitTEff::printDescription
void printDescription(std::ostream &out)
Definition: RootFitTEff.cxx:197
pickleTool.object
object
Definition: pickleTool.py:30
dqt_zlumi_alleff_HIST.eff
int eff
Definition: dqt_zlumi_alleff_HIST.py:113
dqm_algorithms::tools::GetFirstFromMap
double GetFirstFromMap(const std::string &paramName, const std::map< std::string, double > &params)
Definition: AlgorithmHelper.cxx:339
ymax
double ymax
Definition: listroot.cxx:64