CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/FastSimulation/MaterialEffects/src/MultipleScatteringSimulator.cc

Go to the documentation of this file.
00001 #include "FastSimulation/MaterialEffects/interface/MultipleScatteringSimulator.h"
00002 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00003 
00004 #include <cmath>
00005 
00006 MultipleScatteringSimulator::MultipleScatteringSimulator(
00007   const RandomEngine* engine, double A, double Z, double density, double radLen) :
00008     MaterialEffectsSimulator(engine,A,Z,density,radLen)
00009 {
00010   sqr12 = std::sqrt(12.);
00011 }
00012 
00013 void MultipleScatteringSimulator::compute(ParticlePropagator &Particle)
00014 {
00015 
00016   double p2 = Particle.Vect().Mag2();
00017   double m2 = Particle.mass()*Particle.mass();
00018   double e = std::sqrt(p2+m2);
00019 
00020   double pbeta = p2/e;  // This is p*beta
00021 
00022   // Average multiple scattering angle from Moliere radius
00023   // The sqrt(2) factor is because of the *space* angle
00024   double theta0 = 0.0136 / pbeta * Particle.charge() 
00025                                  * std::sqrt(2.*radLengths) 
00026                                  * (1. + 0.038*std::log(radLengths));
00027 
00028   // Generate multiple scattering space angle perpendicular to the particle motion
00029   double theta = random->gaussShoot(0.,theta0); 
00030   // Plus a random rotation angle around the particle motion
00031   double phi = 2. * 3.14159265358979323 * random->flatShoot();
00032   // The two rotations
00033   RawParticle::Rotation rotation1(orthogonal(Particle.Vect()),theta);
00034   RawParticle::Rotation rotation2(Particle.Vect(),phi);
00035   // Rotate!
00036   Particle.rotate(rotation1); 
00037   Particle.rotate(rotation2);
00038 
00039   // Generate mutiple scattering displacements in cm (assuming the detectors
00040   // are silicon only to determine the thickness) in the directions orthogonal
00041   // to the vector normal to the surface
00042   double xp = (cos(phi)*theta/2. + random->gaussShoot(0.,theta0)/sqr12)
00043               * radLengths * radLenIncm();               
00044   double yp = (sin(phi)*theta/2. + random->gaussShoot(0.,theta0)/sqr12)
00045               * radLengths * radLenIncm();
00046 
00047   // Determine a unitary vector tangent to the surface
00048   // This tangent vector is unitary because "normal" is
00049   // either (0,0,1) in the Endcap  or (x,y,0) in the Barrel !
00050   XYZVector normal(theNormalVector.x(),theNormalVector.y(),theNormalVector.z());
00051   XYZVector tangent = orthogonal(normal); 
00052   // The total displacement 
00053   XYZVector delta = xp*tangent + yp*normal.Cross(tangent);
00054   // Translate!
00055   Particle.translate(delta);
00056 
00057 }
00058