CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoMuon/L3MuonProducer/src/L3TkMuonProducer.cc

Go to the documentation of this file.
00001 
00009 // Framework
00010 #include "FWCore/Framework/interface/EDProducer.h"
00011 #include "FWCore/Framework/interface/Event.h"
00012 #include "FWCore/Framework/interface/EventSetup.h"
00013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00014 #include "DataFormats/Common/interface/Handle.h"
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016 
00017 #include "RecoMuon/L3MuonProducer/src/L3TkMuonProducer.h"
00018 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h"
00019 
00020 #include <string>
00021 
00022 using namespace edm;
00023 using namespace std;
00024 using namespace reco;
00025 
00027 L3TkMuonProducer::L3TkMuonProducer(const ParameterSet& parameterSet){
00028   LogTrace("Muon|RecoMuon|L3TkMuonProducer")<<" constructor called";
00029 
00030   // StandAlone Collection Label
00031   theL3CollectionLabel = parameterSet.getParameter<InputTag>("InputObjects");
00032   produces<TrackCollection>();
00033   produces<TrackExtraCollection>();
00034   produces<TrackingRecHitCollection>();
00035 }
00036   
00038 L3TkMuonProducer::~L3TkMuonProducer(){
00039   LogTrace("Muon|RecoMuon|L3TkMuonProducer")<<" L3TkMuonProducer destructor called";
00040 }
00041 
00042 bool L3TkMuonProducer::sharedSeed(const L3MuonTrajectorySeed& s1,const L3MuonTrajectorySeed& s2){
00043   //quit right away on nH=0
00044   if (s1.nHits()==0 || s2.nHits()==0) return false;
00045   //quit right away if not the same number of hits
00046   if (s1.nHits()!=s2.nHits()) return false;
00047   TrajectorySeed::range r1=s1.recHits();
00048   TrajectorySeed::range r2=s2.recHits();
00049   TrajectorySeed::const_iterator i1,i2;
00050   TrajectorySeed::const_iterator & i1_e=r1.second,&i2_e=r2.second;
00051   TrajectorySeed::const_iterator & i1_b=r1.first,&i2_b=r2.first;
00052   //quit right away if first detId does not match. front exist because of ==0 ->quit test
00053   if(i1_b->geographicalId() != i2_b->geographicalId()) return false;
00054   //then check hit by hit if they are the same
00055   for (i1=i1_b,i2=i2_b;i1!=i1_e,i2!=i2_e;++i1,++i2){
00056     if (!i1->sharesInput(&(*i2),TrackingRecHit::all)) return false;
00057   }
00058   return true;
00059 }
00060 
00061 string printvector(const vector<TrackRef> & v){
00062   std::stringstream ss;
00063   for (unsigned int i=0;i!=v.size();++i) {
00064     if (i!=0) ss<<"\n";
00065     ss<<"track with ref: "<<v[i].id().id()<<":"<<v[i].key()
00066       <<" and pT: "<<v[i]->pt()
00067       <<" with seedRef: "<<v[i]->seedRef().id().id()<<":"<<v[i]->seedRef().key();
00068   }
00069   return ss.str();
00070 }
00071 
00072 string printvector(const vector<L3TkMuonProducer::SeedRef> & v){
00073   std::stringstream ss;
00074   for (unsigned int i=0;i!=v.size();++i){
00075     if (i!=0) ss<<"\n";
00076     ss<<"seed ref: "<<v[i].id().id()<<":"<<v[i].key();
00077     if (v[i]->l2Track().isNull())
00078       ss<<" and pT: "<<v[i]->l1Particle()->pt()<<" of L1: "<<v[i]->l1Particle().id().id()<<":"<<v[i]->l1Particle().key();
00079     else 
00080       ss<<" and pT: "<<v[i]->l2Track()->pt()<<" of L2: "<<v[i]->l2Track().id().id()<<":"<<v[i]->l2Track().key();
00081   }
00082   return ss.str();
00083 }
00084 
00085 string printseed(const L3TkMuonProducer::SeedRef & s){
00086   std::stringstream ss;
00087   ss<<" seed ref: "<<s.id().id()<<":"<<s.key()<<" has "<< s->nHits()<<"rechits";
00088   TrajectorySeed::range r=s->recHits();
00089   TrajectorySeed::const_iterator it=r.first;
00090   for (;it!=r.second;++it)
00091     ss<<"\n detId: "<<it->geographicalId()<<" position: "<<it->localPosition()<<" and error: "<<it->localPositionError();
00092   return ss.str();
00093 }
00094 
00096 void L3TkMuonProducer::produce(Event& event, const EventSetup& eventSetup){
00097   const string metname = "Muon|RecoMuon|L3TkMuonProducer";
00098   
00099   // Take the L3 container
00100   LogDebug(metname)<<" Taking the L3/GLB muons: "<<theL3CollectionLabel.label();
00101   Handle<TrackCollection> tracks; 
00102   event.getByLabel(theL3CollectionLabel,tracks);
00103 
00104   //make the LX->L3s pools
00105   LXtoL3sMap LXtoL3s;
00106 
00107   unsigned int maxI = tracks->size();
00108   bool gotL3seeds=false;
00109   edm::Handle<L3MuonTrajectorySeedCollection> l3seeds;
00110 
00111   //make a list of reference to tracker tracks
00112   vector<TrackRef> orderedTrackTracks(maxI);
00113   for (unsigned int i=0;i!=maxI;i++) orderedTrackTracks[i]=TrackRef(tracks,i);
00114   LogDebug(metname)<<"vector of L3 tracks before ordering:\n"<<printvector(orderedTrackTracks);
00115   //order them in pT
00116   sort(orderedTrackTracks.begin(),orderedTrackTracks.end(),trackRefBypT);
00117   LogDebug(metname)<<"vector of L3 tracks after ordering:\n"<<printvector(orderedTrackTracks);
00118   //loop over then
00119   for (unsigned int i=0;i!=maxI;i++) {
00120     TrackRef & tk=orderedTrackTracks[i];  
00121     SeedRef l3seedRef = tk->seedRef().castTo<SeedRef>();
00122 
00123     vector<SeedRef> allPossibleOrderedLx; // with identical hit-set
00124     //add the direct relation
00125     allPossibleOrderedLx.push_back(l3seedRef);
00126     LogDebug(metname)<<"adding the seed ref: "<<l3seedRef.id().id()<<":"<<l3seedRef.key()<<" for this tracker track: "<<tk.id().id()<<":"<<tk.key();
00127 
00128     //add the relations due to shared seeds
00129     //check whether there is a "shared" seed in addition
00130     if (!gotL3seeds){
00131       //need to fetch the handle from the ref
00132       const edm::Provenance & seedsProv=event.getProvenance(l3seedRef.id());
00133       edm::InputTag l3seedsTag(seedsProv.moduleLabel(), seedsProv.productInstanceName(), seedsProv.processName());
00134       event.getByLabel(l3seedsTag, l3seeds);
00135       gotL3seeds=true;
00136       LogDebug(metname)<<"got seeds handle from: "<<l3seedsTag;
00137     }
00138     //loop the other seeds in the collection
00139     for (unsigned int iS=0;iS!=l3seeds->size();++iS){
00140       const L3MuonTrajectorySeed & seed = (*l3seeds)[iS];
00141       const L3MuonTrajectorySeed & thisSeed = *l3seedRef;
00142       if (l3seedRef.key()==iS) continue; //not care about this one
00143       //compare this seed with the seed in the collection
00144       if (sharedSeed(seed,thisSeed)){
00145         SeedRef thisSharedSeedRef(l3seeds,iS);
00146         LogDebug(metname)<<"shared seeds: \n"<<printseed(l3seedRef)<<" and: \n"<<printseed(thisSharedSeedRef)
00147                          <<"\nadding ANOTHER seed ref: "<<thisSharedSeedRef.id().id()<<":"<<thisSharedSeedRef.key()<<" for this tracker track: "<<tk.id().id()<<":"<<tk.key();
00148         //      edm::LogError(metname)<<" we have a shared seed right there.";
00149         allPossibleOrderedLx.push_back(thisSharedSeedRef);
00150       }//seed is shared
00151     }//loop all other existing seed for overlaps
00152 
00153     //now you have the full list of Lx objects that have seed this tracker track.
00154     // order the list in pT of Lx objects
00155     LogDebug(metname)<<"list of possible Lx objects for tracker track: "<<tk.id().id()<<":"<<tk.key()<<" before ordering\n"<<printvector(allPossibleOrderedLx);
00156     sort(allPossibleOrderedLx.begin(),allPossibleOrderedLx.end(),seedRefBypT);
00157     LogDebug(metname)<<"list of possible Lx objects for tracker track: "<<tk.id().id()<<":"<<tk.key()<<" after ordering\n"<<printvector(allPossibleOrderedLx);
00158     // assign this tracker track to the highest pT Lx.
00159     for (unsigned int iL=0;iL!=allPossibleOrderedLx.size();++iL){
00160       SeedRef thisRef=allPossibleOrderedLx[iL];
00161       pseudoRef ref = makePseudoRef(*thisRef);
00162       LogDebug(metname)<<"seed ref: "<<thisRef.id().id()<<":"<<thisRef.key()<<" transcribe to pseudoref: "<<ref.first<<":"<<ref.second;
00163       LXtoL3sMap::iterator f=LXtoL3s.find(ref);
00164       if (f!=LXtoL3s.end()){
00165         //there's already an entry. because of the prior ordering in pT of the tracker track refs
00166         // the track ref already there *has* a higher pT: this one cannot compete and should be assigned to the next Lx;
00167         LogDebug(metname)<<"this tracker track: "<<tk.id().id()<<":"<<tk.key()<<" ("<< tk->pt()<<")"
00168                          <<"\n cannot compete in pT with track: "<<f->second.first.id().id()<<":"<<f->second.first.key()<<" ("<<f->second.first->pt()<<")"
00169                          <<"\n already assigned to pseudo ref: "<<ref.first<<":"<<ref.second<<" which corresponds to seedRef: "<<f->second.second.id().id()<<":"<<f->second.second.key();
00170         continue;
00171       }else{
00172         //there was no entry yet. make the assignement
00173         LogDebug(metname)<<"this tracker track: "<<tk.id().id()<<":"<<tk.key()
00174                          <<" is assigned to pseudo ref: "<<ref.first<<":"<<ref.second<<" which corresponds to seedRef: "<<thisRef.id().id()<<":"<<thisRef.key();
00175         LXtoL3s[ref] = std::make_pair(tk,thisRef);
00176         //once assigned. break
00177         break;
00178       }
00179     }//loop possible Lx for possible assignement
00180   }//loop over ordered list of tracker track refs
00181 
00182 
00183   //prepare the output
00184   std::auto_ptr<TrackCollection> outTracks( new TrackCollection(LXtoL3s.size()));
00185   std::auto_ptr<TrackExtraCollection> outTrackExtras( new TrackExtraCollection(LXtoL3s.size()));
00186   reco::TrackExtraRefProd rTrackExtras = event.getRefBeforePut<TrackExtraCollection>();
00187   std::auto_ptr<TrackingRecHitCollection> outRecHits( new TrackingRecHitCollection());
00188   TrackingRecHitRefProd rHits = event.getRefBeforePut<TrackingRecHitCollection>();
00189 
00190   LogDebug(metname)<<"reading the map to make "<< LXtoL3s.size()<<"products.";
00191   //fill the collection from the map
00192   LXtoL3sMap::iterator f=LXtoL3s.begin();
00193   unsigned int i=0;
00194   for (;f!=LXtoL3s.end();++f,++i){
00195 
00196     LogDebug(metname)<<"copy the track over, and make ref to extra";
00197     const Track & trk = *(f->second.first);
00198     (*outTracks)[i] = Track(trk);
00199     (*outTracks)[i].setExtra( TrackExtraRef(rTrackExtras,i));
00200 
00201     LogDebug(metname)<<"copy the trackExtra too, and change the seedref";
00202     edm::RefToBase<TrajectorySeed> seedRef(f->second.second);
00203     //do not use the copy constructor, otherwise the hit Ref are still the same
00204     (*outTrackExtras)[i] = TrackExtra(
00205                                       trk.outerPosition(), trk.outerMomentum(), trk.outerOk(),
00206                                       trk.innerPosition(), trk.innerMomentum(), trk.innerOk(),
00207                                       trk.outerStateCovariance(), trk.outerDetId(),
00208                                       trk.innerStateCovariance(), trk.innerDetId(),
00209                                       seedRef->direction(),seedRef
00210                                       );
00211 
00212     LogDebug(metname)<<"copy the hits too";
00213     unsigned int iRH=0;
00214     for( trackingRecHit_iterator hit = trk.recHitsBegin(); hit != trk.recHitsEnd(); ++ hit,++iRH ) {
00215       outRecHits->push_back((*hit)->clone());
00216       (*outTrackExtras)[i].add( TrackingRecHitRef( rHits, iRH));
00217     }
00218   }
00219   
00220   LogDebug(metname)<<"made: "<<outTracks->size()<<" tracks, "<<outTrackExtras->size()<<" extras and "<<outRecHits->size()<<" rechits.";
00221 
00222   //put the collection in the event
00223   LogDebug(metname)<<"loading...";
00224   event.put(outTracks);
00225   event.put(outTrackExtras);
00226   event.put(outRecHits);
00227   LogDebug(metname)<<" Event loaded"
00228                    <<"================================";
00229 }