// ExR05RootPersistency.cc // 29-Sep-2000 Bill Seligman // This is an example class for booking histograms of hit information // in GEANT4. #include "ExR05RootPersistency.hh" // Include files for ROOT. #include "Rtypes.h" #include "TROOT.h" #include "TFile.h" #include "TTree.h" // Needed to convert numbers to strings #include #include // Include files for the G4 classes #include "globals.hh" #include "G4Run.hh" #include "G4Event.hh" // Classes needed for access to convert events. #include "ExR05PersistentRootEvent.hh" ExR05RootPersistency::ExR05RootPersistency() { // Since we're not creating the TROOT object in the same scope as we're // creating our histogram objects, we must declare it to be static. // Otherwise, the TROOT object will go away when the constructor is over. // Note: an alternative would be to create rootBase in the main program // (exampleR05.cc). But if we did that, the main program would "know" that // ROOT is being used to make histograms (as opposed to HBOOK, LHC++, etc.). // I'd rather keep that information internal to this class. static TROOT rootBase("simple","Test of ROOT persistent I/O"); // Open a new ROOT file. m_rootFile = new TFile("exampleR05.root","RECREATE","Demo ROOT file with eventss"); } ExR05RootPersistency::~ExR05RootPersistency() { // Close the file. Note that this is automatically done when you leave // the application. m_rootFile->Close(); // We created the file with "new", so we have to destroy it with "delete": delete m_rootFile; } void ExR05RootPersistency::RecordBeginOfRun(const G4Run* a_run) { // Create a new tree for each run. // Note the use of ROOT data types as arguments to the ROOT method. // Need "char*" because ROOT doesn't know about STL strings, only // const char*. char* title; // Create a histogram name that changes with the run number. ostrstream convert2str; // "ends" is the ostrsteam equivalent of "endl"; that is, it ends the string. convert2str << "Tree" << a_run->GetRunID() << std::ends; // The str() method of the ostrstream class converts a (ostrstream) into a (string). string treeName = convert2str.str(); // The following obscure statement "thaws" the ostrstream so that it is deleted // when this method finishes. convert2str.rdbuf()->freeze(0); // The c_str() method of the string class converts a (string) into a (const char *). m_tree = new TTree(treeName.c_str(), title = "Set of events for one run"); // Create a branch within the Tree for each event. char* branchName; char* className; m_rootEvent = 0; // Initial branch with null event. // If we didn't supply the argument, the buffer size is 64 MB. This // is huge compare to the size of our classes, so I'll shrink it for // this example. Int_t bufferSize; // if splitlevel=0, the object is serialized in the branch buffer. // if splitlevel=1 (default), this branch will automatically be split // into subbranches, with one subbranch for each data member or object // of the object itself. In case the object member is a TClonesArray, // the mechanism described in case C is applied to this array. // if splitlevel=2 ,this branch will automatically be split // into subbranches, with one subbranch for each data member or object // of the object itself. In case the object member is a TClonesArray, // it is processed as a TObject*, only one branch. Int_t splitLevel; m_tree->Branch(branchName = "event", className = "ExR05RootEvent", &m_rootEvent, bufferSize = 32000, splitLevel = 1); } void ExR05RootPersistency::RecordEndOfRun(const G4Run* a_run) { // Save the histogram, then delete it. m_rootFile->Write(); delete m_tree; } void ExR05RootPersistency::RecordEndOfEvent(const G4Event* a_event) { // Convert a G4 event into a ROOT-compatible event. m_rootEvent = new ExR05PersistentRootEvent(a_event); // Write the event. m_tree->Fill(); // We don't need the converted event anymore. delete m_rootEvent; }