28#ifndef G4VUSERMOLECULEREACTIONCOUNTER_HH
29#define G4VUSERMOLECULEREACTIONCOUNTER_HH 1
42 static_assert(std::is_base_of<G4VMoleculeReactionCounter::G4VMoleculeReactionCounterIndex, TIndex>::value,
43 "TIndex must be derived from G4VMoleculeReactionCounter::G4VMoleculeReactionCounterIndex! "
44 "No forward declaration is allowed.");
59 void Dump() const override;
81 const std::vector<G4double>&)
const;
111 : G4VMoleculeReactionCounter(name, type)
116template<
typename TIndex>
125template<
typename TIndex>
134template<
typename TIndex>
145template<
typename TIndex>
147 const TIndex& index,
const std::vector<G4double>& times)
const
150 std::vector<G4int> counts = {};
151 for (
auto time : times)
158template<
typename TIndex>
160 std::unique_ptr<G4VMoleculeReactionCounter::G4VMoleculeReactionCounterIndex> pIndex,
163 const TIndex* mapIndex =
dynamic_cast<TIndex*
>(pIndex.get());
167 G4cout <<
"G4VUserMoleculeReactionCounter<"
169 <<
")::RecordReaction : " << mapIndex->GetReactionData()->GetReactionID()
171 G4cout <<
":: [IsTimeAboveUpperBound] Skipping since IsTimeAboveUpperBound == true" <<
G4endl;
177 G4cout <<
"G4VUserMoleculeReactionCounter<"
179 <<
")::RecordReaction : " << mapIndex->GetReactionData()->GetReactionID()
181 G4cout <<
":: [IsTimeBelowLowerBound] Skipping since IsTimeBelowLowerBound == true" <<
G4endl;
187 G4cout <<
"G4VUserMoleculeReactionCounter<"
189 <<
")::RecordReaction : " << mapIndex->GetReactionData()->GetReactionID()
195 if (indexIsNew || it->second.empty()) {
196 it->second.emplace(time, number);
203 auto end = it->second.rbegin();
205 if ((end->first <= time || std::fabs(end->first - time) <=
fTimeComparer.GetPrecisionAtTime(time)))
210 auto [it_time, _] = it->second.emplace(time, end->second);
211 it_time->second += number;
215 errMsg <<
"Time of reaction " << mapIndex->GetReactionData()->GetReactionID() <<
" is "
216 <<
G4BestUnit(time,
"Time") <<
"while the global time is "
218 <<
"(last counter time: " <<
G4BestUnit(end->first,
"Time") <<
")" <<
G4endl;
221 +
">::RecordReaction"),
232 auto [it_new, _] = it->second.emplace(time, it_closest->second);
234 it_new->second += number;
235 }
while (++it_new != it->second.end());
242template<
typename TIndex>
246 G4cout <<
"Entering in G4VUserMoleculeReactionCounter::GetMapIndices" <<
G4endl;
257 G4cout <<
"Entering in G4VUserMoleculeReactionCounter::GetRecordedReactions" <<
G4endl;
259 std::set<const G4DNAMolecularReactionData*> output{};
261 output.insert(it.first.GetReactionData());
303template<
typename TIndex>
307 && !(index < search.fLastIndexSearched->first))
337 if (timeMap.empty()) {
347 if (upperToLast == timeMap.end()) {
351 if (upperToLast->first > time) {
358 auto up_time_it = timeMap.upper_bound(time);
360 if (up_time_it == timeMap.end()) {
361 auto last_time = timeMap.rbegin();
362 return last_time->second;
364 if (up_time_it == timeMap.begin()) {
378template<
typename TIndex>
380 const G4VMoleculeCounterInternalBase* pCounterBase)
382 if (pCounterBase ==
nullptr) {
384 errMsg <<
"Could not cast the pointer to type G4VUserMoleculeReactionCounter<"
386 <<
"Because the pointer is nullptr!" <<
G4endl;
394 if (pCounter ==
nullptr) {
396 errMsg <<
"Could not cast the pointer to type G4VUserMoleculeReactionCounter<"
398 <<
"Because the objects aren't of the same type!" <<
G4endl;
404 if (pCounter->GetType() !=
GetType()) {
406 errMsg <<
"You are trying to absorb a counter with different type!" <<
G4endl;
412 for (
auto const& worker_it : pCounter->GetCounterMap()) {
413 auto [master_it, indexIsNew] =
416 G4int currentNumber = 0, previousNumber = 0;
417 for (
auto const& [time, number] : worker_it.second) {
418 currentNumber = number - previousNumber;
419 previousNumber = number;
421 if (master_it->second.empty()) {
422 master_it->second.emplace(time, currentNumber);
426 auto [it, _] = master_it->second.emplace(time, it_closest->second);
428 it->second += currentNumber;
429 }
while (++it != master_it->second.end());
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
std::map< G4double, G4int, G4MoleculeCounterTimeComparer > InnerCounterMapType
G4GLOB_DLL std::ostream G4cout
static G4MoleculeCounterManager * Instance()
static G4Scheduler * Instance()
G4bool IsTimeBelowLowerBound(G4double) const
G4MoleculeCounterTimeComparer fTimeComparer
const G4String & GetName() const
G4bool IsTimeAboveUpperBound(G4double) const
MoleculeReactionCounterType GetType() const
MoleculeReactionCounterType
void RecordReaction(std::unique_ptr< G4VMoleculeReactionCounterIndex >, G4double, G4int=1) override
G4bool SearchIndexUpdated(Search &, const TIndex &) const
std::set< G4double > GetRecordedTimes() const override
void AbsorbCounter(const G4VMoleculeCounterInternalBase *) override
virtual std::vector< G4int > GetNbReactionsAtTimes(const TIndex &, const std::vector< G4double > &) const
void ResetCounter() override
void Dump() const override
virtual G4int GetNbReactionsAtTime(const TIndex &, G4double) const
std::unique_ptr< G4VMoleculeReactionCounterIndex > BuildSimpleIndex(const G4DNAMolecularReactionData *) const override=0
std::set< const G4DNAMolecularReactionData * > GetRecordedReactions() const override
const std::map< TIndex, InnerCounterMapType > & GetCounterMap() const
std::map< TIndex, InnerCounterMapType > fCounterMap
void DumpCounterMapIndices() const override
std::vector< TIndex > GetMapIndices() const
~G4VUserMoleculeReactionCounter() override=default
void InitializeUser() override=0
G4int SearchUpperBoundTime(Search &, G4double, G4bool) const
G4VUserMoleculeReactionCounter()
G4String GetTemplateTypeName()
void DumpCounterMapIndices(const std::map< T, InnerCounterMapType > &map, G4bool includeEmpty=false)
const std::vector< T > GetMapIndices(const std::map< T, U > &_map)
void DumpCounterMapContents(const std::map< T, InnerCounterMapType > &map, G4bool includeEmpty=false)
std::map< TKey, TValue, TComp >::iterator FindClosestEntryForKey(std::map< TKey, TValue, TComp > &map, TKey key)
std::set< G4double > GetRecordedTimes(const std::map< T, InnerCounterMapType > &map)
std::map< TIndex, InnerCounterMapType >::const_iterator fLastIndexSearched
InnerCounterMapType::const_iterator fLowerBoundTime