00001
00002
00003
00004
00005
00006
00008
00009
00010
00011
00012
00014 #include <string>
00015 #include <cassert>
00016 #include <cmath>
00017
00018 #include <TMCProcess.h>
00019 #include <TVirtualMC.h>
00020 #include <TParticle.h>
00021 #include <TClonesArray.h>
00022 #include <TInterpreter.h>
00023 #include <TGeoManager.h>
00024 #include <TRandom.h>
00025
00026 #include "GeoSwimmer/GeoSwimZCondition.h"
00027 #include "GeoSwimmer/GeoSwimApplication.h"
00028 #include "GeoSwimmer/GeoSwimParticle.h"
00029 #include "GeoSwimmer/GeoSwimStack.h"
00030 #include "Util/LoadMinosPDG.h"
00031 #include "MCApplication/MCApplication.h"
00032 #include "GeoSwimmer/GeoSwimmer.h"
00033 #include "Validity/VldContext.h"
00034 #include "MessageService/MsgService.h"
00035 #include "Conventions/Munits.h"
00036 #include "Conventions/Detector.h"
00037
00038 #include "Swimmer/SwimParticle.h"
00039
00040 #if defined(MACOSX) && (__GNUC__ <= 3)
00041 extern "C" int isnan(double);
00042 extern "C" int isinf(double);
00043 #endif
00044
00045 CVSID("$Id: GeoSwimmer.cxx,v 1.15 2008/08/01 04:23:12 ishi Exp $");
00046
00047 ClassImp(GeoSwimmer)
00048
00049 GeoSwimmer* GeoSwimmer::fgInstance = 0;
00050
00051
00052 GeoSwimmer::GeoSwimmer() :
00053 fMCConfig("PTSim_g3Config.C"), fHallSizeSet(false)
00054 {
00055 fMCAppUser = new GeoSwimApplication("GeoSwimApplication","GeoSwimmer Application");
00056 fUseGeoSwimmer = false;
00057 fgInstance = this;
00058
00059 LoadMinosPDG();
00060 }
00061
00062
00063 GeoSwimmer::~GeoSwimmer()
00064 {
00065 if ( fMCAppUser ) delete fMCAppUser; fMCAppUser = 0;
00066 }
00067
00068
00069
00070 void GeoSwimmer::Initialize(const VldContext& vldc)
00071 {
00072 switch (vldc.GetDetector()) {
00073 case Detector::kFar:
00074 break;
00075 case Detector::kNear:
00076 break;
00077 case Detector::kCalDet:
00078 break;
00079 default:
00080 MSG("GeoSwim",Msg::kError)
00081 << "GeoSwimmer does not support the "
00082 << Detector::AsString(vldc.GetDetector())
00083 << " detector " << endl;
00084 assert(0);
00085 }
00086
00087 MSG("GeoSwim",Msg::kDebug) << "Initialize." << endl;
00088 if ( !fMCAppUser ) {
00089 MSG("GeoSwim",Msg::kWarning) << "No MC application instance." << endl;
00090 abort();
00091 }
00092
00093 MCApplication& mcapp = const_cast<MCApplication&>(MCApplication::Instance());
00094 if ( !(mcapp.GetMC() ) ) {
00095 mcapp.InitMC(fMCConfig.c_str(),vldc);
00096 }
00097 mcapp.InitSnarl(vldc);
00098
00099
00100 mcapp.SetUserApplication(fMCAppUser);
00101
00102 if ( !fHallSizeSet ) {
00103 UgliGeomHandle ugh(vldc);
00104 fHallMin = ugh.GetHallExtentMin();
00105 fHallMax = ugh.GetHallExtentMax();
00106 fMCAppUser->SetHallSize(fHallMin,fHallMax);
00107 fHallSizeSet = true;
00108 }
00109 }
00110
00111
00112
00113 bool GeoSwimmer::SwimForward(GeoSwimParticle& particle, double zFinal)
00114 {
00115 MSG("GeoSwim",Msg::kDebug) << "GeoSwimmer::SwimForward\n";
00116
00117 GeoSwimZCondition zc(zFinal);
00118
00119 return Swim(particle, zc, 1);
00120 }
00121
00122
00123
00124 bool GeoSwimmer::SwimBackward(GeoSwimParticle& particle, double zFinal)
00125 {
00126 MSG("GeoSwim",Msg::kDebug) << "GeoSwimmer::SwimBackward\n";
00127
00128 GeoSwimZCondition zc(zFinal);
00129
00130 return Swim(particle, zc, -1);
00131 }
00132
00133
00134
00135 bool GeoSwimmer::Swim(GeoSwimParticle& particle, GeoSwimZCondition& zc, int dir)
00136 {
00137
00138 double pThres = 0.05*Munits::GeV;
00139 double fUnreasonableEnergy = 1.e+6*Munits::GeV;
00140 bool satisfied = false;
00141
00142 fMCAppUser->SetDirection(dir);
00143 fMCAppUser->SetZCondition(zc);
00144
00145
00146 if (particle.GetMomentumModulus()<pThres) {
00147 satisfied = zc.Satisfied(particle);
00148 return satisfied;
00149 }
00150
00151 Int_t toBeDone = 1;
00152 Int_t parent = -1;
00153 TVector3 pol;
00154 Int_t trkId= -1;
00155
00156 TVector3 momentum = particle.GetMomentum();
00157 Double_t energy = particle.GetEnergy();
00158 TVector3 position = particle.GetPosition();
00159
00160 if (position.X() > fHallMax.X() ||
00161 position.X() < fHallMin.X() ||
00162 position.Y() > fHallMax.Y() ||
00163 position.Y() < fHallMin.Y() ||
00164 position.Z() > fHallMax.Z() ||
00165 position.Z() < fHallMin.Z()) {
00166 MSG("GeoSwim",Msg::kDebug)
00167 << "GeoSwimmer::Swim too large position (m) "
00168 << position.x() << " " << position.y() << " " << position.z() << "\n";
00169 return false;
00170 }
00171
00172 if (isnan(momentum.X()) || isinf(momentum.X()) ||
00173 isnan(momentum.Y()) || isinf(momentum.Y()) ||
00174 isnan(momentum.Z()) || isinf(momentum.Z())) {
00175 MSG("GeoSwim",Msg::kError)
00176 << "Momentum is not number\n";
00177 return false;
00178 }
00179
00180 if (TMath::Abs(momentum.X()) > fUnreasonableEnergy ||
00181 TMath::Abs(momentum.Y()) > fUnreasonableEnergy ||
00182 TMath::Abs(momentum.Z()) > fUnreasonableEnergy) {
00183 MSG("GeoSwim",Msg::kDebug)
00184 << "GeoSwimmer::Swim too large momrutum (GeV) "
00185 << momentum.X() << " " << momentum.Y() << " " << momentum.Z() << "\n";
00186 return false;
00187 }
00188
00189 MSG("GeoSwim",Msg::kDebug)
00190 << "GeoSwimmer::Swim Begin Momentum "
00191 << momentum.x() << " " << momentum.y() << " " << momentum.z() << " "
00192 << " Position(m) " << position.x() << " " << position.y() << " "
00193 << position.z() << " " << dir << "\n";
00194
00195 if(position.Mag()>10000.) return satisfied;
00196
00197 gMC -> GetRandom() -> SetSeed(0);
00198
00199 GeoSwimStack* fStack = fMCAppUser -> GetStack();
00200 fStack -> Reset();
00201
00202
00203 fStack->PushTrack(toBeDone,parent, dir*particle.GetID(),
00204 dir*momentum.x(), dir*momentum.y(), dir*momentum.z(),
00205 energy,
00206 position.x()/Munits::cm, position.y()/Munits::cm, position.z()/Munits::cm,
00207 1.0,
00208 pol.X(), pol.Y(), pol.Z(),
00209 kPPrimary,
00210 trkId,1.,0);
00211
00212
00213 gMC -> ProcessRun(1);
00214
00215
00216 satisfied = fMCAppUser->GetSatisfied();
00217
00218 TLorentzVector pos4;
00219 gMC->TrackPosition(pos4);
00220 TVector3 pos3(pos4.X()*Munits::cm,pos4.Y()*Munits::cm,pos4.Z()*Munits::cm);
00221 particle.SetPosition(pos3);
00222
00223 TLorentzVector mom4;
00224 gMC->TrackMomentum(mom4);
00225 TVector3 mom3(dir*mom4.X(),dir*mom4.Y(),dir*mom4.Z());
00226 particle.SetMomentum(mom3);
00227
00228 particle.SetS(fMCAppUser->GetS()*Munits::cm);
00229 particle.SetRange(fMCAppUser->GetRange());
00230
00231 MSG("GeoSwim",Msg::kDebug)
00232 << "GeoSwimmer::Swim End Momentum "
00233 << mom3.X() << " " << mom3.Y() << " " << mom3.Z() << " "
00234 << " Positiopn (m) " << pos3.X() << " " << pos3.Y() << " "
00235 << pos3.Z() << " " << satisfied << "\n";
00236
00237 return satisfied;
00238 }
00239
00240
00241
00242 bool GeoSwimmer::SwimForward(SwimParticle& swpt, double zFinal)
00243 {
00244 MSG("GeoSwim",Msg::kDebug) << "GeoSwimmer::SwimForward\n";
00245
00246 GeoSwimZCondition zc(zFinal);
00247 GeoSwimParticle particle(swpt.GetPosition(), swpt.GetMomentum(),
00248 swpt.GetCharge(), (int)swpt.GetCharge()*-1*13);
00249
00250 bool satisfied = Swim(particle, zc, 1);
00251
00252 swpt.SetPosition(particle.GetPosition());
00253 swpt.SetMomentum(particle.GetMomentum());
00254 swpt.AddS(particle.GetS());
00255 swpt.AddRange(particle.GetRange());
00256
00257 return satisfied;
00258 }
00259
00260
00261
00262 bool GeoSwimmer::SwimBackward(SwimParticle& swpt, double zFinal)
00263 {
00264 MSG("GeoSwim",Msg::kDebug) << "GeoSwimmer::SwimBackward\n";
00265
00266 GeoSwimZCondition zc(zFinal);
00267 GeoSwimParticle particle(swpt.GetPosition(), swpt.GetMomentum(),
00268 swpt.GetCharge(), (int)swpt.GetCharge()*-1*13);
00269
00270 bool satisfied = Swim(particle, zc, -1);
00271
00272 swpt.SetPosition(particle.GetPosition());
00273 swpt.SetMomentum(particle.GetMomentum());
00274 swpt.AddS(particle.GetS());
00275 swpt.AddRange(particle.GetRange());
00276
00277 return satisfied;
00278 }
00279