Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[14_0_X] Add ParticleFlow Client for Online DQM - GPUvsCPU comparison #45204

Merged
merged 1 commit into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions DQM/Integration/python/clients/pfgpu_dqm_sourceclient-live_cfg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#-------------------------------------
# PF DQM Application using New DQM Sources/Clients
# Taken from HCAL DQM Client
#-------------------------------------

#-------------------------------------
# Standard Python Imports
#-------------------------------------
import os, sys, socket, string

#-------------------------------------
# Standard CMSSW Imports/Definitions
#-------------------------------------
import FWCore.ParameterSet.Config as cms
from Configuration.Eras.Era_Run3_cff import Run3
process = cms.Process('PFDQM', Run3)
subsystem = 'ParticleFlow'
cmssw = os.getenv("CMSSW_VERSION").split("_")
debugstr = "### PFDQM::cfg::DEBUG: "
warnstr = "### PFDQM::cfg::WARN: "
errorstr = "### PFDQM::cfg::ERROR:"
useOfflineGT = False
useFileInput = False
useMap = False
unitTest = 'unitTest=True' in sys.argv

#-------------------------------------
# Central DQM Stuff imports
#-------------------------------------
from DQM.Integration.config.online_customizations_cfi import *

if useOfflineGT:
process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
process.GlobalTag.globaltag = autoCond['run3_data_prompt']
else:
process.load('DQM.Integration.config.FrontierCondition_GT_cfi')

if unitTest:
process.load("DQM.Integration.config.unitteststreamerinputsource_cfi")
from DQM.Integration.config.unitteststreamerinputsource_cfi import options
elif useFileInput:
process.load("DQM.Integration.config.fileinputsource_cfi")
from DQM.Integration.config.fileinputsource_cfi import options
else:
process.load('DQM.Integration.config.inputsource_cfi')
from DQM.Integration.config.inputsource_cfi import options

process.load('DQM.Integration.config.environment_cfi')

#-------------------------------------
# Central DQM Customization
#-------------------------------------

if not useFileInput:
# stream label
if process.runType.getRunType() == process.runType.hi_run:
process.source.streamLabel = "streamHIDQMGPUvsCPU"
else:
process.source.streamLabel = "streamDQMGPUvsCPU"

process.dqmEnv.subSystemFolder = subsystem
process.dqmSaver.tag = 'PFGPU'
process.dqmSaver.runNumber = options.runNumber
process.dqmSaverPB.tag = 'PFGPU'
process.dqmSaverPB.runNumber = options.runNumber
process = customise(process)
process.DQMStore.verbose = 0
if not unitTest and not useFileInput :
if not options.BeamSplashRun :
process.source.minEventsPerLumi = 100

#-------------------------------------
# CMSSW/Hcal non-DQM Related Module import
#-------------------------------------
process.load("Configuration.StandardSequences.GeometryRecoDB_cff")
process.load('FWCore.MessageLogger.MessageLogger_cfi')

#-------------------------------------
# CMSSW/Hcal non-DQM Related Module Settings
# -> runType
# -> Generic Input tag for the Raw Collection
# -> cmssw version
#----------------------------------------------

runType = process.runType.getRunType()
runTypeName = process.runType.getRunTypeName()
isCosmicRun = runTypeName=="cosmic_run" or runTypeName=="cosmic_run_stage1"
isHeavyIon = runTypeName=="hi_run"
cmssw = os.getenv("CMSSW_VERSION").split("_")


#-------------------------------------
# PF DQM Tasks and Harvesters import
# New Style
#-------------------------------------
process.load('DQM.PFTasks.pfHcalGPUComparisonTask_cfi')

#-------------------------------------
# Some Settings before Finishing up
# New Style Modules
#-------------------------------------
oldsubsystem = subsystem
#-------------------------------------
# Hcal DQM Tasks/Clients Sequences Definition
#-------------------------------------
process.tasksPath = cms.Path(
process.pfHcalGPUComparisonTask
)

#-------------------------------------
# Paths/Sequences Definitions
#-------------------------------------

process.dqmPath = cms.EndPath(
process.dqmEnv)
process.dqmPath1 = cms.EndPath(
process.dqmSaver
*process.dqmSaverPB
)

process.schedule = cms.Schedule(
process.tasksPath,
process.dqmPath,
process.dqmPath1
)

#-------------------------------------
# Scheduling and Process Customizations
#-------------------------------------
process.options = cms.untracked.PSet(
Rethrow = cms.untracked.vstring(
"TooManyProducts",
"TooFewProducts"
),
TryToContinue = cms.untracked.vstring('ProductNotFound')
)
process.options.wantSummary = True

