9 #include <TGraphErrors.h>
11 #include <dqm_core/AlgorithmConfig.h>
13 #include <dqm_core/Result.h>
18 #include <dqm_core/AlgorithmManager.h>
36 const dqm_core::AlgorithmConfig &
config )
38 std::unique_ptr<TGraph> newgraph;
40 const TGraph* refhist = 0;
41 if (
obj.IsA()->InheritsFrom(
"TGraph") )
43 ERS_DEBUG(2,
"Got TGraph called: "<<
obj.GetName()<<
" of type:"<<
obj.IsA()->GetName());
44 graph =
static_cast<const TGraph*
>(&
obj);
46 else if (
obj.IsA()->InheritsFrom(
"TH1") )
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();
55 throw dqm_core::BadConfig(ERS_HERE,
name,
"Object is not a TGraph or a TH1");
58 ERS_DEBUG(2,
"Retreiving reference graph");
61 refhist =
static_cast<const TGraph*
>(
config.getReference() );
63 catch ( dqm_core::Exception & ex ) {
64 ERS_DEBUG(2,
"No reference specified, will skip point-by-point comparison");
67 ERS_DEBUG(2,
"Number of points to be checked: "<<
npoints);
69 if ( ! refhist->IsA()->InheritsFrom(
"TGraph") )
71 throw dqm_core::BadRefHist(ERS_HERE,
name,
"Reference is not a TGraph");
73 if ( refhist->GetN() !=
npoints )
75 throw dqm_core::BadConfig(ERS_HERE,
name,
"Reference and object with different number of points");
79 ERS_DEBUG(2,
"No reference specified, will skip point-by-point comparison");
82 const std::string param[
NPARS] = {
"XErrHigh",
"XErrLow",
"YErrHigh",
"YErrLow",
"DistFactor",
"NBins"};
83 Double_t bigNumber = 1.7E+308;
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) {
92 catch ( dqm_core::Exception & ex )
94 ERS_DEBUG(1,
"Parameter: i"<<param[
i]<<
"' for Green not found in configuration, using default: "<<grValue[
i]);
101 catch ( dqm_core::Exception & ex )
103 ERS_DEBUG(1,
"Parameter: i"<<param[
i]<<
"' for Red not found in configuration, using default: "<<reValue[
i]);
105 if ( reValue[
i] < grValue[
i] )
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());
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;
118 configuration<<
" - "<<param[
i]<<
" Green:"<<grValue[
i]<<
" Red:"<<reValue[
i];
120 ERS_DEBUG(2,
"Configuration: "<<configuration.str());
123 Double_t grXEH =grValue[0];
124 Double_t grXEL =grValue[1];
125 Double_t grYEH =grValue[2];
126 Double_t grYEL =grValue[3];
127 Double_t grExpF=grValue[4];
128 Double_t Ngreen=grValue[5];
129 Double_t reXEH =reValue[0];
130 Double_t reXEL =reValue[1];
131 Double_t reYEH =reValue[2];
132 Double_t reYEL =reValue[3];
133 Double_t reExpF=reValue[4];
134 Double_t Nred = reValue[5];
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>();
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 )
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;
154 if ( xEH>reXEH || xEL>reXEL || yEH>reYEH || yEL>reYEL )
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");
159 ++redCounterErrorBars;
160 result->tags_.insert(std::make_pair(
"RedErrorBarsForPoint",
bin));
170 ERS_DEBUG(3,
"Checking compatibility with reference point");
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;
178 xEH_r = refhist->GetErrorXhigh(
bin);
179 xEL_r = refhist->GetErrorXlow(
bin);
180 yEH_r = refhist->GetErrorYhigh(
bin);
181 yEL_r = refhist->GetErrorYlow(
bin);
183 if ( xEH_r==0 && xEL_r==0 )
185 ERS_DEBUG(3,
"Turn off check on x (point "<<
bin<<
")");
188 if ( yEH_r==0 && yEL_r==0 )
190 ERS_DEBUG(3,
"Turn off check on y (point "<<
bin<<
")");
193 if ( DX > grExpF*xEH_r || DX < -grExpF*xEL_r ||
194 DY > grExpF*yEH_r || DY < -grExpF*yEL_r )
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));
207 if ( DX > reExpF*xEH_r || DX < -reExpF*xEL_r ||
208 DY > reExpF*yEH_r || DY < -reExpF*yEL_r )
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");
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));
222 ERS_DEBUG(3,
"End of checks for Point "<<
bin);
224 if ( redCounterErrorBars > Nred || redCounterPoints > Nred )
226 ERS_DEBUG(1,
"[Error] Result with "<<redCounterErrorBars+redCounterPoints<<
" errors");
227 ERS_DEBUG(2,
"List of errors"<<errorsList.str());
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));
235 if ( yellowCounterErrorBars > Ngreen || yellowCounterPoints > Ngreen )
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;
246 ERS_DEBUG(1,
"[GREEN] Result");
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;