00001
00002
00003
00004
00019
00020
00021
00022
00023
00024
00025
00026
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
00035 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00036 #include "FastSimulation/ParamL3MuonProducer/interface/ParamL3MuonProducer.h"
00037
00038
00039 #include "SimDataFormats/Track/interface/SimTrack.h"
00040
00041
00042 #include "FastSimDataFormats/L1GlobalMuonTrigger/interface/SimpleL1MuGMTCand.h"
00043 #include "FastSimulation/Muons/interface/FML1EfficiencyHandler.h"
00044 #include "FastSimulation/Muons/interface/FML1PtSmearer.h"
00045
00046
00047 #include "FastSimulation/ParamL3MuonProducer/interface/FML3EfficiencyHandler.h"
00048 #include "FastSimulation/ParamL3MuonProducer/interface/FML3PtSmearer.h"
00049
00050
00051 #include "FastSimulation/ParamL3MuonProducer/interface/FMGLfromL3EfficiencyHandler.h"
00052 #include "FastSimulation/ParamL3MuonProducer/interface/FMGLfromL3TKEfficiencyHandler.h"
00053 #include "FastSimulation/ParamL3MuonProducer/interface/FMGLfromTKEfficiencyHandler.h"
00054
00055
00056 #include <vector>
00057 #include <iostream>
00058
00059
00060 #include "DataFormats/Math/interface/LorentzVector.h"
00061
00062
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
00070 typedef std::vector<L1MuGMTCand> L1MuonCollection;
00071
00072
00073
00074
00075
00076
00077
00078
00079 double ParamL3MuonProducer::muonMassGeV_ = 0.105658369 ;
00080
00081
00082
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
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
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
00117
00118
00119 if ( random ) {
00120 delete random;
00121 }
00122 }
00123
00124
00125
00126
00127
00128
00129
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
00140
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
00154 iEvent.getByType(theGSRecHits);
00155
00156
00157 int trackIndex = 0;
00158 for ( ; trk!=trkEnd; ++trk) {
00159
00160
00161 std::vector<unsigned> SimTrackIds( fullPattern_ ? trk->recHitsSize() : 0,
00162 static_cast<unsigned>(0));
00163
00164
00165
00166 int idmax = -1;
00167 if ( !fullPattern_ ) {
00168
00169 idmax = findId(*trk);
00170
00171
00172
00173
00174 } else {
00175
00176
00177
00178 trackingRecHit_iterator it = trk->recHitsBegin();
00179 trackingRecHit_iterator rechitsEnd = trk->recHitsEnd();
00180
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 }
00188
00189
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 }
00210 }
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
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
00236 const SimTrack& mySimTrack = (*simMuons)[fsimi];
00237 int pid = mySimTrack.type();
00238
00239
00240
00241 const SimTrack& mySimMuon = fabs(pid)==13 ? (*simMuons)[fsimi] : (*simMuons)[++fsimi];
00242
00243 bool hasL1 = false , hasL3 = false , hasTK = false , hasGL = false;
00244
00245
00246
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
00261
00262 if ( mySimP4.Eta()>minEta_ && mySimP4.Eta()<maxEta_ ) {
00263
00264 nMu++;
00265
00266
00267
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
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
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
00324
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
00335
00336 if (doGL_ && hasL3 && hasTK) {
00337 hasGL = myGLfromL3TKEfficiencyHandler->kill(mySimTrack);
00338 }
00339 else if (doGL_ && hasTK) {
00340 hasGL = myGLfromTKEfficiencyHandler->kill(mySimTrack);
00341 }
00342
00343
00344
00345 if (hasGL) {
00346 int myGLCharge = myTrackerTrack->charge();
00347 const math::XYZTLorentzVector& myGLP4 =
00348 myGLPtSmearer->smear(mySimP4,myTrackerTrack->momentum());
00349
00350
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
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
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
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
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
00422 unsigned int i = 0;
00423
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
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
00452
00453
00454 << std::endl;
00455 std::cout << "- tracker Track"
00456 << " : pT = " << (*l3mu).track()->pt()
00457 << ", eta = " << (*l3mu).track()->eta()
00458 << ", phi = " << (*l3mu).track()->phi()
00459
00460
00461
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
00473
00474
00475 << std::endl;
00476 std::cout << "- tracker Track"
00477 << " : pT = " << (*glmu).track()->pt()
00478 << ", eta = " << (*glmu).track()->eta()
00479 << ", phi = " << (*glmu).track()->phi()
00480
00481
00482
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
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
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
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
00541 for(glmu=mySimpleGLMuonCands.begin();glmu!=mySimpleGLMuonCands.end();++glmu) {
00542 c.push_back(*glmu);
00543 }
00544 }
00545
00546
00547
00548 void ParamL3MuonProducer::beginRun(edm::Run& run, edm::EventSetup const& es)
00549 {
00550
00551
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
00571 myGLPtSmearer = myL3PtSmearer;
00572
00573 }
00574
00575
00576
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
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
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
00631 DEFINE_FWK_MODULE(ParamL3MuonProducer);