CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/RecoTracker/FinalTrackSelectors/src/SimpleTrackListMerger.cc

Go to the documentation of this file.
00001 //
00002 // Package:         RecoTracker/FinalTrackSelectors
00003 // Class:           SimpleTrackListMerger
00004 // 
00005 // Description:     TrackList Cleaner and Merger
00006 //
00007 // Original Author: Steve Wagner, stevew@pizero.colorado.edu
00008 // Created:         Sat Jan 14 22:00:00 UTC 2006
00009 //
00010 // $Author: innocent $
00011 // $Date: 2010/12/14 15:03:08 $
00012 // $Revision: 1.27 $
00013 //
00014 
00015 #include <memory>
00016 #include <string>
00017 #include <iostream>
00018 #include <cmath>
00019 #include <vector>
00020 
00021 #include "RecoTracker/FinalTrackSelectors/interface/SimpleTrackListMerger.h"
00022 
00023 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2DCollection.h"
00024 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit2DCollection.h"
00025 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit1DCollection.h"
00026 #include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h"
00027 #include "DataFormats/TrackCandidate/interface/TrackCandidateCollection.h"
00028 
00029 #include "FWCore/Framework/interface/ESHandle.h"
00030 
00031 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00032 
00033 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00034 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00035 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00036 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00037 
00038 //#include "DataFormats/TrackReco/src/classes.h"
00039 
00040 #include "RecoTracker/TrackProducer/interface/ClusterRemovalRefSetter.h"
00041 
00042 
00043 namespace cms
00044 {
00045   
00046   edm::ProductID clusterProduct( const TrackingRecHit *hit){
00047     edm::ProductID pID;
00048     //cast it into the proper class     and find productID
00049     DetId detid = hit->geographicalId(); 
00050     uint32_t subdet = detid.subdetId();
00051     if ((subdet == PixelSubdetector::PixelBarrel) || (subdet == PixelSubdetector::PixelEndcap)) {
00052       pID=reinterpret_cast<const SiPixelRecHit *>(hit)->cluster().id();
00053     } else {
00054       const std::type_info &type = typeid(*hit);
00055       if (type == typeid(SiStripRecHit2D)) {
00056         pID=reinterpret_cast<const SiStripRecHit2D *>(hit)->cluster().id();
00057       } else if (type == typeid(SiStripRecHit1D)) {
00058         pID=reinterpret_cast<const SiStripRecHit1D *>(hit)->cluster().id();     
00059       } else if (type == typeid(SiStripMatchedRecHit2D)) {
00060         const SiStripMatchedRecHit2D *mhit = reinterpret_cast<const SiStripMatchedRecHit2D *>(hit);
00061         pID=mhit->monoHit()->cluster().id();
00062       } else if (type == typeid(ProjectedSiStripRecHit2D)) {
00063         const ProjectedSiStripRecHit2D *phit = reinterpret_cast<const ProjectedSiStripRecHit2D *>(hit);
00064         pID=(&phit->originalHit())->cluster().id();
00065       } else throw cms::Exception("Unknown RecHit Type") << "RecHit of type " << type.name() << " not supported. (use c++filt to demangle the name)";
00066     }
00067         
00068     return pID;}
00069   
00070 
00071 
00072   SimpleTrackListMerger::SimpleTrackListMerger(edm::ParameterSet const& conf) : 
00073     conf_(conf)
00074   {
00075     copyExtras_ = conf_.getUntrackedParameter<bool>("copyExtras", true);
00076 
00077     produces<reco::TrackCollection>();
00078 
00079     makeReKeyedSeeds_ = conf_.getUntrackedParameter<bool>("makeReKeyedSeeds",false);
00080     if (makeReKeyedSeeds_){
00081       copyExtras_=true;
00082       produces<TrajectorySeedCollection>();
00083     }
00084 
00085     if (copyExtras_) {
00086         produces<reco::TrackExtraCollection>();
00087         produces<TrackingRecHitCollection>();
00088     }
00089     produces< std::vector<Trajectory> >();
00090     produces< TrajTrackAssociationCollection >();
00091     
00092 
00093   }
00094 
00095 
00096   // Virtual destructor needed.
00097   SimpleTrackListMerger::~SimpleTrackListMerger() { }  
00098 
00099   // Functions that gets called by framework every event
00100   void SimpleTrackListMerger::produce(edm::Event& e, const edm::EventSetup& es)
00101   {
00102     // retrieve producer name of input TrackCollection(s)
00103     std::string trackProducer1 = conf_.getParameter<std::string>("TrackProducer1");
00104     std::string trackProducer2 = conf_.getParameter<std::string>("TrackProducer2");
00105 
00106     double maxNormalizedChisq =  conf_.getParameter<double>("MaxNormalizedChisq");
00107     double minPT =  conf_.getParameter<double>("MinPT");
00108     unsigned int minFound = (unsigned int)conf_.getParameter<int>("MinFound");
00109     double epsilon =  conf_.getParameter<double>("Epsilon");
00110     bool use_sharesInput = true;
00111     if ( epsilon > 0.0 )use_sharesInput = false;
00112     double shareFrac =  conf_.getParameter<double>("ShareFrac");
00113   
00114     bool promoteQuality = conf_.getParameter<bool>("promoteTrackQuality");
00115     bool allowFirstHitShare = conf_.getParameter<bool>("allowFirstHitShare");
00116 //
00117 
00118     // New track quality should be read from the file
00119     std::string qualityStr = conf_.getParameter<std::string>("newQuality");
00120     reco::TrackBase::TrackQuality qualityToSet;
00121     if (qualityStr != "") {
00122       qualityToSet = reco::TrackBase::qualityByName(conf_.getParameter<std::string>("newQuality"));
00123     }
00124     else 
00125       qualityToSet = reco::TrackBase::undefQuality;
00126 
00127     // extract tracker geometry
00128     //
00129     edm::ESHandle<TrackerGeometry> theG;
00130     es.get<TrackerDigiGeometryRecord>().get(theG);
00131 
00132 //    using namespace reco;
00133 
00134     // get Inputs 
00135     // if 1 input list doesn't exist, make an empty list, issue a warning, and continue
00136     // this allows SimpleTrackListMerger to be used as a cleaner only if handed just one list
00137     // if both input lists don't exist, will issue 2 warnings and generate an empty output collection
00138     //
00139     const reco::TrackCollection *TC1 = 0;
00140     static const reco::TrackCollection s_empty1, s_empty2;
00141     edm::Handle<reco::TrackCollection> trackCollection1;
00142     e.getByLabel(trackProducer1, trackCollection1);
00143     if (trackCollection1.isValid()) {
00144       TC1 = trackCollection1.product();
00145       //std::cout << "1st collection " << trackProducer1 << " has "<< TC1->size() << " tracks" << std::endl ;
00146     } else {
00147       TC1 = &s_empty1;
00148       edm::LogWarning("SimpleTrackListMerger") << "1st TrackCollection " << trackProducer1 << " not found; will only clean 2nd TrackCollection " << trackProducer2 ;
00149     }
00150     const reco::TrackCollection tC1 = *TC1;
00151 
00152     const reco::TrackCollection *TC2 = 0;
00153     edm::Handle<reco::TrackCollection> trackCollection2;
00154     e.getByLabel(trackProducer2, trackCollection2);
00155     if (trackCollection2.isValid()) {
00156       TC2 = trackCollection2.product();
00157       //std::cout << "2nd collection " << trackProducer2 << " has "<< TC2->size() << " tracks" << std::endl ;
00158     } else {
00159         TC2 = &s_empty2;
00160         edm::LogWarning("SimpleTrackListMerger") << "2nd TrackCollection " << trackProducer2 << " not found; will only clean 1st TrackCollection " << trackProducer1 ;
00161     }
00162     const reco::TrackCollection tC2 = *TC2;
00163 
00164     // Step B: create empty output collection
00165     outputTrks = std::auto_ptr<reco::TrackCollection>(new reco::TrackCollection);
00166     refTrks = e.getRefBeforePut<reco::TrackCollection>();      
00167 
00168     if (copyExtras_) {
00169         outputTrkExtras = std::auto_ptr<reco::TrackExtraCollection>(new reco::TrackExtraCollection);
00170         outputTrkExtras->reserve(TC1->size()+TC2->size());
00171         refTrkExtras    = e.getRefBeforePut<reco::TrackExtraCollection>();
00172         outputTrkHits   = std::auto_ptr<TrackingRecHitCollection>(new TrackingRecHitCollection);
00173         outputTrkHits->reserve((TC1->size()+TC2->size())*25);
00174         refTrkHits      = e.getRefBeforePut<TrackingRecHitCollection>();
00175         if (makeReKeyedSeeds_){
00176           outputSeeds = std::auto_ptr<TrajectorySeedCollection>(new TrajectorySeedCollection);
00177           outputSeeds->reserve(TC1->size()+TC2->size());
00178           refTrajSeeds = e.getRefBeforePut<TrajectorySeedCollection>();
00179         }
00180     }
00181 
00182     outputTrajs = std::auto_ptr< std::vector<Trajectory> >(new std::vector<Trajectory>()); 
00183     outputTrajs->reserve(TC1->size()+TC2->size());
00184     outputTTAss = std::auto_ptr< TrajTrackAssociationCollection >(new TrajTrackAssociationCollection());
00185     //outputTTAss->reserve(TC1->size()+TC2->size());//how do I reserve space for an association map?
00186 
00187   //
00188   //  no input tracks
00189   //
00190 
00191 //    if ( tC1.empty() ){
00192 //      LogDebug("RoadSearch") << "Found " << output.size() << " clouds.";
00193 //      e.put(output);
00194 //      return;  
00195 //    }
00196 
00197   //
00198   //  quality cuts first
00199   // 
00200     int i;
00201 
00202     std::vector<int> selected1; for (unsigned int i=0; i<tC1.size(); ++i){selected1.push_back(1);}
00203 
00204    if ( 0<tC1.size() ){
00205       i=-1;
00206       for (reco::TrackCollection::const_iterator track=tC1.begin(); track!=tC1.end(); track++){
00207         i++;
00208         if ((short unsigned)track->ndof() < 1){
00209           selected1[i]=0; 
00210           //std::cout << "L1Track "<< i << " rejected in SimpleTrackListMerger; ndof() < 1" << std::endl ;
00211           continue;
00212         }
00213         if (track->normalizedChi2() > maxNormalizedChisq){
00214           selected1[i]=0; 
00215           //std::cout << "L1Track "<< i << " rejected in SimpleTrackListMerger; normalizedChi2() > maxNormalizedChisq " << track->normalizedChi2() << " " << maxNormalizedChisq << std::endl ;
00216           continue;
00217         }
00218         if (track->found() < minFound){
00219           selected1[i]=0; 
00220           //std::cout << "L1Track "<< i << " rejected in SimpleTrackListMerger; found() < minFound " << track->found() << " " << minFound << std::endl ;
00221           continue;
00222         }
00223         if (track->pt() < minPT){
00224           selected1[i]=0; 
00225           //std::cout << "L1Track "<< i << " rejected in SimpleTrackListMerger; pt() < minPT " << track->pt() << " " << minPT << std::endl ;
00226           continue;
00227         }
00228       }//end loop over tracks
00229    }//end more than 0 track
00230 
00231 
00232     std::vector<int> selected2; for (unsigned int i=0; i<tC2.size(); ++i){selected2.push_back(1);}
00233 
00234    if ( 0<tC2.size() ){
00235       i=-1;
00236       for (reco::TrackCollection::const_iterator track=tC2.begin(); track!=tC2.end(); track++){
00237         i++;
00238         if ((short unsigned)track->ndof() < 1){
00239           selected2[i]=0; 
00240           //std::cout << "L2Track "<< i << " rejected in SimpleTrackListMerger; ndof() < 1" << std::endl ;
00241           continue;
00242         }
00243         if (track->normalizedChi2() > maxNormalizedChisq){
00244           selected2[i]=0; 
00245           //std::cout << "L2Track "<< i << " rejected in SimpleTrackListMerger; normalizedChi2() > maxNormalizedChisq " << track->normalizedChi2() << " " << maxNormalizedChisq << std::endl ;
00246           continue;
00247         }
00248         if (track->found() < minFound){
00249           selected2[i]=0; 
00250           //std::cout << "L2Track "<< i << " rejected in SimpleTrackListMerger; found() < minFound " << track->found() << " " << minFound << std::endl ;
00251           continue;
00252         }
00253         if (track->pt() < minPT){
00254           selected2[i]=0; 
00255           //std::cout << "L2Track "<< i << " rejected in SimpleTrackListMerger; pt() < minPT " << track->pt() << " " << minPT << std::endl ;
00256           continue;
00257         }
00258       }//end loop over tracks
00259    }//end more than 0 track
00260 
00261    std::map<reco::TrackCollection::const_iterator, std::vector<const TrackingRecHit*> > rh1;
00262    std::map<reco::TrackCollection::const_iterator, std::vector<const TrackingRecHit*> > rh2;
00263    for (reco::TrackCollection::const_iterator track=tC1.begin(); track!=tC1.end(); ++track){
00264      trackingRecHit_iterator itB = track->recHitsBegin();
00265      trackingRecHit_iterator itE = track->recHitsEnd();
00266      for (trackingRecHit_iterator it = itB;  it != itE; ++it) { 
00267        const TrackingRecHit* hit = &(**it);
00268        rh1[track].push_back(hit);
00269      }
00270    }
00271    for (reco::TrackCollection::const_iterator track=tC2.begin(); track!=tC2.end(); ++track){
00272      trackingRecHit_iterator jtB = track->recHitsBegin();
00273      trackingRecHit_iterator jtE = track->recHitsEnd();
00274      for (trackingRecHit_iterator jt = jtB;  jt != jtE; ++jt) { 
00275        const TrackingRecHit* hit = &(**jt);
00276        rh2[track].push_back(hit);
00277      }
00278    }
00279 
00280    if ( (0<tC1.size())&&(0<tC2.size()) ){
00281     i=-1;
00282     for (reco::TrackCollection::const_iterator track=tC1.begin(); track!=tC1.end(); ++track){
00283       i++; 
00284       if (!selected1[i])continue;
00285       std::vector<const TrackingRecHit*>& iHits = rh1[track]; 
00286       unsigned nh1 = iHits.size();
00287       int qualityMaskT1 = track->qualityMask();
00288       int j=-1;
00289       for (reco::TrackCollection::const_iterator track2=tC2.begin(); track2!=tC2.end(); ++track2){
00290         j++;
00291         if ((!selected2[j])||(!selected1[i]))continue;
00292         std::vector<const TrackingRecHit*>& jHits = rh2[track2]; 
00293         unsigned nh2 = jHits.size();
00294         int noverlap=0;
00295         int firstoverlap=0;
00296         for ( unsigned ih=0; ih<nh1; ++ih ) { 
00297           const TrackingRecHit* it = iHits[ih];
00298           if (it->isValid()){
00299             int jj=-1;
00300             for ( unsigned jh=0; jh<nh2; ++jh ) { 
00301               const TrackingRecHit* jt = jHits[jh];
00302               jj++;
00303               if (jt->isValid()){
00304                if (!use_sharesInput){
00305                 float delta = fabs ( it->localPosition().x()-jt->localPosition().x() ); 
00306                 if ((it->geographicalId()==jt->geographicalId())&&(delta<epsilon)) {
00307                   noverlap++;
00308                   if ( allowFirstHitShare && ( ih == 0 ) && ( jh == 0 ) ) firstoverlap=1;
00309                 }
00310                }else{
00311                 if ( it->sharesInput(jt,TrackingRecHit::some) ) {
00312                   noverlap++;
00313                   if ( allowFirstHitShare && ( ih == 0 ) && ( jh == 0 ) ) firstoverlap=1;
00314                 }
00315                }
00316               }
00317             }
00318           }
00319         }
00320         int newQualityMask = (qualityMaskT1 | track2->qualityMask()); // take OR of trackQuality 
00321         int nhit1 = track->numberOfValidHits();
00322         int nhit2 = track2->numberOfValidHits();
00323         //std::cout << " trk1 trk2 nhits1 nhits2 nover " << i << " " << j << " " << track->numberOfValidHits() << " "  << track2->numberOfValidHits() << " " << noverlap << " " << fi << " " << fj  <<std::endl;
00324         if ( (noverlap-firstoverlap) > (std::min(nhit1,nhit2)-firstoverlap)*shareFrac ) {
00325           if ( nhit1 > nhit2 ){
00326             selected2[j]=0; 
00327             selected1[i]=10+newQualityMask; // add 10 to avoid the case where mask = 1
00328             //std::cout << " removing L2 trk in pair " << std::endl;
00329           }else{
00330             if ( nhit1 < nhit2 ){
00331               selected1[i]=0; 
00332               selected2[j]=10+newQualityMask;  // add 10 to avoid the case where mask = 1
00333               //std::cout << " removing L1 trk in pair " << std::endl;
00334             }else{
00335               //std::cout << " removing worst chisq in pair " << track->normalizedChi2() << " " << track2->normalizedChi2() << std::endl;
00336               const double almostSame = 1.001;
00337               if (track->normalizedChi2() > almostSame * track2->normalizedChi2()) {
00338                 selected1[i]=0;
00339                 selected2[j]=10+newQualityMask; // add 10 to avoid the case where mask = 1
00340               }else if (track2->normalizedChi2() > almostSame * track->normalizedChi2()) {
00341                 selected2[j]=0;
00342                 selected1[i]=10+newQualityMask; // add 10 to avoid the case where mask = 1
00343               }else{
00344                 // If tracks from both iterations are virtually identical, choose the one from the first iteration.
00345                 //              std::cout<<"MERGE "<<track->algo()<<" "<<track2->algo()<<" "<<track->normalizedChi2()<<" "<<track2->normalizedChi2()<<" "<<(track->normalizedChi2()-track2->normalizedChi2())/track->normalizedChi2()<<std::endl;
00346                 if (track->algo() <= track2->algo()) {
00347                   selected2[j]=0;
00348                   selected1[i]=10+newQualityMask; // add 10 to avoid the case where mask = 1
00349                 }else{
00350                   selected1[i]=0;
00351                   selected2[j]=10+newQualityMask; // add 10 to avoid the case where mask = 1
00352                 }
00353               }
00354             }//end fi > or = fj
00355           }//end fi < fj
00356         }//end got a duplicate
00357       }//end track2 loop
00358     }//end track loop
00359    }//end more than 1 track
00360 
00361   //
00362   //  output selected tracks - if any
00363   //
00364    trackRefs.resize(tC1.size()+tC2.size());
00365    std::vector<edm::RefToBase<TrajectorySeed> > seedsRefs(tC1.size()+tC2.size());
00366    size_t current = 0;
00367 
00368    if ( 0<tC1.size() ){
00369      i=0;
00370      for (reco::TrackCollection::const_iterator track=tC1.begin(); track!=tC1.end(); 
00371           ++track, ++current, ++i){
00372       if (!selected1[i]){
00373         trackRefs[current] = reco::TrackRef();
00374         continue;
00375       }
00376       const reco::Track & theTrack = * track;
00377       //fill the TrackCollection
00378       outputTrks->push_back( reco::Track( theTrack ) );
00379       if (selected1[i]>1 && promoteQuality){
00380         outputTrks->back().setQualityMask(selected1[i]-10);
00381         outputTrks->back().setQuality(qualityToSet);
00382       }
00383       if (copyExtras_) {
00384           //--------NEW----------
00385           edm::RefToBase<TrajectorySeed> origSeedRef = theTrack.seedRef();
00386           //creating a seed with rekeyed clusters if required
00387           if (makeReKeyedSeeds_){
00388             bool doRekeyOnThisSeed=false;
00389             
00390             edm::InputTag clusterRemovalInfos("");
00391             //grab on of the hits of the seed
00392             if (origSeedRef->nHits()!=0){
00393               TrajectorySeed::const_iterator firstHit=origSeedRef->recHits().first;
00394               const TrackingRecHit *hit = &*firstHit;
00395               if (firstHit->isValid()){
00396                 edm::ProductID  pID=clusterProduct(hit);
00397                 // the cluster collection either produced a removalInfo or mot
00398                 //get the clusterremoval info from the provenance: will rekey if this is found
00399                 edm::Handle<reco::ClusterRemovalInfo> CRIh;
00400                 edm::Provenance prov=e.getProvenance(pID);
00401                 clusterRemovalInfos=edm::InputTag(prov.moduleLabel(),
00402                                                   prov.productInstanceName(),
00403                                                   prov.processName());
00404                 doRekeyOnThisSeed=e.getByLabel(clusterRemovalInfos,CRIh);
00405               }//valid hit
00406             }//nhit!=0
00407             
00408             if (doRekeyOnThisSeed && !(clusterRemovalInfos==edm::InputTag("")))
00409               {
00410                 ClusterRemovalRefSetter refSetter(e,clusterRemovalInfos);
00411                 TrajectorySeed::recHitContainer  newRecHitContainer;
00412                 newRecHitContainer.reserve(origSeedRef->nHits());
00413                 TrajectorySeed::const_iterator iH=origSeedRef->recHits().first;
00414                 TrajectorySeed::const_iterator iH_end=origSeedRef->recHits().second;
00415                 for (;iH!=iH_end;++iH){
00416                   newRecHitContainer.push_back(*iH);
00417                   refSetter.reKey(&newRecHitContainer.back());
00418                 }
00419                 outputSeeds->push_back( TrajectorySeed( origSeedRef->startingState(),
00420                                                         newRecHitContainer,
00421                                                         origSeedRef->direction()));
00422               }
00423             //doRekeyOnThisSeed=true
00424             else{
00425               //just copy the one we had before
00426               outputSeeds->push_back( TrajectorySeed(*origSeedRef));
00427             }
00428             edm::Ref<TrajectorySeedCollection> pureRef(refTrajSeeds, outputSeeds->size()-1);
00429             origSeedRef=edm::RefToBase<TrajectorySeed>( pureRef);
00430           }//creating a new seed and rekeying it rechit clusters.
00431           //--------NEW----------
00432           // Fill TrackExtra collection
00433           outputTrkExtras->push_back( reco::TrackExtra( 
00434                         theTrack.outerPosition(), theTrack.outerMomentum(), theTrack.outerOk(),
00435                         theTrack.innerPosition(), theTrack.innerMomentum(), theTrack.innerOk(),
00436                         theTrack.outerStateCovariance(), theTrack.outerDetId(),
00437                         theTrack.innerStateCovariance(), theTrack.innerDetId(),
00438                         theTrack.seedDirection(), origSeedRef ) );
00439           seedsRefs[current]=origSeedRef;
00440           outputTrks->back().setExtra( reco::TrackExtraRef( refTrkExtras, outputTrkExtras->size() - 1) );
00441           reco::TrackExtra & tx = outputTrkExtras->back();
00442           tx.setResiduals(theTrack.residuals());
00443           // fill TrackingRecHits
00444           std::vector<const TrackingRecHit*>& iHits = rh1[track]; 
00445           unsigned nh1 = iHits.size();
00446           for ( unsigned ih=0; ih<nh1; ++ih ) { 
00447             const TrackingRecHit* hit = iHits[ih];
00448             //for( trackingRecHit_iterator hit = itB; hit != itE; ++hit ) {
00449             outputTrkHits->push_back( hit->clone() );
00450             tx.add( TrackingRecHitRef( refTrkHits, outputTrkHits->size() - 1) );
00451           }
00452       }
00453       trackRefs[current] = reco::TrackRef(refTrks, outputTrks->size() - 1);
00454     
00455 
00456     }//end faux loop over tracks
00457    }//end more than 0 track
00458 
00459    //Fill the trajectories, etc. for 1st collection
00460    edm::Handle< std::vector<Trajectory> > hTraj1;
00461    e.getByLabel(trackProducer1, hTraj1);
00462    edm::Handle< TrajTrackAssociationCollection > hTTAss1;
00463    e.getByLabel(trackProducer1, hTTAss1);
00464    refTrajs    = e.getRefBeforePut< std::vector<Trajectory> >();
00465 
00466    if (!hTraj1.failedToGet() && !hTTAss1.failedToGet()){
00467    for (size_t i = 0, n = hTraj1->size(); i < n; ++i) {
00468      edm::Ref< std::vector<Trajectory> > trajRef(hTraj1, i);
00469      TrajTrackAssociationCollection::const_iterator match = hTTAss1->find(trajRef);
00470      if (match != hTTAss1->end()) {
00471        const edm::Ref<reco::TrackCollection> &trkRef = match->val; 
00472        short oldKey = static_cast<short>(trkRef.key());
00473        if (trackRefs[oldKey].isNonnull()) {
00474          outputTrajs->push_back( *trajRef );
00475          //if making extras and the seeds at the same time, change the seed ref on the trajectory
00476          if (copyExtras_ && makeReKeyedSeeds_)
00477              outputTrajs->back().setSeedRef( seedsRefs[oldKey] );
00478          outputTTAss->insert ( edm::Ref< std::vector<Trajectory> >(refTrajs, outputTrajs->size() - 1), 
00479                                trackRefs[oldKey] );
00480        }
00481      }
00482    }
00483    }
00484 
00485    short offset = current; //save offset into trackRefs
00486 
00487    if ( 0<tC2.size() ){
00488     i=0;
00489     for (reco::TrackCollection::const_iterator track=tC2.begin(); track!=tC2.end();
00490          ++track, ++current, ++i){
00491       if (!selected2[i]){
00492         trackRefs[current] = reco::TrackRef();
00493         continue;
00494       }
00495       const reco::Track & theTrack = * track;
00496       //fill the TrackCollection
00497       outputTrks->push_back( reco::Track( theTrack ) );
00498       if (selected2[i]>1 && promoteQuality){
00499         outputTrks->back().setQualityMask(selected2[i]-10);
00500         outputTrks->back().setQuality(qualityToSet);
00501       }
00502       if (copyExtras_) {
00503           //--------NEW----------
00504           edm::RefToBase<TrajectorySeed> origSeedRef = theTrack.seedRef();
00505           //creating a seed with rekeyed clusters if required
00506           if (makeReKeyedSeeds_){
00507             bool doRekeyOnThisSeed=false;
00508             
00509             edm::InputTag clusterRemovalInfos("");
00510             //grab on of the hits of the seed
00511             if (origSeedRef->nHits()!=0){
00512               TrajectorySeed::const_iterator firstHit=origSeedRef->recHits().first;
00513               const TrackingRecHit *hit = &*firstHit;
00514               if (firstHit->isValid()){
00515                 edm::ProductID  pID=clusterProduct(hit);
00516                 // the cluster collection either produced a removalInfo or mot
00517                 //get the clusterremoval info from the provenance: will rekey if this is found
00518                 edm::Handle<reco::ClusterRemovalInfo> CRIh;
00519                 edm::Provenance prov=e.getProvenance(pID);
00520                 clusterRemovalInfos=edm::InputTag(prov.moduleLabel(),
00521                                                   prov.productInstanceName(),
00522                                                   prov.processName());
00523                 doRekeyOnThisSeed=e.getByLabel(clusterRemovalInfos,CRIh);
00524               }//valid hit
00525             }//nhit!=0
00526             
00527             if (doRekeyOnThisSeed && !(clusterRemovalInfos==edm::InputTag("")))
00528               {
00529                 ClusterRemovalRefSetter refSetter(e,clusterRemovalInfos);
00530                 TrajectorySeed::recHitContainer  newRecHitContainer;
00531                 newRecHitContainer.reserve(origSeedRef->nHits());
00532                 TrajectorySeed::const_iterator iH=origSeedRef->recHits().first;
00533                 TrajectorySeed::const_iterator iH_end=origSeedRef->recHits().second;
00534                 for (;iH!=iH_end;++iH){
00535                   newRecHitContainer.push_back(*iH);
00536                   refSetter.reKey(&newRecHitContainer.back());
00537                 }
00538                 outputSeeds->push_back( TrajectorySeed( origSeedRef->startingState(),
00539                                                         newRecHitContainer,
00540                                                         origSeedRef->direction()));
00541               }//doRekeyOnThisSeed=true
00542               else{
00543                 //just copy the one we had before
00544                 outputSeeds->push_back( TrajectorySeed(*origSeedRef));
00545               }
00546             edm::Ref<TrajectorySeedCollection> pureRef(refTrajSeeds, outputSeeds->size()-1);
00547             origSeedRef=edm::RefToBase<TrajectorySeed>( pureRef);
00548           }//creating a new seed and rekeying it rechit clusters.
00549           //--------NEW----------
00550           // Fill TrackExtra collection
00551           outputTrkExtras->push_back( reco::TrackExtra( 
00552                         theTrack.outerPosition(), theTrack.outerMomentum(), theTrack.outerOk(),
00553                         theTrack.innerPosition(), theTrack.innerMomentum(), theTrack.innerOk(),
00554                         theTrack.outerStateCovariance(), theTrack.outerDetId(),
00555                         theTrack.innerStateCovariance(), theTrack.innerDetId(),
00556                         theTrack.seedDirection(), origSeedRef ) );
00557           seedsRefs[current]=origSeedRef;
00558           outputTrks->back().setExtra( reco::TrackExtraRef( refTrkExtras, outputTrkExtras->size() - 1) );
00559           reco::TrackExtra & tx = outputTrkExtras->back();
00560           tx.setResiduals(theTrack.residuals());
00561           // fill TrackingRecHits
00562           std::vector<const TrackingRecHit*>& jHits = rh2[track]; 
00563           unsigned nh2 = jHits.size();
00564           for ( unsigned jh=0; jh<nh2; ++jh ) { 
00565             const TrackingRecHit* hit = jHits[jh];
00566             outputTrkHits->push_back( hit->clone() );
00567             tx.add( TrackingRecHitRef( refTrkHits, outputTrkHits->size() - 1) );
00568           }
00569       }
00570       trackRefs[current] = reco::TrackRef(refTrks, outputTrks->size() - 1);
00571 
00572     }//end faux loop over tracks
00573    }//end more than 0 track
00574 
00575    //Fill the trajectories, etc. for 2nd collection
00576    edm::Handle< std::vector<Trajectory> > hTraj2;
00577    e.getByLabel(trackProducer2, hTraj2);
00578    edm::Handle< TrajTrackAssociationCollection > hTTAss2;
00579    e.getByLabel(trackProducer2, hTTAss2);
00580 
00581    if (!hTraj2.failedToGet() && !hTTAss2.failedToGet()){
00582    for (size_t i = 0, n = hTraj2->size(); i < n; ++i) {
00583      edm::Ref< std::vector<Trajectory> > trajRef(hTraj2, i);
00584      TrajTrackAssociationCollection::const_iterator match = hTTAss2->find(trajRef);
00585      if (match != hTTAss2->end()) {
00586        const edm::Ref<reco::TrackCollection> &trkRef = match->val; 
00587        short oldKey = static_cast<short>(trkRef.key()) + offset;
00588        if (trackRefs[oldKey].isNonnull()) {
00589            outputTrajs->push_back( Trajectory(*trajRef) );
00590            //if making extras and the seeds at the same time, change the seed ref on the trajectory
00591            if (copyExtras_ && makeReKeyedSeeds_)
00592              outputTrajs->back().setSeedRef( seedsRefs[oldKey] );
00593            outputTTAss->insert ( edm::Ref< std::vector<Trajectory> >(refTrajs, outputTrajs->size() - 1), 
00594                    trackRefs[oldKey] ); 
00595        }
00596      }
00597    }}
00598 
00599     e.put(outputTrks);
00600     if (copyExtras_) {
00601         e.put(outputTrkExtras);
00602         e.put(outputTrkHits);
00603         if (makeReKeyedSeeds_)
00604           e.put(outputSeeds);
00605     }
00606     e.put(outputTrajs);
00607     e.put(outputTTAss);
00608     return;
00609 
00610   }//end produce
00611 }