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 #include <numeric>
21 
22 namespace hitTripletEDProducerT { class ImplBase; }
23 
24 template <typename T_HitTripletGenerator>
26 public:
28  ~HitTripletEDProducerT() override = default;
29 
30  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
31 
32  void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
33 
34 private:
36 
37  std::unique_ptr<hitTripletEDProducerT::ImplBase> impl_;
38 };
39 
40 namespace hitTripletEDProducerT {
41  class ImplBase {
42  public:
43  ImplBase() = default;
44  virtual ~ImplBase() = default;
45 
46  virtual void produces(edm::ProducerBase& producer) const = 0;
47  virtual void produce(const IntermediateHitDoublets& regionDoublets,
48  edm::Event& iEvent, const edm::EventSetup& iSetup) = 0;
49 
50  protected:
52  };
53 
55  template <typename T_HitTripletGenerator>
56  class ImplGeneratorBase: public ImplBase {
57  public:
59  generator_(iConfig, iC)
60  {}
61  ~ImplGeneratorBase() override = default;
62 
63  protected:
64  T_HitTripletGenerator generator_;
65  };
66 
68  template <typename T_HitTripletGenerator,
69  typename T_SeedingHitSets, typename T_IntermediateHitTriplets>
70  class Impl: public ImplGeneratorBase<T_HitTripletGenerator> {
71  public:
73  ImplGeneratorBase<T_HitTripletGenerator>(iConfig, iC) {}
74  ~Impl() override = default;
75 
76  void produces(edm::ProducerBase& producer) const override {
77  T_SeedingHitSets::produces(producer);
78  T_IntermediateHitTriplets::produces(producer);
79  };
80 
81  void produce(const IntermediateHitDoublets& regionDoublets,
82  edm::Event& iEvent, const edm::EventSetup& iSetup) override {
83  const SeedingLayerSetsHits& seedingLayerHits = regionDoublets.seedingLayerHits();
84 
85  auto seedingHitSetsProducer = T_SeedingHitSets();
86  auto intermediateHitTripletsProducer = T_IntermediateHitTriplets(&seedingLayerHits);
87 
88  if(regionDoublets.empty()) {
89  seedingHitSetsProducer.putEmpty(iEvent);
90  intermediateHitTripletsProducer.putEmpty(iEvent);
91  return;
92  }
93 
94  seedingHitSetsProducer.reserve(regionDoublets.regionSize(), this->localRA_.upper());
95  intermediateHitTripletsProducer.reserve(regionDoublets.regionSize(), this->localRA_.upper());
96 
97  // match-making of pair and triplet layers
98  std::vector<LayerTriplets::LayerSetAndLayers> trilayers = LayerTriplets::layers(seedingLayerHits);
99 
100  OrderedHitTriplets triplets;
101  triplets.reserve(this->localRA_.upper());
102  size_t triplets_total = 0;
103 
104  LogDebug("HitTripletEDProducer") << "Creating triplets for " << regionDoublets.regionSize() << " regions, and " << trilayers.size() << " pair+3rd layers from " << regionDoublets.layerPairsSize() << " layer pairs";
105 
106  for(const auto& regionLayerPairs: regionDoublets) {
107  const TrackingRegion& region = regionLayerPairs.region();
108 
109  auto hitCachePtr_filler_shs = seedingHitSetsProducer.beginRegion(&region, nullptr);
110  auto hitCachePtr_filler_iht = intermediateHitTripletsProducer.beginRegion(&region, std::get<0>(hitCachePtr_filler_shs));
111  auto hitCachePtr = std::get<0>(hitCachePtr_filler_iht);
112 
113  LayerHitMapCache& hitCache = *hitCachePtr;
114  hitCache.extend(regionLayerPairs.layerHitMapCache());
115 
116  LogTrace("HitTripletEDProducer") << " starting region";
117 
118  for(const auto& layerPair: regionLayerPairs) {
119  LogTrace("HitTripletEDProducer") << " starting layer pair " << layerPair.innerLayerIndex() << "," << layerPair.outerLayerIndex();
120 
121  auto found = std::find_if(trilayers.begin(), trilayers.end(), [&](const LayerTriplets::LayerSetAndLayers& a) {
122  return a.first[0].index() == layerPair.innerLayerIndex() && a.first[1].index() == layerPair.outerLayerIndex();
123  });
124  if(found == trilayers.end()) {
125  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";
126  exp << "I was looking for layer pair " << layerPair.innerLayerIndex() << "," << layerPair.outerLayerIndex() << ". Triplets have the following pairs:\n";
127  for(const auto& a: trilayers) {
128  exp << " " << a.first[0].index() << "," << a.first[1].index() << ": 3rd layers";
129  for(const auto& b: a.second) {
130  exp << " " << b.index();
131  }
132  exp << "\n";
133  }
134  throw exp;
135  }
136  const auto& thirdLayers = found->second;
137 
138  this->generator_.hitTriplets(region, triplets, iEvent, iSetup, layerPair.doublets(), thirdLayers,
139  intermediateHitTripletsProducer.tripletLastLayerIndexVector(), hitCache);
140 
141 #ifdef EDM_ML_DEBUG
142  LogTrace("HitTripletEDProducer") << " created " << triplets.size() << " triplets for layer pair " << layerPair.innerLayerIndex() << "," << layerPair.outerLayerIndex() << " and 3rd layers";
143  for(const auto& l: thirdLayers) {
144  LogTrace("HitTripletEDProducer") << " " << l.index();
145  }
146 #endif
147 
148  triplets_total += triplets.size();
149  seedingHitSetsProducer.fill(std::get<1>(hitCachePtr_filler_shs), triplets);
150  intermediateHitTripletsProducer.fill(std::get<1>(hitCachePtr_filler_iht), layerPair.layerPair(), thirdLayers, triplets);
151 
152  triplets.clear();
153  }
154  }
155  this->localRA_.update(triplets_total);
156 
157  seedingHitSetsProducer.put(iEvent);
158  intermediateHitTripletsProducer.put(iEvent);
159  }
160  };
161 
162 
164  class DoNothing {
165  public:
168 
169  static void produces(edm::ProducerBase&) {}
170 
171  void reserve(size_t, size_t) {}
172 
174  return std::make_tuple(ptr, 0);
175  }
176 
177  std::vector<int> *tripletLastLayerIndexVector() {
178  return nullptr;
179  }
180 
181  void fill(int, const OrderedHitTriplets&) {}
183  const std::vector<SeedingLayerSetsHits::SeedingLayer>&,
184  const OrderedHitTriplets&) {}
185 
186 
189  };
190 
193  public:
195  seedingHitSets_(std::make_unique<RegionsSeedingHitSets>())
196  {}
197 
199  producer.produces<RegionsSeedingHitSets>();
200  }
201 
202  void reserve(size_t regionsSize, size_t localRAupper) {
203  seedingHitSets_->reserve(regionsSize, localRAupper);
204  }
205 
206  auto beginRegion(const TrackingRegion *region, LayerHitMapCache *ptr) {
207  hitCacheTmp_.clear();
208  return std::make_tuple(&hitCacheTmp_, seedingHitSets_->beginRegion(region));
209  }
210 
212  for(const auto& trpl: triplets) {
213  filler.emplace_back(trpl.inner(), trpl.middle(), trpl.outer());
214  }
215  }
216 
218  seedingHitSets_->shrink_to_fit();
219  putEmpty(iEvent);
220  }
222  iEvent.put(std::move(seedingHitSets_));
223  }
224 
225  private:
226  std::unique_ptr<RegionsSeedingHitSets> seedingHitSets_;
227  LayerHitMapCache hitCacheTmp_; // used if !produceIntermediateHitDoublets
228  };
229 
232  public:
234  intermediateHitTriplets_(std::make_unique<IntermediateHitTriplets>(layers)),
235  layers_(layers)
236  {}
237 
239  producer.produces<IntermediateHitTriplets>();
240  }
241 
242  void reserve(size_t regionsSize, size_t localRAupper) {
243  intermediateHitTriplets_->reserve(regionsSize, layers_->size(), localRAupper);
244  tripletLastLayerIndex_.reserve(localRAupper);
245  }
246 
247  auto beginRegion(const TrackingRegion *region, LayerHitMapCache *) {
248  auto filler = intermediateHitTriplets_->beginRegion(region);
249  return std::make_tuple(&(filler.layerHitMapCache()), std::move(filler));
250  }
251 
252  std::vector<int> *tripletLastLayerIndexVector() {
253  return &tripletLastLayerIndex_;
254  }
255 
257  const IntermediateHitTriplets::LayerPair& layerPair,
258  const std::vector<SeedingLayerSetsHits::SeedingLayer>& thirdLayers,
259  const OrderedHitTriplets& triplets) {
260  if(tripletLastLayerIndex_.size() != triplets.size()) {
261  throw cms::Exception("LogicError") << "tripletLastLayerIndex_.size() " << tripletLastLayerIndex_.size()
262  << " triplets.size() " << triplets.size();
263  }
264  tripletPermutation_.resize(tripletLastLayerIndex_.size());
265  std::iota(tripletPermutation_.begin(), tripletPermutation_.end(), 0); // assign 0,1,2,...,N
266  std::stable_sort(tripletPermutation_.begin(), tripletPermutation_.end(), [&](size_t i, size_t j) {
267  return tripletLastLayerIndex_[i] < tripletLastLayerIndex_[j];
268  });
269 
270  // empty triplets need to propagate here
271  filler.addTriplets(layerPair, thirdLayers, triplets, tripletLastLayerIndex_, tripletPermutation_);
272  tripletLastLayerIndex_.clear();
273  }
274 
276  intermediateHitTriplets_->shrink_to_fit();
277  putEmpty(iEvent);
278  }
280  iEvent.put(std::move(intermediateHitTriplets_));
281  }
282 
283  private:
284  std::unique_ptr<IntermediateHitTriplets> intermediateHitTriplets_;
286  std::vector<size_t> tripletPermutation_;
287  std::vector<int> tripletLastLayerIndex_;
288  };
289 }
290 
291 
292 
293 template <typename T_HitTripletGenerator>
295  doubletToken_(consumes<IntermediateHitDoublets>(iConfig.getParameter<edm::InputTag>("doublets")))
296 {
297  const bool produceSeedingHitSets = iConfig.getParameter<bool>("produceSeedingHitSets");
298  const bool produceIntermediateHitTriplets = iConfig.getParameter<bool>("produceIntermediateHitTriplets");
299 
300  auto iC = consumesCollector();
301 
302  using namespace hitTripletEDProducerT;
303 
304  if(produceSeedingHitSets && produceIntermediateHitTriplets)
305  impl_ = std::make_unique<Impl<T_HitTripletGenerator, ImplSeedingHitSets, ImplIntermediateHitTriplets>>(iConfig, iC);
306  else if(produceSeedingHitSets)
307  impl_ = std::make_unique<Impl<T_HitTripletGenerator, ImplSeedingHitSets, DoNothing>>(iConfig, iC);
308  else if(produceIntermediateHitTriplets)
309  impl_ = std::make_unique<Impl<T_HitTripletGenerator, DoNothing, ImplIntermediateHitTriplets>>(iConfig, iC);
310  else
311  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";
312 
313  impl_->produces(*this);
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") << "HitTripletEDProducerT expects SeedingLayerSetsHits::numberOfLayersInSet() to be >= 3, got " << seedingLayerHits.numberOfLayersInSet() << ". This is likely caused by a configuration error of this module, HitPairEDProducer, or SeedingLayersEDProducer.";
339  }
340 
341  impl_->produce(regionDoublets, iEvent, iSetup);
342 }
343 
344 
345 #endif
#define LogDebug(id)
BranchAliasSetterT< ProductType > produces()
declare what type of product will make and with which optional label
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)
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:137
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:579
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
void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
std::unique_ptr< RegionsSeedingHitSets > seedingHitSets_
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)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
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)
unsigned int size() const override
#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 *)
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)