37 std::unique_ptr<::ImplBase>
impl_;
44 virtual ~ImplBase() =
default;
52 const unsigned int maxElement_;
53 const unsigned int maxElementTotal_;
56 std::vector<unsigned> layerPairBegins_;
59 : maxElement_(iConfig.getParameter<unsigned
int>(
"maxElement")),
60 maxElementTotal_(iConfig.getParameter<unsigned
int>(
"maxElementTotal")),
61 generator_(0, 1, nullptr, maxElement_),
62 layerPairBegins_(iConfig.getParameter<
std::
vector<unsigned>>(
"layerPairs")) {
63 if (layerPairBegins_.empty())
65 <<
"HitPairEDProducer requires at least index for layer pairs (layerPairs parameter), none was given";
69 template <
typename T_SeedingHitSets,
typename T_IntermediateHitDoublets,
typename T_RegionLayers>
70 class Impl :
public ImplBase {
72 template <
typename... Args>
74 : ImplBase(iConfig), regionsLayers_(&layerPairBegins_,
std::forward<Args>(
args)...) {}
75 ~
Impl()
override =
default;
78 T_SeedingHitSets::produces(producesCollector);
79 T_IntermediateHitDoublets::produces(producesCollector);
83 auto regionsLayers = regionsLayers_.beginEvent(
iEvent);
85 auto seedingHitSetsProducer = T_SeedingHitSets(&localRA_);
86 auto intermediateHitDoubletsProducer = T_IntermediateHitDoublets(regionsLayers.seedingLayerSetsHitsPtr());
88 if (!clusterCheckOk) {
89 seedingHitSetsProducer.putEmpty(
iEvent);
90 intermediateHitDoubletsProducer.putEmpty(
iEvent);
94 seedingHitSetsProducer.reserve(regionsLayers.regionsSize());
95 intermediateHitDoubletsProducer.reserve(regionsLayers.regionsSize());
97 unsigned int nDoublets = 0;
99 for (
const auto& regionLayers : regionsLayers) {
101 auto hitCachePtr_filler_shs = seedingHitSetsProducer.beginRegion(&
region,
nullptr);
102 auto hitCachePtr_filler_ihd =
103 intermediateHitDoubletsProducer.beginRegion(&
region, std::get<0>(hitCachePtr_filler_shs));
104 auto hitCachePtr = std::get<0>(hitCachePtr_filler_ihd);
108 LogTrace(
"HitPairEDProducer") <<
" created " <<
doublets.size() <<
" doublets for layers "
109 << layerSet[0].index() <<
"," << layerSet[1].index();
113 if (nDoublets >= maxElementTotal_) {
114 edm::LogError(
"TooManyPairs") <<
"number of total pairs exceed maximum, no pairs produced";
115 auto seedingHitSetsProducerDummy = T_SeedingHitSets(&localRA_);
116 auto intermediateHitDoubletsProducerDummy =
117 T_IntermediateHitDoublets(regionsLayers.seedingLayerSetsHitsPtr());
118 seedingHitSetsProducerDummy.putEmpty(
iEvent);
119 intermediateHitDoubletsProducerDummy.putEmpty(
iEvent);
122 seedingHitSetsProducer.fill(std::get<1>(hitCachePtr_filler_shs),
doublets);
123 intermediateHitDoubletsProducer.fill(std::get<1>(hitCachePtr_filler_ihd), layerSet,
std::move(
doublets));
127 seedingHitSetsProducer.put(
iEvent);
128 intermediateHitDoubletsProducer.put(
iEvent);
132 T_RegionLayers regionsLayers_;
143 void reserve(
size_t) {}
155 class ImplSeedingHitSets {
164 void reserve(
size_t regionsSize) { seedingHitSets_->
reserve(regionsSize, localRA_->upper()); }
167 hitCacheTmp_.clear();
168 return std::make_tuple(&hitCacheTmp_, seedingHitSets_->beginRegion(
region));
178 seedingHitSets_->shrink_to_fit();
179 localRA_->update(seedingHitSets_->size());
186 std::unique_ptr<RegionsSeedingHitSets> seedingHitSets_;
192 class ImplIntermediateHitDoublets {
201 void reserve(
size_t regionsSize) { intermediateHitDoublets_->
reserve(regionsSize, layers_->size()); }
204 auto filler = intermediateHitDoublets_->beginRegion(
region);
205 return std::make_tuple(&(
filler.layerHitMapCache()),
filler);
215 intermediateHitDoublets_->shrink_to_fit();
222 std::unique_ptr<IntermediateHitDoublets> intermediateHitDoublets_;
228 class RegionsLayersSeparate {
236 const std::vector<SeedingLayerSetsHits::SeedingLayerSet>&
layerPairs()
const {
return *layerPairs_; }
240 const std::vector<SeedingLayerSetsHits::SeedingLayerSet>* layerPairs_;
245 class const_iterator {
251 const_iterator(internal_iterator_type iter,
252 const std::vector<SeedingLayerSetsHits::SeedingLayerSet>*
layerPairs)
257 const_iterator& operator++() {
261 const_iterator operator++(
int) {
262 const_iterator
clone(*
this);
271 internal_iterator_type iter_;
272 const std::vector<SeedingLayerSetsHits::SeedingLayerSet>* layerPairs_;
277 const std::vector<unsigned>& layerPairBegins)
278 : seedingLayerSetsHits_(seedingLayerSetsHits), regions_(
regions) {
280 if (seedingLayerSetsHits_->numberOfLayersInSet() > 2) {
281 for (
const auto& layerSet : *seedingLayerSetsHits_) {
282 for (
const auto pairBeginIndex : layerPairBegins) {
285 <<
"Layer pair index " << pairBeginIndex
286 <<
" is out of bounds, input SeedingLayerSetsHits has only "
288 <<
" layers per set, and the index+1 must be < than the number of layers in set";
297 auto found = std::find_if(
299 return pair[0].index() == pairCandidate[0].index() && pair[1].index() == pairCandidate[1].index();
308 if (layerPairBegins.size() != 1) {
310 <<
"With pairs of input layers, it doesn't make sense to specify more than one input layer pair, got "
311 << layerPairBegins.size();
313 if (layerPairBegins[0] != 0) {
315 <<
"With pairs of input layers, it doesn't make sense to specify other input layer pair than 0; got "
316 << layerPairBegins[0];
320 for (
const auto& set : *seedingLayerSetsHits)
327 size_t regionsSize()
const {
return regions_->
size(); }
329 const_iterator begin()
const {
return const_iterator(regions_->begin(), &
layerPairs); }
330 const_iterator cbegin()
const {
return begin(); }
331 const_iterator
end()
const {
return const_iterator(regions_->end(), &
layerPairs); }
332 const_iterator cend()
const {
return end(); }
337 std::vector<SeedingLayerSetsHits::SeedingLayerSet>
layerPairs;
340 RegionsLayersSeparate(
const std::vector<unsigned>* layerPairBegins,
344 : layerPairBegins_(layerPairBegins),
350 iEvent.getByToken(seedingLayerToken_, hlayers);
352 if (
layers->numberOfLayersInSet() < 2)
354 <<
"HitPairEDProducer expects SeedingLayerSetsHits::numberOfLayersInSet() to be >= 2, got "
355 <<
layers->numberOfLayersInSet()
356 <<
". This is likely caused by a configuration error of this module, or SeedingLayersEDProducer.";
358 iEvent.getByToken(regionToken_, hregions);
360 return EventTmp(
layers, hregions.
product(), *layerPairBegins_);
364 const std::vector<unsigned>* layerPairBegins_;
372 class RegionsLayersTogether {
381 <<
"With trackingRegionsSeedingLayers input, the seeding layer sets may only contain layer pairs, now "
387 const SeedingLayerSetsHits* seedingLayerSetsHitsPtr()
const {
return &(regionsLayers_->seedingLayerSetsHits()); }
389 size_t regionsSize()
const {
return regionsLayers_->regionsSize(); }
391 const_iterator begin()
const {
return regionsLayers_->
begin(); }
392 const_iterator cbegin()
const {
return begin(); }
393 const_iterator
end()
const {
return regionsLayers_->end(); }
394 const_iterator cend()
const {
return end(); }
400 RegionsLayersTogether(
const std::vector<unsigned>* layerPairBegins,
404 if (layerPairBegins->size() != 1) {
405 throw cms::Exception(
"LogicError") <<
"With trackingRegionsSeedingLayers mode, it doesn't make sense to "
406 "specify more than one input layer pair, got "
407 << layerPairBegins->size();
409 if ((*layerPairBegins)[0] != 0) {
410 throw cms::Exception(
"LogicError") <<
"With trackingRegionsSeedingLayers mode, it doesn't make sense to "
411 "specify other input layer pair than 0; got "
412 << (*layerPairBegins)[0];
418 iEvent.getByToken(regionLayerToken_, hregions);
419 return EventTmp(hregions.
product());
431 const bool useRegionLayers = !regionLayerTag.
label().empty();
432 if (useRegionLayers) {
435 <<
"HitPairEDProducer requires either trackingRegions or trackingRegionsSeedingLayers to be set, now both "
436 "are set to non-empty value. Set the unneeded parameter to empty value.";
438 if (!layersTag.label().empty()) {
440 <<
"With non-empty trackingRegionsSeedingLayers, please set also seedingLayers to empty value to reduce "
441 "confusion, because the parameter is not used";
444 if (
regionTag.label().empty() && regionLayerTag.
label().empty()) {
446 <<
"HitPairEDProducer requires either trackingRegions or trackingRegionsSeedingLayers to be set, now both are "
447 "set to empty value. Set the needed parameter to a non-empty value.";
456 <<
"Mode 'trackingRegionsSeedingLayers' makes sense only with 'produceSeedingHitsSets', now also "
457 "'produceIntermediateHitDoublets is active";
458 impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::ImplIntermediateHitDoublets, ::RegionsLayersSeparate>>(
459 iConfig, layersTag,
regionTag, consumesCollector());
461 if (useRegionLayers) {
462 impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::DoNothing, ::RegionsLayersTogether>>(
463 iConfig, regionLayerTag, consumesCollector());
465 impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::DoNothing, ::RegionsLayersSeparate>>(
466 iConfig, layersTag,
regionTag, consumesCollector());
471 <<
"Mode 'trackingRegionsSeedingLayers' makes sense only with 'produceSeedingHitsSets', now "
472 "'produceIntermediateHitDoublets is active instead";
473 impl_ = std::make_unique<::Impl<::DoNothing, ::ImplIntermediateHitDoublets, ::RegionsLayersSeparate>>(
474 iConfig, layersTag,
regionTag, consumesCollector());
477 <<
"HitPairEDProducer requires either produceIntermediateHitDoublets or produceSeedingHitSets to be True. If "
478 "neither are needed, just remove this module from your sequence/path as it doesn't do anything useful";
481 if (!clusterCheckTag.label().empty())
484 impl_->produces(producesCollector());
491 ->setComment(
"Set this empty if 'trackingRegionsSeedingLayers' is non-empty");
494 "Input tracking regions when using all layer sets in 'seedingLayers' (conflicts with "
495 "'trackingRegionsSeedingLayers', set this empty to use the other)");
498 "Input tracking regions and corresponding layer sets in case of dynamically limiting the seeding layers "
499 "(conflicts with 'trackingRegions', set this empty to use the other; if using this set also 'seedingLayers' "
502 desc.add<
bool>(
"produceSeedingHitSets",
false);
503 desc.add<
bool>(
"produceIntermediateHitDoublets",
false);
504 desc.add<
unsigned int>(
"maxElement", 1000000);
505 desc.add<
unsigned int>(
"maxElementTotal", 50000000);
506 desc.add<std::vector<unsigned>>(
"layerPairs", std::vector<unsigned>{0})
507 ->setComment(
"Indices to the pairs of consecutive layers, i.e. 0 means (0,1), 1 (1,2) etc.");
509 descriptions.
add(
"hitPairEDProducerDefault",
desc);
513 bool clusterCheckOk =
true;
517 clusterCheckOk = *hclusterCheck;