CMS 3D CMS Logo

HitPairEDProducer.cc
Go to the documentation of this file.
9 
17 
18 namespace { class ImplBase; }
19 
21 public:
22  HitPairEDProducer(const edm::ParameterSet& iConfig);
23  ~HitPairEDProducer() override = default;
24 
25  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
26 
27  void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
28 
29 private:
33 
34  std::unique_ptr<::ImplBase> impl_;
35 };
36 
37 namespace {
38  class ImplBase {
39  public:
40  ImplBase(const edm::ParameterSet& iConfig);
41  virtual ~ImplBase() = default;
42 
43  virtual void produces(edm::ProducerBase& producer) const = 0;
44 
45  virtual void produce(const SeedingLayerSetsHits& layers, const edm::OwnVector<TrackingRegion>& regions, const bool clusterCheckOk,
46  edm::Event& iEvent, const edm::EventSetup& iSetup) = 0;
47 
48  protected:
49  void makeLayerPairs(const SeedingLayerSetsHits& layers, std::vector<SeedingLayerSetsHits::SeedingLayerSet>& layerPairs);
50 
51  edm::RunningAverage localRA_;
52  const unsigned int maxElement_;
53 
55  std::vector<unsigned> layerPairBegins_;
56  };
57  ImplBase::ImplBase(const edm::ParameterSet& iConfig):
58  maxElement_(iConfig.getParameter<unsigned int>("maxElement")),
59  generator_(0, 1, nullptr, maxElement_), // these indices are dummy, TODO: cleanup HitPairGeneratorFromLayerPair
60  layerPairBegins_(iConfig.getParameter<std::vector<unsigned> >("layerPairs"))
61  {
62  if(layerPairBegins_.empty())
63  throw cms::Exception("Configuration") << "HitPairEDProducer requires at least index for layer pairs (layerPairs parameter), none was given";
64  }
65  void ImplBase::makeLayerPairs(const SeedingLayerSetsHits& layers, std::vector<SeedingLayerSetsHits::SeedingLayerSet>& layerPairs) {
66  if(layers.numberOfLayersInSet() > 2) {
67  for(const auto& layerSet: layers) {
68  for(const auto pairBeginIndex: layerPairBegins_) {
69  if(pairBeginIndex+1 >= layers.numberOfLayersInSet()) {
70  throw cms::Exception("LogicError") << "Layer pair index " << pairBeginIndex << " is out of bounds, input SeedingLayerSetsHits has only " << layers.numberOfLayersInSet() << " layers per set, and the index+1 must be < than the number of layers in set";
71  }
72 
73  // Take only the requested pair of the set
74  SeedingLayerSetsHits::SeedingLayerSet pairCandidate = layerSet.slice(pairBeginIndex, pairBeginIndex+1);
75 
76  // it would be trivial to use 128-bit bitfield for O(1) check
77  // if a layer pair has been inserted, but let's test first how
78  // a "straightforward" solution works
79  auto found = std::find_if(layerPairs.begin(), layerPairs.end(), [&](const SeedingLayerSetsHits::SeedingLayerSet& pair) {
80  return pair[0].index() == pairCandidate[0].index() && pair[1].index() == pairCandidate[1].index();
81  });
82  if(found != layerPairs.end())
83  continue;
84 
85  layerPairs.push_back(pairCandidate);
86  }
87  }
88  }
89  else {
90  if(layerPairBegins_.size() != 1) {
91  throw cms::Exception("LogicError") << "With pairs of input layers, it doesn't make sense to specify more than one input layer pair, got " << layerPairBegins_.size();
92  }
93  if(layerPairBegins_[0] != 0) {
94  throw cms::Exception("LogicError") << "With pairs of input layers, it doesn't make sense to specify other input layer pair than 0; got " << layerPairBegins_[0];
95  }
96 
97  layerPairs.reserve(layers.size());
98  for(const auto& set: layers)
99  layerPairs.push_back(set);
100  }
101  }
102 
103 
105  template <typename T_SeedingHitSets, typename T_IntermediateHitDoublets>
106  struct Impl: public ImplBase {
107  Impl(const edm::ParameterSet& iConfig): ImplBase(iConfig) {}
108  ~Impl() override = default;
109 
110  void produces(edm::ProducerBase& producer) const override {
111  T_SeedingHitSets::produces(producer);
112  T_IntermediateHitDoublets::produces(producer);
113  }
114 
115  void produce(const SeedingLayerSetsHits& layers, const edm::OwnVector<TrackingRegion>& regions, const bool clusterCheckOk,
116  edm::Event& iEvent, const edm::EventSetup& iSetup) override {
117  auto seedingHitSetsProducer = T_SeedingHitSets(&localRA_);
118  auto intermediateHitDoubletsProducer = T_IntermediateHitDoublets(&layers);
119 
120  if(!clusterCheckOk) {
121  seedingHitSetsProducer.putEmpty(iEvent);
122  intermediateHitDoubletsProducer.putEmpty(iEvent);
123  return;
124  }
125 
126  seedingHitSetsProducer.reserve(regions.size());
127  intermediateHitDoubletsProducer.reserve(regions.size());
128 
129  std::vector<SeedingLayerSetsHits::SeedingLayerSet> layerPairs;
130  makeLayerPairs(layers, layerPairs);
131 
132  for(const TrackingRegion& region: regions) {
133  auto hitCachePtr_filler_shs = seedingHitSetsProducer.beginRegion(&region, nullptr);
134  auto hitCachePtr_filler_ihd = intermediateHitDoubletsProducer.beginRegion(&region, std::get<0>(hitCachePtr_filler_shs));
135  auto hitCachePtr = std::get<0>(hitCachePtr_filler_ihd);
136 
137  for(SeedingLayerSetsHits::SeedingLayerSet layerSet: layerPairs) {
138  auto doublets = generator_.doublets(region, iEvent, iSetup, layerSet, *hitCachePtr);
139  LogTrace("HitPairEDProducer") << " created " << doublets.size() << " doublets for layers " << layerSet[0].index() << "," << layerSet[1].index();
140  if(doublets.empty()) continue; // don't bother if no pairs from these layers
141  seedingHitSetsProducer.fill(std::get<1>(hitCachePtr_filler_shs), doublets);
142  intermediateHitDoubletsProducer.fill(std::get<1>(hitCachePtr_filler_ihd), layerSet, std::move(doublets));
143  }
144  }
145 
146  seedingHitSetsProducer.put(iEvent);
147  intermediateHitDoubletsProducer.put(iEvent);
148  }
149  };
150 
152  class DoNothing {
153  public:
154  DoNothing(const SeedingLayerSetsHits *) {}
155  DoNothing(edm::RunningAverage *) {}
156 
157  static void produces(edm::ProducerBase&) {};
158 
159  void reserve(size_t) {}
160 
161  auto beginRegion(const TrackingRegion *, LayerHitMapCache *ptr) {
162  return std::make_tuple(ptr, 0);
163  }
164 
165  void fill(int, const HitDoublets&) {}
167 
168  void put(edm::Event&) {}
169  void putEmpty(edm::Event&) {}
170  };
171 
173  class ImplSeedingHitSets {
174  public:
175  ImplSeedingHitSets(edm::RunningAverage *localRA):
176  seedingHitSets_(std::make_unique<RegionsSeedingHitSets>()),
177  localRA_(localRA)
178  {}
179 
180  static void produces(edm::ProducerBase& producer) {
181  producer.produces<RegionsSeedingHitSets>();
182  }
183 
184  void reserve(size_t regionsSize) {
185  seedingHitSets_->reserve(regionsSize, localRA_->upper());
186  }
187 
188  auto beginRegion(const TrackingRegion *region, LayerHitMapCache *) {
189  hitCacheTmp_.clear();
190  return std::make_tuple(&hitCacheTmp_, seedingHitSets_->beginRegion(region));
191  }
192 
194  for(size_t i=0, size=doublets.size(); i<size; ++i) {
195  filler.emplace_back(doublets.hit(i, HitDoublets::inner),
196  doublets.hit(i, HitDoublets::outer));
197  }
198  }
199 
200  void put(edm::Event& iEvent) {
201  seedingHitSets_->shrink_to_fit();
202  localRA_->update(seedingHitSets_->size());
203  putEmpty(iEvent);
204  }
205 
206  void putEmpty(edm::Event& iEvent) {
207  iEvent.put(std::move(seedingHitSets_));
208  }
209 
210  private:
211  std::unique_ptr<RegionsSeedingHitSets> seedingHitSets_;
212  edm::RunningAverage *localRA_;
213  LayerHitMapCache hitCacheTmp_; // used if !produceIntermediateHitDoublets
214  };
215 
217  class ImplIntermediateHitDoublets {
218  public:
219  ImplIntermediateHitDoublets(const SeedingLayerSetsHits *layers):
220  intermediateHitDoublets_(std::make_unique<IntermediateHitDoublets>(layers)),
221  layers_(layers)
222  {}
223 
224  static void produces(edm::ProducerBase& producer) {
225  producer.produces<IntermediateHitDoublets>();
226  }
227 
228  void reserve(size_t regionsSize) {
229  intermediateHitDoublets_->reserve(regionsSize, layers_->size());
230  }
231 
232  auto beginRegion(const TrackingRegion *region, LayerHitMapCache *) {
233  auto filler = intermediateHitDoublets_->beginRegion(region);
234  return std::make_tuple(&(filler.layerHitMapCache()), std::move(filler));
235  }
236 
238  filler.addDoublets(layerSet, std::move(doublets));
239  }
240 
241  void put(edm::Event& iEvent) {
242  intermediateHitDoublets_->shrink_to_fit();
243  putEmpty(iEvent);
244  }
245 
246  void putEmpty(edm::Event& iEvent) {
247  iEvent.put(std::move(intermediateHitDoublets_));
248  }
249 
250  private:
251  std::unique_ptr<IntermediateHitDoublets> intermediateHitDoublets_;
252  const SeedingLayerSetsHits *layers_;
253  };
254 }
255 
256 
257 
259  seedingLayerToken_(consumes<SeedingLayerSetsHits>(iConfig.getParameter<edm::InputTag>("seedingLayers"))),
260  regionToken_(consumes<edm::OwnVector<TrackingRegion> >(iConfig.getParameter<edm::InputTag>("trackingRegions")))
261 {
262  const bool produceSeedingHitSets = iConfig.getParameter<bool>("produceSeedingHitSets");
263  const bool produceIntermediateHitDoublets = iConfig.getParameter<bool>("produceIntermediateHitDoublets");
264 
265  if(produceSeedingHitSets && produceIntermediateHitDoublets)
266  impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::ImplIntermediateHitDoublets>>(iConfig);
267  else if(produceSeedingHitSets)
268  impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::DoNothing>>(iConfig);
269  else if(produceIntermediateHitDoublets)
270  impl_ = std::make_unique<::Impl<::DoNothing, ::ImplIntermediateHitDoublets>>(iConfig);
271  else
272  throw cms::Exception("Configuration") << "HitPairEDProducer requires either produceIntermediateHitDoublets or produceSeedingHitSets to be True. If neither are needed, just remove this module from your sequence/path as it doesn't do anything useful";
273 
274  auto clusterCheckTag = iConfig.getParameter<edm::InputTag>("clusterCheck");
275  if(clusterCheckTag.label() != "")
276  clusterCheckToken_ = consumes<bool>(clusterCheckTag);
277 
278  impl_->produces(*this);
279 }
280 
283 
284  desc.add<edm::InputTag>("seedingLayers", edm::InputTag("seedingLayersEDProducer"));
285  desc.add<edm::InputTag>("trackingRegions", edm::InputTag("globalTrackingRegionFromBeamSpot"));
286  desc.add<edm::InputTag>("clusterCheck", edm::InputTag("trackerClusterCheck"));
287  desc.add<bool>("produceSeedingHitSets", false);
288  desc.add<bool>("produceIntermediateHitDoublets", false);
289  desc.add<unsigned int>("maxElement", 1000000);
290  desc.add<std::vector<unsigned> >("layerPairs", std::vector<unsigned>{{0}})->setComment("Indices to the pairs of consecutive layers, i.e. 0 means (0,1), 1 (1,2) etc.");
291 
292  descriptions.add("hitPairEDProducerDefault", desc);
293 }
294 
296  bool clusterCheckOk = true;
298  edm::Handle<bool> hclusterCheck;
299  iEvent.getByToken(clusterCheckToken_, hclusterCheck);
300  clusterCheckOk = *hclusterCheck;
301  }
302 
304  iEvent.getByToken(seedingLayerToken_, hlayers);
305  const auto& layers = *hlayers;
306  if(layers.numberOfLayersInSet() < 2)
307  throw cms::Exception("LogicError") << "HitPairEDProducer expects SeedingLayerSetsHits::numberOfLayersInSet() to be >= 2, got " << layers.numberOfLayersInSet() << ". This is likely caused by a configuration error of this module, or SeedingLayersEDProducer.";
308 
310  iEvent.getByToken(regionToken_, hregions);
311 
312  impl_->produce(layers, *hregions, clusterCheckOk, iEvent, iSetup);
313 }
314 
BranchAliasSetterT< ProductType > produces()
declare what type of product will make and with which optional label
size
Write out results.
T getParameter(std::string const &) const
unsigned short numberOfLayersInSet() const
Get number of layers in each SeedingLayerSets.
std::size_t size() const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:127
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
Definition: LayerTriplets.cc:4
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:508
SeedingLayerSet slice(size_t begin, size_t end) const
std::unique_ptr<::ImplBase > impl_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
size_type size() const
Definition: OwnVector.h:264
void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
edm::EDGetTokenT< edm::OwnVector< TrackingRegion > > regionToken_
Helper class enforcing correct way of filling the doublets of a region.
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
void put(edm::Event &evt, double value, const char *instanceName)
~HitPairEDProducer() override=default
Definition: __init__.py:1
int iEvent
Definition: GenABIO.cc:230
edm::EDGetTokenT< bool > clusterCheckToken_
ParameterDescriptionBase * add(U const &iLabel, T const &value)
HitPairEDProducer(const edm::ParameterSet &iConfig)
#define LogTrace(id)
void reserve(size_t nregions, size_t nhitsets)
Helper class enforcing correct way of filling the doublets of a region.
edm::EDGetTokenT< SeedingLayerSetsHits > seedingLayerToken_
void addDoublets(const SeedingLayerSetsHits::SeedingLayerSet &layerSet, HitDoublets &&doublets)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
Hit const & hit(int i, layer l) const
HLT enums.
void reserve(size_t nregions, size_t nlayersets)
bool isUninitialized() const
Definition: EDGetToken.h:73
unsigned short size() const
Get the number of SeedingLayerSets.
def move(src, dest)
Definition: eostools.py:510