56 #include "CLHEP/Units/GlobalPhysicalConstants.h" 70 class MTDHitMatchingInfo {
72 MTDHitMatchingInfo() {
79 inline bool operator<(
const MTDHitMatchingInfo&
m2)
const {
84 if (timeChi2 < chi2_cut &&
m2.timeChi2 < chi2_cut)
85 return chi2(low_weight) <
m2.chi2(low_weight);
87 return chi2(high_weight) <
m2.chi2(high_weight);
90 inline float chi2(
float timeWeight = 1.
f)
const {
return estChi2 + timeWeight * timeChi2; }
100 sigmaTofs_.reserve(30);
103 inline uint32_t addSegment(
float tPath,
float tMom2,
float sigmaMom) {
104 segmentPathOvc_.emplace_back(tPath *
c_inv);
105 segmentMom2_.emplace_back(tMom2);
106 segmentSigmaMom_.emplace_back(sigmaMom);
109 LogTrace(
"TrackExtenderWithMTD") <<
"addSegment # " << nSegment_ <<
" s = " << tPath
110 <<
" p = " <<
std::sqrt(tMom2) <<
" sigma_p = " << sigmaMom
111 <<
" sigma_p/p = " << sigmaMom /
std::sqrt(tMom2) * 100 <<
" %";
116 inline float computeTof(
float mass_inv2)
const {
118 for (uint32_t iSeg = 0; iSeg < nSegment_; iSeg++) {
119 float gammasq = 1.f + segmentMom2_[iSeg] * mass_inv2;
121 tof += segmentPathOvc_[iSeg] /
beta;
123 LogTrace(
"TrackExtenderWithMTD") <<
" TOF Segment # " << iSeg + 1 <<
" p = " <<
std::sqrt(segmentMom2_[iSeg])
127 float sigma_tof = segmentPathOvc_[iSeg] * segmentSigmaMom_[iSeg] /
128 (segmentMom2_[iSeg] *
sqrt(segmentMom2_[iSeg] + 1 / mass_inv2) * mass_inv2);
130 LogTrace(
"TrackExtenderWithMTD") <<
"TOF Segment # " << iSeg + 1 <<
std::fixed << std::setw(6)
131 <<
" tof segment = " << segmentPathOvc_[iSeg] /
beta << std::scientific
133 <<
"(rel. err. = " << sigma_tof / (segmentPathOvc_[iSeg] /
beta) * 100
141 inline float computeSigmaTof(
float mass_inv2) {
150 for (uint32_t iSeg = 0; iSeg < nSegment_; iSeg++) {
151 sigma = segmentPathOvc_[iSeg] * segmentSigmaMom_[iSeg] /
152 (segmentMom2_[iSeg] *
sqrt(segmentMom2_[iSeg] + 1 / mass_inv2) * mass_inv2);
153 sigmaTofs_.push_back(sigma);
155 sigmatof += sigma * sigma;
159 for (uint32_t iSeg = 0; iSeg < nSegment_; iSeg++) {
160 for (uint32_t jSeg = iSeg + 1; jSeg < nSegment_; jSeg++) {
161 sigmatof += 2 * sigmaTofs_[iSeg] * sigmaTofs_[jSeg];
165 return sqrt(sigmatof);
168 inline uint32_t
size()
const {
return nSegment_; }
170 inline uint32_t removeFirstSegment() {
172 segmentPathOvc_.erase(segmentPathOvc_.begin());
173 segmentMom2_.erase(segmentMom2_.begin());
179 inline std::pair<float, float> getSegmentPathAndMom2(uint32_t iSegment)
const {
180 if (iSegment >= nSegment_) {
181 throw cms::Exception(
"TrackExtenderWithMTD") <<
"Requesting non existing track segment #" << iSegment;
183 return std::make_pair(segmentPathOvc_[iSegment], segmentMom2_[iSegment]);
186 uint32_t nSegment_ = 0;
187 std::vector<float> segmentPathOvc_;
188 std::vector<float> segmentMom2_;
189 std::vector<float> segmentSigmaMom_;
191 std::vector<float> sigmaTofs_;
194 struct TrackTofPidInfo {
229 enum class TofCalc { kCost = 1, kSegm = 2, kMixd = 3 };
232 const TrackTofPidInfo computeTrackTofPidInfo(
float magp2,
239 bool addPIDError =
true,
240 TofCalc choice = TofCalc::kCost,
245 constexpr float m_k_inv2 = 1.0f / m_k / m_k;
247 constexpr float m_p_inv2 = 1.0f / m_p / m_p;
249 TrackTofPidInfo tofpid;
252 tofpid.tmtderror = t_mtderr;
253 tofpid.pathlength = length;
255 auto deltat = [&](
const float mass_inv2,
const float betatmp) {
259 res = tofpid.pathlength / betatmp *
c_inv;
262 res = trs.computeTof(mass_inv2);
265 res = trs.computeTof(mass_inv2) + tofpid.pathlength / betatmp *
c_inv;
271 auto sigmadeltat = [&](
const float mass_inv2) {
273 switch (sigma_choice) {
274 case SigmaTofCalc::kCost:
276 res = tofpid.pathlength *
c_inv * trs.segmentSigmaMom_[trs.nSegment_ - 1] /
277 (magp2 *
sqrt(magp2 + 1 / mass_inv2) * mass_inv2);
279 case SigmaTofCalc::kSegm:
280 res = trs.computeSigmaTof(mass_inv2);
287 tofpid.gammasq_pi = 1.f + magp2 * m_pi_inv2;
288 tofpid.beta_pi =
std::sqrt(1.
f - 1.
f / tofpid.gammasq_pi);
289 tofpid.dt_pi = deltat(m_pi_inv2, tofpid.beta_pi);
290 tofpid.sigma_dt_pi = sigmadeltat(m_pi_inv2);
292 tofpid.gammasq_k = 1.f + magp2 * m_k_inv2;
293 tofpid.beta_k =
std::sqrt(1.
f - 1.
f / tofpid.gammasq_k);
294 tofpid.dt_k = deltat(m_k_inv2, tofpid.beta_k);
295 tofpid.sigma_dt_k = sigmadeltat(m_k_inv2);
297 tofpid.gammasq_p = 1.f + magp2 * m_p_inv2;
298 tofpid.beta_p =
std::sqrt(1.
f - 1.
f / tofpid.gammasq_p);
299 tofpid.dt_p = deltat(m_p_inv2, tofpid.beta_p);
300 tofpid.sigma_dt_p = sigmadeltat(m_p_inv2);
302 tofpid.dt = tofpid.tmtd - tofpid.dt_pi - t_vtx;
303 tofpid.dterror =
sqrt(tofpid.tmtderror * tofpid.tmtderror + t_vtx_err * t_vtx_err);
304 tofpid.betaerror = 0.f;
307 sqrt(tofpid.dterror * tofpid.dterror + (tofpid.dt_p - tofpid.dt_pi) * (tofpid.dt_p - tofpid.dt_pi));
308 tofpid.betaerror = tofpid.beta_p - tofpid.beta_pi;
311 tofpid.dtchi2 = (tofpid.dt * tofpid.dt) / (tofpid.dterror * tofpid.dterror);
313 tofpid.dt_best = tofpid.dt;
314 tofpid.dterror_best = tofpid.dterror;
315 tofpid.dtchi2_best = tofpid.dtchi2;
317 tofpid.prob_pi = -1.f;
318 tofpid.prob_k = -1.f;
319 tofpid.prob_p = -1.f;
323 float chi2_pi = tofpid.dtchi2;
325 (tofpid.tmtd - tofpid.dt_k - t_vtx) * (tofpid.tmtd - tofpid.dt_k - t_vtx) / (tofpid.dterror * tofpid.dterror);
327 (tofpid.tmtd - tofpid.dt_p - t_vtx) * (tofpid.tmtd - tofpid.dt_p - t_vtx) / (tofpid.dterror * tofpid.dterror);
329 float rawprob_pi =
exp(-0.5
f * chi2_pi);
330 float rawprob_k =
exp(-0.5
f * chi2_k);
331 float rawprob_p =
exp(-0.5
f * chi2_p);
332 float normprob = 1.f / (rawprob_pi + rawprob_k + rawprob_p);
334 tofpid.prob_pi = rawprob_pi * normprob;
335 tofpid.prob_k = rawprob_k * normprob;
336 tofpid.prob_p = rawprob_p * normprob;
338 float prob_heavy = 1.f - tofpid.prob_pi;
341 if (prob_heavy > heavy_threshold) {
342 if (chi2_k < chi2_p) {
343 tofpid.dt_best = (tofpid.tmtd - tofpid.dt_k - t_vtx);
344 tofpid.dtchi2_best = chi2_k;
346 tofpid.dt_best = (tofpid.tmtd - tofpid.dt_p - t_vtx);
347 tofpid.dtchi2_best = chi2_p;
354 bool getTrajectoryStateClosestToBeamLine(
const Trajectory& traj,
362 if (!stateForProjectionToBeamLineOnSurface.
isValid()) {
363 edm::LogError(
"CannotPropagateToBeamLine") <<
"the state on the closest measurement isnot valid. skipping track.";
370 tscbl = tscblBuilder(stateForProjectionToBeamLine,
bs);
379 TrackSegments& trs) {
382 bool validpropagation =
true;
383 float oldp = traj.
measurements().begin()->updatedState().globalMomentum().mag();
384 float pathlength1 = 0.f;
385 float pathlength2 = 0.f;
389 const auto& propresult = thePropagator->
propagateWithPath(
it->updatedState(), (
it + 1)->updatedState().surface());
390 float layerpathlength =
std::abs(propresult.second);
391 if (layerpathlength == 0.
f) {
392 validpropagation =
false;
394 pathlength1 += layerpathlength;
398 (
it + 1)->updatedState().globalMomentum().mag2();
400 trs.addSegment(layerpathlength, (
it + 1)->updatedState().globalMomentum().
mag2(), sigma_p);
403 << std::setw(14) <<
it->updatedState().globalPosition().perp() <<
" z_i " 404 <<
std::fixed << std::setw(14) <<
it->updatedState().globalPosition().z()
406 << (
it + 1)->updatedState().globalPosition().perp() <<
" z_e " <<
std::fixed 407 << std::setw(14) << (
it + 1)->updatedState().globalPosition().z() <<
" p " 408 <<
std::fixed << std::setw(14) << (
it + 1)->updatedState().globalMomentum().mag()
410 << (
it + 1)->updatedState().globalMomentum().mag() - oldp;
411 oldp = (
it + 1)->updatedState().globalMomentum().mag();
419 if (pathlength2 == 0.
f) {
420 validpropagation =
false;
422 pathlength = pathlength1 + pathlength2;
424 float sigma_p =
sqrt(tscblPCA.curvilinearError().matrix()(0, 0)) * tscblPCA.momentum().mag2();
426 trs.addSegment(pathlength2, tscblPCA.momentum().mag2(), sigma_p);
429 << std::setw(14) << tscblPCA.position().perp() <<
" z_e " <<
std::fixed 430 << std::setw(14) << tscblPCA.position().z() <<
" p " <<
std::fixed << std::setw(14)
431 << tscblPCA.momentum().mag() <<
" dp " <<
std::fixed << std::setw(14)
432 << tscblPCA.momentum().mag() - oldp <<
" sigma_p = " <<
std::fixed << std::setw(14)
433 << sigma_p <<
" sigma_p/p = " <<
std::fixed << std::setw(14)
434 << sigma_p / tscblPCA.momentum().mag() * 100 <<
" %";
436 return validpropagation;
443 TrackSegments& trs) {
447 bool tscbl_status = getTrajectoryStateClosestToBeamLine(traj,
bs, thePropagator, tscbl);
452 return trackPathLength(traj, tscbl, thePropagator, pathlength, trs);
457 template <
class TrackCollection>
465 template <
class H,
class T>
476 const TrackSegments&,
483 const bool matchVertex,
484 MTDHitMatchingInfo& bestHit)
const;
490 const TrackSegments&,
497 const bool matchVertex,
498 MTDHitMatchingInfo& bestHit)
const;
500 void fillMatchingHits(
const DetLayer*,
505 const TrackSegments&,
512 MTDHitMatchingInfo&)
const;
521 auto rFirst =
first.mag2();
522 auto rLast =
last.mag2();
528 LogDebug(
"TrackExtenderWithMTD") <<
"Impossible to determine the rechits order" << endl;
547 float& sigmatofp)
const;
550 string dumpLayer(
const DetLayer* layer)
const;
611 template <
class TrackCollection>
617 updateTraj_(iConfig.getParameter<
bool>(
"updateTrackTrajectory")),
618 updateExtra_(iConfig.getParameter<
bool>(
"updateTrackExtra")),
619 updatePattern_(iConfig.getParameter<
bool>(
"updateTrackHitPattern")),
620 mtdRecHitBuilder_(iConfig.getParameter<
std::
string>(
"MTDRecHitBuilder")),
621 propagator_(iConfig.getParameter<
std::
string>(
"Propagator")),
622 transientTrackBuilder_(iConfig.getParameter<
std::
string>(
"TransientTrackBuilder")),
623 estMaxChi2_(iConfig.getParameter<double>(
"estimatorMaxChi2")),
624 estMaxNSigma_(iConfig.getParameter<double>(
"estimatorMaxNSigma")),
625 btlChi2Cut_(iConfig.getParameter<double>(
"btlChi2Cut")),
626 btlTimeChi2Cut_(iConfig.getParameter<double>(
"btlTimeChi2Cut")),
627 etlChi2Cut_(iConfig.getParameter<double>(
"etlChi2Cut")),
628 etlTimeChi2Cut_(iConfig.getParameter<double>(
"etlTimeChi2Cut")),
629 useVertex_(iConfig.getParameter<
bool>(
"useVertex")),
630 useSimVertex_(iConfig.getParameter<
bool>(
"useSimVertex")),
631 dzCut_(iConfig.getParameter<double>(
"dZCut")),
632 bsTimeSpread_(iConfig.getParameter<double>(
"bsTimeSpread")) {
668 gtgToken_ = esConsumes<GlobalTrackingGeometry, GlobalTrackingGeometryRecord>();
669 dlgeoToken_ = esConsumes<MTDDetLayerGeometry, MTDRecoGeometryRecord>();
670 magfldToken_ = esConsumes<MagneticField, IdealMagneticFieldRecord>();
672 ttopoToken_ = esConsumes<TrackerTopology, TrackerTopologyRcd>();
674 produces<edm::OwnVector<TrackingRecHit>>();
675 produces<reco::TrackExtraCollection>();
676 produces<TrackCollection>();
679 template <
class TrackCollection>
689 desc.add<
bool>(
"updateTrackTrajectory",
true);
690 desc.add<
bool>(
"updateTrackExtra",
true);
691 desc.add<
bool>(
"updateTrackHitPattern",
true);
692 desc.add<
std::string>(
"TransientTrackBuilder",
"TransientTrackBuilder");
697 "KFFitterForRefitInsideOut",
698 "KFSmootherForRefitInsideOut",
699 "PropagatorWithMaterialForMTD",
706 desc.add<
double>(
"estimatorMaxChi2", 500.);
707 desc.add<
double>(
"estimatorMaxNSigma", 10.);
708 desc.add<
double>(
"btlChi2Cut", 50.);
709 desc.add<
double>(
"btlTimeChi2Cut", 10.);
710 desc.add<
double>(
"etlChi2Cut", 50.);
711 desc.add<
double>(
"etlTimeChi2Cut", 10.);
712 desc.add<
bool>(
"useVertex",
false);
713 desc.add<
bool>(
"useSimVertex",
false);
714 desc.add<
double>(
"dZCut", 0.1);
715 desc.add<
double>(
"bsTimeSpread", 0.2);
716 descriptions.
add(
"trackExtenderWithMTDBase",
desc);
719 template <
class TrackCollection>
720 template <
class H,
class T>
723 const std::vector<T>& vec,
725 auto out = std::make_unique<edm::ValueMap<T>>();
732 template <
class TrackCollection>
737 theTransformer->setServices(es);
749 hitbuilder_ = es.
getHandle(hitbuilderToken_);
757 auto output = std::make_unique<TrackCollection>();
758 auto extras = std::make_unique<reco::TrackExtraCollection>();
759 auto outhits = std::make_unique<edm::OwnVector<TrackingRecHit>>();
761 std::vector<float> btlMatchChi2;
762 std::vector<float> etlMatchChi2;
763 std::vector<float> btlMatchTimeChi2;
764 std::vector<float> etlMatchTimeChi2;
765 std::vector<int> npixBarrel;
766 std::vector<int> npixEndcap;
767 std::vector<float> pOrigTrkRaw;
768 std::vector<float> betaOrigTrkRaw;
769 std::vector<float> t0OrigTrkRaw;
770 std::vector<float> sigmat0OrigTrkRaw;
771 std::vector<float> pathLengthsOrigTrkRaw;
772 std::vector<float> tmtdOrigTrkRaw;
773 std::vector<float> sigmatmtdOrigTrkRaw;
774 std::vector<float> tofpiOrigTrkRaw;
775 std::vector<float> tofkOrigTrkRaw;
776 std::vector<float> tofpOrigTrkRaw;
777 std::vector<float> sigmatofpiOrigTrkRaw;
778 std::vector<float> sigmatofkOrigTrkRaw;
779 std::vector<float> sigmatofpOrigTrkRaw;
780 std::vector<int> assocOrigTrkRaw;
782 auto const tracksH =
ev.getHandle(tracksToken_);
784 const auto& trjtrks =
ev.get(trajTrackAToken_);
787 const auto&
hits =
ev.get(hitsToken_);
790 const auto&
bs =
ev.get(bsToken_);
793 if (useVertex_ && !useSimVertex_) {
794 auto const& vtxs =
ev.get(vtxToken_);
799 std::unique_ptr<math::XYZTLorentzVectorF> genPV(
nullptr);
800 if (useVertex_ && useSimVertex_) {
801 const auto& genVtxPosition =
ev.get(genVtxPositionToken_);
802 const auto& genVtxTime =
ev.get(genVtxTimeToken_);
803 genPV = std::make_unique<math::XYZTLorentzVectorF>(
804 genVtxPosition.x(), genVtxPosition.y(), genVtxPosition.z(), genVtxTime);
809 if (useSimVertex_ && genPV) {
810 vtxTime = genPV->t();
815 std::vector<unsigned> track_indices;
818 for (
const auto& trjtrk : trjtrks) {
822 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: extrapolating track " << itrack
823 <<
" p/pT = " <<
track->p() <<
" " <<
track->pt() <<
" eta = " <<
track->eta();
824 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: sigma_p = " 826 <<
" sigma_p/p = " <<
sqrt(
track->covariance()(0, 0)) *
track->p() * 100 <<
" %";
828 float trackVtxTime = 0.f;
837 trackVtxTime = vtxTime;
841 auto thits = theTransformer->getTransientRecHits(ttrack);
843 MTDHitMatchingInfo mBTL, mETL;
849 bool tscbl_status = getTrajectoryStateClosestToBeamLine(trajs,
bs, prop, tscbl);
855 trackPathLength(trajs, tscbl, prop, pathlength0, trs0);
857 const auto& btlhits = tryBTLLayers(tsos,
870 mtdthits.insert(mtdthits.end(), btlhits.begin(), btlhits.end());
874 const auto& etlhits = tryETLLayers(tsos,
887 mtdthits.insert(mtdthits.end(), etlhits.begin(), etlhits.end());
891 auto ordering = checkRecHitsOrdering(thits);
893 thits.insert(thits.end(), mtdthits.begin(), mtdthits.end());
896 mtdthits.insert(mtdthits.end(), thits.begin(), thits.end());
897 thits.swap(mtdthits);
900 const auto& trajwithmtd =
901 mtdthits.empty() ? std::vector<Trajectory>(1, trajs) : theTransformer->transform(ttrack, thits);
902 float pMap = 0.f, betaMap = 0.f, t0Map = 0.f, sigmat0Map = -1.f, pathLengthMap = -1.f, tmtdMap = 0.f,
903 sigmatmtdMap = -1.f, tofpiMap = 0.f, tofkMap = 0.f, tofpMap = 0.f, sigmatofpiMap = -1.f, sigmatofkMap = -1.f,
907 for (
const auto& trj : trajwithmtd) {
908 const auto& thetrj = (updateTraj_ ? trj : trajs);
909 float pathLength = 0.f, tmtd = 0.f, sigmatmtd = -1.f, tofpi = 0.f, tofk = 0.f, tofp = 0.f, sigmatofpi = -1.f,
910 sigmatofk = -1.f, sigmatofp = -1.f;
911 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: refit track " << itrack <<
" p/pT = " <<
track->p()
912 <<
" " <<
track->pt() <<
" eta = " <<
track->eta();
919 !trajwithmtd.empty() && !mtdthits.empty(),
933 size_t hitsstart = outhits->size();
934 if (updatePattern_) {
935 t2t(trj, *outhits, trajParams, chi2s);
937 t2t(thetrj, *outhits, trajParams, chi2s);
939 size_t hitsend = outhits->size();
940 extras->push_back(buildTrackExtra(trj));
941 extras->back().setHits(hitsRefProd, hitsstart, hitsend - hitsstart);
942 extras->back().setTrajParams(trajParams, chi2s);
945 btlMatchChi2.push_back(mBTL.hit ? mBTL.estChi2 : -1.f);
946 etlMatchChi2.push_back(mETL.hit ? mETL.estChi2 : -1.f);
947 btlMatchTimeChi2.push_back(mBTL.hit ? mBTL.timeChi2 : -1.f);
948 etlMatchTimeChi2.push_back(mETL.hit ? mETL.timeChi2 : -1.f);
949 pathLengthMap = pathLength;
951 sigmatmtdMap = sigmatmtd;
952 auto& backtrack =
output->back();
953 iMap =
output->size() - 1;
954 pMap = backtrack.p();
955 betaMap = backtrack.beta();
956 t0Map = backtrack.t0();
957 sigmat0Map = std::copysign(
std::sqrt(
std::abs(backtrack.covt0t0())), backtrack.covt0t0());
961 sigmatofpiMap = sigmatofpi;
962 sigmatofkMap = sigmatofk;
963 sigmatofpMap = sigmatofp;
965 backtrack.setExtra((updateExtra_ ? extraRef :
track->extra()));
966 for (
unsigned ihit = hitsstart; ihit < hitsend; ++ihit) {
967 backtrack.appendHitPattern((*outhits)[ihit], ttopo);
969 npixBarrel.push_back(backtrack.hitPattern().numberOfValidPixelBarrelHits());
970 npixEndcap.push_back(backtrack.hitPattern().numberOfValidPixelEndcapHits());
971 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: tmtd " << tmtdMap <<
" +/- " << sigmatmtdMap
972 <<
" t0 " << t0Map <<
" +/- " << sigmat0Map <<
" tof pi/K/p " << tofpiMap
973 <<
"+/-" <<
fmt::format(
"{:0.2g}", sigmatofpiMap) <<
" (" 974 <<
fmt::format(
"{:0.2g}", sigmatofpiMap / tofpiMap * 100) <<
"%) " << tofkMap
975 <<
"+/-" <<
fmt::format(
"{:0.2g}", sigmatofkMap) <<
" (" 976 <<
fmt::format(
"{:0.2g}", sigmatofkMap / tofkMap * 100) <<
"%) " << tofpMap
977 <<
"+/-" <<
fmt::format(
"{:0.2g}", sigmatofpMap) <<
" (" 978 <<
fmt::format(
"{:0.2g}", sigmatofpMap / tofpMap * 100) <<
"%) ";
980 LogTrace(
"TrackExtenderWithMTD") <<
"Error in the MTD track refitting. This should not happen";
984 pOrigTrkRaw.push_back(pMap);
985 betaOrigTrkRaw.push_back(betaMap);
986 t0OrigTrkRaw.push_back(t0Map);
987 sigmat0OrigTrkRaw.push_back(sigmat0Map);
988 pathLengthsOrigTrkRaw.push_back(pathLengthMap);
989 tmtdOrigTrkRaw.push_back(tmtdMap);
990 sigmatmtdOrigTrkRaw.push_back(sigmatmtdMap);
991 tofpiOrigTrkRaw.push_back(tofpiMap);
992 tofkOrigTrkRaw.push_back(tofkMap);
993 tofpOrigTrkRaw.push_back(tofpMap);
994 sigmatofpiOrigTrkRaw.push_back(sigmatofpiMap);
995 sigmatofkOrigTrkRaw.push_back(sigmatofkMap);
996 sigmatofpOrigTrkRaw.push_back(sigmatofpMap);
997 assocOrigTrkRaw.push_back(iMap);
1000 btlMatchChi2.push_back(-1.
f);
1001 etlMatchChi2.push_back(-1.
f);
1002 btlMatchTimeChi2.push_back(-1.
f);
1003 etlMatchTimeChi2.push_back(-1.
f);
1004 npixBarrel.push_back(-1.
f);
1005 npixEndcap.push_back(-1.
f);
1015 fillValueMap(
ev, tracksH, btlMatchChi2, btlMatchChi2Token_);
1016 fillValueMap(
ev, tracksH, etlMatchChi2, etlMatchChi2Token_);
1017 fillValueMap(
ev, tracksH, btlMatchTimeChi2, btlMatchTimeChi2Token_);
1018 fillValueMap(
ev, tracksH, etlMatchTimeChi2, etlMatchTimeChi2Token_);
1019 fillValueMap(
ev, tracksH, npixBarrel, npixBarrelToken_);
1020 fillValueMap(
ev, tracksH, npixEndcap, npixEndcapToken_);
1021 fillValueMap(
ev, tracksH, pOrigTrkRaw, pOrigTrkToken_);
1022 fillValueMap(
ev, tracksH, betaOrigTrkRaw, betaOrigTrkToken_);
1023 fillValueMap(
ev, tracksH, t0OrigTrkRaw, t0OrigTrkToken_);
1024 fillValueMap(
ev, tracksH, sigmat0OrigTrkRaw, sigmat0OrigTrkToken_);
1025 fillValueMap(
ev, tracksH, pathLengthsOrigTrkRaw, pathLengthOrigTrkToken_);
1026 fillValueMap(
ev, tracksH, tmtdOrigTrkRaw, tmtdOrigTrkToken_);
1027 fillValueMap(
ev, tracksH, sigmatmtdOrigTrkRaw, sigmatmtdOrigTrkToken_);
1028 fillValueMap(
ev, tracksH, tofpiOrigTrkRaw, tofpiOrigTrkToken_);
1029 fillValueMap(
ev, tracksH, tofkOrigTrkRaw, tofkOrigTrkToken_);
1030 fillValueMap(
ev, tracksH, tofpOrigTrkRaw, tofpOrigTrkToken_);
1031 fillValueMap(
ev, tracksH, sigmatofpiOrigTrkRaw, sigmatofpiOrigTrkToken_);
1032 fillValueMap(
ev, tracksH, sigmatofkOrigTrkRaw, sigmatofkOrigTrkToken_);
1033 fillValueMap(
ev, tracksH, sigmatofpOrigTrkRaw, sigmatofpOrigTrkToken_);
1034 fillValueMap(
ev, tracksH, assocOrigTrkRaw, assocOrigTrkToken_);
1038 bool cmp_for_detset(
const unsigned one,
const unsigned two) {
return one <
two; };
1045 const float pathlength0,
1046 const TrackSegments& trs0,
1047 const float vtxTime,
1049 const float bsTimeSpread,
1052 bool useVtxConstraint,
1053 std::set<MTDHitMatchingInfo>&
out) {
1054 pair<bool, TrajectoryStateOnSurface>
comp =
layer->compatible(tsos, *prop, *
estimator);
1056 const vector<DetLayer::DetWithState> compDets =
layer->compatibleDets(tsos, *prop, *
estimator);
1057 LogTrace(
"TrackExtenderWithMTD") <<
"Hit search: Compatible dets " << compDets.size();
1058 if (!compDets.empty()) {
1059 for (
const auto& detWithState : compDets) {
1060 auto range =
hits.equal_range(detWithState.first->geographicalId(), cmp_for_detset);
1063 <<
"Hit search: no hit in DetId " << detWithState.first->geographicalId().rawId();
1068 if (pl.second == 0.) {
1070 <<
"Hit search: no propagation to DetId " << detWithState.first->geographicalId().rawId();
1074 const float t_vtx = useVtxConstraint ? vtxTime : 0.f;
1077 const float t_vtx_err = useVtxConstraint ? vtx_res : bsTimeSpread;
1079 float lastpmag2 = trs0.getSegmentPathAndMom2(0).second;
1081 for (
auto detitr =
range.first; detitr !=
range.second; ++detitr) {
1082 for (
const auto&
hit : *detitr) {
1083 auto est =
estimator->estimate(detWithState.second,
hit);
1086 <<
"Hit search: no compatible estimate in DetId " << detWithState.first->geographicalId().rawId()
1087 <<
" for hit at pos (" <<
std::fixed << std::setw(14) <<
hit.globalPosition().
x() <<
"," 1089 <<
hit.globalPosition().
z() <<
")";
1094 <<
"Hit search: spatial compatibility DetId " << detWithState.first->geographicalId().rawId()
1095 <<
" TSOS dx/dy " <<
std::fixed << std::setw(14)
1097 << std::setw(14) <<
std::sqrt(detWithState.second.localError().positionError().yy()) <<
" hit dx/dy " 1100 << std::setw(14) << est.second;
1102 TrackTofPidInfo tof = computeTrackTofPidInfo(lastpmag2,
1111 MTDHitMatchingInfo mi;
1113 mi.estChi2 = est.second;
1114 mi.timeChi2 = tof.dtchi2_best;
1125 template <
class TrackCollection>
1130 const float pathlength0,
1131 const TrackSegments& trs0,
1137 const float vtxTime,
1138 const bool matchVertex,
1139 MTDHitMatchingInfo& bestHit)
const {
1143 bestHit = MTDHitMatchingInfo();
1145 LogTrace(
"TrackExtenderWithMTD") <<
"Hit search: BTL layer at R= " 1146 <<
static_cast<const BarrelDetLayer*
>(ilay)->specificSurface().radius();
1148 fillMatchingHits(ilay, tsos, traj, pmag2, pathlength0, trs0,
hits, prop,
bs, vtxTime, matchVertex,
output, bestHit);
1154 template <
class TrackCollection>
1159 const float pathlength0,
1160 const TrackSegments& trs0,
1166 const float vtxTime,
1167 const bool matchVertex,
1168 MTDHitMatchingInfo& bestHit)
const {
1172 bestHit = MTDHitMatchingInfo();
1175 const float diskZ = disk.position().z();
1180 LogTrace(
"TrackExtenderWithMTD") <<
"Hit search: ETL disk at Z = " << diskZ;
1182 fillMatchingHits(ilay, tsos, traj, pmag2, pathlength0, trs0,
hits, prop,
bs, vtxTime, matchVertex,
output, bestHit);
1187 if (
output.size() == 2) {
1195 template <
class TrackCollection>
1200 const float pathlength0,
1201 const TrackSegments& trs0,
1205 const float& vtxTime,
1206 const bool matchVertex,
1208 MTDHitMatchingInfo& bestHit)
const {
1209 std::set<MTDHitMatchingInfo> hitsInLayer;
1210 bool hitMatched =
false;
1213 auto find_hits = std::bind(find_hits_in_dets,
1227 std::ref(hitsInLayer));
1229 if (useVertex_ && matchVertex)
1230 find_hits(vtxTime,
true);
1232 find_hits(0,
false);
1234 float spaceChi2Cut = ilay->
isBarrel() ? btlChi2Cut_ : etlChi2Cut_;
1235 float timeChi2Cut = ilay->
isBarrel() ? btlTimeChi2Cut_ : etlTimeChi2Cut_;
1238 if (!hitsInLayer.empty()) {
1240 auto const& firstHit = *hitsInLayer.begin();
1241 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: matching trial 1: estChi2= " << firstHit.estChi2
1242 <<
" timeChi2= " << firstHit.timeChi2;
1243 if (firstHit.estChi2 < spaceChi2Cut && firstHit.timeChi2 < timeChi2Cut) {
1245 output.push_back(hitbuilder_->build(firstHit.hit));
1246 if (firstHit < bestHit)
1251 if (useVertex_ && matchVertex && !hitMatched) {
1253 hitsInLayer.clear();
1254 find_hits(0,
false);
1255 if (!hitsInLayer.empty()) {
1256 auto const& firstHit = *hitsInLayer.begin();
1257 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: matching trial 2: estChi2= " << firstHit.estChi2
1258 <<
" timeChi2= " << firstHit.timeChi2;
1259 if (firstHit.timeChi2 < timeChi2Cut) {
1260 if (firstHit.estChi2 < spaceChi2Cut) {
1262 output.push_back(hitbuilder_->build(firstHit.hit));
1263 if (firstHit < bestHit)
1272 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: matched hit with time: " << bestHit.hit->time()
1273 <<
" +/- " << bestHit.hit->timeError();
1275 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: no matched hit";
1282 template <
class TrackCollection>
1290 float& pathLengthOut,
1292 float& sigmatmtdOut,
1298 float& sigmatofp)
const {
1300 bool tsbcl_status = getTrajectoryStateClosestToBeamLine(traj,
bs, thePropagator, tscbl);
1313 float covt0t0 = -1.f;
1314 pathLengthOut = -1.f;
1316 sigmatmtdOut = -1.f;
1317 float betaOut = 0.f;
1318 float covbetabeta = -1.f;
1320 auto routput = [&]() {
1339 bool validpropagation = trackPathLength(trajWithMtd,
bs, thePropagator, pathlength, trs);
1341 float thiterror = -1.f;
1342 bool validmtd =
false;
1344 if (!validpropagation) {
1348 uint32_t ihitcount(0), ietlcount(0);
1353 if (
MTDDetId(
hit.recHit()->geographicalId()).mtdSubDetector() == MTDDetId::MTDType::ETL) {
1359 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: selected #hits " << ihitcount <<
" from ETL " 1363 if (ihitcount == 1) {
1365 thit = mtdhit->
time();
1368 }
else if (ihitcount == 2 && ietlcount == 2) {
1369 std::pair<float, float> lastStep = trs.getSegmentPathAndMom2(0);
1374 if (etlpathlength == 0.
f) {
1375 validpropagation =
false;
1377 pathlength -= etlpathlength;
1378 trs.removeFirstSegment();
1381 TrackTofPidInfo tofInfo = computeTrackTofPidInfo(
1382 lastStep.second, etlpathlength, trs, mtdhit1->
time(), mtdhit1->
timeError(), 0.f, 0.f,
true, TofCalc::kCost);
1386 float err1 = tofInfo.dterror * tofInfo.dterror;
1390 <<
"MTD tracking hits with zero time uncertainty: " << err1 <<
" " << err2;
1392 if ((tofInfo.dt - mtdhit2->
time()) * (tofInfo.dt - mtdhit2->
time()) < (err1 + err2) * etlTimeChi2Cut_) {
1399 thiterror = 1.f / (err1 + err2);
1400 thit = (tofInfo.dt * err1 + mtdhit2->
time() * err2) * thiterror;
1403 <<
"TrackExtenderWithMTD: p trk = " <<
p.mag() <<
" ETL hits times/errors: " << mtdhit1->
time()
1405 <<
" extrapolated time1: " << tofInfo.dt <<
" +/- " << tofInfo.dterror <<
" average = " << thit
1406 <<
" +/- " << thiterror;
1412 thiterror = tofInfo.dterror;
1415 thit = mtdhit2->
time();
1424 <<
"MTD hits #" << ihitcount <<
"ETL hits #" << ietlcount <<
" anomalous pattern, skipping...";
1427 if (validmtd && validpropagation) {
1429 TrackTofPidInfo tofInfo = computeTrackTofPidInfo(
1430 p.mag2(), pathlength, trs, thit, thiterror, 0.f, 0.f,
true, TofCalc::kSegm, SigmaTofCalc::kCost);
1432 pathLengthOut = pathlength;
1434 sigmatmtdOut = thiterror;
1436 covt0t0 = tofInfo.dterror * tofInfo.dterror;
1437 betaOut = tofInfo.beta_pi;
1438 covbetabeta = tofInfo.betaerror * tofInfo.betaerror;
1439 tofpi = tofInfo.dt_pi;
1440 tofk = tofInfo.dt_k;
1441 tofp = tofInfo.dt_p;
1442 sigmatofpi = tofInfo.sigma_dt_pi;
1443 sigmatofk = tofInfo.sigma_dt_k;
1444 sigmatofp = tofInfo.sigma_dt_p;
1451 template <
class TrackCollection>
1453 static const string metname =
"TrackExtenderWithMTD";
1463 unsigned int innerId = 0, outerId = 0;
1486 const GeomDet* outerDet = gtg_->idToDet(outerDetId);
1494 LogTrace(
metname) <<
"The Global Muon outerMostMeasurementState is not compatible with the recHit detector!" 1495 <<
" Setting outerMost postition to recHit position if recHit isValid: " 1496 << outerRecHit->isValid();
1527 template <
class TrackCollection>
1535 sur = &(
layer->surface());
1536 if ((bc = dynamic_cast<const BoundCylinder*>(sur))) {
1537 output <<
" Cylinder of radius: " << bc->radius() << endl;
1538 }
else if ((bd = dynamic_cast<const BoundDisk*>(sur))) {
1539 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
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, float &tofpi, float &tofk, float &tofp, float &sigmatofpi, float &sigmatofk, float &sigmatofp) const
const float estMaxNSigma_
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
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::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
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_
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