Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/advanced/CaTS/src/RootIO.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 //
 28 //  CaTS (Calorimetry and Tracking Simulation)
 29 //
 30 //  Authors : Hans Wenzel
 31 //            Soon Yung Jun
 32 //            (Fermi National Accelerator Laboratory)
 33 //
 34 // History
 35 //   October  18th, 2021 : first implementation
 36 //   November 10th, 2021 : implement writing one file
 37 //                         per worker thread which are then merged
 38 //
 39 // ********************************************************************
 40 //
 41 /// \file RootIO.cc
 42 /// \brief Implementation of the CaTS::RootIO class
 43 
 44 #ifdef WITH_ROOT
 45 // Project headers
 46 #include "RootIO.hh"
 47 #include "ConfigurationManager.hh"
 48 #include "Event.hh"
 49 // Geant4 headers
 50 #include <G4String.hh>
 51 #include <G4ios.hh>
 52 #include <G4Threading.hh>
 53 #include <G4RunManager.hh>
 54 // Root headers
 55 #include "TBranch.h"
 56 #include "TFile.h"
 57 #include "TObject.h"
 58 #include "TSystem.h"
 59 #include "TTree.h"
 60 #include "TROOT.h"
 61 // c++ headers
 62 #include <string>
 63 #include <stdio.h>
 64 
 65 G4ThreadLocal RootIO* RootIO::fgInstance = nullptr;
 66 // mutex in a file scope
 67 namespace {
 68     // Mutex to lock RootIO constructor
 69     G4Mutex RootIOMutex = G4MUTEX_INITIALIZER;
 70 } // namespace
 71 
 72 RootIO::RootIO() {
 73     G4AutoLock lock(&RootIOMutex);
 74     TSystem ts;
 75     gSystem->Load("libCaTSClassesDict");
 76     if (G4Threading::IsMultithreadedApplication()) {
 77         if (G4Threading::IsWorkerThread()) {
 78             G4String fFilename = ConfigurationManager::getInstance()->getfname() +
 79                     "_Thread_" +
 80                     std::to_string(G4Threading::G4GetThreadId()) + ".root";
 81             G4cout << "RootIO:: Opening File: " << fFilename << G4endl;
 82             fFile = new TFile(fFilename.c_str(), "RECREATE");
 83             TTree::SetMaxTreeSize(1000 * Long64_t(2000000000));
 84             // Create a ROOT Tree and one superbranch
 85             ftree = new TTree("Events", "ROOT tree containing Hit collections");
 86             ftree->SetAutoSave(1000000000); // autosave when 1 Gbyte written
 87             Int_t branchStyle = 1;
 88             TTree::SetBranchStyle(branchStyle);
 89         }
 90     } else {
 91         G4String fFilename = ConfigurationManager::getInstance()->getfname() + ".root";
 92         G4cout << "RootIO:: Opening File: " << fFilename << G4endl;
 93         fFile = new TFile(fFilename.c_str(), "RECREATE");
 94         TTree::SetMaxTreeSize(1000 * Long64_t(2000000000));
 95         // Create a ROOT Tree and one superbranch
 96         ftree = new TTree("Events", "ROOT tree containing Hit collections");
 97         ftree->SetAutoSave(1000000000); // autosave when 1 Gbyte written
 98         Int_t branchStyle = 1;
 99         TTree::SetBranchStyle(branchStyle);
100     }
101 }
102 
103 RootIO* RootIO::GetInstance() {
104     if (fgInstance == nullptr) {
105         static G4ThreadLocalSingleton<RootIO> inst;
106         fgInstance = inst.Instance();
107     }
108     return fgInstance;
109 }
110 
111 void RootIO::Write(Event* fevent) {
112     if (ConfigurationManager::getInstance()->isEnable_verbose())
113         G4cout << "writing Event: " << fevent->GetEventNumber() << G4endl;
114     if ((fevent->GetEventNumber()) % 1000 == 0)
115         G4cout << "writing Event: " << fevent->GetEventNumber() << G4endl;
116     if (!fevtinitialized) {
117         Int_t bufsize = 64000;
118         fevtbranch = ftree->Branch("event.", &fevent, bufsize, 0);
119         fevtbranch->SetAutoDelete(kFALSE);
120         fevtinitialized = true;
121     }
122     fFile = ftree->GetCurrentFile(); // just in case we switched to a new file
123     fnb += ftree->Fill();
124     fFile->Write("", TObject::kOverwrite);
125 }
126 
127 void RootIO::Close() {
128     G4cout << " Closing File: "  << G4endl;
129     fFile = ftree->GetCurrentFile();
130     fFile->Close();
131 }
132 
133 void RootIO::Merge() {
134     if (G4Threading::IsMasterThread()) {
135         unsigned int nthreads = G4RunManager::GetRunManager()->GetNumberOfThreads();
136         G4cout << "RootIO::Merging: " << nthreads << " threads" << G4endl;
137         G4String filename = ConfigurationManager::getInstance()->getfname();
138         G4String tmpfn;
139         std::vector<TFile*> filevec;
140         std::vector<Event*> evtvec;
141         std::vector<TTree*> treevec;
142         std::vector<TBranch*> branchvec;
143         TList* list = new TList;
144         TTree* newtree;
145         for (unsigned int i = 0; i < nthreads; i++) {
146             tmpfn = filename + "_Thread_" + std::to_string(i) + ".root";
147             filevec.push_back(new TFile(tmpfn.c_str()));
148             treevec.push_back((TTree*) (filevec[i]->Get("Events")));
149             list->Add(treevec[i]);
150             if (i == nthreads - 1) {
151                 G4String tmpfn2 = filename + "_Merged.root";
152                 TFile* fm = new TFile(tmpfn2.c_str(), "RECREATE");
153                 newtree = TTree::MergeTrees(list);
154                 newtree->SetName("Events");
155                 Event* eventm = new Event();
156                 newtree->SetBranchAddress("event.", &eventm);
157                 TBranch* fevtbranchm = newtree->GetBranch("event.");
158                 int neventm = fevtbranchm->GetEntries();
159                 G4cout << "Nr. of Events:  " << neventm << G4endl;
160                 newtree->Write();
161                 fm->Close();
162             }
163         }
164         for (unsigned int i = 0; i < nthreads; i++) {
165             tmpfn = filename + "_Thread_" + std::to_string(i) + ".root";
166             if (remove(tmpfn.c_str()) != 0) {
167                 G4cout << "Error deleting file: " << tmpfn << G4endl;
168             } else {
169                 G4cout << "File: " << tmpfn << " successfully deleted" << G4endl;
170             }
171         }
172     }
173 }
174 #endif
175