CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoTracker/FinalTrackSelectors/src/DuplicateListMerger.cc

Go to the documentation of this file.
00001 #include "RecoTracker/FinalTrackSelectors/interface/DuplicateListMerger.h"
00002 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00003 #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h"
00004 #include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h"
00005 #include "RecoTracker/TrackProducer/interface/ClusterRemovalRefSetter.h"
00006 #include "DataFormats/Common/interface/ValueMap.h"
00007 
00008 #include "FWCore/Framework/interface/Event.h"
00009 #include "CommonTools/Statistics/interface/ChiSquaredProbability.h"
00010 
00011 using reco::modules::DuplicateListMerger;
00012 
00013 DuplicateListMerger::DuplicateListMerger(const edm::ParameterSet& iPara) 
00014 {
00015   diffHitsCut_ = 9999;
00016   minTrkProbCut_ = 0.0;
00017   if(iPara.exists("diffHitsCut"))diffHitsCut_ = iPara.getParameter<int>("diffHitsCut");
00018   if(iPara.exists("minTrkProbCut"))minTrkProbCut_ = iPara.getParameter<double>("minTrkProbCut");
00019   if(iPara.exists("mergedSource"))mergedTrackSource_ = iPara.getParameter<edm::InputTag>("mergedSource");
00020   if(iPara.exists("originalSource"))originalTrackSource_ = iPara.getParameter<edm::InputTag>("originalSource");
00021   if(iPara.exists("candidateSource"))candidateSource_ = iPara.getParameter<edm::InputTag>("candidateSource");
00022 
00023 
00024   if(iPara.exists("mergedMVAVals")){
00025     mergedMVAVals_ = iPara.getParameter<edm::InputTag>("mergedMVAVals");
00026   }else{
00027     mergedMVAVals_ = edm::InputTag(mergedTrackSource_.label(),"MVAVals");
00028   }
00029   if(iPara.exists("originalMVAVals")){
00030     originalMVAVals_ = iPara.getParameter<edm::InputTag>("originalMVAVals");
00031   }else{
00032     originalMVAVals_ = edm::InputTag(originalTrackSource_.label(),"MVAVals");
00033   }
00034 
00035   copyExtras_ = iPara.getUntrackedParameter<bool>("copyExtras",true);
00036   qualityToSet_ = reco::TrackBase::undefQuality;
00037   if (iPara.exists("newQuality")) {
00038     std::string qualityStr = iPara.getParameter<std::string>("newQuality");
00039     if (qualityStr != "") {
00040       qualityToSet_ = reco::TrackBase::qualityByName(qualityStr);
00041     }
00042   }
00043 
00044   produces<std::vector<reco::Track> >();
00045   produces< std::vector<Trajectory> >();
00046   produces< TrajTrackAssociationCollection >();
00047 
00048   produces<edm::ValueMap<float> >("MVAVals");
00049 
00050   makeReKeyedSeeds_ = iPara.getUntrackedParameter<bool>("makeReKeyedSeeds",false);
00051   if (makeReKeyedSeeds_){
00052     copyExtras_=true;
00053     produces<TrajectorySeedCollection>();
00054   }
00055   if(copyExtras_){
00056     produces<reco::TrackExtraCollection>();
00057     produces<TrackingRecHitCollection>();
00058   }
00059 
00060 }
00061 
00062 DuplicateListMerger::~DuplicateListMerger()
00063 {
00064 
00065   /* no op */
00066 
00067 }
00068 
00069 void DuplicateListMerger::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00070 {
00071   edm::Handle<reco::TrackCollection > originalHandle;
00072   iEvent.getByLabel(originalTrackSource_,originalHandle);
00073   edm::Handle<reco::TrackCollection > mergedHandle;
00074   iEvent.getByLabel(mergedTrackSource_,mergedHandle);
00075 
00076   const reco::TrackCollection& mergedTracks(*mergedHandle);
00077   reco::TrackRefProd originalTrackRefs(originalHandle);
00078   reco::TrackRefProd mergedTrackRefs(mergedHandle);
00079 
00080   edm::Handle< std::vector<Trajectory> >  mergedTrajHandle;
00081   iEvent.getByLabel(mergedTrackSource_,mergedTrajHandle);
00082   edm::Handle< TrajTrackAssociationCollection >  mergedTrajTrackHandle;
00083   iEvent.getByLabel(mergedTrackSource_,mergedTrajTrackHandle);
00084 
00085   edm::Handle< std::vector<Trajectory> >  originalTrajHandle;
00086   iEvent.getByLabel(originalTrackSource_,originalTrajHandle);
00087   edm::Handle< TrajTrackAssociationCollection >  originalTrajTrackHandle;
00088   iEvent.getByLabel(originalTrackSource_,originalTrajTrackHandle);
00089 
00090   edm::Handle<edm::View<DuplicateRecord> > candidateHandle;
00091   iEvent.getByLabel(candidateSource_,candidateHandle);
00092 
00093   std::auto_ptr<std::vector<reco::Track> > out_generalTracks(new std::vector<reco::Track>());
00094   out_generalTracks->reserve(originalHandle->size());
00095   reco::TrackRefProd refTrks = iEvent.getRefBeforePut<reco::TrackCollection>();
00096   std::auto_ptr< std::vector<Trajectory> > outputTrajs = std::auto_ptr< std::vector<Trajectory> >(new std::vector<Trajectory>());
00097   outputTrajs->reserve(originalTrajHandle->size()+mergedTrajHandle->size());
00098   edm::RefProd< std::vector<Trajectory> > refTrajs;
00099   std::auto_ptr< TrajTrackAssociationCollection >  outputTTAss = std::auto_ptr< TrajTrackAssociationCollection >(new TrajTrackAssociationCollection());
00100   //std::auto_ptr< TrajectorySeedCollection > outputSeeds
00101 
00102   std::auto_ptr<reco::TrackExtraCollection> outputTrkExtras;
00103   reco::TrackExtraRefProd refTrkExtras;
00104   std::auto_ptr<TrackingRecHitCollection> outputTrkHits;
00105   TrackingRecHitRefProd refTrkHits;
00106   std::auto_ptr<TrajectorySeedCollection> outputSeeds;
00107   edm::RefProd< TrajectorySeedCollection > refTrajSeeds;
00108 
00109   const int rSize = (int)originalHandle->size();
00110   edm::RefToBase<TrajectorySeed> seedsRefs[rSize];
00111 
00112   edm::Handle<edm::ValueMap<float> > originalMVAStore;
00113   edm::Handle<edm::ValueMap<float> > mergedMVAStore;
00114 
00115   iEvent.getByLabel(originalMVAVals_,originalMVAStore);
00116   iEvent.getByLabel(mergedMVAVals_,mergedMVAStore);
00117 
00118   std::auto_ptr<edm::ValueMap<float> > vmMVA = std::auto_ptr<edm::ValueMap<float> >(new edm::ValueMap<float>);
00119   edm::ValueMap<float>::Filler fillerMVA(*vmMVA);
00120   std::vector<float> mvaVec;
00121 
00122 
00123   if(copyExtras_){
00124     outputTrkExtras = std::auto_ptr<reco::TrackExtraCollection>(new reco::TrackExtraCollection);
00125     outputTrkExtras->reserve(originalHandle->size());
00126     refTrkExtras    = iEvent.getRefBeforePut<reco::TrackExtraCollection>();
00127     outputTrkHits   = std::auto_ptr<TrackingRecHitCollection>(new TrackingRecHitCollection);
00128     outputTrkHits->reserve(originalHandle->size()*25);
00129     refTrkHits      = iEvent.getRefBeforePut<TrackingRecHitCollection>();
00130     if (makeReKeyedSeeds_){
00131       outputSeeds = std::auto_ptr<TrajectorySeedCollection>(new TrajectorySeedCollection);
00132       outputSeeds->reserve(originalHandle->size());
00133       refTrajSeeds = iEvent.getRefBeforePut<TrajectorySeedCollection>();
00134     }
00135   }
00136 
00137   //match new tracks to their candidates
00138   std::vector<std::pair<int,const DuplicateRecord*> > matches;
00139   for(int i = 0; i < (int)candidateHandle->size(); i++){
00140     const DuplicateRecord& duplicateRecord = candidateHandle->at(i);
00141     int matchTrack = matchCandidateToTrack(duplicateRecord.first,mergedHandle);
00142     if(matchTrack < 0)continue;
00143     const reco::Track& matchedTrack(mergedTracks[matchTrack]);
00144     if( ChiSquaredProbability(matchedTrack.chi2(),matchedTrack.ndof()) < minTrkProbCut_)continue;
00145     unsigned int dHits = (duplicateRecord.first.recHits().second - duplicateRecord.first.recHits().first) - matchedTrack.recHitsSize();
00146     if(dHits > diffHitsCut_)continue;
00147     matches.push_back(std::pair<int,const DuplicateRecord*>(matchTrack,&duplicateRecord));
00148   }
00149 
00150   //check for candidates/tracks that share merged tracks, select minimum chi2, remove the rest
00151   std::vector<std::pair<int,const DuplicateRecord*> >::iterator matchIter0 = matches.begin();
00152   std::vector<std::pair<int,const DuplicateRecord*> >::iterator matchIter1;
00153   while(matchIter0 != matches.end()){
00154     double nchi2 = mergedTracks[matchIter0->first].normalizedChi2();
00155     bool advance = true;
00156     for(matchIter1 = matchIter0+1; matchIter1 != matches.end(); matchIter1++){
00157       const reco::Track& match0first = *(matchIter0->second->second.first.get());
00158       const reco::Track& match0second = *(matchIter0->second->second.second.get());
00159       const reco::Track& match1first = *(matchIter1->second->second.first.get());
00160       const reco::Track& match1second = *(matchIter1->second->second.second.get());
00161       if(match1first.seedRef() == match0first.seedRef() ||
00162          match1first.seedRef() == match0second.seedRef() || 
00163          match1second.seedRef() == match0first.seedRef() || 
00164          match1second.seedRef() == match0second.seedRef()){
00165         double nchi2_1 = mergedTracks[matchIter1->first].normalizedChi2();
00166         advance = false;
00167         if(nchi2_1 < nchi2){
00168           matches.erase(matchIter0);
00169         }else{
00170           matches.erase(matchIter1);
00171         }
00172         break;
00173       }
00174     }
00175     if(advance)matchIter0++;
00176   }
00177 
00178   //add the good merged tracks to the output list, remove input tracks
00179   std::vector<reco::Track> inputTracks;
00180 
00181   refTrajs = iEvent.getRefBeforePut< std::vector<Trajectory> >();
00182 
00183   for(matchIter0 = matches.begin(); matchIter0 != matches.end(); matchIter0++){
00184     reco::TrackRef inTrkRef1 = matchIter0->second->second.first;
00185     reco::TrackRef inTrkRef2 = matchIter0->second->second.second;
00186     const reco::Track& inTrk1 = *(inTrkRef1.get());
00187     const reco::Track& inTrk2 = *(inTrkRef2.get());
00188     reco::TrackBase::TrackAlgorithm newTrkAlgo = std::min(inTrk1.algo(),inTrk2.algo());
00189     int combinedQualityMask = (inTrk1.qualityMask() | inTrk2.qualityMask());
00190     inputTracks.push_back(inTrk1);
00191     inputTracks.push_back(inTrk2);
00192     out_generalTracks->push_back(mergedTracks[matchIter0->first]);
00193     reco::TrackRef curTrackRef = reco::TrackRef(refTrks, out_generalTracks->size() - 1);
00194     float mergedMVA = (*mergedMVAStore)[reco::TrackRef(mergedTrackRefs,matchIter0->first)];
00195     mvaVec.push_back(mergedMVA);
00196     out_generalTracks->back().setAlgorithm(newTrkAlgo);
00197     out_generalTracks->back().setQualityMask(combinedQualityMask);
00198     out_generalTracks->back().setQuality(qualityToSet_);
00199     edm::RefToBase<TrajectorySeed> origSeedRef;
00200     if(copyExtras_){
00201       const reco::Track& track = mergedTracks[matchIter0->first];
00202       origSeedRef = track.seedRef();
00203       //creating a seed with rekeyed clusters if required
00204       if (makeReKeyedSeeds_){
00205         bool doRekeyOnThisSeed=false;
00206         
00207         edm::InputTag clusterRemovalInfos("");
00208         //grab on of the hits of the seed
00209         if (origSeedRef->nHits()!=0){
00210           TrajectorySeed::const_iterator firstHit=origSeedRef->recHits().first;
00211           const TrackingRecHit *hit = &*firstHit;
00212           if (firstHit->isValid()){
00213             edm::ProductID  pID=clusterProductB(hit);
00214             // the cluster collection either produced a removalInfo or mot
00215             //get the clusterremoval info from the provenance: will rekey if this is found
00216             edm::Handle<reco::ClusterRemovalInfo> CRIh;
00217             edm::Provenance prov=iEvent.getProvenance(pID);
00218             clusterRemovalInfos=edm::InputTag(prov.moduleLabel(),
00219                                               prov.productInstanceName(),
00220                                               prov.processName());
00221             doRekeyOnThisSeed=iEvent.getByLabel(clusterRemovalInfos,CRIh);
00222           }//valid hit
00223         }//nhit!=0
00224         
00225         if (doRekeyOnThisSeed && !(clusterRemovalInfos==edm::InputTag(""))) {
00226           ClusterRemovalRefSetter refSetter(iEvent,clusterRemovalInfos);
00227           TrajectorySeed::recHitContainer  newRecHitContainer;
00228           newRecHitContainer.reserve(origSeedRef->nHits());
00229           TrajectorySeed::const_iterator iH=origSeedRef->recHits().first;
00230           TrajectorySeed::const_iterator iH_end=origSeedRef->recHits().second;
00231           for (;iH!=iH_end;++iH){
00232             newRecHitContainer.push_back(*iH);
00233             refSetter.reKey(&newRecHitContainer.back());
00234           }
00235           outputSeeds->push_back( TrajectorySeed( origSeedRef->startingState(),
00236                                                   newRecHitContainer,
00237                                                   origSeedRef->direction()));
00238         }
00239         //doRekeyOnThisSeed=true
00240         else{
00241           //just copy the one we had before
00242           outputSeeds->push_back( TrajectorySeed(*origSeedRef));
00243           }
00244         edm::Ref<TrajectorySeedCollection> pureRef(refTrajSeeds, outputSeeds->size()-1);
00245         origSeedRef=edm::RefToBase<TrajectorySeed>( pureRef);
00246       }//creating a new seed and rekeying it rechit clusters.
00247       // Fill TrackExtra collection
00248       outputTrkExtras->push_back( reco::TrackExtra( 
00249                                                    track.outerPosition(), track.outerMomentum(), track.outerOk(),
00250                                                    track.innerPosition(), track.innerMomentum(), track.innerOk(),
00251                                                    track.outerStateCovariance(), track.outerDetId(),
00252                                                    track.innerStateCovariance(), track.innerDetId(),
00253                                                    track.seedDirection(), origSeedRef ) );
00254       seedsRefs[(*matchIter0).first]=origSeedRef;
00255       out_generalTracks->back().setExtra( reco::TrackExtraRef( refTrkExtras, outputTrkExtras->size() - 1) );
00256       reco::TrackExtra & tx = outputTrkExtras->back();
00257       tx.setResiduals(track.residuals());
00258       // fill TrackingRecHits
00259       unsigned nh1=track.recHitsSize();
00260       for ( unsigned ih=0; ih<nh1; ++ih ) { 
00261           //const TrackingRecHit*hit=&((*(track->recHit(ih))));
00262         outputTrkHits->push_back( track.recHit(ih)->clone() );
00263         tx.add( TrackingRecHitRef( refTrkHits, outputTrkHits->size() - 1) );
00264       }
00265     }
00266     edm::Ref< std::vector<Trajectory> > trajRef(mergedTrajHandle, (*matchIter0).first);
00267     TrajTrackAssociationCollection::const_iterator match = mergedTrajTrackHandle->find(trajRef);
00268     if (match != mergedTrajTrackHandle->end()) {
00269         if(curTrackRef.isNonnull()){
00270           outputTrajs->push_back( *trajRef );
00271           if (copyExtras_ && makeReKeyedSeeds_)
00272             outputTrajs->back().setSeedRef( origSeedRef );
00273           outputTTAss->insert(edm::Ref< std::vector<Trajectory> >(refTrajs, outputTrajs->size() - 1),curTrackRef );
00274         }
00275     }
00276   }
00277 
00278   for(int i = 0; i < (int)originalHandle->size(); i++){
00279     bool good = true;
00280     const reco::Track& origTrack = originalHandle->at(i);
00281     for(int j = 0; j < (int)inputTracks.size() && good; j++){
00282       const reco::Track& inputTrack = inputTracks[j];
00283       if(origTrack.seedRef() != inputTrack.seedRef())continue;
00284       if(origTrack.charge() != inputTrack.charge())continue;
00285       if(origTrack.momentum() != inputTrack.momentum())continue;
00286       if(origTrack.referencePoint() != inputTrack.referencePoint())continue;
00287       good = false;
00288     }
00289 
00290     if(good){
00291       out_generalTracks->push_back(origTrack);
00292       reco::TrackRef curTrackRef = reco::TrackRef(refTrks, out_generalTracks->size() - 1);
00293       edm::RefToBase<TrajectorySeed> origSeedRef;
00294       reco::TrackRef origTrackRef = reco::TrackRef(originalHandle,i);
00295       mvaVec.push_back((*originalMVAStore)[origTrackRef]);
00296       //mvaVec.push_back((*originalMVAStore)[reco::TrackRef(originalTrackRefs,i)]);
00297       if(copyExtras_){
00298         const reco::Track& track = origTrack;
00299         origSeedRef = track.seedRef();
00300         //creating a seed with rekeyed clusters if required
00301         if (makeReKeyedSeeds_){
00302           bool doRekeyOnThisSeed=false;
00303           
00304           edm::InputTag clusterRemovalInfos("");
00305           //grab on of the hits of the seed
00306           if (origSeedRef->nHits()!=0){
00307             TrajectorySeed::const_iterator firstHit=origSeedRef->recHits().first;
00308             const TrackingRecHit *hit = &*firstHit;
00309             if (firstHit->isValid()){
00310               edm::ProductID  pID=clusterProductB(hit);
00311               // the cluster collection either produced a removalInfo or mot
00312               //get the clusterremoval info from the provenance: will rekey if this is found
00313               edm::Handle<reco::ClusterRemovalInfo> CRIh;
00314               edm::Provenance prov=iEvent.getProvenance(pID);
00315               clusterRemovalInfos=edm::InputTag(prov.moduleLabel(),
00316                                                 prov.productInstanceName(),
00317                                                 prov.processName());
00318               doRekeyOnThisSeed=iEvent.getByLabel(clusterRemovalInfos,CRIh);
00319             }//valid hit
00320           }//nhit!=0
00321           
00322           if (doRekeyOnThisSeed && !(clusterRemovalInfos==edm::InputTag(""))) {
00323             ClusterRemovalRefSetter refSetter(iEvent,clusterRemovalInfos);
00324             TrajectorySeed::recHitContainer  newRecHitContainer;
00325             newRecHitContainer.reserve(origSeedRef->nHits());
00326             TrajectorySeed::const_iterator iH=origSeedRef->recHits().first;
00327             TrajectorySeed::const_iterator iH_end=origSeedRef->recHits().second;
00328             for (;iH!=iH_end;++iH){
00329               newRecHitContainer.push_back(*iH);
00330               refSetter.reKey(&newRecHitContainer.back());
00331             }
00332             outputSeeds->push_back( TrajectorySeed( origSeedRef->startingState(),
00333                                                     newRecHitContainer,
00334                                                     origSeedRef->direction()));
00335           }
00336           //doRekeyOnThisSeed=true
00337           else{
00338             //just copy the one we had before
00339             outputSeeds->push_back( TrajectorySeed(*origSeedRef));
00340           }
00341           edm::Ref<TrajectorySeedCollection> pureRef(refTrajSeeds, outputSeeds->size()-1);
00342           origSeedRef=edm::RefToBase<TrajectorySeed>( pureRef);
00343         }//creating a new seed and rekeying it rechit clusters.
00344         
00345         // Fill TrackExtra collection
00346         outputTrkExtras->push_back( reco::TrackExtra( 
00347                                                      track.outerPosition(), track.outerMomentum(), track.outerOk(),
00348                                                      track.innerPosition(), track.innerMomentum(), track.innerOk(),
00349                                                      track.outerStateCovariance(), track.outerDetId(),
00350                                                      track.innerStateCovariance(), track.innerDetId(),
00351                                                      track.seedDirection(), origSeedRef ) );
00352         seedsRefs[i]=origSeedRef;
00353         out_generalTracks->back().setExtra( reco::TrackExtraRef( refTrkExtras, outputTrkExtras->size() - 1) );
00354         reco::TrackExtra & tx = outputTrkExtras->back();
00355         tx.setResiduals(track.residuals());
00356         
00357         // fill TrackingRecHits
00358         unsigned nh1=track.recHitsSize();
00359         for ( unsigned ih=0; ih<nh1; ++ih ) { 
00360           //const TrackingRecHit*hit=&((*(track->recHit(ih))));
00361           outputTrkHits->push_back( track.recHit(ih)->clone() );
00362           tx.add( TrackingRecHitRef( refTrkHits, outputTrkHits->size() - 1) );
00363         }
00364         
00365       }
00366 
00367       edm::Ref< std::vector<Trajectory> > trajRef(originalTrajHandle, i);
00368       TrajTrackAssociationCollection::const_iterator match = originalTrajTrackHandle->find(trajRef);
00369       if (match != originalTrajTrackHandle->end()) {
00370         if(curTrackRef.isNonnull()){
00371           outputTrajs->push_back( *trajRef );
00372           if (copyExtras_ && makeReKeyedSeeds_)
00373             outputTrajs->back().setSeedRef( origSeedRef );
00374           outputTTAss->insert(edm::Ref< std::vector<Trajectory> >(refTrajs, outputTrajs->size() - 1),curTrackRef );
00375         }
00376       }
00377     }
00378   }
00379 
00380   edm::ProductID nPID = refTrks.id();
00381   edm::TestHandle<TrackCollection> out_gtHandle(out_generalTracks.get(),nPID);
00382 
00383   fillerMVA.insert(out_gtHandle,mvaVec.begin(),mvaVec.end());
00384   fillerMVA.fill();
00385 
00386   iEvent.put(vmMVA,"MVAVals");
00387   iEvent.put(out_generalTracks);
00388   if (copyExtras_) {
00389     iEvent.put(outputTrkExtras);
00390     iEvent.put(outputTrkHits);
00391     if (makeReKeyedSeeds_)
00392       iEvent.put(outputSeeds);
00393   }
00394   iEvent.put(outputTrajs);
00395   iEvent.put(outputTTAss);
00396 }
00397 
00398 //------------------------------------------------------------
00399 //------------------------------------------------------------
00400 //------------------------------------------------------------
00401 //------------------------------------------------------------
00402 int DuplicateListMerger::matchCandidateToTrack(TrackCandidate candidate, edm::Handle<reco::TrackCollection > tracks){
00403   int track = -1;
00404   std::vector<int> rawIds;
00405   RecHitContainer::const_iterator candBegin = candidate.recHits().first;
00406   RecHitContainer::const_iterator candEnd = candidate.recHits().second;
00407   for(; candBegin != candEnd; candBegin++){
00408     rawIds.push_back((*(candBegin)).rawId());
00409   }
00410  
00411 
00412   for(int i = 0; i < (int)tracks->size() && track < 0;i++){
00413     if((tracks->at(i)).seedRef() != candidate.seedRef())continue;
00414     int match = 0;
00415     trackingRecHit_iterator trackRecBegin = tracks->at(i).recHitsBegin();
00416     trackingRecHit_iterator trackRecEnd = tracks->at(i).recHitsEnd();
00417     for(;trackRecBegin != trackRecEnd; trackRecBegin++){
00418       if(std::find(rawIds.begin(),rawIds.end(),(*(trackRecBegin)).get()->rawId()) != rawIds.end())match++;
00419     }
00420     if(match != (int)tracks->at(i).recHitsSize())continue;
00421     track = i;
00422   }
00423 
00424   return track;
00425 }
00426 //------------------------------------------------------------
00427 //------------------------------------------------------------
00428 //------------------------------------------------------------
00429 //------------------------------------------------------------