00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015
00016 #include <TVirtualMC.h>
00017 #include <TInterpreter.h>
00018 #include <TRandom3.h>
00019 #include <TROOT.h>
00020 #include <TSystem.h>
00021 #include <TDatabasePDG.h>
00022
00023 #include "Util/UtilPDG.h"
00024 #include "Util/UtilMCFlag.h"
00025 using namespace UtilMCFlag;
00026 #include "Util/LoadMinosPDG.h"
00027 #include "MCApplication/MCApp.h"
00028 #include "MCApplication/MCApplication.h"
00029 #include "MessageService/MsgService.h"
00030 #include "BField/BField.h"
00031 #include "GeoGeometry/GeoMedium.h"
00032
00033 ClassImp(MCApplication)
00034
00035 CVSID("$Id: MCApplication.cxx,v 1.21 2009/06/22 03:51:00 kasahara Exp $");
00036
00037
00038 const MCApplication& MCApplication::Instance() {
00039
00040
00041
00042 if ( !TVirtualMCApplication::Instance() ) {
00043
00044 static MCApplication::Cleaner c;
00045 c.ClassIsUsed();
00046 new MCApplication("MCApplication","MINOS MC Application");
00047 }
00048
00049 return dynamic_cast<const MCApplication&>
00050 (*(TVirtualMCApplication::Instance()));
00051
00052 }
00053
00054
00055 MCApplication::MCApplication(const char *name, const char *title)
00056 : TVirtualMCApplication(name,title), fMCAppUser(0),fMC(0),
00057 fUgliGeomHandle(0),fVldContext(),fBField(0),fBFldInZTestSave(0),fRandom(0),
00058 fMCConfigScript(""),fDecayConfigScript(""),fLogLevel(kInfo) {
00059
00060
00061
00062 MSG("MCApp",Msg::kDebug) << "MCApplication normal ctor @ " << this << endl;
00063
00064
00065 fRandom = new TRandom3();
00066
00067 LoadMinosPDG();
00068
00069 }
00070
00071
00072
00073 MCApplication::~MCApplication() {
00074
00075
00076 MSG("MCApp",Msg::kDebug) << "MCApplication dtor @ " << this << endl;
00077
00078 Clear();
00079
00080 }
00081
00082
00083 void MCApplication::Clear(const Option_t* ) {
00084
00085
00086
00087 if ( fUgliGeomHandle ) delete fUgliGeomHandle; fUgliGeomHandle = 0;
00088 if ( fBField ) delete fBField; fBField = 0;
00089 if ( fRandom ) delete fRandom; fRandom = 0;
00090 if ( fMC ) delete fMC; fMC = 0;
00091
00092 }
00093
00094
00095 void MCApplication::SetUserApplication(MCAppUser* appuser) {
00096
00097
00098 fMCAppUser = appuser;
00099 if ( fMC ) fMC -> SetStack(fMCAppUser->GetStack());
00100
00101 }
00102
00103
00104 void MCApplication::InitMC(const char* mcconfigscript, const VldContext& vldc,
00105 const char* decayconfigscript) {
00106
00107
00108
00109
00110
00111 fVldContext = vldc;
00112 fMCConfigScript = mcconfigscript;
00113 fDecayConfigScript = decayconfigscript;
00114 fLogLevel = MsgService::Instance()->GetStream("MCApp")->GetLogLevel();
00115
00116
00117 if ( fMC ) {
00118 MSG("MCApp",Msg::kWarning) << "MCApplication::InitMC called with script "
00119 << fMCConfigScript.c_str() << "\nbut MC already initialized. Ignored."
00120 << endl;
00121 return;
00122 }
00123 if ( fMCConfigScript.empty() || fMCConfigScript == std::string("<null>") ) {
00124 MSG("MCApp",Msg::kFatal) << "MCApplication::InitMC called with null "
00125 << " configuration script." << endl;
00126 abort();
00127 }
00128
00129
00130 std::string mcConfigScriptPath = gSystem->Which(gROOT->GetMacroPath(),
00131 fMCConfigScript.c_str(),kReadPermission);
00132 if ( mcConfigScriptPath.empty() ) {
00133 MSG("MCApp",Msg::kError) << "MCApplication::InitMC configuration script "
00134 << fMCConfigScript.c_str() << " not found in path "
00135 << gROOT->GetMacroPath() << ". Abort." << endl;
00136 abort();
00137 }
00138
00139 MSG("MCApp",Msg::kInfo)
00140 << "MCApplication::InitMC initializing MC with configuration script "
00141 << mcConfigScriptPath.c_str() << ":" << endl;
00142
00143 if ( fLogLevel <= Msg::kInfo ) {
00144 std::string printstr = ".!cat -n " + mcConfigScriptPath;
00145 gInterpreter->ProcessLineSynch(printstr.c_str());
00146 }
00147 gROOT->LoadMacro(mcConfigScriptPath.c_str());
00148 gInterpreter->ProcessLineSynch("Config()");
00149
00150 if ( !gMC ) {
00151 MSG("MCApp",Msg::kFatal) << "Construction of MC implementation failed."
00152 << endl;
00153 abort();
00154 }
00155 fMC = gMC;
00156
00157
00158
00159
00160 fMC -> SetRandom(fRandom);
00161 if ( fMCAppUser ) fMC -> SetStack(fMCAppUser->GetStack());
00162
00163
00164
00165 fMC -> Init();
00166
00167
00168
00169
00170 InitMedia();
00171
00172 fMC -> BuildPhysics();
00173
00174 }
00175
00176
00177 bool MCApplication::InitSnarl(const VldContext& vldc) {
00178
00179
00180 bool isOkay = true;
00181
00182 if ( !fBField || !fUgliGeomHandle ) {
00183 MSG("MCApp",Msg::kError) << "InitSnarl w/" << vldc
00184 << " called before InitMC. Abort."
00185 << endl;
00186 abort();
00187 }
00188
00189
00190 fBField -> ResetVldContext(vldc);
00191
00192
00193 const VldRange& vldrange = fUgliGeomHandle -> GetVldRange();
00194
00195 if ( !(vldrange.IsCompatible(vldc)) ) {
00196 MSG("MCApp",Msg::kError) << "InitSnarl w/vld " << vldc
00197 << " is incompatible with VMC Geometry vld "
00198 << vldrange << ". Abort." << endl;
00199 abort();
00200 }
00201
00202 return isOkay;
00203
00204 }
00205
00206
00207 void MCApplication::FatalNoApp() const {
00208
00209
00210 MSG("MCApp",Msg::kFatal) << "MCApplication has null fMCAppUser. abort."
00211 << endl;
00212 abort();
00213
00214 }
00215
00216
00217 void MCApplication::ConstructGeometry() {
00218
00219
00220
00221 MSG("MCApp",Msg::kDebug) << "MCApplication::ConstructGeometry for vldc "
00222 << fVldContext.AsString() << endl;
00223
00224 if ( fUgliGeomHandle ) {
00225 MSG("MCApp",Msg::kFatal)
00226 << "ConstructGeometry called but fUgliGeomHandle non-null. abort." << endl;
00227 abort();
00228 }
00229 if ( !fVldContext.IsValid() ) {
00230 MSG("MCApp",Msg::kFatal)
00231 << "ConstructGeometry but invalid fVldContext. abort." << endl;
00232 abort();
00233 }
00234
00235 fUgliGeomHandle = new UgliGeomHandle(fVldContext);
00236 fBField = new BField(fVldContext);
00237
00238
00239
00240 UpdateGlobalGeoManager();
00241
00242
00243 gMC -> SetRootGeometry();
00244
00245 return;
00246
00247 }
00248
00249
00250 void MCApplication::AddParticles() {
00251
00252
00253
00254
00255 MSG("MCApp",Msg::kDebug) << "MCApplication::AddParticles" << endl;
00256
00257
00258 AddIons();
00259
00260
00261 AddDecayModes();
00262
00263 return;
00264
00265 }
00266
00267
00268 void MCApplication::AddIons() {
00269
00270
00271
00272
00273
00274
00275 MSG("MCApp",Msg::kDebug) << "MCApplication::AddIons" << endl;
00276
00277
00278
00279 const Int_t zmax = 28;
00280
00281 const TDatabasePDG& dbpdg = *(TDatabasePDG::Instance());
00282 TIter next(dbpdg.ParticleList());
00283 TParticlePDG* particle = 0;
00284 Int_t ia,iz,ij;
00285 Double_t lifetime = 1.e20;
00286
00287 while ((particle = (TParticlePDG*)next())) {
00288 Int_t pdgcode = particle -> PdgCode();
00289 UtilPDG::ionscheme_t ionscheme = UtilPDG::getIonAZJ(pdgcode,ia,iz,ij);
00290 if ( ionscheme == UtilPDG::kPDG2006 && iz <= zmax ) {
00291 std::string pname = particle -> GetName();
00292 Double_t mass = particle -> Mass();
00293 Double_t charge = (particle -> Charge())/3.;
00294 if ( gMC->IdFromPDG(pdgcode) <= 0 ) {
00295 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,22,0)
00296 gMC->DefineParticle(pdgcode,pname.c_str(),kPTIon,mass,charge,lifetime,
00297 "nucleus", 0.0, 1, 1, 0, 1, 1, 0, 0, 1, kTRUE);
00298 #else
00299 gMC->DefineParticle(pdgcode,pname.c_str(),kPTIon,mass,charge,lifetime);
00300 #endif
00301 MSG("MCApp",Msg::kDebug) << "AddIon " << pdgcode << "/"
00302 << pname.c_str() << " mass " << mass << " charge " << charge
00303 << " lifetime " << lifetime << endl;
00304 }
00305 }
00306 }
00307
00308
00309
00310 const Int_t nion = 15+12+1;
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 Int_t izia[nion][2] = {{29,63},
00321 {30,64},
00322 {32,74},
00323 {34,80},
00324 {36,84},
00325
00326
00327
00328 {46,106},
00329 {48,114},
00330 {50,120},
00331 {54,132},
00332 {56,138},
00333
00334
00335
00336
00337 {74,184},
00338 {78,194},
00339 {79,197},
00340 {80,202},
00341 {82,208},
00342
00343 {31,69},
00344 {33,75},
00345 {35,79},
00346 {47,107},
00347 {49,115},
00348 {51,121},
00349 {52,130},
00350 {53,127},
00351 {55,133},
00352 {73,181},
00353 {77,193},
00354 {81,205},
00355 {50,115},
00356 };
00357
00358 for ( int iion = 0; iion < nion; iion++ ) {
00359 Int_t pdgcode = UtilPDG::makeIonPDG(izia[iion][1],izia[iion][0],ij=0,
00360 UtilPDG::kPDG2006);
00361 TParticlePDG* particle = dbpdg.GetParticle(pdgcode);
00362 if ( particle ) {
00363 std::string pname = particle -> GetName();
00364 Double_t mass = particle -> Mass();
00365 Double_t charge = (particle -> Charge())/3.;
00366 if ( gMC->IdFromPDG(pdgcode) <= 0 ) {
00367 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,22,0)
00368 gMC->DefineParticle(pdgcode,pname.c_str(),kPTIon,mass,charge,lifetime,
00369 "nucleus", 0.0, 1, 1, 0, 1, 1, 0, 0, 1, kTRUE);
00370 #else
00371 gMC->DefineParticle(pdgcode,pname.c_str(),kPTIon,mass,charge,lifetime);
00372 #endif
00373 MSG("MCApp",Msg::kDebug) << "AddIon " << pdgcode << "/"
00374 << pname.c_str() << " mass " << mass << " charge " << charge
00375 << " lifetime " << lifetime << endl;
00376 }
00377 }
00378 else {
00379 MSG("MCApp",Msg::kWarning) << "MCApplication::AddIons. Ion "
00380 << pdgcode << " not present "
00381 << "in TDatabasePDG. Will not be defined!"
00382 << endl;
00383 }
00384 }
00385
00386 return;
00387
00388 }
00389
00390
00391 void MCApplication::AddDecayModes() {
00392
00393
00394
00395
00396
00397
00398 if ( fDecayConfigScript.empty()
00399 || fDecayConfigScript == std::string("<null>") ) {
00400 MSG("MCApp",Msg::kDebug) << "MCApplication::AddDecayModes. No "
00401 << "external decay script defined." << endl;
00402 return;
00403 }
00404
00405
00406 std::string decayConfigScriptPath = gSystem->Which(gROOT->GetMacroPath(),
00407 fDecayConfigScript.c_str(),kReadPermission);
00408 if ( decayConfigScriptPath.empty() ) {
00409 MSG("MCApp",Msg::kError) << "MCApplication::InitMC configuration script "
00410 << fDecayConfigScript.c_str() << " not found in path "
00411 << gROOT->GetMacroPath() << ". Abort." << endl;
00412 abort();
00413 }
00414
00415
00416 MSG("MCApp",Msg::kInfo)
00417 << "MCApplication::AddDecayModes initializing decayer with script "
00418 << decayConfigScriptPath.c_str() << ":" << endl;
00419
00420 if ( fLogLevel <= Msg::kInfo ) {
00421 std::string printstr = ".!cat -n " + decayConfigScriptPath;
00422 gInterpreter->ProcessLineSynch(printstr.c_str());
00423 }
00424 gROOT->LoadMacro(decayConfigScriptPath.c_str());
00425 gInterpreter->ProcessLineSynch("DecayConfig()");
00426
00427 return;
00428
00429 }
00430
00431
00432 void MCApplication::InitGeometry() {
00433
00434
00435 return;
00436
00437 }
00438
00439
00440 void MCApplication::InitMedia() {
00441
00442
00443
00444 UpdateGlobalGeoManager();
00445
00446 TIter nextmed(gGeoManager->GetListOfMedia());
00447 TGeoMedium* med = 0;
00448 while ( ( med = (TGeoMedium*)nextmed() ) ) {
00449 GeoMedium* geomed = dynamic_cast<GeoMedium*>(med);
00450 if ( !geomed ) continue;
00451 std::string medName = geomed -> GetName();
00452 const GeoMedium::CutMap& cutmap = geomed -> GetCutMap();
00453 for ( GeoMedium::CutMapConstItr citr = cutmap.begin();
00454 citr != cutmap.end(); citr++ ) {
00455 MSG("Geo",Msg::kDebug) << "Medium " << medName.c_str()
00456 << " " << UtilMCFlag::AsString(citr->first)
00457 << " set to " << citr->second
00458 << " overriding default." << endl;
00459 fMC -> Gstpar(geomed->GetId(),UtilMCFlag::AsString(citr->first),
00460 citr->second);
00461 }
00462 const GeoMedium::ProcessMap& processmap = geomed -> GetProcessMap();
00463 for ( GeoMedium::ProcessMapConstItr citr = processmap.begin();
00464 citr!= processmap.end(); citr++ ) {
00465 MSG("Geo",Msg::kDebug) << "Medium " << medName.c_str()
00466 << " " << UtilMCFlag::AsString(citr->first)
00467 << " set to " << citr->second
00468 << " overriding default." << endl;
00469 fMC -> Gstpar(geomed->GetId(),UtilMCFlag::AsString(citr->first),
00470 citr->second);
00471 }
00472 }
00473
00474 }
00475
00476
00477 void MCApplication::Field(const Double_t* x, Double_t* b) const {
00478
00479
00480
00481
00482
00483
00484
00485 b[0] = 0; b[1] = 0; b[2] = 0;
00486
00487 if ( !fBField ) {
00488 MSG("MCApp",Msg::kWarning) << "MCApplication::Field but Null fBField!"
00489 << endl;
00490 return;
00491 }
00492
00493
00494
00495 TGeoNode* node = gGeoManager->GetCurrentNode();
00496 if ( node -> GetVolume() -> GetMedium() -> GetParam(1) <= 0 ) return;
00497
00498 TVector3 bxyz(0,0,0);
00499 TVector3 xyz(x[0]*Munits::cm,x[1]*Munits::cm,x[2]*Munits::cm);
00500
00501 bxyz = fBField -> GetBField(xyz);
00502
00503
00504 for ( int i = 0; i < 3; i++ ) b[i] = bxyz[i]*10.;
00505
00506 UpdateGlobalGeoManager();
00507
00508 return;
00509
00510
00511 }
00512
00513
00514 void MCApplication::BeginEvent() {
00515
00516
00517
00518 UpdateGlobalGeoManager();
00519
00520
00521
00522
00523 fBFldInZTestSave = fBField -> GetRequireInZTest();
00524
00525
00526 if ( !fMCAppUser ) FatalNoApp();
00527 fMCAppUser -> BeginEvent();
00528
00529 return;
00530
00531 }
00532
00533
00534 void MCApplication::FinishEvent() {
00535
00536
00537 UpdateGlobalGeoManager();
00538
00539
00540 fBField -> SetRequireInZTest(fBFldInZTestSave);
00541
00542 if ( !fMCAppUser ) FatalNoApp();
00543 fMCAppUser -> FinishEvent();
00544
00545 return;
00546
00547 }
00548
00549
00550
00551
00552
00553