CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
FastL1MuonProducer.cc
Go to the documentation of this file.
1 //
2 // Package: FastL1MuonProducer
3 // Class: FastL1MuonProducer
4 //
12 //
13 // Original Author: Andrea Perrotta
14 // Modifications: Patrick Janot.
15 // Created: Mon Oct 30 14:37:24 CET 2006
16 //
17 //
18 
19 // CMSSW headers
25 
26 // Regional eta scales...
31 
32 // Fast Simulation headers
35 
36 // SimTrack
40 
41 // L1
45 
46 // STL headers
47 #include <iostream>
48 
49 // Data Formats
54 
55 // Geometry
57 
58 #include <map>
59 
60 // constants, enums and typedefs
61 
62 //
63 // static data member definitions
64 //
65 
66 double FastL1MuonProducer::muonMassGeV_ = 0.105658369 ; // PDG06
67 
68 //
69 // constructors and destructor
70 //
72  myL1EfficiencyHandler(0),
73  myL1PtSmearer(0)
74 {
75 
77 
78  //register your products
79  produces<L1MuonCollection> ();
80  produces<L1ExtraCollection> ();
81  produces<L1MuGMTReadoutCollection>();
82 
83  // Initialize the random number generator service
85  if ( ! rng.isAvailable() ) {
86  throw cms::Exception("Configuration") <<
87  "ParamMuonProducer requires the RandomGeneratorService \n"
88  "which is not present in the configuration file. \n"
89  "You must add the service in the configuration file\n"
90  "or remove the module that requires it.";
91  }
92 
93  random = new RandomEngine(&(*rng));
94 
95 }
96 
97 
99 {
100 
101  // do anything here that needs to be done at destruction time
102  // (e.g. close files, deallocate resources etc.)
103 
104  if ( random ) {
105  delete random;
106  }
107 }
108 
109 
110 //
111 // member functions
112 //
113 
114 // ------------ method called to produce the data ------------
115 
116 void
118 {
119  using namespace edm;
120 
121  Handle<std::vector<SimTrack> > simMuons;
122  iEvent.getByLabel(theSimModule,simMuons);
123  unsigned nmuons = simMuons->size();
124  // Handle<std::vector<SimVertex> > simVertices;
125  // iEvent.getByLabel(theSimModuleLabel_,simVertices);
126 
127  Handle<PSimHitContainer> muonDTHits;
128  iEvent.getByLabel(theDTHits,muonDTHits);
129  Handle<PSimHitContainer> muonCSCHits;
130  iEvent.getByLabel(theCSCHits,muonCSCHits);
131  Handle<PSimHitContainer> muonRPCHits;
132  iEvent.getByLabel(theRPCHits,muonRPCHits);
133 
134 
135 //
136 // Loop over generated muons and reconstruct L1, L3 and Global muons
137 //
138 
139  int nMu = 0;
140  mySimpleL1MuonCands.clear();
141  mySimpleL1MuonExtraCands.clear();
142 
143  std::multimap<float,SimpleL1MuGMTCand*> mySimpleL1MuonCandsTemp;
144 
145  for( unsigned fsimi=0; fsimi < nmuons; ++fsimi) {
146  // The sim track can be a muon or a decaying hadron
147  const SimTrack& mySimTrack = (*simMuons)[fsimi];
148  // Keep only the muons at L1 (either primary or secondary)
149  int pid = mySimTrack.type();
150  if ( fabs(pid) != 13 ) continue;
151 
152  // Check whether there are hits in DT/CSC/RPC,
153  // and keep for the L1 mu the position of first such hit:
154  bool hasPSimHits = false;
155  GlobalPoint glbPosition;
156  PSimHitContainer::const_iterator simDTHit=muonDTHits->begin();
157  PSimHitContainer::const_iterator endDTHit=muonDTHits->end();
158  for ( ; simDTHit!=endDTHit; ++simDTHit) {
159  if ( simDTHit->trackId() == mySimTrack.trackId() ) {
160  glbPosition = dtGeometry->idToDet(simDTHit->detUnitId())->surface().toGlobal(simDTHit->localPosition());
161  hasPSimHits = true;
162  break;
163  }
164  }
165 
166  if (! hasPSimHits) {
167  PSimHitContainer::const_iterator simCSCHit=muonCSCHits->begin();
168  PSimHitContainer::const_iterator endCSCHit=muonCSCHits->end();
169  for ( ; simCSCHit!=endCSCHit; ++simCSCHit) {
170  if ( simCSCHit->trackId() == mySimTrack.trackId() ) {
171  glbPosition = cscGeometry->idToDet(simCSCHit->detUnitId())->surface().toGlobal(simCSCHit->localPosition());
172  hasPSimHits = true;
173  break;
174  }
175  }
176  }
177 
178  if (! hasPSimHits) {
179  PSimHitContainer::const_iterator simRPCHit=muonRPCHits->begin();
180  PSimHitContainer::const_iterator endRPCHit=muonRPCHits->end();
181  for ( ; simRPCHit!=endRPCHit; ++simRPCHit) {
182  if ( simRPCHit->trackId() == mySimTrack.trackId() ) {
183  glbPosition = rpcGeometry->idToDet(simRPCHit->detUnitId())->surface().toGlobal(simRPCHit->localPosition());
184  hasPSimHits = true;
185  break;
186  }
187  }
188  }
189 
190  // *** Reconstruct parameterized muons starting from undecayed simulated muons
191  if (hasPSimHits) {
192 
193  nMu++;
194 
195  //
196  // Now L1 parametrization
197  //
198  double pT = mySimTrack.momentum().pt();
199  double eta = glbPosition.eta();
200  // Avoid L1MuScales complains if |eta|>2.4:
201  if (eta > 2.4) eta = 2.4-1e-6; else if (eta < -2.4) eta = -2.4+1e-6;
202  double phi = glbPosition.phi();
203  if ( phi < 0. ) phi = 2* M_PI + phi;
204 
205  unsigned etaIndex = theMuScales->getGMTEtaScale()->getPacked(eta);
206  unsigned phiIndex = theMuScales->getPhiScale()->getPacked(phi);
207  unsigned pTIndex = theMuPtScale->getPtScale()->getPacked(pT);
208  float etaValue = theMuScales->getGMTEtaScale()->getLowEdge(etaIndex);
209  float phiValue = theMuScales->getPhiScale()->getLowEdge(phiIndex);
210  float pTValue = theMuPtScale->getPtScale()->getLowEdge(pTIndex) + 1e-6;
211  float etaValue2 = theMuScales->getGMTEtaScale()->getLowEdge(etaIndex+1);
212  float phiValue2 = theMuScales->getPhiScale()->getLowEdge(phiIndex+1);
213  float pTValue2 = theMuPtScale->getPtScale()->getLowEdge(pTIndex+1) + 1e-6;
214 
215  // Choose the closest index. (Not sure it is what is to be done)
216  if ( fabs(etaValue2 - eta) < fabs(etaValue-eta) ) {
217  etaValue = etaValue2;
218  ++etaIndex;
219  }
220  if ( fabs(phiValue2-phi) < fabs(phiValue-phi) ) {
221  phiValue = phiValue2;
222  ++phiIndex;
223  }
224  if ( fabs(pTValue2-pT) < fabs(pTValue-pT) ) {
225  pTValue = pTValue2;
226  ++pTIndex;
227  }
228 
229  SimpleL1MuGMTCand * thisL1MuonCand =
230  new SimpleL1MuGMTCand(&mySimTrack,
231  etaIndex, phiIndex, pTIndex,
232  etaValue,phiValue,pTValue);
233  bool hasL1 = myL1EfficiencyHandler->kill(thisL1MuonCand);
234  if (hasL1) {
235  bool status2 = myL1PtSmearer->smear(thisL1MuonCand);
236  if (!status2) { std::cout << "Pt smearing of L1 muon went wrong!!" << std::endl; }
237  if (status2) {
238  mySimpleL1MuonCandsTemp.insert(
239  std::pair<float,SimpleL1MuGMTCand*>(thisL1MuonCand->ptValue(),thisL1MuonCand));
240  }
241  else {
242  delete thisL1MuonCand;
243  }
244  }
245 
246  }
247 
248  }
249 
250  // kill low ranked L1 muons, and fill L1extra muons -->
251  std::multimap<float,SimpleL1MuGMTCand*>::const_reverse_iterator L1mu = mySimpleL1MuonCandsTemp.rbegin();
252  std::multimap<float,SimpleL1MuGMTCand*>::const_reverse_iterator lastL1mu = mySimpleL1MuonCandsTemp.rend();
253  unsigned rank=0;
254  unsigned rankb=0;
255  unsigned rankf=0;
256  for ( ; L1mu!=lastL1mu; ++L1mu ) {
257  SimpleL1MuGMTCand* theMuon = L1mu->second;
258  theMuon->setRPCBit(0);
259  ++rank;
260  bool addMu = false;
261  if (theMuon->isFwd() ) {
262  if ( rankf < 4 ) addMu = true;
263  theMuon->setRPCIndex(rankf);
264  theMuon->setDTCSCIndex(rankf);
265  rankf++;
266  } else {
267  if ( rankb < 4 ) addMu = true;
268  theMuon->setRPCIndex(rankb);
269  theMuon->setDTCSCIndex(rankb);
270  rankb++;
271  }
272 
273  if ( addMu ) {
274  theMuon->setRank(rank);
275  mySimpleL1MuonCands.push_back(theMuon);
276  double pt = theMuon->ptValue() + 1.e-6 ;
277  double eta = theMuon->etaValue();
278  double phi = theMuon->phiValue();
279  math::PtEtaPhiMLorentzVector PtEtaPhiMP4(pt,eta,phi,muonMassGeV_);
280  math::XYZTLorentzVector myL1P4(PtEtaPhiMP4);
281  // math::PtEtaPhiMLorentzVector myL1P4(pt,eta,phi,muonMassGeV_);
282  mySimpleL1MuonExtraCands.push_back( l1extra::L1MuonParticle( theMuon->charge(), myL1P4, *theMuon ) );
283  }
284  else {
285  theMuon->setRank(0);
286  }
287 
288  }
289 
290 // end killing of low ranked L1 muons -->
291 
292 
293  int nL1 = mySimpleL1MuonCands.size();
294  nMuonTot += nMu;
295  nL1MuonTot += nL1;
296 
297  std::auto_ptr<L1MuonCollection> l1Out(new L1MuonCollection);
298  std::auto_ptr<L1ExtraCollection> l1ExtraOut(new L1ExtraCollection);
299  std::auto_ptr<L1MuGMTReadoutCollection> l1ReadOut(new L1MuGMTReadoutCollection(1));
300 
301  loadL1Muons(*l1Out,*l1ExtraOut,*l1ReadOut);
302  iEvent.put(l1Out);
303  iEvent.put(l1ExtraOut);
304  iEvent.put(l1ReadOut);
305 
306  L1mu = mySimpleL1MuonCandsTemp.rbegin();
307  for ( ; L1mu!=lastL1mu; ++L1mu ) {
308  delete L1mu->second;
309  }
310 }
311 
312 
314  L1ExtraCollection & d,
315  L1MuGMTReadoutCollection & e) const
316 {
317 
318  FML1Muons::const_iterator l1mu;
319  L1ExtraCollection::const_iterator l1ex;
321 
322  // Add L1 muons:
323  // int nmuons = mySimpleL1MuonCands.size();
324  for (l1mu=mySimpleL1MuonCands.begin();l1mu!=mySimpleL1MuonCands.end();++l1mu) {
325  c.push_back(*(*l1mu));
326  }
327 
328 // Add extra particles.
329  int nr = 0;
330  int nrb = 0;
331  int nrf = 0;
332  for (l1ex=mySimpleL1MuonExtraCands.begin();l1ex!=mySimpleL1MuonExtraCands.end();++l1ex) {
333 
334  d.push_back(*l1ex);
335 
336  L1MuGMTExtendedCand aMuon(l1ex->gmtMuonCand());
337 
338  rc.setGMTCand(nr,aMuon);
339  // Find the regional eta index
340  double etaPilePoil = mySimpleL1MuonCands[nr]->getMomentum().Eta();
341 
342  nr++;
343  unsigned typeRPC=0;
344  unsigned typeDTCSC=0;
345  unsigned RPCIndex=0;
346  unsigned DTCSCIndex=0;
347  unsigned RPCRegionalEtaIndex=0;
348  unsigned DTCSCRegionalEtaIndex=0;
349  float etaRPCValue=-10.;
350  float etaDTCSCValue=-10.;
351  // Forward muons
352  if ( aMuon.isFwd() ) {
353 
354  rc.setGMTFwdCand(nrf,aMuon);
355 
356  // CSC
357  typeDTCSC = 2;
358  DTCSCIndex = 8+nrf;
359  DTCSCRegionalEtaIndex = theMuScales->getRegionalEtaScale(2)->getPacked(etaPilePoil);
360  etaDTCSCValue = theMuScales->getRegionalEtaScale(2)->getLowEdge(DTCSCRegionalEtaIndex);
361  float etaDTCSCValue2 = theMuScales->getRegionalEtaScale(2)->getLowEdge(DTCSCRegionalEtaIndex+1);
362  if ( fabs(etaDTCSCValue2-etaPilePoil) < fabs(etaDTCSCValue-etaPilePoil) ) {
363  etaDTCSCValue = etaDTCSCValue2;
364  ++DTCSCRegionalEtaIndex;
365  }
366  // RPC (limited to the RPC acceptance)
367  if ( fabs(etaPilePoil) < 2.1 ) {
368  RPCIndex = 12+nrf;
369  typeRPC = 3;
370  RPCRegionalEtaIndex = theMuScales->getRegionalEtaScale(3)->getPacked(etaPilePoil);
371  etaRPCValue = theMuScales->getRegionalEtaScale(3)->getLowEdge(RPCRegionalEtaIndex);
372  float etaRPCValue2 = theMuScales->getRegionalEtaScale(3)->getLowEdge(RPCRegionalEtaIndex+1);
373  if ( fabs(etaRPCValue2-etaPilePoil) < fabs(etaRPCValue-etaPilePoil) ) {
374  etaRPCValue = etaRPCValue2;
375  ++RPCRegionalEtaIndex;
376  }
377  }
378  // Next muon
379  nrf++;
380 
381  // Barrel muons
382  } else {
383 
384  rc.setGMTBrlCand(nrb,aMuon);
385 
386  // DT
387  typeDTCSC = 0;
388  DTCSCIndex = 0+nrb;
389  DTCSCRegionalEtaIndex = theMuScales->getRegionalEtaScale(0)->getPacked(etaPilePoil);
390  etaDTCSCValue = theMuScales->getRegionalEtaScale(0)->getLowEdge(DTCSCRegionalEtaIndex);
391  float etaDTCSCValue2 = theMuScales->getRegionalEtaScale(0)->getLowEdge(DTCSCRegionalEtaIndex+1);
392  if ( fabs(etaDTCSCValue2-etaPilePoil) < fabs(etaDTCSCValue-etaPilePoil) ) {
393  etaDTCSCValue = etaDTCSCValue2;
394  ++DTCSCRegionalEtaIndex;
395  }
396 
397  // RPC
398  typeRPC = 1;
399  RPCIndex = 4+nrb;
400  RPCRegionalEtaIndex = theMuScales->getRegionalEtaScale(1)->getPacked(etaPilePoil);
401  etaRPCValue = theMuScales->getRegionalEtaScale(1)->getLowEdge(RPCRegionalEtaIndex);
402  float etaRPCValue2 = theMuScales->getRegionalEtaScale(1)->getLowEdge(RPCRegionalEtaIndex+1);
403  if ( fabs(etaRPCValue2-etaPilePoil) < fabs(etaRPCValue-etaPilePoil) ) {
404  etaRPCValue = etaRPCValue2;
405  ++RPCRegionalEtaIndex;
406  }
407 
408  // Next muon
409  nrb++;
410 
411  }
412 
413  // Add a muon regional candidate - first DT/CSC
414  L1MuRegionalCand regionalMuonDTCSC =
415  L1MuRegionalCand(typeDTCSC,
416  aMuon.phiIndex(),
417  DTCSCRegionalEtaIndex,
418  aMuon.ptIndex(),
419  (1-aMuon.charge())/2,
420  aMuon.charge_valid(),
421  1, // FineHalo
422  aMuon.quality(),
423  aMuon.bx());
424  regionalMuonDTCSC.setPhiValue(aMuon.phiValue());
425  regionalMuonDTCSC.setEtaValue(etaDTCSCValue);
426  regionalMuonDTCSC.setPtValue(aMuon.ptValue());
427 
428  rc.setInputCand(DTCSCIndex,regionalMuonDTCSC);
429 
430  // Then RPC (if in RPC acceptance)
431  if ( fabs(etaPilePoil) < 2.1 ) {
432  L1MuRegionalCand regionalMuonRPC =
433  L1MuRegionalCand(typeRPC,
434  aMuon.phiIndex(),
435  RPCRegionalEtaIndex,
436  aMuon.ptIndex(),
437  (1-aMuon.charge())/2,
438  aMuon.charge_valid(),
439  0, // FineHalo
440  aMuon.quality(),
441  aMuon.bx());
442  regionalMuonRPC.setPhiValue(aMuon.phiValue());
443  regionalMuonRPC.setEtaValue(etaRPCValue);
444  regionalMuonRPC.setPtValue(aMuon.ptValue());
445 
446  rc.setInputCand(RPCIndex,regionalMuonRPC);
447 
448  }
449 
450  }
451 
452  // Update the event
453  e.addRecord(rc);
454 
455 }
456 
457 // ------------ method called once each job just before starting event loop ------------
458 void
460 {
461 
462  // Initialize
463  nMuonTot = 0;
464 
465  nL1MuonTot = 0;
466  mySimpleL1MuonCands.clear();
467  mySimpleL1MuonExtraCands.clear();
470 
471 
472 }
473 
474 void
476  const edm::EventSetup & es) {
477 
478 // Get the DT Geometry
479  es.get<MuonGeometryRecord>().get(dtGeometry);
480 // Get the CSC Geometry
482 // Get the RPC Geometry
484 
485  // Read trigger scales
487  es.get< L1MuTriggerScalesRcd >().get( muScales ) ;
488  theMuScales = &(*muScales);
489 
491  es.get< L1MuTriggerPtScaleRcd >().get( muPtScale ) ;
492  theMuPtScale = &(*muPtScale);
493 
494 }
495 
496 // ------------ method called once each job just after ending the event loop ------------
497 void
499 
501  if ( myL1PtSmearer) delete myL1PtSmearer;
502  std::cout << " ===> FastL1MuonProducer , final report." << std::endl;
503  std::cout << " ===> Number of total -> L1 muons in the whole job : "
504  << nMuonTot << " -> " << nL1MuonTot << std::endl;
505 }
506 
507 
509  // Muons
510  theSimModule = fastMuons.getParameter<edm::InputTag>("simModule");
511  theDTHits = fastMuons.getParameter<edm::InputTag>("dtSimHits");
512  theCSCHits = fastMuons.getParameter<edm::InputTag>("cscSimHits");
513  theRPCHits = fastMuons.getParameter<edm::InputTag>("rpcSimHits");
514 
515 }
516 
517 
float etaValue() const
Definition: L1MuGMTCand.cc:116
T getParameter(std::string const &) const
edm::ESHandle< RPCGeometry > rpcGeometry
void setRank(unsigned int rank)
set rank
float phiValue() const
Definition: L1MuGMTCand.cc:102
std::vector< L1MuGMTCand > L1MuonCollection
edm::InputTag theCSCHits
void loadL1Muons(L1MuonCollection &c, L1ExtraCollection &d, L1MuGMTReadoutCollection &e) const
FML1EfficiencyHandler * myL1EfficiencyHandler
const L1MuScale * getPtScale() const
get the Pt scale
std::vector< l1extra::L1MuonParticle > L1ExtraCollection
void readParameters(const edm::ParameterSet &)
void setGMTBrlCand(int nr, L1MuGMTExtendedCand const &cand)
set GMT barrel candidate
virtual float getLowEdge(unsigned packed) const =0
get the low edge of bin represented by packed
FML1PtSmearer * myL1PtSmearer
Geom::Phi< T > phi() const
Definition: PV3DBase.h:63
static double muonMassGeV_
bool smear(SimpleL1MuGMTCand *)
smear the transverse momentum of a SimplL1MuGMTCand
int charge() const
get charge
void setDTCSCIndex(unsigned int idxdtcsc)
set index of contributing DT/CSC muon
void setGMTFwdCand(int nr, L1MuGMTExtendedCand const &cand)
set GMT forward candidate
void setInputCand(int nr, unsigned data)
set Input muon
edm::ESHandle< CSCGeometry > cscGeometry
void setPtValue(float ptVal)
Set Pt Value.
T eta() const
const RandomEngine * random
FastL1MuonProducer(const edm::ParameterSet &)
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
Definition: LorentzVector.h:26
bool kill(const SimpleL1MuGMTCand *)
reject tracks according to parametrized algorithmic efficiency
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:30
int iEvent
Definition: GenABIO.cc:243
void setPhiValue(float phiVal)
Set Phi Value.
const L1MuTriggerPtScale * theMuPtScale
edm::ESHandle< DTGeometry > dtGeometry
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:84
edm::InputTag theSimModule
const L1MuScale * getPhiScale() const
get the phi scale
void setEtaValue(float etaVal)
Set Eta Value (need to set type, first)
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:359
L1ExtraCollection mySimpleL1MuonExtraCands
float ptValue() const
Definition: L1MuGMTCand.cc:130
edm::InputTag theDTHits
#define M_PI
Definition: BFit3D.cc:3
unsigned int trackId() const
Definition: CoreSimTrack.h:49
const T & get() const
Definition: EventSetup.h:55
void addRecord(L1MuGMTReadoutRecord const &rec)
void setRPCBit(unsigned int rpcbit)
set RPC bit (1=RPC, 0=DT/CSC or matched)
T eta() const
Definition: PV3DBase.h:70
const L1MuScale * getRegionalEtaScale(int isys) const
get the regioanl muon trigger eta scale, isys = 0(DT), 1(bRPC), 2(CSC), 3(fwdRPC) ...
int type() const
particle type (HEP PDT convension)
Definition: CoreSimTrack.h:40
virtual void produce(edm::Event &, const edm::EventSetup &)
const L1MuTriggerScales * theMuScales
const math::XYZTLorentzVectorD & momentum() const
particle info...
Definition: CoreSimTrack.h:36
edm::InputTag theRPCHits
virtual unsigned getPacked(float value) const =0
pack a value
virtual void beginRun(edm::Run &run, const edm::EventSetup &es)
tuple cout
Definition: gather_cfg.py:41
const L1MuScale * getGMTEtaScale() const
get the GMT eta scale
void setGMTCand(int nr, L1MuGMTExtendedCand const &cand)
set GMT candidate (does not store rank)
bool isFwd() const
get forward bit (true=forward, false=barrel)
void setRPCIndex(unsigned int idxrpc)
set index of contributing RPC muon
Definition: Run.h:31
Definition: DDAxes.h:10