Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-03-12 05:47:32

0001 #include "FWCore/Framework/interface/global/EDProducer.h"
0002 
0003 #include "FWCore/Framework/interface/Event.h"
0004 #include "FWCore/Framework/interface/ESHandle.h"
0005 #include "FWCore/Framework/interface/MakerMacros.h"
0006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0007 
0008 #include "DataFormats/Common/interface/ContainerMask.h"
0009 #include "DataFormats/Common/interface/DetSetVectorNew.h"
0010 #include "DataFormats/SiPixelCluster/interface/SiPixelCluster.h"
0011 #include "DataFormats/SiStripCluster/interface/SiStripClusterfwd.h"
0012 
0013 #include "RecoTracker/MkFit/interface/MkFitEventOfHits.h"
0014 #include "RecoTracker/MkFit/interface/MkFitHitWrapper.h"
0015 #include "RecoTracker/MkFit/interface/MkFitSeedWrapper.h"
0016 #include "RecoTracker/MkFit/interface/MkFitOutputWrapper.h"
0017 #include "RecoTracker/MkFit/interface/MkFitGeometry.h"
0018 #include "RecoTracker/Record/interface/TrackerRecoGeometryRecord.h"
0019 
0020 // mkFit includes
0021 #include "RecoTracker/MkFitCore/interface/ConfigWrapper.h"
0022 #include "RecoTracker/MkFitCMS/interface/LayerNumberConverter.h"
0023 #include "RecoTracker/MkFitCMS/interface/runFunctions.h"
0024 #include "RecoTracker/MkFitCore/interface/IterationConfig.h"
0025 #include "RecoTracker/MkFitCore/interface/MkBuilderWrapper.h"
0026 
0027 // TBB includes
0028 #include "oneapi/tbb/task_arena.h"
0029 
0030 // std includes
0031 #include <functional>
0032 
0033 class MkFitProducer : public edm::global::EDProducer<edm::StreamCache<mkfit::MkBuilderWrapper>> {
0034 public:
0035   explicit MkFitProducer(edm::ParameterSet const& iConfig);
0036   ~MkFitProducer() override = default;
0037 
0038   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0039 
0040   std::unique_ptr<mkfit::MkBuilderWrapper> beginStream(edm::StreamID) const override;
0041 
0042 private:
0043   void produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const override;
0044 
0045   void stripClusterChargeCut(const std::vector<float>& stripClusterCharge, std::vector<bool>& mask) const;
0046 
0047   const edm::EDGetTokenT<MkFitHitWrapper> pixelHitsToken_;
0048   const edm::EDGetTokenT<MkFitHitWrapper> stripHitsToken_;
0049   const edm::EDGetTokenT<std::vector<float>> stripClusterChargeToken_;
0050   const edm::EDGetTokenT<MkFitEventOfHits> eventOfHitsToken_;
0051   const edm::EDGetTokenT<MkFitSeedWrapper> seedToken_;
0052   edm::EDGetTokenT<edm::ContainerMask<edmNew::DetSetVector<SiPixelCluster>>> pixelMaskToken_;
0053   edm::EDGetTokenT<edm::ContainerMask<edmNew::DetSetVector<SiStripCluster>>> stripMaskToken_;
0054   const edm::ESGetToken<MkFitGeometry, TrackerRecoGeometryRecord> mkFitGeomToken_;
0055   const edm::ESGetToken<mkfit::IterationConfig, TrackerRecoGeometryRecord> mkFitIterConfigToken_;
0056   const edm::EDPutTokenT<MkFitOutputWrapper> putToken_;
0057   const float minGoodStripCharge_;
0058   const bool seedCleaning_;
0059   const bool backwardFitInCMSSW_;
0060   const bool removeDuplicates_;
0061   const bool mkFitSilent_;
0062   const bool limitConcurrency_;
0063 };
0064 
0065 MkFitProducer::MkFitProducer(edm::ParameterSet const& iConfig)
0066     : pixelHitsToken_{consumes(iConfig.getParameter<edm::InputTag>("pixelHits"))},
0067       stripHitsToken_{consumes(iConfig.getParameter<edm::InputTag>("stripHits"))},
0068       stripClusterChargeToken_{consumes(iConfig.getParameter<edm::InputTag>("stripHits"))},
0069       eventOfHitsToken_{consumes(iConfig.getParameter<edm::InputTag>("eventOfHits"))},
0070       seedToken_{consumes(iConfig.getParameter<edm::InputTag>("seeds"))},
0071       mkFitGeomToken_{esConsumes()},
0072       mkFitIterConfigToken_{esConsumes(iConfig.getParameter<edm::ESInputTag>("config"))},
0073       putToken_{produces<MkFitOutputWrapper>()},
0074       minGoodStripCharge_{static_cast<float>(
0075           iConfig.getParameter<edm::ParameterSet>("minGoodStripCharge").getParameter<double>("value"))},
0076       seedCleaning_{iConfig.getParameter<bool>("seedCleaning")},
0077       backwardFitInCMSSW_{iConfig.getParameter<bool>("backwardFitInCMSSW")},
0078       removeDuplicates_{iConfig.getParameter<bool>("removeDuplicates")},
0079       mkFitSilent_{iConfig.getUntrackedParameter<bool>("mkFitSilent")},
0080       limitConcurrency_{iConfig.getUntrackedParameter<bool>("limitConcurrency")} {
0081   const auto clustersToSkip = iConfig.getParameter<edm::InputTag>("clustersToSkip");
0082   if (not clustersToSkip.label().empty()) {
0083     pixelMaskToken_ = consumes(clustersToSkip);
0084     stripMaskToken_ = consumes(clustersToSkip);
0085   }
0086 
0087   const auto build = iConfig.getParameter<std::string>("buildingRoutine");
0088   if (build == "bestHit") {
0089     //buildFunction_ = mkfit::runBuildingTestPlexBestHit;
0090     throw cms::Exception("Configuration") << "bestHit is temporarily disabled";
0091   } else if (build == "standard") {
0092     //buildFunction_ = mkfit::runBuildingTestPlexStandard;
0093     throw cms::Exception("Configuration") << "standard is temporarily disabled";
0094   } else if (build == "cloneEngine") {
0095     //buildFunction_ = mkfit::runBuildingTestPlexCloneEngine;
0096   } else {
0097     throw cms::Exception("Configuration")
0098         << "Invalid value for parameter 'buildingRoutine' " << build << ", allowed are bestHit, standard, cloneEngine";
0099   }
0100 
0101   // TODO: what to do when we have multiple instances of MkFitProducer in a job?
0102   mkfit::MkBuilderWrapper::populate();
0103   mkfit::ConfigWrapper::initializeForCMSSW();
0104 }
0105 
0106 void MkFitProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0107   edm::ParameterSetDescription desc;
0108 
0109   desc.add("pixelHits", edm::InputTag("mkFitSiPixelHits"));
0110   desc.add("stripHits", edm::InputTag("mkFitSiStripHits"));
0111   desc.add("eventOfHits", edm::InputTag("mkFitEventOfHits"));
0112   desc.add("seeds", edm::InputTag("mkFitSeedConverter"));
0113   desc.add("clustersToSkip", edm::InputTag());
0114   desc.add<std::string>("buildingRoutine", "cloneEngine")
0115       ->setComment("Valid values are: 'bestHit', 'standard', 'cloneEngine'");
0116   desc.add<edm::ESInputTag>("config")->setComment(
0117       "ESProduct that has the mkFit configuration parameters for this iteration");
0118   desc.add("seedCleaning", true)->setComment("Clean seeds within mkFit");
0119   desc.add("removeDuplicates", true)->setComment("Run duplicate removal within mkFit");
0120   desc.add("backwardFitInCMSSW", false)
0121       ->setComment("Do backward fit (to innermost hit) in CMSSW (true) or mkFit (false)");
0122   desc.addUntracked("mkFitSilent", true)->setComment("Allows to enables printouts from mkFit with 'False'");
0123   desc.addUntracked("limitConcurrency", false)
0124       ->setComment(
0125           "Use tbb::task_arena to limit the internal concurrency to 1; useful only for timing studies when measuring "
0126           "the module time");
0127 
0128   edm::ParameterSetDescription descCCC;
0129   descCCC.add<double>("value");
0130   desc.add("minGoodStripCharge", descCCC);
0131 
0132   descriptions.add("mkFitProducerDefault", desc);
0133 }
0134 
0135 std::unique_ptr<mkfit::MkBuilderWrapper> MkFitProducer::beginStream(edm::StreamID iID) const {
0136   return std::make_unique<mkfit::MkBuilderWrapper>(mkFitSilent_);
0137 }
0138 
0139 void MkFitProducer::produce(edm::StreamID iID, edm::Event& iEvent, const edm::EventSetup& iSetup) const {
0140   const auto& pixelHits = iEvent.get(pixelHitsToken_);
0141   const auto& stripHits = iEvent.get(stripHitsToken_);
0142   const auto& eventOfHits = iEvent.get(eventOfHitsToken_);
0143   const auto& seeds = iEvent.get(seedToken_);
0144   if (seeds.seeds().empty()) {
0145     iEvent.emplace(putToken_, mkfit::TrackVec(), not backwardFitInCMSSW_);
0146     return;
0147   }
0148   // This producer does not strictly speaking need the MkFitGeometry,
0149   // but the ESProducer sets global variables (yes, that "feature"
0150   // should be removed), so getting the MkFitGeometry makes it
0151   // sure that the ESProducer is called even if the input/output
0152   // converters
0153   const auto& mkFitGeom = iSetup.getData(mkFitGeomToken_);
0154   const auto& mkFitIterConfig = iSetup.getData(mkFitIterConfigToken_);
0155 
0156   const std::vector<bool>* pixelMaskPtr = nullptr;
0157   std::vector<bool> pixelMask;
0158   std::vector<bool> stripMask(stripHits.hits().size(), false);
0159   if (not pixelMaskToken_.isUninitialized()) {
0160     if (not pixelHits.hits().empty()) {
0161       const auto& pixelContainerMask = iEvent.get(pixelMaskToken_);
0162       pixelMask.resize(pixelContainerMask.size(), false);
0163       if UNLIKELY (pixelContainerMask.refProd().id() != pixelHits.clustersID()) {
0164         throw cms::Exception("LogicError") << "MkFitHitWrapper has pixel cluster ID " << pixelHits.clustersID()
0165                                            << " but pixel cluster mask has " << pixelContainerMask.refProd().id();
0166       }
0167       pixelContainerMask.copyMaskTo(pixelMask);
0168       pixelMaskPtr = &pixelMask;
0169     }
0170 
0171     if (not stripHits.hits().empty()) {
0172       const auto& stripContainerMask = iEvent.get(stripMaskToken_);
0173       if UNLIKELY (stripContainerMask.refProd().id() != stripHits.clustersID()) {
0174         throw cms::Exception("LogicError") << "MkFitHitWrapper has strip cluster ID " << stripHits.clustersID()
0175                                            << " but strip cluster mask has " << stripContainerMask.refProd().id();
0176       }
0177       stripContainerMask.copyMaskTo(stripMask);
0178     }
0179   } else {
0180     stripClusterChargeCut(iEvent.get(stripClusterChargeToken_), stripMask);
0181   }
0182 
0183   // seeds need to be mutable because of the possible cleaning
0184   auto seeds_mutable = seeds.seeds();
0185   mkfit::TrackVec tracks;
0186 
0187   auto lambda = [&]() {
0188     mkfit::run_OneIteration(mkFitGeom.trackerInfo(),
0189                             mkFitIterConfig,
0190                             eventOfHits.get(),
0191                             {pixelMaskPtr, &stripMask},
0192                             streamCache(iID)->get(),
0193                             seeds_mutable,
0194                             tracks,
0195                             seedCleaning_,
0196                             not backwardFitInCMSSW_,
0197                             removeDuplicates_);
0198   };
0199 
0200   if (limitConcurrency_) {
0201     tbb::task_arena arena(1);
0202     arena.execute(std::move(lambda));
0203   } else {
0204     tbb::this_task_arena::isolate(std::move(lambda));
0205   }
0206 
0207   iEvent.emplace(putToken_, std::move(tracks), not backwardFitInCMSSW_);
0208 }
0209 
0210 void MkFitProducer::stripClusterChargeCut(const std::vector<float>& stripClusterCharge, std::vector<bool>& mask) const {
0211   if (mask.size() != stripClusterCharge.size()) {
0212     throw cms::Exception("LogicError") << "Mask size (" << mask.size() << ") inconsistent with number of hits ("
0213                                        << stripClusterCharge.size() << ")";
0214   }
0215   for (int i = 0, end = stripClusterCharge.size(); i < end; ++i) {
0216     // mask == true means skip the cluster
0217     mask[i] = mask[i] || (stripClusterCharge[i] <= minGoodStripCharge_);
0218   }
0219 }
0220 
0221 DEFINE_FWK_MODULE(MkFitProducer);