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")} {}
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 det rawId " << detId.rawId()
195 <<
" subdet " << subdet <<
" layer " <<
layer <<
" isStereo " << isStereo;
199 constexpr
int monoLayer = 0;
200 constexpr
int stereoLayer = 1;
202 const auto&
comp = lay->basicComponents();
204 throw cms::Exception(
"LogicError") <<
"Got a tracker layer (subdet " << lay->subDetector()
205 <<
") with empty basicComponents.";
208 const auto& detId =
comp.front()->geographicalId();
209 const auto subdet = detId.subdetId();
213 setDet(subdet,
layer, monoLayer, detId, lay);
216 setDet(subdet,
layer, stereoLayer, detId, lay);
231 const std::vector<const DetLayer*>& detLayers,
242 LogTrace(
"MkFitOutputConverter") <<
"Candidate " << candIndex <<
" pT " <<
cand.pT() <<
" eta " <<
cand.momEta()
243 <<
" phi " <<
cand.momPhi() <<
" chi2 " <<
cand.chi2();
251 bool lastHitInvalid =
false;
253 const auto& hitOnTrack =
cand.getHitOnTrack(
i);
254 LogTrace(
"MkFitOutputConverter") <<
" hit on layer " << hitOnTrack.layer <<
" index " << hitOnTrack.index;
255 if (hitOnTrack.index < 0) {
266 const auto* detLayer = detLayers.at(hitOnTrack.layer);
267 if (detLayer ==
nullptr) {
268 throw cms::Exception(
"LogicError") <<
"DetLayer for layer index " << hitOnTrack.layer <<
" is null!";
273 lastHitInvalid =
true;
276 LogTrace(
"MkFitOutputConverter") <<
" pos " <<
recHits.back().globalPosition().x() <<
" "
277 <<
recHits.back().globalPosition().y() <<
" "
278 <<
recHits.back().globalPosition().z() <<
" mag2 "
279 <<
recHits.back().globalPosition().mag2() <<
" detid "
280 <<
recHits.back().geographicalId().rawId() <<
" cluster "
283 lastHitInvalid =
false;
287 const auto lastHitId =
recHits.back().geographicalId();
291 recHits.sort([](
const auto&
a,
const auto&
b) {
292 const auto asub =
a.geographicalId().subdetId();
293 const auto bsub =
b.geographicalId().subdetId();
299 const auto& apos =
a.globalPosition();
300 const auto& bpos =
b.globalPosition();
303 return apos.perp2() < bpos.perp2();
308 const bool lastHitChanged = (
recHits.back().geographicalId() != lastHitId);
311 const auto seedIndex =
cand.label();
312 LogTrace(
"MkFitOutputConverter") <<
" from seed " << seedIndex <<
" seed hits";
313 const auto& mkseed = mkFitSeeds.at(
cand.label());
314 for (
int i = 0;
i < mkseed.nTotalHits(); ++
i) {
315 const auto& hitOnTrack = mkseed.getHitOnTrack(
i);
316 LogTrace(
"MkFitOutputConverter") <<
" hit on layer " << hitOnTrack.layer <<
" index " << hitOnTrack.index;
318 const auto& candHitOnTrack =
cand.getHitOnTrack(
i);
319 if (hitOnTrack.layer != candHitOnTrack.layer) {
321 <<
"Candidate " << candIndex <<
" from seed " << seedIndex <<
" hit " <<
i
322 <<
" has different layer in candidate (" << candHitOnTrack.layer <<
") and seed (" << hitOnTrack.layer
324 <<
" Hit indices are " << candHitOnTrack.index <<
" and " << hitOnTrack.index <<
", respectively";
326 if (hitOnTrack.index != candHitOnTrack.index) {
327 throw cms::Exception(
"LogicError") <<
"Candidate " << candIndex <<
" from seed " << seedIndex <<
" hit " <<
i
328 <<
" has different hit index in candidate (" << candHitOnTrack.index
329 <<
") and seed (" << hitOnTrack.index <<
") on layer " << hitOnTrack.layer;
335 state.convertFromCCSToCartesian();
336 const auto& param =
state.parameters;
339 for (
int i = 0;
i < 6; ++
i) {
340 for (
int j =
i;
j < 6; ++
j) {
349 if (!fts.curvilinearError().posDef()) {
350 edm::LogWarning(
"MkFitOutputConverter") <<
"Curvilinear error not pos-def\n"
351 << fts.curvilinearError().matrix() <<
"\noriginal 6x6 covariance matrix\n"
352 << cov <<
"\ncandidate ignored";
360 if (!tsosDet.first.isValid()) {
362 <<
"Backward fit of candidate " << candIndex <<
" failed, ignoring the candidate";
373 seeds.refAt(seedIndex),
387 bool lastHitWasInvalid,
388 bool lastHitWasChanged)
const {
392 for (
int i =
hits.size() - 1;
i >= 0; --
i) {
403 const auto& lastHitSurface = firstHits.front()->det()->surface();
407 if (lastHitWasInvalid || lastHitWasChanged) {
408 LogTrace(
"MkFitOutputConverter") <<
"Propagating first opposite, then along, because lastHitWasInvalid? "
409 << lastHitWasInvalid <<
" or lastHitWasChanged? " << lastHitWasChanged;
412 const auto lastHitSubdet = firstHits.front()->geographicalId().subdetId();
413 const auto& surfacePos = lastHitSurface.position();
414 const auto& lastHitPos = firstHits.front()->globalPosition();
415 bool doSwitch =
false;
417 doSwitch = (surfacePos.perp2() < lastHitPos.perp2());
419 doSwitch = (surfacePos.z() < lastHitPos.z());
423 <<
"Propagating first opposite, then along, because surface is inner than the hit; surface perp2 "
424 << surfacePos.perp() <<
" hit " << lastHitPos.perp2() <<
" surface z " << surfacePos.z() <<
" hit "
432 if (!tsosDouble.first.isValid()) {
433 LogDebug(
"MkFitOutputConverter") <<
"Propagating to startingState failed, trying in another direction next";
436 auto& startingState = tsosDouble.first;
438 if (!startingState.isValid()) {
440 <<
"startingState is not valid, FTS was\n"
441 << fts <<
" last hit surface surface:"
442 <<
"\n position " << lastHitSurface.
position() <<
"\n phiSpan " << lastHitSurface.phiSpan().first <<
","
443 << lastHitSurface.phiSpan().first <<
"\n rSpan " << lastHitSurface.rSpan().first <<
","
444 << lastHitSurface.rSpan().first <<
"\n zSpan " << lastHitSurface.zSpan().first <<
","
445 << lastHitSurface.zSpan().first;
446 return std::pair<TrajectoryStateOnSurface, const GeomDet*>();
450 startingState.rescaleError(100.);
455 KFTrajectoryFitter backFitter(
456 &
propagatorAlong, &aKFUpdator, &aChi2MeasurementEstimator, firstHits.size(),
nullptr, &hitCloner);
467 LogDebug(
"MkFitOutputConverter") <<
"using a backward fit of :" << firstHits.size() <<
" hits, starting from:\n"
468 << startingState <<
" to get the estimate of the initial state of the track.";
471 edm::LogWarning(
"MkFitOutputConverter") <<
"FitTester: first hits fit failed";
472 return std::pair<TrajectoryStateOnSurface, const GeomDet*>();
485 LogDebug(
"MkFitOutputConverter") <<
"the initial state is found to be:\n:" << firstState
486 <<
"\n it's field pointer is: " << firstState.magneticField()
487 <<
"\n the pointer from the state of the back fit was: "
490 return std::make_pair(firstState, firstMeas.
recHit()->det());
498 auto det =
hits[0].det();
499 if (det ==
nullptr) {
500 throw cms::Exception(
"LogicError") <<
"Got nullptr from the first hit det()";
503 const auto& firstHitSurface = det->surface();
505 auto tsosDouble =
propagatorAlong.propagateWithPath(fts, firstHitSurface);
506 if (!tsosDouble.first.isValid()) {
507 LogDebug(
"MkFitOutputConverter") <<
"Propagating to startingState along momentum failed, trying opposite next";
511 return std::make_pair(tsosDouble.first, det);