CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 //
00002 // Package:         RecoTracker/FinalTrackSelectors
00003 // Class:           TrackListMerger
00004 // 
00005 // Description:     TrackList Cleaner and Merger able to deal with many lists
00006 //
00007 // Original Author: David Lange
00008 // Created:         April 4, 2011
00009 //
00010 
00011 
00012 #include <memory>
00013 #include <string>
00014 #include <iostream>
00015 #include <cmath>
00016 #include <vector>
00017 
00018 #include "RecoTracker/FinalTrackSelectors/src/TrackListMerger.h"
00019 
00020 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2DCollection.h"
00021 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit2DCollection.h"
00022 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit1DCollection.h"
00023 #include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h"
00024 #include "DataFormats/TrackCandidate/interface/TrackCandidateCollection.h"
00025 #include "DataFormats/Common/interface/ValueMap.h"
00026 #include "FWCore/Framework/interface/ESHandle.h"
00027 
00028 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00029 
00030 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00031 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00032 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00033 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00034 
00035 //#include "DataFormats/TrackReco/src/classes.h"
00036 
00037 #include "RecoTracker/TrackProducer/interface/ClusterRemovalRefSetter.h"
00038 
00039 #ifdef STAT_TSB
00040 #include <x86intrin.h>
00041 #endif
00042 
00043 namespace {
00044 #ifdef STAT_TSB
00045 inline volatile unsigned long long rdtsc() {
00046  return __rdtsc();
00047 }
00048 
00049   struct StatCount {
00050     float maxDP=0.;
00051     float maxDE=0.;
00052     unsigned long long st;
00053     long long totBegin=0;
00054     long long totPre=0;
00055     long long totEnd=0;
00056     unsigned long long timeNo;  // no-overlap
00057     unsigned long long timeOv;  // overlap
00058     void begin(int tt) {
00059       totBegin+=tt;
00060     }
00061     void start() { st=rdtsc(); }
00062     void noOverlap() { timeNo += (rdtsc()-st);}
00063     void overlap() { timeOv += (rdtsc()-st);}
00064     void pre(int tt) { totPre+=tt;}
00065     void end(int tt) { totEnd+=tt;}
00066     void de(float d) { if (d>maxDE) maxDE=d;}
00067     void dp(float d) { if (d>maxDP) maxDP=d;}
00068 
00069 
00070     void print() const {
00071       std::cout << "TrackListMerger stat\nBegin/Pre/End/maxDPhi/maxDEta/Overlap/NoOverlap "
00072                 <<  totBegin <<'/'<< totPre <<'/'<< totEnd <<'/'<< maxDP <<'/'<< maxDE 
00073                 <<'/'<< timeOv/1000 <<'/'<< timeNo/1000
00074                 << std::endl;
00075     }
00076     StatCount() {}
00077     ~StatCount() { print();}
00078   };
00079 
00080 #else
00081   struct StatCount {
00082     void begin(int){}
00083     void pre(int){}
00084     void end(int){}
00085     void start(){}
00086     void noOverlap(){}
00087     void overlap(){}
00088     void de(float){}
00089     void dp(float){}
00090 
00091 
00092   };
00093 #endif
00094 
00095   StatCount statCount;
00096 
00097 }
00098 
00099 
00100 
00101 namespace cms
00102 {
00103   
00104   edm::ProductID clusterProductB( const TrackingRecHit *hit){
00105     return reinterpret_cast<const BaseTrackerRecHit *>(hit)->firstClusterRef().id();
00106   }
00107   
00108 
00109 
00110   TrackListMerger::TrackListMerger(edm::ParameterSet const& conf) {
00111     copyExtras_ = conf.getUntrackedParameter<bool>("copyExtras", true);
00112     
00113     trackProducers_ = conf.getParameter<std::vector<edm::InputTag> >("TrackProducers");
00114     //which of these do I need to turn into vectors?
00115     maxNormalizedChisq_ =  conf.getParameter<double>("MaxNormalizedChisq");
00116     minPT_ =  conf.getParameter<double>("MinPT");
00117     minFound_ = (unsigned int)conf.getParameter<int>("MinFound");
00118     epsilon_ =  conf.getParameter<double>("Epsilon");
00119     shareFrac_ =  conf.getParameter<double>("ShareFrac");
00120     allowFirstHitShare_ = conf.getParameter<bool>("allowFirstHitShare");
00121     foundHitBonus_ = conf.getParameter<double>("FoundHitBonus");
00122     lostHitPenalty_ = conf.getParameter<double>("LostHitPenalty");
00123     indivShareFrac_=conf.getParameter<std::vector<double> >("indivShareFrac");
00124     std::string qualityStr = conf.getParameter<std::string>("newQuality");
00125     
00126     if (qualityStr != "") {
00127       qualityToSet_ = reco::TrackBase::qualityByName(conf.getParameter<std::string>("newQuality"));
00128     }
00129     else 
00130       qualityToSet_ = reco::TrackBase::undefQuality;
00131     
00132     use_sharesInput_ = true;
00133     if ( epsilon_ > 0.0 )use_sharesInput_ = false;
00134     
00135     edm::VParameterSet setsToMerge=conf.getParameter<edm::VParameterSet>("setsToMerge");
00136     
00137     for ( unsigned int i=0; i<setsToMerge.size(); i++) { 
00138       listsToMerge_.push_back(setsToMerge[i].getParameter<std::vector< int> >("tLists"));   
00139       promoteQuality_.push_back(setsToMerge[i].getParameter<bool>("pQual"));   
00140     }
00141     
00142     hasSelector_=conf.getParameter<std::vector<int> >("hasSelector");
00143     selectors_=conf.getParameter<std::vector<edm::InputTag> >("selectedTrackQuals");   
00144     if(conf.exists("mvaValueTags")){
00145       mvaStores_ = conf.getParameter<std::vector<edm::InputTag> >("mvaValueTags");
00146     }else{
00147       std::vector<edm::InputTag> mvaValueTags;
00148       for (int i = 0; i < (int)selectors_.size(); i++){
00149         edm::InputTag ntag(selectors_[i].label(),"MVAVals");
00150         mvaValueTags.push_back(ntag);
00151       }
00152 
00153       mvaStores_ = mvaValueTags;
00154     }
00155     unsigned int numTrkColl = trackProducers_.size();
00156     if (numTrkColl != hasSelector_.size() || numTrkColl != selectors_.size()) {
00157         throw cms::Exception("Inconsistent size") << "need same number of track collections and selectors";
00158     }
00159     if (numTrkColl != hasSelector_.size() || numTrkColl != mvaStores_.size()) {
00160         throw cms::Exception("Inconsistent size") << "need same number of track collections and MVA stores";
00161     }
00162     for (unsigned int i = indivShareFrac_.size(); i < numTrkColl; i++) {
00163       //      edm::LogWarning("TrackListMerger") << "No indivShareFrac for " << trackProducers_[i] <<". Using default value of 1";
00164       indivShareFrac_.push_back(1.0);
00165     }
00166 
00167     trkQualMod_=conf.getParameter<bool>("writeOnlyTrkQuals");
00168     if ( trkQualMod_) {
00169       bool ok=true;
00170       for ( unsigned int i=1; i<numTrkColl; i++) {
00171         if (!(trackProducers_[i]==trackProducers_[0])) ok=false;
00172       }
00173       if ( !ok) {
00174         throw cms::Exception("Bad input") << "to use writeOnlyTrkQuals=True all input InputTags must be the same";
00175       }
00176       produces<edm::ValueMap<int> >();
00177     }
00178     else{
00179       produces<reco::TrackCollection>();
00180       
00181       makeReKeyedSeeds_ = conf.getUntrackedParameter<bool>("makeReKeyedSeeds",false);
00182       if (makeReKeyedSeeds_){
00183         copyExtras_=true;
00184         produces<TrajectorySeedCollection>();
00185       }
00186       
00187       if (copyExtras_) {
00188         produces<reco::TrackExtraCollection>();
00189         produces<TrackingRecHitCollection>();
00190       }
00191       produces< std::vector<Trajectory> >();
00192       produces< TrajTrackAssociationCollection >();
00193     }
00194     produces<edm::ValueMap<float> >("MVAVals");
00195     
00196   }
00197   
00198   
00199   // Virtual destructor needed.
00200   TrackListMerger::~TrackListMerger() { }  
00201   
00202   // Functions that gets called by framework every event
00203   void TrackListMerger::produce(edm::Event& e, const edm::EventSetup& es)
00204   {
00205     // extract tracker geometry
00206     //
00207     //edm::ESHandle<TrackerGeometry> theG;
00208     //es.get<TrackerDigiGeometryRecord>().get(theG);
00209     
00210     //    using namespace reco;
00211     
00212     // get Inputs 
00213     // if 1 input list doesn't exist, make an empty list, issue a warning, and continue
00214     // this allows TrackListMerger to be used as a cleaner only if handed just one list
00215     // if both input lists don't exist, will issue 2 warnings and generate an empty output collection
00216     // 
00217     static const reco::TrackCollection s_empty;
00218     
00219     std::vector<const reco::TrackCollection *> trackColls;
00220     std::vector<edm::Handle<reco::TrackCollection> > trackHandles(trackProducers_.size());
00221     for ( unsigned int i=0; i<trackProducers_.size(); i++) {
00222       trackColls.push_back(0);
00223       //edm::Handle<reco::TrackCollection> trackColl;
00224       e.getByLabel(trackProducers_[i], trackHandles[i]);
00225       if (trackHandles[i].isValid()) {
00226         trackColls[i]= trackHandles[i].product();
00227       } else {
00228         edm::LogWarning("TrackListMerger") << "TrackCollection " << trackProducers_[i] <<" not found";
00229         trackColls[i]=&s_empty;
00230       }
00231     }
00232     
00233     unsigned int collsSize =trackColls.size();
00234     unsigned int rSize=0;
00235     unsigned int trackCollSizes[collsSize];
00236     unsigned int trackCollFirsts[collsSize];
00237     for (unsigned int i=0; i!=collsSize; i++) {
00238       trackCollSizes[i]=trackColls[i]->size();
00239       trackCollFirsts[i]=rSize;
00240       rSize+=trackCollSizes[i];
00241     }
00242     
00243     statCount.begin(rSize);
00244 
00245     //
00246     //  quality cuts first
00247     // 
00248     int i=-1;
00249     
00250     int selected[rSize];
00251     int indexG[rSize];
00252     bool trkUpdated[rSize]; 
00253     int trackCollNum[rSize];
00254     int trackQuals[rSize];
00255     float trackMVAs[rSize];
00256     for (unsigned int j=0; j<rSize;j++) {
00257       indexG[j]=-1; selected[j]=1; trkUpdated[j]=false; trackCollNum[j]=0; trackQuals[j]=0;trackMVAs[j] = -99.0;
00258     }
00259 
00260     int ngood=0;
00261     for (unsigned int j=0; j!= collsSize; j++) {
00262       const reco::TrackCollection *tC1=trackColls[j];
00263       
00264       edm::Handle<edm::ValueMap<int> > trackSelColl;
00265       edm::Handle<edm::ValueMap<float> > trackMVAStore;
00266       e.getByLabel(mvaStores_[j], trackMVAStore);
00267       if ( hasSelector_[j]>0 ){
00268         e.getByLabel(selectors_[j], trackSelColl);
00269       }
00270       
00271       if ( 0<tC1->size() ){
00272         unsigned int iC=0;
00273         for (reco::TrackCollection::const_iterator track=tC1->begin(); track!=tC1->end(); track++){
00274           i++; 
00275           trackCollNum[i]=j;
00276           trackQuals[i]=track->qualityMask();
00277 
00278           reco::TrackRef trkRef=reco::TrackRef(trackHandles[j],iC);
00279           if((*trackMVAStore).contains(trkRef.id()))trackMVAs[i] = (*trackMVAStore)[trkRef];
00280           if ( hasSelector_[j]>0 ) {
00281             int qual=(*trackSelColl)[trkRef];
00282             if ( qual < 0 ) {
00283               selected[i]=0;
00284               iC++;
00285               continue;
00286             }else{
00287               trackQuals[i]=qual;
00288             }
00289           }
00290           iC++;
00291           selected[i]=trackQuals[i]+10;//10 is magic number used throughout...
00292           if ((short unsigned)track->ndof() < 1){
00293             selected[i]=0; 
00294             continue;
00295           }
00296           if (track->normalizedChi2() > maxNormalizedChisq_){
00297             selected[i]=0; 
00298             continue;
00299           }
00300           if (track->found() < minFound_){
00301             selected[i]=0; 
00302             continue;
00303           }
00304           if (track->pt() < minPT_){
00305             selected[i]=0; 
00306             continue;
00307           }
00308           // good!
00309           indexG[i] = ngood++;
00310           //if ( beVerb) std::cout << "inverb " << track->pt() << " " << selected[i] << std::endl;
00311         }//end loop over tracks
00312       }//end more than 0 track
00313     } // loop over trackcolls
00314     
00315     
00316     statCount.pre(ngood);    
00317 
00318     //cache the id and rechits of valid hits
00319     typedef std::pair<unsigned int, const TrackingRecHit*> IHit;
00320     std::vector<IHit> rh1[ngood];  // an array of vectors!
00321     //const TrackingRecHit*  fh1[ngood];  // first hit...
00322     unsigned char algo[ngood];
00323     float score[ngood];
00324 
00325  
00326     for ( unsigned int j=0; j<rSize; j++) {
00327       if (selected[j]==0) continue;
00328       int i = indexG[j];
00329       assert(i>=0);
00330       unsigned int collNum=trackCollNum[j];
00331       unsigned int trackNum=j-trackCollFirsts[collNum];
00332       const reco::Track *track=&((trackColls[collNum])->at(trackNum)); 
00333 
00334       algo[i]=track->algo();
00335       int validHits=track->numberOfValidHits();
00336       int lostHits=track->numberOfLostHits();
00337       score[i] = foundHitBonus_*validHits - lostHitPenalty_*lostHits - track->chi2();
00338 
00339  
00340       rh1[i].reserve(validHits) ; 
00341       auto compById = [](IHit const &  h1, IHit const & h2) {return h1.first < h2.first;};
00342       // fh1[i] = &(**track->recHitsBegin());
00343       for (trackingRecHit_iterator it = track->recHitsBegin();  it != track->recHitsEnd(); ++it) { 
00344         const TrackingRecHit* hit = &(**it);  
00345         unsigned int id = hit->rawId() ;
00346         if(hit->geographicalId().subdetId()>2)  id &= (~3); // mask mono/stereo in strips...
00347         if likely(hit->isValid()) { rh1[i].emplace_back(id,hit); std::push_heap(rh1[i].begin(),rh1[i].end(),compById); }
00348       }
00349       std::sort_heap(rh1[i].begin(),rh1[i].end(),compById);
00350     }
00351     
00352     //DL here
00353     if likely(ngood>1 && collsSize>1)
00354     for ( unsigned int ltm=0; ltm<listsToMerge_.size(); ltm++) {
00355       int saveSelected[rSize];
00356       bool notActive[collsSize];
00357       for (unsigned int cn=0;cn!=collsSize;++cn)
00358         notActive[cn]= find(listsToMerge_[ltm].begin(),listsToMerge_[ltm].end(),cn)==listsToMerge_[ltm].end();
00359 
00360       for ( unsigned int i=0; i<rSize; i++) saveSelected[i]=selected[i];
00361       
00362       //DL protect against 0 tracks? 
00363       for ( unsigned int i=0; i<rSize-1; i++) {
00364         if (selected[i]==0) continue;
00365         unsigned int collNum=trackCollNum[i];
00366         
00367         //check that this track is in one of the lists for this iteration
00368         if (notActive[collNum]) continue;
00369 
00370         int k1 = indexG[i];
00371         unsigned int nh1=rh1[k1].size();
00372         int qualityMaskT1 = trackQuals[i];
00373         
00374         int nhit1 = nh1; // validHits[k1];
00375         float score1 = score[k1];
00376 
00377         // start at next collection
00378         for ( unsigned int j=i+1; j<rSize; j++) {
00379           if (selected[j]==0) continue;
00380           unsigned int collNum2=trackCollNum[j];
00381           if ( (collNum == collNum2) && indivShareFrac_[collNum] > 0.99) continue;
00382           //check that this track is in one of the lists for this iteration
00383           if (notActive[collNum2]) continue;
00384 
00385           int k2 = indexG[j];
00386                   
00387           int newQualityMask = -9; //avoid resetting quality mask if not desired 10+ -9 =1
00388           if (promoteQuality_[ltm]) {
00389             int maskT1= saveSelected[i]>1? saveSelected[i]-10 : qualityMaskT1;
00390             int maskT2= saveSelected[j]>1? saveSelected[j]-10 : trackQuals[j];
00391             newQualityMask =(maskT1 | maskT2); // take OR of trackQuality 
00392           }
00393           unsigned int nh2=rh1[k2].size();
00394           int nhit2 = nh2; 
00395 
00396 
00397           auto share = use_sharesInput_ ? 
00398             [](const TrackingRecHit*  it,const TrackingRecHit*  jt, float)->bool { return it->sharesInput(jt,TrackingRecHit::some); } :
00399           [](const TrackingRecHit*  it,const TrackingRecHit*  jt, float eps)->bool {
00400             float delta = std::abs ( it->localPosition().x()-jt->localPosition().x() ); 
00401             return (it->geographicalId()==jt->geographicalId())&&(delta<eps);
00402           };
00403 
00404           statCount.start();
00405 
00406           //loop over rechits
00407           int noverlap=0;
00408           int firstoverlap=0;
00409           // check first hit  (should use REAL first hit?)
00410           if unlikely(allowFirstHitShare_ && rh1[k1][0].first==rh1[k2][0].first ) {
00411               const TrackingRecHit*  it = rh1[k1][0].second;
00412               const TrackingRecHit*  jt = rh1[k2][0].second;
00413               if (share(it,jt,epsilon_)) firstoverlap=1; 
00414             }
00415 
00416 
00417           // exploit sorting
00418           unsigned int jh=0;
00419           unsigned int ih=0;
00420           while (ih!=nh1 && jh!=nh2) {
00421             // break if not enough to go...
00422             // if ( nprecut-noverlap+firstoverlap > int(nh1-ih)) break;
00423             // if ( nprecut-noverlap+firstoverlap > int(nh2-jh)) break;
00424             auto const id1 = rh1[k1][ih].first; 
00425             auto const id2 = rh1[k2][jh].first; 
00426             if (id1<id2) ++ih;
00427             else if (id2<id1) ++jh;
00428             else {
00429               // in case of split-hit do full conbinatorics
00430               auto li=ih; while( (++li)!=nh1 && id1 == rh1[k1][li].first); 
00431               auto lj=jh; while( (++lj)!=nh2 && id2 == rh1[k2][lj].first);
00432               for (auto ii=ih; ii!=li; ++ii)
00433                 for (auto jj=jh; jj!=lj; ++jj) {
00434                   const TrackingRecHit*  it = rh1[k1][ii].second;
00435                   const TrackingRecHit*  jt = rh1[k2][jj].second;
00436                   if (share(it,jt,epsilon_))  noverlap++;
00437                 }
00438               jh=lj; ih=li;
00439             } // equal ids
00440             
00441           } //loop over ih & jh
00442           
00443           bool dupfound = (collNum != collNum2) ? (noverlap-firstoverlap) > (std::min(nhit1,nhit2)-firstoverlap)*shareFrac_ : 
00444             (noverlap-firstoverlap) > (std::min(nhit1,nhit2)-firstoverlap)*indivShareFrac_[collNum];
00445           
00446           if ( dupfound ) {
00447             float score2 = score[k2];
00448             constexpr float almostSame = 0.01f; // difference rather than ratio due to possible negative values for score
00449             if ( score1 - score2 > almostSame ) {
00450               selected[j]=0;
00451               selected[i]=10+newQualityMask; // add 10 to avoid the case where mask = 1
00452               trkUpdated[i]=true;
00453             } else if ( score2 - score1 > almostSame ) {
00454               selected[i]=0;
00455               selected[j]=10+newQualityMask;  // add 10 to avoid the case where mask = 1
00456               trkUpdated[j]=true;
00457             }else{
00458               // If tracks from both iterations are virtually identical, choose the one from the first iteration.
00459               if (algo[k1] <= algo[k2]) {
00460                 selected[j]=0;
00461                 selected[i]=10+newQualityMask; // add 10 to avoid the case where mask = 1
00462                 trkUpdated[i]=true;
00463               }else{
00464                 selected[i]=0;
00465                 selected[j]=10+newQualityMask; // add 10 to avoid the case where mask = 1
00466                 trkUpdated[j]=true;
00467               }
00468             }//end fi < fj
00469             statCount.overlap();
00470             /*
00471             if (at0[k1]&&at0[k2]) {
00472               statCount.dp(dphi);
00473               if (dz<1.f) statCount.de(deta);
00474             }
00475             */
00476           }//end got a duplicate
00477           else {
00478             statCount.noOverlap();
00479           }
00480           //stop if the ith track is now unselected
00481           if (selected[i]==0) break;
00482         }//end track2 loop
00483       }//end track loop
00484     } //end loop over track list sets
00485     
00486    
00487 
00488     std::auto_ptr<edm::ValueMap<float> > vmMVA = std::auto_ptr<edm::ValueMap<float> >(new edm::ValueMap<float>);
00489     edm::ValueMap<float>::Filler fillerMVA(*vmMVA);
00490 
00491 
00492     
00493     // special case - if just doing the trkquals 
00494     if (trkQualMod_) {
00495       unsigned int tSize=trackColls[0]->size();
00496       std::auto_ptr<edm::ValueMap<int> > vm = std::auto_ptr<edm::ValueMap<int> >(new edm::ValueMap<int>);
00497       edm::ValueMap<int>::Filler filler(*vm);
00498       
00499       std::vector<int> finalQuals(tSize,-1); //default is unselected
00500       for ( unsigned int i=0; i<rSize; i++) {
00501         unsigned int tNum=i%tSize;
00502         
00503         if (selected[i]>1 ) { 
00504           finalQuals[tNum]=selected[i]-10;
00505           if (trkUpdated[i])
00506             finalQuals[tNum]=(finalQuals[tNum] | (1<<qualityToSet_));
00507         }
00508         if ( selected[i]==1 )
00509           finalQuals[tNum]=trackQuals[i];
00510       }
00511       
00512       filler.insert(trackHandles[0], finalQuals.begin(),finalQuals.end());
00513       filler.fill();
00514       
00515       e.put(vm);
00516 
00517       std::vector<float> mvaVec(tSize,-99);
00518 
00519       for(unsigned int i = 0; i < rSize; i++){
00520         unsigned int tNum = i % tSize;
00521         mvaVec[tNum] = trackMVAs[tNum];
00522       }
00523 
00524       fillerMVA.insert(trackHandles[0],mvaVec.begin(),mvaVec.end());
00525       fillerMVA.fill();
00526       e.put(vmMVA,"MVAVals");
00527       return;
00528     }
00529     
00530     
00531     //
00532     //  output selected tracks - if any
00533     //
00534     
00535     reco::TrackRef trackRefs[rSize];
00536     edm::RefToBase<TrajectorySeed> seedsRefs[rSize];
00537     
00538     unsigned int nToWrite=0;
00539     for ( unsigned int i=0; i<rSize; i++) 
00540       if (selected[i]!=0) nToWrite++;
00541     
00542     std::vector<float> mvaVec;
00543     
00544     outputTrks = std::auto_ptr<reco::TrackCollection>(new reco::TrackCollection);
00545     outputTrks->reserve(nToWrite);
00546     refTrks = e.getRefBeforePut<reco::TrackCollection>();      
00547     
00548     if (copyExtras_) {
00549       outputTrkExtras = std::auto_ptr<reco::TrackExtraCollection>(new reco::TrackExtraCollection);
00550       outputTrkExtras->reserve(nToWrite);
00551       refTrkExtras    = e.getRefBeforePut<reco::TrackExtraCollection>();
00552       outputTrkHits   = std::auto_ptr<TrackingRecHitCollection>(new TrackingRecHitCollection);
00553       outputTrkHits->reserve(nToWrite*25);
00554       refTrkHits      = e.getRefBeforePut<TrackingRecHitCollection>();
00555       if (makeReKeyedSeeds_){
00556         outputSeeds = std::auto_ptr<TrajectorySeedCollection>(new TrajectorySeedCollection);
00557         outputSeeds->reserve(nToWrite);
00558         refTrajSeeds = e.getRefBeforePut<TrajectorySeedCollection>();
00559       }
00560     }
00561     
00562 
00563     outputTrajs = std::auto_ptr< std::vector<Trajectory> >(new std::vector<Trajectory>()); 
00564     outputTrajs->reserve(rSize);
00565     outputTTAss = std::auto_ptr< TrajTrackAssociationCollection >(new TrajTrackAssociationCollection());
00566     
00567     
00568     
00569     for ( unsigned int i=0; i<rSize; i++) {
00570       if (selected[i]==0) {
00571         trackRefs[i]=reco::TrackRef();
00572         continue;
00573       }
00574       
00575       unsigned int collNum=trackCollNum[i];
00576       unsigned int trackNum=i-trackCollFirsts[collNum];
00577       const reco::Track *track=&((trackColls[collNum])->at(trackNum)); 
00578       outputTrks->push_back( reco::Track( *track ) );
00579       mvaVec.push_back(trackMVAs[i]);
00580       if (selected[i]>1 ) { 
00581         outputTrks->back().setQualityMask(selected[i]-10);
00582         if (trkUpdated[i])
00583           outputTrks->back().setQuality(qualityToSet_);
00584       }
00585       //might duplicate things, but doesnt hurt
00586       if ( selected[i]==1 )
00587         outputTrks->back().setQualityMask(trackQuals[i]);
00588       
00589       // if ( beVerb ) std::cout << "selected " << outputTrks->back().pt() << " " << outputTrks->back().qualityMask() << " " << selected[i] << std::endl;
00590       
00591       //fill the TrackCollection
00592       if (copyExtras_) {
00593         edm::RefToBase<TrajectorySeed> origSeedRef = track->seedRef();
00594         //creating a seed with rekeyed clusters if required
00595         if (makeReKeyedSeeds_){
00596           bool doRekeyOnThisSeed=false;
00597           
00598           edm::InputTag clusterRemovalInfos("");
00599           //grab on of the hits of the seed
00600           if (origSeedRef->nHits()!=0){
00601             TrajectorySeed::const_iterator firstHit=origSeedRef->recHits().first;
00602             const TrackingRecHit *hit = &*firstHit;
00603             if (firstHit->isValid()){
00604               edm::ProductID  pID=clusterProductB(hit);
00605               // the cluster collection either produced a removalInfo or mot
00606               //get the clusterremoval info from the provenance: will rekey if this is found
00607               edm::Handle<reco::ClusterRemovalInfo> CRIh;
00608               edm::Provenance prov=e.getProvenance(pID);
00609               clusterRemovalInfos=edm::InputTag(prov.moduleLabel(),
00610                                                 prov.productInstanceName(),
00611                                                 prov.processName());
00612               doRekeyOnThisSeed=e.getByLabel(clusterRemovalInfos,CRIh);
00613             }//valid hit
00614           }//nhit!=0
00615           
00616           if (doRekeyOnThisSeed && !(clusterRemovalInfos==edm::InputTag(""))) {
00617             ClusterRemovalRefSetter refSetter(e,clusterRemovalInfos);
00618             TrajectorySeed::recHitContainer  newRecHitContainer;
00619             newRecHitContainer.reserve(origSeedRef->nHits());
00620             TrajectorySeed::const_iterator iH=origSeedRef->recHits().first;
00621             TrajectorySeed::const_iterator iH_end=origSeedRef->recHits().second;
00622             for (;iH!=iH_end;++iH){
00623               newRecHitContainer.push_back(*iH);
00624               refSetter.reKey(&newRecHitContainer.back());
00625             }
00626             outputSeeds->push_back( TrajectorySeed( origSeedRef->startingState(),
00627                                                     newRecHitContainer,
00628                                                     origSeedRef->direction()));
00629           }
00630           //doRekeyOnThisSeed=true
00631           else{
00632             //just copy the one we had before
00633             outputSeeds->push_back( TrajectorySeed(*origSeedRef));
00634           }
00635           edm::Ref<TrajectorySeedCollection> pureRef(refTrajSeeds, outputSeeds->size()-1);
00636           origSeedRef=edm::RefToBase<TrajectorySeed>( pureRef);
00637         }//creating a new seed and rekeying it rechit clusters.
00638         
00639         // Fill TrackExtra collection
00640         outputTrkExtras->push_back( reco::TrackExtra( 
00641                                                      track->outerPosition(), track->outerMomentum(), track->outerOk(),
00642                                                      track->innerPosition(), track->innerMomentum(), track->innerOk(),
00643                                                      track->outerStateCovariance(), track->outerDetId(),
00644                                                      track->innerStateCovariance(), track->innerDetId(),
00645                                                      track->seedDirection(), origSeedRef ) );
00646         seedsRefs[i]=origSeedRef;
00647         outputTrks->back().setExtra( reco::TrackExtraRef( refTrkExtras, outputTrkExtras->size() - 1) );
00648         reco::TrackExtra & tx = outputTrkExtras->back();
00649         tx.setResiduals(track->residuals());
00650         
00651         // fill TrackingRecHits
00652         unsigned nh1=track->recHitsSize();
00653         for ( unsigned ih=0; ih<nh1; ++ih ) { 
00654           //const TrackingRecHit*hit=&((*(track->recHit(ih))));
00655           outputTrkHits->push_back( track->recHit(ih)->clone() );
00656           tx.add( TrackingRecHitRef( refTrkHits, outputTrkHits->size() - 1) );
00657         }
00658       }
00659       trackRefs[i] = reco::TrackRef(refTrks, outputTrks->size() - 1);
00660       
00661       
00662     }//end faux loop over tracks
00663     
00664     //Fill the trajectories, etc. for 1st collection
00665     refTrajs    = e.getRefBeforePut< std::vector<Trajectory> >();
00666   
00667     for (unsigned int ti=0; ti<trackColls.size(); ti++) {
00668       edm::Handle< std::vector<Trajectory> >  hTraj1;
00669       edm::Handle< TrajTrackAssociationCollection >  hTTAss1;
00670       e.getByLabel(trackProducers_[ti], hTraj1);
00671       e.getByLabel(trackProducers_[ti], hTTAss1);
00672       
00673       if (hTraj1.failedToGet() || hTTAss1.failedToGet()) continue;
00674       
00675       for (size_t i = 0, n = hTraj1->size(); i < n; ++i) {
00676         edm::Ref< std::vector<Trajectory> > trajRef(hTraj1, i);
00677         TrajTrackAssociationCollection::const_iterator match = hTTAss1->find(trajRef);
00678         if (match != hTTAss1->end()) {
00679           const edm::Ref<reco::TrackCollection> &trkRef = match->val; 
00680           short oldKey = trackCollFirsts[ti]+static_cast<short>(trkRef.key());
00681           if (trackRefs[oldKey].isNonnull()) {
00682             outputTrajs->push_back( *trajRef );
00683             //if making extras and the seeds at the same time, change the seed ref on the trajectory
00684             if (copyExtras_ && makeReKeyedSeeds_)
00685               outputTrajs->back().setSeedRef( seedsRefs[oldKey] );
00686             outputTTAss->insert ( edm::Ref< std::vector<Trajectory> >(refTrajs, outputTrajs->size() - 1), 
00687                                   trackRefs[oldKey] );
00688           }
00689         }
00690       }
00691     }
00692     
00693     statCount.end(outputTrks->size());
00694 
00695     edm::ProductID nPID = refTrks.id();
00696     edm::TestHandle<reco::TrackCollection> outHandle(outputTrks.get(),nPID);
00697     fillerMVA.insert(outHandle,mvaVec.begin(),mvaVec.end());
00698     fillerMVA.fill();
00699 
00700     e.put(outputTrks);
00701     e.put(vmMVA,"MVAVals");
00702     if (copyExtras_) {
00703       e.put(outputTrkExtras);
00704       e.put(outputTrkHits);
00705       if (makeReKeyedSeeds_)
00706         e.put(outputSeeds);
00707     }
00708     e.put(outputTrajs);
00709     e.put(outputTTAss);
00710     return;
00711   
00712   }//end produce
00713 }