CMS 3D CMS Logo

MuonSimHitProducer.cc
Go to the documentation of this file.
1 //
2 // Package: MuonSimHitProducer
3 // Class: MuonSimHitProducer
4 //
14 //
15 // Original Author: Martijn Mulders/Matthew Jones
16 // Created: Wed Jul 30 11:37:24 CET 2007
17 // Working: Fri Nov 9 09:39:33 CST 2007
18 //
19 // $Id: MuonSimHitProducer.cc,v 1.36 2011/10/07 08:25:42 aperrott Exp $
20 //
21 //
22 
23 // CMSSW headers
25 
26 // Fast Simulation headers
34 
35 // SimTrack
39 
40 // STL headers
41 #include <vector>
42 #include <iostream>
43 
44 // RecoMuon headers
49 
50 // Tracking Tools
53 
54 // Data Formats
58 
59 // for particle table
61 
63 // Geometry, Magnetic Field
69 
71 
72 // #include "TrackingTools/TrackAssociator/interface/TrackDetectorAssociator.h"
73 
74 //for debug only
75 //#define FAMOS_DEBUG
76 
77 //
78 // constructors and destructor
79 //
81  theEstimator(iConfig.getParameter<double>("Chi2EstimatorCut")),
82  propagatorWithoutMaterial(nullptr)
83  {
84 
85  // Read relevant parameters
87  iConfig.getParameter<edm::ParameterSet>("TRACKS"),
88  iConfig.getParameter<edm::ParameterSet>("MaterialEffectsForMuons"));
89 
90  //
91  // register your products ... need to declare at least one possible product...
92  //
93  produces<edm::PSimHitContainer>("MuonCSCHits");
94  produces<edm::PSimHitContainer>("MuonDTHits");
95  produces<edm::PSimHitContainer>("MuonRPCHits");
96 
97  edm::ParameterSet serviceParameters =
98  iConfig.getParameter<edm::ParameterSet>("ServiceParameters");
99  theService = new MuonServiceProxy(serviceParameters);
100 
101  // consumes
102  simMuonToken = consumes<std::vector<SimTrack> >(simMuonLabel);
103  simVertexToken = consumes<std::vector<SimVertex> >(simVertexLabel);
104 
105 }
106 
107 // ---- method called once each job just before starting event loop ----
108 void
110 
111  //services
113  edm::ESHandle<DTGeometry> dtGeometry;
114  edm::ESHandle<CSCGeometry> cscGeometry;
115  edm::ESHandle<RPCGeometry> rpcGeometry;
117 
118  es.get<IdealMagneticFieldRecord>().get(magField);
119  es.get<MuonGeometryRecord>().get("MisAligned",dtGeometry);
120  es.get<MuonGeometryRecord>().get("MisAligned",cscGeometry);
121  es.get<MuonGeometryRecord>().get(rpcGeometry);
122 
123  magfield = &(*magField);
124  dtGeom = &(*dtGeometry);
125  cscGeom = &(*cscGeometry);
126  rpcGeom = &(*rpcGeometry);
127 
128  theService->update(es);
129 
130  // A few propagators
131  propagatorWithMaterial = &(*(theService->propagator("SteppingHelixPropagatorAny")));
133  SteppingHelixPropagator* SHpropagator = dynamic_cast<SteppingHelixPropagator*> (propagatorWithoutMaterial); // Beuark!
134  SHpropagator->setMaterialMode(true); // switches OFF material effects;
135 
136 }
137 
139 {
140  // do anything here that needs to be done at destruction time
141  // (e.g. close files, deallocate resources etc.)
142 
145 }
146 
147 
148 //
149 // member functions
150 //
151 
152 // ------------ method called to produce the data ------------
153 
154 void
156  // using namespace edm;
157  // using namespace std;
159  iSetup.getData(pdg);
160  ParticleTable::Sentry ptable(pdg.product());
161 
163 
164  MuonPatternRecoDumper dumper;
165 
168  std::vector<PSimHit> theCSCHits;
169  std::vector<PSimHit> theDTHits;
170  std::vector<PSimHit> theRPCHits;
171 
173  iEvent.getByToken(simMuonToken,simMuons);
174  iEvent.getByToken(simVertexToken,simVertices);
175 
176  for ( unsigned int itrk=0; itrk<simMuons->size(); itrk++ ) {
177  const SimTrack &mySimTrack = (*simMuons)[itrk];
178  math::XYZTLorentzVector mySimP4(mySimTrack.momentum().x(),
179  mySimTrack.momentum().y(),
180  mySimTrack.momentum().z(),
181  mySimTrack.momentum().t());
182 
183  // Decaying hadrons are now in the list, and so are their muon daughter
184  // Ignore the hadrons here.
185  int pid = mySimTrack.type();
186  if ( abs(pid) != 13 ) continue;
187 
188  double t0 = 0;
189  GlobalPoint initialPosition;
190  int ivert = mySimTrack.vertIndex();
191  if ( ivert >= 0 ) {
192  t0 = (*simVertices)[ivert].position().t();
193  GlobalPoint xyzzy((*simVertices)[ivert].position().x(),
194  (*simVertices)[ivert].position().y(),
195  (*simVertices)[ivert].position().z());
196  initialPosition = xyzzy;
197  }
198 //
199 // Presumably t0 has dimensions of cm if not mm?
200 // Convert to ns for internal calculations.
201 // I wonder where we should get c from?
202 //
203  double tof = t0/29.98;
204 
205 #ifdef FAMOS_DEBUG
206  std::cout << " ===> MuonSimHitProducer::reconstruct() found SIMTRACK - pid = "
207  << pid ;
208  std::cout << " : pT = " << mySimP4.Pt()
209  << ", eta = " << mySimP4.Eta()
210  << ", phi = " << mySimP4.Phi() << std::endl;
211 #endif
212 
213 //
214 // Produce muons sim hits starting from undecayed simulated muons
215 //
216 
217  GlobalPoint startingPosition(mySimTrack.trackerSurfacePosition().x(),
218  mySimTrack.trackerSurfacePosition().y(),
219  mySimTrack.trackerSurfacePosition().z());
220  GlobalVector startingMomentum(mySimTrack.trackerSurfaceMomentum().x(),
221  mySimTrack.trackerSurfaceMomentum().y(),
222  mySimTrack.trackerSurfaceMomentum().z());
223 //
224 // Crap... there's no time-of-flight to the trackerSurfacePosition()...
225 // So, this will be wrong when the curvature can't be neglected, but that
226 // will be rather seldom... May as well ignore the mass too.
227 //
228  GlobalVector dtracker = startingPosition-initialPosition;
229  tof += dtracker.mag()/29.98;
230 
231 #ifdef FAMOS_DEBUG
232  std::cout << " the Muon START position " << startingPosition << std::endl;
233  std::cout << " the Muon START momentum " << startingMomentum << std::endl;
234 #endif
235 
236 //
237 // Some magic to define a TrajectoryStateOnSurface
238 //
239  PlaneBuilder pb;
240  GlobalVector zAxis = startingMomentum.unit();
241  GlobalVector yAxis(zAxis.y(),-zAxis.x(),0);
242  GlobalVector xAxis = yAxis.cross(zAxis);
244  PlaneBuilder::ReturnType startingPlane = pb.plane(startingPosition,rot);
245  GlobalTrajectoryParameters gtp(startingPosition,
246  startingMomentum,
247  (int)mySimTrack.charge(),
248  magfield);
249  TrajectoryStateOnSurface startingState(gtp,*startingPlane);
250 
251  std::vector<const DetLayer *> navLayers;
252  if ( fabs(startingState.globalMomentum().eta()) > 4.5 ) {
253  navLayers = navigation.compatibleEndcapLayers(*(startingState.freeState()),
254  alongMomentum);
255  }
256  else {
257  navLayers = navigation.compatibleLayers(*(startingState.freeState()),
258  alongMomentum);
259  }
260  /*
261  edm::ESHandle<Propagator> propagator =
262  theService->propagator("SteppingHelixPropagatorAny");
263  */
264 
265  if ( navLayers.empty() ) continue;
266 
267 #ifdef FAMOS_DEBUG
268  std::cout << "Found " << navLayers.size()
269  << " compatible DetLayers..." << std::endl;
270 #endif
271 
272  TrajectoryStateOnSurface propagatedState = startingState;
273  for ( unsigned int ilayer=0; ilayer<navLayers.size(); ilayer++ ) {
274 
275 #ifdef FAMOS_DEBUG
276  std::cout << "Propagating to layer " << ilayer << " "
277  << dumper.dumpLayer(navLayers[ilayer])
278  << std::endl;
279 #endif
280 
281  std::vector<DetWithState> comps =
282  navLayers[ilayer]->compatibleDets(propagatedState,*propagatorWithMaterial,theEstimator);
283  if ( comps.empty() ) continue;
284 
285 #ifdef FAMOS_DEBUG
286  std::cout << "Propagating " << propagatedState << std::endl;
287 #endif
288 
289  // Starting momentum
290  double pi = propagatedState.globalMomentum().mag();
291 
292  // Propagate with material effects (dE/dx average only)
293  SteppingHelixStateInfo shsStart(*(propagatedState.freeTrajectoryState()));
294  SteppingHelixStateInfo shsDest;
295  ((const SteppingHelixPropagator*)propagatorWithMaterial)->propagate(shsStart,navLayers[ilayer]->surface(),shsDest);
296  std::pair<TrajectoryStateOnSurface,double> next(shsDest.getStateOnSurface(navLayers[ilayer]->surface()),
297  shsDest.path());
298  // No need to continue if there is no valid propagation available.
299  // This happens rarely (~0.1% of ttbar events)
300  if ( !next.first.isValid() ) continue;
301  // This is the estimate of the number of radiation lengths traversed,
302  // together with the total path length
303  double radPath = shsDest.radPath();
304  double pathLength = next.second;
305 
306  // Now propagate without dE/dx (average)
307  // [To add the dE/dx fluctuations to the actual dE/dx]
308  std::pair<TrajectoryStateOnSurface,double> nextNoMaterial =
309  propagatorWithoutMaterial->propagateWithPath(propagatedState,navLayers[ilayer]->surface());
310 
311  // Update the propagated state
312  propagatedState = next.first;
313  double pf = propagatedState.globalMomentum().mag();
314 
315  // Insert dE/dx fluctuations and multiple scattering
316  // Skip this step if nextNoMaterial.first is not valid
317  // This happens rarely (~0.02% of ttbar events)
318  if ( theMaterialEffects && nextNoMaterial.first.isValid() ) applyMaterialEffects(propagatedState, nextNoMaterial.first, radPath, &random);
319  // Check that the 'shaken' propagatedState is still valid, otherwise continue
320  if ( !propagatedState.isValid() ) continue;
321  // (No evidence that this ever happens)
322 //
323 // Consider this... 1 GeV muon has a velocity that is only 0.5% slower than c...
324 // We probably can safely ignore the mass for anything that makes it out to the
325 // muon chambers.
326 //
327  double pavg = 0.5*(pi+pf);
328  double m = mySimP4.M();
329  double rbeta = sqrt(1+m*m/(pavg*pavg))/29.98;
330  double dtof = pathLength*rbeta;
331 
332 #ifdef FAMOS_DEBUG
333  std::cout << "Propagated to next surface... path length = " << pathLength
334  << " cm, dTOF = " << dtof << " ns" << std::endl;
335 #endif
336 
337  tof += dtof;
338 
339  for ( unsigned int icomp=0; icomp<comps.size(); icomp++ )
340  {
341  const GeomDet *gd = comps[icomp].first;
342  if ( gd->subDetector() == GeomDetEnumerators::DT ) {
344  const DTChamber *chamber = dtGeom->chamber(id);
345  std::vector<const DTSuperLayer *> superlayer = chamber->superLayers();
346  for ( unsigned int isl=0; isl<superlayer.size(); isl++ ) {
347  std::vector<const DTLayer *> layer = superlayer[isl]->layers();
348  for ( unsigned int ilayer=0; ilayer<layer.size(); ilayer++ ) {
349  DTLayerId lid = layer[ilayer]->id();
350 #ifdef FAMOS_DEBUG
351  std::cout << " Extrapolated to DT ("
352  << lid.wheel() << ","
353  << lid.station() << ","
354  << lid.sector() << ","
355  << lid.superlayer() << ","
356  << lid.layer() << ")" << std::endl;
357 #endif
358 
359  const GeomDetUnit *det = dtGeom->idToDetUnit(lid);
360 
361  HelixArbitraryPlaneCrossing crossing(propagatedState.globalPosition().basicVector(),
362  propagatedState.globalMomentum().basicVector(),
363  propagatedState.transverseCurvature(),
364  anyDirection);
365  std::pair<bool,double> path = crossing.pathLength(det->surface());
366  if ( ! path.first ) continue;
367  LocalPoint lpos = det->toLocal(GlobalPoint(crossing.position(path.second)));
368  if ( ! det->surface().bounds().inside(lpos) ) continue;
369  const DTTopology& dtTopo = layer[ilayer]->specificTopology();
370  int wire = dtTopo.channel(lpos);
371  if (wire - dtTopo.firstChannel() < 0 || wire - dtTopo.lastChannel() > 0 ) continue;
372  // no drift cell here (on the chamber edge or just outside)
373  // this hit would otherwise be discarded downstream in the digitizer
374 
375  DTWireId wid(lid,wire);
376  double thickness = det->surface().bounds().thickness();
377  LocalVector lmom = det->toLocal(GlobalVector(crossing.direction(path.second)));
378  lmom = lmom.unit()*propagatedState.localMomentum().mag();
379 
380  // Factor that takes into account the (rec)hits lost because of delta's, etc.:
381  // (Not fully satisfactory patch, but it seems to work...)
382  double pmu = lmom.mag();
383  double theDTHitIneff = pmu>0? exp(kDT*log(pmu)+fDT):0.;
384  if (random.flatShoot()<theDTHitIneff) continue;
385 
386  double eloss = 0;
387  double pz = fabs(lmom.z());
388  LocalPoint entry = lpos - 0.5*thickness*lmom/pz;
389  LocalPoint exit = lpos + 0.5*thickness*lmom/pz;
390  double dtof = path.second*rbeta;
391  int trkid = mySimTrack.trackId();
392  unsigned int id = wid.rawId();
393  short unsigned int processType = 2;
394  PSimHit hit(entry,exit,lmom.mag(),
395  tof+dtof,eloss,pid,id,trkid,lmom.theta(),lmom.phi(),processType);
396  theDTHits.push_back(hit);
397 
398  }
399  }
400  }
401  else if ( gd->subDetector() == GeomDetEnumerators::CSC ) {
402  CSCDetId id(gd->geographicalId());
403  const CSCChamber *chamber = cscGeom->chamber(id);
404  std::vector<const CSCLayer *> layers = chamber->layers();
405  for ( unsigned int ilayer=0; ilayer<layers.size(); ilayer++ ) {
406  CSCDetId lid = layers[ilayer]->id();
407 
408 #ifdef FAMOS_DEBUG
409  std::cout << " Extrapolated to CSC ("
410  << lid.endcap() << ","
411  << lid.ring() << ","
412  << lid.station() << ","
413  << lid.layer() << ")" << std::endl;
414 #endif
415 
416  const GeomDetUnit *det = cscGeom->idToDetUnit(lid);
417  HelixArbitraryPlaneCrossing crossing(propagatedState.globalPosition().basicVector(),
418  propagatedState.globalMomentum().basicVector(),
419  propagatedState.transverseCurvature(),
420  anyDirection);
421  std::pair<bool,double> path = crossing.pathLength(det->surface());
422  if ( ! path.first ) continue;
423  LocalPoint lpos = det->toLocal(GlobalPoint(crossing.position(path.second)));
424  // For CSCs the Bounds are for chamber frames not gas regions
425  // if ( ! det->surface().bounds().inside(lpos) ) continue;
426  // New function knows where the 'active' volume is:
427  const CSCLayerGeometry* laygeom = layers[ilayer]->geometry();
428  if ( ! laygeom->inside( lpos ) ) continue;
429  //double thickness = laygeom->thickness(); gives number which is about 20 times too big
430  double thickness = det->surface().bounds().thickness(); // this one works much better...
431  LocalVector lmom = det->toLocal(GlobalVector(crossing.direction(path.second)));
432  lmom = lmom.unit()*propagatedState.localMomentum().mag();
433 
434  // Factor that takes into account the (rec)hits lost because of delta's, etc.:
435  // (Not fully satisfactory patch, but it seems to work...)
436  double pmu = lmom.mag();
437  double theCSCHitIneff = pmu>0? exp(kCSC*log(pmu)+fCSC):0.;
438  // Take into account the different geometry in ME11:
439  if (id.station()==1 && id.ring()==1) theCSCHitIneff = theCSCHitIneff*0.442;
440  if (random.flatShoot()<theCSCHitIneff) continue;
441 
442  double eloss = 0;
443  double pz = fabs(lmom.z());
444  LocalPoint entry = lpos - 0.5*thickness*lmom/pz;
445  LocalPoint exit = lpos + 0.5*thickness*lmom/pz;
446  double dtof = path.second*rbeta;
447  int trkid = mySimTrack.trackId();
448  unsigned int id = lid.rawId();
449  short unsigned int processType = 2;
450  PSimHit hit(entry,exit,lmom.mag(),
451  tof+dtof,eloss,pid,id,trkid,lmom.theta(),lmom.phi(),processType);
452  theCSCHits.push_back(hit);
453  }
454  }
455  else if ( gd->subDetector() == GeomDetEnumerators::RPCBarrel ||
457  RPCDetId id(gd->geographicalId());
458  const RPCChamber *chamber = rpcGeom->chamber(id);
459  std::vector<const RPCRoll *> roll = chamber->rolls();
460  for ( unsigned int iroll=0; iroll<roll.size(); iroll++ ) {
461  RPCDetId rid = roll[iroll]->id();
462 
463 #ifdef FAMOS_DEBUG
464  std::cout << " Extrapolated to RPC ("
465  << rid.ring() << ","
466  << rid.station() << ","
467  << rid.sector() << ","
468  << rid.subsector() << ","
469  << rid.layer() << ","
470  << rid.roll() << ")" << std::endl;
471 #endif
472 
473  const GeomDetUnit *det = rpcGeom->idToDetUnit(rid);
474  HelixArbitraryPlaneCrossing crossing(propagatedState.globalPosition().basicVector(),
475  propagatedState.globalMomentum().basicVector(),
476  propagatedState.transverseCurvature(),
477  anyDirection);
478  std::pair<bool,double> path = crossing.pathLength(det->surface());
479  if ( ! path.first ) continue;
480  LocalPoint lpos = det->toLocal(GlobalPoint(crossing.position(path.second)));
481  if ( ! det->surface().bounds().inside(lpos) ) continue;
482  double thickness = det->surface().bounds().thickness();
483  LocalVector lmom = det->toLocal(GlobalVector(crossing.direction(path.second)));
484  lmom = lmom.unit()*propagatedState.localMomentum().mag();
485  double eloss = 0;
486  double pz = fabs(lmom.z());
487  LocalPoint entry = lpos - 0.5*thickness*lmom/pz;
488  LocalPoint exit = lpos + 0.5*thickness*lmom/pz;
489  double dtof = path.second*rbeta;
490  int trkid = mySimTrack.trackId();
491  unsigned int id = rid.rawId();
492  short unsigned int processType = 2;
493  PSimHit hit(entry,exit,lmom.mag(),
494  tof+dtof,eloss,pid,id,trkid,lmom.theta(),lmom.phi(),processType);
495  theRPCHits.push_back(hit);
496  }
497  }
498  else {
499  std::cout << "Extrapolated to unknown subdetector '" << gd->subDetector() << "'..." << std::endl;
500  }
501  }
502  }
503  }
504 
505  std::unique_ptr<edm::PSimHitContainer> pcsc(new edm::PSimHitContainer);
506  int n = 0;
507  for ( std::vector<PSimHit>::const_iterator i = theCSCHits.begin();
508  i != theCSCHits.end(); i++ ) {
509  pcsc->push_back(*i);
510  n += 1;
511  }
512  iEvent.put(std::move(pcsc),"MuonCSCHits");
513 
514  std::unique_ptr<edm::PSimHitContainer> pdt(new edm::PSimHitContainer);
515  n = 0;
516  for ( std::vector<PSimHit>::const_iterator i = theDTHits.begin();
517  i != theDTHits.end(); i++ ) {
518  pdt->push_back(*i);
519  n += 1;
520  }
521  iEvent.put(std::move(pdt),"MuonDTHits");
522 
523  std::unique_ptr<edm::PSimHitContainer> prpc(new edm::PSimHitContainer);
524  n = 0;
525  for ( std::vector<PSimHit>::const_iterator i = theRPCHits.begin();
526  i != theRPCHits.end(); i++ ) {
527  prpc->push_back(*i);
528  n += 1;
529  }
530  iEvent.put(std::move(prpc),"MuonRPCHits");
531 
532 }
533 
534 void
536  const edm::ParameterSet& fastTracks,
537  const edm::ParameterSet& matEff) {
538  // Muons
539  std::string _simModuleLabel = fastMuons.getParameter<std::string>("simModuleLabel");
540  std::string _simModuleProcess = fastMuons.getParameter<std::string>("simModuleProcess");
541  simMuonLabel = edm::InputTag(_simModuleLabel,_simModuleProcess);
542  simVertexLabel = edm::InputTag(_simModuleLabel);
543 
544  std::vector<double> simHitIneffDT = fastMuons.getParameter<std::vector<double> >("simHitDTIneffParameters");
545  std::vector<double> simHitIneffCSC = fastMuons.getParameter<std::vector<double> >("simHitCSCIneffParameters");
546  kDT = simHitIneffDT[0];
547  fDT = simHitIneffDT[1];
548  kCSC = simHitIneffCSC[0];
549  fCSC = simHitIneffCSC[1];
550 
551  // Tracks
552  fullPattern_ = fastTracks.getUntrackedParameter<bool>("FullPatternRecognition");
553 
554  // The following should be on LogInfo
555  // std::cout << " MUON SIM HITS: FastSimulation parameters " << std::endl;
556  // std::cout << " ============================================== " << std::endl;
557  // if ( fullPattern_ )
558  // std::cout << " The FULL pattern recognition option is turned ON" << std::endl;
559  // else
560  // std::cout << " The FAST tracking option is turned ON" << std::endl;
561 
562  // Material Effects
563  theMaterialEffects = nullptr;
564  if ( matEff.getParameter<bool>("PairProduction") ||
565  matEff.getParameter<bool>("Bremsstrahlung") ||
566  matEff.getParameter<bool>("MuonBremsstrahlung") ||
567  matEff.getParameter<bool>("EnergyLoss") ||
568  matEff.getParameter<bool>("MultipleScattering") )
569  theMaterialEffects = new MaterialEffects(matEff);
570 }
571 
572 void
575  double radPath,
577 
578  // The energy loss simulator
580 
581  // The multiple scattering simulator
583 
584  // The Muon Bremsstrahlung simulator
586 
587 
588  // Initialize the Particle position, momentum and energy
589  const Surface& nextSurface = tsos.surface();
590  GlobalPoint gPos = energyLoss ? tsos.globalPosition() : tsosWithdEdx.globalPosition();
591  GlobalVector gMom = energyLoss ? tsos.globalMomentum() : tsosWithdEdx.globalMomentum();
592  double mu = 0.1056583692;
593  double en = std::sqrt(gMom.mag2()+mu*mu);
594 
595  // And now create the Particle
596  XYZTLorentzVector position(gPos.x(),gPos.y(),gPos.z(),0.);
597  XYZTLorentzVector momentum(gMom.x(),gMom.y(),gMom.z(),en);
598  float charge = (float)(tsos.charge());
599  ParticlePropagator theMuon(momentum,position,charge,nullptr);
600  theMuon.setID(-(int)charge*13);
601 
602  // Recompute the energy loss to get the fluctuations
603  if ( energyLoss ) {
604  // Difference between with and without dE/dx (average only)
605  // (for corrections once fluctuations are applied)
606  GlobalPoint gPosWithdEdx = tsosWithdEdx.globalPosition();
607  GlobalVector gMomWithdEdx = tsosWithdEdx.globalMomentum();
608  double enWithdEdx = std::sqrt(gMomWithdEdx.mag2()+mu*mu);
610  deltaPos(gPosWithdEdx.x()-gPos.x(),gPosWithdEdx.y()-gPos.y(),
611  gPosWithdEdx.z()-gPos.z(),0.);
613  deltaMom(gMomWithdEdx.x()-gMom.x(),gMomWithdEdx.y()-gMom.y(),
614  gMomWithdEdx.z()-gMom.z(), enWithdEdx -en);
615 
616  // Energy loss in iron (+ fluctuations)
617  energyLoss->updateState(theMuon, radPath, random);
618 
619  // Correcting factors to account for slight differences in material descriptions
620  // (Material description is more accurate in the stepping helix propagator)
621  radPath *= -deltaMom.E()/energyLoss->mostLikelyLoss();
622  double fac = energyLoss->deltaMom().E()/energyLoss->mostLikelyLoss();
623 
624  // Particle momentum & position after energy loss + fluctuation
625  XYZTLorentzVector theNewMomentum = theMuon.momentum() + energyLoss->deltaMom() + fac * deltaMom;
626  XYZTLorentzVector theNewPosition = theMuon.vertex() + fac * deltaPos;
627  fac = (theNewMomentum.E()*theNewMomentum.E()-mu*mu)/theNewMomentum.Vect().Mag2();
628  fac = fac>0.? std::sqrt(fac) : 1E-9;
629  theMuon.SetXYZT(theNewMomentum.Px()*fac,theNewMomentum.Py()*fac,
630  theNewMomentum.Pz()*fac,theNewMomentum.E());
631  theMuon.setVertex(theNewPosition);
632 
633  }
634 
635  // Does the actual mutliple scattering
636  if ( multipleScattering ) {
637  // Pass the vector normal to the "next" surface
638  GlobalVector normal = nextSurface.tangentPlane(tsos.globalPosition())->normalVector();
639  multipleScattering->setNormalVector(normal);
640  // Compute the amount of multiple scattering after a given path length
641  multipleScattering->updateState(theMuon, radPath, random);
642  }
643 
644  // Muon Bremsstrahlung
645  if ( bremsstrahlung ) {
646  // Compute the amount of Muon Bremsstrahlung after given path length
647  bremsstrahlung->updateState(theMuon, radPath, random);
648  }
649 
650 
651  // Fill the propagated state
652  GlobalPoint propagatedPosition(theMuon.X(),theMuon.Y(),theMuon.Z());
653  GlobalVector propagatedMomentum(theMuon.Px(),theMuon.Py(),theMuon.Pz());
654  GlobalTrajectoryParameters propagatedGtp(propagatedPosition,propagatedMomentum,(int)charge,magfield);
655  tsosWithdEdx = TrajectoryStateOnSurface(propagatedGtp,nextSurface);
656 
657 }
658 
659 
660 
661 //define this as a plug-in
void update(const edm::EventSetup &setup)
update the services each event
MuonSimHitProducer(const edm::ParameterSet &)
double mostLikelyLoss() const
Return most probable energy loss.
edm::ESHandle< MuonDetLayerGeometry > detLayerGeometry() const
get the detLayer geometry
const math::XYZVectorD & trackerSurfacePosition() const
Definition: SimTrack.h:36
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
const MagneticField * magfield
T mag2() const
Definition: PV3DBase.h:66
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:137
virtual Propagator * clone() const =0
virtual ConstReferenceCountingPointer< TangentPlane > tangentPlane(const GlobalPoint &) const =0
const GeomDet * idToDetUnit(DetId) const override
Return the pointer to the GeomDetUnit corresponding to a given DetId.
Definition: RPCGeometry.cc:48
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
Definition: LayerTriplets.cc:4
int channel(const LocalPoint &p) const override
Definition: DTTopology.cc:79
const DTGeometry * dtGeom
const DTChamber * chamber(const DTChamberId &id) const
Return a DTChamber given its id.
Definition: DTGeometry.cc:117
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
void setNormalVector(const GlobalVector &normal)
Sets the vector normal to the surface traversed.
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
MaterialEffects * theMaterialEffects
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
MultipleScatteringSimulator * multipleScatteringSimulator() const
Return the Multiple Scattering engine.
ReturnType plane(const PositionType &pos, const RotationType &rot) const
Definition: PlaneBuilder.h:22
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:47
T y() const
Definition: PV3DBase.h:63
GlobalPoint globalPosition() const
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:69
const Bounds & bounds() const
Definition: Surface.h:120
void updateState(ParticlePropagator &myTrack, double radlen, RandomEngineAndDistribution const *)
Compute the material effect (calls the sub class)
edm::EDGetTokenT< std::vector< SimVertex > > simVertexToken
TRandom random
Definition: MVATrainer.cc:138
int layer() const
Return the layer number.
Definition: DTLayerId.h:53
#define nullptr
float charge() const
charge
Definition: CoreSimTrack.cc:18
int layer() const
Definition: CSCDetId.h:61
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:42
void getData(T &iHolder) const
Definition: EventSetup.h:97
int firstChannel() const
Returns the wire number of the first wire.
Definition: DTTopology.h:78
const Double_t pi
Geom::Theta< T > theta() const
Definition: PV3DBase.h:75
const RPCGeometry * rpcGeom
LocalVector localMomentum() const
int endcap() const
Definition: CSCDetId.h:93
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
int lastChannel() const
Returns the wire number of the last wire.
Definition: DTTopology.h:80
const RPCChamber * chamber(RPCDetId id) const
Definition: RPCGeometry.cc:71
MuonBremsstrahlungSimulator * muonBremsstrahlungSimulator() const
Return the Muon Bremsstrahlung engine.
virtual bool inside(const Local3DPoint &) const =0
Determine if the point is inside the bounds.
int iEvent
Definition: GenABIO.cc:230
const SurfaceType & surface() const
const XYZTLorentzVector & momentum() const
the momentum fourvector
Definition: RawParticle.h:286
T mag() const
Definition: PV3DBase.h:67
int roll() const
Definition: RPCDetId.h:120
const GeomDet * idToDetUnit(DetId) const override
Return the pointer to the GeomDetUnit corresponding to a given DetId.
Definition: DTGeometry.cc:88
FreeTrajectoryState const * freeTrajectoryState(bool withErrors=true) const
const std::vector< const DTSuperLayer * > & superLayers() const
Return the superlayers in the chamber.
Definition: DTChamber.cc:60
int ring() const
Definition: RPCDetId.h:72
const Propagator * propagatorWithMaterial
TrajectoryStateOnSurface getStateOnSurface(const Surface &surf, bool returnTangentPlane=false) const
T sqrt(T t)
Definition: SSEVec.h:18
Propagator * propagatorWithoutMaterial
T z() const
Definition: PV3DBase.h:64
double Y() const
y of vertex
Definition: RawParticle.h:275
void setID(const int id)
Definition: RawParticle.cc:102
const XYZTLorentzVector & deltaMom() const
Returns the actual energy lost.
double Z() const
z of vertex
Definition: RawParticle.h:276
virtual std::pair< TrajectoryStateOnSurface, double > propagateWithPath(const FreeTrajectoryState &, const Surface &) const final
Definition: Propagator.cc:15
const std::vector< const RPCRoll * > & rolls() const
Return the Rolls.
Definition: RPCChamber.cc:68
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const CSCGeometry * cscGeom
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:79
void beginRun(edm::Run const &run, const edm::EventSetup &es) override
void produce(edm::Event &, const edm::EventSetup &) override
const int mu
Definition: Constants.h:22
bool inside(const Local3DPoint &, const LocalError &, float scale=1.f) const override
int vertIndex() const
index of the vertex in the Event container (-1 if no vertex)
Definition: SimTrack.h:29
const XYZTLorentzVector & vertex() const
the vertex fourvector
Definition: RawParticle.h:285
int superlayer() const
Return the superlayer number (deprecated method name)
int ring() const
Definition: CSCDetId.h:75
Vector3DBase unit() const
Definition: Vector3DBase.h:57
int layer() const
Definition: RPCDetId.h:108
unsigned int trackId() const
Definition: CoreSimTrack.h:34
virtual float thickness() const =0
const math::XYZTLorentzVectorD & trackerSurfaceMomentum() const
Definition: SimTrack.h:38
const CSCChamber * chamber(CSCDetId id) const
Return the chamber corresponding to given DetId.
Definition: CSCGeometry.cc:133
edm::EDGetTokenT< std::vector< SimTrack > > simMuonToken
int sector() const
Sector id: the group of chambers at same phi (and increasing r)
Definition: RPCDetId.h:102
double X() const
x of vertex
Definition: RawParticle.h:274
MuonServiceProxy * theService
const GeomDet * idToDetUnit(DetId) const override
Return the pointer to the GeomDetUnit corresponding to a given DetId.
Definition: CSCGeometry.cc:108
int subsector() const
SubSector id : some sectors are divided along the phi direction in subsectors (from 1 to 4 in Barrel...
Definition: RPCDetId.h:114
int type() const
particle type (HEP PDT convension)
Definition: CoreSimTrack.h:25
void readParameters(const edm::ParameterSet &, const edm::ParameterSet &, const edm::ParameterSet &)
GlobalVector globalMomentum() const
int sector() const
Definition: DTChamberId.h:61
const math::XYZTLorentzVectorD & momentum() const
Definition: CoreSimTrack.h:22
static int position[264][3]
Definition: ReadPGInfo.cc:509
T get() const
Definition: EventSetup.h:62
TkRotation< float > RotationType
edm::InputTag simMuonLabel
StreamID streamID() const
Definition: Event.h:96
int station() const
Definition: CSCDetId.h:86
std::vector< PSimHit > PSimHitContainer
int station() const
Return the station number.
Definition: DTChamberId.h:51
EnergyLossSimulator * energyLossSimulator() const
Return the Energy Loss engine.
virtual SubDetector subDetector() const
Which subdetector.
Definition: GeomDet.cc:44
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:45
T x() const
Definition: PV3DBase.h:62
const BasicVectorType & basicVector() const
Definition: PV3DBase.h:56
void applyMaterialEffects(TrajectoryStateOnSurface &tsosWithdEdx, TrajectoryStateOnSurface &tsos, double radPath, RandomEngineAndDistribution const *)
Simulate material effects in iron (dE/dx, multiple scattering)
T const * product() const
Definition: ESHandle.h:86
void setMaterialMode(bool noMaterial)
Switch for material effects mode: no material effects if true.
void setVertex(const XYZTLorentzVector &vtx)
set the vertex
Definition: RawParticle.h:288
def move(src, dest)
Definition: eostools.py:511
edm::ESHandle< Propagator > propagator(std::string propagatorName) const
get the propagator
Definition: Run.h:44
Global3DVector GlobalVector
Definition: GlobalVector.h:10
math::XYZTLorentzVector XYZTLorentzVector
Definition: RawParticle.h:15
edm::InputTag simVertexLabel
Chi2MeasurementEstimator theEstimator
int station() const
Definition: RPCDetId.h:96