CMS 3D CMS Logo

HICaloCompatibleTrackSelector.cc
Go to the documentation of this file.
1 /*
2 
3  Based on analytical track selector
4 
5  - This track selector assigns a quality bit to tracks deemed compatible with matching calo info
6  - The default mode is to use the matching provided by particle flow,
7  but a delta R matching to calorimeter towers is also supported
8  - No selection is done other then selecting calo-compatible tracks.
9  - The code always keeps all tracks in the input collection (should make configurable)
10  - Note that matching by PF candidate only works on the same track collection used as input to PF
11  - Tower code not up to data
12 
13  Authors: Matthew Nguyen, Andre Yoon, Frank Ma (November 4th, 2011)
14 
15  */
16 
17 // Basic inclusion
19 
22 
24 #include <Math/DistFunc.h>
25 #include "TMath.h"
26 
28 
29 HICaloCompatibleTrackSelector::HICaloCompatibleTrackSelector(const edm::ParameterSet& cfg)
30  : srcTracks_(consumes<TrackCollection>(cfg.getParameter<edm::InputTag>("srcTracks"))),
31  srcPFCands_(consumes<PFCandidateCollection>(cfg.getParameter<edm::InputTag>("srcPFCands"))),
32  srcTower_(consumes<CaloTowerCollection>(cfg.getParameter<edm::InputTag>("srcTower"))),
33  usePFCandMatching_(cfg.getUntrackedParameter<bool>("usePFCandMatching", true)),
34  trkMatchPtMin_(cfg.getUntrackedParameter<double>("trkMatchPtMin", 10.0)),
35  trkCompPtMin_(cfg.getUntrackedParameter<double>("trkCompPtMin", 35.0)),
36  trkEtaMax_(cfg.getUntrackedParameter<double>("trkEtaMax", 2.4)),
37  towerPtMin_(cfg.getUntrackedParameter<double>("towerPtMin", 5.0)),
38  matchConeRadius_(cfg.getUntrackedParameter<double>("matchConeRadius", 0.087)),
39  keepAllTracks_(cfg.getUntrackedParameter<bool>("keepAllTracks", true)),
40  copyExtras_(cfg.getUntrackedParameter<bool>("copyExtras", true)),
41  copyTrajectories_(cfg.getUntrackedParameter<bool>("copyTrajectories", true)),
42  qualityToSet_(cfg.getParameter<std::string>("qualityToSet")),
43  qualityToSkip_(cfg.getParameter<std::string>("qualityToSkip")),
44  qualityToMatch_(cfg.getParameter<std::string>("qualityToMatch")),
45  minimumQuality_(cfg.getParameter<std::string>("minimumQuality")),
46  resetQuality_(cfg.getUntrackedParameter<bool>("resetQuality", true)),
47  passMuons_(cfg.getUntrackedParameter<bool>("passMuons", true)),
48  passElectrons_(cfg.getUntrackedParameter<bool>("passElectrons", false)),
49  funcDeltaRTowerMatch_(cfg.getParameter<std::string>("funcDeltaRTowerMatch")),
50  funcCaloComp_(cfg.getParameter<std::string>("funcCaloComp")) {
51  std::string alias(cfg.getParameter<std::string>("@module_label"));
52  produces<reco::TrackCollection>().setBranchAlias(alias + "Tracks");
53  if (copyExtras_) {
54  produces<reco::TrackExtraCollection>().setBranchAlias(alias + "TrackExtras");
55  produces<TrackingRecHitCollection>().setBranchAlias(alias + "RecHits");
56  }
57  if (copyTrajectories_) {
58  produces<std::vector<Trajectory>>().setBranchAlias(alias + "Trajectories");
59  produces<TrajTrackAssociationCollection>().setBranchAlias(alias + "TrajectoryTrackAssociations");
60  srcTrackTrajs_ = (consumes<std::vector<Trajectory>>(cfg.getParameter<edm::InputTag>("srcTracks")));
61  srcTrackTrajAssoc_ = (consumes<TrajTrackAssociationCollection>(cfg.getParameter<edm::InputTag>("srcTracks")));
62  }
63 
64  // pt dependence of delta R matching requirement
65  fDeltaRTowerMatch = new TF1("fDeltaRTowerMatch", funcDeltaRTowerMatch_.c_str(), 0, 200);
66  // pt dependance of calo compatibility, i.e., minimum sum Calo Et vs. track pT
67  fCaloComp = new TF1("fCaloComp", funcCaloComp_.c_str(), 0, 200); // a parameterization of pt dependent cut
68 }
69 
71 
73  using namespace std;
74  using namespace edm;
75  using namespace reco;
76 
77  LogDebug("HICaloCompatibleTrackSelector") << "min pt for selection = " << trkMatchPtMin_ << endl;
78 
79  Handle<TrackCollection> hSrcTrack;
83 
84  evt.getByToken(srcTracks_, hSrcTrack);
85 
86  selTracks_ = std::make_unique<TrackCollection>();
88  if (copyExtras_) {
89  selTrackExtras_ = std::make_unique<TrackExtraCollection>();
90  selHits_ = std::make_unique<TrackingRecHitCollection>();
93  }
94 
96  trackRefs_.resize(hSrcTrack->size());
97 
100 
101  bool isPFThere = false;
102  bool isTowerThere = false;
103 
104  if (usePFCandMatching_)
105  isPFThere = evt.getByToken(srcPFCands_, pfCandidates);
106  else
107  isTowerThere = evt.getByToken(srcTower_, towers);
108 
109  size_t current = 0;
110  for (TI ti = hSrcTrack->begin(), ed = hSrcTrack->end(); ti != ed; ++ti, ++current) {
111  const reco::Track& trk = *ti;
112 
113  bool isSelected;
114  if (usePFCandMatching_)
115  isSelected = selectByPFCands(ti, hSrcTrack, pfCandidates, isPFThere);
116  else
117  isSelected = selectByTowers(ti, hSrcTrack, towers, isTowerThere);
118 
119  if (!keepAllTracks_ && !isSelected)
120  continue;
121 
122  // Add all tracks to output collection, the rest of the code only sets the quality bit
123  selTracks_->push_back(reco::Track(trk)); // clone and store
124 
125  if (isSelected)
127 
128  if (copyExtras_) {
129  // TrackExtras
130  selTrackExtras_->push_back(TrackExtra(trk.outerPosition(),
131  trk.outerMomentum(),
132  trk.outerOk(),
133  trk.innerPosition(),
134  trk.innerMomentum(),
135  trk.innerOk(),
136  trk.outerStateCovariance(),
137  trk.outerDetId(),
138  trk.innerStateCovariance(),
139  trk.innerDetId(),
140  trk.seedDirection(),
141  trk.seedRef()));
142  selTracks_->back().setExtra(TrackExtraRef(rTrackExtras_, selTrackExtras_->size() - 1));
143  TrackExtra& tx = selTrackExtras_->back();
144  tx.setResiduals(trk.residuals());
145  // TrackingRecHits
146  auto const firstHitIndex = selHits_->size();
147  for (trackingRecHit_iterator hit = trk.recHitsBegin(); hit != trk.recHitsEnd(); ++hit) {
148  selHits_->push_back((*hit)->clone());
149  }
150  tx.setHits(rHits_, firstHitIndex, selHits_->size() - firstHitIndex);
151  }
152  if (copyTrajectories_) {
153  trackRefs_[current] = TrackRef(rTracks_, selTracks_->size() - 1);
154  }
155 
156  } // close track loop
157 
158  if (copyTrajectories_) {
161  evt.getByToken(srcTrackTrajs_, hTTAss);
162  evt.getByToken(srcTrackTrajAssoc_, hTraj);
163  selTrajs_ = std::make_unique<std::vector<Trajectory>>();
164  rTrajectories_ = evt.getRefBeforePut<vector<Trajectory>>();
165  selTTAss_ = std::make_unique<TrajTrackAssociationCollection>();
166  for (size_t i = 0, n = hTraj->size(); i < n; ++i) {
167  Ref<vector<Trajectory>> trajRef(hTraj, i);
169  if (match != hTTAss->end()) {
170  const Ref<TrackCollection>& trkRef = match->val;
171  short oldKey = static_cast<short>(trkRef.key());
172  if (trackRefs_[oldKey].isNonnull()) {
173  selTrajs_->push_back(Trajectory(*trajRef));
174  selTTAss_->insert(Ref<vector<Trajectory>>(rTrajectories_, selTrajs_->size() - 1), trackRefs_[oldKey]);
175  }
176  }
177  }
178  }
179 
180  static const string emptyString;
181  evt.put(std::move(selTracks_));
182  if (copyExtras_) {
184  evt.put(std::move(selHits_));
185  }
186  if (copyTrajectories_) {
187  evt.put(std::move(selTrajs_));
188  evt.put(std::move(selTTAss_));
189  }
190 }
191 
195  bool isPFThere) {
196  const reco::Track& trk = *ti;
197 
198  // If it passes this quality threshold or is under the minimum match pT, automatically save it
200  return true;
202  return false;
203  } else {
204  double trkPt = trk.pt();
205  //if(trkPt < trkMatchPtMin_ ) return false;
206 
207  double caloEt = 0.0;
208  if (usePFCandMatching_) {
209  if (isPFThere) {
210  unsigned int trackKey = ti - hSrcTrack->begin();
211  caloEt = matchPFCandToTrack(pfCandidates, trackKey, trkPt);
212  }
213  }
214 
215  // Set quality bit based on calo matching
216  if (!(caloEt > 0.))
217  return false;
218 
219  if (trkPt <= trkCompPtMin_) {
221  return true;
222  else
223  return false;
224  } else {
225  // loose cuts are implied in selectors, make configurable?
226  float compPt =
227  (fCaloComp->Eval(trkPt) != fCaloComp->Eval(trkPt)) ? 0 : fCaloComp->Eval(trkPt); // protect agains NaN
228  if (caloEt > compPt)
229  return true;
230  else
231  return false;
232  }
233  } // else above trkMatchPtMin_
234 
235  throw cms::Exception("Undefined case in HICaloCompatibleTrackSelector")
236  << "Undefined case in HICaloCompatibleTrackSelector";
237 }
238 
242  bool isTowerThere) {
243  // Not up to date! use PF towers instead
244 
245  const reco::Track& trk = *ti;
246 
247  // If it passes the high purity cuts, then consider it confirmed
249  return true;
250  } else {
252  return false;
253 
254  double caloEt = 0.0;
255  if (isTowerThere) {
256  double matchDr;
257  matchByDrAllowReuse(trk, towers, matchDr, caloEt);
258  float matchConeRadius_pt = (fDeltaRTowerMatch->Eval(trk.pt()) != fDeltaRTowerMatch->Eval(trk.pt()))
259  ? 0
260  : fDeltaRTowerMatch->Eval(trk.pt()); // protect agains NaN
261  if (caloEt > 0 && matchDr > matchConeRadius_pt)
262  caloEt = 0.;
263  }
264 
265  if (trk.pt() < trkCompPtMin_ || caloEt > 0.75 * (trk.pt() - trkCompPtMin_))
266  return true;
267  else
268  return false;
269  }
270 }
271 
273  unsigned it,
274  double trkPt) {
275  // This function returns the sum of the calo energy in the block containing the track
276  // There is another piece of information which could be useful which is the pT assigned to the charged hadron by PF
277 
278  double sum_ecal = 0.0, sum_hcal = 0.0;
279 
280  int candType = 0;
281  reco::PFCandidate matchedCand;
282 
283  // loop over the PFCandidates until you find the one whose trackRef points to the track
284 
285  for (CI ci = pfCandidates->begin(); ci != pfCandidates->end(); ++ci) {
286  const reco::PFCandidate& cand = *ci;
287 
288  int type = cand.particleId();
289 
290  // only charged hadrons and leptons can be asscociated with a track
291  if (!(type == PFCandidate::h || //type1
292  type == PFCandidate::e || //type2
293  type == PFCandidate::mu //type3
294  ))
295  continue;
296 
297  unsigned candTrackRefKey = cand.trackRef().key();
298 
299  if (it == candTrackRefKey) {
300  matchedCand = cand;
301  candType = type;
302  break;
303  }
304  }
305  // take all muons as compatible, extend to electrons when validataed
306  if (passMuons_ && candType == 3)
307  return 9999.;
308  if (passElectrons_ && candType == 2)
309  return 9999.;
310 
311  if (trkPt < trkMatchPtMin_)
312  return 0.;
313 
314  if (candType > 0) {
315  // Now that we found the matched PF candidate, loop over the elements in the block summing the calo Et
316  for (unsigned ib = 0; ib < matchedCand.elementsInBlocks().size(); ib++) {
317  PFBlockRef blockRef = matchedCand.elementsInBlocks()[ib].first;
318 
319  unsigned indexInBlock = matchedCand.elementsInBlocks()[ib].second;
320  const edm::OwnVector<reco::PFBlockElement>& elements = (*blockRef).elements();
321 
322  //This tells you what type of element it is:
323  //cout<<" block type"<<elements[indexInBlock].type()<<endl;
324 
325  switch (elements[indexInBlock].type()) {
326  case PFBlockElement::ECAL: {
327  reco::PFClusterRef clusterRef = elements[indexInBlock].clusterRef();
328  sum_ecal += clusterRef->energy() / cosh(clusterRef->eta());
329  break;
330  }
331 
332  case PFBlockElement::HCAL: {
333  reco::PFClusterRef clusterRef = elements[indexInBlock].clusterRef();
334  sum_hcal += clusterRef->energy() / cosh(clusterRef->eta());
335  break;
336  }
337  case PFBlockElement::TRACK: {
338  //Do nothing since track are not normally linked to other tracks
339  break;
340  }
341  default:
342  break;
343  }
344 
345  // We could also add in the PS, HO, ..
346 
347  } // end of elementsInBlocks()
348  } // end of isCandFound
349 
350  return sum_ecal + sum_hcal;
351 }
352 
355  double& bestdr,
356  double& bestpt) {
357  // loop over towers
358  bestdr = 1e10;
359  bestpt = 0.;
360  for (unsigned int i = 0; i < towers->size(); ++i) {
361  const CaloTower& tower = (*towers)[i];
362  double pt = tower.pt();
363  if (pt < towerPtMin_)
364  continue;
365  if (fabs(tower.eta()) > trkEtaMax_)
366  continue;
367  double dr = reco::deltaR(tower, trk);
368  if (dr < bestdr) {
369  bestdr = dr;
370  bestpt = pt;
371  }
372  }
373 }
#define LogDebug(id)
type
Definition: HCALResponse.h:21
const edm::RefToBase< TrajectorySeed > & seedRef() const
Definition: Track.h:155
T getParameter(std::string const &) const
edm::EDGetTokenT< CaloTowerCollection > srcTower_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:131
double eta() const final
momentum pseudorapidity
const_iterator end() const
last iterator over the map (read only)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:525
void setHits(TrackingRecHitRefProd const &prod, unsigned firstH, unsigned int nH)
std::unique_ptr< TrackingRecHitCollection > selHits_
const_iterator find(const key_type &k) const
find element with specified reference key
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:14
bool innerOk() const
return true if the innermost hit is valid
Definition: Track.h:53
double pt() const final
transverse momentum
edm::Ref< TrackExtraCollection > TrackExtraRef
persistent reference to a TrackExtra
Definition: TrackExtraFwd.h:16
key_type key() const
Accessor for product key.
Definition: Ref.h:250
const math::XYZPoint & outerPosition() const
position of the outermost hit
Definition: Track.h:62
edm::EDGetTokenT< reco::TrackCollection > srcTracks_
source collection label
edm::EDGetTokenT< std::vector< Trajectory > > srcTrackTrajs_
reco::TrackRef trackRef() const
Definition: PFCandidate.cc:408
const math::XYZPoint & innerPosition() const
position of the innermost hit
Definition: Track.h:56
reco::PFCandidateCollection::const_iterator CI
std::unique_ptr< std::vector< Trajectory > > selTrajs_
edm::RefProd< std::vector< Trajectory > > rTrajectories_
CovarianceMatrix outerStateCovariance() const
outermost trajectory state curvilinear errors
Definition: Track.h:68
double pt() const
track transverse momentum
Definition: TrackBase.h:602
void produce(edm::Event &evt, const edm::EventSetup &es) override
process one event
unsigned int outerDetId() const
DetId of the detector on which surface the outermost state is located.
Definition: Track.h:79
bool selectByTowers(TI ti, const edm::Handle< TrackCollection > hSrcTrack, const edm::Handle< CaloTowerCollection > towers, bool isTowerThere)
bool copyExtras_
copy only the tracks, not extras and rechits (for AOD)
trackingRecHit_iterator recHitsBegin() const
Iterator to first hit on the track.
Definition: Track.h:88
edm::EDGetTokenT< reco::PFCandidateCollection > srcPFCands_
RefProd< PROD > getRefBeforePut()
Definition: Event.h:156
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:30
std::unique_ptr< TrajTrackAssociationCollection > selTTAss_
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
std::vector< TrackExtra > TrackExtraCollection
collection of TrackExtra objects
Definition: TrackExtraFwd.h:10
static TrackQuality qualityByName(const std::string &name)
Definition: TrackBase.cc:126
double matchPFCandToTrack(const edm::Handle< PFCandidateCollection > &pfCandidates, unsigned it, double trkPt)
const math::XYZVector & outerMomentum() const
momentum vector at the outermost hit position
Definition: Track.h:65
bool outerOk() const
return true if the outermost hit is valid
Definition: Track.h:50
const PropagationDirection & seedDirection() const
direction of how the hits were sorted in the original seed
Definition: Track.h:148
edm::Ref< TrackCollection > TrackRef
persistent reference to a Track
Definition: TrackFwd.h:20
CovarianceMatrix innerStateCovariance() const
innermost trajectory state curvilinear errors
Definition: Track.h:71
bool quality(const TrackQuality) const
Track quality.
Definition: TrackBase.h:531
static std::string const emptyString("")
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
fixed size matrix
HLT enums.
std::unique_ptr< reco::TrackExtraCollection > selTrackExtras_
size_type size() const
const math::XYZVector & innerMomentum() const
momentum vector at the innermost hit position
Definition: Track.h:59
std::unique_ptr< reco::TrackCollection > selTracks_
storage
const TrackResiduals & residuals() const
get the residuals
Definition: Track.h:158
bool selectByPFCands(TI ti, const edm::Handle< TrackCollection > hSrcTrack, const edm::Handle< PFCandidateCollection > pfCandidates, bool isPFThere)
void matchByDrAllowReuse(const reco::Track &trk, const edm::Handle< CaloTowerCollection > &towers, double &bestdr, double &bestpt)
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
virtual ParticleType particleId() const
Definition: PFCandidate.h:366
bool copyTrajectories_
copy also trajectories and trajectory->track associations
const ElementsInBlocks & elementsInBlocks() const
Definition: PFCandidate.cc:636
unsigned int innerDetId() const
DetId of the detector on which surface the innermost state is located.
Definition: Track.h:82
def move(src, dest)
Definition: eostools.py:511
ib
Definition: cuy.py:662
edm::EDGetTokenT< TrajTrackAssociationCollection > srcTrackTrajAssoc_
trackingRecHit_iterator recHitsEnd() const
Iterator to last hit on the track.
Definition: Track.h:91
void setResiduals(const TrackResiduals &r)
set the residuals
Definition: TrackExtra.h:132