CMS 3D CMS Logo

CalibrationTrackSelector.cc
Go to the documentation of this file.
2 
5 
7 
15 
19 
22 
23 // constructor ----------------------------------------------------------------
24 
26  : applyBasicCuts_(cfg.getParameter<bool>("applyBasicCuts")),
27  applyNHighestPt_(cfg.getParameter<bool>("applyNHighestPt")),
28  applyMultiplicityFilter_(cfg.getParameter<bool>("applyMultiplicityFilter")),
29  seedOnlyFromAbove_(cfg.getParameter<int>("seedOnlyFrom")),
30  applyIsolation_(cfg.getParameter<bool>("applyIsolationCut")),
31  chargeCheck_(cfg.getParameter<bool>("applyChargeCheck")),
32  nHighestPt_(cfg.getParameter<int>("nHighestPt")),
33  minMultiplicity_(cfg.getParameter<int>("minMultiplicity")),
34  maxMultiplicity_(cfg.getParameter<int>("maxMultiplicity")),
35  multiplicityOnInput_(cfg.getParameter<bool>("multiplicityOnInput")),
36  ptMin_(cfg.getParameter<double>("ptMin")),
37  ptMax_(cfg.getParameter<double>("ptMax")),
38  etaMin_(cfg.getParameter<double>("etaMin")),
39  etaMax_(cfg.getParameter<double>("etaMax")),
40  phiMin_(cfg.getParameter<double>("phiMin")),
41  phiMax_(cfg.getParameter<double>("phiMax")),
42  nHitMin_(cfg.getParameter<double>("nHitMin")),
43  nHitMax_(cfg.getParameter<double>("nHitMax")),
44  chi2nMax_(cfg.getParameter<double>("chi2nMax")),
45  minHitChargeStrip_(cfg.getParameter<double>("minHitChargeStrip")),
46  minHitIsolation_(cfg.getParameter<double>("minHitIsolation")),
47  rphirecHitsTag_(cfg.getParameter<edm::InputTag>("rphirecHits")),
48  matchedrecHitsTag_(cfg.getParameter<edm::InputTag>("matchedrecHits")),
49  nHitMin2D_(cfg.getParameter<unsigned int>("nHitMin2D")),
50  // Ugly to use the same getParameter 6 times, but this allows const cut
51  // variables...
52  minHitsinTIB_(cfg.getParameter<edm::ParameterSet>("minHitsPerSubDet").getParameter<int>("inTIB")),
53  minHitsinTOB_(cfg.getParameter<edm::ParameterSet>("minHitsPerSubDet").getParameter<int>("inTOB")),
54  minHitsinTID_(cfg.getParameter<edm::ParameterSet>("minHitsPerSubDet").getParameter<int>("inTID")),
55  minHitsinTEC_(cfg.getParameter<edm::ParameterSet>("minHitsPerSubDet").getParameter<int>("inTEC")),
56  minHitsinBPIX_(cfg.getParameter<edm::ParameterSet>("minHitsPerSubDet").getParameter<int>("inBPIX")),
57  minHitsinFPIX_(cfg.getParameter<edm::ParameterSet>("minHitsPerSubDet").getParameter<int>("inFPIX")) {
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  // edm::LogDebug("CalibrationTrackSelector") << "tracks all,kept: " <<
117  // tracks.size() << "," << result.size();
118 
119  return result;
120 }
121 
122 // make basic cuts ------------------------------------------------------------
123 
125  const edm::Event &evt) const {
126  Tracks result;
127 
128  for (Tracks::const_iterator it = tracks.begin(); it != tracks.end(); ++it) {
129  const reco::Track *trackp = *it;
130  float pt = trackp->pt();
131  float eta = trackp->eta();
132  float phi = trackp->phi();
133  int nhit = trackp->numberOfValidHits();
134  float chi2n = trackp->normalizedChi2();
135 
136  // edm::LogDebug("CalibrationTrackSelector") << " pt,eta,phi,nhit: "
137  // <<pt<<","<<eta<<","<<phi<<","<<nhit;
138 
139  if (pt > ptMin_ && pt < ptMax_ && eta > etaMin_ && eta < etaMax_ && phi > phiMin_ && phi < phiMax_ &&
140  nhit >= nHitMin_ && nhit <= nHitMax_ && chi2n < chi2nMax_) {
141  if (this->detailedHitsCheck(trackp, evt))
142  result.push_back(trackp);
143  }
144  }
145 
146  return result;
147 }
148 
149 //-----------------------------------------------------------------------------
150 
152  // checking hit requirements beyond simple number of valid hits
153 
155  nHitMin2D_ || chargeCheck_ || applyIsolation_) { // any detailed hit cut is active, so have to check
156 
157  int nhitinTIB = 0, nhitinTOB = 0, nhitinTID = 0;
158  int nhitinTEC = 0, nhitinBPIX = 0, nhitinFPIX = 0;
159  unsigned int nHit2D = 0;
160  unsigned int thishit = 0;
161 
162  for (auto const &hit : trackp->recHits()) {
163  thishit++;
164  int type = hit->geographicalId().subdetId();
165 
166  // *** thishit == 1 means last hit in CTF ***
167  // (FIXME: assumption might change or not be valid for all tracking
168  // algorthms)
169  // ==> for cosmics
170  // seedOnlyFrom = 1 is TIB-TOB-TEC tracks only
171  // seedOnlyFrom = 2 is TOB-TEC tracks only
172  if (seedOnlyFromAbove_ == 1 && thishit == 1 &&
173  (type == int(StripSubdetector::TOB) || type == int(StripSubdetector::TEC)))
174  return false;
175 
176  if (seedOnlyFromAbove_ == 2 && thishit == 1 && type == int(StripSubdetector::TIB))
177  return false;
178 
179  if (!hit->isValid())
180  continue; // only real hits count as in trackp->numberOfValidHits()
181  const DetId detId(hit->geographicalId());
182  if (detId.det() != DetId::Tracker) {
183  edm::LogError("DetectorMismatch")
184  << "@SUB=CalibrationTrackSelector::detailedHitsCheck"
185  << "DetId.det() != DetId::Tracker (=" << DetId::Tracker << "), but " << detId.det() << ".";
186  }
187  if (chargeCheck_ && !(this->isOkCharge(hit)))
188  return false;
189  if (applyIsolation_ && (!this->isIsolated(hit, evt)))
190  return false;
191  if (StripSubdetector::TIB == detId.subdetId())
192  ++nhitinTIB;
193  else if (StripSubdetector::TOB == detId.subdetId())
194  ++nhitinTOB;
195  else if (StripSubdetector::TID == detId.subdetId())
196  ++nhitinTID;
197  else if (StripSubdetector::TEC == detId.subdetId())
198  ++nhitinTEC;
199  else if (kBPIX == detId.subdetId())
200  ++nhitinBPIX;
201  else if (kFPIX == detId.subdetId())
202  ++nhitinFPIX;
203  // Do not call isHit2D(..) if already enough 2D hits for performance
204  // reason:
205  if (nHit2D < nHitMin2D_ && this->isHit2D(*hit))
206  ++nHit2D;
207  } // end loop on hits
208  return (nhitinTIB >= minHitsinTIB_ && nhitinTOB >= minHitsinTOB_ && nhitinTID >= minHitsinTID_ &&
209  nhitinTEC >= minHitsinTEC_ && nhitinBPIX >= minHitsinBPIX_ && nhitinFPIX >= minHitsinFPIX_ &&
210  nHit2D >= nHitMin2D_);
211  } else { // no cuts set, so we are just fine and can avoid loop on hits
212  return true;
213  }
214 }
215 
216 //-----------------------------------------------------------------------------
217 
219  if (hit.dimension() < 2) {
220  return false; // some (muon...) stuff really has RecHit1D
221  } else {
222  const DetId detId(hit.geographicalId());
223  if (detId.det() == DetId::Tracker) {
224  if (detId.subdetId() == kBPIX || detId.subdetId() == kFPIX) {
225  return true; // pixel is always 2D
226  } else { // should be SiStrip now
227  if (dynamic_cast<const SiStripRecHit2D *>(&hit))
228  return false; // normal hit
229  else if (dynamic_cast<const SiStripMatchedRecHit2D *>(&hit))
230  return true; // matched is 2D
231  else if (dynamic_cast<const ProjectedSiStripRecHit2D *>(&hit))
232  return false; // crazy hit...
233  else {
234  edm::LogError("UnkownType") << "@SUB=CalibrationTrackSelector::isHit2D"
235  << "Tracker hit not in pixel and neither SiStripRecHit2D nor "
236  << "SiStripMatchedRecHit2D nor ProjectedSiStripRecHit2D.";
237  return false;
238  }
239  }
240  } else { // not tracker??
241  edm::LogWarning("DetectorMismatch") << "@SUB=CalibrationTrackSelector::isHit2D"
242  << "Hit not in tracker with 'official' dimension >=2.";
243  return true; // dimension() >= 2 so accept that...
244  }
245  }
246  // never reached...
247 }
248 
249 //-----------------------------------------------------------------------------
250 
252  float charge1 = 0;
253  float charge2 = 0;
254  const SiStripMatchedRecHit2D *matchedhit = dynamic_cast<const SiStripMatchedRecHit2D *>(therechit);
255  const SiStripRecHit2D *hit = dynamic_cast<const SiStripRecHit2D *>(therechit);
256  const ProjectedSiStripRecHit2D *unmatchedhit = dynamic_cast<const ProjectedSiStripRecHit2D *>(therechit);
257 
258  if (matchedhit) {
259  const SiStripCluster &monocluster = matchedhit->monoCluster();
260  const std::vector<uint16_t> amplitudesmono(monocluster.amplitudes().begin(), monocluster.amplitudes().end());
261  for (size_t ia = 0; ia < amplitudesmono.size(); ++ia) {
262  charge1 += amplitudesmono[ia];
263  }
264 
265  const SiStripCluster &stereocluster = matchedhit->stereoCluster();
266  const std::vector<uint16_t> amplitudesstereo(stereocluster.amplitudes().begin(), stereocluster.amplitudes().end());
267  for (size_t ia = 0; ia < amplitudesstereo.size(); ++ia) {
268  charge2 += amplitudesstereo[ia];
269  }
270  // std::cout << "charge1 = " << charge1 << "\n";
271  // std::cout << "charge2 = " << charge2 << "\n";
272  if (charge1 < minHitChargeStrip_ || charge2 < minHitChargeStrip_)
273  return false;
274  } else if (hit) {
275  const SiStripCluster *cluster = &*(hit->cluster());
276  const std::vector<uint16_t> amplitudes(cluster->amplitudes().begin(), cluster->amplitudes().end());
277  for (size_t ia = 0; ia < amplitudes.size(); ++ia) {
278  charge1 += amplitudes[ia];
279  }
280  // std::cout << "charge1 = " << charge1 << "\n";
281  if (charge1 < minHitChargeStrip_)
282  return false;
283  } else if (unmatchedhit) {
284  const SiStripRecHit2D &orighit = unmatchedhit->originalHit();
285  const SiStripCluster *origcluster = &*(orighit.cluster());
286  const std::vector<uint16_t> amplitudes(origcluster->amplitudes().begin(), origcluster->amplitudes().end());
287  for (size_t ia = 0; ia < amplitudes.size(); ++ia) {
288  charge1 += amplitudes[ia];
289  }
290  // std::cout << "charge1 = " << charge1 << "\n";
291  if (charge1 < minHitChargeStrip_)
292  return false;
293  }
294  return true;
295 }
296 
297 //-----------------------------------------------------------------------------
298 
299 bool CalibrationTrackSelector::isIsolated(const TrackingRecHit *therechit, const edm::Event &evt) const {
300  // edm::ESHandle<TrackerGeometry> tracker;
303  // es.get<TrackerDigiGeometryRecord>().get(tracker);
304  evt.getByLabel(rphirecHitsTag_, rphirecHits);
305  evt.getByLabel(matchedrecHitsTag_, matchedrecHits);
306 
309  const SiStripRecHit2DCollection &stripcollSt = *rphirecHits;
310  const SiStripMatchedRecHit2DCollection &stripcollStm = *matchedrecHits;
311 
312  DetId idet = therechit->geographicalId();
313 
314  // FIXME: instead of looping the full hit collection, we should explore the
315  // features of SiStripRecHit2DCollection::rangeRphi = rphirecHits.get(idet)
316  // and loop only from rangeRphi.first until rangeRphi.second
317  for (istripSt = stripcollSt.data().begin(); istripSt != stripcollSt.data().end(); ++istripSt) {
318  const SiStripRecHit2D *aHit = &*(istripSt);
319  DetId mydet1 = aHit->geographicalId();
320  if (idet.rawId() != mydet1.rawId())
321  continue;
322  float theDistance = (therechit->localPosition() - aHit->localPosition()).mag();
323  // std::cout << "theDistance1 = " << theDistance << "\n";
324  if (theDistance > 0.001 && theDistance < minHitIsolation_)
325  return false;
326  }
327 
328  // FIXME: see above
329  for (istripStm = stripcollStm.data().begin(); istripStm != stripcollStm.data().end(); ++istripStm) {
330  const SiStripMatchedRecHit2D *aHit = &*(istripStm);
331  DetId mydet2 = aHit->geographicalId();
332  if (idet.rawId() != mydet2.rawId())
333  continue;
334  float theDistance = (therechit->localPosition() - aHit->localPosition()).mag();
335  // std::cout << "theDistance1 = " << theDistance << "\n";
336  if (theDistance > 0.001 && theDistance < minHitIsolation_)
337  return false;
338  }
339  return true;
340 }
341 //-----------------------------------------------------------------------------
342 
344  Tracks sortedTracks = tracks;
345  Tracks result;
346 
347  // sort in pt
348  std::sort(sortedTracks.begin(), sortedTracks.end(), ptComparator);
349 
350  // copy theTrackMult highest pt tracks to result vector
351  int n = 0;
352  for (Tracks::const_iterator it = sortedTracks.begin(); it != sortedTracks.end(); ++it) {
353  if (n < nHighestPt_) {
354  result.push_back(*it);
355  n++;
356  }
357  }
358 
359  return result;
360 }
type
Definition: HCALResponse.h:21
const edm::InputTag matchedrecHitsTag_
boost::transform_iterator< IterHelp, const_IdIter > const_iterator
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:600
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
SiStripCluster const & monoCluster() const
Tracks select(const Tracks &tracks, const edm::Event &evt) const
select tracks
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:684
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:690
bool isIsolated(const TrackingRecHit *therechit, const edm::Event &evt) const
bool detailedHitsCheck(const reco::Track *track, const edm::Event &evt) const
checking hit requirements beyond simple number of valid hits
virtual int dimension() const =0
double pt() const
track transverse momentum
Definition: TrackBase.h:660
data_type const * data(size_t cell) const
auto recHits() const
Access to reconstructed hits on the track.
Definition: Track.h:106
const edm::InputTag rphirecHitsTag_
ClusterRef cluster() const
unsigned short numberOfValidHits() const
number of valid hits found
Definition: TrackBase.h:901
bool isOkCharge(const TrackingRecHit *therechit) const
virtual LocalPoint localPosition() const =0
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:480
SiStripRecHit2D originalHit() const
Definition: DetId.h:18
const int kBPIX
const int kFPIX
std::vector< const reco::Track * > Tracks
SiStripCluster const & stereoCluster() const
HLT enums.
Tracks theNHighestPtTracks(const Tracks &tracks) const
filter the n highest pt tracks
bool isHit2D(const TrackingRecHit &hit) const
CalibrationTrackSelector(const edm::ParameterSet &cfg)
constructor
LocalPoint localPosition() const final
Tracks basicCuts(const Tracks &tracks, const edm::Event &evt) const
apply basic cuts on pt,eta,phi,nhit
DetId geographicalId() const
const std::vector< uint8_t > & amplitudes() const