40 #include "LayerNumberConverter.h"
42 #include "mkFit/HitStructures.h"
77 const std::vector<const DetLayer*>& detLayers,
85 bool lastHitWasInvalid,
86 bool lastHitWasChanged)
const;
113 pixelClusterIndexToHitToken_{consumes(iConfig.getParameter<
edm::InputTag>(
"mkFitPixelHits"))},
114 stripClusterIndexToHitToken_{consumes(iConfig.getParameter<
edm::InputTag>(
"mkFitStripHits"))},
115 mkfitSeedToken_{consumes<MkFitSeedWrapper>(iConfig.getParameter<
edm::InputTag>(
"mkFitSeeds"))},
116 tracksToken_{consumes<MkFitOutputWrapper>(iConfig.getParameter<
edm::InputTag>(
"tracks"))},
117 seedToken_{consumes<edm::View<TrajectorySeed>>(iConfig.getParameter<
edm::InputTag>(
"seeds"))},
118 propagatorAlongToken_{
119 esConsumes<Propagator, TrackingComponentsRecord>(iConfig.getParameter<
edm::ESInputTag>(
"propagatorAlong"))},
120 propagatorOppositeToken_{esConsumes<Propagator, TrackingComponentsRecord>(
122 mfToken_{esConsumes<MagneticField, IdealMagneticFieldRecord>()},
123 ttrhBuilderToken_{esConsumes<TransientTrackingRecHitBuilder, TransientRecHitRecord>(
125 mkFitGeomToken_{esConsumes<MkFitGeometry, TrackerRecoGeometryRecord>()},
126 putTrackCandidateToken_{produces<TrackCandidateCollection>()},
127 putSeedStopInfoToken_{produces<std::vector<SeedStopInfo>>()} {}
150 const auto* tkBuilder = dynamic_cast<TkTransientTrackingRecHitBuilder const*>(&ttrhBuilder);
152 throw cms::Exception(
"LogicError") <<
"TTRHBuilder must be of type TkTransientTrackingRecHitBuilder";
167 mkFitGeom.detLayers(),
168 mkfitSeeds.seeds()));
183 const std::vector<const DetLayer*>& detLayers,
194 LogTrace(
"MkFitOutputConverter") <<
"Candidate " << candIndex <<
" pT " <<
cand.pT() <<
" eta " <<
cand.momEta()
195 <<
" phi " <<
cand.momPhi() <<
" chi2 " <<
cand.chi2();
203 bool lastHitInvalid =
false;
205 const auto& hitOnTrack =
cand.getHitOnTrack(
i);
206 LogTrace(
"MkFitOutputConverter") <<
" hit on layer " << hitOnTrack.layer <<
" index " << hitOnTrack.index;
207 if (hitOnTrack.index < 0) {
218 const auto* detLayer = detLayers.at(hitOnTrack.layer);
219 if (detLayer ==
nullptr) {
220 throw cms::Exception(
"LogicError") <<
"DetLayer for layer index " << hitOnTrack.layer <<
" is null!";
225 lastHitInvalid =
true;
228 auto const&
hits =
isPixel ? pixelClusterIndexToHit.
hits() : stripClusterIndexToHit.
hits();
230 auto const& thit = static_cast<BaseTrackerRecHit const&>(*
hits[hitOnTrack.index]);
231 if (thit.firstClusterRef().isPixel() || thit.detUnit()->type().isEndcap()) {
232 recHits.push_back(
hits[hitOnTrack.index]->clone());
234 recHits.push_back(std::make_unique<SiStripRecHit1D>(
235 thit.localPosition(),
238 thit.firstClusterRef()));
240 LogTrace(
"MkFitOutputConverter") <<
" pos " <<
recHits.back().globalPosition().x() <<
" "
241 <<
recHits.back().globalPosition().y() <<
" "
242 <<
recHits.back().globalPosition().z() <<
" mag2 "
243 <<
recHits.back().globalPosition().mag2() <<
" detid "
244 <<
recHits.back().geographicalId().rawId() <<
" cluster " << hitOnTrack.index;
245 lastHitInvalid =
false;
249 const auto lastHitId =
recHits.back().geographicalId();
253 recHits.sort([](
const auto&
a,
const auto&
b) {
254 const auto asub =
a.geographicalId().subdetId();
255 const auto bsub =
b.geographicalId().subdetId();
261 const auto& apos =
a.globalPosition();
262 const auto& bpos =
b.globalPosition();
265 return apos.perp2() < bpos.perp2();
270 const bool lastHitChanged = (
recHits.back().geographicalId() != lastHitId);
273 const auto seedIndex =
cand.label();
274 LogTrace(
"MkFitOutputConverter") <<
" from seed " << seedIndex <<
" seed hits";
278 state.convertFromCCSToGlbCurvilinear();
279 const auto& param =
state.parameters;
282 for (
int i = 0;
i < 5; ++
i) {
283 for (
int j =
i;
j < 5; ++
j) {
292 if (!fts.curvilinearError().posDef()) {
293 edm::LogWarning(
"MkFitOutputConverter") <<
"Curvilinear error not pos-def\n"
294 << fts.curvilinearError().matrix() <<
"\ncandidate ignored";
302 if (!tsosDet.first.isValid()) {
304 <<
"Backward fit of candidate " << candIndex <<
" failed, ignoring the candidate";
315 seeds.refAt(seedIndex),
329 bool lastHitWasInvalid,
330 bool lastHitWasChanged)
const {
334 for (
int i =
hits.size() - 1;
i >= 0; --
i) {
345 const auto& lastHitSurface = firstHits.front()->det()->surface();
349 if (lastHitWasInvalid || lastHitWasChanged) {
350 LogTrace(
"MkFitOutputConverter") <<
"Propagating first opposite, then along, because lastHitWasInvalid? "
351 << lastHitWasInvalid <<
" or lastHitWasChanged? " << lastHitWasChanged;
354 const auto lastHitSubdet = firstHits.front()->geographicalId().subdetId();
355 const auto& surfacePos = lastHitSurface.position();
356 const auto& lastHitPos = firstHits.front()->globalPosition();
357 bool doSwitch =
false;
359 doSwitch = (surfacePos.perp2() < lastHitPos.perp2());
361 doSwitch = (surfacePos.z() < lastHitPos.z());
365 <<
"Propagating first opposite, then along, because surface is inner than the hit; surface perp2 "
366 << surfacePos.perp() <<
" hit " << lastHitPos.perp2() <<
" surface z " << surfacePos.z() <<
" hit "
374 if (!tsosDouble.first.isValid()) {
375 LogDebug(
"MkFitOutputConverter") <<
"Propagating to startingState failed, trying in another direction next";
378 auto& startingState = tsosDouble.first;
380 if (!startingState.isValid()) {
382 <<
"startingState is not valid, FTS was\n"
383 << fts <<
" last hit surface surface:"
384 <<
"\n position " << lastHitSurface.
position() <<
"\n phiSpan " << lastHitSurface.phiSpan().first <<
","
385 << lastHitSurface.phiSpan().first <<
"\n rSpan " << lastHitSurface.rSpan().first <<
","
386 << lastHitSurface.rSpan().first <<
"\n zSpan " << lastHitSurface.zSpan().first <<
","
387 << lastHitSurface.zSpan().first;
388 return std::pair<TrajectoryStateOnSurface, const GeomDet*>();
392 startingState.rescaleError(100.);
398 &
propagatorAlong, &aKFUpdator, &aChi2MeasurementEstimator, firstHits.size(),
nullptr, &hitCloner);
409 LogDebug(
"MkFitOutputConverter") <<
"using a backward fit of :" << firstHits.size() <<
" hits, starting from:\n"
410 << startingState <<
" to get the estimate of the initial state of the track.";
413 edm::LogWarning(
"MkFitOutputConverter") <<
"FitTester: first hits fit failed";
414 return std::pair<TrajectoryStateOnSurface, const GeomDet*>();
427 LogDebug(
"MkFitOutputConverter") <<
"the initial state is found to be:\n:" << firstState
428 <<
"\n it's field pointer is: " << firstState.magneticField()
429 <<
"\n the pointer from the state of the back fit was: "
432 return std::make_pair(firstState, firstMeas.
recHit()->det());
440 auto det =
hits[0].det();
441 if (det ==
nullptr) {
442 throw cms::Exception(
"LogicError") <<
"Got nullptr from the first hit det()";
445 const auto& firstHitSurface = det->surface();
447 auto tsosDouble =
propagatorAlong.propagateWithPath(fts, firstHitSurface);
448 if (!tsosDouble.first.isValid()) {
449 LogDebug(
"MkFitOutputConverter") <<
"Propagating to startingState along momentum failed, trying opposite next";
453 return std::make_pair(tsosDouble.first, det);