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