8 #include "montecarlo/mccore/GGSRunManagerExtensions.h"
11 #include "G4LogicalVolumeStore.hh"
15 : _nDiscardedEvsInKilledEvs(0), _nKilledEvs(0), _isCurrEvKilled(false), _simAgainKilledEv(false),
16 _ggsGeneratorAction(nullptr), _eventRandomFileBase(
""), _eventRandomFilePath(
""), _restoredFrom(
""),
17 _readEventRngStateFromFile(false), _saveEventRngStateToFile(false), _messenger(this,
"/GGS/"),
18 _randomMessenger(this,
"/GGS/random/") {
21 _messenger.DeclareProperty(
"rndmPrintModulo", _printModulo,
22 "Set the number of events between two dumps on screen of the random engine status "
23 "(set to 0 to disable the dump).");
25 _randomMessenger.DeclareProperty(
"eventRngStateFileBase", _eventRandomFileBase,
26 "Base name for random generator state files of each event");
27 _randomMessenger.DeclareProperty(
"eventRngStateFilePath", _eventRandomFilePath,
28 "Path for random generator state files of each event");
29 _randomMessenger.DeclareProperty(
"readEventRngStateFromFile", _readEventRngStateFromFile,
30 "Read the random number generator state for each event from file");
31 _randomMessenger.DeclareProperty(
"saveEventRngStateToFile", _saveEventRngStateToFile,
32 "Save the random number generator state for each event to file");
36 static const std::string routineName(
"GGSRunManager::KillEvent");
37 if (!_isCurrEvKilled) {
38 GGSCOUT(DEEPDEB) <<
"Kill event" << std::endl;
39 G4EventManager::GetEventManager()->AbortCurrentEvent();
40 _isCurrEvKilled =
true;
42 if (_ggsGeneratorAction)
43 _nDiscardedEvsInKilledEvs += _ggsGeneratorAction->
GetNDiscarded();
48 std::stringstream buffer;
49 G4Random::getTheEngine()->put(buffer);
50 _stateAtBeginOfEvent = std::move(buffer.str());
55 _isCurrEvKilled =
false;
56 _simAgainKilledEv =
false;
60 auto Indent = [](
const std::string &str) {
61 std::string indentedStr;
64 auto newlinePos = str.find_first_of(
'\n', pos);
65 if (newlinePos != std::string::npos) {
66 indentedStr.append(
" ").append(str, pos, newlinePos - pos + 1);
75 if (_printModulo != 0) {
76 if (eventID % _printModulo == 0 && eventID > _lastPrinted) {
77 std::stringstream outSS, bufferSS;
78 outSS <<
"---> Begin of event: " << eventID <<
"\n";
79 outSS <<
"--------- " << G4Random::getTheEngine()->name() <<
" random engine state ---------\n";
84 outSS <<
" State at begin of event tracking: \n";
85 G4Random::getTheEngine()->put(bufferSS);
86 outSS << Indent(bufferSS.str());
87 outSS <<
"----------------------------------------\n";
88 G4cout << outSS.str() << G4endl;
89 _lastPrinted = eventID;
95 static const char *routineName =
"GGSRunManagerExtensions::IsKilledAndToBeSimulatedAgain";
96 if (_isCurrEvKilled) {
97 GGSCOUT(DEEPDEB) <<
"Event " << ev->GetEventID() <<
" has been killed. " <<
GGSENDL;
98 if (_ggsGeneratorAction) {
100 <<
" (total: " << _nDiscardedEvsInKilledEvs <<
")" <<
GGSENDL;
102 if (_simAgainKilledEv) {
107 GGSCOUT(DEEPDEB) <<
"Finished simulating event " << ev->GetEventID() <<
GGSENDL;
108 if (_ggsGeneratorAction) {
114 _nDiscardedEvsInKilledEvs = 0;
116 if (_simAgainKilledEv) {
117 static bool printDone =
false;
119 GGSCOUT(WARNING) <<
"Request to re-simulate an event which has not been flagged as killed. Ignoring."
121 GGSCCOUT(WARNING) <<
"This message will be printed only once." <<
GGSENDL;
132 auto &rmExt =
dynamic_cast<G4RunManager &
>(*this);
133 rmExt.SetUserAction(userAction);
137 if (_ggsGeneratorAction) {
138 return _nDiscardedEvsInKilledEvs + _ggsGeneratorAction->
GetNDiscarded();
144 static const std::string routineName(
"GGSRunManagerExtensions::PrintLogVols");
145 G4LogicalVolumeStore *logVolStore = G4LogicalVolumeStore::GetInstance();
147 GGSCOUT(INFO) <<
"Logical volumes in current geometry:" <<
GGSENDL;
148 for (
auto &logVol : *logVolStore) {
155 if (_saveEventRngStateToFile || _readEventRngStateFromFile) {
157 const std::string fileName = _eventRandomFilePath + _eventRandomFileBase +
"run" + std::to_string(runID) +
"evt" +
158 std::to_string(eventID) +
".rndm";
160 if (_readEventRngStateFromFile) {
164 std::stringstream cerrDummyBuf;
165 std::streambuf *cerrBuf = std::cerr.rdbuf();
166 std::cerr.rdbuf(cerrDummyBuf.rdbuf());
167 std::ifstream stateFile(fileName);
170 std::string errorMessage;
172 G4Random::getTheEngine()->get(stateFile);
173 std::cerr.rdbuf(cerrBuf);
174 if (cerrDummyBuf.str() !=
"") {
176 errorMessage = cerrDummyBuf.str();
178 }
catch (std::exception &exc) {
180 errorMessage = exc.what();
183 errorMessage =
"unknown";
186 G4Exception(
"GGSRunManagerExtensions::HandleEventRngStateFile",
"Can't read state file",
187 G4ExceptionSeverity::FatalException,
188 ((
"Error when restoring the state of the random engine from file ") + fileName +
189 "\nReason: " + errorMessage)
192 _restoredFrom = fileName;
195 G4Exception(
"GGSRunManagerExtensions::HandleEventRngStateFile",
"Missing state file",
196 G4ExceptionSeverity::FatalException,
197 ((
"Can't find the random engine state file ") + fileName).c_str());
201 if (_saveEventRngStateToFile && !_readEventRngStateFromFile) {
202 std::ofstream stateFile(fileName);
203 G4Random::getTheEngine()->put(stateFile);
void PrintLogVols()
Print a list of logical volumes in current geometries.
#define GGSCCOUT(level)
Smart log utility which prints no header at the beginning of the line.
void SetGGSGeneratorAction(G4VUserPrimaryGeneratorAction *userAction)
Replacement of the SetUserAction method.
bool IsKilledAndToBeSimulatedAgain(const G4Event *ev)
Checks if the event has been killed and has to be re-simulated.
Base class for GGS generator actions.
void HandleEventRngStateFile(int runID, int eventID)
Handles the read/write operations to/from the random generator state file for each event...
int GetNDiscardedEvents()
Getter method for number of discarded events.
GGSRunManagerExtensions()
Constructor.
void DumpStatus(G4int eventID)
Prints the status of the random number generator.
const std::string & GetRandomStateAtBeginOfEvent()
Getter method for random engine state at the beginning of the current event.
unsigned int GetNDiscarded() const
Returns the number of discarded events for the current event generation.
void BeginOfEventSimulation()
Reset the internal flags at the beginning of event simulation.
void BeginOfEventProcessing()
Method for storing the random engine state and resetting the internal flags at the beginning event ge...
const std::string & RngStateRestoredFrom()
The random engine state file for this event.
void KillEvent()
Kills the current event.