58 bool isPhase1Barrel(
T subdet) {
64 bool isPhase1Endcap(
T subdet) {
91 const std::vector<const DetLayer*>& detLayers,
95 const tensorflow::Session*
session)
const;
103 bool lastHitWasInvalid,
104 bool lastHitWasChanged)
const;
112 const std::vector<TrajectoryStateOnSurface>& states,
115 const tensorflow::Session*
session,
116 const std::vector<float>&
chi2,
117 const bool rescaledError)
const;
155 pixelClusterIndexToHitToken_{consumes(iConfig.getParameter<
edm::InputTag>(
"mkFitPixelHits"))},
156 stripClusterIndexToHitToken_{consumes(iConfig.getParameter<
edm::InputTag>(
"mkFitStripHits"))},
157 mkfitSeedToken_{consumes<MkFitSeedWrapper>(iConfig.getParameter<
edm::InputTag>(
"mkFitSeeds"))},
158 tracksToken_{consumes<MkFitOutputWrapper>(iConfig.getParameter<
edm::InputTag>(
"tracks"))},
159 seedToken_{consumes<edm::View<TrajectorySeed>>(iConfig.getParameter<
edm::InputTag>(
"seeds"))},
160 propagatorAlongToken_{
161 esConsumes<Propagator, TrackingComponentsRecord>(iConfig.getParameter<
edm::ESInputTag>(
"propagatorAlong"))},
162 propagatorOppositeToken_{esConsumes<Propagator, TrackingComponentsRecord>(
164 mfToken_{esConsumes<MagneticField, IdealMagneticFieldRecord>()},
165 ttrhBuilderToken_{esConsumes<TransientTrackingRecHitBuilder, TransientRecHitRecord>(
167 mkFitGeomToken_{esConsumes<MkFitGeometry, TrackerRecoGeometryRecord>()},
168 tTopoToken_{esConsumes<TrackerTopology, TrackerTopologyRcd>()},
169 putTrackCandidateToken_{produces<TrackCandidateCollection>()},
170 putSeedStopInfoToken_{produces<std::vector<SeedStopInfo>>()},
171 qualityMaxInvPt_{
float(iConfig.getParameter<
double>(
"qualityMaxInvPt"))},
172 qualityMinTheta_{
float(iConfig.getParameter<
double>(
"qualityMinTheta"))},
173 qualityMaxRsq_{
float(
pow(iConfig.getParameter<
double>(
"qualityMaxR"), 2))},
174 qualityMaxZ_{
float(iConfig.getParameter<
double>(
"qualityMaxZ"))},
175 qualityMaxPosErrSq_{
float(
pow(iConfig.getParameter<
double>(
"qualityMaxPosErr"), 2))},
176 qualitySignPt_{iConfig.getParameter<
bool>(
"qualitySignPt")},
177 doErrorRescale_{iConfig.getParameter<
bool>(
"doErrorRescale")},
179 TString(iConfig.getParameter<
edm::InputTag>(
"seeds").
label()).ReplaceAll(
"Seeds",
"").Data())},
180 algoCandSelection_{
bool(iConfig.getParameter<
bool>(
"candMVASel"))},
181 algoCandWorkingPoint_{
float(iConfig.getParameter<
double>(
"candWP"))},
182 bsize_{
int(iConfig.getParameter<
int>(
"batchSize"))},
183 bsToken_(algoCandSelection_ ? consumes<reco::BeamSpot>(
edm::InputTag(
"offlineBeamSpot"))
185 verticesToken_(algoCandSelection_ ? consumes<reco::VertexCollection>(
edm::InputTag(
"firstStepPrimaryVertices"))
187 tfDnnLabel_(iConfig.getParameter<
std::string>(
"tfDnnLabel")),
203 desc.add<
double>(
"qualityMaxInvPt", 100)->setComment(
"max(1/pt) for converted tracks");
204 desc.add<
double>(
"qualityMinTheta", 0.01)->setComment(
"lower bound on theta (or pi-theta) for converted tracks");
205 desc.add<
double>(
"qualityMaxR", 120)->setComment(
"max(R) for the state position for converted tracks");
206 desc.add<
double>(
"qualityMaxZ", 280)->setComment(
"max(|Z|) for the state position for converted tracks");
207 desc.add<
double>(
"qualityMaxPosErr", 100)->setComment(
"max position error for converted tracks");
208 desc.add<
bool>(
"qualitySignPt",
true)->setComment(
"check sign of 1/pt for converted tracks");
210 desc.add<
bool>(
"doErrorRescale",
true)->setComment(
"rescale candidate error before final fit");
214 desc.add<
bool>(
"candMVASel",
false)->setComment(
"flag used to trigger MVA selection at cand level");
215 desc.add<
double>(
"candWP", 0)->setComment(
"MVA selection at cand level working point");
216 desc.add<
int>(
"batchSize", 16)->setComment(
"batch size for cand DNN evaluation");
228 throw cms::Exception(
"LogicError") <<
"TTRHBuilder must be of type TkTransientTrackingRecHitBuilder";
240 const tensorflow::Session*
session =
nullptr;
257 mkFitGeom.detLayers(),
278 const std::vector<const DetLayer*>& detLayers,
282 const tensorflow::Session*
session)
const {
289 std::vector<float>
chi2;
290 std::vector<TrajectoryStateOnSurface> states;
297 LogTrace(
"MkFitOutputConverter") <<
"Candidate " << candIndex <<
" pT " <<
cand.pT() <<
" eta " <<
cand.momEta()
298 <<
" phi " <<
cand.momPhi() <<
" chi2 " <<
cand.chi2();
304 (
cand.state().errors.At(0, 0) +
cand.state().errors.At(1, 1) +
cand.state().errors.At(2, 2)) >
307 <<
"Candidate " << candIndex <<
" failed state quality checks" <<
cand.state().parameters;
312 state.convertFromCCSToGlbCurvilinear();
313 const auto& param =
state.parameters;
316 for (
int i = 0;
i < 5; ++
i) {
317 for (
int j =
i;
j < 5; ++
j) {
326 if (!fts.curvilinearError().posDef()) {
328 <<
"Curvilinear error not pos-def\n" 329 << fts.curvilinearError().matrix() <<
"\ncandidate " << candIndex <<
"ignored";
337 <<
"Fail pos-def check sub2.det for candidate " << candIndex <<
" with fts " << fts;
341 <<
"Fail pos-def check sub3.det for candidate " << candIndex <<
" with fts " << fts;
345 <<
"Fail pos-def check sub4.det for candidate " << candIndex <<
" with fts " << fts;
347 }
else if ((!fts.curvilinearError().matrix().Det2(det)) || det < 0) {
349 <<
"Fail pos-def check det for candidate " << candIndex <<
" with fts " << fts;
358 bool lastHitInvalid =
false;
361 const auto& hitOnTrack =
cand.getHitOnTrack(
i);
362 LogTrace(
"MkFitOutputConverter") <<
" hit on layer " << hitOnTrack.layer <<
" index " << hitOnTrack.index;
363 if (hitOnTrack.index < 0) {
374 const auto* detLayer = detLayers.at(hitOnTrack.layer);
375 if (detLayer ==
nullptr) {
376 throw cms::Exception(
"LogicError") <<
"DetLayer for layer index " << hitOnTrack.layer <<
" is null!";
381 lastHitInvalid =
true;
384 auto const&
hits =
isPixel ? pixelClusterIndexToHit.
hits() : stripClusterIndexToHit.
hits();
388 if (thit.firstClusterRef().isPixel() || thit.detUnit()->type().isEndcap()) {
389 recHits.push_back(
hits[hitOnTrack.index]->clone());
391 recHits.push_back(std::make_unique<SiStripRecHit1D>(
392 thit.localPosition(),
395 thit.firstClusterRef()));
398 if (thit.firstClusterRef().isPixel()) {
399 recHits.push_back(
hits[hitOnTrack.index]->clone());
400 }
else if (thit.firstClusterRef().isPhase2()) {
401 recHits.push_back(std::make_unique<Phase2TrackerRecHit1D>(
402 thit.localPosition(),
405 thit.firstClusterRef().cluster_phase2OT()));
408 LogTrace(
"MkFitOutputConverter") <<
" pos " <<
recHits.back().globalPosition().x() <<
" " 409 <<
recHits.back().globalPosition().y() <<
" " 410 <<
recHits.back().globalPosition().z() <<
" mag2 " 411 <<
recHits.back().globalPosition().mag2() <<
" detid " 412 <<
recHits.back().geographicalId().rawId() <<
" cluster " << hitOnTrack.index;
413 lastHitInvalid =
false;
417 const auto lastHitId =
recHits.back().geographicalId();
427 const auto asub_ph1 =
a.geographicalId().subdetId();
428 const auto bsub_ph1 =
b.geographicalId().subdetId();
429 const auto& apos_ph1 =
a.globalPosition();
430 const auto& bpos_ph1 =
b.globalPosition();
431 if (asub_ph1 != bsub_ph1) {
433 return asub_ph1 < bsub_ph1;
436 if (isPhase1Barrel(asub_ph1)) {
437 return apos_ph1.perp2() < bpos_ph1.perp2();
447 const auto& apos =
a.globalPosition();
448 const auto& bpos =
b.globalPosition();
449 const auto aid =
a.geographicalId().rawId();
450 const auto bid =
b.geographicalId().rawId();
451 const auto asubid =
a.geographicalId().subdetId();
452 const auto bsubid =
b.geographicalId().subdetId();
458 return apos.mag2() < bpos.mag2();
462 return apos.perp2() < bpos.perp2();
471 const bool lastHitChanged = (
recHits.back().geographicalId() != lastHitId);
474 const auto seedIndex =
cand.label();
475 LogTrace(
"MkFitOutputConverter") <<
" from seed " << seedIndex <<
" seed hits";
482 fts.rescaleError(100.);
493 if (!tsosDet.first.isValid()) {
495 <<
"Backward fit of candidate " << candIndex <<
" failed, ignoring the candidate";
506 seeds.refAt(seedIndex),
512 states.push_back(tsosDet.first);
520 reducedOutput.reserve(
output.size());
522 for (
const auto&
score : dnnScores) {
524 reducedOutput.push_back(
output[scoreIndex]);
528 output.swap(reducedOutput);
541 bool lastHitWasInvalid,
542 bool lastHitWasChanged)
const {
546 for (
int i =
hits.size() - 1;
i >= 0; --
i) {
557 const auto& lastHitSurface = firstHits.front()->det()->surface();
561 if (lastHitWasInvalid || lastHitWasChanged) {
562 LogTrace(
"MkFitOutputConverter") <<
"Propagating first opposite, then along, because lastHitWasInvalid? " 563 << lastHitWasInvalid <<
" or lastHitWasChanged? " << lastHitWasChanged;
566 bool doSwitch =
false;
567 const auto& surfacePos = lastHitSurface.position();
568 const auto& lastHitPos = firstHits.front()->globalPosition();
570 const auto lastHitSubdet = firstHits.front()->geographicalId().subdetId();
571 if (isPhase1Barrel(lastHitSubdet)) {
572 doSwitch = (surfacePos.perp2() < lastHitPos.perp2());
574 doSwitch = (surfacePos.z() < lastHitPos.z());
577 const auto lastHitSubdet = firstHits.front()->det()->subDetector();
579 doSwitch = (surfacePos.perp2() < lastHitPos.perp2());
581 doSwitch = (surfacePos.z() < lastHitPos.z());
586 <<
"Propagating first opposite, then along, because surface is inner than the hit; surface perp2 " 587 << surfacePos.perp() <<
" hit " << lastHitPos.perp2() <<
" surface z " << surfacePos.z() <<
" hit " 595 if (!tsosDouble.first.isValid()) {
596 LogDebug(
"MkFitOutputConverter") <<
"Propagating to startingState failed, trying in another direction next";
599 auto& startingState = tsosDouble.first;
601 if (!startingState.isValid()) {
603 <<
"startingState is not valid, FTS was\n" 604 << fts <<
" last hit surface surface:" 605 <<
"\n position " << lastHitSurface.
position() <<
"\n phiSpan " << lastHitSurface.phiSpan().first <<
"," 606 << lastHitSurface.phiSpan().first <<
"\n rSpan " << lastHitSurface.rSpan().first <<
"," 607 << lastHitSurface.rSpan().first <<
"\n zSpan " << lastHitSurface.zSpan().first <<
"," 608 << lastHitSurface.zSpan().first;
609 return std::pair<TrajectoryStateOnSurface, const GeomDet*>();
613 startingState.rescaleError(100.);
619 &
propagatorAlong, &aKFUpdator, &aChi2MeasurementEstimator, firstHits.size(),
nullptr, &hitCloner);
630 LogDebug(
"MkFitOutputConverter") <<
"using a backward fit of :" << firstHits.size() <<
" hits, starting from:\n" 631 << startingState <<
" to get the estimate of the initial state of the track.";
634 edm::LogWarning(
"MkFitOutputConverter") <<
"FitTester: first hits fit failed";
635 return std::pair<TrajectoryStateOnSurface, const GeomDet*>();
648 LogDebug(
"MkFitOutputConverter") <<
"the initial state is found to be:\n:" << firstState
649 <<
"\n it's field pointer is: " << firstState.magneticField()
650 <<
"\n the pointer from the state of the back fit was: " 653 return std::make_pair(firstState, firstMeas.
recHit()->det());
661 auto det =
hits[0].det();
662 if (det ==
nullptr) {
663 throw cms::Exception(
"LogicError") <<
"Got nullptr from the first hit det()";
666 const auto& firstHitSurface = det->surface();
668 auto tsosDouble =
propagatorAlong.propagateWithPath(fts, firstHitSurface);
669 if (!tsosDouble.first.isValid()) {
670 LogDebug(
"MkFitOutputConverter") <<
"Propagating to startingState along momentum failed, trying opposite next";
674 return std::make_pair(tsosDouble.first, det);
678 const std::vector<TrajectoryStateOnSurface>& states,
681 const tensorflow::Session*
session,
682 const std::vector<float>&
chi2,
683 const bool rescaledError)
const {
684 int size_in = (
int)tkCC.size();
685 int nbatches = size_in /
bsize_;
687 std::vector<float>
output(size_in, 0);
691 tensorflow::Tensor
input1(tensorflow::DT_FLOAT, {
bsize_, 29});
692 tensorflow::Tensor
input2(tensorflow::DT_FLOAT, {
bsize_, 1});
694 for (
auto nb = 0; nb < nbatches + 1; nb++) {
695 std::vector<bool> invalidProp(
bsize_,
false);
699 if (itrack >= size_in)
702 auto const& tkC = tkCC.at(itrack);
707 state.rescaleError(1 / 100.
f);
710 tscblBuilder(*
state.freeState(), *
bs);
712 if (!(tsAtClosestApproachTrackCand.
isValid())) {
713 edm::LogVerbatim(
"TrackBuilding") <<
"TrajectoryStateClosestToBeamLine not valid";
714 invalidProp[
nt] =
true;
718 auto const& stateAtPCA = tsAtClosestApproachTrackCand.
trackStateAtPCA();
719 auto v0 = stateAtPCA.position();
720 auto p = stateAtPCA.momentum();
725 reco::Track trk(0, 0,
pos, mom, stateAtPCA.charge(), stateAtPCA.curvilinearError());
733 dzmin = trk.dz(
vertex.position());
734 dxy_zmin = trk.dxy(
vertex.position());
742 for (
auto const&
recHit : tkC.recHits()) {
744 auto const subdet =
recHit.geographicalId().subdetId();
752 input1.matrix<
float>()(
nt, 0) = trk.pt();
756 input1.matrix<
float>()(
nt, 4) =
p.perp();
760 input1.matrix<
float>()(
nt, 8) =
p.perp();
761 input1.matrix<
float>()(
nt, 9) = trk.ptError();
762 input1.matrix<
float>()(
nt, 10) = dxy_zmin;
763 input1.matrix<
float>()(
nt, 11) = dzmin;
764 input1.matrix<
float>()(
nt, 12) = trk.dxy(
bs->position());
765 input1.matrix<
float>()(
nt, 13) = trk.dz(
bs->position());
766 input1.matrix<
float>()(
nt, 14) = trk.dxyError();
767 input1.matrix<
float>()(
nt, 15) = trk.dzError();
769 input1.matrix<
float>()(
nt, 17) = trk.eta();
770 input1.matrix<
float>()(
nt, 18) = trk.phi();
771 input1.matrix<
float>()(
nt, 19) = trk.etaError();
772 input1.matrix<
float>()(
nt, 20) = trk.phiError();
773 input1.matrix<
float>()(
nt, 21) = pix;
792 std::vector<tensorflow::Tensor>
outputs;
797 if (itrack >= size_in)
800 float out0 = 2.0 *
outputs[0].matrix<
float>()(
nt, 0) - 1.0;
void rescaleError(double factor)
Log< level::Info, true > LogVerbatim
static constexpr auto TEC
const edm::EDGetTokenT< MkFitClusterIndexToHit > pixelClusterIndexToHitToken_
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
std::vector< NamedTensor > NamedTensorList
T getParameter(std::string const &) const
unsigned int tobSide(const DetId &id) const
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
const edm::ESGetToken< MkFitGeometry, TrackerRecoGeometryRecord > mkFitGeomToken_
const edm::ESGetToken< Propagator, TrackingComponentsRecord > propagatorOppositeToken_
const LocalTrajectoryError & localError() const
const bool qualitySignPt_
const edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > tTopoToken_
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 MkFitGeometry &mkFitGeom, const TrackerTopology &tTopo, 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
bool isBarrel(GeomDetEnumerators::SubDetector m)
std::vector< TrackCandidate > TrackCandidateCollection
bool propagatedToFirstLayer() const
Global3DPoint GlobalPoint
const edm::EDGetTokenT< reco::BeamSpot > bsToken_
std::vector< Vertex > VertexCollection
collection of Vertex objects
void produce(edm::StreamID, edm::Event &iEvent, const edm::EventSetup &iSetup) const override
const LocalTrajectoryParameters & localParameters() const
std::pair< TrajectoryStateOnSurface, const GeomDet * > backwardFit(const FreeTrajectoryState &fts, const edm::OwnVector< TrackingRecHit > &hits, const Propagator &propagatorAlong, const Propagator &propagatorOpposite, const TkClonerImpl &hitCloner, const bool isPhase1, bool lastHitWasInvalid, bool lastHitWasChanged) const
const edm::EDGetTokenT< MkFitOutputWrapper > tracksToken_
const SurfaceType & surface() const
const edm::EDGetTokenT< reco::VertexCollection > verticesToken_
const std::string tfDnnLabel_
void swap(Association< C > &lhs, Association< C > &rhs)
TrajectoryMeasurement const & lastMeasurement() const
GlobalPoint position() const
std::pair< std::string, Tensor > NamedTensor
const edm::EDPutTokenT< std::vector< SeedStopInfo > > putSeedStopInfoToken_
mkfit::TrackVec const & tracks() const
const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > mfToken_
~MkFitOutputConverter() override=default
const float algoCandWorkingPoint_
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)
const bool doErrorRescale_
Abs< T >::type abs(const T &t)
const edm::EDGetTokenT< edm::View< TrajectorySeed > > seedToken_
const edm::EDPutTokenT< TrackCandidateCollection > putTrackCandidateToken_
#define DEFINE_FWK_MODULE(type)
FTS const & trackStateAtPCA() const
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
const edm::EDGetTokenT< MkFitSeedWrapper > mkfitSeedToken_
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
XYZPointD XYZPoint
point in space with cartesian internal representation
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
const bool algoCandSelection_
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_
const float qualityMaxPosErrSq_
bool isPixel(HitType hitType)
static TrackAlgorithm algoByName(const std::string &name)
const float qualityMinTheta_
ROOT::Math::SMatrix< double, 3, 3, ROOT::Math::MatRepSym< double, 3 > > AlgebraicSymMatrix33
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_
static constexpr auto TID
Power< A, B >::type pow(const A &a, const B &b)
std::pair< TrajectoryStateOnSurface, const GeomDet * > convertInnermostState(const FreeTrajectoryState &fts, const edm::OwnVector< TrackingRecHit > &hits, const Propagator &propagatorAlong, const Propagator &propagatorOpposite) const
const float qualityMaxRsq_
ConstRecHitPointer const & recHit() const
Global3DVector GlobalVector
const edm::ESGetToken< TransientTrackingRecHitBuilder, TransientRecHitRecord > ttrhBuilderToken_
const edm::EDGetTokenT< MkFitClusterIndexToHit > stripClusterIndexToHitToken_
const float qualityMaxInvPt_