CMS 3D CMS Logo

MkFitOutputConverter.cc
Go to the documentation of this file.
2 
7 
15 
19 
22 
31 
38 
39 // mkFit indludes
43 
44 //extra for DNN with cands
51 
52 namespace {
53  template <typename T>
54  bool isBarrel(T subdet) {
55  return subdet == PixelSubdetector::PixelBarrel || subdet == StripSubdetector::TIB ||
56  subdet == StripSubdetector::TOB;
57  }
58 
59  template <typename T>
60  bool isEndcap(T subdet) {
61  return subdet == PixelSubdetector::PixelEndcap || subdet == StripSubdetector::TID ||
62  subdet == StripSubdetector::TEC;
63  }
64 } // namespace
65 
67 public:
68  explicit MkFitOutputConverter(edm::ParameterSet const& iConfig);
69  ~MkFitOutputConverter() override = default;
70 
71  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
72 
73 private:
74  void produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const override;
75 
78  const MkFitClusterIndexToHit& pixelClusterIndexToHit,
79  const MkFitClusterIndexToHit& stripClusterIndexToHit,
81  const MagneticField& mf,
84  const TkClonerImpl& hitCloner,
85  const std::vector<const DetLayer*>& detLayers,
87  const reco::BeamSpot* bs,
89  const tensorflow::Session* session) const;
90 
91  std::pair<TrajectoryStateOnSurface, const GeomDet*> backwardFit(const FreeTrajectoryState& fts,
95  const TkClonerImpl& hitCloner,
96  bool lastHitWasInvalid,
97  bool lastHitWasChanged) const;
98 
99  std::pair<TrajectoryStateOnSurface, const GeomDet*> convertInnermostState(const FreeTrajectoryState& fts,
102  const Propagator& propagatorOpposite) const;
103 
104  std::vector<float> computeDNNs(TrackCandidateCollection const& tkCC,
105  const std::vector<TrajectoryStateOnSurface>& states,
106  const reco::BeamSpot* bs,
108  const tensorflow::Session* session,
109  const std::vector<float>& chi2,
110  const bool rescaledError) const;
111 
125 
126  const float qualityMaxInvPt_;
127  const float qualityMinTheta_;
128  const float qualityMaxRsq_;
129  const float qualityMaxZ_;
130  const float qualityMaxPosErrSq_;
131  const bool qualitySignPt_;
132 
133  const bool doErrorRescale_;
134 
135  const int algo_;
136  const bool algoCandSelection_;
138  const int bsize_;
143 };
144 
146  : eventOfHitsToken_{consumes<MkFitEventOfHits>(iConfig.getParameter<edm::InputTag>("mkFitEventOfHits"))},
147  pixelClusterIndexToHitToken_{consumes(iConfig.getParameter<edm::InputTag>("mkFitPixelHits"))},
148  stripClusterIndexToHitToken_{consumes(iConfig.getParameter<edm::InputTag>("mkFitStripHits"))},
149  mkfitSeedToken_{consumes<MkFitSeedWrapper>(iConfig.getParameter<edm::InputTag>("mkFitSeeds"))},
150  tracksToken_{consumes<MkFitOutputWrapper>(iConfig.getParameter<edm::InputTag>("tracks"))},
151  seedToken_{consumes<edm::View<TrajectorySeed>>(iConfig.getParameter<edm::InputTag>("seeds"))},
152  propagatorAlongToken_{
153  esConsumes<Propagator, TrackingComponentsRecord>(iConfig.getParameter<edm::ESInputTag>("propagatorAlong"))},
154  propagatorOppositeToken_{esConsumes<Propagator, TrackingComponentsRecord>(
155  iConfig.getParameter<edm::ESInputTag>("propagatorOpposite"))},
156  mfToken_{esConsumes<MagneticField, IdealMagneticFieldRecord>()},
157  ttrhBuilderToken_{esConsumes<TransientTrackingRecHitBuilder, TransientRecHitRecord>(
158  iConfig.getParameter<edm::ESInputTag>("ttrhBuilder"))},
159  mkFitGeomToken_{esConsumes<MkFitGeometry, TrackerRecoGeometryRecord>()},
160  putTrackCandidateToken_{produces<TrackCandidateCollection>()},
161  putSeedStopInfoToken_{produces<std::vector<SeedStopInfo>>()},
162  qualityMaxInvPt_{float(iConfig.getParameter<double>("qualityMaxInvPt"))},
163  qualityMinTheta_{float(iConfig.getParameter<double>("qualityMinTheta"))},
164  qualityMaxRsq_{float(pow(iConfig.getParameter<double>("qualityMaxR"), 2))},
165  qualityMaxZ_{float(iConfig.getParameter<double>("qualityMaxZ"))},
166  qualityMaxPosErrSq_{float(pow(iConfig.getParameter<double>("qualityMaxPosErr"), 2))},
167  qualitySignPt_{iConfig.getParameter<bool>("qualitySignPt")},
168  doErrorRescale_{iConfig.getParameter<bool>("doErrorRescale")},
170  TString(iConfig.getParameter<edm::InputTag>("seeds").label()).ReplaceAll("Seeds", "").Data())},
171  algoCandSelection_{bool(iConfig.getParameter<bool>("candMVASel"))},
172  algoCandWorkingPoint_{float(iConfig.getParameter<double>("candWP"))},
173  bsize_{int(iConfig.getParameter<int>("batchSize"))},
174  bsToken_(algoCandSelection_ ? consumes<reco::BeamSpot>(edm::InputTag("offlineBeamSpot"))
176  verticesToken_(algoCandSelection_ ? consumes<reco::VertexCollection>(edm::InputTag("firstStepPrimaryVertices"))
178  tfDnnLabel_(iConfig.getParameter<std::string>("tfDnnLabel")),
179  tfDnnToken_(esConsumes(edm::ESInputTag("", tfDnnLabel_))) {}
180 
183 
184  desc.add("mkFitEventOfHits", edm::InputTag{"mkFitEventOfHits"});
185  desc.add("mkFitPixelHits", edm::InputTag{"mkFitSiPixelHits"});
186  desc.add("mkFitStripHits", edm::InputTag{"mkFitSiStripHits"});
187  desc.add("mkFitSeeds", edm::InputTag{"mkFitSeedConverter"});
188  desc.add("tracks", edm::InputTag{"mkFitProducer"});
189  desc.add("seeds", edm::InputTag{"initialStepSeeds"});
190  desc.add("ttrhBuilder", edm::ESInputTag{"", "WithTrackAngle"});
191  desc.add("propagatorAlong", edm::ESInputTag{"", "PropagatorWithMaterial"});
192  desc.add("propagatorOpposite", edm::ESInputTag{"", "PropagatorWithMaterialOpposite"});
193 
194  desc.add<double>("qualityMaxInvPt", 100)->setComment("max(1/pt) for converted tracks");
195  desc.add<double>("qualityMinTheta", 0.01)->setComment("lower bound on theta (or pi-theta) for converted tracks");
196  desc.add<double>("qualityMaxR", 120)->setComment("max(R) for the state position for converted tracks");
197  desc.add<double>("qualityMaxZ", 280)->setComment("max(|Z|) for the state position for converted tracks");
198  desc.add<double>("qualityMaxPosErr", 100)->setComment("max position error for converted tracks");
199  desc.add<bool>("qualitySignPt", true)->setComment("check sign of 1/pt for converted tracks");
200 
201  desc.add<bool>("doErrorRescale", true)->setComment("rescale candidate error before final fit");
202 
203  desc.add<std::string>("tfDnnLabel", "trackSelectionTf");
204 
205  desc.add<bool>("candMVASel", false)->setComment("flag used to trigger MVA selection at cand level");
206  desc.add<double>("candWP", 0)->setComment("MVA selection at cand level working point");
207  desc.add<int>("batchSize", 16)->setComment("batch size for cand DNN evaluation");
208 
209  descriptions.addWithDefaultLabel(desc);
210 }
211 
213  const auto& seeds = iEvent.get(seedToken_);
214  const auto& mkfitSeeds = iEvent.get(mkfitSeedToken_);
215 
216  const auto& ttrhBuilder = iSetup.getData(ttrhBuilderToken_);
217  const auto* tkBuilder = dynamic_cast<TkTransientTrackingRecHitBuilder const*>(&ttrhBuilder);
218  if (!tkBuilder) {
219  throw cms::Exception("LogicError") << "TTRHBuilder must be of type TkTransientTrackingRecHitBuilder";
220  }
221  const auto& mkFitGeom = iSetup.getData(mkFitGeomToken_);
222 
223  // primary vertices under the algo_ because in initialStepPreSplitting there are no firstStepPrimaryVertices
224  // beamspot as well since the producer can be used in hlt
225  const reco::VertexCollection* vertices = nullptr;
226  const reco::BeamSpot* beamspot = nullptr;
227  if (algoCandSelection_) {
229  beamspot = &iEvent.get(bsToken_);
230  }
231 
232  const tensorflow::Session* session = nullptr;
233  if (algoCandSelection_)
234  session = iSetup.getData(tfDnnToken_).getSession();
235 
236  // Convert mkfit presentation back to CMSSW
239  iEvent.get(eventOfHitsToken_).get(),
242  seeds,
243  iSetup.getData(mfToken_),
246  tkBuilder->cloner(),
247  mkFitGeom.detLayers(),
248  mkfitSeeds.seeds(),
249  beamspot,
250  vertices,
251  session));
252 
253  // TODO: SeedStopInfo is currently unfilled
254  iEvent.emplace(putSeedStopInfoToken_, seeds.size());
255 }
256 
259  const MkFitClusterIndexToHit& pixelClusterIndexToHit,
260  const MkFitClusterIndexToHit& stripClusterIndexToHit,
262  const MagneticField& mf,
265  const TkClonerImpl& hitCloner,
266  const std::vector<const DetLayer*>& detLayers,
268  const reco::BeamSpot* bs,
270  const tensorflow::Session* session) const {
272  const auto& candidates = mkFitOutput.tracks();
273  output.reserve(candidates.size());
274 
275  LogTrace("MkFitOutputConverter") << "Number of candidates " << candidates.size();
276 
277  std::vector<float> chi2;
278  std::vector<TrajectoryStateOnSurface> states;
279  chi2.reserve(candidates.size());
280  states.reserve(candidates.size());
281 
282  int candIndex = -1;
283  for (const auto& cand : candidates) {
284  ++candIndex;
285  LogTrace("MkFitOutputConverter") << "Candidate " << candIndex << " pT " << cand.pT() << " eta " << cand.momEta()
286  << " phi " << cand.momPhi() << " chi2 " << cand.chi2();
287 
288  // state: check for basic quality first
289  if (cand.state().invpT() > qualityMaxInvPt_ || (qualitySignPt_ && cand.state().invpT() < 0) ||
290  cand.state().theta() < qualityMinTheta_ || (M_PI - cand.state().theta()) < qualityMinTheta_ ||
291  cand.state().posRsq() > qualityMaxRsq_ || std::abs(cand.state().z()) > qualityMaxZ_ ||
292  (cand.state().errors.At(0, 0) + cand.state().errors.At(1, 1) + cand.state().errors.At(2, 2)) >
294  edm::LogInfo("MkFitOutputConverter")
295  << "Candidate " << candIndex << " failed state quality checks" << cand.state().parameters;
296  continue;
297  }
298 
299  auto state = cand.state(); // copy because have to modify
300  state.convertFromCCSToGlbCurvilinear();
301  const auto& param = state.parameters;
302  const auto& err = state.errors;
304  for (int i = 0; i < 5; ++i) {
305  for (int j = i; j < 5; ++j) {
306  cov[i][j] = err.At(i, j);
307  }
308  }
309 
310  auto fts = FreeTrajectoryState(
312  GlobalPoint(param[0], param[1], param[2]), GlobalVector(param[3], param[4], param[5]), state.charge, &mf),
314  if (!fts.curvilinearError().posDef()) {
315  edm::LogInfo("MkFitOutputConverter")
316  << "Curvilinear error not pos-def\n"
317  << fts.curvilinearError().matrix() << "\ncandidate " << candIndex << "ignored";
318  continue;
319  }
320 
321  //Sylvester's criterion, start from the smaller submatrix size
322  double det = 0;
323  if ((!fts.curvilinearError().matrix().Sub<AlgebraicSymMatrix22>(0, 0).Det(det)) || det < 0) {
324  edm::LogInfo("MkFitOutputConverter")
325  << "Fail pos-def check sub2.det for candidate " << candIndex << " with fts " << fts;
326  continue;
327  } else if ((!fts.curvilinearError().matrix().Sub<AlgebraicSymMatrix33>(0, 0).Det(det)) || det < 0) {
328  edm::LogInfo("MkFitOutputConverter")
329  << "Fail pos-def check sub3.det for candidate " << candIndex << " with fts " << fts;
330  continue;
331  } else if ((!fts.curvilinearError().matrix().Sub<AlgebraicSymMatrix44>(0, 0).Det(det)) || det < 0) {
332  edm::LogInfo("MkFitOutputConverter")
333  << "Fail pos-def check sub4.det for candidate " << candIndex << " with fts " << fts;
334  continue;
335  } else if ((!fts.curvilinearError().matrix().Det2(det)) || det < 0) {
336  edm::LogInfo("MkFitOutputConverter")
337  << "Fail pos-def check det for candidate " << candIndex << " with fts " << fts;
338  continue;
339  }
340 
341  // hits
343  // nTotalHits() gives sum of valid hits (nFoundHits()) and invalid/missing hits.
344  const int nhits = cand.nTotalHits();
345  bool lastHitInvalid = false;
346  for (int i = 0; i < nhits; ++i) {
347  const auto& hitOnTrack = cand.getHitOnTrack(i);
348  LogTrace("MkFitOutputConverter") << " hit on layer " << hitOnTrack.layer << " index " << hitOnTrack.index;
349  if (hitOnTrack.index < 0) {
350  // See index-desc.txt file in mkFit for description of negative values
351  //
352  // In order to use the regular InvalidTrackingRecHit I'd need
353  // a GeomDet (and "unfortunately" that is needed in
354  // TrackProducer).
355  //
356  // I guess we could take the track state and propagate it to
357  // each layer to find the actual module the track crosses, and
358  // check whether it is active or not to be able to mark
359  // inactive hits
360  const auto* detLayer = detLayers.at(hitOnTrack.layer);
361  if (detLayer == nullptr) {
362  throw cms::Exception("LogicError") << "DetLayer for layer index " << hitOnTrack.layer << " is null!";
363  }
364  // In principle an InvalidTrackingRecHitNoDet could be
365  // inserted here, but it seems that it is best to deal with
366  // them in the TrackProducer.
367  lastHitInvalid = true;
368  } else {
369  auto const isPixel = eventOfHits[hitOnTrack.layer].is_pixel();
370  auto const& hits = isPixel ? pixelClusterIndexToHit.hits() : stripClusterIndexToHit.hits();
371 
372  auto const& thit = static_cast<BaseTrackerRecHit const&>(*hits[hitOnTrack.index]);
373  if (thit.firstClusterRef().isPixel() || thit.detUnit()->type().isEndcap()) {
374  recHits.push_back(hits[hitOnTrack.index]->clone());
375  } else {
376  recHits.push_back(std::make_unique<SiStripRecHit1D>(
377  thit.localPosition(),
378  LocalError(thit.localPositionError().xx(), 0.f, std::numeric_limits<float>::max()),
379  *thit.det(),
380  thit.firstClusterRef()));
381  }
382  LogTrace("MkFitOutputConverter") << " pos " << recHits.back().globalPosition().x() << " "
383  << recHits.back().globalPosition().y() << " "
384  << recHits.back().globalPosition().z() << " mag2 "
385  << recHits.back().globalPosition().mag2() << " detid "
386  << recHits.back().geographicalId().rawId() << " cluster " << hitOnTrack.index;
387  lastHitInvalid = false;
388  }
389  }
390 
391  const auto lastHitId = recHits.back().geographicalId();
392 
393  // MkFit hits are *not* in the order of propagation, sort by 3D radius for now (as we don't have loopers)
394  // TODO: Improve the sorting (extract keys? maybe even bubble sort would work well as the hits are almost in the correct order)
395  recHits.sort([](const auto& a, const auto& b) {
396  const auto asub = a.geographicalId().subdetId();
397  const auto bsub = b.geographicalId().subdetId();
398  if (asub != bsub) {
399  // Subdetector order (BPix, FPix, TIB, TID, TOB, TEC) corresponds also the navigation
400  return asub < bsub;
401  }
402 
403  const auto& apos = a.globalPosition();
404  const auto& bpos = b.globalPosition();
405 
406  if (isBarrel(asub)) {
407  return apos.perp2() < bpos.perp2();
408  }
409  return std::abs(apos.z()) < std::abs(bpos.z());
410  });
411 
412  const bool lastHitChanged = (recHits.back().geographicalId() != lastHitId); // TODO: make use of the bools
413 
414  // seed
415  const auto seedIndex = cand.label();
416  LogTrace("MkFitOutputConverter") << " from seed " << seedIndex << " seed hits";
417 
418  // Rescale candidate error if candidate is already propagated to first layer,
419  // to be consistent with TransientInitialStateEstimator::innerState used in CkfTrackCandidateMakerBase
420  // Error is only rescaled for candidates propagated to first layer;
421  // otherwise, candidates undergo backwardFit where error is already rescaled
422  if (mkFitOutput.propagatedToFirstLayer() && doErrorRescale_)
423  fts.rescaleError(100.);
424  auto tsosDet =
425  mkFitOutput.propagatedToFirstLayer()
427  : backwardFit(fts, recHits, propagatorAlong, propagatorOpposite, hitCloner, lastHitInvalid, lastHitChanged);
428  if (!tsosDet.first.isValid()) {
429  edm::LogInfo("MkFitOutputConverter")
430  << "Backward fit of candidate " << candIndex << " failed, ignoring the candidate";
431  continue;
432  }
433 
434  // convert to persistent, from CkfTrackCandidateMakerBase
435  auto pstate = trajectoryStateTransform::persistentState(tsosDet.first, tsosDet.second->geographicalId().rawId());
436 
437  output.emplace_back(
438  recHits,
439  seeds.at(seedIndex),
440  pstate,
441  seeds.refAt(seedIndex),
442  0, // mkFit does not produce loopers, so set nLoops=0
443  static_cast<uint8_t>(StopReason::UNINITIALIZED) // TODO: ignore details of stopping reason as well for now
444  );
445 
446  chi2.push_back(cand.chi2());
447  states.push_back(tsosDet.first);
448  }
449 
450  if (algoCandSelection_) {
451  const auto& dnnScores = computeDNNs(
452  output, states, bs, vertices, session, chi2, mkFitOutput.propagatedToFirstLayer() && doErrorRescale_);
453 
454  TrackCandidateCollection reducedOutput;
455  reducedOutput.reserve(output.size());
456  int scoreIndex = 0;
457  for (const auto& score : dnnScores) {
459  reducedOutput.push_back(output[scoreIndex]);
460  scoreIndex++;
461  }
462 
463  output.swap(reducedOutput);
464  }
465 
466  return output;
467 }
468 
469 std::pair<TrajectoryStateOnSurface, const GeomDet*> MkFitOutputConverter::backwardFit(
470  const FreeTrajectoryState& fts,
474  const TkClonerImpl& hitCloner,
475  bool lastHitWasInvalid,
476  bool lastHitWasChanged) const {
477  // First filter valid hits as in TransientInitialStateEstimator
479 
480  for (int i = hits.size() - 1; i >= 0; --i) {
481  if (hits[i].det()) {
482  // TransientTrackingRecHit::ConstRecHitContainer has shared_ptr,
483  // and it is passed to backFitter below so it is really needed
484  // to keep the interface. Since we keep the ownership in hits,
485  // let's disable the deleter.
486  firstHits.emplace_back(&(hits[i]), edm::do_nothing_deleter{});
487  }
488  }
489 
490  // Then propagate along to the surface of the last hit to get a TSOS
491  const auto& lastHitSurface = firstHits.front()->det()->surface();
492 
493  const Propagator* tryFirst = &propagatorAlong;
494  const Propagator* trySecond = &propagatorOpposite;
495  if (lastHitWasInvalid || lastHitWasChanged) {
496  LogTrace("MkFitOutputConverter") << "Propagating first opposite, then along, because lastHitWasInvalid? "
497  << lastHitWasInvalid << " or lastHitWasChanged? " << lastHitWasChanged;
498  std::swap(tryFirst, trySecond);
499  } else {
500  const auto lastHitSubdet = firstHits.front()->geographicalId().subdetId();
501  const auto& surfacePos = lastHitSurface.position();
502  const auto& lastHitPos = firstHits.front()->globalPosition();
503  bool doSwitch = false;
504  if (isBarrel(lastHitSubdet)) {
505  doSwitch = (surfacePos.perp2() < lastHitPos.perp2());
506  } else {
507  doSwitch = (surfacePos.z() < lastHitPos.z());
508  }
509  if (doSwitch) {
510  LogTrace("MkFitOutputConverter")
511  << "Propagating first opposite, then along, because surface is inner than the hit; surface perp2 "
512  << surfacePos.perp() << " hit " << lastHitPos.perp2() << " surface z " << surfacePos.z() << " hit "
513  << lastHitPos.z();
514 
515  std::swap(tryFirst, trySecond);
516  }
517  }
518 
519  auto tsosDouble = tryFirst->propagateWithPath(fts, lastHitSurface);
520  if (!tsosDouble.first.isValid()) {
521  LogDebug("MkFitOutputConverter") << "Propagating to startingState failed, trying in another direction next";
522  tsosDouble = trySecond->propagateWithPath(fts, lastHitSurface);
523  }
524  auto& startingState = tsosDouble.first;
525 
526  if (!startingState.isValid()) {
527  edm::LogWarning("MkFitOutputConverter")
528  << "startingState is not valid, FTS was\n"
529  << fts << " last hit surface surface:"
530  << "\n position " << lastHitSurface.position() << "\n phiSpan " << lastHitSurface.phiSpan().first << ","
531  << lastHitSurface.phiSpan().first << "\n rSpan " << lastHitSurface.rSpan().first << ","
532  << lastHitSurface.rSpan().first << "\n zSpan " << lastHitSurface.zSpan().first << ","
533  << lastHitSurface.zSpan().first;
534  return std::pair<TrajectoryStateOnSurface, const GeomDet*>();
535  }
536 
537  // Then return back to the logic from TransientInitialStateEstimator
538  startingState.rescaleError(100.);
539 
540  // avoid cloning
541  KFUpdator const aKFUpdator;
542  Chi2MeasurementEstimator const aChi2MeasurementEstimator(100., 3);
543  KFTrajectoryFitter backFitter(
544  &propagatorAlong, &aKFUpdator, &aChi2MeasurementEstimator, firstHits.size(), nullptr, &hitCloner);
545 
546  // assume for now that the propagation in mkfit always alongMomentum
547  PropagationDirection backFitDirection = oppositeToMomentum;
548 
549  // only direction matters in this context
551 
552  // ignore loopers for now
553  Trajectory fitres = backFitter.fitOne(fakeSeed, firstHits, startingState, TrajectoryFitter::standard);
554 
555  LogDebug("MkFitOutputConverter") << "using a backward fit of :" << firstHits.size() << " hits, starting from:\n"
556  << startingState << " to get the estimate of the initial state of the track.";
557 
558  if (!fitres.isValid()) {
559  edm::LogWarning("MkFitOutputConverter") << "FitTester: first hits fit failed";
560  return std::pair<TrajectoryStateOnSurface, const GeomDet*>();
561  }
562 
563  TrajectoryMeasurement const& firstMeas = fitres.lastMeasurement();
564 
565  // magnetic field can be different!
566  TrajectoryStateOnSurface firstState(firstMeas.updatedState().localParameters(),
567  firstMeas.updatedState().localError(),
568  firstMeas.updatedState().surface(),
569  propagatorAlong.magneticField());
570 
571  firstState.rescaleError(100.);
572 
573  LogDebug("MkFitOutputConverter") << "the initial state is found to be:\n:" << firstState
574  << "\n it's field pointer is: " << firstState.magneticField()
575  << "\n the pointer from the state of the back fit was: "
576  << firstMeas.updatedState().magneticField();
577 
578  return std::make_pair(firstState, firstMeas.recHit()->det());
579 }
580 
581 std::pair<TrajectoryStateOnSurface, const GeomDet*> MkFitOutputConverter::convertInnermostState(
582  const FreeTrajectoryState& fts,
585  const Propagator& propagatorOpposite) const {
586  auto det = hits[0].det();
587  if (det == nullptr) {
588  throw cms::Exception("LogicError") << "Got nullptr from the first hit det()";
589  }
590 
591  const auto& firstHitSurface = det->surface();
592 
593  auto tsosDouble = propagatorAlong.propagateWithPath(fts, firstHitSurface);
594  if (!tsosDouble.first.isValid()) {
595  LogDebug("MkFitOutputConverter") << "Propagating to startingState along momentum failed, trying opposite next";
596  tsosDouble = propagatorOpposite.propagateWithPath(fts, firstHitSurface);
597  }
598 
599  return std::make_pair(tsosDouble.first, det);
600 }
601 
603  const std::vector<TrajectoryStateOnSurface>& states,
604  const reco::BeamSpot* bs,
606  const tensorflow::Session* session,
607  const std::vector<float>& chi2,
608  const bool rescaledError) const {
609  int size_in = (int)tkCC.size();
610  int nbatches = size_in / bsize_;
611 
612  std::vector<float> output(size_in, 0);
613 
614  TSCBLBuilderNoMaterial tscblBuilder;
615 
616  tensorflow::Tensor input1(tensorflow::DT_FLOAT, {bsize_, 29});
617  tensorflow::Tensor input2(tensorflow::DT_FLOAT, {bsize_, 1});
618 
619  for (auto nb = 0; nb < nbatches + 1; nb++) {
620  std::vector<bool> invalidProp(bsize_, false);
621 
622  for (auto nt = 0; nt < bsize_; nt++) {
623  int itrack = nt + bsize_ * nb;
624  if (itrack >= size_in)
625  continue;
626 
627  auto const& tkC = tkCC.at(itrack);
628 
629  TrajectoryStateOnSurface state = states.at(itrack);
630 
631  if (rescaledError)
632  state.rescaleError(1 / 100.f);
633 
634  TrajectoryStateClosestToBeamLine tsAtClosestApproachTrackCand =
635  tscblBuilder(*state.freeState(), *bs); //as in TrackProducerAlgorithm
636 
637  if (!(tsAtClosestApproachTrackCand.isValid())) {
638  edm::LogVerbatim("TrackBuilding") << "TrajectoryStateClosestToBeamLine not valid";
639  invalidProp[nt] = true;
640  continue;
641  }
642 
643  auto const& stateAtPCA = tsAtClosestApproachTrackCand.trackStateAtPCA();
644  auto v0 = stateAtPCA.position();
645  auto p = stateAtPCA.momentum();
646  math::XYZPoint pos(v0.x(), v0.y(), v0.z());
647  math::XYZVector mom(p.x(), p.y(), p.z());
648 
649  //pseudo track for access to easy methods
650  reco::Track trk(0, 0, pos, mom, stateAtPCA.charge(), stateAtPCA.curvilinearError());
651 
652  // get best vertex
653  float dzmin = std::numeric_limits<float>::max();
654  float dxy_zmin = 0;
655 
656  for (auto const& vertex : *vertices) {
657  if (std::abs(trk.dz(vertex.position())) < dzmin) {
658  dzmin = trk.dz(vertex.position());
659  dxy_zmin = trk.dxy(vertex.position());
660  }
661  }
662 
663  // loop over the RecHits
664  int ndof = 0;
665  int pix = 0;
666  int strip = 0;
667  for (auto const& recHit : tkC.recHits()) {
668  ndof += recHit.dimension();
669  auto const subdet = recHit.geographicalId().subdetId();
671  pix++;
672  else
673  strip++;
674  }
675  ndof = ndof - 5;
676 
677  input1.matrix<float>()(nt, 0) = trk.pt(); //using inner track only
678  input1.matrix<float>()(nt, 1) = p.x();
679  input1.matrix<float>()(nt, 2) = p.y();
680  input1.matrix<float>()(nt, 3) = p.z();
681  input1.matrix<float>()(nt, 4) = p.perp();
682  input1.matrix<float>()(nt, 5) = p.x();
683  input1.matrix<float>()(nt, 6) = p.y();
684  input1.matrix<float>()(nt, 7) = p.z();
685  input1.matrix<float>()(nt, 8) = p.perp();
686  input1.matrix<float>()(nt, 9) = trk.ptError();
687  input1.matrix<float>()(nt, 10) = dxy_zmin;
688  input1.matrix<float>()(nt, 11) = dzmin;
689  input1.matrix<float>()(nt, 12) = trk.dxy(bs->position());
690  input1.matrix<float>()(nt, 13) = trk.dz(bs->position());
691  input1.matrix<float>()(nt, 14) = trk.dxyError();
692  input1.matrix<float>()(nt, 15) = trk.dzError();
693  input1.matrix<float>()(nt, 16) = ndof > 0 ? chi2[itrack] / ndof : chi2[itrack] * 1e6;
694  input1.matrix<float>()(nt, 17) = trk.eta();
695  input1.matrix<float>()(nt, 18) = trk.phi();
696  input1.matrix<float>()(nt, 19) = trk.etaError();
697  input1.matrix<float>()(nt, 20) = trk.phiError();
698  input1.matrix<float>()(nt, 21) = pix;
699  input1.matrix<float>()(nt, 22) = strip;
700  input1.matrix<float>()(nt, 23) = ndof;
701  input1.matrix<float>()(nt, 24) = 0;
702  input1.matrix<float>()(nt, 25) = 0;
703  input1.matrix<float>()(nt, 26) = 0;
704  input1.matrix<float>()(nt, 27) = 0;
705  input1.matrix<float>()(nt, 28) = 0;
706 
707  input2.matrix<float>()(nt, 0) = algo_;
708  }
709 
710  //inputs finalized
712  inputs.resize(2);
715 
716  //eval and rescale
717  std::vector<tensorflow::Tensor> outputs;
718  tensorflow::run(session, inputs, {"Identity"}, &outputs);
719 
720  for (auto nt = 0; nt < bsize_; nt++) {
721  int itrack = nt + bsize_ * nb;
722  if (itrack >= size_in)
723  continue;
724 
725  float out0 = 2.0 * outputs[0].matrix<float>()(nt, 0) - 1.0;
726  if (invalidProp[nt])
727  out0 = -1;
728 
729  output[itrack] = out0;
730  }
731  }
732 
733  return output;
734 }
735 
Log< level::Info, true > LogVerbatim
static constexpr auto TEC
const edm::EDGetTokenT< MkFitClusterIndexToHit > pixelClusterIndexToHitToken_
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
std::vector< NamedTensor > NamedTensorList
Definition: TensorFlow.h:31
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
bool isValid() const
Definition: Trajectory.h:257
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
const edm::ESGetToken< MkFitGeometry, TrackerRecoGeometryRecord > mkFitGeomToken_
const edm::ESGetToken< Propagator, TrackingComponentsRecord > propagatorOppositeToken_
const LocalTrajectoryError & localError() const
TrackCandidateCollection convertCandidates(const MkFitOutputWrapper &mkFitOutput, const mkfit::EventOfHits &eventOfHits, const MkFitClusterIndexToHit &pixelClusterIndexToHit, const MkFitClusterIndexToHit &stripClusterIndexToHit, const edm::View< TrajectorySeed > &seeds, const MagneticField &mf, const Propagator &propagatorAlong, const Propagator &propagatorOpposite, const TkClonerImpl &hitCloner, const std::vector< const DetLayer *> &detLayers, const mkfit::TrackVec &mkFitSeeds, const reco::BeamSpot *bs, const reco::VertexCollection *vertices, const tensorflow::Session *session) const
std::pair< TrajectoryStateOnSurface, const GeomDet * > backwardFit(const FreeTrajectoryState &fts, const edm::OwnVector< TrackingRecHit > &hits, const Propagator &propagatorAlong, const Propagator &propagatorOpposite, const TkClonerImpl &hitCloner, bool lastHitWasInvalid, bool lastHitWasChanged) const
std::vector< TrackCandidate > TrackCandidateCollection
bool propagatedToFirstLayer() const
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
PTrajectoryStateOnDet persistentState(const TrajectoryStateOnSurface &ts, unsigned int detid)
GeometricSearchDet Det
Definition: DetBelowR.h:8
const edm::EDGetTokenT< reco::BeamSpot > bsToken_
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
void produce(edm::StreamID, edm::Event &iEvent, const edm::EventSetup &iSetup) const override
const LocalTrajectoryParameters & localParameters() const
std::string const & label() const
Definition: InputTag.h:36
PropagationDirection
const edm::EDGetTokenT< MkFitOutputWrapper > tracksToken_
const SurfaceType & surface() const
const edm::EDGetTokenT< reco::VertexCollection > verticesToken_
const std::string tfDnnLabel_
#define input2
Definition: AMPTWrapper.h:159
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:112
TrajectoryMeasurement const & lastMeasurement() const
Definition: Trajectory.h:150
#define LogTrace(id)
GlobalPoint position() const
std::pair< std::string, Tensor > NamedTensor
Definition: TensorFlow.h:30
const edm::EDPutTokenT< std::vector< SeedStopInfo > > putSeedStopInfoToken_
int iEvent
Definition: GenABIO.cc:224
mkfit::TrackVec const & tracks() const
const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > mfToken_
~MkFitOutputConverter() override=default
MkFitOutputConverter(edm::ParameterSet const &iConfig)
void run(Session *session, const NamedTensorList &inputs, const std::vector< std::string > &outputNames, std::vector< Tensor > *outputs, const thread::ThreadPoolOptions &threadPoolOptions)
Definition: TensorFlow.cc:259
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const edm::EDGetTokenT< edm::View< TrajectorySeed > > seedToken_
const edm::EDPutTokenT< TrackCandidateCollection > putTrackCandidateToken_
double f[11][100]
#define input1
Definition: AMPTWrapper.h:139
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
ROOT::Math::SMatrix< double, 4, 4, ROOT::Math::MatRepSym< double, 4 > > AlgebraicSymMatrix44
static constexpr auto TOB
virtual std::pair< TrajectoryStateOnSurface, double > propagateWithPath(const FreeTrajectoryState &, const Surface &) const final
Definition: Propagator.cc:10
bool isEndcap(GeomDetEnumerators::SubDetector m)
const edm::EDGetTokenT< MkFitSeedWrapper > mkfitSeedToken_
int nt
Definition: AMPTWrapper.h:42
#define M_PI
std::vector< ConstRecHitPointer > ConstRecHitContainer
Log< level::Info, false > LogInfo
std::vector< Track > TrackVec
static constexpr auto TIB
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
double b
Definition: hdecay.h:120
ROOT::Math::SMatrix< double, 2, 2, ROOT::Math::MatRepSym< double, 2 > > AlgebraicSymMatrix22
TrajectoryStateOnSurface const & updatedState() const
std::vector< float > computeDNNs(TrackCandidateCollection const &tkCC, const std::vector< TrajectoryStateOnSurface > &states, const reco::BeamSpot *bs, const reco::VertexCollection *vertices, const tensorflow::Session *session, const std::vector< float > &chi2, const bool rescaledError) const
const edm::EDGetTokenT< MkFitEventOfHits > eventOfHitsToken_
double a
Definition: hdecay.h:121
bool isPixel(HitType hitType)
static TrackAlgorithm algoByName(const std::string &name)
Definition: TrackBase.cc:137
ROOT::Math::SMatrix< double, 3, 3, ROOT::Math::MatRepSym< double, 3 > > AlgebraicSymMatrix33
Definition: output.py:1
const edm::ESGetToken< Propagator, TrackingComponentsRecord > propagatorAlongToken_
const MagneticField * magneticField() const
std::vector< TrackingRecHit const * > & hits()
Log< level::Warning, false > LogWarning
const edm::ESGetToken< TfGraphDefWrapper, TfGraphRecord > tfDnnToken_
long double T
static constexpr auto TID
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
std::pair< TrajectoryStateOnSurface, const GeomDet * > convertInnermostState(const FreeTrajectoryState &fts, const edm::OwnVector< TrackingRecHit > &hits, const Propagator &propagatorAlong, const Propagator &propagatorOpposite) const
ConstRecHitPointer const & recHit() const
Global3DVector GlobalVector
Definition: GlobalVector.h:10
const edm::ESGetToken< TransientTrackingRecHitBuilder, TransientRecHitRecord > ttrhBuilderToken_
#define LogDebug(id)
const edm::EDGetTokenT< MkFitClusterIndexToHit > stripClusterIndexToHitToken_