Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/models/src/G4DNAEventScheduler.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 //
 27 #include <memory>
 28 #include "G4DNAEventScheduler.hh"
 29 #include "G4DNAGillespieDirectMethod.hh"
 30 #include "G4SystemOfUnits.hh"
 31 #include "G4UnitsTable.hh"
 32 #include "G4DNAUpdateSystemModel.hh"
 33 #include "G4DNAMolecularReactionTable.hh"
 34 #include "G4Timer.hh"
 35 #include "G4Scheduler.hh"
 36 #include "G4UserMeshAction.hh"
 37 #include "G4MoleculeCounter.hh"
 38 #include "G4DNAScavengerMaterial.hh"
 39 #include "G4Molecule.hh"
 40 
 41 G4DNAEventScheduler::G4DNAEventScheduler()
 42   : fpGillespieReaction(new G4DNAGillespieDirectMethod())
 43   , fpEventSet(new G4DNAEventSet())
 44   , fpUpdateSystem(new G4DNAUpdateSystemModel())
 45 {}
 46 
 47 void G4DNAEventScheduler::ClearAndReChargeCounter()
 48 {
 49   fCounterMap.clear();
 50   if(fTimeToRecord.empty())
 51   {
 52     G4String WarMessage = "fTimeToRecord is empty ";
 53     G4Exception("G4DNAEventScheduler::ClearAndReChargeCounter()",
 54                 "TimeToRecord is empty", JustWarning, WarMessage);
 55   }
 56   fLastRecoredTime = fTimeToRecord.begin();
 57 
 58   if(G4VMoleculeCounter::Instance()->InUse())  // copy from MoleculeCounter
 59   {
 60     G4MoleculeCounter::RecordedMolecules species;
 61     species = G4MoleculeCounter::Instance()->GetRecordedMolecules();
 62     if(species.get() == nullptr)
 63     {
 64       return;
 65     }
 66     if(species->empty())
 67     {
 68       G4MoleculeCounter::Instance()->ResetCounter();
 69       return;
 70     }
 71     for(auto time_mol : fTimeToRecord)
 72     {
 73       if(time_mol > fStartTime)
 74       {
 75         continue;
 76       }
 77 
 78       for(auto molecule : *species)
 79       {
 80         G4int n_mol = G4MoleculeCounter::Instance()->GetNMoleculesAtTime(
 81           molecule, time_mol);
 82 
 83         if(n_mol < 0)
 84         {
 85           G4cerr << "G4DNAEventScheduler::ClearAndReChargeCounter() ::N "
 86                     "molecules not valid < 0 "
 87                  << G4endl;
 88           G4Exception("", "N<0", FatalException, "");
 89         }
 90         fCounterMap[time_mol][molecule] = n_mol;
 91       }
 92       fLastRecoredTime++;
 93     }
 94     G4MoleculeCounter::Instance()->ResetCounter();  // reset
 95     G4MoleculeCounter::Instance()->Use(false);      // no more used
 96   }
 97   else
 98   {
 99     G4ExceptionDescription exceptionDescription;
100     exceptionDescription << "G4VMoleculeCounter is not used";
101     G4Exception("G4DNAEventScheduler::ClearAndReChargeCounter()",
102                 "G4DNAEventScheduler010", JustWarning, exceptionDescription);
103   }
104 }
105 
106 [[maybe_unused]] void G4DNAEventScheduler::AddTimeToRecord(const G4double& time)
107 {
108   if(fTimeToRecord.find(time) == fTimeToRecord.end())
109   {
110     fTimeToRecord.insert(time);
111   }
112 }
113 
114 G4DNAEventScheduler::~G4DNAEventScheduler() = default;
115 
116 void G4DNAEventScheduler::Voxelizing()
117 {
118   auto pMainList = G4ITTrackHolder::Instance()->GetMainList();
119   std::map<G4VDNAMesh::Index, MapList> TrackKeyMap;
120   for(auto track : *pMainList)
121   {
122     auto molType = GetMolecule(track)->GetMolecularConfiguration();
123 
124     auto pScavengerMaterial = dynamic_cast<G4DNAScavengerMaterial*>(
125       G4Scheduler::Instance()->GetScavengerMaterial());
126     if(pScavengerMaterial != nullptr &&
127        pScavengerMaterial->find(molType))  // avoid voxelize the scavenger
128     {
129       continue;
130     }
131 
132     auto key = fpMesh->GetIndex(track->GetPosition());
133     if(TrackKeyMap.find(key) != TrackKeyMap.end())
134     {
135       std::map<MolType, size_t>& TrackTypeMap = TrackKeyMap[key];
136       if(TrackTypeMap.find(molType) != TrackTypeMap.end())
137       {
138         TrackTypeMap[molType]++;
139       }
140       else
141       {
142         TrackTypeMap[molType] = 1;
143       }
144     }
145     else
146     {
147       TrackKeyMap[key][molType] = 1;
148     }
149   }
150 
151   for(auto& it : TrackKeyMap)
152   {
153     fpMesh->InitializeVoxel(it.first, std::move(it.second));
154   }
155 }
156 
157 void G4DNAEventScheduler::ReVoxelizing(G4int pixel)
158 {
159   fPixel       = pixel;
160   auto newMesh = new G4DNAMesh(fpMesh->GetBoundingBox(), fPixel);
161 
162   auto begin = fpMesh->begin();
163   auto end   = fpMesh->end();
164   std::map<G4VDNAMesh::Index, MapList> TrackKeyMap;
165   for(; begin != end; begin++)
166   {
167     auto index    = std::get<0>(*begin);
168     auto newIndex = fpMesh->ConvertIndex(index, fPixel);
169     if(TrackKeyMap.find(newIndex) == TrackKeyMap.end())
170     {
171       TrackKeyMap[newIndex] = std::get<2>(*begin);
172     }
173     else
174     {
175       for(const auto& it : std::get<2>(*begin))
176       {
177         TrackKeyMap[newIndex][it.first] += it.second;
178       }
179       if(fVerbose > 1)
180       {
181         G4cout << " ReVoxelizing:: Old index : " << index
182                << " new index : " << fpMesh->ConvertIndex(index, fPixel)
183                << " number: " << std::get<2>(*begin).begin()->second << G4endl;
184       }
185     }
186   }
187   fpMesh.reset(newMesh);
188 
189   for(auto& it : TrackKeyMap)
190   {
191     fpMesh->InitializeVoxel(it.first, std::move(it.second));
192   }
193 }
194 void G4DNAEventScheduler::Reset()
195 {
196   // find another solultion
197   fGlobalTime = fEndTime;
198 
199   //
200   LastRegisterForCounter();//Last register for counter
201 
202   if(fVerbose > 0)
203   {
204     G4cout << "End Processing and reset Gird, ScavengerTable, EventSet for new "
205               "simulation!!!!"
206            << G4endl;
207   }
208   fInitialized    = false;
209   fTimeStep       = 0;
210   fStepNumber     = 0;
211   fGlobalTime     = fStartTime;
212   fRunning        = true;
213   fReactionNumber = 0;
214   fJumpingNumber  = 0;
215 
216   fpEventSet->RemoveEventSet();
217   fpMesh->Reset();
218   fpGillespieReaction->ResetEquilibrium();
219 }
220 
221 void G4DNAEventScheduler::Initialize(const G4DNABoundingBox& boundingBox,
222                                      G4int pixel)
223 {
224   if(!fInitialized)
225   {
226     fPixel = pixel;
227     fpMesh = std::make_unique<G4DNAMesh>(boundingBox, pixel);
228 
229     if(!CheckingReactionRadius(fpMesh->GetResolution()))
230     {
231       G4String WarMessage = "resolution is not good : " +
232                             std::to_string(fpMesh->GetResolution() / nm);
233       G4Exception("G4DNAEventScheduler::InitializeInMesh()", "WrongResolution",
234                   JustWarning, WarMessage);
235     }
236 
237     // Scavenger();
238 
239     auto pScavengerMaterial = dynamic_cast<G4DNAScavengerMaterial*>(
240       G4Scheduler::Instance()->GetScavengerMaterial());
241     if(pScavengerMaterial == nullptr)
242     {
243       G4cout << "There is no scavenger" << G4endl;
244     }
245     else
246     {
247       if(fVerbose > 1)
248       {
249         pScavengerMaterial->PrintInfo();
250       }
251     }
252 
253     Voxelizing();
254     fpGillespieReaction->SetVoxelMesh(*fpMesh);
255     fpGillespieReaction->SetEventSet(fpEventSet.get());
256     fpGillespieReaction->SetTimeStep(0);// reset fTimeStep = 0 in fpGillespieReaction
257     fpGillespieReaction->Initialize();
258     fpGillespieReaction->CreateEvents();
259     fpUpdateSystem->SetMesh(fpMesh.get());
260     ClearAndReChargeCounter();
261     fInitialized = true;
262   }
263 
264   if(fVerbose > 0)
265   {
266     fpUpdateSystem->SetVerbose(1);
267   }
268 
269   if(fVerbose > 2)
270   {
271     fpMesh->PrintMesh();
272   }
273 }
274 void G4DNAEventScheduler::InitializeInMesh()
275 {
276   if(fPixel <= 1)
277   {
278     fRunning = false;
279     return;
280   }
281   // TEST /3
282   ReVoxelizing(fPixel / 2);  //
283   // ReVoxelizing(fPixel/3);//
284 
285   fpGillespieReaction->SetVoxelMesh(*fpMesh);
286   fpUpdateSystem->SetMesh(fpMesh.get());
287   fpGillespieReaction->CreateEvents();
288 }
289 
290 void G4DNAEventScheduler::ResetInMesh()
291 {
292   if(fVerbose > 0)
293   {
294     G4cout
295       << "*** End Processing In Mesh and reset Mesh, EventSet for new Mesh!!!!"
296       << G4endl;
297   }
298   fpEventSet->RemoveEventSet();
299   fInitialized      = false;
300   fIsChangeMesh     = false;
301   fReactionNumber   = 0;
302   fJumpingNumber    = 0;
303   fStepNumberInMesh = 0;
304 }
305 
306 G4double G4DNAEventScheduler::GetStartTime() const { return fStartTime; }
307 
308 G4double G4DNAEventScheduler::GetEndTime() const { return fEndTime; }
309 
310 [[maybe_unused]] G4double G4DNAEventScheduler::GetTimeStep() const
311 {
312   return fTimeStep;
313 }
314 
315 G4int G4DNAEventScheduler::GetVerbose() const { return fVerbose; }
316 
317 [[maybe_unused]] void G4DNAEventScheduler::SetMaxNbSteps(G4int max)
318 {
319   fMaxStep = max;
320 }
321 
322 [[maybe_unused]] void G4DNAEventScheduler::SetStartTime(G4double time)
323 {
324   fStartTime  = time;
325   fGlobalTime = fStartTime;
326 }
327 
328 void G4DNAEventScheduler::Stop() { fRunning = false; }
329 void G4DNAEventScheduler::Run()
330 {
331   G4Timer localtimer;
332   if(fVerbose > 2)
333   {
334     localtimer.Start();
335     G4cout << "***G4DNAEventScheduler::Run*** for Pixel : " << fPixel << G4endl;
336   }
337   while(fEndTime > fGlobalTime && fRunning)
338   {
339     RunInMesh();
340   }
341   if(fVerbose > 2)
342   {
343     if(!fRunning)
344     {
345       G4cout << " StepNumber(" << fStepNumber << ") = MaxStep(" << fMaxStep
346              << ")" << G4endl;
347     }
348     else if(fEndTime <= fGlobalTime)
349     {
350       G4cout << " GlobalTime(" << fGlobalTime << ") > EndTime(" << fEndTime
351              << ")"
352              << " StepNumber : " << fStepNumber << G4endl;
353     }
354     localtimer.Stop();
355     G4cout << "***G4DNAEventScheduler::Ending::"
356            << G4BestUnit(fGlobalTime, "Time")
357            << " Events left : " << fpEventSet->size() << G4endl;
358     if(fVerbose > 1)
359     {
360       fpMesh->PrintMesh();
361     }
362     G4cout << " Computing Time : " << localtimer << G4endl;
363   }
364   Reset();
365 }
366 
367 void G4DNAEventScheduler::RunInMesh()
368 {
369   if(!fInitialized)
370   {
371     InitializeInMesh();
372   }
373   if(fVerbose > 0)
374   {
375     G4double resolution = fpMesh->GetResolution();
376     G4cout << "At Time : " << std::setw(7) << G4BestUnit(fGlobalTime, "Time")
377            << " the Mesh has " << fPixel << " x " << fPixel << " x " << fPixel
378            << " voxels with Resolution " << G4BestUnit(resolution, "Length")
379            << " during next "
380            << G4BestUnit(resolution * resolution * C / (6 * D), "Time")
381            << G4endl;
382   }
383 
384   if(fVerbose > 2)
385   {
386     fpMesh->PrintMesh();
387   }
388 
389   if(fpUserMeshAction != nullptr)
390   {
391     fpUserMeshAction->BeginOfMesh(fpMesh.get(), fGlobalTime);
392   }
393 
394   // if diffusive jumping is avaiable, EventSet is never empty
395 
396   while(!fpEventSet->Empty() && !fIsChangeMesh && fEndTime > fGlobalTime)
397   {
398     Stepping();
399     fGlobalTime = fTimeStep + fStartTime;
400 
401     if(fpUserMeshAction != nullptr)
402     {
403       fpUserMeshAction->InMesh(fpMesh.get(), fGlobalTime);
404     }
405 
406     if(fVerbose > 2)
407     {
408       G4cout << "fGlobalTime : " << G4BestUnit(fGlobalTime, "Time")
409              << " fTimeStep : " << G4BestUnit(fTimeStep, "Time") << G4endl;
410     }
411     G4double resolution = fpMesh->GetResolution();
412     fTransferTime       = resolution * resolution * C / (6 * D);
413     if(fTransferTime == 0)
414     {
415       G4ExceptionDescription exceptionDescription;
416       exceptionDescription << "fTransferTime == 0";
417       G4Exception("G4DNAEventScheduler::RunInMesh", "G4DNAEventScheduler001",
418                   FatalErrorInArgument, exceptionDescription);
419     }
420     if(fTransferTime < fTimeStep &&
421        fPixel != 1)  // dont change Mesh if fPixel == 1
422     {
423       if(fSetChangeMesh)
424       {
425         if(fVerbose > 1)
426         {
427           G4cout << " Pixels : " << fPixel << "  resolution : "
428                  << G4BestUnit(fpMesh->GetResolution(), "Length")
429                  << "  fStepNumberInMesh : " << fStepNumberInMesh
430                  << " at fGlobalTime : " << G4BestUnit(fGlobalTime, "Time")
431                  << " at fTimeStep : " << G4BestUnit(fTimeStep, "Time")
432                  << "  fReactionNumber : " << fReactionNumber
433                  << " transferTime : " << G4BestUnit(fTransferTime, "Time")
434                  << G4endl;
435         }
436         fIsChangeMesh = true;
437       }
438     }
439   }
440 
441   if(fVerbose > 1)
442   {
443     G4cout << "***G4DNAEventScheduler::Ending::"
444            << G4BestUnit(fGlobalTime, "Time")
445            << " Event left : " << fpEventSet->size() << G4endl;
446     G4cout << " Due to : ";
447     if(fpEventSet->Empty())
448     {
449       G4cout << "EventSet is Empty" << G4endl;
450     }
451     else if(fIsChangeMesh)
452     {
453       G4cout << "Changing Mesh from : " << fPixel
454              << " pixels to : " << fPixel / 2 << " pixels" << G4endl;
455       G4cout << "Info : ReactionNumber : " << fReactionNumber
456              << "   JumpingNumber : " << fJumpingNumber << G4endl;
457     }
458     else if(fEndTime > fGlobalTime)
459     {
460       G4cout << " GlobalTime(" << fGlobalTime << ") > EndTime(" << fEndTime
461              << ")"
462              << " StepNumber : " << fStepNumber << G4endl;
463     }
464     if(fVerbose > 2)
465     {
466       fpMesh->PrintMesh();
467     }
468     G4cout << G4endl;
469   }
470 
471   if(fpUserMeshAction != nullptr)
472   {
473     fpUserMeshAction->EndOfMesh(fpMesh.get(), fGlobalTime);
474   }
475   ResetInMesh();
476 }
477 
478 void G4DNAEventScheduler::Stepping()  // this event loop
479 {
480   fStepNumber < fMaxStep ? fStepNumber++ : static_cast<int>(fRunning = false);
481   if(fpEventSet->size() > fpMesh->size())
482   {
483     G4ExceptionDescription exceptionDescription;
484     exceptionDescription
485       << "impossible that fpEventSet->size() > fpMesh->size()";
486     G4Exception("G4DNAEventScheduler::Stepping", "G4DNAEventScheduler002",
487                 FatalErrorInArgument, exceptionDescription);
488   }
489 
490   auto selected = fpEventSet->begin();
491   auto index    = (*selected)->GetIndex();
492 
493   if(fVerbose > 1)
494   {
495     G4cout << "G4DNAEventScheduler::Stepping()*********************************"
496               "*******"
497            << G4endl;
498     (*selected)->PrintEvent();
499   }
500 
501   // get selected time step
502   fTimeStep = (*selected)->GetTime();
503 
504   // selected data
505   auto pJumping  = (*selected)->GetJumpingData();
506   auto pReaction = (*selected)->GetReactionData();
507 
508   fpUpdateSystem->SetGlobalTime(fTimeStep +
509                                 fStartTime);  // this is just for printing
510   fpGillespieReaction->SetTimeStep(fTimeStep);
511   if(pJumping == nullptr && pReaction != nullptr)
512   {
513     fpUpdateSystem->UpdateSystem(index, *pReaction);
514     fpEventSet->RemoveEvent(selected);
515 
516     //hoang's exp
517     if(fpGillespieReaction->SetEquilibrium(pReaction))
518     {
519       ResetEventSet();
520     }
521     //end Hoang's exp
522 
523     // create new event
524     fpGillespieReaction->CreateEvent(index);
525     fReactionNumber++;
526     // recordTime in reaction
527     RecordTime();
528   }
529   else if(pJumping != nullptr && pReaction == nullptr)
530   {
531     // dont change this
532     fpUpdateSystem->UpdateSystem(index, *pJumping);
533     // save jumping Index before delete selected event
534     auto jumpingIndex = pJumping->second;
535     fpEventSet->RemoveEvent(selected);
536     // create new event
537     // should create Jumping before key
538     fpGillespieReaction->CreateEvent(jumpingIndex);
539     fpGillespieReaction->CreateEvent(index);
540     fJumpingNumber++;
541   }
542   else
543   {
544     G4ExceptionDescription exceptionDescription;
545     exceptionDescription << "pJumping == nullptr && pReaction == nullptr";
546     G4Exception("G4DNAEventScheduler::Stepping", "G4DNAEventScheduler003",
547                 FatalErrorInArgument, exceptionDescription);
548   }
549 
550   if(fVerbose > 1)
551   {
552     G4cout << "G4DNAEventScheduler::Stepping::end "
553               "Print***********************************"
554            << G4endl;
555     G4cout << G4endl;
556   }
557   fStepNumberInMesh++;
558 }
559 
560 void G4DNAEventScheduler::SetEndTime(const G4double& endTime)
561 {
562   fEndTime = endTime;
563 }
564 
565 void G4DNAEventScheduler::RecordTime()
566 {
567   auto recordTime = *fLastRecoredTime;
568   if(fGlobalTime >= recordTime && fCounterMap[recordTime].empty())
569   {
570     auto begin = fpMesh->begin();
571     auto end   = fpMesh->end();
572     for(; begin != end; begin++)
573     {
574       const auto& mapData = std::get<2>(*begin);
575       if(mapData.empty())
576       {
577         continue;
578       }
579       for(const auto& it : mapData)
580       {
581         fCounterMap[recordTime][it.first] += it.second;
582       }
583     }
584     fLastRecoredTime++;
585   }
586 }
587 
588 void G4DNAEventScheduler::PrintRecordTime()
589 {
590   G4cout << "CounterMap.size : " << fCounterMap.size() << G4endl;
591   for(const auto& i : fCounterMap)
592   {
593     auto map   = i.second;
594     auto begin = map.begin();  //
595     auto end   = map.end();    //
596     for(; begin != end; begin++)
597     {
598       auto molecule = begin->first;
599       auto number   = begin->second;
600       if(number == 0)
601       {
602         continue;
603       }
604       G4cout << "molecule : " << molecule->GetName() << " number : " << number
605              << G4endl;
606     }
607   }
608 }
609 
610 std::map<G4double /*time*/, G4DNAEventScheduler::MapCounter>
611 G4DNAEventScheduler::GetCounterMap() const
612 {
613   return fCounterMap;
614 }
615 
616 void G4DNAEventScheduler::SetUserMeshAction(
617   std::unique_ptr<G4UserMeshAction> pUserMeshAction)
618 {
619   fpUserMeshAction = std::move(pUserMeshAction);
620 }
621 
622 G4DNAMesh* G4DNAEventScheduler::GetMesh() const { return fpMesh.get(); }
623 
624 G4int G4DNAEventScheduler::GetPixels() const { return fPixel; }
625 
626 G4bool G4DNAEventScheduler::CheckingReactionRadius(G4double resolution)
627 {
628   auto pMolecularReactionTable = G4DNAMolecularReactionTable::Instance();
629   auto reactionDataList = pMolecularReactionTable->GetVectorOfReactionData();
630   if(reactionDataList.empty())
631   {
632     G4cout << "reactionDataList.empty()" << G4endl;
633     return true;
634   }
635   
636   for(auto it : reactionDataList)
637   {
638     if(it->GetEffectiveReactionRadius() >= resolution / CLHEP::pi)
639     {
640       G4cout << it->GetReactant1()->GetName() << " + "
641              << it->GetReactant2()->GetName() << G4endl;
642       G4cout << "G4DNAEventScheduler::ReactionRadius : "
643              << G4BestUnit(it->GetEffectiveReactionRadius(), "Length")
644              << G4endl;
645       G4cout << "resolution : " << G4BestUnit(resolution, "Length") << G4endl;
646       return false;
647     }
648   }
649   return true;
650 }
651 
652 void G4DNAEventScheduler::ResetEventSet()
653 {
654   fpEventSet->RemoveEventSet();
655   fpGillespieReaction->CreateEvents();
656 }
657 
658 void G4DNAEventScheduler::LastRegisterForCounter()
659 {
660   if(fLastRecoredTime == fTimeToRecord.end())
661   {
662     //fully recorded -> happy ending
663     return;
664   }else
665   {
666     auto lastRecorded = --fLastRecoredTime;//fixed
667     while (fLastRecoredTime != fTimeToRecord.end())
668     {
669       fCounterMap[*fLastRecoredTime] = fCounterMap[*lastRecorded];
670       fLastRecoredTime++;
671     }
672   }
673 
674 }