41#include <TDatabasePDG.h>
43#include <TGeoManager.h>
44#include <TGeoMedium.h>
46#include <TGeoPhysicalNode.h>
48#include <TGeoVolume.h>
51#include <TInterpreter.h>
56#include <TParticlePDG.h>
60#include <TVirtualMC.h>
61#include <TVirtualMCStack.h>
77 , fActiveDetectors(nullptr)
78 , fFairTaskList(nullptr)
84 , fPythiaDecayer(kFALSE)
85 , fPythiaDecayerConfig(
"")
87 , fRootManager(nullptr)
88 , fSenVolumes(nullptr)
92 , fTrajFilter(nullptr)
93 , fTrajAccepted(kFALSE)
95 , fUserDecayConfig(
"")
103 , fTrkPos(TLorentzVector(0, 0, 0, 0))
105 , fRadLenMan(nullptr)
107 , fRadMapMan(nullptr)
108 , fRadGridMan(nullptr)
109 , fEventHeader(nullptr)
110 , fMCEventHeader(nullptr)
111 , listActiveDetectors()
115 , fSaveCurrentEvent(kTRUE)
118 , fGeometryIsInitialized(kFALSE)
124 LOG(
debug) <<
"FairMCApplication-ctor " <<
this;
146 LOG(
error) <<
"Dynamic cast fails. Object neither FairDetector nor FairModule in module list";
161 fgMasterInstance =
this;
167 , fActiveDetectors(nullptr)
168 , fFairTaskList(nullptr)
169 , fDetectors(nullptr)
174 , fPythiaDecayer(kFALSE)
175 , fPythiaDecayerConfig(rhs.fPythiaDecayerConfig)
177 , fRootManager(nullptr)
178 , fSenVolumes(nullptr)
179 , fxField(rhs.fxField)
181 , fMcVersion(rhs.fMcVersion)
182 , fTrajFilter(nullptr)
183 , fTrajAccepted(kFALSE)
185 , fUserDecayConfig(rhs.fUserDecayConfig)
193 , fTrkPos(rhs.fTrkPos)
195 , fRadLenMan(nullptr)
197 , fRadMapMan(nullptr)
198 , fRadGridMan(nullptr)
199 , fEventHeader(nullptr)
200 , fMCEventHeader(nullptr)
201 , listActiveDetectors()
205 , fSaveCurrentEvent(kTRUE)
208 , fGeometryIsInitialized(kFALSE)
213 LOG(
debug) <<
"FairMCApplication-copy-ctor " <<
this;
220 rhs.fModIter->Reset();
221 while ((obj = rhs.fModIter->Next())) {
232 if (obj->InheritsFrom(
"FairDetector")) {
242 LOG(
error) <<
"Dynamic cast fails.";
260 , fActiveDetectors(0)
267 , fPythiaDecayer(kFALSE)
268 , fPythiaDecayerConfig(
"")
275 , fTrajFilter(nullptr)
276 , fTrajAccepted(kFALSE)
278 , fUserDecayConfig(
"")
286 , fTrkPos(TLorentzVector(0, 0, 0, 0))
288 , fRadLenMan(nullptr)
290 , fRadMapMan(nullptr)
291 , fRadGridMan(nullptr)
292 , fEventHeader(nullptr)
293 , fMCEventHeader(nullptr)
294 , listActiveDetectors()
298 , fSaveCurrentEvent(kTRUE)
301 , fGeometryIsInitialized(kFALSE)
328 TVirtualMCApplication::operator=(rhs);
360 fGeometryIsInitialized = kFALSE;
369 while ((obj = rhs.fModIter->Next())) {
379 if (obj->InheritsFrom(
"FairDetector")) {
389 LOG(
error) <<
"Dynamic cast fails.";
418 fMC = TVirtualMC::GetMC();
421 LOG(fatal) <<
"No MC engine defined";
426 LOG(fatal) <<
"No Stack defined.";
435 TString MCName =
fMC->GetName();
436 if (MCName ==
"TGeant3" || MCName ==
"TGeant3TGeo") {
438 }
else if (MCName ==
"TGeant4") {
440 }
else if (MCName ==
"TFluka") {
447 LOG(info) <<
"Monte Carlo Engine Initialisation with: " << MCName.Data();
461 fMC->ProcessRun(nofEvents);
472 LOG(
debug) <<
"FairMCMCApplication::FinishRun() start";
475 detectorPtr->FinishRun();
487 TObjArray* meshlist =
nullptr;
498 LOG(info) <<
"=======================================================";
500 LOG(info) <<
"=======================================================";
503 radGridFile->mkdir(
"Dosimetry");
504 radGridFile->cd(
"Dosimetry");
506 for (Int_t
i = 0;
i < meshlist->GetEntriesFast();
i++) {
509 aMesh->
Scale(1. / nprimary);
518 radGridFile->Write();
519 radGridFile->Close();
534 UndoGeometryModifications();
537 LOG(
debug) <<
"Done FairMCMCApplication::FinishRun()";
547 detectorPtr->BeginEvent();
557 detectorPtr->BeginPrimary();
568 detectorPtr->PreTrack();
574 TParticle* particle =
fStack->GetCurrentTrack();
593 LOG(info) <<
"FairMCApplication::CloneForWorker ";
598 workerRun->SetName(
fRun->GetName());
613 return workerApplication;
640 LOG(info) <<
"Monte Carlo Engine Worker Initialisation with: " <<
fMC->GetName();
646 LOG(
debug) <<
"FairMCApplication::FinishRunOnWorker: ";
659 static Int_t TrackId = 0;
660 if (
fMcVersion == 2 &&
fMC->GetStack()->GetCurrentTrackNumber() != TrackId) {
662 TrackId =
fMC->GetStack()->GetCurrentTrackNumber();
675 Int_t
id =
fMC->CurrentVolID(copyNo);
676 Bool_t InMap = kFALSE;
688 if (copyNo == fCopyNo) {
712 fVolMap.insert(pair<Int_t, FairVolume*>(
id, fNewV));
740 id =
fMC->CurrentVolID(copyNo);
745 id =
fMC->CurrentVolID(copyNo);
760 detectorPtr->PostTrack();
770 detectorPtr->FinishPrimary();
785 LOG(warn) <<
"StopRun() exiting not safetly oopps !!!@@@!!!";
803 << gMC->CurrentEvent() <<
")";
822 detectorPtr->FinishEvent();
832 detectorPtr->EndOfEvent();
840 gGeoManager->GetListOfTracks()->Delete();
895 LOG(fatal) <<
"gGeoManager not initialized at FairMCApplication::ConstructGeometry\n";
902 Int_t NoOfVolumes = 0;
903 Int_t NoOfVolumesBefore = 0;
906 TObjArray* tgeovolumelist = gGeoManager->GetListOfVolumes();
909 NoOfVolumesBefore = tgeovolumelist->GetEntriesFast();
912 NoOfVolumes = tgeovolumelist->GetEntriesFast();
913 for (Int_t
n = NoOfVolumesBefore;
n < NoOfVolumes;
n++) {
914 TGeoVolume*
v = (TGeoVolume*)tgeovolumelist->At(
n);
915 fModVolMap.insert(pair<Int_t, Int_t>(
v->GetNumber(), ModId));
920 int NoOfVolumesBeforeClose = tgeovolumelist->GetEntries();
921 gGeoManager->CloseGeometry();
922 int NoOfVolumesAfterClose = tgeovolumelist->GetEntries();
927 if (NoOfVolumesBeforeClose != NoOfVolumesAfterClose) {
928 LOG(
error) <<
"TGeoManager::CloseGeometry() modified the volume list from " << NoOfVolumesBeforeClose <<
" to "
929 << NoOfVolumesAfterClose <<
"\n"
930 <<
"This almost certainly means inconsistent lookup structures used in simulation/stepping.\n";
934 TVirtualMC::GetMC()->SetRootGeometry();
935 LOG(info) <<
"TGeometry will be imported to VMC"
938 LOG(info) <<
"TGeometry will not be imported to VMC"
943 const THashList* list = pdgDatabase->ParticleList();
945 pdgDatabase->ReadPDGTable();
946 list = pdgDatabase->ParticleList();
948 TIterator* particleIter = list->MakeIterator();
949 TParticlePDG* Particle = 0;
950 while ((Particle =
dynamic_cast<TParticlePDG*
>(particleIter->Next())) && (Counter <= 256)) {
951 TString Name = gGeoManager->GetPdgName(Particle->PdgCode());
954 gGeoManager->SetPdgName(Particle->PdgCode(), Particle->GetName());
967 gGeoManager->RefreshPhysicalNodes(kFALSE);
990 if (fGeometryIsInitialized)
1004 LOG(warn) <<
"Stack is not registered ";
1016 module = dynamic_cast<FairModule*>(obj);
1018 module->SetSpecialPhysicsCuts();
1022 if (detector->IsActive()) {
1024 detector->Register();
1042 LOG(info) <<
"Simulation RunID: " << runId;
1084 LOG(
error) <<
"No FairVolume in fSenVolumes at position " <<
i;
1090 TGeoVolume*
v = gGeoManager->GetVolume(fv->GetName());
1093 fNs =
v->GetNodes();
1096 for (Int_t k = 0; k < fNs->GetEntriesFast(); k++) {
1097 fN =
dynamic_cast<TGeoNode*
>(fNs->At(k));
1099 LOG(
error) <<
"No TGeoNode in fNs at position " << k;
1107 fVolMap.insert(pair<Int_t, FairVolume*>(
id, fNewV));
1115 fVolMap.insert(pair<Int_t, FairVolume*>(
id, fNewV));
1118 fVolMap.insert(pair<Int_t, FairVolume*>(
id, fv));
1122 fGeometryIsInitialized = kTRUE;
1132 LOG(
debug) <<
"FairMCApplication::GeneratePrimaries: " <<
fEvGen;
1151 TIterator* Iter = NewIons->MakeIterator();
1155 while ((obj = Iter->Next())) {
1156 ion =
dynamic_cast<FairIon*
>(obj);
1164 Int_t ionPdg = GetIonPdg(ion->
GetZ(), ion->
GetA());
1165 if (!pdgDatabase->GetParticle(ionPdg)) {
1170 ion->SetName(pdgDatabase->GetParticle(ionPdg)->GetName());
1174 gGeoManager->SetPdgName(pdgDatabase->GetParticle(ion->GetName())->PdgCode(), ion->GetName());
1176 LOG(info) <<
"Add Ion: " << ion->GetName() <<
" with PDG "
1177 << pdgDatabase->GetParticle(ion->GetName())->PdgCode();
1190 TIterator* parIter = NewPart->MakeIterator();
1196 LOG(fatal) <<
"No MC engine was defined before AddParticles()";
1200 while ((obj = parIter->Next())) {
1204 LOG(info) <<
"Add Particle: " << particle->
GetName() <<
" with PDG " << particle->
GetPDG() <<
"\n"
1205 << particle->
GetName() <<
" // const TString& name \n"
1206 << particle->
GetMCType() <<
" // TMCParticleType mcType \n"
1207 << particle->
GetMass() <<
" // Double_t mass \n"
1208 << particle->
GetCharge() <<
" // Double_t charge \n"
1209 << particle->
GetDecayTime() <<
" // Double_t lifetime \n"
1210 << particle->
GetPType() <<
" // const TString& pType, \n"
1211 << particle->
GetWidth() <<
" // Double_t width \n"
1212 << particle->
GetSpin() <<
" // Int_t iSpin \n"
1213 << particle->
GetiParity() <<
" // Int_t iParity \n"
1215 << particle->
GetIsospin() <<
" // Int_t iIsospin \n"
1216 << particle->
GetIsospinZ() <<
" // Int_t iIsospinZ \n"
1217 << particle->
GetgParity() <<
" // Int_t gParity \n"
1218 << particle->
GetLepton() <<
" // Int_t lepton \n"
1219 << particle->
GetBaryon() <<
" // Int_t baryon \n"
1220 << particle->
IsStable() <<
" // Bool_t stable \n";
1222 curMC->DefineParticle(particle->
GetPDG(),
1243 gGeoManager->SetPdgName(particle->
GetPDG(), particle->
GetName());
1254 TString work = getenv(
"VMCWORKDIR");
1255 TString work_config = work +
"/gconfig/";
1256 work_config.ReplaceAll(
"//",
"/");
1258 TString config_dir = getenv(
"CONFIG_DIR");
1259 config_dir.ReplaceAll(
"//",
"/");
1261 Bool_t AbsPath = kFALSE;
1263 if (!config_dir.EndsWith(
"/")) {
1269 TString decayConfig;
1271 decayConfig =
"DecayConfig.C";
1280 if (!AbsPath && TString(gSystem->FindFile(config_dir.Data(), decayConfig)) != TString(
"")) {
1281 LOG(info) <<
"---User path for Configuration (DecayConfig.C) is used : " << config_dir.Data();
1290 LOG(info) <<
"External Decay Modes with script \n " << decayConfig.Data();
1292 Int_t pyt = gROOT->LoadMacro(decayConfig.Data());
1294 gInterpreter->ProcessLine(
"DecayConfig()");
1302 Userdecay =
"UserDecay.C";
1311 if (!AbsPath && TString(gSystem->FindFile(config_dir.Data(), Userdecay)) != TString(
"")) {
1312 LOG(info) <<
"---User path for Configuration (UserDecay.C) is used : " << config_dir.Data();
1320 LOG(info) <<
"User Decay Modes with script \n " << Userdecay.Data();
1321 Int_t dec = gROOT->LoadMacro(Userdecay.Data());
1323 gInterpreter->ProcessLine(
"UserDecayConfig()");
1367 LOG(info) <<
"Initialize Tasks--------------------------";
1378 LOG(warn) <<
"The function is not available in MT mode";
1411Int_t FairMCApplication::GetIonPdg(Int_t
z, Int_t
a)
const
1416 return 1000000000 + 10 * 1000 *
z + 10 *
a;
1420void FairMCApplication::UndoGeometryModifications()
1432 TObjArray* physNodes = gGeoManager->GetListOfPhysicalNodes();
1433 Int_t numPhysNodes = physNodes->GetEntriesFast();
1435 if (0 == numPhysNodes)
1439 LOG(info) <<
"Undo all misalignment";
1441 TGeoPhysicalNode*
node =
nullptr;
1442 TGeoHMatrix* ng3 =
nullptr;
1443 for (Int_t k = 0; k < numPhysNodes; k++) {
1444 node =
static_cast<TGeoPhysicalNode*
>(physNodes->At(k));
1445 ng3 =
node->GetOriginalMatrix();
1449 gGeoManager->ClearPhysicalNodes(kFALSE);
default_random_engine gen(dev())
std::unique_ptr< expressions::Node > node
ClassImp(FairMCApplication)
char error[CURL_ERROR_SIZE]
virtual Bool_t ProcessHits(FairVolume *v=0)=0
virtual void Initialize()
virtual void FinishPrimary()
virtual void UpdateTrackIndex(TRefArray *)
virtual void FillTrackArray()
void SetDetArrayList(TRefArray *detArray)
Double_t GetExcEnergy() const
void InitMC(const char *setup, const char *cuts)
virtual void AddParticles()
void SetRadiationMapReg(Bool_t RadMap)
void AddMeshList(TObjArray *meshList)
std::list< FairDetector * > listActiveDetectors
virtual void BeginPrimary()
virtual void FinishPrimary()
void AddTask(TTask *fTask)
virtual void FinishEvent()
FairMCEventHeader * fMCEventHeader
FairRadLenManager * fRadLenMan
FairRadGridManager * fRadGridMan
FairPrimaryGenerator * fEvGen
virtual void FinishRunOnWorker()
void SetField(FairField *field)
FairRadMapManager * fRadMapMan
FairGenericStack * fStack
std::map< Int_t, Int_t >::iterator fModVolIter
std::multimap< Int_t, FairVolume * >::iterator fVolIter
void SetGenerator(FairPrimaryGenerator *fxGenerator)
virtual void ConstructOpGeometry()
virtual void BeginEvent()
std::map< Int_t, Int_t > fModVolMap
FairRootManager * fRootManager
void RunMC(Int_t nofEvents)
virtual TVirtualMCApplication * CloneForWorker() const
virtual ~FairMCApplication()
std::list< FairDetector * > listDetectors
FairPrimaryGenerator * GetGenerator()
virtual void InitOnWorker()
FairEventHeader * fEventHeader
FairGenericStack * GetStack()
TString fPythiaDecayerConfig
void SetRadiationLengthReg(Bool_t RadLen)
virtual void ConstructGeometry()
virtual void GeneratePrimaries()
FairTrajFilter * fTrajFilter
std::multimap< Int_t, FairVolume * > fVolMap
TRefArray * fActiveDetectors
FairMCApplicationState fState
virtual Double_t TrackingRmax() const
virtual void InitGeometry()
virtual Double_t TrackingZmax() const
FairDetector * GetDetector(const char *DetName)
virtual void AddDecayModes()
virtual Bool_t MisalignGeometry()
virtual void ConstructOpGeometry()
virtual FairModule * CloneModule() const
virtual void RegisterAlignmentMatrices()
virtual void ConstructGeometry()
static thread_local TRefArray * svList
virtual const char * GetName() const
const TString & GetPType()
TMCParticleType GetMCType()
void SetEvent(FairMCEventHeader *event)
virtual FairPrimaryGenerator * ClonePrimaryGenerator() const
virtual Bool_t GenerateEvent(FairGenericStack *pStack)
void AddMeshList(TObjArray *list)
TObjArray * GetMeshList()
TString GetOutputFileName()
void AddPoint(Int_t &ModuleId)
void AddPoint(Int_t &ModuleId)
static FairRootManager * Instance()
Int_t GetInstanceId() const
Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
TObjArray * GetUserDefIons()
FairMCEventHeader * GetMCEventHeader()
FairPrimaryGenerator * GetPrimaryGenerator()
static FairRunSim * Instance()
TObjArray * GetUserDefParticles()
Bool_t IsImportTGeoToVMC() const
Bool_t GetStoreTraj() const
static FairRun * Instance()
Bool_t IsRunInfoGenerated()
void SetSink(FairSink *tempSink)
void AlignGeometry() const
virtual Sink_Type GetSinkType()=0
virtual FairSink * CloneSink()=0
virtual void ExecuteTask(Option_t *option="0")
virtual void FinishTask()
virtual void FinishEvent()
Bool_t IsAccepted(const TParticle *p) const
void Init(TString brName="GeoTracks", TString folderName="MCGeoTrack")
static FairTrajFilter * Instance()
Double_t GetStepSizeCut() const
TGeoTrack * CheckAddTrack(Int_t trackId, TParticle *p)
TGeoTrack * GetCurrentTrk()
FairDetector * GetDetector()
void SetModule(FairModule *mod)
FairGeoNode * getGeoNode()
GLuint const GLchar * name
GLboolean GLboolean GLboolean GLboolean a
GLdouble GLdouble GLdouble z
D const SVectorGPU< T, D > & rhs
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"