From 248d490960dd1e4335c36e124ee1cf548288233b Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 23 Sep 2020 12:35:56 +0200 Subject: [PATCH 01/30] Commenting out TensorFlow usage and turn some funcions inactive (temporarily) --- RecoHGCal/GraphReco/BuildFile.xml | 3 +- .../GraphReco/interface/InferenceWindow.h | 20 +++++--- RecoHGCal/GraphReco/plugins/BuildFile.xml | 3 ++ RecoHGCal/GraphReco/src/InferenceWindow.cpp | 46 ++++++++++++++++--- 4 files changed, 58 insertions(+), 14 deletions(-) diff --git a/RecoHGCal/GraphReco/BuildFile.xml b/RecoHGCal/GraphReco/BuildFile.xml index fc30404ff2366..1e5ddc2f1bd07 100644 --- a/RecoHGCal/GraphReco/BuildFile.xml +++ b/RecoHGCal/GraphReco/BuildFile.xml @@ -8,9 +8,10 @@ + - \ No newline at end of file + diff --git a/RecoHGCal/GraphReco/interface/InferenceWindow.h b/RecoHGCal/GraphReco/interface/InferenceWindow.h index 22759675c547c..76073a1ba72c2 100644 --- a/RecoHGCal/GraphReco/interface/InferenceWindow.h +++ b/RecoHGCal/GraphReco/interface/InferenceWindow.h @@ -9,7 +9,7 @@ #define SRC_RECOHGCAL_GRAPHRECO_INTERFACE_INFERENCEWINDOW_H_ #include "../interface/WindowBase.h" -#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" +//#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" class InferenceWindow: public WindowBase { public: @@ -26,9 +26,11 @@ class InferenceWindow: public WindowBase { void fillFeatureArrays(); - void evaluate(tensorflow::Session* sess); + //void evaluate(tensorflow::Session* sess); + void evaluate(); - void getOutput() const{}//needs output format etc. + //tensorflow::Tensor getOutput(); + void getOutput(); void flattenRechitFeatures(); @@ -40,12 +42,16 @@ class InferenceWindow: public WindowBase { InferenceWindow(){} // - //Inference - tensorflow::Tensor inputTensor; - tensorflow::NamedTensorList inputTensorList; - tensorflow::Tensor outputTensor; + //Inference + //tensorflow::Tensor inputTensor_; + //tensorflow::NamedTensorList inputTensorList_; + //tensorflow::Tensor outputTensor_; + std::string inputTensorName_; std::string outputTensorName_; + size_t padSize_; + size_t nFeatures_; + bool batchedModel_; }; diff --git a/RecoHGCal/GraphReco/plugins/BuildFile.xml b/RecoHGCal/GraphReco/plugins/BuildFile.xml index 932fce8cc0b24..4c33a6fe0560c 100644 --- a/RecoHGCal/GraphReco/plugins/BuildFile.xml +++ b/RecoHGCal/GraphReco/plugins/BuildFile.xml @@ -6,6 +6,9 @@ + + + diff --git a/RecoHGCal/GraphReco/src/InferenceWindow.cpp b/RecoHGCal/GraphReco/src/InferenceWindow.cpp index a0b917305c5c2..307c8016773c9 100644 --- a/RecoHGCal/GraphReco/src/InferenceWindow.cpp +++ b/RecoHGCal/GraphReco/src/InferenceWindow.cpp @@ -31,7 +31,9 @@ std::vector InferenceWindow::createWindows(size_t nSegmentsPhi, } void InferenceWindow::fillFeatureArrays(){ - float * data = 0; //inputTensor.data() + //FIXME + //float* data = inputTensor_.flat().data(); + float* data = 0; if(getMode() == useRechits){ for(const auto& rh:recHits){ @@ -47,20 +49,52 @@ void InferenceWindow::fillFeatureArrays(){ for(const auto& tr:tracks_){ fillTrackFeatures(data,tr); } - //do some zero padding if needed - - //FIXME + //do some zero padding if needed + if(getMode() == useRechits) + { + for (float i = nFeatures_*recHits.size(); i < nFeatures_*padSize_; i++, data++) + { + *data = 0.; + } + } } void InferenceWindow::setupTFInterface(size_t padSize, size_t nFeatures, bool batchedModel, const std::string& inputTensorName, - const std::string& outputTensorName) { + const std::string& outputTensorName) { + + inputTensorName_ = inputTensorName; + outputTensorName_ = outputTensorName; + + padSize_ = padSize; + nFeatures_ = nFeatures; + //inputTensor_ = tensorflow::Tensor(tensorflow::DT_FLOAT, { 1, (int) padSize_, (int) nFeatures_ }); } -void InferenceWindow::evaluate(tensorflow::Session* sess) { +// void InferenceWindow::evaluate(tensorflow::Session* sess) { + +// std::vector outputs; +// tensorflow::run(sess, { { inputTensorName_, inputTensor_ } }, { outputTensorName_ }, &outputs); +// outputTensor_ = outputs[0]; +// } +void InferenceWindow::evaluate() { + + //FIXME +} + + +// tensorflow::Tensor InferenceWindow::getOutput(){ + +// return outputTensor_; +// } + +void InferenceWindow::getOutput(){ + + //FIXME + } From df29d1c8b528b16130914911f69b65249712eb75 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 23 Sep 2020 12:36:58 +0200 Subject: [PATCH 02/30] Deleting old window inference analyzer that uses TF --- .../GraphReco/plugins/WindowInference.cc | 210 ------------------ .../GraphReco/test/windowInference_cfg.py | 68 ------ 2 files changed, 278 deletions(-) delete mode 100644 RecoHGCal/GraphReco/plugins/WindowInference.cc delete mode 100644 RecoHGCal/GraphReco/test/windowInference_cfg.py diff --git a/RecoHGCal/GraphReco/plugins/WindowInference.cc b/RecoHGCal/GraphReco/plugins/WindowInference.cc deleted file mode 100644 index e9a1d2e6ecd00..0000000000000 --- a/RecoHGCal/GraphReco/plugins/WindowInference.cc +++ /dev/null @@ -1,210 +0,0 @@ -/* - * CMSSW plugin that performs a Window-based inference of networks using RecHits. - * - * Author: Marcel Rieger - */ - -#include - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Framework/interface/stream/EDAnalyzer.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Utilities/interface/Exception.h" - -#include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" - -#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" - -#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" - -#include "RecoHGCal/GraphReco/interface/InferenceWindow.h" - - -// macros for simplified logs -// message logger disabled for the moment -// #define INFO edm::LogInfo("WindowInference") -// #define WARNING edm::LogWarning("WindowInference") -// #define ERROR edm::LogError("WindowInference") -#define INFO std::cout << "WindowInference INFO : " -#define WARNING std::cout << "WindowInference WARNING: " -#define ERROR std::cout << "WindowInference ERROR : " - -// datastructure hold by edm::GlobalCache -struct WindowInferenceCache { - WindowInferenceCache(const edm::ParameterSet& config) : - graphDef(nullptr) { - } - - std::atomic graphDef; -}; - -class WindowInference: public edm::stream::EDAnalyzer< - edm::GlobalCache > { - public: - explicit WindowInference(const edm::ParameterSet&, - const WindowInferenceCache*); - ~WindowInference(); - - // methods for handling the global cache - static std::unique_ptr initializeGlobalCache( - const edm::ParameterSet&); - static void globalEndJob(const WindowInferenceCache*); - - private: - void beginStream(edm::StreamID); - void endStream(); - void analyze(const edm::Event&, const edm::EventSetup&); - - void fillWindows(const edm::Event&); - - - // options - std::vector recHitCollections_; - - std::string inputTensorName_; - std::string outputTensorName_; - bool batchedModel_; - size_t padSize_; - - // tokens - std::vector > recHitTokens_; - - // rechit tools - hgcal::RecHitTools recHitTools_; - - // windows - std::vector windows_; - - double minEta_; - double maxEta_; - double etaFrameWidth_; - double phiFrameWidth_; - size_t nEtaSegments_; - size_t nPhiSegments_; - - // the tensorflow session - tensorflow::Session* session_; - - -}; - -std::unique_ptr WindowInference::initializeGlobalCache( - const edm::ParameterSet& config) { - // this method is supposed to create, initialize and - //return a WindowInferenceCache instance - WindowInferenceCache* windowInferenceCache = new WindowInferenceCache( - config); - - // load the graph def and save it - std::string graphPath = config.getParameter("graphPath"); - INFO<< "loading graph from " << graphPath << std::endl; - windowInferenceCache->graphDef = tensorflow::loadGraphDef(graphPath); - - // set some global configs, such as the TF log level - tensorflow::setLogging("0"); - - return std::unique_ptr(windowInferenceCache); -} - -void WindowInference::globalEndJob( - const WindowInferenceCache* windowInferenceCache) { - // reset the graphDef - if (windowInferenceCache->graphDef != nullptr) { - delete windowInferenceCache->graphDef; - } -} - -WindowInference::WindowInference(const edm::ParameterSet& config, - const WindowInferenceCache* windowInferenceCache) : - recHitCollections_( - config.getParameter >( - "recHitCollections")), inputTensorName_( - config.getParameter("inputTensorName")), outputTensorName_( - config.getParameter("outputTensorName")), batchedModel_( - config.getParameter("batchedModel")), padSize_( - (size_t) config.getParameter("padSize")), - - //FIXME: actually these are all not needed if windows are created in the constructor! - minEta_(config.getParameter("minEta")), - maxEta_(config.getParameter("maxEta")), - etaFrameWidth_(config.getParameter("etaFrameWidth")), - phiFrameWidth_(config.getParameter("phiFrameWidth")), - nEtaSegments_((size_t)config.getParameter("nEtaSegments")), - nPhiSegments_((size_t)config.getParameter("nPhiSegments")), - session_(nullptr){ - // sanity checks for sliding windows - - - // get tokens - for (edm::InputTag& recHitCollection : recHitCollections_) { - recHitTokens_.push_back( - consumes(recHitCollection)); - } - - // mount the graphDef stored in windowInferenceCache onto the session - //FIXME - // session_ = tensorflow::createSession(windowInferenceCache->graphDef); -} - -WindowInference::~WindowInference() { -} - - -void WindowInference::beginStream(edm::StreamID streamId) { - windows_ = InferenceWindow::createWindows(nPhiSegments_,nEtaSegments_,minEta_,maxEta_,etaFrameWidth_,phiFrameWidth_); -} - -void WindowInference::endStream() { - // close the session - //FIXME - // tensorflow::closeSession(session_); - session_ = nullptr; - - - windows_.clear(); -} - -void WindowInference::analyze(const edm::Event& event, - const edm::EventSetup& setup) { - recHitTools_.getEventSetup(setup); - - - // fill rechits into windows - fillWindows(event); - - // run the evaluation per window - for (auto & window : windows_) { - window.evaluate(session_); - } - - // reconstruct showers using all windows and put them into the event - //reconstructShowers(); - - // clear all windows - for (auto& window : windows_) { - window.clear(); - } -} - - - -void WindowInference::fillWindows(const edm::Event& event) { - - if (!windows_.size()) { - throw cms::Exception("NoWindows") << "no windows initialized"; - } - - //Window::mode windowmode = windows_.at(0).getMode(); - // skip layer cluster or rechit loop accordingly - - //FIXME - - -} - -//remove - -DEFINE_FWK_MODULE(WindowInference); diff --git a/RecoHGCal/GraphReco/test/windowInference_cfg.py b/RecoHGCal/GraphReco/test/windowInference_cfg.py deleted file mode 100644 index 873959fce5faf..0000000000000 --- a/RecoHGCal/GraphReco/test/windowInference_cfg.py +++ /dev/null @@ -1,68 +0,0 @@ -# coding: utf-8 - -""" -Test config to run the WindowInference plugin. -""" - - -import os -import subprocess - -import FWCore.ParameterSet.Config as cms -from FWCore.ParameterSet.VarParsing import VarParsing - - -# determine the location of _this_ file -if "__file__" in globals(): - this_dir = os.path.dirname(os.path.abspath(__file__)) -else: - this_dir = os.path.expandvars("$CMSSW_BASE/src/RecoHGCal/GraphReco/test") - -# ensure that the graph exists -# if not, call the create_dummy_graph.py script in a subprocess since tensorflow complains -# when its loaded twice (once here in python, once in c++) -graph_path = os.path.join(this_dir, "graph.pb") -if not os.path.exists(graph_path): - script_path = os.path.join(this_dir, "create_dummy_graph.py") - code = subprocess.call(["python", script_path, graph_path]) - if code != 0: - raise Exception("create_dummy_graph.py failed") - -# setup minimal options -options = VarParsing("python") -options.setDefault("inputFiles", "file:///eos/cms/store/cmst3/group/hgcal/CMG_studies/hgcalsim/sim.RecoTask/closeby_1.0To100.0_idsmix_dR0.3_n5_rnd1_s1/prod5/reco_2327_n100.root") -options.parseArguments() - -# define the process to run for the Phase2 era -from Configuration.Eras.Era_Phase2C8_cff import Phase2C8 -process = cms.Process("HGR", Phase2C8) - -# standard sequences and modules -process.load("Configuration.StandardSequences.Services_cff") -process.load("FWCore.MessageService.MessageLogger_cfi") -process.load("Configuration.Geometry.GeometryExtended2023D41Reco_cff") -process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") - -# minimal configuration -process.MessageLogger.cerr.FwkReport.reportEvery = 1 -process.maxEvents = cms.untracked.PSet(input=cms.untracked.int32(10)) -process.source = cms.Source("PoolSource", fileNames=cms.untracked.vstring(options.inputFiles)) - -# global tag -from Configuration.AlCa.GlobalTag import GlobalTag -process.GlobalTag = GlobalTag(process.GlobalTag, "auto:phase2_realistic", "") - -# process options -process.options = cms.untracked.PSet( - allowUnscheduled=cms.untracked.bool(True), - wantSummary=cms.untracked.bool(True), -) - -# load and configure the windowInference module -from RecoHGCal.GraphReco.windowInference_cfi import windowInference -process.windowInference = windowInference.clone( - graphPath=cms.string(graph_path), -) - -# define the path to run -process.p = cms.Path(process.windowInference) From b7d4cda9d8ee0c0067e31e17f87bcbfe0228e856 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 23 Sep 2020 12:39:45 +0200 Subject: [PATCH 03/30] Producer to create pepr PF candidates from hits, but with dummy functionality as placeholder for inference via Triton --- .../plugins/peprCandidateFromHitProducer.cc | 430 ++++++++++++++++++ .../peprCandidateFromHitProducer_cfi.py | 43 ++ 2 files changed, 473 insertions(+) create mode 100644 RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc create mode 100644 RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc new file mode 100644 index 0000000000000..ba8a8da2d0dcb --- /dev/null +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -0,0 +1,430 @@ +/* + * CMSSW plugin that performs a Window-based inference of networks using RecHits. + * + * Authors: Marcel Rieger + * Gerrit Van Onsem + */ + +#include + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/Exception.h" + +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/TrackReco/interface/TrackFwd.h" +#include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" +#include "DataFormats/CaloRecHit/interface/CaloClusterFwd.h" +#include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" + +#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" +//#include "HGCSimTruth/HGCSimTruth/interface/SimClusterTools.h" + +//#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" + +#include "RecoHGCal/GraphReco/interface/InferenceWindow.h" + +#include "DataFormats/Common/interface/View.h" + +#include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h" +#include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h" +#include "DataFormats/Candidate/interface/LeafCandidate.h" + +#include "DataFormats/HGCalReco/interface/Trackster.h" + +using namespace ticl; + +// macros for simplified logs +// message logger disabled for the moment +// #define INFO edm::LogInfo("peprCandidateFromHitProducer") +// #define WARNING edm::LogWarning("peprCandidateFromHitProducer") +// #define ERROR edm::LogError("peprCandidateFromHitProducer") +#define INFO std::cout << "peprCandidateFromHitProducer INFO : " +#define WARNING std::cout << "peprCandidateFromHitProducer WARNING: " +#define ERROR std::cout << "peprCandidateFromHitProducer ERROR : " + +// // datastructure hold by edm::GlobalCache +// struct WindowInferenceCache { +// WindowInferenceCache(const edm::ParameterSet& config) : +// graphDef(nullptr) { +// } + +// std::atomic graphDef; +// }; + +//FIXME, to be replaced? +struct WindowInferenceCache { + WindowInferenceCache(const edm::ParameterSet& config) + { + } +}; + + +class peprCandidateFromHitProducer: public edm::stream::EDProducer< + edm::GlobalCache > { + public: + explicit peprCandidateFromHitProducer(const edm::ParameterSet&, + const WindowInferenceCache*); + ~peprCandidateFromHitProducer(); + + // methods for handling the global cache + static std::unique_ptr initializeGlobalCache( + const edm::ParameterSet&); + static void globalEndJob(const WindowInferenceCache*); + + private: + void beginStream(edm::StreamID); + void endStream(); + void produce(edm::Event&, const edm::EventSetup&) override; + + void fillWindows(const edm::Event&); + + + // options + std::vector recHitCollections_; + + // tokens + std::vector > recHitTokens_; + edm::EDGetTokenT> tracksToken_; + edm::EDGetTokenT> simClusterToken_; + + //FIXME, to be replaced + std::string inputTensorName_; + std::string outputTensorName_; + bool batchedModel_; + size_t padSize_; + + // rechit tools + hgcal::RecHitTools recHitTools_; + //SimClusterTools sctools_; + + // windows + std::vector windows_; + + double minEta_; + double maxEta_; + double etaFrameWidth_; + double phiFrameWidth_; + size_t nEtaSegments_; + size_t nPhiSegments_; + + //FIXME, to be replaced + // the tensorflow session + //tensorflow::Session* session_; + + +}; + +std::unique_ptr peprCandidateFromHitProducer::initializeGlobalCache( + const edm::ParameterSet& config) { + // this method is supposed to create, initialize and + //return a WindowInferenceCache instance + WindowInferenceCache* windowInferenceCache = new WindowInferenceCache( + config); + + // load the graph def and save it + std::string graphPath = config.getParameter("graphPath"); + INFO<< "(FIXME) loading graph from " << graphPath << std::endl; + //windowInferenceCache->graphDef = tensorflow::loadGraphDef(graphPath); + + // set some global configs, such as the TF log level + //tensorflow::setLogging("0"); + + return std::unique_ptr(windowInferenceCache); +} + +void peprCandidateFromHitProducer::globalEndJob( + const WindowInferenceCache* windowInferenceCache) { + + //FIXME + // reset the graphDef + //if (windowInferenceCache->graphDef != nullptr) { + // delete windowInferenceCache->graphDef; + //} +} + +peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterSet& config, + const WindowInferenceCache* windowInferenceCache) : + recHitCollections_(config.getParameter >("recHitCollections")), + tracksToken_(consumes>(config.getParameter("tracks"))), + simClusterToken_(consumes>(config.getParameter("simClusters"))), + inputTensorName_(config.getParameter("inputTensorName")), + outputTensorName_(config.getParameter("outputTensorName")), + batchedModel_(config.getParameter("batchedModel")), + padSize_((size_t) config.getParameter("padSize")), + //FIXME: actually these are all not needed if windows are created in the constructor! + minEta_(config.getParameter("minEta")), + maxEta_(config.getParameter("maxEta")), + etaFrameWidth_(config.getParameter("etaFrameWidth")), + phiFrameWidth_(config.getParameter("phiFrameWidth")), + nEtaSegments_((size_t)config.getParameter("nEtaSegments")), + nPhiSegments_((size_t)config.getParameter("nPhiSegments")) + //session_(nullptr) + { + + // sanity checks for sliding windows + + // get tokens + for (edm::InputTag& recHitCollection : recHitCollections_) { + recHitTokens_.push_back(consumes(recHitCollection)); + } + + + produces(); + //produces>(); + + // mount the graphDef stored in windowInferenceCache onto the session + //session_ = tensorflow::createSession(windowInferenceCache->graphDef); +} + +peprCandidateFromHitProducer::~peprCandidateFromHitProducer() { +} + + +void peprCandidateFromHitProducer::beginStream(edm::StreamID streamId) { + windows_ = InferenceWindow::createWindows(nPhiSegments_,nEtaSegments_,minEta_,maxEta_,etaFrameWidth_,phiFrameWidth_); + + // FIXME, make configurable? + for(auto& w: windows_) + w.setMode(WindowBase::useRechits); +} + +void peprCandidateFromHitProducer::endStream() { + // close the session + //tensorflow::closeSession(session_); + //session_ = nullptr; + + + windows_.clear(); +} + +void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSetup& setup) { + + recHitTools_.getEventSetup(setup); + //sctools_.setRechitTools(recHitTools_); //is it needed? + + auto simclusters = event.get(simClusterToken_); + std::cout << "The size of the simclusters is " << simclusters.size() << std::endl; + + + + // fill rechits into windows + fillWindows(event); + + // // one tensor per window + // std::vector windowoutputs; + // // run the evaluation per window + // for (auto & window : windows_) { + // window.evaluate(session_); + // windowoutputs.push_back(window.getOutput()); + // } + + //FIXME, needs different format + //// one tensor per window + //std::vector windowoutputs; + // run the evaluation per window + for (auto & window : windows_) { + window.evaluate(); + //windowoutputs.push_back(window.getOutput()); + } + + + + // reconstruct showers using all windows and put them into the event + //reconstructShowers(); + + + // // making candidate collection + // auto candidates = std::make_unique(); + // std::cout << "TEST " << std::endl; + // auto result = std::make_unique>(); + // for (unsigned int i=0; i().data(); + // //std::cout << " outputs shape dimensions: " << windowoutputs[i].shape().dims() << std::endl; + // //std::cout << " outputs shape 0: " << windowoutputs[i].shape().dim_size(0) << std::endl; + // //std::cout << " outputs shape 1: " << windowoutputs[i].shape().dim_size(1) << std::endl; + // //std::cout << " outputs shape 2: " << windowoutputs[i].shape().dim_size(2) << std::endl; + + // // FIXME: convert E, px, py, pz to XYZT maybe? + // // for now: assume the lorentzvector is in the right format already (dummy) + // float X = -9999., Y=-9999., Z=-9999., E=-9999.; + // // loop over particles reconstructed in the window + // for (int k = 0; k < windowoutputs[i].shape().dim_size(1); k++) { + // std::cout << " particle " << k << std::endl; + // //const auto abs_pdg_id = -9999; + // //const auto charge = -9999; + // const auto charge = 0; // FIXME! + // X = *data; + // //std::cout << " four-vector X: " << X << std::endl; + // data++; + // Y = *data; + // //std::cout << " four-vector Y: " << Y << std::endl; + // data++; + // Z = *data; + // //std::cout << " four-vector Z: " << Z << std::endl; + // data++; + // E = *data; + // //std::cout << " four-vector T: " << T << std::endl; + // //const auto& four_mom = math::XYZTLorentzVector(X,Y,Z,T); + // //reco::PFCandidate::ParticleType part_type = reco::PFCandidate::X; + // //candidates->emplace_back(charge, four_mom, part_type); + + // Trackster tmp; + // //tmp.setRegressedEnergy(E); + // //tmp.setRawEnergy(E); + // //tmp.setBarycenter( math::XYZVector(X,Y,Z) ); + // ////set to randomly chosen values + // std::cout << " E = " << E << ", X = " << X << ", Y = " << Y << ", Z = " << Z << std::endl; + // tmp.setRegressedEnergy(222.); + // tmp.setRawEnergy(222.); + // tmp.setBarycenter( math::XYZVector(99,99,99) ); + // result->emplace_back(tmp); + // } + // } + + // making candidate collection + auto candidates = std::make_unique(); + std::cout << "Making PF candidates " << std::endl; + ////auto result = std::make_unique>(); + //for (unsigned int i=0; i().data(); + ////std::cout << " outputs shape dimensions: " << windowoutputs[i].shape().dims() << std::endl; + ////std::cout << " outputs shape 0: " << windowoutputs[i].shape().dim_size(0) << std::endl; + ////std::cout << " outputs shape 1: " << windowoutputs[i].shape().dim_size(1) << std::endl; + ////std::cout << " outputs shape 2: " << windowoutputs[i].shape().dim_size(2) << std::endl; + + // FIXME: convert E, px, py, pz to XYZT maybe? + // for now: assume the lorentzvector is in the right format already (dummy) + //float X = -9999., Y=-9999., Z=-9999., E=-9999.; + // loop over particles reconstructed in the window + //FIXME, 15 is hardcoded. + //for (int k = 0; k < 15; k++) { + //FIXMESimclusters size to be revisisted if working with windows + for(size_t it=0;it allrechits; + for (auto & token : recHitTokens_) { + for (const auto& rh : event.get(token)) { + HGCRecHitWithPos rhp = { const_cast(&rh), recHitTools_.getPosition(rh.detid()) }; + allrechits.push_back(rhp); + } + } + // sort according to the energy + std::sort(allrechits.begin(), allrechits.end(), + [](const HGCRecHitWithPos& rh1, const HGCRecHitWithPos& rh2) + { return rh1.hit->energy() > rh2.hit->energy();}); + + + // fills a vector of the specified size with zeroes (entries will be 0 if rechit is not filled, and 1 if it is filled) + std::vector filledrechits(allrechits.size(),0); + + // FIXME: make number of features configurable? + size_t nfeatures = 12; + + for (auto & window : windows_) { + //fill rechits in this window + for(size_t it=0;it3) continue; + if(window.maybeAddRecHit(allrechits.at(it))) + filledrechits.at(it)++; + } + + // TF interface setup needs to be called before fillFeatureArrays, in order to do the zero padding + window.setupTFInterface(padSize_, nfeatures, batchedModel_, inputTensorName_, outputTensorName_); + //FIXME to fill the actual arrays + //window.fillFeatureArrays(); + } + + +} + +//remove + +DEFINE_FWK_MODULE(peprCandidateFromHitProducer); diff --git a/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py b/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py new file mode 100644 index 0000000000000..2d7d36ff0690b --- /dev/null +++ b/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py @@ -0,0 +1,43 @@ +# coding: utf-8 + +""" +Initialization file for the WindowInference module. +""" + + +__all__ = ["peprCandidateFromHitProducer"] + + +import math + +import FWCore.ParameterSet.Config as cms + + +peprCandidateFromHitProducer = cms.EDProducer("peprCandidateFromHitProducer", + # the collections of rechits to use + recHitCollections=cms.VInputTag( + cms.InputTag("HGCalRecHit", "HGCEERecHits"), + cms.InputTag("HGCalRecHit", "HGCHEFRecHits"), + cms.InputTag("HGCalRecHit", "HGCHEBRecHits"), + ), + tracks = cms.InputTag("generalTracks"), + simClusters = cms.InputTag("mix", "MergedCaloTruth"), + inputTensorName=cms.string("input"), + outputTensorName=cms.string("output"), + # whether or not the model in the graph expects a batch dimension + batchedModel=cms.bool(True), + # dimension of the padding of the second dimension, i.e., the rec hits themselves + padSize=cms.uint32(10000), + # graph to the trained model + graphPath=cms.string("graph.pb"), + + minEta=cms.double(1.6), + maxEta=cms.double(3.0), + # window size in phi and eta + etaFrameWidth=cms.double(0.1), + phiFrameWidth=cms.double(0.1), + # overlap in phi and eta + nEtaSegments=cms.uint32(3), + nPhiSegments=cms.uint32(1), + # names of the input and output tensors +) From 72cc26e30c05f6531f6e5ac46dd566b97e9286e5 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 23 Sep 2020 15:13:23 +0200 Subject: [PATCH 04/30] Removing WindowInfererenceCache functionality and some commented TF lines as will be obsolete --- .../plugins/peprCandidateFromHitProducer.cc | 85 +------------------ .../peprCandidateFromHitProducer_cfi.py | 2 +- 2 files changed, 4 insertions(+), 83 deletions(-) diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc index ba8a8da2d0dcb..a677b81a1731a 100644 --- a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -24,8 +24,6 @@ #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" //#include "HGCSimTruth/HGCSimTruth/interface/SimClusterTools.h" -//#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" - #include "RecoHGCal/GraphReco/interface/InferenceWindow.h" #include "DataFormats/Common/interface/View.h" @@ -47,35 +45,12 @@ using namespace ticl; #define WARNING std::cout << "peprCandidateFromHitProducer WARNING: " #define ERROR std::cout << "peprCandidateFromHitProducer ERROR : " -// // datastructure hold by edm::GlobalCache -// struct WindowInferenceCache { -// WindowInferenceCache(const edm::ParameterSet& config) : -// graphDef(nullptr) { -// } - -// std::atomic graphDef; -// }; - -//FIXME, to be replaced? -struct WindowInferenceCache { - WindowInferenceCache(const edm::ParameterSet& config) - { - } -}; - -class peprCandidateFromHitProducer: public edm::stream::EDProducer< - edm::GlobalCache > { +class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { public: - explicit peprCandidateFromHitProducer(const edm::ParameterSet&, - const WindowInferenceCache*); + explicit peprCandidateFromHitProducer(const edm::ParameterSet&); ~peprCandidateFromHitProducer(); - // methods for handling the global cache - static std::unique_ptr initializeGlobalCache( - const edm::ParameterSet&); - static void globalEndJob(const WindowInferenceCache*); - private: void beginStream(edm::StreamID); void endStream(); @@ -112,43 +87,10 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer< size_t nEtaSegments_; size_t nPhiSegments_; - //FIXME, to be replaced - // the tensorflow session - //tensorflow::Session* session_; - - }; -std::unique_ptr peprCandidateFromHitProducer::initializeGlobalCache( - const edm::ParameterSet& config) { - // this method is supposed to create, initialize and - //return a WindowInferenceCache instance - WindowInferenceCache* windowInferenceCache = new WindowInferenceCache( - config); - - // load the graph def and save it - std::string graphPath = config.getParameter("graphPath"); - INFO<< "(FIXME) loading graph from " << graphPath << std::endl; - //windowInferenceCache->graphDef = tensorflow::loadGraphDef(graphPath); - // set some global configs, such as the TF log level - //tensorflow::setLogging("0"); - - return std::unique_ptr(windowInferenceCache); -} - -void peprCandidateFromHitProducer::globalEndJob( - const WindowInferenceCache* windowInferenceCache) { - - //FIXME - // reset the graphDef - //if (windowInferenceCache->graphDef != nullptr) { - // delete windowInferenceCache->graphDef; - //} -} - -peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterSet& config, - const WindowInferenceCache* windowInferenceCache) : +peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterSet& config) : recHitCollections_(config.getParameter >("recHitCollections")), tracksToken_(consumes>(config.getParameter("tracks"))), simClusterToken_(consumes>(config.getParameter("simClusters"))), @@ -163,7 +105,6 @@ peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterS phiFrameWidth_(config.getParameter("phiFrameWidth")), nEtaSegments_((size_t)config.getParameter("nEtaSegments")), nPhiSegments_((size_t)config.getParameter("nPhiSegments")) - //session_(nullptr) { // sanity checks for sliding windows @@ -177,8 +118,6 @@ peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterS produces(); //produces>(); - // mount the graphDef stored in windowInferenceCache onto the session - //session_ = tensorflow::createSession(windowInferenceCache->graphDef); } peprCandidateFromHitProducer::~peprCandidateFromHitProducer() { @@ -194,10 +133,6 @@ void peprCandidateFromHitProducer::beginStream(edm::StreamID streamId) { } void peprCandidateFromHitProducer::endStream() { - // close the session - //tensorflow::closeSession(session_); - //session_ = nullptr; - windows_.clear(); } @@ -343,26 +278,12 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe reco::PFCandidate::ParticleType part_type = reco::PFCandidate::X; candidates->emplace_back(charge, four_mom, part_type); - // Trackster tmp; - // //tmp.setRegressedEnergy(E); - // //tmp.setRawEnergy(E); - // //tmp.setBarycenter( math::XYZVector(X,Y,Z) ); - // ////set to randomly chosen values - // std::cout << " E = " << E << ", X = " << X << ", Y = " << Y << ", Z = " << Z << std::endl; - // tmp.setRegressedEnergy(222.); - // tmp.setRawEnergy(222.); - // tmp.setBarycenter( math::XYZVector(99,99,99) ); - - // result->emplace_back(tmp); - - } //} event.put(std::move(candidates)); - //event.put(std::move(result)); std::cout << "[TEST] Results produced and put in event" << std::endl; diff --git a/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py b/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py index 2d7d36ff0690b..bb58c726e97c2 100644 --- a/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py +++ b/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py @@ -29,7 +29,7 @@ # dimension of the padding of the second dimension, i.e., the rec hits themselves padSize=cms.uint32(10000), # graph to the trained model - graphPath=cms.string("graph.pb"), + #graphPath=cms.string("graph.pb"), minEta=cms.double(1.6), maxEta=cms.double(3.0), From 38a4fa9ce45affc616461136eaec3a8eb2b83f3f Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Sat, 26 Sep 2020 01:20:15 +0200 Subject: [PATCH 05/30] First not functional version of pepr PF candidate producer --- .../plugins/peprCandidateFromHitProducer.cc | 44 +++++++++++++++---- .../peprCandidateFromHitProducer_cfi.py | 16 ++++--- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc index a677b81a1731a..21281e57e39bf 100644 --- a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -57,7 +57,7 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { void produce(edm::Event&, const edm::EventSetup&) override; void fillWindows(const edm::Event&); - + void writeInputArrays(const std::vector >&); // options std::vector recHitCollections_; @@ -72,6 +72,7 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { std::string outputTensorName_; bool batchedModel_; size_t padSize_; + std::string pipeName_; // rechit tools hgcal::RecHitTools recHitTools_; @@ -87,6 +88,8 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { size_t nEtaSegments_; size_t nPhiSegments_; + + }; @@ -98,6 +101,7 @@ peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterS outputTensorName_(config.getParameter("outputTensorName")), batchedModel_(config.getParameter("batchedModel")), padSize_((size_t) config.getParameter("padSize")), + pipeName_(config.getParameter("pipeName")), //FIXME: actually these are all not needed if windows are created in the constructor! minEta_(config.getParameter("minEta")), maxEta_(config.getParameter("maxEta")), @@ -134,7 +138,7 @@ void peprCandidateFromHitProducer::beginStream(edm::StreamID streamId) { void peprCandidateFromHitProducer::endStream() { - windows_.clear(); + //windows_.clear(); } void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSetup& setup) { @@ -162,8 +166,13 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe //// one tensor per window //std::vector windowoutputs; // run the evaluation per window + std::vector > hitFeatures; for (auto & window : windows_) { - window.evaluate(); + + hitFeatures = window.getHitFeatures(); + std::cout << " hitFeatures size = " << hitFeatures.size() << std::endl; + + //window.evaluate(); //windowoutputs.push_back(window.getOutput()); } @@ -225,6 +234,9 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe // } // } + +//tmp commented to reduce noise +/* // making candidate collection auto candidates = std::make_unique(); std::cout << "Making PF candidates " << std::endl; @@ -269,7 +281,7 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe math::XYZTLorentzVector cartesian(direction.X(), direction.Y(), direction.Z(), simclusters.at(it).energy()); //// Convert px, py, pz, E vector to CMS standard pt/eta/phi/m vector reco::Candidate::LorentzVector p4(cartesian); - + //const auto& four_mom = math::XYZTLorentzVector(X,Y,Z,E); @@ -286,6 +298,7 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe event.put(std::move(candidates)); std::cout << "[TEST] Results produced and put in event" << std::endl; +*/ // clear all windows for (auto& window : windows_) { @@ -302,7 +315,9 @@ void peprCandidateFromHitProducer::fillWindows(const edm::Event& event) { if (!windows_.size()) { throw cms::Exception("NoWindows") << "no windows initialized"; } - + + std::cout << "Number of windows = " << windows_.size() << std::endl; + ////FIXME ////Window::mode windowmode = windows_.at(0).getMode(); //// skip layer cluster or rechit loop accordingly @@ -327,7 +342,11 @@ void peprCandidateFromHitProducer::fillWindows(const edm::Event& event) { std::vector filledrechits(allrechits.size(),0); // FIXME: make number of features configurable? - size_t nfeatures = 12; + //size_t nfeatures = 12; + + //window. + //std::ofstream inputArrayStream; + for (auto & window : windows_) { //fill rechits in this window @@ -338,14 +357,23 @@ void peprCandidateFromHitProducer::fillWindows(const edm::Event& event) { } // TF interface setup needs to be called before fillFeatureArrays, in order to do the zero padding - window.setupTFInterface(padSize_, nfeatures, batchedModel_, inputTensorName_, outputTensorName_); + //window.setupTFInterface(padSize_, nfeatures, batchedModel_, inputTensorName_, outputTensorName_); //FIXME to fill the actual arrays - //window.fillFeatureArrays(); + window.fillFeatureArrays(); } } + +void peprCandidateFromHitProducer::writeInputArrays(const std::vector >&) { + + //std::ofstream inputArrayStream("/dev/shm/inputArrays.txt"); //in RAM + //std::ofstream inputArrayStream("inputArrays.txt"); + +} + + //remove DEFINE_FWK_MODULE(peprCandidateFromHitProducer); diff --git a/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py b/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py index bb58c726e97c2..7ef1774133d89 100644 --- a/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py +++ b/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py @@ -30,14 +30,20 @@ padSize=cms.uint32(10000), # graph to the trained model #graphPath=cms.string("graph.pb"), - + pipeName=cms.string("arrayspipe"), minEta=cms.double(1.6), maxEta=cms.double(3.0), + # # window size in phi and eta + # etaFrameWidth=cms.double(0.1), + # phiFrameWidth=cms.double(0.1), + # # overlap in phi and eta + # nEtaSegments=cms.uint32(3), + # nPhiSegments=cms.uint32(1), # window size in phi and eta - etaFrameWidth=cms.double(0.1), - phiFrameWidth=cms.double(0.1), + etaFrameWidth=cms.double(100), + phiFrameWidth=cms.double(100), # overlap in phi and eta - nEtaSegments=cms.uint32(3), - nPhiSegments=cms.uint32(1), + nEtaSegments=cms.uint32(1), + nPhiSegments=cms.uint32(1), # names of the input and output tensors ) From f7cb071a30d6b603a422839e55decfd57507b773 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Sat, 26 Sep 2020 02:14:19 +0200 Subject: [PATCH 06/30] Implementing write function for input rechit arrays for the model --- .../plugins/peprCandidateFromHitProducer.cc | 31 ++++++++++++------- .../peprCandidateFromHitProducer_cfi.py | 3 -- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc index 21281e57e39bf..3781dea7ba69f 100644 --- a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -1,11 +1,13 @@ /* - * CMSSW plugin that performs a Window-based inference of networks using RecHits. + * CMSSW plugin that performs a Window-based inference of networks using RecHits and produced PF candidates. * - * Authors: Marcel Rieger - * Gerrit Van Onsem + * Authors: Gerrit Van Onsem + * Marcel Rieger */ #include +#include +#include #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/Frameworkfwd.h" @@ -68,8 +70,6 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { edm::EDGetTokenT> simClusterToken_; //FIXME, to be replaced - std::string inputTensorName_; - std::string outputTensorName_; bool batchedModel_; size_t padSize_; std::string pipeName_; @@ -96,9 +96,7 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterSet& config) : recHitCollections_(config.getParameter >("recHitCollections")), tracksToken_(consumes>(config.getParameter("tracks"))), - simClusterToken_(consumes>(config.getParameter("simClusters"))), - inputTensorName_(config.getParameter("inputTensorName")), - outputTensorName_(config.getParameter("outputTensorName")), + simClusterToken_(consumes>(config.getParameter("simClusters"))), batchedModel_(config.getParameter("batchedModel")), padSize_((size_t) config.getParameter("padSize")), pipeName_(config.getParameter("pipeName")), @@ -171,6 +169,7 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe hitFeatures = window.getHitFeatures(); std::cout << " hitFeatures size = " << hitFeatures.size() << std::endl; + writeInputArrays(hitFeatures); //window.evaluate(); //windowoutputs.push_back(window.getOutput()); @@ -342,7 +341,7 @@ void peprCandidateFromHitProducer::fillWindows(const edm::Event& event) { std::vector filledrechits(allrechits.size(),0); // FIXME: make number of features configurable? - //size_t nfeatures = 12; + //size_t nfeatures = 9; //window. //std::ofstream inputArrayStream; @@ -358,7 +357,6 @@ void peprCandidateFromHitProducer::fillWindows(const edm::Event& event) { // TF interface setup needs to be called before fillFeatureArrays, in order to do the zero padding //window.setupTFInterface(padSize_, nfeatures, batchedModel_, inputTensorName_, outputTensorName_); - //FIXME to fill the actual arrays window.fillFeatureArrays(); } @@ -366,11 +364,20 @@ void peprCandidateFromHitProducer::fillWindows(const edm::Event& event) { } -void peprCandidateFromHitProducer::writeInputArrays(const std::vector >&) { +void peprCandidateFromHitProducer::writeInputArrays(const std::vector >& hitFeatures) { //std::ofstream inputArrayStream("/dev/shm/inputArrays.txt"); //in RAM - //std::ofstream inputArrayStream("inputArrays.txt"); + std::ofstream inputArrayStream(pipeName_.c_str()); + for (size_t i=0; i Date: Sat, 26 Sep 2020 04:01:22 +0200 Subject: [PATCH 07/30] Adding system commands to make use of Triton server; dummy model output reading; cleaning up --- .../plugins/peprCandidateFromHitProducer.cc | 195 +++++++----------- .../peprCandidateFromHitProducer_cfi.py | 6 +- 2 files changed, 80 insertions(+), 121 deletions(-) diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc index 3781dea7ba69f..b82b9dd413c94 100644 --- a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -24,7 +24,6 @@ #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" -//#include "HGCSimTruth/HGCSimTruth/interface/SimClusterTools.h" #include "RecoHGCal/GraphReco/interface/InferenceWindow.h" @@ -60,6 +59,7 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { void fillWindows(const edm::Event&); void writeInputArrays(const std::vector >&); + void readOutputArrays(); // options std::vector recHitCollections_; @@ -71,12 +71,12 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { //FIXME, to be replaced bool batchedModel_; - size_t padSize_; - std::string pipeName_; + std::string tritonPath_; + std::string inpipeName_; + std::string outpipeName_; // rechit tools hgcal::RecHitTools recHitTools_; - //SimClusterTools sctools_; // windows std::vector windows_; @@ -89,7 +89,6 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { size_t nPhiSegments_; - }; @@ -98,8 +97,9 @@ peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterS tracksToken_(consumes>(config.getParameter("tracks"))), simClusterToken_(consumes>(config.getParameter("simClusters"))), batchedModel_(config.getParameter("batchedModel")), - padSize_((size_t) config.getParameter("padSize")), - pipeName_(config.getParameter("pipeName")), + tritonPath_(config.getParameter("tritonPath")), + inpipeName_(config.getParameter("inpipeName")), + outpipeName_(config.getParameter("outpipeName")), //FIXME: actually these are all not needed if windows are created in the constructor! minEta_(config.getParameter("minEta")), maxEta_(config.getParameter("maxEta")), @@ -120,9 +120,36 @@ peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterS produces(); //produces>(); + + //launch scripts to work with Triton clients + //https://github.com/cms-pepr/HGCalML/tree/master/triton + + std::string str0 = "cd " + tritonPath_; + const char *cdcommand = str0.c_str(); + system(cdcommand); + + std::string str1 = "./cmssw_oc_server.sh > serverlog.txt &"; + const char *clientcommand1 = str1.c_str(); + std::cout << "Executing: " << clientcommand1 << std::endl; + system(clientcommand1); + + std::cout << "Sleeping 30s... " << std::endl; + system("sleep 30"); + + std::string str2 = "./cmssw_oc_forward_client.sh " + inpipeName_; + const char *clientcommand2 = str2.c_str(); + std::cout << "Executing: " << clientcommand2 << std::endl; + system(clientcommand2); + + system("cd -"); + } peprCandidateFromHitProducer::~peprCandidateFromHitProducer() { + + //FIXME: find process ID of scripts run in the constructor + //system("killtask <...> 15"); + //system("killtask <...> 15"); } @@ -142,26 +169,16 @@ void peprCandidateFromHitProducer::endStream() { void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSetup& setup) { recHitTools_.getEventSetup(setup); - //sctools_.setRechitTools(recHitTools_); //is it needed? auto simclusters = event.get(simClusterToken_); std::cout << "The size of the simclusters is " << simclusters.size() << std::endl; - // fill rechits into windows fillWindows(event); - // // one tensor per window - // std::vector windowoutputs; - // // run the evaluation per window - // for (auto & window : windows_) { - // window.evaluate(session_); - // windowoutputs.push_back(window.getOutput()); - // } - //FIXME, needs different format - //// one tensor per window + //FIXME: check window treatment //std::vector windowoutputs; // run the evaluation per window std::vector > hitFeatures; @@ -171,7 +188,9 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe std::cout << " hitFeatures size = " << hitFeatures.size() << std::endl; writeInputArrays(hitFeatures); - //window.evaluate(); + //FIXME: how to check if output exists? (How long is waiting time? Rest of code on hold until output pipe available?) + readOutputArrays(); + //windowoutputs.push_back(window.getOutput()); } @@ -181,107 +200,37 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe //reconstructShowers(); - // // making candidate collection - // auto candidates = std::make_unique(); - // std::cout << "TEST " << std::endl; - // auto result = std::make_unique>(); - // for (unsigned int i=0; i().data(); - // //std::cout << " outputs shape dimensions: " << windowoutputs[i].shape().dims() << std::endl; - // //std::cout << " outputs shape 0: " << windowoutputs[i].shape().dim_size(0) << std::endl; - // //std::cout << " outputs shape 1: " << windowoutputs[i].shape().dim_size(1) << std::endl; - // //std::cout << " outputs shape 2: " << windowoutputs[i].shape().dim_size(2) << std::endl; - - // // FIXME: convert E, px, py, pz to XYZT maybe? - // // for now: assume the lorentzvector is in the right format already (dummy) - // float X = -9999., Y=-9999., Z=-9999., E=-9999.; - // // loop over particles reconstructed in the window - // for (int k = 0; k < windowoutputs[i].shape().dim_size(1); k++) { - // std::cout << " particle " << k << std::endl; - // //const auto abs_pdg_id = -9999; - // //const auto charge = -9999; - // const auto charge = 0; // FIXME! - // X = *data; - // //std::cout << " four-vector X: " << X << std::endl; - // data++; - // Y = *data; - // //std::cout << " four-vector Y: " << Y << std::endl; - // data++; - // Z = *data; - // //std::cout << " four-vector Z: " << Z << std::endl; - // data++; - // E = *data; - // //std::cout << " four-vector T: " << T << std::endl; - // //const auto& four_mom = math::XYZTLorentzVector(X,Y,Z,T); - // //reco::PFCandidate::ParticleType part_type = reco::PFCandidate::X; - // //candidates->emplace_back(charge, four_mom, part_type); - - // Trackster tmp; - // //tmp.setRegressedEnergy(E); - // //tmp.setRawEnergy(E); - // //tmp.setBarycenter( math::XYZVector(X,Y,Z) ); - // ////set to randomly chosen values - // std::cout << " E = " << E << ", X = " << X << ", Y = " << Y << ", Z = " << Z << std::endl; - // tmp.setRegressedEnergy(222.); - // tmp.setRawEnergy(222.); - // tmp.setBarycenter( math::XYZVector(99,99,99) ); - // result->emplace_back(tmp); - // } - // } - - -//tmp commented to reduce noise -/* + //FIXME: block below temporarily uses simclusters as a placeholder for OC candidates + //FIXME: check window treatment + // making candidate collection auto candidates = std::make_unique(); - std::cout << "Making PF candidates " << std::endl; - ////auto result = std::make_unique>(); + std::cout << "Creating PF candidates " << std::endl; //for (unsigned int i=0; i().data(); - ////std::cout << " outputs shape dimensions: " << windowoutputs[i].shape().dims() << std::endl; - ////std::cout << " outputs shape 0: " << windowoutputs[i].shape().dim_size(0) << std::endl; - ////std::cout << " outputs shape 1: " << windowoutputs[i].shape().dim_size(1) << std::endl; - ////std::cout << " outputs shape 2: " << windowoutputs[i].shape().dim_size(2) << std::endl; - // FIXME: convert E, px, py, pz to XYZT maybe? - // for now: assume the lorentzvector is in the right format already (dummy) + // FIXME: need to take care of converting E, px, py, pz <--> XYZT whenever needed //float X = -9999., Y=-9999., Z=-9999., E=-9999.; + // loop over particles reconstructed in the window - //FIXME, 15 is hardcoded. - //for (int k = 0; k < 15; k++) { - //FIXMESimclusters size to be revisisted if working with windows + //FIXME: Simclusters size to be revisited if working with windows for(size_t it=0;it Date: Sun, 27 Sep 2020 23:58:44 +0200 Subject: [PATCH 08/30] Addressing most comments of Jan --- .../plugins/peprCandidateFromHitProducer.cc | 241 +++++++++++++----- .../peprCandidateFromHitProducer_cfi.py | 7 +- 2 files changed, 174 insertions(+), 74 deletions(-) diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc index b82b9dd413c94..d6b5e29ebe72f 100644 --- a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -8,6 +8,10 @@ #include #include #include +#include +#include +#include +#include #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/Frameworkfwd.h" @@ -59,7 +63,8 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { void fillWindows(const edm::Event&); void writeInputArrays(const std::vector >&); - void readOutputArrays(); + void readOutputArrays(std::vector >&); + pid_t start_background(std::string); // options std::vector recHitCollections_; @@ -88,6 +93,7 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { size_t nEtaSegments_; size_t nPhiSegments_; + pid_t forward_client_id_; }; @@ -120,36 +126,40 @@ peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterS produces(); //produces>(); + int pid = getpid(); + char * mypid = (char*)malloc(6); + sprintf(mypid, "%d", pid); + std::cout << "Process ID of producer: " << mypid << std::endl; + inpipeName_ = std::string(mypid) + "_" + inpipeName_; + outpipeName_ = std::string(mypid) + "_" + outpipeName_; + //for local testing (e.g. when one does not know the pid in advance) + //inpipeName_ = "TEST_" + inpipeName_; + //outpipeName_ = "TEST_" + outpipeName_; - //launch scripts to work with Triton clients - //https://github.com/cms-pepr/HGCalML/tree/master/triton - - std::string str0 = "cd " + tritonPath_; - const char *cdcommand = str0.c_str(); - system(cdcommand); - - std::string str1 = "./cmssw_oc_server.sh > serverlog.txt &"; - const char *clientcommand1 = str1.c_str(); - std::cout << "Executing: " << clientcommand1 << std::endl; - system(clientcommand1); - std::cout << "Sleeping 30s... " << std::endl; - system("sleep 30"); - - std::string str2 = "./cmssw_oc_forward_client.sh " + inpipeName_; - const char *clientcommand2 = str2.c_str(); - std::cout << "Executing: " << clientcommand2 << std::endl; - system(clientcommand2); + //launch script(s) to work with Triton clients + //https://github.com/cms-pepr/HGCalML/tree/master/triton + //for now: start client manually in other terminal (but on same machine) - system("cd -"); +/* + //attempt to start processes such that process ID can be retrieved; to be tested further + std::string clientcommand = tritonPath_ + "cmssw_oc_forward_client.sh " + inpipeName_; + std::cout << "Executing: " << clientcommand << std::endl; + forward_client_id_ = start_background(clientcommand); + std::cout << " forward client id after start_background = " << int(forward_client_id_) << std::endl; +*/ } peprCandidateFromHitProducer::~peprCandidateFromHitProducer() { - //FIXME: find process ID of scripts run in the constructor - //system("killtask <...> 15"); - //system("killtask <...> 15"); + //FIXME: find process ID of scripts run in the constructor; to be tested further +/* + char * forwardclientid = (char*)malloc(6); + sprintf(forwardclientid, "%d", int(forward_client_id_)); + std::cout << "Process ID of forward client to kill: " << forwardclientid << std::endl; + system(("kill -15 " + std::string(forwardclientid)).c_str()); +*/ } @@ -170,80 +180,114 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe recHitTools_.getEventSetup(setup); - auto simclusters = event.get(simClusterToken_); - std::cout << "The size of the simclusters is " << simclusters.size() << std::endl; - + //auto simclusters = event.get(simClusterToken_); + //std::cout << "The size of the simclusters is " << simclusters.size() << std::endl; // fill rechits into windows fillWindows(event); - - //FIXME: check window treatment - //std::vector windowoutputs; + //vector (from multiple windows) of vector of ~ OC candidates + std::vector< std::vector > > windowoutputs; + // run the evaluation per window std::vector > hitFeatures; for (auto & window : windows_) { + std::cout << "New window " << std::endl; hitFeatures = window.getHitFeatures(); - std::cout << " hitFeatures size = " << hitFeatures.size() << std::endl; + std::cout << " hitFeatures size = " << hitFeatures.size() << std::endl; + //std::cout << " number of features per hit = " << hitFeatures[0].size() << std::endl; + writeInputArrays(hitFeatures); + + //inner vector is regressed energy, 2D position, and time (total 4 elements) + std::vector > candidates; + readOutputArrays(candidates); - //FIXME: how to check if output exists? (How long is waiting time? Rest of code on hold until output pipe available?) - readOutputArrays(); + windowoutputs.push_back( candidates ); - //windowoutputs.push_back(window.getOutput()); + //break; //if quickly testing just one window } + // making candidate collection + auto pfcandidates = std::make_unique(); + std::cout << "Creating PF candidates " << std::endl; - // reconstruct showers using all windows and put them into the event - //reconstructShowers(); + for (size_t i=0; i(); - std::cout << "Creating PF candidates " << std::endl; - //for (unsigned int i=0; i XYZT whenever needed - //float X = -9999., Y=-9999., Z=-9999., E=-9999.; + float X = -9999., Y=-9999., E=-9999.; - // loop over particles reconstructed in the window - //FIXME: Simclusters size to be revisited if working with windows - for(size_t it=0;it >& hitFeatures) { std::string inpipeRAM = "/dev/shm/" + inpipeName_; //write in RAM - //std::ofstream inputArrayStream(inpipeName_.c_str()); //do not write in RAM (local testing) - std::ofstream inputArrayStream(inpipeRAM.c_str()); - + //std::string inpipeRAM = inpipeName_; //do not write in RAM (local testing) + ////std::ofstream inputArrayStream(inpipeRAM.c_str()); + std::ofstream inputArrayStream; + inputArrayStream.open(inpipeRAM.c_str(), std::ofstream::out | std::ofstream::app); + inputArrayStream.flush(); + std::cout << " inpipeRAM = " << inpipeRAM << std::endl; + + //FIXME: write with highest precision + inputArrayStream << std::scientific; for (size_t i=0; i >& candidates) { std::string outpipeRAM = "/dev/shm/" + outpipeName_; //read from RAM - //std::ifstream outputArrayStream(outpipeName_.c_str()); //do not read from RAM (local testing) - std::ifstream outputArrayStream(outpipeRAM.c_str()); + //std::string outpipeRAM = outpipeName_; //do not read from RAM (local testing) + ////std::ifstream outputArrayStream(outpipeRAM.c_str()); + std::ifstream outputArrayStream; + outputArrayStream.open(outpipeRAM.c_str(), std::ofstream::out | std::ofstream::app); + std::cout << " outpipeRAM = " << outpipeRAM << std::endl; std::string line; if(outputArrayStream.is_open()) { std::cout << "Output array file opened!" << std::endl; - while ( getline (outputArrayStream,line) ) + while ( true ) { + //std::cout << " ... reading new line ... "<< std::endl; + getline (outputArrayStream,line); std::cout << line << '\n'; + + if(line.empty()){ + break; + } + + // //split line according to spaces + std::istringstream iss(line); + std::vector values(std::istream_iterator{iss}, + std::istream_iterator()); + + std::string energy_str = "-9999.", X_str = "-9999.", Y_str = "-9999.", T_str = "-9999."; + if(values.size() == 16 || values.size() == 17) { + energy_str = values[10]; + X_str = values[11]; + Y_str = values[12]; + T_str = values[13]; + + //std::cout << " Storing values from the model output" << std::endl; + std::vector candidate = {std::stof(energy_str), std::stof(X_str), std::stof(Y_str), std::stof(T_str) }; + candidates.push_back( candidate ); + } + else { + if (values.size() == 2) { + //this is the line with shapes; ignore for now + } + else { + std::cout << " Please check model output to retrieve desired regressed properties" << std::endl; + } + } + } + std::cout << "Closing output array stream" << std::endl; outputArrayStream.close(); } } -//remove +pid_t peprCandidateFromHitProducer::start_background(std::string osstr) +{ + //int rv; + pid_t child_pid = fork(); + std::cout << " Child pid = " << int(child_pid) << std::endl; + + if(child_pid) //this is the parent process + { + std::cout << " This is the parent process" << std::endl; + return child_pid; + } + else //this is the child process + { + std::cout << " This is the child process" << std::endl; + system(osstr.data()); //make this blocking (no "&" at the end), so that the child process runs until killed + } + + return(child_pid); +} DEFINE_FWK_MODULE(peprCandidateFromHitProducer); diff --git a/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py b/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py index 0e99cd76166d1..9eff7a520ba5e 100644 --- a/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py +++ b/RecoHGCal/GraphReco/python/peprCandidateFromHitProducer_cfi.py @@ -24,8 +24,7 @@ simClusters = cms.InputTag("mix", "MergedCaloTruth"), # whether or not the model in the graph expects a batch dimension batchedModel=cms.bool(True), - # graph to the trained model - #graphPath=cms.string("graph.pb"), + #tritonPath=cms.string("/eos/home-j/jkiesele/singularity/triton/"), tritonPath=cms.string("/afs/cern.ch/work/g/gvonsem/public/HGCAL/ML/HGCalML/triton/"), inpipeName=cms.string("arrayspipe"), outpipeName=cms.string("arrayspipe_pred"), @@ -38,8 +37,8 @@ # nEtaSegments=cms.uint32(3), # nPhiSegments=cms.uint32(1), # window size in phi and eta - etaFrameWidth=cms.double(100), - phiFrameWidth=cms.double(100), + etaFrameWidth=cms.double(0.2), + phiFrameWidth=cms.double(0.2), # overlap in phi and eta nEtaSegments=cms.uint32(1), nPhiSegments=cms.uint32(1), From 8e98ce6c480d19f9790b2642707bff8461817f62 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Mon, 28 Sep 2020 18:36:12 +0200 Subject: [PATCH 09/30] Fixes in candidate construction --- .../plugins/peprCandidateFromHitProducer.cc | 67 +++++++++++++------ 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc index d6b5e29ebe72f..959ad82574e2e 100644 --- a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -130,11 +130,11 @@ peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterS char * mypid = (char*)malloc(6); sprintf(mypid, "%d", pid); std::cout << "Process ID of producer: " << mypid << std::endl; - inpipeName_ = std::string(mypid) + "_" + inpipeName_; - outpipeName_ = std::string(mypid) + "_" + outpipeName_; + //inpipeName_ = std::string(mypid) + "_" + inpipeName_; + //outpipeName_ = std::string(mypid) + "_" + outpipeName_; //for local testing (e.g. when one does not know the pid in advance) - //inpipeName_ = "TEST_" + inpipeName_; - //outpipeName_ = "TEST_" + outpipeName_; + inpipeName_ = "TEST_" + inpipeName_; + outpipeName_ = "TEST_" + outpipeName_; //launch script(s) to work with Triton clients @@ -202,7 +202,14 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe //inner vector is regressed energy, 2D position, and time (total 4 elements) std::vector > candidates; - readOutputArrays(candidates); + readOutputArrays(candidates); + + for (unsigned int i=0; i values(std::istream_iterator{iss}, std::istream_iterator()); - std::string energy_str = "-9999.", X_str = "-9999.", Y_str = "-9999.", T_str = "-9999."; + std::string energy_str, X_str, Y_str, Z_str, Xrel_str, Yrel_str; //T_str; + float E = -9999., X = -9999., Y = -9999., Z = -9999.; //T = -9999.; + if(values.size() == 16 || values.size() == 17) { + + //input rechit position + X_str = values[5]; + Y_str = values[6]; + Z_str = values[7]; + energy_str = values[10]; - X_str = values[11]; - Y_str = values[12]; - T_str = values[13]; + //values are relative to input rechit position + Xrel_str = values[11]; + Yrel_str = values[12]; + //FIXME: is T also relative to T of rechit? + //T_str = values[13]; + + E = std::stof(energy_str); + X = std::stof(X_str) + std::stof(Xrel_str); + Y = std::stof(Y_str) + std::stof(Yrel_str); + + //positive Z of rechit means Z = 320 cm (at HGCAL surface) + if ( std::stof(Z_str) > 0 ) Z = 320.; //in cm + else Z = -320.; //in cm + - //std::cout << " Storing values from the model output" << std::endl; - std::vector candidate = {std::stof(energy_str), std::stof(X_str), std::stof(Y_str), std::stof(T_str) }; + std::cout << " Storing values from the model output" << std::endl; + std::vector candidate = {E, X, Y, Z }; candidates.push_back( candidate ); } else { if (values.size() == 2) { - //this is the line with shapes; ignore for now + std::cout << " this is the line with shapes; ignore for now" << std::endl; } else { std::cout << " Please check model output to retrieve desired regressed properties" << std::endl; From 8de444579ccb65d80a7b5de4d73fe9325ce555f6 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Mon, 28 Sep 2020 18:53:09 +0200 Subject: [PATCH 10/30] Removing some printouts --- .../plugins/peprCandidateFromHitProducer.cc | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc index 959ad82574e2e..da602f75c52c2 100644 --- a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -202,14 +202,7 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe //inner vector is regressed energy, 2D position, and time (total 4 elements) std::vector > candidates; - readOutputArrays(candidates); - - for (unsigned int i=0; i 0 ) Z = 320.; //in cm else Z = -320.; //in cm - std::cout << " Storing values from the model output" << std::endl; + //std::cout << " Storing values from the model output" << std::endl; std::vector candidate = {E, X, Y, Z }; candidates.push_back( candidate ); } else { if (values.size() == 2) { - std::cout << " this is the line with shapes; ignore for now" << std::endl; + //std::cout << " this is the line with shapes; ignore for now" << std::endl; } else { std::cout << " Please check model output to retrieve desired regressed properties" << std::endl; From ec94eb2d2f819fba8a6b2622bda0b702f95cf692 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Mon, 28 Sep 2020 22:32:21 +0200 Subject: [PATCH 11/30] Fix in Z coordinate assignment of PF candidate --- .../GraphReco/plugins/peprCandidateFromHitProducer.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc index da602f75c52c2..64fbac289757b 100644 --- a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -233,9 +233,10 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe E = windowoutputs[i][j][0]; X = windowoutputs[i][j][1]; Y = windowoutputs[i][j][2]; - Z = windowoutputs[i][j][2]; + Z = windowoutputs[i][j][3]; //block inspired by calcP4 method in TICL TracksterP4FromEnergySum plugin + //below assuming (0,0,0) as vertex //starts from 'position (X,Y,Z)' math::XYZVector direction(X, Y, Z); direction = direction.Unit(); @@ -244,7 +245,13 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe //// Convert px, py, pz, E vector to CMS standard pt/eta/phi/m vector reco::Candidate::LorentzVector p4(cartesian); - //const auto& four_mom = math::XYZTLorentzVector(X,Y,Z,E); + // //Alternative calculation as check + // float R = std::sqrt(X*X + Y*Y + Z*Z); + // float px = E * X / R; + // float py = E * Y / R; + // float pz = E * Z / R; + // std::cout << " (px,py,pz) = " << "(" << px << "," << py << "," << pz << ")" << std::endl; + const auto& four_mom = p4; //std::cout << " PF particle energy " << four_mom.E() << ", Px = " << four_mom.Px() << ", Py = " << four_mom.Py() << ", Pz = " << four_mom.Pz() << std::endl; reco::PFCandidate::ParticleType part_type = reco::PFCandidate::X; From 9582c85fd1f682712483ec072aba88089629dc95 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Tue, 29 Sep 2020 00:54:49 +0200 Subject: [PATCH 12/30] Starting forward client in background and proceeding only when pipe is open --- .../plugins/peprCandidateFromHitProducer.cc | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc index 64fbac289757b..9f9094bb09f58 100644 --- a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/Frameworkfwd.h" @@ -130,36 +131,34 @@ peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterS char * mypid = (char*)malloc(6); sprintf(mypid, "%d", pid); std::cout << "Process ID of producer: " << mypid << std::endl; - //inpipeName_ = std::string(mypid) + "_" + inpipeName_; - //outpipeName_ = std::string(mypid) + "_" + outpipeName_; + inpipeName_ = std::string(mypid) + "_" + inpipeName_; + outpipeName_ = std::string(mypid) + "_" + outpipeName_; //for local testing (e.g. when one does not know the pid in advance) - inpipeName_ = "TEST_" + inpipeName_; - outpipeName_ = "TEST_" + outpipeName_; + //inpipeName_ = "TEST_" + inpipeName_; + //outpipeName_ = "TEST_" + outpipeName_; //launch script(s) to work with Triton clients //https://github.com/cms-pepr/HGCalML/tree/master/triton - //for now: start client manually in other terminal (but on same machine) -/* - //attempt to start processes such that process ID can be retrieved; to be tested further + //start process in background such that process ID can be retrieved std::string clientcommand = tritonPath_ + "cmssw_oc_forward_client.sh " + inpipeName_; - std::cout << "Executing: " << clientcommand << std::endl; forward_client_id_ = start_background(clientcommand); - std::cout << " forward client id after start_background = " << int(forward_client_id_) << std::endl; -*/ + //std::cout << " forward client id after start_background = " << int(forward_client_id_) << std::endl; } peprCandidateFromHitProducer::~peprCandidateFromHitProducer() { - //FIXME: find process ID of scripts run in the constructor; to be tested further /* + //FIXME: find process ID of scripts run in the constructor; to be tested further + //the block below makes the child process crash in an ugly way, and the client is still running char * forwardclientid = (char*)malloc(6); sprintf(forwardclientid, "%d", int(forward_client_id_)); std::cout << "Process ID of forward client to kill: " << forwardclientid << std::endl; system(("kill -15 " + std::string(forwardclientid)).c_str()); */ + } @@ -351,6 +350,19 @@ void peprCandidateFromHitProducer::writeInputArrays(const std::vector proceed" << std::endl; + pipe_open = true; + } + } + std::ofstream inputArrayStream; inputArrayStream.open(inpipeRAM.c_str(), std::ofstream::out | std::ofstream::app); inputArrayStream.flush(); @@ -454,12 +466,14 @@ pid_t peprCandidateFromHitProducer::start_background(std::string osstr) if(child_pid) //this is the parent process { - std::cout << " This is the parent process" << std::endl; + //std::cout << " This is the parent process" << std::endl; return child_pid; } else //this is the child process { - std::cout << " This is the child process" << std::endl; + //std::cout << " This is the child process" << std::endl; + //std::cout << " Will execute in background: " << osstr.data() << std::endl; + system(osstr.data()); //make this blocking (no "&" at the end), so that the child process runs until killed } From f0e48d78c8e986251489a892e9334e0f5e54cb73 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Tue, 29 Sep 2020 10:59:20 +0200 Subject: [PATCH 13/30] Using full float precision in writing to pipe --- RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc index 9f9094bb09f58..94d8f2bdeedd2 100644 --- a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include @@ -369,7 +369,7 @@ void peprCandidateFromHitProducer::writeInputArrays(const std::vector&1 | grep "Connected to"` +while [[ ! $check ]] +do +sleep 1 +check=`nc -vz ${server} 8001 2>&1 | grep "Connected to"` +done + +#clean pipes + + +sys_rm=`which rm` + +function finish { +$sys_rm -f $fifo_location "${fifo_location}_pred" +$sys_rm -f $containerpid_location +} +finish + +trap finish EXIT SIGHUP SIGKILL SIGTERM + +echo "server found... connecting to triton" +sing=`which singularity` +unset PATH +cd + +$sing run \ + -B/eos/home-j/jkiesele/singularity/triton/oc_client:/oc_client \ + /eos/home-j/jkiesele/singularity/triton/tritonserver_20.08-py3-clientsdk.sif \ + python /oc_client/triton_forward_client.py -u $server:$port -f $fifo_location -m hgcal_oc_reco & + +echo $! > $containerpid_location + +wait + + +finish + From f9743615282e771ec1ca1776b5eb648fb23c5cfb Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Tue, 29 Sep 2020 17:19:20 +0200 Subject: [PATCH 15/30] Killing Triton container in destructor --- .../plugins/peprCandidateFromHitProducer.cc | 55 ++++++------------- 1 file changed, 16 insertions(+), 39 deletions(-) diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc index 94d8f2bdeedd2..3c3d5956ddd31 100644 --- a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -80,6 +80,7 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { std::string tritonPath_; std::string inpipeName_; std::string outpipeName_; + std::string containerPIDName_; // rechit tools hgcal::RecHitTools recHitTools_; @@ -116,8 +117,6 @@ peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterS nPhiSegments_((size_t)config.getParameter("nPhiSegments")) { - // sanity checks for sliding windows - // get tokens for (edm::InputTag& recHitCollection : recHitCollections_) { recHitTokens_.push_back(consumes(recHitCollection)); @@ -130,9 +129,10 @@ peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterS int pid = getpid(); char * mypid = (char*)malloc(6); sprintf(mypid, "%d", pid); - std::cout << "Process ID of producer: " << mypid << std::endl; + //std::cout << "Process ID of producer: " << mypid << std::endl; inpipeName_ = std::string(mypid) + "_" + inpipeName_; - outpipeName_ = std::string(mypid) + "_" + outpipeName_; + outpipeName_ = std::string(mypid) + "_" + outpipeName_; + containerPIDName_ = "containerpid"; //for local testing (e.g. when one does not know the pid in advance) //inpipeName_ = "TEST_" + inpipeName_; //outpipeName_ = "TEST_" + outpipeName_; @@ -140,25 +140,23 @@ peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterS //launch script(s) to work with Triton clients //https://github.com/cms-pepr/HGCalML/tree/master/triton - - //start process in background such that process ID can be retrieved - std::string clientcommand = tritonPath_ + "cmssw_oc_forward_client.sh " + inpipeName_; - forward_client_id_ = start_background(clientcommand); - //std::cout << " forward client id after start_background = " << int(forward_client_id_) << std::endl; + + //within the client script, the container is also started in the background and its process ID is stored for later kill command in destructor + std::string clientcommand = tritonPath_ + "cmssw_oc_forward_client.sh " + inpipeName_ + " " + containerPIDName_ + " &"; + system(clientcommand.data()); + std::cout << " Forward client command executed" << std::endl; } peprCandidateFromHitProducer::~peprCandidateFromHitProducer() { -/* - //FIXME: find process ID of scripts run in the constructor; to be tested further - //the block below makes the child process crash in an ugly way, and the client is still running - char * forwardclientid = (char*)malloc(6); - sprintf(forwardclientid, "%d", int(forward_client_id_)); - std::cout << "Process ID of forward client to kill: " << forwardclientid << std::endl; - system(("kill -15 " + std::string(forwardclientid)).c_str()); -*/ - + std::string containerpid_location="/dev/shm/" + containerPIDName_; + int containerpid; + std::ifstream containerpidfile; + containerpidfile.open(containerpid_location); + containerpidfile >> containerpid; + std::cout << "Process ID of triton container to kill: " << containerpid << std::endl; + system(("kill -9 " + std::to_string(containerpid)).data()); } @@ -458,26 +456,5 @@ void peprCandidateFromHitProducer::readOutputArrays(std::vector Date: Tue, 29 Sep 2020 18:42:55 +0200 Subject: [PATCH 16/30] Moving few parameters from config to producer, and removing some unused parameters --- .../plugins/peprCandidateFromHitProducer.cc | 66 ++++--------------- .../peprCandidateFromHitProducer_cfi.py | 21 +----- 2 files changed, 16 insertions(+), 71 deletions(-) diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc index 3c3d5956ddd31..8e8364e4985ca 100644 --- a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -1,5 +1,5 @@ /* - * CMSSW plugin that performs a Window-based inference of networks using RecHits and produced PF candidates. + * CMSSW plugin that performs a Window-based inference of networks using RecHits and produces PF candidates. * * Authors: Gerrit Van Onsem * Marcel Rieger @@ -26,7 +26,6 @@ #include "DataFormats/TrackReco/interface/TrackFwd.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" #include "DataFormats/CaloRecHit/interface/CaloClusterFwd.h" -#include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" @@ -73,10 +72,7 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { // tokens std::vector > recHitTokens_; edm::EDGetTokenT> tracksToken_; - edm::EDGetTokenT> simClusterToken_; - //FIXME, to be replaced - bool batchedModel_; std::string tritonPath_; std::string inpipeName_; std::string outpipeName_; @@ -95,26 +91,18 @@ class peprCandidateFromHitProducer: public edm::stream::EDProducer<> { size_t nEtaSegments_; size_t nPhiSegments_; - pid_t forward_client_id_; - }; peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterSet& config) : recHitCollections_(config.getParameter >("recHitCollections")), tracksToken_(consumes>(config.getParameter("tracks"))), - simClusterToken_(consumes>(config.getParameter("simClusters"))), - batchedModel_(config.getParameter("batchedModel")), tritonPath_(config.getParameter("tritonPath")), inpipeName_(config.getParameter("inpipeName")), outpipeName_(config.getParameter("outpipeName")), //FIXME: actually these are all not needed if windows are created in the constructor! minEta_(config.getParameter("minEta")), - maxEta_(config.getParameter("maxEta")), - etaFrameWidth_(config.getParameter("etaFrameWidth")), - phiFrameWidth_(config.getParameter("phiFrameWidth")), - nEtaSegments_((size_t)config.getParameter("nEtaSegments")), - nPhiSegments_((size_t)config.getParameter("nPhiSegments")) + maxEta_(config.getParameter("maxEta")) { // get tokens @@ -122,6 +110,12 @@ peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterS recHitTokens_.push_back(consumes(recHitCollection)); } + // window size and overlap in phi and eta + etaFrameWidth_ = 0.2; + phiFrameWidth_ = 0.2; + nEtaSegments_ = 1; + nPhiSegments_ = 1; + produces(); //produces>(); @@ -144,7 +138,7 @@ peprCandidateFromHitProducer::peprCandidateFromHitProducer(const edm::ParameterS //within the client script, the container is also started in the background and its process ID is stored for later kill command in destructor std::string clientcommand = tritonPath_ + "cmssw_oc_forward_client.sh " + inpipeName_ + " " + containerPIDName_ + " &"; system(clientcommand.data()); - std::cout << " Forward client command executed" << std::endl; + //std::cout << " Forward client command executed" << std::endl; } @@ -155,7 +149,7 @@ peprCandidateFromHitProducer::~peprCandidateFromHitProducer() { std::ifstream containerpidfile; containerpidfile.open(containerpid_location); containerpidfile >> containerpid; - std::cout << "Process ID of triton container to kill: " << containerpid << std::endl; + //std::cout << "Process ID of triton container being killed: " << containerpid << std::endl; system(("kill -9 " + std::to_string(containerpid)).data()); } @@ -177,9 +171,6 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe recHitTools_.getEventSetup(setup); - //auto simclusters = event.get(simClusterToken_); - //std::cout << "The size of the simclusters is " << simclusters.size() << std::endl; - // fill rechits into windows fillWindows(event); @@ -214,7 +205,7 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe for (size_t i=0; i 0 ) Z = 320.; //in cm else Z = -320.; //in cm - //std::cout << " Storing values from the model output" << std::endl; std::vector candidate = {E, X, Y, Z }; @@ -449,7 +409,7 @@ void peprCandidateFromHitProducer::readOutputArrays(std::vector Date: Wed, 30 Sep 2020 00:38:10 +0200 Subject: [PATCH 17/30] Update README --- README | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/README b/README index 75f528d29b13c..ea0f3d61c14fb 100644 --- a/README +++ b/README @@ -1 +1,56 @@ -Introduction to CMSSW: http://cms-sw.github.io +# Running the pepr PF candidate producer for HGCAL + +This example demonstrates how to run the particle reconstruction in the HGCAL subdetector via inference of a graph neural network. + +## Setup + +Install CMSSW: +``` +export SCRAM_ARCH="slc7_amd64_gcc820" +cmsrel CMSSW_11_1_0_pre7 +cd CMSSW_11_1_0_pre7/src +cmsenv +scram b -j 8 +``` + +Install custom packages: +``` +git cms-init +git cms-merge-topic gvonsem:pepr_CMSSW_11_1_0_pre7_peprCandDev +git clone --recursive https://github.com/CMS-HGCAL/reco-prodtools.git reco_prodtools +scram b -j 8 +``` + +Create prodtools templates: +``` +cd reco_prodtools/templates/python +./produceSkeletons_D49_NoSmear_NoDQMNoHLT_PU_AVE_200_BX_25ns.sh +cd ../../../ +scram b python +``` + +Check out the configuration files to generate events: +``` +cd ../../ +git clone -b pepr_CMSSW_11_1_0_pre7_peprCandDev https://github.com/gvonsem/production_tests.git +``` + +## Generate events + +First we produce GEN-SIM-DIGI events, in this example by shooting particles (e.g. photons) +in a certain energy range towards the HGCAL subdetector via the `FlatEtaRangeGunProducer`. +``` +cd production_tests +cmsRun GSD_GUN.py seed=1 outputFile="file:1_GSD.root" maxEvents=5 +``` +When the GSD events are produced, we can run the reconstruction step: +``` +cmsRun RECO.py inputFiles="file://1_GSD.root" outputFile="file:1_RECO.root" outputFileDQM="file:1_DQM.root" +``` +A dedicated EDProducer module, the `peprCandidateFromHitProducer` located +in the [RecoHGCAL/GraphReco](https://github.com/gvonsem/cmssw/tree/pepr_CMSSW_11_1_0_pre7_peprCandDev/RecoHGCal/GraphReco) package, +produces PF candidates straight from rechit information, in this example via the [Object Condensation](https://arxiv.org/abs/2002.03605v3) method. +The inference of trained graph neural network models is done by sending the rechit information per endcap to a custom Triton server, evaluating the model, +and retrieving the regressed energy and position of clustered particle candidates. +These candidates are subsequently turned into a PFcandidate collection named `recoPFCandidates_peprCandidateFromHitProducer__RECO`. + From 0949a9b733de1481f41c2c7953c250a05dde40b9 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 30 Sep 2020 00:39:37 +0200 Subject: [PATCH 18/30] Rename README to README.md --- README => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README => README.md (100%) diff --git a/README b/README.md similarity index 100% rename from README rename to README.md From b0140bbd45380ebc6b3ece49d9771b5181dbe398 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 30 Sep 2020 00:46:52 +0200 Subject: [PATCH 19/30] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ea0f3d61c14fb..5e94f57c02f28 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Running the pepr PF candidate producer for HGCAL -This example demonstrates how to run the particle reconstruction in the HGCAL subdetector via inference of a graph neural network. +This example demonstrates how to run a particle reconstruction in the HGCAL subdetector via inference of graph neural networks. ## Setup @@ -37,20 +37,20 @@ git clone -b pepr_CMSSW_11_1_0_pre7_peprCandDev https://github.com/gvonsem/produ ## Generate events -First we produce GEN-SIM-DIGI events, in this example by shooting particles (e.g. photons) +First we produce GEN-SIM-DIGI (GSD) events, in this example by shooting particles (e.g. photons) in a certain energy range towards the HGCAL subdetector via the `FlatEtaRangeGunProducer`. ``` cd production_tests cmsRun GSD_GUN.py seed=1 outputFile="file:1_GSD.root" maxEvents=5 ``` -When the GSD events are produced, we can run the reconstruction step: +Once the GSD events are produced, we can run the reconstruction step: ``` -cmsRun RECO.py inputFiles="file://1_GSD.root" outputFile="file:1_RECO.root" outputFileDQM="file:1_DQM.root" +cmsRun RECO.py inputFiles="file://1_GSD.root" outputFile="file:1_RECO.root" outputFileDQM="file:1_DQM.root" maxEvents=5 ``` A dedicated EDProducer module, the `peprCandidateFromHitProducer` located in the [RecoHGCAL/GraphReco](https://github.com/gvonsem/cmssw/tree/pepr_CMSSW_11_1_0_pre7_peprCandDev/RecoHGCal/GraphReco) package, produces PF candidates straight from rechit information, in this example via the [Object Condensation](https://arxiv.org/abs/2002.03605v3) method. The inference of trained graph neural network models is done by sending the rechit information per endcap to a custom Triton server, evaluating the model, and retrieving the regressed energy and position of clustered particle candidates. -These candidates are subsequently turned into a PFcandidate collection named `recoPFCandidates_peprCandidateFromHitProducer__RECO`. +These candidates are subsequently turned into a PFcandidate collection named `recoPFCandidates_peprCandidateFromHitProducer__RECO`. Particle and charge identification as well as track-cluster matching are work in progress and not included yet. From 79e4167d73c3a9ab7e8548d6ea869cc5c2f4ae66 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 30 Sep 2020 01:20:56 +0200 Subject: [PATCH 20/30] Update README.md --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5e94f57c02f28..0821bcad56c99 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Running the pepr PF candidate producer for HGCAL -This example demonstrates how to run a particle reconstruction in the HGCAL subdetector via inference of graph neural networks. +This example demonstrates how to run the particle reconstruction in the HGCAL subdetector via inference of graph neural networks. ## Setup @@ -54,3 +54,13 @@ The inference of trained graph neural network models is done by sending the rech and retrieving the regressed energy and position of clustered particle candidates. These candidates are subsequently turned into a PFcandidate collection named `recoPFCandidates_peprCandidateFromHitProducer__RECO`. Particle and charge identification as well as track-cluster matching are work in progress and not included yet. +**Note:** it may take some time for the event loop in the reconstruction to start, and inference may be slow on a CPU server. The speed of communication with the client and especially the inference will improve drastically once dedicated Triton GPU servers are used. + +The sequence of the producer module is as follows: +* In the constructor of the producer, the Triton client is started. +* The producer checks for open pipes (set up to communicate with the Triton server) and will wait until the pipes are open to send the rechit data to the server. +* In case the pipes are open before the producer reaches the check, the client will wait until the rechit data is passed from the producer. +* The inference itself is done on the Triton server via the trained model that is stored there, and the results are passed back to the module where a collection of reconstructed particle candidates is created. +* The Triton client is automatically closed in the destructor of the producer + + From 40f521a77d8bdc471a637693041041033df715c6 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 30 Sep 2020 01:23:30 +0200 Subject: [PATCH 21/30] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0821bcad56c99..ac394eebbba7a 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Once the GSD events are produced, we can run the reconstruction step: ``` cmsRun RECO.py inputFiles="file://1_GSD.root" outputFile="file:1_RECO.root" outputFileDQM="file:1_DQM.root" maxEvents=5 ``` -A dedicated EDProducer module, the `peprCandidateFromHitProducer` located +A dedicated **EDProducer module**, the `peprCandidateFromHitProducer` located in the [RecoHGCAL/GraphReco](https://github.com/gvonsem/cmssw/tree/pepr_CMSSW_11_1_0_pre7_peprCandDev/RecoHGCal/GraphReco) package, produces PF candidates straight from rechit information, in this example via the [Object Condensation](https://arxiv.org/abs/2002.03605v3) method. The inference of trained graph neural network models is done by sending the rechit information per endcap to a custom Triton server, evaluating the model, @@ -56,7 +56,7 @@ These candidates are subsequently turned into a PFcandidate collection named `re **Note:** it may take some time for the event loop in the reconstruction to start, and inference may be slow on a CPU server. The speed of communication with the client and especially the inference will improve drastically once dedicated Triton GPU servers are used. -The sequence of the producer module is as follows: +The **sequence** of the producer module is as follows: * In the constructor of the producer, the Triton client is started. * The producer checks for open pipes (set up to communicate with the Triton server) and will wait until the pipes are open to send the rechit data to the server. * In case the pipes are open before the producer reaches the check, the client will wait until the rechit data is passed from the producer. From 709108b7863431b251ef7364153ffde9061890ad Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 30 Sep 2020 10:31:05 +0200 Subject: [PATCH 22/30] Commenting some printouts --- .../plugins/peprCandidateFromHitProducer.cc | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc index 8e8364e4985ca..1916c2314b30d 100644 --- a/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc +++ b/RecoHGCal/GraphReco/plugins/peprCandidateFromHitProducer.cc @@ -180,10 +180,10 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe // run the evaluation per window std::vector > hitFeatures; for (auto & window : windows_) { - std::cout << "New window " << std::endl; + //std::cout << "New window " << std::endl; hitFeatures = window.getHitFeatures(); - std::cout << " hitFeatures size = " << hitFeatures.size() << std::endl; + //std::cout << " hitFeatures size = " << hitFeatures.size() << std::endl; //std::cout << " number of features per hit = " << hitFeatures[0].size() << std::endl; writeInputArrays(hitFeatures); @@ -200,7 +200,7 @@ void peprCandidateFromHitProducer::produce(edm::Event& event, const edm::EventSe // making candidate collection auto pfcandidates = std::make_unique(); - std::cout << "Creating PF candidates " << std::endl; + //std::cout << "Creating PF candidates " << std::endl; for (size_t i=0; i Date: Wed, 30 Sep 2020 10:49:03 +0200 Subject: [PATCH 23/30] Adding back accidentally deleted historical windowInference test config --- .../GraphReco/test/windowInference_cfg.py | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 RecoHGCal/GraphReco/test/windowInference_cfg.py diff --git a/RecoHGCal/GraphReco/test/windowInference_cfg.py b/RecoHGCal/GraphReco/test/windowInference_cfg.py new file mode 100644 index 0000000000000..873959fce5faf --- /dev/null +++ b/RecoHGCal/GraphReco/test/windowInference_cfg.py @@ -0,0 +1,68 @@ +# coding: utf-8 + +""" +Test config to run the WindowInference plugin. +""" + + +import os +import subprocess + +import FWCore.ParameterSet.Config as cms +from FWCore.ParameterSet.VarParsing import VarParsing + + +# determine the location of _this_ file +if "__file__" in globals(): + this_dir = os.path.dirname(os.path.abspath(__file__)) +else: + this_dir = os.path.expandvars("$CMSSW_BASE/src/RecoHGCal/GraphReco/test") + +# ensure that the graph exists +# if not, call the create_dummy_graph.py script in a subprocess since tensorflow complains +# when its loaded twice (once here in python, once in c++) +graph_path = os.path.join(this_dir, "graph.pb") +if not os.path.exists(graph_path): + script_path = os.path.join(this_dir, "create_dummy_graph.py") + code = subprocess.call(["python", script_path, graph_path]) + if code != 0: + raise Exception("create_dummy_graph.py failed") + +# setup minimal options +options = VarParsing("python") +options.setDefault("inputFiles", "file:///eos/cms/store/cmst3/group/hgcal/CMG_studies/hgcalsim/sim.RecoTask/closeby_1.0To100.0_idsmix_dR0.3_n5_rnd1_s1/prod5/reco_2327_n100.root") +options.parseArguments() + +# define the process to run for the Phase2 era +from Configuration.Eras.Era_Phase2C8_cff import Phase2C8 +process = cms.Process("HGR", Phase2C8) + +# standard sequences and modules +process.load("Configuration.StandardSequences.Services_cff") +process.load("FWCore.MessageService.MessageLogger_cfi") +process.load("Configuration.Geometry.GeometryExtended2023D41Reco_cff") +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") + +# minimal configuration +process.MessageLogger.cerr.FwkReport.reportEvery = 1 +process.maxEvents = cms.untracked.PSet(input=cms.untracked.int32(10)) +process.source = cms.Source("PoolSource", fileNames=cms.untracked.vstring(options.inputFiles)) + +# global tag +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, "auto:phase2_realistic", "") + +# process options +process.options = cms.untracked.PSet( + allowUnscheduled=cms.untracked.bool(True), + wantSummary=cms.untracked.bool(True), +) + +# load and configure the windowInference module +from RecoHGCal.GraphReco.windowInference_cfi import windowInference +process.windowInference = windowInference.clone( + graphPath=cms.string(graph_path), +) + +# define the path to run +process.p = cms.Path(process.windowInference) From caac5d8744883f68a10b0a18810dad6a0d683de2 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 30 Sep 2020 11:51:58 +0200 Subject: [PATCH 24/30] Moving README to GraphReco --- RecoHGCal/GraphReco/README.md | 66 +++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 RecoHGCal/GraphReco/README.md diff --git a/RecoHGCal/GraphReco/README.md b/RecoHGCal/GraphReco/README.md new file mode 100644 index 0000000000000..ac394eebbba7a --- /dev/null +++ b/RecoHGCal/GraphReco/README.md @@ -0,0 +1,66 @@ +# Running the pepr PF candidate producer for HGCAL + +This example demonstrates how to run the particle reconstruction in the HGCAL subdetector via inference of graph neural networks. + +## Setup + +Install CMSSW: +``` +export SCRAM_ARCH="slc7_amd64_gcc820" +cmsrel CMSSW_11_1_0_pre7 +cd CMSSW_11_1_0_pre7/src +cmsenv +scram b -j 8 +``` + +Install custom packages: +``` +git cms-init +git cms-merge-topic gvonsem:pepr_CMSSW_11_1_0_pre7_peprCandDev +git clone --recursive https://github.com/CMS-HGCAL/reco-prodtools.git reco_prodtools +scram b -j 8 +``` + +Create prodtools templates: +``` +cd reco_prodtools/templates/python +./produceSkeletons_D49_NoSmear_NoDQMNoHLT_PU_AVE_200_BX_25ns.sh +cd ../../../ +scram b python +``` + +Check out the configuration files to generate events: +``` +cd ../../ +git clone -b pepr_CMSSW_11_1_0_pre7_peprCandDev https://github.com/gvonsem/production_tests.git +``` + +## Generate events + +First we produce GEN-SIM-DIGI (GSD) events, in this example by shooting particles (e.g. photons) +in a certain energy range towards the HGCAL subdetector via the `FlatEtaRangeGunProducer`. +``` +cd production_tests +cmsRun GSD_GUN.py seed=1 outputFile="file:1_GSD.root" maxEvents=5 +``` +Once the GSD events are produced, we can run the reconstruction step: +``` +cmsRun RECO.py inputFiles="file://1_GSD.root" outputFile="file:1_RECO.root" outputFileDQM="file:1_DQM.root" maxEvents=5 +``` +A dedicated **EDProducer module**, the `peprCandidateFromHitProducer` located +in the [RecoHGCAL/GraphReco](https://github.com/gvonsem/cmssw/tree/pepr_CMSSW_11_1_0_pre7_peprCandDev/RecoHGCal/GraphReco) package, +produces PF candidates straight from rechit information, in this example via the [Object Condensation](https://arxiv.org/abs/2002.03605v3) method. +The inference of trained graph neural network models is done by sending the rechit information per endcap to a custom Triton server, evaluating the model, +and retrieving the regressed energy and position of clustered particle candidates. +These candidates are subsequently turned into a PFcandidate collection named `recoPFCandidates_peprCandidateFromHitProducer__RECO`. Particle and charge identification as well as track-cluster matching are work in progress and not included yet. + +**Note:** it may take some time for the event loop in the reconstruction to start, and inference may be slow on a CPU server. The speed of communication with the client and especially the inference will improve drastically once dedicated Triton GPU servers are used. + +The **sequence** of the producer module is as follows: +* In the constructor of the producer, the Triton client is started. +* The producer checks for open pipes (set up to communicate with the Triton server) and will wait until the pipes are open to send the rechit data to the server. +* In case the pipes are open before the producer reaches the check, the client will wait until the rechit data is passed from the producer. +* The inference itself is done on the Triton server via the trained model that is stored there, and the results are passed back to the module where a collection of reconstructed particle candidates is created. +* The Triton client is automatically closed in the destructor of the producer + + From f179f2ebaacee5c33bdc8c0f8643375394c11c02 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 30 Sep 2020 11:53:46 +0200 Subject: [PATCH 25/30] Update and rename README.md to README --- README | 1 + README.md | 66 ------------------------------------------------------- 2 files changed, 1 insertion(+), 66 deletions(-) create mode 100644 README delete mode 100644 README.md diff --git a/README b/README new file mode 100644 index 0000000000000..75f528d29b13c --- /dev/null +++ b/README @@ -0,0 +1 @@ +Introduction to CMSSW: http://cms-sw.github.io diff --git a/README.md b/README.md deleted file mode 100644 index ac394eebbba7a..0000000000000 --- a/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# Running the pepr PF candidate producer for HGCAL - -This example demonstrates how to run the particle reconstruction in the HGCAL subdetector via inference of graph neural networks. - -## Setup - -Install CMSSW: -``` -export SCRAM_ARCH="slc7_amd64_gcc820" -cmsrel CMSSW_11_1_0_pre7 -cd CMSSW_11_1_0_pre7/src -cmsenv -scram b -j 8 -``` - -Install custom packages: -``` -git cms-init -git cms-merge-topic gvonsem:pepr_CMSSW_11_1_0_pre7_peprCandDev -git clone --recursive https://github.com/CMS-HGCAL/reco-prodtools.git reco_prodtools -scram b -j 8 -``` - -Create prodtools templates: -``` -cd reco_prodtools/templates/python -./produceSkeletons_D49_NoSmear_NoDQMNoHLT_PU_AVE_200_BX_25ns.sh -cd ../../../ -scram b python -``` - -Check out the configuration files to generate events: -``` -cd ../../ -git clone -b pepr_CMSSW_11_1_0_pre7_peprCandDev https://github.com/gvonsem/production_tests.git -``` - -## Generate events - -First we produce GEN-SIM-DIGI (GSD) events, in this example by shooting particles (e.g. photons) -in a certain energy range towards the HGCAL subdetector via the `FlatEtaRangeGunProducer`. -``` -cd production_tests -cmsRun GSD_GUN.py seed=1 outputFile="file:1_GSD.root" maxEvents=5 -``` -Once the GSD events are produced, we can run the reconstruction step: -``` -cmsRun RECO.py inputFiles="file://1_GSD.root" outputFile="file:1_RECO.root" outputFileDQM="file:1_DQM.root" maxEvents=5 -``` -A dedicated **EDProducer module**, the `peprCandidateFromHitProducer` located -in the [RecoHGCAL/GraphReco](https://github.com/gvonsem/cmssw/tree/pepr_CMSSW_11_1_0_pre7_peprCandDev/RecoHGCal/GraphReco) package, -produces PF candidates straight from rechit information, in this example via the [Object Condensation](https://arxiv.org/abs/2002.03605v3) method. -The inference of trained graph neural network models is done by sending the rechit information per endcap to a custom Triton server, evaluating the model, -and retrieving the regressed energy and position of clustered particle candidates. -These candidates are subsequently turned into a PFcandidate collection named `recoPFCandidates_peprCandidateFromHitProducer__RECO`. Particle and charge identification as well as track-cluster matching are work in progress and not included yet. - -**Note:** it may take some time for the event loop in the reconstruction to start, and inference may be slow on a CPU server. The speed of communication with the client and especially the inference will improve drastically once dedicated Triton GPU servers are used. - -The **sequence** of the producer module is as follows: -* In the constructor of the producer, the Triton client is started. -* The producer checks for open pipes (set up to communicate with the Triton server) and will wait until the pipes are open to send the rechit data to the server. -* In case the pipes are open before the producer reaches the check, the client will wait until the rechit data is passed from the producer. -* The inference itself is done on the Triton server via the trained model that is stored there, and the results are passed back to the module where a collection of reconstructed particle candidates is created. -* The Triton client is automatically closed in the destructor of the producer - - From c2bcfcaa98231a496f9c3952ccd7879ccce81ff2 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 30 Sep 2020 13:05:15 +0200 Subject: [PATCH 26/30] Update README.md --- RecoHGCal/GraphReco/README.md | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/RecoHGCal/GraphReco/README.md b/RecoHGCal/GraphReco/README.md index ac394eebbba7a..48df49b0e11ed 100644 --- a/RecoHGCal/GraphReco/README.md +++ b/RecoHGCal/GraphReco/README.md @@ -17,22 +17,13 @@ Install custom packages: ``` git cms-init git cms-merge-topic gvonsem:pepr_CMSSW_11_1_0_pre7_peprCandDev -git clone --recursive https://github.com/CMS-HGCAL/reco-prodtools.git reco_prodtools scram b -j 8 ``` -Create prodtools templates: -``` -cd reco_prodtools/templates/python -./produceSkeletons_D49_NoSmear_NoDQMNoHLT_PU_AVE_200_BX_25ns.sh -cd ../../../ -scram b python -``` - Check out the configuration files to generate events: ``` cd ../../ -git clone -b pepr_CMSSW_11_1_0_pre7_peprCandDev https://github.com/gvonsem/production_tests.git +git clone https://github.com/cms-pepr/production_tests ``` ## Generate events From a560ae4327f13761bc968c5aed418f5443baf64a Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 30 Sep 2020 13:06:45 +0200 Subject: [PATCH 27/30] Update README.md --- RecoHGCal/GraphReco/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RecoHGCal/GraphReco/README.md b/RecoHGCal/GraphReco/README.md index 48df49b0e11ed..d60f8b70c772a 100644 --- a/RecoHGCal/GraphReco/README.md +++ b/RecoHGCal/GraphReco/README.md @@ -16,7 +16,7 @@ scram b -j 8 Install custom packages: ``` git cms-init -git cms-merge-topic gvonsem:pepr_CMSSW_11_1_0_pre7_peprCandDev +git cms-merge-topic cms-pepr:pepr_CMSSW_11_1_0_pre7 scram b -j 8 ``` From c3d3066b28cebad897b5432093015f0a32180558 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 30 Sep 2020 13:12:41 +0200 Subject: [PATCH 28/30] Update README.md --- RecoHGCal/GraphReco/README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/RecoHGCal/GraphReco/README.md b/RecoHGCal/GraphReco/README.md index d60f8b70c772a..f0c119b782690 100644 --- a/RecoHGCal/GraphReco/README.md +++ b/RecoHGCal/GraphReco/README.md @@ -20,18 +20,12 @@ git cms-merge-topic cms-pepr:pepr_CMSSW_11_1_0_pre7 scram b -j 8 ``` -Check out the configuration files to generate events: -``` -cd ../../ -git clone https://github.com/cms-pepr/production_tests -``` - ## Generate events First we produce GEN-SIM-DIGI (GSD) events, in this example by shooting particles (e.g. photons) in a certain energy range towards the HGCAL subdetector via the `FlatEtaRangeGunProducer`. ``` -cd production_tests +cd RecoHGCal/GraphReco/test cmsRun GSD_GUN.py seed=1 outputFile="file:1_GSD.root" maxEvents=5 ``` Once the GSD events are produced, we can run the reconstruction step: From a295d9bf7a597cec6a02085972733049b9f060ed Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 30 Sep 2020 13:13:40 +0200 Subject: [PATCH 29/30] Adding GSD and RECO configuration files to test pepr workflow --- RecoHGCal/GraphReco/test/GSD_GUN.py | 110 +++++++++++++++++ RecoHGCal/GraphReco/test/RECO_pf.py | 182 ++++++++++++++++++++++++++++ 2 files changed, 292 insertions(+) create mode 100644 RecoHGCal/GraphReco/test/GSD_GUN.py create mode 100644 RecoHGCal/GraphReco/test/RECO_pf.py diff --git a/RecoHGCal/GraphReco/test/GSD_GUN.py b/RecoHGCal/GraphReco/test/GSD_GUN.py new file mode 100644 index 0000000000000..3a0bf068fbae8 --- /dev/null +++ b/RecoHGCal/GraphReco/test/GSD_GUN.py @@ -0,0 +1,110 @@ +# coding: utf-8 + +import os +import math + +import FWCore.ParameterSet.Config as cms +from FWCore.ParameterSet.VarParsing import VarParsing +from reco_prodtools.templates.GSD_fragment import process + +# option parsing +options = VarParsing('python') +options.setDefault('outputFile', 'file:partGun_PDGid22_x96_Pt1.0To100.0_GSD_1.root') +options.setDefault('maxEvents', 1) +options.register("pileup", 0, VarParsing.multiplicity.singleton, VarParsing.varType.int, + "pileup") +options.register("seed", 1, VarParsing.multiplicity.singleton, VarParsing.varType.int, + "random seed") +options.register( + 'EminFineTrack', + 10000., + VarParsing.multiplicity.singleton, + VarParsing.varType.float, + "Minimum energy in MeV for which secondary tracks in Calo will be saved" + ) +options.register( + 'EminFinePhoton', + 500., + VarParsing.multiplicity.singleton, + VarParsing.varType.float, + "Minimum energy in MeV for which secondary photons in Calo will be saved" + ) +options.register("doFineCalo", 0, VarParsing.multiplicity.singleton, VarParsing.varType.int, + "turn do fineCalo on/off") +options.register("storeHGCBoundaryCross", 1, VarParsing.multiplicity.singleton, VarParsing.varType.int, + "turn do StoreHGCBoundarCross on/off") +options.parseArguments() + +process.maxEvents.input = cms.untracked.int32(options.maxEvents) + +seed = int(options.seed)+1 +# random seeds +process.RandomNumberGeneratorService.generator.initialSeed = cms.untracked.uint32(seed) +process.RandomNumberGeneratorService.VtxSmeared.initialSeed = cms.untracked.uint32(seed) +process.RandomNumberGeneratorService.mix.initialSeed = cms.untracked.uint32(seed) + +# Input source +process.source.firstLuminosityBlock = cms.untracked.uint32(seed) + +# Output definition +process.FEVTDEBUGoutput.fileName = cms.untracked.string( + options.__getattr__("outputFile", noTags=True)) + +process.FEVTDEBUGoutput.outputCommands.append("keep *_*G4*_*_*") + +# helper +def calculate_rho(z, eta): + return z * math.tan(2 * math.atan(math.exp(-eta))) + + +process.generator = cms.EDProducer("FlatEtaRangeGunProducer", + # particle ids + #particleIDs=cms.vint32(22,22,11,-11,211,-211,13,-13), + particleIDs=cms.vint32(22), + # max number of particles to shoot at a time + nParticles=cms.int32(1), + # shoot exactly the particles defined in particleIDs in that order + exactShoot=cms.bool(False), + # randomly shoot [1, nParticles] particles, each time randomly drawn from particleIDs + randomShoot=cms.bool(False), + # energy range + eMin=cms.double(3.0), + eMax=cms.double(100.0), + # phi range + phiMin=cms.double(-math.pi), + phiMax=cms.double(math.pi), + # eta range + etaMin=cms.double(1.52), + etaMax=cms.double(3.00), + + debug=cms.untracked.bool(True), +) + +# Options for saving fine hits +process.g4SimHits.CaloSD.StoreHGCBoundaryCross = cms.bool(bool(options.storeHGCBoundaryCross)) +# Seems to be an interplay between hgcboundaryCross and fineCaloID +process.g4SimHits.CaloSD.UseFineCaloID = cms.bool(bool(options.storeHGCBoundaryCross+options.doFineCalo)) +process.g4SimHits.CaloTrkProcessing.DoFineCalo = cms.bool(bool(options.doFineCalo)) +process.g4SimHits.CaloTrkProcessing.EminFineTrack = cms.double(options.EminFineTrack) +process.g4SimHits.CaloTrkProcessing.EminFinePhoton = cms.double(options.EminFinePhoton) + + +#load and configure the appropriate pileup modules +if options.pileup > 0: + process.load("SimGeneral.MixingModule.mix_POISSON_average_cfi") + process.mix.input.nbPileupEvents.averageNumber = cms.double(options.pileup) + # process.mix.input.fileNames = cms.untracked.vstring(["/store/relval/CMSSW_10_6_0_patch2/RelValMinBias_14TeV/GEN-SIM/106X_upgrade2023_realistic_v3_2023D41noPU-v1/10000/F7FE3FE9-565B-544A-855E-902BA4E3C5FD.root', '/store/relval/CMSSW_10_6_0_patch2/RelValMinBias_14TeV/GEN-SIM/106X_upgrade2023_realistic_v3_2023D41noPU-v1/10000/82584FBA-A1E6-DF48-99BA-B1759C3A190F.root', '/store/relval/CMSSW_10_6_0_patch2/RelValMinBias_14TeV/GEN-SIM/106X_upgrade2023_realistic_v3_2023D41noPU-v1/10000/F806295A-492F-EF4F-9D91-15DA8769DD72.root', '/store/relval/CMSSW_10_6_0_patch2/RelValMinBias_14TeV/GEN-SIM/106X_upgrade2023_realistic_v3_2023D41noPU-v1/10000/6FCA2E1D-D1E2-514B-8ABA-5B71A2C1E1B3.root', '/store/relval/CMSSW_10_6_0_patch2/RelValMinBias_14TeV/GEN-SIM/106X_upgrade2023_realistic_v3_2023D41noPU-v1/10000/287275CC-953A-0C4C-B352-E39EC2D571F0.root', '/store/relval/CMSSW_10_6_0_patch2/RelValMinBias_14TeV/GEN-SIM/106X_upgrade2023_realistic_v3_2023D41noPU-v1/10000/657065A5-F35B-3147-AED9-E4ACA915C982.root', '/store/relval/CMSSW_10_6_0_patch2/RelValMinBias_14TeV/GEN-SIM/106X_upgrade2023_realistic_v3_2023D41noPU-v1/10000/2C56BC73-5687-674C-8684-6C785A88DB78.root', '/store/relval/CMSSW_10_6_0_patch2/RelValMinBias_14TeV/GEN-SIM/106X_upgrade2023_realistic_v3_2023D41noPU-v1/10000/B96F4064-156C-5E47-90A0-07475310157A.root', '/store/relval/CMSSW_10_6_0_patch2/RelValMinBias_14TeV/GEN-SIM/106X_upgrade2023_realistic_v3_2023D41noPU-v1/10000/2564B36D-A0DB-6C42-9105-B1CFF44F311D.root', '/store/relval/CMSSW_10_6_0_patch2/RelValMinBias_14TeV/GEN-SIM/106X_upgrade2023_realistic_v3_2023D41noPU-v1/10000/2CB8C960-47C0-1A40-A9F7-0B62987097E0.root"]) # noqa: E501 + local_pu_dir = "/eos/user/m/mrieger/data/hgc/RelvalMinBias14" + process.mix.input.fileNames = cms.untracked.vstring([ + "file://" + os.path.abspath(os.path.join(local_pu_dir, elem)) + for elem in os.listdir(local_pu_dir) + if elem.endswith(".root") + ]) +else: + process.load("SimGeneral.MixingModule.mixNoPU_cfi") + process.mix.digitizers = cms.PSet(process.theDigitizersValid) + # I don't think this matters, but just to be safe... + process.mix.bunchspace = cms.int32(25) + process.mix.minBunch = cms.int32(-3) + process.mix.maxBunch = cms.int32(3) + diff --git a/RecoHGCal/GraphReco/test/RECO_pf.py b/RecoHGCal/GraphReco/test/RECO_pf.py new file mode 100644 index 0000000000000..8a23a451ecd40 --- /dev/null +++ b/RecoHGCal/GraphReco/test/RECO_pf.py @@ -0,0 +1,182 @@ +# coding: utf-8 +import os + +import FWCore.ParameterSet.Config as cms +from FWCore.ParameterSet.VarParsing import VarParsing +from Configuration.Eras.Era_Phase2C9_cff import Phase2C9 + +process = cms.Process('RECO',Phase2C9) + +# import of standard configurations +process.load('Configuration.StandardSequences.Services_cff') +process.load('SimGeneral.HepPDTESSource.pythiapdt_cfi') +process.load('FWCore.MessageService.MessageLogger_cfi') +process.load('Configuration.EventContent.EventContent_cff') +process.load('SimGeneral.MixingModule.mix_POISSON_average_cfi') +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('Configuration.StandardSequences.RawToDigi_cff') +process.load('Configuration.StandardSequences.L1Reco_cff') +process.load('Configuration.StandardSequences.Reconstruction_cff') +process.load('Configuration.StandardSequences.RecoSim_cff') +process.load('Configuration.StandardSequences.EndOfProcess_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(10), + output = cms.optional.untracked.allowed(cms.int32,cms.PSet) +) + +# Input source +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring('file:step3_DIGI2RAW.root'), + secondaryFileNames = cms.untracked.vstring() +) + +process.options = cms.untracked.PSet( + FailPath = cms.untracked.vstring(), + IgnoreCompletely = cms.untracked.vstring(), + Rethrow = cms.untracked.vstring(), + SkipEvent = cms.untracked.vstring(), + allowUnscheduled = cms.obsolete.untracked.bool, + canDeleteEarly = cms.untracked.vstring(), + emptyRunLumiMode = cms.obsolete.untracked.string, + eventSetup = cms.untracked.PSet( + forceNumberOfConcurrentIOVs = cms.untracked.PSet( + + ), + numberOfConcurrentIOVs = cms.untracked.uint32(1) + ), + fileMode = cms.untracked.string('FULLMERGE'), + forceEventSetupCacheClearOnNewRun = cms.untracked.bool(False), + makeTriggerResults = cms.obsolete.untracked.bool, + numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(1), + numberOfConcurrentRuns = cms.untracked.uint32(1), + numberOfStreams = cms.untracked.uint32(0), + numberOfThreads = cms.untracked.uint32(1), + printDependencies = cms.untracked.bool(False), + sizeOfStackForThreadsInKB = cms.optional.untracked.uint32, + throwIfIllegalParameter = cms.untracked.bool(True), + wantSummary = cms.untracked.bool(False) +) + +# Production Info +process.configurationMetadata = cms.untracked.PSet( + annotation = cms.untracked.string('step3 nevts:10'), + name = cms.untracked.string('Applications'), + version = cms.untracked.string('$Revision: 1.19 $') +) + +# Output definition + +process.FEVTDEBUGoutput = cms.OutputModule("PoolOutputModule", + dataset = cms.untracked.PSet( + dataTier = cms.untracked.string('GEN-SIM-RECO'), + filterName = cms.untracked.string('') + ), + fileName = cms.untracked.string('step3_RAW2DIGI_L1Reco_RECO_RECOSIM_PU.root'), + outputCommands = process.FEVTDEBUGEventContent.outputCommands, + splitLevel = cms.untracked.int32(0) +) + +# Additional output definition + +# Other statements +process.mix.input.nbPileupEvents.averageNumber = cms.double(200.000000) +process.mix.bunchspace = cms.int32(25) +process.mix.minBunch = cms.int32(-3) +process.mix.maxBunch = cms.int32(3) +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic_T15', '') + +# Path and EndPath definitions +process.raw2digi_step = cms.Path(process.RawToDigi) +process.L1Reco_step = cms.Path(process.L1Reco) +process.reconstruction_step = cms.Path(process.reconstruction) +process.recosim_step = cms.Path(process.recosim) +process.endjob_step = cms.EndPath(process.endOfProcess) +process.FEVTDEBUGoutput_step = cms.EndPath(process.FEVTDEBUGoutput) + +# Schedule definition +process.schedule = cms.Schedule(process.raw2digi_step,process.L1Reco_step,process.reconstruction_step,process.recosim_step,process.endjob_step,process.FEVTDEBUGoutput_step) +from PhysicsTools.PatAlgos.tools.helpers import associatePatAlgosToolsTask +associatePatAlgosToolsTask(process) + +#do not add changes to your config after this point (unless you know what you are doing) +from FWCore.ParameterSet.Utilities import convertToUnscheduled +process=convertToUnscheduled(process) + + +# Customisation from command line + +#Have logErrorHarvester wait for the same EDProducers to finish as those providing data for the OutputModule +from FWCore.Modules.logErrorHarvester_cff import customiseLogErrorHarvesterUsingOutputCommands +process = customiseLogErrorHarvesterUsingOutputCommands(process) + +# Add early deletion of temporary data products to reduce peak memory need +from Configuration.StandardSequences.earlyDeleteSettings_cff import customiseEarlyDelete +process = customiseEarlyDelete(process) +# End adding early deletion + +# option parsing +options = VarParsing('python') +options.setDefault('outputFile', 'file:partGun_PDGid22_x96_Pt1.0To100.0_RECO_1.root') +options.setDefault('inputFiles', "file://partGun_PDGid22_x96_Pt1.0To100.0_GSD_1.root") +options.setDefault('maxEvents', -1) +options.register('outputFileDQM', 'file:partGun_PDGid22_x96_Pt1.0To100.0_DQM_1.root', + VarParsing.multiplicity.singleton, VarParsing.varType.string, 'path to the DQM output file') +options.parseArguments() + +process.maxEvents.input = cms.untracked.int32(options.maxEvents) + + +# pepr PF candidate producer +test_dir = os.path.expandvars("$CMSSW_BASE/src/RecoHGCal/GraphReco/test/") +from RecoHGCal.GraphReco.peprCandidateFromHitProducer_cfi import peprCandidateFromHitProducer +process.peprCandidateFromHitProducer = peprCandidateFromHitProducer.clone( + tritonPath=cms.string(test_dir), +) +process.reconstruction_step += process.peprCandidateFromHitProducer + + +process.load("SimTracker.TrackAssociation.trackingParticleRecoTrackAsssociation_cfi") +# append the HGCTruthProducer to the recosim step +process.hgcSimTruth = cms.EDProducer("HGCTruthProducer", +) +process.trackingParticleMergedSCAssociation = cms.EDProducer("TrackingParticleSimClusterAssociationProducer", + simClusters = cms.InputTag("mix:MergedCaloTruth"), + trackingParticles= cms.InputTag("mix:MergedTrackTruth") + +) + +process.trackingParticleSimClusterAssociation = cms.EDProducer("TrackingParticleSimClusterAssociationProducer", + #simClusters = cms.InputTag("mix:MergedCaloTruth"), + simClusters = cms.InputTag("hgcSimTruth"), + trackingParticles= cms.InputTag("mix:MergedTrackTruth") + +) +process.recosim_step *= process.hgcSimTruth +process.recosim_step *= process.trackingParticleRecoTrackAsssociation +process.recosim_step *= process.trackingParticleSimClusterAssociation +process.recosim_step *= process.trackingParticleMergedSCAssociation + +#process.dump=cms.EDAnalyzer('EventContentAnalyzer') +#process.recosim_step += process.dump + +# Input source +process.source.fileNames = cms.untracked.vstring(options.inputFiles) + +# Output definition +process.FEVTDEBUGoutput.fileName = cms.untracked.string( + options.__getattr__("outputFile", noTags=True)) +process.FEVTDEBUGoutput.outputCommands.append("keep *_*G4*_*_*") +process.FEVTDEBUGoutput.outputCommands.append("keep *_trackingParticleRecoTrackAsssociation_*_*") +process.FEVTDEBUGoutput.outputCommands.append("keep *_MergedTrackTruth_*_*") +process.FEVTDEBUGoutput.outputCommands.append("keep *_hgcSimTruth_*_*") +process.FEVTDEBUGoutput.outputCommands.append("keep *_trackingParticleSimClusterAssociation_*_*") +process.FEVTDEBUGoutput.outputCommands.append("keep *_trackingParticleMergedSCAssociation_*_*") +process.FEVTDEBUGoutput.outputCommands.append("keep *_peprCandidateFromHitProducer_*_*") + +if hasattr(process, "DQMoutput"): + process.DQMoutput.fileName = cms.untracked.string(options.outputFileDQM) + From e9ddba7c2b3d1207ee4d39972ad4e9b641794f84 Mon Sep 17 00:00:00 2001 From: Gerrit Van Onsem Date: Wed, 30 Sep 2020 13:26:48 +0200 Subject: [PATCH 30/30] Update README.md --- RecoHGCal/GraphReco/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RecoHGCal/GraphReco/README.md b/RecoHGCal/GraphReco/README.md index f0c119b782690..8f68d4693f9f0 100644 --- a/RecoHGCal/GraphReco/README.md +++ b/RecoHGCal/GraphReco/README.md @@ -30,7 +30,7 @@ cmsRun GSD_GUN.py seed=1 outputFile="file:1_GSD.root" maxEvents=5 ``` Once the GSD events are produced, we can run the reconstruction step: ``` -cmsRun RECO.py inputFiles="file://1_GSD.root" outputFile="file:1_RECO.root" outputFileDQM="file:1_DQM.root" maxEvents=5 +cmsRun RECO_pf.py inputFiles="file://1_GSD.root" outputFile="file:1_RECO.root" outputFileDQM="file:1_DQM.root" maxEvents=5 ``` A dedicated **EDProducer module**, the `peprCandidateFromHitProducer` located in the [RecoHGCAL/GraphReco](https://github.com/gvonsem/cmssw/tree/pepr_CMSSW_11_1_0_pre7_peprCandDev/RecoHGCal/GraphReco) package,