diff --git a/DQM/CTPPS/plugins/CTPPSRandomDQMSource.cc b/DQM/CTPPS/plugins/CTPPSRandomDQMSource.cc new file mode 100644 index 0000000000000..514fdd610b99a --- /dev/null +++ b/DQM/CTPPS/plugins/CTPPSRandomDQMSource.cc @@ -0,0 +1,206 @@ +/****************************************** + * + * This is a part of CTPPSDQM software. + * Authors: + * A. Bellora (Universita' e INFN Torino) + * + *******************************************/ + +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/InputTag.h" + +#include "DQMServices/Core/interface/DQMEDAnalyzer.h" +#include "DQMServices/Core/interface/DQMStore.h" + +#include "DataFormats/Common/interface/DetSetVector.h" + +#include "CondFormats/PPSObjects/interface/CTPPSPixelIndices.h" +#include "DataFormats/CTPPSDetId/interface/CTPPSDetId.h" +#include "DataFormats/CTPPSDigi/interface/CTPPSPixelDigi.h" +#include "DataFormats/CTPPSDigi/interface/CTPPSPixelDataError.h" +#include "DataFormats/CTPPSReco/interface/CTPPSPixelCluster.h" +#include "DataFormats/CTPPSReco/interface/CTPPSPixelLocalTrack.h" +#include "DataFormats/Common/interface/TriggerResults.h" + +#include + +//----------------------------------------------------------------------------- + +class CTPPSRandomDQMSource : public DQMEDAnalyzer { +public: + CTPPSRandomDQMSource(const edm::ParameterSet &ps); + ~CTPPSRandomDQMSource() override = default; + static void fillDescriptions(edm::ConfigurationDescriptions &descriptions); + +protected: + void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override; + void analyze(edm::Event const &e, edm::EventSetup const &eSetup) override; + +private: + edm::EDGetTokenT> const tokenDigi_; + + static constexpr int kNArms_ = 2; + static constexpr int kNStationMAX_ = 3; // in an arm + static constexpr int kNRPotsMAX_ = 6; // per station + static constexpr int kNplaneMAX_ = 6; // per RPot + static constexpr int kFirstRPn_ = 3, kLastRPn_ = 4; + static constexpr int kStationIDMAX_ = 4; // possible range of ID + static constexpr int kRPotsIDMAX_ = 8; // possible range of ID + + const std::string folderName_ = "PPSRANDOM/RandomPixel"; + + unsigned int rpStatusWord_ = 0x8008; // 220_fr_hr(stn2rp3)+ 210_fr_hr + int rpStatus_[kStationIDMAX_][kRPotsIDMAX_]; // symmetric in both arms + int stationStatus_[kStationIDMAX_]; // symmetric in both arms + const int kIndexNotValid = 0; + + MonitorElement *hBX_; + + static constexpr int kRPotsTotalNumber_ = kNArms_ * kNStationMAX_ * kNRPotsMAX_; + + int RPindexValid_[kRPotsTotalNumber_]; + MonitorElement *h2HitsVsBXRandoms_[kRPotsTotalNumber_]; + + int getRPindex(int arm, int station, int rp) const { + if (arm < 0 || station < 0 || rp < 0) + return (kIndexNotValid); + if (arm > 1 || station >= kNStationMAX_ || rp >= kNRPotsMAX_) + return (kIndexNotValid); + int rc = (arm * kNStationMAX_ + station) * kNRPotsMAX_ + rp; + return (rc); + } +}; + +//------------------------------------------------------------------------------- + +CTPPSRandomDQMSource::CTPPSRandomDQMSource(const edm::ParameterSet &ps) + : tokenDigi_(consumes>(ps.getParameter("tagRPixDigi"))), + folderName_(ps.getUntrackedParameter("folderName", "PPSRANDOM/RandomPixel")), + rpStatusWord_(ps.getUntrackedParameter("RPStatusWord", 0x8008)) { + for (int stn = 0; stn < kStationIDMAX_; stn++) { + stationStatus_[stn] = 0; + for (int rp = 0; rp < kRPotsIDMAX_; rp++) + rpStatus_[stn][rp] = 0; + } + + unsigned int rpSts = rpStatusWord_ << 1; + for (int stn = 0; stn < kNStationMAX_; stn++) { + int stns = 0; + for (int rp = 0; rp < kNRPotsMAX_; rp++) { + rpSts = (rpSts >> 1); + rpStatus_[stn][rp] = rpSts & 1; + if (rpStatus_[stn][rp] > 0) + stns = 1; + } + stationStatus_[stn] = stns; + } + + for (int index = 0; index < 2 * 3 * kNRPotsMAX_; index++) + RPindexValid_[index] = 0; +} + +//-------------------------------------------------------------------------- + +void CTPPSRandomDQMSource::bookHistograms(DQMStore::IBooker &ibooker, edm::Run const &, edm::EventSetup const &) { + ibooker.cd(); + ibooker.setCurrentFolder(folderName_); + + hBX_ = ibooker.book1D("events per BX", "ctpps_pixel;Event.BX", 4002, -1.5, 4000. + 0.5); + + for (int arm = 0; arm < kNArms_; arm++) { + CTPPSDetId ID(CTPPSDetId::sdTrackingPixel, arm, 0); + std::string sd; + ID.armName(sd, CTPPSDetId::nShort); + sd = folderName_ + "/sector " + sd; + + ibooker.setCurrentFolder(sd); + + for (int stn = 0; stn < kNStationMAX_; stn++) { + if (stationStatus_[stn] == 0) + continue; + ID.setStation(stn); + std::string stnd; + CTPPSDetId(ID.stationId()).stationName(stnd, CTPPSDetId::nShort); + stnd = sd + "/station " + stnd; + + ibooker.setCurrentFolder(stnd); + + for (int rp = kFirstRPn_; rp < kLastRPn_; rp++) { // only installed pixel pots + ID.setRP(rp); + std::string rpd, rpTitle; + CTPPSDetId(ID.rpId()).rpName(rpTitle, CTPPSDetId::nFull); + CTPPSDetId(ID.rpId()).rpName(rpd, CTPPSDetId::nShort); + rpd = stnd + "/" + rpd; + + ibooker.setCurrentFolder(rpd); + + int indexP = getRPindex(arm, stn, rp); + RPindexValid_[indexP] = 1; + + h2HitsVsBXRandoms_[indexP] = ibooker.book2D("Digi per plane per BX - random triggers", + rpTitle + ";Event.BX;Plane", + 4002, + -1.5, + 4000. + 0.5, + kNplaneMAX_, + 0, + kNplaneMAX_); + h2HitsVsBXRandoms_[indexP]->getTH2F()->SetOption("colz"); + + } // end for(int rp=0; rpFill(event.bunchCrossing()); + + for (int arm = 0; arm < 2; arm++) { + for (int stn = 0; stn < kNStationMAX_; stn++) { + if (!stationStatus_[stn]) + continue; + for (int rp = 0; rp < kNRPotsMAX_; rp++) { + if (!rpStatus_[stn][rp]) + continue; + int index = getRPindex(arm, stn, rp); + if (RPindexValid_[index] == 0) + continue; + + for (int p = 0; p < kNplaneMAX_; p++) { + CTPPSPixelDetId planeId(arm, stn, rp, p); + auto pix_d = pixDigi->find(planeId.rawId()); + if (pix_d != pixDigi->end()) { + int n_digis = pix_d->size(); + h2HitsVsBXRandoms_[index]->Fill(event.bunchCrossing(), p, n_digis); + } + } + } // end for (int rp=0; rp("tagRPixDigi", edm::InputTag("ctppsPixelDigisAlCaRecoProducer")); + desc.addUntracked("folderName", "PPSRANDOM/RandomPixel"); + desc.addUntracked("RPStatusWord", 0x8008); + descriptions.add("ctppsRandomDQMSource", desc); +} + +//--------------------------------------------------------------------------- +DEFINE_FWK_MODULE(CTPPSRandomDQMSource); diff --git a/DQM/CTPPS/python/ctppsDQM_cff.py b/DQM/CTPPS/python/ctppsDQM_cff.py index b44cb02db3d11..413038a3156b7 100644 --- a/DQM/CTPPS/python/ctppsDQM_cff.py +++ b/DQM/CTPPS/python/ctppsDQM_cff.py @@ -17,6 +17,8 @@ from DQM.CTPPS.ctppsCommonDQMSource_cfi import * +from DQM.CTPPS.ctppsRandomDQMSource_cfi import * + # sequences used by the online DQM in normal running ctppsCommonDQMSourceOnline = ctppsCommonDQMSource.clone( makeProtonRecoPlots = False @@ -51,6 +53,14 @@ makeProtonRecoPlots = True ) +# sequences used by the dedicated random trigger stream +_ctppsDQMRandomSource = cms.Sequence( + ctppsRandomDQMSource +) + +_ctppsDQMRandomHarvest = cms.Sequence( +) + #Check if perLSsaving is enabled to mask MEs vs LS from Configuration.ProcessModifiers.dqmPerLSsaving_cff import dqmPerLSsaving dqmPerLSsaving.toModify(ctppsDiamondDQMSource, perLSsaving=True) @@ -99,3 +109,8 @@ ctppsDQMOfflineHarvest = cms.Sequence() ctpps.toReplaceWith(ctppsDQMOfflineSource, _ctppsDQMOfflineSource) ctpps.toReplaceWith(ctppsDQMOfflineHarvest, _ctppsDQMOfflineHarvest) + +ctppsDQMRandomSource = cms.Sequence() +ctppsDQMRandomHarvest = cms.Sequence() +ctpps.toReplaceWith(ctppsDQMRandomSource, _ctppsDQMRandomSource) +ctpps.toReplaceWith(ctppsDQMRandomHarvest, _ctppsDQMRandomHarvest) diff --git a/DQM/CTPPS/python/ctppsRandomDQMSource_cfi.py b/DQM/CTPPS/python/ctppsRandomDQMSource_cfi.py new file mode 100644 index 0000000000000..d83a2ca8461cf --- /dev/null +++ b/DQM/CTPPS/python/ctppsRandomDQMSource_cfi.py @@ -0,0 +1,9 @@ +import FWCore.ParameterSet.Config as cms + +from DQMServices.Core.DQMEDAnalyzer import DQMEDAnalyzer + +ctppsRandomDQMSource = DQMEDAnalyzer('CTPPSRandomDQMSource', + tagRPixDigi = cms.InputTag("ctppsPixelDigisAlCaRecoProducer", ""), + folderName = cms.untracked.string("PPSRANDOM/RandomPixel"), + RPStatusWord = cms.untracked.uint32(0x8008) # rpots in readout:220_fr_hr; 210_fr_hr +) \ No newline at end of file diff --git a/DQM/CTPPS/test/pps_random_dqm_test_from_alcaraw_cfg.py b/DQM/CTPPS/test/pps_random_dqm_test_from_alcaraw_cfg.py new file mode 100644 index 0000000000000..7cb77ad19b70b --- /dev/null +++ b/DQM/CTPPS/test/pps_random_dqm_test_from_alcaraw_cfg.py @@ -0,0 +1,62 @@ +import FWCore.ParameterSet.Config as cms + +from Configuration.Eras.Modifier_ctpps_cff import ctpps +process = cms.Process('ctppsRandomDQMfromRAW', ctpps) + +# minimum of logs +process.MessageLogger = cms.Service("MessageLogger", + statistics = cms.untracked.vstring(), + destinations = cms.untracked.vstring('cerr'), + cerr = cms.untracked.PSet( + threshold = cms.untracked.string('WARNING') + ) +) + +# load DQM framework +process.load("DQM.Integration.config.environment_cfi") +process.dqmEnv.subSystemFolder = "CTPPS" +process.dqmEnv.eventInfoFolder = "EventInfo" +process.dqmSaver.path = "" +process.dqmSaver.tag = "CTPPS" + +# raw data source +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring( + '/store/group/dpg_ctpps/comm_ctpps/PixelRandomTrigger2023/outputExpressPPSRandom.root' + ), + + inputCommands = cms.untracked.vstring( + 'drop *', + 'keep FEDRawDataCollection_*_*_*' + ) +) + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(-1) +) + +# global tag - conditions for P5 cluster +process.load("DQM.Integration.config.FrontierCondition_GT_cfi") + +# raw-to-digi conversion +from EventFilter.CTPPSRawToDigi.ctppsRawToDigi_cff import ctppsPixelDigis as _ctppsPixelDigis +process.ctppsPixelDigisAlCaRecoProducer = _ctppsPixelDigis.clone(inputLabel = 'hltPPSCalibrationRaw') + +# CTPPS DQM modules +process.load("DQM.CTPPS.ctppsDQM_cff") + +process.path = cms.Path( + process.ctppsPixelDigisAlCaRecoProducer * + process.ctppsDQMRandomSource * + process.ctppsDQMRandomHarvest +) + +process.end_path = cms.EndPath( + process.dqmEnv + + process.dqmSaver +) + +process.schedule = cms.Schedule( + process.path, + process.end_path +) diff --git a/DQM/Integration/python/clients/ppsrandom_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/ppsrandom_dqm_sourceclient-live_cfg.py new file mode 100644 index 0000000000000..8240ed8331816 --- /dev/null +++ b/DQM/Integration/python/clients/ppsrandom_dqm_sourceclient-live_cfg.py @@ -0,0 +1,97 @@ +import FWCore.ParameterSet.Config as cms + +import sys +from Configuration.Eras.Era_Run3_cff import Run3 +process = cms.Process('CTPPSDQM', Run3) + +test = False +unitTest = False + +if 'unitTest=True' in sys.argv: + unitTest=True + +# event source +if unitTest: + process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options +elif not test: + # for live online DQM in P5 + process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options +else: + # for testing in lxplus + process.load("DQM.Integration.config.fileinputsource_cfi") + from DQM.Integration.config.fileinputsource_cfi import options + process.source.fileNames = cms.untracked.vstring( + "/store/group/dpg_ctpps/comm_ctpps/PixelRandomTrigger2023/outputExpressPPSRandom.root" + ) + process.source.inputCommands = cms.untracked.vstring( + 'drop *', + 'keep FEDRawDataCollection_*_*_*' + ) + +process.source.streamLabel = "streamDQMPPSRandom" + +# DQM environment +process.load("DQM.Integration.config.environment_cfi") +process.dqmEnv.subSystemFolder = 'PPSRANDOM' +process.dqmSaver.tag = 'PPSRANDOM' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'PPSRANDOM' +process.dqmSaverPB.runNumber = options.runNumber + +if test: + process.dqmSaver.path = "." + process.dqmSaverPB.path = "./pb" + +process.load("DQMServices.Components.DQMProvInfo_cfi") + +# message logger +process.MessageLogger = cms.Service("MessageLogger", + destinations = cms.untracked.vstring('cout'), + cout = cms.untracked.PSet(threshold = cms.untracked.string('WARNING')) +) + +# global tag - conditions for P5 cluster +process.load("DQM.Integration.config.FrontierCondition_GT_cfi") + +# raw-to-digi conversion +from EventFilter.CTPPSRawToDigi.ctppsRawToDigi_cff import ctppsPixelDigis as _ctppsPixelDigis +process.ctppsPixelDigisAlCaRecoProducer = _ctppsPixelDigis.clone(inputLabel = 'hltPPSCalibrationRaw') + +# loading Meta tags used by commonDQM +process.load('EventFilter.OnlineMetaDataRawToDigi.onlineMetaDataRawToDigi_cfi') +process.onlineMetaDataDigis = cms.EDProducer('OnlineMetaDataRawToDigi') + + +# DQM Modules +process.load("DQM.CTPPS.ctppsDQM_cff") + +# processing path +process.recoStep = cms.Sequence( + process.ctppsPixelDigisAlCaRecoProducer * + process.onlineMetaDataDigis +) + +process.dqmModules = cms.Sequence( + process.ctppsDQMRandomSource * + process.ctppsDQMRandomHarvest +) + +process.path = cms.Path( + process.recoStep * + process.dqmModules * + + process.dqmEnv * + process.dqmSaver * + process.dqmSaverPB +) + +process.schedule = cms.Schedule(process.path) + +process.dqmProvInfo.runType = process.runType.getRunTypeName() + +# Process customizations included here +from DQM.Integration.config.online_customizations_cfi import * +print("Final Source settings:", process.source) +process = customise(process)