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