ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RunActionMaster.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file RunActionMaster.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 //
29 
30 #include "G4MPImanager.hh"
31 #include <stdio.h>
32 #include "G4Threading.hh"
33 #include "Analysis.hh"
34 #include "RunActionMaster.hh"
35 #include "g4root.hh" //ROOT Format for output
36 #include "RunMerger.hh"
37 #include "G4MPIscorerMerger.hh"
38 #include "G4MPIhistoMerger.hh" // New code with use of g4analysis
39 #include "Run.hh"
40 
41 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
43 {
44 }
45 
46 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
48 {
49  return new Run;
50 }
51 
52 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
54 {
55 }
56 
57 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
58 void
60 {
62  myana-> Clear();
63  myana->Book();
64 }
65 
66 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
67 void
69 {
70  //This is executed by master thread only. Worker threads have already
71  //merged their results into this master threads.
72 
73  //We are going to merge the results via MPI for:
74  // 1. User-defined "Run" object
75  // 2. Command line scorers, if exists
76  // 3. G4Analysis objects
77 
78  // For debugging purposes in the following we write out results twice:
79  // BEFORE and AFTER the merging, so that rank 0 actually
80  // writes two files, the one called "*rank000*" will contain the partial
81  // results only from rank #0,
82  // the file *merged* contains the reduction from all ranks.
83  // It should be very easy to adapt this code
84 
85  const G4int rank = G4MPImanager::GetManager()-> GetRank();
86 
87  G4cout << "=====================================================" << G4endl;
88  G4cout << "Start EndOfRunAction for master thread in rank: " << rank<<G4endl;
89  G4cout << "=====================================================" << G4endl;
90 
91  //Merging of G4Run object:
92  //All ranks > 0 merge to rank #0
93  RunMerger rm(static_cast<const Run*>(arun));
94  G4int ver = 0 ; //Use 4 for lots of info
95  if ( rank == 0 && ver == 0) ver = 1;
96 
97  if ( ver > 1 ) {
98  G4cout<<"Before merge the Run object has test counter value: "
99  <<static_cast<const Run*>(arun)->GetCounter()<<G4endl;
100  }
101  rm.SetVerbosity( ver );
102  rm.Merge();
103  if ( ver > 1 ) {
104  G4cout<<"After merge the Run object has test counter value: "
105  <<static_cast<const Run*>(arun)->GetCounter()
106  <<" (with 1 thread== number of ranks)"<<G4endl;
107  }
108 
109  //Merge of scorers
110  ver = 0;
112  const auto scor = G4ScoringManager::GetScoringManager();
113  G4MPIscorerMerger sm(scor);
114  sm.SetVerbosity(ver);
115  //Debug!
116  auto debugme = [&scor](){
117  for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
118  const auto m = scor->GetMesh(idx);
119  const auto map = m->GetScoreMap();
120  std::for_each(map.begin(),map.end(),
121  [](const G4VScoringMesh::MeshScoreMap::value_type& e) {
122  G4cout<<e.first<<"("<<e.second<<"):"<<G4endl;
123  const auto data = e.second->GetMap();
124  for( auto it = data->begin() ; it != data->end() ; ++it ) {
125  G4cout<<it->first<<" => G4StatDouble(n,sum_w,sum_w2,sum_wx,sum_wx2): "
126  <<it->second->n()<<" "<<it->second->sum_w()<<" "
127  <<it->second->sum_w2()<<" "<<it->second->sum_wx()<<" "
128  <<it->second->sum_wx2()<<G4endl;
129  }
130  });
131  }
132  };
133  //Debug!
134  if ( ver > 4 ) {
135  G4cout<<"Before merging: Meshes dump"<<G4endl;
136  debugme();
137  }
138  //Write partial scorers from single ranks *before* merging
139  //Do not rely on UI command to write out scorers, because rank-specific
140  //files will have same file name: need to add rank # to file name
141  if ( true ) {
142  for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
143  const auto m = scor->GetMesh(idx);
144  const auto& mn = m->GetWorldName();
145  std::ostringstream fname;
146  fname<<"scorer-"<<mn<<"-rank"<<rank<<".csv";
147  scor->DumpAllQuantitiesToFile(mn,fname.str());
148  }
149  }
150 
151  //Now reduce all scorers to rank #0
152  sm.Merge();
153 
154  //Debug!
155  if ( ver > 4 ) {
156  G4cout<<"After merging: Meshes dump"<<G4endl;
157  debugme();
158  }
159  //For rank #0 write out the merged files
160  if ( rank == 0 ) {
161  for ( size_t idx = 0 ; idx < scor->GetNumberOfMesh() ; ++idx) {
162  const auto m = scor->GetMesh(idx);
163  const auto& mn = m->GetWorldName();
164  std::ostringstream fname;
165  fname<<"scorer-"<<mn<<"-merged.csv";
166  scor->DumpAllQuantitiesToFile(mn,fname.str());
167  }
168  }
169  }
170 
171  //Save histograms *before* MPI merging for rank #0
172  if (rank == 0)
173  {
174  G4String fname("dose-rank0");
175  Analysis* myana = Analysis::GetAnalysis();
176  myana-> Save(fname);
177  myana-> Close(false); // close file withour resetting data
178  }
179  //Merge of g4analysis objects
180  ver=0;
182  hm.SetVerbosity(ver);
183  hm.Merge();
184 
185  //Save g4analysis objects to a file
186  //NB: It is important that the save is done *after* MPI-merging of histograms
187 
188  //One can save all ranks or just rank0, chane the if
189  if (true /*rank == 0*/)
190  {
191  std::ostringstream fname;
192  fname<<"dose-rank"<<rank;
193  if (rank == 0) {
194  fname.str("dose-merged");
195  }
196  Analysis* myana = Analysis::GetAnalysis();
197  myana-> Save(fname.str());
198  }
199  Analysis* myana = Analysis::GetAnalysis();
200  myana-> Close();
201 
202  G4cout << "===================================================" << G4endl;
203  G4cout << "End EndOfRunAction for master thread in rank: " << rank << G4endl;
204  G4cout << "===================================================" << G4endl;
205 
206 }