CMS 3D CMS Logo

TrackExtenderWithMTD.cc
Go to the documentation of this file.
8 
11 
14 
16 
18 
21 
26 
29 
33 
35 
38 
41 
43 
46 
47 #include <sstream>
48 
50 
53 
56 #include "CLHEP/Units/GlobalPhysicalConstants.h"
58 
61 
62 using namespace std;
63 using namespace edm;
64 using namespace reco;
65 
66 namespace {
67  constexpr float c_cm_ns = geant_units::operators::convertMmToCm(CLHEP::c_light); // [mm/ns] -> [cm/ns]
68  constexpr float c_inv = 1.0f / c_cm_ns;
69 
70  class MTDHitMatchingInfo {
71  public:
72  MTDHitMatchingInfo() {
73  hit = nullptr;
76  }
77 
78  //Operator used to sort the hits while performing the matching step at the MTD
79  inline bool operator<(const MTDHitMatchingInfo& m2) const {
80  //only for good matching in time use estChi2, otherwise use mostly time compatibility
81  constexpr float chi2_cut = 10.f;
82  constexpr float low_weight = 3.f;
83  constexpr float high_weight = 8.f;
84  if (timeChi2 < chi2_cut && m2.timeChi2 < chi2_cut)
85  return chi2(low_weight) < m2.chi2(low_weight);
86  else
87  return chi2(high_weight) < m2.chi2(high_weight);
88  }
89 
90  inline float chi2(float timeWeight = 1.f) const { return estChi2 + timeWeight * timeChi2; }
91 
92  const MTDTrackingRecHit* hit;
93  float estChi2;
94  float timeChi2;
95  };
96 
97  class TrackSegments {
98  public:
99  TrackSegments() {
100  sigmaTofs_.reserve(30); // observed upper limit on nSegments
101  };
102 
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);
107  nSegment_++;
108 
109  LogTrace("TrackExtenderWithMTD") << "addSegment # " << nSegment_ << " s = " << tPath
110  << " p = " << std::sqrt(tMom2) << " sigma_p = " << sigmaMom
111  << " sigma_p/p = " << sigmaMom / std::sqrt(tMom2) * 100 << " %";
112 
113  return nSegment_;
114  }
115 
116  inline float computeTof(float mass_inv2) const {
117  float tof(0.f);
118  for (uint32_t iSeg = 0; iSeg < nSegment_; iSeg++) {
119  float gammasq = 1.f + segmentMom2_[iSeg] * mass_inv2;
120  float beta = std::sqrt(1.f - 1.f / gammasq);
121  tof += segmentPathOvc_[iSeg] / beta;
122 
123  LogTrace("TrackExtenderWithMTD") << " TOF Segment # " << iSeg + 1 << " p = " << std::sqrt(segmentMom2_[iSeg])
124  << " tof = " << tof;
125 
126 #ifdef EDM_ML_DEBUG
127  float sigma_tof = segmentPathOvc_[iSeg] * segmentSigmaMom_[iSeg] /
128  (segmentMom2_[iSeg] * sqrt(segmentMom2_[iSeg] + 1 / mass_inv2) * mass_inv2);
129 
130  LogTrace("TrackExtenderWithMTD") << "TOF Segment # " << iSeg + 1 << std::fixed << std::setw(6)
131  << " tof segment = " << segmentPathOvc_[iSeg] / beta << std::scientific
132  << "+/- " << sigma_tof << std::fixed
133  << "(rel. err. = " << sigma_tof / (segmentPathOvc_[iSeg] / beta) * 100
134  << " %)";
135 #endif
136  }
137 
138  return tof;
139  }
140 
141  inline float computeSigmaTof(float mass_inv2) {
142  float sigmatof = 0.;
143 
144  // remove previously calculated sigmaTofs
145  sigmaTofs_.clear();
146 
147  // compute sigma(tof) on each segment first by propagating sigma(p)
148  // also add diagonal terms to sigmatof
149  float sigma = 0.;
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);
154 
155  sigmatof += sigma * sigma;
156  }
157 
158  // compute sigma on sum of tofs assuming full correlation between segments
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];
162  }
163  }
164 
165  return sqrt(sigmatof);
166  }
167 
168  inline uint32_t size() const { return nSegment_; }
169 
170  inline uint32_t removeFirstSegment() {
171  if (nSegment_ > 0) {
172  segmentPathOvc_.erase(segmentPathOvc_.begin());
173  segmentMom2_.erase(segmentMom2_.begin());
174  nSegment_--;
175  }
176  return nSegment_;
177  }
178 
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;
182  }
183  return std::make_pair(segmentPathOvc_[iSegment], segmentMom2_[iSegment]);
184  }
185 
186  uint32_t nSegment_ = 0;
187  std::vector<float> segmentPathOvc_;
188  std::vector<float> segmentMom2_;
189  std::vector<float> segmentSigmaMom_;
190 
191  std::vector<float> sigmaTofs_;
192  };
193 
194  struct TrackTofPidInfo {
195  float tmtd;
196  float tmtderror;
197  float pathlength;
198 
199  float betaerror;
200 
201  float dt;
202  float dterror;
203  float dtchi2;
204 
205  float dt_best;
206  float dterror_best;
207  float dtchi2_best;
208 
209  float gammasq_pi;
210  float beta_pi;
211  float dt_pi;
212  float sigma_dt_pi;
213 
214  float gammasq_k;
215  float beta_k;
216  float dt_k;
217  float sigma_dt_k;
218 
219  float gammasq_p;
220  float beta_p;
221  float dt_p;
222  float sigma_dt_p;
223 
224  float prob_pi;
225  float prob_k;
226  float prob_p;
227  };
228 
229  enum class TofCalc { kCost = 1, kSegm = 2, kMixd = 3 };
230  enum class SigmaTofCalc { kCost = 1, kSegm = 2 };
231 
232  const TrackTofPidInfo computeTrackTofPidInfo(float magp2,
233  float length,
234  TrackSegments trs,
235  float t_mtd,
236  float t_mtderr,
237  float t_vtx,
238  float t_vtx_err,
239  bool addPIDError = true,
240  TofCalc choice = TofCalc::kCost,
241  SigmaTofCalc sigma_choice = SigmaTofCalc::kCost) {
242  constexpr float m_pi = 0.13957018f;
243  constexpr float m_pi_inv2 = 1.0f / m_pi / m_pi;
244  constexpr float m_k = 0.493677f;
245  constexpr float m_k_inv2 = 1.0f / m_k / m_k;
246  constexpr float m_p = 0.9382720813f;
247  constexpr float m_p_inv2 = 1.0f / m_p / m_p;
248 
249  TrackTofPidInfo tofpid;
250 
251  tofpid.tmtd = t_mtd;
252  tofpid.tmtderror = t_mtderr;
253  tofpid.pathlength = length;
254 
255  auto deltat = [&](const float mass_inv2, const float betatmp) {
256  float res(1.f);
257  switch (choice) {
258  case TofCalc::kCost:
259  res = tofpid.pathlength / betatmp * c_inv;
260  break;
261  case TofCalc::kSegm:
262  res = trs.computeTof(mass_inv2);
263  break;
264  case TofCalc::kMixd:
265  res = trs.computeTof(mass_inv2) + tofpid.pathlength / betatmp * c_inv;
266  break;
267  }
268  return res;
269  };
270 
271  auto sigmadeltat = [&](const float mass_inv2) {
272  float res(1.f);
273  switch (sigma_choice) {
274  case SigmaTofCalc::kCost:
275  // sigma(t) = sigma(p) * |dt/dp| = sigma(p) * DeltaL/c * m^2 / (p^2 * E)
276  res = tofpid.pathlength * c_inv * trs.segmentSigmaMom_[trs.nSegment_ - 1] /
277  (magp2 * sqrt(magp2 + 1 / mass_inv2) * mass_inv2);
278  break;
279  case SigmaTofCalc::kSegm:
280  res = trs.computeSigmaTof(mass_inv2);
281  break;
282  }
283 
284  return res;
285  };
286 
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);
291 
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);
296 
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);
301 
302  tofpid.dt = tofpid.tmtd - tofpid.dt_pi - t_vtx; //assume by default the pi hypothesis
303  tofpid.dterror = sqrt(tofpid.tmtderror * tofpid.tmtderror + t_vtx_err * t_vtx_err);
304  tofpid.betaerror = 0.f;
305  if (addPIDError) {
306  tofpid.dterror =
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;
309  }
310 
311  tofpid.dtchi2 = (tofpid.dt * tofpid.dt) / (tofpid.dterror * tofpid.dterror);
312 
313  tofpid.dt_best = tofpid.dt;
314  tofpid.dterror_best = tofpid.dterror;
315  tofpid.dtchi2_best = tofpid.dtchi2;
316 
317  tofpid.prob_pi = -1.f;
318  tofpid.prob_k = -1.f;
319  tofpid.prob_p = -1.f;
320 
321  if (!addPIDError) {
322  //*TODO* deal with heavier nucleons and/or BSM case here?
323  float chi2_pi = tofpid.dtchi2;
324  float chi2_k =
325  (tofpid.tmtd - tofpid.dt_k - t_vtx) * (tofpid.tmtd - tofpid.dt_k - t_vtx) / (tofpid.dterror * tofpid.dterror);
326  float chi2_p =
327  (tofpid.tmtd - tofpid.dt_p - t_vtx) * (tofpid.tmtd - tofpid.dt_p - t_vtx) / (tofpid.dterror * tofpid.dterror);
328 
329  float rawprob_pi = exp(-0.5f * chi2_pi);
330  float rawprob_k = exp(-0.5f * chi2_k);
331  float rawprob_p = exp(-0.5f * chi2_p);
332  float normprob = 1.f / (rawprob_pi + rawprob_k + rawprob_p);
333 
334  tofpid.prob_pi = rawprob_pi * normprob;
335  tofpid.prob_k = rawprob_k * normprob;
336  tofpid.prob_p = rawprob_p * normprob;
337 
338  float prob_heavy = 1.f - tofpid.prob_pi;
339  constexpr float heavy_threshold = 0.75f;
340 
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;
345  } else {
346  tofpid.dt_best = (tofpid.tmtd - tofpid.dt_p - t_vtx);
347  tofpid.dtchi2_best = chi2_p;
348  }
349  }
350  }
351  return tofpid;
352  }
353 
354  bool getTrajectoryStateClosestToBeamLine(const Trajectory& traj,
355  const reco::BeamSpot& bs,
356  const Propagator* thePropagator,
358  // get the state closest to the beamline
359  TrajectoryStateOnSurface stateForProjectionToBeamLineOnSurface =
360  traj.closestMeasurement(GlobalPoint(bs.x0(), bs.y0(), bs.z0())).updatedState();
361 
362  if (!stateForProjectionToBeamLineOnSurface.isValid()) {
363  edm::LogError("CannotPropagateToBeamLine") << "the state on the closest measurement isnot valid. skipping track.";
364  return false;
365  }
366 
367  const FreeTrajectoryState& stateForProjectionToBeamLine = *stateForProjectionToBeamLineOnSurface.freeState();
368 
369  TSCBLBuilderWithPropagator tscblBuilder(*thePropagator);
370  tscbl = tscblBuilder(stateForProjectionToBeamLine, bs);
371 
372  return tscbl.isValid();
373  }
374 
375  bool trackPathLength(const Trajectory& traj,
377  const Propagator* thePropagator,
378  float& pathlength,
379  TrackSegments& trs) {
380  pathlength = 0.f;
381 
382  bool validpropagation = true;
383  float oldp = traj.measurements().begin()->updatedState().globalMomentum().mag();
384  float pathlength1 = 0.f;
385  float pathlength2 = 0.f;
386 
387  //add pathlength layer by layer
388  for (auto it = traj.measurements().begin(); it != traj.measurements().end() - 1; ++it) {
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;
393  }
394  pathlength1 += layerpathlength;
395 
396  // sigma(p) from curvilinear error (on q/p)
397  float sigma_p = sqrt((it + 1)->updatedState().curvilinearError().matrix()(0, 0)) *
398  (it + 1)->updatedState().globalMomentum().mag2();
399 
400  trs.addSegment(layerpathlength, (it + 1)->updatedState().globalMomentum().mag2(), sigma_p);
401 
402  LogTrace("TrackExtenderWithMTD") << "TSOS " << std::fixed << std::setw(4) << trs.size() << " R_i " << std::fixed
403  << std::setw(14) << it->updatedState().globalPosition().perp() << " z_i "
404  << std::fixed << std::setw(14) << it->updatedState().globalPosition().z()
405  << " R_e " << std::fixed << std::setw(14)
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()
409  << " dp " << std::fixed << std::setw(14)
410  << (it + 1)->updatedState().globalMomentum().mag() - oldp;
411  oldp = (it + 1)->updatedState().globalMomentum().mag();
412  }
413 
414  //add distance from bs to first measurement
415  auto const& tscblPCA = tscbl.trackStateAtPCA();
416  auto const& aSurface = traj.direction() == alongMomentum ? traj.firstMeasurement().updatedState().surface()
417  : traj.lastMeasurement().updatedState().surface();
418  pathlength2 = thePropagator->propagateWithPath(tscblPCA, aSurface).second;
419  if (pathlength2 == 0.f) {
420  validpropagation = false;
421  }
422  pathlength = pathlength1 + pathlength2;
423 
424  float sigma_p = sqrt(tscblPCA.curvilinearError().matrix()(0, 0)) * tscblPCA.momentum().mag2();
425 
426  trs.addSegment(pathlength2, tscblPCA.momentum().mag2(), sigma_p);
427 
428  LogTrace("TrackExtenderWithMTD") << "TSOS " << std::fixed << std::setw(4) << trs.size() << " R_e " << std::fixed
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 << " %";
435 
436  return validpropagation;
437  }
438 
439  bool trackPathLength(const Trajectory& traj,
440  const reco::BeamSpot& bs,
441  const Propagator* thePropagator,
442  float& pathlength,
443  TrackSegments& trs) {
444  pathlength = 0.f;
445 
447  bool tscbl_status = getTrajectoryStateClosestToBeamLine(traj, bs, thePropagator, tscbl);
448 
449  if (!tscbl_status)
450  return false;
451 
452  return trackPathLength(traj, tscbl, thePropagator, pathlength, trs);
453  }
454 
455 } // namespace
456 
457 template <class TrackCollection>
459 public:
462 
464 
465  template <class H, class T>
466  void fillValueMap(edm::Event& iEvent, const H& handle, const std::vector<T>& vec, const edm::EDPutToken& token) const;
467 
468  void produce(edm::Event& ev, const edm::EventSetup& es) final;
469 
470  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
471 
473  const Trajectory& traj,
474  const float,
475  const float,
476  const TrackSegments&,
478  const MTDDetLayerGeometry*,
479  const MagneticField* field,
480  const Propagator* prop,
481  const reco::BeamSpot& bs,
482  const float vtxTime,
483  const bool matchVertex,
484  MTDHitMatchingInfo& bestHit) const;
485 
487  const Trajectory& traj,
488  const float,
489  const float,
490  const TrackSegments&,
492  const MTDDetLayerGeometry*,
493  const MagneticField* field,
494  const Propagator* prop,
495  const reco::BeamSpot& bs,
496  const float vtxTime,
497  const bool matchVertex,
498  MTDHitMatchingInfo& bestHit) const;
499 
500  void fillMatchingHits(const DetLayer*,
502  const Trajectory&,
503  const float,
504  const float,
505  const TrackSegments&,
507  const Propagator*,
508  const reco::BeamSpot&,
509  const float&,
510  const bool,
512  MTDHitMatchingInfo&) const;
513 
516  if (!recHits.empty()) {
517  GlobalPoint first = gtg_->idToDet(recHits.front()->geographicalId())->position();
518  GlobalPoint last = gtg_->idToDet(recHits.back()->geographicalId())->position();
519 
520  // maybe perp2?
521  auto rFirst = first.mag2();
522  auto rLast = last.mag2();
523  if (rFirst < rLast)
525  if (rFirst > rLast)
527  }
528  LogDebug("TrackExtenderWithMTD") << "Impossible to determine the rechits order" << endl;
530  }
531 
532  reco::Track buildTrack(const reco::TrackRef&,
533  const Trajectory&,
534  const Trajectory&,
535  const reco::BeamSpot&,
536  const MagneticField* field,
537  const Propagator* prop,
538  bool hasMTD,
539  float& pathLength,
540  float& tmtdOut,
541  float& sigmatmtdOut,
542  float& tofpi,
543  float& tofk,
544  float& tofp,
545  float& sigmatofpi,
546  float& sigmatofk,
547  float& sigmatofp) const;
548  reco::TrackExtra buildTrackExtra(const Trajectory& trajectory) const;
549 
550  string dumpLayer(const DetLayer* layer) const;
551 
552 private:
573 
581 
582  const bool updateTraj_, updateExtra_, updatePattern_;
583  const std::string mtdRecHitBuilder_, propagator_, transientTrackBuilder_;
584  std::unique_ptr<MeasurementEstimator> theEstimator;
585  std::unique_ptr<TrackTransformer> theTransformer;
592 
597 
598  const float estMaxChi2_;
599  const float estMaxNSigma_;
600  const float btlChi2Cut_;
601  const float btlTimeChi2Cut_;
602  const float etlChi2Cut_;
603  const float etlTimeChi2Cut_;
604 
605  const bool useVertex_;
606  const bool useSimVertex_;
607  const float dzCut_;
608  const float bsTimeSpread_;
609 };
610 
611 template <class TrackCollection>
613  : tracksToken_(consumes<InputCollection>(iConfig.getParameter<edm::InputTag>("tracksSrc"))),
614  trajTrackAToken_(consumes<TrajTrackAssociationCollection>(iConfig.getParameter<edm::InputTag>("trjtrkAssSrc"))),
615  hitsToken_(consumes<MTDTrackingDetSetVector>(iConfig.getParameter<edm::InputTag>("hitsSrc"))),
616  bsToken_(consumes<reco::BeamSpot>(iConfig.getParameter<edm::InputTag>("beamSpotSrc"))),
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")) {
633  if (useVertex_) {
634  if (useSimVertex_) {
635  genVtxPositionToken_ = consumes<GlobalPoint>(iConfig.getParameter<edm::InputTag>("genVtxPositionSrc"));
636  genVtxTimeToken_ = consumes<float>(iConfig.getParameter<edm::InputTag>("genVtxTimeSrc"));
637  } else
638  vtxToken_ = consumes<VertexCollection>(iConfig.getParameter<edm::InputTag>("vtxSrc"));
639  }
640 
641  theEstimator = std::make_unique<Chi2MeasurementEstimator>(estMaxChi2_, estMaxNSigma_);
642  theTransformer = std::make_unique<TrackTransformer>(iConfig.getParameterSet("TrackTransformer"), consumesCollector());
643 
644  btlMatchChi2Token_ = produces<edm::ValueMap<float>>("btlMatchChi2");
645  etlMatchChi2Token_ = produces<edm::ValueMap<float>>("etlMatchChi2");
646  btlMatchTimeChi2Token_ = produces<edm::ValueMap<float>>("btlMatchTimeChi2");
647  etlMatchTimeChi2Token_ = produces<edm::ValueMap<float>>("etlMatchTimeChi2");
648  npixBarrelToken_ = produces<edm::ValueMap<int>>("npixBarrel");
649  npixEndcapToken_ = produces<edm::ValueMap<int>>("npixEndcap");
650  pOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackp");
651  betaOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackBeta");
652  t0OrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackt0");
653  sigmat0OrigTrkToken_ = produces<edm::ValueMap<float>>("generalTracksigmat0");
654  pathLengthOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackPathLength");
655  tmtdOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTracktmtd");
656  sigmatmtdOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTracksigmatmtd");
657  tofpiOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackTofPi");
658  tofkOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackTofK");
659  tofpOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackTofP");
660  sigmatofpiOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackSigmaTofPi");
661  sigmatofkOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackSigmaTofK");
662  sigmatofpOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackSigmaTofP");
663  assocOrigTrkToken_ = produces<edm::ValueMap<int>>("generalTrackassoc");
664 
665  builderToken_ = esConsumes<TransientTrackBuilder, TransientTrackRecord>(edm::ESInputTag("", transientTrackBuilder_));
667  esConsumes<TransientTrackingRecHitBuilder, TransientRecHitRecord>(edm::ESInputTag("", mtdRecHitBuilder_));
668  gtgToken_ = esConsumes<GlobalTrackingGeometry, GlobalTrackingGeometryRecord>();
669  dlgeoToken_ = esConsumes<MTDDetLayerGeometry, MTDRecoGeometryRecord>();
670  magfldToken_ = esConsumes<MagneticField, IdealMagneticFieldRecord>();
671  propToken_ = esConsumes<Propagator, TrackingComponentsRecord>(edm::ESInputTag("", propagator_));
672  ttopoToken_ = esConsumes<TrackerTopology, TrackerTopologyRcd>();
673 
674  produces<edm::OwnVector<TrackingRecHit>>();
675  produces<reco::TrackExtraCollection>();
676  produces<TrackCollection>();
677 }
678 
679 template <class TrackCollection>
682  desc.add<edm::InputTag>("tracksSrc", edm::InputTag("generalTracks"));
683  desc.add<edm::InputTag>("trjtrkAssSrc", edm::InputTag("generalTracks"));
684  desc.add<edm::InputTag>("hitsSrc", edm::InputTag("mtdTrackingRecHits"));
685  desc.add<edm::InputTag>("beamSpotSrc", edm::InputTag("offlineBeamSpot"));
686  desc.add<edm::InputTag>("genVtxPositionSrc", edm::InputTag("genParticles:xyz0"));
687  desc.add<edm::InputTag>("genVtxTimeSrc", edm::InputTag("genParticles:t0"));
688  desc.add<edm::InputTag>("vtxSrc", edm::InputTag("offlinePrimaryVertices4D"));
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");
693  desc.add<std::string>("MTDRecHitBuilder", "MTDRecHitBuilder");
694  desc.add<std::string>("Propagator", "PropagatorWithMaterialForMTD");
696  false,
697  "KFFitterForRefitInsideOut",
698  "KFSmootherForRefitInsideOut",
699  "PropagatorWithMaterialForMTD",
700  "alongMomentum",
701  true,
702  "WithTrackAngle",
703  "MuonRecHitBuilder",
704  "MTDRecHitBuilder");
705  desc.add<edm::ParameterSetDescription>("TrackTransformer", transDesc);
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);
717 }
718 
719 template <class TrackCollection>
720 template <class H, class T>
722  const H& handle,
723  const std::vector<T>& vec,
724  const edm::EDPutToken& token) const {
725  auto out = std::make_unique<edm::ValueMap<T>>();
727  filler.insert(handle, vec.begin(), vec.end());
728  filler.fill();
729  iEvent.put(token, std::move(out));
730 }
731 
732 template <class TrackCollection>
734  //this produces pieces of the track extra
735  Traj2TrackHits t2t;
736 
737  theTransformer->setServices(es);
738 
739  TrackingRecHitRefProd hitsRefProd = ev.getRefBeforePut<TrackingRecHitCollection>();
740  reco::TrackExtraRefProd extrasRefProd = ev.getRefBeforePut<reco::TrackExtraCollection>();
741 
742  gtg_ = es.getHandle(gtgToken_);
743 
744  auto geo = es.getTransientHandle(dlgeoToken_);
745 
746  auto magfield = es.getTransientHandle(magfldToken_);
747 
748  builder_ = es.getHandle(builderToken_);
749  hitbuilder_ = es.getHandle(hitbuilderToken_);
750 
751  auto propH = es.getTransientHandle(propToken_);
752  const Propagator* prop = propH.product();
753 
754  auto httopo = es.getTransientHandle(ttopoToken_);
755  const TrackerTopology& ttopo = *httopo;
756 
757  auto output = std::make_unique<TrackCollection>();
758  auto extras = std::make_unique<reco::TrackExtraCollection>();
759  auto outhits = std::make_unique<edm::OwnVector<TrackingRecHit>>();
760 
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;
781 
782  auto const tracksH = ev.getHandle(tracksToken_);
783 
784  const auto& trjtrks = ev.get(trajTrackAToken_);
785 
786  //MTD hits DetSet
787  const auto& hits = ev.get(hitsToken_);
788 
789  //beam spot
790  const auto& bs = ev.get(bsToken_);
791 
792  const Vertex* pv = nullptr;
793  if (useVertex_ && !useSimVertex_) {
794  auto const& vtxs = ev.get(vtxToken_);
795  if (!vtxs.empty())
796  pv = &vtxs[0];
797  }
798 
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);
805  }
806 
807  float vtxTime = 0.f;
808  if (useVertex_) {
809  if (useSimVertex_ && genPV) {
810  vtxTime = genPV->t();
811  } else if (pv)
812  vtxTime = pv->t(); //already in ns
813  }
814 
815  std::vector<unsigned> track_indices;
816  unsigned itrack = 0;
817 
818  for (const auto& trjtrk : trjtrks) {
819  const Trajectory& trajs = *trjtrk.key;
820  const reco::TrackRef& track = trjtrk.val;
821 
822  LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: extrapolating track " << itrack
823  << " p/pT = " << track->p() << " " << track->pt() << " eta = " << track->eta();
824  LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: sigma_p = "
825  << sqrt(track->covariance()(0, 0)) * track->p2()
826  << " sigma_p/p = " << sqrt(track->covariance()(0, 0)) * track->p() * 100 << " %";
827 
828  float trackVtxTime = 0.f;
829  if (useVertex_) {
830  float dz;
831  if (useSimVertex_)
832  dz = std::abs(track->dz(math::XYZPoint(*genPV)));
833  else
834  dz = std::abs(track->dz(pv->position()));
835 
836  if (dz < dzCut_)
837  trackVtxTime = vtxTime;
838  }
839 
840  reco::TransientTrack ttrack(track, magfield.product(), gtg_);
841  auto thits = theTransformer->getTransientRecHits(ttrack);
843  MTDHitMatchingInfo mBTL, mETL;
844 
845  if (trajs.isValid()) {
846  // get the outermost trajectory point on the track
847  TrajectoryStateOnSurface tsos = builder_->build(track).outermostMeasurementState();
849  bool tscbl_status = getTrajectoryStateClosestToBeamLine(trajs, bs, prop, tscbl);
850 
851  if (tscbl_status) {
852  float pmag2 = tscbl.trackStateAtPCA().momentum().mag2();
853  float pathlength0;
854  TrackSegments trs0;
855  trackPathLength(trajs, tscbl, prop, pathlength0, trs0);
856 
857  const auto& btlhits = tryBTLLayers(tsos,
858  trajs,
859  pmag2,
860  pathlength0,
861  trs0,
862  hits,
863  geo.product(),
864  magfield.product(),
865  prop,
866  bs,
867  trackVtxTime,
868  trackVtxTime != 0.f,
869  mBTL);
870  mtdthits.insert(mtdthits.end(), btlhits.begin(), btlhits.end());
871 
872  // in the future this should include an intermediate refit before propagating to the ETL
873  // for now it is ok
874  const auto& etlhits = tryETLLayers(tsos,
875  trajs,
876  pmag2,
877  pathlength0,
878  trs0,
879  hits,
880  geo.product(),
881  magfield.product(),
882  prop,
883  bs,
884  trackVtxTime,
885  trackVtxTime != 0.f,
886  mETL);
887  mtdthits.insert(mtdthits.end(), etlhits.begin(), etlhits.end());
888  }
889  }
890 
891  auto ordering = checkRecHitsOrdering(thits);
893  thits.insert(thits.end(), mtdthits.begin(), mtdthits.end());
894  } else {
895  std::reverse(mtdthits.begin(), mtdthits.end());
896  mtdthits.insert(mtdthits.end(), thits.begin(), thits.end());
897  thits.swap(mtdthits);
898  }
899 
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,
904  sigmatofpMap = -1.f;
905  int iMap = -1;
906 
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();
913  reco::Track result = buildTrack(track,
914  thetrj,
915  trj,
916  bs,
917  magfield.product(),
918  prop,
919  !trajwithmtd.empty() && !mtdthits.empty(),
920  pathLength,
921  tmtd,
922  sigmatmtd,
923  tofpi,
924  tofk,
925  tofp,
926  sigmatofpi,
927  sigmatofk,
928  sigmatofp);
929  if (result.ndof() >= 0) {
931  reco::TrackExtra::TrajParams trajParams;
933  size_t hitsstart = outhits->size();
934  if (updatePattern_) {
935  t2t(trj, *outhits, trajParams, chi2s); // this fills the output hit collection
936  } else {
937  t2t(thetrj, *outhits, trajParams, chi2s);
938  }
939  size_t hitsend = outhits->size();
940  extras->push_back(buildTrackExtra(trj)); // always push back the fully built extra, update by setting in track
941  extras->back().setHits(hitsRefProd, hitsstart, hitsend - hitsstart);
942  extras->back().setTrajParams(trajParams, chi2s);
943  //create the track
944  output->push_back(result);
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;
950  tmtdMap = tmtd;
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());
958  tofpiMap = tofpi;
959  tofkMap = tofk;
960  tofpMap = tofp;
961  sigmatofpiMap = sigmatofpi;
962  sigmatofkMap = sigmatofk;
963  sigmatofpMap = sigmatofp;
964  reco::TrackExtraRef extraRef(extrasRefProd, extras->size() - 1);
965  backtrack.setExtra((updateExtra_ ? extraRef : track->extra()));
966  for (unsigned ihit = hitsstart; ihit < hitsend; ++ihit) {
967  backtrack.appendHitPattern((*outhits)[ihit], ttopo);
968  }
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) << "%) ";
979  } else {
980  LogTrace("TrackExtenderWithMTD") << "Error in the MTD track refitting. This should not happen";
981  }
982  }
983 
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);
998 
999  if (iMap == -1) {
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);
1006  }
1007 
1008  ++itrack;
1009  }
1010 
1011  auto outTrksHandle = ev.put(std::move(output));
1012  ev.put(std::move(extras));
1013  ev.put(std::move(outhits));
1014 
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_);
1035 }
1036 
1037 namespace {
1038  bool cmp_for_detset(const unsigned one, const unsigned two) { return one < two; };
1039 
1040  void find_hits_in_dets(const MTDTrackingDetSetVector& hits,
1041  const Trajectory& traj,
1042  const DetLayer* layer,
1043  const TrajectoryStateOnSurface& tsos,
1044  const float pmag2,
1045  const float pathlength0,
1046  const TrackSegments& trs0,
1047  const float vtxTime,
1048  const reco::BeamSpot& bs,
1049  const float bsTimeSpread,
1050  const Propagator* prop,
1052  bool useVtxConstraint,
1053  std::set<MTDHitMatchingInfo>& out) {
1054  pair<bool, TrajectoryStateOnSurface> comp = layer->compatible(tsos, *prop, *estimator);
1055  if (comp.first) {
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);
1061  if (range.first == range.second) {
1062  LogTrace("TrackExtenderWithMTD")
1063  << "Hit search: no hit in DetId " << detWithState.first->geographicalId().rawId();
1064  continue;
1065  }
1066 
1067  auto pl = prop->propagateWithPath(tsos, detWithState.second.surface());
1068  if (pl.second == 0.) {
1069  LogTrace("TrackExtenderWithMTD")
1070  << "Hit search: no propagation to DetId " << detWithState.first->geographicalId().rawId();
1071  continue;
1072  }
1073 
1074  const float t_vtx = useVtxConstraint ? vtxTime : 0.f;
1075 
1076  constexpr float vtx_res = 0.008f;
1077  const float t_vtx_err = useVtxConstraint ? vtx_res : bsTimeSpread;
1078 
1079  float lastpmag2 = trs0.getSegmentPathAndMom2(0).second;
1080 
1081  for (auto detitr = range.first; detitr != range.second; ++detitr) {
1082  for (const auto& hit : *detitr) {
1083  auto est = estimator->estimate(detWithState.second, hit);
1084  if (!est.first) {
1085  LogTrace("TrackExtenderWithMTD")
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() << ","
1088  << std::fixed << std::setw(14) << hit.globalPosition().y() << "," << std::fixed << std::setw(14)
1089  << hit.globalPosition().z() << ")";
1090  continue;
1091  }
1092 
1093  LogTrace("TrackExtenderWithMTD")
1094  << "Hit search: spatial compatibility DetId " << detWithState.first->geographicalId().rawId()
1095  << " TSOS dx/dy " << std::fixed << std::setw(14)
1096  << std::sqrt(detWithState.second.localError().positionError().xx()) << " " << std::fixed
1097  << std::setw(14) << std::sqrt(detWithState.second.localError().positionError().yy()) << " hit dx/dy "
1098  << std::fixed << std::setw(14) << std::sqrt(hit.localPositionError().xx()) << " " << std::fixed
1099  << std::setw(14) << std::sqrt(hit.localPositionError().yy()) << " chi2 " << std::fixed
1100  << std::setw(14) << est.second;
1101 
1102  TrackTofPidInfo tof = computeTrackTofPidInfo(lastpmag2,
1103  std::abs(pl.second),
1104  trs0,
1105  hit.time(),
1106  hit.timeError(),
1107  t_vtx,
1108  t_vtx_err, //put vtx error by hand for the moment
1109  false,
1110  TofCalc::kMixd);
1111  MTDHitMatchingInfo mi;
1112  mi.hit = &hit;
1113  mi.estChi2 = est.second;
1114  mi.timeChi2 = tof.dtchi2_best; //use the chi2 for the best matching hypothesis
1115 
1116  out.insert(mi);
1117  }
1118  }
1119  }
1120  }
1121  }
1122  }
1123 } // namespace
1124 
1125 template <class TrackCollection>
1127  const TrajectoryStateOnSurface& tsos,
1128  const Trajectory& traj,
1129  const float pmag2,
1130  const float pathlength0,
1131  const TrackSegments& trs0,
1133  const MTDDetLayerGeometry* geo,
1134  const MagneticField* field,
1135  const Propagator* prop,
1136  const reco::BeamSpot& bs,
1137  const float vtxTime,
1138  const bool matchVertex,
1139  MTDHitMatchingInfo& bestHit) const {
1140  const vector<const DetLayer*>& layers = geo->allBTLLayers();
1141 
1143  bestHit = MTDHitMatchingInfo();
1144  for (const DetLayer* ilay : layers) {
1145  LogTrace("TrackExtenderWithMTD") << "Hit search: BTL layer at R= "
1146  << static_cast<const BarrelDetLayer*>(ilay)->specificSurface().radius();
1147 
1148  fillMatchingHits(ilay, tsos, traj, pmag2, pathlength0, trs0, hits, prop, bs, vtxTime, matchVertex, output, bestHit);
1149  }
1150 
1151  return output;
1152 }
1153 
1154 template <class TrackCollection>
1156  const TrajectoryStateOnSurface& tsos,
1157  const Trajectory& traj,
1158  const float pmag2,
1159  const float pathlength0,
1160  const TrackSegments& trs0,
1162  const MTDDetLayerGeometry* geo,
1163  const MagneticField* field,
1164  const Propagator* prop,
1165  const reco::BeamSpot& bs,
1166  const float vtxTime,
1167  const bool matchVertex,
1168  MTDHitMatchingInfo& bestHit) const {
1169  const vector<const DetLayer*>& layers = geo->allETLLayers();
1170 
1172  bestHit = MTDHitMatchingInfo();
1173  for (const DetLayer* ilay : layers) {
1174  const BoundDisk& disk = static_cast<const ForwardDetLayer*>(ilay)->specificSurface();
1175  const float diskZ = disk.position().z();
1176 
1177  if (tsos.globalPosition().z() * diskZ < 0)
1178  continue; // only propagate to the disk that's on the same side
1179 
1180  LogTrace("TrackExtenderWithMTD") << "Hit search: ETL disk at Z = " << diskZ;
1181 
1182  fillMatchingHits(ilay, tsos, traj, pmag2, pathlength0, trs0, hits, prop, bs, vtxTime, matchVertex, output, bestHit);
1183  }
1184 
1185  // the ETL hits order must be from the innermost to the outermost
1186 
1187  if (output.size() == 2) {
1188  if (std::abs(output[0]->globalPosition().z()) > std::abs(output[1]->globalPosition().z())) {
1189  std::reverse(output.begin(), output.end());
1190  }
1191  }
1192  return output;
1193 }
1194 
1195 template <class TrackCollection>
1197  const TrajectoryStateOnSurface& tsos,
1198  const Trajectory& traj,
1199  const float pmag2,
1200  const float pathlength0,
1201  const TrackSegments& trs0,
1203  const Propagator* prop,
1204  const reco::BeamSpot& bs,
1205  const float& vtxTime,
1206  const bool matchVertex,
1208  MTDHitMatchingInfo& bestHit) const {
1209  std::set<MTDHitMatchingInfo> hitsInLayer;
1210  bool hitMatched = false;
1211 
1212  using namespace std::placeholders;
1213  auto find_hits = std::bind(find_hits_in_dets,
1214  std::cref(hits),
1215  std::cref(traj),
1216  ilay,
1217  std::cref(tsos),
1218  pmag2,
1219  pathlength0,
1220  trs0,
1221  _1,
1222  std::cref(bs),
1223  bsTimeSpread_,
1224  prop,
1225  theEstimator.get(),
1226  _2,
1227  std::ref(hitsInLayer));
1228 
1229  if (useVertex_ && matchVertex)
1230  find_hits(vtxTime, true);
1231  else
1232  find_hits(0, false);
1233 
1234  float spaceChi2Cut = ilay->isBarrel() ? btlChi2Cut_ : etlChi2Cut_;
1235  float timeChi2Cut = ilay->isBarrel() ? btlTimeChi2Cut_ : etlTimeChi2Cut_;
1236 
1237  //just take the first hit because the hits are sorted on their matching quality
1238  if (!hitsInLayer.empty()) {
1239  //check hits to pass minimum quality matching requirements
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) {
1244  hitMatched = true;
1245  output.push_back(hitbuilder_->build(firstHit.hit));
1246  if (firstHit < bestHit)
1247  bestHit = firstHit;
1248  }
1249  }
1250 
1251  if (useVertex_ && matchVertex && !hitMatched) {
1252  //try a second search with beamspot hypothesis
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) {
1261  hitMatched = true;
1262  output.push_back(hitbuilder_->build(firstHit.hit));
1263  if (firstHit < bestHit)
1264  bestHit = firstHit;
1265  }
1266  }
1267  }
1268  }
1269 
1270 #ifdef EDM_ML_DEBUG
1271  if (hitMatched) {
1272  LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: matched hit with time: " << bestHit.hit->time()
1273  << " +/- " << bestHit.hit->timeError();
1274  } else {
1275  LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: no matched hit";
1276  }
1277 #endif
1278 }
1279 
1280 //below is unfortunately ripped from other places but
1281 //since track producer doesn't know about MTD we have to do this
1282 template <class TrackCollection>
1284  const Trajectory& traj,
1285  const Trajectory& trajWithMtd,
1286  const reco::BeamSpot& bs,
1287  const MagneticField* field,
1288  const Propagator* thePropagator,
1289  bool hasMTD,
1290  float& pathLengthOut,
1291  float& tmtdOut,
1292  float& sigmatmtdOut,
1293  float& tofpi,
1294  float& tofk,
1295  float& tofp,
1296  float& sigmatofpi,
1297  float& sigmatofk,
1298  float& sigmatofp) const {
1300  bool tsbcl_status = getTrajectoryStateClosestToBeamLine(traj, bs, thePropagator, tscbl);
1301 
1302  if (!tsbcl_status)
1303  return reco::Track();
1304 
1305  GlobalPoint v = tscbl.trackStateAtPCA().position();
1306  math::XYZPoint pos(v.x(), v.y(), v.z());
1307  GlobalVector p = tscbl.trackStateAtPCA().momentum();
1308  math::XYZVector mom(p.x(), p.y(), p.z());
1309 
1310  int ndof = traj.ndof();
1311 
1312  float t0 = 0.f;
1313  float covt0t0 = -1.f;
1314  pathLengthOut = -1.f; // if there is no MTD flag the pathlength with -1
1315  tmtdOut = 0.f;
1316  sigmatmtdOut = -1.f;
1317  float betaOut = 0.f;
1318  float covbetabeta = -1.f;
1319 
1320  auto routput = [&]() {
1321  return reco::Track(traj.chiSquared(),
1322  int(ndof),
1323  pos,
1324  mom,
1325  tscbl.trackStateAtPCA().charge(),
1327  orig->algo(),
1329  t0,
1330  betaOut,
1331  covt0t0,
1332  covbetabeta);
1333  };
1334 
1335  //compute path length for time backpropagation, using first MTD hit for the momentum
1336  if (hasMTD) {
1337  float pathlength;
1338  TrackSegments trs;
1339  bool validpropagation = trackPathLength(trajWithMtd, bs, thePropagator, pathlength, trs);
1340  float thit = 0.f;
1341  float thiterror = -1.f;
1342  bool validmtd = false;
1343 
1344  if (!validpropagation) {
1345  return routput();
1346  }
1347 
1348  uint32_t ihitcount(0), ietlcount(0);
1349  for (auto const& hit : trajWithMtd.measurements()) {
1350  if (hit.recHit()->geographicalId().det() == DetId::Forward &&
1351  ForwardSubdetector(hit.recHit()->geographicalId().subdetId()) == FastTime) {
1352  ihitcount++;
1353  if (MTDDetId(hit.recHit()->geographicalId()).mtdSubDetector() == MTDDetId::MTDType::ETL) {
1354  ietlcount++;
1355  }
1356  }
1357  }
1358 
1359  LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: selected #hits " << ihitcount << " from ETL "
1360  << ietlcount;
1361 
1362  auto ihit1 = trajWithMtd.measurements().cbegin();
1363  if (ihitcount == 1) {
1364  const MTDTrackingRecHit* mtdhit = static_cast<const MTDTrackingRecHit*>((*ihit1).recHit()->hit());
1365  thit = mtdhit->time();
1366  thiterror = mtdhit->timeError();
1367  validmtd = true;
1368  } else if (ihitcount == 2 && ietlcount == 2) {
1369  std::pair<float, float> lastStep = trs.getSegmentPathAndMom2(0);
1370  float etlpathlength = std::abs(lastStep.first * c_cm_ns);
1371  //
1372  // The information of the two ETL hits is combined and attributed to the innermost hit
1373  //
1374  if (etlpathlength == 0.f) {
1375  validpropagation = false;
1376  } else {
1377  pathlength -= etlpathlength;
1378  trs.removeFirstSegment();
1379  const MTDTrackingRecHit* mtdhit1 = static_cast<const MTDTrackingRecHit*>((*ihit1).recHit()->hit());
1380  const MTDTrackingRecHit* mtdhit2 = static_cast<const MTDTrackingRecHit*>((*(ihit1 + 1)).recHit()->hit());
1381  TrackTofPidInfo tofInfo = computeTrackTofPidInfo(
1382  lastStep.second, etlpathlength, trs, mtdhit1->time(), mtdhit1->timeError(), 0.f, 0.f, true, TofCalc::kCost);
1383  //
1384  // Protect against incompatible times
1385  //
1386  float err1 = tofInfo.dterror * tofInfo.dterror;
1387  float err2 = mtdhit2->timeError() * mtdhit2->timeError();
1388  if (cms_rounding::roundIfNear0(err1) == 0.f || cms_rounding::roundIfNear0(err2) == 0.f) {
1389  edm::LogError("TrackExtenderWithMTD")
1390  << "MTD tracking hits with zero time uncertainty: " << err1 << " " << err2;
1391  } else {
1392  if ((tofInfo.dt - mtdhit2->time()) * (tofInfo.dt - mtdhit2->time()) < (err1 + err2) * etlTimeChi2Cut_) {
1393  //
1394  // Subtract the ETL time of flight from the outermost measurement, and combine it in a weighted average with the innermost
1395  // the mass ambiguity related uncertainty on the time of flight is added as an additional uncertainty
1396  //
1397  err1 = 1.f / err1;
1398  err2 = 1.f / err2;
1399  thiterror = 1.f / (err1 + err2);
1400  thit = (tofInfo.dt * err1 + mtdhit2->time() * err2) * thiterror;
1401  thiterror = std::sqrt(thiterror);
1402  LogTrace("TrackExtenderWithMTD")
1403  << "TrackExtenderWithMTD: p trk = " << p.mag() << " ETL hits times/errors: " << mtdhit1->time()
1404  << " +/- " << mtdhit1->timeError() << " , " << mtdhit2->time() << " +/- " << mtdhit2->timeError()
1405  << " extrapolated time1: " << tofInfo.dt << " +/- " << tofInfo.dterror << " average = " << thit
1406  << " +/- " << thiterror;
1407  validmtd = true;
1408  } else {
1409  // if back extrapolated time of the outermost measurement not compatible with the innermost, keep the one with smallest error
1410  if (err1 <= err2) {
1411  thit = tofInfo.dt;
1412  thiterror = tofInfo.dterror;
1413  validmtd = true;
1414  } else {
1415  thit = mtdhit2->time();
1416  thiterror = mtdhit2->timeError();
1417  validmtd = true;
1418  }
1419  }
1420  }
1421  }
1422  } else {
1423  edm::LogInfo("TrackExtenderWithMTD")
1424  << "MTD hits #" << ihitcount << "ETL hits #" << ietlcount << " anomalous pattern, skipping...";
1425  }
1426 
1427  if (validmtd && validpropagation) {
1428  //here add the PID uncertainty for later use in the 1st step of 4D vtx reconstruction
1429  TrackTofPidInfo tofInfo = computeTrackTofPidInfo(
1430  p.mag2(), pathlength, trs, thit, thiterror, 0.f, 0.f, true, TofCalc::kSegm, SigmaTofCalc::kCost);
1431 
1432  pathLengthOut = pathlength; // set path length if we've got a timing hit
1433  tmtdOut = thit;
1434  sigmatmtdOut = thiterror;
1435  t0 = tofInfo.dt;
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;
1445  }
1446  }
1447 
1448  return routput();
1449 }
1450 
1451 template <class TrackCollection>
1453  static const string metname = "TrackExtenderWithMTD";
1454 
1455  const Trajectory::RecHitContainer transRecHits = trajectory.recHits();
1456 
1457  // put the collection of TrackingRecHit in the event
1458 
1459  // sets the outermost and innermost TSOSs
1460  // ToDo: validation for track states with MTD
1461  TrajectoryStateOnSurface outerTSOS;
1462  TrajectoryStateOnSurface innerTSOS;
1463  unsigned int innerId = 0, outerId = 0;
1465  DetId outerDetId;
1466 
1467  if (trajectory.direction() == alongMomentum) {
1468  LogTrace(metname) << "alongMomentum";
1469  outerTSOS = trajectory.lastMeasurement().updatedState();
1470  innerTSOS = trajectory.firstMeasurement().updatedState();
1471  outerId = trajectory.lastMeasurement().recHit()->geographicalId().rawId();
1472  innerId = trajectory.firstMeasurement().recHit()->geographicalId().rawId();
1473  outerRecHit = trajectory.lastMeasurement().recHit();
1474  outerDetId = trajectory.lastMeasurement().recHit()->geographicalId();
1475  } else if (trajectory.direction() == oppositeToMomentum) {
1476  LogTrace(metname) << "oppositeToMomentum";
1477  outerTSOS = trajectory.firstMeasurement().updatedState();
1478  innerTSOS = trajectory.lastMeasurement().updatedState();
1479  outerId = trajectory.firstMeasurement().recHit()->geographicalId().rawId();
1480  innerId = trajectory.lastMeasurement().recHit()->geographicalId().rawId();
1481  outerRecHit = trajectory.firstMeasurement().recHit();
1482  outerDetId = trajectory.firstMeasurement().recHit()->geographicalId();
1483  } else
1484  LogError(metname) << "Wrong propagation direction!";
1485 
1486  const GeomDet* outerDet = gtg_->idToDet(outerDetId);
1487  GlobalPoint outerTSOSPos = outerTSOS.globalParameters().position();
1488  bool inside = outerDet->surface().bounds().inside(outerDet->toLocal(outerTSOSPos));
1489 
1490  GlobalPoint hitPos =
1491  (outerRecHit->isValid()) ? outerRecHit->globalPosition() : outerTSOS.globalParameters().position();
1492 
1493  if (!inside) {
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();
1497  LogTrace(metname) << "From " << outerTSOSPos << " to " << hitPos;
1498  }
1499 
1500  //build the TrackExtra
1501  GlobalPoint v = (inside) ? outerTSOSPos : hitPos;
1502  GlobalVector p = outerTSOS.globalParameters().momentum();
1503  math::XYZPoint outpos(v.x(), v.y(), v.z());
1504  math::XYZVector outmom(p.x(), p.y(), p.z());
1505 
1506  v = innerTSOS.globalParameters().position();
1507  p = innerTSOS.globalParameters().momentum();
1508  math::XYZPoint inpos(v.x(), v.y(), v.z());
1509  math::XYZVector inmom(p.x(), p.y(), p.z());
1510 
1511  reco::TrackExtra trackExtra(outpos,
1512  outmom,
1513  true,
1514  inpos,
1515  inmom,
1516  true,
1517  outerTSOS.curvilinearError(),
1518  outerId,
1519  innerTSOS.curvilinearError(),
1520  innerId,
1521  trajectory.direction(),
1522  trajectory.seedRef());
1523 
1524  return trackExtra;
1525 }
1526 
1527 template <class TrackCollection>
1529  stringstream output;
1530 
1531  const BoundSurface* sur = nullptr;
1532  const BoundCylinder* bc = nullptr;
1533  const BoundDisk* bd = nullptr;
1534 
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;
1540  }
1541  return output.str();
1542 }
1543 
1544 //define this as a plug-in
1551 
size
Write out results.
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
float dt
Definition: AMPTWrapper.h:136
TrackExtenderWithMTDT< reco::TrackCollection > TrackExtenderWithMTD
edm::EDPutToken btlMatchTimeChi2Token_
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
bool isValid() const
Definition: Trajectory.h:257
edm::ESGetToken< TransientTrackingRecHitBuilder, TransientRecHitRecord > hitbuilderToken_
const CurvilinearTrajectoryError & curvilinearError() const
edm::EDPutToken btlMatchChi2Token_
std::vector< unsigned char > Chi2sFive
constexpr double c_cm_ns
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)
Definition: IOVSyncValue.h:34
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:58
edm::ESGetToken< GlobalTrackingGeometry, GlobalTrackingGeometryRecord > gtgToken_
edm::EDPutToken sigmatofkOrigTrkToken_
T z() const
Definition: PV3DBase.h:61
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
Definition: GlobalPoint.h:10
edm::EDPutToken etlMatchChi2Token_
edm::View< TrackType > InputCollection
edm::EDGetTokenT< GlobalPoint > genVtxPositionToken_
float chiSquared() const
Definition: Trajectory.h:241
edm::RefToBase< TrajectorySeed > seedRef(void) const
Definition: Trajectory.h:303
Log< level::Error, false > LogError
T mag2() const
Definition: PV3DBase.h:63
const SurfaceType & surface() const
edm::EDPutToken tofkOrigTrkToken_
edm::EDPutToken etlMatchTimeChi2Token_
ForwardSubdetector
edm::EDPutToken sigmat0OrigTrkToken_
void fillValueMap(edm::Event &iEvent, const H &handle, const std::vector< T > &vec, const edm::EDPutToken &token) const
float float float z
edm::EDPutToken tmtdOrigTrkToken_
Definition: Electron.h:6
TrajectoryMeasurement const & lastMeasurement() const
Definition: Trajectory.h:150
edm::EDGetTokenT< MTDTrackingDetSetVector > hitsToken_
#define LogTrace(id)
Detector identifier base class for the MIP Timing Layer.
Definition: MTDDetId.h:21
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
Definition: Trajectory.h:178
GlobalPoint position() const
edm::EDPutToken sigmatofpiOrigTrkToken_
string dumpLayer(const DetLayer *layer) const
std::vector< LocalTrajectoryParameters > TrajParams
int iEvent
Definition: GenABIO.cc:224
int ndof(bool bon=true) const
Definition: Trajectory.cc:97
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
edm::ESGetToken< TransientTrackBuilder, TransientTrackRecord > builderToken_
const std::string mtdRecHitBuilder_
T sqrt(T t)
Definition: SSEVec.h:19
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
Definition: Trajectory.cc:133
TrackCharge charge() const
ConstRecHitContainer recHits() const
Definition: Trajectory.h:186
GlobalVector momentum() const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::EDPutToken assocOrigTrkToken_
const std::string propagator_
edm::ESGetToken< Propagator, TrackingComponentsRecord > propToken_
virtual std::pair< TrajectoryStateOnSurface, double > propagateWithPath(const FreeTrajectoryState &, const Surface &) const final
Definition: Propagator.cc:10
constexpr valType roundIfNear0(valType value, double tolerance=1.e-7)
Definition: Rounding.h:11
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:130
edm::ESHandle< TransientTrackingRecHitBuilder > hitbuilder_
const std::vector< const DetLayer * > & allBTLLayers() const
return the BTL DetLayers (barrel), inside-out
std::vector< ConstRecHitPointer > ConstRecHitContainer
constexpr double c_inv
const std::string transientTrackBuilder_
Log< level::Info, false > LogInfo
Definition: DetId.h:17
std::vector< TrackExtra > TrackExtraCollection
collection of TrackExtra objects
Definition: TrackExtraFwd.h:10
ConstRecHitContainer RecHitContainer
Definition: Trajectory.h:42
constexpr NumType convertMmToCm(NumType millimeters)
Definition: angle_units.h:44
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const CurvilinearTrajectoryError & curvilinearError() const
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
reco::TrackExtra buildTrackExtra(const Trajectory &trajectory) const
A 2D TrackerRecHit with time and time error information.
CurvilinearTrajectoryError curvilinearError(const PerigeeTrajectoryError &perigeeError, const GlobalTrajectoryParameters &gtp)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
TrackingRecHit::ConstRecHitPointer ConstRecHitPointer
edm::ESHandle< TransientTrackBuilder > builder_
float timeError() const
static void fillPSetDescription(edm::ParameterSetDescription &descriptions, bool doPredictionsOnly=false, const std::string &fitter="KFFitterForRefitInsideOut", const std::string &smoother="KFSmootherForRefitInsideOut", const std::string &propagator="SmartPropagatorAnyRK", const std::string &refitDirection="alongMomentum", bool refitRPCHits=true, const std::string &trackerRecHitBuilder="WithTrackAngle", const std::string &muonRecHitBuilder="MuonRecHitBuilder", const std::string &mtdRecHitBuilder="MTDRecHitBuilder")
fillDescriptions
std::unique_ptr< TrackTransformer > theTransformer
TrajectoryStateOnSurface const & updatedState() const
edm::EDPutToken npixBarrelToken_
edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > magfldToken_
edm::EDPutToken npixEndcapToken_
fixed size matrix
HLT enums.
TrajectoryMeasurement const & firstMeasurement() const
Definition: Trajectory.h:166
static int position[264][3]
Definition: ReadPGInfo.cc:289
TrajectoryMeasurement const & closestMeasurement(GlobalPoint) const
Definition: Trajectory.cc:256
edm::EDPutToken betaOrigTrkToken_
FreeTrajectoryState const * freeState(bool withErrors=true) const
ESTransientHandle< T > getTransientHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:141
edm::EDGetTokenT< TrajTrackAssociationCollection > trajTrackAToken_
float time() const
edm::EDPutToken pathLengthOrigTrkToken_
Definition: output.py:1
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_
ordering
Definition: config.py:7
edm::EDGetTokenT< VertexCollection > vtxToken_
void produce(edm::Event &ev, const edm::EventSetup &es) final
bool isBarrel() const
Definition: DetLayer.h:31
TrackCollection::value_type TrackType
edm::EDGetTokenT< InputCollection > tracksToken_
const std::vector< const DetLayer * > & allETLLayers() const
return the ETL DetLayers (endcap), -Z to +Z
def move(src, dest)
Definition: eostools.py:511
RefitDirection::GeometricalDirection checkRecHitsOrdering(TransientTrackingRecHit::ConstRecHitContainer const &recHits) const
ConstRecHitPointer const & recHit() const
edm::EDPutToken sigmatofpOrigTrkToken_
#define LogDebug(id)
edm::ESGetToken< MTDDetLayerGeometry, MTDRecoGeometryRecord > dlgeoToken_
#define m_pi
Definition: RPCConst.cc:8
const Bounds & bounds() const
Definition: Surface.h:87