diff --git a/CommonTools/RecoAlgos/plugins/RecHitToPFCandAssociationProducer.cc b/CommonTools/RecoAlgos/plugins/RecHitToPFCandAssociationProducer.cc new file mode 100644 index 0000000000000..0badbb1b6e795 --- /dev/null +++ b/CommonTools/RecoAlgos/plugins/RecHitToPFCandAssociationProducer.cc @@ -0,0 +1,133 @@ +// system include files +#include +#include + +// user include files +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/Framework/interface/ESHandle.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h" +#include "SimDataFormats/CaloAnalysis/interface/SimClusterFwd.h" +#include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" +#include "DataFormats/CaloRecHit/interface/CaloRecHit.h" +#include "SimDataFormats/CaloHit/interface/PCaloHit.h" +#include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h" +#include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" + +#include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h" +#include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h" +#include "DataFormats/ParticleFlowReco/interface/PFRecHit.h" +#include "DataFormats/ParticleFlowReco/interface/PFRecHitFraction.h" +#include "DataFormats/ParticleFlowReco/interface/PFBlock.h" +#include "DataFormats/ParticleFlowReco/interface/PFBlockFwd.h" +#include "DataFormats/ParticleFlowReco/interface/PFCluster.h" +#include "DataFormats/ParticleFlowReco/interface/PFClusterFwd.h" + +#include "DataFormats/Common/interface/Association.h" + +#include "FWCore/Utilities/interface/transform.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include + +// +// class decleration +// +typedef std::pair IdxAndFraction; + +class RecHitToPFCandAssociationProducer : public edm::stream::EDProducer<> { +public: + explicit RecHitToPFCandAssociationProducer(const edm::ParameterSet&); + ~RecHitToPFCandAssociationProducer() override; + +private: + void produce(edm::Event&, const edm::EventSetup&) override; + + std::vector caloRechitTags_; + std::vector> caloSimhitCollectionTokens_; + //std::vector> trackSimhitCollectionTokens_; + std::vector>> caloRechitCollectionTokens_; + edm::EDGetTokenT pfCollectionToken_; +}; + +RecHitToPFCandAssociationProducer::RecHitToPFCandAssociationProducer(const edm::ParameterSet& pset) + : //caloSimhitCollectionTokens_(edm::vector_transform(pset.getParameter>("caloSimHits"), + // [this](const edm::InputTag& tag) {return mayConsume(tag); })), + //trackSimhitCollectionTokens_(edm::vector_transform(pset.getParameter("trackSimHits"), + // [this](const edm::InputTag& tag) {return mayConsume(tag); }), + caloRechitTags_(pset.getParameter>("caloRecHits")), + caloRechitCollectionTokens_(edm::vector_transform( + caloRechitTags_, [this](const edm::InputTag& tag) { return mayConsume>(tag); })), + pfCollectionToken_(consumes(pset.getParameter("pfCands"))) { + for (auto& tag : caloRechitTags_) { + const std::string& label = tag.instance(); + //TODO: Can this be an edm::View? + produces>(label + "ToPFCand"); + } +} + +RecHitToPFCandAssociationProducer::~RecHitToPFCandAssociationProducer() {} + +// +// member functions +// + +// ------------ method called to produce the data ------------ +void RecHitToPFCandAssociationProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + edm::Handle pfCollection; + iEvent.getByToken(pfCollectionToken_, pfCollection); + std::unordered_map hitDetIdToIndex; + + for (size_t j = 0; j < pfCollection->size(); j++) { + const auto& pfCand = pfCollection->at(j); + const reco::PFCandidate::ElementsInBlocks& elements = pfCand.elementsInBlocks(); + for (auto& element : elements) { + const reco::PFBlockRef blockRef = element.first; + for (const auto& block : blockRef->elements()) { + if (block.type() == reco::PFBlockElement::HGCAL) { + const reco::PFClusterRef& cluster = block.clusterRef(); + const std::vector& rhf = cluster->recHitFractions(); + for (const auto& hf : rhf) { + auto& hit = hf.recHitRef(); + if (!hit) + throw cms::Exception("RecHitToPFCandAssociationProducer") << "Invalid RecHit ref"; + size_t detId = hit->detId(); + auto entry = hitDetIdToIndex.find(detId); + if (entry == hitDetIdToIndex.end() || entry->second.second < hf.fraction()) + hitDetIdToIndex[detId] = {j, hf.fraction()}; + } + } + } + } + } + + for (size_t i = 0; i < caloRechitCollectionTokens_.size(); i++) { + std::string label = caloRechitTags_.at(i).instance(); + std::vector rechitIndices; + + edm::Handle> caloRechitCollection; + iEvent.getByToken(caloRechitCollectionTokens_.at(i), caloRechitCollection); + + for (size_t h = 0; h < caloRechitCollection->size(); h++) { + const CaloRecHit& caloRh = caloRechitCollection->at(h); + size_t id = caloRh.detid().rawId(); + int match = hitDetIdToIndex.find(id) == hitDetIdToIndex.end() ? -1 : hitDetIdToIndex.at(id).first; + rechitIndices.push_back(match); + } + + auto assoc = std::make_unique>(pfCollection); + edm::Association::Filler filler(*assoc); + filler.insert(caloRechitCollection, rechitIndices.begin(), rechitIndices.end()); + filler.fill(); + iEvent.put(std::move(assoc), label + "ToPFCand"); + } +} + +// define this as a plug-in +DEFINE_FWK_MODULE(RecHitToPFCandAssociationProducer); diff --git a/CommonTools/RecoAlgos/plugins/SimClusterRecHitAssocitionProducer.cc b/CommonTools/RecoAlgos/plugins/SimClusterRecHitAssocitionProducer.cc new file mode 100644 index 0000000000000..4208f6a0b7ec9 --- /dev/null +++ b/CommonTools/RecoAlgos/plugins/SimClusterRecHitAssocitionProducer.cc @@ -0,0 +1,136 @@ +// system include files +#include +#include + +// user include files +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/Framework/interface/ESHandle.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h" +#include "SimDataFormats/CaloAnalysis/interface/SimClusterFwd.h" +#include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" +#include "DataFormats/CaloRecHit/interface/CaloRecHit.h" +#include "SimDataFormats/CaloHit/interface/PCaloHit.h" +#include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h" + +#include "DataFormats/Common/interface/Association.h" + +#include "FWCore/Utilities/interface/transform.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include + +// +// class decleration +// +typedef std::pair IdxAndFraction; + +class SimClusterRecHitAssociationProducer : public edm::stream::EDProducer<> { +public: + explicit SimClusterRecHitAssociationProducer(const edm::ParameterSet&); + ~SimClusterRecHitAssociationProducer() override; + +private: + void produce(edm::Event&, const edm::EventSetup&) override; + + std::vector caloRechitTags_; + std::vector> caloSimhitCollectionTokens_; + //std::vector> trackSimhitCollectionTokens_; + std::vector>> caloRechitCollectionTokens_; + edm::EDGetTokenT scCollectionToken_; +}; + +SimClusterRecHitAssociationProducer::SimClusterRecHitAssociationProducer(const edm::ParameterSet& pset) + : //caloSimhitCollectionTokens_(edm::vector_transform(pset.getParameter>("caloSimHits"), + // [this](const edm::InputTag& tag) {return mayConsume(tag); })), + //trackSimhitCollectionTokens_(edm::vector_transform(pset.getParameter("trackSimHits"), + // [this](const edm::InputTag& tag) {return mayConsume(tag); }), + caloRechitTags_(pset.getParameter>("caloRecHits")), + caloRechitCollectionTokens_(edm::vector_transform( + caloRechitTags_, [this](const edm::InputTag& tag) { return mayConsume>(tag); })), + scCollectionToken_(consumes(pset.getParameter("simClusters"))) { + for (auto& tag : caloRechitTags_) { + const std::string& label = tag.instance(); + produces>(label + "ToSimClus"); + } + produces>(); +} + +SimClusterRecHitAssociationProducer::~SimClusterRecHitAssociationProducer() {} + +// +// member functions +// + +// ------------ method called to produce the data ------------ +void SimClusterRecHitAssociationProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + auto simClusterToRecEnergy = std::make_unique>(); + edm::Handle scCollection; + iEvent.getByToken(scCollectionToken_, scCollection); + std::unordered_map hitDetIdToIndex; + std::unordered_map hitDetIdToTotalSimFrac; + + for (size_t s = 0; s < scCollection->size(); s++) { + const auto& sc = scCollection->at(s); + (*simClusterToRecEnergy)[s] = 0.; + for (auto& hf : sc.hits_and_fractions()) { + auto entry = hitDetIdToIndex.find(hf.first); + // Update SimCluster assigment if detId has been found in no other SCs or if + // SC has greater fraction of energy in DetId than the SC already found + if (entry == hitDetIdToIndex.end()) { + hitDetIdToTotalSimFrac[hf.first] = hf.second; + hitDetIdToIndex[hf.first] = {s, hf.second}; + } else { + hitDetIdToTotalSimFrac[hf.first] += hf.second; + if (entry->second.second < hf.second) + hitDetIdToIndex[hf.first] = {s, hf.second}; + } + } + } + + std::unordered_map hitDetIdToTotalRecEnergy; + + for (size_t i = 0; i < caloRechitCollectionTokens_.size(); i++) { + std::string label = caloRechitTags_.at(i).instance(); + std::vector rechitIndices; + + edm::Handle> caloRechitCollection; + iEvent.getByToken(caloRechitCollectionTokens_.at(i), caloRechitCollection); + + for (size_t h = 0; h < caloRechitCollection->size(); h++) { + const CaloRecHit& caloRh = caloRechitCollection->at(h); + size_t id = caloRh.detid().rawId(); + auto entry = hitDetIdToTotalRecEnergy.find(id); + float energy = caloRh.energy(); + if (entry == hitDetIdToTotalRecEnergy.end()) + hitDetIdToTotalRecEnergy[id] = energy; + else + hitDetIdToTotalRecEnergy.at(id) += energy; + + int match = hitDetIdToIndex.find(id) == hitDetIdToIndex.end() ? -1 : hitDetIdToIndex.at(id).first; + float fraction = match != -1 ? hitDetIdToTotalSimFrac.at(id) : 1.; + if (simClusterToRecEnergy->find(match) == simClusterToRecEnergy->end()) + (*simClusterToRecEnergy)[match] = energy * fraction; + else + simClusterToRecEnergy->at(match) += energy * fraction; + + rechitIndices.push_back(match); + } + + auto assoc = std::make_unique>(scCollection); + edm::Association::Filler filler(*assoc); + filler.insert(caloRechitCollection, rechitIndices.begin(), rechitIndices.end()); + filler.fill(); + iEvent.put(std::move(assoc), label + "ToSimClus"); + } + iEvent.put(std::move(simClusterToRecEnergy)); +} + +// define this as a plug-in +DEFINE_FWK_MODULE(SimClusterRecHitAssociationProducer); diff --git a/DPGAnalysis/CommonNanoAOD/BuildFile.xml b/DPGAnalysis/CommonNanoAOD/BuildFile.xml new file mode 100644 index 0000000000000..6cc75a882ba98 --- /dev/null +++ b/DPGAnalysis/CommonNanoAOD/BuildFile.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/DPGAnalysis/CommonNanoAOD/plugins/BuildFile.xml b/DPGAnalysis/CommonNanoAOD/plugins/BuildFile.xml new file mode 100644 index 0000000000000..dc57b6da53c8e --- /dev/null +++ b/DPGAnalysis/CommonNanoAOD/plugins/BuildFile.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/DPGAnalysis/CommonNanoAOD/plugins/HitPositionTableProducer.cc b/DPGAnalysis/CommonNanoAOD/plugins/HitPositionTableProducer.cc new file mode 100644 index 0000000000000..f86ee30ea25d5 --- /dev/null +++ b/DPGAnalysis/CommonNanoAOD/plugins/HitPositionTableProducer.cc @@ -0,0 +1,119 @@ +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "DataFormats/NanoAOD/interface/FlatTable.h" +#include "DataFormats/Common/interface/View.h" +#include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h" +#include "SimDataFormats/TrackingHit/interface/PSimHit.h" +#include "CommonTools/Utils/interface/StringCutObjectSelector.h" + +#include "DataFormats/ForwardDetId/interface/HGCalDetId.h" +#include "DataFormats/ForwardDetId/interface/HGCScintillatorDetId.h" +#include "DataFormats/ForwardDetId/interface/HGCSiliconDetId.h" + +#include "DataFormats/GeometryVector/interface/GlobalPoint.h" +#include "Geometry/CaloGeometry/interface/CaloGeometry.h" +#include "Geometry/HGCalGeometry/interface/HGCalGeometry.h" +#include "Geometry/Records/interface/CaloGeometryRecord.h" +#include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h" +#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" +#include "Geometry/CSCGeometry/interface/CSCGeometry.h" +#include "Geometry/Records/interface/GlobalTrackingGeometryRecord.h" +#include "SimDataFormats/TrackingHit/interface/PSimHit.h" +#include "DataFormats/CaloRecHit/interface/CaloRecHit.h" +#include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" +#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" + +#include +#include + +template +class HitPositionTableProducer : public edm::stream::EDProducer<> { +public: + HitPositionTableProducer(edm::ParameterSet const& params) + : name_(params.getParameter("name")), + doc_(params.getParameter("doc")), + src_(consumes(params.getParameter("src"))), + cut_(params.getParameter("cut"), true) { + produces(); + } + + ~HitPositionTableProducer() override {} + + void beginRun(const edm::Run&, const edm::EventSetup& iSetup) override { + // TODO: check that the geometry exists + iSetup.get().get(caloGeom_); + rhtools_.setGeometry(*caloGeom_); + iSetup.get().get("idealForDigi", trackGeom_); + // Believe this is ideal, but we're not so precise here... + iSetup.get().get(globalGeom_); + } + + GlobalPoint positionFromHit(const PCaloHit& hit) { + DetId id = hit.id(); + return positionFromDetId(id); + } + + GlobalPoint positionFromHit(const CaloRecHit& hit) { return positionFromDetId(hit.detid()); } + + // Should really only be used for HGCAL + GlobalPoint positionFromDetId(DetId id) { + DetId::Detector det = id.det(); + if (det == DetId::Hcal || det == DetId::HGCalEE || det == DetId::HGCalHSi || det == DetId::HGCalHSc) { + return rhtools_.getPosition(id); + } else { + throw cms::Exception("HitPositionTableProducer") << "Unsupported DetId type"; + } + } + + GlobalPoint positionFromHit(const PSimHit& hit) { + auto detId = DetId(hit.detUnitId()); + auto surface = detId.det() == DetId::Muon ? globalGeom_->idToDet(hit.detUnitId())->surface() + : trackGeom_->idToDet(hit.detUnitId())->surface(); + GlobalPoint position = surface.toGlobal(hit.localPosition()); + return position; + } + + void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override { + edm::Handle objs; + iEvent.getByToken(src_, objs); + + std::vector xvals; + std::vector yvals; + std::vector zvals; + for (const auto& obj : *objs) { + if (cut_(obj)) { + auto position = positionFromHit(obj); + xvals.emplace_back(position.x()); + yvals.emplace_back(position.y()); + zvals.emplace_back(position.z()); + } + } + + auto tab = std::make_unique(xvals.size(), name_, false, true); + tab->addColumn("x", xvals, "x position"); + tab->addColumn("y", yvals, "y position"); + tab->addColumn("z", zvals, "z position"); + + iEvent.put(std::move(tab)); + } + +protected: + const std::string name_, doc_; + const edm::EDGetTokenT src_; + const StringCutObjectSelector cut_; + edm::ESHandle caloGeom_; + edm::ESHandle trackGeom_; + edm::ESHandle globalGeom_; + hgcal::RecHitTools rhtools_; +}; + +#include "FWCore/Framework/interface/MakerMacros.h" +typedef HitPositionTableProducer> PCaloHitPositionTableProducer; +typedef HitPositionTableProducer> PSimHitPositionTableProducer; +typedef HitPositionTableProducer HGCRecHitPositionTableProducer; +DEFINE_FWK_MODULE(HGCRecHitPositionTableProducer); +DEFINE_FWK_MODULE(PCaloHitPositionTableProducer); +DEFINE_FWK_MODULE(PSimHitPositionTableProducer); diff --git a/DPGAnalysis/CommonNanoAOD/python/pfCands_cff.py b/DPGAnalysis/CommonNanoAOD/python/pfCands_cff.py new file mode 100644 index 0000000000000..8b5aafaee8a1c --- /dev/null +++ b/DPGAnalysis/CommonNanoAOD/python/pfCands_cff.py @@ -0,0 +1,32 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.common_cff import CandVars,Var + +pfCandTable = cms.EDProducer("SimpleCandidateFlatTableProducer", + src = cms.InputTag("particleFlow"), + cut = cms.string(""), + name = cms.string("PFCand"), + doc = cms.string("ParticleFlow candidates"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the muons + variables = cms.PSet(CandVars, + Vtx_x = Var('vertex().x()', 'float', precision=14, doc='vertex x pos'), + Vtx_y = Var('vertex().y()', 'float', precision=14, doc='vertex y pos'), + Vtx_z = Var('vertex().z()', 'float', precision=14, doc='vertex z pos'), + ) +) + +pfTICLCandTable = cms.EDProducer("SimpleCandidateFlatTableProducer", + src = cms.InputTag("pfTICL"), + cut = cms.string(""), + name = cms.string("PFTICLCand"), + doc = cms.string("ParticleFlow candidates"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), + variables = cms.PSet(CandVars, + Vtx_x = Var('vertex().x()', 'float', precision=14, doc='vertex x pos'), + Vtx_y = Var('vertex().y()', 'float', precision=14, doc='vertex y pos'), + Vtx_z = Var('vertex().z()', 'float', precision=14, doc='vertex z pos'), + ) +) + +pfCandTables = cms.Sequence(pfCandTable+pfTICLCandTable) diff --git a/DPGAnalysis/HGCalNanoAOD/BuildFile.xml b/DPGAnalysis/HGCalNanoAOD/BuildFile.xml new file mode 100644 index 0000000000000..6cc75a882ba98 --- /dev/null +++ b/DPGAnalysis/HGCalNanoAOD/BuildFile.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/DPGAnalysis/HGCalNanoAOD/plugins/BuildFile.xml b/DPGAnalysis/HGCalNanoAOD/plugins/BuildFile.xml new file mode 100644 index 0000000000000..f5ae82be55fc7 --- /dev/null +++ b/DPGAnalysis/HGCalNanoAOD/plugins/BuildFile.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/DPGAnalysis/HGCalNanoAOD/plugins/ObjectIndexFromAssociationProducer.cc b/DPGAnalysis/HGCalNanoAOD/plugins/ObjectIndexFromAssociationProducer.cc new file mode 100644 index 0000000000000..9a25348c1bd3f --- /dev/null +++ b/DPGAnalysis/HGCalNanoAOD/plugins/ObjectIndexFromAssociationProducer.cc @@ -0,0 +1,31 @@ +#include "PhysicsTools/NanoAOD/interface/ObjectIndexFromAssociationProducer.h" +#include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" +#include "SimDataFormats/CaloAnalysis/interface/SimClusterFwd.h" +#include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h" +#include "SimDataFormats/CaloAnalysis/interface/CaloParticleFwd.h" +#include "SimDataFormats/Track/interface/SimTrack.h" +#include "SimDataFormats/Track/interface/SimTrackContainer.h" +#include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h" +#include "DataFormats/CaloRecHit/interface/CaloRecHit.h" +#include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h" +#include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +typedef ObjectIndexFromAssociationTableProducer + SimTrackToSimClusterIndexTableProducer; +typedef ObjectIndexFromAssociationTableProducer + CaloHitToSimClusterIndexTableProducer; +typedef ObjectIndexFromAssociationTableProducer, SimClusterCollection> + CaloRecHitToSimClusterIndexTableProducer; +typedef ObjectIndexFromAssociationTableProducer, reco::PFCandidateCollection> + CaloRecHitToPFCandIndexTableProducer; +typedef ObjectIndexFromAssociationTableProducer + SimClusterToCaloParticleIndexTableProducer; +typedef ObjectIndexFromAssociationTableProducer + SimClusterToSimClusterIndexTableProducer; +DEFINE_FWK_MODULE(SimTrackToSimClusterIndexTableProducer); +DEFINE_FWK_MODULE(CaloHitToSimClusterIndexTableProducer); +DEFINE_FWK_MODULE(SimClusterToCaloParticleIndexTableProducer); +DEFINE_FWK_MODULE(CaloRecHitToSimClusterIndexTableProducer); +DEFINE_FWK_MODULE(SimClusterToSimClusterIndexTableProducer); +DEFINE_FWK_MODULE(CaloRecHitToPFCandIndexTableProducer); diff --git a/DPGAnalysis/HGCalNanoAOD/plugins/SimClusterRecEnergyTableProducer.cc b/DPGAnalysis/HGCalNanoAOD/plugins/SimClusterRecEnergyTableProducer.cc new file mode 100644 index 0000000000000..295f71418841d --- /dev/null +++ b/DPGAnalysis/HGCalNanoAOD/plugins/SimClusterRecEnergyTableProducer.cc @@ -0,0 +1,7 @@ +#include "PhysicsTools/NanoAOD/interface/ObjectPropertyFromIndexMapTableProducer.h" +#include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" +#include "SimDataFormats/CaloAnalysis/interface/SimClusterFwd.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +typedef ObjectPropertyFromIndexMapTableProducer SimClusterRecEnergyTableProducer; +DEFINE_FWK_MODULE(SimClusterRecEnergyTableProducer); diff --git a/DPGAnalysis/HGCalNanoAOD/plugins/SimpleHGCFlatTableProducerPlugins.cc b/DPGAnalysis/HGCalNanoAOD/plugins/SimpleHGCFlatTableProducerPlugins.cc new file mode 100644 index 0000000000000..cd1e3b044668e --- /dev/null +++ b/DPGAnalysis/HGCalNanoAOD/plugins/SimpleHGCFlatTableProducerPlugins.cc @@ -0,0 +1,18 @@ +#include "PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h" + +#include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" +typedef SimpleFlatTableProducer SimpleSimClusterFlatTableProducer; + +#include "SimDataFormats/CaloHit/interface/PCaloHit.h" +typedef SimpleFlatTableProducer SimplePCaloHitFlatTableProducer; +#include "DataFormats/CaloRecHit/interface/CaloRecHit.h" +typedef SimpleFlatTableProducer SimpleCaloRecHitFlatTableProducer; + +#include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h" +typedef SimpleFlatTableProducer SimpleCaloParticleFlatTableProducer; + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(SimplePCaloHitFlatTableProducer); +DEFINE_FWK_MODULE(SimpleCaloRecHitFlatTableProducer); +DEFINE_FWK_MODULE(SimpleSimClusterFlatTableProducer); +DEFINE_FWK_MODULE(SimpleCaloParticleFlatTableProducer); diff --git a/DPGAnalysis/HGCalNanoAOD/python/caloParticles_cff.py b/DPGAnalysis/HGCalNanoAOD/python/caloParticles_cff.py new file mode 100644 index 0000000000000..91617d618bded --- /dev/null +++ b/DPGAnalysis/HGCalNanoAOD/python/caloParticles_cff.py @@ -0,0 +1,20 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.common_cff import CandVars,Var + +caloParticleTable = cms.EDProducer("SimpleCaloParticleFlatTableProducer", + src = cms.InputTag("mix:MergedCaloTruth"), + cut = cms.string(""), + name = cms.string("CaloPart"), + doc = cms.string("CaloPart"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the muons + variables = cms.PSet(CandVars, + simEnergy = Var('simEnergy', 'int', precision=-1, doc='Number of associated gen particles'), + nGenPart = Var('genParticles().size()', 'int', precision=-1, doc='Number of associated gen particles'), + GenPartIdx = Var('? genParticles.size() ? genParticles().at(0).key() : -1', 'int', precision=-1, doc='Number of associated gen particles'), + nSimHit = Var('numberOfSimHits', 'int', precision=-1, doc='Number of simhits'), + trackId = Var('g4Tracks().at(0).trackId', 'int', precision=-1, doc='Geant4 track ID of first track'), + nSimTrack = Var('g4Tracks().size', 'int', precision=-1, doc='Number of associated simtracks'), + ) +) + diff --git a/DPGAnalysis/HGCalNanoAOD/python/hgcRecHits_cff.py b/DPGAnalysis/HGCalNanoAOD/python/hgcRecHits_cff.py new file mode 100644 index 0000000000000..de6170d977354 --- /dev/null +++ b/DPGAnalysis/HGCalNanoAOD/python/hgcRecHits_cff.py @@ -0,0 +1,114 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.common_cff import Var,P3Vars + +hgcEERecHitsTable = cms.EDProducer("SimpleCaloRecHitFlatTableProducer", + src = cms.InputTag("HGCalRecHit:HGCEERecHits"), + cut = cms.string(""), + name = cms.string("RecHitHGCEE"), + doc = cms.string("RecHits in HGCAL Electromagnetic endcap"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the muons + variables = cms.PSet( + detId = Var('detid().rawId()', 'int', precision=-1, doc='detId'), + energy = Var('energy', 'float', precision=14, doc='energy'), + time = Var('time', 'float', precision=14, doc='hit time'), + ) +) + +hgcRecHitsToSimClusters = cms.EDProducer("SimClusterRecHitAssociationProducer", + caloRecHits = cms.VInputTag("HGCalRecHit:HGCEERecHits", + "HGCalRecHit:HGCHEFRecHits", "HGCalRecHit:HGCHEBRecHits", + ), + simClusters = cms.InputTag("mix:MergedCaloTruth"), +) + +hgcEERecHitsToSimClusterTable = cms.EDProducer("CaloRecHitToSimClusterIndexTableProducer", + cut = hgcEERecHitsTable.cut, + src = hgcEERecHitsTable.src, + objName = hgcEERecHitsTable.name, + branchName = cms.string("SimCluster"), + objMap = cms.InputTag("hgcRecHitsToSimClusters:HGCEERecHitsToSimClus"), + docString = cms.string("SimCluster responsible for most sim energy in RecHit DetId") +) + +# TODO: Pair with simclusters +simClusterRecEnergyTable = cms.EDProducer("SimClusterRecEnergyTableProducer", + src = cms.InputTag("mix:MergedCaloTruth"), + cut = cms.string(""), + objName = cms.string("SimCluster"), + branchName = cms.string("recEnergy"), + valueMap = cms.InputTag("hgcRecHitsToSimClusters"), + docString = cms.string("SimCluster deposited reconstructed energy associated to SimCluster") +) + +hgcRecHitsToPFCands = cms.EDProducer("RecHitToPFCandAssociationProducer", + caloRecHits = cms.VInputTag("HGCalRecHit:HGCEERecHits", + "HGCalRecHit:HGCHEFRecHits", "HGCalRecHit:HGCHEBRecHits", + ), + pfCands = cms.InputTag("particleFlow"), +) + +hgcEERecHitsToPFCandTable = cms.EDProducer("CaloRecHitToPFCandIndexTableProducer", + cut = hgcEERecHitsTable.cut, + src = hgcEERecHitsTable.src, + objName = hgcEERecHitsTable.name, + branchName = cms.string("PFCand"), + objMap = cms.InputTag("hgcRecHitsToPFCands:HGCEERecHitsToPFCand"), + docString = cms.string("PFCand with most associated energy in RecHit DetId") +) + +hgcHEfrontRecHitsTable = hgcEERecHitsTable.clone() +hgcHEfrontRecHitsTable.src = "HGCalRecHit:HGCHEFRecHits" +hgcHEfrontRecHitsTable.name = "RecHitHGCHEF" + +hgcHEfrontRecHitsToSimClusterTable = hgcEERecHitsToSimClusterTable.clone() +hgcHEfrontRecHitsToSimClusterTable.src = hgcHEfrontRecHitsTable.src +hgcHEfrontRecHitsToSimClusterTable.objName = hgcHEfrontRecHitsTable.name +hgcHEfrontRecHitsToSimClusterTable.objMap = "hgcRecHitsToSimClusters:HGCHEFRecHitsToSimClus" + +hgcHEfrontRecHitsToPFCandTable = hgcEERecHitsToPFCandTable.clone() +hgcHEfrontRecHitsToPFCandTable.src = hgcHEfrontRecHitsTable.src +hgcHEfrontRecHitsToPFCandTable.objName = hgcHEfrontRecHitsTable.name +hgcHEfrontRecHitsToPFCandTable.objMap = "hgcRecHitsToPFCands:HGCHEFRecHitsToPFCand" + +hgcHEbackRecHitsTable = hgcEERecHitsTable.clone() +hgcHEbackRecHitsTable.src = "HGCalRecHit:HGCHEBRecHits" +hgcHEbackRecHitsTable.name = "RecHitHGCHEB" + +hgcHEbackRecHitsToSimClusterTable = hgcEERecHitsToSimClusterTable.clone() +hgcHEbackRecHitsToSimClusterTable.src = hgcHEbackRecHitsTable.src +hgcHEbackRecHitsToSimClusterTable.objName = hgcHEbackRecHitsTable.name +hgcHEbackRecHitsToSimClusterTable.objMap = "hgcRecHitsToSimClusters:HGCHEBRecHitsToSimClus" + +hgcHEbackRecHitsToPFCandTable = hgcEERecHitsToPFCandTable.clone() +hgcHEbackRecHitsToPFCandTable.src = hgcHEbackRecHitsTable.src +hgcHEbackRecHitsToPFCandTable.objName = hgcHEbackRecHitsTable.name +hgcHEbackRecHitsToPFCandTable.objMap = "hgcRecHitsToPFCands:HGCHEBRecHitsToPFCand" + +hgcEERecHitsPositionTable = cms.EDProducer("HGCRecHitPositionTableProducer", + src = hgcEERecHitsTable.src, + cut = hgcEERecHitsTable.cut, + name = hgcEERecHitsTable.name, + doc = hgcEERecHitsTable.doc, +) +# +hgcHEfrontRecHitsPositionTable = hgcEERecHitsPositionTable.clone() +hgcHEfrontRecHitsPositionTable.name = hgcHEfrontRecHitsTable.name +hgcHEfrontRecHitsPositionTable.src = hgcHEfrontRecHitsTable.src + +hgcHEbackRecHitsPositionTable = hgcEERecHitsPositionTable.clone() +hgcHEbackRecHitsPositionTable.name = hgcHEbackRecHitsTable.name +hgcHEbackRecHitsPositionTable.src = hgcHEbackRecHitsTable.src + +hgcRecHitsSequence = cms.Sequence(hgcEERecHitsTable+hgcHEbackRecHitsTable+hgcHEfrontRecHitsTable + +hgcRecHitsToSimClusters + +simClusterRecEnergyTable + +hgcRecHitsToPFCands + +hgcEERecHitsToPFCandTable+hgcHEfrontRecHitsToPFCandTable+hgcHEbackRecHitsToPFCandTable + +hgcEERecHitsPositionTable + +hgcHEfrontRecHitsPositionTable + +hgcHEbackRecHitsPositionTable + +hgcEERecHitsToSimClusterTable + +hgcHEfrontRecHitsToSimClusterTable + +hgcHEbackRecHitsToSimClusterTable +) diff --git a/DPGAnalysis/HGCalNanoAOD/python/hgcSimHits_cff.py b/DPGAnalysis/HGCalNanoAOD/python/hgcSimHits_cff.py new file mode 100644 index 0000000000000..e9beb4ee24a08 --- /dev/null +++ b/DPGAnalysis/HGCalNanoAOD/python/hgcSimHits_cff.py @@ -0,0 +1,68 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.common_cff import Var,P3Vars + +hgcEESimHitsTable = cms.EDProducer("SimplePCaloHitFlatTableProducer", + src = cms.InputTag("g4SimHits:HGCHitsEE"), + cut = cms.string(""), + name = cms.string("SimHitHGCEE"), + doc = cms.string("Geant4 SimHits in HGCAL Electromagnetic endcap"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the muons + variables = cms.PSet( + detId = Var('id', 'int', precision=-1, doc='detId'), + energy = Var('energy', 'float', precision=14, doc='energy'), + trackId = Var('geantTrackId', 'int', precision=-1, doc='Geant4 track ID'), + ) +) + +hgcEEHitsToSimClusterTable = cms.EDProducer("CaloHitToSimClusterIndexTableProducer", + cut = hgcEESimHitsTable.cut, + src = hgcEESimHitsTable.src, + objName = hgcEESimHitsTable.name, + branchName = cms.string("SimCluster"), + objMap = cms.InputTag("mix:simHitHGCEEToSimCluster"), + docString = cms.string("SimCluster containing SimHit") +) + +hgcHEfrontSimHitsTable = hgcEESimHitsTable.clone() +hgcHEfrontSimHitsTable.src = "g4SimHits:HGCHitsHEfront" +hgcHEfrontSimHitsTable.name = "SimHitHGCHEF" + +hgcHEfrontHitsToSimClusterTable = hgcEEHitsToSimClusterTable.clone() +hgcHEfrontHitsToSimClusterTable.src = hgcHEfrontSimHitsTable.src +hgcHEfrontHitsToSimClusterTable.objName = hgcHEfrontSimHitsTable.name +hgcHEfrontHitsToSimClusterTable.objMap = "mix:simHitHGCHEfrontToSimCluster" + +hgcHEbackSimHitsTable = hgcEESimHitsTable.clone() +hgcHEbackSimHitsTable.src = "g4SimHits:HGCHitsHEback" +hgcHEbackSimHitsTable.name = "SimHitHGCHEB" + +hgcHEbackHitsToSimClusterTable = hgcEEHitsToSimClusterTable.clone() +hgcHEbackHitsToSimClusterTable.src = hgcHEbackSimHitsTable.src +hgcHEbackHitsToSimClusterTable.objName = hgcHEbackSimHitsTable.name +hgcHEbackHitsToSimClusterTable.objMap = "mix:simHitHGCHEbackToSimCluster" + +hgcEESimHitsPositionTable = cms.EDProducer("PCaloHitPositionTableProducer", + src = hgcEESimHitsTable.src, + cut = hgcEESimHitsTable.cut, + name = hgcEESimHitsTable.name, + doc = hgcEESimHitsTable.doc, +) + +hgcHEfrontSimHitsPositionTable = hgcEESimHitsPositionTable.clone() +hgcHEfrontSimHitsPositionTable.name = hgcHEfrontSimHitsTable.name +hgcHEfrontSimHitsPositionTable.src = hgcHEfrontSimHitsTable.src + +hgcHEbackSimHitsPositionTable = hgcEESimHitsPositionTable.clone() +hgcHEbackSimHitsPositionTable.name = hgcHEbackSimHitsTable.name +hgcHEbackSimHitsPositionTable.src = hgcHEbackSimHitsTable.src + +hgcSimHitsSequence = cms.Sequence(hgcEESimHitsTable+hgcHEbackSimHitsTable+hgcHEfrontSimHitsTable + +hgcEESimHitsPositionTable + +hgcHEfrontSimHitsPositionTable + +hgcHEbackSimHitsPositionTable + +hgcEEHitsToSimClusterTable + +hgcHEfrontHitsToSimClusterTable + +hgcHEbackHitsToSimClusterTable + +hgcHEfrontSimHitsTable+hgcHEbackSimHitsTable) + diff --git a/DPGAnalysis/HGCalNanoAOD/python/hgcSimTracks_cff.py b/DPGAnalysis/HGCalNanoAOD/python/hgcSimTracks_cff.py new file mode 100644 index 0000000000000..8a9870c44bb0c --- /dev/null +++ b/DPGAnalysis/HGCalNanoAOD/python/hgcSimTracks_cff.py @@ -0,0 +1,41 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.common_cff import Var + +simTrackTable = cms.EDProducer("SimpleSimTrackFlatTableProducer", + src = cms.InputTag("g4SimHits"), + cut = cms.string("abs(momentum().eta) > 1.52 || abs(getMomentumAtBoundary().eta()) > 1.52"), + name = cms.string("SimTrack"), + doc = cms.string("Geant4 sim tracks in HGCAL Electromagnetic endcap"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the muons + variables = cms.PSet( + crossedBoundary = Var('crossedBoundary', 'bool', doc='track crossed boundary'), + pdgId = Var('type', 'int', doc='pdgId (track type)'), + charge = Var('charge', 'int', doc='ID'), + trackId = Var('trackId', 'int', precision=-1, doc='ID'), + trackIdAtBoundary = Var('getIDAtBoundary', 'int', precision=-1, doc='ID at boundary crossing'), + pt = Var('momentum().pt()', 'float', precision=14, doc='pt'), + eta = Var('momentum().eta()', 'float', precision=14, doc='eta'), + phi = Var('momentum().phi()', 'float', precision=14, doc='phi'), + lastPos_x = Var('trackerSurfacePosition().x()', 'float', precision=14, doc='x position at HGCAL boundary'), + lastPos_y = Var('trackerSurfacePosition().y()', 'float', precision=14, doc='y position at HGCAL boundary'), + lastPos_z = Var('trackerSurfacePosition().z()', 'float', precision=14, doc='z position at HGCAL boundary'), + boundaryPos_x = Var('getPositionAtBoundary().x()', 'float', precision=14, doc='x position at HGCAL boundary'), + boundaryPos_y = Var('getPositionAtBoundary().y()', 'float', precision=14, doc='y position at HGCAL boundary'), + boundaryPos_z = Var('getPositionAtBoundary().z()', 'float', precision=14, doc='z position at HGCAL boundary'), + boundaryMomentum_pt = Var('getMomentumAtBoundary().pt()', 'float', precision=14, doc='pt at HGCAL boundary'), + boundaryMomentum_eta = Var('getMomentumAtBoundary().eta()', 'float', precision=14, doc='eta position at HGCAL boundary'), + boundaryMomentum_phi = Var('getMomentumAtBoundary().phi()', 'float', precision=14, doc='phi position at HGCAL boundary'), + ) +) + +simTrackToSimClusterTable = cms.EDProducer("SimTrackToSimClusterIndexTableProducer", + cut = simTrackTable.cut, + src = simTrackTable.src, + objName = simTrackTable.name, + branchName = cms.string("SimCluster"), + objMap = cms.InputTag("mix:simTrackToSimCluster"), + docString = cms.string("SimCluster containing track") +) + +simTrackTables = cms.Sequence(simTrackTable+simTrackToSimClusterTable) diff --git a/DPGAnalysis/HGCalNanoAOD/python/nanoHGCML_cff.py b/DPGAnalysis/HGCalNanoAOD/python/nanoHGCML_cff.py new file mode 100644 index 0000000000000..bd97e10ce7c45 --- /dev/null +++ b/DPGAnalysis/HGCalNanoAOD/python/nanoHGCML_cff.py @@ -0,0 +1,35 @@ +from __future__ import print_function +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.common_cff import * +from PhysicsTools.NanoAOD.genparticles_cff import genParticleTable +from PhysicsTools.NanoAOD.genVertex_cff import * +from DPGAnalysis.HGCalNanoAOD.hgcSimHits_cff import * +from DPGAnalysis.HGCalNanoAOD.hgcSimTracks_cff import * +from DPGAnalysis.HGCalNanoAOD.hgcRecHits_cff import * +from DPGAnalysis.HGCalNanoAOD.simClusters_cff import * +from DPGAnalysis.HGCalNanoAOD.caloParticles_cff import * +from DPGAnalysis.TrackNanoAOD.trackSimHits_cff import * +from DPGAnalysis.TrackNanoAOD.trackingParticles_cff import * +from DPGAnalysis.TrackNanoAOD.tracks_cff import * +from DPGAnalysis.CommonNanoAOD.pfCands_cff import * + +nanoMetadata = cms.EDProducer("UniqueStringProducer", + strings = cms.PSet( + tag = cms.string("untagged"), + ) +) + +genParticleTable.src = "genParticles" +genParticleTable.variables = cms.PSet(genParticleTable.variables, + charge = CandVars.charge) + +nanoHGCMLSequence = cms.Sequence(nanoMetadata+genVertexTables+genParticleTable+ + trackingParticleTable+caloParticleTable+simClusterTables+ + simTrackTables+hgcSimHitsSequence+trackerSimHitTables) + +def customizeReco(process): + process.nanoHGCMLSequence.insert(1, hgcRecHitsSequence) + process.nanoHGCMLSequence.insert(2, pfCandTable) + process.nanoHGCMLSequence.insert(3, pfTICLCandTable) + process.nanoHGCMLSequence.insert(4, trackTables) + return process diff --git a/DPGAnalysis/HGCalNanoAOD/python/simClusters_cff.py b/DPGAnalysis/HGCalNanoAOD/python/simClusters_cff.py new file mode 100644 index 0000000000000..abe312f1b1bf1 --- /dev/null +++ b/DPGAnalysis/HGCalNanoAOD/python/simClusters_cff.py @@ -0,0 +1,41 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.common_cff import CandVars,Var + +simClusterTable = cms.EDProducer("SimpleSimClusterFlatTableProducer", + src = cms.InputTag("mix:MergedCaloTruth"), + cut = cms.string(""), + name = cms.string("SimCluster"), + doc = cms.string("SimCluster information"), + singleton = cms.bool(False), + extension = cms.bool(False), + variables = cms.PSet(CandVars, + lastPos_x = Var('g4Tracks.at(0).trackerSurfacePosition().x()', 'float', precision=14, doc='track x final position'), + lastPos_y = Var('g4Tracks.at(0).trackerSurfacePosition().y()', 'float', precision=14, doc='track y final position'), + lastPos_z = Var('g4Tracks.at(0).trackerSurfacePosition().z()', 'float', precision=14, doc='track z final position'), + impactPoint_x = Var('g4Tracks().at(0).getPositionAtBoundary().x()', 'float', precision=14, doc='x position'), + impactPoint_y = Var('g4Tracks().at(0).getPositionAtBoundary().y()', 'float', precision=14, doc='y position'), + impactPoint_z = Var('g4Tracks().at(0).getPositionAtBoundary().z()', 'float', precision=14, doc='z position'), + impactPoint_t = Var('g4Tracks().at(0).getPositionAtBoundary().t()', 'float', precision=14, doc='Impact time'), + # For stupid reasons lost on me, the nsimhits_ variable is uninitialized, and hits_ (which are really simhits) + # are often referred to as rechits in the SimCluster class + nHits = Var('numberOfRecHits', 'int', precision=-1, doc='number of simhits'), + sumHitEnergy = Var('energy', 'float', precision=14, doc='total energy of simhits'), + boundaryPmag = Var('g4Tracks().at(0).getMomentumAtBoundary().P()', 'float', precision=14, doc='magnitude of the boundary 3-momentum vector'), + boundaryP4 = Var('g4Tracks().at(0).getMomentumAtBoundary().mag()', 'float', precision=14, doc='magnitude of four vector'), + boundaryEnergy = Var('g4Tracks().at(0).getMomentumAtBoundary().energy()', 'float', precision=14, doc='magnitude of four vector'), + boundaryPt = Var('g4Tracks().at(0).getMomentumAtBoundary().pt()', 'float', precision=14, doc='magnitude of four vector'), + trackId = Var('g4Tracks().at(0).trackId()', 'int', precision=-1, doc='Geant track id'), + trackIdAtBoundary = Var('g4Tracks().at(0).getIDAtBoundary()', 'int', precision=-1, doc='Track ID at boundary'), + ) +) + +simClusterToCaloPartTable = cms.EDProducer("SimClusterToCaloParticleIndexTableProducer", + cut = simClusterTable.cut, + src = simClusterTable.src, + objName = simClusterTable.name, + branchName = cms.string("CaloPart"), + objMap = cms.InputTag("mix:simClusterToCaloParticle"), + docString = cms.string("Index of CaloPart containing SimCluster") +) + +simClusterTables = cms.Sequence(simClusterTable+simClusterToCaloPartTable) diff --git a/DPGAnalysis/HGCalNanoAOD/test/nanoMLGSD_cfg.py b/DPGAnalysis/HGCalNanoAOD/test/nanoMLGSD_cfg.py new file mode 100644 index 0000000000000..425a24eab4d35 --- /dev/null +++ b/DPGAnalysis/HGCalNanoAOD/test/nanoMLGSD_cfg.py @@ -0,0 +1,117 @@ +# Auto generated configuration file +# using: +# Revision: 1.19 +# Source: /local/reps/CMSSW/CMSSW/Configuration/Applications/python/ConfigBuilder.py,v +# with command line options: step1 --filein file:test.root --fileout testNanoML.root --mc --eventcontent NANOAODSIM --datatier NANOAODSIM --conditions auto:mc --step NANO +import FWCore.ParameterSet.Config as cms +from FWCore.ParameterSet.VarParsing import VarParsing + + +process = cms.Process('NANO') +options = VarParsing('python') +options.setDefault('outputFile', 'testNanoML.root') +options.parseArguments() + +# 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.mixNoPU_cfi') +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('DPGAnalysis.HGCalNanoAOD.nanoHGCML_cff') +process.load('Configuration.StandardSequences.EndOfProcess_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(-1), + output = cms.optional.untracked.allowed(cms.int32,cms.PSet) +) + +# Input source +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring(options.inputFiles), + 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( + allowAnyLabel_=cms.required.untracked.uint32 + ), + 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('step1 nevts:1'), + name = cms.untracked.string('Applications'), + version = cms.untracked.string('$Revision: 1.19 $') +) + +# Output definition + +process.NANOAODSIMoutput = cms.OutputModule("NanoAODOutputModule", + compressionAlgorithm = cms.untracked.string('LZMA'), + compressionLevel = cms.untracked.int32(9), + dataset = cms.untracked.PSet( + dataTier = cms.untracked.string('NANOAODSIM'), + filterName = cms.untracked.string('') + ), + fileName = cms.untracked.string(options.outputFile), + outputCommands = process.NANOAODSIMEventContent.outputCommands +) + +process.NANOAODSIMoutput.outputCommands.remove("keep edmTriggerResults_*_*_*") + +# Additional output definition + +# Other statements +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:mc', '') + +# Path and EndPath definitions +process.nanoAOD_step = cms.Path(process.nanoHGCMLSequence) +process.endjob_step = cms.EndPath(process.endOfProcess) +process.NANOAODSIMoutput_step = cms.EndPath(process.NANOAODSIMoutput) + +# Schedule definition +process.schedule = cms.Schedule(process.nanoAOD_step,process.endjob_step,process.NANOAODSIMoutput_step) +from PhysicsTools.PatAlgos.tools.helpers import associatePatAlgosToolsTask +associatePatAlgosToolsTask(process) + +# customisation of the process. +from DPGAnalysis.HGCalNanoAOD.nanoHGCML_cff import customizeReco +#process = customizeReco(process) + +# End of customisation functions + + +# Customisation from command line + +# 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 + diff --git a/DPGAnalysis/HGCalNanoAOD/test/nanoML_cfg.py b/DPGAnalysis/HGCalNanoAOD/test/nanoML_cfg.py new file mode 100644 index 0000000000000..fc1de4ff88a5d --- /dev/null +++ b/DPGAnalysis/HGCalNanoAOD/test/nanoML_cfg.py @@ -0,0 +1,116 @@ +# Auto generated configuration file +# using: +# Revision: 1.19 +# Source: /local/reps/CMSSW/CMSSW/Configuration/Applications/python/ConfigBuilder.py,v +# with command line options: step1 --filein file:test.root --fileout testNanoML.root --mc --eventcontent NANOAODSIM --datatier NANOAODSIM --conditions auto:mc --step NANO +import FWCore.ParameterSet.Config as cms +from FWCore.ParameterSet.VarParsing import VarParsing + + +process = cms.Process('NANO') +options = VarParsing('python') +options.setDefault('outputFile', 'testNanoML.root') +options.parseArguments() + +# 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.mixNoPU_cfi') +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('DPGAnalysis.HGCalNanoAOD.nanoHGCML_cff') +process.load('Configuration.StandardSequences.EndOfProcess_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(-1), + output = cms.optional.untracked.allowed(cms.int32,cms.PSet) +) + +# Input source +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring(options.inputFiles), + 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( + allowAnyLabel_=cms.required.untracked.uint32 + ), + 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('step1 nevts:1'), + name = cms.untracked.string('Applications'), + version = cms.untracked.string('$Revision: 1.19 $') +) + +# Output definition + +process.NANOAODSIMoutput = cms.OutputModule("NanoAODOutputModule", + compressionAlgorithm = cms.untracked.string('LZMA'), + compressionLevel = cms.untracked.int32(9), + dataset = cms.untracked.PSet( + dataTier = cms.untracked.string('NANOAODSIM'), + filterName = cms.untracked.string('') + ), + fileName = cms.untracked.string(options.outputFile), + outputCommands = process.NANOAODSIMEventContent.outputCommands +) + +process.NANOAODSIMoutput.outputCommands.remove("keep edmTriggerResults_*_*_*") + +# Additional output definition + +# Other statements +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:mc', '') + +# Path and EndPath definitions +process.nanoAOD_step = cms.Path(process.nanoHGCMLSequence) +process.endjob_step = cms.EndPath(process.endOfProcess) +process.NANOAODSIMoutput_step = cms.EndPath(process.NANOAODSIMoutput) + +# Schedule definition +process.schedule = cms.Schedule(process.nanoAOD_step,process.endjob_step,process.NANOAODSIMoutput_step) +from PhysicsTools.PatAlgos.tools.helpers import associatePatAlgosToolsTask +associatePatAlgosToolsTask(process) + +# customisation of the process. +from DPGAnalysis.HGCalNanoAOD.nanoHGCML_cff import customizeReco +process = customizeReco(process) + +# End of customisation functions + + +# Customisation from command line + +# 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 diff --git a/DPGAnalysis/TrackNanoAOD/BuildFile.xml b/DPGAnalysis/TrackNanoAOD/BuildFile.xml new file mode 100644 index 0000000000000..6cc75a882ba98 --- /dev/null +++ b/DPGAnalysis/TrackNanoAOD/BuildFile.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/DPGAnalysis/TrackNanoAOD/plugins/BuildFile.xml b/DPGAnalysis/TrackNanoAOD/plugins/BuildFile.xml new file mode 100644 index 0000000000000..e91a9c160e5f5 --- /dev/null +++ b/DPGAnalysis/TrackNanoAOD/plugins/BuildFile.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/DPGAnalysis/TrackNanoAOD/plugins/SimpleTrackFlatTableProducerPlugins.cc b/DPGAnalysis/TrackNanoAOD/plugins/SimpleTrackFlatTableProducerPlugins.cc new file mode 100644 index 0000000000000..b23e57e8bebaf --- /dev/null +++ b/DPGAnalysis/TrackNanoAOD/plugins/SimpleTrackFlatTableProducerPlugins.cc @@ -0,0 +1,18 @@ +#include "PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h" + +#include "SimDataFormats/TrackingHit/interface/PSimHit.h" +typedef SimpleFlatTableProducer SimplePSimHitFlatTableProducer; + +#include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h" +typedef SimpleFlatTableProducer SimpleTrackingParticleFlatTableProducer; + +#include "SimDataFormats/Track/interface/SimTrack.h" +typedef SimpleFlatTableProducer SimpleSimTrackFlatTableProducer; +#include "DataFormats/TrackReco/interface/Track.h" +typedef SimpleFlatTableProducer SimpleTrackFlatTableProducer; + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(SimplePSimHitFlatTableProducer); +DEFINE_FWK_MODULE(SimpleSimTrackFlatTableProducer); +DEFINE_FWK_MODULE(SimpleTrackingParticleFlatTableProducer); +DEFINE_FWK_MODULE(SimpleTrackFlatTableProducer); diff --git a/DPGAnalysis/TrackNanoAOD/python/trackSimHits_cff.py b/DPGAnalysis/TrackNanoAOD/python/trackSimHits_cff.py new file mode 100644 index 0000000000000..2067b9a50ca79 --- /dev/null +++ b/DPGAnalysis/TrackNanoAOD/python/trackSimHits_cff.py @@ -0,0 +1,53 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.common_cff import CandVars,Var + +trackerHitsPixelEndcapLowTofTable = cms.EDProducer("SimplePSimHitFlatTableProducer", + src = cms.InputTag("g4SimHits:TrackerHitsPixelEndcapLowTof"), + cut = cms.string(""), + name = cms.string("SimHitPixelECLowTof"), + doc = cms.string("Geant4 SimHits in tracker endcap"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the muons + variables = cms.PSet( + detId = Var('detUnitId', 'int', precision=-1, doc='detId'), + energy = Var('energyLoss', 'float', precision=14, doc='energy'), + pMag = Var('pabs', 'float', precision=14, doc='magnitude of momentum'), + trackId = Var('trackId', 'int', precision=-1, doc='Geant4 track ID'), + pdgId = Var('particleType', 'int', doc='PDG ID of associated track'), + ) +) + +trackerHitsPixelEndcapLowTofPositionTable = cms.EDProducer("PSimHitPositionTableProducer", + src = trackerHitsPixelEndcapLowTofTable.src, + cut = trackerHitsPixelEndcapLowTofTable.cut, + name = trackerHitsPixelEndcapLowTofTable.name, + doc = trackerHitsPixelEndcapLowTofTable.doc, +) + +trackerHitsPixelBarrelLowTofTable = trackerHitsPixelEndcapLowTofTable.clone() +trackerHitsPixelBarrelLowTofTable.src = "g4SimHits:TrackerHitsPixelBarrelLowTof" +trackerHitsPixelBarrelLowTofTable.name = "SimHitPixelLowTof" +trackerHitsPixelBarrelLowTofTable.doc = "Geant4 SimHits in pixel barrel" + +trackerHitsPixelBarrelLowTofPositionTable = cms.EDProducer("PSimHitPositionTableProducer", + src = trackerHitsPixelBarrelLowTofTable.src, + cut = trackerHitsPixelBarrelLowTofTable.cut, + name = trackerHitsPixelBarrelLowTofTable.name, + doc = trackerHitsPixelBarrelLowTofTable.doc, +) + +muonCSCHitsTable = trackerHitsPixelEndcapLowTofTable.clone() +muonCSCHitsTable.src = "g4SimHits:MuonCSCHits" +muonCSCHitsTable.name = "SimHitMuonCSC" +muonCSCHitsTable.doc = "Geant4 SimHits in Muon CSCs" + +muonCSCHitsPositionTable = cms.EDProducer("PSimHitPositionTableProducer", + src = muonCSCHitsTable.src, + cut = muonCSCHitsTable.cut, + name = muonCSCHitsTable.name, + doc = muonCSCHitsTable.doc, +) + +trackerSimHitTables = cms.Sequence(trackerHitsPixelEndcapLowTofTable+trackerHitsPixelEndcapLowTofPositionTable+ + trackerHitsPixelBarrelLowTofTable+trackerHitsPixelBarrelLowTofPositionTable+ + muonCSCHitsTable+muonCSCHitsPositionTable) diff --git a/DPGAnalysis/TrackNanoAOD/python/trackingParticles_cff.py b/DPGAnalysis/TrackNanoAOD/python/trackingParticles_cff.py new file mode 100644 index 0000000000000..c2c7e4f4d72e0 --- /dev/null +++ b/DPGAnalysis/TrackNanoAOD/python/trackingParticles_cff.py @@ -0,0 +1,28 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.common_cff import CandVars,Var + +trackingParticleTable = cms.EDProducer("SimpleTrackingParticleFlatTableProducer", + src = cms.InputTag("mix:MergedTrackTruth"), + cut = cms.string(""), + name = cms.string("TrackingPart"), + doc = cms.string("TrackingPart"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the muons + variables = cms.PSet(CandVars, + nGenPart = Var('genParticles().size()', 'int', precision=-1, doc='Number of associated gen particles'), + GenPartIdx = Var('? genParticles.size() ? genParticles().at(0).key() : -1', 'int', precision=-1, doc='Number of associated gen particles'), + trackId = Var('g4Tracks.at(0).trackId', 'int', precision=-1, doc='Geant4 track ID of first track'), + nSimTrack = Var('g4Tracks().size', 'int', precision=-1, doc='Number of associated simtracks'), + Vtx_x = Var('vx()', 'float', precision=14, doc='parent vertex x pos'), + Vtx_y = Var('vy()', 'float', precision=14, doc='parent vertex y pos'), + Vtx_z = Var('vz()', 'float', precision=14, doc='parent vertex z pos'), + Vtx_t = Var('parentVertex().position().T()', 'float', precision=14, doc='parent vertex time'), + nDecayVtx = Var('decayVertices().size()', 'int', precision=-1, doc='number of decay vertices'), + DecayVtx_y = Var('? decayVertices().size() > 0 ? decayVertices().at(0).position().x : 10000', 'float', precision=14, doc='x position of first decay vertex'), + DecayVtx_x = Var('? decayVertices().size() > 0 ? decayVertices().at(0).position().y : 10000', 'float', precision=14, doc='y position of first decay vertex'), + DecayVtx_z = Var('? decayVertices().size() > 0 ? decayVertices().at(0).position().z : 10000', 'float', precision=14, doc='z position of first decay vertex'), + DecayVtx_t = Var('? decayVertices().size() > 0 ? decayVertices().at(0).position().t : 10000', 'float', precision=14, doc='time of first decay vertex'), + ) +) + + diff --git a/DPGAnalysis/TrackNanoAOD/python/tracks_cff.py b/DPGAnalysis/TrackNanoAOD/python/tracks_cff.py new file mode 100644 index 0000000000000..20f2d66769761 --- /dev/null +++ b/DPGAnalysis/TrackNanoAOD/python/tracks_cff.py @@ -0,0 +1,48 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.common_cff import P3Vars,Var + +generalTrackTable = cms.EDProducer("SimpleTrackFlatTableProducer", + src = cms.InputTag("generalTracks"), + cut = cms.string(""), + name = cms.string("Track"), + doc = cms.string("reco::Track"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the muons + variables = cms.PSet(P3Vars, + charge = Var("charge", int, doc="electric charge"), + normChiSq = Var("normalizedChi2", float, precision=14, doc="Chi^2/ndof"), + numberOfValidHits = Var('numberOfValidHits()', 'int', precision=-1, doc='Number of valid hits in track'), + numberOfLostHits = Var('numberOfLostHits()', 'int', precision=-1, doc='Number of lost hits in track'), + Vtx_x = Var('vx()', 'float', precision=14, doc='parent vertex x pos'), + Vtx_y = Var('vy()', 'float', precision=14, doc='parent vertex y pos'), + Vtx_z = Var('vz()', 'float', precision=14, doc='parent vertex z pos'), + Vtx_t = Var('t0', 'float', precision=14, doc='parent vertex time'), + # Be careful here, this isn't really a decay vertex + DecayVtx_y = Var('outerPosition().x()', 'float', precision=14, doc='x position of first decay vertex'), + DecayVtx_x = Var('outerPosition().y()', 'float', precision=14, doc='y position of first decay vertex'), + DecayVtx_z = Var('outerPosition().z()', 'float', precision=14, doc='z position of first decay vertex'), + DecayVtx_t = Var('0', 'float', precision=14, doc='DUMMY VALUE! for time of first decay vertex'), + ) +) + +trackConversionsTable = generalTrackTable.clone() +trackConversionsTable.src = "conversionStepTracks" +trackConversionsTable.name = "TrackConv" + +trackDisplacedTable = cms.EDProducer("SimpleTrackFlatTableProducer", + src = cms.InputTag("displacedTracks"), + cut = cms.string(""), + name = cms.string("TrackDisp"), + doc = cms.string("reco::Track"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the muons + variables = cms.PSet(P3Vars, + charge = Var("charge", int, doc="electric charge"), + Vtx_x = Var('vx()', 'float', precision=14, doc='parent vertex x pos'), + Vtx_y = Var('vy()', 'float', precision=14, doc='parent vertex y pos'), + Vtx_z = Var('vz()', 'float', precision=14, doc='parent vertex z pos'), + Vtx_t = Var('t0', 'float', precision=14, doc='parent vertex time'), + ) +) + +trackTables = cms.Sequence(generalTrackTable+trackConversionsTable+trackDisplacedTable) diff --git a/DPGAnalysis/TrackNanoAOD/test/nanoMLGSD_cfg.py b/DPGAnalysis/TrackNanoAOD/test/nanoMLGSD_cfg.py new file mode 100644 index 0000000000000..a696831220612 --- /dev/null +++ b/DPGAnalysis/TrackNanoAOD/test/nanoMLGSD_cfg.py @@ -0,0 +1,118 @@ +# Auto generated configuration file +# using: +# Revision: 1.19 +# Source: /local/reps/CMSSW/CMSSW/Configuration/Applications/python/ConfigBuilder.py,v +# with command line options: step1 --filein file:test.root --fileout testNanoML.root --mc --eventcontent NANOAODSIM --datatier NANOAODSIM --conditions auto:mc --step NANO +import FWCore.ParameterSet.Config as cms +from FWCore.ParameterSet.VarParsing import VarParsing + + +process = cms.Process('NANO') +options = VarParsing('python') +options.setDefault('outputFile', 'testNanoML.root') +options.parseArguments() + +# 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.mixNoPU_cfi') +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('PhysicsTools.NanoAOD.nanoHGCML_cff') +process.load('Configuration.StandardSequences.EndOfProcess_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(-1), + output = cms.optional.untracked.allowed(cms.int32,cms.PSet) +) + +# Input source +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring(options.inputFiles), + 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( + allowAnyLabel_=cms.required.untracked.uint32 + ), + 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('step1 nevts:1'), + name = cms.untracked.string('Applications'), + version = cms.untracked.string('$Revision: 1.19 $') +) + +# Output definition + +process.NANOAODSIMoutput = cms.OutputModule("NanoAODOutputModule", + compressionAlgorithm = cms.untracked.string('LZMA'), + compressionLevel = cms.untracked.int32(9), + dataset = cms.untracked.PSet( + dataTier = cms.untracked.string('NANOAODSIM'), + filterName = cms.untracked.string('') + ), + fileName = cms.untracked.string(options.outputFile), + outputCommands = process.NANOAODSIMEventContent.outputCommands +) + +process.NANOAODSIMoutput.outputCommands.remove("keep edmTriggerResults_*_*_*") + +# Additional output definition + +# Other statements +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:mc', '') + +# Path and EndPath definitions +process.nanoAOD_step = cms.Path(process.nanoHGCMLSequence) +process.endjob_step = cms.EndPath(process.endOfProcess) +process.NANOAODSIMoutput_step = cms.EndPath(process.NANOAODSIMoutput) + +# Schedule definition +process.schedule = cms.Schedule(process.nanoAOD_step,process.endjob_step,process.NANOAODSIMoutput_step) +from PhysicsTools.PatAlgos.tools.helpers import associatePatAlgosToolsTask +associatePatAlgosToolsTask(process) + +# customisation of the process. + +# End of customisation functions +from PhysicsTools.NanoAOD.nanoHGCML_cff import customizeNoMergedCaloTruth,customizeMergedSimClusters +# Uncomment if you didn't schedule SimClusters/CaloParticles +# process = customizeNoMergedCaloTruth(process) +# merged simclusters (turn off if you aren't running through PEPR) +process = customizeMergedSimClusters(process) + +# Customisation from command line + +# 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 diff --git a/DPGAnalysis/TrackNanoAOD/test/nanoML_cfg.py b/DPGAnalysis/TrackNanoAOD/test/nanoML_cfg.py new file mode 100644 index 0000000000000..c3e61dbb2b302 --- /dev/null +++ b/DPGAnalysis/TrackNanoAOD/test/nanoML_cfg.py @@ -0,0 +1,120 @@ +# Auto generated configuration file +# using: +# Revision: 1.19 +# Source: /local/reps/CMSSW/CMSSW/Configuration/Applications/python/ConfigBuilder.py,v +# with command line options: step1 --filein file:test.root --fileout testNanoML.root --mc --eventcontent NANOAODSIM --datatier NANOAODSIM --conditions auto:mc --step NANO +import FWCore.ParameterSet.Config as cms +from FWCore.ParameterSet.VarParsing import VarParsing + + +process = cms.Process('NANO') +options = VarParsing('python') +options.setDefault('outputFile', 'testNanoML.root') +options.parseArguments() + +# 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.mixNoPU_cfi') +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('PhysicsTools.NanoAOD.nanoHGCML_cff') +process.load('Configuration.StandardSequences.EndOfProcess_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(-1), + output = cms.optional.untracked.allowed(cms.int32,cms.PSet) +) + +# Input source +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring(options.inputFiles), + 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( + allowAnyLabel_=cms.required.untracked.uint32 + ), + 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('step1 nevts:1'), + name = cms.untracked.string('Applications'), + version = cms.untracked.string('$Revision: 1.19 $') +) + +# Output definition + +process.NANOAODSIMoutput = cms.OutputModule("NanoAODOutputModule", + compressionAlgorithm = cms.untracked.string('LZMA'), + compressionLevel = cms.untracked.int32(9), + dataset = cms.untracked.PSet( + dataTier = cms.untracked.string('NANOAODSIM'), + filterName = cms.untracked.string('') + ), + fileName = cms.untracked.string(options.outputFile), + outputCommands = process.NANOAODSIMEventContent.outputCommands +) + +process.NANOAODSIMoutput.outputCommands.remove("keep edmTriggerResults_*_*_*") + +# Additional output definition + +# Other statements +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:mc', '') + +# Path and EndPath definitions +process.nanoAOD_step = cms.Path(process.nanoHGCMLSequence) +process.endjob_step = cms.EndPath(process.endOfProcess) +process.NANOAODSIMoutput_step = cms.EndPath(process.NANOAODSIMoutput) + +# Schedule definition +process.schedule = cms.Schedule(process.nanoAOD_step,process.endjob_step,process.NANOAODSIMoutput_step) +from PhysicsTools.PatAlgos.tools.helpers import associatePatAlgosToolsTask +associatePatAlgosToolsTask(process) + +# customisation of the process. +from PhysicsTools.NanoAOD.nanoHGCML_cff import customizeReco,customizeMergedSimClusters +process = customizeReco(process) +# Uncomment if you didn't schedule SimClusters/CaloParticles +# process = customizeNoMergedCaloTruth(process) +# merged simclusters (turn off if you aren't running through PEPR) +process = customizeMergedSimClusters(process) + +# End of customisation functions + + +# Customisation from command line + +# 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 diff --git a/IOMC/ParticleGuns/interface/FlatEtaRangeGunProducer.h b/IOMC/ParticleGuns/interface/FlatEtaRangeGunProducer.h new file mode 100644 index 0000000000000..2eeeb8cb26d75 --- /dev/null +++ b/IOMC/ParticleGuns/interface/FlatEtaRangeGunProducer.h @@ -0,0 +1,67 @@ +/* + * Particle gun that can be positioned in space given ranges in rho, z and phi. + */ + +#ifndef IOMC_PARTICLEGUN_FlatEtaRangeGunProducer_H +#define IOMC_PARTICLEGUN_FlatEtaRangeGunProducer_H + +#include "FWCore/Framework/interface/one/EDProducer.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Run.h" + +#include "HepMC/GenEvent.h" +#include "HepPDT/ParticleDataTable.hh" + +namespace edm { + + class FlatEtaRangeGunProducer : public one::EDProducer { + public: + static void fillDescriptions(edm::ConfigurationDescriptions&); + + explicit FlatEtaRangeGunProducer(const ParameterSet&); + ~FlatEtaRangeGunProducer() override; + void beginRun(const edm::Run&, const edm::EventSetup&) override; + void endRun(const edm::Run&, const edm::EventSetup&) override; + void endRunProduce(edm::Run&, const edm::EventSetup&) override; + + private: + void produce(Event&, const EventSetup&) override; + + protected: + // ids of particles to shoot + std::vector particleIDs_; + + // the number of particles to shoot + int nParticles_; + + // flag that denotes that exactly the particles defined by fPartIds should be shot, with that order and quantity + bool exactShoot_; + + // flag that denotes whether a random number of particles in the range [1, fNParticles] is shot + bool randomShoot_; + + // energy range + double eMin_; + double eMax_; + + // eta range + double etaMin_; + double etaMax_; + + // phi range + double phiMin_; + double phiMax_; + + // debug flag + bool debug_; + + // pointer to the current event + + // pdg table + ESHandle pdgTable_; + }; + +} // namespace edm + +#endif // IOMC_PARTICLEGUN_FlatEtaRangeGunProducer_H diff --git a/IOMC/ParticleGuns/src/FlatEtaRangeGunProducer.cc b/IOMC/ParticleGuns/src/FlatEtaRangeGunProducer.cc new file mode 100644 index 0000000000000..92c69b0c26b9a --- /dev/null +++ b/IOMC/ParticleGuns/src/FlatEtaRangeGunProducer.cc @@ -0,0 +1,150 @@ +#include + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/Utilities/interface/RandomNumberGenerator.h" + +#include "SimDataFormats/GeneratorProducts/interface/GenEventInfoProduct.h" +#include "SimDataFormats/GeneratorProducts/interface/GenRunInfoProduct.h" +#include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h" + +#include "SimGeneral/HepPDTRecord/interface/ParticleDataTable.h" + +#include "DataFormats/Math/interface/Vector3D.h" + +#include "IOMC/ParticleGuns/interface/FlatEtaRangeGunProducer.h" + +#include "CLHEP/Random/RandFlat.h" +#include "CLHEP/Units/GlobalPhysicalConstants.h" +#include "CLHEP/Units/GlobalSystemOfUnits.h" + +void edm::FlatEtaRangeGunProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + + desc.add>("particleIDs"); + desc.add("nParticles", 1); + desc.add("exactShoot", true); + desc.add("randomShoot", false); + desc.add("eMin", 1.); + desc.add("eMax", 100.); + desc.add("etaMin", 1.5); + desc.add("etaMax", 3.0); + desc.add("phiMin", 0.); + desc.add("phiMax", 2 * pi); + desc.addUntracked("debug", false); + + descriptions.add("FlatEtaRangeGunProducer", desc); +} + +edm::FlatEtaRangeGunProducer::FlatEtaRangeGunProducer(const edm::ParameterSet& params) + : particleIDs_(params.getParameter>("particleIDs")), + nParticles_(params.getParameter("nParticles")), + exactShoot_(params.getParameter("exactShoot")), + randomShoot_(params.getParameter("randomShoot")), + eMin_(params.getParameter("eMin")), + eMax_(params.getParameter("eMax")), + etaMin_(params.getParameter("etaMin")), + etaMax_(params.getParameter("etaMax")), + phiMin_(params.getParameter("phiMin")), + phiMax_(params.getParameter("phiMax")), + debug_(params.getUntrackedParameter("debug")) { + produces("unsmeared"); + produces(); + produces(); +} + +edm::FlatEtaRangeGunProducer::~FlatEtaRangeGunProducer() {} + +void edm::FlatEtaRangeGunProducer::beginRun(const edm::Run& run, const edm::EventSetup& setup) { + setup.getData(pdgTable_); +} + +void edm::FlatEtaRangeGunProducer::endRun(const edm::Run& run, const edm::EventSetup& setup) {} + +void edm::FlatEtaRangeGunProducer::produce(edm::Event& event, const edm::EventSetup& setup) { + edm::Service rng; + CLHEP::HepRandomEngine* engine = &(rng->getEngine(event.streamID())); + + if (debug_) { + LogDebug("FlatEtaRangeGunProducer") << " : Begin New Event Generation" << std::endl; + } + + // create a new event to fill + auto* genEvent = new HepMC::GenEvent(); + + // determine the number of particles to shoot + int n = 0; + if (exactShoot_) { + n = (int)particleIDs_.size(); + } else if (randomShoot_) { + n = CLHEP::RandFlat::shoot(engine, 1, nParticles_ + 1); + } else { + n = nParticles_; + } + + int particle_counter = 0; + // shoot particles + for (int i = 0; i < 2 * n; i++) { //n for positive and n for negative eta + // create a random deltaR + + // obtain kinematics + int id = particleIDs_[exactShoot_ ? particle_counter : CLHEP::RandFlat::shoot(engine, 0, particleIDs_.size())]; + particle_counter++; + if (particle_counter >= n) + particle_counter = 0; + + const HepPDT::ParticleData* pData = pdgTable_->particle(HepPDT::ParticleID(abs(id))); + double eta = CLHEP::RandFlat::shoot(engine, etaMin_, etaMax_); + if (i < n) + eta *= -1; + double phi = CLHEP::RandFlat::shoot(engine, phiMin_, phiMax_); + double e = CLHEP::RandFlat::shoot(engine, eMin_, eMax_); + double m = pData->mass().value(); + double p = sqrt(e * e - m * m); + math::XYZVector pVec = p * math::XYZVector(cos(phi), sin(phi), sinh(eta)).unit(); + + HepMC::GenVertex* vtx = new HepMC::GenVertex(HepMC::FourVector(0, 0, 0, 0)); + + // create the GenParticle + HepMC::FourVector fVec(pVec.x(), pVec.y(), pVec.z(), e); + HepMC::GenParticle* particle = new HepMC::GenParticle(fVec, id, 1); + particle->suggest_barcode(i + 1); + + // add the particle to the vertex and the vertex to the event + vtx->add_particle_out(particle); + genEvent->add_vertex(vtx); + + if (debug_) { + vtx->print(); + particle->print(); + } + } + + // fill event attributes + genEvent->set_event_number(event.id().event()); + genEvent->set_signal_process_id(20); + + if (debug_) { + genEvent->print(); + } + + // store outputs + std::unique_ptr BProduct(new HepMCProduct()); + BProduct->addHepMCData(genEvent); + event.put(std::move(BProduct), "unsmeared"); + auto genEventInfo = std::make_unique(genEvent); + event.put(std::move(genEventInfo)); + + if (debug_) { + LogDebug("FlatEtaRangeGunProducer") << " : Event Generation Done " << std::endl; + } +} + +void edm::FlatEtaRangeGunProducer::endRunProduce(edm::Run& run, const edm::EventSetup& setup) { + std::unique_ptr genRunInfo(new GenRunInfoProduct()); + run.put(std::move(genRunInfo)); +} diff --git a/PhysicsTools/NanoAOD/interface/ObjectIndexFromAssociationProducer.h b/PhysicsTools/NanoAOD/interface/ObjectIndexFromAssociationProducer.h new file mode 100644 index 0000000000000..ee02c1d7beb08 --- /dev/null +++ b/PhysicsTools/NanoAOD/interface/ObjectIndexFromAssociationProducer.h @@ -0,0 +1,55 @@ +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "DataFormats/NanoAOD/interface/FlatTable.h" +#include "DataFormats/Common/interface/View.h" +#include "DataFormats/Common/interface/Association.h" +#include "CommonTools/Utils/interface/StringCutObjectSelector.h" +#include + +template +class ObjectIndexFromAssociationTableProducer : public edm::global::EDProducer<> { +public: + ObjectIndexFromAssociationTableProducer(edm::ParameterSet const& params) + : objName_(params.getParameter("objName")), + branchName_(params.getParameter("branchName")), + doc_(params.getParameter("docString")), + src_(consumes(params.getParameter("src"))), + objMap_(consumes>(params.getParameter("objMap"))), + cut_(params.getParameter("cut"), true) { + produces(); + } + + ~ObjectIndexFromAssociationTableProducer() override {} + + void produce(edm::StreamID id, edm::Event& iEvent, const edm::EventSetup& iSetup) const override { + edm::Handle objs; + iEvent.getByToken(src_, objs); + + edm::Handle> assoc; + iEvent.getByToken(objMap_, assoc); + + std::vector keys; + for (unsigned int i = 0; i < objs->size(); ++i) { + edm::Ref tk(objs, i); + if (cut_(*tk)) { + edm::Ref match = (*assoc)[tk]; + int key = match.isNonnull() ? match.key() : -1; + keys.emplace_back(key); + } + } + + auto tab = std::make_unique(keys.size(), objName_, false, true); + tab->addColumn(branchName_ + "Idx", keys, doc_); + + iEvent.put(std::move(tab)); + } + +protected: + const std::string objName_, branchName_, doc_; + const edm::EDGetTokenT src_; + const edm::EDGetTokenT> objMap_; + const StringCutObjectSelector cut_; +}; diff --git a/PhysicsTools/NanoAOD/interface/ObjectPropertyFromIndexMapTableProducer.h b/PhysicsTools/NanoAOD/interface/ObjectPropertyFromIndexMapTableProducer.h new file mode 100644 index 0000000000000..c0da1f742e5f8 --- /dev/null +++ b/PhysicsTools/NanoAOD/interface/ObjectPropertyFromIndexMapTableProducer.h @@ -0,0 +1,74 @@ +#ifndef NanoAOD_ObjectPropertyFromIndexMapTableProducer_h +#define NanoAOD_ObjectPropertyFromIndexMapTableProducer_h + +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "DataFormats/NanoAOD/interface/FlatTable.h" +#include "DataFormats/Common/interface/View.h" +#include "DataFormats/Common/interface/Association.h" +#include "CommonTools/Utils/interface/StringCutObjectSelector.h" +#include +#include + +template +class ObjectPropertyFromIndexMapTableProducer : public edm::global::EDProducer<> { +public: + ObjectPropertyFromIndexMapTableProducer(edm::ParameterSet const& params) + : objName_(params.getParameter("objName")), + branchName_(params.getParameter("branchName")), + doc_(params.getParameter("docString")), + src_(consumes(params.getParameter("src"))), + mapToken_(consumes>(params.getParameter("valueMap"))), + cut_(params.getParameter("cut"), true) { + produces(); + } + + ~ObjectPropertyFromIndexMapTableProducer() override {} + // + // Because I'm not sure if this can be templated, overload instead... + std::unique_ptr fillTable(const std::vector& values, const std::string& objName) const { + auto tab = std::make_unique(values.size(), objName, false, true); + tab->addColumn(branchName_, values, doc_); + return tab; + } + + // Because I'm not sure if this can be templated, overload instead... + std::unique_ptr fillTable(const std::vector& values, const std::string& objName) const { + auto tab = std::make_unique(values.size(), objName, false, true); + tab->addColumn(branchName_, values, doc_); + return tab; + } + + void produce(edm::StreamID id, edm::Event& iEvent, const edm::EventSetup& iSetup) const override { + edm::Handle objs; + iEvent.getByToken(src_, objs); + + edm::Handle> valueMap; + iEvent.getByToken(mapToken_, valueMap); + + std::vector values; + for (unsigned int i = 0; i < objs->size(); ++i) { + edm::Ref obj(objs, i); + if (cut_(*obj)) { + if (valueMap->find(i) == valueMap->end()) + throw cms::Exception("ObjectPropertyFromIndexMapTableProducer") + << "No entry in value map for candidate " << i; + values.emplace_back(valueMap->at(i)); + } + } + + auto tab = fillTable(values, objName_); + iEvent.put(std::move(tab)); + } + +protected: + const std::string objName_, branchName_, doc_; + const edm::EDGetTokenT src_; + const edm::EDGetTokenT> mapToken_; + const StringCutObjectSelector cut_; +}; + +#endif diff --git a/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h b/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h index 087fa85bdb3b9..d18f551fb1dd7 100644 --- a/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h +++ b/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h @@ -1,3 +1,6 @@ +#ifndef NanoAOD_SimpleFlatTableProducer_h +#define NanoAOD_SimpleFlatTableProducer_h + #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Framework/interface/ConsumesCollector.h" @@ -271,3 +274,5 @@ class FirstObjectSimpleFlatTableProducer : public SimpleFlatTableProducerBase + + + + + + diff --git a/SimDataFormats/CaloAnalysis/src/classes_def.xml b/SimDataFormats/CaloAnalysis/src/classes_def.xml index 89a2b4c9f5aaf..a8a1e3ad56f62 100644 --- a/SimDataFormats/CaloAnalysis/src/classes_def.xml +++ b/SimDataFormats/CaloAnalysis/src/classes_def.xml @@ -12,6 +12,10 @@ + + + + diff --git a/SimGeneral/CaloAnalysis/plugins/CaloTruthAccumulator.cc b/SimGeneral/CaloAnalysis/plugins/CaloTruthAccumulator.cc index 4f13f5c49f5a7..e2b02c1491c48 100644 --- a/SimGeneral/CaloAnalysis/plugins/CaloTruthAccumulator.cc +++ b/SimGeneral/CaloAnalysis/plugins/CaloTruthAccumulator.cc @@ -147,6 +147,8 @@ class CaloTruthAccumulator : public DigiAccumulatorMixMod { std::unordered_map> &simTrackDetIdEnergyMap, const T &event, const edm::EventSetup &setup); + std::unique_ptr> fillSimHitAssociation( + edm::Handle> &inColl, edm::OrphanHandle &matchColl); const std::string messageCategory_; @@ -183,6 +185,10 @@ class CaloTruthAccumulator : public DigiAccumulatorMixMod { struct OutputCollections { std::unique_ptr pSimClusters; std::unique_ptr pCaloParticles; + std::unique_ptr> pTrackSCAssoc; + std::unique_ptr> pHGCEEHitSCAssoc; + std::unique_ptr> pHGCHEfrontHitSCAssoc; + std::unique_ptr> pHGCHEbackHitSCAssoc; }; struct calo_particles { @@ -209,6 +215,8 @@ class CaloTruthAccumulator : public DigiAccumulatorMixMod { // geometry type (0 pre-TDR; 1 TDR) int geometryType_; bool doHGCAL; + std::vector trackToSimClusterIndices_; + std::unordered_map caloHitToSimClusterIdx_; }; /* Graph utility functions */ @@ -291,11 +299,13 @@ namespace { CaloTruthAccumulator::calo_particles &caloParticles, std::unordered_multimap &simHitBarcodeToIndex, std::unordered_map> &simTrackDetIdEnergyMap, + std::unordered_map &caloHitToSimClusterIdxMap, Selector selector) : output_(output), caloParticles_(caloParticles), simHitBarcodeToIndex_(simHitBarcodeToIndex), simTrackDetIdEnergyMap_(simTrackDetIdEnergyMap), + caloHitIdToSimClusterIdxMap_(caloHitToSimClusterIdxMap), selector_(selector) {} template void discover_vertex(Vertex u, const Graph &g) { @@ -314,6 +324,7 @@ namespace { auto &simcluster = output_.pSimClusters->back(); std::unordered_map acc_energy; for (auto const &hit_and_energy : simTrackDetIdEnergyMap_[trackIdx]) { + caloHitIdToSimClusterIdxMap_[hit_and_energy.first] = output_.pSimClusters->size() - 1; acc_energy[hit_and_energy.first] += hit_and_energy.second; } for (auto const &hit_and_energy : acc_energy) { @@ -353,6 +364,7 @@ namespace { CaloTruthAccumulator::calo_particles &caloParticles_; std::unordered_multimap &simHitBarcodeToIndex_; std::unordered_map> &simTrackDetIdEnergyMap_; + std::unordered_map &caloHitIdToSimClusterIdxMap_; Selector selector_; }; } // namespace @@ -379,6 +391,16 @@ CaloTruthAccumulator::CaloTruthAccumulator(const edm::ParameterSet &config, producesCollector.produces>>("MergedCaloTruth"); } + if (true) { + producesCollector.produces>("simClusterToCaloParticle"); + producesCollector.produces>("simTrackToSimCluster"); + producesCollector.produces>("simHitHGCEEToSimCluster"); + producesCollector.produces>("simHitHGCHEfrontToSimCluster"); + producesCollector.produces>("simHitHGCHEbackToSimCluster"); + } + + iC.consumes>(simTrackLabel_); + iC.consumes>(simTrackLabel_); iC.consumes>(simVertexLabel_); iC.consumes>(genParticleLabel_); @@ -443,6 +465,8 @@ void CaloTruthAccumulator::initializeEvent(edm::Event const &event, edm::EventSe output_.pCaloParticles = std::make_unique(); m_detIdToTotalSimEnergy.clear(); + caloHitToSimClusterIdx_.clear(); + trackToSimClusterIndices_.clear(); } /** Create handle to edm::HepMCProduct here because event.getByLabel with @@ -511,22 +535,61 @@ void CaloTruthAccumulator::finalizeEvent(edm::Event &event, edm::EventSetup cons // save the SimCluster orphan handle so we can fill the calo particles auto scHandle = event.put(std::move(output_.pSimClusters), "MergedCaloTruth"); + output_.pTrackSCAssoc = std::make_unique>(scHandle); + edm::Association::Filler filler(*output_.pTrackSCAssoc); + filler.insert(hSimTracks, trackToSimClusterIndices_.begin(), trackToSimClusterIndices_.end()); + filler.fill(); + event.put(std::move(output_.pTrackSCAssoc), "simTrackToSimCluster"); + + for (auto const &collectionTag : collectionTags_) { + edm::Handle> hSimHits; + const bool isHGCal = (collectionTag.instance().find("HGCHits") != std::string::npos); + if (!isHGCal) + continue; + event.getByLabel(collectionTag, hSimHits); + + if (collectionTag.instance().find("HEfront") != std::string::npos) { + output_.pHGCHEfrontHitSCAssoc = fillSimHitAssociation(hSimHits, scHandle); + } else if (collectionTag.instance().find("HEback") != std::string::npos) { + output_.pHGCHEbackHitSCAssoc = fillSimHitAssociation(hSimHits, scHandle); + } else + output_.pHGCEEHitSCAssoc = fillSimHitAssociation(hSimHits, scHandle); + } + event.put(std::move(output_.pHGCEEHitSCAssoc), "simHitHGCEEToSimCluster"); + event.put(std::move(output_.pHGCHEfrontHitSCAssoc), "simHitHGCHEfrontToSimCluster"); + event.put(std::move(output_.pHGCHEbackHitSCAssoc), "simHitHGCHEbackToSimCluster"); + + std::unordered_map simClusIdxToCaloParticleIdxMap; // now fill the calo particles for (unsigned i = 0; i < output_.pCaloParticles->size(); ++i) { auto &cp = (*output_.pCaloParticles)[i]; for (unsigned j = m_caloParticles.sc_start_[i]; j < m_caloParticles.sc_stop_[i]; ++j) { edm::Ref ref(scHandle, j); + simClusIdxToCaloParticleIdxMap[j] = i; cp.addSimCluster(ref); } } - event.put(std::move(output_.pCaloParticles), "MergedCaloTruth"); + auto cpHandle = event.put(std::move(output_.pCaloParticles), "MergedCaloTruth"); calo_particles().swap(m_caloParticles); std::unordered_map().swap(m_detIdToTotalSimEnergy); std::unordered_multimap().swap(m_simHitBarcodeToIndex); + + std::vector caloPartIdx; + for (size_t i = 0; i < scHandle->size(); i++) { + int matchIdx = -1; + if (simClusIdxToCaloParticleIdxMap.find(i) != simClusIdxToCaloParticleIdxMap.end()) + matchIdx = simClusIdxToCaloParticleIdxMap[i]; + caloPartIdx.emplace_back(matchIdx); + } + auto assocMap = std::make_unique>(cpHandle); + edm::Association::Filler cpfiller(*assocMap); + cpfiller.insert(scHandle, caloPartIdx.begin(), caloPartIdx.end()); + cpfiller.fill(); + event.put(std::move(assocMap), "simClusterToCaloParticle"); } template @@ -652,6 +715,7 @@ void CaloTruthAccumulator::accumulateEvent(const T &event, m_caloParticles, m_simHitBarcodeToIndex, simTrackDetIdEnergyMap, + caloHitToSimClusterIdx_, [&](EdgeProperty &edge_property) -> bool { // Apply selection on SimTracks in order to promote them to be // CaloParticles. The function returns TRUE if the particle satisfies @@ -663,6 +727,19 @@ void CaloTruthAccumulator::accumulateEvent(const T &event, }); depth_first_search(decay, visitor(caloParticleCreator)); + std::unordered_map trackIdxToSimClusterIdx; + for (size_t i = 0; i < output_.pSimClusters->size(); i++) { + auto &sc = output_.pSimClusters->at(i); + for (const auto &tk : sc.g4Tracks()) { + trackIdxToSimClusterIdx[trackid_to_track_index.at(tk.trackId())] = i; + } + } + + for (size_t i = 0; i < hSimTracks->size(); i++) { + int idx = trackIdxToSimClusterIdx.find(i) != trackIdxToSimClusterIdx.end() ? trackIdxToSimClusterIdx[i] : -1; + trackToSimClusterIndices_.emplace_back(idx); + } + #if DEBUG boost::write_graphviz(std::cout, decay, @@ -671,6 +748,23 @@ void CaloTruthAccumulator::accumulateEvent(const T &event, #endif } +std::unique_ptr> CaloTruthAccumulator::fillSimHitAssociation( + edm::Handle> &inColl, edm::OrphanHandle &matchColl) { + std::vector matchIndices(inColl->size(), -1); + + for (size_t i = 0; i < inColl->size(); i++) { + auto &hit = inColl->at(i); + if (caloHitToSimClusterIdx_.find(hit.id()) != caloHitToSimClusterIdx_.end()) + matchIndices[i] = caloHitToSimClusterIdx_[hit.id()]; + } + + auto assocMap = std::make_unique>(matchColl); + edm::Association::Filler filler(*assocMap); + filler.insert(inColl, matchIndices.begin(), matchIndices.end()); + filler.fill(); + return assocMap; +} + template void CaloTruthAccumulator::fillSimHits(std::vector> &returnValue, std::unordered_map> &simTrackDetIdEnergyMap,