ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ITTrackHolder.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4ITTrackHolder.cc
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  * G4MIMolecularTracks.cc
28  *
29  * Created on: 17 sept. 2014
30  * Author: kara
31  */
32 
33 #include <G4Scheduler.hh>
34 #include <G4VScheduler.hh>
35 #include "G4ITTrackHolder.hh"
36 #include "G4IT.hh"
37 #include "G4Track.hh"
38 #include "G4UnitsTable.hh"
39 #include "G4AutoLock.hh"
40 #include "G4Threading.hh"
41 
42 using namespace std;
43 
45  G4TrackList::Watcher(), fpMainList(0), fpWaitingList(0)
46 {
47 }
48 
50  G4TrackList::Watcher(), fpMainList(0), fpWaitingList(0)
51 {
52  NewMainList(allMainList);
53 }
54 
56  G4TrackList::Watcher(),
57  fpMainList(right.fpMainList),
58  fpWaitingList(right.fpWaitingList)
59 {
60 }
61 
63 {
64  if (fpMainList)
65  {
66  delete fpMainList;
67  fpMainList = 0;
68  }
69  if (fpWaitingList)
70  {
71  delete fpWaitingList;
72  fpWaitingList = 0;
73  }
74 }
75 
77 {
78  if (__list == fpMainList)
79  {
80 // StopWatching(fpMainList);
81  fpMainList = 0;
82  }
83  else if (__list == fpWaitingList)
84  {
85 // StopWatching(fpWaitingList);
86  fpWaitingList = 0;
87  }
88 }
89 
91  G4TrackManyList& allMainList)
92 {
93  fpMainList = __list;
94  allMainList.Add(__list);
96 }
97 
99 {
100  G4TrackList* trackList = new G4TrackList();
101  NewMainList(trackList, allMainList);
102  return fpMainList;
103 }
104 
106  G4TrackManyList& allMainList)
107 {
108  if (fpMainList == 0)
109  {
110  NewMainList(allMainList);
111  }
112  fpMainList->push_back(__track);
113 }
114 
116  G4TrackManyList& allMainList)
117 {
118  if (fpMainList)
119  {
120  __list->transferTo(fpMainList);
121  delete __list;
122  __list = 0;
123  }
124  else
125  {
126  NewMainList(__list, allMainList);
127  }
128 }
129 
131  G4TrackManyList& listOfAllSecondaries)
132 {
133  // if (priorityList->fSecondaries.empty())
135  {
136  listOfAllSecondaries.Add(&fSecondaries);
137  }
138  fSecondaries.push_back(__track);
139 }
140 
142 {
143  if (fpWaitingList == 0)
144  {
145  fpWaitingList = new G4TrackList();
146  }
147  fpWaitingList->push_back(__track);
148 }
149 
151 {
153 }
154 
156 {
157  if (fpMainList == 0) fpMainList = new G4TrackList();
158  fpMainList->push_back(track);
159 }
160 
162 {
163  if (fpMainList == 0) fpMainList = new G4TrackList();
164  trackList->transferTo(trackList);
165 }
166 
168 {
169  int nTracks = 0;
170 
171  if (fpMainList)
172  {
173  nTracks += fpMainList->size();
174  }
175 
176  if (fpWaitingList)
177  {
178  nTracks += fpWaitingList->size();
179  }
180 
181  nTracks += fSecondaries.size();
182 
183  return nTracks;
184 }
185 
186 //=============================================================================
187 // G4ITTrackHolder
188 //=============================================================================
189 
192 
195 
197 {
198  if (fgInstance == 0)
199  {
200  fgInstance = new G4ITTrackHolder();
203  )
204  {
206  }
207 
208  }
209  return fgInstance;
210 }
211 
213 {
215  if (fgMasterInstance == 0)
216  {
218  }
219  lock.unlock();
220  return fgMasterInstance;
221 }
222 
225 {
226  fNbTracks = -1;
227  fMainListHaveBeenSet = false;
228  fVerbose = 0;
229 
231 // fPreActivityGlobalTime = -1;
232 }
233 
235 {
236  std::map<Key, PriorityList*>::iterator end = fLists.end();
237 
238  for (std::map<Key, PriorityList*>::iterator it = fLists.begin(); it != end;
239  it++)
240  {
241  delete it->second;
242  it->second = 0;
243  }
244 
245  if (!fDelayedList.empty())
246  {
247  MapOfDelayedLists::iterator fDelayedList_i = fDelayedList.begin();
248  MapOfDelayedLists::iterator fDelayedList_end = fDelayedList.end();
249 
250  for (; fDelayedList_i != fDelayedList_end; fDelayedList_i++)
251  {
252  std::map<Key, G4TrackList*>::iterator it = fDelayedList_i->second.begin();
253  std::map<Key, G4TrackList*>::iterator __end =
254  fDelayedList_i->second.end();
255 
256  for (; it != __end; it++)
257  {
258  if (it->second) delete (it->second);
259  it->second = 0;
260  }
261  }
262  fDelayedList.clear();
263  }
264 
267  fNbTracks = -1;
268 }
269 
270 /*
271  void G4MIMolecularTracks::Decide()
272  {
273  cout << "G4MIMolecularTracks::Decide" << endl;
274 
275  if (fDelayedList.empty())
276  {
277  cout << "fDelayedList.empty()" << endl;
278  return;
279  }
280  fPostActivityGlobalTime = GetNextTime();
281  // PushActivity(workspace->GetScheduler(), this);
282  }
283  */
284 
285 /*
286  * param time = time of the merged list
287  * returned = was there actually merged data ?
288  */
290 {
291 // G4cout << "G4ITTrackHolder::MergeNextTimeToMainList" << G4endl;
292  if (fDelayedList.empty())
293  {
294  return false;
295  }
296 
297 // G4cout << "fDelayedList.size = " << fDelayedList.size() <<G4endl;
298 
299  std::map<Key, G4TrackList*>::iterator it =
300  fDelayedList.begin()->second.begin();
301  std::map<Key, G4TrackList*>::iterator end =
302  fDelayedList.begin()->second.end();
303  if (it == end) return false;
304 
305  bool output = false;
306  for (; it != end; it++)
307  {
308  PriorityList* right_listUnion(0);
309 
310  std::map<Key, PriorityList*>::iterator it_listUnion = fLists.find(
311  it->first);
312  if (it_listUnion == fLists.end())
313  {
314  right_listUnion = (fLists[it->first] = new PriorityList());
315  }
316  else
317  {
318  if (it_listUnion->second == 0)
319  {
320  it_listUnion->second = new PriorityList();
321  }
322  right_listUnion = it_listUnion->second;
323  }
324 
325  if (it->second == 0) continue;
326 
327  /*
328  if (right_listUnion->GetMainList() == 0)
329  {
330  // right_listUnion->fpMainList = new G4TrackList();
331  // if(it->second)
332  // {
333  right_listUnion->NewMainList(it->second, fAllMainList);
334  // }
335  }
336  else
337  {
338  right_listUnion->TransferToMainList(it->second);
339  delete it->second;
340  }*/
341 
342  right_listUnion->TransferToMainList(it->second, fAllMainList);
343 
344  if (output == false)
345  {
346  if (right_listUnion->GetMainList()->size())
347  {
348  output = true;
349  }
350  }
351  it->second = 0;
352  }
353 
354  if (output) time = fDelayedList.begin()->first;
355  fDelayedList.erase(fDelayedList.begin());
356  return output;
357 }
358 
360 {
361  std::map<Key, PriorityList*>::iterator it = fLists.begin();
362  std::map<Key, PriorityList*>::iterator end = fLists.end();
363 
364  for (; it != end; it++)
365  {
366  if (it->second->GetMainList() == 0)
367  {
368  it->second->NewMainList(fAllMainList);
369  }
370 
371  it->second->TransferSecondariesToMainList();
372  }
373 }
374 
375 //_________________________________________________________________________
376 
378 {
379  //if(fNbTracks == 0) fNbTracks = -1;
380  track->SetTrackID(fNbTracks);
381  fNbTracks--;
382 }
383 
384 //_________________________________________________________________________
385 
387 {
388 // if (G4VScheduler::Instance()->IsRunning())
389 // {
390 // G4ExceptionDescription exceptionDescription;
391 // exceptionDescription
392 // << "G4ITTrackHolder::PushTrack : You are trying to push tracks while the "
393 // "ITStepManager is running";
394 // G4Exception("G4ITTrackHolder::PushTrack", "ITStepManager012",
395 // FatalErrorInArgument, exceptionDescription);
396 // }
397  _PushTrack(track);
398 
399 // G4MIConstituent::NotifyEntityAdded(track);
400 }
401 //_________________________________________________________________________
403 {
404  int moleculeID = GetIT(track)->GetITSubType();
405  std::map<Key, PriorityList*>::iterator it = fLists.find(moleculeID);
406 
407  PriorityList* priorityList(0);
408 
409  if (it == fLists.end())
410  {
411  priorityList = new PriorityList(fAllMainList);
412  fLists[moleculeID] = priorityList;
413  }
414  else
415  {
416  priorityList = it->second;
417  }
418 
419  switch (type)
420  {
422  {
423  priorityList->PushToMainList(track, fAllMainList);
424  break;
425  }
427  {
428  priorityList->PushToListOfSecondaries(track, fAllSecondariesList);
429  break;
430  }
432  {
433  priorityList->PushToWaitingList(track);
434  return;
435  break;
436  }
437 
438  default:
439  {
440  return;
441  break;
442  }
443  }
444 }
445 //_________________________________________________________________________
446 
448 {
449  if (track == 0)
450  {
451  G4ExceptionDescription exceptionDescription;
452  exceptionDescription
453  << "You are trying to push a non-existing track (track pointer is null)"
454  << G4endl;
455 
456  G4Exception("G4ITTrackHolder::_PushTrack", "ITStepManager014",
457  FatalErrorInArgument, exceptionDescription);
458  }
459 
460  G4double globalTime = track->GetGlobalTime();
461 
462  if (track->GetTrackID() == 0)
463  {
464  // Set track ID
465  AddTrackID(track);
466  }
467 
468  double currentGlobalTime = G4Scheduler::Instance()->GetGlobalTime();
469 
470 #ifdef G4VERBOSE
471  if (fVerbose)
472  {
473  G4cout << G4endl;
474  G4cout << "\t"<< ">> Pushing a track --> ";
475  G4cout << GetIT(track)->GetName() << " (" << track->GetTrackID() <<")"
476  << " -- ";
477  G4cout << "Global current time: " << G4BestUnit(currentGlobalTime,"Time")
478  << "\t";
479  G4cout << "Track's time: " << G4BestUnit(track->GetGlobalTime(),"Time")
480  << G4endl;
481  }
482 #endif
483 
484  if (G4Scheduler::Instance()->IsRunning() == false)
485  {
486  if (globalTime < currentGlobalTime)
487  {
488  G4ExceptionDescription exceptionDescription;
489  exceptionDescription
490  << "You are trying to push a track with a global time"
491  << " inferior to the current simulation time." << G4endl<< "The time is going back : " << G4endl
492  << "The time in the step manager : "
493  << G4BestUnit(currentGlobalTime,"Time")
494  << G4endl
495  << "The time of the track : "
496  << G4BestUnit(globalTime,"Time")
497  << G4endl
498  << "(ITStepManager is not yet running)"
499  << G4endl;
500 
501  G4Exception("G4ITTrackHolder::_PushTrack", "ITStepManager014",
502  FatalErrorInArgument, exceptionDescription);
503  }
504 
505  // Push the track to the rigth track list :
506  // If the track time is the same as the main track list,
507  // it will be push to the main track list
508  // otherwise, it will be pushed to the delayed track list.
509  if (fMainListHaveBeenSet == false)
510  {
511  PushDelayed(track);
512  }
513  else
514  {
515  if (globalTime == currentGlobalTime)
516  {
517  #ifdef G4VERBOSE
518  if (fVerbose)
519  {
520  G4cout << G4endl;
521  G4cout << "\t"<< ">> Pushing to *main* list --> ";
522  G4cout << GetIT(track)->GetName() << " (" << track->GetTrackID() <<")"
523  << " -- ";
524  G4cout << "Global current time: " << G4BestUnit(currentGlobalTime,"Time")
525  << "\t";
526  G4cout << "Track's time: " << G4BestUnit(track->GetGlobalTime(),"Time")
527  << G4endl;
528  }
529  #endif
531  }
532  else
533  {
534  // if(currentGlobalTime > 1*CLHEP::picosecond) abort();
535  #ifdef G4VERBOSE
536  if (fVerbose)
537  {
538  G4cout << G4endl;
539  G4cout << "\t"<< ">> Pushing to *delayed* list --> ";
540  G4cout << GetIT(track)->GetName() << " (" << track->GetTrackID() <<")"
541  << " -- ";
542  G4cout << "Global current time: " << G4BestUnit(currentGlobalTime,"Time")
543  << "\t";
544  G4cout << "Track's time: " << G4BestUnit(track->GetGlobalTime(),"Time")
545  << G4endl;
546  }
547  #endif
548  PushDelayed(track);
549  }
550  }
551  }
552  else // Is running
553  {
554  double timeDifference = globalTime - currentGlobalTime;
555  double timeTolerance = G4Scheduler::Instance()->GetTimeTolerance();
556 
557  if (timeDifference < -1 * timeTolerance)
558  {
559  G4ExceptionDescription exceptionDescription;
560  exceptionDescription
561  << "You are trying to push a track with a global time"
562  << " inferior to the current simulation time." << G4endl<< "The time is going back : "
563  << G4endl
564  << "The time in the step manager : "
565  << G4BestUnit(timeDifference,"Time")
566  << G4endl
567  << "The time of the track : " << G4BestUnit(globalTime,"Time")
568  << G4endl
569  << "(ITStepManager is running)"
570  << G4endl;
571 
572  G4Exception("G4ITTrackHolder::_PushTrack", "ITStepManager015",
573  FatalErrorInArgument, exceptionDescription);
574  }
575 
576  // Push the track to the rigth track list :
577  // If the track time is the same as the main track list,
578  // it will be push to the secondary list
579  // otherwise, it will be pushed to the delayed track list.
580  if (fabs(timeDifference) < timeTolerance)
581  {
582 // G4cout << "Is pushing " << GetIT(track)->GetName() << G4endl;
583 
584  #ifdef G4VERBOSE
585  if (fVerbose)
586  {
587  G4cout << G4endl;
588  G4cout << "\t"<< ">> Pushing to *secondary* list --> ";
589  G4cout << GetIT(track)->GetName() << " (" << track->GetTrackID() <<")"
590  << " -- ";
591  G4cout << "Global current time: " << G4BestUnit(currentGlobalTime,"Time")
592  << "\t";
593  G4cout << "Track's time: " << G4BestUnit(track->GetGlobalTime(),"Time")
594  << G4endl;
595  }
596  #endif
598  }
599  else // globalTime < fGlobalTime already taken into account above
600  {
601  G4ExceptionDescription exceptionDescription;
602  exceptionDescription
603  << "While running you cannot push a track"
604  << " with a bigger global time than the current global time" << G4endl<< "The time in the step manager : "
605  << G4BestUnit(currentGlobalTime,"Time")
606  << G4endl
607  << "The time of the track : " << G4BestUnit(globalTime,"Time")
608  << G4endl
609  << "(ITStepManager is running)"
610  << G4endl;
611 
612  G4Exception("G4ITTrackHolder::_PushTrack", "ITStepManager016",
613  FatalErrorInArgument, exceptionDescription);
614  // PushDelayed(track, globalTime);
615  }
616  }
617 }
618 
619 //_________________________________________________________________________
620 
622 {
623 #ifdef G4VERBOSE
624  if (fVerbose)
625  {
626  G4cout << "\t" << ">> Pushing a delayed track" << G4endl;
627  }
628 #endif
629 
630  int moleculeID = GetIT(track)->GetITSubType();
631  // std::map<int, PriorityList>::iterator it = fLists.find(moleculeID);
632 
633  G4double globalTime = track->GetGlobalTime();
634 
635  std::map<double, std::map<Key, G4TrackList*> >::iterator it_delayed =
636  fDelayedList.find(globalTime);
637 
638  if (it_delayed == fDelayedList.end())
639  {
640  (fDelayedList[globalTime][moleculeID] = new G4TrackList())->push_back(
641  track);
642  }
643  else
644  {
645  std::map<Key, G4TrackList*>::iterator it_trackList =
646  it_delayed->second.find(moleculeID);
647 
648  if (it_trackList == it_delayed->second.end())
649  {
650  (it_delayed->second[moleculeID] = new G4TrackList())->push_back(track);
651  }
652  else
653  {
654  if (it_trackList->second != 0)
655  {
656  it_trackList->second->push_back(track);
657  }
658  }
659  }
660 
661  // fDelayedList[globalTime][moleculeID]
662 
663  /*
664  std::map<double,std::map<int, G4TrackList* > >::iterator it_delayed =
665  fDelayedList.begin();
666 
667  std::map<double,std::map<int, G4TrackList* > >::iterator end_delayed =
668  fDelayedList.end();
669 
670  for(it_delayed != end_delayed ; it_delayed++)
671  {
672  std::map<int, G4TrackList*> & trackListMap = it->second;
673 
674 
675  }
676  */
677  /*
678  std::map<double,G4TrackList* > :: iterator
679  fDelayedList_i = fDelayedList.find(globalTime) ;
680 
681  if(fDelayedList_i == fDelayedList.end())
682  {
683 
684  G4TrackList* newList = new G4TrackList ;
685  newList -> push_back(track);
686  fDelayedList[globalTime] = newList ;
687  }
688  else
689  {
690  fDelayedList_i->second-> push_back(track);
691  }
692  */
693 }
694 //______________________________________________________________________________
695 
697 {
698  if (fToBeKilledList.size() == 0) return;
699 #ifdef G4VERBOSE
700  if (fVerbose > 1)
701  {
702  G4cout << "*** G4ITTrackHolder::KillTracks , step #"
704  << " ***" << G4endl;
705  G4cout << "Nb of tracks to kill "<< fToBeKilledList.size() << G4endl;
706  G4cout << setw(25) << left << "#Name"
707  << setw(25) << "track ID"<< G4endl;
708 
710  for(; it != fToBeKilledList.end();)
711  {
712  G4Track* toBeErased = *it;
713 
714  G4cout << setw(25) << GetIT(toBeErased)->GetName()
715  << setw(25) << toBeErased->GetTrackID()
716  << G4endl;
717 
718  it = fToBeKilledList.erase(toBeErased);
719  }
720  }
721  else
722 #endif
724 }
725 
727 {
730 // fAllMainList.RemoveLists();
731 // fAllSecondariesList.RemoveLists();
732 
733  std::map<Key, PriorityList*>::iterator it = fLists.begin();
734 
735  for (; it != fLists.end(); it++)
736  {
737  if (it->second) delete it->second;
738  it->second = 0;
739  }
740  fLists.clear();
741 
742  MapOfDelayedLists::iterator it1 = fDelayedList.begin();
743 
744  for (; it1 != fDelayedList.end(); it1++)
745  {
746  std::map<Key, G4TrackList*>::iterator it2 = it1->second.begin();
747 
748  for (; it2 != it1->second.end(); it2++)
749  {
750  if (it2->second) delete it2->second;
751  it2->second = 0;
752  }
753  }
754 
755  fDelayedList.clear();
756 
757 // fAllMainList.ClearLists();
758 // fAllSecondariesList.ClearLists();
761  KillTracks();
762 
763  fNbTracks = -1;
764 }
765 
767 {
768  std::map<Key, PriorityList*>::iterator it = fLists.find(i);
769  if (it == fLists.end()) return 0;
770  return it->second;
771 }
772 
774 {
775  PriorityList* priorityList = GetPriorityList(i);
776  if (priorityList)
777  {
778  return priorityList->GetMainList();
779  }
780  return 0;
781 }
782 
784  G4TrackList::Watcher* watcher,
785  PriorityList::Type type)
786 {
787  std::map<Key, PriorityList*>::iterator it = fLists.find(id);
788  if (it == fLists.end()) return false;
789 
790  G4TrackList* trackList = it->second->Get(type);
791  if (trackList == 0) return false;
792  trackList->AddWatcher(watcher);
793  return true;
794 }
795 
796 void G4ITTrackHolder::AddWatcherForMainList(G4TrackList::Watcher* watcher)
797 {
799 }
800 
801 void G4ITTrackHolder::AddWatcherForKillList(G4TrackList::Watcher* watcher)
802 {
803  watcher->Watch(&fToBeKilledList);
804 }
805 
807 {
808  G4ITTrackHolder* trackHolder = MasterInstance();
809 
811  trackHolder->PushDelayed(track);
812  lock.unlock();
813 }
814 
816 {
817  size_t nTracks(0);
818  nTracks += fAllMainList.size();
819  nTracks += fAllSecondariesList.size();
820 
821  // G4cout << "nTracks = " << nTracks << G4endl;
822 
823  MapOfDelayedLists::iterator delayedmap_it = fDelayedList.begin();
824  MapOfDelayedLists::iterator delayedmap_end = fDelayedList.end();
825 
826  for (; delayedmap_it != delayedmap_end; delayedmap_it++)
827  {
828  std::map<Key, G4TrackList*>::iterator it = delayedmap_it->second.begin();
829  std::map<Key, G4TrackList*>::iterator end = delayedmap_it->second.end();
830 
831  for (; it != end; it++)
832  {
833  if (it->second) nTracks += it->second->size();
834  }
835  }
836 
837  // G4cout << "nTracks = " << nTracks << G4endl;
838 
839  return nTracks;
840 }
841 
843 {
844  MapOfPriorityLists::iterator it = fLists.begin();
845  MapOfPriorityLists::iterator end = fLists.end();
846  for (; it != end; it++)
847  {
848  if (PriorityList* lists = it->second)
849  {
850  lists->SetWaitingList(lists->GetMainList());
851  //TODO
852  }
853  }
855 }
856 
858 {
859  MapOfDelayedLists::iterator __it = fDelayedList.begin();
860  MapOfDelayedLists::iterator __end = fDelayedList.end();
861  for (; __it != __end; __it++)
862  {
863  std::map<Key, G4TrackList*>& mapOfLists = __it->second;
864  if (mapOfLists.empty() == false)
865  {
866  std::map<Key, G4TrackList*>::iterator it = mapOfLists.begin();
867  std::map<Key, G4TrackList*>::iterator end = mapOfLists.end();
868  for (; it != end; it++)
869  {
870  if (G4TrackList* mainList = it->second)
871  {
872  if (!(mainList->empty())) return true;
873  }
874  }
875  }
876  }
877  return false;
878 }
879 
881  PriorityList::Type type)
882 {
883  MapOfPriorityLists::iterator it = mapOfLists.begin();
884  MapOfPriorityLists::iterator end = mapOfLists.end();
885  for (; it != end; it++)
886  {
887  if (PriorityList* lists = it->second)
888  {
889  if (G4TrackList* trackList = lists->Get(type))
890  {
891  if (!(trackList->empty())) return true;
892  }
893  }
894  }
895  return false;
896 }