# tracer
#process.Tracer = cms.Service("Tracer")
print("Final Source settings:", process.source)
process = customise(process)
6 changes: 6 additions & 0 deletions DQM/PFTasks/BuildFile.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<use name="FWCore/Framework"/>
<use name="rootmath"/>
<use name="DQM/HcalCommon"/>
<export>
<lib name="PFTasks"/>
</export>
7 changes: 7 additions & 0 deletions DQM/PFTasks/plugins/BuildFile.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<use name="FWCore/Framework"/>
<use name="DataFormats/ParticleFlowReco"/>
<use name="DataFormats/ParticleFlowCandidate"/>
<use name="rootmath"/>
<use name="DQM/HcalTasks"/>
<use name="DQM/HcalCommon"/>
<flags EDM_PLUGIN="1"/>
223 changes: 223 additions & 0 deletions DQM/PFTasks/plugins/PFHcalGPUComparisonTask.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
// -*- C++ -*-
//

#include "DQM/HcalCommon/interface/DQTask.h"
#include "DQM/HcalCommon/interface/Utilities.h"
#include "DQM/HcalCommon/interface/HashFilter.h"
#include "DQM/HcalCommon/interface/Container1D.h"
#include "DQM/HcalCommon/interface/Container2D.h"
#include "DQM/HcalCommon/interface/ContainerProf1D.h"
#include "DQM/HcalCommon/interface/ContainerProf2D.h"
#include "DQM/HcalCommon/interface/ContainerSingle1D.h"
#include "DQM/HcalCommon/interface/ContainerSingle2D.h"
#include "DQM/HcalCommon/interface/ContainerSingleProf2D.h"
#include "DQM/HcalCommon/interface/ElectronicsMap.h"
#include "DQMServices/Core/interface/DQMEDAnalyzer.h"
#include "DQMServices/Core/interface/DQMStore.h"
#include "DataFormats/CaloRecHit/interface/CaloCluster.h"
#include "DataFormats/CaloRecHit/interface/CaloClusterFwd.h"
#include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
#include "DataFormats/CaloTowers/interface/CaloTowerDetId.h"
#include "DataFormats/Common/interface/Handle.h"
#include "DataFormats/DetId/interface/DetId.h"
#include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
#include "DataFormats/HcalDetId/interface/HcalDetId.h"
#include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
#include "DataFormats/Math/interface/Vector3D.h"
#include "DataFormats/Math/interface/deltaR.h"
#include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
#include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
#include "DataFormats/ParticleFlowReco/interface/PFBlockElementCluster.h"
#include "DataFormats/ParticleFlowReco/interface/PFBlockElementTrack.h"
#include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
#include "DataFormats/ParticleFlowReco/interface/PFClusterFwd.h"
#include "DataFormats/ParticleFlowReco/interface/PFLayer.h"
#include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
#include "DataFormats/ParticleFlowReco/interface/PFRecHitFraction.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/EventSetup.h"
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/PluginManager/interface/ModuleDef.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"

#include <cmath>
#ifdef PFLOW_DEBUG
#define LOGVERB(x) edm::LogVerbatim(x)
#else
#define LOGVERB(x) LogTrace(x)
#endif

using namespace hcaldqm;
using namespace hcaldqm::constants;
using namespace hcaldqm::filter;

class PFHcalGPUComparisonTask : public hcaldqm::DQTask {
public:
PFHcalGPUComparisonTask(edm::ParameterSet const&);
~PFHcalGPUComparisonTask() override = default;

void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
std::shared_ptr<hcaldqm::Cache> globalBeginLuminosityBlock(edm::LuminosityBlock const&,
edm::EventSetup const&) const override;
void globalEndLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);

private:
void _process(edm::Event const&, edm::EventSetup const&) override;
void _resetMonitors(hcaldqm::UpdateFreq) override;

edm::EDGetTokenT<reco::PFClusterCollection> pfClusterTok_ref_;
edm::EDGetTokenT<reco::PFClusterCollection> pfClusterTok_target_;

MonitorElement* pfCluster_Multiplicity_HostvsDevice_;
MonitorElement* pfCluster_Energy_HostvsDevice_;
MonitorElement* pfCluster_RecHitMultiplicity_HostvsDevice_;
MonitorElement* pfCluster_Layer_HostvsDevice_;
MonitorElement* pfCluster_Depth_HostvsDevice_;
MonitorElement* pfCluster_Eta_HostvsDevice_;
MonitorElement* pfCluster_Phi_HostvsDevice_;
MonitorElement* pfCluster_DuplicateMatches_HostvsDevice_;

