BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSRandom.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) BDSIM Collaboration, 2001 - 2026.
3
4This file is part of BDSIM.
5
6BDSIM is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published
8by the Free Software Foundation version 3 of the License.
9
10BDSIM is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "BDSDebug.hh"
19#include "BDSException.hh"
20#include "BDSGlobalConstants.hh"
21#include "BDSRandom.hh"
22#include "BDSUtilities.hh"
23
24#include "globals.hh"
25#include "G4String.hh"
26#include "G4Types.hh"
27
28#include "CLHEP/Random/Random.h"
29#include "CLHEP/Random/JamesRandom.h"
30#ifdef CLHEPHASMIXMAX
31#include "CLHEP/Random/MixMaxRng.h"
32#else
33#include "CLHEP/ClhepVersion.h"
34#endif
35
36#include <ctime>
37#include <map>
38#include <string>
39#include <sstream>
40
41template<>
42std::map<BDSRandomEngineType, std::string>* BDSRandomEngineType::dictionary =
43 new std::map<BDSRandomEngineType, std::string> ({
44 {BDSRandomEngineType::hepjames, "hepjames"},
45 {BDSRandomEngineType::mixmax, "mixmax"}
46 });
47
48BDSRandomEngineType BDSRandom::DetermineRandomEngineType(G4String engineType)
49{
50 std::map<G4String, BDSRandomEngineType> types;
51 types["hepjames"] = BDSRandomEngineType::hepjames;
52 types["mixmax"] = BDSRandomEngineType::mixmax;
53
54 engineType = BDS::LowerCase(engineType);
55
56 auto result = types.find(engineType);
57 if (result == types.end())
58 {// it's not a valid key
59 G4String msg = "\"" + engineType + "\" is not a valid random engine\n";
60 msg += "Available random engines are:\n";
61 for (auto& it : types)
62 {msg += "\"" + it.first + "\"\n";}
63 throw BDSException(__METHOD_NAME__, msg);
64 }
65 return result->second;
66}
67
68void BDSRandom::CreateRandomNumberGenerator(const G4String& engineName)
69{
70 auto et = BDSRandom::DetermineRandomEngineType(engineName);
71 G4cout << __METHOD_NAME__ << "Engine name: " << et.ToString() << G4endl;
72 switch (et.underlying())
73 {
74 case BDSRandomEngineType::hepjames:
75 {CLHEP::HepRandom::setTheEngine(new CLHEP::HepJamesRandom()); break;}
76 case BDSRandomEngineType::mixmax:
77#ifdef CLHEPHASMIXMAX
78 {CLHEP::HepRandom::setTheEngine(new CLHEP::MixMaxRng()); break;}
79#else
80 {
81 G4String msg = G4String(et.ToString()) + " is not available in CLHEP version: " + G4String(CLHEP::Version::String());
82 throw BDSException(__METHOD_NAME__, msg);
83 break;
84 }
85#endif
86 default:
87 {throw BDSException(__METHOD_NAME__, "engine \"" + engineName + "\" not implemented"); break;}
88 }
89}
90
91void BDSRandom::SetSeed()
92{
93#ifdef BDSDEBUG
94 G4cout << __METHOD_NAME__ << "set the seed" << G4endl;
95 G4cout << __METHOD_NAME__ << "seed from BDSGlobalConstants = "
96 << BDSGlobalConstants::Instance()->Seed() << G4endl
97 << __METHOD_NAME__ << "seed set in GMAD options: "
98 << BDSGlobalConstants::Instance()->SeedSet() << G4endl;
99#endif
100 // if seed positive set it, else use the time
101 long seed = 0;
102
103 if(BDSGlobalConstants::Instance()->Seed() < 0)
104 {seed = time(nullptr);}
105 else
106 {seed = BDSGlobalConstants::Instance()->Seed();}
107
108#ifdef BDSDEBUG
109 G4cout << __METHOD_NAME__ << "selected seed = " << seed << G4endl;
110#endif
111
112 CLHEP::HepRandom::setTheSeed(seed);
113
114 // feedback - get the seed from the generator itself (ensures set correctly)
115 G4cout << __METHOD_NAME__ << "Random number generator's seed = "
116 << CLHEP::HepRandom::getTheSeed() << G4endl;
117#ifdef BDSDEBUG
118 BDSRandom::PrintFullSeedState();
119#endif
120}
121
122void BDSRandom::PrintFullSeedState()
123{
124 G4cout << __METHOD_NAME__ << "Random number generator's state: " << G4endl << G4endl;
125 CLHEP::HepRandom::saveFullState(G4cout);
126 G4cout << G4endl;
127}
128
129void BDSRandom::WriteSeedState(const G4String& suffix)
130{
131 G4String baseFileName = BDSGlobalConstants::Instance()->OutputFileName();
132 G4String seedstatefilename = baseFileName + suffix + ".seedstate.txt";
133 std::ofstream ofseedstate;
134 ofseedstate.open(seedstatefilename);
135 CLHEP::HepRandom::saveFullState(ofseedstate);
136 ofseedstate.close();
137}
138
139G4String BDSRandom::GetSeedState()
140{
141 std::stringstream currentState;
142 CLHEP::HepRandom::saveFullState(currentState);
143 return G4String(currentState.str());
144}
145
146void BDSRandom::LoadSeedState(const G4String& inSeedFilename)
147{
148#ifdef BDSDEBUG
149 G4cout << __METHOD_NAME__ << "loading file: " << inSeedFilename << G4endl;
150#endif
151 std::ifstream ifseedstate;
152 ifseedstate.open(inSeedFilename);
153 if (ifseedstate.is_open())
154 {CLHEP::HepRandom::restoreFullState(ifseedstate);}
155 else
156 {throw BDSException(__METHOD_NAME__, "cannot open file : " + inSeedFilename);}
157 ifseedstate.close();
158#ifdef BDSDEBUG
159 BDSRandom::PrintFullSeedState();
160#endif
161}
162
163void BDSRandom::SetSeedState(const G4String& seedState)
164{
165 if (seedState.empty())
166 {G4cout << __METHOD_NAME__ << "empty seed state supplied - no seed state set" << G4endl; return;}
167 std::stringstream ss;
168 ss.str(seedState); // set contents of string stream as input string
169 SetSeedState(ss);
170}
171
172void BDSRandom::SetSeedState(std::stringstream& seedState)
173{
174 CLHEP::HepRandom::restoreFullState(seedState);
175#ifdef BDSEBUG
176 BDSRandom::PrintFullSeedState();
177#endif
178}
General exception with possible name of object and message.
static BDSGlobalConstants * Instance()
Access method.
Improve type-safety of native enum data type in C++.
static std::map< BDSTypeSafeEnum< def, inner >, std::string > * dictionary
G4String LowerCase(const G4String &str)
Utility function to simplify lots of syntax changes for pedantic g4 changes.