25#include <FairMonitor.h>
26#include <FairParRootFileIo.h>
27#include <FairRootFileSink.h>
28#include <FairRunSim.h>
29#include <FairRuntimeDb.h>
30#include <FairSystemInfo.h>
31#include <FairUrqmdGenerator.h>
34#include <TDatabasePDG.h>
35#include <TG4RunConfiguration.h>
37#include <TGeant3TGeo.h>
39#include <TGeoManager.h>
40#include <TPythia6Decayer.h>
43#include <TStopwatch.h>
47#include <TVirtualMC.h>
49#include <boost/filesystem.hpp>
58using std::stringstream;
63 : TNamed(
"CbmTransport",
"Transport Run")
69 , fRun(new FairRunSim())
79 , fGenerateRunInfo(kFALSE)
80 , fStoreTrajectories(kFALSE)
97 auto pdgdb = TDatabasePDG::Instance();
98 pdgdb->ReadPDGTable();
116 FairGenerator* generator = NULL;
119 if (gSystem->AccessPathName(fileName)) {
120 LOG(fatal) << GetName() <<
": Input file " << fileName <<
" not found!";
126 LOG(fatal) << GetName() <<
": Input file " << fileName <<
" not found!";
133 case kUrqmd: generator =
new FairUrqmdGenerator(fileName);
break;
156 std::cout << std::endl;
157 LOG(info) << GetName() <<
": Configuring VMC...";
158 TVirtualMC* vmc =
nullptr;
161 TString* gModel =
fRun->GetGeoModel();
162 if (strncmp(gModel->Data(),
"TGeo", 4) == 0) {
163 LOG(info) << GetName() <<
": Create TGeant3TGeo";
164 vmc =
new TGeant3TGeo(
"C++ Interface to Geant3 with TGeo");
167 LOG(info) << GetName() <<
": Create TGeant3";
168 vmc =
new TGeant3(
"C++ Interface to Geant3");
175 LOG(info) << GetName() <<
": Create TGeant4";
178 TG4RunConfiguration* runConfig =
179 new TG4RunConfiguration(runConfigSettings[0], runConfigSettings[1], runConfigSettings[2]);
180 vmc =
new TGeant4(
"TGeant4",
"C++ Interface to Geant4", runConfig);
185 LOG(fatal) << GetName() <<
": unknown transport engine!";
188 std::unique_ptr<CbmStack> stack(
new CbmStack());
190 if (vmc) vmc->SetStack(stack.release());
218 auto pdgdb = TDatabasePDG::Instance();
222 LOG(fatal) << GetName() <<
": Forcing decay modes is not possible with TGeant4!";
226 Int_t pdg = decay.first;
227 UInt_t nDaughters = decay.second.size();
229 log << GetName() <<
": Force decay " << pdgdb->GetParticle(pdg)->GetName() <<
" -> ";
240 if (gMC->ParticleMCType(pdg) == kPTUndefined) {
241 LOG(info) << log.str();
242 LOG(fatal) << GetName() <<
": PDG " << pdg <<
" not in VMC!";
247 if (nDaughters <= 3) {
248 Float_t branch[6] = {100., 0., 0., 0., 0., 0.};
249 Int_t mode[6][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
250 for (UInt_t iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
251 mode[0][iDaughter] = decay.second[iDaughter];
252 log << pdgdb->GetParticle(decay.second[iDaughter])->GetName() <<
" ";
254 Bool_t success = gMC->SetDecayMode(pdg, branch, mode);
256 LOG(info) << log.str();
257 LOG(fatal) << GetName() <<
": Setting decay mode failed!";
259 log <<
", using native decayer.";
264 auto p6decayer = TPythia6Decayer::Instance();
265 Int_t daughterPdg[nDaughters];
266 Int_t multiplicity[nDaughters];
267 for (UInt_t iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
268 daughterPdg[iDaughter] = decay.second[iDaughter];
269 multiplicity[iDaughter] = 1;
270 log << pdgdb->GetParticle(decay.second[iDaughter])->GetName() <<
" ";
272 p6decayer->ForceParticleDecay(pdg, daughterPdg, multiplicity, nDaughters);
274 gMC->SetUserDecay(pdg);
277 LOG(info) << log.str();
290 std::cout << std::endl;
291 LOG(info) <<
"----- Settings for event generator";
293 LOG(info) <<
"----- End settings for event generator";
294 std::cout << std::endl;
300 LOG(fatal) << GetName() <<
": Beam profile is not consistent with target!";
331 TDatabasePDG* pdgdb = TDatabasePDG::Instance();
332 const char* name =
"";
335 Bool_t stable = kTRUE;
336 Double_t charge = 0.;
344 pdgdb->AddParticle(name, name, mass, stable, 0., charge,
"Ion", code);
345 pdgdb->AddAntiParticle(
"d-", -1 * code);
353 pdgdb->AddParticle(name, name, mass, stable, 0., charge,
"Ion", code);
354 pdgdb->AddAntiParticle(
"t-", -1 * code);
362 pdgdb->AddParticle(name, name, mass, stable, 0., charge,
"Ion", code);
363 pdgdb->AddAntiParticle(
"He3-", -1 * code);
371 pdgdb->AddParticle(name, name, mass, stable, 0., charge,
"Ion", code);
372 pdgdb->AddAntiParticle(
"He3-", -1 * code);
381 fRun->SetRadLenRegister(choice);
382 LOG(info) << GetName() <<
": Radiation length register is enabled";
397 LOG(info) << GetName() <<
": Set decay modes for pi0 and eta";
400 std::cout << std::endl << std::endl;
401 LOG(warn) <<
"***********************************";
402 LOG(warn) <<
"***********************************";
403 LOG(warn) << GetName() <<
": User decay modes cannot be set with TGeant4!";
404 LOG(warn) << GetName() <<
": Built-in decay modes for pi0 and eta will be used!";
405 LOG(warn) <<
"***********************************";
406 LOG(warn) <<
"***********************************";
407 std::cout << std::endl << std::endl;
411 TGeant3* gMC3 =
static_cast<TGeant3*
>(vmc);
443 gMC3->Gsdk(17, brEta, modeEta);
458 for (Int_t iMode = 2; iMode < 6; iMode++) {
464 gMC3->Gsdk(7, brPi, modePi);
475 Int_t numAvailEvents {0};
476 Int_t numMinAvailEvents {INT_MAX};
477 TObjArray* genList =
fEventGen->GetListOfGenerators();
478 for (Int_t i = 0; i < genList->GetEntries(); i++) {
482 if (nEvents > numAvailEvents) {
483 if (numAvailEvents < numMinAvailEvents) { numMinAvailEvents = numAvailEvents; }
489 if (nEvents > numAvailEvents) {
490 if (numAvailEvents < numMinAvailEvents) { numMinAvailEvents = numAvailEvents; }
494 if (nEvents > numMinAvailEvents) {
496 LOG(warning) <<
"The number of requested events (" << nEvents <<
") is larger than the number of available events ("
497 << numMinAvailEvents <<
")";
498 LOG(warning) <<
"Set the number of events to process to " << numMinAvailEvents;
500 nEvents = numMinAvailEvents;
510 if (
fOutFileName.IsNull()) LOG(fatal) << GetName() <<
": No output file specified!";
511 if (
fParFileName.IsNull()) LOG(fatal) << GetName() <<
": No parameter file specified!";
512 std::cout << std::endl << std::endl;
520 const char* engineName =
"";
522 case kGeant3: engineName =
"TGeant3";
break;
523 case kGeant4: engineName =
"TGeant4";
break;
525 LOG(warn) << GetName() <<
": Unknown transport engine ";
526 engineName =
"TGeant3";
530 LOG(info) << GetName() <<
": Using engine " << engineName;
531 fRun->SetName(engineName);
544 LOG(info) <<
fTarget->ToString();
548 LOG(warn) << GetName() <<
": No target defined!";
552 LOG(info) << GetName() <<
": Register magnetic field";
572 fRun->SetSimSetup(f);
594 FairRuntimeDb* rtdb =
fRun->GetRuntimeDb();
597 fieldPar->setChanged();
598 FairParRootFileIo* parOut =
new FairParRootFileIo(kTRUE);
600 rtdb->setOutput(parOut);
610 TDirectory* oldDir = gDirectory;
613 auto sink =
fRun->GetSink();
614 assert(sink->GetSinkType() == kFILESINK);
615 auto rootFileSink =
static_cast<FairRootFileSink*
>(sink);
616 TFile* outfile = rootFileSink->GetRootFile();
620 LOG(info) <<
"Here I am";
622 LOG(info) <<
"Write Geant3Settings";
626 LOG(info) <<
"Write Geant4Settings";
644 std::cout << std::endl;
645 LOG(info) << GetName() <<
": Run finished successfully.";
646 LOG(info) << GetName() <<
": Wall time for Init : " <<
fRealTimeInit <<
" s ";
647 LOG(info) << GetName() <<
": Wall time for Run : " <<
fRealTimeRun <<
" s ("
649 LOG(info) << GetName() <<
": Output file : " <<
fOutFileName;
650 LOG(info) << GetName() <<
": Parameter file : " <<
fParFileName;
652 std::cout << std::endl << std::endl;
658 if (gROOT->GetVersionInt() >= 60602) {
659 gGeoManager->GetListOfVolumes()->Delete();
660 gGeoManager->GetListOfShapes()->Delete();
691 LOG(fatal) << GetName() <<
": User decay mode for PDG " << pdg <<
" is already defined!";
695 for (UInt_t iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
696 fDecayModes[pdg].push_back(daughterPdg[iDaughter]);
707 std::string name = fileName.Data();
708 Int_t found = name.find_last_of(
"/");
710 TString geoDir = name.substr(0, found);
711 if (gSystem->AccessPathName(geoDir.Data())) {
712 LOG(error) << GetName() <<
": Directory for geometry file " << geoDir
713 <<
" does not exist; the file will not be created.";
728 if (gSystem->AccessPathName(fileName)) {
729 std::string name = fileName.Data();
730 Int_t found = name.find_last_of(
"/");
732 TString parDir = name.substr(0, found);
733 if (gSystem->AccessPathName(parDir.Data())) {
734 LOG(fatal) << GetName() <<
": Parameter directory " << parDir <<
" does not exist!";
755 if ((!gSystem->AccessPathName(fileName.Data())) && (!overwrite)) {
756 LOG(fatal) << fName <<
": output file " << fileName <<
" already exists!";
761 const char* directory = gSystem->DirName(fileName.Data());
762 if (gSystem->AccessPathName(directory)) {
763 Int_t success = gSystem->mkdir(directory, kTRUE);
765 LOG(fatal) << fName <<
": output directory " << directory <<
" does not exist and cannot be created!";
767 LOG(info) << fName <<
": created directory " << directory;
777 Double_t z, Double_t angle, Double_t density)
friend fvec log(const fvec &a)
Bool_t CheckWithTarget(const CbmTarget &target) const
Check consistency with a target.
virtual void Print(Option_t *opt="") const
Log output.
void SetBeamAngle(Double_t meanThetaX, Double_t meanThetaY, Double_t sigmaThetaX=-1., Double_t sigmaThetaY=-1.)
Set the beam angle in the focal plane.
void SetTarget(std::shared_ptr< const CbmTarget > target)
Set target properties.
void ForceVertexAtZ(Double_t zVertex)
Force event vertex to be at a given z.
const CbmBeamProfile & GetBeamProfile()
Beam profile.
void SetBeamPosition(Double_t meanX, Double_t meanY, Double_t sigmaX=-1., Double_t sigmaY=-1., Double_t zF=0.)
Set the beam position in the focal plane.
void ForceVertexInTarget(Bool_t choice=kTRUE)
Enable or disable forcing the vertex to be in the target.
void SetParameters(FairField *field)
User interface class to define the Geant3 simulation settings.
void Init(TVirtualMC *)
Set all parameters defined in this class.
User interface class to define the Geant4 simulation settings.
std::array< std::string, 3 > GetG4RunConfig()
Get the Geant4 run configuration.
void Init(TVirtualMC *)
Set all parameters defined in this class.
Class deciding whether to store an MC event.
Int_t GetNumAvailableEvents()
Get the maximum number of events available in the input file.
void SetSetupSource(ECbmSetupSource setupSource)
Set the source the setup will be loaded from.
CbmFieldMap * CreateFieldMap()
void LoadSetup(const char *setupName)
Class for filtering the stack before writing.
Class for constructing the geometry of the CBM target.
User interface class for transport simulation.
void SetDecayMode(Int_t pdg, UInt_t nDaughters, Int_t *daughterPdg)
Set a decay mode for a particle.
void SetTarget(const char *medium="Gold", Double_t thickness=0.025, Double_t diameter=2.5, Double_t x=0., Double_t y=0., Double_t z=-44.0, Double_t rot=0., Double_t density=-1)
Define the target.
std::shared_ptr< CbmTarget > fTarget
void RegisterRadLength(Bool_t choice=kTRUE)
Enable registration of radiation length.
virtual ~CbmTransport()
Destructor
void SetOutFileName(TString name, Bool_t overwrite=kFALSE)
Set the output file name.
CbmTransport()
Constructor.
CbmGeant3Settings * fGeant3Settings
std::unique_ptr< CbmMCEventFilter > fEventFilter
void SetGeoFileName(TString name)
Define geometry file name (output)
void LoadSetup(const char *setupName)
Use a standard setup.
void PiAndEtaDecay(TVirtualMC *vmc)
Correct decay modes for pi0 and eta.
void SetBeamPosition(Double_t x0, Double_t y0, Double_t sigmaX=-1., Double_t sigmaY=-1., Double_t zF=0.)
Set the beam position.
void SetRandomEventPlane(Double_t phiMin=0., Double_t phiMax=2. *TMath::Pi())
Activate random event plane.
void AddInput(const char *fileName, ECbmGenerator generator=kUnigen)
Add an input by file name and generator type.
void SetVertexSmearZ(Bool_t choice=kTRUE)
Enable smearing of event vertex in z.
void ConfigureVMC()
Set the parameters for the TVirtualMC.
void ForceVertexAtZ(Double_t zVertex)
Force the event vertex to be at a given z position.
void RegisterIons()
Register ions.
void SetParFileName(TString name)
Define parameter file name.
std::unique_ptr< CbmStackFilter > fStackFilter
void SetVertexSmearXY(Bool_t choice=kTRUE)
Enable smearing of event vertex in x and y.
void ForceUserDecays()
Force user-defined single-mode decays.
Bool_t fStoreTrajectories
void InitEventGenerator()
Event generator initialisation.
void SetSetupSource(ECbmSetupSource setupSource)
Set the source the setup will be loaded from.
void RegisterSetup()
Create and register the setup modules.
CbmGeant4Settings * fGeant4Settings
void Run(Int_t nEvents)
Execute transport run.
std::map< Int_t, std::vector< Int_t > > fDecayModes
CbmEventGenerator * fEventGen
void SetBeamAngle(Double_t x0, Double_t y0, Double_t sigmaX=-1., Double_t sigmaY=-1.)
Set the beam angle (emittency at the beam position)
void ForceVertexInTarget(Bool_t choice=kTRUE)
Enable or disable forcing the vertex to be in the target.
Generates input to transport simulation from files in Unigen format.
Int_t GetNumAvailableEvents()
Get the maximum number of events available in the input file.
bool IsRootFile(std::string filename)
Check if a the file exist and is a root file.