Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-10-01 22:41:02

0001 #include "FWCore/Framework/interface/stream/EDProducer.h"
0002 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0003 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0004 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0005 #include "FWCore/Framework/interface/ConsumesCollector.h"
0006 #include "FWCore/Framework/interface/ProducesCollector.h"
0007 #include "FWCore/Utilities/interface/EDGetToken.h"
0008 #include "FWCore/Framework/interface/Event.h"
0009 #include "DataFormats/Common/interface/Handle.h"
0010 #include "FWCore/Utilities/interface/RunningAverage.h"
0011 
0012 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegion.h"
0013 #include "DataFormats/Common/interface/OwnVector.h"
0014 #include "TrackingTools/TransientTrackingRecHit/interface/SeedingLayerSetsHits.h"
0015 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegionsSeedingLayerSets.h"
0016 #include "RecoTracker/TkHitPairs/interface/LayerHitMapCache.h"
0017 #include "RecoTracker/TkHitPairs/interface/HitPairGeneratorFromLayerPair.h"
0018 #include "RecoTracker/TkHitPairs/interface/IntermediateHitDoublets.h"
0019 #include "RecoTracker/TkHitPairs/interface/RegionsSeedingHitSets.h"
0020 
0021 namespace {
0022   class ImplBase;
0023 }
0024 
0025 class HitPairEDProducer : public edm::stream::EDProducer<> {
0026 public:
0027   HitPairEDProducer(const edm::ParameterSet& iConfig);
0028   ~HitPairEDProducer() override = default;
0029 
0030   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0031 
0032   void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0033 
0034 private:
0035   edm::EDGetTokenT<bool> clusterCheckToken_;
0036 
0037   std::unique_ptr<::ImplBase> impl_;
0038 };
0039 
0040 namespace {
0041   class ImplBase {
0042   public:
0043     ImplBase(const edm::ParameterSet& iConfig, edm::ConsumesCollector iC);
0044     virtual ~ImplBase() = default;
0045 
0046     virtual void produces(edm::ProducesCollector) const = 0;
0047 
0048     virtual void produce(const bool clusterCheckOk, edm::Event& iEvent, const edm::EventSetup& iSetup) = 0;
0049 
0050   protected:
0051     edm::RunningAverage localRA_;
0052     const unsigned int maxElement_;
0053     const unsigned int maxElementTotal_;
0054 
0055     HitPairGeneratorFromLayerPair generator_;
0056     std::vector<unsigned> layerPairBegins_;
0057   };
0058   ImplBase::ImplBase(const edm::ParameterSet& iConfig, edm::ConsumesCollector iC)
0059       : maxElement_(iConfig.getParameter<unsigned int>("maxElement")),
0060         maxElementTotal_(iConfig.getParameter<unsigned int>("maxElementTotal")),
0061         generator_(
0062             iC, 0, 1, nullptr, maxElement_),  // these indices are dummy, TODO: cleanup HitPairGeneratorFromLayerPair
0063         layerPairBegins_(iConfig.getParameter<std::vector<unsigned>>("layerPairs")) {
0064     if (layerPairBegins_.empty())
0065       throw cms::Exception("Configuration")
0066           << "HitPairEDProducer requires at least index for layer pairs (layerPairs parameter), none was given";
0067   }
0068 
0069   /////
0070   template <typename T_SeedingHitSets, typename T_IntermediateHitDoublets, typename T_RegionLayers>
0071   class Impl : public ImplBase {
0072   public:
0073     template <typename... Args>
0074     Impl(const edm::ParameterSet& iConfig, edm::ConsumesCollector iC, Args&&... args)
0075         : ImplBase(iConfig, iC), regionsLayers_(&layerPairBegins_, std::forward<Args>(args)..., iC) {}
0076     ~Impl() override = default;
0077 
0078     void produces(edm::ProducesCollector producesCollector) const override {
0079       T_SeedingHitSets::produces(producesCollector);
0080       T_IntermediateHitDoublets::produces(producesCollector);
0081     }
0082 
0083     void produce(const bool clusterCheckOk, edm::Event& iEvent, const edm::EventSetup& iSetup) override {
0084       auto regionsLayers = regionsLayers_.beginEvent(iEvent);
0085 
0086       auto seedingHitSetsProducer = T_SeedingHitSets(&localRA_);
0087       auto intermediateHitDoubletsProducer = T_IntermediateHitDoublets(regionsLayers.seedingLayerSetsHitsPtr());
0088 
0089       if (!clusterCheckOk) {
0090         seedingHitSetsProducer.putEmpty(iEvent);
0091         intermediateHitDoubletsProducer.putEmpty(iEvent);
0092         return;
0093       }
0094 
0095       seedingHitSetsProducer.reserve(regionsLayers.regionsSize());
0096       intermediateHitDoubletsProducer.reserve(regionsLayers.regionsSize());
0097 
0098       unsigned int nDoublets = 0;
0099 
0100       for (const auto& regionLayers : regionsLayers) {
0101         const TrackingRegion& region = regionLayers.region();
0102         auto hitCachePtr_filler_shs = seedingHitSetsProducer.beginRegion(&region, nullptr);
0103         auto hitCachePtr_filler_ihd =
0104             intermediateHitDoubletsProducer.beginRegion(&region, std::get<0>(hitCachePtr_filler_shs));
0105         auto hitCachePtr = std::get<0>(hitCachePtr_filler_ihd);
0106 
0107         for (SeedingLayerSetsHits::SeedingLayerSet layerSet : regionLayers.layerPairs()) {
0108           auto doublets = generator_.doublets(region, iEvent, iSetup, layerSet, *hitCachePtr);
0109           LogTrace("HitPairEDProducer") << " created " << doublets.size() << " doublets for layers "
0110                                         << layerSet[0].index() << "," << layerSet[1].index();
0111           if (doublets.empty())
0112             continue;  // don't bother if no pairs from these layers
0113           nDoublets += doublets.size();
0114           if (nDoublets >= maxElementTotal_) {
0115             edm::LogError("TooManyPairs") << "number of total pairs exceed maximum, no pairs produced";
0116             auto seedingHitSetsProducerDummy = T_SeedingHitSets(&localRA_);
0117             auto intermediateHitDoubletsProducerDummy =
0118                 T_IntermediateHitDoublets(regionsLayers.seedingLayerSetsHitsPtr());
0119             seedingHitSetsProducerDummy.putEmpty(iEvent);
0120             intermediateHitDoubletsProducerDummy.putEmpty(iEvent);
0121             return;
0122           }
0123           seedingHitSetsProducer.fill(std::get<1>(hitCachePtr_filler_shs), doublets);
0124           intermediateHitDoubletsProducer.fill(std::get<1>(hitCachePtr_filler_ihd), layerSet, std::move(doublets));
0125         }
0126       }
0127 
0128       seedingHitSetsProducer.put(iEvent);
0129       intermediateHitDoubletsProducer.put(iEvent);
0130     }
0131 
0132   private:
0133     T_RegionLayers regionsLayers_;
0134   };
0135 
0136   /////
0137   class DoNothing {
0138   public:
0139     DoNothing(const SeedingLayerSetsHits*) {}
0140     DoNothing(edm::RunningAverage*) {}
0141 
0142     static void produces(edm::ProducesCollector){};
0143 
0144     void reserve(size_t) {}
0145 
0146     auto beginRegion(const TrackingRegion*, LayerHitMapCache* ptr) { return std::make_tuple(ptr, 0); }
0147 
0148     void fill(int, const HitDoublets&) {}
0149     void fill(int, const SeedingLayerSetsHits::SeedingLayerSet&, HitDoublets&&) {}
0150 
0151     void put(edm::Event&) {}
0152     void putEmpty(edm::Event&) {}
0153   };
0154 
0155   /////
0156   class ImplSeedingHitSets {
0157   public:
0158     ImplSeedingHitSets(edm::RunningAverage* localRA)
0159         : seedingHitSets_(std::make_unique<RegionsSeedingHitSets>()), localRA_(localRA) {}
0160 
0161     static void produces(edm::ProducesCollector producesCollector) {
0162       producesCollector.produces<RegionsSeedingHitSets>();
0163     }
0164 
0165     void reserve(size_t regionsSize) { seedingHitSets_->reserve(regionsSize, localRA_->upper()); }
0166 
0167     auto beginRegion(const TrackingRegion* region, LayerHitMapCache*) {
0168       hitCacheTmp_.clear();
0169       return std::make_tuple(&hitCacheTmp_, seedingHitSets_->beginRegion(region));
0170     }
0171 
0172     void fill(RegionsSeedingHitSets::RegionFiller& filler, const HitDoublets& doublets) {
0173       for (size_t i = 0, size = doublets.size(); i < size; ++i) {
0174         filler.emplace_back(doublets.hit(i, HitDoublets::inner), doublets.hit(i, HitDoublets::outer));
0175       }
0176     }
0177 
0178     void put(edm::Event& iEvent) {
0179       seedingHitSets_->shrink_to_fit();
0180       localRA_->update(seedingHitSets_->size());
0181       putEmpty(iEvent);
0182     }
0183 
0184     void putEmpty(edm::Event& iEvent) { iEvent.put(std::move(seedingHitSets_)); }
0185 
0186   private:
0187     std::unique_ptr<RegionsSeedingHitSets> seedingHitSets_;
0188     edm::RunningAverage* localRA_;
0189     LayerHitMapCache hitCacheTmp_;  // used if !produceIntermediateHitDoublets
0190   };
0191 
0192   /////
0193   class ImplIntermediateHitDoublets {
0194   public:
0195     ImplIntermediateHitDoublets(const SeedingLayerSetsHits* layers)
0196         : intermediateHitDoublets_(std::make_unique<IntermediateHitDoublets>(layers)), layers_(layers) {}
0197 
0198     static void produces(edm::ProducesCollector producesCollector) {
0199       producesCollector.produces<IntermediateHitDoublets>();
0200     }
0201 
0202     void reserve(size_t regionsSize) { intermediateHitDoublets_->reserve(regionsSize, layers_->size()); }
0203 
0204     auto beginRegion(const TrackingRegion* region, LayerHitMapCache*) {
0205       auto filler = intermediateHitDoublets_->beginRegion(region);
0206       return std::make_tuple(&(filler.layerHitMapCache()), filler);
0207     }
0208 
0209     void fill(IntermediateHitDoublets::RegionFiller& filler,
0210               const SeedingLayerSetsHits::SeedingLayerSet& layerSet,
0211               HitDoublets&& doublets) {
0212       filler.addDoublets(layerSet, std::move(doublets));
0213     }
0214 
0215     void put(edm::Event& iEvent) {
0216       intermediateHitDoublets_->shrink_to_fit();
0217       putEmpty(iEvent);
0218     }
0219 
0220     void putEmpty(edm::Event& iEvent) { iEvent.put(std::move(intermediateHitDoublets_)); }
0221 
0222   private:
0223     std::unique_ptr<IntermediateHitDoublets> intermediateHitDoublets_;
0224     const SeedingLayerSetsHits* layers_;
0225   };
0226 
0227   /////
0228   // For the usual case that TrackingRegions and seeding layers are read separately
0229   class RegionsLayersSeparate {
0230   public:
0231     class RegionLayers {
0232     public:
0233       RegionLayers(const TrackingRegion* region, const std::vector<SeedingLayerSetsHits::SeedingLayerSet>* layerPairs)
0234           : region_(region), layerPairs_(layerPairs) {}
0235 
0236       const TrackingRegion& region() const { return *region_; }
0237       const std::vector<SeedingLayerSetsHits::SeedingLayerSet>& layerPairs() const { return *layerPairs_; }
0238 
0239     private:
0240       const TrackingRegion* region_;
0241       const std::vector<SeedingLayerSetsHits::SeedingLayerSet>* layerPairs_;
0242     };
0243 
0244     class EventTmp {
0245     public:
0246       class const_iterator {
0247       public:
0248         using internal_iterator_type = edm::OwnVector<TrackingRegion>::const_iterator;
0249         using value_type = RegionLayers;
0250         using difference_type = internal_iterator_type::difference_type;
0251 
0252         const_iterator(internal_iterator_type iter,
0253                        const std::vector<SeedingLayerSetsHits::SeedingLayerSet>* layerPairs)
0254             : iter_(iter), layerPairs_(layerPairs) {}
0255 
0256         value_type operator*() const { return value_type(&(*iter_), layerPairs_); }
0257 
0258         const_iterator& operator++() {
0259           ++iter_;
0260           return *this;
0261         }
0262         const_iterator operator++(int) {
0263           const_iterator clone(*this);
0264           ++(*this);
0265           return clone;
0266         }
0267 
0268         bool operator==(const const_iterator& other) const { return iter_ == other.iter_; }
0269         bool operator!=(const const_iterator& other) const { return !operator==(other); }
0270 
0271       private:
0272         internal_iterator_type iter_;
0273         const std::vector<SeedingLayerSetsHits::SeedingLayerSet>* layerPairs_;
0274       };
0275 
0276       EventTmp(const SeedingLayerSetsHits* seedingLayerSetsHits,
0277                const edm::OwnVector<TrackingRegion>* regions,
0278                const std::vector<unsigned>& layerPairBegins)
0279           : seedingLayerSetsHits_(seedingLayerSetsHits), regions_(regions) {
0280         // construct the pairs from the sets
0281         if (seedingLayerSetsHits_->numberOfLayersInSet() > 2) {
0282           for (const auto& layerSet : *seedingLayerSetsHits_) {
0283             for (const auto pairBeginIndex : layerPairBegins) {
0284               if (pairBeginIndex + 1 >= seedingLayerSetsHits->numberOfLayersInSet()) {
0285                 throw cms::Exception("LogicError")
0286                     << "Layer pair index " << pairBeginIndex
0287                     << " is out of bounds, input SeedingLayerSetsHits has only "
0288                     << seedingLayerSetsHits->numberOfLayersInSet()
0289                     << " layers per set, and the index+1 must be < than the number of layers in set";
0290               }
0291 
0292               // Take only the requested pair of the set
0293               SeedingLayerSetsHits::SeedingLayerSet pairCandidate = layerSet.slice(pairBeginIndex, pairBeginIndex + 1);
0294 
0295               // it would be trivial to use 128-bit bitfield for O(1) check
0296               // if a layer pair has been inserted, but let's test first how
0297               // a "straightforward" solution works
0298               auto found = std::find_if(
0299                   layerPairs.begin(), layerPairs.end(), [&](const SeedingLayerSetsHits::SeedingLayerSet& pair) {
0300                     return pair[0].index() == pairCandidate[0].index() && pair[1].index() == pairCandidate[1].index();
0301                   });
0302               if (found != layerPairs.end())
0303                 continue;
0304 
0305               layerPairs.push_back(pairCandidate);
0306             }
0307           }
0308         } else {
0309           if (layerPairBegins.size() != 1) {
0310             throw cms::Exception("LogicError")
0311                 << "With pairs of input layers, it doesn't make sense to specify more than one input layer pair, got "
0312                 << layerPairBegins.size();
0313           }
0314           if (layerPairBegins[0] != 0) {
0315             throw cms::Exception("LogicError")
0316                 << "With pairs of input layers, it doesn't make sense to specify other input layer pair than 0; got "
0317                 << layerPairBegins[0];
0318           }
0319 
0320           layerPairs.reserve(seedingLayerSetsHits->size());
0321           for (const auto& set : *seedingLayerSetsHits)
0322             layerPairs.push_back(set);
0323         }
0324       }
0325 
0326       const SeedingLayerSetsHits* seedingLayerSetsHitsPtr() const { return seedingLayerSetsHits_; }
0327 
0328       size_t regionsSize() const { return regions_->size(); }
0329 
0330       const_iterator begin() const { return const_iterator(regions_->begin(), &layerPairs); }
0331       const_iterator cbegin() const { return begin(); }
0332       const_iterator end() const { return const_iterator(regions_->end(), &layerPairs); }
0333       const_iterator cend() const { return end(); }
0334 
0335     private:
0336       const SeedingLayerSetsHits* seedingLayerSetsHits_;
0337       const edm::OwnVector<TrackingRegion>* regions_;
0338       std::vector<SeedingLayerSetsHits::SeedingLayerSet> layerPairs;
0339     };
0340 
0341     RegionsLayersSeparate(const std::vector<unsigned>* layerPairBegins,
0342                           const edm::InputTag& seedingLayerTag,
0343                           const edm::InputTag& regionTag,
0344                           edm::ConsumesCollector iC)
0345         : layerPairBegins_(layerPairBegins),
0346           seedingLayerToken_(iC.consumes<SeedingLayerSetsHits>(seedingLayerTag)),
0347           regionToken_(iC.consumes<edm::OwnVector<TrackingRegion>>(regionTag)) {}
0348 
0349     EventTmp beginEvent(const edm::Event& iEvent) const {
0350       edm::Handle<SeedingLayerSetsHits> hlayers;
0351       iEvent.getByToken(seedingLayerToken_, hlayers);
0352       const auto* layers = hlayers.product();
0353       if (layers->numberOfLayersInSet() < 2)
0354         throw cms::Exception("LogicError")
0355             << "HitPairEDProducer expects SeedingLayerSetsHits::numberOfLayersInSet() to be >= 2, got "
0356             << layers->numberOfLayersInSet()
0357             << ". This is likely caused by a configuration error of this module, or SeedingLayersEDProducer.";
0358       edm::Handle<edm::OwnVector<TrackingRegion>> hregions;
0359       iEvent.getByToken(regionToken_, hregions);
0360 
0361       return EventTmp(layers, hregions.product(), *layerPairBegins_);
0362     }
0363 
0364   private:
0365     const std::vector<unsigned>* layerPairBegins_;
0366     edm::EDGetTokenT<SeedingLayerSetsHits> seedingLayerToken_;
0367     edm::EDGetTokenT<edm::OwnVector<TrackingRegion>> regionToken_;
0368   };
0369 
0370   /////
0371   // For the case of automated pixel inactive region recovery where
0372   // TrackingRegions and seeding layers become together
0373   class RegionsLayersTogether {
0374   public:
0375     class EventTmp {
0376     public:
0377       using const_iterator = TrackingRegionsSeedingLayerSets::const_iterator;
0378 
0379       explicit EventTmp(const TrackingRegionsSeedingLayerSets* regionsLayers) : regionsLayers_(regionsLayers) {
0380         if (regionsLayers->seedingLayerSetsHits().numberOfLayersInSet() != 2) {
0381           throw cms::Exception("LogicError")
0382               << "With trackingRegionsSeedingLayers input, the seeding layer sets may only contain layer pairs, now "
0383                  "got sets with "
0384               << regionsLayers->seedingLayerSetsHits().numberOfLayersInSet() << " layers";
0385         }
0386       }
0387 
0388       const SeedingLayerSetsHits* seedingLayerSetsHitsPtr() const { return &(regionsLayers_->seedingLayerSetsHits()); }
0389 
0390       size_t regionsSize() const { return regionsLayers_->regionsSize(); }
0391 
0392       const_iterator begin() const { return regionsLayers_->begin(); }
0393       const_iterator cbegin() const { return begin(); }
0394       const_iterator end() const { return regionsLayers_->end(); }
0395       const_iterator cend() const { return end(); }
0396 
0397     private:
0398       const TrackingRegionsSeedingLayerSets* regionsLayers_;
0399     };
0400 
0401     RegionsLayersTogether(const std::vector<unsigned>* layerPairBegins,
0402                           const edm::InputTag& regionLayerTag,
0403                           edm::ConsumesCollector iC)
0404         : regionLayerToken_(iC.consumes<TrackingRegionsSeedingLayerSets>(regionLayerTag)) {
0405       if (layerPairBegins->size() != 1) {
0406         throw cms::Exception("LogicError") << "With trackingRegionsSeedingLayers mode, it doesn't make sense to "
0407                                               "specify more than one input layer pair, got "
0408                                            << layerPairBegins->size();
0409       }
0410       if ((*layerPairBegins)[0] != 0) {
0411         throw cms::Exception("LogicError") << "With trackingRegionsSeedingLayers mode, it doesn't make sense to "
0412                                               "specify other input layer pair than 0; got "
0413                                            << (*layerPairBegins)[0];
0414       }
0415     }
0416 
0417     EventTmp beginEvent(const edm::Event& iEvent) const {
0418       edm::Handle<TrackingRegionsSeedingLayerSets> hregions;
0419       iEvent.getByToken(regionLayerToken_, hregions);
0420       return EventTmp(hregions.product());
0421     }
0422 
0423   private:
0424     edm::EDGetTokenT<TrackingRegionsSeedingLayerSets> regionLayerToken_;
0425   };
0426 }  // namespace
0427 
0428 HitPairEDProducer::HitPairEDProducer(const edm::ParameterSet& iConfig) {
0429   auto layersTag = iConfig.getParameter<edm::InputTag>("seedingLayers");
0430   auto regionTag = iConfig.getParameter<edm::InputTag>("trackingRegions");
0431   auto regionLayerTag = iConfig.getParameter<edm::InputTag>("trackingRegionsSeedingLayers");
0432   const bool useRegionLayers = !regionLayerTag.label().empty();
0433   if (useRegionLayers) {
0434     if (!regionTag.label().empty()) {
0435       throw cms::Exception("Configuration")
0436           << "HitPairEDProducer requires either trackingRegions or trackingRegionsSeedingLayers to be set, now both "
0437              "are set to non-empty value. Set the unneeded parameter to empty value.";
0438     }
0439     if (!layersTag.label().empty()) {
0440       throw cms::Exception("Configuration")
0441           << "With non-empty trackingRegionsSeedingLayers, please set also seedingLayers to empty value to reduce "
0442              "confusion, because the parameter is not used";
0443     }
0444   }
0445   if (regionTag.label().empty() && regionLayerTag.label().empty()) {
0446     throw cms::Exception("Configuration")
0447         << "HitPairEDProducer requires either trackingRegions or trackingRegionsSeedingLayers to be set, now both are "
0448            "set to empty value. Set the needed parameter to a non-empty value.";
0449   }
0450 
0451   const bool produceSeedingHitSets = iConfig.getParameter<bool>("produceSeedingHitSets");
0452   const bool produceIntermediateHitDoublets = iConfig.getParameter<bool>("produceIntermediateHitDoublets");
0453 
0454   if (produceSeedingHitSets && produceIntermediateHitDoublets) {
0455     if (useRegionLayers)
0456       throw cms::Exception("Configuration")
0457           << "Mode 'trackingRegionsSeedingLayers' makes sense only with 'produceSeedingHitsSets', now also "
0458              "'produceIntermediateHitDoublets is active";
0459     impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::ImplIntermediateHitDoublets, ::RegionsLayersSeparate>>(
0460         iConfig, consumesCollector(), layersTag, regionTag);
0461   } else if (produceSeedingHitSets) {
0462     if (useRegionLayers) {
0463       impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::DoNothing, ::RegionsLayersTogether>>(
0464           iConfig, consumesCollector(), regionLayerTag);
0465     } else {
0466       impl_ = std::make_unique<::Impl<::ImplSeedingHitSets, ::DoNothing, ::RegionsLayersSeparate>>(
0467           iConfig, consumesCollector(), layersTag, regionTag);
0468     }
0469   } else if (produceIntermediateHitDoublets) {
0470     if (useRegionLayers)
0471       throw cms::Exception("Configuration")
0472           << "Mode 'trackingRegionsSeedingLayers' makes sense only with 'produceSeedingHitsSets', now "
0473              "'produceIntermediateHitDoublets is active instead";
0474     impl_ = std::make_unique<::Impl<::DoNothing, ::ImplIntermediateHitDoublets, ::RegionsLayersSeparate>>(
0475         iConfig, consumesCollector(), layersTag, regionTag);
0476   } else
0477     throw cms::Exception("Configuration")
0478         << "HitPairEDProducer requires either produceIntermediateHitDoublets or produceSeedingHitSets to be True. If "
0479            "neither are needed, just remove this module from your sequence/path as it doesn't do anything useful";
0480 
0481   auto clusterCheckTag = iConfig.getParameter<edm::InputTag>("clusterCheck");
0482   if (!clusterCheckTag.label().empty())
0483     clusterCheckToken_ = consumes<bool>(clusterCheckTag);
0484 
0485   impl_->produces(producesCollector());
0486 }
0487 
0488 void HitPairEDProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0489   edm::ParameterSetDescription desc;
0490 
0491   desc.add<edm::InputTag>("seedingLayers", edm::InputTag("seedingLayersEDProducer"))
0492       ->setComment("Set this empty if 'trackingRegionsSeedingLayers' is non-empty");
0493   desc.add<edm::InputTag>("trackingRegions", edm::InputTag("globalTrackingRegionFromBeamSpot"))
0494       ->setComment(
0495           "Input tracking regions when using all layer sets in 'seedingLayers' (conflicts with "
0496           "'trackingRegionsSeedingLayers', set this empty to use the other)");
0497   desc.add<edm::InputTag>("trackingRegionsSeedingLayers", edm::InputTag(""))
0498       ->setComment(
0499           "Input tracking regions and corresponding layer sets in case of dynamically limiting the seeding layers "
0500           "(conflicts with 'trackingRegions', set this empty to use the other; if using this set also 'seedingLayers' "
0501           "to empty)");
0502   desc.add<edm::InputTag>("clusterCheck", edm::InputTag("trackerClusterCheck"));
0503   desc.add<bool>("produceSeedingHitSets", false);
0504   desc.add<bool>("produceIntermediateHitDoublets", false);
0505   desc.add<unsigned int>("maxElement", 1000000);
0506   desc.add<unsigned int>("maxElementTotal", 50000000);
0507   desc.add<std::vector<unsigned>>("layerPairs", std::vector<unsigned>{0})
0508       ->setComment("Indices to the pairs of consecutive layers, i.e. 0 means (0,1), 1 (1,2) etc.");
0509 
0510   descriptions.add("hitPairEDProducerDefault", desc);
0511 }
0512 
0513 void HitPairEDProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0514   bool clusterCheckOk = true;
0515   if (!clusterCheckToken_.isUninitialized()) {
0516     edm::Handle<bool> hclusterCheck;
0517     iEvent.getByToken(clusterCheckToken_, hclusterCheck);
0518     clusterCheckOk = *hclusterCheck;
0519   }
0520 
0521   impl_->produce(clusterCheckOk, iEvent, iSetup);
0522 }
0523 
0524 #include "FWCore/PluginManager/interface/ModuleDef.h"
0525 #include "FWCore/Framework/interface/MakerMacros.h"
0526 DEFINE_FWK_MODULE(HitPairEDProducer);