CMS 3D CMS Logo

TrackTimeValueMapProducer.cc
Go to the documentation of this file.
1 // This producer assigns vertex times (with a specified resolution) to tracks.
2 // The times are produced as valuemaps associated to tracks, so the track
3 // dataformat doesn't need to be modified.
4 
7 
10 
12 
16 
32 
33 #include <memory>
34 #include <random>
35 
36 #include "CLHEP/Units/SystemOfUnits.h"
40 
42 public:
45 
46  void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override;
47 
48 private:
49  // inputs
55  // tracking particle associators by order of preference
56  const std::vector<edm::EDGetTokenT<reco::TrackToTrackingParticleAssociator>> associators_;
57  // eta bounds
59  // options
60  std::vector<std::unique_ptr<const ResolutionModel>> resolutions_;
61  // functions
62  float extractTrackVertexTime(const TrackingParticle &, const reco::TransientTrack &) const;
63 };
64 
66 
67 namespace {
68  constexpr float m_pion = 139.57061e-3;
69  const std::string resolution("Resolution");
70 
71  template <typename ParticleType, typename T>
72  void writeValueMap(edm::Event &iEvent,
74  const std::vector<T> &values,
75  const std::string &label) {
76  std::unique_ptr<edm::ValueMap<T>> valMap(new edm::ValueMap<T>());
77  typename edm::ValueMap<T>::Filler filler(*valMap);
78  filler.insert(handle, values.begin(), values.end());
79  filler.fill();
80  iEvent.put(std::move(valMap), label);
81  }
82 } // namespace
83 
85  : tracks_(consumes<edm::View<reco::Track>>(conf.getParameter<edm::InputTag>("trackSrc"))),
86  tracksName_(conf.getParameter<edm::InputTag>("trackSrc").label()),
87  trackingParticles_(consumes<TrackingParticleCollection>(conf.getParameter<edm::InputTag>("trackingParticleSrc"))),
88  trackingVertices_(consumes<TrackingVertexCollection>(conf.getParameter<edm::InputTag>("trackingVertexSrc"))),
90  consumes<std::vector<PileupSummaryInfo>>(conf.getParameter<edm::InputTag>("pileupSummaryInfo"))),
92  conf.getParameter<std::vector<edm::InputTag>>("associators"),
93  [this](const edm::InputTag &tag) { return this->consumes<reco::TrackToTrackingParticleAssociator>(tag); })),
94  etaMin_(conf.getParameter<double>("etaMin")),
95  etaMax_(conf.getParameter<double>("etaMax")),
96  ptMin_(conf.getParameter<double>("ptMin")),
97  pMin_(conf.getParameter<double>("pMin")),
98  etaMaxForPtThreshold_(conf.getParameter<double>("etaMaxForPtThreshold")) {
99  // setup resolution models
100  const std::vector<edm::ParameterSet> &resos = conf.getParameterSetVector("resolutionModels");
101  for (const auto &reso : resos) {
102  const std::string &name = reso.getParameter<std::string>("modelName");
103  resolutions_.emplace_back(ResolutionModelFactory::get()->create(name, reso));
104 
105  // times and time resolutions for general tracks
106  produces<edm::ValueMap<float>>(tracksName_ + name);
107  produces<edm::ValueMap<float>>(tracksName_ + name + resolution);
108  }
109 }
110 
112  // get sim track associators
113  std::vector<edm::Handle<reco::TrackToTrackingParticleAssociator>> associators;
114  for (const auto &token : associators_) {
115  associators.emplace_back();
116  auto &back = associators.back();
117  evt.getByToken(token, back);
118  }
119 
120  std::vector<float> generalTrackTimes;
121 
122  // get track collections
123  edm::Handle<edm::View<reco::Track>> TrackCollectionH;
124  evt.getByToken(tracks_, TrackCollectionH);
125  const edm::View<reco::Track> &TrackCollection = *TrackCollectionH;
126 
127  // get tracking particle collections
129  evt.getByToken(trackingParticles_, TPCollectionH);
130 
132  evt.getByToken(pileupSummaryInfo_, pileupSummaryH);
133 
134  // transient track builder
136  es.get<TransientTrackRecord>().get("TransientTrackBuilder", theB);
137 
138  // associate the reco tracks / gsf Tracks
139  std::vector<reco::RecoToSimCollection> associatedTracks;
140  for (auto associator : associators) {
141  associatedTracks.emplace_back(associator->associateRecoToSim(TrackCollectionH, TPCollectionH));
142  }
143 
144  double sumSimTime = 0.;
145  double sumSimTimeSq = 0.;
146  int nsim = 0;
147  for (const PileupSummaryInfo &puinfo : *pileupSummaryH) {
148  if (puinfo.getBunchCrossing() == 0) {
149  for (const float &time : puinfo.getPU_times()) {
150  double simtime = time;
151  sumSimTime += simtime;
152  sumSimTimeSq += simtime * simtime;
153  ++nsim;
154  }
155  break;
156  }
157  }
158 
159  double meanSimTime = sumSimTime / double(nsim);
160  double varSimTime = sumSimTimeSq / double(nsim) - meanSimTime * meanSimTime;
161  double rmsSimTime = std::sqrt(std::max(0.1 * 0.1, varSimTime));
162  std::normal_distribution<float> gausSimTime(meanSimTime, rmsSimTime);
163 
164  // get event-based seed for RNG
165  unsigned int runNum_uint = static_cast<unsigned int>(evt.id().run());
166  unsigned int lumiNum_uint = static_cast<unsigned int>(evt.id().luminosityBlock());
167  unsigned int evNum_uint = static_cast<unsigned int>(evt.id().event());
168  unsigned int tkChi2_uint = uint32_t(TrackCollection.empty() ? 0 : TrackCollection.refAt(0)->chi2() / 0.01);
169  std::uint32_t seed = tkChi2_uint + (lumiNum_uint << 10) + (runNum_uint << 20) + evNum_uint;
170  std::mt19937 rng(seed);
171 
172  for (unsigned itk = 0; itk < TrackCollection.size(); ++itk) {
173  const auto tkref = TrackCollection.refAt(itk);
174  reco::RecoToSimCollection::const_iterator track_tps = associatedTracks.back().end();
175 
176  for (const auto &association : associatedTracks) {
177  track_tps = association.find(tkref);
178  if (track_tps != association.end())
179  break;
180  }
181 
182  if (track_tps != associatedTracks.back().end() && track_tps->val.size() == 1) {
183  reco::TransientTrack tt = theB->build(*tkref);
184  float time = extractTrackVertexTime(*track_tps->val[0].first, tt);
185  generalTrackTimes.push_back(time);
186  } else {
187  float rndtime = gausSimTime(rng);
188  generalTrackTimes.push_back(rndtime);
189  if (track_tps != associatedTracks.back().end() && track_tps->val.size() > 1) {
190  LogDebug("TooManyTracks") << "track matched to " << track_tps->val.size() << " tracking particles!"
191  << std::endl;
192  }
193  }
194  }
195 
196  for (const auto &reso : resolutions_) {
197  const std::string &name = reso->name();
198  std::vector<float> times, resos;
199 
200  times.reserve(TrackCollection.size());
201  resos.reserve(TrackCollection.size());
202 
203  for (unsigned i = 0; i < TrackCollection.size(); ++i) {
204  const reco::Track &tk = TrackCollection[i];
205  const float absEta = std::abs(tk.eta());
206  bool inAcceptance = absEta < etaMax_ && absEta >= etaMin_ && tk.p() > pMin_ &&
207  (absEta > etaMaxForPtThreshold_ || tk.pt() > ptMin_);
208  if (inAcceptance) {
209  const float resolution = reso->getTimeResolution(tk);
210  std::normal_distribution<float> gausGeneralTime(generalTrackTimes[i], resolution);
211  times.push_back(gausGeneralTime(rng));
212  resos.push_back(resolution);
213  } else {
214  times.push_back(0.0f);
215  resos.push_back(-1.);
216  }
217  }
218 
219  writeValueMap(evt, TrackCollectionH, times, tracksName_ + name);
220  writeValueMap(evt, TrackCollectionH, resos, tracksName_ + name + resolution);
221  }
222 }
223 
225  const reco::TransientTrack &tt) const {
226  int pdgid = tp.pdgId();
227  const auto &tvertex = tp.parentVertex();
228  math::XYZTLorentzVectorD result = tvertex->position();
229 
230  // account for secondary vertices...
231  if (tvertex->nSourceTracks() && tvertex->sourceTracks()[0]->pdgId() == pdgid) {
232  auto pvertex = tvertex->sourceTracks()[0]->parentVertex();
233  result = pvertex->position();
234  while (pvertex->nSourceTracks() && pvertex->sourceTracks()[0]->pdgId() == pdgid) {
235  pvertex = pvertex->sourceTracks()[0]->parentVertex();
236  result = pvertex->position();
237  }
238  }
239 
240  float time = result.T() * CLHEP::second;
241  // correct for time of flight from track reference position
242  GlobalPoint result_pos(result.x(), result.y(), result.z());
243  const auto &tkstate = tt.trajectoryStateClosestToPoint(result_pos);
244  float tkphi = tkstate.momentum().phi();
245  float tkz = tkstate.position().z();
246  float dphi = reco::deltaPhi(tkphi, tt.track().phi());
247  float dz = tkz - tt.track().vz();
248 
249  float radius = 100. * tt.track().pt() / (0.3 * tt.field()->inTesla(GlobalPoint(0, 0, 0)).z());
250  float pathlengthrphi = tt.track().charge() * dphi * radius;
251 
252  float pathlength = std::sqrt(pathlengthrphi * pathlengthrphi + dz * dz);
253  float p = tt.track().p();
254 
255  float speed = std::sqrt(1. / (1. + m_pion / p)) * CLHEP::c_light / CLHEP::cm; // speed in cm/ns
256  float dt = pathlength / speed;
257 
258  return time - dt;
259 }
#define LogDebug(id)
RunNumber_t run() const
Definition: EventID.h:38
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
double p() const
momentum vector magnitude
Definition: TrackBase.h:599
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
EventNumber_t event() const
Definition: EventID.h:40
float dt
Definition: AMPTWrapper.h:136
const edm::EDGetTokenT< TrackingVertexCollection > trackingVertices_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:131
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:14
std::vector< TrackingParticle > TrackingParticleCollection
def create(alignables, pedeDump, additionalData, outputFile, config)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:525
int pdgId() const
PDG ID.
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:14
reco::TransientTrack build(const reco::Track *p) const
size_type size() const
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:614
const MagneticField * field() const
LuminosityBlockNumber_t luminosityBlock() const
Definition: EventID.h:39
std::vector< std::unique_ptr< const ResolutionModel > > resolutions_
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
RefToBase< value_type > refAt(size_type i) const
U second(std::pair< T, U > const &p)
char const * label
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:617
T sqrt(T t)
Definition: SSEVec.h:19
double pt() const
track transverse momentum
Definition: TrackBase.h:602
T z() const
Definition: PV3DBase.h:61
bool empty() const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
float extractTrackVertexTime(const TrackingParticle &, const reco::TransientTrack &) const
double f[11][100]
const TrackingVertexRef & parentVertex() const
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
TrackTimeValueMapProducer(const edm::ParameterSet &)
const edm::EDGetTokenT< TrackingParticleCollection > trackingParticles_
double vz() const
z coordinate of the reference point on track
Definition: TrackBase.h:626
auto vector_transform(std::vector< InputType > const &input, Function predicate) -> std::vector< typename std::remove_cv< typename std::remove_reference< decltype(predicate(input.front()))>::type >::type >
Definition: transform.h:11
const Track & track() const
TrajectoryStateClosestToPoint trajectoryStateClosestToPoint(const GlobalPoint &point) const
std::vector< TrackingVertex > TrackingVertexCollection
const std::vector< edm::EDGetTokenT< reco::TrackToTrackingParticleAssociator > > associators_
edm::EventID id() const
Definition: EventBase.h:59
fixed size matrix
HLT enums.
T get() const
Definition: EventSetup.h:73
const edm::EDGetTokenT< edm::View< reco::Track > > tracks_
Monte Carlo truth information used for tracking validation.
int charge() const
track electric charge
Definition: TrackBase.h:575
def move(src, dest)
Definition: eostools.py:511
#define constexpr
const edm::EDGetTokenT< std::vector< PileupSummaryInfo > > pileupSummaryInfo_