CMS 3D CMS Logo

MkFitProducer.cc
Go to the documentation of this file.
2 
7 
12 
19 
20 // mkFit includes
25 
26 // TBB includes
27 #include "oneapi/tbb/task_arena.h"
28 
29 // std includes
30 #include <functional>
31 
32 class MkFitProducer : public edm::global::EDProducer<edm::StreamCache<mkfit::MkBuilderWrapper>> {
33 public:
34  explicit MkFitProducer(edm::ParameterSet const& iConfig);
35  ~MkFitProducer() override = default;
36 
37  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
38 
39  std::unique_ptr<mkfit::MkBuilderWrapper> beginStream(edm::StreamID) const override;
40 
41 private:
42  void produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const override;
43 
44  void stripClusterChargeCut(const std::vector<float>& stripClusterCharge, std::vector<bool>& mask) const;
45 
56  const float minGoodStripCharge_;
57  const bool seedCleaning_;
58  const bool backwardFitInCMSSW_;
59  const bool removeDuplicates_;
60  const bool mkFitSilent_;
61  const bool limitConcurrency_;
62 };
63 
65  : pixelHitsToken_{consumes(iConfig.getParameter<edm::InputTag>("pixelHits"))},
66  stripHitsToken_{consumes(iConfig.getParameter<edm::InputTag>("stripHits"))},
67  stripClusterChargeToken_{consumes(iConfig.getParameter<edm::InputTag>("stripHits"))},
68  eventOfHitsToken_{consumes(iConfig.getParameter<edm::InputTag>("eventOfHits"))},
69  seedToken_{consumes(iConfig.getParameter<edm::InputTag>("seeds"))},
70  mkFitGeomToken_{esConsumes()},
71  mkFitIterConfigToken_{esConsumes(iConfig.getParameter<edm::ESInputTag>("config"))},
72  putToken_{produces<MkFitOutputWrapper>()},
73  minGoodStripCharge_{static_cast<float>(
74  iConfig.getParameter<edm::ParameterSet>("minGoodStripCharge").getParameter<double>("value"))},
75  seedCleaning_{iConfig.getParameter<bool>("seedCleaning")},
76  backwardFitInCMSSW_{iConfig.getParameter<bool>("backwardFitInCMSSW")},
77  removeDuplicates_{iConfig.getParameter<bool>("removeDuplicates")},
78  mkFitSilent_{iConfig.getUntrackedParameter<bool>("mkFitSilent")},
79  limitConcurrency_{iConfig.getUntrackedParameter<bool>("limitConcurrency")} {
80  const auto clustersToSkip = iConfig.getParameter<edm::InputTag>("clustersToSkip");
81  if (not clustersToSkip.label().empty()) {
82  pixelMaskToken_ = consumes(clustersToSkip);
83  stripMaskToken_ = consumes(clustersToSkip);
84  }
85 
86  const auto build = iConfig.getParameter<std::string>("buildingRoutine");
87  if (build == "bestHit") {
88  //buildFunction_ = mkfit::runBuildingTestPlexBestHit;
89  throw cms::Exception("Configuration") << "bestHit is temporarily disabled";
90  } else if (build == "standard") {
91  //buildFunction_ = mkfit::runBuildingTestPlexStandard;
92  throw cms::Exception("Configuration") << "standard is temporarily disabled";
93  } else if (build == "cloneEngine") {
94  //buildFunction_ = mkfit::runBuildingTestPlexCloneEngine;
95  } else {
96  throw cms::Exception("Configuration")
97  << "Invalid value for parameter 'buildingRoutine' " << build << ", allowed are bestHit, standard, cloneEngine";
98  }
99 
100  // TODO: what to do when we have multiple instances of MkFitProducer in a job?
102 }
103 
106 
107  desc.add("pixelHits", edm::InputTag("mkFitSiPixelHits"));
108  desc.add("stripHits", edm::InputTag("mkFitSiStripHits"));
109  desc.add("eventOfHits", edm::InputTag("mkFitEventOfHits"));
110  desc.add("seeds", edm::InputTag("mkFitSeedConverter"));
111  desc.add("clustersToSkip", edm::InputTag());
112  desc.add<std::string>("buildingRoutine", "cloneEngine")
113  ->setComment("Valid values are: 'bestHit', 'standard', 'cloneEngine'");
114  desc.add<edm::ESInputTag>("config")->setComment(
115  "ESProduct that has the mkFit configuration parameters for this iteration");
116  desc.add("seedCleaning", true)->setComment("Clean seeds within mkFit");
117  desc.add("removeDuplicates", true)->setComment("Run duplicate removal within mkFit");
118  desc.add("backwardFitInCMSSW", false)
119  ->setComment("Do backward fit (to innermost hit) in CMSSW (true) or mkFit (false)");
120  desc.addUntracked("mkFitSilent", true)->setComment("Allows to enables printouts from mkFit with 'False'");
121  desc.addUntracked("limitConcurrency", false)
122  ->setComment(
123  "Use tbb::task_arena to limit the internal concurrency to 1; useful only for timing studies when measuring "
124  "the module time");
125 
127  descCCC.add<double>("value");
128  desc.add("minGoodStripCharge", descCCC);
129 
130  descriptions.add("mkFitProducerDefault", desc);
131 }
132 
133 std::unique_ptr<mkfit::MkBuilderWrapper> MkFitProducer::beginStream(edm::StreamID iID) const {
134  return std::make_unique<mkfit::MkBuilderWrapper>(mkFitSilent_);
135 }
136 
138  const auto& pixelHits = iEvent.get(pixelHitsToken_);
139  const auto& stripHits = iEvent.get(stripHitsToken_);
140  const auto& eventOfHits = iEvent.get(eventOfHitsToken_);
141  const auto& seeds = iEvent.get(seedToken_);
142  if (seeds.seeds().empty()) {
144  return;
145  }
146  // This producer does not strictly speaking need the MkFitGeometry,
147  // but the ESProducer sets global variables (yes, that "feature"
148  // should be removed), so getting the MkFitGeometry makes it
149  // sure that the ESProducer is called even if the input/output
150  // converters
151  const auto& mkFitGeom = iSetup.getData(mkFitGeomToken_);
152  const auto& mkFitIterConfig = iSetup.getData(mkFitIterConfigToken_);
153 
154  const std::vector<bool>* pixelMaskPtr = nullptr;
155  std::vector<bool> pixelMask;
156  std::vector<bool> stripMask(stripHits.hits().size(), false);
157  if (not pixelMaskToken_.isUninitialized()) {
158  if (not pixelHits.hits().empty()) {
159  const auto& pixelContainerMask = iEvent.get(pixelMaskToken_);
160  pixelMask.resize(pixelContainerMask.size(), false);
161  if UNLIKELY (pixelContainerMask.refProd().id() != pixelHits.clustersID()) {
162  throw cms::Exception("LogicError") << "MkFitHitWrapper has pixel cluster ID " << pixelHits.clustersID()
163  << " but pixel cluster mask has " << pixelContainerMask.refProd().id();
164  }
165  pixelContainerMask.copyMaskTo(pixelMask);
166  pixelMaskPtr = &pixelMask;
167  }
168 
169  if (not stripHits.hits().empty()) {
170  const auto& stripContainerMask = iEvent.get(stripMaskToken_);
171  if UNLIKELY (stripContainerMask.refProd().id() != stripHits.clustersID()) {
172  throw cms::Exception("LogicError") << "MkFitHitWrapper has strip cluster ID " << stripHits.clustersID()
173  << " but strip cluster mask has " << stripContainerMask.refProd().id();
174  }
175  stripContainerMask.copyMaskTo(stripMask);
176  }
177  } else {
179  }
180 
181  // seeds need to be mutable because of the possible cleaning
182  auto seeds_mutable = seeds.seeds();
184 
185  auto lambda = [&]() {
186  mkfit::run_OneIteration(mkFitGeom.trackerInfo(),
187  mkFitIterConfig,
188  eventOfHits.get(),
189  {pixelMaskPtr, &stripMask},
190  streamCache(iID)->get(),
191  seeds_mutable,
192  tracks,
196  };
197 
198  if (limitConcurrency_) {
199  tbb::task_arena arena(1);
200  arena.execute(std::move(lambda));
201  } else {
202  tbb::this_task_arena::isolate(std::move(lambda));
203  }
204 
206 }
207 
208 void MkFitProducer::stripClusterChargeCut(const std::vector<float>& stripClusterCharge, std::vector<bool>& mask) const {
209  if (mask.size() != stripClusterCharge.size()) {
210  throw cms::Exception("LogicError") << "Mask size (" << mask.size() << ") inconsistent with number of hits ("
211  << stripClusterCharge.size() << ")";
212  }
213  for (int i = 0, end = stripClusterCharge.size(); i < end; ++i) {
214  // mask == true means skip the cluster
215  mask[i] = mask[i] || (stripClusterCharge[i] <= minGoodStripCharge_);
216  }
217 }
218 
const bool seedCleaning_
edm::EDGetTokenT< edm::ContainerMask< edmNew::DetSetVector< SiStripCluster > > > stripMaskToken_
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
edm::EDGetTokenT< edm::ContainerMask< edmNew::DetSetVector< SiPixelCluster > > > pixelMaskToken_
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
const bool backwardFitInCMSSW_
const bool removeDuplicates_
const edm::EDPutTokenT< MkFitOutputWrapper > putToken_
constexpr bool isUninitialized() const noexcept
Definition: EDGetToken.h:104
constexpr uint32_t mask
Definition: gpuClustering.h:26
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
const edm::EDGetTokenT< std::vector< float > > stripClusterChargeToken_
const bool limitConcurrency_
void stripClusterChargeCut(const std::vector< float > &stripClusterCharge, std::vector< bool > &mask) const
void run_OneIteration(const TrackerInfo &trackerInfo, const IterationConfig &itconf, const EventOfHits &eoh, const std::vector< const std::vector< bool > *> &hit_masks, MkBuilder &builder, TrackVec &seeds, TrackVec &out_tracks, bool do_seed_clean, bool do_backward_fit, bool do_remove_duplicates)
Definition: runFunctions.cc:29
const edm::EDGetTokenT< MkFitHitWrapper > stripHitsToken_
int iEvent
Definition: GenABIO.cc:224
std::unique_ptr< mkfit::MkBuilderWrapper > beginStream(edm::StreamID) const override
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
~MkFitProducer() override=default
ParameterDescriptionBase * add(U const &iLabel, T const &value)
const float minGoodStripCharge_
std::vector< Track > TrackVec
void add(std::string const &label, ParameterSetDescription const &psetDescription)
const bool mkFitSilent_
const edm::EDGetTokenT< MkFitHitWrapper > pixelHitsToken_
void produce(edm::StreamID, edm::Event &iEvent, const edm::EventSetup &iSetup) const override
const edm::ESGetToken< mkfit::IterationConfig, TrackerRecoGeometryRecord > mkFitIterConfigToken_
const edm::ESGetToken< MkFitGeometry, TrackerRecoGeometryRecord > mkFitGeomToken_
const edm::EDGetTokenT< MkFitEventOfHits > eventOfHitsToken_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
#define UNLIKELY(x)
Definition: Likely.h:21
MkFitProducer(edm::ParameterSet const &iConfig)
const edm::EDGetTokenT< MkFitSeedWrapper > seedToken_
def move(src, dest)
Definition: eostools.py:511