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