1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
#include <algorithm>
#include "DataFormats/NanoAOD/interface/FlatTable.h"
#include "DataFormats/HGCalReco/interface/Trackster.h"
#include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h"
#include "SimDataFormats/CaloAnalysis/interface/SimCluster.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/global/EDProducer.h"
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/Framework/interface/MakerMacros.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
class SimTracksterTableProducer : public edm::global::EDProducer<> {
public:
SimTracksterTableProducer(const edm::ParameterSet& cfg)
: tableName_(cfg.getParameter<std::string>("tableName")),
skipNonExistingSrc_(cfg.getParameter<bool>("skipNonExistingSrc")),
simTrackstersToken_(mayConsume<std::vector<ticl::Trackster>>(cfg.getParameter<edm::InputTag>("simTracksters"))),
caloParticlesToken_(mayConsume<std::vector<CaloParticle>>(cfg.getParameter<edm::InputTag>("caloParticles"))),
simClustersToken_(mayConsume<std::vector<SimCluster>>(cfg.getParameter<edm::InputTag>("simClusters"))),
caloParticleToSimClustersMap_token_(mayConsume<std::map<uint, std::vector<uint>>>(
cfg.getParameter<edm::InputTag>("caloParticleToSimClustersMap"))),
precision_(cfg.getParameter<int>("precision")) {
produces<nanoaod::FlatTable>(tableName_);
}
static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
edm::ParameterSetDescription desc;
desc.add<std::string>("tableName", "hltSimTrackstersTable")
->setComment("Table name, needs to be the same as the main Tau table");
desc.add<bool>("skipNonExistingSrc", false)
->setComment("whether or not to skip producing the table on absent input product");
desc.add<edm::InputTag>("simTracksters", edm::InputTag("hltTiclSimTracksters"));
desc.add<edm::InputTag>("caloParticles", edm::InputTag("mix", "MergedCaloTruth"));
desc.add<edm::InputTag>("simClusters", edm::InputTag("mix", "MergedCaloTruth"));
desc.add<edm::InputTag>("caloParticleToSimClustersMap", edm::InputTag("hltTiclSimTracksters"));
desc.add<int>("precision", 7);
descriptions.addWithDefaultLabel(desc);
}
private:
void produce(edm::StreamID id, edm::Event& event, const edm::EventSetup& setup) const override {
const auto simTrackstersHandle = event.getHandle(simTrackstersToken_);
const auto& simTracksters = *simTrackstersHandle;
const auto caloParticlesHandle = event.getHandle(caloParticlesToken_);
const auto& caloParticles = *caloParticlesHandle;
const auto simClustersHandle = event.getHandle(simClustersToken_);
const auto& simClusters = *simClustersHandle;
const auto cpToSCMap = event.get(caloParticleToSimClustersMap_token_);
const size_t nSimTracksters = simTrackstersHandle.isValid() ? simTrackstersHandle->size() : 0;
static constexpr float default_value = std::numeric_limits<float>::quiet_NaN();
std::vector<float> boundaryX(nSimTracksters, default_value);
std::vector<float> boundaryY(nSimTracksters, default_value);
std::vector<float> boundaryZ(nSimTracksters, default_value);
std::vector<float> boundaryPx(nSimTracksters, default_value);
std::vector<float> boundaryPy(nSimTracksters, default_value);
std::vector<float> boundaryPz(nSimTracksters, default_value);
std::vector<float> boundaryEta(nSimTracksters, default_value);
std::vector<float> boundaryPhi(nSimTracksters, default_value);
std::vector<float> simEnergy(nSimTracksters, default_value);
std::vector<float> simTime(nSimTracksters, default_value);
std::vector<float> genPt(nSimTracksters, default_value);
std::vector<float> mass(nSimTracksters, default_value);
//utility lambda for filling vectors
auto fillVectors = [&](const auto& obj, size_t iSim, float time) {
const auto& simTrack = obj.g4Tracks()[0];
const auto caloPt = obj.pt();
const auto simHitSumEnergy = obj.simEnergy();
const auto caloMass = obj.mass();
boundaryX[iSim] = simTrack.getPositionAtBoundary().x();
boundaryY[iSim] = simTrack.getPositionAtBoundary().y();
boundaryZ[iSim] = simTrack.getPositionAtBoundary().z();
boundaryEta[iSim] = simTrack.getPositionAtBoundary().eta();
boundaryPhi[iSim] = simTrack.getPositionAtBoundary().phi();
boundaryPx[iSim] = simTrack.getMomentumAtBoundary().x();
boundaryPy[iSim] = simTrack.getMomentumAtBoundary().y();
boundaryPz[iSim] = simTrack.getMomentumAtBoundary().z();
simTime[iSim] = time;
simEnergy[iSim] = simHitSumEnergy;
genPt[iSim] = caloPt;
mass[iSim] = caloMass;
};
if (simTrackstersHandle.isValid() || !(this->skipNonExistingSrc_)) {
for (size_t iSim = 0; iSim < simTracksters.size(); ++iSim) {
const auto& simT = simTracksters[iSim];
float time = default_value;
if (simT.seedID() == caloParticlesHandle.id()) {
const auto& cp = caloParticles[simT.seedIndex()];
time = cp.simTime();
fillVectors(cp, iSim, time);
} else {
const auto& sc = simClusters[simT.seedIndex()];
//SCtoCP map not availalbe, use CPtoSC map instead
for (const auto& [cpIdx, scVec] : cpToSCMap) {
if (std::ranges::find(scVec, simT.seedIndex()) != scVec.end()) {
time = caloParticles[cpIdx].simTime();
break; //dont need to check further
}
}
fillVectors(sc, iSim, time);
}
}
}
auto simTrackstersTable =
std::make_unique<nanoaod::FlatTable>(nSimTracksters, tableName_, /*singleton*/ false, /*extension*/ true);
simTrackstersTable->addColumn<float>(
"boundaryX", boundaryX, "CaloVolume boundary Position X [cm] of associated Simobject", precision_);
simTrackstersTable->addColumn<float>(
"boundaryY", boundaryY, "CaloVolume boundary Position Y [cm] of associated Simobject", precision_);
simTrackstersTable->addColumn<float>(
"boundaryZ", boundaryZ, "CaloVolume boundary Position Z [cm] of associated Simobject", precision_);
simTrackstersTable->addColumn<float>(
"boundaryEta", boundaryEta, "CaloVolume boundary pseudorapidity of associated Simobject", precision_);
simTrackstersTable->addColumn<float>(
"boundaryPhi", boundaryEta, "CaloVolume boundary phi of associated Simobject", precision_);
simTrackstersTable->addColumn<float>(
"boundaryPx", boundaryPx, "X component of momentum at CaloVolume boundary of associated Simobject", precision_);
simTrackstersTable->addColumn<float>(
"boundaryPy", boundaryPy, "Y component of momentum at CaloVolume boundary of associated Simobject", precision_);
simTrackstersTable->addColumn<float>(
"boundaryPz", boundaryPz, "Z component of momentum at CaloVolume boundary of associated Simobject", precision_);
simTrackstersTable->addColumn<float>("simTime", simTime, "Sim-Time of simulated object [ns]", precision_);
simTrackstersTable->addColumn<float>("genPt", genPt, "Gen-pT associated with SimObject", precision_);
simTrackstersTable->addColumn<float>("mass", mass, "mass associated with SimObject", precision_);
event.put(std::move(simTrackstersTable), tableName_);
}
private:
const std::string tableName_;
const bool skipNonExistingSrc_;
const edm::EDGetTokenT<std::vector<ticl::Trackster>> simTrackstersToken_;
const edm::EDGetTokenT<std::vector<CaloParticle>> caloParticlesToken_;
const edm::EDGetTokenT<std::vector<SimCluster>> simClustersToken_;
const edm::EDGetTokenT<std::map<uint, std::vector<uint>>> caloParticleToSimClustersMap_token_;
const unsigned int precision_;
};
#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(SimTracksterTableProducer);
|