85 const std::vector<const DetLayer*>& detLayers,
89 const tensorflow::Session* session)
const;
96 bool lastHitWasInvalid,
97 bool lastHitWasChanged)
const;
105 const std::vector<TrajectoryStateOnSurface>& states,
108 const tensorflow::Session* session,
109 const std::vector<float>&
chi2,
110 const bool rescaledError)
const;
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>(
156 mfToken_{esConsumes<MagneticField, IdealMagneticFieldRecord>()},
157 ttrhBuilderToken_{esConsumes<TransientTrackingRecHitBuilder, TransientRecHitRecord>(
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")),
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");
201 desc.add<
bool>(
"doErrorRescale",
true)->setComment(
"rescale candidate error before final fit");
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");
219 throw cms::Exception(
"LogicError") <<
"TTRHBuilder must be of type TkTransientTrackingRecHitBuilder";
232 const tensorflow::Session* session =
nullptr;
247 mkFitGeom.detLayers(),
266 const std::vector<const DetLayer*>& detLayers,
270 const tensorflow::Session* session)
const {
277 std::vector<float>
chi2;
278 std::vector<TrajectoryStateOnSurface> states;
285 LogTrace(
"MkFitOutputConverter") <<
"Candidate " << candIndex <<
" pT " <<
cand.pT() <<
" eta " <<
cand.momEta()
286 <<
" phi " <<
cand.momPhi() <<
" chi2 " <<
cand.chi2();
292 (
cand.state().errors.At(0, 0) +
cand.state().errors.At(1, 1) +
cand.state().errors.At(2, 2)) >
295 <<
"Candidate " << candIndex <<
" failed state quality checks" <<
cand.state().parameters;
300 state.convertFromCCSToGlbCurvilinear();
301 const auto& param =
state.parameters;
304 for (
int i = 0;
i < 5; ++
i) {
305 for (
int j =
i;
j < 5; ++
j) {
314 if (!fts.curvilinearError().posDef()) {
316 <<
"Curvilinear error not pos-def\n" 317 << fts.curvilinearError().matrix() <<
"\ncandidate " << candIndex <<
"ignored";
325 <<
"Fail pos-def check sub2.det for candidate " << candIndex <<
" with fts " << fts;
329 <<
"Fail pos-def check sub3.det for candidate " << candIndex <<
" with fts " << fts;
333 <<
"Fail pos-def check sub4.det for candidate " << candIndex <<
" with fts " << fts;
335 }
else if ((!fts.curvilinearError().matrix().Det2(det)) || det < 0) {
337 <<
"Fail pos-def check det for candidate " << candIndex <<
" with fts " << fts;
345 bool lastHitInvalid =
false;
347 const auto& hitOnTrack =
cand.getHitOnTrack(
i);
348 LogTrace(
"MkFitOutputConverter") <<
" hit on layer " << hitOnTrack.layer <<
" index " << hitOnTrack.index;
349 if (hitOnTrack.index < 0) {
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!";
367 lastHitInvalid =
true;
370 auto const&
hits =
isPixel ? pixelClusterIndexToHit.
hits() : stripClusterIndexToHit.
hits();
373 if (thit.firstClusterRef().isPixel() || thit.detUnit()->type().isEndcap()) {
374 recHits.push_back(
hits[hitOnTrack.index]->clone());
376 recHits.push_back(std::make_unique<SiStripRecHit1D>(
377 thit.localPosition(),
380 thit.firstClusterRef()));
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;
391 const auto lastHitId =
recHits.back().geographicalId();
395 recHits.sort([](
const auto&
a,
const auto&
b) {
396 const auto asub =
a.geographicalId().subdetId();
397 const auto bsub =
b.geographicalId().subdetId();
403 const auto& apos =
a.globalPosition();
404 const auto& bpos =
b.globalPosition();
407 return apos.perp2() < bpos.perp2();
412 const bool lastHitChanged = (
recHits.back().geographicalId() != lastHitId);
415 const auto seedIndex =
cand.label();
416 LogTrace(
"MkFitOutputConverter") <<
" from seed " << seedIndex <<
" seed hits";
423 fts.rescaleError(100.);
428 if (!tsosDet.first.isValid()) {
430 <<
"Backward fit of candidate " << candIndex <<
" failed, ignoring the candidate";
441 seeds.refAt(seedIndex),
447 states.push_back(tsosDet.first);
455 reducedOutput.reserve(
output.size());
457 for (
const auto&
score : dnnScores) {
459 reducedOutput.push_back(
output[scoreIndex]);
463 output.swap(reducedOutput);
475 bool lastHitWasInvalid,
476 bool lastHitWasChanged)
const {
480 for (
int i =
hits.size() - 1;
i >= 0; --
i) {
491 const auto& lastHitSurface = firstHits.front()->det()->surface();
495 if (lastHitWasInvalid || lastHitWasChanged) {
496 LogTrace(
"MkFitOutputConverter") <<
"Propagating first opposite, then along, because lastHitWasInvalid? " 497 << lastHitWasInvalid <<
" or lastHitWasChanged? " << lastHitWasChanged;
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;
505 doSwitch = (surfacePos.perp2() < lastHitPos.perp2());
507 doSwitch = (surfacePos.z() < lastHitPos.z());
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 " 520 if (!tsosDouble.first.isValid()) {
521 LogDebug(
"MkFitOutputConverter") <<
"Propagating to startingState failed, trying in another direction next";
524 auto& startingState = tsosDouble.first;
526 if (!startingState.isValid()) {
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*>();
538 startingState.rescaleError(100.);
544 &
propagatorAlong, &aKFUpdator, &aChi2MeasurementEstimator, firstHits.size(),
nullptr, &hitCloner);
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.";
559 edm::LogWarning(
"MkFitOutputConverter") <<
"FitTester: first hits fit failed";
560 return std::pair<TrajectoryStateOnSurface, const GeomDet*>();
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: " 578 return std::make_pair(firstState, firstMeas.
recHit()->det());
586 auto det =
hits[0].det();
587 if (det ==
nullptr) {
588 throw cms::Exception(
"LogicError") <<
"Got nullptr from the first hit det()";
591 const auto& firstHitSurface = det->surface();
593 auto tsosDouble =
propagatorAlong.propagateWithPath(fts, firstHitSurface);
594 if (!tsosDouble.first.isValid()) {
595 LogDebug(
"MkFitOutputConverter") <<
"Propagating to startingState along momentum failed, trying opposite next";
599 return std::make_pair(tsosDouble.first, det);
603 const std::vector<TrajectoryStateOnSurface>& states,
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_;
612 std::vector<float>
output(size_in, 0);
616 tensorflow::Tensor
input1(tensorflow::DT_FLOAT, {
bsize_, 29});
617 tensorflow::Tensor
input2(tensorflow::DT_FLOAT, {
bsize_, 1});
619 for (
auto nb = 0; nb < nbatches + 1; nb++) {
620 std::vector<bool> invalidProp(
bsize_,
false);
624 if (itrack >= size_in)
627 auto const& tkC = tkCC.at(itrack);
632 state.rescaleError(1 / 100.
f);
635 tscblBuilder(*
state.freeState(), *
bs);
637 if (!(tsAtClosestApproachTrackCand.
isValid())) {
638 edm::LogVerbatim(
"TrackBuilding") <<
"TrajectoryStateClosestToBeamLine not valid";
639 invalidProp[
nt] =
true;
643 auto const& stateAtPCA = tsAtClosestApproachTrackCand.
trackStateAtPCA();
644 auto v0 = stateAtPCA.position();
645 auto p = stateAtPCA.momentum();
650 reco::Track trk(0, 0,
pos, mom, stateAtPCA.charge(), stateAtPCA.curvilinearError());
658 dzmin = trk.dz(
vertex.position());
659 dxy_zmin = trk.dxy(
vertex.position());
667 for (
auto const&
recHit : tkC.recHits()) {
669 auto const subdet =
recHit.geographicalId().subdetId();
677 input1.matrix<
float>()(
nt, 0) = trk.pt();
681 input1.matrix<
float>()(
nt, 4) =
p.perp();
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();
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;
717 std::vector<tensorflow::Tensor>
outputs;
722 if (itrack >= size_in)
725 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_
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
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_
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
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
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_