00001
00002
00003
00004
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "FWCore/ServiceRegistry/interface/Service.h"
00021 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00022 #include "FWCore/Framework/interface/Event.h"
00023 #include "FWCore/Framework/interface/ESHandle.h"
00024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00025
00026
00027 #include "CondFormats/L1TObjects/interface/L1MuTriggerScales.h"
00028 #include "CondFormats/DataRecord/interface/L1MuTriggerScalesRcd.h"
00029 #include "CondFormats/L1TObjects/interface/L1MuTriggerPtScale.h"
00030 #include "CondFormats/DataRecord/interface/L1MuTriggerPtScaleRcd.h"
00031
00032
00033 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00034 #include "FastSimulation/Muons/plugins/FastL1MuonProducer.h"
00035
00036
00037 #include "SimDataFormats/Track/interface/SimTrack.h"
00038 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
00039 #include "SimDataFormats/TrackingHit/interface/PSimHit.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 <iostream>
00048
00049
00050 #include "DataFormats/L1GlobalMuonTrigger/interface/L1MuGMTReadoutCollection.h"
00051 #include "DataFormats/L1Trigger/interface/L1MuonParticle.h"
00052 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
00053 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00054
00055
00056 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00057
00058 #include <map>
00059
00060
00061
00062
00063
00064
00065
00066 double FastL1MuonProducer::muonMassGeV_ = 0.105658369 ;
00067
00068
00069
00070
00071 FastL1MuonProducer::FastL1MuonProducer(const edm::ParameterSet& iConfig):
00072 myL1EfficiencyHandler(0),
00073 myL1PtSmearer(0)
00074 {
00075
00076 readParameters(iConfig.getParameter<edm::ParameterSet>("MUONS"));
00077
00078
00079 produces<L1MuonCollection> ();
00080 produces<L1ExtraCollection> ();
00081 produces<L1MuGMTReadoutCollection>();
00082
00083
00084 edm::Service<edm::RandomNumberGenerator> rng;
00085 if ( ! rng.isAvailable() ) {
00086 throw cms::Exception("Configuration") <<
00087 "ParamMuonProducer requires the RandomGeneratorService \n"
00088 "which is not present in the configuration file. \n"
00089 "You must add the service in the configuration file\n"
00090 "or remove the module that requires it.";
00091 }
00092
00093 random = new RandomEngine(&(*rng));
00094
00095 }
00096
00097
00098 FastL1MuonProducer::~FastL1MuonProducer()
00099 {
00100
00101
00102
00103
00104 if ( random ) {
00105 delete random;
00106 }
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116 void
00117 FastL1MuonProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00118 {
00119 using namespace edm;
00120
00121 Handle<std::vector<SimTrack> > simMuons;
00122 iEvent.getByLabel(theSimModule,simMuons);
00123 unsigned nmuons = simMuons->size();
00124
00125
00126
00127 Handle<PSimHitContainer> muonDTHits;
00128 iEvent.getByLabel(theDTHits,muonDTHits);
00129 Handle<PSimHitContainer> muonCSCHits;
00130 iEvent.getByLabel(theCSCHits,muonCSCHits);
00131 Handle<PSimHitContainer> muonRPCHits;
00132 iEvent.getByLabel(theRPCHits,muonRPCHits);
00133
00134
00135
00136
00137
00138
00139 int nMu = 0;
00140 mySimpleL1MuonCands.clear();
00141 mySimpleL1MuonExtraCands.clear();
00142
00143 std::multimap<float,SimpleL1MuGMTCand*> mySimpleL1MuonCandsTemp;
00144
00145 for( unsigned fsimi=0; fsimi < nmuons; ++fsimi) {
00146
00147 const SimTrack& mySimTrack = (*simMuons)[fsimi];
00148
00149 int pid = mySimTrack.type();
00150 if ( fabs(pid) != 13 ) continue;
00151
00152
00153
00154 bool hasPSimHits = false;
00155 GlobalPoint glbPosition;
00156 PSimHitContainer::const_iterator simDTHit=muonDTHits->begin();
00157 PSimHitContainer::const_iterator endDTHit=muonDTHits->end();
00158 for ( ; simDTHit!=endDTHit; ++simDTHit) {
00159 if ( simDTHit->trackId() == mySimTrack.trackId() ) {
00160 glbPosition = dtGeometry->idToDet(simDTHit->detUnitId())->surface().toGlobal(simDTHit->localPosition());
00161 hasPSimHits = true;
00162 break;
00163 }
00164 }
00165
00166 if (! hasPSimHits) {
00167 PSimHitContainer::const_iterator simCSCHit=muonCSCHits->begin();
00168 PSimHitContainer::const_iterator endCSCHit=muonCSCHits->end();
00169 for ( ; simCSCHit!=endCSCHit; ++simCSCHit) {
00170 if ( simCSCHit->trackId() == mySimTrack.trackId() ) {
00171 glbPosition = cscGeometry->idToDet(simCSCHit->detUnitId())->surface().toGlobal(simCSCHit->localPosition());
00172 hasPSimHits = true;
00173 break;
00174 }
00175 }
00176 }
00177
00178 if (! hasPSimHits) {
00179 PSimHitContainer::const_iterator simRPCHit=muonRPCHits->begin();
00180 PSimHitContainer::const_iterator endRPCHit=muonRPCHits->end();
00181 for ( ; simRPCHit!=endRPCHit; ++simRPCHit) {
00182 if ( simRPCHit->trackId() == mySimTrack.trackId() ) {
00183 glbPosition = rpcGeometry->idToDet(simRPCHit->detUnitId())->surface().toGlobal(simRPCHit->localPosition());
00184 hasPSimHits = true;
00185 break;
00186 }
00187 }
00188 }
00189
00190
00191 if (hasPSimHits) {
00192
00193 nMu++;
00194
00195
00196
00197
00198 double pT = mySimTrack.momentum().pt();
00199 double eta = glbPosition.eta();
00200
00201 if (eta > 2.4) eta = 2.4-1e-6; else if (eta < -2.4) eta = -2.4+1e-6;
00202 double phi = glbPosition.phi();
00203 if ( phi < 0. ) phi = 2* M_PI + phi;
00204
00205 unsigned etaIndex = theMuScales->getGMTEtaScale()->getPacked(eta);
00206 unsigned phiIndex = theMuScales->getPhiScale()->getPacked(phi);
00207 unsigned pTIndex = theMuPtScale->getPtScale()->getPacked(pT);
00208 float etaValue = theMuScales->getGMTEtaScale()->getLowEdge(etaIndex);
00209 float phiValue = theMuScales->getPhiScale()->getLowEdge(phiIndex);
00210 float pTValue = theMuPtScale->getPtScale()->getLowEdge(pTIndex) + 1e-6;
00211 float etaValue2 = theMuScales->getGMTEtaScale()->getLowEdge(etaIndex+1);
00212 float phiValue2 = theMuScales->getPhiScale()->getLowEdge(phiIndex+1);
00213 float pTValue2 = theMuPtScale->getPtScale()->getLowEdge(pTIndex+1) + 1e-6;
00214
00215
00216 if ( fabs(etaValue2 - eta) < fabs(etaValue-eta) ) {
00217 etaValue = etaValue2;
00218 ++etaIndex;
00219 }
00220 if ( fabs(phiValue2-phi) < fabs(phiValue-phi) ) {
00221 phiValue = phiValue2;
00222 ++phiIndex;
00223 }
00224 if ( fabs(pTValue2-pT) < fabs(pTValue-pT) ) {
00225 pTValue = pTValue2;
00226 ++pTIndex;
00227 }
00228
00229 SimpleL1MuGMTCand * thisL1MuonCand =
00230 new SimpleL1MuGMTCand(&mySimTrack,
00231 etaIndex, phiIndex, pTIndex,
00232 etaValue,phiValue,pTValue);
00233 bool hasL1 = myL1EfficiencyHandler->kill(thisL1MuonCand);
00234 if (hasL1) {
00235 bool status2 = myL1PtSmearer->smear(thisL1MuonCand);
00236 if (!status2) { std::cout << "Pt smearing of L1 muon went wrong!!" << std::endl; }
00237 if (status2) {
00238 mySimpleL1MuonCandsTemp.insert(
00239 std::pair<float,SimpleL1MuGMTCand*>(thisL1MuonCand->ptValue(),thisL1MuonCand));
00240 }
00241 else {
00242 delete thisL1MuonCand;
00243 }
00244 }
00245
00246 }
00247
00248 }
00249
00250
00251 std::multimap<float,SimpleL1MuGMTCand*>::const_reverse_iterator L1mu = mySimpleL1MuonCandsTemp.rbegin();
00252 std::multimap<float,SimpleL1MuGMTCand*>::const_reverse_iterator lastL1mu = mySimpleL1MuonCandsTemp.rend();
00253 unsigned rank=0;
00254 unsigned rankb=0;
00255 unsigned rankf=0;
00256 for ( ; L1mu!=lastL1mu; ++L1mu ) {
00257 SimpleL1MuGMTCand* theMuon = L1mu->second;
00258 theMuon->setRPCBit(0);
00259 ++rank;
00260 bool addMu = false;
00261 if (theMuon->isFwd() ) {
00262 if ( rankf < 4 ) addMu = true;
00263 theMuon->setRPCIndex(rankf);
00264 theMuon->setDTCSCIndex(rankf);
00265 rankf++;
00266 } else {
00267 if ( rankb < 4 ) addMu = true;
00268 theMuon->setRPCIndex(rankb);
00269 theMuon->setDTCSCIndex(rankb);
00270 rankb++;
00271 }
00272
00273 if ( addMu ) {
00274 theMuon->setRank(rank);
00275 mySimpleL1MuonCands.push_back(theMuon);
00276 double pt = theMuon->ptValue() + 1.e-6 ;
00277 double eta = theMuon->etaValue();
00278 double phi = theMuon->phiValue();
00279 math::PtEtaPhiMLorentzVector PtEtaPhiMP4(pt,eta,phi,muonMassGeV_);
00280 math::XYZTLorentzVector myL1P4(PtEtaPhiMP4);
00281
00282 mySimpleL1MuonExtraCands.push_back( l1extra::L1MuonParticle( theMuon->charge(), myL1P4, *theMuon ) );
00283 }
00284 else {
00285 theMuon->setRank(0);
00286 }
00287
00288 }
00289
00290
00291
00292
00293 int nL1 = mySimpleL1MuonCands.size();
00294 nMuonTot += nMu;
00295 nL1MuonTot += nL1;
00296
00297 std::auto_ptr<L1MuonCollection> l1Out(new L1MuonCollection);
00298 std::auto_ptr<L1ExtraCollection> l1ExtraOut(new L1ExtraCollection);
00299 std::auto_ptr<L1MuGMTReadoutCollection> l1ReadOut(new L1MuGMTReadoutCollection(1));
00300
00301 loadL1Muons(*l1Out,*l1ExtraOut,*l1ReadOut);
00302 iEvent.put(l1Out);
00303 iEvent.put(l1ExtraOut);
00304 iEvent.put(l1ReadOut);
00305
00306 L1mu = mySimpleL1MuonCandsTemp.rbegin();
00307 for ( ; L1mu!=lastL1mu; ++L1mu ) {
00308 delete L1mu->second;
00309 }
00310 }
00311
00312
00313 void FastL1MuonProducer::loadL1Muons(L1MuonCollection & c ,
00314 L1ExtraCollection & d,
00315 L1MuGMTReadoutCollection & e) const
00316 {
00317
00318 FML1Muons::const_iterator l1mu;
00319 L1ExtraCollection::const_iterator l1ex;
00320 L1MuGMTReadoutRecord rc = L1MuGMTReadoutRecord(0);
00321
00322
00323
00324 for (l1mu=mySimpleL1MuonCands.begin();l1mu!=mySimpleL1MuonCands.end();++l1mu) {
00325 c.push_back(*(*l1mu));
00326 }
00327
00328
00329 int nr = 0;
00330 int nrb = 0;
00331 int nrf = 0;
00332 for (l1ex=mySimpleL1MuonExtraCands.begin();l1ex!=mySimpleL1MuonExtraCands.end();++l1ex) {
00333
00334 d.push_back(*l1ex);
00335
00336 L1MuGMTExtendedCand aMuon(l1ex->gmtMuonCand());
00337
00338 rc.setGMTCand(nr,aMuon);
00339
00340 double etaPilePoil = mySimpleL1MuonCands[nr]->getMomentum().Eta();
00341
00342 nr++;
00343 unsigned typeRPC=0;
00344 unsigned typeDTCSC=0;
00345 unsigned RPCIndex=0;
00346 unsigned DTCSCIndex=0;
00347 unsigned RPCRegionalEtaIndex=0;
00348 unsigned DTCSCRegionalEtaIndex=0;
00349 float etaRPCValue=-10.;
00350 float etaDTCSCValue=-10.;
00351
00352 if ( aMuon.isFwd() ) {
00353
00354 rc.setGMTFwdCand(nrf,aMuon);
00355
00356
00357 typeDTCSC = 2;
00358 DTCSCIndex = 8+nrf;
00359 DTCSCRegionalEtaIndex = theMuScales->getRegionalEtaScale(2)->getPacked(etaPilePoil);
00360 etaDTCSCValue = theMuScales->getRegionalEtaScale(2)->getLowEdge(DTCSCRegionalEtaIndex);
00361 float etaDTCSCValue2 = theMuScales->getRegionalEtaScale(2)->getLowEdge(DTCSCRegionalEtaIndex+1);
00362 if ( fabs(etaDTCSCValue2-etaPilePoil) < fabs(etaDTCSCValue-etaPilePoil) ) {
00363 etaDTCSCValue = etaDTCSCValue2;
00364 ++DTCSCRegionalEtaIndex;
00365 }
00366
00367 if ( fabs(etaPilePoil) < 2.1 ) {
00368 RPCIndex = 12+nrf;
00369 typeRPC = 3;
00370 RPCRegionalEtaIndex = theMuScales->getRegionalEtaScale(3)->getPacked(etaPilePoil);
00371 etaRPCValue = theMuScales->getRegionalEtaScale(3)->getLowEdge(RPCRegionalEtaIndex);
00372 float etaRPCValue2 = theMuScales->getRegionalEtaScale(3)->getLowEdge(RPCRegionalEtaIndex+1);
00373 if ( fabs(etaRPCValue2-etaPilePoil) < fabs(etaRPCValue-etaPilePoil) ) {
00374 etaRPCValue = etaRPCValue2;
00375 ++RPCRegionalEtaIndex;
00376 }
00377 }
00378
00379 nrf++;
00380
00381
00382 } else {
00383
00384 rc.setGMTBrlCand(nrb,aMuon);
00385
00386
00387 typeDTCSC = 0;
00388 DTCSCIndex = 0+nrb;
00389 DTCSCRegionalEtaIndex = theMuScales->getRegionalEtaScale(0)->getPacked(etaPilePoil);
00390 etaDTCSCValue = theMuScales->getRegionalEtaScale(0)->getLowEdge(DTCSCRegionalEtaIndex);
00391 float etaDTCSCValue2 = theMuScales->getRegionalEtaScale(0)->getLowEdge(DTCSCRegionalEtaIndex+1);
00392 if ( fabs(etaDTCSCValue2-etaPilePoil) < fabs(etaDTCSCValue-etaPilePoil) ) {
00393 etaDTCSCValue = etaDTCSCValue2;
00394 ++DTCSCRegionalEtaIndex;
00395 }
00396
00397
00398 typeRPC = 1;
00399 RPCIndex = 4+nrb;
00400 RPCRegionalEtaIndex = theMuScales->getRegionalEtaScale(1)->getPacked(etaPilePoil);
00401 etaRPCValue = theMuScales->getRegionalEtaScale(1)->getLowEdge(RPCRegionalEtaIndex);
00402 float etaRPCValue2 = theMuScales->getRegionalEtaScale(1)->getLowEdge(RPCRegionalEtaIndex+1);
00403 if ( fabs(etaRPCValue2-etaPilePoil) < fabs(etaRPCValue-etaPilePoil) ) {
00404 etaRPCValue = etaRPCValue2;
00405 ++RPCRegionalEtaIndex;
00406 }
00407
00408
00409 nrb++;
00410
00411 }
00412
00413
00414 L1MuRegionalCand regionalMuonDTCSC =
00415 L1MuRegionalCand(typeDTCSC,
00416 aMuon.phiIndex(),
00417 DTCSCRegionalEtaIndex,
00418 aMuon.ptIndex(),
00419 (1-aMuon.charge())/2,
00420 aMuon.charge_valid(),
00421 1,
00422 aMuon.quality(),
00423 aMuon.bx());
00424 regionalMuonDTCSC.setPhiValue(aMuon.phiValue());
00425 regionalMuonDTCSC.setEtaValue(etaDTCSCValue);
00426 regionalMuonDTCSC.setPtValue(aMuon.ptValue());
00427
00428 rc.setInputCand(DTCSCIndex,regionalMuonDTCSC);
00429
00430
00431 if ( fabs(etaPilePoil) < 2.1 ) {
00432 L1MuRegionalCand regionalMuonRPC =
00433 L1MuRegionalCand(typeRPC,
00434 aMuon.phiIndex(),
00435 RPCRegionalEtaIndex,
00436 aMuon.ptIndex(),
00437 (1-aMuon.charge())/2,
00438 aMuon.charge_valid(),
00439 0,
00440 aMuon.quality(),
00441 aMuon.bx());
00442 regionalMuonRPC.setPhiValue(aMuon.phiValue());
00443 regionalMuonRPC.setEtaValue(etaRPCValue);
00444 regionalMuonRPC.setPtValue(aMuon.ptValue());
00445
00446 rc.setInputCand(RPCIndex,regionalMuonRPC);
00447
00448 }
00449
00450 }
00451
00452
00453 e.addRecord(rc);
00454
00455 }
00456
00457
00458 void
00459 FastL1MuonProducer::beginJob()
00460 {
00461
00462
00463 nMuonTot = 0;
00464
00465 nL1MuonTot = 0;
00466 mySimpleL1MuonCands.clear();
00467 mySimpleL1MuonExtraCands.clear();
00468 myL1EfficiencyHandler = new FML1EfficiencyHandler(random);
00469 myL1PtSmearer = new FML1PtSmearer(random);
00470
00471
00472 }
00473
00474 void
00475 FastL1MuonProducer::beginRun(edm::Run & run,
00476 const edm::EventSetup & es) {
00477
00478
00479 es.get<MuonGeometryRecord>().get(dtGeometry);
00480
00481 es.get<MuonGeometryRecord>().get(cscGeometry);
00482
00483 es.get<MuonGeometryRecord>().get(rpcGeometry);
00484
00485
00486 edm::ESHandle< L1MuTriggerScales > muScales ;
00487 es.get< L1MuTriggerScalesRcd >().get( muScales ) ;
00488 theMuScales = &(*muScales);
00489
00490 edm::ESHandle< L1MuTriggerPtScale > muPtScale ;
00491 es.get< L1MuTriggerPtScaleRcd >().get( muPtScale ) ;
00492 theMuPtScale = &(*muPtScale);
00493
00494 }
00495
00496
00497 void
00498 FastL1MuonProducer::endJob() {
00499
00500 if (myL1EfficiencyHandler) delete myL1EfficiencyHandler;
00501 if ( myL1PtSmearer) delete myL1PtSmearer;
00502 std::cout << " ===> FastL1MuonProducer , final report." << std::endl;
00503 std::cout << " ===> Number of total -> L1 muons in the whole job : "
00504 << nMuonTot << " -> " << nL1MuonTot << std::endl;
00505 }
00506
00507
00508 void FastL1MuonProducer::readParameters(const edm::ParameterSet& fastMuons) {
00509
00510 theSimModule = fastMuons.getParameter<edm::InputTag>("simModule");
00511 theDTHits = fastMuons.getParameter<edm::InputTag>("dtSimHits");
00512 theCSCHits = fastMuons.getParameter<edm::InputTag>("cscSimHits");
00513 theRPCHits = fastMuons.getParameter<edm::InputTag>("rpcSimHits");
00514
00515 }
00516
00517