Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

SwimDefStepper.cxx

Go to the documentation of this file.
00001 
00002 // SwimDefStepper
00003 //
00005 #include "Swimmer/SwimDefStepper.h"
00006 #include "Swimmer/SwimParticle.h"
00007 #include "Swimmer/SwimStepData.h"
00008 #include "BField/BField.h"
00009 #include "Conventions/Munits.h"
00010 #include "Conventions/Mphysical.h"
00011 #include <iostream>
00012 #include "TMath.h"
00013 #include "MessageService/MsgService.h"
00014 
00015 CVSID("$Id: SwimDefStepper.cxx,v 1.20 2008/02/20 11:40:34 bckhouse Exp $");
00016 
00017 //......................................................................
00018 
00019 SwimDefStepper::SwimDefStepper(BField* f) : fBfield(f) 
00020 {
00021   this->SetUpIntegrator();
00022 }
00023 
00024 //......................................................................
00025 
00026 SwimDefStepper::SwimDefStepper(BField* f, double min, double acc) : 
00027   fMinStepSize(min),
00028   fAcc(acc),
00029   fBfield(f)
00030 {
00031   this->SetUpIntegrator();
00032 }
00033 
00034 //......................................................................
00035 
00036 void SwimDefStepper::SetUpIntegrator() 
00037 {
00038 //======================================================================
00039 // Purpose: Setup the integrator object
00040 //======================================================================
00041   double s[6] = {1.0,1.0,1.0,  // Typical sizes of x,y,z and
00042                  1.0,1.0,1.0}; // px,py,pz
00043   // Setup the integration object
00044   fIntegrator.SetNvar(6);
00045   fIntegrator.SetScales(s);
00046   fIntegrator.SetAccuracy(fAcc);
00047   fIntegrator.SetMinStepSize(fMinStepSize);
00048   fIntegrator.SetDerivFunc(fDerivFunc);
00049 }
00050 
00051 //......................................................................
00052 
00053 bool SwimDefStepper::StepOnce(SwimParticle& particle, 
00054                               SwimStepData* stepData)
00055 {
00056   // Setup step
00057   fX[0] = particle.GetPosition().X();
00058   fX[1] = particle.GetPosition().Y();
00059   fX[2] = particle.GetPosition().Z();
00060   fX[3] = particle.GetMomentum().X();
00061   fX[4] = particle.GetMomentum().Y();
00062   fX[5] = particle.GetMomentum().Z();
00063   double stepSize = stepData->GetStepSize();
00064   // Used to calculate path, range traveled in this step
00065   double density = SwimGeo::GetSwimMaterialDensity(stepData->GetSwimMaterial());
00066   TVector3 startpos, path, startmom, deltamom;
00067   startpos = particle.GetPosition();
00068   startmom = particle.GetMomentum();
00069 
00070   fDerivFunc.SetChargeBField(particle.GetCharge(),fBfield);
00071   // TVector3 Bxyz = fBfield->GetBField(startpos);
00072   // cout << " pos " << fX[0] << " " << fX[1] << " z  " << fX[2] << " " << fX[4]/fX[5] << " "  << fX[5] << endl ;
00073   // cout << " density " << density << endl;
00074   //  cout << " bfield " << Bxyz.X() << " " <<      Bxyz.Y() << " " <<  Bxyz.Z() << " " <<   endl;
00075   // Integrate across the step
00076   fIntegrator.SetInitialCondition(fX);
00077   fIntegrator.SetStartPoint(0.0);
00078   if (stepData->GetIsForward())
00079     fIntegrator.SetEndPoint(stepSize);
00080   else
00081     fIntegrator.SetEndPoint(-stepSize);
00082 
00083   // 20 Feb 2008 - Avoid assert(stepSize>0) in fIntegrator.
00084   if(stepSize > 0){
00085     fIntegrator.SetStepSize(stepSize);
00086   }
00087   else{
00088     MSG("Swim", Msg::kError) << "Unexpected stepSize of " << stepSize << " bailing...\n";
00089     return false;
00090   }
00091 
00092   bool aok = fIntegrator.Integrate(fX);
00093 
00094   // Shuffle to output
00095   TVector3 position;
00096   TVector3 momentum;
00097   double   pModulus2 = fX[3]*fX[3]+fX[4]*fX[4]+fX[5]*fX[5];
00098   position.SetXYZ(fX[0],fX[1],fX[2]);
00099   particle.SetPosition(position);
00100   if (pModulus2!=0.0)
00101     momentum.SetXYZ(fX[3],fX[4],fX[5]);
00102   else
00103     momentum.SetXYZ(0.0,0.0,0.0);
00104   particle.SetMomentum(momentum);
00105 
00106   // Calculate path, range in this step, add to particle totals
00107   path = particle.GetPosition();
00108   
00109   double endz =path[2];
00110   deltamom = particle.GetMomentum();
00111   path -= startpos;
00112   deltamom -= startmom;
00113   particle.AddS(path.Mag());
00114   particle.AddRange(density*path.Mag()/(Munits::g/Munits::cm2));
00115   
00116   MSG("Swim",Msg::kDebug) << " start/end z " << startpos[2] <<  "/" << endz << " density " << density/1000. << " dzds " << fabs(path[2]/path.Mag())  << " dRange  " << density*path.Mag() << endl;
00117 
00118   particle.AddVxB(deltamom.Mag());
00119   
00120   return aok;
00121 }
00122 
00123 //......................................................................
00124 
00125 SwimDefStepper::DerivFunc::DerivFunc(double q, BField* b) 
00126 {
00127   // Initialize force coeff. and BField
00128   this->SetChargeBField(q,b);
00129 }
00130 
00131 //......................................................................
00132 
00133 void SwimDefStepper::DerivFunc::SetChargeBField(double q, BField* b)
00134 {
00135   // The units conversion is c[m/s]*[eV]/[GeV]
00136   static const double unitsC = 
00137     (Mphysical::c_light/(Munits::m/Munits::s))/1.0e9;
00138   fForceCoef = unitsC*q;
00139   fBfield    = b;
00140 }
00141 
00142 //......................................................................
00143 
00144 void SwimDefStepper::DerivFunc::operator()(double /* x */, 
00145                                            const double* y, 
00146                                            double* dydx) 
00147 {
00148   //const double oneOverSqrt2 = 1./sqrt(2.);
00149   // y[0] - x coordinate (base length units)
00150   // y[1] - y coordinate (base length units)
00151   // y[2] - z coordinate (base length units)
00152   // y[3] - x momentum   (base momentum units)
00153   // y[4] - y momentum   (base momentum units)
00154   // y[5] - z momentum   (base momentum units)
00155   double ptotSqr = y[3]*y[3]+y[4]*y[4]+y[5]*y[5];
00156   if (ptotSqr != 0.0) {
00157     double oneOverPtot = 1.0/TMath::Sqrt(ptotSqr);      
00158     dydx[0] = y[3]*oneOverPtot; // (d/ds)x = Px/Ptot
00159     dydx[1] = y[4]*oneOverPtot; // (d/ds)y = Py/Ptot
00160     dydx[2] = y[5]*oneOverPtot; // (d/ds)z = Pz/Ptot
00161     
00162     //the point is passed in in xyz, even though the measurements are in uvz - 
00163     //the rotation is done in the fitter.
00164     TVector3 xyz(y[0],y[1],y[2]);
00165 
00166     //since the Bfield is also in xyz, we are all happy.
00167     TVector3 B = fBfield->GetBField(xyz);
00168 
00169     // Calculate derivatives
00170     double qOverE = fForceCoef*oneOverPtot;
00171     dydx[3] = (y[4]*B[2]-y[5]*B[1])*qOverE; // dP/ds = q*(p x B)/E/v
00172     dydx[4] = (y[5]*B[0]-y[3]*B[2])*qOverE; // dP/ds = q*(p x B)/E/v
00173     dydx[5] = (y[3]*B[1]-y[4]*B[0])*qOverE; // dP/ds = q*(p x B)/E/v
00174   }
00175   else {
00176     // Particle is stopped
00177     dydx[0] = 0.0;
00178     dydx[1] = 0.0;
00179     dydx[2] = 0.0;
00180     dydx[3] = 0.0;
00181     dydx[4] = 0.0;
00182     dydx[5] = 0.0;
00183   }
00184 }
00185 

Generated on Mon Feb 15 11:07:40 2010 for loon by  doxygen 1.3.9.1