ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4XmlAnalysisManager.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4XmlAnalysisManager.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 // Author: Ivana Hrivnacova, 18/06/2013 (ivana@ipno.in2p3.fr)
28 
29 #include "G4XmlAnalysisManager.hh"
30 #include "G4XmlFileManager.hh"
31 #include "G4XmlNtupleManager.hh"
33 #include "G4Threading.hh"
34 #include "G4AutoLock.hh"
35 
36 // mutex in a file scope
37 
38 namespace {
39  //Mutex to lock master manager when merging H1 histograms
40  G4Mutex mergeH1Mutex = G4MUTEX_INITIALIZER;
41  //Mutex to lock master manager when merging H1 histograms
42  G4Mutex mergeH2Mutex = G4MUTEX_INITIALIZER;
43  //Mutex to lock master manager when merging H1 histograms
44  G4Mutex mergeH3Mutex = G4MUTEX_INITIALIZER;
45  //Mutex to lock master manager when merging P1 profiles
46  G4Mutex mergeP1Mutex = G4MUTEX_INITIALIZER;
47  //Mutex to lock master manager when merging P2 profiles
48  G4Mutex mergeP2Mutex = G4MUTEX_INITIALIZER;
49 }
50 
53 
54 //_____________________________________________________________________________
56 {
57  if ( fgInstance == nullptr ) {
58  G4bool isMaster = ! G4Threading::IsWorkerThread();
59  fgInstance = new G4XmlAnalysisManager(isMaster);
60  }
61 
62  return fgInstance;
63 }
64 
65 //_____________________________________________________________________________
67 {
68  return ( fgInstance != 0 );
69 }
70 
71 //_____________________________________________________________________________
73  : G4ToolsAnalysisManager("Xml", isMaster),
74  fNtupleManager(nullptr),
75  fFileManager(nullptr)
76 {
77  if ( ( isMaster && fgMasterInstance ) || ( fgInstance ) ) {
78  G4ExceptionDescription description;
79  description
80  << " "
81  << "G4XmlAnalysisManager already exists."
82  << "Cannot create another instance.";
83  G4Exception("G4XmlAnalysisManager::G4XmlAnalysisManager",
84  "Analysis_F001", FatalException, description);
85  }
86  if ( isMaster ) fgMasterInstance = this;
87  fgInstance = this;
88 
89  // Create managers
91  fFileManager = std::make_shared<G4XmlFileManager>(fState);
93  // The managers will be deleted by the base class
94 
95  // Set managers to base class which takes then their ownership
98 }
99 
100 //_____________________________________________________________________________
102 {
103  if ( fState.GetIsMaster() ) fgMasterInstance = nullptr;
104  fgInstance = nullptr;
105 }
106 
107 //
108 // private methods
109 //
110 
111 //_____________________________________________________________________________
113 {
114  auto h1Vector = fH1Manager->GetH1Vector();
115  auto hnVector = fH1Manager->GetHnVector();
116 
117  if ( ! h1Vector.size() ) return true;
118 
119  auto result = true;
120 
121  if ( ! G4Threading::IsWorkerThread() ) {
122  auto directoryName = fFileManager->GetHistoDirectoryName();
123  result = WriteT(h1Vector, hnVector, directoryName, "h1");
124  }
125  else {
126  // The worker manager just adds its histograms to the master
127  // This operation needs a lock
128  G4AutoLock lH1(&mergeH1Mutex);
130  lH1.unlock();
131  }
132 
133  return result;
134 }
135 
136 //_____________________________________________________________________________
138 {
139  auto h2Vector = fH2Manager->GetH2Vector();
140  auto hnVector = fH2Manager->GetHnVector();
141 
142  if ( ! h2Vector.size() ) return true;
143 
144  auto result = true;
145 
146  if ( ! G4Threading::IsWorkerThread() ) {
147  auto directoryName = fFileManager->GetHistoDirectoryName();
148  result = WriteT(h2Vector, hnVector, directoryName, "h2");
149  }
150  else {
151  // The worker manager just adds its histograms to the master
152  // This operation needs a lock
153  G4AutoLock lH2(&mergeH2Mutex);
155  lH2.unlock();
156  }
157 
158  return result;
159 }
160 
161 //_____________________________________________________________________________
163 {
164  auto h3Vector = fH3Manager->GetH3Vector();
165  auto hnVector = fH3Manager->GetHnVector();
166 
167  if ( ! h3Vector.size() ) return true;
168 
169  auto result = true;
170 
171  if ( ! G4Threading::IsWorkerThread() ) {
172  auto directoryName = fFileManager->GetHistoDirectoryName();
173  result = WriteT(h3Vector, hnVector, directoryName, "h3");
174  }
175  else {
176  // The worker manager just adds its histograms to the master
177  // This operation needs a lock
178  G4AutoLock lH3(&mergeH3Mutex);
180  lH3.unlock();
181  }
182 
183  return result;
184 }
185 
186 //_____________________________________________________________________________
188 {
189  auto p1Vector = fP1Manager->GetP1Vector();
190  auto hnVector = fP1Manager->GetHnVector();
191 
192  if ( ! p1Vector.size() ) return true;
193 
194  auto result = true;
195 
196  if ( ! G4Threading::IsWorkerThread() ) {
197  auto directoryName = fFileManager->GetHistoDirectoryName();
198  result = WriteT(p1Vector, hnVector, directoryName, "p1");
199  }
200  else {
201  // The worker manager just adds its profiles to the master
202  // This operation needs a lock
203  G4AutoLock lP1(&mergeP1Mutex);
205  lP1.unlock();
206  }
207 
208  return result;
209 }
210 
211 //_____________________________________________________________________________
213 {
214  auto p2Vector = fP2Manager->GetP2Vector();
215  auto hnVector = fP2Manager->GetHnVector();
216 
217  if ( ! p2Vector.size() ) return true;
218 
219  auto result = true;
220 
221  if ( ! G4Threading::IsWorkerThread() ) {
222  auto directoryName = fFileManager->GetHistoDirectoryName();
223  result = WriteT(p2Vector, hnVector, directoryName, "p2");
224  }
225  else {
226  // The worker manager just adds its profiles to the master
227  // This operation needs a lock
228  G4AutoLock lP2(&mergeP2Mutex);
230  lP2.unlock();
231  }
232 
233  return result;
234 }
235 
236 //_____________________________________________________________________________
238 {
239  auto ntupleVector = fNtupleManager->GetNtupleDescriptionVector();
240 
241  for ( auto ntuple : ntupleVector ) {
242  if ( ntuple->fNtuple ) ntuple->fNtuple->write_trailer();
243  }
244 
245  return true;
246 }
247 
248 //_____________________________________________________________________________
250 {
251  auto ntupleDescriptionVector = fNtupleManager->GetNtupleDescriptionVector();
252 
253  // Close ntuple files
254  for ( auto ntupleDescription : ntupleDescriptionVector) {
255  fFileManager->CloseNtupleFile((ntupleDescription));
256  }
257 
258  return true;
259 }
260 
261 
262 //_____________________________________________________________________________
264 {
265 // Reset histograms and ntuple
266 
267  auto finalResult = true;
268 
269  auto result = G4ToolsAnalysisManager::Reset();
270  finalResult = finalResult && result;
271 
272  result = fNtupleManager->Reset(true);
273  finalResult = finalResult && result;
274 
275  return finalResult;
276 }
277 
278 //
279 // protected methods
280 //
281 
282 //_____________________________________________________________________________
284 {
285  auto finalResult = true;
286  auto result = fFileManager->SetFileName(fileName);
287  finalResult = finalResult && result;
288 
289 #ifdef G4VERBOSE
290  auto name = fFileManager->GetFullFileName();
291  if ( fState.GetVerboseL4() ) {
292  fState.GetVerboseL4()->Message("open", "analysis file", name);
293  }
294 #endif
295 
296  // Only lock file name in file manager
297  result = fFileManager->OpenFile(fileName);
298  finalResult = finalResult && result;
299 
300  // Create histograms file (on master)
301  if ( fState.GetIsMaster() ) {
302  result = fFileManager->CreateHnFile();
303  finalResult = finalResult && result;
304  }
305 
306  // Create ntuples if they are booked
307  // (The files will be created with creating ntuples)
309 
310 #ifdef G4VERBOSE
311  if ( fState.GetVerboseL1() )
312  fState.GetVerboseL1()->Message("open", "analysis file", name, finalResult);
313 #endif
314 
315  return finalResult;
316 }
317 
318 //_____________________________________________________________________________
320 {
321  auto finalResult = true;
322 
323 #ifdef G4VERBOSE
324  auto name = fFileManager->GetFullFileName();
325  if ( fState.GetVerboseL4() )
326  fState.GetVerboseL4()->Message("write", "files", name);
327 #endif
328 
329  // ntuples
330  WriteNtuple();
331 
332  if ( ! fgMasterInstance &&
333  ( ( ! fH1Manager->IsEmpty() ) || ( ! fH2Manager->IsEmpty() ) ||
334  ( ! fH3Manager->IsEmpty() ) || ( ! fP1Manager->IsEmpty() ) ||
335  ( ! fP2Manager->IsEmpty() ) ) ) {
336 
337  G4ExceptionDescription description;
338  description
339  << " " << "No master G4XmlAnalysisManager instance exists."
340  << G4endl
341  << " " << "Histogram data will not be merged.";
342  G4Exception("G4XmlAnalysisManager::Write()",
343  "Analysis_W031", JustWarning, description);
344 
345  // Create Hn file per thread
346  auto result = fFileManager->CreateHnFile();
347  if ( ! result ) return false;
348  }
349 
350  // H1
351  auto result = WriteH1();
352  finalResult = finalResult && result;
353 
354  // H2
355  result = WriteH2();
356  finalResult = finalResult && result;
357 
358  // H3
359  result = WriteH3();
360  finalResult = finalResult && result;
361 
362  // P1
363  result = WriteP1();
364  finalResult = finalResult && result;
365 
366  // P2
367  result = WriteP2();
368  finalResult = finalResult && result;
369 
370  // Write ASCII if activated
371  if ( IsAscii() ) {
372  result = WriteAscii(fFileManager->GetFileName());
373  finalResult = finalResult && result;
374  }
375 
376 #ifdef G4VERBOSE
377  if ( fState.GetVerboseL1() )
379  ->Message("write", "file", fFileManager->GetFullFileName(), finalResult);
380 #endif
381 
382  return finalResult;
383 }
384 
385 //_____________________________________________________________________________
387 {
388  auto finalResult = true;
389 
390 #ifdef G4VERBOSE
391  if ( fState.GetVerboseL4() )
392  fState.GetVerboseL4()->Message("close", "files", "");
393 #endif
394 
395  // Unlock file name only
396  auto result = fFileManager->CloseFile();
397  finalResult = finalResult && result;
398 
399  // Close Hn file
400  result = fFileManager->CloseHnFile();
401  finalResult = finalResult && result;
402 
403  // Close ntuple files
404  result = CloseNtupleFiles();
405  finalResult = finalResult && result;
406 
407  // reset data
408  if ( reset ) {
409  result = Reset();
410  } else {
411  // ntuple must be reset
412  result = fNtupleManager->Reset(true);
413  }
414  if ( ! result ) {
415  G4ExceptionDescription description;
416  description << " " << "Resetting data failed";
417  G4Exception("G4XmlAnalysisManager::CloseFile()",
418  "Analysis_W021", JustWarning, description);
419  }
420  finalResult = finalResult && result;
421 
422  // delete files if empty
423  // (ntuple files are created only if an ntuple is created)
424  if ( fFileManager->GetHnFile().get() &&
426  fP1Manager->IsEmpty() && fP2Manager->IsEmpty() ) {
427  result = ! std::remove(fFileManager->GetFullFileName());
428  // std::remove returns 0 when success
429  if ( ! result ) {
430  G4ExceptionDescription description;
431  description << " " << "Removing file "
432  << fFileManager->GetFullFileName() << " failed";
433  G4Exception("G4XmlAnalysisManager::CloseFile()",
434  "Analysis_W021", JustWarning, description);
435  }
436  finalResult = finalResult && result;
437 #ifdef G4VERBOSE
438  if ( fState.GetVerboseL1() )
440  ->Message("delete", "empty file", fFileManager->GetFullFileName());
441 #endif
442  }
443  else {
444 #ifdef G4VERBOSE
445  if ( fState.GetVerboseL2() )
447  ->Message("close", "files", "");
448 #endif
449  }
450 
451  return finalResult;
452 }