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 {
230 enum class TofCalc { kCost = 1, kSegm = 2, kMixd = 3 };
233 const TrackTofPidInfo computeTrackTofPidInfo(
float magp2,
240 bool addPIDError =
true,
241 TofCalc choice = TofCalc::kCost,
246 constexpr float m_k_inv2 = 1.0f / m_k / m_k;
248 constexpr float m_p_inv2 = 1.0f / m_p / m_p;
250 TrackTofPidInfo tofpid;
253 tofpid.tmtderror = t_mtderr;
254 tofpid.pathlength = length;
256 auto deltat = [&](
const float mass_inv2,
const float betatmp) {
260 res = tofpid.pathlength / betatmp *
c_inv;
263 res = trs.computeTof(mass_inv2);
266 res = trs.computeTof(mass_inv2) + tofpid.pathlength / betatmp *
c_inv;
272 auto sigmadeltat = [&](
const float mass_inv2) {
274 switch (sigma_choice) {
275 case SigmaTofCalc::kCost:
277 res = tofpid.pathlength *
c_inv * trs.segmentSigmaMom_[trs.nSegment_ - 1] /
278 (magp2 *
sqrt(magp2 + 1 / mass_inv2) * mass_inv2);
280 case SigmaTofCalc::kSegm:
281 res = trs.computeSigmaTof(mass_inv2);
283 case SigmaTofCalc::kMixd:
284 float res1 = tofpid.pathlength *
c_inv * trs.segmentSigmaMom_[trs.nSegment_ - 1] /
285 (magp2 *
sqrt(magp2 + 1 / mass_inv2) * mass_inv2);
286 float res2 = trs.computeSigmaTof(mass_inv2);
287 res =
sqrt(res1 * res1 + res2 * res2 + 2 * res1 * res2);
293 tofpid.gammasq_pi = 1.f + magp2 * m_pi_inv2;
294 tofpid.beta_pi =
std::sqrt(1.
f - 1.
f / tofpid.gammasq_pi);
295 tofpid.dt_pi = deltat(m_pi_inv2, tofpid.beta_pi);
296 tofpid.sigma_dt_pi = sigmadeltat(m_pi_inv2);
298 tofpid.gammasq_k = 1.f + magp2 * m_k_inv2;
299 tofpid.beta_k =
std::sqrt(1.
f - 1.
f / tofpid.gammasq_k);
300 tofpid.dt_k = deltat(m_k_inv2, tofpid.beta_k);
301 tofpid.sigma_dt_k = sigmadeltat(m_k_inv2);
303 tofpid.gammasq_p = 1.f + magp2 * m_p_inv2;
304 tofpid.beta_p =
std::sqrt(1.
f - 1.
f / tofpid.gammasq_p);
305 tofpid.dt_p = deltat(m_p_inv2, tofpid.beta_p);
306 tofpid.sigma_dt_p = sigmadeltat(m_p_inv2);
308 tofpid.dt = tofpid.tmtd - tofpid.dt_pi - t_vtx;
309 tofpid.dterror2 = tofpid.tmtderror * tofpid.tmtderror + t_vtx_err * t_vtx_err;
310 tofpid.betaerror = 0.f;
312 tofpid.dterror2 = tofpid.dterror2 + (tofpid.dt_p - tofpid.dt_pi) * (tofpid.dt_p - tofpid.dt_pi);
313 tofpid.betaerror = tofpid.beta_p - tofpid.beta_pi;
316 tofpid.dterror2 = tofpid.dterror2 + tofpid.sigma_dt_pi * tofpid.sigma_dt_pi;
318 tofpid.dterror =
sqrt(tofpid.dterror2);
320 tofpid.dtchi2 = (tofpid.dt * tofpid.dt) / tofpid.dterror2;
322 tofpid.dt_best = tofpid.dt;
323 tofpid.dterror_best = tofpid.dterror;
324 tofpid.dtchi2_best = tofpid.dtchi2;
326 tofpid.prob_pi = -1.f;
327 tofpid.prob_k = -1.f;
328 tofpid.prob_p = -1.f;
332 const float dterror2_wo_sigmatof = tofpid.dterror2 - tofpid.sigma_dt_pi * tofpid.sigma_dt_pi;
333 float chi2_pi = tofpid.dtchi2;
334 float chi2_k = (tofpid.tmtd - tofpid.dt_k - t_vtx) * (tofpid.tmtd - tofpid.dt_k - t_vtx) /
335 (dterror2_wo_sigmatof + tofpid.sigma_dt_k * tofpid.sigma_dt_k);
336 float chi2_p = (tofpid.tmtd - tofpid.dt_p - t_vtx) * (tofpid.tmtd - tofpid.dt_p - t_vtx) /
337 (dterror2_wo_sigmatof + tofpid.sigma_dt_p * tofpid.sigma_dt_p);
339 float rawprob_pi =
exp(-0.5
f * chi2_pi);
340 float rawprob_k =
exp(-0.5
f * chi2_k);
341 float rawprob_p =
exp(-0.5
f * chi2_p);
342 float normprob = 1.f / (rawprob_pi + rawprob_k + rawprob_p);
344 tofpid.prob_pi = rawprob_pi * normprob;
345 tofpid.prob_k = rawprob_k * normprob;
346 tofpid.prob_p = rawprob_p * normprob;
348 float prob_heavy = 1.f - tofpid.prob_pi;
351 if (prob_heavy > heavy_threshold) {
352 if (chi2_k < chi2_p) {
353 tofpid.dt_best = (tofpid.tmtd - tofpid.dt_k - t_vtx);
354 tofpid.dtchi2_best = chi2_k;
356 tofpid.dt_best = (tofpid.tmtd - tofpid.dt_p - t_vtx);
357 tofpid.dtchi2_best = chi2_p;
364 bool getTrajectoryStateClosestToBeamLine(
const Trajectory& traj,
372 if (!stateForProjectionToBeamLineOnSurface.
isValid()) {
373 edm::LogError(
"CannotPropagateToBeamLine") <<
"the state on the closest measurement isnot valid. skipping track.";
380 tscbl = tscblBuilder(stateForProjectionToBeamLine,
bs);
389 TrackSegments& trs) {
392 bool validpropagation =
true;
393 float oldp = traj.
measurements().begin()->updatedState().globalMomentum().mag();
394 float pathlength1 = 0.f;
395 float pathlength2 = 0.f;
399 const auto& propresult = thePropagator->
propagateWithPath(
it->updatedState(), (
it + 1)->updatedState().surface());
400 float layerpathlength =
std::abs(propresult.second);
401 if (layerpathlength == 0.
f) {
402 validpropagation =
false;
404 pathlength1 += layerpathlength;
408 (
it + 1)->updatedState().globalMomentum().mag2();
410 trs.addSegment(layerpathlength, (
it + 1)->updatedState().globalMomentum().
mag2(), sigma_p);
413 << std::setw(14) <<
it->updatedState().globalPosition().perp() <<
" z_i " 414 <<
std::fixed << std::setw(14) <<
it->updatedState().globalPosition().z()
416 << (
it + 1)->updatedState().globalPosition().perp() <<
" z_e " <<
std::fixed 417 << std::setw(14) << (
it + 1)->updatedState().globalPosition().z() <<
" p " 418 <<
std::fixed << std::setw(14) << (
it + 1)->updatedState().globalMomentum().mag()
420 << (
it + 1)->updatedState().globalMomentum().mag() - oldp;
421 oldp = (
it + 1)->updatedState().globalMomentum().mag();
429 if (pathlength2 == 0.
f) {
430 validpropagation =
false;
432 pathlength = pathlength1 + pathlength2;
434 float sigma_p =
sqrt(tscblPCA.curvilinearError().matrix()(0, 0)) * tscblPCA.momentum().mag2();
436 trs.addSegment(pathlength2, tscblPCA.momentum().mag2(), sigma_p);
439 << std::setw(14) << tscblPCA.position().perp() <<
" z_e " <<
std::fixed 440 << std::setw(14) << tscblPCA.position().z() <<
" p " <<
std::fixed << std::setw(14)
441 << tscblPCA.momentum().mag() <<
" dp " <<
std::fixed << std::setw(14)
442 << tscblPCA.momentum().mag() - oldp <<
" sigma_p = " <<
std::fixed << std::setw(14)
443 << sigma_p <<
" sigma_p/p = " <<
std::fixed << std::setw(14)
444 << sigma_p / tscblPCA.momentum().mag() * 100 <<
" %";
446 return validpropagation;
453 TrackSegments& trs) {
457 bool tscbl_status = getTrajectoryStateClosestToBeamLine(traj,
bs, thePropagator, tscbl);
462 return trackPathLength(traj, tscbl, thePropagator, pathlength, trs);
467 template <
class TrackCollection>
475 template <
class H,
class T>
486 const TrackSegments&,
493 const bool matchVertex,
494 MTDHitMatchingInfo& bestHit)
const;
500 const TrackSegments&,
507 const bool matchVertex,
508 MTDHitMatchingInfo& bestHit)
const;
510 void fillMatchingHits(
const DetLayer*,
515 const TrackSegments&,
522 MTDHitMatchingInfo&)
const;
531 auto rFirst =
first.mag2();
532 auto rLast =
last.mag2();
538 LogDebug(
"TrackExtenderWithMTD") <<
"Impossible to determine the rechits order" << endl;
557 float& sigmatofp)
const;
560 string dumpLayer(
const DetLayer* layer)
const;
621 template <
class TrackCollection>
627 updateTraj_(iConfig.getParameter<
bool>(
"updateTrackTrajectory")),
628 updateExtra_(iConfig.getParameter<
bool>(
"updateTrackExtra")),
629 updatePattern_(iConfig.getParameter<
bool>(
"updateTrackHitPattern")),
630 mtdRecHitBuilder_(iConfig.getParameter<
std::
string>(
"MTDRecHitBuilder")),
631 propagator_(iConfig.getParameter<
std::
string>(
"Propagator")),
632 transientTrackBuilder_(iConfig.getParameter<
std::
string>(
"TransientTrackBuilder")),
633 estMaxChi2_(iConfig.getParameter<double>(
"estimatorMaxChi2")),
634 estMaxNSigma_(iConfig.getParameter<double>(
"estimatorMaxNSigma")),
635 btlChi2Cut_(iConfig.getParameter<double>(
"btlChi2Cut")),
636 btlTimeChi2Cut_(iConfig.getParameter<double>(
"btlTimeChi2Cut")),
637 etlChi2Cut_(iConfig.getParameter<double>(
"etlChi2Cut")),
638 etlTimeChi2Cut_(iConfig.getParameter<double>(
"etlTimeChi2Cut")),
639 useVertex_(iConfig.getParameter<
bool>(
"useVertex")),
640 useSimVertex_(iConfig.getParameter<
bool>(
"useSimVertex")),
641 dzCut_(iConfig.getParameter<double>(
"dZCut")),
642 bsTimeSpread_(iConfig.getParameter<double>(
"bsTimeSpread")) {
678 gtgToken_ = esConsumes<GlobalTrackingGeometry, GlobalTrackingGeometryRecord>();
679 dlgeoToken_ = esConsumes<MTDDetLayerGeometry, MTDRecoGeometryRecord>();
680 magfldToken_ = esConsumes<MagneticField, IdealMagneticFieldRecord>();
682 ttopoToken_ = esConsumes<TrackerTopology, TrackerTopologyRcd>();
684 produces<edm::OwnVector<TrackingRecHit>>();
685 produces<reco::TrackExtraCollection>();
686 produces<TrackCollection>();
689 template <
class TrackCollection>
699 desc.add<
bool>(
"updateTrackTrajectory",
true);
700 desc.add<
bool>(
"updateTrackExtra",
true);
701 desc.add<
bool>(
"updateTrackHitPattern",
true);
702 desc.add<
std::string>(
"TransientTrackBuilder",
"TransientTrackBuilder");
707 "KFFitterForRefitInsideOut",
708 "KFSmootherForRefitInsideOut",
709 "PropagatorWithMaterialForMTD",
716 desc.add<
double>(
"estimatorMaxChi2", 500.);
717 desc.add<
double>(
"estimatorMaxNSigma", 10.);
718 desc.add<
double>(
"btlChi2Cut", 50.);
719 desc.add<
double>(
"btlTimeChi2Cut", 10.);
720 desc.add<
double>(
"etlChi2Cut", 50.);
721 desc.add<
double>(
"etlTimeChi2Cut", 10.);
722 desc.add<
bool>(
"useVertex",
false);
723 desc.add<
bool>(
"useSimVertex",
false);
724 desc.add<
double>(
"dZCut", 0.1);
725 desc.add<
double>(
"bsTimeSpread", 0.2);
726 descriptions.
add(
"trackExtenderWithMTDBase",
desc);
729 template <
class TrackCollection>
730 template <
class H,
class T>
733 const std::vector<T>& vec,
735 auto out = std::make_unique<edm::ValueMap<T>>();
742 template <
class TrackCollection>
747 theTransformer->setServices(es);
759 hitbuilder_ = es.
getHandle(hitbuilderToken_);
767 auto output = std::make_unique<TrackCollection>();
768 auto extras = std::make_unique<reco::TrackExtraCollection>();
769 auto outhits = std::make_unique<edm::OwnVector<TrackingRecHit>>();
771 std::vector<float> btlMatchChi2;
772 std::vector<float> etlMatchChi2;
773 std::vector<float> btlMatchTimeChi2;
774 std::vector<float> etlMatchTimeChi2;
775 std::vector<int> npixBarrel;
776 std::vector<int> npixEndcap;
777 std::vector<float> pOrigTrkRaw;
778 std::vector<float> betaOrigTrkRaw;
779 std::vector<float> t0OrigTrkRaw;
780 std::vector<float> sigmat0OrigTrkRaw;
781 std::vector<float> pathLengthsOrigTrkRaw;
782 std::vector<float> tmtdOrigTrkRaw;
783 std::vector<float> sigmatmtdOrigTrkRaw;
784 std::vector<float> tofpiOrigTrkRaw;
785 std::vector<float> tofkOrigTrkRaw;
786 std::vector<float> tofpOrigTrkRaw;
787 std::vector<float> sigmatofpiOrigTrkRaw;
788 std::vector<float> sigmatofkOrigTrkRaw;
789 std::vector<float> sigmatofpOrigTrkRaw;
790 std::vector<int> assocOrigTrkRaw;
792 auto const tracksH =
ev.getHandle(tracksToken_);
794 const auto& trjtrks =
ev.get(trajTrackAToken_);
797 const auto&
hits =
ev.get(hitsToken_);
800 const auto&
bs =
ev.get(bsToken_);
803 if (useVertex_ && !useSimVertex_) {
804 auto const& vtxs =
ev.get(vtxToken_);
809 std::unique_ptr<math::XYZTLorentzVectorF> genPV(
nullptr);
810 if (useVertex_ && useSimVertex_) {
811 const auto& genVtxPosition =
ev.get(genVtxPositionToken_);
812 const auto& genVtxTime =
ev.get(genVtxTimeToken_);
813 genPV = std::make_unique<math::XYZTLorentzVectorF>(
814 genVtxPosition.x(), genVtxPosition.y(), genVtxPosition.z(), genVtxTime);
819 if (useSimVertex_ && genPV) {
820 vtxTime = genPV->t();
825 std::vector<unsigned> track_indices;
828 for (
const auto& trjtrk : trjtrks) {
832 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: extrapolating track " << itrack
833 <<
" p/pT = " <<
track->p() <<
" " <<
track->pt() <<
" eta = " <<
track->eta();
834 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: sigma_p = " 836 <<
" sigma_p/p = " <<
sqrt(
track->covariance()(0, 0)) *
track->p() * 100 <<
" %";
838 float trackVtxTime = 0.f;
847 trackVtxTime = vtxTime;
851 auto thits = theTransformer->getTransientRecHits(ttrack);
853 MTDHitMatchingInfo mBTL, mETL;
859 bool tscbl_status = getTrajectoryStateClosestToBeamLine(trajs,
bs, prop, tscbl);
865 trackPathLength(trajs, tscbl, prop, pathlength0, trs0);
867 const auto& btlhits = tryBTLLayers(tsos,
880 mtdthits.insert(mtdthits.end(), btlhits.begin(), btlhits.end());
884 const auto& etlhits = tryETLLayers(tsos,
897 mtdthits.insert(mtdthits.end(), etlhits.begin(), etlhits.end());
901 auto ordering = checkRecHitsOrdering(thits);
903 thits.insert(thits.end(), mtdthits.begin(), mtdthits.end());
906 mtdthits.insert(mtdthits.end(), thits.begin(), thits.end());
907 thits.swap(mtdthits);
910 const auto& trajwithmtd =
911 mtdthits.empty() ? std::vector<Trajectory>(1, trajs) : theTransformer->transform(ttrack, thits);
912 float pMap = 0.f, betaMap = 0.f, t0Map = 0.f, sigmat0Map = -1.f, pathLengthMap = -1.f, tmtdMap = 0.f,
913 sigmatmtdMap = -1.f, tofpiMap = 0.f, tofkMap = 0.f, tofpMap = 0.f, sigmatofpiMap = -1.f, sigmatofkMap = -1.f,
917 for (
const auto& trj : trajwithmtd) {
918 const auto& thetrj = (updateTraj_ ? trj : trajs);
919 float pathLength = 0.f, tmtd = 0.f, sigmatmtd = -1.f, tofpi = 0.f, tofk = 0.f, tofp = 0.f, sigmatofpi = -1.f,
920 sigmatofk = -1.f, sigmatofp = -1.f;
921 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: refit track " << itrack <<
" p/pT = " <<
track->p()
922 <<
" " <<
track->pt() <<
" eta = " <<
track->eta();
929 !trajwithmtd.empty() && !mtdthits.empty(),
943 size_t hitsstart = outhits->size();
944 if (updatePattern_) {
945 t2t(trj, *outhits, trajParams, chi2s);
947 t2t(thetrj, *outhits, trajParams, chi2s);
949 size_t hitsend = outhits->size();
950 extras->push_back(buildTrackExtra(trj));
951 extras->back().setHits(hitsRefProd, hitsstart, hitsend - hitsstart);
952 extras->back().setTrajParams(trajParams, chi2s);
955 btlMatchChi2.push_back(mBTL.hit ? mBTL.estChi2 : -1.f);
956 etlMatchChi2.push_back(mETL.hit ? mETL.estChi2 : -1.f);
957 btlMatchTimeChi2.push_back(mBTL.hit ? mBTL.timeChi2 : -1.f);
958 etlMatchTimeChi2.push_back(mETL.hit ? mETL.timeChi2 : -1.f);
959 pathLengthMap = pathLength;
961 sigmatmtdMap = sigmatmtd;
962 auto& backtrack =
output->back();
963 iMap =
output->size() - 1;
964 pMap = backtrack.p();
965 betaMap = backtrack.beta();
966 t0Map = backtrack.t0();
967 sigmat0Map = std::copysign(
std::sqrt(
std::abs(backtrack.covt0t0())), backtrack.covt0t0());
971 sigmatofpiMap = sigmatofpi;
972 sigmatofkMap = sigmatofk;
973 sigmatofpMap = sigmatofp;
975 backtrack.setExtra((updateExtra_ ? extraRef :
track->extra()));
976 for (
unsigned ihit = hitsstart; ihit < hitsend; ++ihit) {
977 backtrack.appendHitPattern((*outhits)[ihit], ttopo);
979 npixBarrel.push_back(backtrack.hitPattern().numberOfValidPixelBarrelHits());
980 npixEndcap.push_back(backtrack.hitPattern().numberOfValidPixelEndcapHits());
981 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: tmtd " << tmtdMap <<
" +/- " << sigmatmtdMap
982 <<
" t0 " << t0Map <<
" +/- " << sigmat0Map <<
" tof pi/K/p " << tofpiMap
983 <<
"+/-" <<
fmt::format(
"{:0.2g}", sigmatofpiMap) <<
" (" 984 <<
fmt::format(
"{:0.2g}", sigmatofpiMap / tofpiMap * 100) <<
"%) " << tofkMap
985 <<
"+/-" <<
fmt::format(
"{:0.2g}", sigmatofkMap) <<
" (" 986 <<
fmt::format(
"{:0.2g}", sigmatofkMap / tofkMap * 100) <<
"%) " << tofpMap
987 <<
"+/-" <<
fmt::format(
"{:0.2g}", sigmatofpMap) <<
" (" 988 <<
fmt::format(
"{:0.2g}", sigmatofpMap / tofpMap * 100) <<
"%) ";
990 LogTrace(
"TrackExtenderWithMTD") <<
"Error in the MTD track refitting. This should not happen";
994 pOrigTrkRaw.push_back(pMap);
995 betaOrigTrkRaw.push_back(betaMap);
996 t0OrigTrkRaw.push_back(t0Map);
997 sigmat0OrigTrkRaw.push_back(sigmat0Map);
998 pathLengthsOrigTrkRaw.push_back(pathLengthMap);
999 tmtdOrigTrkRaw.push_back(tmtdMap);
1000 sigmatmtdOrigTrkRaw.push_back(sigmatmtdMap);
1001 tofpiOrigTrkRaw.push_back(tofpiMap);
1002 tofkOrigTrkRaw.push_back(tofkMap);
1003 tofpOrigTrkRaw.push_back(tofpMap);
1004 sigmatofpiOrigTrkRaw.push_back(sigmatofpiMap);
1005 sigmatofkOrigTrkRaw.push_back(sigmatofkMap);
1006 sigmatofpOrigTrkRaw.push_back(sigmatofpMap);
1007 assocOrigTrkRaw.push_back(iMap);
1010 btlMatchChi2.push_back(-1.
f);
1011 etlMatchChi2.push_back(-1.
f);
1012 btlMatchTimeChi2.push_back(-1.
f);
1013 etlMatchTimeChi2.push_back(-1.
f);
1014 npixBarrel.push_back(-1.
f);
1015 npixEndcap.push_back(-1.
f);
1025 fillValueMap(
ev, tracksH, btlMatchChi2, btlMatchChi2Token_);
1026 fillValueMap(
ev, tracksH, etlMatchChi2, etlMatchChi2Token_);
1027 fillValueMap(
ev, tracksH, btlMatchTimeChi2, btlMatchTimeChi2Token_);
1028 fillValueMap(
ev, tracksH, etlMatchTimeChi2, etlMatchTimeChi2Token_);
1029 fillValueMap(
ev, tracksH, npixBarrel, npixBarrelToken_);
1030 fillValueMap(
ev, tracksH, npixEndcap, npixEndcapToken_);
1031 fillValueMap(
ev, tracksH, pOrigTrkRaw, pOrigTrkToken_);
1032 fillValueMap(
ev, tracksH, betaOrigTrkRaw, betaOrigTrkToken_);
1033 fillValueMap(
ev, tracksH, t0OrigTrkRaw, t0OrigTrkToken_);
1034 fillValueMap(
ev, tracksH, sigmat0OrigTrkRaw, sigmat0OrigTrkToken_);
1035 fillValueMap(
ev, tracksH, pathLengthsOrigTrkRaw, pathLengthOrigTrkToken_);
1036 fillValueMap(
ev, tracksH, tmtdOrigTrkRaw, tmtdOrigTrkToken_);
1037 fillValueMap(
ev, tracksH, sigmatmtdOrigTrkRaw, sigmatmtdOrigTrkToken_);
1038 fillValueMap(
ev, tracksH, tofpiOrigTrkRaw, tofpiOrigTrkToken_);
1039 fillValueMap(
ev, tracksH, tofkOrigTrkRaw, tofkOrigTrkToken_);
1040 fillValueMap(
ev, tracksH, tofpOrigTrkRaw, tofpOrigTrkToken_);
1041 fillValueMap(
ev, tracksH, sigmatofpiOrigTrkRaw, sigmatofpiOrigTrkToken_);
1042 fillValueMap(
ev, tracksH, sigmatofkOrigTrkRaw, sigmatofkOrigTrkToken_);
1043 fillValueMap(
ev, tracksH, sigmatofpOrigTrkRaw, sigmatofpOrigTrkToken_);
1044 fillValueMap(
ev, tracksH, assocOrigTrkRaw, assocOrigTrkToken_);
1048 bool cmp_for_detset(
const unsigned one,
const unsigned two) {
return one <
two; };
1055 const float pathlength0,
1056 const TrackSegments& trs0,
1057 const float vtxTime,
1059 const float bsTimeSpread,
1062 bool useVtxConstraint,
1063 std::set<MTDHitMatchingInfo>&
out) {
1064 pair<bool, TrajectoryStateOnSurface>
comp =
layer->compatible(tsos, *prop, *
estimator);
1066 const vector<DetLayer::DetWithState> compDets =
layer->compatibleDets(tsos, *prop, *
estimator);
1067 LogTrace(
"TrackExtenderWithMTD") <<
"Hit search: Compatible dets " << compDets.size();
1068 if (!compDets.empty()) {
1069 for (
const auto& detWithState : compDets) {
1070 auto range =
hits.equal_range(detWithState.first->geographicalId(), cmp_for_detset);
1073 <<
"Hit search: no hit in DetId " << detWithState.first->geographicalId().rawId();
1078 if (pl.second == 0.) {
1080 <<
"Hit search: no propagation to DetId " << detWithState.first->geographicalId().rawId();
1084 const float t_vtx = useVtxConstraint ? vtxTime : 0.f;
1087 const float t_vtx_err = useVtxConstraint ? vtx_res : bsTimeSpread;
1089 float lastpmag2 = trs0.getSegmentPathAndMom2(0).second;
1091 for (
auto detitr =
range.first; detitr !=
range.second; ++detitr) {
1092 for (
const auto&
hit : *detitr) {
1093 auto est =
estimator->estimate(detWithState.second,
hit);
1096 <<
"Hit search: no compatible estimate in DetId " << detWithState.first->geographicalId().rawId()
1097 <<
" for hit at pos (" <<
std::fixed << std::setw(14) <<
hit.globalPosition().
x() <<
"," 1099 <<
hit.globalPosition().
z() <<
")";
1104 <<
"Hit search: spatial compatibility DetId " << detWithState.first->geographicalId().rawId()
1105 <<
" TSOS dx/dy " <<
std::fixed << std::setw(14)
1107 << std::setw(14) <<
std::sqrt(detWithState.second.localError().positionError().yy()) <<
" hit dx/dy " 1110 << std::setw(14) << est.second;
1112 TrackTofPidInfo tof = computeTrackTofPidInfo(lastpmag2,
1121 SigmaTofCalc::kMixd);
1122 MTDHitMatchingInfo mi;
1124 mi.estChi2 = est.second;
1125 mi.timeChi2 = tof.dtchi2_best;
1136 template <
class TrackCollection>
1141 const float pathlength0,
1142 const TrackSegments& trs0,
1148 const float vtxTime,
1149 const bool matchVertex,
1150 MTDHitMatchingInfo& bestHit)
const {
1154 bestHit = MTDHitMatchingInfo();
1156 LogTrace(
"TrackExtenderWithMTD") <<
"Hit search: BTL layer at R= " 1157 <<
static_cast<const BarrelDetLayer*
>(ilay)->specificSurface().radius();
1159 fillMatchingHits(ilay, tsos, traj, pmag2, pathlength0, trs0,
hits, prop,
bs, vtxTime, matchVertex,
output, bestHit);
1165 template <
class TrackCollection>
1170 const float pathlength0,
1171 const TrackSegments& trs0,
1177 const float vtxTime,
1178 const bool matchVertex,
1179 MTDHitMatchingInfo& bestHit)
const {
1183 bestHit = MTDHitMatchingInfo();
1186 const float diskZ = disk.position().z();
1191 LogTrace(
"TrackExtenderWithMTD") <<
"Hit search: ETL disk at Z = " << diskZ;
1193 fillMatchingHits(ilay, tsos, traj, pmag2, pathlength0, trs0,
hits, prop,
bs, vtxTime, matchVertex,
output, bestHit);
1198 if (
output.size() == 2) {
1206 template <
class TrackCollection>
1211 const float pathlength0,
1212 const TrackSegments& trs0,
1216 const float& vtxTime,
1217 const bool matchVertex,
1219 MTDHitMatchingInfo& bestHit)
const {
1220 std::set<MTDHitMatchingInfo> hitsInLayer;
1221 bool hitMatched =
false;
1224 auto find_hits = std::bind(find_hits_in_dets,
1238 std::ref(hitsInLayer));
1240 if (useVertex_ && matchVertex)
1241 find_hits(vtxTime,
true);
1243 find_hits(0,
false);
1245 float spaceChi2Cut = ilay->
isBarrel() ? btlChi2Cut_ : etlChi2Cut_;
1246 float timeChi2Cut = ilay->
isBarrel() ? btlTimeChi2Cut_ : etlTimeChi2Cut_;
1249 if (!hitsInLayer.empty()) {
1251 auto const& firstHit = *hitsInLayer.begin();
1252 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: matching trial 1: estChi2= " << firstHit.estChi2
1253 <<
" timeChi2= " << firstHit.timeChi2;
1254 if (firstHit.estChi2 < spaceChi2Cut && firstHit.timeChi2 < timeChi2Cut) {
1256 output.push_back(hitbuilder_->build(firstHit.hit));
1257 if (firstHit < bestHit)
1262 if (useVertex_ && matchVertex && !hitMatched) {
1264 hitsInLayer.clear();
1265 find_hits(0,
false);
1266 if (!hitsInLayer.empty()) {
1267 auto const& firstHit = *hitsInLayer.begin();
1268 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: matching trial 2: estChi2= " << firstHit.estChi2
1269 <<
" timeChi2= " << firstHit.timeChi2;
1270 if (firstHit.timeChi2 < timeChi2Cut) {
1271 if (firstHit.estChi2 < spaceChi2Cut) {
1273 output.push_back(hitbuilder_->build(firstHit.hit));
1274 if (firstHit < bestHit)
1283 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: matched hit with time: " << bestHit.hit->time()
1284 <<
" +/- " << bestHit.hit->timeError();
1286 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: no matched hit";
1293 template <
class TrackCollection>
1301 float& pathLengthOut,
1303 float& sigmatmtdOut,
1309 float& sigmatofp)
const {
1311 bool tsbcl_status = getTrajectoryStateClosestToBeamLine(traj,
bs, thePropagator, tscbl);
1324 float covt0t0 = -1.f;
1325 pathLengthOut = -1.f;
1327 sigmatmtdOut = -1.f;
1328 float betaOut = 0.f;
1329 float covbetabeta = -1.f;
1331 auto routput = [&]() {
1350 bool validpropagation = trackPathLength(trajWithMtd,
bs, thePropagator, pathlength, trs);
1352 float thiterror = -1.f;
1353 bool validmtd =
false;
1355 if (!validpropagation) {
1359 uint32_t ihitcount(0), ietlcount(0);
1364 if (
MTDDetId(
hit.recHit()->geographicalId()).mtdSubDetector() == MTDDetId::MTDType::ETL) {
1370 LogTrace(
"TrackExtenderWithMTD") <<
"TrackExtenderWithMTD: selected #hits " << ihitcount <<
" from ETL " 1374 if (ihitcount == 1) {
1376 thit = mtdhit->
time();
1379 }
else if (ihitcount == 2 && ietlcount == 2) {
1380 std::pair<float, float> lastStep = trs.getSegmentPathAndMom2(0);
1385 if (etlpathlength == 0.
f) {
1386 validpropagation =
false;
1388 pathlength -= etlpathlength;
1389 trs.removeFirstSegment();
1392 TrackTofPidInfo tofInfo = computeTrackTofPidInfo(
1393 lastStep.second, etlpathlength, trs, mtdhit1->
time(), mtdhit1->
timeError(), 0.f, 0.f,
true, TofCalc::kCost);
1397 float err1 = tofInfo.dterror2;
1401 <<
"MTD tracking hits with zero time uncertainty: " << err1 <<
" " << err2;
1403 if ((tofInfo.dt - mtdhit2->
time()) * (tofInfo.dt - mtdhit2->
time()) < (err1 + err2) * etlTimeChi2Cut_) {
1410 thiterror = 1.f / (err1 + err2);
1411 thit = (tofInfo.dt * err1 + mtdhit2->
time() * err2) * thiterror;
1414 <<
"TrackExtenderWithMTD: p trk = " <<
p.mag() <<
" ETL hits times/errors: " << mtdhit1->
time()
1416 <<
" extrapolated time1: " << tofInfo.dt <<
" +/- " << tofInfo.dterror <<
" average = " << thit
1417 <<
" +/- " << thiterror;
1423 thiterror = tofInfo.dterror;
1426 thit = mtdhit2->
time();
1435 <<
"MTD hits #" << ihitcount <<
"ETL hits #" << ietlcount <<
" anomalous pattern, skipping...";
1438 if (validmtd && validpropagation) {
1440 TrackTofPidInfo tofInfo = computeTrackTofPidInfo(
1441 p.mag2(), pathlength, trs, thit, thiterror, 0.f, 0.f,
true, TofCalc::kSegm, SigmaTofCalc::kCost);
1443 pathLengthOut = pathlength;
1445 sigmatmtdOut = thiterror;
1447 covt0t0 = tofInfo.dterror2;
1448 betaOut = tofInfo.beta_pi;
1449 covbetabeta = tofInfo.betaerror * tofInfo.betaerror;
1450 tofpi = tofInfo.dt_pi;
1451 tofk = tofInfo.dt_k;
1452 tofp = tofInfo.dt_p;
1453 sigmatofpi = tofInfo.sigma_dt_pi;
1454 sigmatofk = tofInfo.sigma_dt_k;
1455 sigmatofp = tofInfo.sigma_dt_p;
1462 template <
class TrackCollection>
1464 static const string metname =
"TrackExtenderWithMTD";
1474 unsigned int innerId = 0, outerId = 0;
1497 const GeomDet* outerDet = gtg_->idToDet(outerDetId);
1505 LogTrace(
metname) <<
"The Global Muon outerMostMeasurementState is not compatible with the recHit detector!" 1506 <<
" Setting outerMost postition to recHit position if recHit isValid: " 1507 << outerRecHit->isValid();
1538 template <
class TrackCollection>
1546 sur = &(
layer->surface());
1547 if ((bc = dynamic_cast<const BoundCylinder*>(sur))) {
1548 output <<
" Cylinder of radius: " << bc->radius() << endl;
1549 }
else if ((bd = dynamic_cast<const BoundDisk*>(sur))) {
1550 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_
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