51 {
53
54 if(
object.
IsA()->InheritsFrom(
"TH1" ) ) {
57 throw dqm_core::BadConfig( ERS_HERE, name, "dimension > 2 " );
58 }
59 } else {
60 throw dqm_core::BadConfig( ERS_HERE, name, "does not inherit from TH1" );
61 }
62
71
72
73 bool reverseConvention = TString(
histogram->GetYaxis()->GetTitle()).EndsWith(
"+y");
74
75 std::map<std::string,std::set<std::pair<int,int>>> knownBins;
76
77 auto knownBinParser = [&](const std::string& cutName) {
79
81 while (i < known.length() && !std::isdigit(known[i])) {
83 }
84 known = known.substr(i);
85 known += ";";
87 while(i != std::string::npos) {
88 size_t j = known.find(";");
89 knownBins[cutName].insert({TString(known.substr(0,i)).Atoi(),TString(known.substr(i+1,j-i-1)).Atoi()});
90 known = known.substr(j+1);
92 }
93 };
94
95 std::vector<std::pair<double,std::string>> orderedCuts;
96 double mostNegativeCut = 0;
97 for(
auto& [k,v] :
config.getParameters()) {
99 if(!
kk.EndsWith(
"Cut"))
continue;
101 orderedCuts.push_back({
v,
kk.Data()});
102 mostNegativeCut = std::min(mostNegativeCut,v);
103 knownBinParser(
kk.Data());
104 }
105 knownBinParser("Dead");
106
107
108 std::sort(orderedCuts.begin(),orderedCuts.end(),[](
const auto& v1,
const auto& v2) { return std::abs(v1.first) > std::abs(v2.first); });
109
110 if (
histogram->GetEntries() < minstat ) {
111 dqm_core::Result *
result =
new dqm_core::Result(dqm_core::Result::Undefined);
112 result->status_ = dqm_core::Result::Yellow;
115 }
116
117
119
120 std::map<int,dqm_core::Result*> resultsByTimeBin;
121 std::map<std::string,int>
counts;
122 dqm_core::Result* lastFilledResult = nullptr;
123
124 for(
int t=(nBinsZ>0 ? range[0] : -1) ;
t <= (nBinsZ>0 ?
range[1] : -1);
t++) {
127 if(t!=-1) {
128
129
132 }
133
134
135 std::set<int> filledRows;
136
137
138 std::vector<double> stripsMedian;
139 std::vector<double> stripsAvg;
140 std::vector<double> stripsVariance;
141 std::vector<size_t> stripsN;
142 std::vector<double> stripsProb;
145 std::vector<double> onestrip;
146 double stripSum=0;
147 for (
int j =
ymin; j <=
ymax; ++j ) {
149 if (binvalue < ignoreBelow) continue;
150 if(binvalue>0) filledRows.insert(j);
151
152 bool knownAnomaly=false;
153 for(auto& [k,v] : knownBins) {
154 if(
v.find({i,j})!=
v.end()) {
155 knownAnomaly = true; break;
156 }
157 }
158 if(!knownAnomaly) {
159 onestrip.push_back(binvalue);
160 stripSum += binvalue;
161 }
162
163 }
164 stripsAvg.push_back(stripSum/onestrip.size());
165
166
167
168
169 std::sort(onestrip.begin(),onestrip.end());
170
171 stripsMedian.push_back( onestrip.at(onestrip.size()/2) );
172
173 stripsVariance.push_back( std::pow((onestrip.at(onestrip.size()*0.84) - onestrip.at(onestrip.size()*0.16))/2.,2) );
174 stripsN.push_back(onestrip.size());
175
176 if(stripsVariance.back() > 0) {
177 std::vector<double> stripRef;
178 for (
size_t i = 0;
i < onestrip.size();
i++) {
179
180
181 double nextVal = 0;
182 do {
183 nextVal = (stripsVariance.back()>=100) ?
r.Gaus(stripsAvg.back(), std::sqrt(stripsVariance.back())) :
r.Poisson(stripsAvg.back());
184 } while(nextVal<ignoreBelow);
185 stripRef.push_back(nextVal);
186 }
187 std::sort(stripRef.begin(),stripRef.end());
188 stripsProb.push_back( TMath::KolmogorovTest(onestrip.size(),&onestrip[0],stripRef.size(),&stripRef[0],"") );
189 } else {
190 stripsProb.push_back(1);
191 }
192 }
193 if(nBinsZ>0 && filledRows.empty()) {
194 continue;
195 }
196
197 dqm_core::Result*
result =
new dqm_core::Result();
198 std::map<std::pair<int,int>,
bin>
bins;
200 double strip_median = stripsMedian[
k -
xmin];
201 double strip_variance = stripsVariance[
k -
xmin];
204 if (binvalue < ignoreBelow) continue;
205 double residual = (strip_variance) ? ((binvalue - strip_median) / std::sqrt(strip_variance)) : 0;
208 }
209 }
210
211
212 bool testDeadStrips = (filledRows.size() ==
size_t(
ymax-
ymin+1));
213
214
215
216
217 counts[
"NDeadStrip"]= (testDeadStrips) ? 0 : -1;
220 counts[
"NConsecUnlikelyStrip"]=0;
221 for(auto& [cut,k] : orderedCuts) {
223 }
224
225
226 int nUnlikelyStrips = 0;
227 for(
size_t i = 0;
i<stripsVariance.size();
i++) {
228 if (testDeadStrips && stripsVariance.at(i) == 0 && stripsAvg.at(i) == 0) {
229
230 if( (i>0 && (stripsAvg.at(i-1)*stripsN.at(i-1))>=minstat) || (i<stripsVariance.size()-1 && (stripsAvg.at(i+1)*stripsN.at(i+1))>=minstat)) {
231 result->tags_[TString::Format(
"_DeadStrip%02ld", i+1).Data()] =
histogram->GetXaxis()->GetBinCenter(
xmin + i);
233 }
234
235 }
236 if (stripsProb.at(i) < probThreshold) {
237 result->tags_[TString::Format(
"_UnlikelyStrip%02ld", i+1).Data()] = -
log(stripsProb.at(i));
238 nUnlikelyStrips++;
239 if(nUnlikelyStrips > counts[
"NConsecUnlikelyStrip"])
counts[
"NConsecUnlikelyStrip"] = nUnlikelyStrips;
240 } else {
241 nUnlikelyStrips=0;
242 }
243 if(publishDetail & 0x1) {
244 result->tags_[TString::Format(
"_Median%02ld", i+1).Data()] = stripsMedian.at(i);
245 }
246 if(publishDetail & 0x2) {
247 result->tags_[TString::Format(
"_StdDev%02ld", i+1).Data()] = sqrt(stripsVariance.at(i));
248 }
249 if(publishDetail & 0x4) {
250 result->tags_[TString::Format(
"_Prob%02ld", i+1).Data()] = stripsProb.at(i);
251 }
252 if(publishDetail & 0x8) {
253
254 result->tags_[TString::Format(
"_Noise%02ld", i+1).Data()] = sqrt(std::abs(stripsVariance.at(i) - stripsMedian.at(i)));
255 }
256 }
257
258
259
262
266 }
267 } else {
268 if( (publishDetail & 0x10) &&
bin.
m_value==0) {
270 }
271
272 double classCut = 0;
273 for(auto& [cut,k] : orderedCuts) {
281 } else {
282
283 result->tags_[TString::Format(
"_Known%s(%d,%d)",
k.c_str(),
bin.
m_ix,
285 }
286 break;
287 }
288 }
289
290
291 if(
bin.
m_value>0 && knownBins[
"Dead"].find({bin.m_ix,bin.m_iy})!=knownBins[
"Dead"].end()) {
295 } else if(classCut != 0) {
296
297 for(auto& [cut,k] : orderedCuts) {
299 if(cut*classCut < 0) {
303 }
304 }
305 }
306 }
307 }
308
310 lastFilledResult =
result;
311
312 }
313
315 if(nBinsZ>0) {
316
320 counts[
"NConsecUnlikelyStrip"]=0;
321 for(auto& [cut,k] : orderedCuts) {
323 }
324 dqm_core::Result* lastResult = nullptr;
325 result =
new dqm_core::Result();
326
327 std::map<std::string,int> anomalies;
328 for(
int t=range[0];
t<=
range[1]+1;
t++) {
329 if(resultsByTimeBin.find(t)==resultsByTimeBin.end()) {
330
331 for(auto& [k,v] : anomalies) {
332 if(v>=minDuration) {
333 if(printLevel<=2) std::cout <<
" Got anomaly: " <<
k <<
" duration: " <<
v <<
" end: " <<
t << std::endl;
334 int lbStart =
histogram->GetXaxis()->GetBinLowEdge(t-v);
335 int lbEnd =
histogram->GetXaxis()->GetBinLowEdge(t);
336
337 if (lastResult){
338 if(liveMode) {
339 result->tags_[
k] = lastResult->tags_[
k];
340 } else {
342 TString::Format(
"_LB%d-%d", lbStart, lbEnd).Data()] = lastResult->tags_[
k];
343 }
344 }
345
346 if(
k.find(
"_DeadStrip")==0) {
348 }
else if(
k.find(
"_Dead")==0) {
350 }
else if(
k.find(
"_UnlikelyStrip")==0) {
351
352 }
else if(
k.find(
"_Un")==0) {
354 } else {
355 for(auto& [cut,k2] : orderedCuts) {
356 if(
k.find(
"_" + k2)==0) {
358 }
359 }
360 }
361 }
362 }
363 anomalies.clear();
364 } else {
365 auto thisResult = resultsByTimeBin[
t];
366 if(liveMode && thisResult==lastFilledResult) {
367
368
369 delete thisResult;
370 continue;
371 }
372
373 for(auto& [k,v] : thisResult->tags_) {
374
375 if(
k.find(
"_DeadStrip")==0) {
377 }
else if(
k.find(
"_Dead")==0) {
379 }
else if(
k.find(
"_UnlikelyStrip")==0) {
381 }
else if(
k.find(
"_Un")==0) {
383 } else {
384 for(auto& [cut,k2] : orderedCuts) {
385 if(
k.find(
"_" + k2)==0) {
387 }
388 }
389 }
390 }
391
392
393
394 for(auto& [k,v] : anomalies) {
395 if(thisResult->tags_.find(k) != thisResult->tags_.end()) continue;
396 if(v>=minDuration) {
397 int lbStart =
histogram->GetXaxis()->GetBinLowEdge(t-v);
398 int lbEnd =
histogram->GetXaxis()->GetBinLowEdge(t);
399 if(liveMode) {
400
401 } else {
402 result->tags_[
k+TString::Format(
"_LB%d-%d",lbStart,lbEnd).Data()]=lastResult->tags_[
k];
403 }
404
405
406 if(
k.find(
"_DeadStrip")==0) {
408 }
else if(
k.find(
"_Dead")==0) {
410 }
else if(
k.find(
"_UnlikelyStrip")==0) {
411
412 }
else if(
k.find(
"_Un")==0) {
414 } else {
415 for(auto& [cut,k2] : orderedCuts) {
416 if(
k.find(
"_" + k2)==0) {
418 }
419 }
420 }
421 }
423 }
424
425 if(lastResult) delete lastResult;
426 lastResult = thisResult;
427 }
428 }
429 if(lastResult) delete lastResult;
430
431
432 } else {
433
434 result = resultsByTimeBin[-1];
435 }
436
437
438
439
440
441 const auto& redThresholds =
config.getRedThresholds();
442 const auto& greenThresholds =
config.getGreenThresholds();
443 result->status_ = dqm_core::Result::Undefined;
444 if(publishDetail & 0x20) {
445 result->tags_[
"StatusCode"] = 0;
446 }
447 for(auto& [k,v] : counts) {
448 if(nBinsZ>0 && k=="NConsecUnlikelyStrip") continue;
451 result->status_ = dqm_core::Result::Red;
452 if(publishDetail & 0x20) {
453 result->tags_[
"StatusCode"] = 3;
454 }
456 result->status_ = dqm_core::Result::Yellow;
457 if(publishDetail & 0x20) {
458 result->tags_[
"StatusCode"] = 2;
459 }
460 }
else if(
result->status_==dqm_core::Result::Undefined && greenThresholds.find(k)!=greenThresholds.end()) {
461 result->status_ = dqm_core::Result::Green;
462 if(publishDetail & 0x20) {
463 result->tags_[
"StatusCode"] = 1;
464 }
465 }
466 }
467
468
470
471}
static const std::vector< std::string > bins
std::string find(const std::string &s)
return a remapped string
cut
This script demonstrates how to call a C++ class from Python Also how to use PyROOT is shown.
l
Printing final latex table to .tex output file.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
#define IsA
Declare the TObject style functions.