Back to home page

Project CMSSW displayed by LXR

 
 

    


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     //utility lambda for filling vectors
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           //SCtoCP map not availalbe, use CPtoSC map instead
0101           for (const auto& [cpIdx, scVec] : cpToSCMap) {
0102             if (std::ranges::find(scVec, simT.seedIndex()) != scVec.end()) {
0103               time = caloParticles[cpIdx].simTime();
0104               break;  //dont need to check further
0105             }
0106           }
0107           fillVectors(sc, iSim, time);
0108         }
0109       }
0110     }
0111     auto simTrackstersTable =
0112         std::make_unique<nanoaod::FlatTable>(nSimTracksters, tableName_, /*singleton*/ false, /*extension*/ 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);