CMS 3D CMS Logo

HitTripletEDProducerT.h
Go to the documentation of this file.
1 #ifndef RecoPixelVertexing_PixelTriplets_HitTripletEDProducerT_H
2 #define RecoPixelVertexing_PixelTriplets_HitTripletEDProducerT_H
3 
13 
19 
20 namespace hitTripletEDProducerT { class ImplBase; }
21 
22 template <typename T_HitTripletGenerator>
24 public:
26  ~HitTripletEDProducerT() = default;
27 
28  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
29 
30  virtual void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
31 
32 private:
34 
35  std::unique_ptr<hitTripletEDProducerT::ImplBase> impl_;
36 };
37 
38 namespace hitTripletEDProducerT {
39  class ImplBase {
40  public:
41  ImplBase() = default;
42  virtual ~ImplBase() = default;
43 
44  virtual void produces(edm::ProducerBase& producer) const = 0;
45  virtual void produce(const IntermediateHitDoublets& regionDoublets,
46  edm::Event& iEvent, const edm::EventSetup& iSetup) = 0;
47 
48  protected:
50  };
51 
53  template <typename T_HitTripletGenerator>
54  class ImplGeneratorBase: public ImplBase {
55  public:
57  generator_(iConfig, iC)
58  {}
59  ~ImplGeneratorBase() = default;
60 
61  protected:
62  T_HitTripletGenerator generator_;
63  };
64 
66  template <typename T_HitTripletGenerator,
67  typename T_SeedingHitSets, typename T_IntermediateHitTriplets>
68  class Impl: public ImplGeneratorBase<T_HitTripletGenerator> {
69  public:
71  ImplGeneratorBase<T_HitTripletGenerator>(iConfig, iC) {}
72  ~Impl() = default;
73 
74  void produces(edm::ProducerBase& producer) const override {
75  T_SeedingHitSets::produces(producer);
76  T_IntermediateHitTriplets::produces(producer);
77  };
78 
79  void produce(const IntermediateHitDoublets& regionDoublets,
80  edm::Event& iEvent, const edm::EventSetup& iSetup) override {
81  const SeedingLayerSetsHits& seedingLayerHits = regionDoublets.seedingLayerHits();
82 
83  auto seedingHitSetsProducer = T_SeedingHitSets();
84  auto intermediateHitTripletsProducer = T_IntermediateHitTriplets(&seedingLayerHits);
85 
86  if(regionDoublets.empty()) {
87  seedingHitSetsProducer.putEmpty(iEvent);
88  intermediateHitTripletsProducer.putEmpty(iEvent);
89  return;
90  }
91 
92  seedingHitSetsProducer.reserve(regionDoublets.regionSize(), this->localRA_.upper());
93  intermediateHitTripletsProducer.reserve(regionDoublets.regionSize(), this->localRA_.upper());
94 
95  // match-making of pair and triplet layers
96  std::vector<LayerTriplets::LayerSetAndLayers> trilayers = LayerTriplets::layers(seedingLayerHits);
97 
99  triplets.reserve(this->localRA_.upper());
100  size_t triplets_total = 0;
101 
102  LogDebug("HitTripletEDProducer") << "Creating triplets for " << regionDoublets.regionSize() << " regions, and " << trilayers.size() << " pair+3rd layers from " << regionDoublets.layerPairsSize() << " layer pairs";
103 
104  for(const auto& regionLayerPairs: regionDoublets) {
105  const TrackingRegion& region = regionLayerPairs.region();
106 
107  auto hitCachePtr_filler_shs = seedingHitSetsProducer.beginRegion(&region, nullptr);
108  auto hitCachePtr_filler_iht = intermediateHitTripletsProducer.beginRegion(&region, std::get<0>(hitCachePtr_filler_shs));
109  auto hitCachePtr = std::get<0>(hitCachePtr_filler_iht);
110 
111  LayerHitMapCache& hitCache = *hitCachePtr;
112  hitCache.extend(regionLayerPairs.layerHitMapCache());
113 
114  LogTrace("HitTripletEDProducer") << " starting region";
115 
116  for(const auto& layerPair: regionLayerPairs) {
117  LogTrace("HitTripletEDProducer") << " starting layer pair " << layerPair.innerLayerIndex() << "," << layerPair.outerLayerIndex();
118 
119  auto found = std::find_if(trilayers.begin(), trilayers.end(), [&](const LayerTriplets::LayerSetAndLayers& a) {
120  return a.first[0].index() == layerPair.innerLayerIndex() && a.first[1].index() == layerPair.outerLayerIndex();
121  });
122  if(found == trilayers.end()) {
123  auto exp = cms::Exception("LogicError") << "Did not find the layer pair from vector<pair+third layers>. This is a sign of some internal inconsistency\n";
124  exp << "I was looking for layer pair " << layerPair.innerLayerIndex() << "," << layerPair.outerLayerIndex() << ". Triplets have the following pairs:\n";
125  for(const auto& a: trilayers) {
126  exp << " " << a.first[0].index() << "," << a.first[1].index() << ": 3rd layers";
127  for(const auto& b: a.second) {
128  exp << " " << b.index();
129  }
130  exp << "\n";
131  }
132  throw exp;
133  }
134  const auto& thirdLayers = found->second;
135 
136  this->generator_.hitTriplets(region, triplets, iEvent, iSetup, layerPair.doublets(), thirdLayers,
137  intermediateHitTripletsProducer.tripletLastLayerIndexVector(), hitCache);
138 
139 #ifdef EDM_ML_DEBUG
140  LogTrace("HitTripletEDProducer") << " created " << triplets.size() << " triplets for layer pair " << layerPair.innerLayerIndex() << "," << layerPair.outerLayerIndex() << " and 3rd layers";
141  for(const auto& l: thirdLayers) {
142  LogTrace("HitTripletEDProducer") << " " << l.index();
143  }
144 #endif
145 
146  triplets_total += triplets.size();
147  seedingHitSetsProducer.fill(std::get<1>(hitCachePtr_filler_shs), triplets);
148  intermediateHitTripletsProducer.fill(std::get<1>(hitCachePtr_filler_iht), layerPair.layerPair(), thirdLayers, triplets);
149 
150  triplets.clear();
151  }
152  }
153  this->localRA_.update(triplets_total);
154 
155  seedingHitSetsProducer.put(iEvent);
156  intermediateHitTripletsProducer.put(iEvent);
157  }
158  };
159 
160 
162  class DoNothing {
163  public:
166 
167  static void produces(edm::ProducerBase&) {}
168 
169  void reserve(size_t, size_t) {}
170 
172  return std::make_tuple(ptr, 0);
173  }
174 
175  std::vector<int> *tripletLastLayerIndexVector() {
176  return nullptr;
177  }
178 
179  void fill(int, const OrderedHitTriplets&) {}
181  const std::vector<SeedingLayerSetsHits::SeedingLayer>&,
182  const OrderedHitTriplets&) {}
183 
184 
187  };
188 
191  public:
193  seedingHitSets_(std::make_unique<RegionsSeedingHitSets>())
194  {}
195 
197  producer.produces<RegionsSeedingHitSets>();
198  }
199 
200  void reserve(size_t regionsSize, size_t localRAupper) {
201  seedingHitSets_->reserve(regionsSize, localRAupper);
202  }
203 
204  auto beginRegion(const TrackingRegion *region, LayerHitMapCache *ptr) {
205  hitCacheTmp_.clear();
206  return std::make_tuple(&hitCacheTmp_, seedingHitSets_->beginRegion(region));
207  }
208 
210  for(const auto& trpl: triplets) {
211  filler.emplace_back(trpl.inner(), trpl.middle(), trpl.outer());
212  }
213  }
214 
216  seedingHitSets_->shrink_to_fit();
217  putEmpty(iEvent);
218  }
220  iEvent.put(std::move(seedingHitSets_));
221  }
222 
223  private:
224  std::unique_ptr<RegionsSeedingHitSets> seedingHitSets_;
225  LayerHitMapCache hitCacheTmp_; // used if !produceIntermediateHitDoublets
226  };
227 
230  public:
232  intermediateHitTriplets_(std::make_unique<IntermediateHitTriplets>(layers)),
233  layers_(layers)
234  {}
235 
237  producer.produces<IntermediateHitTriplets>();
238  }
239 
240  void reserve(size_t regionsSize, size_t localRAupper) {
241  intermediateHitTriplets_->reserve(regionsSize, layers_->size(), localRAupper);
242  tripletLastLayerIndex_.reserve(localRAupper);
243  }
244 
245  auto beginRegion(const TrackingRegion *region, LayerHitMapCache *) {
246  auto filler = intermediateHitTriplets_->beginRegion(region);
247  return std::make_tuple(&(filler.layerHitMapCache()), std::move(filler));
248  }
249 
250  std::vector<int> *tripletLastLayerIndexVector() {
251  return &tripletLastLayerIndex_;
252  }
253 
255  const IntermediateHitTriplets::LayerPair& layerPair,
256  const std::vector<SeedingLayerSetsHits::SeedingLayer>& thirdLayers,
257  const OrderedHitTriplets& triplets) {
258  if(tripletLastLayerIndex_.size() != triplets.size()) {
259  throw cms::Exception("LogicError") << "tripletLastLayerIndex_.size() " << tripletLastLayerIndex_.size()
260  << " triplets.size() " << triplets.size();
261  }
262  tripletPermutation_.resize(tripletLastLayerIndex_.size());
263  std::iota(tripletPermutation_.begin(), tripletPermutation_.end(), 0); // assign 0,1,2,...,N
264  std::stable_sort(tripletPermutation_.begin(), tripletPermutation_.end(), [&](size_t i, size_t j) {
265  return tripletLastLayerIndex_[i] < tripletLastLayerIndex_[j];
266  });
267 
268  // empty triplets need to propagate here
269  filler.addTriplets(layerPair, thirdLayers, triplets, tripletLastLayerIndex_, tripletPermutation_);
270  tripletLastLayerIndex_.clear();
271  }
272 
274  intermediateHitTriplets_->shrink_to_fit();
275  putEmpty(iEvent);
276  }
278  iEvent.put(std::move(intermediateHitTriplets_));
279  }
280 
281  private:
282  std::unique_ptr<IntermediateHitTriplets> intermediateHitTriplets_;
284  std::vector<size_t> tripletPermutation_;
285  std::vector<int> tripletLastLayerIndex_;
286  };
287 }
288 
289 
290 
291 template <typename T_HitTripletGenerator>
293  doubletToken_(consumes<IntermediateHitDoublets>(iConfig.getParameter<edm::InputTag>("doublets")))
294 {
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 
302  if(produceSeedingHitSets && produceIntermediateHitTriplets)
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);
306  else if(produceIntermediateHitTriplets)
307  impl_ = std::make_unique<Impl<T_HitTripletGenerator, DoNothing, ImplIntermediateHitTriplets>>(iConfig, iC);
308  else
309  throw cms::Exception("Configuration") << "HitTripletEDProducerT requires either produceIntermediateHitTriplets or produceSeedingHitSets to be True. If neither are needed, just remove this module from your sequence/path as it doesn't do anything useful";
310 
311  impl_->produces(*this);
312 }
313 
314 template <typename T_HitTripletGenerator>
317 
318  desc.add<edm::InputTag>("doublets", edm::InputTag("hitPairEDProducer"));
319  desc.add<bool>("produceSeedingHitSets", false);
320  desc.add<bool>("produceIntermediateHitTriplets", false);
321 
322  T_HitTripletGenerator::fillDescriptions(desc);
323 
324  auto label = T_HitTripletGenerator::fillDescriptionsLabel() + std::string("EDProducerDefault");
325  descriptions.add(label, desc);
326 }
327 
328 template <typename T_HitTripletGenerator>
331  iEvent.getByToken(doubletToken_, hdoublets);
332  const auto& regionDoublets = *hdoublets;
333 
334  const SeedingLayerSetsHits& seedingLayerHits = regionDoublets.seedingLayerHits();
335  if(seedingLayerHits.numberOfLayersInSet() < 3) {
336  throw cms::Exception("LogicError") << "HitTripletEDProducerT expects SeedingLayerSetsHits::numberOfLayersInSet() to be >= 3, got " << seedingLayerHits.numberOfLayersInSet() << ". This is likely caused by a configuration error of this module, HitPairEDProducer, or SeedingLayersEDProducer.";
337  }
338 
339  impl_->produce(regionDoublets, iEvent, iSetup);
340 }
341 
342 
343 #endif
#define LogDebug(id)
void fill(int, const IntermediateHitTriplets::LayerPair &, const std::vector< SeedingLayerSetsHits::SeedingLayer > &, const OrderedHitTriplets &)
T getParameter(std::string const &) const
auto beginRegion(const TrackingRegion *, LayerHitMapCache *ptr)
int i
Definition: DBlmapReader.cc:9
unsigned short numberOfLayersInSet() const
Get number of layers in each SeedingLayerSets.
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:122
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
Definition: LayerTriplets.cc:4
void fill(int, const OrderedHitTriplets &)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:457
static void produces(edm::ProducerBase &producer)
static void produces(edm::ProducerBase &)
void reserve(size_t regionsSize, size_t localRAupper)
std::unique_ptr< hitTripletEDProducerT::ImplBase > impl_
Definition: __init__.py:1
Impl(const edm::ParameterSet &iConfig, edm::ConsumesCollector &iC)
int iEvent
Definition: GenABIO.cc:230
virtual void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
std::unique_ptr< RegionsSeedingHitSets > seedingHitSets_
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
std::unique_ptr< IntermediateHitTriplets > intermediateHitTriplets_
void addTriplets(const LayerPair &layerPair, const std::vector< SeedingLayerSetsHits::SeedingLayer > &thirdLayers, const OrderedHitTriplets &triplets, const std::vector< int > &thirdLayerIndex, const std::vector< size_t > &permutations)
TypeLabelItem const & produces()
declare what type of product will make and with which optional label
int j
Definition: DBlmapReader.cc:9
DoNothing(const SeedingLayerSetsHits *layers)
void produce(const IntermediateHitDoublets &regionDoublets, edm::Event &iEvent, const edm::EventSetup &iSetup) override
std::tuple< SeedingLayerSetsHits::LayerIndex, SeedingLayerSetsHits::LayerIndex > LayerPair
ParameterDescriptionBase * add(U const &iLabel, T const &value)
#define LogTrace(id)
auto beginRegion(const TrackingRegion *region, LayerHitMapCache *ptr)
std::pair< LayerSet, std::vector< Layer > > LayerSetAndLayers
Definition: LayerTriplets.h:16
Helper class enforcing correct way of filling the doublets of a region.
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)
static void produces(edm::ProducerBase &producer)
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
void produces(edm::ProducerBase &producer) const override
Helper class enforcing correct way of filling the doublets of a region.
std::vector< int > * tripletLastLayerIndexVector()
HitTripletEDProducerT(const edm::ParameterSet &iConfig)
auto beginRegion(const TrackingRegion *region, LayerHitMapCache *)
virtual unsigned int size() const
ImplIntermediateHitTriplets(const SeedingLayerSetsHits *layers)
def move(src, dest)
Definition: eostools.py:510
ImplGeneratorBase(const edm::ParameterSet &iConfig, edm::ConsumesCollector &iC)
const SeedingLayerSetsHits & seedingLayerHits() const
void reserve(size_t regionsSize, size_t localRAupper)