Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 26 27 // Author: Ivana Hrivnacova, 18/06/2013 (ivan 27 // Author: Ivana Hrivnacova, 18/06/2013 (ivana@ipno.in2p3.fr) 28 28 29 #include "G4ToolsAnalysisManager.hh" 29 #include "G4ToolsAnalysisManager.hh" 30 #include "G4VNtupleFileManager.hh" << 30 #include "G4H1ToolsManager.hh" >> 31 #include "G4H2ToolsManager.hh" >> 32 #include "G4H3ToolsManager.hh" >> 33 #include "G4P1ToolsManager.hh" >> 34 #include "G4P2ToolsManager.hh" 31 #include "G4PlotManager.hh" 35 #include "G4PlotManager.hh" 32 #include "G4MPIToolsManager.hh" 36 #include "G4MPIToolsManager.hh" 33 #include "G4AnalysisUtilities.hh" 37 #include "G4AnalysisUtilities.hh" 34 #include "G4AutoLock.hh" 38 #include "G4AutoLock.hh" 35 #include "G4Threading.hh" 39 #include "G4Threading.hh" 36 40 37 using namespace G4Analysis; 41 using namespace G4Analysis; 38 42 39 namespace { 43 namespace { 40 //Mutex to lock master manager when merging 44 //Mutex to lock master manager when merging histograms 41 G4Mutex mergeHnMutex = G4MUTEX_INITIALIZER; 45 G4Mutex mergeHnMutex = G4MUTEX_INITIALIZER; 42 } 46 } 43 47 44 //____________________________________________ 48 //_____________________________________________________________________________ 45 G4ToolsAnalysisManager* G4ToolsAnalysisManager 49 G4ToolsAnalysisManager* G4ToolsAnalysisManager::Instance() 46 { 50 { 47 return fgToolsInstance; 51 return fgToolsInstance; 48 } 52 } 49 53 50 //____________________________________________ 54 //_____________________________________________________________________________ 51 G4bool G4ToolsAnalysisManager::IsInstance() 55 G4bool G4ToolsAnalysisManager::IsInstance() 52 { 56 { 53 return ( fgToolsInstance != nullptr ); 57 return ( fgToolsInstance != nullptr ); 54 } 58 } 55 59 56 //____________________________________________ 60 //_____________________________________________________________________________ 57 G4ToolsAnalysisManager::G4ToolsAnalysisManager 61 G4ToolsAnalysisManager::G4ToolsAnalysisManager(const G4String& type) 58 : G4VAnalysisManager(type) 62 : G4VAnalysisManager(type) 59 { 63 { 60 // Set instance pointer 64 // Set instance pointer 61 if ( ! G4Threading::IsWorkerThread() ) fgMas 65 if ( ! G4Threading::IsWorkerThread() ) fgMasterToolsInstance = this; 62 fgToolsInstance = this; 66 fgToolsInstance = this; 63 67 64 // Create managers 68 // Create managers 65 fH1Manager = new G4THnToolsManager<kDim1, to << 69 fH1Manager = new G4H1ToolsManager(fState); 66 fH2Manager = new G4THnToolsManager<kDim2, to << 70 fH2Manager = new G4H2ToolsManager(fState); 67 fH3Manager = new G4THnToolsManager<kDim3, to << 71 fH3Manager = new G4H3ToolsManager(fState); 68 fP1Manager = new G4THnToolsManager<kDim2, to << 72 fP1Manager = new G4P1ToolsManager(fState); 69 fP2Manager = new G4THnToolsManager<kDim3, to << 73 fP2Manager = new G4P2ToolsManager(fState); 70 // The managers will be deleted by the b 74 // The managers will be deleted by the base class 71 75 72 // Set managers to base class which takes th 76 // Set managers to base class which takes then their ownership 73 SetH1Manager(fH1Manager); 77 SetH1Manager(fH1Manager); 74 SetH2Manager(fH2Manager); 78 SetH2Manager(fH2Manager); 75 SetH3Manager(fH3Manager); 79 SetH3Manager(fH3Manager); 76 SetP1Manager(fP1Manager); 80 SetP1Manager(fP1Manager); 77 SetP2Manager(fP2Manager); 81 SetP2Manager(fP2Manager); 78 82 79 // Plot manager 83 // Plot manager 80 fPlotManager = std::make_unique<G4PlotManage << 84 SetPlotManager(std::make_shared<G4PlotManager>(fState)); >> 85 >> 86 // Messenger >> 87 fMessenger = std::make_unique<G4ToolsAnalysisMessenger>(this); 81 } 88 } 82 89 83 //____________________________________________ 90 //_____________________________________________________________________________ 84 G4ToolsAnalysisManager::~G4ToolsAnalysisManage 91 G4ToolsAnalysisManager::~G4ToolsAnalysisManager() 85 { 92 { 86 if ( fState.GetIsMaster() ) fgMasterToolsIns 93 if ( fState.GetIsMaster() ) fgMasterToolsInstance = nullptr; 87 fgToolsInstance = nullptr; 94 fgToolsInstance = nullptr; 88 } 95 } 89 96 90 // 97 // 91 // private methods << 98 // protected methods 92 // 99 // 93 100 94 //____________________________________________ 101 //_____________________________________________________________________________ 95 G4bool G4ToolsAnalysisManager::WriteHns() << 102 G4bool G4ToolsAnalysisManager::PlotImpl() 96 { 103 { 97 // Nothing to be done on worker << 98 if ( G4Threading::IsWorkerThread() ) return << 99 << 100 auto result = true; << 101 << 102 // Write all histograms/profile on master << 103 result &= WriteT(fH1Manager->GetTHnVectorRef << 104 result &= WriteT(fH2Manager->GetTHnVectorRef << 105 result &= WriteT(fH3Manager->GetTHnVectorRef << 106 result &= WriteT(fP1Manager->GetTHnVectorRef << 107 result &= WriteT(fP2Manager->GetTHnVectorRef << 108 << 109 return result; << 110 } << 111 104 112 //____________________________________________ << 105 // Only master thread performs plotting 113 G4bool G4ToolsAnalysisManager::ResetHns() << 106 if ( G4Threading::IsWorkerThread() ) return true; 114 { << 115 // Reset histograms and profiles << 116 107 117 auto result = true; 108 auto result = true; 118 109 119 result &= fH1Manager->Reset(); << 110 // Open output file 120 result &= fH2Manager->Reset(); << 111 fPlotManager->OpenFile(fVFileManager->GetPlotFileName()); 121 result &= fH3Manager->Reset(); << 122 result &= fP1Manager->Reset(); << 123 result &= fP2Manager->Reset(); << 124 112 125 return result; << 113 // H1 126 } << 114 result >> 115 &= fPlotManager->PlotAndWrite<tools::histo::h1d>(fH1Manager->GetH1Vector(), >> 116 fH1Manager->GetHnVector()); 127 117 128 //____________________________________________ << 118 // H2 129 G4bool G4ToolsAnalysisManager::MergeHns() << 119 result 130 { << 120 &= fPlotManager->PlotAndWrite<tools::histo::h2d>(fH2Manager->GetH2Vector(), 131 // Nothing to be done on master << 121 fH2Manager->GetHnVector()); 132 if ( ! G4Threading::IsWorkerThread() ) retur << 133 122 134 if (fgMasterToolsInstance == nullptr) { << 123 // H3 135 if (! IsEmpty() ) { << 124 // not yet available in tools 136 Warn("No master G4AnalysisManager instan << 137 "Histogram/profile data will not be << 138 fkClass, "Merge"); << 139 return false; << 140 } << 141 return true; << 142 } << 143 125 144 Message(kVL4, "merge on worker", "histograms << 126 // P1 >> 127 result >> 128 &= fPlotManager->PlotAndWrite<tools::histo::p1d>(fP1Manager->GetP1Vector(), >> 129 fP1Manager->GetHnVector()); 145 130 146 // The worker manager just adds its histogra << 131 // P2 147 fH1Manager->Merge(mergeHnMutex, fgMasterTool << 132 // not yet available in tools 148 fH2Manager->Merge(mergeHnMutex, fgMasterTool << 149 fH3Manager->Merge(mergeHnMutex, fgMasterTool << 150 fP1Manager->Merge(mergeHnMutex, fgMasterTool << 151 fP2Manager->Merge(mergeHnMutex, fgMasterTool << 152 133 153 Message(kVL3, "merge on worker", "histograms << 134 // Close output file >> 135 result &= fPlotManager->CloseFile(); 154 136 155 return true; << 137 return result; 156 } 138 } 157 139 158 // << 159 // protected methods << 160 // << 161 << 162 //____________________________________________ 140 //_____________________________________________________________________________ 163 G4bool G4ToolsAnalysisManager::OpenFileImpl(co << 141 G4bool G4ToolsAnalysisManager::MergeImpl(tools::histo::hmpi* hmpi) 164 { 142 { 165 // Create ntuple manager(s) << 166 // and set it to base class which takes then << 167 SetNtupleManager(fVNtupleFileManager->Create << 168 << 169 auto result = true; << 170 << 171 // Open file << 172 if ( fVNtupleFileManager->GetMergeMode() != << 173 result &= fVFileManager->OpenFile(fileName << 174 } << 175 143 176 // Open ntuple files and create ntuples from << 144 // if ( G4Threading::IsWorkerThread() ) return true; 177 result &= fVNtupleFileManager->ActionAtOpenF << 178 << 179 return result; << 180 } << 181 145 182 //____________________________________________ << 146 if ( ! hmpi ) return false; 183 G4bool G4ToolsAnalysisManager::WriteImpl() << 184 { << 185 Message(kVL4, "write", "files"); << 186 147 187 auto result = true; 148 auto result = true; 188 if ( G4Threading::IsWorkerThread() ) { << 189 result &= MergeHns(); << 190 } << 191 else { << 192 // Open all files registered with objects << 193 fVFileManager->OpenFiles(); << 194 149 195 // Write all histograms/profile on master << 150 // Create MPI manager 196 result &= WriteHns(); << 151 G4MPIToolsManager mpiToolsManager(fState, hmpi); 197 } << 198 152 199 // Ntuples << 153 // H1 200 if (fVNtupleFileManager) { << 154 result 201 result &= fVNtupleFileManager->ActionAtWri << 155 &= mpiToolsManager.Merge<tools::histo::h1d>(fH1Manager->GetH1Vector(), 202 } << 156 fH1Manager->GetHnVector()); 203 157 204 // Files << 158 // H2 205 if ( (fVNtupleFileManager == nullptr) || << 159 result 206 (fVNtupleFileManager->GetMergeMode() != << 160 &= mpiToolsManager.Merge<tools::histo::h2d>(fH2Manager->GetH2Vector(), 207 result &= fVFileManager->WriteFiles(); << 161 fH2Manager->GetHnVector()); 208 } << 209 162 210 // Write ASCII if activated << 163 // H3 211 if ( IsAscii() ) { << 164 result 212 result &= WriteAscii(fVFileManager->GetFil << 165 &= mpiToolsManager.Merge<tools::histo::h3d>(fH3Manager->GetH3Vector(), 213 } << 166 fH3Manager->GetHnVector()); >> 167 >> 168 // P1 >> 169 result >> 170 &= mpiToolsManager.Merge<tools::histo::p1d>(fP1Manager->GetP1Vector(), >> 171 fP1Manager->GetHnVector()); 214 172 215 Message(kVL3, "write", "files", "", result); << 173 // P2 >> 174 result >> 175 &= mpiToolsManager.Merge<tools::histo::p2d>(fP2Manager->GetP2Vector(), >> 176 fP2Manager->GetHnVector()); 216 177 217 return result; 178 return result; 218 } 179 } 219 180 220 //____________________________________________ 181 //_____________________________________________________________________________ 221 G4bool G4ToolsAnalysisManager::CloseFileImpl(G << 182 G4bool G4ToolsAnalysisManager::WriteImpl() 222 { 183 { 223 Message(kVL4, "close", "files"); << 184 // Nothing to be done on worker >> 185 if ( G4Threading::IsWorkerThread() ) return false; 224 186 225 auto result = true; 187 auto result = true; 226 if (fVNtupleFileManager) { << 227 result &= fVNtupleFileManager->ActionAtClo << 228 } << 229 188 230 // close file << 189 // Write all histograms/profile on master 231 if ( (fVNtupleFileManager == nullptr) || << 190 result &=WriteT(fH1Manager->GetH1Vector(), fH1Manager->GetHnVector()); 232 (fVNtupleFileManager->GetMergeMode() != << 191 result &=WriteT(fH2Manager->GetH2Vector(), fH2Manager->GetHnVector()); 233 if ( ! fVFileManager->CloseFiles() ) { << 192 result &=WriteT(fH3Manager->GetH3Vector(), fH3Manager->GetHnVector()); 234 Warn("Closing files failed", fkClass, "C << 193 result &=WriteT(fP1Manager->GetP1Vector(), fP1Manager->GetHnVector()); 235 result = false; << 194 result &=WriteT(fP2Manager->GetP2Vector(), fP2Manager->GetHnVector()); 236 } << 237 } << 238 << 239 // delete empty files << 240 if ( ! fVFileManager->DeleteEmptyFiles() ) { << 241 Warn("Deleting empty files failed", fkClas << 242 result = false; << 243 } << 244 << 245 // reset histograms << 246 if ( reset ) { << 247 if ( ! Reset() ) { << 248 Warn("Resetting data failed", fkClass, " << 249 result = false; << 250 } << 251 } << 252 << 253 Message(kVL3, "close", "files", "", result); << 254 195 255 return result; 196 return result; 256 } 197 } 257 198 258 //____________________________________________ 199 //_____________________________________________________________________________ 259 G4bool G4ToolsAnalysisManager::ResetImpl() 200 G4bool G4ToolsAnalysisManager::ResetImpl() 260 { 201 { 261 // Reset histograms and ntuple << 202 // Reset histograms and profiles 262 << 263 Message(kVL4, "reset", ""); << 264 203 265 auto result = true; 204 auto result = true; 266 result &= ResetHns(); << 267 if ( fVNtupleFileManager != nullptr ) { << 268 result &= fVNtupleFileManager->Reset(); << 269 } << 270 205 271 Message(kVL3, "reset", "", "", result); << 206 result &= fH1Manager->Reset(); >> 207 result &= fH2Manager->Reset(); >> 208 result &= fH3Manager->Reset(); >> 209 result &= fP1Manager->Reset(); >> 210 result &= fP2Manager->Reset(); 272 211 273 return result; 212 return result; 274 } 213 } 275 214 276 //____________________________________________ 215 //_____________________________________________________________________________ 277 void G4ToolsAnalysisManager::ClearImpl() 216 void G4ToolsAnalysisManager::ClearImpl() 278 { 217 { 279 // Reset histograms and profiles 218 // Reset histograms and profiles 280 219 281 fH1Manager->ClearData(); 220 fH1Manager->ClearData(); 282 fH2Manager->ClearData(); 221 fH2Manager->ClearData(); 283 fH3Manager->ClearData(); 222 fH3Manager->ClearData(); 284 fP1Manager->ClearData(); 223 fP1Manager->ClearData(); 285 fP2Manager->ClearData(); 224 fP2Manager->ClearData(); 286 } 225 } 287 226 288 //____________________________________________ 227 //_____________________________________________________________________________ 289 G4bool G4ToolsAnalysisManager::PlotImpl() << 228 G4bool G4ToolsAnalysisManager::Merge() 290 { << 291 << 292 // Only master thread performs plotting << 293 if ( G4Threading::IsWorkerThread() ) return << 294 << 295 auto result = true; << 296 << 297 // Open output file << 298 fPlotManager->OpenFile(fVFileManager->GetPlo << 299 << 300 // H1 << 301 result << 302 &= fPlotManager->PlotAndWrite<tools::histo << 303 << 304 // H2 << 305 result << 306 &= fPlotManager->PlotAndWrite<tools::histo << 307 << 308 // H3 << 309 // not yet available in tools << 310 << 311 // P1 << 312 result << 313 &= fPlotManager->PlotAndWrite<tools::histo << 314 << 315 // P2 << 316 // not yet available in tools << 317 << 318 // Close output file << 319 result &= fPlotManager->CloseFile(); << 320 << 321 return result; << 322 } << 323 << 324 //____________________________________________ << 325 G4bool G4ToolsAnalysisManager::MergeImpl(tools << 326 { 229 { >> 230 // Nothing to be done on master >> 231 if ( ! G4Threading::IsWorkerThread() ) return false; 327 232 328 // if ( G4Threading::IsWorkerThread() ) ret << 233 if ( ! fgMasterToolsInstance ) { 329 << 234 if (! IsEmpty() ) { 330 if (hmpi == nullptr) return false; << 235 Warn("No master G4AnalysisManager instance exists.\n" 331 << 236 "Histogram/profile data will not be merged.", 332 auto result = true; << 237 fkClass, "Merge"); 333 << 238 return false; 334 // Create MPI manager << 239 } 335 G4MPIToolsManager mpiToolsManager(fState, hm << 240 return true; 336 << 241 } 337 // H1 << 338 result &= mpiToolsManager.Merge<tools::histo << 339 << 340 // H2 << 341 result &= mpiToolsManager.Merge<tools::histo << 342 242 343 // H3 << 243 Message(kVL4, "merge on worker", "histograms"); 344 result &= mpiToolsManager.Merge<tools::histo << 345 244 346 // P1 << 245 // The worker manager just adds its histograms to the master 347 result &= mpiToolsManager.Merge<tools::histo << 246 fH1Manager->Merge(mergeHnMutex, fgMasterToolsInstance->fH1Manager); >> 247 fH2Manager->Merge(mergeHnMutex, fgMasterToolsInstance->fH2Manager); >> 248 fH3Manager->Merge(mergeHnMutex, fgMasterToolsInstance->fH3Manager); >> 249 fP1Manager->Merge(mergeHnMutex, fgMasterToolsInstance->fP1Manager); >> 250 fP2Manager->Merge(mergeHnMutex, fgMasterToolsInstance->fP2Manager); 348 251 349 // P2 << 252 Message(kVL3, "merge on worker", "histograms"); 350 result &= mpiToolsManager.Merge<tools::histo << 351 253 352 return result; << 254 return true; 353 } 255 } 354 << 355 256 356 //____________________________________________ 257 //_____________________________________________________________________________ 357 G4bool G4ToolsAnalysisManager::IsEmpty() 258 G4bool G4ToolsAnalysisManager::IsEmpty() 358 { 259 { 359 return fH1Manager->IsEmpty() && fH2Manager-> 260 return fH1Manager->IsEmpty() && fH2Manager->IsEmpty() && fH3Manager->IsEmpty() && 360 fP1Manager->IsEmpty() && fP2Manager-> 261 fP1Manager->IsEmpty() && fP2Manager->IsEmpty(); 361 } 262 } 362 263