ATLAS Offline Software
Loading...
Searching...
No Matches
GraphTest.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
9#include <TGraphErrors.h>
10#include <TClass.h>
11#include <dqm_core/AlgorithmConfig.h>
13#include <dqm_core/Result.h>
14#include <ers/ers.h>
15#include <string>
16#include <sstream>
17#include <iostream>
18#include <dqm_core/AlgorithmManager.h>
19
20#define NPARS 6
21
23
25 dqm_core::AlgorithmManager::instance().registerAlgorithm("GraphTest",this);
26}
27
29
33
34dqm_core::Result* dqm_algorithms::GraphTest::execute(const std::string & name,
35 const TObject & obj,
36 const dqm_core::AlgorithmConfig & config )
37{
38 std::unique_ptr<TGraph> newgraph;
39 const TGraph* graph;
40 const TGraph* refhist = 0;
41 if ( obj.IsA()->InheritsFrom("TGraph") )
42 {
43 ERS_DEBUG(2,"Got TGraph called: "<<obj.GetName()<<" of type:"<<obj.IsA()->GetName());
44 graph = static_cast<const TGraph*>(&obj);
45 }
46 else if ( obj.IsA()->InheritsFrom("TH1") )
47 {
48 ERS_DEBUG(2,"Got TH1: converting to TGraphErrors");
49 newgraph = std::make_unique<TGraphErrors>(static_cast<const TH1*>(&obj));
50 newgraph->SetNameTitle("TempG","TempG");
51 graph = newgraph.get();
52 }
53 else
54 {
55 throw dqm_core::BadConfig(ERS_HERE,name,"Object is not a TGraph or a TH1");
56 }
57 //Now get reference object and check compatibility
58 ERS_DEBUG(2,"Retreiving reference graph");
59
60 try {
61 refhist = static_cast<const TGraph*>( config.getReference() );
62 }
63 catch ( dqm_core::Exception & ex ) {
64 ERS_DEBUG(2,"No reference specified, will skip point-by-point comparison");
65 }
66 Int_t npoints = graph->GetN();
67 ERS_DEBUG(2,"Number of points to be checked: "<<npoints);
68 if ( refhist ) {
69 if ( ! refhist->IsA()->InheritsFrom("TGraph") )
70 {
71 throw dqm_core::BadRefHist(ERS_HERE,name,"Reference is not a TGraph");
72 }
73 if ( refhist->GetN() != npoints )
74 {
75 throw dqm_core::BadConfig(ERS_HERE,name,"Reference and object with different number of points");
76 }
77 }
78 else {
79 ERS_DEBUG(2,"No reference specified, will skip point-by-point comparison");
80 }
81 // Configure the DQ algorithm
82 const std::string param[NPARS] = {"XErrHigh","XErrLow","YErrHigh","YErrLow","DistFactor","NBins"};
83 Double_t bigNumber = 1.7E+308; //some big number...
84 Double_t grValue[NPARS] = { bigNumber , bigNumber , bigNumber , bigNumber , 1, 0 };
85 Double_t reValue[NPARS] = { bigNumber , bigNumber , bigNumber , bigNumber , 1, 0 };
86 for ( unsigned int i = 0; i<NPARS;++i) {
87 // get configuration for Green Threshold
88 try
89 {
90 grValue[i] = dqm_algorithms::tools::GetFromMap(param[i] , config.getGreenThresholds() );
91 }
92 catch ( dqm_core::Exception & ex )
93 {
94 ERS_DEBUG(1,"Parameter: i"<<param[i]<<"' for Green not found in configuration, using default: "<<grValue[i]);
95 }
96 // get configuration for Red Threshold
97 try
98 {
99 reValue[i] = dqm_algorithms::tools::GetFromMap(param[i] , config.getRedThresholds() );
100 }
101 catch ( dqm_core::Exception & ex )
102 {
103 ERS_DEBUG(1,"Parameter: i"<<param[i]<<"' for Red not found in configuration, using default: "<<reValue[i]);
104 }
105 if ( reValue[i] < grValue[i] ) // Non sense values
106 {
107 std::stringstream msg;
108 msg<<"Configuration Error (Red<Green):"<<param[i]<<" G="<<grValue[i]<<" R="<<reValue[i];
109 throw dqm_core::BadConfig(ERS_HERE,name,msg.str());
110 }
111 } // End of configuration retreival
112#if DEBUG_LEVEL > 1
113 if ( grValue[4]==0 ) { ERS_DEBUG(2,"Exact Match request for Green"); }
114 if ( reValue[4]==0 ) { ERS_DEBUG(2,"Exact Match request for Red"); }
115 std::stringstream configuration;
116 for ( int i = 0;i<NPARS;++i)
117 {
118 configuration<<" - "<<param[i]<<" Green:"<<grValue[i]<<" Red:"<<reValue[i];
119 }
120 ERS_DEBUG(2,"Configuration: "<<configuration.str());
121#endif
122 // Just a translation in something more readable...
123 Double_t grXEH =grValue[0]; // Error (High) on X
124 Double_t grXEL =grValue[1]; // Error (Low) on X
125 Double_t grYEH =grValue[2]; // Error (High) on Y
126 Double_t grYEL =grValue[3]; // Error (Low) on Y
127 Double_t grExpF=grValue[4]; // Moltiplicative Factor for DX,DY
128 Double_t Ngreen=grValue[5]; // Number of points to fail
129 Double_t reXEH =reValue[0]; // Error (High) on X
130 Double_t reXEL =reValue[1]; // Error (Low) on X
131 Double_t reYEH =reValue[2]; // Error (High) on Y
132 Double_t reYEL =reValue[3]; // Error (Low) on Y
133 Double_t reExpF=reValue[4]; // Multiplicative Factor for DX,DY
134 Double_t Nred = reValue[5]; // Number of points to fail
135 // Everything is now configured correctly, we can start
136 Int_t yellowCounterErrorBars=0 , yellowCounterPoints=0;
137 Int_t redCounterErrorBars=0 , redCounterPoints=0;
138 std::stringstream errorsList;
139 auto result = std::make_unique<dqm_core::Result>();
140 for ( Int_t bin = 0 ; bin < npoints ; ++bin) //Loop on all points
141 {
142 // Check point error bars
143 ERS_DEBUG(3,"====> Starting check on point "<<bin);
144 ERS_DEBUG(3,"Checking error bars");
145 Double_t xEH=graph->GetErrorXhigh(bin),xEL=graph->GetErrorXlow(bin);
146 Double_t yEH=graph->GetErrorYhigh(bin),yEL=graph->GetErrorYlow(bin);
147 if ( xEH>grXEH || xEL>grXEL || yEH>grYEH || yEL>grYEL )
148 {
149 ERS_DEBUG(2,"[YELLOW] (point "<<bin<<") error bars:xH="<<xEH<<",xL="<<xEL<<",yH="<<yEH<<",yL="<<yEL);
150 ERS_DEBUG(3,"Limits are: xH="<<grValue[0]<<" xL="<<grValue[1]<<" yH="<<grValue[2]<<" yL="<<grValue[3]<<" nGreen="<<grValue[5]);
151 errorsList<<"; point "<<bin<<" Err. bars:xH="<<xEH<<",xL="<<xEL<<",yH="<<yEH<<",yL="<<yEL;
152 ++yellowCounterErrorBars;
153 }
154 if ( xEH>reXEH || xEL>reXEL || yEH>reYEH || yEL>reYEL )
155 {
156 ERS_DEBUG(2,"[RED] (point "<<bin<<") error bars:xH="<<xEH<<",xL="<<xEL<<",yH="<<yEH<<",yL="<<yEL);
157 ERS_DEBUG(3,"Limits are: xH="<<reValue[0]<<" xL="<<reValue[1]<<" yH="<<reValue[2]<<" yL="<<reValue[3]<<" nRed="<<reValue[5]);
158 ERS_DEBUG(1,"[RED] Result");// game over, RED level reached
159 ++redCounterErrorBars;
160 result->tags_.insert(std::make_pair("RedErrorBarsForPoint",bin));
161 }
162 // Now Check if point is compatible with reference point (x_r,y_r)
163 // reference point (asymmetric) errors bars
164 // (xEH,xEL,yEH,yEL) define the max. allowed distance for
165 // The ProximityFactor can be used to set two different thresholds for
166 // yellow and red.
167 // If ref. point errors bars are zeros do not check that coordinate
168 // Ex. Point is Green if: x_r - f*xEL =< x =< x_r + f*xEH AND
169 // y_r - f*yEL =< y =< y_r + f*yEH
170 ERS_DEBUG(3,"Checking compatibility with reference point");
171 Double_t x,y;
172 graph->GetPoint(bin,x,y);
173 Double_t x_r = x ,y_r = y;
174 if (refhist) refhist->GetPoint(bin,x_r,y_r);
175 Double_t DX = x-x_r , DY=y-y_r;
176 Double_t xEH_r = 0 , xEL_r = 0 , yEH_r = 0 , yEL_r = 0;
177 if ( refhist ) {
178 xEH_r = refhist->GetErrorXhigh(bin);
179 xEL_r = refhist->GetErrorXlow(bin);
180 yEH_r = refhist->GetErrorYhigh(bin);
181 yEL_r = refhist->GetErrorYlow(bin);
182 }
183 if ( xEH_r==0 && xEL_r==0 )
184 {
185 ERS_DEBUG(3,"Turn off check on x (point "<<bin<<")");
186 DX=0; // Do not check X
187 }
188 if ( yEH_r==0 && yEL_r==0 )
189 {
190 ERS_DEBUG(3,"Turn off check on y (point "<<bin<<")");
191 DY=0; // Do not check Y
192 }
193 if ( DX > grExpF*xEH_r || DX < -grExpF*xEL_r ||
194 DY > grExpF*yEH_r || DY < -grExpF*yEL_r )
195 {
196 ERS_DEBUG(2,"[YELLOW] Point "<<bin<<" does not match with reference value (DX,DY)=("<<DX<<","<<DY<<")");
197 ERS_DEBUG(3,"Limits are: "<<-grExpF*xEL_r<<"<DX<"<<grExpF*xEH_r<<" ; "<<-grExpF*yEL_r<<"<DY<"<<grExpF*yEH_r);
198 errorsList<<"; point "<<bin<<" Does not match with reference (DX,DY)=("<<DX<<","<<DY<<")";
199 ++yellowCounterPoints;
200 std::stringstream out;
201 out << yellowCounterPoints;
202 std::string yellowtag = out.str();
203 if(yellowCounterPoints<10) yellowtag= "0"+yellowtag;
204 yellowtag ="YellowPointNumber"+yellowtag;
205 result->tags_.insert(std::make_pair(yellowtag,bin));
206 }
207 if ( DX > reExpF*xEH_r || DX < -reExpF*xEL_r ||
208 DY > reExpF*yEH_r || DY < -reExpF*yEL_r )
209 {
210 ERS_DEBUG(2,"[RED] Point "<<bin<<" does not match with reference value (DX,DY)=("<<DX<<","<<DY<<")");
211 ERS_DEBUG(3,"Limits are: "<<-grExpF*xEL_r<<"<DX<"<<grExpF*xEH_r<<" ; "<<-grExpF*yEL_r<<"<DY<"<<grExpF*yEH_r);
212 ERS_DEBUG(1,"[RED] Result");
213 ++redCounterPoints;
214 std::stringstream out;
215 out << redCounterPoints;
216 std::string redtag = out.str();
217 if(redCounterPoints<10) redtag= "0"+redtag;
218 redtag ="RedPointNumber"+redtag;
219 result->tags_.insert(std::make_pair(redtag,bin));
220 //result->tags_.insert(std::make_pair("RedPointNumber"+redCounterPoints,bin));
221 }
222 ERS_DEBUG(3,"End of checks for Point "<<bin);
223 } // End loop on points
224 if ( redCounterErrorBars > Nred || redCounterPoints > Nred )
225 {
226 ERS_DEBUG(1,"[Error] Result with "<<redCounterErrorBars+redCounterPoints<<" errors");
227 ERS_DEBUG(2,"List of errors"<<errorsList.str());
228 result->status_=dqm_core::Result::Red;
229 if ( redCounterErrorBars > 0 )
230 result->tags_.insert(std::make_pair("NumRedErrorBars",redCounterErrorBars));
231 if ( redCounterPoints > 0 )
232 result->tags_.insert(std::make_pair("NumRedComparison",redCounterPoints));
233 return result.release();
234 }
235 if ( yellowCounterErrorBars > Ngreen || yellowCounterPoints > Ngreen )
236 {
237 ERS_DEBUG(1,"[YELLOW] Result with "<<yellowCounterErrorBars+yellowCounterPoints<<" errors");
238 ERS_DEBUG(2,"List of errors"<<errorsList.str());
239 if ( yellowCounterErrorBars > 0 )
240 result->tags_.insert(std::make_pair("NumYellowsErrorBars",yellowCounterErrorBars));
241 if ( yellowCounterPoints > 0 )
242 result->tags_.insert(std::make_pair("NumYellowsComparison",yellowCounterPoints));
243 result->status_=dqm_core::Result::Yellow;
244 return result.release();
245 }
246 ERS_DEBUG(1,"[GREEN] Result");
247 return new dqm_core::Result(dqm_core::Result::Green);
248}
249
250void
252{
253 out<<"GraphTest DQ algorithm: check validity of a TGraph (or TH1)"<<std::endl
254 <<"This test can be used to perform a test on a TGraph with (or without) error bars, in case asymmmetric."<<std::endl
255 <<"It performs two tests:"<<std::endl
256 <<"1- It checks that each point in the TGraph has \"small\" error bars"<<std::endl
257 <<"2- It checks that each point is \"close\" to a reference value"<<std::endl
258 <<"For test 2 a reference TGraph has to be provided (in this way each point may have a different reference value). "<<std::endl
259 <<"The (x,y) coordinates of the point are compared with the reference point coordinates (x_r,y_r) and REFERENCE "<<std::endl
260 <<" point error bars defining the maximum allowed distance. i.e."<<std::endl
261 <<"the point is good if: x_r - f*x_err < x < x_r + f*x_err AND y_r - f*y_err < y < y_r + f*y_err"<<std::endl
262 <<"\"f\" is a factor that can be used to specify different limits for Green and Red thresholds."<<std::endl
263 <<"If, for a specific reference point, the error bars along one coordinate are set to zero the test 2 is NOT performed for that point (this can be used to exclude, for example, a dead channel through the reference graph). "<<std::endl
264 <<"The algorithms can work also with TGraphAsymmErrors object, so high and low errors can always be specified separately."<<std::endl
265 <<"The optional parameters that can be set, separetely, for Green and Red thresholds are:"<<std::endl
266 <<"XErrHigh : Maximum (higher) error bar length x coord (default is 1.844E19)."<<std::endl
267 <<"XErrLow : Maximum (lower) error bar length x coord (default is 1.844E19)."<<std::endl
268 <<"YErrHigh : Maximum (higher) error bar length y coord (default is 1.844E19)."<<std::endl
269 <<"YErrLow : Maximum (lower) error bar length y coord (default is 1.844E19)."<<std::endl
270 <<"DistFactor : The factor \"f\" used in second part of the test (default is 1)."<<std::endl
271 <<"NBins : This is the number of points allowed to fail to change result(default is 0)."<<std::endl;
272
273}
static dqm_algorithms::BinContentComp myInstance
#define NPARS
Definition GraphTest.cxx:20
file declares the dqm_algorithms::GraphTest class.
#define y
#define x
virtual dqm_core::Result * execute(const std::string &, const TObject &obj, const dqm_core::AlgorithmConfig &conf)
Definition GraphTest.cxx:34
void printDescription(std::ostream &out)
virtual GraphTest * clone()
Definition GraphTest.cxx:30
const T & GetFromMap(const std::string &pname, const std::map< std::string, T > &params)
MsgStream & msg
Definition testRead.cxx:32