std::string pfCaloGPUCompDir_;
};

PFHcalGPUComparisonTask::PFHcalGPUComparisonTask(edm::ParameterSet const& conf)
: DQTask(conf),
pfClusterTok_ref_{
consumes<reco::PFClusterCollection>(conf.getUntrackedParameter<edm::InputTag>("pfClusterToken_ref"))},
pfClusterTok_target_{
consumes<reco::PFClusterCollection>(conf.getUntrackedParameter<edm::InputTag>("pfClusterToken_target"))},
pfCaloGPUCompDir_{conf.getUntrackedParameter<std::string>("name")} {}

void PFHcalGPUComparisonTask::bookHistograms(DQMStore::IBooker& ibooker, edm::Run const& r, edm::EventSetup const& es) {
_subsystem = "ParticleFlow";
ibooker.setCurrentFolder("ParticleFlow/" + pfCaloGPUCompDir_);
DQTask::bookHistograms(ibooker, r, es);
// Book monitoring elements
const char* histo;

histo = "pfCluster_Multiplicity_HostvsDevice";
const char* histoAxis = "pfCluster_Multiplicity_HostvsDevice;Multiplicity Device;Multiplicity Device";
pfCluster_Multiplicity_HostvsDevice_ = ibooker.book2I(histo, histoAxis, 1000, 0, 1000, 1000, 0, 1000);

histo = "pfCluster_Energy_HostvsDevice";
histoAxis = "pfCluster_Energy_HostvsDevice;Energy Host [GeV];Energy Device [GeV]";
pfCluster_Energy_HostvsDevice_ = ibooker.book2D(histo, histoAxis, 500, 0, 500, 500, 0, 500);

histo = "pfCluster_RecHitMultiplicity_HostvsDevice";
histoAxis = "pfCluster_RecHitMultiplicity_HostvsDevice;RecHit Multiplicity Host;RecHit Multiplicity Device";
pfCluster_RecHitMultiplicity_HostvsDevice_ = ibooker.book2I(histo, histoAxis, 100, 0, 100, 100, 0, 100);

histo = "pfCluster_Layer_HostvsDevice";
histoAxis = "pfCluster_Layer_HostvsDevice;Cluster Layer Host;Cluster Layer Device";
pfCluster_Layer_HostvsDevice_ = ibooker.book2I(histo, histoAxis, 4, 0, 3, 4, 0, 3);

histo = "pfCluster_Depth_HostvsDevice";
histoAxis = "pfCluster_Depth_HostvsDevice;Cluster Depth Host;Cluster Depth Device";
pfCluster_Depth_HostvsDevice_ = ibooker.book2I(histo, histoAxis, 8, 0, 7, 8, 0, 7);

histo = "pfCluster_Eta_HostvsDevice";
histoAxis = "pfCluster_Eta_HostvsDevice;Cluster #eta Host;Cluster #eta Device";
pfCluster_Eta_HostvsDevice_ = ibooker.book2D(histo, histoAxis, 100, -5.f, 5.f, 100, -5.f, 5.f);

histo = "pfCluster_Phi_HostvsDevice";
histoAxis = "pfCluster_Phi_HostvsDevice;Cluster #phi Host;Cluster #phi Device";
pfCluster_Phi_HostvsDevice_ = ibooker.book2D(histo, histoAxis, 100, -M_PI, M_PI, 100, -M_PI, M_PI);

histo = "pfCluster_DuplicateMatches_HostvsDevice";
histoAxis = "pfCluster_Duplicates_HostvsDevice;Cluster Duplicates Host;Cluster Duplicates Device";
pfCluster_DuplicateMatches_HostvsDevice_ = ibooker.book1I(histo, histoAxis, 100, 0., 1000);
}

void PFHcalGPUComparisonTask::_resetMonitors(hcaldqm::UpdateFreq uf) { DQTask::_resetMonitors(uf); }

