File indexing completed on 2025-07-15 22:06:31
0001 #include <algorithm>
0002 #include "DataFormats/NanoAOD/interface/FlatTable.h"
0003 #include "DataFormats/HGCalReco/interface/Trackster.h"
0004 #include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h"
0005 #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h"
0006 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0007 #include "FWCore/Framework/interface/Event.h"
0008 #include "FWCore/Framework/interface/global/EDProducer.h"
0009 #include "FWCore/Framework/interface/Frameworkfwd.h"
0010 #include "FWCore/Framework/interface/MakerMacros.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012
0013 class SimTracksterTableProducer : public edm::global::EDProducer<> {
0014 public:
0015 SimTracksterTableProducer(const edm::ParameterSet& cfg)
0016 : tableName_(cfg.getParameter<std::string>("tableName")),
0017 skipNonExistingSrc_(cfg.getParameter<bool>("skipNonExistingSrc")),
0018 simTrackstersToken_(mayConsume<std::vector<ticl::Trackster>>(cfg.getParameter<edm::InputTag>("simTracksters"))),
0019 caloParticlesToken_(mayConsume<std::vector<CaloParticle>>(cfg.getParameter<edm::InputTag>("caloParticles"))),
0020 simClustersToken_(mayConsume<std::vector<SimCluster>>(cfg.getParameter<edm::InputTag>("simClusters"))),
0021 caloParticleToSimClustersMap_token_(mayConsume<std::map<uint, std::vector<uint>>>(
0022 cfg.getParameter<edm::InputTag>("caloParticleToSimClustersMap"))),
0023 precision_(cfg.getParameter<int>("precision")) {
0024 produces<nanoaod::FlatTable>(tableName_);
0025 }
0026
0027 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0028 edm::ParameterSetDescription desc;
0029 desc.add<std::string>("tableName", "hltSimTrackstersTable")
0030 ->setComment("Table name, needs to be the same as the main Tau table");
0031 desc.add<bool>("skipNonExistingSrc", false)
0032 ->setComment("whether or not to skip producing the table on absent input product");
0033 desc.add<edm::InputTag>("simTracksters", edm::InputTag("hltTiclSimTracksters"));
0034 desc.add<edm::InputTag>("caloParticles", edm::InputTag("mix", "MergedCaloTruth"));
0035 desc.add<edm::InputTag>("simClusters", edm::InputTag("mix", "MergedCaloTruth"));
0036 desc.add<edm::InputTag>("caloParticleToSimClustersMap", edm::InputTag("hltTiclSimTracksters"));
0037 desc.add<int>("precision", 7);
0038 descriptions.addWithDefaultLabel(desc);
0039 }
0040
0041 private:
0042 void produce(edm::StreamID id, edm::Event& event, const edm::EventSetup& setup) const override {
0043 const auto simTrackstersHandle = event.getHandle(simTrackstersToken_);
0044 const auto& simTracksters = *simTrackstersHandle;
0045 const auto caloParticlesHandle = event.getHandle(caloParticlesToken_);
0046 const auto& caloParticles = *caloParticlesHandle;
0047 const auto simClustersHandle = event.getHandle(simClustersToken_);
0048 const auto& simClusters = *simClustersHandle;
0049 const auto cpToSCMap = event.get(caloParticleToSimClustersMap_token_);
0050 const size_t nSimTracksters = simTrackstersHandle.isValid() ? simTrackstersHandle->size() : 0;
0051
0052 static constexpr float default_value = std::numeric_limits<float>::quiet_NaN();
0053
0054 std::vector<float> boundaryX(nSimTracksters, default_value);
0055 std::vector<float> boundaryY(nSimTracksters, default_value);
0056 std::vector<float> boundaryZ(nSimTracksters, default_value);
0057 std::vector<float> boundaryPx(nSimTracksters, default_value);
0058 std::vector<float> boundaryPy(nSimTracksters, default_value);
0059 std::vector<float> boundaryPz(nSimTracksters, default_value);
0060 std::vector<float> boundaryEta(nSimTracksters, default_value);
0061 std::vector<float> boundaryPhi(nSimTracksters, default_value);
0062 std::vector<float> simEnergy(nSimTracksters, default_value);
0063 std::vector<float> simTime(nSimTracksters, default_value);
0064 std::vector<float> genPt(nSimTracksters, default_value);
0065 std::vector<float> mass(nSimTracksters, default_value);
0066
0067
0068 auto fillVectors = [&](const auto& obj, size_t iSim, float time) {
0069 const auto& simTrack = obj.g4Tracks()[0];
0070 const auto caloPt = obj.pt();
0071 const auto simHitSumEnergy = obj.simEnergy();
0072 const auto caloMass = obj.mass();
0073
0074 boundaryX[iSim] = simTrack.getPositionAtBoundary().x();
0075 boundaryY[iSim] = simTrack.getPositionAtBoundary().y();
0076 boundaryZ[iSim] = simTrack.getPositionAtBoundary().z();
0077 boundaryEta[iSim] = simTrack.getPositionAtBoundary().eta();
0078 boundaryPhi[iSim] = simTrack.getPositionAtBoundary().phi();
0079 boundaryPx[iSim] = simTrack.getMomentumAtBoundary().x();
0080 boundaryPy[iSim] = simTrack.getMomentumAtBoundary().y();
0081 boundaryPz[iSim] = simTrack.getMomentumAtBoundary().z();
0082
0083 simTime[iSim] = time;
0084 simEnergy[iSim] = simHitSumEnergy;
0085 genPt[iSim] = caloPt;
0086 mass[iSim] = caloMass;
0087 };
0088
0089 if (simTrackstersHandle.isValid() || !(this->skipNonExistingSrc_)) {
0090 for (size_t iSim = 0; iSim < simTracksters.size(); ++iSim) {
0091 const auto& simT = simTracksters[iSim];
0092 float time = default_value;
0093
0094 if (simT.seedID() == caloParticlesHandle.id()) {
0095 const auto& cp = caloParticles[simT.seedIndex()];
0096 time = cp.simTime();
0097 fillVectors(cp, iSim, time);
0098 } else {
0099 const auto& sc = simClusters[simT.seedIndex()];
0100
0101 for (const auto& [cpIdx, scVec] : cpToSCMap) {
0102 if (std::ranges::find(scVec, simT.seedIndex()) != scVec.end()) {
0103 time = caloParticles[cpIdx].simTime();
0104 break;
0105 }
0106 }
0107 fillVectors(sc, iSim, time);
0108 }
0109 }
0110 }
0111 auto simTrackstersTable =
0112 std::make_unique<nanoaod::FlatTable>(nSimTracksters, tableName_, false, true);
0113 simTrackstersTable->addColumn<float>(
0114 "boundaryX", boundaryX, "CaloVolume boundary Position X [cm] of associated Simobject", precision_);
0115 simTrackstersTable->addColumn<float>(
0116 "boundaryY", boundaryY, "CaloVolume boundary Position Y [cm] of associated Simobject", precision_);
0117 simTrackstersTable->addColumn<float>(
0118 "boundaryZ", boundaryZ, "CaloVolume boundary Position Z [cm] of associated Simobject", precision_);
0119 simTrackstersTable->addColumn<float>(
0120 "boundaryEta", boundaryEta, "CaloVolume boundary pseudorapidity of associated Simobject", precision_);
0121 simTrackstersTable->addColumn<float>(
0122 "boundaryPhi", boundaryEta, "CaloVolume boundary phi of associated Simobject", precision_);
0123 simTrackstersTable->addColumn<float>(
0124 "boundaryPx", boundaryPx, "X component of momentum at CaloVolume boundary of associated Simobject", precision_);
0125 simTrackstersTable->addColumn<float>(
0126 "boundaryPy", boundaryPy, "Y component of momentum at CaloVolume boundary of associated Simobject", precision_);
0127 simTrackstersTable->addColumn<float>(
0128 "boundaryPz", boundaryPz, "Z component of momentum at CaloVolume boundary of associated Simobject", precision_);
0129 simTrackstersTable->addColumn<float>("simTime", simTime, "Sim-Time of simulated object [ns]", precision_);
0130 simTrackstersTable->addColumn<float>("genPt", genPt, "Gen-pT associated with SimObject", precision_);
0131 simTrackstersTable->addColumn<float>("mass", mass, "mass associated with SimObject", precision_);
0132
0133 event.put(std::move(simTrackstersTable), tableName_);
0134 }
0135
0136 private:
0137 const std::string tableName_;
0138 const bool skipNonExistingSrc_;
0139 const edm::EDGetTokenT<std::vector<ticl::Trackster>> simTrackstersToken_;
0140 const edm::EDGetTokenT<std::vector<CaloParticle>> caloParticlesToken_;
0141 const edm::EDGetTokenT<std::vector<SimCluster>> simClustersToken_;
0142 const edm::EDGetTokenT<std::map<uint, std::vector<uint>>> caloParticleToSimClustersMap_token_;
0143 const unsigned int precision_;
0144 };
0145
0146 #include "FWCore/Framework/interface/MakerMacros.h"
0147 DEFINE_FWK_MODULE(SimTracksterTableProducer);