Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:07:22

0001 #include "DQM/EcalMonitorTasks/interface/TimingTask.h"
0002 
0003 #include "DQM/EcalCommon/interface/EcalDQMCommonUtils.h"
0004 #include "FWCore/Framework/interface/EventSetup.h"
0005 
0006 #include "FWCore/Framework/interface/Event.h"
0007 
0008 #include "DataFormats/EcalRawData/interface/EcalDCCHeaderBlock.h"
0009 
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 
0012 namespace ecaldqm {
0013   TimingTask::TimingTask()
0014       : DQWorkerTask(),
0015         bxBinEdges_(),
0016         bxBin_(0.),
0017         chi2ThresholdEB_(0.),
0018         chi2ThresholdEE_(0.),
0019         energyThresholdEB_(0.),
0020         energyThresholdEE_(0.),
0021         energyThresholdEEFwd_(0.),
0022         timingVsBXThreshold_(0.),
0023         timeErrorThreshold_(0.),
0024         meTimeMapByLS(nullptr) {}
0025 
0026   void TimingTask::setParams(edm::ParameterSet const& _params) {
0027     bxBinEdges_ = onlineMode_ ? _params.getUntrackedParameter<std::vector<int> >("bxBins")
0028                               : _params.getUntrackedParameter<std::vector<int> >("bxBinsFine");
0029     chi2ThresholdEB_ = _params.getUntrackedParameter<double>("chi2ThresholdEB");
0030     chi2ThresholdEE_ = _params.getUntrackedParameter<double>("chi2ThresholdEE");
0031     energyThresholdEB_ = _params.getUntrackedParameter<double>("energyThresholdEB");
0032     energyThresholdEE_ = _params.getUntrackedParameter<double>("energyThresholdEE");
0033     energyThresholdEEFwd_ = _params.getUntrackedParameter<double>("energyThresholdEEFwd");
0034     timingVsBXThreshold_ = _params.getUntrackedParameter<double>("timingVsBXThreshold");
0035     timeErrorThreshold_ = _params.getUntrackedParameter<double>("timeErrorThreshold");
0036     splashSwitch_ = _params.getUntrackedParameter<bool>("splashSwitch", false);
0037   }
0038 
0039   bool TimingTask::filterRunType(short const* _runType) {
0040     for (int iFED(0); iFED < nDCC; iFED++) {
0041       if (_runType[iFED] == EcalDCCHeaderBlock::COSMIC || _runType[iFED] == EcalDCCHeaderBlock::MTCC ||
0042           _runType[iFED] == EcalDCCHeaderBlock::COSMICS_GLOBAL ||
0043           _runType[iFED] == EcalDCCHeaderBlock::PHYSICS_GLOBAL || _runType[iFED] == EcalDCCHeaderBlock::COSMICS_LOCAL ||
0044           _runType[iFED] == EcalDCCHeaderBlock::PHYSICS_LOCAL)
0045         return true;
0046     }
0047 
0048     return false;
0049   }
0050 
0051   void TimingTask::beginEvent(edm::Event const& _evt, edm::EventSetup const& _es, bool const& ByLumiResetSwitch, bool&) {
0052     using namespace std;
0053     std::vector<int>::iterator pBin = std::upper_bound(bxBinEdges_.begin(), bxBinEdges_.end(), _evt.bunchCrossing());
0054     bxBin_ = static_cast<int>(pBin - bxBinEdges_.begin()) - 0.5;
0055     if (ByLumiResetSwitch) {
0056       meTimeMapByLS = &MEs_.at("TimeMapByLS");
0057       if (timestamp_.iLumi % 10 == 0)
0058         meTimeMapByLS->reset(GetElectronicsMap());
0059     }
0060   }
0061 
0062   void TimingTask::runOnRecHits(EcalRecHitCollection const& _hits, Collections _collection) {
0063     MESet& meTimeAmp(MEs_.at("TimeAmp"));
0064     MESet& meTimeAmpAll(MEs_.at("TimeAmpAll"));
0065     MESet& meTimingVsBX(onlineMode_ ? MEs_.at("BarrelTimingVsBX") : MEs_.at("BarrelTimingVsBXFineBinned"));
0066     MESet& meTimeAll(MEs_.at("TimeAll"));
0067     MESet& meTimeAllMap(MEs_.at("TimeAllMap"));
0068     MESet& meTimeMap(MEs_.at("TimeMap"));  // contains cumulative run stats => not suitable for Trend plots
0069     MESet& meTime1D(MEs_.at("Time1D"));
0070     MESet& meChi2(MEs_.at("Chi2"));
0071 
0072     uint32_t goodOROOTBits(0x1 << EcalRecHit::kGood | 0x1 << EcalRecHit::kOutOfTime);
0073     int signedSubdet;
0074 
0075     std::for_each(_hits.begin(), _hits.end(), [&](EcalRecHitCollection::value_type const& hit) {
0076       if (!hit.checkFlagMask(goodOROOTBits))
0077         return;
0078 
0079       DetId id(hit.id());
0080 
0081       float time(hit.time());
0082       float energy(hit.energy());
0083 
0084       float energyThreshold;
0085       if (id.subdetId() == EcalBarrel) {
0086         energyThreshold = energyThresholdEB_;
0087         signedSubdet = EcalBarrel;
0088       } else {
0089         energyThreshold = (isForward(id)) ? energyThresholdEEFwd_ : energyThresholdEE_;
0090         EEDetId eeId(hit.id());
0091         if (eeId.zside() < 0)
0092           signedSubdet = -EcalEndcap;
0093         else
0094           signedSubdet = EcalEndcap;
0095       }
0096 
0097       if (energy > energyThreshold)
0098         meChi2.fill(getEcalDQMSetupObjects(), signedSubdet, hit.chi2());
0099 
0100       if (!splashSwitch_) {  //Not applied for splash events
0101         float chi2Threshold;
0102         if (id.subdetId() == EcalBarrel)
0103           chi2Threshold = chi2ThresholdEB_;
0104         else
0105           chi2Threshold = chi2ThresholdEE_;
0106 
0107         //Apply cut on chi2 of pulse shape fit
0108         if (hit.chi2() > chi2Threshold)
0109           return;
0110       }
0111       // Apply cut based on timing error of rechit
0112       if (hit.timeError() > timeErrorThreshold_)
0113         return;
0114 
0115       meTimeAmp.fill(getEcalDQMSetupObjects(), id, energy, time);
0116       meTimeAmpAll.fill(getEcalDQMSetupObjects(), id, energy, time);
0117 
0118       if (energy > timingVsBXThreshold_ && signedSubdet == EcalBarrel)
0119         meTimingVsBX.fill(getEcalDQMSetupObjects(), bxBin_, time);
0120 
0121       if (energy > energyThreshold) {
0122         meTimeAll.fill(getEcalDQMSetupObjects(), id, time);
0123         meTimeMap.fill(getEcalDQMSetupObjects(), id, time);
0124         meTimeMapByLS->fill(getEcalDQMSetupObjects(), id, time);
0125         meTime1D.fill(getEcalDQMSetupObjects(), id, time);
0126         meTimeAllMap.fill(getEcalDQMSetupObjects(), id, time);
0127       }
0128     });
0129   }
0130 
0131   // For In-time vs Out-of-Time amplitude correlation MEs:
0132   // Only UncalibRecHits carry information about OOT amplitude
0133   // But still need to make sure we apply similar cuts as on RecHits
0134   void TimingTask::runOnUncalibRecHits(EcalUncalibratedRecHitCollection const& _uhits) {
0135     MESet& meTimeAmpBXm(MEs_.at("TimeAmpBXm"));
0136     MESet& meTimeAmpBXp(MEs_.at("TimeAmpBXp"));
0137 
0138     for (EcalUncalibratedRecHitCollection::const_iterator uhitItr(_uhits.begin()); uhitItr != _uhits.end(); ++uhitItr) {
0139       // Apply reconstruction quality cuts
0140       if (!uhitItr->checkFlag(EcalUncalibratedRecHit::kGood))
0141         continue;
0142       DetId id(uhitItr->id());
0143       float chi2Threshold = 0.;
0144       float ampThreshold = 0.;
0145       if (id.subdetId() == EcalBarrel) {
0146         chi2Threshold = chi2ThresholdEB_;
0147         ampThreshold = 20. * energyThresholdEB_;  // 1 GeV ~ 20 ADC in EB
0148       } else {
0149         chi2Threshold = chi2ThresholdEE_;
0150         ampThreshold = 5. * ((isForward(id)) ? energyThresholdEEFwd_ : energyThresholdEE_);  // 1 GeV ~ 5 ADC in EE
0151       }
0152 
0153       if (uhitItr->chi2() > chi2Threshold)
0154         continue;
0155 
0156       // Apply amplitude cut based on approx rechit energy
0157       float amp(uhitItr->amplitude());
0158       if (amp < ampThreshold)
0159         continue;
0160 
0161       // Apply jitter timing cut based on approx rechit timing
0162       float timeOff(id.subdetId() == EcalBarrel ? 0.4 : 1.8);
0163       float hitTime(uhitItr->jitter() * 25. + timeOff);  // 1 jitter ~ 25 ns
0164       if (std::abs(hitTime) >= 5.)
0165         continue;
0166 
0167       // Fill MEs
0168       meTimeAmpBXm.fill(getEcalDQMSetupObjects(), id, amp, uhitItr->outOfTimeAmplitude(4));  // BX-1
0169       meTimeAmpBXp.fill(getEcalDQMSetupObjects(), id, amp, uhitItr->outOfTimeAmplitude(6));  // BX+1
0170     }
0171   }
0172 
0173   DEFINE_ECALDQM_WORKER(TimingTask);
0174 }  // namespace ecaldqm