CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MultiTrackSelector.cc
Go to the documentation of this file.
2 
5 #include <Math/DistFunc.h>
6 #include "TMath.h"
7 
9 
10 MultiTrackSelector::MultiTrackSelector( const edm::ParameterSet & cfg ) :
11  src_( cfg.getParameter<edm::InputTag>( "src" ) ),
12  beamspot_( cfg.getParameter<edm::InputTag>( "beamspot" ) ),
13  useVertices_( cfg.getParameter<bool>( "useVertices" ) ),
14  useVtxError_( cfg.getParameter<bool>( "useVtxError" ) ),
15  vertices_( useVertices_ ? cfg.getParameter<edm::InputTag>( "vertices" ) : edm::InputTag("NONE"))
16  // now get the pset for each selector
17 {
18 
19  std::vector<edm::ParameterSet> trkSelectors( cfg.getParameter<std::vector< edm::ParameterSet> >("trackSelectors") );
20  qualityToSet_.reserve(trkSelectors.size());
21  vtxNumber_.reserve(trkSelectors.size());
22  vertexCut_.reserve(trkSelectors.size());
23  res_par_.reserve(trkSelectors.size());
24  chi2n_par_.reserve(trkSelectors.size());
25  chi2n_no1Dmod_par_.reserve(trkSelectors.size());
26  d0_par1_.reserve(trkSelectors.size());
27  dz_par1_.reserve(trkSelectors.size());
28  d0_par2_.reserve(trkSelectors.size());
29  dz_par2_.reserve(trkSelectors.size());
30  applyAdaptedPVCuts_.reserve(trkSelectors.size());
31  max_d0_.reserve(trkSelectors.size());
32  max_z0_.reserve(trkSelectors.size());
33  nSigmaZ_.reserve(trkSelectors.size());
34  min_layers_.reserve(trkSelectors.size());
35  min_3Dlayers_.reserve(trkSelectors.size());
36  max_lostLayers_.reserve(trkSelectors.size());
37  min_hits_bypass_.reserve(trkSelectors.size());
38  applyAbsCutsIfNoPV_.reserve(trkSelectors.size());
39  max_d0NoPV_.reserve(trkSelectors.size());
40  max_z0NoPV_.reserve(trkSelectors.size());
41  preFilter_.reserve(trkSelectors.size());
42  max_relpterr_.reserve(trkSelectors.size());
43  min_nhits_.reserve(trkSelectors.size());
44 
45  for ( unsigned int i=0; i<trkSelectors.size(); i++) {
46 
48  // parameters for vertex selection
49  vtxNumber_.push_back( useVertices_ ? trkSelectors[i].getParameter<int32_t>("vtxNumber") : 0 );
50  vertexCut_.push_back( useVertices_ ? trkSelectors[i].getParameter<std::string>("vertexCut") : 0);
51  // parameters for adapted optimal cuts on chi2 and primary vertex compatibility
52  res_par_.push_back(trkSelectors[i].getParameter< std::vector<double> >("res_par") );
53  chi2n_par_.push_back( trkSelectors[i].getParameter<double>("chi2n_par") );
54  chi2n_no1Dmod_par_.push_back( trkSelectors[i].getParameter<double>("chi2n_no1Dmod_par") );
55  d0_par1_.push_back(trkSelectors[i].getParameter< std::vector<double> >("d0_par1"));
56  dz_par1_.push_back(trkSelectors[i].getParameter< std::vector<double> >("dz_par1"));
57  d0_par2_.push_back(trkSelectors[i].getParameter< std::vector<double> >("d0_par2"));
58  dz_par2_.push_back(trkSelectors[i].getParameter< std::vector<double> >("dz_par2"));
59  // Boolean indicating if adapted primary vertex compatibility cuts are to be applied.
60  applyAdaptedPVCuts_.push_back(trkSelectors[i].getParameter<bool>("applyAdaptedPVCuts"));
61  // Impact parameter absolute cuts.
62  max_d0_.push_back(trkSelectors[i].getParameter<double>("max_d0"));
63  max_z0_.push_back(trkSelectors[i].getParameter<double>("max_z0"));
64  nSigmaZ_.push_back(trkSelectors[i].getParameter<double>("nSigmaZ"));
65  // Cuts on numbers of layers with hits/3D hits/lost hits.
66  min_layers_.push_back(trkSelectors[i].getParameter<uint32_t>("minNumberLayers") );
67  min_3Dlayers_.push_back(trkSelectors[i].getParameter<uint32_t>("minNumber3DLayers") );
68  max_lostLayers_.push_back(trkSelectors[i].getParameter<uint32_t>("maxNumberLostLayers"));
69  min_hits_bypass_.push_back(trkSelectors[i].getParameter<uint32_t>("minHitsToBypassChecks"));
70  // Flag to apply absolute cuts if no PV passes the selection
71  applyAbsCutsIfNoPV_.push_back(trkSelectors[i].getParameter<bool>("applyAbsCutsIfNoPV"));
72  keepAllTracks_.push_back( trkSelectors[i].getParameter<bool>("keepAllTracks"));
73  max_relpterr_.push_back(trkSelectors[i].getParameter<double>("max_relpterr"));
74  min_nhits_.push_back(trkSelectors[i].getParameter<uint32_t>("min_nhits"));
75 
76 
77  setQualityBit_.push_back( false );
78  std::string qualityStr = trkSelectors[i].getParameter<std::string>("qualityBit");
79  if (qualityStr != "") {
80  setQualityBit_[i] = true;
81  qualityToSet_[i] = TrackBase::qualityByName(trkSelectors[i].getParameter<std::string>("qualityBit"));
82  }
83 
84  if (setQualityBit_[i] && (qualityToSet_[i] == TrackBase::undefQuality)) throw cms::Exception("Configuration") <<
85  "You can't set the quality bit " << trkSelectors[i].getParameter<std::string>("qualityBit") << " as it is 'undefQuality' or unknown.\n";
86 
87  if (applyAbsCutsIfNoPV_[i]) {
88  max_d0NoPV_.push_back(trkSelectors[i].getParameter<double>("max_d0NoPV"));
89  max_z0NoPV_.push_back(trkSelectors[i].getParameter<double>("max_z0NoPV"));
90  }
91  else{//dummy values
92  max_d0NoPV_.push_back(0.);
93  max_z0NoPV_.push_back(0.);
94  }
95 
96  name_.push_back( trkSelectors[i].getParameter<std::string>("name") );
97 
98  preFilter_[i]=trkSelectors.size(); // no prefilter
99 
100  std::string pfName=trkSelectors[i].getParameter<std::string>("preFilterName");
101  if (pfName!="") {
102  bool foundPF=false;
103  for ( unsigned int j=0; j<i; j++)
104  if (name_[j]==pfName ) {
105  foundPF=true;
106  preFilter_[i]=j;
107  }
108  if ( !foundPF)
109  throw cms::Exception("Configuration") << "Invalid prefilter name in MultiTrackSelector "
110  << trkSelectors[i].getParameter<std::string>("preFilterName");
111 
112  }
113 
114  // produces<std::vector<int> >(name_[i]).setBranchAlias( name_[i] + "TrackQuals");
115  produces<edm::ValueMap<int> >(name_[i]).setBranchAlias( name_[i] + "TrackQuals");
116  }
117 }
118 
120 }
121 
123 {
124  using namespace std;
125  using namespace edm;
126  using namespace reco;
127 
128  // Get tracks
129  Handle<TrackCollection> hSrcTrack;
130  evt.getByLabel( src_, hSrcTrack );
131 
132  // looking for the beam spot
134  evt.getByLabel(beamspot_, hBsp);
135  reco::BeamSpot vertexBeamSpot;
136  vertexBeamSpot = *hBsp;
137 
138  // Select good primary vertices for use in subsequent track selection
140  if (useVertices_) evt.getByLabel(vertices_, hVtx);
141 
142  unsigned int trkSize=hSrcTrack->size();
143  std::vector<int> selTracksSave( qualityToSet_.size()*trkSize,0);
144 
145  //loop over all of the selectors...
146  for (unsigned int i=0; i<qualityToSet_.size(); i++) {
147  std::vector<int> selTracks(trkSize,0);
148  auto_ptr<edm::ValueMap<int> > selTracksValueMap = auto_ptr<edm::ValueMap<int> >(new edm::ValueMap<int>);
149  edm::ValueMap<int>::Filler filler(*selTracksValueMap);
150 
151  std::vector<Point> points;
152  std::vector<double> vterr;
153  std::vector<double> vzerr;
154  if (useVertices_) selectVertices(i,*hVtx, points, vterr, vzerr);
155 
156  // Loop over tracks
157  size_t current = 0;
158  for (TrackCollection::const_iterator it = hSrcTrack->begin(), ed = hSrcTrack->end(); it != ed; ++it, ++current) {
159  const Track & trk = * it;
160  // Check if this track passes cuts
161 
162  LogTrace("TrackSelection") << "ready to check track with pt="<< trk.pt() ;
163 
164  //already removed
165  bool ok=true;
166  if (preFilter_[i]<i && selTracksSave[preFilter_[i]*trkSize+current] < 0) {
167  selTracks.at(current)=-1;
168  ok=false;
169  if ( !keepAllTracks_[i])
170  continue;
171  }
172  else {
173  ok = select(i,vertexBeamSpot, trk, points, vterr, vzerr);
174  if (!ok) {
175  LogTrace("TrackSelection") << "track with pt="<< trk.pt() << " NOT selected";
176  if (!keepAllTracks_[i]) {
177  selTracks.at(current)=-1;
178  continue;
179  }
180  }
181  else
182  LogTrace("TrackSelection") << "track with pt="<< trk.pt() << " selected";
183  }
184 
185  if (preFilter_[i]<i ) {
186  selTracks.at(current)=selTracksSave[preFilter_[i]*trkSize+current];
187  }
188  else {
189  selTracks.at(current)=trk.qualityMask();
190  }
191  if ( ok && setQualityBit_[i]) {
192  selTracks.at(current)= (selTracks.at(current) | (1<<qualityToSet_[i]));
193  if (!points.empty()) {
195  selTracks.at(current)=(selTracks.at(current) | (1<<TrackBase::looseSetWithPV));
196  }
197  else if (qualityToSet_[i]==TrackBase::highPurity) {
198  selTracks.at(current)=(selTracks.at(current) | (1<<TrackBase::highPuritySetWithPV));
199  }
200  }
201  }
202  }
203  for ( unsigned int j=0; j< trkSize; j++ ) selTracksSave[j+i*trkSize]=selTracks.at(j);
204  filler.insert(hSrcTrack, selTracks.begin(),selTracks.end());
205  filler.fill();
206 
207  // evt.put(selTracks,name_[i]);
208  evt.put(selTracksValueMap,name_[i]);
209  }
210 }
211 
212 
213  bool MultiTrackSelector::select(unsigned int tsNum,
214  const reco::BeamSpot &vertexBeamSpot,
215  const reco::Track &tk,
216  const std::vector<Point> &points,
217  std::vector<double> &vterr,
218  std::vector<double> &vzerr) {
219  // Decide if the given track passes selection cuts.
220 
221  using namespace std;
222 
223  if(tk.found()>=min_hits_bypass_[tsNum]) return true;
224  if ( tk.ndof() < 1E-5 ) return false;
225 
226  // Cuts on numbers of layers with hits/3D hits/lost hits.
227  uint32_t nlayers = tk.hitPattern().trackerLayersWithMeasurement();
228  uint32_t nlayers3D = tk.hitPattern().pixelLayersWithMeasurement() +
230  uint32_t nlayersLost = tk.hitPattern().trackerLayersWithoutMeasurement();
231  LogDebug("TrackSelection") << "cuts on nlayers: " << nlayers << " " << nlayers3D << " " << nlayersLost << " vs "
232  << min_layers_[tsNum] << " " << min_3Dlayers_[tsNum] << " " << max_lostLayers_[tsNum];
233  if (nlayers < min_layers_[tsNum]) return false;
234  if (nlayers3D < min_3Dlayers_[tsNum]) return false;
235  if (nlayersLost > max_lostLayers_[tsNum]) return false;
236  LogTrace("TrackSelection") << "cuts on nlayers passed";
237 
238  double chi2n = tk.normalizedChi2();
239  double chi2n_no1Dmod = chi2n;
240 
241  int count1dhits = 0;
242  for (trackingRecHit_iterator ith = tk.recHitsBegin(), edh = tk.recHitsEnd(); ith != edh; ++ith) {
243  const TrackingRecHit * hit = ith->get();
244  if (hit->isValid()) {
245  if (typeid(*hit) == typeid(SiStripRecHit1D)) ++count1dhits;
246  }
247  }
248  if (count1dhits > 0) {
249  double chi2 = tk.chi2();
250  double ndof = tk.ndof();
251  chi2n = (chi2+count1dhits)/double(ndof+count1dhits);
252  }
253  // For each 1D rechit, the chi^2 and ndof is increased by one. This is a way of retaining approximately
254  // the same normalized chi^2 distribution as with 2D rechits.
255  if (chi2n > chi2n_par_[tsNum]*nlayers) return false;
256 
257  if (chi2n_no1Dmod > chi2n_no1Dmod_par_[tsNum]*nlayers) return false;
258 
259  // Get track parameters
260  double pt = tk.pt(), eta = tk.eta();
261 
262  //cuts on relative error on pt and number of valid hits
263  double relpterr = tk.ptError()/max(pt,1e-9);
264  uint32_t nhits = tk.numberOfValidHits();
265  if(relpterr > max_relpterr_[tsNum]) return false;
266  if(nhits < min_nhits_[tsNum]) return false;
267 
268 
269  //other track parameters
270  double d0 = -tk.dxy(vertexBeamSpot.position()), d0E = tk.d0Error(),
271  dz = tk.dz(vertexBeamSpot.position()), dzE = tk.dzError();
272 
273  // parametrized d0 resolution for the track pt
274  double nomd0E = sqrt(res_par_[tsNum][0]*res_par_[tsNum][0]+(res_par_[tsNum][1]/max(pt,1e-9))*(res_par_[tsNum][1]/max(pt,1e-9)));
275  // parametrized z0 resolution for the track pt and eta
276  double nomdzE = nomd0E*(std::cosh(eta));
277 
278  double dzCut = min( pow(dz_par1_[tsNum][0]*nlayers,dz_par1_[tsNum][1])*nomdzE,
279  pow(dz_par2_[tsNum][0]*nlayers,dz_par2_[tsNum][1])*dzE );
280  double d0Cut = min( pow(d0_par1_[tsNum][0]*nlayers,d0_par1_[tsNum][1])*nomd0E,
281  pow(d0_par2_[tsNum][0]*nlayers,d0_par2_[tsNum][1])*d0E );
282 
283 
284  // ---- PrimaryVertex compatibility cut
285  bool primaryVertexZCompatibility(false);
286  bool primaryVertexD0Compatibility(false);
287 
288  if (points.empty()) { //If not primaryVertices are reconstructed, check just the compatibility with the BS
289  //z0 within (n sigma + dzCut) of the beam spot z, if no good vertex is found
290  if ( abs(dz) < hypot(vertexBeamSpot.sigmaZ()*nSigmaZ_[tsNum],dzCut) ) primaryVertexZCompatibility = true;
291  // d0 compatibility with beam line
292  if (abs(d0) < d0Cut) primaryVertexD0Compatibility = true;
293  }
294 
295  int iv=0;
296  for (std::vector<Point>::const_iterator point = points.begin(), end = points.end(); point != end; ++point) {
297  LogTrace("TrackSelection") << "Test track w.r.t. vertex with z position " << point->z();
298  if(primaryVertexZCompatibility && primaryVertexD0Compatibility) break;
299  double dzPV = tk.dz(*point); //re-evaluate the dz with respect to the vertex position
300  double d0PV = tk.dxy(*point); //re-evaluate the dxy with respect to the vertex position
301  if(useVtxError_){
302  double dzErrPV = sqrt(dzE*dzE+vzerr[iv]*vzerr[iv]); // include vertex error in z
303  double d0ErrPV = sqrt(d0E*d0E+vterr[iv]*vterr[iv]); // include vertex error in xy
304  iv++;
305  if (abs(dzPV) < dz_par1_[tsNum][0]*pow(nlayers,dz_par1_[tsNum][1])*nomdzE &&
306  abs(dzPV) < dz_par2_[tsNum][0]*pow(nlayers,dz_par2_[tsNum][1])*dzErrPV &&
307  abs(dzPV) < max_z0_[tsNum]) primaryVertexZCompatibility = true;
308  if (abs(d0PV) < d0_par1_[tsNum][0]*pow(nlayers,d0_par1_[tsNum][1])*nomd0E &&
309  abs(d0PV) < d0_par2_[tsNum][0]*pow(nlayers,d0_par2_[tsNum][1])*d0ErrPV &&
310  abs(d0PV) < max_d0_[tsNum]) primaryVertexD0Compatibility = true;
311  }else{
312  if (abs(dzPV) < dzCut) primaryVertexZCompatibility = true;
313  if (abs(d0PV) < d0Cut) primaryVertexD0Compatibility = true;
314  }
315  LogTrace("TrackSelection") << "distances " << dzPV << " " << d0PV << " vs " << dzCut << " " << d0Cut;
316  }
317 
318  if (points.empty() && applyAbsCutsIfNoPV_[tsNum]) {
319  if ( abs(dz) > max_z0NoPV_[tsNum] || abs(d0) > max_d0NoPV_[tsNum]) return false;
320  } else {
321  // Absolute cuts on all tracks impact parameters with respect to beam-spot.
322  // If BS is not compatible, verify if at least the reco-vertex is compatible (useful for incorrect BS settings)
323  if (abs(d0) > max_d0_[tsNum] && !primaryVertexD0Compatibility) return false;
324  LogTrace("TrackSelection") << "absolute cuts on d0 passed";
325  if (abs(dz) > max_z0_[tsNum] && !primaryVertexZCompatibility) return false;
326  LogTrace("TrackSelection") << "absolute cuts on dz passed";
327  }
328 
329  LogTrace("TrackSelection") << "cuts on PV: apply adapted PV cuts? " << applyAdaptedPVCuts_[tsNum]
330  << " d0 compatibility? " << primaryVertexD0Compatibility
331  << " z compatibility? " << primaryVertexZCompatibility ;
332 
333  if (applyAdaptedPVCuts_[tsNum]) {
334  return (primaryVertexD0Compatibility && primaryVertexZCompatibility);
335  } else {
336  return true;
337  }
338 
339 }
340 
341  void MultiTrackSelector::selectVertices(unsigned int tsNum,
342  const reco::VertexCollection &vtxs,
343  std::vector<Point> &points,
344  std::vector<double> &vterr,
345  std::vector<double> &vzerr) {
346  // Select good primary vertices
347  using namespace reco;
348  int32_t toTake = vtxNumber_[tsNum];
349  for (VertexCollection::const_iterator it = vtxs.begin(), ed = vtxs.end(); it != ed; ++it) {
350 
351  LogDebug("SelectVertex") << " select vertex with z position " << it->z() << " "
352  << it->chi2() << " " << it->ndof() << " " << TMath::Prob(it->chi2(), static_cast<int32_t>(it->ndof()));
353  Vertex vtx = *it;
354  bool pass = vertexCut_[tsNum]( vtx );
355  if( pass ) {
356  points.push_back(it->position());
357  vterr.push_back(sqrt(it->yError()*it->xError()));
358  vzerr.push_back(it->zError());
359  LogTrace("SelectVertex") << " SELECTED vertex with z position " << it->z();
360  toTake--; if (toTake == 0) break;
361  }
362  }
363 }
#define LogDebug(id)
T getParameter(std::string const &) const
std::vector< double > max_d0_
Impact parameter absolute cuts.
int i
Definition: DBlmapReader.cc:9
void selectVertices(unsigned int tsNum, const reco::VertexCollection &vtxs, std::vector< Point > &points, std::vector< double > &vterr, std::vector< double > &vzerr)
double d0Error() const
error on d0
Definition: TrackBase.h:211
std::vector< std::vector< double > > dz_par1_
double normalizedChi2() const
chi-squared divided by n.d.o.f. (or chi-squared * 1e6 if n.d.o.f. is zero)
Definition: TrackBase.h:111
std::vector< std::vector< double > > d0_par1_
std::vector< std::vector< double > > d0_par2_
virtual void produce(edm::Event &evt, const edm::EventSetup &es)
process one event
int pixelLayersWithMeasurement() const
Definition: HitPattern.h:710
int trackerLayersWithoutMeasurement() const
Definition: HitPattern.h:723
#define abs(x)
Definition: mlp_lapack.h:159
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
std::vector< uint32_t > min_3Dlayers_
#define min(a, b)
Definition: mlp_lapack.h:161
T eta() const
int numberOfValidStripLayersWithMonoAndStereo() const
Definition: HitPattern.cc:224
std::vector< int32_t > vtxNumber_
vertex cuts
std::vector< std::string > name_
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:141
const T & max(const T &a, const T &b)
double chi2() const
chi-squared of the fit
Definition: TrackBase.h:107
std::vector< std::vector< double > > res_par_
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:85
double ndof() const
number of degrees of freedom of the fit
Definition: TrackBase.h:109
int trackerLayersWithMeasurement() const
Definition: HitPattern.h:705
T sqrt(T t)
Definition: SSEVec.h:46
double pt() const
track transverse momentum
Definition: TrackBase.h:131
std::vector< uint32_t > min_nhits_
double ptError() const
error on Pt (set to 1000 TeV if charge==0 for safety)
Definition: TrackBase.h:194
int qualityMask() const
Definition: TrackBase.h:286
int j
Definition: DBlmapReader.cc:9
std::vector< unsigned int > preFilter_
unsigned short numberOfValidHits() const
number of valid hits found
Definition: TrackBase.h:232
bool select(unsigned tsNum, const reco::BeamSpot &vertexBeamSpot, const reco::Track &tk, const std::vector< Point > &points, std::vector< double > &vterr, std::vector< double > &vzerr)
return class, or -1 if rejected
#define end
Definition: vmac.h:38
trackingRecHit_iterator recHitsBegin() const
Iterator to first hit on the track.
Definition: Track.h:63
const HitPattern & hitPattern() const
Access the hit pattern, indicating in which Tracker layers the track has hits.
Definition: TrackBase.h:223
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:356
#define LogTrace(id)
std::vector< uint32_t > min_hits_bypass_
edm::InputTag src_
source collection label
double dz() const
dz parameter (= dsz/cos(lambda)). This is the track z0 w.r.t (0,0,0) only if the refPoint is close to...
Definition: TrackBase.h:127
double dzError() const
error on dz
Definition: TrackBase.h:215
static TrackQuality qualityByName(const std::string &name)
Definition: TrackBase.cc:46
std::vector< double > chi2n_no1Dmod_par_
std::vector< StringCutObjectSelector< reco::Vertex > > vertexCut_
double sigmaZ() const
sigma z
Definition: BeamSpot.h:81
bool isValid() const
std::vector< TrackBase::TrackQuality > qualityToSet_
std::vector< bool > setQualityBit_
do I have to set a quality bit?
std::vector< uint32_t > min_layers_
Cuts on numbers of layers with hits/3D hits/lost hits.
unsigned short found() const
Number of valid hits on track.
Definition: Track.h:100
const Point & position() const
position
Definition: BeamSpot.h:63
std::vector< uint32_t > max_lostLayers_
double dxy() const
dxy parameter. (This is the transverse impact parameter w.r.t. to (0,0,0) ONLY if refPoint is close t...
Definition: TrackBase.h:121
std::vector< std::vector< double > > dz_par2_
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
*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
trackingRecHit_iterator recHitsEnd() const
Iterator to last hit on the track.
Definition: Track.h:65