39 std::unique_ptr<::ImplBase>
impl_;
46 virtual ~ImplBase() =
default;
54 const unsigned int maxElement_;
55 const unsigned int maxElementTotal_;
56 const bool putEmptyIfMaxElementReached_;
59 std::vector<unsigned> layerPairBegins_;
62 : maxElement_(iConfig.getParameter<unsigned
int>(
"maxElement")),
63 maxElementTotal_(iConfig.getParameter<unsigned
int>(
"maxElementTotal")),
64 putEmptyIfMaxElementReached_(iConfig.getParameter<
bool>(
"putEmptyIfMaxElementReached")),
66 iC, 0, 1, nullptr, maxElement_),
67 layerPairBegins_(iConfig.getParameter<
std::
vector<unsigned>>(
"layerPairs")) {
68 if (layerPairBegins_.empty())
70 <<
"HitPairEDProducer requires at least index for layer pairs (layerPairs parameter), none was given";
74 template <
typename T_SeedingHitSets,
typename T_IntermediateHitDoublets,
typename T_RegionLayers>
75 class Impl :
public ImplBase {
77 template <
typename... Args>
79 : ImplBase(iConfig, iC), regionsLayers_(&layerPairBegins_,
std::forward<Args>(
args)..., iC) {}
80 ~
Impl()
override =
default;
83 T_SeedingHitSets::produces(producesCollector);
84 T_IntermediateHitDoublets::produces(producesCollector);
88 auto regionsLayers = regionsLayers_.beginEvent(
iEvent);
90 auto seedingHitSetsProducer = T_SeedingHitSets(&localRA_);
91 auto intermediateHitDoubletsProducer = T_IntermediateHitDoublets(regionsLayers.seedingLayerSetsHitsPtr());
93 if (!clusterCheckOk) {
94 seedingHitSetsProducer.putEmpty(
iEvent);
95 intermediateHitDoubletsProducer.putEmpty(
iEvent);
99 seedingHitSetsProducer.reserve(regionsLayers.regionsSize());
100 intermediateHitDoubletsProducer.reserve(regionsLayers.regionsSize());
102 unsigned int nDoublets = 0;
104 for (
const auto& regionLayers : regionsLayers) {
106 auto hitCachePtr_filler_shs = seedingHitSetsProducer.beginRegion(&
region,
nullptr);
107 auto hitCachePtr_filler_ihd =
108 intermediateHitDoubletsProducer.beginRegion(&
region, std::get<0>(hitCachePtr_filler_shs));
109 auto hitCachePtr = std::get<0>(hitCachePtr_filler_ihd);
112 auto doubletsOpt = generator_.doublets(
region,
iEvent, iSetup, layerSet, *hitCachePtr);
113 if (not doubletsOpt) {
114 if (putEmptyIfMaxElementReached_) {
115 putEmpty(
iEvent, regionsLayers);
122 LogTrace(
"HitPairEDProducer") <<
" created " <<
doublets.size() <<
" doublets for layers " 123 << layerSet[0].index() <<
"," << layerSet[1].index();
127 if (nDoublets >= maxElementTotal_) {
128 edm::LogError(
"TooManyPairs") <<
"number of total pairs exceed maximum, no pairs produced";
129 putEmpty(
iEvent, regionsLayers);
132 seedingHitSetsProducer.fill(std::get<1>(hitCachePtr_filler_shs),
doublets);
133 intermediateHitDoubletsProducer.fill(std::get<1>(hitCachePtr_filler_ihd), layerSet,
std::move(
doublets));
137 seedingHitSetsProducer.put(
iEvent);
138 intermediateHitDoubletsProducer.put(
iEvent);
142 template <
typename T>
144 auto seedingHitSetsProducerDummy = T_SeedingHitSets(&localRA_);
145 auto intermediateHitDoubletsProducerDummy = T_IntermediateHitDoublets(regionsLayers.seedingLayerSetsHitsPtr());
146 seedingHitSetsProducerDummy.putEmpty(
iEvent);
147 intermediateHitDoubletsProducerDummy.putEmpty(
iEvent);
150 T_RegionLayers regionsLayers_;
161 void reserve(
size_t) {}
173 class ImplSeedingHitSets {
182 void reserve(
size_t regionsSize) { seedingHitSets_->
reserve(regionsSize, localRA_->upper()); }
185 hitCacheTmp_.clear();
186 return std::make_tuple(&hitCacheTmp_, seedingHitSets_->beginRegion(
region));
196 seedingHitSets_->shrink_to_fit();
197 localRA_->update(seedingHitSets_->size());
204 std::unique_ptr<RegionsSeedingHitSets> seedingHitSets_;
210 class ImplIntermediateHitDoublets {
219 void reserve(
size_t regionsSize) { intermediateHitDoublets_->
reserve(regionsSize, layers_->size()); }
222 auto filler = intermediateHitDoublets_->beginRegion(
region);
223 return std::make_tuple(&(
filler.layerHitMapCache()),
filler);
233 intermediateHitDoublets_->shrink_to_fit();
240 std::unique_ptr<IntermediateHitDoublets> intermediateHitDoublets_;
246 class RegionsLayersSeparate {
254 const std::vector<SeedingLayerSetsHits::SeedingLayerSet>&
layerPairs()
const {
return *layerPairs_; }
258 const std::vector<SeedingLayerSetsHits::SeedingLayerSet>* layerPairs_;
263 class const_iterator {
265 using internal_iterator_type = std::vector<std::unique_ptr<TrackingRegion>>::const_iterator;
267 using difference_type = internal_iterator_type::difference_type;
269 const_iterator(internal_iterator_type iter,
270 const std::vector<SeedingLayerSetsHits::SeedingLayerSet>*
layerPairs)
280 const_iterator
clone(*
this);
289 internal_iterator_type iter_;
290 const std::vector<SeedingLayerSetsHits::SeedingLayerSet>* layerPairs_;
295 const std::vector<unsigned>& layerPairBegins)
296 : seedingLayerSetsHits_(seedingLayerSetsHits), regions_(
regions) {
298 if (seedingLayerSetsHits_->numberOfLayersInSet() > 2) {
299 for (
const auto& layerSet : *seedingLayerSetsHits_) {
300 for (
const auto pairBeginIndex : layerPairBegins) {
303 <<
"Layer pair index " << pairBeginIndex
304 <<
" is out of bounds, input SeedingLayerSetsHits has only " 306 <<
" layers per set, and the index+1 must be < than the number of layers in set";
315 auto found = std::find_if(
317 return pair[0].index() == pairCandidate[0].index() && pair[1].index() == pairCandidate[1].index();
326 if (layerPairBegins.size() != 1) {
328 <<
"With pairs of input layers, it doesn't make sense to specify more than one input layer pair, got " 329 << layerPairBegins.size();
331 if (layerPairBegins[0] != 0) {
333 <<
"With pairs of input layers, it doesn't make sense to specify other input layer pair than 0; got " 334 << layerPairBegins[0];
338 for (
const auto&
set : *seedingLayerSetsHits)
345 size_t regionsSize()
const {
return regions_->
size(); }
347 const_iterator
begin()
const {
return const_iterator(regions_->begin(), &
layerPairs); }
348 const_iterator cbegin()
const {
return begin(); }
349 const_iterator
end()
const {
return const_iterator(regions_->end(), &
layerPairs); }
350 const_iterator cend()
const {
return end(); }
354 const std::vector<std::unique_ptr<TrackingRegion>>* regions_;
355 std::vector<SeedingLayerSetsHits::SeedingLayerSet>
layerPairs;
358 RegionsLayersSeparate(
const std::vector<unsigned>* layerPairBegins,
362 : layerPairBegins_(layerPairBegins),
368 iEvent.getByToken(seedingLayerToken_, hlayers);
370 if (
layers->numberOfLayersInSet() < 2)
372 <<
"HitPairEDProducer expects SeedingLayerSetsHits::numberOfLayersInSet() to be >= 2, got " 373 <<
layers->numberOfLayersInSet()
374 <<
". This is likely caused by a configuration error of this module, or SeedingLayersEDProducer.";
380 const std::vector<unsigned>* layerPairBegins_;
388 class RegionsLayersTogether {
397 <<
"With trackingRegionsSeedingLayers input, the seeding layer sets may only contain layer pairs, now " 403 const SeedingLayerSetsHits* seedingLayerSetsHitsPtr()
const {
return &(regionsLayers_->seedingLayerSetsHits()); }
405 size_t regionsSize()
const {
return regionsLayers_->regionsSize(); }
407 const_iterator
begin()
const {
return regionsLayers_->begin(); }
408 const_iterator cbegin()
const {
return begin(); }
409 const_iterator
end()
const {
return regionsLayers_->end(); }
410 const_iterator cend()
const {
return end(); }
416 RegionsLayersTogether(
const std::vector<unsigned>* layerPairBegins,
420 if (layerPairBegins->size() != 1) {
421 throw cms::Exception(
"LogicError") <<
"With trackingRegionsSeedingLayers mode, it doesn't make sense to " 422 "specify more than one input layer pair, got " 423 << layerPairBegins->size();
425 if ((*layerPairBegins)[0] != 0) {
426 throw cms::Exception(
"LogicError") <<
"With trackingRegionsSeedingLayers mode, it doesn't make sense to " 427 "specify other input layer pair than 0; got " 428 << (*layerPairBegins)[0];
434 iEvent.getByToken(regionLayerToken_, hregions);
435 return EventTmp(hregions.
product());
447 const bool useRegionLayers = !regionLayerTag.
label().empty();
448 if (useRegionLayers) {
451 <<
"HitPairEDProducer requires either trackingRegions or trackingRegionsSeedingLayers to be set, now both " 452 "are set to non-empty value. Set the unneeded parameter to empty value.";
454 if (!layersTag.label().empty()) {
456 <<
"With non-empty trackingRegionsSeedingLayers, please set also seedingLayers to empty value to reduce " 457 "confusion, because the parameter is not used";
460 if (
regionTag.label().empty() && regionLayerTag.
label().empty()) {
462 <<
"HitPairEDProducer requires either trackingRegions or trackingRegionsSeedingLayers to be set, now both are " 463 "set to empty value. Set the needed parameter to a non-empty value.";
472 <<
"Mode 'trackingRegionsSeedingLayers' makes sense only with 'produceSeedingHitsSets', now also " 473 "'produceIntermediateHitDoublets is active";
474 impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::ImplIntermediateHitDoublets, ::RegionsLayersSeparate>>(
475 iConfig, consumesCollector(), layersTag,
regionTag);
477 if (useRegionLayers) {
478 impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::DoNothing, ::RegionsLayersTogether>>(
479 iConfig, consumesCollector(), regionLayerTag);
481 impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::DoNothing, ::RegionsLayersSeparate>>(
482 iConfig, consumesCollector(), layersTag,
regionTag);
487 <<
"Mode 'trackingRegionsSeedingLayers' makes sense only with 'produceSeedingHitsSets', now " 488 "'produceIntermediateHitDoublets is active instead";
489 impl_ = std::make_unique<::Impl<::DoNothing, ::ImplIntermediateHitDoublets, ::RegionsLayersSeparate>>(
490 iConfig, consumesCollector(), layersTag,
regionTag);
493 <<
"HitPairEDProducer requires either produceIntermediateHitDoublets or produceSeedingHitSets to be True. If " 494 "neither are needed, just remove this module from your sequence/path as it doesn't do anything useful";
497 if (!clusterCheckTag.label().empty())
500 impl_->produces(producesCollector());
507 ->setComment(
"Set this empty if 'trackingRegionsSeedingLayers' is non-empty");
510 "Input tracking regions when using all layer sets in 'seedingLayers' (conflicts with " 511 "'trackingRegionsSeedingLayers', set this empty to use the other)");
514 "Input tracking regions and corresponding layer sets in case of dynamically limiting the seeding layers " 515 "(conflicts with 'trackingRegions', set this empty to use the other; if using this set also 'seedingLayers' " 518 desc.add<
bool>(
"produceSeedingHitSets",
false);
519 desc.add<
bool>(
"produceIntermediateHitDoublets",
false);
520 desc.add<
unsigned int>(
"maxElement", 1000000);
521 desc.add<
unsigned int>(
"maxElementTotal", 50000000);
522 desc.add<
bool>(
"putEmptyIfMaxElementReached",
false)
524 "If set to true (default is 'false'), abort processing and put empty data products also if any layer pair " 525 "yields at least maxElement doublets, in addition to aborting processing if the sum of doublets from all " 526 "layer pairs reaches maxElementTotal.");
527 desc.add<std::vector<unsigned>>(
"layerPairs", std::vector<unsigned>{0})
528 ->setComment(
"Indices to the pairs of consecutive layers, i.e. 0 means (0,1), 1 (1,2) etc.");
530 descriptions.
add(
"hitPairEDProducerDefault",
desc);
534 bool clusterCheckOk =
true;
538 clusterCheckOk = *hclusterCheck;
T getParameter(std::string const &) const
ProductRegistryHelper::BranchAliasSetterT< ProductType > produces()
SeedingLayerSet slice(size_t begin, size_t end) const
std::unique_ptr<::ImplBase > impl_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
T const * product() const
constexpr bool isUninitialized() const noexcept
constexpr Process operator++(Process p)
void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
unsigned short size() const
Get the number of SeedingLayerSets.
Log< level::Error, false > LogError
void put(edm::Event &evt, double value, const char *instanceName)
~HitPairEDProducer() override=default
Container::value_type value_type
bool operator==(const QGLikelihoodParameters &lhs, const QGLikelihoodCategory &rhs)
Test if parameters are compatible with category.
edm::EDGetTokenT< bool > clusterCheckToken_
produceIntermediateHitDoublets
#define DEFINE_FWK_MODULE(type)
HitPairEDProducer(const edm::ParameterSet &iConfig)
unsigned short numberOfLayersInSet() const
Get number of layers in each SeedingLayerSets.
void reserve(size_t nregions, size_t nhitsets)
Helper class enforcing correct way of filling the doublets of a region.
bool operator!=(DTCELinkId const &lhs, DTCELinkId const &rhs)
const SeedingLayerSetsHits & seedingLayerSetsHits() const
void add(std::string const &label, ParameterSetDescription const &psetDescription)
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
MatrixMeschach operator*(const MatrixMeschach &mat1, const MatrixMeschach &mat2)