GGS(GenericGEANT4Simulation)Software  2.7.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 
13 #include "montecarlo/dataobjs/GGSTHitVolInfo.h"
14 #include "montecarlo/dataobjs/GGSTParameters.h"
15 #include "utils/GGSSmartLog.h"
16 
17 #include "G4LogicalVolume.hh"
18 #include "G4SystemOfUnits.hh"
19 
20 #include "TTree.h"
21 
22 #include <sstream>
23 
24 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
25 
26 GGSRootFileService::FileInfo::FileInfo()
27  : absBaseName(""), filePtr(NULL), defaultEventsTree(NULL), nRequests(0), detectorsMap(NULL), detectorsArray(NULL) {}
28 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
29 
31  static GGSRootFileService instance;
32  return instance;
33 }
34 
35 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
36 
37 GGSRootFileService::GGSRootFileService() : _suffix(""), _defaultOutBase("GGSRootOutput"), _currVolStorageFile(NULL) {}
38 
39 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
40 
42  for (FileInfoContainer::iterator iter = _files.begin(); iter != _files.end(); iter++)
43  if (iter->filePtr != NULL) {
44  iter->filePtr->Close();
45  delete iter->filePtr;
46  }
47 }
48 
49 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
50 
51 #include "G4Run.hh"
52 TFile *GGSRootFileService::GetFileForThisRun(const path &baseName, const G4Run *run) {
53 
54  path absBaseName;
55 
56  // Set default if no base name has been provided
57  if (baseName.string() == "") {
58  absBaseName = _defaultOutBase;
59  } else
60  absBaseName = baseName;
61 
62  // Retrieve absolute path
63  absBaseName = _GetAbsolutePath(absBaseName);
64 
65  // check if the file is already opened
66  for (FileInfoContainer::iterator iter = _files.begin(); iter != _files.end(); iter++)
67  if (absBaseName == iter->absBaseName) {
68  iter->nRequests++;
69  return iter->filePtr;
70  }
71 
72  // Create new file info struct
73  FileInfo fInfo;
74  fInfo.nRequests = 1;
75  fInfo.absBaseName = absBaseName;
76 
77  // Strip extension and append suffix and extension
78  TString absFileName = _AppendSuffixAndExt(absBaseName, run);
79 
80  // Open file and store it
81  fInfo.filePtr = new TFile(absFileName, "RECREATE");
82  _files.push_back(fInfo);
83 
84  // Write simulation informations
85  _simInfo.Write();
86 
87  // Write geometry informations
89  GGSTGeoParams geoParams;
90  geoParams.SetIntGeoParams(geoCons->GetIntParameters());
91  geoParams.SetBoolGeoParams(geoCons->GetBoolParameters());
92  geoParams.SetRealGeoParams(geoCons->GetRealParameters());
93  geoParams.SetStringGeoParams(geoCons->GetStringParameters());
94  geoParams.SetVectIntGeoParams(geoCons->GetVectIntParameters());
95  geoParams.SetVectBoolGeoParams(geoCons->GetVectBoolParameters());
96  geoParams.SetVectRealGeoParams(geoCons->GetVectRealParameters());
97  geoParams.SetVectStringGeoParams(geoCons->GetVectStringParameters());
98  geoParams.Write("GGSGeoParams");
99 
100  // Write generator informations
101  // These are written only for GGS generators that export a parameter object containing the "generator" name setting.
102  auto *genAction =
103  dynamic_cast<const GGSGeneratorAction *>(GGSRunManager::GetRunManager()->GetUserPrimaryGeneratorAction());
104  if (genAction) {
105  GGSTParameters generatorParams(genAction->GetParameters());
106  try {
107  generatorParams.GetParam<std::string>("generator"); // Throws if "generator" parameter is not present
108  generatorParams.Write("GGSGenParams");
109  } catch (...) {
110  }
111  }
112  // Set storage of detector to null values to force proper initialization in StoreVolume
113  _currVolStorageFile = NULL;
114  _currDetVolName = "";
115 
116  return fInfo.filePtr;
117 }
118 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
119 
120 void GGSRootFileService::CloseFileForThisRun(const path &baseName) {
121 
122  path absBaseName;
123 
124  // Set default if no base name has been provided
125  if (baseName.string() == "") {
126  absBaseName = _defaultOutBase;
127  } else
128  absBaseName = baseName;
129  absBaseName = _GetAbsolutePath(absBaseName);
130 
131  for (FileInfoContainer::iterator iter = _files.begin(); iter != _files.end(); iter++)
132  if (iter->absBaseName == absBaseName) {
133  if (iter->nRequests > 1) {
134  iter->nRequests--;
135  return;
136  } else {
137  iter->filePtr->cd();
138  if (iter->defaultEventsTree)
139  iter->defaultEventsTree->Write();
140  if (iter->detectorsArray)
141  iter->detectorsArray->Write(
142  "GGSHitDetInfo",
143  TObject::kSingleKey); // Automatically set iter->detectorsArray ownership to iter->filePtr
144  iter->filePtr->Close();
145  delete iter->filePtr;
146  delete iter->detectorsMap;
147  iter = _files.erase(iter);
148  }
149  }
150 }
151 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
152 
154 
155  for (FileInfoContainer::iterator iter = _files.begin(); iter != _files.end(); iter++) {
156  if (file == iter->filePtr) {
157  if (iter->defaultEventsTree == NULL) {
158  iter->filePtr->cd();
159  iter->defaultEventsTree = new TTree("GGSEventsTree", "GGS events tree. Info: ");
160  }
161  return iter->defaultEventsTree;
162  }
163  }
164  return NULL;
165 }
166 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
167 
168 path GGSRootFileService::_GetAbsolutePath(const path &baseName) {
169 
170  path absBaseName(baseName);
171 
172  absBaseName = absolute(baseName);
173 
174  return absBaseName;
175 }
176 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
177 
178 TString GGSRootFileService::_AppendSuffixAndExt(const path &baseName, const G4Run *run) {
179 
180  int runID = run->GetRunID();
181 
182  path fileName(baseName);
183  fileName.replace_extension(); // Remove the extension
184  TString newFileName = fileName.string();
185 
186  // if runID > 0 append _RunID
187  if (runID > 0) {
188  newFileName += "_Run";
189  newFileName.Form(newFileName + "%i", runID);
190  }
191 
192  // Append suffix
193  if (_suffix != "")
194  newFileName = newFileName + "_" + _suffix;
195 
196  // Append extension
197  newFileName += ".root";
198 
199  return newFileName;
200 }
201 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
202 
203 void GGSRootFileService::_FillDefaultEventsTrees() {
204  for (FileInfoContainer::iterator iter = _files.begin(); iter != _files.end(); iter++) {
205  if (iter->filePtr && iter->defaultEventsTree) {
206  iter->filePtr->cd();
207  iter->defaultEventsTree->Fill();
208  }
209  }
210 }
211 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
212 
213 int GGSRootFileService::StoreVolume(TFile *filePtr, const std::string &detector, const G4VPhysicalVolume *volume,
214  const G4ThreeVector &position, int id) {
215  static const std::string routineName("GGSRootFileService::StoreVolume");
216 
217  std::string detVolName = detector.substr(0, detector.find_first_of('.'));
218 
219  // 1. Retrieve file info structure
220  bool fileChanged = false;
221  if (filePtr != _currVolStorageFile) {
222  fileChanged = true;
223  _currVolStorageFile = filePtr;
224  for (_currVolStorageFileInfo = _files.begin(); _currVolStorageFileInfo != _files.end(); _currVolStorageFileInfo++) {
225  if (_currVolStorageFileInfo->filePtr == filePtr)
226  break;
227  }
228  if (_currVolStorageFileInfo == _files.end()) {
229  COUT(WARNING) << "The requested file is not managed by GGSRootFileService. Volume informations will not be saved."
230  << ENDL;
231  return -1;
232  }
233  }
234 
235  // 2. Find the detector in the index
236  static HitDetMap::iterator currDetector;
237  static GGSTHitDetInfo *currPersDetector = NULL;
238  if (fileChanged || _currDetVolName != detVolName) {
239  if (_currVolStorageFileInfo->detectorsMap == NULL)
240  _currVolStorageFileInfo->detectorsMap = new HitDetMap;
241  _currDetVolName = detVolName;
242  int currPersDetectorIndex = 0;
243  for (currDetector = _currVolStorageFileInfo->detectorsMap->begin();
244  currDetector != _currVolStorageFileInfo->detectorsMap->end(); currDetector++, currPersDetectorIndex++) {
245  if (currDetector->first == _currDetVolName)
246  break;
247  }
248  if (currDetector == _currVolStorageFileInfo->detectorsMap->end()) {
249  // 2.1 Detector not found. Create it both in index and persistence array
250  _currVolStorageFileInfo->detectorsMap->push_back(std::pair<std::string, HitVolMap>(_currDetVolName, HitVolMap()));
251  currDetector = _currVolStorageFileInfo->detectorsMap->end(); // Past-the-end iterator
252  currDetector--; // Set the iterator to the last element
253  if (_currVolStorageFileInfo->detectorsArray == NULL) {
254  _currVolStorageFileInfo->detectorsArray = new TClonesArray("GGSTHitDetInfo");
255  }
256  currPersDetectorIndex = _currVolStorageFileInfo->detectorsArray->GetEntries(); // Redundant
257  currPersDetector = new ((*(_currVolStorageFileInfo->detectorsArray))[currPersDetectorIndex]) GGSTHitDetInfo;
258  currPersDetector->detectorName = _currDetVolName.data();
259  } else {
260  // 2.2 Detector found. Set the current persistent detector
261  currPersDetector = (GGSTHitDetInfo *)(_currVolStorageFileInfo->detectorsArray->At(currPersDetectorIndex));
262  }
263  }
264 
265  // 3. Insert the volume in the index and in the persistency structure
266 
267  // Append volume ID to volume name to avoid placing all the replicated volumes at the same place in the index
268  static std::stringstream ss;
269  ss.str("");
270  ss << id;
271  std::string volAndId = volume->GetName() + ss.str();
272 
273  std::pair<VolumeKey, G4int> insertValue(VolumeKey(volAndId, volume, position),
274  currPersDetector->volumes.GetEntries());
275  std::pair<HitVolMap::iterator, bool> insertResult;
276  insertResult = currDetector->second.insert(insertValue); // TODO: using emplace instead of insert would improve speed?
277  if (insertResult.second) {
278  // 3.1 No hash collision: this is a new volume. Add it also to the volumes array in detector object...
279  GGSTHitVolInfo *volInfo = new ((currPersDetector->volumes)[currPersDetector->volumes.GetEntries()]) GGSTHitVolInfo;
280  volInfo->volumeName = volume->GetName().data();
281  for (int i = 0; i < 3; i++) {
282  volInfo->volumePos[i] = position[i] / cm;
283  }
284  volInfo->id = id;
285  // ... then return its position in the array
286  return currPersDetector->volumes.GetEntries() - 1;
287  } else {
288  // 3.2 A hash collision has happened: the volume is already present. So take its position from the index
289  return insertResult.first->second;
290  }
291 }
292 
293 //....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.
const std::map< std::string, std::vector< bool > > & GetVectBoolParameters()
Getter method for vector-of-booleans geometry parameters.
void SetVectBoolGeoParams(const std::map< std::string, std::vector< bool >> &vectBoolGeoParams)
Sets the vector-of-booleans geometry parameters.
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.
Base class for GGS generator actions.
Abstract class needed to load GGS geometry.
static GGSGeoPluginManager & GetInstance()
Get the singleton instance.
T GetParam(const std::string &name) const
Gets a parameter.
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:105
const std::map< std::string, std::vector< std::string > > & GetVectStringParameters()
Getter method for vector-of-strings geometry parameters.
#define COUT(level)
Smart log macro. It writes on stdout only if the specified verbosity level is lesser than the maximum...
Definition: GGSSmartLog.h:76
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::vector< int > > & GetVectIntParameters()
Getter method for vector-of-integers 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, std::vector< double > > & GetVectRealParameters()
Getter method for vector-of-reals geometry parameters.
void SetVectRealGeoParams(const std::map< std::string, std::vector< double >> &vectRealGeoParams)
Sets the vector-of-reals geometry parameters.
void SetVectStringGeoParams(const std::map< std::string, std::vector< std::string >> &vectStringGeoParams)
Sets the vector-of-strings geometry parameters.
const std::map< std::string, bool > & GetBoolParameters()
Getter method for boolean geometry parameters.
static GGSRunManager * GetRunManager()
Static getter function the run manager.
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.
void SetVectIntGeoParams(const std::map< std::string, std::vector< int >> &vectIntGeoParams)
Sets the vector-of-integers geometry parameters.
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.
Class for writing parameters into the output Root file.
void SetIntGeoParams(const std::map< std::string, int > &intGeoParams)
Sets the integer geometry parameters.