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