40static G4Mutex masterInstanceMutex;
41static G4Mutex workerInstancesMutex;
44std::vector<const G4MoleculeCounterManager*> G4MoleculeCounterManager::fWorkerInstances = {};
45G4ThreadLocal std::unique_ptr<G4MoleculeCounterManager> G4MoleculeCounterManager::fpInstance =
nullptr;
49G4ThreadLocal std::atomic<G4bool> G4MoleculeCounterManager::fBeginOfEventTriggered(
false);
50std::atomic<G4bool> G4MoleculeCounterManager::fBeginOfRunTriggered(
false);
59 : fVerbosity(0), fIsInitialized(false), fIsActive(true)
61 fpMessenger = std::make_unique<G4MoleculeCounterManagerMessenger>(
this);
72 "The molecule counter manager was configured to reset counters before each run"
73 " but the BeginOfRunAction was never triggered!\n"
74 "Ensure that the user code calls either the G4DNAChemistryManager's or "
75 "G4MoleculeCounterManager's Run methods!");
82 "The molecule counter manager was configured to reset counters before each event"
83 " but the BeginOfEventAction was never triggered!\n"
84 "This can occurr if this thread is never processing an event but:\n"
85 "Ensure that the user code calls either the G4DNAChemistryManager's or "
86 "G4MoleculeCounterManager's Event methods!");
94 fpMasterInstance =
nullptr;
101 auto it = std::find(fWorkerInstances.begin(), fWorkerInstances.end(),
this);
102 if (it == fWorkerInstances.end()) {
104 "G4MoleculeCounterManager::~G4MoleculeCounterManager",
"MOLMAN_DTOR",
JustWarning,
105 "The destroyed instance of G4MoleculeCounterManager has not been registered as a worker!");
113void G4MoleculeCounterManager::RegisterInstance()
115 if (fInstancesRegistered) {
117 "Instances were already registered once!");
122 if (fpMasterInstance !=
nullptr) {
124 "Master instance was set already!");
130 fWorkerInstances.push_back(
Instance());
132 fInstancesRegistered =
true;
138 if (fpInstance ==
nullptr) {
140 fpInstance = std::make_unique<G4MoleculeCounterManager>(G4MoleculeCounterManager::Private());
141 fpInstance->RegisterInstance();
143 return fpInstance.get();
148 return fpInstance.get();
155 if (fpInstance !=
nullptr) {
169 if (fVerbosity > 0) {
170 G4cout <<
"G4MoleculeCounterManager::Initialize ("
185void G4MoleculeCounterManager::InitializeMaster()
187 if (fIsInitialized)
return;
188 for (
auto&
counter : fCounters)
192void G4MoleculeCounterManager::InitializeWorker()
194 if (fIsInitialized)
return;
195 for (
auto& counter : fCounters)
196 counter.second->Initialize();
208 for (
auto& [
id,
counter] : fCounters) {
209 counter->AddMolecule(
counter->BuildSimpleIndex(molecule), time, n);
216 for (
auto& [
id,
counter] : fCounters) {
217 counter->RemoveMolecule(
counter->BuildSimpleIndex(molecule), time, n);
223 for (
auto& [
id,
counter] : fCounters) {
230 for (
auto& [
id,
counter] : fCounters) {
238 for (
auto& [
id,
counter] : fCounters) {
239 if (
counter->GetSensitiveToStepping()) {
240 counter->AddMolecule(
counter->BuildIndex(aTrack, aStepPoint), time, n);
248 for (
auto& [
id,
counter] : fCounters) {
249 if (
counter->GetSensitiveToStepping()) {
250 counter->RemoveMolecule(
counter->BuildIndex(aTrack, aStepPoint), time, n);
260 for (
auto& [
id,
counter] : fReactionCounters) {
261 counter->RecordReaction(
counter->BuildSimpleIndex(reactionData), time, n);
283 for (
auto& [
id,
counter] : fCounters) {
287 if (!(*preStepIndex == *postStepIndex)) {
290 G4cout <<
"G4MoleculeCounterManager::NotifyOfStep for counter " <<
counter->GetName()
291 <<
":\n-- Pre = " << preStepIndex->GetInfo() <<
"\n"
292 <<
"-- Post = " << postStepIndex->GetInfo() <<
G4endl;
303 for (
auto& [
id,
counter] : fCounters) {
304 counter->SchedulerFinalizedTracking();
314 for (
auto& [
id,
counter] : fCounters) {
315 counter->IgnoreMolecule(molecule);
321 for (
auto& [
id,
counter] : fCounters) {
322 counter->IgnoreReactant(molecule);
328 for (
auto& [
id,
counter] : fCounters) {
341 auto idProvider = [&]() {
342 if (fCounters.size() == 0)
return 0;
344 auto lastIndex = *indices.rbegin();
355 auto idProvider = [&] {
356 if (fReactionCounters.size() == 0)
return 0;
358 auto lastIndex = *indices.rbegin();
369 for (
auto& [
id, ctr] : fCounters) {
374 for (
auto& [
id, ctr] : fReactionCounters) {
377 fReactionCounters.clear();
388 if (fVerbosity > 0) {
389 G4cout <<
"G4MoleculeCounterManager::ResetCounters ("
393 for (
auto& [
id,
counter] : fCounters)
395 for (
auto& [
id,
counter] : fReactionCounters)
403 G4bool belowTimeInclusive)
405 if (fVerbosity > 0) {
406 G4cout <<
"G4MoleculeCounterManager::ActivateCounterAtTimes ("
411 counter->SetActiveLowerBound(aboveTime, aboveTimeInclusive);
412 counter->SetActiveUpperBound(belowTime, belowTimeInclusive);
417 G4bool aboveTimeInclusive,
418 G4bool belowTimeInclusive)
420 if (fVerbosity > 0) {
421 G4cout <<
"G4MoleculeCounterManager::ActivateReactionCounterAtTimes ("
426 counter->SetActiveLowerBound(aboveTime, aboveTimeInclusive);
427 counter->SetActiveUpperBound(belowTime, belowTimeInclusive);
434 auto it = fCounters.find(
id);
435 if (it == fCounters.end()) {
437 description <<
"No molecule counter with Id = " <<
id <<
" was found!\n";
448 std::vector<const G4VMoleculeCounter*> output;
449 output.reserve(fCounters.size());
450 for (
auto& [
id,
counter] : fCounters)
457 std::vector<const G4VMoleculeCounter*> output;
458 for (
auto& [
id,
counter] : fCounters) {
469 auto it = fReactionCounters.find(
id);
470 if (it == fReactionCounters.end()) {
472 description <<
"No molecule reaction counter with Id = " <<
id <<
" was found!\n";
473 G4Exception(
"G4MoleculeCounterManager::GetMoleculeReactionCounter",
"MOLMAN001",
482std::vector<const G4VMoleculeReactionCounter*>
485 std::vector<const G4VMoleculeReactionCounter*> output;
486 output.reserve(fReactionCounters.size());
487 for (
auto& [
id,
counter] : fReactionCounters)
492std::vector<const G4VMoleculeReactionCounter*>
495 std::vector<const G4VMoleculeReactionCounter*> output;
496 for (
auto& [
id,
counter] : fReactionCounters) {
506 fBeginOfEventTriggered =
true;
525 fBeginOfRunTriggered =
true;
571 description <<
"This method may only be called from the master thread!";
572 G4Exception(
"G4MoleculeCounterManager::AbsorbWorkerManagerCounters",
"MOLMAN999",
580 for (
auto const& worker : fWorkerInstances) {
581 if (selectedWorker ==
nullptr || worker != selectedWorker)
continue;
583 for (
auto& [
id, masterCounter] : fpMasterInstance->fCounters) {
585 auto workerCounter = worker->GetMoleculeCounter(
id);
586 masterCounter->AbsorbCounter(workerCounter);
589 for (
auto& [
id, masterCounter] : fpMasterInstance->fReactionCounters) {
591 auto workerCounter = worker->GetMoleculeReactionCounter(
id);
592 masterCounter->AbsorbCounter(workerCounter);
603 for (
auto const& pCounter : fpMasterInstance->GetMoleculeCounters()) {
604 G4cout <<
"=========================================================================== \n"
605 <<
" >> [MASTER] Dumping Molecule Counter `" << pCounter->GetName() <<
"`\n"
608 G4cout <<
"\n=========================================================================== "
612 for (
auto const& pCounter : fpMasterInstance->GetMoleculeReactionCounters()) {
613 G4cout <<
"=========================================================================== \n"
614 <<
" >> [MASTER] Dumping Molecule Reaction Counter `" << pCounter->GetName() <<
"`\n"
617 G4cout <<
"\n=========================================================================== "
628 for (
auto const& worker : G4MoleculeCounterManager::fWorkerInstances) {
629 for (
auto const& pCounter : worker->GetMoleculeCounters()) {
630 G4cout <<
"=========================================================================== \n"
631 <<
" >> [WORKER<" << worker <<
">] Dumping Molecule Counter `" << pCounter->GetName()
635 G4cout <<
"\n=========================================================================== "
639 for (
auto const& pCounter : worker->GetMoleculeReactionCounters()) {
640 G4cout <<
"=========================================================================== \n"
641 <<
" >> [WORKER<" << worker <<
">] Dumping Molecule Reaction Counter `"
642 << pCounter->GetName() <<
"`\n"
645 G4cout <<
"\n=========================================================================== "
653std::atomic<G4bool> G4MoleculeCounterManager::fResetCountersBeforeEvent(
false);
654std::atomic<G4bool> G4MoleculeCounterManager::fResetCountersBeforeRun(
false);
655std::atomic<G4bool> G4MoleculeCounterManager::fAccumulateCounterIntoMaster(
true);
656std::atomic<G4bool> G4MoleculeCounterManager::fResetMasterCounterWithWorkers(
false);
660 return fResetCountersBeforeEvent.load();
665 fResetCountersBeforeEvent = flag;
669 "This flag may only be set during the PreInit state!");
674 return fResetCountersBeforeRun.load();
679 fResetCountersBeforeRun = flag;
682 "This flag may only be set during the PreInit state!");
687 return fAccumulateCounterIntoMaster.load();
692 fAccumulateCounterIntoMaster = flag;
694 G4Exception(
"G4DNAChemistryManager::SetAccumulateCounterIntoMaster",
"WRONG_STATE",
695 FatalException,
"This flag may only be set during the PreInit state!");
700 return fResetMasterCounterWithWorkers.load();
705 fResetMasterCounterWithWorkers = flag;
707 G4Exception(
"G4DNAChemistryManager::SetResetMasterCounterWithWorkers",
"WRONG_STATE",
708 FatalException,
"This flag may only be set during the PreInit state!");
G4TemplateAutoLock< G4Mutex > G4AutoLock
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4GLOB_DLL std::ostream G4cout
void ActivateReactionCounterAtTimes(G4int, G4double, G4double, G4bool=true, G4bool=true)
G4MoleculeCounterManager(Private)
void BroadcastIgnoreMolecule(const G4MoleculeDefinition *)
void DumpMasterCounters() const
G4int GetVerbosity() const
void BroadcastRegisterAllMoleculesAndReactants()
G4bool GetResetCountersBeforeRun() const
void DeregisterAllCounters()
void RecordReaction(const G4DNAMolecularReactionData *, G4double, G4int=1)
void EndOfEventAction(const G4Event *)
void BeginOfRunAction(const G4Run *)
void SetResetMasterCounterWithWorkers(G4bool=true)
void EndOfRunAction(const G4Run *)
void AddMoleculeWithoutTrack(const G4MolecularConfiguration *, G4double, G4int=1)
G4int RegisterCounter(std::unique_ptr< G4VMoleculeCounter >)
G4VMoleculeReactionCounter * GetEditableMoleculeReactionCounter(G4int) const
void SetAccumulateCounterIntoMaster(G4bool=true)
void AddMolecule(const G4Track *, G4double, G4int=1)
void BeginOfEventAction(const G4Event *)
void RemoveMoleculeWithoutTrack(const G4MolecularConfiguration *, G4double, G4int=1)
static G4MoleculeCounterManager * GetInstanceIfExists()
G4VMoleculeCounter * GetEditableMoleculeCounter(G4int) const
G4bool GetResetMasterCounterWithWorkers() const
void AbsorbWorkerManagerCounters(const G4MoleculeCounterManager *=nullptr)
static G4MoleculeCounterManager * Instance()
void ActivateCounterAtTimes(G4int, G4double, G4double, G4bool=true, G4bool=true)
static void DeleteInstance()
G4bool GetAccumulateCounterIntoMaster() const
void NotifyOfStep(const G4Step *)
std::vector< const G4VMoleculeReactionCounter * > GetMoleculeReactionCounters() const
void SetResetCountersBeforeRun(G4bool=true)
void DumpWorkerCounters() const
G4bool GetResetCountersBeforeEvent() const
~G4MoleculeCounterManager()
void RemoveMolecule(const G4Track *, G4double, G4int=1)
void SetResetCountersBeforeEvent(G4bool=true)
void BroadcastIgnoreReactant(const G4MolecularConfiguration *)
std::vector< const G4VMoleculeCounter * > GetMoleculeCounters() const
static G4StateManager * GetStateManager()
G4Track * GetTrack() const
G4StepPoint * GetPreStepPoint() const
G4StepPoint * GetPostStepPoint() const
G4double GetGlobalTime() const
G4bool IsMultithreadedApplication()
const std::vector< T > GetMapIndices(const std::map< T, U > &_map)