Analysis Reader Classes

The analysis reader classes allow to read in g4analysis objects from the files generated by the analysis manager(s) during processing Geant4 application.

An analysis reader class is available for each supported output format:

  • G4CsvAnalysisReader

  • G4Hdf5AnalysisReader

  • G4RootAnalysisReader

  • G4XmlAnalysisReader

For a simplicity of use, each analysis reader provides the complete access to all interfaced functions though it is implemented via a more complex design. This design allows the user to use all output technologies in an identical way via a generic G4AnalysisReder type defined as:

  • using G4AnalysisReder = G4XyzAnalysisReader;

    where Xyz = Csv, Hdf5, Root, Xml

The readers are implemented as Geant4 singletons. User code will access a pointer to a single instance of the desired reader object. The reader is created with the first call to the Instance() function and it is deleted by Geant4 kernel at the end of a user application. All objects created via analysis reader are deleted automatically with the manager.

While the histograms and profiles objects handled by the analysis reader are of the same type as those handled by the analysis manager, the reader’s ntuple type is different.

All objects read with G4AnalysisReader (histograms, profiles and ntuples) get automatically attributed an integer identifier which value is returned from the “Read” or “GetNtuple” function. The default start value is 0 and it is incremented by 1 for each next created object. The numbering each object type is independent from other objects types and also from the numbering of the same object type in analysis manager. The start identifier value can be changed in the same way as with the analysis manager (see Creating Histograms).

The read objects can be accessed in the analysis reader via their integer identifiers or by their names in the same way as in the analysis manager (see Accessing Analysis Objects). Note that the type of read ntuple is different from the ntuple type in the analysis manager.

The specific manager classes are singletons and so it is not possible to create more than one instance of an analysis reader of one type, e.g. G4RootAnalysisReader. However two analysis reader objects of different types can coexist.

As well as all other Geant4 categories, the analysis code has been adapted for multi-threading. In multi-threading mode, the analysis reader instances are internally created on the master or thread workers, depending on the client code call, and data reading can be processed in parallel on workers threads.

Analysis Reader

For reading in the output files created with G4AnalysisManager, an instance of the analysis reader must be created. The analysis reader object is created with the first call to G4AnalysisReader::Instance() the next calls to this function will just provide the pointer to this analysis manager object.

The example of the code for creating the analysis reader for the Root output type is given below:

#include "G4RootAnalysisReader.hh"

using G4AnalysisReader = G4RootAnalysisReader;

// Create (or get) analysis reader
auto analysisReader = G4AnalysisReader::Instance();
analysisReader->SetVerboseLevel(1);

The using declaration defines the G4RootAnalysisReader as G4AnalysisReader type.

The level of informative printings can be set by SetVerboseLevel(G4int). Currently the levels from 0 (default) up to 4 are supported.

File handling

The name of file to be read can be specified either via G4AnalysisReader::SetFileName() function, or directly when reading an object. It is possible to change the base file name at any time. The analysis reader can handle more than one file at same time.

auto analysisReader = G4AnalysisReader::Instance();
// Define a base file name
analysisReader->SetFileName("MyFileName");

The following functions are defined for handling files:

void SetFileName(const G4String& fileName);
G4String GetFileName() const;

A file is open only when any “Read” function is called. When more objects are read from the same file (Xml, Root), the file is open only once. When reading an object without specifying the file name explicitly in “Read” call, the object is searched in all open files in the order of their creation time.

Histograms and Profiles

In the following example the code for reading an histogram is presented.

// Code to create (or get) analysis reader
auto analysisReader = G4AnalysisReader::Instance();

// Define a base file name
analysisReader->SetFileName("MyFileName");

// Read 1D histogram of "Edep" name
G4int h1Id = analysisReader->ReadH1("Edep");
if ( h1Id >= 0 ) {
  G4H1* h1 = analysisReader->GetH1(h1Id);
  if ( h1 ) {
    G4cout << "   H1: "
           << "   mean: " << h1->mean() << " rms: " << h1->rms() << G4endl;
  }
}

The histograms and profiles can be read with these G4AnalysisReader functions:

G4int ReadH1(const G4String& h1Name, const G4String& fileName = "");
G4int ReadH2(const G4String& h2Name, const G4String& fileName = "");
G4int ReadH3(const G4String& h3Name, const G4String& fileName = "");
G4int ReadP1(const G4String& h1Name, const G4String& fileName = "");
G4int ReadP2(const G4String& h2Name, const G4String& fileName = "");

where hNname is the name of the object to be read from a file. The file name can be defined explicitly for each reading object.

All histograms and profiles created by G4AnalysisReader are automatically deleted with deleting the G4AnalysisReader object in the end of the application.

Ntuples

In the following example the code for reading ntuples is presented.

// Code to create (or get) analysis reader
auto analysisReader = G4AnalysisReader::Instance();

// Define a base file name
analysisReader->SetFileName("MyFileName");

// Read ntuple
G4int ntupleId = analysisReader->GetNtuple("TrackL");;
if ( ntupleId >= 0 ) {
  G4double trackL;
  analysisReader->SetNtupleDColumn("Labs", trackL);
  G4cout << "Ntuple TrackL, reading selected column Labs" << G4endl;
  while ( analysisReader->GetNtupleRow() ) {
      G4cout << counter++ << "th entry: "
             << "  TrackL: " << trackL << std::endl;
  }
}

When the ntuple columns are associated with the variables of the appropriate type, the ntuple they can be read in a loop with GetNtupleRow() function. The function returns true until all data are read in.

An overview of all available functions for ntuple reading is given below:

// Methods to read ntuple from a file
G4int GetNtuple(const G4String& ntupleName, const G4String& fileName = "");

// Methods for ntuple with id = FirstNtupleId
G4bool SetNtupleXColumn(const G4String& columnName, Xtype& value);
G4bool SetNtupleXColumn(const G4String& columnName, std::vector<Xtype>& vector);
G4bool GetNtupleRow();

// Methods for ntuple with id > FirstNtupleId
G4bool SetNtupleXColumn(G4int ntupleId,
                        const G4String& columnName, Xtype& value);
G4bool SetNtupleXColumn(G4int ntupleId,
                        const G4String& columnName, std::vector<Xtype>& vector);
G4bool GetNtupleRow(G4int ntupleId);

where [X, Xtype] in SetNtupleXColumn() can be [I, G4int], [F, G4float], [D, G4double] or [S, G4String].

All ntuples and ntuple columns created by G4AnalysisReader are automatically deleted with deleting the G4AnalysisReader object in the end of the application.