00001
00002
00003
00004
00005
00006
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"
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
00032
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
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),
00073 fAcc(1.0e-4),
00074 fNmaxStep(10000),
00075 fOwnBfield(false),
00076 fOwnSwimGeo(false)
00077 {
00078
00079
00080
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
00096
00097
00098 fSwimGeo = SwimGeo::Instance(vldc);
00099 fOwnSwimGeo = false;
00100
00101
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
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
00166 this->DeleteStepper();
00167
00168
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
00176
00177
00178 if (fStepper) return true;
00179
00180
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
00190 fStepData->SetIsForward(true);
00191 return Swim(particle, c);
00192 }
00193
00194
00195
00196 bool SwimSwimmer::SwimBackward(SwimParticle& particle, SwimCondition& c)
00197 {
00198
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;
00213
00214
00215 if (particle.GetMomentumModulus()<pThres) {
00216 satisfied = c.Satisfied(particle);
00217 return satisfied;
00218 }
00219
00220
00221 fStepData->SetSPI(-1);
00222
00223 for (int i=0; i<fNmaxStep; ++i) {
00224
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
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;
00243
00244
00245
00246 material = fSwimGeo->GetSwimMaterial(xyz, zDir, *fStepData);
00247
00248 if (material==SwimGeo::kError)
00249 break;
00250
00251 fStepData->SetSwimMaterial(material);
00252
00253
00254 distToNextPlane = fSwimGeo->DistToNextPlane(xyz,
00255 direction);
00256
00257
00258 if (distToNextPlane==0.0 || distToNextPlane>=11.6*Munits::m)
00259 break;
00260
00261
00262
00263
00264
00265
00266 stepSize = c.StepSize(particle);
00267
00268
00269 if (particle.GetDirection().Z() != 0.0) {
00270 distToNextPlane = fSwimGeo->DistToNextPlane(xyz,
00271 direction);
00272
00273
00274 if ((distToNextPlane<stepSize) && distToNextPlane!=0.0)
00275 stepSize = distToNextPlane;
00276
00277
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 }
00288
00289 fStepData->SetStepSize(stepSize);
00290
00291
00292
00293
00294 fStepper->Action(particle,fStepData);
00295
00296
00297 if (particle.GetMomentumModulus()<pThres) {
00298 satisfied = c.Satisfied(particle);
00299 break;
00300 }
00301
00302 }
00303
00304 return satisfied;
00305 }
00306