CMS 3D CMS Logo

TrajSeedMatcher.cc
Go to the documentation of this file.
2 
7 
11 
15 
17 
20 
22  cacheIDMagField_(0),
23  minNrHits_(pset.getParameter<std::vector<unsigned int> >("minNrHits")),
24  minNrHitsValidLayerBins_(pset.getParameter<std::vector<int> >("minNrHitsValidLayerBins"))
25 {
26  useRecoVertex_ = pset.getParameter<bool>("useRecoVertex");
27  navSchoolLabel_ = pset.getParameter<std::string>("navSchool");
28  detLayerGeomLabel_ = pset.getParameter<std::string>("detLayerGeom");
29  const auto cutsPSets=pset.getParameter<std::vector<edm::ParameterSet> >("matchingCuts");
30  for(const auto & cutPSet : cutsPSets){
31  matchingCuts_.push_back(MatchingCuts(cutPSet));
32  }
33 
34  if(minNrHitsValidLayerBins_.size()+1!=minNrHits_.size()){
35  throw cms::Exception("InvalidConfig")<<" minNrHitsValidLayerBins should be 1 less than minNrHits when its "<<minNrHitsValidLayerBins_.size()<<" vs "<<minNrHits_.size();
36  }
37 }
38 
40 {
42  desc.add<bool>("useRecoVertex",false);
43  desc.add<std::string>("navSchool","SimpleNavigationSchool");
44  desc.add<std::string>("detLayerGeom","hltESPGlobalDetLayerGeometry");
45  desc.add<std::vector<int> >("minNrHitsValidLayerBins",{4});
46  desc.add<std::vector<unsigned int> >("minNrHits",{2,3});
47 
48 
50  cutsDesc.add<double>("dPhiMax",0.04);
51  cutsDesc.add<double>("dRZMax",0.09);
52  cutsDesc.add<double>("dRZMaxLowEtThres",20.);
53  cutsDesc.add<std::vector<double> >("dRZMaxLowEtEtaBins",std::vector<double>{1.,1.5});
54  cutsDesc.add<std::vector<double> >("dRZMaxLowEt",std::vector<double>{0.09,0.15,0.09});
55  desc.addVPSet("matchingCuts",cutsDesc);
56  return desc;
57 }
58 
60 {
62  iSetup.get<IdealMagneticFieldRecord>().get(magField_);
63  cacheIDMagField_=iSetup.get<IdealMagneticFieldRecord>().cacheIdentifier();
64  forwardPropagator_=std::make_unique<PropagatorWithMaterial>(alongMomentum,kElectronMass_,&*(magField_));
65  backwardPropagator_=std::make_unique<PropagatorWithMaterial>(oppositeToMomentum,kElectronMass_,&*(magField_));
66  }
69 }
70 
71 
72 std::vector<TrajSeedMatcher::SeedWithInfo>
74  const GlobalPoint & vprim, const float energy)
75 {
77  throw cms::Exception("LogicError") <<__FUNCTION__<<" can not make pixel seeds as event setup has not properly been called";
78  }
79 
80  clearCache();
81 
82  std::vector<SeedWithInfo> matchedSeeds;
83  for(const auto& seed : seeds) {
84  std::vector<HitInfo> matchedHitsNeg = processSeed(seed,candPos,vprim,energy,-1);
85  std::vector<HitInfo> matchedHitsPos = processSeed(seed,candPos,vprim,energy,+1);
86  int nrValidLayersPos = 0;
87  int nrValidLayersNeg = 0;
88  if(matchedHitsNeg.size()>=2){
89  nrValidLayersNeg = getNrValidLayersAlongTraj(matchedHitsNeg[0],
90  matchedHitsNeg[1],
91  candPos,vprim,energy,-1);
92  }
93  if(matchedHitsPos.size()>=2){
94  nrValidLayersPos = getNrValidLayersAlongTraj(matchedHitsPos[0],
95  matchedHitsPos[1],
96  candPos,vprim,energy,+1);
97  }
98 
99  int nrValidLayers = std::max(nrValidLayersNeg,nrValidLayersPos);
100  size_t nrHitsRequired = getNrHitsRequired(nrValidLayers);
101  //so we require the number of hits to exactly match, this is because we currently do not
102  //do any duplicate cleaning for the input seeds
103  //this means is a hit pair with a 3rd hit will appear twice (or however many hits it has)
104  //so if you did >=nrHitsRequired, you would get the same seed multiple times
105  //ideally we should fix this and clean our input seed collection so each seed is only in once
106  //also it should be studied what impact having a 3rd hit has on a GsfTrack
107  //ie will we get a significantly different result seeding with a hit pair
108  //and the same the hit pair with a 3rd hit added
109  //in that case, perhaps it should be >=
110  if(matchedHitsNeg.size()==nrHitsRequired ||
111  matchedHitsPos.size()==nrHitsRequired){
112  matchedSeeds.push_back({seed,matchedHitsPos,matchedHitsNeg,nrValidLayers});
113  }
114 
115 
116  }
117  return matchedSeeds;
118 }
119 
120 //checks if the hits of the seed match within requested selection
121 //matched hits are required to be consecutive, as soon as hit isnt matched,
122 //the function returns, it doesnt allow skipping hits
123 std::vector<TrajSeedMatcher::HitInfo>
125  const GlobalPoint & vprim, const float energy, const int charge )
126 {
127  const float candEta = candPos.eta();
128  const float candEt = energy*std::sin(candPos.theta());
129 
130  FreeTrajectoryState trajStateFromVtx = FTSFromVertexToPointFactory::get(*magField_, candPos, vprim, energy, charge);
132  TrajectoryStateOnSurface initialTrajState(trajStateFromVtx,*bpb(trajStateFromVtx.position(),
133  trajStateFromVtx.momentum()));
134 
135  std::vector<HitInfo> matchedHits;
136  HitInfo firstHit = matchFirstHit(seed,initialTrajState,vprim,*backwardPropagator_);
137  if(passesMatchSel(firstHit,0,candEt,candEta)){
138  matchedHits.push_back(firstHit);
139 
140  //now we can figure out the z vertex
141  double zVertex = useRecoVertex_ ? vprim.z() : getZVtxFromExtrapolation(vprim,firstHit.pos(),candPos);
142  GlobalPoint vertex(vprim.x(),vprim.y(),zVertex);
143 
144  FreeTrajectoryState firstHitFreeTraj = FTSFromVertexToPointFactory::get(*magField_, firstHit.pos(),
145  vertex, energy, charge) ;
146 
147  GlobalPoint prevHitPos = firstHit.pos();
148  for(size_t hitNr=1;hitNr<matchingCuts_.size() && hitNr<seed.nHits();hitNr++){
149  HitInfo hit = match2ndToNthHit(seed,firstHitFreeTraj,hitNr,prevHitPos,vertex,*forwardPropagator_);
150  if(passesMatchSel(hit,hitNr,candEt,candEta)){
151  matchedHits.push_back(hit);
152  prevHitPos = hit.pos();
153  }else break;
154  }
155  }
156  return matchedHits;
157 }
158 
159 // compute the z vertex from the candidate position and the found pixel hit
161  const GlobalPoint& candPos)
162 {
163  auto sq = [](float x){return x*x;};
164  auto calRDiff = [sq](const GlobalPoint& p1,const GlobalPoint& p2){
165  return std::sqrt(sq(p2.x()-p1.x()) + sq(p2.y()-p1.y()));
166  };
167  const double r1Diff = calRDiff(primeVtxPos,hitPos);
168  const double r2Diff = calRDiff(hitPos,candPos);
169  return hitPos.z() - r1Diff*(candPos.z()-hitPos.z())/r2Diff;
170 }
171 
172 bool TrajSeedMatcher::passTrajPreSel(const GlobalPoint& hitPos,const GlobalPoint& candPos)const
173 {
174  float dt = hitPos.x()*candPos.x()+hitPos.y()*candPos.y();
175  if (dt<0) return false;
176  if (dt<kPhiCut_*(candPos.perp()*hitPos.perp())) return false;
177  return true;
178 }
179 
181 {
182  auto& trajStateFromVtxCache = initialState.charge()==1 ? trajStateFromVtxPosChargeCache_ :
184 
185  auto key = hit.det()->gdetIndex();
186  auto res = trajStateFromVtxCache.find(key);
187  if(res!=trajStateFromVtxCache.end()) return res->second;
188  else{ //doesnt exist, need to make it
189  //FIXME: check for efficiency
190  auto val = trajStateFromVtxCache.emplace(key,propagator.propagate(initialState,hit.det()->surface()));
191  return val.first->second;
192  }
193 }
194 
196 {
197 
198  auto& trajStateFromPointCache = initialState.charge()==1 ? trajStateFromPointPosChargeCache_ :
200 
201  auto key = std::make_pair(hit.det()->gdetIndex(),point);
202  auto res = trajStateFromPointCache.find(key);
203  if(res!=trajStateFromPointCache.end()) return res->second;
204  else{ //doesnt exist, need to make it
205  //FIXME: check for efficiency
206  auto val = trajStateFromPointCache.emplace(key,propagator.propagate(initialState,hit.det()->surface()));
207  return val.first->second;
208  }
209 }
210 
212 {
213  const TrajectorySeed::range& hits = seed.recHits();
214  auto hitIt = hits.first;
215 
216  if(hitIt->isValid()){
217  const TrajectoryStateOnSurface& trajStateFromVtx = getTrajStateFromVtx(*hitIt,initialState,propagator);
218  if(trajStateFromVtx.isValid()) return HitInfo(vtxPos,trajStateFromVtx,*hitIt);
219  }
220  return HitInfo();
221 }
222 
224  const FreeTrajectoryState& initialState,
225  const size_t hitNr,
226  const GlobalPoint& prevHitPos,
227  const GlobalPoint& vtxPos,
229 {
230  const TrajectorySeed::range& hits = seed.recHits();
231  auto hitIt = hits.first+hitNr;
232 
233  if(hitIt->isValid()){
234  const TrajectoryStateOnSurface& trajState = getTrajStateFromPoint(*hitIt,initialState,prevHitPos,propagator);
235  if(trajState.isValid()){
236  return HitInfo(vtxPos,trajState,*hitIt);
237  }
238  }
239  return HitInfo();
240 
241 }
242 
244 {
249 }
250 
251 bool TrajSeedMatcher::passesMatchSel(const TrajSeedMatcher::HitInfo& hit,const size_t hitNr,float scEt,float scEta)const
252 {
253  if(hitNr<matchingCuts_.size()){
254  return matchingCuts_[hitNr](hit,scEt,scEta);
255  }else{
256  throw cms::Exception("LogicError") <<" Error, attempting to apply selection to hit "<<hitNr<<" but only cuts for "<<matchingCuts_.size()<<" defined";
257  }
258 
259 }
260 
262  const GlobalPoint& candPos,
263  const GlobalPoint & vprim,
264  const float energy, const int charge)
265 {
266  double zVertex = useRecoVertex_ ? vprim.z() : getZVtxFromExtrapolation(vprim,hit1.pos(),candPos);
267  GlobalPoint vertex(vprim.x(),vprim.y(),zVertex);
268 
270  vertex, energy, charge);
271  const TrajectoryStateOnSurface& secondHitTraj = getTrajStateFromPoint(*hit2.hit(),firstHitFreeTraj,hit1.pos(),*forwardPropagator_);
272  return getNrValidLayersAlongTraj(hit2.hit()->geographicalId(),secondHitTraj);
273 }
274 
276 {
277 
278  const DetLayer* detLayer = detLayerGeom_->idToLayer(hitId);
279  if(detLayer==nullptr) return 0;
280 
281  const FreeTrajectoryState& hitFreeState = *hitTrajState.freeState();
282  const std::vector<const DetLayer*> inLayers = navSchool_->compatibleLayers(*detLayer,hitFreeState,oppositeToMomentum);
283  const std::vector<const DetLayer*> outLayers = navSchool_->compatibleLayers(*detLayer,hitFreeState,alongMomentum);
284 
285  int nrValidLayers=1; //because our current hit is also valid and wont be included in the count otherwise
286  int nrPixInLayers=0;
287  int nrPixOutLayers=0;
288  for(auto layer : inLayers){
289  if(GeomDetEnumerators::isTrackerPixel(layer->subDetector())){
290  nrPixInLayers++;
291  if(layerHasValidHits(*layer,hitTrajState,*backwardPropagator_)) nrValidLayers++;
292  }
293  }
294  for(auto layer : outLayers){
295  if(GeomDetEnumerators::isTrackerPixel(layer->subDetector())){
296  nrPixOutLayers++;
297  if(layerHasValidHits(*layer,hitTrajState,*forwardPropagator_)) nrValidLayers++;
298  }
299  }
300  return nrValidLayers;
301 }
302 
304  const Propagator& propToLayerFromState)const
305 {
306  //FIXME: do not hardcode with werid magic numbers stolen from ancient tracking code
307  //its taken from https://cmssdt.cern.ch/dxr/CMSSW/source/RecoTracker/TrackProducer/interface/TrackProducerBase.icc#165
308  //which inspires this code
309  Chi2MeasurementEstimator estimator(30.,-3.0,0.5,2.0,0.5,1.e12); // same as defauts....
310 
311  const std::vector<GeometricSearchDet::DetWithState>& detWithState = layer.compatibleDets(hitSurState,propToLayerFromState,estimator);
312  if(detWithState.empty()) return false;
313  else{
314  DetId id = detWithState.front().first->geographicalId();
316  if(measDet.isActive()) return true;
317  else return false;
318  }
319 }
320 
321 
322 size_t TrajSeedMatcher::getNrHitsRequired(const int nrValidLayers)const
323 {
324  for(size_t binNr=0;binNr<minNrHitsValidLayerBins_.size();binNr++){
325  if(nrValidLayers<minNrHitsValidLayerBins_[binNr]) return minNrHits_[binNr];
326  }
327  return minNrHits_.back();
328 
329 }
330 
332  const TrajectoryStateOnSurface& trajState,
333  const TrackingRecHit& hit):
334  detId_(hit.geographicalId()),
335  pos_(hit.globalPosition()),
336  hit_(&hit)
337 {
338  EleRelPointPair pointPair(pos_,trajState.globalParameters().position(),vtxPos);
339  dRZ_ = detId_.subdetId()==PixelSubdetector::PixelBarrel ? pointPair.dZ() : pointPair.dPerp();
340  dPhi_ = pointPair.dPhi();
341 }
342 
343 
346  const std::vector<HitInfo>& posCharge,
347  const std::vector<HitInfo>& negCharge,
348  int nrValidLayers):
349  seed_(seed),nrValidLayers_(nrValidLayers)
350 {
351  size_t nrHitsMax = std::max(posCharge.size(),negCharge.size());
352  for(size_t hitNr=0;hitNr<nrHitsMax;hitNr++){
353  DetId detIdPos = hitNr<posCharge.size() ? posCharge[hitNr].detId() : DetId(0);
354  float dRZPos = hitNr<posCharge.size() ? posCharge[hitNr].dRZ() : std::numeric_limits<float>::max();
355  float dPhiPos = hitNr<posCharge.size() ? posCharge[hitNr].dPhi() : std::numeric_limits<float>::max();
356 
357  DetId detIdNeg = hitNr<negCharge.size() ? negCharge[hitNr].detId() : DetId(0);
358  float dRZNeg = hitNr<negCharge.size() ? negCharge[hitNr].dRZ() : std::numeric_limits<float>::max();
359  float dPhiNeg = hitNr<negCharge.size() ? negCharge[hitNr].dPhi() : std::numeric_limits<float>::max();
360 
361  if(detIdPos!=detIdNeg && (detIdPos.rawId()!=0 && detIdNeg.rawId()!=0)){
362  cms::Exception("LogicError")<<" error in "<<__FILE__<<", "<<__LINE__<<" hits to be combined have different detIDs, this should not be possible and nothing good will come of it";
363  }
364  DetId detId = detIdPos.rawId()!=0 ? detIdPos : detIdNeg;
365  matchInfo_.push_back(MatchInfo(detId,dRZPos,dRZNeg,dPhiPos,dPhiNeg));
366  }
367 }
368 
370  dPhiMax_(pset.getParameter<double>("dPhiMax")),
371  dRZMax_(pset.getParameter<double>("dRZMax")),
372  dRZMaxLowEtThres_(pset.getParameter<double>("dRZMaxLowEtThres")),
373  dRZMaxLowEtEtaBins_(pset.getParameter<std::vector<double> >("dRZMaxLowEtEtaBins")),
374  dRZMaxLowEt_(pset.getParameter<std::vector<double> >("dRZMaxLowEt"))
375 {
376  if(dRZMaxLowEtEtaBins_.size()+1!=dRZMaxLowEt_.size()){
377  throw cms::Exception("InvalidConfig")<<" dRZMaxLowEtEtaBins should be 1 less than dRZMaxLowEt when its "<<dRZMaxLowEtEtaBins_.size()<<" vs "<<dRZMaxLowEt_.size();
378  }
379 }
380 
381 bool TrajSeedMatcher::MatchingCuts::operator()(const TrajSeedMatcher::HitInfo& hit,const float scEt,const float scEta)const
382 {
383  if(dPhiMax_>=0 && std::abs(hit.dPhi()) > dPhiMax_) return false;
384 
385  const float dRZMax = getDRZCutValue(scEt,scEta);
386  if(dRZMax_>=0 && std::abs(hit.dRZ()) > dRZMax) return false;
387 
388  return true;
389 }
390 
391 float TrajSeedMatcher::MatchingCuts::getDRZCutValue(const float scEt,const float scEta)const
392 {
393  if(scEt>=dRZMaxLowEtThres_) return dRZMax_;
394  else{
395  const float absEta = std::abs(scEta);
396  for(size_t etaNr=0;etaNr<dRZMaxLowEtEtaBins_.size();etaNr++){
397  if(absEta<dRZMaxLowEtEtaBins_[etaNr]) return dRZMaxLowEt_[etaNr];
398  }
399  return dRZMaxLowEt_.back();
400  }
401 }
T getParameter(std::string const &) const
unsigned long long cacheIdentifier() const
std::unordered_map< std::pair< int, GlobalPoint >, TrajectoryStateOnSurface > trajStateFromPointNegChargeCache_
MeasurementDetWithData idToDet(const DetId &id) const
Previous MeasurementDetSystem interface.
void doEventSetup(const edm::EventSetup &iSetup)
float dt
Definition: AMPTWrapper.h:126
std::vector< TrajSeedMatcher::SeedWithInfo > compatibleSeeds(const TrajectorySeedCollection &seeds, const GlobalPoint &candPos, const GlobalPoint &vprim, const float energy)
std::unordered_map< int, TrajectoryStateOnSurface > trajStateFromVtxNegChargeCache_
static FreeTrajectoryState get(MagneticField const &magField, GlobalPoint const &xmeas, GlobalPoint const &xvert, float momentum, TrackCharge charge)
ParameterDescriptionBase * addVPSet(U const &iLabel, ParameterSetDescription const &validator, std::vector< ParameterSet > const &defaults)
T perp() const
Definition: PV3DBase.h:72
DetId detId(size_t hitNr) const
const TrajectoryStateOnSurface & getTrajStateFromVtx(const TrackingRecHit &hit, const TrajectoryStateOnSurface &initialState, const PropagatorWithMaterial &propagator)
int gdetIndex() const
Definition: GeomDet.h:103
std::unordered_map< int, TrajectoryStateOnSurface > trajStateFromVtxPosChargeCache_
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
edm::ESHandle< DetLayerGeometry > detLayerGeom_
float dRZPos(size_t hitNr) const
bool passTrajPreSel(const GlobalPoint &hitPos, const GlobalPoint &candPos) const
std::unique_ptr< PropagatorWithMaterial > forwardPropagator_
T y() const
Definition: PV3DBase.h:63
const std::vector< int > minNrHitsValidLayerBins_
float getDRZCutValue(const float scEt, const float scEta) const
TrajSeedMatcher::HitInfo matchFirstHit(const TrajectorySeed &seed, const TrajectoryStateOnSurface &trajState, const GlobalPoint &vtxPos, const PropagatorWithMaterial &propagator)
TrackCharge charge() const
static float getZVtxFromExtrapolation(const GlobalPoint &primeVtxPos, const GlobalPoint &hitPos, const GlobalPoint &candPos)
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:42
SeedWithInfo(const TrajectorySeed &seed, const std::vector< HitInfo > &posCharge, const std::vector< HitInfo > &negCharge, int nrValidLayers)
virtual std::vector< DetWithState > compatibleDets(const TrajectoryStateOnSurface &startingState, const Propagator &prop, const MeasurementEstimator &est) const
Definition: Electron.h:4
MatchingCuts(const edm::ParameterSet &pset)
const TrajectoryStateOnSurface & getTrajStateFromPoint(const TrackingRecHit &hit, const FreeTrajectoryState &initialState, const GlobalPoint &point, const PropagatorWithMaterial &propagator)
Geom::Theta< T > theta() const
Definition: PV3DBase.h:75
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
bool operator()(const HitInfo &hit, const float scEt, const float scEta) const
edm::ESHandle< NavigationSchool > navSchool_
unsigned long long cacheIDMagField_
std::unordered_map< std::pair< int, GlobalPoint >, TrajectoryStateOnSurface > trajStateFromPointPosChargeCache_
static edm::ParameterSetDescription makePSetDescription()
std::vector< TrajectorySeed > TrajectorySeedCollection
edm::ESHandle< MagneticField > magField_
const GeomDet * det() const
std::vector< MatchingCuts > matchingCuts_
T sqrt(T t)
Definition: SSEVec.h:18
TrajSeedMatcher::HitInfo match2ndToNthHit(const TrajectorySeed &seed, const FreeTrajectoryState &trajState, const size_t hitNr, const GlobalPoint &prevHitPos, const GlobalPoint &vtxPos, const PropagatorWithMaterial &propagator)
int getNrValidLayersAlongTraj(const HitInfo &hit1, const HitInfo &hit2, const GlobalPoint &candPos, const GlobalPoint &vprim, const float energy, const int charge)
std::vector< MatchInfo > matchInfo_
FreeTrajectoryState const * freeState(bool withErrors=true) const
T z() const
Definition: PV3DBase.h:64
std::vector< const DetLayer * > compatibleLayers(const DetLayer &detLayer, Args &&...args) const
Returns all layers compatible.
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::pair< const_iterator, const_iterator > range
float dPhiPos(size_t hitNr) const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
double p2[4]
Definition: TauolaWrapper.h:90
const std::vector< double > dRZMaxLowEtEtaBins_
size_t getNrHitsRequired(const int nrValidLayers) const
const GlobalPoint & pos() const
std::string navSchoolLabel_
Definition: DetId.h:18
const GlobalTrajectoryParameters & globalParameters() const
const T & get() const
Definition: EventSetup.h:56
edm::Handle< MeasurementTrackerEvent > measTkEvt_
static float kElectronMass_
bool passesMatchSel(const HitInfo &hit, const size_t hitNr, const float scEt, const float scEta) const
range recHits() const
TrajectoryStateOnSurface propagate(STA const &state, SUR const &surface) const
Definition: Propagator.h:53
bool isTrackerPixel(const GeomDetEnumerators::SubDetector m)
const TrackingRecHit * hit() const
T eta() const
Definition: PV3DBase.h:76
unsigned int nHits() const
double p1[4]
Definition: TauolaWrapper.h:89
const std::vector< double > dRZMaxLowEt_
TrajSeedMatcher(const edm::ParameterSet &pset)
std::vector< HitInfo > processSeed(const TrajectorySeed &seed, const GlobalPoint &candPos, const GlobalPoint &vprim, const float energy, const int charge)
std::string detLayerGeomLabel_
float dRZNeg(size_t hitNr) const
DetId geographicalId() const
bool isValid() const
Definition: ESHandle.h:47
virtual const DetLayer * idToLayer(const DetId &detId) const
T x() const
Definition: PV3DBase.h:62
std::unique_ptr< PropagatorWithMaterial > backwardPropagator_
bool layerHasValidHits(const DetLayer &layer, const TrajectoryStateOnSurface &hitSurState, const Propagator &propToLayerFromState) const
static float kPhiCut_
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
float dPhiNeg(size_t hitNr) const
const std::vector< unsigned int > minNrHits_