GGS(GenericGEANT4Simulation)Software  2.6.0
 All Data Structures Namespaces Files Functions Variables Typedefs Macros
Data Structures | Public Member Functions | Static Public Member Functions | Friends
GGSRootFileService Class Reference

Singleton for a centralized ROOT files management. More...

#include <GGSRootFileService.h>

Public Member Functions

 ~GGSRootFileService ()
 Destructor.
 
TFile * GetFileForThisRun (const path &baseName, const G4Run *run)
 Opens a file for a given run and returns a pointer to it. More...
 
void CloseFileForThisRun (const path &baseName)
 Closes the ROOT output file. More...
 
TTree * GetDefaultTree (TFile *file)
 Gets the default tree for this file. More...
 
void SetSuffix (const std::string &suffix)
 Sets the suffix for file names. More...
 
void SetDefaultFileBase (const path &newFileBase)
 Sets the default file name. More...
 
int StoreVolume (TFile *filePtr, const std::string &detector, const G4VPhysicalVolume *volume, const G4ThreeVector &position, int id)
 Set persistence for the specified volume. More...
 
void SetSimInfo (const GGSTSimInfo &simInfo)
 Set the simulation info object to be saved on output files. More...
 

Static Public Member Functions

static GGSRootFileServiceGetInstance ()
 Get reference to GGSRootFileService unique instance. More...
 

Friends

class GGSUserActionsManager
 
std::size_t hash_value (const VolumeKey &key)
 

Detailed Description

Singleton for a centralized ROOT files management.

The aim of this class is to provide a centralized management for ROOT output files. For each run, the singleton will provide pointers to output file to the action which may require them with the GetFileForThisRun method. The purpose of this is to allow multiple actions to write on the same ROOT file, avoiding the proliferation of output files when many actions are in use. Typically, the singleton will create a file the first time that file is requested; if subsequently other actions require the same file, the singleton will not open it again, but it will simply return a pointer to the already opened file. Consistently, file closure requests issued by calling CloseFileForThisRun will be ignored until no more actions require that file. Users wishing to use this service in their actions are demanded to call GetFileForThisRun in BeginOfRunAction to get the file and to close it with CloseFileForThisRun in EndOfRunAction. The service also provides a standard TTree called GGSEventsTree to let actions save their event data in different branches of the same tree rather than in different trees. This helps I/O performance. See GetDefaultTree.

Definition at line 46 of file GGSRootFileService.h.

Member Function Documentation

void GGSRootFileService::CloseFileForThisRun ( const path &  baseName)

Closes the ROOT output file.

The closure request is handled this way: if a file has been requested N times, it will be closed when this method is called for the N-th time. This will avoid to close the file when other actions may still need it.

WARNING: when a ROOT file is closed, all the TTree objects associated to it will be automatically deleted. User must NOT delete its trees before calling this method. Eg.:

outRootFile->cd(); outTree->Write(); GGSRootFileService::GetInstance().CloseFileForThisRun(outBase); //delete outTree; // Uncommenting this will generate a segfault

Parameters
baseNameThe file base name.

Definition at line 109 of file GGSRootFileService.cpp.

109  {
110 
111  path absBaseName;
112 
113  // Set default if no base name has been provided
114  if (baseName.string() == "") {
115  absBaseName = _defaultOutBase;
116  }
117  else
118  absBaseName = baseName;
119  absBaseName = _GetAbsolutePath(absBaseName);
120 
121  for (FileInfoContainer::iterator iter = _files.begin(); iter != _files.end(); iter++)
122  if (iter->absBaseName == absBaseName) {
123  if (iter->nRequests > 1) {
124  iter->nRequests--;
125  return;
126  }
127  else {
128  iter->filePtr->cd();
129  if (iter->defaultEventsTree)
130  iter->defaultEventsTree->Write();
131  if (iter->detectorsArray)
132  iter->detectorsArray->Write("GGSHitDetInfo", TObject::kSingleKey); // Automatically set iter->detectorsArray ownership to iter->filePtr
133  iter->filePtr->Close();
134  delete iter->filePtr;
135  delete iter->detectorsMap;
136  iter = _files.erase(iter);
137  }
138  }
139 }
TTree * GGSRootFileService::GetDefaultTree ( TFile *  file)

