00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "RecoHI/HiTracking/interface/HICaloCompatibleTrackSelector.h"
00020
00021 #include "DataFormats/TrackReco/interface/Track.h"
00022 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00023
00024 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
00025 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00026 #include "DataFormats/ParticleFlowReco/interface/PFClusterFwd.h"
00027
00028 #include "DataFormats/RecoCandidate/interface/TrackAssociation.h"
00029 #include "SimTracker/Records/interface/TrackAssociatorRecord.h"
00030 #include "SimTracker/TrackAssociation/interface/TrackAssociatorByHits.h"
00031 #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h"
00032 #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticleFwd.h"
00033
00034 #include "DataFormats/CaloTowers/interface/CaloTower.h"
00035 #include "DataFormats/CaloTowers/interface/CaloTowerFwd.h"
00036
00037 #include "FWCore/Framework/interface/EventSetup.h"
00038 #include "FWCore/Framework/interface/ESHandle.h"
00039
00040 #include "DataFormats/Math/interface/deltaR.h"
00041 #include <Math/DistFunc.h>
00042 #include "TMath.h"
00043
00044
00045 using reco::modules::HICaloCompatibleTrackSelector;
00046
00047 HICaloCompatibleTrackSelector::HICaloCompatibleTrackSelector( const edm::ParameterSet & cfg ) :
00048 srcTracks_(cfg.getParameter<edm::InputTag>("srcTracks")),
00049 srcPFCands_(cfg.getParameter<edm::InputTag>("srcPFCands")),
00050 srcTower_(cfg.getParameter<edm::InputTag>("srcTower")),
00051 usePFCandMatching_(cfg.getUntrackedParameter<bool>("usePFCandMatching", true)),
00052 trkMatchPtMin_(cfg.getUntrackedParameter<double>("trkMatchPtMin",10.0)),
00053 trkCompPtMin_(cfg.getUntrackedParameter<double>("trkCompPtMin",35.0)),
00054 trkEtaMax_(cfg.getUntrackedParameter<double>("trkEtaMax",2.4)),
00055 towerPtMin_(cfg.getUntrackedParameter<double>("towerPtMin",5.0)),
00056 matchConeRadius_(cfg.getUntrackedParameter<double>("matchConeRadius",0.087)),
00057 keepAllTracks_(cfg.getUntrackedParameter<bool>("keepAllTracks", true)),
00058 copyExtras_(cfg.getUntrackedParameter<bool>("copyExtras", true)),
00059 copyTrajectories_(cfg.getUntrackedParameter<bool>("copyTrajectories", true)),
00060 qualityToSet_(cfg.getParameter<std::string>("qualityToSet")),
00061 qualityToSkip_(cfg.getParameter<std::string>("qualityToSkip")),
00062 qualityToMatch_(cfg.getParameter<std::string>("qualityToMatch")),
00063 minimumQuality_(cfg.getParameter<std::string>("minimumQuality")),
00064 resetQuality_(cfg.getUntrackedParameter<bool>("resetQuality", true)),
00065 passMuons_(cfg.getUntrackedParameter<bool>("passMuons", true)),
00066 passElectrons_(cfg.getUntrackedParameter<bool>("passElectrons", false)),
00067 funcDeltaRTowerMatch_(cfg.getParameter<std::string>("funcDeltaRTowerMatch")),
00068 funcCaloComp_(cfg.getParameter<std::string>("funcCaloComp"))
00069 {
00070 std::string alias( cfg.getParameter<std::string>( "@module_label" ) );
00071 produces<reco::TrackCollection>().setBranchAlias( alias + "Tracks");
00072 if (copyExtras_) {
00073 produces<reco::TrackExtraCollection>().setBranchAlias( alias + "TrackExtras");
00074 produces<TrackingRecHitCollection>().setBranchAlias( alias + "RecHits");
00075 }
00076 if (copyTrajectories_) {
00077 produces< std::vector<Trajectory> >().setBranchAlias( alias + "Trajectories");
00078 produces< TrajTrackAssociationCollection >().setBranchAlias( alias + "TrajectoryTrackAssociations");
00079 }
00080
00081
00082 fDeltaRTowerMatch = new TF1("fDeltaRTowerMatch",funcDeltaRTowerMatch_.c_str(),0,200);
00083
00084 fCaloComp = new TF1("fCaloComp",funcCaloComp_.c_str(),0,200);
00085
00086
00087 }
00088
00089 HICaloCompatibleTrackSelector::~HICaloCompatibleTrackSelector() {
00090 }
00091
00092
00093 void HICaloCompatibleTrackSelector::produce( edm::Event& evt, const edm::EventSetup& es )
00094 {
00095 using namespace std;
00096 using namespace edm;
00097 using namespace reco;
00098
00099 LogDebug("HICaloCompatibleTrackSelector")<<"min pt for selection = "<< trkMatchPtMin_<<endl;
00100
00101
00102 Handle<TrackCollection> hSrcTrack;
00103 Handle< vector<Trajectory> > hTraj;
00104 Handle< vector<Trajectory> > hTrajP;
00105 Handle< TrajTrackAssociationCollection > hTTAss;
00106
00107 evt.getByLabel(srcTracks_,hSrcTrack);
00108
00109 selTracks_ = auto_ptr<TrackCollection>(new TrackCollection());
00110 rTracks_ = evt.getRefBeforePut<TrackCollection>();
00111 if (copyExtras_) {
00112 selTrackExtras_ = auto_ptr<TrackExtraCollection>(new TrackExtraCollection());
00113 selHits_ = auto_ptr<TrackingRecHitCollection>(new TrackingRecHitCollection());
00114 rHits_ = evt.getRefBeforePut<TrackingRecHitCollection>();
00115 rTrackExtras_ = evt.getRefBeforePut<TrackExtraCollection>();
00116 }
00117
00118
00119 if (copyTrajectories_) trackRefs_.resize(hSrcTrack->size());
00120
00121
00122 Handle<PFCandidateCollection> pfCandidates;
00123 Handle<CaloTowerCollection> towers;
00124
00125 bool isPFThere = false;
00126 bool isTowerThere = false;
00127
00128 if(usePFCandMatching_) isPFThere = evt.getByLabel(srcPFCands_, pfCandidates);
00129 else isTowerThere = evt.getByLabel(srcTower_, towers);
00130
00131 size_t current = 0;
00132 for (TI ti = hSrcTrack->begin(), ed = hSrcTrack->end(); ti != ed; ++ti, ++current) {
00133
00134
00135 const reco::Track& trk = *ti;
00136
00137 bool isSelected;
00138 if(usePFCandMatching_) isSelected = selectByPFCands(ti, hSrcTrack, pfCandidates, isPFThere);
00139 else isSelected = selectByTowers(ti, hSrcTrack, towers, isTowerThere);
00140
00141 if(!keepAllTracks_ && !isSelected) continue;
00142
00143
00144 selTracks_->push_back( reco::Track( trk ) );
00145
00146
00147 if(isSelected) selTracks_->back().setQuality(reco::TrackBase::qualityByName(qualityToSet_.c_str()));
00148
00149
00150 if (copyExtras_) {
00151
00152 selTrackExtras_->push_back( TrackExtra( trk.outerPosition(), trk.outerMomentum(), trk.outerOk(),
00153 trk.innerPosition(), trk.innerMomentum(), trk.innerOk(),
00154 trk.outerStateCovariance(), trk.outerDetId(),
00155 trk.innerStateCovariance(), trk.innerDetId(),
00156 trk.seedDirection(), trk.seedRef() ) );
00157 selTracks_->back().setExtra( TrackExtraRef( rTrackExtras_, selTrackExtras_->size() - 1) );
00158 TrackExtra & tx = selTrackExtras_->back();
00159 tx.setResiduals(trk.residuals());
00160
00161 for( trackingRecHit_iterator hit = trk.recHitsBegin(); hit != trk.recHitsEnd(); ++ hit ) {
00162 selHits_->push_back( (*hit)->clone() );
00163 tx.add( TrackingRecHitRef( rHits_, selHits_->size() - 1) );
00164 }
00165 }
00166 if (copyTrajectories_) {
00167 trackRefs_[current] = TrackRef(rTracks_, selTracks_->size() - 1);
00168 }
00169
00170
00171 }
00172
00173 if ( copyTrajectories_ ) {
00174 Handle< vector<Trajectory> > hTraj;
00175 Handle< TrajTrackAssociationCollection > hTTAss;
00176 evt.getByLabel(srcTracks_, hTTAss);
00177 evt.getByLabel(srcTracks_, hTraj);
00178 selTrajs_ = auto_ptr< vector<Trajectory> >(new vector<Trajectory>());
00179 rTrajectories_ = evt.getRefBeforePut< vector<Trajectory> >();
00180 selTTAss_ = auto_ptr< TrajTrackAssociationCollection >(new TrajTrackAssociationCollection());
00181 for (size_t i = 0, n = hTraj->size(); i < n; ++i) {
00182 Ref< vector<Trajectory> > trajRef(hTraj, i);
00183 TrajTrackAssociationCollection::const_iterator match = hTTAss->find(trajRef);
00184 if (match != hTTAss->end()) {
00185 const Ref<TrackCollection> &trkRef = match->val;
00186 short oldKey = static_cast<short>(trkRef.key());
00187 if (trackRefs_[oldKey].isNonnull()) {
00188 selTrajs_->push_back( Trajectory(*trajRef) );
00189 selTTAss_->insert ( Ref< vector<Trajectory> >(rTrajectories_, selTrajs_->size() - 1), trackRefs_[oldKey] );
00190 }
00191 }
00192 }
00193 }
00194
00195 static const string emptyString;
00196 evt.put(selTracks_);
00197 if (copyExtras_ ) {
00198 evt.put(selTrackExtras_);
00199 evt.put(selHits_);
00200 }
00201 if ( copyTrajectories_ ) {
00202 evt.put(selTrajs_);
00203 evt.put(selTTAss_);
00204 }
00205 }
00206
00207
00208
00209 bool
00210 HICaloCompatibleTrackSelector::selectByPFCands(TI ti, edm::Handle<TrackCollection> hSrcTrack, edm::Handle<PFCandidateCollection> pfCandidates, bool isPFThere)
00211 {
00212
00213 const reco::Track& trk = *ti;
00214
00215
00216 if(trk.quality(reco::TrackBase::qualityByName(qualityToSkip_))){
00217 return true;
00218 }
00219 else if(!trk.quality(reco::TrackBase::qualityByName(minimumQuality_))){
00220 return false;
00221 }
00222 else
00223 {
00224
00225 double trkPt = trk.pt();
00226
00227
00228 double caloEt = 0.0;
00229 if(usePFCandMatching_){
00230 if(isPFThere){
00231 unsigned int trackKey = ti - hSrcTrack->begin();
00232 caloEt = matchPFCandToTrack(pfCandidates, trackKey, trkPt);
00233 }
00234 }
00235
00236
00237 if(!(caloEt>0.)) return false;
00238
00239
00240 if(trkPt<=trkCompPtMin_){
00241 if(trk.quality(reco::TrackBase::qualityByName(qualityToMatch_))) return true;
00242 else return false;
00243 }
00244 else{
00245
00246 float compPt = (fCaloComp->Eval(trkPt)!=fCaloComp->Eval(trkPt)) ? 0 : fCaloComp->Eval(trkPt);
00247 if(caloEt>compPt) return true;
00248 else return false;
00249 }
00250 }
00251
00252 throw cms::Exception("Undefined case in HICaloCompatibleTrackSelector") << "Undefined case in HICaloCompatibleTrackSelector";
00253 }
00254
00255
00256 bool
00257 HICaloCompatibleTrackSelector::selectByTowers(TI ti, edm::Handle<TrackCollection> hSrcTrack, edm::Handle<CaloTowerCollection> towers, bool isTowerThere)
00258 {
00259
00260
00261
00262 const reco::Track& trk = *ti;
00263
00264
00265 if(trk.quality(reco::TrackBase::qualityByName(qualityToSkip_))){
00266 return true;
00267 }
00268 else{
00269 if(trk.pt() < trkMatchPtMin_ || !trk.quality(reco::TrackBase::qualityByName(qualityToMatch_))) return false;
00270
00271 double caloEt = 0.0;
00272 if(isTowerThere){
00273 double matchDr;
00274 matchByDrAllowReuse(trk,towers,matchDr,caloEt);
00275 float matchConeRadius_pt = (fDeltaRTowerMatch->Eval(trk.pt())!=fDeltaRTowerMatch->Eval(trk.pt())) ? 0 : fDeltaRTowerMatch->Eval(trk.pt());
00276 if (caloEt>0 && matchDr>matchConeRadius_pt) caloEt=0.;
00277 }
00278
00279 if(trk.pt()<trkCompPtMin_||caloEt>0.75*(trk.pt()-trkCompPtMin_)) return true;
00280 else return false;
00281 }
00282 }
00283
00284 double
00285 HICaloCompatibleTrackSelector::matchPFCandToTrack( const edm::Handle<reco::PFCandidateCollection> & pfCandidates, unsigned it, double trkPt)
00286 {
00287
00288
00289
00290
00291
00292 double sum_ecal=0.0, sum_hcal=0.0;
00293
00294 int candType = 0;
00295 reco::PFCandidate matchedCand;
00296
00297
00298
00299 for( CI ci = pfCandidates->begin(); ci!=pfCandidates->end(); ++ci) {
00300
00301 const reco::PFCandidate& cand = *ci;
00302
00303 int type = cand.particleId();
00304
00305
00306 if(!(type == PFCandidate::h ||
00307 type == PFCandidate::e ||
00308 type == PFCandidate::mu
00309 )
00310 ) continue;
00311
00312
00313 unsigned candTrackRefKey = cand.trackRef().key();
00314
00315 if(it==candTrackRefKey) {
00316 matchedCand = cand;
00317 candType = type;
00318 break;
00319 }
00320 }
00321
00322 if(passMuons_ && candType==3) return 9999.;
00323 if(passElectrons_ && candType==2) return 9999.;
00324
00325 if(trkPt < trkMatchPtMin_ ) return 0.;
00326
00327 if(candType>0){
00328
00329
00330 for(unsigned ib=0; ib<matchedCand.elementsInBlocks().size(); ib++) {
00331
00332 PFBlockRef blockRef = matchedCand.elementsInBlocks()[ib].first;
00333
00334 unsigned indexInBlock = matchedCand.elementsInBlocks()[ib].second;
00335 const edm::OwnVector< reco::PFBlockElement>& elements = (*blockRef).elements();
00336
00337
00338
00339
00340 switch (elements[indexInBlock].type()) {
00341
00342 case PFBlockElement::ECAL: {
00343 reco::PFClusterRef clusterRef = elements[indexInBlock].clusterRef();
00344 sum_ecal += clusterRef->energy()/cosh(clusterRef->eta());
00345 break;
00346 }
00347
00348 case PFBlockElement::HCAL: {
00349 reco::PFClusterRef clusterRef = elements[indexInBlock].clusterRef();
00350 sum_hcal += clusterRef->energy()/cosh(clusterRef->eta());
00351 break;
00352 }
00353 case PFBlockElement::TRACK: {
00354
00355 break;
00356 }
00357 default:
00358 break;
00359 }
00360
00361
00362
00363 }
00364 }
00365
00366
00367
00368 return sum_ecal+sum_hcal;
00369
00370 }
00371
00372 void HICaloCompatibleTrackSelector::matchByDrAllowReuse(const reco::Track & trk, const edm::Handle<CaloTowerCollection> & towers, double & bestdr, double & bestpt)
00373 {
00374
00375 bestdr=1e10;
00376 bestpt=0.;
00377 for(unsigned int i = 0; i < towers->size(); ++i){
00378 const CaloTower & tower= (*towers)[i];
00379 double pt = tower.pt();
00380 if (pt<towerPtMin_) continue;
00381 if (fabs(tower.eta())>trkEtaMax_) continue;
00382 double dr = reco::deltaR(tower,trk);
00383 if (dr<bestdr) {
00384 bestdr = dr;
00385 bestpt = pt;
00386 }
00387 }
00388 }