87 const std::vector<const DetLayer*>& detLayers,
91 const tensorflow::Session* session)
const;
98 bool lastHitWasInvalid,
99 bool lastHitWasChanged)
const;
107 const std::vector<TrajectoryStateOnSurface>& states,
110 const tensorflow::Session* session,
111 const std::vector<float>&
chi2,
112 const bool rescaledError)
const;
149 pixelClusterIndexToHitToken_{consumes(iConfig.getParameter<
edm::InputTag>(
"mkFitPixelHits"))},
150 stripClusterIndexToHitToken_{consumes(iConfig.getParameter<
edm::InputTag>(
"mkFitStripHits"))},
151 mkfitSeedToken_{consumes<MkFitSeedWrapper>(iConfig.getParameter<
edm::InputTag>(
"mkFitSeeds"))},
152 tracksToken_{consumes<MkFitOutputWrapper>(iConfig.getParameter<
edm::InputTag>(
"tracks"))},
153 seedToken_{consumes<edm::View<TrajectorySeed>>(iConfig.getParameter<
edm::InputTag>(
"seeds"))},
154 propagatorAlongToken_{
155 esConsumes<Propagator, TrackingComponentsRecord>(iConfig.getParameter<
edm::ESInputTag>(
"propagatorAlong"))},
156 propagatorOppositeToken_{esConsumes<Propagator, TrackingComponentsRecord>(
158 mfToken_{esConsumes<MagneticField, IdealMagneticFieldRecord>()},
159 ttrhBuilderToken_{esConsumes<TransientTrackingRecHitBuilder, TransientRecHitRecord>(
161 mkFitGeomToken_{esConsumes<MkFitGeometry, TrackerRecoGeometryRecord>()},
162 putTrackCandidateToken_{produces<TrackCandidateCollection>()},
163 putSeedStopInfoToken_{produces<std::vector<SeedStopInfo>>()},
164 qualityMaxInvPt_{
float(iConfig.getParameter<
double>(
"qualityMaxInvPt"))},
165 qualityMinTheta_{
float(iConfig.getParameter<
double>(
"qualityMinTheta"))},
166 qualityMaxRsq_{
float(
pow(iConfig.getParameter<
double>(
"qualityMaxR"), 2))},
167 qualityMaxZ_{
float(iConfig.getParameter<
double>(
"qualityMaxZ"))},
168 qualityMaxPosErrSq_{
float(
pow(iConfig.getParameter<
double>(
"qualityMaxPosErr"), 2))},
169 qualitySignPt_{iConfig.getParameter<
bool>(
"qualitySignPt")},
170 doErrorRescale_{iConfig.getParameter<
bool>(
"doErrorRescale")},
172 TString(iConfig.getParameter<
edm::InputTag>(
"seeds").
label()).ReplaceAll(
"Seeds",
"").Data())},
173 algoCandSelection_{
bool(iConfig.getParameter<
bool>(
"candMVASel"))},
174 algoCandWorkingPoint_{
float(iConfig.getParameter<
double>(
"candWP"))},
175 bsize_{
int(iConfig.getParameter<
int>(
"batchSize"))},
176 bsToken_(algoCandSelection_ ? consumes<reco::BeamSpot>(
edm::InputTag(
"offlineBeamSpot"))
178 verticesToken_(algoCandSelection_ ? consumes<reco::VertexCollection>(
edm::InputTag(
"firstStepPrimaryVertices"))
180 tfDnnLabel_(iConfig.getParameter<
std::string>(
"tfDnnLabel")),
196 desc.add<
double>(
"qualityMaxInvPt", 100)->setComment(
"max(1/pt) for converted tracks");
197 desc.add<
double>(
"qualityMinTheta", 0.01)->setComment(
"lower bound on theta (or pi-theta) for converted tracks");
198 desc.add<
double>(
"qualityMaxR", 120)->setComment(
"max(R) for the state position for converted tracks");
199 desc.add<
double>(
"qualityMaxZ", 280)->setComment(
"max(|Z|) for the state position for converted tracks");
200 desc.add<
double>(
"qualityMaxPosErr", 100)->setComment(
"max position error for converted tracks");
201 desc.add<
bool>(
"qualitySignPt",
true)->setComment(
"check sign of 1/pt for converted tracks");
203 desc.add<
bool>(
"doErrorRescale",
true)->setComment(
"rescale candidate error before final fit");
207 desc.add<
bool>(
"candMVASel",
false)->setComment(
"flag used to trigger MVA selection at cand level");
208 desc.add<
double>(
"candWP", 0)->setComment(
"MVA selection at cand level working point");
209 desc.add<
int>(
"batchSize", 16)->setComment(
"batch size for cand DNN evaluation");
221 throw cms::Exception(
"LogicError") <<
"TTRHBuilder must be of type TkTransientTrackingRecHitBuilder";
234 const tensorflow::Session* session =
nullptr;
250 mkFitGeom.detLayers(),
270 const std::vector<const DetLayer*>& detLayers,
274 const tensorflow::Session* session)
const {
281 std::vector<float>
chi2;
282 std::vector<TrajectoryStateOnSurface> states;
289 LogTrace(
"MkFitOutputConverter") <<
"Candidate " << candIndex <<
" pT " <<
cand.pT() <<
" eta " <<
cand.momEta()
290 <<
" phi " <<
cand.momPhi() <<
" chi2 " <<
cand.chi2();
296 (
cand.state().errors.At(0, 0) +
cand.state().errors.At(1, 1) +
cand.state().errors.At(2, 2)) >
299 <<
"Candidate " << candIndex <<
" failed state quality checks" <<
cand.state().parameters;
304 state.convertFromCCSToGlbCurvilinear();
305 const auto& param =
state.parameters;
308 for (
int i = 0;
i < 5; ++
i) {
309 for (
int j =
i;
j < 5; ++
j) {
318 if (!fts.curvilinearError().posDef()) {
320 <<
"Curvilinear error not pos-def\n" 321 << fts.curvilinearError().matrix() <<
"\ncandidate " << candIndex <<
"ignored";
329 <<
"Fail pos-def check sub2.det for candidate " << candIndex <<
" with fts " << fts;
333 <<
"Fail pos-def check sub3.det for candidate " << candIndex <<
" with fts " << fts;
337 <<
"Fail pos-def check sub4.det for candidate " << candIndex <<
" with fts " << fts;
339 }
else if ((!fts.curvilinearError().matrix().Det2(det)) || det < 0) {
341 <<
"Fail pos-def check det for candidate " << candIndex <<
" with fts " << fts;
349 bool lastHitInvalid =
false;
351 const auto& hitOnTrack =
cand.getHitOnTrack(
i);
352 LogTrace(
"MkFitOutputConverter") <<
" hit on layer " << hitOnTrack.layer <<
" index " << hitOnTrack.index;
353 if (hitOnTrack.index < 0) {
364 const auto* detLayer = detLayers.at(hitOnTrack.layer);
365 if (detLayer ==
nullptr) {
366 throw cms::Exception(
"LogicError") <<
"DetLayer for layer index " << hitOnTrack.layer <<
" is null!";
371 lastHitInvalid =
true;
374 auto const&
hits =
isPixel ? pixelClusterIndexToHit.
hits() : stripClusterIndexToHit.
hits();
378 if (thit.firstClusterRef().isPixel() || thit.detUnit()->type().isEndcap()) {
379 recHits.push_back(
hits[hitOnTrack.index]->clone());
381 recHits.push_back(std::make_unique<SiStripRecHit1D>(
382 thit.localPosition(),
385 thit.firstClusterRef()));
388 recHits.push_back(
hits[hitOnTrack.index]->clone());
390 LogTrace(
"MkFitOutputConverter") <<
" pos " <<
recHits.back().globalPosition().x() <<
" " 391 <<
recHits.back().globalPosition().y() <<
" " 392 <<
recHits.back().globalPosition().z() <<
" mag2 " 393 <<
recHits.back().globalPosition().mag2() <<
" detid " 394 <<
recHits.back().geographicalId().rawId() <<
" cluster " << hitOnTrack.index;
395 lastHitInvalid =
false;
399 const auto lastHitId =
recHits.back().geographicalId();
403 recHits.sort([](
const auto&
a,
const auto&
b) {
404 const auto asub =
a.geographicalId().subdetId();
405 const auto bsub =
b.geographicalId().subdetId();
411 const auto& apos =
a.globalPosition();
412 const auto& bpos =
b.globalPosition();
415 return apos.perp2() < bpos.perp2();
420 const bool lastHitChanged = (
recHits.back().geographicalId() != lastHitId);
423 const auto seedIndex =
cand.label();
424 LogTrace(
"MkFitOutputConverter") <<
" from seed " << seedIndex <<
" seed hits";
431 fts.rescaleError(100.);
436 if (!tsosDet.first.isValid()) {
438 <<
"Backward fit of candidate " << candIndex <<
" failed, ignoring the candidate";
449 seeds.refAt(seedIndex),
455 states.push_back(tsosDet.first);
463 reducedOutput.reserve(
output.size());
465 for (
const auto&
score : dnnScores) {
467 reducedOutput.push_back(
output[scoreIndex]);
471 output.swap(reducedOutput);
483 bool lastHitWasInvalid,
484 bool lastHitWasChanged)
const {
488 for (
int i =
hits.size() - 1;
i >= 0; --
i) {
499 const auto& lastHitSurface = firstHits.front()->det()->surface();
503 if (lastHitWasInvalid || lastHitWasChanged) {
504 LogTrace(
"MkFitOutputConverter") <<
"Propagating first opposite, then along, because lastHitWasInvalid? " 505 << lastHitWasInvalid <<
" or lastHitWasChanged? " << lastHitWasChanged;
508 const auto lastHitSubdet = firstHits.front()->geographicalId().subdetId();
509 const auto& surfacePos = lastHitSurface.position();
510 const auto& lastHitPos = firstHits.front()->globalPosition();
511 bool doSwitch =
false;
513 doSwitch = (surfacePos.perp2() < lastHitPos.perp2());
515 doSwitch = (surfacePos.z() < lastHitPos.z());
519 <<
"Propagating first opposite, then along, because surface is inner than the hit; surface perp2 " 520 << surfacePos.perp() <<
" hit " << lastHitPos.perp2() <<
" surface z " << surfacePos.z() <<
" hit " 528 if (!tsosDouble.first.isValid()) {
529 LogDebug(
"MkFitOutputConverter") <<
"Propagating to startingState failed, trying in another direction next";
532 auto& startingState = tsosDouble.first;
534 if (!startingState.isValid()) {
536 <<
"startingState is not valid, FTS was\n" 537 << fts <<
" last hit surface surface:" 538 <<
"\n position " << lastHitSurface.
position() <<
"\n phiSpan " << lastHitSurface.phiSpan().first <<
"," 539 << lastHitSurface.phiSpan().first <<
"\n rSpan " << lastHitSurface.rSpan().first <<
"," 540 << lastHitSurface.rSpan().first <<
"\n zSpan " << lastHitSurface.zSpan().first <<
"," 541 << lastHitSurface.zSpan().first;
542 return std::pair<TrajectoryStateOnSurface, const GeomDet*>();
546 startingState.rescaleError(100.);
552 &
propagatorAlong, &aKFUpdator, &aChi2MeasurementEstimator, firstHits.size(),
nullptr, &hitCloner);
563 LogDebug(
"MkFitOutputConverter") <<
"using a backward fit of :" << firstHits.size() <<
" hits, starting from:\n" 564 << startingState <<
" to get the estimate of the initial state of the track.";
567 edm::LogWarning(
"MkFitOutputConverter") <<
"FitTester: first hits fit failed";
568 return std::pair<TrajectoryStateOnSurface, const GeomDet*>();
581 LogDebug(
"MkFitOutputConverter") <<
"the initial state is found to be:\n:" << firstState
582 <<
"\n it's field pointer is: " << firstState.magneticField()
583 <<
"\n the pointer from the state of the back fit was: " 586 return std::make_pair(firstState, firstMeas.
recHit()->det());
594 auto det =
hits[0].det();
595 if (det ==
nullptr) {
596 throw cms::Exception(
"LogicError") <<
"Got nullptr from the first hit det()";
599 const auto& firstHitSurface = det->surface();
601 auto tsosDouble =
propagatorAlong.propagateWithPath(fts, firstHitSurface);
602 if (!tsosDouble.first.isValid()) {
603 LogDebug(
"MkFitOutputConverter") <<
"Propagating to startingState along momentum failed, trying opposite next";
607 return std::make_pair(tsosDouble.first, det);
611 const std::vector<TrajectoryStateOnSurface>& states,
614 const tensorflow::Session* session,
615 const std::vector<float>&
chi2,
616 const bool rescaledError)
const {
617 int size_in = (
int)tkCC.size();
618 int nbatches = size_in /
bsize_;
620 std::vector<float>
output(size_in, 0);
624 tensorflow::Tensor
input1(tensorflow::DT_FLOAT, {
bsize_, 29});
625 tensorflow::Tensor
input2(tensorflow::DT_FLOAT, {
bsize_, 1});
627 for (
auto nb = 0; nb < nbatches + 1; nb++) {
628 std::vector<bool> invalidProp(
bsize_,
false);
632 if (itrack >= size_in)
635 auto const& tkC = tkCC.at(itrack);
640 state.rescaleError(1 / 100.
f);
643 tscblBuilder(*
state.freeState(), *
bs);
645 if (!(tsAtClosestApproachTrackCand.
isValid())) {
646 edm::LogVerbatim(
"TrackBuilding") <<
"TrajectoryStateClosestToBeamLine not valid";
647 invalidProp[
nt] =
true;
651 auto const& stateAtPCA = tsAtClosestApproachTrackCand.
trackStateAtPCA();
652 auto v0 = stateAtPCA.position();
653 auto p = stateAtPCA.momentum();
658 reco::Track trk(0, 0,
pos, mom, stateAtPCA.charge(), stateAtPCA.curvilinearError());
666 dzmin = trk.dz(
vertex.position());
667 dxy_zmin = trk.dxy(
vertex.position());
675 for (
auto const&
recHit : tkC.recHits()) {
677 auto const subdet =
recHit.geographicalId().subdetId();
685 input1.matrix<
float>()(
nt, 0) = trk.pt();
689 input1.matrix<
float>()(
nt, 4) =
p.perp();
693 input1.matrix<
float>()(
nt, 8) =
p.perp();
694 input1.matrix<
float>()(
nt, 9) = trk.ptError();
695 input1.matrix<
float>()(
nt, 10) = dxy_zmin;
696 input1.matrix<
float>()(
nt, 11) = dzmin;
697 input1.matrix<
float>()(
nt, 12) = trk.dxy(
bs->position());
698 input1.matrix<
float>()(
nt, 13) = trk.dz(
bs->position());
699 input1.matrix<
float>()(
nt, 14) = trk.dxyError();
700 input1.matrix<
float>()(
nt, 15) = trk.dzError();
702 input1.matrix<
float>()(
nt, 17) = trk.eta();
703 input1.matrix<
float>()(
nt, 18) = trk.phi();
704 input1.matrix<
float>()(
nt, 19) = trk.etaError();
705 input1.matrix<
float>()(
nt, 20) = trk.phiError();
706 input1.matrix<
float>()(
nt, 21) = pix;
725 std::vector<tensorflow::Tensor>
outputs;
730 if (itrack >= size_in)
733 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
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_
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
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
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
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 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
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
bool isEndcap(GeomDetEnumerators::SubDetector m)
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_