20 namespace {
class ImplBase; }
34 std::unique_ptr<::ImplBase>
impl_;
41 virtual ~ImplBase() =
default;
49 const unsigned int maxElement_;
50 const unsigned int maxElementTotal_;
53 std::vector<unsigned> layerPairBegins_;
56 maxElement_(iConfig.
getParameter<
unsigned int>(
"maxElement")),
57 maxElementTotal_(iConfig.
getParameter<
unsigned int>(
"maxElementTotal")),
58 generator_(0, 1,
nullptr, maxElement_),
59 layerPairBegins_(iConfig.
getParameter<std::vector<unsigned> >(
"layerPairs"))
61 if(layerPairBegins_.empty())
62 throw cms::Exception(
"Configuration") <<
"HitPairEDProducer requires at least index for layer pairs (layerPairs parameter), none was given";
66 template <
typename T_SeedingHitSets,
typename T_IntermediateHitDoublets,
typename T_RegionLayers>
67 class Impl:
public ImplBase {
69 template <
typename... Args>
72 regionsLayers_(&layerPairBegins_, std::forward<Args>(
args)...)
74 ~Impl()
override =
default;
77 T_SeedingHitSets::produces(producer);
78 T_IntermediateHitDoublets::produces(producer);
82 auto regionsLayers = regionsLayers_.beginEvent(iEvent);
84 auto seedingHitSetsProducer = T_SeedingHitSets(&localRA_);
85 auto intermediateHitDoubletsProducer = T_IntermediateHitDoublets(regionsLayers.seedingLayerSetsHitsPtr());
88 seedingHitSetsProducer.putEmpty(iEvent);
89 intermediateHitDoubletsProducer.putEmpty(iEvent);
93 seedingHitSetsProducer.reserve(regionsLayers.regionsSize());
94 intermediateHitDoubletsProducer.reserve(regionsLayers.regionsSize());
96 unsigned int nDoublets = 0;
98 for(
const auto& regionLayers: regionsLayers) {
100 auto hitCachePtr_filler_shs = seedingHitSetsProducer.beginRegion(®ion,
nullptr);
101 auto hitCachePtr_filler_ihd = intermediateHitDoubletsProducer.beginRegion(®ion, std::get<0>(hitCachePtr_filler_shs));
102 auto hitCachePtr = std::get<0>(hitCachePtr_filler_ihd);
105 auto doublets = generator_.doublets(region, iEvent, iSetup, layerSet, *hitCachePtr);
106 LogTrace(
"HitPairEDProducer") <<
" created " <<
doublets.size() <<
" doublets for layers " << layerSet[0].index() <<
"," << layerSet[1].index();
109 if (nDoublets >= maxElementTotal_){
110 edm::LogError(
"TooManyPairs")<<
"number of total pairs exceed maximum, no pairs produced";
111 auto seedingHitSetsProducerDummy = T_SeedingHitSets(&localRA_);
112 auto intermediateHitDoubletsProducerDummy = T_IntermediateHitDoublets(regionsLayers.seedingLayerSetsHitsPtr());
113 seedingHitSetsProducerDummy.putEmpty(iEvent);
114 intermediateHitDoubletsProducerDummy.putEmpty(iEvent);
117 seedingHitSetsProducer.fill(std::get<1>(hitCachePtr_filler_shs),
doublets);
118 intermediateHitDoubletsProducer.fill(std::get<1>(hitCachePtr_filler_ihd), layerSet,
std::move(
doublets));
122 seedingHitSetsProducer.put(iEvent);
123 intermediateHitDoubletsProducer.put(iEvent);
127 T_RegionLayers regionsLayers_;
138 void reserve(
size_t) {}
141 return std::make_tuple(ptr, 0);
152 class ImplSeedingHitSets {
155 seedingHitSets_(std::make_unique<RegionsSeedingHitSets>()),
163 void reserve(
size_t regionsSize) {
164 seedingHitSets_->
reserve(regionsSize, localRA_->upper());
168 hitCacheTmp_.clear();
169 return std::make_tuple(&hitCacheTmp_, seedingHitSets_->beginRegion(region));
180 seedingHitSets_->shrink_to_fit();
181 localRA_->update(seedingHitSets_->size());
190 std::unique_ptr<RegionsSeedingHitSets> seedingHitSets_;
196 class ImplIntermediateHitDoublets {
199 intermediateHitDoublets_(std::make_unique<IntermediateHitDoublets>(layers)),
207 void reserve(
size_t regionsSize) {
208 intermediateHitDoublets_->
reserve(regionsSize, layers_->size());
212 auto filler = intermediateHitDoublets_->beginRegion(region);
221 intermediateHitDoublets_->shrink_to_fit();
230 std::unique_ptr<IntermediateHitDoublets> intermediateHitDoublets_;
236 class RegionsLayersSeparate {
241 region_(region), layerPairs_(layerPairs) {}
244 const std::vector<SeedingLayerSetsHits::SeedingLayerSet>&
layerPairs()
const {
return *layerPairs_; }
248 const std::vector<SeedingLayerSetsHits::SeedingLayerSet> *layerPairs_;
253 class const_iterator {
257 using difference_type = internal_iterator_type::difference_type;
259 const_iterator(internal_iterator_type iter,
const std::vector<SeedingLayerSetsHits::SeedingLayerSet> *
layerPairs):
260 iter_(iter), layerPairs_(layerPairs) {}
264 const_iterator& operator++() { ++iter_;
return *
this; }
265 const_iterator operator++(
int) {
266 const_iterator
clone(*
this);
271 bool operator==(
const const_iterator&
other)
const {
return iter_ == other.iter_; }
275 internal_iterator_type iter_;
276 const std::vector<SeedingLayerSetsHits::SeedingLayerSet> *layerPairs_;
281 const std::vector<unsigned>& layerPairBegins):
282 seedingLayerSetsHits_(seedingLayerSetsHits), regions_(regions) {
285 if(seedingLayerSetsHits_->numberOfLayersInSet() > 2) {
286 for(
const auto& layerSet: *seedingLayerSetsHits_) {
287 for(
const auto pairBeginIndex: layerPairBegins) {
289 throw cms::Exception(
"LogicError") <<
"Layer pair index " << pairBeginIndex <<
" is out of bounds, input SeedingLayerSetsHits has only " << seedingLayerSetsHits->
numberOfLayersInSet() <<
" layers per set, and the index+1 must be < than the number of layers in set";
299 return pair[0].index() == pairCandidate[0].index() && pair[1].index() == pairCandidate[1].index();
309 if(layerPairBegins.size() != 1) {
310 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();
312 if(layerPairBegins[0] != 0) {
313 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];
317 for(
const auto&
set: *seedingLayerSetsHits)
324 size_t regionsSize()
const {
return regions_->
size(); }
326 const_iterator
begin()
const {
return const_iterator(regions_->begin(), &
layerPairs); }
327 const_iterator cbegin()
const {
return begin(); }
328 const_iterator
end()
const {
return const_iterator(regions_->end(), &
layerPairs); }
329 const_iterator cend()
const {
return end(); }
334 std::vector<SeedingLayerSetsHits::SeedingLayerSet>
layerPairs;
337 RegionsLayersSeparate(
const std::vector<unsigned> *layerPairBegins,
341 layerPairBegins_(layerPairBegins),
348 iEvent.
getByToken(seedingLayerToken_, hlayers);
350 if(
layers->numberOfLayersInSet() < 2)
351 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.";
355 return EventTmp(
layers, hregions.
product(), *layerPairBegins_);
359 const std::vector<unsigned> *layerPairBegins_;
367 class RegionsLayersTogether {
374 regionsLayers_(regionsLayers) {
380 const SeedingLayerSetsHits *seedingLayerSetsHitsPtr()
const {
return &(regionsLayers_->seedingLayerSetsHits()); }
382 size_t regionsSize()
const {
return regionsLayers_->regionsSize(); }
384 const_iterator
begin()
const {
return regionsLayers_->begin(); }
385 const_iterator cbegin()
const {
return begin(); }
386 const_iterator
end()
const {
return regionsLayers_->end(); }
387 const_iterator cend()
const {
return end(); }
393 RegionsLayersTogether(
const std::vector<unsigned> *layerPairBegins,
398 if(layerPairBegins->size() != 1) {
399 throw cms::Exception(
"LogicError") <<
"With trackingRegionsSeedingLayers mode, it doesn't make sense to specify more than one input layer pair, got " << layerPairBegins->size();
401 if((*layerPairBegins)[0] != 0) {
402 throw cms::Exception(
"LogicError") <<
"With trackingRegionsSeedingLayers mode, it doesn't make sense to specify other input layer pair than 0; got " << (*layerPairBegins)[0];
408 iEvent.
getByToken(regionLayerToken_, hregions);
409 return EventTmp(hregions.
product());
423 const bool useRegionLayers = !regionLayerTag.
label().empty();
424 if(useRegionLayers) {
425 if(!regionTag.
label().empty()) {
426 throw cms::Exception(
"Configuration") <<
"HitPairEDProducer requires either trackingRegions or trackingRegionsSeedingLayers to be set, now both are set to non-empty value. Set the unneeded parameter to empty value.";
428 if(!layersTag.label().empty()) {
429 throw cms::Exception(
"Configuration") <<
"With non-empty trackingRegionsSeedingLayers, please set also seedingLayers to empty value to reduce confusion, because the parameter is not used";
432 if(regionTag.
label().empty() && regionLayerTag.
label().empty()) {
433 throw cms::Exception(
"Configuration") <<
"HitPairEDProducer requires either trackingRegions or trackingRegionsSeedingLayers to be set, now both are set to empty value. Set the needed parameter to a non-empty value.";
439 if(produceSeedingHitSets && produceIntermediateHitDoublets) {
440 if(useRegionLayers)
throw cms::Exception(
"Configuration") <<
"Mode 'trackingRegionsSeedingLayers' makes sense only with 'produceSeedingHitsSets', now also 'produceIntermediateHitDoublets is active";
441 impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::ImplIntermediateHitDoublets, ::RegionsLayersSeparate>>(iConfig, layersTag, regionTag, consumesCollector());
443 else if(produceSeedingHitSets) {
444 if(useRegionLayers) {
445 impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::DoNothing, ::RegionsLayersTogether>>(iConfig, regionLayerTag, consumesCollector());
448 impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::DoNothing, ::RegionsLayersSeparate>>(iConfig, layersTag, regionTag, consumesCollector());
451 else if(produceIntermediateHitDoublets) {
452 if(useRegionLayers)
throw cms::Exception(
"Configuration") <<
"Mode 'trackingRegionsSeedingLayers' makes sense only with 'produceSeedingHitsSets', now 'produceIntermediateHitDoublets is active instead";
453 impl_ = std::make_unique<::Impl<::DoNothing, ::ImplIntermediateHitDoublets, ::RegionsLayersSeparate>>(iConfig, layersTag, regionTag, consumesCollector());
456 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";
459 if(!clusterCheckTag.label().empty())
462 impl_->produces(*
this);
468 desc.
add<
edm::InputTag>(
"seedingLayers",
edm::InputTag(
"seedingLayersEDProducer"))->setComment(
"Set this empty if 'trackingRegionsSeedingLayers' is non-empty");
469 desc.
add<
edm::InputTag>(
"trackingRegions",
edm::InputTag(
"globalTrackingRegionFromBeamSpot"))->setComment(
"Input tracking regions when using all layer sets in 'seedingLayers' (conflicts with 'trackingRegionsSeedingLayers', set this empty to use the other)");
470 desc.
add<
edm::InputTag>(
"trackingRegionsSeedingLayers",
edm::InputTag(
""))->setComment(
"Input tracking regions and corresponding layer sets in case of dynamically limiting the seeding layers (conflicts with 'trackingRegions', set this empty to use the other; if using this set also 'seedingLayers' to empty)");
472 desc.
add<
bool>(
"produceSeedingHitSets",
false);
473 desc.
add<
bool>(
"produceIntermediateHitDoublets",
false);
474 desc.
add<
unsigned int>(
"maxElement", 1000000);
475 desc.
add<
unsigned int>(
"maxElementTotal", 50000000);
476 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.");
478 descriptions.
add(
"hitPairEDProducerDefault", desc);
482 bool clusterCheckOk =
true;
486 clusterCheckOk = *hclusterCheck;
489 impl_->produce(clusterCheckOk, iEvent, iSetup);
BranchAliasSetterT< ProductType > produces()
declare what type of product will make and with which optional label
T getParameter(std::string const &) const
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)
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)
void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
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_
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool operator!=(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
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.
void emplace_back(Args &&...args)
T const * product() const
void add(std::string const &label, ParameterSetDescription const &psetDescription)
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
produceIntermediateHitDoublets
const SeedingLayerSetsHits & seedingLayerSetsHits() const
Hit const & hit(int i, layer l) const
bool isUninitialized() const
MatrixMeschach operator*(const MatrixMeschach &mat1, const MatrixMeschach &mat2)
unsigned short size() const
Get the number of SeedingLayerSets.