CMS 3D CMS Logo

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