CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/FastSimulation/ParticlePropagator/src/ParticlePropagator.cc

Go to the documentation of this file.
00001 //CMSSW headers
00002 #include "DataFormats/GeometrySurface/interface/BoundDisk.h"
00003 #include "DataFormats/GeometrySurface/interface/BoundCylinder.h"
00004 
00005 //FAMOS headers
00006 #include "FastSimulation/ParticlePropagator/interface/ParticlePropagator.h"
00007 #include "FastSimulation/ParticlePropagator/interface/MagneticFieldMap.h"
00008 #include "FastSimulation/TrackerSetup/interface/TrackerLayer.h"
00009 #include "FastSimulation/Event/interface/FSimTrack.h"
00010 #include "FastSimulation/Event/interface/FSimVertex.h"
00011 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00012 
00013 ParticlePropagator::ParticlePropagator() : 
00014   BaseParticlePropagator(), random(0) {;}
00015 
00016 ParticlePropagator::ParticlePropagator(const RawParticle& myPart,
00017                                        double RCyl, double ZCyl, 
00018                                        const MagneticFieldMap* aFieldMap,
00019                                        const RandomEngine* engine) :
00020   BaseParticlePropagator(myPart,RCyl,ZCyl,0.),
00021   theFieldMap(aFieldMap),
00022   random(engine)
00023 {
00024   setMagneticField(fieldMap(X(),Y(),Z()));
00025   initProperDecayTime();
00026 }
00027 
00028 ParticlePropagator::ParticlePropagator( const RawParticle& myPart,
00029                                         const MagneticFieldMap* aFieldMap,
00030                                         const RandomEngine* engine) : 
00031   BaseParticlePropagator(myPart,0.,0.,0.),
00032   theFieldMap(aFieldMap),
00033   random(engine)
00034  
00035 {
00036   setMagneticField(fieldMap(X(),Y(),Z()));
00037   initProperDecayTime();
00038 }
00039 
00040 ParticlePropagator::ParticlePropagator(const XYZTLorentzVector& mom, 
00041                                        const XYZTLorentzVector& vert, float q,
00042                                        const MagneticFieldMap* aFieldMap) :
00043   BaseParticlePropagator(RawParticle(mom,vert),0.,0.,0.),
00044   theFieldMap(aFieldMap),
00045   random(0)
00046 {
00047   setCharge(q);
00048   setMagneticField(fieldMap(X(),Y(),Z()));
00049 }
00050 
00051 ParticlePropagator::ParticlePropagator(const XYZTLorentzVector& mom, 
00052                                        const XYZVector& vert, float q,
00053                                        const MagneticFieldMap* aFieldMap) :
00054   BaseParticlePropagator(
00055     RawParticle(mom,XYZTLorentzVector(vert.X(),vert.Y(),vert.Z(),0.0)),0.,0.,0.),
00056   theFieldMap(aFieldMap),
00057   random(0)
00058 {
00059   setCharge(q);
00060   setMagneticField(fieldMap(X(),Y(),Z()));
00061 }
00062 
00063 ParticlePropagator::ParticlePropagator(const FSimTrack& simTrack,
00064                                        const MagneticFieldMap* aFieldMap,
00065                                        const RandomEngine* engine) : 
00066   BaseParticlePropagator(RawParticle(simTrack.type(),simTrack.momentum()),
00067                          0.,0.,0.),
00068   theFieldMap(aFieldMap),
00069   random(engine)
00070 {
00071   setVertex(simTrack.vertex().position());
00072   setMagneticField(fieldMap(X(),Y(),Z()));
00073   if ( simTrack.decayTime() < 0. ) { 
00074     if ( simTrack.nDaughters() ) 
00075       // This particle already decayed, don't decay it twice
00076       this->setProperDecayTime(1E99);
00077     else
00078       // This particle hasn't decayed yet. Decay time according to particle lifetime
00079       initProperDecayTime();
00080   } else {
00081     // Decay time pre-defined at generator level 
00082     this->setProperDecayTime(simTrack.decayTime());
00083   }
00084 }
00085 
00086 ParticlePropagator::ParticlePropagator(const ParticlePropagator& myPropPart) :
00087   BaseParticlePropagator(myPropPart),
00088   theFieldMap(myPropPart.theFieldMap)
00089 {  
00090   //  setMagneticField(fieldMap(x(),y(),z()));
00091 }
00092 
00093 ParticlePropagator::ParticlePropagator(const BaseParticlePropagator& myPropPart,
00094                                        const MagneticFieldMap* aFieldMap) :
00095   BaseParticlePropagator(myPropPart),
00096   theFieldMap(aFieldMap)
00097 {  
00098   setMagneticField(fieldMap(X(),Y(),Z()));
00099 }
00100 
00101 
00102 void 
00103 ParticlePropagator::initProperDecayTime() {
00104 
00105   // And this is the proper time at which the particle will decay
00106   double properDecayTime = 
00107     (pid()==0||pid()==22||abs(pid())==11||abs(pid())==2112||abs(pid())==2212||
00108      !random) ?
00109     1E99 : -PDGcTau() * std::log(random->flatShoot());
00110 
00111   this->setProperDecayTime(properDecayTime);
00112 
00113 }
00114 
00115 
00116 bool
00117 ParticlePropagator::propagateToClosestApproach(double x0, double y0, bool first) {
00118   setMagneticField(fieldMap(0.,0.,0.));
00119   return BaseParticlePropagator::propagateToClosestApproach(x0,y0,first);
00120 }
00121 
00122 bool
00123 ParticlePropagator::propagateToNominalVertex(const XYZTLorentzVector& v) {
00124   setMagneticField(fieldMap(0.,0.,0.));
00125   return BaseParticlePropagator::propagateToNominalVertex(v);
00126 }
00127 
00128 ParticlePropagator
00129 ParticlePropagator::propagated() const {
00130   return ParticlePropagator(BaseParticlePropagator::propagated(),theFieldMap);
00131 }
00132 
00133 double
00134 ParticlePropagator::fieldMap(double xx,double yy, double zz) {
00135   // Arguments now passed in cm.
00136   //  return MagneticFieldMap::instance()->inTesla(GlobalPoint(xx/10.,yy/10.,zz/10.)).z();
00137   // Return a dummy value for neutral particles!
00138   return charge() == 0.0 || theFieldMap == 0 ? 
00139     4. : theFieldMap->inTeslaZ(GlobalPoint(xx,yy,zz));
00140 }
00141 
00142 double
00143 ParticlePropagator::fieldMap(const TrackerLayer& layer, double coord, int success) {
00144   // Arguments now passed in cm.
00145   //  return MagneticFieldMap::instance()->inTesla(GlobalPoint(xx/10.,yy/10.,zz/10.)).z();
00146   // Return a dummy value for neutral particles!
00147   return charge() == 0.0 || theFieldMap == 0 ? 
00148     4. : theFieldMap->inTeslaZ(layer,coord,success);
00149 }
00150 
00151 bool
00152 ParticlePropagator::propagateToBoundSurface(const TrackerLayer& layer) {
00153 
00154 
00155   fiducial = true;
00156   BoundDisk* disk = layer.disk();
00157   //  bool disk = layer.forward();
00158   //  double innerradius=-999;
00159   double innerradius = disk ? layer.diskInnerRadius() : -999. ;
00160 
00161   //  if( disk ) {
00162     //    const Surface& surface = layer.surface();
00163     //    const BoundDisk & myDisk = dynamic_cast<const BoundDisk&>(surface);
00164     //    innerradius=myDisk.innerRadius();       
00165   //    innerradius=myDisk->innerRadius();        
00166   //  }
00167 
00168   bool done = propagate();
00169 
00170   // Set the magnetic field at the new location (if succesfully propagated)
00171   if ( done && !hasDecayed() ) { 
00172     if ( success == 2 ) 
00173       setMagneticField(fieldMap(layer,r(),success));
00174     else if ( success == 1 )
00175       setMagneticField(fieldMap(layer,z(),success));
00176   }     
00177        
00178   // There is some real material here
00179   fiducial = !(!disk &&  success!=1) &&
00180              !( disk && (success!=2  || r()<innerradius));
00181 
00182   return done;
00183 }
00184 
00185 void 
00186 ParticlePropagator::setPropagationConditions(const TrackerLayer& layer, 
00187                                              bool firstLoop) { 
00188   // Set the magentic field
00189   // setMagneticField(fieldMap(x(),y(),z()));
00190 
00191   // Set R and Z according to the Tracker Layer characteristics.
00192   //  const Surface& surface = layer.surface();
00193 
00194   if( layer.forward() ) {
00195 
00196     //    const BoundDisk & myDisk = dynamic_cast<const BoundDisk&>(surface);
00197     // ParticlePropagator works in mm, whereas the detector geometry is in cm
00198     BaseParticlePropagator::setPropagationConditions(
00199                                   layer.diskOuterRadius(),
00200                                   fabs(layer.disk()->position().z()),
00201                                   firstLoop);       
00202 
00203   // ... or if it is a cylinder barrel 
00204   } else {
00205 
00206     //    const BoundCylinder & myCylinder = dynamic_cast<const BoundCylinder &>(surface);
00207     // ParticlePropagator works now in cm
00208     BaseParticlePropagator::setPropagationConditions(
00209                                          layer.cylinder()->bounds().width()/2.,
00210                                          layer.cylinder()->bounds().length()/2.,
00211                                          firstLoop);
00212   }
00213 
00214 }
00215