CMS 3D CMS Logo

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