CMS 3D CMS Logo

CalibrationTrackSelector.cc
Go to the documentation of this file.
2 
5 
7 
13 
17 
20 
21 // constructor ----------------------------------------------------------------
22 
24  : applyBasicCuts_(cfg.getParameter<bool>("applyBasicCuts")),
25  applyNHighestPt_(cfg.getParameter<bool>("applyNHighestPt")),
26  applyMultiplicityFilter_(cfg.getParameter<bool>("applyMultiplicityFilter")),
27  seedOnlyFromAbove_(cfg.getParameter<int>("seedOnlyFrom")),
28  applyIsolation_(cfg.getParameter<bool>("applyIsolationCut")),
29  chargeCheck_(cfg.getParameter<bool>("applyChargeCheck")),
30  nHighestPt_(cfg.getParameter<int>("nHighestPt")),
31  minMultiplicity_(cfg.getParameter<int>("minMultiplicity")),
32  maxMultiplicity_(cfg.getParameter<int>("maxMultiplicity")),
33  multiplicityOnInput_(cfg.getParameter<bool>("multiplicityOnInput")),
34  ptMin_(cfg.getParameter<double>("ptMin")),
35  ptMax_(cfg.getParameter<double>("ptMax")),
36  etaMin_(cfg.getParameter<double>("etaMin")),
37  etaMax_(cfg.getParameter<double>("etaMax")),
38  phiMin_(cfg.getParameter<double>("phiMin")),
39  phiMax_(cfg.getParameter<double>("phiMax")),
40  nHitMin_(cfg.getParameter<double>("nHitMin")),
41  nHitMax_(cfg.getParameter<double>("nHitMax")),
42  chi2nMax_(cfg.getParameter<double>("chi2nMax")),
43  minHitChargeStrip_(cfg.getParameter<double>("minHitChargeStrip")),
44  minHitIsolation_(cfg.getParameter<double>("minHitIsolation")),
45  rphirecHitsTag_(cfg.getParameter<edm::InputTag>("rphirecHits")),
46  matchedrecHitsTag_(cfg.getParameter<edm::InputTag>("matchedrecHits")),
47  nHitMin2D_(cfg.getParameter<unsigned int>("nHitMin2D")),
48  // Ugly to use the same getParameter 6 times, but this allows const cut
49  // variables...
50  minHitsinTIB_(cfg.getParameter<edm::ParameterSet>("minHitsPerSubDet").getParameter<int>("inTIB")),
51  minHitsinTOB_(cfg.getParameter<edm::ParameterSet>("minHitsPerSubDet").getParameter<int>("inTOB")),
52  minHitsinTID_(cfg.getParameter<edm::ParameterSet>("minHitsPerSubDet").getParameter<int>("inTID")),
53  minHitsinTEC_(cfg.getParameter<edm::ParameterSet>("minHitsPerSubDet").getParameter<int>("inTEC")),
54  minHitsinBPIX_(cfg.getParameter<edm::ParameterSet>("minHitsPerSubDet").getParameter<int>("inBPIX")),
55  minHitsinFPIX_(cfg.getParameter<edm::ParameterSet>("minHitsPerSubDet").getParameter<int>("inFPIX")),
56  rphirecHitsToken_(iC.consumes<SiStripRecHit2DCollection>(rphirecHitsTag_)),
57  matchedrecHitsToken_(iC.consumes<SiStripMatchedRecHit2DCollection>(matchedrecHitsTag_)) {
58  if (applyBasicCuts_)
59  edm::LogInfo("CalibrationTrackSelector")
60  << "applying basic track cuts ..."
61  << "\nptmin,ptmax: " << ptMin_ << "," << ptMax_ << "\netamin,etamax: " << etaMin_ << "," << etaMax_
62  << "\nphimin,phimax: " << phiMin_ << "," << phiMax_ << "\nnhitmin,nhitmax: " << nHitMin_ << "," << nHitMax_
63  << "\nnhitmin2D: " << nHitMin2D_ << "\nchi2nmax: " << chi2nMax_;
64 
65  if (applyNHighestPt_)
66  edm::LogInfo("CalibrationTrackSelector") << "filter N tracks with highest Pt N=" << nHighestPt_;
67 
69  edm::LogInfo("CalibrationTrackSelector")
70  << "apply multiplicity filter N>= " << minMultiplicity_ << "and N<= " << maxMultiplicity_ << " on "
71  << (multiplicityOnInput_ ? "input" : "output");
72 
73  if (applyIsolation_)
74  edm::LogInfo("CalibrationTrackSelector")
75  << "only retain tracks isolated at least by " << minHitIsolation_ << " cm from other rechits";
76 
77  if (chargeCheck_)
78  edm::LogInfo("CalibrationTrackSelector")
79  << "only retain hits with at least " << minHitChargeStrip_ << " ADC counts of total cluster charge";
80 
81  edm::LogInfo("CalibrationTrackSelector")
82  << "Minimum number of hits in TIB/TID/TOB/TEC/BPIX/FPIX = " << minHitsinTIB_ << "/" << minHitsinTID_ << "/"
83  << minHitsinTOB_ << "/" << minHitsinTEC_ << "/" << minHitsinBPIX_ << "/" << minHitsinFPIX_;
84 }
85 
86 // destructor -----------------------------------------------------------------
87 
89 
90 // do selection ---------------------------------------------------------------
91 
94  (tracks.size() < static_cast<unsigned int>(minMultiplicity_) ||
95  tracks.size() > static_cast<unsigned int>(maxMultiplicity_))) {
96  return Tracks(); // empty collection
97  }
98 
100  // apply basic track cuts (if selected)
101  if (applyBasicCuts_)
102  result = this->basicCuts(result, evt);
103 
104  // filter N tracks with highest Pt (if selected)
105  if (applyNHighestPt_)
106  result = this->theNHighestPtTracks(result);
107 
108  // apply minimum multiplicity requirement (if selected)
110  if (result.size() < static_cast<unsigned int>(minMultiplicity_) ||
111  result.size() > static_cast<unsigned int>(maxMultiplicity_)) {
112  result.clear();
113  }
114  }
115 
116  return result;
117 }
118 
119 // make basic cuts ------------------------------------------------------------
120 
122  const edm::Event &evt) const {
123  Tracks result;
124 
125  for (Tracks::const_iterator it = tracks.begin(); it != tracks.end(); ++it) {
126  const reco::Track *trackp = *it;
127  float pt = trackp->pt();
128  float eta = trackp->eta();
129  float phi = trackp->phi();
130  int nhit = trackp->numberOfValidHits();
131  float chi2n = trackp->normalizedChi2();
132 
133  if (pt > ptMin_ && pt < ptMax_ && eta > etaMin_ && eta < etaMax_ && phi > phiMin_ && phi < phiMax_ &&
134  nhit >= nHitMin_ && nhit <= nHitMax_ && chi2n < chi2nMax_) {
135  if (this->detailedHitsCheck(trackp, evt))
136  result.push_back(trackp);
137  }
138  }
139 
140  return result;
141 }
142 
143 //-----------------------------------------------------------------------------
144 
146  // checking hit requirements beyond simple number of valid hits
147 
149  nHitMin2D_ || chargeCheck_ || applyIsolation_) { // any detailed hit cut is active, so have to check
150 
151  int nhitinTIB = 0, nhitinTOB = 0, nhitinTID = 0;
152  int nhitinTEC = 0, nhitinBPIX = 0, nhitinFPIX = 0;
153  unsigned int nHit2D = 0;
154  unsigned int thishit = 0;
155 
156  for (auto const &hit : trackp->recHits()) {
157  thishit++;
158  int type = hit->geographicalId().subdetId();
159 
160  // *** thishit == 1 means last hit in CTF ***
161  // (FIXME: assumption might change or not be valid for all tracking
162  // algorthms)
163  // ==> for cosmics
164  // seedOnlyFrom = 1 is TIB-TOB-TEC tracks only
165  // seedOnlyFrom = 2 is TOB-TEC tracks only
166  if (seedOnlyFromAbove_ == 1 && thishit == 1 &&
168  return false;
169 
170  if (seedOnlyFromAbove_ == 2 && thishit == 1 && type == int(StripSubdetector::TIB))
171  return false;
172 
173  if (!hit->isValid())
174  continue; // only real hits count as in trackp->numberOfValidHits()
175  const DetId detId(hit->geographicalId());
176  if (detId.det() != DetId::Tracker) {
177  edm::LogError("DetectorMismatch")
178  << "@SUB=CalibrationTrackSelector::detailedHitsCheck"
179  << "DetId.det() != DetId::Tracker (=" << DetId::Tracker << "), but " << detId.det() << ".";
180  }
181  if (chargeCheck_ && !(this->isOkCharge(hit)))
182  return false;
183  if (applyIsolation_ && (!this->isIsolated(hit, evt)))
184  return false;
185  if (StripSubdetector::TIB == detId.subdetId())
186  ++nhitinTIB;
187  else if (StripSubdetector::TOB == detId.subdetId())
188  ++nhitinTOB;
189  else if (StripSubdetector::TID == detId.subdetId())
190  ++nhitinTID;
191  else if (StripSubdetector::TEC == detId.subdetId())
192  ++nhitinTEC;
193  else if (kBPIX == detId.subdetId())
194  ++nhitinBPIX;
195  else if (kFPIX == detId.subdetId())
196  ++nhitinFPIX;
197  // Do not call isHit2D(..) if already enough 2D hits for performance
198  // reason:
199  if (nHit2D < nHitMin2D_ && this->isHit2D(*hit))
200  ++nHit2D;
201  } // end loop on hits
202  return (nhitinTIB >= minHitsinTIB_ && nhitinTOB >= minHitsinTOB_ && nhitinTID >= minHitsinTID_ &&
203  nhitinTEC >= minHitsinTEC_ && nhitinBPIX >= minHitsinBPIX_ && nhitinFPIX >= minHitsinFPIX_ &&
204  nHit2D >= nHitMin2D_);
205  } else { // no cuts set, so we are just fine and can avoid loop on hits
206  return true;
207  }
208 }
209 
210 //-----------------------------------------------------------------------------
211 
213  if (hit.dimension() < 2) {
214  return false; // some (muon...) stuff really has RecHit1D
215  } else {
216  const DetId detId(hit.geographicalId());
217  if (detId.det() == DetId::Tracker) {
218  if (detId.subdetId() == kBPIX || detId.subdetId() == kFPIX) {
219  return true; // pixel is always 2D
220  } else { // should be SiStrip now
221  if (dynamic_cast<const SiStripRecHit2D *>(&hit))
222  return false; // normal hit
223  else if (dynamic_cast<const SiStripMatchedRecHit2D *>(&hit))
224  return true; // matched is 2D
225  else if (dynamic_cast<const ProjectedSiStripRecHit2D *>(&hit))
226  return false; // crazy hit...
227  else {
228  edm::LogError("UnknownType") << "@SUB=CalibrationTrackSelector::isHit2D"
229  << "Tracker hit not in pixel and neither SiStripRecHit2D nor "
230  << "SiStripMatchedRecHit2D nor ProjectedSiStripRecHit2D.";
231  return false;
232  }
233  }
234  } else { // not tracker??
235  edm::LogWarning("DetectorMismatch") << "@SUB=CalibrationTrackSelector::isHit2D"
236  << "Hit not in tracker with 'official' dimension >=2.";
237  return true; // dimension() >= 2 so accept that...
238  }
239  }
240  // never reached...
241 }
242 
243 //-----------------------------------------------------------------------------
244 
246  float charge1 = 0;
247  float charge2 = 0;
248  const SiStripMatchedRecHit2D *matchedhit = dynamic_cast<const SiStripMatchedRecHit2D *>(therechit);
249  const SiStripRecHit2D *hit = dynamic_cast<const SiStripRecHit2D *>(therechit);
250  const ProjectedSiStripRecHit2D *unmatchedhit = dynamic_cast<const ProjectedSiStripRecHit2D *>(therechit);
251 
252  if (matchedhit) {
253  const SiStripCluster &monocluster = matchedhit->monoCluster();
254  const std::vector<uint16_t> amplitudesmono(monocluster.amplitudes().begin(), monocluster.amplitudes().end());
255  for (size_t ia = 0; ia < amplitudesmono.size(); ++ia) {
256  charge1 += amplitudesmono[ia];
257  }
258 
259  const SiStripCluster &stereocluster = matchedhit->stereoCluster();
260  const std::vector<uint16_t> amplitudesstereo(stereocluster.amplitudes().begin(), stereocluster.amplitudes().end());
261  for (size_t ia = 0; ia < amplitudesstereo.size(); ++ia) {
262  charge2 += amplitudesstereo[ia];
263  }
264  if (charge1 < minHitChargeStrip_ || charge2 < minHitChargeStrip_)
265  return false;
266  } else if (hit) {
267  const SiStripCluster *cluster = &*(hit->cluster());
268  const std::vector<uint16_t> amplitudes(cluster->amplitudes().begin(), cluster->amplitudes().end());
269  for (size_t ia = 0; ia < amplitudes.size(); ++ia) {
270  charge1 += amplitudes[ia];
271  }
272  if (charge1 < minHitChargeStrip_)
273  return false;
274  } else if (unmatchedhit) {
275  const SiStripRecHit2D &orighit = unmatchedhit->originalHit();
276  const SiStripCluster *origcluster = &*(orighit.cluster());
277  const std::vector<uint16_t> amplitudes(origcluster->amplitudes().begin(), origcluster->amplitudes().end());
278  for (size_t ia = 0; ia < amplitudes.size(); ++ia) {
279  charge1 += amplitudes[ia];
280  }
281  if (charge1 < minHitChargeStrip_)
282  return false;
283  }
284  return true;
285 }
286 
287 //-----------------------------------------------------------------------------
288 
289 bool CalibrationTrackSelector::isIsolated(const TrackingRecHit *therechit, const edm::Event &evt) const {
292 
295  const SiStripRecHit2DCollection &stripcollSt = *rphirecHits;
296  const SiStripMatchedRecHit2DCollection &stripcollStm = *matchedrecHits;
297 
298  DetId idet = therechit->geographicalId();
299 
300  // FIXME: instead of looping the full hit collection, we should explore the
301  // features of SiStripRecHit2DCollection::rangeRphi = rphirecHits.get(idet)
302  // and loop only from rangeRphi.first until rangeRphi.second
303  for (istripSt = stripcollSt.data().begin(); istripSt != stripcollSt.data().end(); ++istripSt) {
304  const SiStripRecHit2D *aHit = &*(istripSt);
305  DetId mydet1 = aHit->geographicalId();
306  if (idet.rawId() != mydet1.rawId())
307  continue;
308  float theDistance = (therechit->localPosition() - aHit->localPosition()).mag();
309  if (theDistance > 0.001 && theDistance < minHitIsolation_)
310  return false;
311  }
312 
313  // FIXME: see above
314  for (istripStm = stripcollStm.data().begin(); istripStm != stripcollStm.data().end(); ++istripStm) {
315  const SiStripMatchedRecHit2D *aHit = &*(istripStm);
316  DetId mydet2 = aHit->geographicalId();
317  if (idet.rawId() != mydet2.rawId())
318  continue;
319  float theDistance = (therechit->localPosition() - aHit->localPosition()).mag();
320  if (theDistance > 0.001 && theDistance < minHitIsolation_)
321  return false;
322  }
323  return true;
324 }
325 //-----------------------------------------------------------------------------
326 
328  Tracks sortedTracks = tracks;
329  Tracks result;
330 
331  // sort in pt
332  std::sort(sortedTracks.begin(), sortedTracks.end(), ptComparator);
333 
334  // copy theTrackMult highest pt tracks to result vector
335  int n = 0;
336  for (Tracks::const_iterator it = sortedTracks.begin(); it != sortedTracks.end(); ++it) {
337  if (n < nHighestPt_) {
338  result.push_back(*it);
339  n++;
340  }
341  }
342 
343  return result;
344 }
static constexpr auto TEC
Tracks select(const Tracks &tracks, const edm::Event &evt) const
select tracks
const edm::EDGetTokenT< SiStripRecHit2DCollection > rphirecHitsToken_
unsigned short numberOfValidHits() const
number of valid hits found
Definition: TrackBase.h:798
data_type const * data(size_t cell) const
auto const * begin() const
Log< level::Error, false > LogError
auto const * end() const
bool detailedHitsCheck(const reco::Track *track, const edm::Event &evt) const
checking hit requirements beyond simple number of valid hits
Tracks theNHighestPtTracks(const Tracks &tracks) const
filter the n highest pt tracks
ClusterRef cluster() const
bool isHit2D(const TrackingRecHit &hit) const
bool isOkCharge(const TrackingRecHit *therechit) const
double pt() const
track transverse momentum
Definition: TrackBase.h:637
auto recHits() const
Access to reconstructed hits on the track.
Definition: Track.h:85
SiStripCluster const & monoCluster() const
SiStripCluster const & amplitudes() const
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:649
static constexpr auto TOB
bool isIsolated(const TrackingRecHit *therechit, const edm::Event &evt) const
const edm::EDGetTokenT< SiStripMatchedRecHit2DCollection > matchedrecHitsToken_
Log< level::Info, false > LogInfo
boost::transform_iterator< IterHelp, const_IdIter > const_iterator
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:652
Definition: DetId.h:17
static constexpr auto TIB
const int kBPIX
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
DetId geographicalId() const
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
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:593
const int kFPIX
SiStripCluster const & stereoCluster() const
std::vector< const reco::Track * > Tracks
Handle< PROD > getHandle(EDGetTokenT< PROD > token) const
Definition: Event.h:550
HLT enums.
Tracks basicCuts(const Tracks &tracks, const edm::Event &evt) const
apply basic cuts on pt,eta,phi,nhit
SiStripRecHit2D originalHit() const
LocalPoint localPosition() const override
CalibrationTrackSelector(const edm::ParameterSet &cfg, edm::ConsumesCollector &iC)
constructor
Log< level::Warning, false > LogWarning
virtual LocalPoint localPosition() const =0
static constexpr auto TID