Gets the default tree for this file.

This method returns the default events tree for the specified file. This is intended to allow user actions to write their output as branches of the same tree instead of using a tree for each action. In this way the best performance of the I/O system of ROOT can be exploited (see https://twiki.cern.ch/twiki/bin/view/LHCb/PersistencyMigration#POOL). The Fill() and Write() operations for the default tree are managed by GGSRootFileService. The only operation that can be done with the tree is the creation of a branch. Explicitly calling Fill() or Write() for the default tree in user actions will result in a wrong number of events and in multiple keys for the tree in the output file. Fill() will be automatically called at the end of each event after calling EndOfEventAction() for every user action.

Different default trees can be requested for different files.

Parameters
fileThe file on which the default tree will be saved. This file pointer must have been previously retrieved by calling GetFileForThisRun; DON'T use a file created in any other way.
Returns
a pointer to the default tree, NULL if file has not been created by GetFileForThisRun.

Definition at line 142 of file GGSRootFileService.cpp.

142  {
143 
144  for (FileInfoContainer::iterator iter = _files.begin(); iter != _files.end(); iter++) {
145  if (file == iter->filePtr) {
146  if (iter->defaultEventsTree == NULL) {
147  iter->filePtr->cd();
148  iter->defaultEventsTree = new TTree("GGSEventsTree", "GGS events tree. Info: ");
149  }
150  return iter->defaultEventsTree;
151  }
152  }
153  return NULL;
154 }
TFile * GGSRootFileService::GetFileForThisRun ( const path &  baseName,
const G4Run *  run 
)

Opens a file for a given run and returns a pointer to it.

This method will open a file for a given run and return a pointer to it; if the file is already opened, it will simply return the pointer without attempting to open it again. The created file will be named baseName.root for run 0 (eventually baseName_suffix.root if a suffix is specified calling SetSuffix); for subsequent runs, it will be named baseName_RunID.root (or baseName_RunID_suffix.root).

Parameters
baseNameThe file base name (.root extension, run ID and suffix will be (eventually) automatically appended). If no name is provided, the default one ("GGSRootOutput") will be used (it can also be set with SetDefaultFileBase).
runThe current run.
Returns
Pointer to the (eventually opened) output ROOT file.

Definition at line 55 of file GGSRootFileService.cpp.

55  {
56 
57  path absBaseName;
58 
59  // Set default if no base name has been provided
60  if (baseName.string() == "") {
61  absBaseName = _defaultOutBase;
62  }
63  else
64  absBaseName = baseName;
65 
66  // Retrieve absolute path
67  absBaseName = _GetAbsolutePath(absBaseName);
68 
69  // check if the file is already opened
70  for (FileInfoContainer::iterator iter = _files.begin(); iter != _files.end(); iter++)
71  if (absBaseName == iter->absBaseName) {
72  iter->nRequests++;
73  return iter->filePtr;
74  }
75 
76  // Create new file info struct
77  FileInfo fInfo;
78  fInfo.nRequests = 1;
79  fInfo.absBaseName = absBaseName;
80 
81  // Strip extension and append suffix and extension
82  TString absFileName = _AppendSuffixAndExt(absBaseName, run);
83 
84  // Open file and store it
85  fInfo.filePtr = new TFile(absFileName, "RECREATE");
86  _files.push_back(fInfo);
87 
88  // Write simulation informations
89  _simInfo.Write();
90 
91  // Write geometry informations
93  GGSTGeoParams geoParams;
94  geoParams.SetIntGeoParams(geoCons->GetIntParameters());
95  geoParams.SetBoolGeoParams(geoCons->GetBoolParameters());
96  geoParams.SetRealGeoParams(geoCons->GetRealParameters());
97  geoParams.SetStringGeoParams(geoCons->GetStringParameters());
98  geoParams.Write("GGSGeoParams");
99 
100  // Set storage of detector to null values to force proper initialization in StoreVolume
101  _currVolStorageFile = NULL;
102  _currDetVolName = "";
103 
104  return fInfo.filePtr;
105 
106 }
const std::map< std::string, int > & GetIntParameters()
Getter method for integer geometry parameters.
const std::map< std::string, double > & GetRealParameters()
Getter method for real geometry parameters.
Abstract class needed to load GGS geometry.
static GGSGeoPluginManager & GetInstance()
Get the singleton instance.
void SetStringGeoParams(const std::map< std::string, std::string > &stringGeoParams)
Sets the string geometry parameters.
void SetRealGeoParams(const std::map< std::string, double > &realGeoParams)
Sets the real geometry parameters.
const std::map< std::string, std::string > & GetStringParameters()
Getter method for string geometry parameters.
const std::map< std::string, bool > & GetBoolParameters()
Getter method for boolean geometry parameters.
Class for storing the geometry parameters on Root output file.
Definition: GGSTGeoParams.h:18
GGSVGeometryConstruction * GetGeoConstruction()
Returns the geometry construction object.
void SetBoolGeoParams(const std::map< std::string, bool > &boolGeoParams)
Sets the boolean geometry parameters.
void SetIntGeoParams(const std::map< std::string, int > &intGeoParams)
Sets the integer geometry parameters.
GGSRootFileService & GGSRootFileService::GetInstance ( )
static

Get reference to GGSRootFileService unique instance.

Returns
reference to the root file service.

Definition at line 30 of file GGSRootFileService.cpp.

30  {
31  static GGSRootFileService instance;
32  return instance;
33 }
Singleton for a centralized ROOT files management.
void GGSRootFileService::SetDefaultFileBase ( const path &  newFileBase)
inline

Sets the default file name.

The default file name is used when a file is requested by calling GetFileForThisRun but no file name is provided.

Parameters
newFileBaseThe new default file base name (optionally with path).

Definition at line 124 of file GGSRootFileService.h.

124  {
125  _defaultOutBase = newFileBase;
126  }
void GGSRootFileService::SetSimInfo ( const GGSTSimInfo simInfo)
inline

Set the simulation info object to be saved on output files.

Parameters
simInfoThe object containing informations about the simulation.

Definition at line 151 of file GGSRootFileService.h.

151  {
152  _simInfo = simInfo;
153  }
void GGSRootFileService::SetSuffix ( const std::string &  suffix)
inline

Sets the suffix for file names.

The suffix will be appended after just before the .root extension.

Parameters
suffixThe suffix.

Definition at line 114 of file GGSRootFileService.h.

114  {
115  _suffix = suffix;
116  }
int GGSRootFileService::StoreVolume ( TFile *  filePtr,
const std::string &  detector,
const G4VPhysicalVolume *  volume,
const G4ThreeVector &  position,
int  id 
)

Set persistence for the specified volume.

The specified volume (volume name, position and id) will be saved as a GGSTHitVolInfo object inside the GGSTHitDetInfo object corresponding to the specified detector. The GGSTHitDetInfo is saved as an element of a TClonesArray called GGSHitDetArray inside the specified file.

The (volume name, id) pair must be unique for each volume to be stored.

Parameters
filePtrThe file where to save the informations about detectors and volumes.
detectorThe name of the detector.
volumeThe pointer to the physical volume.
positionThe position of the volume (in internal G4 units; will be saved in [cm]).
idThe ID of the volume (see GGSTHitVolInfo).
Returns
The position of the volume in the store.
See Also
GGSTHitVolInfo

Definition at line 202 of file GGSRootFileService.cpp.

203  {
204  static const std::string routineName("GGSRootFileService::StoreVolume");
205 
206  std::string detVolName = detector.substr(0, detector.find_first_of('.'));
207 
208  // 1. Retrieve file info structure
209  bool fileChanged = false;
210  if (filePtr != _currVolStorageFile) {
211  fileChanged = true;
212  _currVolStorageFile = filePtr;
213  for (_currVolStorageFileInfo = _files.begin(); _currVolStorageFileInfo != _files.end(); _currVolStorageFileInfo++) {
214  if (_currVolStorageFileInfo->filePtr == filePtr)
215  break;
216  }
217  if (_currVolStorageFileInfo == _files.end()) {
218  COUT(WARNING) << "The requested file is not managed by GGSRootFileService. Volume informations will not be saved."
219  << ENDL;
220  return -1;
221  }
222  }
223 
224  // 2. Find the detector in the index
225  static HitDetMap::iterator currDetector;
226  static GGSTHitDetInfo *currPersDetector = NULL;
227  if (fileChanged || _currDetVolName != detVolName) {
228  if (_currVolStorageFileInfo->detectorsMap == NULL)
229  _currVolStorageFileInfo->detectorsMap = new HitDetMap;
230  _currDetVolName = detVolName;
231  int currPersDetectorIndex = 0;
232  for (currDetector = _currVolStorageFileInfo->detectorsMap->begin();
233  currDetector != _currVolStorageFileInfo->detectorsMap->end(); currDetector++, currPersDetectorIndex++) {
234  if (currDetector->first == _currDetVolName)
235  break;
236  }
237  if (currDetector == _currVolStorageFileInfo->detectorsMap->end()) {
238  // 2.1 Detector not found. Create it both in index and persistence array
239  _currVolStorageFileInfo->detectorsMap->push_back(std::pair<std::string, HitVolMap>(_currDetVolName, HitVolMap()));
240  currDetector = _currVolStorageFileInfo->detectorsMap->end(); // Past-the-end iterator
241  currDetector--; // Set the iterator to the last element
242  if (_currVolStorageFileInfo->detectorsArray == NULL) {
243  _currVolStorageFileInfo->detectorsArray = new TClonesArray("GGSTHitDetInfo");
244  }
245  currPersDetectorIndex = _currVolStorageFileInfo->detectorsArray->GetEntries(); // Redundant
246  currPersDetector = new ((*(_currVolStorageFileInfo->detectorsArray))[currPersDetectorIndex]) GGSTHitDetInfo;
247  currPersDetector->detectorName = _currDetVolName.data();
248  }
249  else {
250  // 2.2 Detector found. Set the current persistent detector
251  currPersDetector = (GGSTHitDetInfo*) (_currVolStorageFileInfo->detectorsArray->At(currPersDetectorIndex));
252  }
253  }
254 
255  // 3. Insert the volume in the index and in the persistency structure
256 
257  // Append volume ID to volume name to avoid placing all the replicated volumes at the same place in the index
258  static std::stringstream ss;
259  ss.str("");
260  ss << id;
261  std::string volAndId = volume->GetName() + ss.str();
262 
263  std::pair<VolumeKey, G4int> insertValue(VolumeKey(volAndId, volume, position),
264  currPersDetector->volumes.GetEntries());
265  std::pair<HitVolMap::iterator, bool> insertResult;
266  insertResult = currDetector->second.insert(insertValue); // TODO: using emplace instead of insert would improve speed?
267  if (insertResult.second) {
268  // 3.1 No hash collision: this is a new volume. Add it also to the volumes array in detector object...
269  GGSTHitVolInfo *volInfo = new ((currPersDetector->volumes)[currPersDetector->volumes.GetEntries()]) GGSTHitVolInfo;
270  volInfo->volumeName = volume->GetName().data();
271  for (int i = 0; i < 3; i++) {
272  volInfo->volumePos[i] = position[i] / cm;
273  }
274  volInfo->id = id;
275  // ... then return its position in the array
276  return currPersDetector->volumes.GetEntries() - 1;
277  }
278  else {
279  // 3.2 A hash collision has happened: the volume is already present. So take its position from the index
280  return insertResult.first->second;
281  }
282 
283 }
Float_t volumePos[3]
Position of the touchable in world volume coordinates [cm].
Int_t id
ID of the volume.
Class to store detector informations.
#define ENDL
Definition: GGSSmartLog.h:93
#define COUT(level)
Smart log macro. It writes on stdout only if the specified verbosity level is lesser than the maximum...
Definition: GGSSmartLog.h:66
TClonesArray volumes
Array of GGSTHitVolInfo objects.
TString volumeName
Name of the physical volume.
GGSTHitVolInfo.h GGSTHitVolInfo class declaration.
TString detectorName
Name of detector associated to integrated hits.

The documentation for this class was generated from the following files: