GGS(GenericGEANT4Simulation)Software  2.6.0
 All Data Structures Namespaces Files Functions Variables Typedefs Macros
GGSRootFileService.cpp
1 /*
2  * GGSRootFileService.cpp
3  *
4  * Created on: 03 Jun 2011
5  * Author: Nicola Mori
6  */
7 
8 #include "utils/GGSSmartLog.h"
11 #include "montecarlo/dataobjs/GGSTHitVolInfo.h"
14 
15 #include "G4SystemOfUnits.hh"
16 #include "G4LogicalVolume.hh"
17 
18 #include "TTree.h"
19 
20 #include <sstream>
21 
22 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
23 
24 GGSRootFileService::FileInfo::FileInfo() :
25  absBaseName(""), filePtr(NULL), defaultEventsTree(NULL), nRequests(0), detectorsMap(NULL), detectorsArray(NULL) {
26 
27 }
28 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
29 
31  static GGSRootFileService instance;
32  return instance;
33 }
34 
35 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
36 
37 GGSRootFileService::GGSRootFileService() :
38  _suffix(""), _defaultOutBase("GGSRootOutput"), _currVolStorageFile(
39  NULL) {
40 }
41 
42 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
43 
45  for (FileInfoContainer::iterator iter = _files.begin(); iter != _files.end(); iter++)
46  if (iter->filePtr != NULL) {
47  iter->filePtr->Close();
48  delete iter->filePtr;
49  }
50 }
51 
52 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
53 
54 #include "G4Run.hh"
55 TFile* GGSRootFileService::GetFileForThisRun(const path &baseName, const G4Run *run) {
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 }
107 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
108 
109 void GGSRootFileService::CloseFileForThisRun(const path &baseName) {
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 }
140 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
141 
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 }
155 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
156 
157 path GGSRootFileService::_GetAbsolutePath(const path &baseName) {
158 
159  path absBaseName(baseName);
160 
161  absBaseName = absolute(baseName);
162 
163  return absBaseName;
164 }
165 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
166 
167 TString GGSRootFileService::_AppendSuffixAndExt(const path &baseName, const G4Run *run) {
168 
169  int runID = run->GetRunID();
170 
171  path fileName(baseName);
172  fileName.replace_extension(); // Remove the extension
173  TString newFileName = fileName.string();
174 
175  // if runID > 0 append _RunID
176  if (runID > 0) {
177  newFileName += "_Run";
178  newFileName.Form(newFileName + "%i", runID);
179  }
180 
181  // Append suffix
182  if (_suffix != "")
183  newFileName = newFileName + "_" + _suffix;
184 
185  // Append extension
186  newFileName += ".root";
187 
188  return newFileName;
189 }
190 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
191 
192 void GGSRootFileService::_FillDefaultEventsTrees() {
193  for (FileInfoContainer::iterator iter = _files.begin(); iter != _files.end(); iter++) {
194  if (iter->filePtr && iter->defaultEventsTree) {
195  iter->filePtr->cd();
196  iter->defaultEventsTree->Fill();
197  }
198  }
199 }
200 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
201 
202 int GGSRootFileService::StoreVolume(TFile *filePtr, const std::string &detector, const G4VPhysicalVolume *volume,
203  const G4ThreeVector &position, int id) {
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 }
284 
285 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
TFile * GetFileForThisRun(const path &baseName, const G4Run *run)
Opens a file for a given run and returns a pointer to it.
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.
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 CloseFileForThisRun(const path &baseName)
Closes the ROOT output file.
void SetStringGeoParams(const std::map< std::string, std::string > &stringGeoParams)
Sets the string geometry parameters.
#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
int StoreVolume(TFile *filePtr, const std::string &detector, const G4VPhysicalVolume *volume, const G4ThreeVector &position, int id)
Set persistence for the specified volume.
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.
TClonesArray volumes
Array of GGSTHitVolInfo objects.
Singleton for a centralized ROOT files management.
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
TTree * GetDefaultTree(TFile *file)
Gets the default tree for this file.
static GGSRootFileService & GetInstance()
Get reference to GGSRootFileService unique instance.
TString volumeName
Name of the physical volume.
GGSVGeometryConstruction * GetGeoConstruction()
Returns the geometry construction object.
void SetBoolGeoParams(const std::map< std::string, bool > &boolGeoParams)
Sets the boolean geometry parameters.
~GGSRootFileService()
Destructor.
GGSTHitVolInfo.h GGSTHitVolInfo class declaration.
TString detectorName
Name of detector associated to integrated hits.
void SetIntGeoParams(const std::map< std::string, int > &intGeoParams)
Sets the integer geometry parameters.