Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-25 02:14:11

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/MkFitCMS/interface/LayerNumberConverter.h"
0022 #include "RecoTracker/MkFitCMS/interface/runFunctions.h"
0023 #include "RecoTracker/MkFitCore/interface/IterationConfig.h"
0024 #include "RecoTracker/MkFitCore/interface/MkBuilderWrapper.h"
0025 
0026 // TBB includes
0027 #include "oneapi/tbb/task_arena.h"
0028 
0029 // std includes
0030 #include <functional>
0031 
0032 class MkFitProducer : public edm::global::EDProducer<edm::StreamCache<mkfit::MkBuilderWrapper>> {
0033 public:
0034   explicit MkFitProducer(edm::ParameterSet const& iConfig);
0035   ~MkFitProducer() override;
0036 
0037   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0038 
0039   std::unique_ptr<mkfit::MkBuilderWrapper> beginStream(edm::StreamID) const override;
0040 
0041 private:
0042   void produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const override;
0043 
0044   void stripClusterChargeCut(const std::vector<float>& stripClusterCharge, std::vector<bool>& mask) const;
0045 
0046   const edm::EDGetTokenT<MkFitHitWrapper> pixelHitsToken_;
0047   const edm::EDGetTokenT<MkFitHitWrapper> stripHitsToken_;
0048   const edm::EDGetTokenT<std::vector<float>> stripClusterChargeToken_;
0049   const edm::EDGetTokenT<MkFitEventOfHits> eventOfHitsToken_;
0050   const edm::EDGetTokenT<MkFitSeedWrapper> seedToken_;
0051   edm::EDGetTokenT<edm::ContainerMask<edmNew::DetSetVector<SiPixelCluster>>> pixelMaskToken_;
0052   edm::EDGetTokenT<edm::ContainerMask<edmNew::DetSetVector<SiStripCluster>>> stripMaskToken_;
0053   const edm::ESGetToken<MkFitGeometry, TrackerRecoGeometryRecord> mkFitGeomToken_;
0054   const edm::ESGetToken<mkfit::IterationConfig, TrackerRecoGeometryRecord> mkFitIterConfigToken_;
0055   const edm::EDPutTokenT<MkFitOutputWrapper> putToken_;
0056   const float minGoodStripCharge_;
0057   const bool seedCleaning_;
0058   const bool backwardFitInCMSSW_;
0059   const bool removeDuplicates_;
0060   const bool mkFitSilent_;
0061   const bool limitConcurrency_;
0062 };
0063 
0064 MkFitProducer::MkFitProducer(edm::ParameterSet const& iConfig)
0065     : pixelHitsToken_{consumes(iConfig.getParameter<edm::InputTag>("pixelHits"))},
0066       stripHitsToken_{consumes(iConfig.getParameter<edm::InputTag>("stripHits"))},
0067       stripClusterChargeToken_{consumes(iConfig.getParameter<edm::InputTag>("stripHits"))},
0068       eventOfHitsToken_{consumes(iConfig.getParameter<edm::InputTag>("eventOfHits"))},
0069       seedToken_{consumes(iConfig.getParameter<edm::InputTag>("seeds"))},
0070       mkFitGeomToken_{esConsumes()},
0071       mkFitIterConfigToken_{esConsumes(iConfig.getParameter<edm::ESInputTag>("config"))},
0072       putToken_{produces<MkFitOutputWrapper>()},
0073       minGoodStripCharge_{static_cast<float>(
0074           iConfig.getParameter<edm::ParameterSet>("minGoodStripCharge").getParameter<double>("value"))},
0075       seedCleaning_{iConfig.getParameter<bool>("seedCleaning")},
0076       backwardFitInCMSSW_{iConfig.getParameter<bool>("backwardFitInCMSSW")},
0077       removeDuplicates_{iConfig.getParameter<bool>("removeDuplicates")},
0078       mkFitSilent_{iConfig.getUntrackedParameter<bool>("mkFitSilent")},
0079       limitConcurrency_{iConfig.getUntrackedParameter<bool>("limitConcurrency")} {
0080   const auto clustersToSkip = iConfig.getParameter<edm::InputTag>("clustersToSkip");
0081   if (not clustersToSkip.label().empty()) {
0082     pixelMaskToken_ = consumes(clustersToSkip);
0083     stripMaskToken_ = consumes(clustersToSkip);
0084   }
0085 
0086   const auto build = iConfig.getParameter<std::string>("buildingRoutine");
0087   if (build == "bestHit") {
0088     //buildFunction_ = mkfit::runBuildingTestPlexBestHit;
0089     throw cms::Exception("Configuration") << "bestHit is temporarily disabled";
0090   } else if (build == "standard") {
0091     //buildFunction_ = mkfit::runBuildingTestPlexStandard;
0092     throw cms::Exception("Configuration") << "standard is temporarily disabled";
0093   } else if (build == "cloneEngine") {
0094     //buildFunction_ = mkfit::runBuildingTestPlexCloneEngine;
0095   } else {
0096     throw cms::Exception("Configuration")
0097         << "Invalid value for parameter 'buildingRoutine' " << build << ", allowed are bestHit, standard, cloneEngine";
0098   }
0099 
0100   // TODO: what to do when we have multiple instances of MkFitProducer in a job?
0101   mkfit::MkBuilderWrapper::populate();
0102 }
0103 
0104 MkFitProducer::~MkFitProducer() { mkfit::MkBuilderWrapper::clear(); }
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     if (mkFitGeom.isPhase1())
0181       stripClusterChargeCut(iEvent.get(stripClusterChargeToken_), stripMask);
0182   }
0183 
0184   // seeds need to be mutable because of the possible cleaning
0185   auto seeds_mutable = seeds.seeds();
0186   mkfit::TrackVec tracks;
0187 
0188   auto lambda = [&]() {
0189     mkfit::run_OneIteration(mkFitGeom.trackerInfo(),
0190                             mkFitIterConfig,
0191                             eventOfHits.get(),
0192                             {pixelMaskPtr, &stripMask},
0193                             streamCache(iID)->get(),
0194                             seeds_mutable,
0195                             tracks,
0196                             seedCleaning_,
0197                             not backwardFitInCMSSW_,
0198                             removeDuplicates_);
0199   };
0200 
0201   if (limitConcurrency_) {
0202     tbb::task_arena arena(1);
0203     arena.execute(std::move(lambda));
0204   } else {
0205     tbb::this_task_arena::isolate(std::move(lambda));
0206   }
0207 
0208   iEvent.emplace(putToken_, std::move(tracks), not backwardFitInCMSSW_);
0209 }
0210 
0211 void MkFitProducer::stripClusterChargeCut(const std::vector<float>& stripClusterCharge, std::vector<bool>& mask) const {
0212   if (mask.size() != stripClusterCharge.size()) {
0213     throw cms::Exception("LogicError") << "Mask size (" << mask.size() << ") inconsistent with number of hits ("
0214                                        << stripClusterCharge.size() << ")";
0215   }
0216   for (int i = 0, end = stripClusterCharge.size(); i < end; ++i) {
0217     // mask == true means skip the cluster
0218     mask[i] = mask[i] || (stripClusterCharge[i] <= minGoodStripCharge_);
0219   }
0220 }
0221 
0222 DEFINE_FWK_MODULE(MkFitProducer);