CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/FastSimulation/ParamL3MuonProducer/src/ParamL3MuonProducer.cc

Go to the documentation of this file.
00001 //
00002 // Package:    ParamL3MuonProducer
00003 // Class:      ParamL3MuonProducer
00004 // 
00019 //
00020 // Original Author:  Andrea Perrotta
00021 //         Created:  Mon Oct 30 14:37:24 CET 2006
00022 // $Id: ParamL3MuonProducer.cc,v 1.18 2009/03/12 19:41:52 abdullin Exp $
00023 //
00024 //
00025 
00026 // CMSSW headers 
00027 #include "FWCore/ServiceRegistry/interface/Service.h"
00028 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00029 #include "FWCore/Utilities/interface/Exception.h"
00030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00031 #include "FWCore/Framework/interface/Event.h"
00032 #include "FWCore/Framework/interface/MakerMacros.h"
00033 
00034 // Fast Simulation headers
00035 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00036 #include "FastSimulation/ParamL3MuonProducer/interface/ParamL3MuonProducer.h"
00037 
00038 // SimTrack
00039 #include "SimDataFormats/Track/interface/SimTrack.h"
00040 
00041 // L1
00042 #include "FastSimDataFormats/L1GlobalMuonTrigger/interface/SimpleL1MuGMTCand.h"
00043 #include "FastSimulation/Muons/interface/FML1EfficiencyHandler.h"
00044 #include "FastSimulation/Muons/interface/FML1PtSmearer.h"
00045 
00046 // L3
00047 #include "FastSimulation/ParamL3MuonProducer/interface/FML3EfficiencyHandler.h"
00048 #include "FastSimulation/ParamL3MuonProducer/interface/FML3PtSmearer.h"
00049 
00050 // GL
00051 #include "FastSimulation/ParamL3MuonProducer/interface/FMGLfromL3EfficiencyHandler.h"
00052 #include "FastSimulation/ParamL3MuonProducer/interface/FMGLfromL3TKEfficiencyHandler.h"
00053 #include "FastSimulation/ParamL3MuonProducer/interface/FMGLfromTKEfficiencyHandler.h"
00054 
00055 // STL headers 
00056 #include <vector>
00057 #include <iostream>
00058 
00059 // CLHEP headers
00060 #include "DataFormats/Math/interface/LorentzVector.h"
00061 
00062 // Data Formats
00063 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00064 #include "DataFormats/TrackReco/interface/Track.h"
00065 #include "DataFormats/TrackerRecHit2D/interface/SiTrackerGSRecHit2D.h"
00066 #include "DataFormats/TrackerRecHit2D/interface/SiTrackerGSRecHit2DCollection.h"
00067 #include "DataFormats/MuonReco/interface/Muon.h"
00068 
00069 // constants, enums and typedefs
00070 typedef std::vector<L1MuGMTCand> L1MuonCollection;
00071 
00072 //
00073 // static data member definitions
00074 //
00075 
00076 //for debug only 
00077 //#define FAMOS_DEBUG
00078 
00079 double ParamL3MuonProducer::muonMassGeV_ = 0.105658369 ; // PDG06
00080 
00081 //
00082 // constructors and destructor
00083 //
00084 ParamL3MuonProducer::ParamL3MuonProducer(const edm::ParameterSet& iConfig)
00085 {
00086 
00087   readParameters(iConfig.getParameter<edm::ParameterSet>("MUONS"),
00088                  iConfig.getParameter<edm::ParameterSet>("TRACKS"));
00089 
00090   //register your products
00091   if (doL1_) {
00092     produces<L1MuonCollection> ("ParamL1Muons");
00093     produces<L1ExtraCollection> ("ParamL1Muons");
00094   }
00095   if (doL3_) produces<reco::MuonCollection>("ParamL3Muons");
00096   if (doGL_) produces<reco::MuonCollection>("ParamGlobalMuons");
00097 
00098   // Initialize the random number generator service
00099   edm::Service<edm::RandomNumberGenerator> rng;
00100   if ( ! rng.isAvailable() ) {
00101     throw cms::Exception("Configuration") <<
00102       "ParamMuonProducer requires the RandomGeneratorService \n"
00103       "which is not present in the configuration file. \n"
00104       "You must add the service in the configuration file\n"
00105       "or remove the module that requires it.";
00106   }
00107 
00108   random = new RandomEngine(&(*rng));
00109 
00110 }
00111 
00112 
00113 ParamL3MuonProducer::~ParamL3MuonProducer()
00114 {
00115  
00116   // do anything here that needs to be done at destruction time
00117   // (e.g. close files, deallocate resources etc.)
00118   
00119   if ( random ) { 
00120     delete random;
00121   }
00122 }
00123 
00124 
00125 //
00126 // member functions
00127 //
00128 
00129 // ------------ method called to produce the data  ------------
00130 
00131 void ParamL3MuonProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00132 {
00133   using namespace edm;
00134 
00135   Handle<std::vector<SimTrack> > simMuons;
00136   iEvent.getByLabel(theSimModuleLabel_,theSimModuleProcess_,simMuons);
00137 
00138   unsigned nmuons = simMuons->size();
00139   //  Handle<std::vector<SimVertex> > simVertices;
00140   //  iEvent.getByLabel(theSimModuleLabel_,simVertices);
00141 
00142   int ntrks = 0;
00143   Handle<reco::TrackCollection> theTracks;
00144   reco::TrackRefVector allMuonTracks;
00145   Handle<SiTrackerGSRecHit2DCollection> theGSRecHits;
00146   std::vector<SimTrack> trackOriginalMuons;  
00147 
00148   if (doL3_ || doGL_) {
00149     iEvent.getByLabel(theTrkModuleLabel_,theTracks);
00150     ntrks =  theTracks->size();
00151     reco::TrackCollection::const_iterator trk=theTracks->begin();
00152     reco::TrackCollection::const_iterator trkEnd=theTracks->end();
00153     //Get RecHits from the event
00154     iEvent.getByType(theGSRecHits);
00155 
00156     // Associate the reconstructed trackerTrack with the simTrack...
00157     int trackIndex = 0;
00158     for ( ; trk!=trkEnd; ++trk) {
00159 
00160       // The vector of SimTrack id for each rechits (useful only for full pattern recognition)
00161       std::vector<unsigned> SimTrackIds( fullPattern_ ? trk->recHitsSize() : 0,
00162                                          static_cast<unsigned>(0));
00163 
00164       // Here is the case with fast tracking (no pattern recognition) 
00165       // All rechits come from the same sim track, so only the first hit is checked.
00166       int idmax = -1;
00167       if ( !fullPattern_ ) { 
00168         // Find the SimTrack Id
00169         idmax = findId(*trk);
00170 
00171       // Now comes the case with full pattern recognition
00172       // The rechits may come from several simtracks, so take the simtrack which shares
00173       // the largest number of hits with the reconstructed track 
00174       } else { 
00175 
00176         // Fill it!
00177         // The rechit iterator
00178         trackingRecHit_iterator it = trk->recHitsBegin();
00179         trackingRecHit_iterator rechitsEnd = trk->recHitsEnd();
00180         // Loop on the rechits for this track
00181         for ( unsigned ih=0; it!=rechitsEnd; ++it,++ih ) { 
00182           if ((*it)->isValid()) {
00183             const SiTrackerGSRecHit2D * rechit = dynamic_cast<const SiTrackerGSRecHit2D *> (it->get());
00184             if ( rechit ) SimTrackIds[ih] = rechit->simtrackId();
00185           }
00186         }
00187       }  // end of loop over the recHits belonging to the track
00188 
00189       // Now find the simTrack with the largest number of hits in common
00190       int nmax = 0;
00191       for(size_t j=0; j<SimTrackIds.size(); j++){
00192         int n = std::count(SimTrackIds.begin(), SimTrackIds.end(), SimTrackIds[j]);
00193         if(n>nmax){
00194           nmax = n;
00195           idmax = SimTrackIds[j];
00196         }
00197       }
00198 
00199       for( unsigned fsimi=0; fsimi < nmuons; ++fsimi) {
00200         const SimTrack& simTrack = (*simMuons)[fsimi];
00201         if( (int) simTrack.trackId() == idmax) {
00202           allMuonTracks.push_back(reco::TrackRef(theTracks,trackIndex));
00203           trackOriginalMuons.push_back(simTrack);
00204           break;
00205         }
00206       }
00207 
00208       trackIndex++;
00209     } // end loop on rec tracks
00210   }   // end if clause
00211 
00212 
00213 #ifdef FAMOS_DEBUG
00214   std::cout << " *** ParamMuonProducer::reconstruct() -> entering " << std::endl;
00215   std::cout << " *** Event with " << nmuons << " simulated muons and " 
00216             << ntrks << " tracker tracks" << std::endl;
00217 #endif
00218 
00219 //
00220 // Loop over generated muons and reconstruct L1, L3 and Global muons
00221 //
00222   
00223   int nMu = 0;
00224   mySimpleL1MuonCands.clear();
00225   mySimpleL1MuonExtraCands.clear();
00226   mySimpleL3MuonCands.clear();
00227   mySimpleL3MuonSeeds.clear();
00228   mySimpleGLMuonCands.clear();
00229 
00230   FML1Muons  mySimpleL1MuonCandsTemp;
00231   reco::MuonCollection  mySimpleL3MuonCandsTemp;
00232 
00233 
00234   for( unsigned fsimi=0; fsimi < nmuons; ++fsimi) {
00235     // The sim track can be a muon or a decaying hadron
00236     const SimTrack& mySimTrack = (*simMuons)[fsimi];
00237     int pid = mySimTrack.type();        
00238     // The daughter muons in case of a decaying hadron is just after the muon in the list
00239     // We keep the daughter muon momentum for L1 and skip the daughter muon in the loop 
00240     // to avoid double counting at L1 
00241     const SimTrack& mySimMuon = fabs(pid)==13 ? (*simMuons)[fsimi] : (*simMuons)[++fsimi];
00242 
00243     bool hasL1 = false , hasL3 = false , hasTK = false , hasGL = false;
00244 
00245     //Replace with this as soon transition to ROOTMath is complete
00246     //    math::XYZTLorentzVector& mySimP4 =  mySimTrack.momentum();
00247     math::XYZTLorentzVector mySimP4 =  math::XYZTLorentzVector(mySimTrack.momentum().x(),
00248                                                                mySimTrack.momentum().y(),
00249                                                                mySimTrack.momentum().z(),
00250                                                                mySimTrack.momentum().t());
00251 
00252 #ifdef FAMOS_DEBUG
00253     std::cout << " ===> ParamMuonProducer::reconstruct() - pid = "
00254               << mySimTrack.type() ;
00255     std::cout << " : pT = " << mySimP4.Pt()
00256               << ", eta = " << mySimP4.Eta()
00257               << ", phi = " << mySimP4.Phi() << std::endl;
00258 #endif
00259 
00260 // *** Reconstruct parameterized muons starting from undecayed simulated muons
00261  
00262     if ( mySimP4.Eta()>minEta_ && mySimP4.Eta()<maxEta_ ) {
00263       
00264       nMu++;
00265 
00266 //
00267 // Now L1
00268 //
00269       
00270       SimpleL1MuGMTCand * thisL1MuonCand = new SimpleL1MuGMTCand(&mySimMuon);
00271       if (doL1_ || doL3_ || doGL_) {
00272         hasL1 = myL1EfficiencyHandler->kill(thisL1MuonCand);
00273         if (hasL1) {
00274           bool status2 = myL1PtSmearer->smear(thisL1MuonCand);
00275           if (!status2) { std::cout << "Pt smearing of L1 muon went wrong!!" << std::endl; }
00276           if (status2) {
00277             mySimpleL1MuonCandsTemp.push_back(thisL1MuonCand);
00278             float pt = thisL1MuonCand->ptValue();
00279             unsigned int rank=1;
00280             FML1Muons::const_iterator l1st;
00281             for(l1st=mySimpleL1MuonCandsTemp.begin();(*l1st)!=thisL1MuonCand;++l1st) {
00282               if ((*l1st)->ptValue()>=pt) {
00283                 unsigned int newrank = (*l1st)->rank()+1;
00284                 (*l1st)->setRank(newrank);
00285               }
00286               else ++rank;
00287             }
00288             thisL1MuonCand->setRank(rank);
00289           }
00290           else {
00291             hasL1 = false;
00292             delete thisL1MuonCand;
00293           }
00294         }
00295       }
00296 
00297 
00298       reco::TrackRef myTrackerTrack;
00299       if (doL3_ || doGL_) {
00300 
00301 // Check if a correspondig track does exist:
00302         std::vector<SimTrack>::const_iterator genmu;
00303         reco::track_iterator trkmu=allMuonTracks.begin();
00304         for (genmu=trackOriginalMuons.begin();
00305              genmu!=trackOriginalMuons.end();genmu++) {
00306           if(mySimTrack.trackId() == (*genmu).trackId()) {
00307             hasTK = true;
00308             myTrackerTrack = (*trkmu);
00309             break;
00310           }
00311           trkmu++;
00312         }
00313 
00314 //
00315 // L3 muon
00316 //
00317         if (hasL1 && hasTK) {
00318           hasL3 = myL3EfficiencyHandler->kill(mySimTrack);
00319           if (hasL3) {
00320             int myL3Charge = myTrackerTrack->charge();
00321             const math::XYZTLorentzVector& myL3P4 =
00322               myL3PtSmearer->smear(mySimP4,myTrackerTrack->momentum());
00323             // const math::PtEtaPhiMLorentzVector& myL3P4 =
00324             // math::PtEtaPhiMLorentzVector( myL3PtSmearer->smear(mySimP4,myTrackerTrack->momentum()) );
00325             math::XYZPoint myL3Vertex = myTrackerTrack->referencePoint();
00326             reco::Muon * thisL3MuonCand = new reco::Muon(myL3Charge,myL3P4,myL3Vertex);
00327             thisL3MuonCand->setInnerTrack(myTrackerTrack);
00328             mySimpleL3MuonCandsTemp.push_back((*thisL3MuonCand));
00329             mySimpleL3MuonSeeds.push_back(thisL1MuonCand);
00330           }
00331         }
00332 
00333 //
00334 // Global Muon
00335 //
00336         if (doGL_ && hasL3 && hasTK) {
00337           hasGL = myGLfromL3TKEfficiencyHandler->kill(mySimTrack);
00338         }
00339         else if (doGL_ && hasTK) {
00340           hasGL = myGLfromTKEfficiencyHandler->kill(mySimTrack);
00341         }
00342         //      else if (doGL_ && hasL3) {
00343         //      hasGL = myGLfromL3EfficiencyHandler->kill(mySimTrack);
00344         //      }
00345         if (hasGL) {
00346           int myGLCharge = myTrackerTrack->charge();
00347           const math::XYZTLorentzVector& myGLP4 =
00348             myGLPtSmearer->smear(mySimP4,myTrackerTrack->momentum());
00349           // const math::PtEtaPhiMLorentzVector& myGLP4 =
00350           //  math::PtEtaPhiMLorentzVector ( myGLPtSmearer->smear(mySimP4,myTrackerTrack->momentum()) );
00351           math::XYZPoint myGLVertex = myTrackerTrack->referencePoint();
00352           reco::Muon * thisGLMuonCand = new reco::Muon(myGLCharge,myGLP4,myGLVertex);
00353           thisGLMuonCand->setInnerTrack(myTrackerTrack);
00354           mySimpleGLMuonCands.push_back((*thisGLMuonCand));
00355         }
00356       }
00357 
00358 //
00359 // Summary debug for this generated muon:
00360 //
00361 #ifdef FAMOS_DEBUG
00362       std::cout << " Muon " << nMu << " reconstructed with: " ;
00363       if (hasL1) std::cout << " L1 ; " ;
00364       if (hasTK) std::cout << " Tk ; " ;
00365       if (hasL3) std::cout << " L3 ; " ;
00366       if (hasGL) std::cout << " GL . " ;
00367       std::cout << std::endl;
00368 #endif
00369       
00370     }
00371 
00372   }
00373 
00374 
00375 // kill low ranked L1 and L3 muons, and fill L1extra muons -->
00376   unsigned int rankmax = mySimpleL1MuonCandsTemp.size();
00377   FML1Muons::const_iterator l1mu;
00378   reco::MuonCollection::const_iterator l3mu;
00379   l1mu = mySimpleL3MuonSeeds.begin();
00380   for (l3mu=mySimpleL3MuonCandsTemp.begin(); l3mu!=mySimpleL3MuonCandsTemp.end(); ++l3mu) {
00381     unsigned int rank = (*l1mu)->rank();
00382     if (rank+4>rankmax) mySimpleL3MuonCands.push_back(*l3mu);
00383 #ifdef FAMOS_DEBUG
00384     else 
00385       std::cout << " Killed L3 muon candidate of rank " << rank
00386                 << " when rankmax is " << rankmax << std::endl;
00387 #endif
00388     ++l1mu;
00389   }
00390   for (l1mu=mySimpleL1MuonCandsTemp.begin(); l1mu!=mySimpleL1MuonCandsTemp.end(); ++l1mu) {
00391     unsigned int rank = (*l1mu)->rank();
00392     if (rank+4>rankmax) {
00393       mySimpleL1MuonCands.push_back(*l1mu);
00394 
00395       double pt = (*l1mu)->ptValue() + 1.e-6 ;
00396       double eta = (*l1mu)->etaValue();
00397       double phi = (*l1mu)->phiValue();
00398       math::PtEtaPhiMLorentzVector PtEtaPhiMP4(pt,eta,phi,muonMassGeV_);
00399       math::XYZTLorentzVector myL1P4(PtEtaPhiMP4);
00400       // math::PtEtaPhiMLorentzVector myL1P4(pt,eta,phi,muonMassGeV_);
00401       mySimpleL1MuonExtraCands.push_back( l1extra::L1MuonParticle( (*l1mu)->charge(), myL1P4, *(*l1mu)) );
00402    }
00403 #ifdef FAMOS_DEBUG
00404     else 
00405       std::cout << " Killed L1 muon candidate of rank " << rank
00406                 << " when rankmax is " << rankmax << std::endl;
00407 #endif
00408   }
00409 // end killing of low ranked L1 and L3 muons -->
00410 
00411 
00412   int nL1 =  mySimpleL1MuonCands.size();
00413   int nL3 =  mySimpleL3MuonCands.size();
00414   int nGL =  mySimpleGLMuonCands.size();
00415   nMuonTot   += nMu;
00416   nL1MuonTot += nL1;
00417   nL3MuonTot += nL3;
00418   nGLMuonTot += nGL;
00419 
00420 #ifdef FAMOS_DEBUG
00421 // start debug -->
00422   unsigned int i = 0;
00423   //    FML1Muons::const_iterator l1mu;
00424   for (l1mu=mySimpleL1MuonCands.begin(); l1mu!=mySimpleL1MuonCands.end(); l1mu++) {
00425     ++i;
00426     std::cout << "FastMuon L1 Cand " << i 
00427               << " : pT = " << (*l1mu)->ptValue()
00428               << ", eta = " << (*l1mu)->etaValue()
00429               << ", phi = " << (*l1mu)->phiValue()
00430               << ", rank = " << (*l1mu)->rank()
00431               << std::endl;
00432   }
00433   i=0;
00434   L1ExtraCollection::const_iterator l1ex;
00435   for (l1ex=mySimpleL1MuonExtraCands.begin(); l1ex!=mySimpleL1MuonExtraCands.end(); l1ex++) {
00436     ++i;
00437     std::cout << "FastMuon L1 Extra Cand " << i 
00438               << " : pT = " << (*l1ex).pt()
00439               << ", eta = " << (*l1ex).eta()
00440               << ", phi = " << (*l1ex).phi()
00441               << std::endl;
00442   }
00443   i=0;
00444   //    reco::MuonCollection::const_iterator l3mu;
00445   for (l3mu=mySimpleL3MuonCands.begin(); l3mu!=mySimpleL3MuonCands.end(); l3mu++) {
00446     ++i;
00447     std::cout << "FastMuon L3 Cand " << i 
00448               << " : pT = " << (*l3mu).pt()
00449               << ", eta = " << (*l3mu).eta()
00450               << ", phi = " << (*l3mu).phi()
00451       //                << ", vertex = ( " << (*l3mu).vx()
00452       //                                   << " , " << (*l3mu).vy()
00453       //                                     << " , " << (*l3mu).vz() << " )"
00454               << std::endl;
00455     std::cout << "-    tracker Track" 
00456               << " : pT = " << (*l3mu).track()->pt()
00457               << ", eta = " << (*l3mu).track()->eta()
00458               << ", phi = " << (*l3mu).track()->phi()
00459       //                << ", vertex = ( " << (*l3mu).track()->vx()
00460       //                                   << " , " << (*l3mu).track()->vy()
00461       //                                     << " , " << (*l3mu).track()->vz() << " )"
00462               << std::endl;
00463   }
00464   i=0;
00465   reco::MuonCollection::const_iterator glmu;
00466   for (glmu=mySimpleGLMuonCands.begin(); glmu!=mySimpleGLMuonCands.end(); glmu++) {
00467     ++i;
00468     std::cout << "FastGlobalMuon Cand " << i 
00469               << " : pT = " << (*glmu).pt()
00470               << ", eta = " << (*glmu).eta()
00471               << ", phi = " << (*glmu).phi() 
00472       //                << ", vertex = ( " << (*l3mu).vx()
00473       //                                   << " , " << (*l3mu).vy()
00474       //                                     << " , " << (*l3mu).vz() << " )"
00475               << std::endl;
00476     std::cout << "-    tracker Track" 
00477               << " : pT = " << (*glmu).track()->pt()
00478               << ", eta = " << (*glmu).track()->eta()
00479               << ", phi = " << (*glmu).track()->phi()
00480       //                << ", vertex = ( " << (*l3mu).track()->vx()
00481       //                                   << " , " << (*l3mu).track()->vy()
00482       //                                     << " , " << (*l3mu).track()->vz() << " )"
00483               << std::endl;
00484   }
00485   
00486   std::cout << " ===> Number of generator -> L1 / L3 / Global muons in the event : "
00487             << nMu << " -> " << nL1 <<  " / " << nL3 <<  " / " << nGL << std::endl;
00488   
00489 // end debug -->
00490 #endif
00491 
00492   if (doL1_) {
00493     std::auto_ptr<L1MuonCollection> l1Out(new L1MuonCollection);
00494     std::auto_ptr<L1ExtraCollection> l1ExtraOut(new L1ExtraCollection);
00495     loadL1Muons(*l1Out,*l1ExtraOut);
00496     iEvent.put(l1Out,"ParamL1Muons");
00497     iEvent.put(l1ExtraOut,"ParamL1Muons");
00498   }
00499   if (doL3_) {
00500     std::auto_ptr<reco::MuonCollection> l3Out(new reco::MuonCollection);
00501     loadL3Muons(*l3Out);
00502     iEvent.put(l3Out,"ParamL3Muons");
00503   }
00504   if (doGL_) {
00505     std::auto_ptr<reco::MuonCollection> glOut(new reco::MuonCollection);
00506     loadGLMuons(*glOut);
00507     iEvent.put(glOut,"ParamGlobalMuons");
00508   }
00509 
00510 }
00511 
00512 
00513 void ParamL3MuonProducer::loadL1Muons(L1MuonCollection & c , L1ExtraCollection & d) const
00514 {
00515 
00516   FML1Muons::const_iterator l1mu;
00517   L1ExtraCollection::const_iterator l1ex;
00518   // Add L1 muons:
00519   for (l1mu=mySimpleL1MuonCands.begin();l1mu!=mySimpleL1MuonCands.end();++l1mu) {
00520       c.push_back(*(*l1mu));
00521   }
00522   for (l1ex=mySimpleL1MuonExtraCands.begin();l1ex!=mySimpleL1MuonExtraCands.end();++l1ex) {
00523       d.push_back(*l1ex);
00524   }
00525 
00526 }
00527 
00528 void ParamL3MuonProducer::loadL3Muons(reco::MuonCollection & c) const
00529 {
00530   reco::MuonCollection::const_iterator l3mu;
00531   // Add L3 muons:
00532   for(l3mu=mySimpleL3MuonCands.begin();l3mu!=mySimpleL3MuonCands.end();++l3mu) {
00533       c.push_back(*l3mu);
00534   }
00535 }
00536 
00537 void ParamL3MuonProducer::loadGLMuons(reco::MuonCollection & c) const
00538 {
00539   reco::MuonCollection::const_iterator glmu;
00540   // Add Global muons:
00541   for(glmu=mySimpleGLMuonCands.begin();glmu!=mySimpleGLMuonCands.end();++glmu) {
00542     c.push_back(*glmu);
00543   }
00544 }
00545 
00546 
00547 // ------------ method called once each job just before starting event loop  ------------
00548 void ParamL3MuonProducer::beginRun(edm::Run& run, edm::EventSetup const& es)
00549 {
00550 
00551   // Initialize
00552   nMuonTot = 0;
00553 
00554   nL1MuonTot = 0;
00555   mySimpleL1MuonCands.clear();
00556   mySimpleL1MuonExtraCands.clear();
00557   myL1EfficiencyHandler = new FML1EfficiencyHandler(random);
00558   myL1PtSmearer = new FML1PtSmearer(random);
00559 
00560   nL3MuonTot = 0;
00561   mySimpleL3MuonCands.clear();
00562   myL3EfficiencyHandler = new FML3EfficiencyHandler(random);
00563   myL3PtSmearer = new FML3PtSmearer(random);
00564 
00565   nGLMuonTot = 0;
00566   mySimpleGLMuonCands.clear();
00567   myGLfromL3TKEfficiencyHandler = new FMGLfromL3TKEfficiencyHandler(random);
00568   myGLfromL3EfficiencyHandler = new FMGLfromL3EfficiencyHandler(random);
00569   myGLfromTKEfficiencyHandler = new FMGLfromTKEfficiencyHandler(random);
00570   //  myGLPtSmearer = new FML3PtSmearer(random);
00571   myGLPtSmearer = myL3PtSmearer;
00572 
00573 }
00574 
00575 
00576 // ------------ method called once each job just after ending the event loop  ------------
00577 void ParamL3MuonProducer::endRun() {
00578 
00579   std::cout << " ===> ParamL3MuonProducer , final report." << std::endl;
00580   std::cout << " ===> Number of total -> L1 / L3 / GL muons in the whole run : "
00581             <<   nMuonTot << " -> " << nL1MuonTot << " / "
00582             << nL3MuonTot << " / " << nGLMuonTot << std::endl;
00583 }
00584 
00585 
00586 void ParamL3MuonProducer::readParameters(const edm::ParameterSet& fastMuons, 
00587                                          const edm::ParameterSet& fastTracks) {
00588   // Muons
00589   doL1_ = fastMuons.getUntrackedParameter<bool>("ProduceL1Muons");
00590   doL3_ = fastMuons.getUntrackedParameter<bool>("ProduceL3Muons");
00591   doGL_ = fastMuons.getUntrackedParameter<bool>("ProduceGlobalMuons");
00592   theSimModuleLabel_ = fastMuons.getParameter<std::string>("simModuleLabel");
00593   theSimModuleProcess_ = fastMuons.getParameter<std::string>("simModuleProcess");
00594   theTrkModuleLabel_ = fastMuons.getParameter<std::string>("trackModuleLabel");
00595   minEta_ = fastMuons.getParameter<double>("MinEta");
00596   maxEta_ = fastMuons.getParameter<double>("MaxEta");
00597   if (minEta_ > maxEta_) {
00598     double tempEta_ = maxEta_ ;
00599     maxEta_ = minEta_ ;
00600     minEta_ = tempEta_ ;
00601   }
00602 
00603   // Tracks
00604   fullPattern_  = fastTracks.getUntrackedParameter<bool>("FullPatternRecognition");
00605 
00606   std::cout << " Parameterized MUONS: FastSimulation parameters " << std::endl;
00607   std::cout << " ============================================== " << std::endl;
00608   std::cout << " Parameterized muons reconstructed in the pseudorapidity range : "
00609             << minEta_ << " -> " << maxEta_ << std::endl;
00610   if ( fullPattern_ ) 
00611     std::cout << " The FULL pattern recognition option is turned ON" << std::endl;
00612   else
00613     std::cout << " The FAST tracking option is turned ON" << std::endl;
00614 }
00615 
00616 int 
00617 ParamL3MuonProducer::findId(const reco::Track& aTrack) const {
00618   int trackId = -1;
00619   trackingRecHit_iterator aHit = aTrack.recHitsBegin();
00620   trackingRecHit_iterator lastHit = aTrack.recHitsEnd();
00621   for ( ; aHit!=lastHit; ++aHit ) {
00622     if ( !aHit->get()->isValid() ) continue;
00623     const SiTrackerGSRecHit2D * rechit = (const SiTrackerGSRecHit2D*) (aHit->get());
00624     trackId = rechit->simtrackId();
00625     break;
00626   }
00627   return trackId;
00628 }
00629 
00630 //define this as a plug-in
00631 DEFINE_FWK_MODULE(ParamL3MuonProducer);