File indexing completed on 2024-09-11 04:32:56
0001 #include "DQMServices/Core/interface/QTest.h"
0002 #include "DQMServices/Core/interface/DQMStore.h"
0003 #include "Math/ProbFuncMathCore.h"
0004 #include "TMath.h"
0005 #include <cmath>
0006 #include <iostream>
0007 #include <sstream>
0008
0009 using namespace std;
0010
0011 const float QCriterion::ERROR_PROB_THRESHOLD = 0.50;
0012 const float QCriterion::WARNING_PROB_THRESHOLD = 0.90;
0013
0014
0015 void QCriterion::init() {
0016 errorProb_ = ERROR_PROB_THRESHOLD;
0017 warningProb_ = WARNING_PROB_THRESHOLD;
0018 setAlgoName("NO_ALGORITHM");
0019 status_ = dqm::qstatus::DID_NOT_RUN;
0020 message_ = "NO_MESSAGE";
0021 verbose_ = 0;
0022 }
0023
0024 float QCriterion::runTest(const MonitorElement* ) { return 0.; }
0025
0026
0027
0028
0029
0030
0031
0032 float ContentsXRange::runTest(const MonitorElement* me) {
0033 badChannels_.clear();
0034
0035 if (!me)
0036 return -1;
0037 if (!me->getRootObject())
0038 return -1;
0039 TH1* h = nullptr;
0040
0041 if (verbose_ > 1)
0042 std::cout << "QTest:" << getAlgoName() << "::runTest called on " << me->getFullname() << "\n";
0043
0044 if (me->kind() == MonitorElement::Kind::TH1F) {
0045 h = me->getTH1F();
0046 }
0047
0048 else if (me->kind() == MonitorElement::Kind::TH1S) {
0049 h = me->getTH1S();
0050 }
0051
0052 else if (me->kind() == MonitorElement::Kind::TH1D) {
0053 h = me->getTH1D();
0054 } else {
0055 if (verbose_ > 0)
0056 std::cout << "QTest:ContentsXRange"
0057 << " ME " << me->getFullname() << " does not contain TH1F/TH1S/TH1D, exiting\n";
0058 return -1;
0059 }
0060
0061 if (!rangeInitialized_) {
0062 if (h->GetXaxis())
0063 setAllowedXRange(h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
0064 else
0065 return -1;
0066 }
0067 int ncx = h->GetXaxis()->GetNbins();
0068
0069 int first = 0;
0070
0071 int last = ncx + 1;
0072
0073 double sum = 0;
0074
0075 double fail = 0;
0076 int bin;
0077 for (bin = first; bin <= last; ++bin) {
0078 double contents = h->GetBinContent(bin);
0079 double x = h->GetBinCenter(bin);
0080 sum += contents;
0081 if (x < xmin_ || x > xmax_)
0082 fail += contents;
0083 }
0084
0085 if (sum == 0)
0086 return 1;
0087
0088 return (sum - fail) / sum;
0089 }
0090
0091
0092
0093
0094 float ContentsYRange::runTest(const MonitorElement* me) {
0095 badChannels_.clear();
0096
0097 if (!me)
0098 return -1;
0099 if (!me->getRootObject())
0100 return -1;
0101 TH1* h = nullptr;
0102
0103 if (verbose_ > 1)
0104 std::cout << "QTest:" << getAlgoName() << "::runTest called on " << me->getFullname() << "\n";
0105
0106 if (me->kind() == MonitorElement::Kind::TH1F) {
0107 h = me->getTH1F();
0108 } else if (me->kind() == MonitorElement::Kind::TH1S) {
0109 h = me->getTH1S();
0110 } else if (me->kind() == MonitorElement::Kind::TH1D) {
0111 h = me->getTH1D();
0112 } else {
0113 if (verbose_ > 0)
0114 std::cout << "QTest:ContentsYRange"
0115 << " ME " << me->getFullname() << " does not contain TH1F/TH1S/TH1D, exiting\n";
0116 return -1;
0117 }
0118
0119 if (!rangeInitialized_ || !h->GetXaxis())
0120 return 1;
0121 int ncx = h->GetXaxis()->GetNbins();
0122
0123 int first = 1;
0124
0125 int last = ncx;
0126
0127 int fail = 0;
0128 int bin;
0129
0130 if (useEmptyBins_)
0131 {
0132 for (bin = first; bin <= last; ++bin) {
0133 double contents = h->GetBinContent(bin);
0134 bool failure = false;
0135 failure = (contents < ymin_ || contents > ymax_);
0136 if (failure) {
0137 DQMChannel chan(bin, 0, 0, contents, h->GetBinError(bin));
0138 badChannels_.push_back(chan);
0139 ++fail;
0140 }
0141 }
0142
0143 return 1. * (ncx - fail) / ncx;
0144 } else
0145 {
0146 for (bin = first; bin <= last; ++bin) {
0147 double contents = h->GetBinContent(bin);
0148 bool failure = false;
0149 if (contents)
0150 failure = (contents < ymin_ || contents > ymax_);
0151 if (failure)
0152 ++fail;
0153 }
0154
0155 return 1. * (ncx - fail) / ncx;
0156 }
0157 }
0158
0159
0160
0161
0162 float DeadChannel::runTest(const MonitorElement* me) {
0163 badChannels_.clear();
0164 if (!me)
0165 return -1;
0166 if (!me->getRootObject())
0167 return -1;
0168 TH1* h1 = nullptr;
0169 TH2* h2 = nullptr;
0170
0171 if (verbose_ > 1)
0172 std::cout << "QTest:" << getAlgoName() << "::runTest called on " << me->getFullname() << "\n";
0173
0174 if (me->kind() == MonitorElement::Kind::TH1F) {
0175 h1 = me->getTH1F();
0176 }
0177
0178 else if (me->kind() == MonitorElement::Kind::TH1S) {
0179 h1 = me->getTH1S();
0180 }
0181
0182 else if (me->kind() == MonitorElement::Kind::TH1D) {
0183 h1 = me->getTH1D();
0184 }
0185
0186 else if (me->kind() == MonitorElement::Kind::TH2F) {
0187 h2 = me->getTH2F();
0188 }
0189
0190 else if (me->kind() == MonitorElement::Kind::TH2S) {
0191 h2 = me->getTH2S();
0192 }
0193
0194 else if (me->kind() == MonitorElement::Kind::TH2D) {
0195 h2 = me->getTH2D();
0196 } else {
0197 if (verbose_ > 0)
0198 std::cout << "QTest:DeadChannel"
0199 << " ME " << me->getFullname() << " does not contain TH1F/TH1S/TH1D/TH2F/TH2S/TH2D, exiting\n";
0200 return -1;
0201 }
0202
0203 int fail = 0;
0204
0205
0206 if (h1 != nullptr) {
0207 if (!rangeInitialized_ || !h1->GetXaxis())
0208 return 1;
0209 int ncx = h1->GetXaxis()->GetNbins();
0210 int first = 1;
0211 int last = ncx;
0212 int bin;
0213
0214
0215 for (bin = first; bin <= last; ++bin) {
0216 double contents = h1->GetBinContent(bin);
0217 bool failure = false;
0218 failure = contents <= ymin_;
0219 if (failure) {
0220 DQMChannel chan(bin, 0, 0, contents, h1->GetBinError(bin));
0221 badChannels_.push_back(chan);
0222 ++fail;
0223 }
0224 }
0225
0226 return 1. * (ncx - fail) / ncx;
0227 }
0228
0229
0230
0231 else if (h2 != nullptr) {
0232 int ncx = h2->GetXaxis()->GetNbins();
0233 int ncy = h2->GetYaxis()->GetNbins();
0234
0235
0236 for (int cx = 1; cx <= ncx; ++cx) {
0237 for (int cy = 1; cy <= ncy; ++cy) {
0238 double contents = h2->GetBinContent(h2->GetBin(cx, cy));
0239 bool failure = false;
0240 failure = contents <= ymin_;
0241 if (failure) {
0242 DQMChannel chan(cx, cy, 0, contents, h2->GetBinError(h2->GetBin(cx, cy)));
0243 badChannels_.push_back(chan);
0244 ++fail;
0245 }
0246 }
0247 }
0248
0249 return 1. * (ncx * ncy - fail) / (ncx * ncy);
0250 } else {
0251 if (verbose_ > 0)
0252 std::cout << "QTest:DeadChannel"
0253 << " TH1/TH2F are NULL, exiting\n";
0254 return -1;
0255 }
0256 }
0257
0258
0259
0260
0261
0262
0263 float NoisyChannel::runTest(const MonitorElement* me) {
0264 badChannels_.clear();
0265 if (!me)
0266 return -1;
0267 if (!me->getRootObject())
0268 return -1;
0269 TH1* h = nullptr;
0270 TH2* h2 = nullptr;
0271
0272 if (verbose_ > 1)
0273 std::cout << "QTest:" << getAlgoName() << "::runTest called on " << me->getFullname() << "\n";
0274
0275 int nbins = 0;
0276 int nbinsX = 0, nbinsY = 0;
0277
0278 if (me->kind() == MonitorElement::Kind::TH1F) {
0279 nbins = me->getTH1F()->GetXaxis()->GetNbins();
0280 h = me->getTH1F();
0281 }
0282
0283 else if (me->kind() == MonitorElement::Kind::TH1S) {
0284 nbins = me->getTH1S()->GetXaxis()->GetNbins();
0285 h = me->getTH1S();
0286 }
0287
0288 else if (me->kind() == MonitorElement::Kind::TH1D) {
0289 nbins = me->getTH1D()->GetXaxis()->GetNbins();
0290 h = me->getTH1D();
0291 }
0292
0293 else if (me->kind() == MonitorElement::Kind::TH2F) {
0294 nbinsX = me->getTH2F()->GetXaxis()->GetNbins();
0295 nbinsY = me->getTH2F()->GetYaxis()->GetNbins();
0296 h2 = me->getTH2F();
0297 }
0298
0299 else if (me->kind() == MonitorElement::Kind::TH2S) {
0300 nbinsX = me->getTH2S()->GetXaxis()->GetNbins();
0301 nbinsY = me->getTH2S()->GetYaxis()->GetNbins();
0302 h2 = me->getTH2S();
0303 }
0304
0305 else if (me->kind() == MonitorElement::Kind::TH2D) {
0306 nbinsX = me->getTH2F()->GetXaxis()->GetNbins();
0307 nbinsY = me->getTH2F()->GetYaxis()->GetNbins();
0308 h2 = me->getTH2D();
0309 } else {
0310 if (verbose_ > 0)
0311 std::cout << "QTest:NoisyChannel"
0312 << " ME " << me->getFullname() << " does not contain TH1F/TH1S/TH1D or TH2F/TH2S/TH2D, exiting\n";
0313 return -1;
0314 }
0315
0316
0317
0318
0319 int first = 1;
0320
0321 int last = nbins;
0322 int lastX = nbinsX, lastY = nbinsY;
0323
0324 int fail = 0;
0325 int bin;
0326 int binX, binY;
0327 if (h != nullptr) {
0328 if (!rangeInitialized_ || !h->GetXaxis()) {
0329 return 1;
0330 }
0331 for (bin = first; bin <= last; ++bin) {
0332 double contents = h->GetBinContent(bin);
0333 double average = getAverage(bin, h);
0334 bool failure = false;
0335 if (average != 0)
0336 failure = (((contents - average) / std::abs(average)) > tolerance_);
0337
0338 if (failure) {
0339 ++fail;
0340 DQMChannel chan(bin, 0, 0, contents, h->GetBinError(bin));
0341 badChannels_.push_back(chan);
0342 }
0343 }
0344
0345
0346 return 1. * (nbins - fail) / nbins;
0347 } else if (h2 != nullptr) {
0348 for (binY = first; binY <= lastY; ++binY) {
0349 for (binX = first; binX <= lastX; ++binX) {
0350 double contents = h2->GetBinContent(binX, binY);
0351 double average = getAverage2D(binX, binY, h2);
0352 bool failure = false;
0353 if (average != 0)
0354 failure = (((contents - average) / std::abs(average)) > tolerance_);
0355 if (failure) {
0356 ++fail;
0357 DQMChannel chan(binX, 0, 0, contents, h2->GetBinError(binX));
0358 badChannels_.push_back(chan);
0359 }
0360 }
0361 }
0362
0363 return 1. * ((nbinsX * nbinsY) - fail) / (nbinsX * nbinsY);
0364 }
0365 else {
0366 if (verbose_ > 0)
0367 std::cout << "QTest:NoisyChannel"
0368 << " TH1/TH2F are NULL, exiting\n";
0369 return -1;
0370 }
0371 }
0372
0373
0374
0375 double NoisyChannel::getAverage(int bin, const TH1* h) const {
0376 int first = 1;
0377 int ncx = h->GetXaxis()->GetNbins();
0378 double sum = 0;
0379 int bin_start, bin_end;
0380 int add_right = 0;
0381 int add_left = 0;
0382
0383 bin_start = bin - numNeighbors_;
0384 bin_end = bin + numNeighbors_;
0385
0386 if (bin_start < first) {
0387 add_right = first - bin_start;
0388 bin_start = first;
0389 bin_end += add_right;
0390 if (bin_end > ncx)
0391 bin_end = ncx;
0392 }
0393
0394 if (bin_end > ncx) {
0395 add_left = bin_end - ncx;
0396 bin_end = ncx;
0397 bin_start -= add_left;
0398 if (bin_start < first)
0399 bin_start = first;
0400 }
0401
0402 sum += h->Integral(bin_start, bin_end);
0403 sum -= h->GetBinContent(bin);
0404
0405 int dimension = 2 * numNeighbors_ + 1;
0406 if (dimension > h->GetNbinsX())
0407 dimension = h->GetNbinsX();
0408
0409 return sum / (dimension - 1);
0410 }
0411
0412 double NoisyChannel::getAverage2D(int binX, int binY, const TH2* h2) const {
0413
0414 int firstX = 1;
0415 int firstY = 1;
0416 double sum = 0;
0417 int ncx = h2->GetXaxis()->GetNbins();
0418 int ncy = h2->GetYaxis()->GetNbins();
0419
0420 int neighborsX, neighborsY;
0421 neighborsX = numNeighbors_;
0422 neighborsY = numNeighbors_;
0423 int bin_startX, bin_endX;
0424 int add_rightX = 0;
0425 int add_leftX = 0;
0426 int bin_startY, bin_endY;
0427 int add_topY = 0;
0428 int add_downY = 0;
0429
0430 bin_startX = binX - neighborsX;
0431 bin_endX = binX + neighborsX;
0432
0433 if (bin_startX < firstX) {
0434 add_rightX = firstX - bin_startX;
0435 bin_startX = firstX;
0436 bin_endX += add_rightX;
0437 if (bin_endX > ncx)
0438 bin_endX = ncx;
0439 }
0440
0441 if (bin_endX > ncx) {
0442 add_leftX = bin_endX - ncx;
0443 bin_endX = ncx;
0444 bin_startX -= add_leftX;
0445 if (bin_startX < firstX)
0446 bin_startX = firstX;
0447 }
0448
0449 bin_startY = binY - neighborsY;
0450 bin_endY = binY + neighborsY;
0451
0452 if (bin_startY < firstY) {
0453 add_topY = firstY - bin_startY;
0454 bin_startY = firstY;
0455 bin_endY += add_topY;
0456 if (bin_endY > ncy)
0457 bin_endY = ncy;
0458 }
0459
0460 if (bin_endY > ncy) {
0461 add_downY = bin_endY - ncy;
0462 bin_endY = ncy;
0463 bin_startY -= add_downY;
0464 if (bin_startY < firstY)
0465 bin_startY = firstY;
0466 }
0467
0468 sum += h2->Integral(bin_startX, bin_endX, bin_startY, bin_endY);
0469 sum -= h2->GetBinContent(binX, binY);
0470
0471 int dimensionX = 2 * neighborsX + 1;
0472 int dimensionY = 2 * neighborsY + 1;
0473
0474 if (dimensionX > h2->GetNbinsX())
0475 dimensionX = h2->GetNbinsX();
0476 if (dimensionY > h2->GetNbinsY())
0477 dimensionY = h2->GetNbinsY();
0478
0479 return sum / (dimensionX * dimensionY - 1);
0480
0481 }
0482
0483
0484
0485
0486
0487
0488 float ContentSigma::runTest(const MonitorElement* me) {
0489 badChannels_.clear();
0490 if (!me)
0491 return -1;
0492 if (!me->getRootObject())
0493 return -1;
0494 TH1* h = nullptr;
0495
0496 if (verbose_ > 1)
0497 std::cout << "QTest:" << getAlgoName() << "::runTest called on " << me->getFullname() << "\n";
0498
0499 unsigned nbinsX;
0500 unsigned nbinsY;
0501
0502
0503 if (me->kind() == MonitorElement::Kind::TH1F) {
0504 nbinsX = me->getTH1F()->GetXaxis()->GetNbins();
0505 nbinsY = me->getTH1F()->GetYaxis()->GetNbins();
0506 h = me->getTH1F();
0507 }
0508
0509 else if (me->kind() == MonitorElement::Kind::TH1S) {
0510 nbinsX = me->getTH1S()->GetXaxis()->GetNbins();
0511 nbinsY = me->getTH1S()->GetYaxis()->GetNbins();
0512 h = me->getTH1S();
0513 }
0514
0515 else if (me->kind() == MonitorElement::Kind::TH1D) {
0516 nbinsX = me->getTH1D()->GetXaxis()->GetNbins();
0517 nbinsY = me->getTH1D()->GetYaxis()->GetNbins();
0518 h = me->getTH1D();
0519 }
0520
0521 else if (me->kind() == MonitorElement::Kind::TH2F) {
0522 nbinsX = me->getTH2F()->GetXaxis()->GetNbins();
0523 nbinsY = me->getTH2F()->GetYaxis()->GetNbins();
0524 h = me->getTH2F();
0525 }
0526
0527 else if (me->kind() == MonitorElement::Kind::TH2S) {
0528 nbinsX = me->getTH2S()->GetXaxis()->GetNbins();
0529 nbinsY = me->getTH2S()->GetYaxis()->GetNbins();
0530 h = me->getTH2S();
0531 }
0532
0533 else if (me->kind() == MonitorElement::Kind::TH2D) {
0534 nbinsX = me->getTH2D()->GetXaxis()->GetNbins();
0535 nbinsY = me->getTH2D()->GetYaxis()->GetNbins();
0536 h = me->getTH2D();
0537 } else {
0538 if (verbose_ > 0)
0539 std::cout << "QTest:ContentSigma"
0540 << " ME " << me->getFullname() << " does not contain TH1F/TH1S/TH1D or TH2F/TH2S/TH2D, exiting\n";
0541 return -1;
0542 }
0543
0544
0545
0546 if (!rangeInitialized_ || !h->GetXaxis())
0547 return 1;
0548
0549 int fail = 0;
0550 unsigned xMin = 1;
0551 unsigned yMin = 1;
0552 unsigned xMax = nbinsX;
0553 unsigned yMax = nbinsY;
0554 unsigned XBlocks = numXblocks_;
0555 unsigned YBlocks = numYblocks_;
0556 unsigned neighborsX = numNeighborsX_;
0557 unsigned neighborsY = numNeighborsY_;
0558 unsigned Xbinnum = 1;
0559 unsigned Ybinnum = 1;
0560 unsigned XWidth = 0;
0561 unsigned YWidth = 0;
0562
0563 if (neighborsX == 999) {
0564 neighborsX = 0;
0565 }
0566 if (neighborsY == 999) {
0567 neighborsY = 0;
0568 }
0569
0570
0571
0572
0573 if (xMin_ != 0 && xMax_ != 0) {
0574 if ((xMax_ <= nbinsX) && (xMin_ <= xMax_)) {
0575 nbinsX = xMax_ - xMin_ + 1;
0576 xMax = xMax_;
0577 xMin = xMin_;
0578 }
0579 }
0580
0581 if (yMin_ != 0 && yMax_ != 0) {
0582 if ((yMax_ <= nbinsY) && (yMin_ <= yMax_)) {
0583 nbinsY = yMax_ - yMin_ + 1;
0584 yMax = yMax_;
0585 yMin = yMin_;
0586 }
0587 }
0588
0589 if (neighborsX * 2 >= nbinsX) {
0590 if (nbinsX % 2 == 0) {
0591 neighborsX = nbinsX / 2 - 1;
0592 } else {
0593 neighborsX = (nbinsX - 1) / 2;
0594 }
0595 }
0596
0597 if (neighborsY * 2 >= nbinsY) {
0598 if (nbinsY % 2 == 0) {
0599 neighborsY = nbinsY / 2 - 1;
0600 } else {
0601 neighborsY = (nbinsY - 1) / 2;
0602 }
0603 }
0604
0605 if (XBlocks == 999) {
0606 XBlocks = nbinsX;
0607 }
0608 if (YBlocks == 999) {
0609 YBlocks = nbinsY;
0610 }
0611
0612 Xbinnum = nbinsX / XBlocks;
0613 Ybinnum = nbinsY / YBlocks;
0614 for (unsigned groupx = 0; groupx < XBlocks; ++groupx) {
0615 for (unsigned groupy = 0; groupy < YBlocks; ++groupy) {
0616 double blocksum = 0;
0617 for (unsigned binx = 0; binx < Xbinnum; ++binx) {
0618 for (unsigned biny = 0; biny < Ybinnum; ++biny) {
0619 if (groupx * Xbinnum + xMin + binx <= xMax && groupy * Ybinnum + yMin + biny <= yMax) {
0620 blocksum += abs(h->GetBinContent(groupx * Xbinnum + xMin + binx, groupy * Ybinnum + yMin + biny));
0621 }
0622 }
0623 }
0624
0625 double sum = getNeighborSum(groupx, groupy, XBlocks, YBlocks, neighborsX, neighborsY, h);
0626 sum -= blocksum;
0627
0628 if (neighborsX > groupx) {
0629 XWidth = neighborsX + groupx + 1;
0630 } else if (neighborsX > (XBlocks - (groupx + 1))) {
0631 XWidth = (XBlocks - groupx) + neighborsX;
0632 } else {
0633 XWidth = 2 * neighborsX + 1;
0634 }
0635 if (neighborsY > groupy) {
0636 YWidth = neighborsY + groupy + 1;
0637 } else if (neighborsY > (YBlocks - (groupy + 1))) {
0638 YWidth = (YBlocks - groupy) + neighborsY;
0639 } else {
0640 YWidth = 2 * neighborsY + 1;
0641 }
0642
0643 double average = sum / (XWidth * YWidth - 1);
0644 double sigma = getNeighborSigma(average, groupx, groupy, XBlocks, YBlocks, neighborsX, neighborsY, h);
0645
0646 sigma -= (average - blocksum) * (average - blocksum);
0647 double sigma_2 = sqrt(sigma) / sqrt(XWidth * YWidth - 2);
0648 double sigma_real = sigma_2 / (XWidth * YWidth - 1);
0649
0650 double avg_uncrt = 3 * sigma_real;
0651
0652 double probNoisy = ROOT::Math::poisson_cdf_c(blocksum - 1, average + avg_uncrt);
0653 double probDead = ROOT::Math::poisson_cdf(blocksum, average - avg_uncrt);
0654 double thresholdNoisy = ROOT::Math::normal_cdf_c(toleranceNoisy_);
0655 double thresholdDead = ROOT::Math::normal_cdf(-1 * toleranceDead_);
0656
0657 int failureNoisy = 0;
0658 int failureDead = 0;
0659
0660 if (average != 0) {
0661 if (noisy_ && dead_) {
0662 if (blocksum > average) {
0663 failureNoisy = probNoisy < thresholdNoisy;
0664 } else {
0665 failureDead = probDead < thresholdDead;
0666 }
0667 } else if (noisy_) {
0668 if (blocksum > average) {
0669 failureNoisy = probNoisy < thresholdNoisy;
0670 }
0671 } else if (dead_) {
0672 if (blocksum < average) {
0673 failureDead = probDead < thresholdDead;
0674 }
0675 } else {
0676 std::cout << "No test type selected!\n";
0677 }
0678
0679
0680
0681
0682 }
0683
0684 if (failureNoisy || failureDead) {
0685 ++fail;
0686
0687
0688 }
0689 }
0690 }
0691 return 1. * ((XBlocks * YBlocks) - fail) / (XBlocks * YBlocks);
0692 }
0693
0694
0695 double ContentSigma::getNeighborSum(unsigned groupx,
0696 unsigned groupy,
0697 unsigned Xblocks,
0698 unsigned Yblocks,
0699 unsigned neighborsX,
0700 unsigned neighborsY,
0701 const TH1* h) const {
0702 double sum = 0;
0703 unsigned nbinsX = h->GetXaxis()->GetNbins();
0704 unsigned nbinsY = h->GetYaxis()->GetNbins();
0705 unsigned xMin = 1;
0706 unsigned yMin = 1;
0707 unsigned xMax = nbinsX;
0708 unsigned yMax = nbinsY;
0709 unsigned Xbinnum = 1;
0710 unsigned Ybinnum = 1;
0711
0712
0713
0714
0715 if (xMin_ != 0 && xMax_ != 0) {
0716 if ((xMax_ <= nbinsX) && (xMin_ <= xMax_)) {
0717 nbinsX = xMax_ - xMin_ + 1;
0718 xMax = xMax_;
0719 xMin = xMin_;
0720 }
0721 }
0722 if (yMin_ != 0 && yMax_ != 0) {
0723 if ((yMax_ <= nbinsY) && (yMin_ <= yMax_)) {
0724 nbinsY = yMax_ - yMin_ + 1;
0725 yMax = yMax_;
0726 yMin = yMin_;
0727 }
0728 }
0729
0730 if (Xblocks == 999) {
0731 Xblocks = nbinsX;
0732 }
0733 if (Yblocks == 999) {
0734 Yblocks = nbinsY;
0735 }
0736
0737 Xbinnum = nbinsX / Xblocks;
0738 Ybinnum = nbinsY / Yblocks;
0739
0740 unsigned xLow, xHi, yLow, yHi;
0741 if (groupx > neighborsX) {
0742 xLow = (groupx - neighborsX) * Xbinnum + xMin;
0743 if (xLow < xMin) {
0744 xLow = xMin;
0745 }
0746 } else {
0747 xLow = xMin;
0748 }
0749 xHi = (groupx + 1 + neighborsX) * Xbinnum + xMin;
0750 if (xHi > xMax) {
0751 xHi = xMax;
0752 }
0753 if (groupy > neighborsY) {
0754 yLow = (groupy - neighborsY) * Ybinnum + yMin;
0755 if (yLow < yMin) {
0756 yLow = yMin;
0757 }
0758 } else {
0759 yLow = yMin;
0760 }
0761 yHi = (groupy + 1 + neighborsY) * Ybinnum + yMin;
0762 if (yHi > yMax) {
0763 yHi = yMax;
0764 }
0765
0766 for (unsigned xbin = xLow; xbin <= xHi; ++xbin) {
0767 for (unsigned ybin = yLow; ybin <= yHi; ++ybin) {
0768 sum += h->GetBinContent(xbin, ybin);
0769 }
0770 }
0771 return sum;
0772 }
0773
0774
0775 double ContentSigma::getNeighborSigma(double average,
0776 unsigned groupx,
0777 unsigned groupy,
0778 unsigned Xblocks,
0779 unsigned Yblocks,
0780 unsigned neighborsX,
0781 unsigned neighborsY,
0782 const TH1* h) const {
0783 double sigma = 0;
0784 unsigned nbinsX = h->GetXaxis()->GetNbins();
0785 unsigned nbinsY = h->GetYaxis()->GetNbins();
0786 unsigned xMin = 1;
0787 unsigned yMin = 1;
0788 unsigned xMax = nbinsX;
0789 unsigned yMax = nbinsY;
0790 unsigned Xbinnum = 1;
0791 unsigned Ybinnum = 1;
0792 double block_sum;
0793
0794 if (xMin_ != 0 && xMax_ != 0) {
0795 if ((xMax_ <= nbinsX) && (xMin_ <= xMax_)) {
0796 nbinsX = xMax_ - xMin_ + 1;
0797 xMax = xMax_;
0798 xMin = xMin_;
0799 }
0800 }
0801 if (yMin_ != 0 && yMax_ != 0) {
0802 if ((yMax_ <= nbinsY) && (yMin_ <= yMax_)) {
0803 nbinsY = yMax_ - yMin_ + 1;
0804 yMax = yMax_;
0805 yMin = yMin_;
0806 }
0807 }
0808 if (Xblocks == 999) {
0809 Xblocks = nbinsX;
0810 }
0811 if (Yblocks == 999) {
0812 Yblocks = nbinsY;
0813 }
0814
0815 Xbinnum = nbinsX / Xblocks;
0816 Ybinnum = nbinsY / Yblocks;
0817
0818 unsigned xLow, xHi, yLow, yHi;
0819 for (unsigned x_block_count = 0; x_block_count <= 2 * neighborsX; ++x_block_count) {
0820 for (unsigned y_block_count = 0; y_block_count <= 2 * neighborsY; ++y_block_count) {
0821
0822 if (groupx + x_block_count > neighborsX) {
0823 xLow = (groupx + x_block_count - neighborsX) * Xbinnum + xMin;
0824 if (xLow < xMin) {
0825 xLow = xMin;
0826 }
0827 } else {
0828 xLow = xMin;
0829 }
0830 xHi = xLow + Xbinnum;
0831 if (xHi > xMax) {
0832 xHi = xMax;
0833 }
0834 if (groupy + y_block_count > neighborsY) {
0835 yLow = (groupy + y_block_count - neighborsY) * Ybinnum + yMin;
0836 if (yLow < yMin) {
0837 yLow = yMin;
0838 }
0839 } else {
0840 yLow = yMin;
0841 }
0842 yHi = yLow + Ybinnum;
0843 if (yHi > yMax) {
0844 yHi = yMax;
0845 }
0846 block_sum = 0;
0847 for (unsigned x_block_bin = xLow; x_block_bin <= xHi; ++x_block_bin) {
0848 for (unsigned y_block_bin = yLow; y_block_bin <= yHi; ++y_block_bin) {
0849 block_sum += h->GetBinContent(x_block_bin, y_block_bin);
0850 }
0851 }
0852 sigma += (average - block_sum) * (average - block_sum);
0853 }
0854 }
0855 return sigma;
0856 }
0857
0858
0859
0860
0861
0862
0863 float ContentsWithinExpected::runTest(const MonitorElement* me) {
0864 badChannels_.clear();
0865 if (!me)
0866 return -1;
0867 if (!me->getRootObject())
0868 return -1;
0869 TH1* h = nullptr;
0870
0871 if (verbose_ > 1)
0872 std::cout << "QTest:" << getAlgoName() << "::runTest called on " << me->getFullname() << "\n";
0873
0874 int ncx;
0875 int ncy;
0876
0877 if (useEmptyBins_) {
0878
0879 if (me->kind() == MonitorElement::Kind::TH2F) {
0880 ncx = me->getTH2F()->GetXaxis()->GetNbins();
0881 ncy = me->getTH2F()->GetYaxis()->GetNbins();
0882 h = me->getTH2F();
0883 }
0884
0885 else if (me->kind() == MonitorElement::Kind::TH2S) {
0886 ncx = me->getTH2S()->GetXaxis()->GetNbins();
0887 ncy = me->getTH2S()->GetYaxis()->GetNbins();
0888 h = me->getTH2S();
0889 }
0890
0891 else if (me->kind() == MonitorElement::Kind::TH2D) {
0892 ncx = me->getTH2D()->GetXaxis()->GetNbins();
0893 ncy = me->getTH2D()->GetYaxis()->GetNbins();
0894 h = me->getTH2D();
0895 }
0896
0897 else if (me->kind() == MonitorElement::Kind::TPROFILE) {
0898 ncx = me->getTProfile()->GetXaxis()->GetNbins();
0899 ncy = 1;
0900 h = me->getTProfile();
0901 }
0902
0903 else if (me->kind() == MonitorElement::Kind::TPROFILE2D) {
0904 ncx = me->getTProfile2D()->GetXaxis()->GetNbins();
0905 ncy = me->getTProfile2D()->GetYaxis()->GetNbins();
0906 h = me->getTProfile2D();
0907 } else {
0908 if (verbose_ > 0)
0909 std::cout << "QTest:ContentsWithinExpected"
0910 << " ME does not contain TH2F/TH2S/TH2D/TPROFILE/TPROFILE2D, exiting\n";
0911 return -1;
0912 }
0913
0914 int nsum = 0;
0915 double sum = 0.0;
0916 double average = 0.0;
0917
0918 if (checkMeanTolerance_) {
0919
0920 for (int cx = 1; cx <= ncx; ++cx) {
0921 for (int cy = 1; cy <= ncy; ++cy) {
0922 if (me->kind() == MonitorElement::Kind::TH2F) {
0923 sum += h->GetBinContent(h->GetBin(cx, cy));
0924 ++nsum;
0925 } else if (me->kind() == MonitorElement::Kind::TH2S) {
0926 sum += h->GetBinContent(h->GetBin(cx, cy));
0927 ++nsum;
0928 } else if (me->kind() == MonitorElement::Kind::TH2D) {
0929 sum += h->GetBinContent(h->GetBin(cx, cy));
0930 ++nsum;
0931 } else if (me->kind() == MonitorElement::Kind::TPROFILE) {
0932 if (me->getTProfile()->GetBinEntries(h->GetBin(cx)) >= minEntries_ / (ncx)) {
0933 sum += h->GetBinContent(h->GetBin(cx));
0934 ++nsum;
0935 }
0936 } else if (me->kind() == MonitorElement::Kind::TPROFILE2D) {
0937 if (me->getTProfile2D()->GetBinEntries(h->GetBin(cx, cy)) >= minEntries_ / (ncx * ncy)) {
0938 sum += h->GetBinContent(h->GetBin(cx, cy));
0939 ++nsum;
0940 }
0941 }
0942 }
0943 }
0944
0945 if (nsum > 0)
0946 average = sum / nsum;
0947
0948 }
0949
0950 int fail = 0;
0951
0952 for (int cx = 1; cx <= ncx; ++cx) {
0953 for (int cy = 1; cy <= ncy; ++cy) {
0954 bool failMean = false;
0955 bool failRMS = false;
0956 bool failMeanTolerance = false;
0957
0958 if (me->kind() == MonitorElement::Kind::TPROFILE &&
0959 me->getTProfile()->GetBinEntries(h->GetBin(cx)) < minEntries_ / (ncx))
0960 continue;
0961
0962 if (me->kind() == MonitorElement::Kind::TPROFILE2D &&
0963 me->getTProfile2D()->GetBinEntries(h->GetBin(cx, cy)) < minEntries_ / (ncx * ncy))
0964 continue;
0965
0966 if (checkMean_) {
0967 double mean = h->GetBinContent(h->GetBin(cx, cy));
0968 failMean = (mean < minMean_ || mean > maxMean_);
0969 }
0970
0971 if (checkRMS_) {
0972 double rms = h->GetBinError(h->GetBin(cx, cy));
0973 failRMS = (rms < minRMS_ || rms > maxRMS_);
0974 }
0975
0976 if (checkMeanTolerance_) {
0977 double mean = h->GetBinContent(h->GetBin(cx, cy));
0978 failMeanTolerance = (std::abs(mean - average) > toleranceMean_ * std::abs(average));
0979 }
0980
0981 if (failMean || failRMS || failMeanTolerance) {
0982 if (me->kind() == MonitorElement::Kind::TH2F) {
0983 DQMChannel chan(cx, cy, 0, h->GetBinContent(h->GetBin(cx, cy)), h->GetBinError(h->GetBin(cx, cy)));
0984 badChannels_.push_back(chan);
0985 } else if (me->kind() == MonitorElement::Kind::TH2S) {
0986 DQMChannel chan(cx, cy, 0, h->GetBinContent(h->GetBin(cx, cy)), h->GetBinError(h->GetBin(cx, cy)));
0987 badChannels_.push_back(chan);
0988 } else if (me->kind() == MonitorElement::Kind::TH2D) {
0989 DQMChannel chan(cx, cy, 0, h->GetBinContent(h->GetBin(cx, cy)), h->GetBinError(h->GetBin(cx, cy)));
0990 badChannels_.push_back(chan);
0991 } else if (me->kind() == MonitorElement::Kind::TPROFILE) {
0992 DQMChannel chan(
0993 cx, cy, int(me->getTProfile()->GetBinEntries(h->GetBin(cx))), 0, h->GetBinError(h->GetBin(cx)));
0994 badChannels_.push_back(chan);
0995 } else if (me->kind() == MonitorElement::Kind::TPROFILE2D) {
0996 DQMChannel chan(cx,
0997 cy,
0998 int(me->getTProfile2D()->GetBinEntries(h->GetBin(cx, cy))),
0999 h->GetBinContent(h->GetBin(cx, cy)),
1000 h->GetBinError(h->GetBin(cx, cy)));
1001 badChannels_.push_back(chan);
1002 }
1003 ++fail;
1004 }
1005 }
1006 }
1007 return 1. * (ncx * ncy - fail) / (ncx * ncy);
1008 }
1009
1010 else
1011 {
1012 if (me->kind() == MonitorElement::Kind::TH2F) {
1013 ncx = me->getTH2F()->GetXaxis()->GetNbins();
1014 ncy = me->getTH2F()->GetYaxis()->GetNbins();
1015 h = me->getTH2F();
1016 } else if (me->kind() == MonitorElement::Kind::TH2S) {
1017 ncx = me->getTH2S()->GetXaxis()->GetNbins();
1018 ncy = me->getTH2S()->GetYaxis()->GetNbins();
1019 h = me->getTH2S();
1020 } else if (me->kind() == MonitorElement::Kind::TH2D) {
1021 ncx = me->getTH2D()->GetXaxis()->GetNbins();
1022 ncy = me->getTH2D()->GetYaxis()->GetNbins();
1023 h = me->getTH2D();
1024 } else {
1025 if (verbose_ > 0)
1026 std::cout << "QTest:ContentsWithinExpected AS"
1027 << " ME does not contain TH2F/TH2S/TH2D, exiting\n";
1028 return -1;
1029 }
1030
1031
1032 int fail = 0;
1033 for (int cx = 1; cx <= ncx; ++cx) {
1034 for (int cy = 1; cy <= ncy; ++cy) {
1035 bool failure = false;
1036 double Content = h->GetBinContent(h->GetBin(cx, cy));
1037 if (Content)
1038 failure = (Content < minMean_ || Content > maxMean_);
1039 if (failure)
1040 ++fail;
1041 }
1042 }
1043 return 1. * (ncx * ncy - fail) / (ncx * ncy);
1044 }
1045 }
1046
1047 void ContentsWithinExpected::setMeanRange(double xmin, double xmax) {
1048 if (xmax < xmin)
1049 if (verbose_ > 0)
1050 std::cout << "QTest:ContentsWitinExpected"
1051 << " Illogical range: (" << xmin << ", " << xmax << "\n";
1052 minMean_ = xmin;
1053 maxMean_ = xmax;
1054 checkMean_ = true;
1055 }
1056
1057
1058 void ContentsWithinExpected::setRMSRange(double xmin, double xmax) {
1059 if (xmax < xmin)
1060 if (verbose_ > 0)
1061 std::cout << "QTest:ContentsWitinExpected"
1062 << " Illogical range: (" << xmin << ", " << xmax << "\n";
1063 minRMS_ = xmin;
1064 maxRMS_ = xmax;
1065 checkRMS_ = true;
1066 }
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081 float MeanWithinExpected::runTest(const MonitorElement* me) {
1082 if (!me)
1083 return -1;
1084 if (!me->getRootObject())
1085 return -1;
1086 TH1* h = nullptr;
1087
1088 if (verbose_ > 1)
1089 std::cout << "QTest:" << getAlgoName() << "::runTest called on " << me->getFullname() << "\n";
1090
1091 if (minEntries_ != 0 && me->getEntries() < minEntries_)
1092 return -1;
1093
1094 if (me->kind() == MonitorElement::Kind::TH1F) {
1095 h = me->getTH1F();
1096 } else if (me->kind() == MonitorElement::Kind::TH1S) {
1097 h = me->getTH1S();
1098 } else if (me->kind() == MonitorElement::Kind::TH1D) {
1099 h = me->getTH1D();
1100 } else {
1101 if (verbose_ > 0)
1102 std::cout << "QTest:MeanWithinExpected"
1103 << " ME " << me->getFullname() << " does not contain TH1F/TH1S/TH1D, exiting\n";
1104 return -1;
1105 }
1106
1107 if (useRange_) {
1108 double mean = h->GetMean();
1109 if (mean <= xmax_ && mean >= xmin_)
1110 return 1;
1111 else
1112 return 0;
1113 } else if (useSigma_) {
1114 if (sigma_ != 0.) {
1115 double chi = (h->GetMean() - expMean_) / sigma_;
1116 return TMath::Prob(chi * chi, 1);
1117 } else {
1118 if (verbose_ > 0)
1119 std::cout << "QTest:MeanWithinExpected"
1120 << " Error, sigma_ is zero, exiting\n";
1121 return 0;
1122 }
1123 } else if (useRMS_) {
1124 if (h->GetRMS() != 0.) {
1125 double chi = (h->GetMean() - expMean_) / h->GetRMS();
1126 return TMath::Prob(chi * chi, 1);
1127 } else {
1128 if (verbose_ > 0)
1129 std::cout << "QTest:MeanWithinExpected"
1130 << " Error, RMS is zero, exiting\n";
1131 return 0;
1132 }
1133 } else {
1134 if (verbose_ > 0)
1135 std::cout << "QTest:MeanWithinExpected"
1136 << " Error, neither Range, nor Sigma, nor RMS, exiting\n";
1137 return -1;
1138 }
1139 }
1140
1141 void MeanWithinExpected::useRange(double xmin, double xmax) {
1142 useRange_ = true;
1143 useSigma_ = useRMS_ = false;
1144 xmin_ = xmin;
1145 xmax_ = xmax;
1146 if (xmin_ > xmax_)
1147 if (verbose_ > 0)
1148 std::cout << "QTest:MeanWithinExpected"
1149 << " Illogical range: (" << xmin_ << ", " << xmax_ << "\n";
1150 }
1151 void MeanWithinExpected::useSigma(double expectedSigma) {
1152 useSigma_ = true;
1153 useRMS_ = useRange_ = false;
1154 sigma_ = expectedSigma;
1155 if (sigma_ == 0)
1156 if (verbose_ > 0)
1157 std::cout << "QTest:MeanWithinExpected"
1158 << " Expected sigma = " << sigma_ << "\n";
1159 }
1160
1161 void MeanWithinExpected::useRMS() {
1162 useRMS_ = true;
1163 useSigma_ = useRange_ = false;
1164 }
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177 float CompareToMedian::runTest(const MonitorElement* me) {
1178 int32_t nbins = 0, failed = 0;
1179 badChannels_.clear();
1180
1181 if (!me)
1182 return -1;
1183 if (!me->getRootObject())
1184 return -1;
1185 TH1* h = nullptr;
1186
1187 if (verbose_ > 1) {
1188 std::cout << "QTest:" << getAlgoName() << "::runTest called on " << me->getFullname() << "\n";
1189 std::cout << "\tMin = " << _min << "; Max = " << _max << "\n";
1190 std::cout << "\tMinMedian = " << _minMed << "; MaxMedian = " << _maxMed << "\n";
1191 std::cout << "\tUseEmptyBins = " << (_emptyBins ? "Yes" : "No") << "\n";
1192 }
1193
1194 if (me->kind() == MonitorElement::Kind::TPROFILE2D) {
1195 h = me->getTProfile2D();
1196 } else {
1197 if (verbose_ > 0)
1198 std::cout << "QTest:ContentsWithinExpected"
1199 << " ME does not contain TPROFILE2D, exiting\n";
1200 return -1;
1201 }
1202
1203 nBinsX = h->GetNbinsX();
1204 nBinsY = h->GetNbinsY();
1205 int entries = 0;
1206 float median = 0.0;
1207
1208
1209 for (int binX = 1; binX <= nBinsX; binX++) {
1210 reset();
1211
1212 for (int binY = 1; binY <= nBinsY; binY++) {
1213 int bin = h->GetBin(binX, binY);
1214 auto content = (double)h->GetBinContent(bin);
1215 if (content == 0 && !_emptyBins)
1216 continue;
1217 binValues.push_back(content);
1218 entries = me->getTProfile2D()->GetBinEntries(bin);
1219 }
1220 if (binValues.empty())
1221 continue;
1222 nbins += binValues.size();
1223
1224
1225 if (!binValues.empty()) {
1226 int medPos = (int)binValues.size() / 2;
1227 nth_element(binValues.begin(), binValues.begin() + medPos, binValues.end());
1228 median = *(binValues.begin() + medPos);
1229 }
1230
1231
1232 if (median == 0) {
1233 if (verbose_ > 0) {
1234 std::cout << "QTest: Median is 0; the fixed cuts: [" << _minMed << "; " << _maxMed << "] are used\n";
1235 }
1236 for (int binY = 1; binY <= nBinsY; binY++) {
1237 int bin = h->GetBin(binX, binY);
1238 auto content = (double)h->GetBinContent(bin);
1239 entries = me->getTProfile2D()->GetBinEntries(bin);
1240 if (entries == 0)
1241 continue;
1242 if (content > _maxMed || content < _minMed) {
1243 DQMChannel chan(binX, binY, 0, content, h->GetBinError(bin));
1244 badChannels_.push_back(chan);
1245 failed++;
1246 }
1247 }
1248 continue;
1249 }
1250
1251
1252 if (median * entries < _statCut)
1253 continue;
1254
1255
1256 if (median > _maxMed || median < _minMed) {
1257 for (int binY = 1; binY <= nBinsY; binY++) {
1258 int bin = h->GetBin(binX, binY);
1259 auto content = (double)h->GetBinContent(bin);
1260 entries = me->getTProfile2D()->GetBinEntries(bin);
1261 if (entries == 0)
1262 continue;
1263 DQMChannel chan(binX, binY, 0, content / median, h->GetBinError(bin));
1264 badChannels_.push_back(chan);
1265 failed++;
1266 }
1267 continue;
1268 }
1269
1270
1271 float minCut = median * _min;
1272 float maxCut = median * _max;
1273 for (int binY = 1; binY <= nBinsY; binY++) {
1274 int bin = h->GetBin(binX, binY);
1275 auto content = (double)h->GetBinContent(bin);
1276 entries = me->getTProfile2D()->GetBinEntries(bin);
1277 if (entries == 0)
1278 continue;
1279 if (content > maxCut || content < minCut) {
1280 DQMChannel chan(binX, binY, 0, content / median, h->GetBinError(bin));
1281 badChannels_.push_back(chan);
1282 failed++;
1283 }
1284 }
1285 }
1286
1287 if (nbins == 0) {
1288 if (verbose_ > 0)
1289 std::cout << "QTest:CompareToMedian: Histogram is empty" << std::endl;
1290 return 1.;
1291 }
1292 return 1 - (float)failed / nbins;
1293 }
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304 float CompareLastFilledBin::runTest(const MonitorElement* me) {
1305 if (!me)
1306 return -1;
1307 if (!me->getRootObject())
1308 return -1;
1309 TH1* h1 = nullptr;
1310 TH2* h2 = nullptr;
1311 if (verbose_ > 1) {
1312 std::cout << "QTest:" << getAlgoName() << "::runTest called on " << me->getFullname() << "\n";
1313 std::cout << "\tMin = " << _min << "; Max = " << _max << "\n";
1314 }
1315 if (me->kind() == MonitorElement::Kind::TH1F) {
1316 h1 = me->getTH1F();
1317 } else if (me->kind() == MonitorElement::Kind::TH2F) {
1318 h2 = me->getTH2F();
1319 } else {
1320 if (verbose_ > 0)
1321 std::cout << "QTest:ContentsWithinExpected"
1322 << " ME does not contain TH1F or TH2F, exiting\n";
1323 return -1;
1324 }
1325 int lastBinX = 0;
1326 int lastBinY = 0;
1327 float lastBinVal;
1328
1329
1330 if (h1 != nullptr) {
1331 lastBinX = h1->FindLastBinAbove(_average, 1);
1332 lastBinVal = h1->GetBinContent(lastBinX);
1333 if (h1->GetEntries() == 0 || lastBinVal < 0)
1334 return 1;
1335 } else if (h2 != nullptr) {
1336 lastBinX = h2->FindLastBinAbove(_average, 1);
1337 lastBinY = h2->FindLastBinAbove(_average, 2);
1338 if (h2->GetEntries() == 0 || lastBinX < 0 || lastBinY < 0)
1339 return 1;
1340 lastBinVal = h2->GetBinContent(h2->GetBin(lastBinX, lastBinY));
1341 } else {
1342 if (verbose_ > 0)
1343 std::cout << "QTest:" << getAlgoName() << " Histogram does not exist" << std::endl;
1344 return 1;
1345 }
1346 if (verbose_ > 0)
1347 std::cout << "Min and Max values " << _min << " " << _max << " Av value " << _average << " lastBinX " << lastBinX
1348 << " lastBinY " << lastBinY << " lastBinVal " << lastBinVal << std::endl;
1349 if (lastBinVal > _min && lastBinVal <= _max)
1350 return 1;
1351 else
1352 return 0;
1353 }
1354
1355
1356
1357 float CheckVariance::runTest(const MonitorElement* me) {
1358 badChannels_.clear();
1359
1360 if (!me)
1361 return -1;
1362 if (!me->getRootObject())
1363 return -1;
1364 TH1* h = nullptr;
1365
1366 if (verbose_ > 1)
1367 std::cout << "QTest:" << getAlgoName() << "::runTest called on " << me->getFullname() << "\n";
1368
1369 if (me->kind() == MonitorElement::Kind::TH1F) {
1370 h = me->getTH1F();
1371 }
1372
1373 else if (me->kind() == MonitorElement::Kind::TH1D) {
1374 h = me->getTH1D();
1375 } else if (me->kind() == MonitorElement::Kind::TPROFILE) {
1376 h = me->getTProfile();
1377 } else {
1378 if (verbose_ > 0)
1379 std::cout << "QTest:CheckVariance"
1380 << " ME " << me->getFullname() << " does not contain TH1F/TH1D/TPROFILE, exiting\n";
1381 return -1;
1382 }
1383
1384 int ncx = h->GetXaxis()->GetNbins();
1385
1386 double sum = 0;
1387 double sum2 = 0;
1388 for (int bin = 1; bin <= ncx; ++bin) {
1389 double contents = h->GetBinContent(bin);
1390 sum += contents;
1391 }
1392 if (sum == 0)
1393 return -1;
1394 double avg = sum / ncx;
1395
1396 for (int bin = 1; bin <= ncx; ++bin) {
1397 double contents = h->GetBinContent(bin);
1398 sum2 += (contents - avg) * (contents - avg);
1399 }
1400
1401 double Variance = TMath::Sqrt(sum2 / ncx);
1402 return Variance;
1403 }