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

SwimSwimmer.cxx

Go to the documentation of this file.
00001 
00002 // $Id: SwimSwimmer.cxx,v 1.22 2007/11/11 04:37:27 rhatcher Exp $
00003 //
00004 // Swimming through a particle, forward or backward
00005 //
00006 // seun@huhepl.harvard.edu
00008 #include "Swimmer/SwimSwimmer.h"
00009 #include "Swimmer/SwimParticle.h"
00010 #include "Swimmer/SwimCondition.h"
00011 #include "Swimmer/SwimG4Stepper.h"
00012 #include "Swimmer/SwimDefStepper.h"
00013 #include "Swimmer/SwimGeo.h"
00014 #include "Swimmer/SwimStepData.h"
00015 #include "BField/BField.h"
00016 #include "Validity/VldRange.h"
00017 #include "MessageService/MsgService.h" // For MSG
00018 #include <string>
00019 #include <cassert>
00020 
00021 CVSID("$Id: SwimSwimmer.cxx,v 1.22 2007/11/11 04:37:27 rhatcher Exp $");
00022 
00023 //......................................................................
00024 SwimSwimmer::SwimSwimmer(const VldContext& vldc) :
00025   fMagField(0),
00026   fStepMax(0.0254*Munits::m),
00027   fStepMin(1.0e-6*Munits::m),
00028   fAcc(1.0e-4),
00029   fNmaxStep(10000)
00030 {
00031   // This is the "proper" constructor, it should be used for all reco purposes!!!!!!
00032   // Choice of BField determined from validity. 
00033   switch (vldc.GetDetector()) {
00034   case Detector::kFar:
00035     fMagField  = new BField(vldc);
00036     fOwnBfield = true;
00037     break;
00038   case Detector::kNear:
00039     fMagField = new BField(vldc);
00040     fOwnBfield = true;
00041     break;
00042   case Detector::kCalDet:
00043     fMagField = new BField(vldc,0,0);
00044     fOwnBfield = true;
00045     break;
00046   default:
00047     fOwnBfield = false;
00048     MSG("Swim",Msg::kError)
00049       << "SwimSwimmer does not support the "
00050       << Detector::AsString(vldc.GetDetector())
00051       << " detector " << endl;
00052     assert(0);
00053   }
00054 
00055   fSwimGeo = SwimGeo::Instance(vldc);
00056   fOwnSwimGeo = false;
00057 
00058   // DefaultStepper depends on fMagBield
00059   fStepper = this->CreateDefaultStepper();
00060 
00061   fStepData = new SwimStepData();
00062   fStepData->SetStepper(fStepper);
00063 }
00064 
00065 //......................................................................
00066 
00067 SwimSwimmer::SwimSwimmer(BField* magField) :
00068   fMagField(magField),
00069   fSwimGeo(0),
00070   fStepper(this->CreateDefaultStepper()),
00071   fStepMax(0.0254*Munits::m),   
00072   fStepMin(1.0e-6*Munits::m),  // Used by NumericalMethods
00073   fAcc(1.0e-4),                // Used by NumericalMethods
00074   fNmaxStep(10000),
00075   fOwnBfield(false),
00076   fOwnSwimGeo(false)
00077 {
00078   // This is constructor for special testing ONLY!!!!
00079   // It allows to force  Swimmer to use some user defined BField. 
00080   // Don't use this for real reconstruction!!!!! 
00081   fStepData = new SwimStepData();
00082   fStepData->SetStepper(fStepper);
00083 }
00084 
00085 //......................................................................
00086 
00087 SwimSwimmer::SwimSwimmer(const VldContext& vldc, BField* magField) :
00088   fMagField(magField),
00089   fStepMax(0.0254*Munits::m),
00090   fStepMin(1.0e-6*Munits::m),
00091   fAcc(1.0e-4),
00092   fNmaxStep(10000),
00093   fOwnBfield(false)
00094 {
00095   // This is constructor for special testing ONLY!!!!
00096   // It allows to force  Swimmer to use some user defined BField. 
00097   // Don't use this for real reconstruction!!!!! 
00098   fSwimGeo = SwimGeo::Instance(vldc);
00099   fOwnSwimGeo = false;
00100 
00101   // DefaultStepper depends on fMagBield
00102   fStepper = this->CreateDefaultStepper();
00103   
00104   fStepData = new SwimStepData();
00105   fStepData->SetStepper(fStepper);
00106 }
00107 //......................................................................
00108 
00109 SwimSwimmer::~SwimSwimmer()
00110 {
00111   this->DeleteBfield();
00112   this->DeleteSwimGeo();
00113   this->DeleteStepper();
00114 
00115   if (fStepData) {
00116     delete fStepData;
00117     fStepData = 0;
00118   }
00119 }
00120 
00121 //......................................................................
00122 
00123 SwimStepper* SwimSwimmer::CreateDefaultStepper()
00124 {
00125 //======================================================================
00126 // Purpose: Create and return a default stepper object
00127 //======================================================================
00128   return new SwimDefStepper(fMagField,fStepMin,fAcc);
00129 }
00130 
00131 //......................................................................
00132 
00133 void SwimSwimmer::DeleteBfield()
00134 {
00135   if (fMagField && fOwnBfield) {
00136     delete fMagField;
00137     fMagField = 0;
00138   }
00139 }
00140 
00141 //......................................................................
00142 
00143 void SwimSwimmer::DeleteSwimGeo()
00144 {
00145   if (fSwimGeo && fOwnSwimGeo) {
00146     delete fSwimGeo;
00147     fSwimGeo = 0;
00148   }
00149 }
00150 
00151 //......................................................................
00152 
00153 void SwimSwimmer::DeleteStepper()
00154 {
00155   if (fStepper) {
00156     delete fStepper;
00157     fStepper = 0;
00158   }
00159 }
00160 
00161 //......................................................................
00162 
00163 bool SwimSwimmer::SetStepper(const char* name)
00164 {
00165   // Delete any stepper we may have already created
00166   this->DeleteStepper();
00167 
00168   // Create a new stepper
00169   if (name == 0) fStepper = this->CreateDefaultStepper();
00170 
00171   string s(name);
00172   if (s == "")        fStepper = this->CreateDefaultStepper();
00173   if (s == "default") fStepper = this->CreateDefaultStepper();
00174   if (s == "G4") fStepper = new SwimG4Stepper(fMagField,fStepMin,fAcc);
00175   // Provide a template to show people how to add new steppers
00176   // if (s == "NewStepper") fStepper = new NewStepper();
00177 
00178   if (fStepper) return true;
00179   // else
00180   // Sorry, the stepper you asked for does not exist...
00181   MSG("Swim",Msg::kError) << "Unknown stepper '" << name << "'\n";
00182   return false;
00183 }
00184 
00185 //......................................................................
00186 
00187 bool SwimSwimmer::SwimForward(SwimParticle& particle, SwimCondition& c)
00188 {
00189   // Arrow of time, true for dt>0, false for dt<0
00190   fStepData->SetIsForward(true);
00191   return Swim(particle, c);
00192 }
00193 
00194 //......................................................................
00195 
00196 bool SwimSwimmer::SwimBackward(SwimParticle& particle, SwimCondition& c)
00197 {
00198   // Arrow of time, true for dt>0, false for dt<0
00199   fStepData->SetIsForward(false);
00200   return Swim(particle, c);
00201 }
00202 
00203 //......................................................................
00204 
00205 bool SwimSwimmer::Swim(SwimParticle& particle, SwimCondition& c)
00206 {
00207   SwimGeo::SwimMaterial_t material;
00208   double              stepSize;
00209   double              distToNextPlane;
00210   double              pThres = 0.05*Munits::GeV;
00211   bool                satisfied = false;
00212   bool                zDirInitial = false, zDir;   // z-momentum direction
00213 
00214   // Check if particle has a momentum < 50MeV
00215   if (particle.GetMomentumModulus()<pThres) {
00216     satisfied = c.Satisfied(particle);
00217     return satisfied;
00218   }
00219 
00220   // initial layer is undefined (gets set in GetSwimMaterial)
00221   fStepData->SetSPI(-1);
00222   
00223   for (int i=0; i<fNmaxStep; ++i) {
00224     // Check if condition is satisfied, if yes break out of loop
00225     satisfied = c.Satisfied(particle);
00226     if (satisfied) break;
00227 
00228     const TVector3 xyz = particle.GetPosition();
00229     const TVector3 direction = particle.GetDirection();
00230     Double_t momZ= particle.GetMomentum().Z();
00231 
00232    // particle traveling in position/negative z-direction
00233     if ((fStepData->GetIsForward() && momZ>0.0) ||
00234         (!(fStepData->GetIsForward()) && momZ<0.0))
00235       zDir = true;
00236     else
00237       zDir = false;
00238 
00239     if (i==0)
00240       zDirInitial = zDir;
00241     if (zDir!=zDirInitial)
00242       break;          // particle changed swimming direction. Exit for loop
00243 
00244     // Determine the material of the step
00245     //material = fSwimGeo->GetSwimMaterial(particle.GetPosition(), zDir);
00246     material = fSwimGeo->GetSwimMaterial(xyz, zDir, *fStepData);
00247     
00248     if (material==SwimGeo::kError)
00249       break;          // Outside the detector. Exit for loop
00250 
00251     fStepData->SetSwimMaterial(material);
00252 
00253     // Calculate the distance to the next plane
00254     distToNextPlane = fSwimGeo->DistToNextPlane(xyz,
00255                                                 direction);
00256 
00257     // Far detector limit: 11.6 meters, which always works for near detector
00258     if (distToNextPlane==0.0 || distToNextPlane>=11.6*Munits::m)
00259       break;           // Outside the detector. Exit for loop
00260 
00261     //======================================================================
00262     // Stepsize Calculation
00263     //======================================================================
00264     // stepSize changes accordingly if ZCondition is provided
00265     // stepSize = 1cm if momentum condition is provided
00266     stepSize = c.StepSize(particle);
00267   
00268     // if particle is not traveling vertically
00269     if (particle.GetDirection().Z() != 0.0) {
00270       distToNextPlane = fSwimGeo->DistToNextPlane(xyz,
00271                                                   direction);
00272       
00273       // If ((non-zero) distance to the next plane < stepsize)
00274       if ((distToNextPlane<stepSize) && distToNextPlane!=0.0)
00275         stepSize = distToNextPlane;
00276       
00277       // Set Maximum stepsize
00278       if (material==SwimGeo::kAir && stepSize>1.0*Munits::m)
00279         stepSize = 1.0*Munits::m;
00280       
00281       if ((material!=SwimGeo::kAir) && (stepSize>fStepMax))
00282         stepSize = fStepMax;
00283     }
00284     else {
00285       if (material==SwimGeo::kAir) stepSize = 1.0*Munits::m;
00286       if (material!=SwimGeo::kAir) stepSize = fStepMax;
00287     } // particle travels vertically
00288 
00289     fStepData->SetStepSize(stepSize);
00290 
00291     //======================================================================
00292     // Step Action: StepOnce, dEdx
00293     //======================================================================
00294     fStepper->Action(particle,fStepData);
00295 
00296     // Check if particle has a momentum < 50MeV
00297     if (particle.GetMomentumModulus()<pThres) {
00298       satisfied = c.Satisfied(particle);
00299       break; // Exit for loop
00300     }
00301     
00302   }
00303     
00304   return satisfied;
00305 }
00306 

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