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")),
62 iC, 0, 1, nullptr, maxElement_),
63 layerPairBegins_(iConfig.getParameter<std::
vector<unsigned>>(
"layerPairs")) {
64 if (layerPairBegins_.empty())
66 <<
"HitPairEDProducer requires at least index for layer pairs (layerPairs parameter), none was given";
70 template <
typename T_SeedingHitSets,
typename T_IntermediateHitDoublets,
typename T_RegionLayers>
71 class Impl :
public ImplBase {
73 template <
typename... Args>
75 : ImplBase(iConfig, iC), regionsLayers_(&layerPairBegins_, std::forward<Args>(
args)..., iC) {}
76 ~Impl()
override =
default;
79 T_SeedingHitSets::produces(producesCollector);
80 T_IntermediateHitDoublets::produces(producesCollector);
84 auto regionsLayers = regionsLayers_.beginEvent(iEvent);
86 auto seedingHitSetsProducer = T_SeedingHitSets(&localRA_);
87 auto intermediateHitDoubletsProducer = T_IntermediateHitDoublets(regionsLayers.seedingLayerSetsHitsPtr());
89 if (!clusterCheckOk) {
90 seedingHitSetsProducer.putEmpty(iEvent);
91 intermediateHitDoubletsProducer.putEmpty(iEvent);
95 seedingHitSetsProducer.reserve(regionsLayers.regionsSize());
96 intermediateHitDoubletsProducer.reserve(regionsLayers.regionsSize());
98 unsigned int nDoublets = 0;
100 for (
const auto& regionLayers : regionsLayers) {
102 auto hitCachePtr_filler_shs = seedingHitSetsProducer.beginRegion(®ion,
nullptr);
103 auto hitCachePtr_filler_ihd =
104 intermediateHitDoubletsProducer.beginRegion(®ion, std::get<0>(hitCachePtr_filler_shs));
105 auto hitCachePtr = std::get<0>(hitCachePtr_filler_ihd);
108 auto doublets = generator_.doublets(region, iEvent, iSetup, layerSet, *hitCachePtr);
109 LogTrace(
"HitPairEDProducer") <<
" created " <<
doublets.size() <<
" doublets for layers "
110 << layerSet[0].index() <<
"," << layerSet[1].index();
114 if (nDoublets >= maxElementTotal_) {
115 edm::LogError(
"TooManyPairs") <<
"number of total pairs exceed maximum, no pairs produced";
116 auto seedingHitSetsProducerDummy = T_SeedingHitSets(&localRA_);
117 auto intermediateHitDoubletsProducerDummy =
118 T_IntermediateHitDoublets(regionsLayers.seedingLayerSetsHitsPtr());
119 seedingHitSetsProducerDummy.putEmpty(iEvent);
120 intermediateHitDoubletsProducerDummy.putEmpty(iEvent);
123 seedingHitSetsProducer.fill(std::get<1>(hitCachePtr_filler_shs),
doublets);
124 intermediateHitDoubletsProducer.fill(std::get<1>(hitCachePtr_filler_ihd), layerSet,
std::move(
doublets));
128 seedingHitSetsProducer.put(iEvent);
129 intermediateHitDoubletsProducer.put(iEvent);
133 T_RegionLayers regionsLayers_;
144 void reserve(
size_t) {}
156 class ImplSeedingHitSets {
165 void reserve(
size_t regionsSize) { seedingHitSets_->
reserve(regionsSize, localRA_->upper()); }
168 hitCacheTmp_.clear();
169 return std::make_tuple(&hitCacheTmp_, seedingHitSets_->beginRegion(region));
179 seedingHitSets_->shrink_to_fit();
180 localRA_->update(seedingHitSets_->size());
187 std::unique_ptr<RegionsSeedingHitSets> seedingHitSets_;
193 class ImplIntermediateHitDoublets {
202 void reserve(
size_t regionsSize) { intermediateHitDoublets_->
reserve(regionsSize, layers_->size()); }
205 auto filler = intermediateHitDoublets_->beginRegion(region);
206 return std::make_tuple(&(filler.layerHitMapCache()), filler);
216 intermediateHitDoublets_->shrink_to_fit();
223 std::unique_ptr<IntermediateHitDoublets> intermediateHitDoublets_;
229 class RegionsLayersSeparate {
234 : region_(region), layerPairs_(layerPairs) {}
237 const std::vector<SeedingLayerSetsHits::SeedingLayerSet>&
layerPairs()
const {
return *layerPairs_; }
241 const std::vector<SeedingLayerSetsHits::SeedingLayerSet>* layerPairs_;
246 class const_iterator {
252 const_iterator(internal_iterator_type iter,
253 const std::vector<SeedingLayerSetsHits::SeedingLayerSet>*
layerPairs)
254 : iter_(iter), layerPairs_(layerPairs) {}
258 const_iterator& operator++() {
262 const_iterator operator++(
int) {
263 const_iterator
clone(*
this);
268 bool operator==(
const const_iterator& other)
const {
return iter_ == other.iter_; }
272 internal_iterator_type iter_;
273 const std::vector<SeedingLayerSetsHits::SeedingLayerSet>* layerPairs_;
278 const std::vector<unsigned>& layerPairBegins)
279 : seedingLayerSetsHits_(seedingLayerSetsHits), regions_(regions) {
281 if (seedingLayerSetsHits_->numberOfLayersInSet() > 2) {
282 for (
const auto& layerSet : *seedingLayerSetsHits_) {
283 for (
const auto pairBeginIndex : layerPairBegins) {
286 <<
"Layer pair index " << pairBeginIndex
287 <<
" is out of bounds, input SeedingLayerSetsHits has only "
289 <<
" layers per set, and the index+1 must be < than the number of layers in set";
298 auto found = std::find_if(
300 return pair[0].index() == pairCandidate[0].index() && pair[1].index() == pairCandidate[1].index();
309 if (layerPairBegins.size() != 1) {
311 <<
"With pairs of input layers, it doesn't make sense to specify more than one input layer pair, got "
312 << layerPairBegins.size();
314 if (layerPairBegins[0] != 0) {
316 <<
"With pairs of input layers, it doesn't make sense to specify other input layer pair than 0; got "
317 << layerPairBegins[0];
321 for (
const auto& set : *seedingLayerSetsHits)
328 size_t regionsSize()
const {
return regions_->
size(); }
330 const_iterator
begin()
const {
return const_iterator(regions_->begin(), &
layerPairs); }
331 const_iterator cbegin()
const {
return begin(); }
332 const_iterator
end()
const {
return const_iterator(regions_->end(), &
layerPairs); }
333 const_iterator cend()
const {
return end(); }
338 std::vector<SeedingLayerSetsHits::SeedingLayerSet>
layerPairs;
341 RegionsLayersSeparate(
const std::vector<unsigned>* layerPairBegins,
345 : layerPairBegins_(layerPairBegins),
347 regionToken_(iC.consumes<edm::OwnVector<
TrackingRegion>>(regionTag)) {}
349 EventTmp beginEvent(
const edm::Event& iEvent)
const {
351 iEvent.
getByToken(seedingLayerToken_, hlayers);
353 if (
layers->numberOfLayersInSet() < 2)
355 <<
"HitPairEDProducer expects SeedingLayerSetsHits::numberOfLayersInSet() to be >= 2, got "
356 <<
layers->numberOfLayersInSet()
357 <<
". This is likely caused by a configuration error of this module, or SeedingLayersEDProducer.";
361 return EventTmp(
layers, hregions.
product(), *layerPairBegins_);
365 const std::vector<unsigned>* layerPairBegins_;
373 class RegionsLayersTogether {
382 <<
"With trackingRegionsSeedingLayers input, the seeding layer sets may only contain layer pairs, now "
388 const SeedingLayerSetsHits* seedingLayerSetsHitsPtr()
const {
return &(regionsLayers_->seedingLayerSetsHits()); }
390 size_t regionsSize()
const {
return regionsLayers_->regionsSize(); }
392 const_iterator
begin()
const {
return regionsLayers_->begin(); }
393 const_iterator cbegin()
const {
return begin(); }
394 const_iterator
end()
const {
return regionsLayers_->end(); }
395 const_iterator cend()
const {
return end(); }
401 RegionsLayersTogether(
const std::vector<unsigned>* layerPairBegins,
405 if (layerPairBegins->size() != 1) {
406 throw cms::Exception(
"LogicError") <<
"With trackingRegionsSeedingLayers mode, it doesn't make sense to "
407 "specify more than one input layer pair, got "
408 << layerPairBegins->size();
410 if ((*layerPairBegins)[0] != 0) {
411 throw cms::Exception(
"LogicError") <<
"With trackingRegionsSeedingLayers mode, it doesn't make sense to "
412 "specify other input layer pair than 0; got "
413 << (*layerPairBegins)[0];
417 EventTmp beginEvent(
const edm::Event& iEvent)
const {
419 iEvent.
getByToken(regionLayerToken_, hregions);
420 return EventTmp(hregions.
product());
432 const bool useRegionLayers = !regionLayerTag.
label().empty();
433 if (useRegionLayers) {
434 if (!regionTag.
label().empty()) {
436 <<
"HitPairEDProducer requires either trackingRegions or trackingRegionsSeedingLayers to be set, now both "
437 "are set to non-empty value. Set the unneeded parameter to empty value.";
439 if (!layersTag.label().empty()) {
441 <<
"With non-empty trackingRegionsSeedingLayers, please set also seedingLayers to empty value to reduce "
442 "confusion, because the parameter is not used";
445 if (regionTag.
label().empty() && regionLayerTag.
label().empty()) {
447 <<
"HitPairEDProducer requires either trackingRegions or trackingRegionsSeedingLayers to be set, now both are "
448 "set to empty value. Set the needed parameter to a non-empty value.";
454 if (produceSeedingHitSets && produceIntermediateHitDoublets) {
457 <<
"Mode 'trackingRegionsSeedingLayers' makes sense only with 'produceSeedingHitsSets', now also "
458 "'produceIntermediateHitDoublets is active";
459 impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::ImplIntermediateHitDoublets, ::RegionsLayersSeparate>>(
460 iConfig, consumesCollector(), layersTag, regionTag);
461 }
else if (produceSeedingHitSets) {
462 if (useRegionLayers) {
463 impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::DoNothing, ::RegionsLayersTogether>>(
464 iConfig, consumesCollector(), regionLayerTag);
466 impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::DoNothing, ::RegionsLayersSeparate>>(
467 iConfig, consumesCollector(), layersTag, regionTag);
469 }
else if (produceIntermediateHitDoublets) {
472 <<
"Mode 'trackingRegionsSeedingLayers' makes sense only with 'produceSeedingHitsSets', now "
473 "'produceIntermediateHitDoublets is active instead";
474 impl_ = std::make_unique<::Impl<::DoNothing, ::ImplIntermediateHitDoublets, ::RegionsLayersSeparate>>(
475 iConfig, consumesCollector(), layersTag, regionTag);
478 <<
"HitPairEDProducer requires either produceIntermediateHitDoublets or produceSeedingHitSets to be True. If "
479 "neither are needed, just remove this module from your sequence/path as it doesn't do anything useful";
482 if (!clusterCheckTag.label().empty())
485 impl_->produces(producesCollector());
492 ->setComment(
"Set this empty if 'trackingRegionsSeedingLayers' is non-empty");
495 "Input tracking regions when using all layer sets in 'seedingLayers' (conflicts with "
496 "'trackingRegionsSeedingLayers', set this empty to use the other)");
499 "Input tracking regions and corresponding layer sets in case of dynamically limiting the seeding layers "
500 "(conflicts with 'trackingRegions', set this empty to use the other; if using this set also 'seedingLayers' "
503 desc.
add<
bool>(
"produceSeedingHitSets",
false);
504 desc.
add<
bool>(
"produceIntermediateHitDoublets",
false);
505 desc.
add<
unsigned int>(
"maxElement", 1000000);
506 desc.
add<
unsigned int>(
"maxElementTotal", 50000000);
507 desc.
add<std::vector<unsigned>>(
"layerPairs", std::vector<unsigned>{0})
508 ->setComment(
"Indices to the pairs of consecutive layers, i.e. 0 means (0,1), 1 (1,2) etc.");
510 descriptions.
add(
"hitPairEDProducerDefault", desc);
514 bool clusterCheckOk =
true;
518 clusterCheckOk = *hclusterCheck;
521 impl_->produce(clusterCheckOk, iEvent, iSetup);
unsigned short numberOfLayersInSet() const
Get number of layers in each SeedingLayerSets.
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
ProductRegistryHelper::BranchAliasSetterT< ProductType > produces()
bool getByToken(EDGetToken token, Handle< PROD > &result) const
SeedingLayerSet slice(size_t begin, size_t end) const
std::unique_ptr<::ImplBase > impl_
#define DEFINE_FWK_MODULE(type)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
constexpr bool isUninitialized() const noexcept
tuple produceIntermediateHitDoublets
void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
Log< level::Error, false > LogError
void put(edm::Event &evt, double value, const char *instanceName)
~HitPairEDProducer() override=default
Container::value_type value_type
ptrdiff_t difference_type
bool operator==(const QGLikelihoodParameters &lhs, const QGLikelihoodCategory &rhs)
Test if parameters are compatible with category.
edm::EDGetTokenT< bool > clusterCheckToken_
tuple produceSeedingHitSets
ParameterDescriptionBase * add(U const &iLabel, T const &value)
HitPairEDProducer(const edm::ParameterSet &iConfig)
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)
void emplace_back(Args &&...args)
void fill(std::map< std::string, TH1 * > &h, const std::string &s, double x)
T const * product() const
T getParameter(std::string const &) const
void add(std::string const &label, ParameterSetDescription const &psetDescription)
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
const SeedingLayerSetsHits & seedingLayerSetsHits() const
Hit const & hit(int i, layer l) const
MatrixMeschach operator*(const MatrixMeschach &mat1, const MatrixMeschach &mat2)
unsigned short size() const
Get the number of SeedingLayerSets.
tuple size
Write out results.