CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MkFitProducer.cc
Go to the documentation of this file.
2 
7 
12 
19 
20 // mkFit includes
21 #include "ConfigWrapper.h"
22 #include "LayerNumberConverter.h"
23 #include "mkFit/buildtestMPlex.h"
24 #include "mkFit/IterationConfig.h"
25 #include "mkFit/MkBuilderWrapper.h"
26 
27 // TBB includes
28 #include "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  std::function<double(mkfit::Event&, mkfit::MkBuilder&)> buildFunction_;
58  const float minGoodStripCharge_;
59  const bool seedCleaning_;
60  const bool backwardFitInCMSSW_;
61  const bool removeDuplicates_;
62  const bool mkFitSilent_;
63  const bool limitConcurrency_;
64 };
65 
67  : pixelHitsToken_{consumes(iConfig.getParameter<edm::InputTag>("pixelHits"))},
68  stripHitsToken_{consumes(iConfig.getParameter<edm::InputTag>("stripHits"))},
69  stripClusterChargeToken_{consumes(iConfig.getParameter<edm::InputTag>("stripHits"))},
70  eventOfHitsToken_{consumes(iConfig.getParameter<edm::InputTag>("eventOfHits"))},
71  seedToken_{consumes(iConfig.getParameter<edm::InputTag>("seeds"))},
72  mkFitGeomToken_{esConsumes()},
73  mkFitIterConfigToken_{esConsumes(iConfig.getParameter<edm::ESInputTag>("config"))},
74  putToken_{produces<MkFitOutputWrapper>()},
75  minGoodStripCharge_{static_cast<float>(
76  iConfig.getParameter<edm::ParameterSet>("minGoodStripCharge").getParameter<double>("value"))},
77  seedCleaning_{iConfig.getParameter<bool>("seedCleaning")},
78  backwardFitInCMSSW_{iConfig.getParameter<bool>("backwardFitInCMSSW")},
79  removeDuplicates_{iConfig.getParameter<bool>("removeDuplicates")},
80  mkFitSilent_{iConfig.getUntrackedParameter<bool>("mkFitSilent")},
81  limitConcurrency_{iConfig.getUntrackedParameter<bool>("limitConcurrency")} {
82  const auto clustersToSkip = iConfig.getParameter<edm::InputTag>("clustersToSkip");
83  if (not clustersToSkip.label().empty()) {
84  pixelMaskToken_ = consumes(clustersToSkip);
85  stripMaskToken_ = consumes(clustersToSkip);
86  }
87 
88  const auto build = iConfig.getParameter<std::string>("buildingRoutine");
89  if (build == "bestHit") {
90  //buildFunction_ = mkfit::runBuildingTestPlexBestHit;
91  throw cms::Exception("Configuration") << "bestHit is temporarily disabled";
92  } else if (build == "standard") {
93  //buildFunction_ = mkfit::runBuildingTestPlexStandard;
94  throw cms::Exception("Configuration") << "standard is temporarily disabled";
95  } else if (build == "cloneEngine") {
96  //buildFunction_ = mkfit::runBuildingTestPlexCloneEngine;
97  } else {
98  throw cms::Exception("Configuration")
99  << "Invalid value for parameter 'buildingRoutine' " << build << ", allowed are bestHit, standard, cloneEngine";
100  }
101 
102  // TODO: what to do when we have multiple instances of MkFitProducer in a job?
103  mkfit::MkBuilderWrapper::populate();
104  mkfit::ConfigWrapper::initializeForCMSSW(mkFitSilent_);
105 }
106 
109 
110  desc.add("pixelHits", edm::InputTag("mkFitSiPixelHits"));
111  desc.add("stripHits", edm::InputTag("mkFitSiStripHits"));
112  desc.add("eventOfHits", edm::InputTag("mkFitEventOfHits"));
113  desc.add("seeds", edm::InputTag("mkFitSeedConverter"));
114  desc.add("clustersToSkip", edm::InputTag());
115  desc.add<std::string>("buildingRoutine", "cloneEngine")
116  ->setComment("Valid values are: 'bestHit', 'standard', 'cloneEngine'");
117  desc.add<edm::ESInputTag>("config")->setComment(
118  "ESProduct that has the mkFit configuration parameters for this iteration");
119  desc.add("seedCleaning", true)->setComment("Clean seeds within mkFit");
120  desc.add("removeDuplicates", true)->setComment("Run duplicate removal within mkFit");
121  desc.add("backwardFitInCMSSW", false)
122  ->setComment("Do backward fit (to innermost hit) in CMSSW (true) or mkFit (false)");
123  desc.addUntracked("mkFitSilent", true)->setComment("Allows to enables printouts from mkFit with 'False'");
124  desc.addUntracked("limitConcurrency", false)
125  ->setComment(
126  "Use tbb::task_arena to limit the internal concurrency to 1; useful only for timing studies when measuring "
127  "the module time");
128 
130  descCCC.add<double>("value");
131  desc.add("minGoodStripCharge", descCCC);
132 
133  descriptions.add("mkFitProducerDefault", desc);
134 }
135 
136 std::unique_ptr<mkfit::MkBuilderWrapper> MkFitProducer::beginStream(edm::StreamID iID) const {
137  return std::make_unique<mkfit::MkBuilderWrapper>();
138 }
139 
140 namespace {
141  std::once_flag geometryFlag;
142 }
144  const auto& pixelHits = iEvent.get(pixelHitsToken_);
145  const auto& stripHits = iEvent.get(stripHitsToken_);
146  const auto& eventOfHits = iEvent.get(eventOfHitsToken_);
147  const auto& seeds = iEvent.get(seedToken_);
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  // Initialize the number of layers, has to be done exactly once in
184  // the whole program.
185  // TODO: the mechanism needs to be improved...
186  std::call_once(geometryFlag, [nlayers = mkFitGeom.layerNumberConverter().nLayers()]() {
187  mkfit::ConfigWrapper::setNTotalLayers(nlayers);
188  });
189 
190  // seeds need to be mutable because of the possible cleaning
191  auto seeds_mutable = seeds.seeds();
193 
194  auto lambda = [&]() {
195  mkfit::run_OneIteration(mkFitGeom.trackerInfo(),
196  mkFitIterConfig,
197  eventOfHits.get(),
198  {pixelMaskPtr, &stripMask},
199  streamCache(iID)->get(),
200  seeds_mutable,
201  tracks,
205  };
206 
207  if (limitConcurrency_) {
208  tbb::task_arena arena(1);
209  arena.execute(std::move(lambda));
210  } else {
211  tbb::this_task_arena::isolate(std::move(lambda));
212  }
213 
214  iEvent.emplace(putToken_, std::move(tracks), not backwardFitInCMSSW_);
215 }
216 
217 void MkFitProducer::stripClusterChargeCut(const std::vector<float>& stripClusterCharge, std::vector<bool>& mask) const {
218  if (mask.size() != stripClusterCharge.size()) {
219  throw cms::Exception("LogicError") << "Mask size (" << mask.size() << ") inconsistent with number of hits ("
220  << stripClusterCharge.size() << ")";
221  }
222  for (int i = 0, end = stripClusterCharge.size(); i < end; ++i) {
223  // mask == true means skip the cluster
224  mask[i] = mask[i] || (stripClusterCharge[i] <= minGoodStripCharge_);
225  }
226 }
227 
void setComment(std::string const &value)
const bool seedCleaning_
edm::EDGetTokenT< edm::ContainerMask< edmNew::DetSetVector< SiStripCluster > > > stripMaskToken_
edm::EDGetTokenT< edm::ContainerMask< edmNew::DetSetVector< SiPixelCluster > > > pixelMaskToken_
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
const bool backwardFitInCMSSW_
void stripClusterChargeCut(const std::vector< float > &stripClusterCharge, std::vector< bool > &mask) const
#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
auto const & tracks
cannot be loose
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
const edm::EDGetTokenT< std::vector< float > > stripClusterChargeToken_
const bool limitConcurrency_
bool getData(T &iHolder) const
Definition: EventSetup.h:128
const edm::EDGetTokenT< MkFitHitWrapper > stripHitsToken_
int iEvent
Definition: GenABIO.cc:224
std::function< double(mkfit::Event &, mkfit::MkBuilder &)> buildFunction_
def move
Definition: eostools.py:511
std::unique_ptr< mkfit::MkBuilderWrapper > beginStream(edm::StreamID) const override
bool get(ProductID const &oid, Handle< PROD > &result) const
Definition: Event.h:346
~MkFitProducer() override=default
ParameterDescriptionBase * add(U const &iLabel, T const &value)
const float minGoodStripCharge_
std::vector< Track > TrackVec
OrphanHandle< PROD > emplace(EDPutTokenT< PROD > token, Args &&...args)
puts a new product
Definition: Event.h:433
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
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_
string end
Definition: dataset.py:937
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_
ESGetTokenH3DDVariant esConsumes(std::string const &Reccord, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
tuple clustersToSkip