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 dataformat doesn't
3 // need to be modified.
4 
7 
10 
12 
16 
32 
33 #include <random>
34 #include <memory>
35 
37 #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
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>
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 }
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") ) ),
89  pileupSummaryInfo_(consumes<std::vector<PileupSummaryInfo> >( conf.getParameter<edm::InputTag>("pileupSummaryInfo") ) ),
90  associators_( edm::vector_transform( conf.getParameter<std::vector<edm::InputTag> >("associators"), [this](const edm::InputTag& tag){ return this->consumes<reco::TrackToTrackingParticleAssociator>(tag); } ) ),
91  etaMin_( conf.getParameter<double>("etaMin") ),
92  etaMax_( conf.getParameter<double>("etaMax") ),
93  ptMin_( conf.getParameter<double>("ptMin") ),
94  pMin_( conf.getParameter<double>("pMin") ),
95  etaMaxForPtThreshold_( conf.getParameter<double>("etaMaxForPtThreshold") )
96 {
97  // setup resolution models
98  const std::vector<edm::ParameterSet>& resos = conf.getParameterSetVector("resolutionModels");
99  for( const auto& reso : resos ) {
100  const std::string& name = reso.getParameter<std::string>("modelName");
101  ResolutionModel* resomod = ResolutionModelFactory::get()->create(name,reso);
102  resolutions_.emplace_back( resomod );
103 
104  // times and time resolutions for general tracks
105  produces<edm::ValueMap<float> >(tracksName_+name);
106  produces<edm::ValueMap<float> >(tracksName_+name+resolution);
107  }
108 }
109 
111  // get sim track associators
112  std::vector<edm::Handle<reco::TrackToTrackingParticleAssociator> > associators;
113  for( const auto& token : associators_ ) {
114  associators.emplace_back();
115  auto& back = associators.back();
116  evt.getByToken(token,back);
117  }
118 
119  std::vector<float> generalTrackTimes;
120 
121  //get track collections
122  edm::Handle<edm::View<reco::Track> > TrackCollectionH;
123  evt.getByToken(tracks_, TrackCollectionH);
124  const edm::View<reco::Track>& TrackCollection = *TrackCollectionH;
125 
126  //get tracking particle collections
128  evt.getByToken(trackingParticles_, TPCollectionH);
129 
131  evt.getByToken(pileupSummaryInfo_, pileupSummaryH);
132 
133  //transient track builder
135  es.get<TransientTrackRecord>().get("TransientTrackBuilder",theB);
136 
137  // associate the reco tracks / gsf Tracks
138  std::vector<reco::RecoToSimCollection> associatedTracks;
139  for( auto associator : associators ) {
140  associatedTracks.emplace_back(associator->associateRecoToSim(TrackCollectionH, TPCollectionH));
141  }
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() ) break;
179  }
180 
181  if (track_tps != associatedTracks.back().end() && track_tps->val.size() == 1) {
182  reco::TransientTrack tt = theB->build(*tkref);
183  float time = extractTrackVertexTime(*track_tps->val[0].first,tt);
184  generalTrackTimes.push_back(time);
185  }
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!" << std::endl;
191  }
192  }
193  }
194 
195  for( const auto& reso : resolutions_ ) {
196  const std::string& name = reso->name();
197  std::vector<float> times, resos;
198 
199  times.reserve(TrackCollection.size());
200  resos.reserve(TrackCollection.size());
201 
202  for( unsigned i = 0; i < TrackCollection.size(); ++i ) {
203  const reco::Track& tk = TrackCollection[i];
204  const float absEta = std::abs(tk.eta());
205  bool inAcceptance = absEta < etaMax_ && absEta >= etaMin_ && tk.p()>pMin_ && (absEta>etaMaxForPtThreshold_ || tk.pt()>ptMin_);
206  if (inAcceptance) {
207  const float resolution = reso->getTimeResolution(tk);
208  std::normal_distribution<float> gausGeneralTime(generalTrackTimes[i], resolution);
209  times.push_back( gausGeneralTime(rng) );
210  resos.push_back( resolution );
211  }
212  else {
213  times.push_back(0.0f);
214  resos.push_back(-1.);
215  }
216  }
217 
218  writeValueMap( evt, TrackCollectionH, times, tracksName_+name );
219  writeValueMap( evt, TrackCollectionH, resos, tracksName_+name+resolution );
220  }
221 }
222 
225  int pdgid = tp.pdgId();
226  const auto& tvertex = tp.parentVertex();
227  math::XYZTLorentzVectorD result = tvertex->position();
228 
229  // account for secondary vertices...
230  if( tvertex->nSourceTracks() && tvertex->sourceTracks()[0]->pdgId()==pdgid ) {
231  auto pvertex = tvertex->sourceTracks()[0]->parentVertex();
232  result = pvertex->position();
233  while( pvertex->nSourceTracks() && pvertex->sourceTracks()[0]->pdgId()==pdgid ) {
234  pvertex = pvertex->sourceTracks()[0]->parentVertex();
235  result = pvertex->position();
236  }
237  }
238 
239  float time = result.T()*CLHEP::second;
240  //correct for time of flight from track reference position
241  GlobalPoint result_pos(result.x(),result.y(),result.z());
242  const auto &tkstate = tt.trajectoryStateClosestToPoint(result_pos);
243  float tkphi = tkstate.momentum().phi();
244  float tkz = tkstate.position().z();
245  float dphi = reco::deltaPhi(tkphi,tt.track().phi());
246  float dz = tkz - tt.track().vz();
247 
248  float radius = 100.*tt.track().pt()/(0.3*tt.field()->inTesla(GlobalPoint(0,0,0)).z());
249  float pathlengthrphi = tt.track().charge()*dphi*radius;
250 
251  float pathlength = std::sqrt(pathlengthrphi*pathlengthrphi + dz*dz);
252  float p = tt.track().p();
253 
254  float speed = std::sqrt(1./(1.+m_pion/p))*CLHEP::c_light/CLHEP::cm; //speed in cm/ns
255  float dt = pathlength/speed;
256 
257  return time-dt;
258 }
#define LogDebug(id)
RunNumber_t run() const
Definition: EventID.h:39
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:22
double p() const
momentum vector magnitude
Definition: TrackBase.h:648
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
EventNumber_t event() const
Definition: EventID.h:41
float dt
Definition: AMPTWrapper.h:126
const edm::EDGetTokenT< TrackingVertexCollection > trackingVertices_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:137
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:14
std::vector< TrackingParticle > TrackingParticleCollection
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
int pdgId() const
PDG ID.
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
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:678
const MagneticField * field() const
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
LuminosityBlockNumber_t luminosityBlock() const
Definition: EventID.h:40
#define constexpr
std::vector< std::unique_ptr< const ResolutionModel > > resolutions_
void writeValueMap(edm::Event &iEvent, const edm::Handle< HandleType > &handle, const std::vector< ValueType > &values, const std::string &label)
Definition: Utils.h:13
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:230
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:684
T sqrt(T t)
Definition: SSEVec.h:18
double pt() const
track transverse momentum
Definition: TrackBase.h:654
T z() const
Definition: PV3DBase.h:64
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:702
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:60
fixed size matrix
HLT enums.
T get() const
Definition: EventSetup.h:68
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:600
def move(src, dest)
Definition: eostools.py:511
T get(const Candidate &c)
Definition: component.h:55
const edm::EDGetTokenT< std::vector< PileupSummaryInfo > > pileupSummaryInfo_