Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 09:21:48

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // ********************************************************************
0027 //
0028 //  CaTS (Calorimetry and Tracking Simulation)
0029 //
0030 //  Authors : Hans Wenzel
0031 //            Soon Yung Jun
0032 //            (Fermi National Accelerator Laboratory)
0033 //
0034 // History
0035 //   October  18th, 2021 : first implementation
0036 //   November 10th, 2021 : implement writing one file
0037 //                         per worker thread which are then merged
0038 //
0039 // ********************************************************************
0040 //
0041 /// \file RootIO.cc
0042 /// \brief Implementation of the CaTS::RootIO class
0043 
0044 #ifdef WITH_ROOT
0045 // Project headers
0046 #include "RootIO.hh"
0047 #include "ConfigurationManager.hh"
0048 #include "Event.hh"
0049 // Geant4 headers
0050 #include <G4String.hh>
0051 #include <G4ios.hh>
0052 #include <G4Threading.hh>
0053 #include <G4RunManager.hh>
0054 // Root headers
0055 #include "TBranch.h"
0056 #include "TFile.h"
0057 #include "TObject.h"
0058 #include "TSystem.h"
0059 #include "TTree.h"
0060 #include "TROOT.h"
0061 // c++ headers
0062 #include <string>
0063 #include <stdio.h>
0064 
0065 G4ThreadLocal RootIO* RootIO::fgInstance = nullptr;
0066 // mutex in a file scope
0067 namespace {
0068     // Mutex to lock RootIO constructor
0069     G4Mutex RootIOMutex = G4MUTEX_INITIALIZER;
0070 } // namespace
0071 
0072 RootIO::RootIO() {
0073     G4AutoLock lock(&RootIOMutex);
0074     TSystem ts;
0075     gSystem->Load("libCaTSClassesDict");
0076     if (G4Threading::IsMultithreadedApplication()) {
0077         if (G4Threading::IsWorkerThread()) {
0078             G4String fFilename = ConfigurationManager::getInstance()->getfname() +
0079                     "_Thread_" +
0080                     std::to_string(G4Threading::G4GetThreadId()) + ".root";
0081             G4cout << "RootIO:: Opening File: " << fFilename << G4endl;
0082             fFile = new TFile(fFilename.c_str(), "RECREATE");
0083             TTree::SetMaxTreeSize(1000 * Long64_t(2000000000));
0084             // Create a ROOT Tree and one superbranch
0085             ftree = new TTree("Events", "ROOT tree containing Hit collections");
0086             ftree->SetAutoSave(1000000000); // autosave when 1 Gbyte written
0087             Int_t branchStyle = 1;
0088             TTree::SetBranchStyle(branchStyle);
0089         }
0090     } else {
0091         G4String fFilename = ConfigurationManager::getInstance()->getfname() + ".root";
0092         G4cout << "RootIO:: Opening File: " << fFilename << G4endl;
0093         fFile = new TFile(fFilename.c_str(), "RECREATE");
0094         TTree::SetMaxTreeSize(1000 * Long64_t(2000000000));
0095         // Create a ROOT Tree and one superbranch
0096         ftree = new TTree("Events", "ROOT tree containing Hit collections");
0097         ftree->SetAutoSave(1000000000); // autosave when 1 Gbyte written
0098         Int_t branchStyle = 1;
0099         TTree::SetBranchStyle(branchStyle);
0100     }
0101 }
0102 
0103 RootIO* RootIO::GetInstance() {
0104     if (fgInstance == nullptr) {
0105         static G4ThreadLocalSingleton<RootIO> inst;
0106         fgInstance = inst.Instance();
0107     }
0108     return fgInstance;
0109 }
0110 
0111 void RootIO::Write(Event* fevent) {
0112     if (ConfigurationManager::getInstance()->isEnable_verbose())
0113         G4cout << "writing Event: " << fevent->GetEventNumber() << G4endl;
0114     if ((fevent->GetEventNumber()) % 1000 == 0)
0115         G4cout << "writing Event: " << fevent->GetEventNumber() << G4endl;
0116     if (!fevtinitialized) {
0117         Int_t bufsize = 64000;
0118         fevtbranch = ftree->Branch("event.", &fevent, bufsize, 0);
0119         fevtbranch->SetAutoDelete(kFALSE);
0120         fevtinitialized = true;
0121     }
0122     fFile = ftree->GetCurrentFile(); // just in case we switched to a new file
0123     fnb += ftree->Fill();
0124     fFile->Write("", TObject::kOverwrite);
0125 }
0126 
0127 void RootIO::Close() {
0128     G4cout << " Closing File: "  << G4endl;
0129     fFile = ftree->GetCurrentFile();
0130     fFile->Close();
0131 }
0132 
0133 void RootIO::Merge() {
0134     if (G4Threading::IsMasterThread()) {
0135         unsigned int nthreads = G4RunManager::GetRunManager()->GetNumberOfThreads();
0136         G4cout << "RootIO::Merging: " << nthreads << " threads" << G4endl;
0137         G4String filename = ConfigurationManager::getInstance()->getfname();
0138         G4String tmpfn;
0139         std::vector<TFile*> filevec;
0140         std::vector<Event*> evtvec;
0141         std::vector<TTree*> treevec;
0142         std::vector<TBranch*> branchvec;
0143         TList* list = new TList;
0144         TTree* newtree;
0145         for (unsigned int i = 0; i < nthreads; i++) {
0146             tmpfn = filename + "_Thread_" + std::to_string(i) + ".root";
0147             filevec.push_back(new TFile(tmpfn.c_str()));
0148             treevec.push_back((TTree*) (filevec[i]->Get("Events")));
0149             list->Add(treevec[i]);
0150             if (i == nthreads - 1) {
0151                 G4String tmpfn2 = filename + "_Merged.root";
0152                 TFile* fm = new TFile(tmpfn2.c_str(), "RECREATE");
0153                 newtree = TTree::MergeTrees(list);
0154                 newtree->SetName("Events");
0155                 Event* eventm = new Event();
0156                 newtree->SetBranchAddress("event.", &eventm);
0157                 TBranch* fevtbranchm = newtree->GetBranch("event.");
0158                 int neventm = fevtbranchm->GetEntries();
0159                 G4cout << "Nr. of Events:  " << neventm << G4endl;
0160                 newtree->Write();
0161                 fm->Close();
0162             }
0163         }
0164         for (unsigned int i = 0; i < nthreads; i++) {
0165             tmpfn = filename + "_Thread_" + std::to_string(i) + ".root";
0166             if (remove(tmpfn.c_str()) != 0) {
0167                 G4cout << "Error deleting file: " << tmpfn << G4endl;
0168             } else {
0169                 G4cout << "File: " << tmpfn << " successfully deleted" << G4endl;
0170             }
0171         }
0172     }
0173 }
0174 #endif