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 beginRun(const edm::Run&, const edm::EventSetup&) override;
35  void produce(edm::Event&, edm::EventSetup const&) override;
36 
37  std::unordered_map<uint32_t, double> makeHitMap(edm::Event const&,
38  edm::EventSetup const&,
39  HGCalTriggerGeometryBase const&) const;
40 
42 
51 
54 
56 };
57 
59  : makeCellsCollection_(config.getParameter<bool>("makeCellsCollection")),
60  caloParticlesToken_(consumes<CaloParticleCollection>(config.getParameter<edm::InputTag>("caloParticles"))),
61  triggerCellsToken_(
62  consumes<l1t::HGCalTriggerCellBxCollection>(config.getParameter<edm::InputTag>("triggerCells"))),
63  simHitsTokenEE_(consumes<std::vector<PCaloHit>>(config.getParameter<edm::InputTag>("simHitsEE"))),
64  simHitsTokenHEfront_(consumes<std::vector<PCaloHit>>(config.getParameter<edm::InputTag>("simHitsHEfront"))),
65  simHitsTokenHEback_(consumes<std::vector<PCaloHit>>(config.getParameter<edm::InputTag>("simHitsHEback"))),
66  triggerGeomToken_(esConsumes<HGCalTriggerGeometryBase, CaloGeometryRecord, edm::Transition::BeginRun>()),
67  dummyClustering_(config.getParameterSet("dummyClustering")) {
68  produces<CaloToCellsMap>();
69  produces<l1t::HGCalClusterBxCollection>();
70  produces<l1t::HGCalMulticlusterBxCollection>();
72  produces<l1t::HGCalTriggerCellBxCollection>();
73 }
74 
76 
79 }
80 
82  edm::Handle<CaloParticleCollection> caloParticlesHandle;
83  event.getByToken(caloParticlesToken_, caloParticlesHandle);
84  auto const& caloParticles(*caloParticlesHandle);
85 
87  event.getByToken(triggerCellsToken_, triggerCellsHandle);
88  auto const& triggerCells(*triggerCellsHandle);
89 
90  auto const& geometry(*triggerGeomHandle_);
91 
95 
96  std::unordered_map<uint32_t, CaloParticleRef> tcToCalo;
97 
98  std::unordered_map<uint32_t, double> hitToEnergy(makeHitMap(event, setup, geometry)); // cellId -> sim energy
99  std::unordered_map<uint32_t, std::pair<double, double>>
100  tcToEnergies; // tcId -> {total sim energy, fractioned sim energy}
101 
102  for (auto const& he : hitToEnergy) {
103  DetId hitId(he.first);
104  // this line will throw if (for whatever reason) hitId is not mapped to a trigger cell id
105  uint32_t tcId(geometry.getTriggerCellFromCell(hitId));
106  tcToEnergies[tcId].first += he.second;
107  }
108 
109  // used later to order multiclusters
110  std::map<int, CaloParticleRef> orderedCaloRefs;
111 
112  for (unsigned iP(0); iP != caloParticles.size(); ++iP) {
113  auto const& caloParticle(caloParticles.at(iP));
114  if (caloParticle.g4Tracks().at(0).eventId().event() != 0) // pileup
115  continue;
116 
117  CaloParticleRef ref(caloParticlesHandle, iP);
118 
119  SimClusterRefVector const& simClusters(caloParticle.simClusters());
120  for (auto const& simCluster : simClusters) {
121  for (auto const& hAndF : simCluster->hits_and_fractions()) {
122  DetId hitId(hAndF.first);
123  uint32_t tcId;
124  try {
125  tcId = geometry.getTriggerCellFromCell(hitId);
126  } catch (cms::Exception const& ex) {
127  edm::LogError("CaloTruthCellsProducer") << ex.what();
128  continue;
129  }
130 
131  tcToCalo.emplace(tcId, ref);
132  tcToEnergies[tcId].second += hitToEnergy[hAndF.first] * hAndF.second;
133  }
134  }
135 
136  // ordered by the gen particle index
137  int genIndex(caloParticle.g4Tracks().at(0).genpartIndex() - 1);
138  orderedCaloRefs[genIndex] = ref;
139  }
140 
141  auto outMap(std::make_unique<CaloToCellsMap>(caloParticlesHandle, triggerCellsHandle));
142  std::unique_ptr<l1t::HGCalTriggerCellBxCollection> outCollection;
144  outCollection = std::make_unique<l1t::HGCalTriggerCellBxCollection>();
145 
146  typedef edm::Ptr<l1t::HGCalTriggerCell> TriggerCellPtr;
147  typedef edm::Ptr<l1t::HGCalCluster> ClusterPtr;
148 
149  // ClusteringDummyImpl only considers BX 0, so we dump all cells to one vector
150  std::vector<TriggerCellPtr> triggerCellPtrs;
151 
152  // loop through all bunch crossings
153  for (int bx(triggerCells.getFirstBX()); bx <= triggerCells.getLastBX(); ++bx) {
154  for (auto cItr(triggerCells.begin(bx)); cItr != triggerCells.end(bx); ++cItr) {
155  auto const& cell(*cItr);
156 
157  auto mapElem(tcToCalo.find(cell.detId()));
158  if (mapElem == tcToCalo.end())
159  continue;
160 
161  outMap->insert(mapElem->second,
162  edm::Ref<l1t::HGCalTriggerCellBxCollection>(triggerCellsHandle, triggerCells.key(cItr)));
163 
164  if (makeCellsCollection_) {
165  auto const& simEnergies(tcToEnergies.at(cell.detId()));
166  if (simEnergies.first > 0.) {
167  double eFraction(simEnergies.second / simEnergies.first);
168 
169  outCollection->push_back(bx, cell);
170  auto& newCell((*outCollection)[outCollection->size() - 1]);
171 
172  newCell.setMipPt(cell.mipPt() * eFraction);
173  newCell.setP4(cell.p4() * eFraction);
174  }
175  }
176 
177  triggerCellPtrs.emplace_back(triggerCellsHandle, triggerCells.key(cItr));
178  }
179  }
180 
181  event.put(std::move(outMap));
183  event.put(std::move(outCollection));
184 
185  auto outClusters(std::make_unique<l1t::HGCalClusterBxCollection>());
186 
187  auto sortCellPtrs(
188  [](TriggerCellPtr const& lhs, TriggerCellPtr const& rhs) -> bool { return lhs->mipPt() > rhs->mipPt(); });
189 
190  std::sort(triggerCellPtrs.begin(), triggerCellPtrs.end(), sortCellPtrs);
191  dummyClustering_.clusterizeDummy(triggerCellPtrs, *outClusters);
192 
193  std::unordered_map<unsigned, std::vector<unsigned>> caloToClusterIndices;
194  for (unsigned iC(0); iC != outClusters->size(); ++iC) {
195  auto const& cluster((*outClusters)[iC]);
196  // cluster detId and cell detId are identical
197  auto caloRef(tcToCalo.at(cluster.detId()));
198  caloToClusterIndices[caloRef.key()].push_back(iC);
199  }
200 
201  auto clustersHandle(event.put(std::move(outClusters)));
202 
203  auto outMulticlusters(std::make_unique<l1t::HGCalMulticlusterBxCollection>());
204 
205  for (auto const& ocr : orderedCaloRefs) {
206  auto const& ref(ocr.second);
207 
208  if (ref.isNull()) // shouldn't happen
209  continue;
210 
211  auto const& caloParticle(*ref);
212 
213  l1t::HGCalMulticluster multicluster;
214 
215  for (unsigned iC : caloToClusterIndices[ref.key()]) {
216  ClusterPtr clPtr(clustersHandle, iC);
217  multicluster.addConstituent(clPtr, true, 1.);
218  }
219 
220  // Set the gen particle index as the DetId
221  multicluster.setDetId(caloParticle.g4Tracks().at(0).genpartIndex() - 1);
222 
223  auto const& centre(multicluster.centre());
224  math::PtEtaPhiMLorentzVector multiclusterP4(multicluster.sumPt(), centre.eta(), centre.phi(), 0.);
225  multicluster.setP4(multiclusterP4);
226 
227  showerShape_.fillShapes(multicluster, geometry);
228 
229  // not setting the quality flag
230  // multicluster.setHwQual(id_->decision(multicluster));
231  // fill H/E
232  multicluster.saveHOverE();
233 
234  outMulticlusters->push_back(0, multicluster);
235  }
236 
237  event.put(std::move(outMulticlusters));
238 }
239 
240 std::unordered_map<uint32_t, double> CaloTruthCellsProducer::makeHitMap(
242  std::unordered_map<uint32_t, double> hitMap; // cellId -> sim energy
243 
244  typedef std::function<DetId(DetId const&)> DetIdMapper;
245  typedef std::pair<edm::EDGetTokenT<std::vector<PCaloHit>> const*, DetIdMapper> SimHitSpec;
246 
247  SimHitSpec specs[3] = {{&simHitsTokenEE_,
248  [this, &geometry](DetId const& simId) -> DetId {
249  return this->triggerTools_.simToReco(simId, geometry.eeTopology());
250  }},
252  [this, &geometry](DetId const& simId) -> DetId {
253  return this->triggerTools_.simToReco(simId, geometry.fhTopology());
254  }},
255  {&simHitsTokenHEback_, [this, &geometry](DetId const& simId) -> DetId {
256  return this->triggerTools_.simToReco(simId, geometry.hscTopology());
257  }}};
258 
259  for (auto const& tt : specs) {
261  event.getByToken(*tt.first, handle);
262  auto const& simhits(*handle);
263 
264  for (auto const& simhit : simhits)
265  hitMap.emplace(tt.second(simhit.id()), simhit.energy());
266  }
267 
268  return hitMap;
269 }
270 
272  //The following says we do not know what parameters are allowed so do no validation
273  // Please change this to state exactly what you do use, even if it is no parameters
275  desc.setUnknown();
276  descriptions.addDefault(desc);
277 }
278 
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_
void beginRun(const edm::Run &, const edm::EventSetup &) override
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
T const * product() const
Definition: ESHandle.h:86
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_
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:130
edm::EDGetTokenT< std::vector< PCaloHit > > simHitsTokenHEback_
Definition: DetId.h:17
edm::EDGetTokenT< std::vector< PCaloHit > > simHitsTokenHEfront_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
edm::ESHandle< HGCalTriggerGeometryBase > triggerGeomHandle_
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
Definition: Run.h:45