57 #include "CLHEP/Units/GlobalPhysicalConstants.h" 71 class MTDHitMatchingInfo {
73 MTDHitMatchingInfo() {
80 inline bool operator<(
const MTDHitMatchingInfo&
m2)
const {
85 if (timeChi2 < chi2_cut &&
m2.timeChi2 < chi2_cut)
86 return chi2(low_weight) <
m2.chi2(low_weight);
88 return chi2(high_weight) <
m2.chi2(high_weight);
91 inline float chi2(
float timeWeight = 1.
f)
const {
return estChi2 + timeWeight * timeChi2; }
101 sigmaTofs_.reserve(30);
104 inline uint32_t addSegment(
float tPath,
float tMom2,
float sigmaMom) {
105 segmentPathOvc_.emplace_back(tPath *
c_inv);
106 segmentMom2_.emplace_back(tMom2);
107 segmentSigmaMom_.emplace_back(sigmaMom);
110 LogTrace(
"TrackExtenderWithMTD") <<
"addSegment # " << nSegment_ <<
" s = " << tPath
111 <<
" p = " <<
std::sqrt(tMom2) <<
" sigma_p = " << sigmaMom
112 <<
" sigma_p/p = " << sigmaMom /
std::sqrt(tMom2) * 100 <<
" %";
117 inline float computeTof(
float mass_inv2)
const {
119 for (uint32_t iSeg = 0; iSeg < nSegment_; iSeg++) {
120 float gammasq = 1.f + segmentMom2_[iSeg] * mass_inv2;
122 tof += segmentPathOvc_[iSeg] /
beta;
124 LogTrace(
"TrackExtenderWithMTD") <<
" TOF Segment # " << iSeg + 1 <<
" p = " <<
std::sqrt(segmentMom2_[iSeg])
128 float sigma_tof = segmentPathOvc_[iSeg] * segmentSigmaMom_[iSeg] /
129 (segmentMom2_[iSeg] *
sqrt(segmentMom2_[iSeg] + 1 / mass_inv2) * mass_inv2);
131 LogTrace(
"TrackExtenderWithMTD") <<
"TOF Segment # " << iSeg + 1 <<
std::fixed << std::setw(6)
132 <<
" tof segment = " << segmentPathOvc_[iSeg] /
beta << std::scientific
134 <<
"(rel. err. = " << sigma_tof / (segmentPathOvc_[iSeg] /
beta) * 100
142 inline float computeSigmaTof(
float mass_inv2) {
151 for (uint32_t iSeg = 0; iSeg < nSegment_; iSeg++) {
152 sigma = segmentPathOvc_[iSeg] * segmentSigmaMom_[iSeg] /
153 (segmentMom2_[iSeg] *
sqrt(segmentMom2_[iSeg] + 1 / mass_inv2) * mass_inv2);
154 sigmaTofs_.push_back(sigma);
156 sigmatof += sigma * sigma;
160 for (uint32_t iSeg = 0; iSeg < nSegment_; iSeg++) {
161 for (uint32_t jSeg = iSeg + 1; jSeg < nSegment_; jSeg++) {
162 sigmatof += 2 * sigmaTofs_[iSeg] * sigmaTofs_[jSeg];
166 return sqrt(sigmatof);
169 inline uint32_t
size()
const {
return nSegment_; }
171 inline uint32_t removeFirstSegment() {
173 segmentPathOvc_.erase(segmentPathOvc_.begin());
174 segmentMom2_.erase(segmentMom2_.begin());
180 inline std::pair<float, float> getSegmentPathAndMom2(uint32_t iSegment)
const {
181 if (iSegment >= nSegment_) {
182 throw cms::Exception(
"TrackExtenderWithMTD") <<
"Requesting non existing track segment #" << iSegment;
184 return std::make_pair(segmentPathOvc_[iSegment], segmentMom2_[iSegment]);
187 uint32_t nSegment_ = 0;
188 std::vector<float> segmentPathOvc_;
189 std::vector<float> segmentMom2_;
190 std::vector<float> segmentSigmaMom_;
192 std::vector<float> sigmaTofs_;
195 struct TrackTofPidInfo {
231 enum class TofCalc { kCost = 1, kSegm = 2, kMixd = 3 };
234 const TrackTofPidInfo computeTrackTofPidInfo(
float magp2,
241 bool addPIDError =
true,
242 TofCalc choice = TofCalc::kCost,
247 constexpr float m_k_inv2 = 1.0f / m_k / m_k;
249 constexpr float m_p_inv2 = 1.0f / m_p / m_p;
251 TrackTofPidInfo tofpid;
254 tofpid.tmtderror = t_mtderr;
255 tofpid.pathlength = length;
257 auto deltat = [&](
const float mass_inv2,
const float betatmp) {
261 res = tofpid.pathlength / betatmp *
c_inv;
264 res = trs.computeTof(mass_inv2);
267 res = trs.computeTof(mass_inv2) + tofpid.pathlength / betatmp *
c_inv;
273 auto sigmadeltat = [&](
const float mass_inv2) {
275 switch (sigma_choice) {
276 case SigmaTofCalc::kCost:
278 res = tofpid.pathlength *
c_inv * trs.segmentSigmaMom_[trs.nSegment_ - 1] /
279 (magp2 *
sqrt(magp2 + 1 / mass_inv2) * mass_inv2);
281 case SigmaTofCalc::kSegm:
282 res = trs.computeSigmaTof(mass_inv2);
284 case SigmaTofCalc::kMixd:
285 float res1 = tofpid.pathlength *
c_inv * trs.segmentSigmaMom_[trs.nSegment_ - 1] /
286 (magp2 *
sqrt(magp2 + 1 / mass_inv2) * mass_inv2);
287 float res2 = trs.computeSigmaTof(mass_inv2);
288 res =
sqrt(res1 * res1 + res2 * res2 + 2 * res1 * res2);
294 tofpid.gammasq_pi = 1.f + magp2 * m_pi_inv2;
295 tofpid.beta_pi =
std::sqrt(1.
f - 1.
f / tofpid.gammasq_pi);
296 tofpid.dt_pi = deltat(m_pi_inv2, tofpid.beta_pi);
297 tofpid.sigma_dt_pi = sigmadeltat(m_pi_inv2);
299 tofpid.gammasq_k = 1.f + magp2 * m_k_inv2;
300 tofpid.beta_k =
std::sqrt(1.
f - 1.
f / tofpid.gammasq_k);
301 tofpid.dt_k = deltat(m_k_inv2, tofpid.beta_k);
302 tofpid.sigma_dt_k = sigmadeltat(m_k_inv2);
304 tofpid.gammasq_p = 1.f + magp2 * m_p_inv2;
305 tofpid.beta_p =
std::sqrt(1.
f - 1.
f / tofpid.gammasq_p);
306 tofpid.dt_p = deltat(m_p_inv2, tofpid.beta_p);
307 tofpid.sigma_dt_p = sigmadeltat(m_p_inv2);
309 tofpid.dt = tofpid.tmtd - tofpid.dt_pi - t_vtx;
310 tofpid.dterror2 = tofpid.tmtderror * tofpid.tmtderror + t_vtx_err * t_vtx_err;
311 tofpid.betaerror = 0.f;
313 tofpid.dterror2 = tofpid.dterror2 + (tofpid.dt_p - tofpid.dt_pi) * (tofpid.dt_p - tofpid.dt_pi);
314 tofpid.betaerror = tofpid.beta_p - tofpid.beta_pi;
317 tofpid.dterror2 = tofpid.dterror2 + tofpid.sigma_dt_pi * tofpid.sigma_dt_pi;
319 tofpid.dterror =
sqrt(tofpid.dterror2);
321 tofpid.dtchi2 = (tofpid.dt * tofpid.dt) / tofpid.dterror2;
323 tofpid.dt_best = tofpid.dt;
324 tofpid.dterror_best = tofpid.dterror;
325 tofpid.dtchi2_best = tofpid.dtchi2;
327 tofpid.prob_pi = -1.f;
328 tofpid.prob_k = -1.f;
329 tofpid.prob_p = -1.f;
333 const float dterror2_wo_sigmatof = tofpid.dterror2 - tofpid.sigma_dt_pi * tofpid.sigma_dt_pi;
334 float chi2_pi = tofpid.dtchi2;
335 float chi2_k = (tofpid.tmtd - tofpid.dt_k - t_vtx) * (tofpid.tmtd - tofpid.dt_k - t_vtx) /
336 (dterror2_wo_sigmatof + tofpid.sigma_dt_k * tofpid.sigma_dt_k);
337 float chi2_p = (tofpid.tmtd - tofpid.dt_p - t_vtx) * (tofpid.tmtd - tofpid.dt_p - t_vtx) /
338 (dterror2_wo_sigmatof + tofpid.sigma_dt_p * tofpid.sigma_dt_p);
340 float rawprob_pi =
exp(-0.5
f * chi2_pi);
341 float rawprob_k =
exp(-0.5
f * chi2_k);
342 float rawprob_p =
exp(-0.5
f * chi2_p);
343 float normprob = 1.f / (rawprob_pi + rawprob_k + rawprob_p);
345 tofpid.prob_pi = rawprob_pi * normprob;
346 tofpid.prob_k = rawprob_k * normprob;
347 tofpid.prob_p = rawprob_p * normprob;
349 float prob_heavy = 1.f - tofpid.prob_pi;
352 if (prob_heavy > heavy_threshold) {
353 if (chi2_k < chi2_p) {
354 tofpid.dt_best = (tofpid.tmtd - tofpid.dt_k - t_vtx);
355 tofpid.dtchi2_best = chi2_k;
357 tofpid.dt_best = (tofpid.tmtd - tofpid.dt_p - t_vtx);
358 tofpid.dtchi2_best = chi2_p;
365 bool getTrajectoryStateClosestToBeamLine(
const Trajectory& traj,
373 if (!stateForProjectionToBeamLineOnSurface.
isValid()) {
374 edm::LogError(
"CannotPropagateToBeamLine") <<
"the state on the closest measurement isnot valid. skipping track.";
381 tscbl = tscblBuilder(stateForProjectionToBeamLine,
bs);
390 TrackSegments& trs) {
393 bool validpropagation =
true;
394 float oldp = traj.
measurements().begin()->updatedState().globalMomentum().mag();
395 float pathlength1 = 0.f;
396 float pathlength2 = 0.f;
400 const auto& propresult = thePropagator->
propagateWithPath(
it->updatedState(), (
it + 1)->updatedState().surface());
401 float layerpathlength =
std::abs(propresult.second);
402 if (layerpathlength == 0.
f) {
403 validpropagation =
false;
405 pathlength1 += layerpathlength;
409 (
it + 1)->updatedState().globalMomentum().mag2();
411 trs.addSegment(layerpathlength, (
it + 1)->updatedState().globalMomentum().
mag2(), sigma_p);
414 << std::setw(14) <<
it->updatedState().globalPosition().perp() <<
" z_i " 415 <<
std::fixed << std::setw(14) <<
it->updatedState().globalPosition().z()
417 << (
it + 1)->updatedState().globalPosition().perp() <<
" z_e " <<
std::fixed 418 << std::setw(14) << (
it + 1)->updatedState().globalPosition().z() <<
" p " 419 <<
std::fixed << std::setw(14) << (
it + 1)->updatedState().globalMomentum().mag()
421 << (
it + 1)->updatedState().globalMomentum().mag() - oldp;
422 oldp = (
it + 1)->updatedState().globalMomentum().mag();
430 if (pathlength2 == 0.
f) {
431 validpropagation =
false;
433 pathlength = pathlength1 + pathlength2;
435 float sigma_p =
sqrt(tscblPCA.curvilinearError().matrix()(0, 0)) * tscblPCA.momentum().mag2();
437 trs.addSegment(pathlength2, tscblPCA.momentum().mag2(), sigma_p);
440 << std::setw(14) << tscblPCA.position().perp() <<
" z_e " <<
std::fixed 441 << std::setw(14) << tscblPCA.position().z() <<
" p " <<
std::fixed << std::setw(14)
442 << tscblPCA.momentum().mag() <<
" dp " <<
std::fixed << std::setw(14)
443 << tscblPCA.momentum().mag() - oldp <<
" sigma_p = " <<
std::fixed << std::setw(14)
444 << sigma_p <<
" sigma_p/p = " <<
std::fixed << std::setw(14)
445 << sigma_p / tscblPCA.momentum().mag() * 100 <<
" %";
447 return validpropagation;
454 TrackSegments& trs) {
458 bool tscbl_status = getTrajectoryStateClosestToBeamLine(traj,
bs, thePropagator, tscbl);
463 return trackPathLength(traj, tscbl, thePropagator, pathlength, trs);
468 template <
class TrackCollection>
476 template <
class H,
class T>
487 const TrackSegments&,
494 const bool matchVertex,
495 MTDHitMatchingInfo& bestHit)
const;
501 const TrackSegments&,
508 const bool matchVertex,
509 MTDHitMatchingInfo& bestHit)
const;
511 void fillMatchingHits(
const DetLayer*,
516 const TrackSegments&,
523 MTDHitMatchingInfo&)
const;
532 auto rFirst =
first.mag2();
533 auto rLast =
last.mag2();
539 LogDebug(
"TrackExtenderWithMTD") <<
"Impossible to determine the rechits order" << endl;
559 float& sigmatofp)
const;
562 string dumpLayer(
const DetLayer* layer)
const;
625 template <
class TrackCollection>
631 updateTraj_(iConfig.getParameter<
bool>(
"updateTrackTrajectory")),
632 updateExtra_(iConfig.getParameter<
bool>(
"updateTrackExtra")),
633 updatePattern_(iConfig.getParameter<
bool>(
"updateTrackHitPattern")),
634 mtdRecHitBuilder_(iConfig.getParameter<
std::
string>(
"MTDRecHitBuilder")),
635 propagator_(iConfig.getParameter<
std::
string>(
"Propagator")),
636 transientTrackBuilder_(iConfig.getParameter<
std::
string>(
"TransientTrackBuilder")),
637 estMaxChi2_(iConfig.getParameter<double>(
"estimatorMaxChi2")),
638 estMaxNSigma_(iConfig.getParameter<double>(
"estimatorMaxNSigma")),
639 btlChi2Cut_(iConfig.getParameter<double>(
"btlChi2Cut")),
640 btlTimeChi2Cut_(iConfig.getParameter<double>(
"btlTimeChi2Cut")),
641 etlChi2Cut_(iConfig.getParameter<double>(
"etlChi2Cut")),
642 etlTimeChi2Cut_(iConfig.getParameter<double>(
"etlTimeChi2Cut")),
643 useVertex_(iConfig.getParameter<
bool>(
"useVertex")),
644 useSimVertex_(iConfig.getParameter<
bool>(
"useSimVertex")),
645 dzCut_(iConfig.getParameter<double>(
"dZCut")),
646 bsTimeSpread_(iConfig.getParameter<double>(
"bsTimeSpread")) {
684 gtgToken_ = esConsumes<GlobalTrackingGeometry, GlobalTrackingGeometryRecord>();
685 dlgeoToken_ = esConsumes<MTDDetLayerGeometry, MTDRecoGeometryRecord>();
686 magfldToken_ = esConsumes<MagneticField, IdealMagneticFieldRecord>();
688 ttopoToken_ = esConsumes<TrackerTopology, TrackerTopologyRcd>();
690 produces<edm::OwnVector<TrackingRecHit>>();
691 produces<reco::TrackExtraCollection>();
692 produces<TrackCollection>();
695 template <
class TrackCollection>
705 desc.add<
bool>(
"updateTrackTrajectory",
true);
706 desc.add<
bool>(
"updateTrackExtra",
true);
707 desc.add<
bool>(
"updateTrackHitPattern",
true);
708 desc.add<
std::string>(
"TransientTrackBuilder",
"TransientTrackBuilder");
713 "KFFitterForRefitInsideOut",
714 "KFSmootherForRefitInsideOut",
715 "PropagatorWithMaterialForMTD",
722 desc.add<
double>(
"estimatorMaxChi2", 500.);
723 desc.add<
double>(
"estimatorMaxNSigma", 10.);
724 desc.add<
double>(
"btlChi2Cut", 50.);
725 desc.add<
double>(
"btlTimeChi2Cut", 10.);
726 desc.add<
double>(
"etlChi2Cut", 50.);
727 desc.add<
double>(
"etlTimeChi2Cut", 10.);
728 desc.add<
bool>(
"useVertex",
false);
729 desc.add<
bool>(
"useSimVertex",
false);
730 desc.add<
double>(
"dZCut", 0.1);
731 desc.add<
double>(
"bsTimeSpread", 0.2);
732 descriptions.
add(
"trackExtenderWithMTDBase",
desc);
735 template <
class TrackCollection>
736 template <
class H,
class T>
739 const std::vector<T>& vec,
741 auto out = std::make_unique<edm::ValueMap<T>>();
748 template <
class TrackCollection>
753 theTransformer->setServices(es);
764 hitbuilder_ = es.
getHandle(hitbuilderToken_);
772 auto output = std::make_unique<TrackCollection>();
773 auto extras = std::make_unique<reco::TrackExtraCollection>();
774 auto outhits = std::make_unique<edm::OwnVector<TrackingRecHit>>();
776 std::vector<float> btlMatchChi2;
777 std::vector<float> etlMatchChi2;
778 std::vector<float> btlMatchTimeChi2;
779 std::vector<float> etlMatchTimeChi2;
780 std::vector<int> npixBarrel;
781 std::vector<int> npixEndcap;
782 std::vector<float> outermostHitPosition;
783 std::vector<float> pOrigTrkRaw;
784 std::vector<float> betaOrigTrkRaw;
785 std::vector<float> t0OrigTrkRaw;
786 std::vector<float> sigmat0OrigTrkRaw;
787 std::vector<float> pathLengthsOrigTrkRaw;
788 std::vector<float> tmtdOrigTrkRaw;
789 std::vector<float> sigmatmtdOrigTrkRaw;
790 std::vector<GlobalPoint> tmtdPosOrigTrkRaw;
791 std::vector<float> tofpiOrigTrkRaw;
792 std::vector<float> tofkOrigTrkRaw;
793 std::vector<float> tofpOrigTrkRaw;
794 std::vector<float> sigmatofpiOrigTrkRaw;
795 std::vector<float> sigmatofkOrigTrkRaw;
796 std::vector<float> sigmatofpOrigTrkRaw;
797 std::vector<int> assocOrigTrkRaw;
799 auto const tracksH =
ev.getHandle(tracksToken_);
801 const auto& trjtrks =
ev.get(trajTrackAToken_);
804 const auto&
hits =
ev.get(hitsToken_);
807 const auto&
bs =
ev.get(bsToken_);
810 if (useVertex_ && !useSimVertex_) {
811 auto const& vtxs =
ev.get(vtxToken_);
816 std::unique_ptr<math::XYZTLorentzVectorF> genPV(
nullptr);
817 if (useVertex_ && useSimVertex_) {
818 const auto& genVtxPosition =
ev.get(genVtxPositionToken_);
819 const auto& genVtxTime =
ev.get(genVtxTimeToken_);
820 genPV = std::make_unique<math::XYZTLorentzVectorF>(
821 genVtxPosition.x(), genVtxPosition.y(), genVtxPosition.z(), genVtxTime);
826 if (useSimVertex_ && genPV) {
827 vtxTime = genPV->t();
832 std::vector<unsigned> track_indices;
835 for (
const auto& trjtrk : trjtrks) {
839 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: extrapolating track " << itrack
840 <<
" p/pT = " <<
track->p() <<
" " <<
track->pt() <<
" eta = " <<
track->eta();
841 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: sigma_p = " 843 <<
" sigma_p/p = " <<
sqrt(
track->covariance()(0, 0)) *
track->p() * 100 <<
" %";
845 float trackVtxTime = 0.f;
854 trackVtxTime = vtxTime;
858 auto thits = theTransformer->getTransientRecHits(ttrack);
860 MTDHitMatchingInfo mBTL, mETL;
866 bool tscbl_status = getTrajectoryStateClosestToBeamLine(trajs,
bs, prop, tscbl);
872 trackPathLength(trajs, tscbl, prop, pathlength0, trs0);
874 const auto& btlhits = tryBTLLayers(tsos,
887 mtdthits.insert(mtdthits.end(), btlhits.begin(), btlhits.end());
891 const auto& etlhits = tryETLLayers(tsos,
904 mtdthits.insert(mtdthits.end(), etlhits.begin(), etlhits.end());
908 LogTrace(
"TrackExtenderWithMTD") <<
"Failing getTrajectoryStateClosestToBeamLine, no search for hits in MTD!";
913 auto ordering = checkRecHitsOrdering(thits);
915 thits.insert(thits.end(), mtdthits.begin(), mtdthits.end());
918 mtdthits.insert(mtdthits.end(), thits.begin(), thits.end());
919 thits.swap(mtdthits);
922 const auto& trajwithmtd =
923 mtdthits.empty() ? std::vector<Trajectory>(1, trajs) : theTransformer->transform(ttrack, thits);
924 float pMap = 0.f, betaMap = 0.f, t0Map = 0.f, sigmat0Map = -1.f, pathLengthMap = -1.f, tmtdMap = 0.f,
925 sigmatmtdMap = -1.f, tofpiMap = 0.f, tofkMap = 0.f, tofpMap = 0.f, sigmatofpiMap = -1.f, sigmatofkMap = -1.f,
930 for (
const auto& trj : trajwithmtd) {
931 const auto& thetrj = (updateTraj_ ? trj : trajs);
932 float pathLength = 0.f, tmtd = 0.f, sigmatmtd = -1.f, tofpi = 0.f, tofk = 0.f, tofp = 0.f, sigmatofpi = -1.f,
933 sigmatofk = -1.f, sigmatofp = -1.f;
935 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: refit track " << itrack <<
" p/pT = " <<
track->p()
936 <<
" " <<
track->pt() <<
" eta = " <<
track->eta();
943 !trajwithmtd.empty() && !mtdthits.empty(),
958 size_t hitsstart = outhits->size();
959 if (updatePattern_) {
960 t2t(trj, *outhits, trajParams, chi2s);
962 t2t(thetrj, *outhits, trajParams, chi2s);
964 size_t hitsend = outhits->size();
965 extras->push_back(buildTrackExtra(trj));
966 extras->back().setHits(hitsRefProd, hitsstart, hitsend - hitsstart);
967 extras->back().setTrajParams(trajParams, chi2s);
970 btlMatchChi2.push_back(mBTL.hit ? mBTL.estChi2 : -1.f);
971 etlMatchChi2.push_back(mETL.hit ? mETL.estChi2 : -1.f);
972 btlMatchTimeChi2.push_back(mBTL.hit ? mBTL.timeChi2 : -1.f);
973 etlMatchTimeChi2.push_back(mETL.hit ? mETL.timeChi2 : -1.f);
974 pathLengthMap = pathLength;
976 sigmatmtdMap = sigmatmtd;
977 tmtdPosMap = tmtdPos;
978 auto& backtrack =
output->back();
979 iMap =
output->size() - 1;
980 pMap = backtrack.p();
981 betaMap = backtrack.beta();
982 t0Map = backtrack.t0();
983 sigmat0Map = std::copysign(
std::sqrt(
std::abs(backtrack.covt0t0())), backtrack.covt0t0());
987 sigmatofpiMap = sigmatofpi;
988 sigmatofkMap = sigmatofk;
989 sigmatofpMap = sigmatofp;
991 backtrack.setExtra((updateExtra_ ? extraRef :
track->extra()));
992 for (
unsigned ihit = hitsstart; ihit < hitsend; ++ihit) {
993 backtrack.appendHitPattern((*outhits)[ihit], ttopo);
996 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: hit pattern of refitted track";
1000 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: missing hit pattern of refitted track";
1005 npixBarrel.push_back(backtrack.hitPattern().numberOfValidPixelBarrelHits());
1006 npixEndcap.push_back(backtrack.hitPattern().numberOfValidPixelEndcapHits());
1007 outermostHitPosition.push_back(
1008 mBTL.hit ? (
float)(*track).outerRadius()
1009 : (
float)(*track).outerZ());
1011 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: tmtd " << tmtdMap <<
" +/- " << sigmatmtdMap
1012 <<
" t0 " << t0Map <<
" +/- " << sigmat0Map <<
" tof pi/K/p " << tofpiMap
1013 <<
"+/-" <<
fmt::format(
"{:0.2g}", sigmatofpiMap) <<
" (" 1014 <<
fmt::format(
"{:0.2g}", sigmatofpiMap / tofpiMap * 100) <<
"%) " << tofkMap
1015 <<
"+/-" <<
fmt::format(
"{:0.2g}", sigmatofkMap) <<
" (" 1016 <<
fmt::format(
"{:0.2g}", sigmatofkMap / tofkMap * 100) <<
"%) " << tofpMap
1017 <<
"+/-" <<
fmt::format(
"{:0.2g}", sigmatofpMap) <<
" (" 1018 <<
fmt::format(
"{:0.2g}", sigmatofpMap / tofpMap * 100) <<
"%) ";
1020 LogTrace(
"TrackExtenderWithMTD") <<
"Error in the MTD track refitting. This should not happen";
1024 pOrigTrkRaw.push_back(pMap);
1025 betaOrigTrkRaw.push_back(betaMap);
1026 t0OrigTrkRaw.push_back(t0Map);
1027 sigmat0OrigTrkRaw.push_back(sigmat0Map);
1028 pathLengthsOrigTrkRaw.push_back(pathLengthMap);
1029 tmtdOrigTrkRaw.push_back(tmtdMap);
1030 sigmatmtdOrigTrkRaw.push_back(sigmatmtdMap);
1031 tmtdPosOrigTrkRaw.push_back(tmtdPosMap);
1032 tofpiOrigTrkRaw.push_back(tofpiMap);
1033 tofkOrigTrkRaw.push_back(tofkMap);
1034 tofpOrigTrkRaw.push_back(tofpMap);
1035 sigmatofpiOrigTrkRaw.push_back(sigmatofpiMap);
1036 sigmatofkOrigTrkRaw.push_back(sigmatofkMap);
1037 sigmatofpOrigTrkRaw.push_back(sigmatofpMap);
1038 assocOrigTrkRaw.push_back(iMap);
1041 btlMatchChi2.push_back(-1.
f);
1042 etlMatchChi2.push_back(-1.
f);
1043 btlMatchTimeChi2.push_back(-1.
f);
1044 etlMatchTimeChi2.push_back(-1.
f);
1045 npixBarrel.push_back(-1.
f);
1046 npixEndcap.push_back(-1.
f);
1047 outermostHitPosition.push_back(0.);
1057 fillValueMap(
ev, tracksH, btlMatchChi2, btlMatchChi2Token_);
1058 fillValueMap(
ev, tracksH, etlMatchChi2, etlMatchChi2Token_);
1059 fillValueMap(
ev, tracksH, btlMatchTimeChi2, btlMatchTimeChi2Token_);
1060 fillValueMap(
ev, tracksH, etlMatchTimeChi2, etlMatchTimeChi2Token_);
1061 fillValueMap(
ev, tracksH, npixBarrel, npixBarrelToken_);
1062 fillValueMap(
ev, tracksH, npixEndcap, npixEndcapToken_);
1063 fillValueMap(
ev, tracksH, outermostHitPosition, outermostHitPositionToken_);
1064 fillValueMap(
ev, tracksH, pOrigTrkRaw, pOrigTrkToken_);
1065 fillValueMap(
ev, tracksH, betaOrigTrkRaw, betaOrigTrkToken_);
1066 fillValueMap(
ev, tracksH, t0OrigTrkRaw, t0OrigTrkToken_);
1067 fillValueMap(
ev, tracksH, sigmat0OrigTrkRaw, sigmat0OrigTrkToken_);
1068 fillValueMap(
ev, tracksH, pathLengthsOrigTrkRaw, pathLengthOrigTrkToken_);
1069 fillValueMap(
ev, tracksH, tmtdOrigTrkRaw, tmtdOrigTrkToken_);
1070 fillValueMap(
ev, tracksH, sigmatmtdOrigTrkRaw, sigmatmtdOrigTrkToken_);
1071 fillValueMap(
ev, tracksH, tmtdPosOrigTrkRaw, tmtdPosOrigTrkToken_);
1072 fillValueMap(
ev, tracksH, tofpiOrigTrkRaw, tofpiOrigTrkToken_);
1073 fillValueMap(
ev, tracksH, tofkOrigTrkRaw, tofkOrigTrkToken_);
1074 fillValueMap(
ev, tracksH, tofpOrigTrkRaw, tofpOrigTrkToken_);
1075 fillValueMap(
ev, tracksH, sigmatofpiOrigTrkRaw, sigmatofpiOrigTrkToken_);
1076 fillValueMap(
ev, tracksH, sigmatofkOrigTrkRaw, sigmatofkOrigTrkToken_);
1077 fillValueMap(
ev, tracksH, sigmatofpOrigTrkRaw, sigmatofpOrigTrkToken_);
1078 fillValueMap(
ev, tracksH, assocOrigTrkRaw, assocOrigTrkToken_);
1082 bool cmp_for_detset(
const unsigned one,
const unsigned two) {
return one <
two; };
1089 const float pathlength0,
1090 const TrackSegments& trs0,
1091 const float vtxTime,
1093 const float bsTimeSpread,
1096 bool useVtxConstraint,
1097 std::set<MTDHitMatchingInfo>&
out) {
1098 pair<bool, TrajectoryStateOnSurface>
comp =
layer->compatible(tsos, *prop, *
estimator);
1100 const vector<DetLayer::DetWithState> compDets =
layer->compatibleDets(tsos, *prop, *
estimator);
1101 LogTrace(
"TrackExtenderWithMTD") <<
"Hit search: Compatible dets " << compDets.size();
1102 if (!compDets.empty()) {
1103 for (
const auto& detWithState : compDets) {
1104 auto range =
hits.equal_range(detWithState.first->geographicalId(), cmp_for_detset);
1107 <<
"Hit search: no hit in DetId " << detWithState.first->geographicalId().rawId();
1112 if (pl.second == 0.) {
1114 <<
"Hit search: no propagation to DetId " << detWithState.first->geographicalId().rawId();
1118 const float t_vtx = useVtxConstraint ? vtxTime : 0.f;
1121 const float t_vtx_err = useVtxConstraint ? vtx_res : bsTimeSpread;
1123 float lastpmag2 = trs0.getSegmentPathAndMom2(0).second;
1125 for (
auto detitr =
range.first; detitr !=
range.second; ++detitr) {
1126 for (
const auto&
hit : *detitr) {
1127 auto est =
estimator->estimate(detWithState.second,
hit);
1130 <<
"Hit search: no compatible estimate in DetId " << detWithState.first->geographicalId().rawId()
1131 <<
" for hit at pos (" <<
std::fixed << std::setw(14) <<
hit.globalPosition().
x() <<
"," 1133 <<
hit.globalPosition().
z() <<
")";
1138 <<
"Hit search: spatial compatibility DetId " << detWithState.first->geographicalId().rawId()
1139 <<
" TSOS dx/dy " <<
std::fixed << std::setw(14)
1141 << std::setw(14) <<
std::sqrt(detWithState.second.localError().positionError().yy()) <<
" hit dx/dy " 1144 << std::setw(14) << est.second;
1146 TrackTofPidInfo tof = computeTrackTofPidInfo(lastpmag2,
1155 SigmaTofCalc::kMixd);
1156 MTDHitMatchingInfo mi;
1158 mi.estChi2 = est.second;
1159 mi.timeChi2 = tof.dtchi2_best;
1170 template <
class TrackCollection>
1175 const float pathlength0,
1176 const TrackSegments& trs0,
1182 const float vtxTime,
1183 const bool matchVertex,
1184 MTDHitMatchingInfo& bestHit)
const {
1188 bestHit = MTDHitMatchingInfo();
1190 LogTrace(
"TrackExtenderWithMTD") <<
"Hit search: BTL layer at R= " 1191 <<
static_cast<const BarrelDetLayer*
>(ilay)->specificSurface().radius();
1193 fillMatchingHits(ilay, tsos, traj, pmag2, pathlength0, trs0,
hits, prop,
bs, vtxTime, matchVertex,
output, bestHit);
1199 template <
class TrackCollection>
1204 const float pathlength0,
1205 const TrackSegments& trs0,
1211 const float vtxTime,
1212 const bool matchVertex,
1213 MTDHitMatchingInfo& bestHit)
const {
1217 bestHit = MTDHitMatchingInfo();
1220 const float diskZ = disk.position().z();
1225 LogTrace(
"TrackExtenderWithMTD") <<
"Hit search: ETL disk at Z = " << diskZ;
1227 fillMatchingHits(ilay, tsos, traj, pmag2, pathlength0, trs0,
hits, prop,
bs, vtxTime, matchVertex,
output, bestHit);
1232 if (
output.size() == 2) {
1240 template <
class TrackCollection>
1245 const float pathlength0,
1246 const TrackSegments& trs0,
1250 const float& vtxTime,
1251 const bool matchVertex,
1253 MTDHitMatchingInfo& bestHit)
const {
1254 std::set<MTDHitMatchingInfo> hitsInLayer;
1255 bool hitMatched =
false;
1258 auto find_hits = std::bind(find_hits_in_dets,
1272 std::ref(hitsInLayer));
1274 if (useVertex_ && matchVertex)
1275 find_hits(vtxTime,
true);
1277 find_hits(0,
false);
1279 float spaceChi2Cut = ilay->
isBarrel() ? btlChi2Cut_ : etlChi2Cut_;
1280 float timeChi2Cut = ilay->
isBarrel() ? btlTimeChi2Cut_ : etlTimeChi2Cut_;
1283 if (!hitsInLayer.empty()) {
1285 auto const& firstHit = *hitsInLayer.begin();
1286 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: matching trial 1: estChi2= " << firstHit.estChi2
1287 <<
" timeChi2= " << firstHit.timeChi2;
1288 if (firstHit.estChi2 < spaceChi2Cut && firstHit.timeChi2 < timeChi2Cut) {
1290 output.push_back(hitbuilder_->build(firstHit.hit));
1291 if (firstHit < bestHit)
1296 if (useVertex_ && matchVertex && !hitMatched) {
1298 hitsInLayer.clear();
1299 find_hits(0,
false);
1300 if (!hitsInLayer.empty()) {
1301 auto const& firstHit = *hitsInLayer.begin();
1302 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: matching trial 2: estChi2= " << firstHit.estChi2
1303 <<
" timeChi2= " << firstHit.timeChi2;
1304 if (firstHit.timeChi2 < timeChi2Cut) {
1305 if (firstHit.estChi2 < spaceChi2Cut) {
1307 output.push_back(hitbuilder_->build(firstHit.hit));
1308 if (firstHit < bestHit)
1317 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: matched hit with time: " << bestHit.hit->time()
1318 <<
" +/- " << bestHit.hit->timeError();
1320 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: no matched hit";
1327 template <
class TrackCollection>
1335 float& pathLengthOut,
1337 float& sigmatmtdOut,
1344 float& sigmatofp)
const {
1346 bool tsbcl_status = getTrajectoryStateClosestToBeamLine(traj,
bs, thePropagator, tscbl);
1359 float covt0t0 = -1.f;
1360 pathLengthOut = -1.f;
1362 sigmatmtdOut = -1.f;
1363 float betaOut = 0.f;
1364 float covbetabeta = -1.f;
1366 auto routput = [&]() {
1385 bool validpropagation = trackPathLength(trajWithMtd,
bs, thePropagator, pathlength, trs);
1387 float thiterror = -1.f;
1389 bool validmtd =
false;
1391 if (!validpropagation) {
1395 uint32_t ihitcount(0), ietlcount(0);
1400 if (
MTDDetId(
hit.recHit()->geographicalId()).mtdSubDetector() == MTDDetId::MTDType::ETL) {
1406 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: selected #hits " << ihitcount <<
" from ETL " 1410 if (ihitcount == 1) {
1412 thit = mtdhit->
time();
1416 }
else if (ihitcount == 2 && ietlcount == 2) {
1417 std::pair<float, float> lastStep = trs.getSegmentPathAndMom2(0);
1422 if (etlpathlength == 0.
f) {
1423 validpropagation =
false;
1425 pathlength -= etlpathlength;
1426 trs.removeFirstSegment();
1429 TrackTofPidInfo tofInfo = computeTrackTofPidInfo(
1430 lastStep.second, etlpathlength, trs, mtdhit1->
time(), mtdhit1->
timeError(), 0.f, 0.f,
true, TofCalc::kCost);
1434 float err1 = tofInfo.dterror2;
1438 <<
"MTD tracking hits with zero time uncertainty: " << err1 <<
" " << err2;
1440 if ((tofInfo.dt - mtdhit2->
time()) * (tofInfo.dt - mtdhit2->
time()) < (err1 + err2) * etlTimeChi2Cut_) {
1447 thiterror = 1.f / (err1 + err2);
1448 thit = (tofInfo.dt * err1 + mtdhit2->
time() * err2) * thiterror;
1452 <<
"TrackExtenderWithMTD: p trk = " <<
p.mag() <<
" ETL hits times/errors: 1) " << mtdhit1->
time()
1454 <<
" extrapolated time1: " << tofInfo.dt <<
" +/- " << tofInfo.dterror <<
" average = " << thit
1455 <<
" +/- " << thiterror <<
"\n hit1 pos: " << mtdhit1->
globalPosition()
1456 <<
" hit2 pos: " << mtdhit2->
globalPosition() <<
" etl path length " << etlpathlength << std::endl;
1462 thiterror = tofInfo.dterror;
1465 thit = mtdhit2->
time();
1474 <<
"MTD hits #" << ihitcount <<
"ETL hits #" << ietlcount <<
" anomalous pattern, skipping...";
1477 if (validmtd && validpropagation) {
1479 TrackTofPidInfo tofInfo = computeTrackTofPidInfo(
1480 p.mag2(), pathlength, trs, thit, thiterror, 0.f, 0.f,
true, TofCalc::kSegm, SigmaTofCalc::kCost);
1482 pathLengthOut = pathlength;
1484 sigmatmtdOut = thiterror;
1485 tmtdPosOut = thitpos;
1487 covt0t0 = tofInfo.dterror2;
1488 betaOut = tofInfo.beta_pi;
1489 covbetabeta = tofInfo.betaerror * tofInfo.betaerror;
1490 tofpi = tofInfo.dt_pi;
1491 tofk = tofInfo.dt_k;
1492 tofp = tofInfo.dt_p;
1493 sigmatofpi = tofInfo.sigma_dt_pi;
1494 sigmatofk = tofInfo.sigma_dt_k;
1495 sigmatofp = tofInfo.sigma_dt_p;
1502 template <
class TrackCollection>
1504 static const string metname =
"TrackExtenderWithMTD";
1514 unsigned int innerId = 0, outerId = 0;
1537 const GeomDet* outerDet = gtg_->idToDet(outerDetId);
1545 LogTrace(
metname) <<
"The Global Muon outerMostMeasurementState is not compatible with the recHit detector!" 1546 <<
" Setting outerMost postition to recHit position if recHit isValid: " 1547 << outerRecHit->isValid();
1578 template <
class TrackCollection>
1586 sur = &(
layer->surface());
1587 if ((bc = dynamic_cast<const BoundCylinder*>(sur))) {
1588 output <<
" Cylinder of radius: " << bc->radius() << endl;
1589 }
else if ((bd = dynamic_cast<const BoundDisk*>(sur))) {
1590 output <<
" Disk at: " << bd->position().z() << endl;
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
TrackExtenderWithMTDT< reco::TrackCollection > TrackExtenderWithMTD
edm::EDPutToken btlMatchTimeChi2Token_
T getParameter(std::string const &) const
edm::EDPutToken pOrigTrkToken_
edm::ESGetToken< TransientTrackingRecHitBuilder, TransientRecHitRecord > hitbuilderToken_
edm::EDPutToken t0OrigTrkToken_
const CurvilinearTrajectoryError & curvilinearError() const
const float bsTimeSpread_
edm::EDPutToken btlMatchChi2Token_
virtual bool inside(const Local3DPoint &) const =0
Determine if the point is inside the bounds.
edm::EDPutToken tofpOrigTrkToken_
bool operator<(IOVSyncValue const &iLHS, IOVSyncValue const &iRHS)
const float btlTimeChi2Cut_
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
GlobalPoint position() const
edm::ESGetToken< GlobalTrackingGeometry, GlobalTrackingGeometryRecord > gtgToken_
edm::EDPutToken sigmatofkOrigTrkToken_
const std::string metname
edm::EDGetTokenT< reco::BeamSpot > bsToken_
std::unique_ptr< MeasurementEstimator > theEstimator
TrackExtenderWithMTDT(const ParameterSet &pset)
edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > ttopoToken_
const GlobalTrajectoryParameters & globalParameters() const
ParameterSet const & getParameterSet(std::string const &) const
Global3DPoint GlobalPoint
edm::EDPutToken etlMatchChi2Token_
edm::View< TrackType > InputCollection
edm::EDGetTokenT< GlobalPoint > genVtxPositionToken_
edm::RefToBase< TrajectorySeed > seedRef(void) const
Log< level::Error, false > LogError
const SurfaceType & surface() const
edm::EDPutToken tofkOrigTrkToken_
edm::EDPutToken etlMatchTimeChi2Token_
edm::EDPutToken sigmat0OrigTrkToken_
void fillValueMap(edm::Event &iEvent, const H &handle, const std::vector< T > &vec, const edm::EDPutToken &token) const
edm::EDPutToken tmtdOrigTrkToken_
TrajectoryMeasurement const & lastMeasurement() const
edm::EDGetTokenT< MTDTrackingDetSetVector > hitsToken_
Detector identifier base class for the MIP Timing Layer.
TransientTrackingRecHit::ConstRecHitContainer tryETLLayers(const TrajectoryStateOnSurface &, const Trajectory &traj, const float, const float, const TrackSegments &, const MTDTrackingDetSetVector &, const MTDDetLayerGeometry *, const MagneticField *field, const Propagator *prop, const reco::BeamSpot &bs, const float vtxTime, const bool matchVertex, MTDHitMatchingInfo &bestHit) const
DataContainer const & measurements() const
GlobalPoint position() const
edm::EDPutToken sigmatofpiOrigTrkToken_
string dumpLayer(const DetLayer *layer) const
GlobalVector momentum() const
int ndof(bool bon=true) const
Container::value_type value_type
GlobalPoint globalPosition() const
const float estMaxNSigma_
edm::EDPutToken tmtdPosOrigTrkToken_
edm::ESGetToken< TransientTrackBuilder, TransientTrackRecord > builderToken_
const std::string mtdRecHitBuilder_
void fillMatchingHits(const DetLayer *, const TrajectoryStateOnSurface &, const Trajectory &, const float, const float, const TrackSegments &, const MTDTrackingDetSetVector &, const Propagator *, const reco::BeamSpot &, const float &, const bool, TransientTrackingRecHit::ConstRecHitContainer &, MTDHitMatchingInfo &) const
PropagationDirection const & direction() const
TrackCharge charge() const
ConstRecHitContainer recHits() const
reco::Track buildTrack(const reco::TrackRef &, const Trajectory &, const Trajectory &, const reco::BeamSpot &, const MagneticField *field, const Propagator *prop, bool hasMTD, float &pathLength, float &tmtdOut, float &sigmatmtdOut, GlobalPoint &tmtdPosOut, float &tofpi, float &tofk, float &tofp, float &sigmatofpi, float &sigmatofk, float &sigmatofp) const
GlobalVector momentum() const
Abs< T >::type abs(const T &t)
#define DEFINE_FWK_MODULE(type)
FTS const & trackStateAtPCA() const
edm::EDPutToken assocOrigTrkToken_
const std::string propagator_
edm::EDPutToken outermostHitPositionToken_
edm::ESGetToken< Propagator, TrackingComponentsRecord > propToken_
virtual std::pair< TrajectoryStateOnSurface, double > propagateWithPath(const FreeTrajectoryState &, const Surface &) const final
constexpr valType roundIfNear0(valType value, double tolerance=1.e-7)
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
edm::ESHandle< TransientTrackingRecHitBuilder > hitbuilder_
const std::vector< const DetLayer * > & allBTLLayers() const
return the BTL DetLayers (barrel), inside-out
std::vector< ConstRecHitPointer > ConstRecHitContainer
const std::string transientTrackBuilder_
Log< level::Info, false > LogInfo
GlobalPoint globalPosition() const final
std::vector< TrackExtra > TrackExtraCollection
collection of TrackExtra objects
ConstRecHitContainer RecHitContainer
constexpr NumType convertMmToCm(NumType millimeters)
const Plane & surface() const
The nominal surface of the GeomDet.
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const CurvilinearTrajectoryError & curvilinearError() const
XYZVectorD XYZVector
spatial vector with cartesian internal representation
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
XYZPointD XYZPoint
point in space with cartesian internal representation
reco::TrackExtra buildTrackExtra(const Trajectory &trajectory) const
A 2D TrackerRecHit with time and time error information.
CurvilinearTrajectoryError curvilinearError(const PerigeeTrajectoryError &perigeeError, const GlobalTrajectoryParameters >p)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
TrackingRecHit::ConstRecHitPointer ConstRecHitPointer
edm::ESHandle< TransientTrackBuilder > builder_
std::unique_ptr< TrackTransformer > theTransformer
TrajectoryStateOnSurface const & updatedState() const
edm::EDPutToken npixBarrelToken_
edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > magfldToken_
edm::EDPutToken npixEndcapToken_
TrajectoryMeasurement const & firstMeasurement() const
static int position[264][3]
TrajectoryMeasurement const & closestMeasurement(GlobalPoint) const
edm::EDPutToken betaOrigTrkToken_
FreeTrajectoryState const * freeState(bool withErrors=true) const
ESTransientHandle< T > getTransientHandle(const ESGetToken< T, R > &iToken) const
edm::EDGetTokenT< TrajTrackAssociationCollection > trajTrackAToken_
edm::EDPutToken pathLengthOrigTrkToken_
edm::ESHandle< GlobalTrackingGeometry > gtg_
edm::EDPutToken sigmatmtdOrigTrkToken_
TransientTrackingRecHit::ConstRecHitContainer tryBTLLayers(const TrajectoryStateOnSurface &, const Trajectory &traj, const float, const float, const TrackSegments &, const MTDTrackingDetSetVector &, const MTDDetLayerGeometry *, const MagneticField *field, const Propagator *prop, const reco::BeamSpot &bs, const float vtxTime, const bool matchVertex, MTDHitMatchingInfo &bestHit) const
edm::EDPutToken tofpiOrigTrkToken_
edm::EDGetTokenT< float > genVtxTimeToken_
edm::EDGetTokenT< VertexCollection > vtxToken_
if(threadIdxLocalY==0 &&threadIdxLocalX==0)
void produce(edm::Event &ev, const edm::EventSetup &es) final
TrackCollection::value_type TrackType
edm::EDGetTokenT< InputCollection > tracksToken_
const std::vector< const DetLayer * > & allETLLayers() const
return the ETL DetLayers (endcap), -Z to +Z
const float etlTimeChi2Cut_
RefitDirection::GeometricalDirection checkRecHitsOrdering(TransientTrackingRecHit::ConstRecHitContainer const &recHits) const
ConstRecHitPointer const & recHit() const
edm::EDPutToken sigmatofpOrigTrkToken_
edm::ESGetToken< MTDDetLayerGeometry, MTDRecoGeometryRecord > dlgeoToken_
const Bounds & bounds() const