CMS 3D CMS Logo

HitTripletEDProducerT.h
Go to the documentation of this file.
1 #ifndef RecoTracker_PixelSeeding_HitTripletEDProducerT_h
2 #define RecoTracker_PixelSeeding_HitTripletEDProducerT_h
3 
14 
20 
21 #include <numeric>
22 
24  class ImplBase;
25 }
26 
27 template <typename T_HitTripletGenerator>
29 public:
31  ~HitTripletEDProducerT() override = default;
32 
33  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
34 
35  void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
36 
37 private:
39 
40  std::unique_ptr<hitTripletEDProducerT::ImplBase> impl_;
41 };
42 
43 namespace hitTripletEDProducerT {
44  class ImplBase {
45  public:
46  ImplBase() = default;
47  virtual ~ImplBase() = default;
48 
49  virtual void produces(edm::ProducesCollector) const = 0;
50  virtual void produce(const IntermediateHitDoublets& regionDoublets,
52  const edm::EventSetup& iSetup) = 0;
53 
54  protected:
56  };
57 
59  template <typename T_HitTripletGenerator>
60  class ImplGeneratorBase : public ImplBase {
61  public:
63  ~ImplGeneratorBase() override = default;
64 
65  protected:
66  T_HitTripletGenerator generator_;
67  };
68 
70  template <typename T_HitTripletGenerator, typename T_SeedingHitSets, typename T_IntermediateHitTriplets>
71  class Impl : public ImplGeneratorBase<T_HitTripletGenerator> {
72  public:
74  : ImplGeneratorBase<T_HitTripletGenerator>(iConfig, iC) {}
75  ~Impl() override = default;
76 
77  void produces(edm::ProducesCollector producesCollector) const override {
78  T_SeedingHitSets::produces(producesCollector);
79  T_IntermediateHitTriplets::produces(producesCollector);
80  };
81 
82  void produce(const IntermediateHitDoublets& regionDoublets,
84  const edm::EventSetup& iSetup) override {
85  const SeedingLayerSetsHits& seedingLayerHits = regionDoublets.seedingLayerHits();
86 
87  auto seedingHitSetsProducer = T_SeedingHitSets();
88  auto intermediateHitTripletsProducer = T_IntermediateHitTriplets(&seedingLayerHits);
89 
90  if (regionDoublets.empty()) {
91  seedingHitSetsProducer.putEmpty(iEvent);
92  intermediateHitTripletsProducer.putEmpty(iEvent);
93  return;
94  }
95 
96  seedingHitSetsProducer.reserve(regionDoublets.regionSize(), this->localRA_.upper());
97  intermediateHitTripletsProducer.reserve(regionDoublets.regionSize(), this->localRA_.upper());
98 
99  // match-making of pair and triplet layers
100  std::vector<LayerTriplets::LayerSetAndLayers> trilayers = LayerTriplets::layers(seedingLayerHits);
101 
102  OrderedHitTriplets triplets;
103  triplets.reserve(this->localRA_.upper());
104  size_t triplets_total = 0;
105 
106  LogDebug("HitTripletEDProducer") << "Creating triplets for " << regionDoublets.regionSize() << " regions, and "
107  << trilayers.size() << " pair+3rd layers from "
108  << regionDoublets.layerPairsSize() << " layer pairs";
109 
110  for (const auto& regionLayerPairs : regionDoublets) {
111  const TrackingRegion& region = regionLayerPairs.region();
112 
113  auto hitCachePtr_filler_shs = seedingHitSetsProducer.beginRegion(&region, nullptr);
114  auto hitCachePtr_filler_iht =
115  intermediateHitTripletsProducer.beginRegion(&region, std::get<0>(hitCachePtr_filler_shs));
116  auto hitCachePtr = std::get<0>(hitCachePtr_filler_iht);
117 
118  LayerHitMapCache& hitCache = *hitCachePtr;
119  hitCache.extend(regionLayerPairs.layerHitMapCache());
120 
121  LogTrace("HitTripletEDProducer") << " starting region";
122 
123  for (const auto& layerPair : regionLayerPairs) {
124  LogTrace("HitTripletEDProducer")
125  << " starting layer pair " << layerPair.innerLayerIndex() << "," << layerPair.outerLayerIndex();
126 
127  auto found = std::find_if(trilayers.begin(), trilayers.end(), [&](const LayerTriplets::LayerSetAndLayers& a) {
128  return a.first[0].index() == layerPair.innerLayerIndex() &&
129  a.first[1].index() == layerPair.outerLayerIndex();
130  });
131  if (found == trilayers.end()) {
132  auto exp = cms::Exception("LogicError") << "Did not find the layer pair from vector<pair+third layers>. "
133  "This is a sign of some internal inconsistency\n";
134  exp << "I was looking for layer pair " << layerPair.innerLayerIndex() << "," << layerPair.outerLayerIndex()
135  << ". Triplets have the following pairs:\n";
136  for (const auto& a : trilayers) {
137  exp << " " << a.first[0].index() << "," << a.first[1].index() << ": 3rd layers";
138  for (const auto& b : a.second) {
139  exp << " " << b.index();
140  }
141  exp << "\n";
142  }
143  throw exp;
144  }
145  const auto& thirdLayers = found->second;
146 
147  this->generator_.hitTriplets(region,
148  triplets,
149  iEvent,
150  iSetup,
151  layerPair.doublets(),
152  thirdLayers,
153  intermediateHitTripletsProducer.tripletLastLayerIndexVector(),
154  hitCache);
155 
156 #ifdef EDM_ML_DEBUG
157  LogTrace("HitTripletEDProducer")
158  << " created " << triplets.size() << " triplets for layer pair " << layerPair.innerLayerIndex() << ","
159  << layerPair.outerLayerIndex() << " and 3rd layers";
160  for (const auto& l : thirdLayers) {
161  LogTrace("HitTripletEDProducer") << " " << l.index();
162  }
163 #endif
164 
165  triplets_total += triplets.size();
166  seedingHitSetsProducer.fill(std::get<1>(hitCachePtr_filler_shs), triplets);
167  intermediateHitTripletsProducer.fill(
168  std::get<1>(hitCachePtr_filler_iht), layerPair.layerPair(), thirdLayers, triplets);
169 
170  triplets.clear();
171  }
172  }
173  this->localRA_.update(triplets_total);
174 
175  seedingHitSetsProducer.put(iEvent);
176  intermediateHitTripletsProducer.put(iEvent);
177  }
178  };
179 
181  class DoNothing {
182  public:
185 
187 
188  void reserve(size_t, size_t) {}
189 
190  auto beginRegion(const TrackingRegion*, LayerHitMapCache* ptr) { return std::make_tuple(ptr, 0); }
191 
192  std::vector<int>* tripletLastLayerIndexVector() { return nullptr; }
193 
194  void fill(int, const OrderedHitTriplets&) {}
195  void fill(int,
197  const std::vector<SeedingLayerSetsHits::SeedingLayer>&,
198  const OrderedHitTriplets&) {}
199 
202  };
203 
206  public:
208 
209  static void produces(edm::ProducesCollector producesCollector) {
210  producesCollector.produces<RegionsSeedingHitSets>();
211  }
212 
213  void reserve(size_t regionsSize, size_t localRAupper) { seedingHitSets_->reserve(regionsSize, localRAupper); }
214 
217  return std::make_tuple(&hitCacheTmp_, seedingHitSets_->beginRegion(region));
218  }
219 
221  for (const auto& trpl : triplets) {
222  filler.emplace_back(trpl.inner(), trpl.middle(), trpl.outer());
223  }
224  }
225 
227  seedingHitSets_->shrink_to_fit();
228  putEmpty(iEvent);
229  }
231 
232  private:
233  std::unique_ptr<RegionsSeedingHitSets> seedingHitSets_;
234  LayerHitMapCache hitCacheTmp_; // used if !produceIntermediateHitDoublets
235  };
236 
239  public:
242 
243  static void produces(edm::ProducesCollector producesCollector) {
244  producesCollector.produces<IntermediateHitTriplets>();
245  }
246 
247  void reserve(size_t regionsSize, size_t localRAupper) {
248  intermediateHitTriplets_->reserve(regionsSize, layers_->size(), localRAupper);
249  tripletLastLayerIndex_.reserve(localRAupper);
250  }
251 
253  auto filler = intermediateHitTriplets_->beginRegion(region);
254  return std::make_tuple(&(filler.layerHitMapCache()), filler);
255  }
256 
257  std::vector<int>* tripletLastLayerIndexVector() { return &tripletLastLayerIndex_; }
258 
260  const IntermediateHitTriplets::LayerPair& layerPair,
261  const std::vector<SeedingLayerSetsHits::SeedingLayer>& thirdLayers,
262  const OrderedHitTriplets& triplets) {
263  if (tripletLastLayerIndex_.size() != triplets.size()) {
264  throw cms::Exception("LogicError") << "tripletLastLayerIndex_.size() " << tripletLastLayerIndex_.size()
265  << " triplets.size() " << triplets.size();
266  }
268  std::iota(tripletPermutation_.begin(), tripletPermutation_.end(), 0); // assign 0,1,2,...,N
269  std::stable_sort(tripletPermutation_.begin(), tripletPermutation_.end(), [&](size_t i, size_t j) {
271  });
272 
273  // empty triplets need to propagate here
274  filler.addTriplets(layerPair, thirdLayers, triplets, tripletLastLayerIndex_, tripletPermutation_);
275  tripletLastLayerIndex_.clear();
276  }
277 
279  intermediateHitTriplets_->shrink_to_fit();
280  putEmpty(iEvent);
281  }
283 
284  private:
285  std::unique_ptr<IntermediateHitTriplets> intermediateHitTriplets_;
287  std::vector<size_t> tripletPermutation_;
288  std::vector<int> tripletLastLayerIndex_;
289  };
290 } // namespace hitTripletEDProducerT
291 
292 template <typename T_HitTripletGenerator>
294  : doubletToken_(consumes<IntermediateHitDoublets>(iConfig.getParameter<edm::InputTag>("doublets"))) {
295  const bool produceSeedingHitSets = iConfig.getParameter<bool>("produceSeedingHitSets");
296  const bool produceIntermediateHitTriplets = iConfig.getParameter<bool>("produceIntermediateHitTriplets");
297 
298  auto iC = consumesCollector();
299 
300  using namespace hitTripletEDProducerT;
301 
303  impl_ = std::make_unique<Impl<T_HitTripletGenerator, ImplSeedingHitSets, ImplIntermediateHitTriplets>>(iConfig, iC);
304  else if (produceSeedingHitSets)
305  impl_ = std::make_unique<Impl<T_HitTripletGenerator, ImplSeedingHitSets, DoNothing>>(iConfig, iC);
307  impl_ = std::make_unique<Impl<T_HitTripletGenerator, DoNothing, ImplIntermediateHitTriplets>>(iConfig, iC);
308  else
309  throw cms::Exception("Configuration")
310  << "HitTripletEDProducerT requires either produceIntermediateHitTriplets or produceSeedingHitSets to be True. "
311  "If neither are needed, just remove this module from your sequence/path as it doesn't do anything useful";
312 
313  impl_->produces(producesCollector());
314 }
315 
316 template <typename T_HitTripletGenerator>
319 
320  desc.add<edm::InputTag>("doublets", edm::InputTag("hitPairEDProducer"));
321  desc.add<bool>("produceSeedingHitSets", false);
322  desc.add<bool>("produceIntermediateHitTriplets", false);
323 
325 
326  auto label = T_HitTripletGenerator::fillDescriptionsLabel() + std::string("EDProducerDefault");
327  descriptions.add(label, desc);
328 }
329 
330 template <typename T_HitTripletGenerator>
333  iEvent.getByToken(doubletToken_, hdoublets);
334  const auto& regionDoublets = *hdoublets;
335 
336  const SeedingLayerSetsHits& seedingLayerHits = regionDoublets.seedingLayerHits();
337  if (seedingLayerHits.numberOfLayersInSet() < 3) {
338  throw cms::Exception("LogicError")
339  << "HitTripletEDProducerT expects SeedingLayerSetsHits::numberOfLayersInSet() to be >= 3, got "
340  << seedingLayerHits.numberOfLayersInSet()
341  << ". This is likely caused by a configuration error of this module, HitPairEDProducer, or "
342  "SeedingLayersEDProducer.";
343  }
344 
345  impl_->produce(regionDoublets, iEvent, iSetup);
346 }
347 
348 #endif
void fill(int, const IntermediateHitTriplets::LayerPair &, const std::vector< SeedingLayerSetsHits::SeedingLayer > &, const OrderedHitTriplets &)
auto beginRegion(const TrackingRegion *, LayerHitMapCache *ptr)
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
Definition: LayerTriplets.cc:4
void fill(int, const OrderedHitTriplets &)
ProductRegistryHelper::BranchAliasSetterT< ProductType > produces()
static void produces(edm::ProducesCollector producesCollector)
virtual void produces(edm::ProducesCollector) const =0
unsigned short size() const
Get the number of SeedingLayerSets.
~HitTripletEDProducerT() override=default
#define LogTrace(id)
void reserve(size_t regionsSize, size_t localRAupper)
std::unique_ptr< hitTripletEDProducerT::ImplBase > impl_
char const * label
Definition: __init__.py:1
Impl(const edm::ParameterSet &iConfig, edm::ConsumesCollector &iC)
int iEvent
Definition: GenABIO.cc:224
void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
const SeedingLayerSetsHits & seedingLayerHits() const
std::unique_ptr< RegionsSeedingHitSets > seedingHitSets_
std::unique_ptr< IntermediateHitTriplets > intermediateHitTriplets_
static void produces(edm::ProducesCollector producesCollector)
DoNothing(const SeedingLayerSetsHits *layers)
virtual void produce(const IntermediateHitDoublets &regionDoublets, edm::Event &iEvent, const edm::EventSetup &iSetup)=0
static void produces(edm::ProducesCollector)
void produce(const IntermediateHitDoublets &regionDoublets, edm::Event &iEvent, const edm::EventSetup &iSetup) override
std::tuple< SeedingLayerSetsHits::LayerIndex, SeedingLayerSetsHits::LayerIndex > LayerPair
auto beginRegion(const TrackingRegion *region, LayerHitMapCache *ptr)
unsigned short numberOfLayersInSet() const
Get number of layers in each SeedingLayerSets.
std::pair< LayerSet, std::vector< Layer > > LayerSetAndLayers
Definition: LayerTriplets.h:16
Helper class enforcing correct way of filling the doublets of a region.
void produces(edm::ProducesCollector producesCollector) const override
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void fill(IntermediateHitTriplets::RegionFiller &filler, const IntermediateHitTriplets::LayerPair &layerPair, const std::vector< SeedingLayerSetsHits::SeedingLayer > &thirdLayers, const OrderedHitTriplets &triplets)
void fill(RegionsSeedingHitSets::RegionFiller &filler, const OrderedHitTriplets &triplets)
edm::EDGetTokenT< IntermediateHitDoublets > doubletToken_
double b
Definition: hdecay.h:120
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void extend(const LayerHitMapCache &other)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
HLT enums.
double a
Definition: hdecay.h:121
Helper class enforcing correct way of filling the doublets of a region.
~Impl() override=default
std::vector< int > * tripletLastLayerIndexVector()
HitTripletEDProducerT(const edm::ParameterSet &iConfig)
auto beginRegion(const TrackingRegion *region, LayerHitMapCache *)
ImplIntermediateHitTriplets(const SeedingLayerSetsHits *layers)
unsigned int size() const override
def move(src, dest)
Definition: eostools.py:511
void update(unsigned int q)
ImplGeneratorBase(const edm::ParameterSet &iConfig, edm::ConsumesCollector &iC)
void reserve(size_t regionsSize, size_t localRAupper)
#define LogDebug(id)