Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
#include "DQM/EcalMonitorClient/interface/IntegrityClient.h"

#include "CondFormats/EcalObjects/interface/EcalDQMStatusHelper.h"

#include "FWCore/ParameterSet/interface/ParameterSet.h"

#include "DataFormats/EcalDetId/interface/EBDetId.h"
#include "DataFormats/EcalDetId/interface/EEDetId.h"

#include "DQM/EcalCommon/interface/EcalDQMCommonUtils.h"
#include "DQM/EcalCommon/interface/MESetNonObject.h"

namespace ecaldqm {
  IntegrityClient::IntegrityClient() : DQWorkerClient(), errFractionThreshold_(0.), processedEvents(0) {
    qualitySummaries_.insert("Quality");
    qualitySummaries_.insert("QualitySummary");
  }

  void IntegrityClient::setParams(edm::ParameterSet const& _params) {
    errFractionThreshold_ = _params.getUntrackedParameter<double>("errFractionThreshold");
  }

  void IntegrityClient::setTokens(edm::ConsumesCollector& _collector) {
    chStatusToken = _collector.esConsumes<edm::Transition::EndLuminosityBlock>();
  }

  // Check Channel Status Record at every endLumi
  // Used to fill Channel Status Map MEs
  void IntegrityClient::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const& _es) {
    chStatus = &_es.getData(chStatusToken);
  }

  void IntegrityClient::producePlots(ProcessType) {
    uint32_t mask(1 << EcalDQMStatusHelper::CH_ID_ERROR | 1 << EcalDQMStatusHelper::CH_GAIN_ZERO_ERROR |
                  1 << EcalDQMStatusHelper::CH_GAIN_SWITCH_ERROR | 1 << EcalDQMStatusHelper::TT_ID_ERROR |
                  1 << EcalDQMStatusHelper::TT_SIZE_ERROR);

    MESet& meQuality(MEs_.at("Quality"));
    MESet& meQualitySummary(MEs_.at("QualitySummary"));
    MESet& meChStatus(MEs_.at("ChStatus"));

    MESet const& sOccupancy(sources_.at("Occupancy"));
    MESet const& sGain(sources_.at("Gain"));
    MESet const& sChId(sources_.at("ChId"));
    MESet const& sGainSwitch(sources_.at("GainSwitch"));
    MESet const& sTowerId(sources_.at("TowerId"));
    MESet const& sBlockSize(sources_.at("BlockSize"));
    MESetNonObject const& sNumEvents(static_cast<MESetNonObject&>(sources_.at("NumEvents")));

    //Get the no.of events per LS calculated in OccupancyTask
    int nEv = sNumEvents.getFloatValue();
    processedEvents += nEv;  //Sum it up to get the total processed events for the whole run.

    //TTID errors nomalized by total no.of events in a run.
    MESet& meTTIDNorm(MEs_.at("TowerIdNormalized"));
    MESet::iterator tEnd(meTTIDNorm.end(GetElectronicsMap()));
    for (MESet::iterator tItr(meTTIDNorm.beginChannel(GetElectronicsMap())); tItr != tEnd;
         tItr.toNextChannel(GetElectronicsMap())) {
      DetId id(tItr->getId());
      float towerid(sTowerId.getBinContent(getEcalDQMSetupObjects(), id));
      tItr->setBinContent(towerid / processedEvents);
    }
    // Fill Channel Status Map MEs
    // Record is checked for updates at every endLumi and filled here
    MESet::iterator chSEnd(meChStatus.end(GetElectronicsMap()));
    for (MESet::iterator chSItr(meChStatus.beginChannel(GetElectronicsMap())); chSItr != chSEnd;
         chSItr.toNextChannel(GetElectronicsMap())) {
      DetId id(chSItr->getId());

      EcalChannelStatusMap::const_iterator chIt(nullptr);

      // Set appropriate channel map (EB or EE)
      if (id.subdetId() == EcalBarrel) {
        EBDetId ebid(id);
        chIt = chStatus->find(ebid);
      } else {
        EEDetId eeid(id);
        chIt = chStatus->find(eeid);
      }

      // Get status code and fill ME
      if (chIt != chStatus->end()) {
        uint16_t code(chIt->getEncodedStatusCode());
        chSItr->setBinContent(code);
      }

    }  // Channel Status Map

    MESet::iterator qEnd(meQuality.end(GetElectronicsMap()));
    MESet::const_iterator occItr(GetElectronicsMap(), sOccupancy);
    for (MESet::iterator qItr(meQuality.beginChannel(GetElectronicsMap())); qItr != qEnd;
         qItr.toNextChannel(GetElectronicsMap())) {
      occItr = qItr;

      DetId id(qItr->getId());

      bool doMask(meQuality.maskMatches(id, mask, statusManager_, GetTrigTowerMap()));

      float entries(occItr->getBinContent());

      float gain(sGain.getBinContent(getEcalDQMSetupObjects(), id));
      float chid(sChId.getBinContent(getEcalDQMSetupObjects(), id));
      float gainswitch(sGainSwitch.getBinContent(getEcalDQMSetupObjects(), id));

      float towerid(sTowerId.getBinContent(getEcalDQMSetupObjects(), id));
      float blocksize(sBlockSize.getBinContent(getEcalDQMSetupObjects(), id));

      if (entries + gain + chid + gainswitch + towerid + blocksize < 1.) {
        qItr->setBinContent(doMask ? kMUnknown : kUnknown);
        meQualitySummary.setBinContent(getEcalDQMSetupObjects(), id, doMask ? kMUnknown : kUnknown);
        continue;
      }

      float chErr((gain + chid + gainswitch + towerid + blocksize) /
                  (entries + gain + chid + gainswitch + towerid + blocksize));

      if (chErr > errFractionThreshold_) {
        qItr->setBinContent(doMask ? kMBad : kBad);
        meQualitySummary.setBinContent(getEcalDQMSetupObjects(), id, doMask ? kMBad : kBad);
      } else {
        qItr->setBinContent(doMask ? kMGood : kGood);
        meQualitySummary.setBinContent(getEcalDQMSetupObjects(), id, doMask ? kMGood : kGood);
      }
    }

    // Quality check: set an entire FED to BAD if "any" DCC-SRP or DCC-TCC mismatch errors are detected AND the number of events affected by the DCC-SRP or DCC-TCC mismatch errors is more than 1% of the events analyzed in the run
    // Fill mismatch statistics
    MESet const& sBXSRP(sources_.at("BXSRP"));
    MESet const& sBXTCC(sources_.at("BXTCC"));
    std::vector<bool> hasMismatchDCC(nDCC, false);
    for (unsigned iDCC(0); iDCC < nDCC; ++iDCC) {
      int nBXSRPdesync = sBXSRP.getBinContent(getEcalDQMSetupObjects(), iDCC + 1);
      int nBXTCCdesync = sBXTCC.getBinContent(getEcalDQMSetupObjects(), iDCC + 1);

      if (nBXSRPdesync > 50. || nBXTCCdesync > 50.) {  // "any" => 50
        if (nBXSRPdesync > int(0.01 * processedEvents) ||
            nBXTCCdesync >
                int(0.01 *
                    processedEvents)) {  // check if the events with DCC-SRP or DCC-TCC desyncs for the given DCC is more than 1% of the events analyzed
          hasMismatchDCC[iDCC] = true;
        }
      }
    }
    // Analyze mismatch statistics
    for (MESet::iterator qsItr(meQualitySummary.beginChannel(GetElectronicsMap()));
         qsItr != meQualitySummary.end(GetElectronicsMap());
         qsItr.toNextChannel(GetElectronicsMap())) {
      DetId id(qsItr->getId());
      unsigned iDCC(dccId(id, GetElectronicsMap()) - 1);
      if (hasMismatchDCC[iDCC])
        meQualitySummary.setBinContent(
            getEcalDQMSetupObjects(),
            id,
            meQualitySummary.maskMatches(id, mask, statusManager_, GetTrigTowerMap()) ? kMBad : kBad);
    }

  }  // producePlots()

  DEFINE_ECALDQM_WORKER(IntegrityClient);
}  // namespace ecaldqm