CMS 3D CMS Logo

CaloTruthCellsProducer.cc
Go to the documentation of this file.
1 #include <memory>
2 
25 
27 public:
29  ~CaloTruthCellsProducer() override;
30 
31  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
32 
33 private:
34  void produce(edm::Event&, edm::EventSetup const&) override;
35 
36  std::unordered_map<uint32_t, double> makeHitMap(edm::Event const&,
37  edm::EventSetup const&,
38  HGCalTriggerGeometryBase const&) const;
39 
41 
49 
52 
54 };
55 
57  : makeCellsCollection_(config.getParameter<bool>("makeCellsCollection")),
58  caloParticlesToken_(consumes<CaloParticleCollection>(config.getParameter<edm::InputTag>("caloParticles"))),
59  triggerCellsToken_(
60  consumes<l1t::HGCalTriggerCellBxCollection>(config.getParameter<edm::InputTag>("triggerCells"))),
61  simHitsTokenEE_(consumes<std::vector<PCaloHit>>(config.getParameter<edm::InputTag>("simHitsEE"))),
62  simHitsTokenHEfront_(consumes<std::vector<PCaloHit>>(config.getParameter<edm::InputTag>("simHitsHEfront"))),
63  simHitsTokenHEback_(consumes<std::vector<PCaloHit>>(config.getParameter<edm::InputTag>("simHitsHEback"))),
64  triggerGeomToken_(esConsumes<HGCalTriggerGeometryBase, CaloGeometryRecord, edm::Transition::BeginRun>()),
65  dummyClustering_(config.getParameterSet("dummyClustering")) {
66  produces<CaloToCellsMap>();
67  produces<l1t::HGCalClusterBxCollection>();
68  produces<l1t::HGCalMulticlusterBxCollection>();
70  produces<l1t::HGCalTriggerCellBxCollection>();
71 }
72 
74 
76  auto caloParticlesHandle = event.getHandle(caloParticlesToken_);
77  auto const& caloParticles = *caloParticlesHandle;
78 
79  auto const& triggerCellsHandle = event.getHandle(triggerCellsToken_);
80  auto const& triggerCells = *triggerCellsHandle;
81 
82  auto const& geometry = setup.getData(triggerGeomToken_);
83  ;
84 
88 
89  std::unordered_map<uint32_t, CaloParticleRef> tcToCalo;
90 
91  std::unordered_map<uint32_t, double> hitToEnergy(makeHitMap(event, setup, geometry)); // cellId -> sim energy
92  std::unordered_map<uint32_t, std::pair<double, double>>
93  tcToEnergies; // tcId -> {total sim energy, fractioned sim energy}
94 
95  for (auto const& he : hitToEnergy) {
96  DetId hitId(he.first);
97  // this line will throw if (for whatever reason) hitId is not mapped to a trigger cell id
98  uint32_t tcId(geometry.getTriggerCellFromCell(hitId));
99  tcToEnergies[tcId].first += he.second;
100  }
101 
102  // used later to order multiclusters
103  std::map<int, CaloParticleRef> orderedCaloRefs;
104 
105  for (unsigned iP(0); iP != caloParticles.size(); ++iP) {
106  auto const& caloParticle(caloParticles.at(iP));
107  if (caloParticle.g4Tracks().at(0).eventId().event() != 0) // pileup
108  continue;
109 
110  CaloParticleRef ref(caloParticlesHandle, iP);
111 
112  SimClusterRefVector const& simClusters(caloParticle.simClusters());
113  for (auto const& simCluster : simClusters) {
114  for (auto const& hAndF : simCluster->hits_and_fractions()) {
115  DetId hitId(hAndF.first);
116  uint32_t tcId;
117  try {
118  tcId = geometry.getTriggerCellFromCell(hitId);
119  } catch (cms::Exception const& ex) {
120  edm::LogError("CaloTruthCellsProducer") << ex.what();
121  continue;
122  }
123 
124  tcToCalo.emplace(tcId, ref);
125  tcToEnergies[tcId].second += hitToEnergy[hAndF.first] * hAndF.second;
126  }
127  }
128 
129  // ordered by the gen particle index
130  int genIndex(caloParticle.g4Tracks().at(0).genpartIndex() - 1);
131  orderedCaloRefs[genIndex] = ref;
132  }
133 
134  auto outMap(std::make_unique<CaloToCellsMap>(caloParticlesHandle, triggerCellsHandle));
135  std::unique_ptr<l1t::HGCalTriggerCellBxCollection> outCollection;
137  outCollection = std::make_unique<l1t::HGCalTriggerCellBxCollection>();
138 
139  typedef edm::Ptr<l1t::HGCalTriggerCell> TriggerCellPtr;
140  typedef edm::Ptr<l1t::HGCalCluster> ClusterPtr;
141 
142  // ClusteringDummyImpl only considers BX 0, so we dump all cells to one vector
143  std::vector<TriggerCellPtr> triggerCellPtrs;
144 
145  // loop through all bunch crossings
146  for (int bx(triggerCells.getFirstBX()); bx <= triggerCells.getLastBX(); ++bx) {
147  for (auto cItr(triggerCells.begin(bx)); cItr != triggerCells.end(bx); ++cItr) {
148  auto const& cell(*cItr);
149 
150  auto mapElem(tcToCalo.find(cell.detId()));
151  if (mapElem == tcToCalo.end())
152  continue;
153 
154  outMap->insert(mapElem->second,
155  edm::Ref<l1t::HGCalTriggerCellBxCollection>(triggerCellsHandle, triggerCells.key(cItr)));
156 
157  if (makeCellsCollection_) {
158  auto const& simEnergies(tcToEnergies.at(cell.detId()));
159  if (simEnergies.first > 0.) {
160  double eFraction(simEnergies.second / simEnergies.first);
161 
162  outCollection->push_back(bx, cell);
163  auto& newCell((*outCollection)[outCollection->size() - 1]);
164 
165  newCell.setMipPt(cell.mipPt() * eFraction);
166  newCell.setP4(cell.p4() * eFraction);
167  }
168  }
169 
170  triggerCellPtrs.emplace_back(triggerCellsHandle, triggerCells.key(cItr));
171  }
172  }
173 
174  event.put(std::move(outMap));
176  event.put(std::move(outCollection));
177 
178  auto outClusters(std::make_unique<l1t::HGCalClusterBxCollection>());
179 
180  auto sortCellPtrs(
181  [](TriggerCellPtr const& lhs, TriggerCellPtr const& rhs) -> bool { return lhs->mipPt() > rhs->mipPt(); });
182 
183  std::sort(triggerCellPtrs.begin(), triggerCellPtrs.end(), sortCellPtrs);
184  dummyClustering_.clusterizeDummy(triggerCellPtrs, *outClusters);
185 
186  std::unordered_map<unsigned, std::vector<unsigned>> caloToClusterIndices;
187  for (unsigned iC(0); iC != outClusters->size(); ++iC) {
188  auto const& cluster((*outClusters)[iC]);
189  // cluster detId and cell detId are identical
190  auto caloRef(tcToCalo.at(cluster.detId()));
191  caloToClusterIndices[caloRef.key()].push_back(iC);
192  }
193 
194  auto clustersHandle(event.put(std::move(outClusters)));
195 
196  auto outMulticlusters(std::make_unique<l1t::HGCalMulticlusterBxCollection>());
197 
198  for (auto const& ocr : orderedCaloRefs) {
199  auto const& ref(ocr.second);
200 
201  if (ref.isNull()) // shouldn't happen
202  continue;
203 
204  auto const& caloParticle(*ref);
205 
206  l1t::HGCalMulticluster multicluster;
207 
208  for (unsigned iC : caloToClusterIndices[ref.key()]) {
209  ClusterPtr clPtr(clustersHandle, iC);
210  multicluster.addConstituent(clPtr, true, 1.);
211  }
212 
213  // Set the gen particle index as the DetId
214  multicluster.setDetId(caloParticle.g4Tracks().at(0).genpartIndex() - 1);
215 
216  auto const& centre(multicluster.centre());
217  math::PtEtaPhiMLorentzVector multiclusterP4(multicluster.sumPt(), centre.eta(), centre.phi(), 0.);
218  multicluster.setP4(multiclusterP4);
219 
220  showerShape_.fillShapes(multicluster, geometry);
221 
222  // not setting the quality flag
223  // multicluster.setHwQual(id_->decision(multicluster));
224  // fill H/E
225  multicluster.saveHOverE();
226 
227  outMulticlusters->push_back(0, multicluster);
228  }
229 
230  event.put(std::move(outMulticlusters));
231 }
232 
233 std::unordered_map<uint32_t, double> CaloTruthCellsProducer::makeHitMap(
235  std::unordered_map<uint32_t, double> hitMap; // cellId -> sim energy
236 
237  typedef std::function<DetId(DetId const&)> DetIdMapper;
238  typedef std::pair<edm::EDGetTokenT<std::vector<PCaloHit>> const*, DetIdMapper> SimHitSpec;
239 
240  SimHitSpec specs[3] = {{&simHitsTokenEE_,
241  [this, &geometry](DetId const& simId) -> DetId {
242  return this->triggerTools_.simToReco(simId, geometry.eeTopology());
243  }},
245  [this, &geometry](DetId const& simId) -> DetId {
246  return this->triggerTools_.simToReco(simId, geometry.fhTopology());
247  }},
248  {&simHitsTokenHEback_, [this, &geometry](DetId const& simId) -> DetId {
249  return this->triggerTools_.simToReco(simId, geometry.hscTopology());
250  }}};
251 
252  for (auto const& tt : specs) {
254  event.getByToken(*tt.first, handle);
255  auto const& simhits(*handle);
256 
257  for (auto const& simhit : simhits)
258  hitMap.emplace(tt.second(simhit.id()), simhit.energy());
259  }
260 
261  return hitMap;
262 }
263 
265  //The following says we do not know what parameters are allowed so do no validation
266  // Please change this to state exactly what you do use, even if it is no parameters
268  desc.setUnknown();
269  descriptions.addDefault(desc);
270 }
271 
void addConstituent(const edm::Ptr< C > &c, bool updateCentre=true, float fraction=1.)
Definition: HGCalClusterT.h:54
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
HGCalClusteringDummyImpl dummyClustering_
BXVector< HGCalTriggerCell > HGCalTriggerCellBxCollection
void setDetId(uint32_t id)
Definition: HGCalClusterT.h:93
edm::EDGetTokenT< std::vector< PCaloHit > > simHitsTokenEE_
void setGeometry(const HGCalTriggerGeometryBase *const geom)
edm::ESGetToken< HGCalTriggerGeometryBase, CaloGeometryRecord > triggerGeomToken_
void produce(edm::Event &, edm::EventSetup const &) override
delete x;
Definition: CaloConfig.h:22
Definition: config.py:1
Log< level::Error, false > LogError
void clusterizeDummy(const std::vector< edm::Ptr< l1t::HGCalTriggerCell >> &triggerCellsPtrs, l1t::HGCalClusterBxCollection &clusters)
const GlobalPoint & centre() const
std::unordered_map< uint32_t, double > makeHitMap(edm::Event const &, edm::EventSetup const &, HGCalTriggerGeometryBase const &) const
void setGeometry(const HGCalTriggerGeometryBase *const)
CaloTruthCellsProducer(edm::ParameterSet const &)
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
Definition: LorentzVector.h:25
Definition: TTTypes.h:54
void addDefault(ParameterSetDescription const &psetDescription)
edm::EDGetTokenT< l1t::HGCalTriggerCellBxCollection > triggerCellsToken_
void setGeometry(const HGCalTriggerGeometryBase *const geom)
void fillShapes(l1t::HGCalMulticluster &, const HGCalTriggerGeometryBase &) const
DetId simToReco(const DetId &, const HGCalTopology &) const
Transition
Definition: Transition.h:12
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::EDGetTokenT< CaloParticleCollection > caloParticlesToken_
edm::EDGetTokenT< std::vector< PCaloHit > > simHitsTokenHEback_
Definition: DetId.h:17
edm::EDGetTokenT< std::vector< PCaloHit > > simHitsTokenHEfront_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
ParameterSet const & getParameterSet(ParameterSetID const &id)
HLT enums.
std::vector< CaloParticle > CaloParticleCollection
edm::AssociationMap< edm::OneToMany< CaloParticleCollection, l1t::HGCalTriggerCellBxCollection > > CaloToCellsMap
char const * what() const noexcept override
Definition: Exception.cc:107
void setP4(const LorentzVector &p4) final
set 4-momentum
double sumPt() const
Definition: HGCalClusterT.h:95
def move(src, dest)
Definition: eostools.py:511
Definition: event.py:1