44 #include "LayerNumberConverter.h"
71 std::vector<const DetLayer*>
createDetLayers(
const mkfit::LayerNumberConverter& lnc,
83 const std::vector<const DetLayer*>& detLayers,
91 bool lastHitWasInvalid,
92 bool lastHitWasChanged)
const;
119 tracksToken_{consumes<MkFitOutputWrapper>(iConfig.getParameter<
edm::InputTag>(
"tracks"))},
120 seedToken_{consumes<edm::View<TrajectorySeed>>(iConfig.getParameter<
edm::InputTag>(
"seeds"))},
121 mteToken_{consumes<MeasurementTrackerEvent>(iConfig.getParameter<
edm::InputTag>(
"measurementTrackerEvent"))},
122 geomToken_{esConsumes<TrackerGeometry, TrackerDigiGeometryRecord>()},
123 propagatorAlongToken_{
124 esConsumes<Propagator, TrackingComponentsRecord>(iConfig.getParameter<
edm::ESInputTag>(
"propagatorAlong"))},
125 propagatorOppositeToken_{esConsumes<Propagator, TrackingComponentsRecord>(
127 ttopoToken_{esConsumes<TrackerTopology, TrackerTopologyRcd>()},
128 mfToken_{esConsumes<MagneticField, IdealMagneticFieldRecord>()},
129 ttrhBuilderToken_{esConsumes<TransientTrackingRecHitBuilder, TransientRecHitRecord>(
131 putTrackCandidateToken_{produces<TrackCandidateCollection>()},
132 putSeedStopInfoToken_{produces<std::vector<SeedStopInfo>>()},
133 backwardFitInCMSSW_{iConfig.getParameter<
bool>(
"backwardFitInCMSSW")} {}
141 desc.
add(
"measurementTrackerEvent",
edm::InputTag{
"MeasurementTrackerEvent"});
144 desc.
add(
"propagatorOpposite",
edm::ESInputTag{
"",
"PropagatorWithMaterialOpposite"});
145 desc.
add(
"backwardFitInCMSSW",
false)
146 ->
setComment(
"Do backward fit (to innermost hit) in CMSSW (true) or mkFit (false)");
157 const auto* tkBuilder = dynamic_cast<TkTransientTrackingRecHitBuilder const*>(&ttrhBuilder);
159 throw cms::Exception(
"LogicError") <<
"TTRHBuilder must be of type TkTransientTrackingRecHitBuilder";
163 const auto detlayers =
184 std::vector<const DetLayer*> dets(lnc.nLayers(),
nullptr);
186 auto isPlusSide = [&ttopo](
const DetId& detid) {
189 auto setDet = [&lnc, &dets, &isPlusSide](
190 const int subdet,
const int layer,
const int isStereo,
const DetId& detId,
const DetLayer* lay) {
191 const int index = lnc.convertLayerNumber(subdet, layer,
false, isStereo, isPlusSide(detId));
192 if (
index < 0
or static_cast<unsigned>(
index) >= dets.size()) {
193 throw cms::Exception(
"LogicError") <<
"Invalid mkFit layer index " <<
index <<
" for DetId " << detId
194 <<
" subdet " << subdet <<
" layer " << layer <<
" isStereo " << isStereo;
198 constexpr
int monoLayer = 0;
199 constexpr
int stereoLayer = 1;
201 const auto&
comp = lay->basicComponents();
203 throw cms::Exception(
"LogicError") <<
"Got a tracker layer (subdet " << lay->subDetector()
204 <<
") with empty basicComponents.";
207 const auto& detId =
comp.front()->geographicalId();
208 const auto subdet = detId.subdetId();
209 const auto layer = ttopo.
layer(detId);
212 setDet(subdet, layer, monoLayer, detId, lay);
215 setDet(subdet, layer, stereoLayer, detId, lay);
230 const std::vector<const DetLayer*>& detLayers,
241 LogTrace(
"MkFitOutputConverter") <<
"Candidate " << candIndex <<
" pT " <<
cand.pT() <<
" eta " <<
cand.momEta()
242 <<
" phi " <<
cand.momPhi() <<
" chi2 " <<
cand.chi2();
250 bool lastHitInvalid =
false;
252 const auto& hitOnTrack =
cand.getHitOnTrack(
i);
253 LogTrace(
"MkFitOutputConverter") <<
" hit on layer " << hitOnTrack.layer <<
" index " << hitOnTrack.index;
254 if (hitOnTrack.index < 0) {
265 const auto* detLayer = detLayers.at(hitOnTrack.layer);
266 if (detLayer ==
nullptr) {
267 throw cms::Exception(
"LogicError") <<
"DetLayer for layer index " << hitOnTrack.layer <<
" is null!";
272 lastHitInvalid =
true;
275 LogTrace(
"MkFitOutputConverter") <<
" pos " <<
recHits.back().globalPosition().x() <<
" "
276 <<
recHits.back().globalPosition().y() <<
" "
277 <<
recHits.back().globalPosition().z() <<
" mag2 "
278 <<
recHits.back().globalPosition().mag2() <<
" detid "
279 <<
recHits.back().geographicalId().rawId() <<
" cluster "
282 lastHitInvalid =
false;
286 const auto lastHitId =
recHits.back().geographicalId();
290 recHits.sort([](
const auto&
a,
const auto&
b) {
291 const auto asub =
a.geographicalId().subdetId();
292 const auto bsub =
b.geographicalId().subdetId();
298 const auto& apos =
a.globalPosition();
299 const auto& bpos =
b.globalPosition();
302 return apos.perp2() < bpos.perp2();
307 const bool lastHitChanged = (
recHits.back().geographicalId() != lastHitId);
310 const auto seedIndex =
cand.label();
311 LogTrace(
"MkFitOutputConverter") <<
" from seed " << seedIndex <<
" seed hits";
312 const auto& mkseed = mkFitSeeds.at(
cand.label());
313 for (
int i = 0;
i < mkseed.nTotalHits(); ++
i) {
314 const auto& hitOnTrack = mkseed.getHitOnTrack(
i);
315 LogTrace(
"MkFitOutputConverter") <<
" hit on layer " << hitOnTrack.layer <<
" index " << hitOnTrack.index;
317 const auto& candHitOnTrack =
cand.getHitOnTrack(
i);
318 if (hitOnTrack.layer != candHitOnTrack.layer) {
320 <<
"Candidate " << candIndex <<
" from seed " << seedIndex <<
" hit " <<
i
321 <<
" has different layer in candidate (" << candHitOnTrack.layer <<
") and seed (" << hitOnTrack.layer
323 <<
" Hit indices are " << candHitOnTrack.index <<
" and " << hitOnTrack.index <<
", respectively";
325 if (hitOnTrack.index != candHitOnTrack.index) {
326 throw cms::Exception(
"LogicError") <<
"Candidate " << candIndex <<
" from seed " << seedIndex <<
" hit " <<
i
327 <<
" has different hit index in candidate (" << candHitOnTrack.index
328 <<
") and seed (" << hitOnTrack.index <<
") on layer " << hitOnTrack.layer;
333 auto state =
cand.state();
334 state.convertFromCCSToCartesian();
335 const auto& param = state.parameters;
336 const auto&
err = state.errors;
338 for (
int i = 0;
i < 6; ++
i) {
339 for (
int j =
i;
j < 6; ++
j) {
348 if (!fts.curvilinearError().posDef()) {
349 edm::LogWarning(
"MkFitOutputConverter") <<
"Curvilinear error not pos-def\n"
350 << fts.curvilinearError().matrix() <<
"\noriginal 6x6 covariance matrix\n"
351 << cov <<
"\ncandidate ignored";
359 if (!tsosDet.first.isValid()) {
361 <<
"Backward fit of candidate " << candIndex <<
" failed, ignoring the candidate";
372 seeds.refAt(seedIndex),
386 bool lastHitWasInvalid,
387 bool lastHitWasChanged)
const {
391 for (
int i =
hits.size() - 1;
i >= 0; --
i) {
402 const auto& lastHitSurface = firstHits.front()->det()->surface();
406 if (lastHitWasInvalid || lastHitWasChanged) {
407 LogTrace(
"MkFitOutputConverter") <<
"Propagating first opposite, then along, because lastHitWasInvalid? "
408 << lastHitWasInvalid <<
" or lastHitWasChanged? " << lastHitWasChanged;
411 const auto lastHitSubdet = firstHits.front()->geographicalId().subdetId();
412 const auto& surfacePos = lastHitSurface.position();
413 const auto& lastHitPos = firstHits.front()->globalPosition();
414 bool doSwitch =
false;
416 doSwitch = (surfacePos.perp2() < lastHitPos.perp2());
418 doSwitch = (surfacePos.z() < lastHitPos.z());
422 <<
"Propagating first opposite, then along, because surface is inner than the hit; surface perp2 "
423 << surfacePos.perp() <<
" hit " << lastHitPos.perp2() <<
" surface z " << surfacePos.z() <<
" hit "
431 if (!tsosDouble.first.isValid()) {
432 LogDebug(
"MkFitOutputConverter") <<
"Propagating to startingState failed, trying in another direction next";
435 auto& startingState = tsosDouble.first;
437 if (!startingState.isValid()) {
439 <<
"startingState is not valid, FTS was\n"
440 << fts <<
" last hit surface surface:"
441 <<
"\n position " << lastHitSurface.
position() <<
"\n phiSpan " << lastHitSurface.phiSpan().first <<
","
442 << lastHitSurface.phiSpan().first <<
"\n rSpan " << lastHitSurface.rSpan().first <<
","
443 << lastHitSurface.rSpan().first <<
"\n zSpan " << lastHitSurface.zSpan().first <<
","
444 << lastHitSurface.zSpan().first;
445 return std::pair<TrajectoryStateOnSurface, const GeomDet*>();
449 startingState.rescaleError(100.);
454 KFTrajectoryFitter backFitter(
455 &
propagatorAlong, &aKFUpdator, &aChi2MeasurementEstimator, firstHits.size(),
nullptr, &hitCloner);
466 LogDebug(
"MkFitOutputConverter") <<
"using a backward fit of :" << firstHits.size() <<
" hits, starting from:\n"
467 << startingState <<
" to get the estimate of the initial state of the track.";
470 edm::LogWarning(
"MkFitOutputConverter") <<
"FitTester: first hits fit failed";
471 return std::pair<TrajectoryStateOnSurface, const GeomDet*>();
484 LogDebug(
"MkFitOutputConverter") <<
"the initial state is found to be:\n:" << firstState
485 <<
"\n it's field pointer is: " << firstState.magneticField()
486 <<
"\n the pointer from the state of the back fit was: "
489 return std::make_pair(firstState, firstMeas.
recHit()->det());
497 auto det =
hits[0].det();
498 if (det ==
nullptr) {
499 throw cms::Exception(
"LogicError") <<
"Got nullptr from the first hit det()";
502 const auto& firstHitSurface = det->surface();
504 auto tsosDouble =
propagatorAlong.propagateWithPath(fts, firstHitSurface);
505 if (!tsosDouble.first.isValid()) {
506 LogDebug(
"MkFitOutputConverter") <<
"Propagating to startingState along momentum failed, trying opposite next";
510 return std::make_pair(tsosDouble.first, det);