void PFHcalGPUComparisonTask::_process(edm::Event const& event, edm::EventSetup const&) {
edm::Handle<reco::PFClusterCollection> pfClusters_ref;
event.getByToken(pfClusterTok_ref_, pfClusters_ref);

edm::Handle<reco::PFClusterCollection> pfClusters_target;
event.getByToken(pfClusterTok_target_, pfClusters_target);

auto lumiCache = luminosityBlockCache(event.getLuminosityBlock().index());
_currentLS = lumiCache->currentLS;
// Compare per-event PF cluster multiplicity

if (pfClusters_ref->size() != pfClusters_target->size())
LOGVERB("PFCaloGPUComparisonTask") << " PFCluster multiplicity " << pfClusters_ref->size() << " "
<< pfClusters_target->size();
pfCluster_Multiplicity_HostvsDevice_->Fill((float)pfClusters_ref->size(), (float)pfClusters_target->size());

//
// Find matching PF cluster pairs
std::vector<int> matched_idx;
matched_idx.reserve(pfClusters_ref->size());
for (unsigned i = 0; i < pfClusters_ref->size(); ++i) {
bool matched = false;
for (unsigned j = 0; j < pfClusters_target->size(); ++j) {
if (pfClusters_ref->at(i).seed() == pfClusters_target->at(j).seed()) {
if (!matched) {
matched = true;
matched_idx.push_back((int)j);
} else {
edm::LogWarning("PFCaloGPUComparisonTask") << "Found duplicate match";
pfCluster_DuplicateMatches_HostvsDevice_->Fill((int)j);
}
}
}
if (!matched)
matched_idx.push_back(-1); // if you don't find a match, put a dummy number
}

//
// Plot matching PF cluster variables
for (unsigned i = 0; i < pfClusters_ref->size(); ++i) {
if (matched_idx[i] >= 0) {
unsigned int j = matched_idx[i];
int ref_energy_bin =
pfCluster_Energy_HostvsDevice_->getTH2F()->GetXaxis()->FindBin(pfClusters_ref->at(i).energy());
int target_energy_bin =
pfCluster_Energy_HostvsDevice_->getTH2F()->GetXaxis()->FindBin(pfClusters_target->at(j).energy());
if (ref_energy_bin != target_energy_bin)
edm::LogPrint("PFCaloGPUComparisonTask")
<< "Off-diagonal energy bin entries: " << pfClusters_ref->at(i).energy() << " "
<< pfClusters_ref->at(i).eta() << " " << pfClusters_ref->at(i).phi() << " "
<< pfClusters_target->at(j).energy() << " " << pfClusters_target->at(j).eta() << " "
<< pfClusters_target->at(j).phi() << std::endl;
pfCluster_Energy_HostvsDevice_->Fill(pfClusters_ref->at(i).energy(), pfClusters_target->at(j).energy());
pfCluster_Layer_HostvsDevice_->Fill(pfClusters_ref->at(i).layer(), pfClusters_target->at(j).layer());
pfCluster_Eta_HostvsDevice_->Fill(pfClusters_ref->at(i).eta(), pfClusters_target->at(j).eta());
pfCluster_Phi_HostvsDevice_->Fill(pfClusters_ref->at(i).phi(), pfClusters_target->at(j).phi());
pfCluster_Depth_HostvsDevice_->Fill(pfClusters_ref->at(i).depth(), pfClusters_target->at(j).depth());
pfCluster_RecHitMultiplicity_HostvsDevice_->Fill((float)pfClusters_ref->at(i).recHitFractions().size(),
(float)pfClusters_target->at(j).recHitFractions().size());
}
}
}

std::shared_ptr<hcaldqm::Cache> PFHcalGPUComparisonTask::globalBeginLuminosityBlock(edm::LuminosityBlock const& lb,
edm::EventSetup const& es) const {
return DQTask::globalBeginLuminosityBlock(lb, es);
}

void PFHcalGPUComparisonTask::globalEndLuminosityBlock(edm::LuminosityBlock const& lb, edm::EventSetup const& es) {
if (_ptype != fOnline)
return;

auto lumiCache = luminosityBlockCache(lb.index());
_currentLS = lumiCache->currentLS;

// in the end always do the DQTask::endLumi
DQTask::globalEndLuminosityBlock(lb, es);
}

void PFHcalGPUComparisonTask::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
edm::ParameterSetDescription desc;
desc.addUntracked<std::string>("name", "pfCaloGPUCompDir");
desc.addUntracked<edm::InputTag>("pfClusterToken_ref", edm::InputTag("hltParticleFlowClusterHCALSerialSync"));
desc.addUntracked<edm::InputTag>("pfClusterToken_target", edm::InputTag("hltParticleFlowClusterHCAL"));
descriptions.addWithDefaultLabel(desc);
}

DEFINE_FWK_MODULE(PFHcalGPUComparisonTask);