GGS(GenericGEANT4Simulation)Software  2.6.0
 All Data Structures Namespaces Files Functions Variables Typedefs Macros
GGSTHitsReader.cpp
Go to the documentation of this file.
1 /*
2  * GGSTHitsReader.cpp
3  *
4  * Created on: Nov 8, 2010
5  * Author: Elena Vannuccini
6  * Reworked on: 17 Aug 2011
7  * Author: Nicola Mori
8  * Content: MC truth stripped out. File opening removed.
9  */
10 
13 #include "utils/GGSSmartLog.h"
15 
16 #include "TFile.h"
17 #include "TFriendElement.h"
18 
19 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
20 
22  _chain(NULL), _firstEntryOfCurrentFile(-1), _detInfo(NULL) {
23  _detectors.reserve(50);
24  // The elements of these vectors will be used as output buffers for branches, so
25  // their location in memory must not change. The instructions below guarantee
26  // correct behavior for a number of detectors up to 50.
27  _intHitArrays.reserve(50);
28  _partHitArrays.reserve(50);
29  _posHitArrays.reserve(50);
30 }
31 
32 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
33 
35 
36  for (unsigned int i = 0; i < _intHitArrays.size(); i++)
37  delete _intHitArrays[i];
38  for (unsigned int i = 0; i < _partHitArrays.size(); i++)
39  delete _partHitArrays[i];
40  for (unsigned int i = 0; i < _posHitArrays.size(); i++)
41  delete _posHitArrays[i];
42  delete _detInfo;
43 }
44 
45 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
46 
47 bool GGSTHitsReader::SetChain(TChain *hitsChain) {
48 
49  _chain = hitsChain;
50  _detInfo = (TClonesArray*) (_chain->GetFile()->Get("GGSHitDetInfo"));
51 
52  // Search for hit branches in master chain
53  for (int iBranch = 0; iBranch < _chain->GetListOfBranches()->GetEntries(); iBranch++) {
54  if (TString(((TBranch*) (_chain->GetListOfBranches()->At(iBranch)))->GetName()).Contains("GGSIntHits")) {
55  return true;
56  }
57  }
58 
59  // Search for hit branches in friend chains
60  if (_chain->GetListOfFriends()) {
61  for (int iFriend = 0; iFriend < _chain->GetListOfFriends()->GetEntries(); iFriend++) {
62  TTree *currFriend = ((TFriendElement*) (_chain->GetListOfFriends()->At(iFriend)))->GetTree();
63  for (int iBranch = 0; iBranch < currFriend->GetListOfBranches()->GetEntries(); iBranch++) {
64  if (TString(((TBranch*) (currFriend->GetListOfBranches()->At(iBranch)))->GetName()).Contains("GGSIntHits")) {
65  return true;
66  }
67  }
68  }
69  }
70 
71  _chain = NULL;
72  _detInfo = NULL;
73  _firstEntryOfCurrentFile = -1;
74 
75  return false;
76 }
77 
78 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
79 
80 void GGSTHitsReader::GetEntry(Long64_t entry) {
81  static const std::string routineName("GGSTHitsReader::GetEntry");
82 
83  if (entry != _chain->GetReadEntry()) {
84  _chain->GetEntry(entry);
85  }
86 
87  if (_chain->GetChainEntryNumber(0) != _firstEntryOfCurrentFile) {
88  COUT(DEBUG) << "Switching to file " << _chain->GetFile()->GetName() << ENDL;
89  _firstEntryOfCurrentFile = _chain->GetChainEntryNumber(0);
90 
91  // Read the GGSHitDetInfo TClonesArray from the new file
92  _detInfo = (TClonesArray*) (_chain->GetFile()->Get("GGSHitDetInfo"));
93 
94  // Update the detector indexes in _detectors
95  for (unsigned int iDet = 0; iDet < _detectors.size(); iDet++)
96  _detectors[iDet].detInfoArrayIndex = _GetDetectorIndexFromStorage(_detectors[iDet].logVolName.data());
97 
98  // Reload time bins and thresholds
99  _timeBins.clear();
100  _thresholds.clear();
101  for (unsigned int iDet = 0; iDet < _detectors.size(); iDet++) {
102  delete _timeBins[iDet];
103  _timeBins.push_back((TArrayF*) (_chain->GetFile()->Get(TString(_detectors[iDet].name) + "-GGSIntHits-TimeBins")));
104  delete _thresholds[iDet];
105  _thresholds.push_back(
106  (std::vector<float>*) (_chain->GetFile()->Get(TString(_detectors[iDet].name) + "-GGSIntHits-Thresholds")));
107  }
108  }
109 }
110 
111 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
112 
113 void GGSTHitsReader::SetDetector(const char* detector, bool readPartHits, bool readPosHits) {
114 
115  static const std::string routineName("GGSTHitsReader::SetDetector");
116 
117  if (!_chain)
118  return;
119 
120  if (readPosHits) {
121  readPartHits = true;
122  }
123 
124  TString detBranchName = detector;
125  detBranchName.Append("-GGSIntHits");
126  TBranch *branches[3] = { nullptr, nullptr, nullptr }; // New branches (for integrated, particle and position hits)
127  if (_CheckDetector(detector) && _CheckBranch(detBranchName)) {
128 
129  std::string infoString("Set detector ");
130  infoString.append(detector);
131 
132  if (readPartHits) {
133  TString branchName(detector);
134  branchName.Append("-GGSPartHits");
135  TBranch *branch = _chain->GetBranch(branchName);
136  if (branch) {
137  infoString.append(" (+PartHits)");
138  _partHitArrays.push_back(NULL);
139  _chain->SetBranchAddress(branchName, &(_partHitArrays.back()));
140  branches[1] = _chain->GetBranch(branchName);
141  _readPartHits.push_back(true);
142  }
143  else {
144  throw std::runtime_error(std::string("PartHits missing for detector ") + detector);
145  }
146  }
147  else {
148  _partHitArrays.push_back(NULL);
149  _readPartHits.push_back(false);
150  }
151 
152  if (readPosHits) {
153  TString branchName(detector);
154  branchName.Append("-GGSPosHits");
155  TBranch *branch = _chain->GetBranch(branchName);
156  if (branch) {
157  infoString.append(" (+PosHits)");
158  _posHitArrays.push_back(NULL);
159  _chain->SetBranchAddress(branchName, &(_posHitArrays.back()));
160  branches[2] = _chain->GetBranch(branchName);
161  _readPosHits.push_back(true);
162  }
163  else {
164  _partHitArrays.pop_back();
165  _readPartHits.pop_back();
166  _chain->ResetBranchAddress(_chain->GetBranch((std::string(detector) + "-GGSPartHits").c_str()));
167  throw std::runtime_error(std::string("PosHits missing for detector ") + detector);
168  }
169  }
170  else {
171  _posHitArrays.push_back(NULL);
172  _readPosHits.push_back(false);
173  }
174 
175  _intHitArrays.push_back(NULL);
176  _chain->SetBranchAddress(detBranchName, &(_intHitArrays.back()));
177  branches[0] = _chain->GetBranch(detBranchName);
178  _detInfo = (TClonesArray*) (_chain->GetFile()->Get("GGSHitDetInfo"));
179  _timeBins.push_back((TArrayF*) (_chain->GetFile()->Get(TString(detector) + "-GGSIntHits-TimeBins")));
180  _thresholds.push_back((std::vector<float>*) (_chain->GetFile()->Get(TString(detector) + "-GGSIntHits-Thresholds")));
181 
182  Detector det;
183  det.name = detector;
184  det.logVolName = detector;
185  det.logVolName = det.logVolName.substr(0, det.logVolName.find_first_of('.')); // remove names of scorer and sensitive detector
186  det.detInfoArrayIndex = _GetDetectorIndexFromStorage(det.logVolName.c_str());
187  _detectors.push_back(det);
188 
189  COUT(INFO) << infoString << ENDL;
190  }
191  else {
192  throw std::runtime_error(std::string("IntHits missing for detector ") + detector);
193  }
194 
195  // Synchronize the branches that have just been set for reading
196  if (_chain->GetReadEntry() != -1) {
197  for (int iBranch = 0; iBranch < 3; ++iBranch) {
198  if (branches[iBranch]) {
199  branches[iBranch]->GetEntry(_chain->GetReadEntry());
200  }
201  }
202  }
203 }
204 
205 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
206 
207 bool GGSTHitsReader::DetectorExists(const char *detector) {
208 
209  if (_chain) {
210  TString detectorString(detector);
211  detectorString.Append("-GGSIntHits");
212  return _CheckBranch(detectorString.Data());
213  }
214 
215  return false;
216 
217 }
218 
219 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
220 
222 
223  static const std::string routineName("GGSTHitsReader::ListDetectors");
224 
225  if (_chain) {
226  TObjArray *branches = _chain->GetListOfBranches();
227  COUT(INFO) << "List of detectors in hits tree:" << ENDL;
228  for (int i = 0; i < branches->GetEntries(); i++) {
229  TBranch *branch = (TBranch*) (branches->At(i));
230  if (_CheckBranch(branch->GetName())) {
231  TString detName = branch->GetName();
232  detName.Remove(detName.Length() - 11); // Remove the trailing "-GGSIntHits"
233  std::string infoString(" ");
234  infoString.append(detName.Data());
235  if (_chain->GetBranch(detName + "-GGSPartHits"))
236  infoString.append(" (PartHits)");
237  if (_chain->GetBranch(detName + "-GGSPosHits"))
238  infoString.append(" (PosHits)");
239  CCOUT(INFO) << infoString << ENDL;
240  }
241  }
242 
243  }
244 }
245 
246 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
247 
248 std::vector<TString> GGSTHitsReader::GetListOfDetectors() {
249 
250  static const std::string routineName("GGSTHitsReader::GetListOfDetectors");
251 
252  std::vector<TString> _list;
253 
254  if (_chain) {
255  TObjArray *branches = _chain->GetListOfBranches();
256  for (int i = 0; i < branches->GetEntries(); i++) {
257  TBranch *branch = (TBranch*) (branches->At(i));
258  if (_CheckBranch(branch->GetName())) {
259  TString detName = branch->GetName();
260  detName.Remove(detName.Length() - 11); // Remove the trailing "-GGSIntHits"
261  _list.emplace_back(detName);
262  }
263  }
264 
265  }
266 
267  return _list;
268 }
269 
270 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
271 
272 Int_t GGSTHitsReader::GetNHits(const char *detector) {
273  static short int iHitArray;
274  iHitArray = GetDetectorIndex(detector);
275  if (iHitArray != -1)
276  return (_GetHitArray(iHitArray))->GetEntries();
277  else
278  return 0;
279 }
280 
281 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
282 
283 Int_t GGSTHitsReader::GetNHits(int iDet) {
284 
285  TClonesArray *detArray = _GetHitArray(iDet);
286  if (detArray)
287  return detArray->GetEntries();
288  else
289  return 0;
290 
291 }
292 
293 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
294 
295 GGSTIntHit *GGSTHitsReader::GetHit(const char *detector, unsigned int iHit) {
296  int iDet = GetDetectorIndex(detector);
297  if (iDet != -1)
298  return GetHit(iDet, iHit);
299  else
300  return NULL;
301 }
302 
303 GGSTIntHit *GGSTHitsReader::GetHit(int iDet, unsigned int iHit) {
304  static TClonesArray* hitArray = NULL;
305  hitArray = _GetHitArray(iDet);
306  if (hitArray) {
307  static GGSTIntHit *hit = NULL;
308  hit = (GGSTIntHit*) (hitArray->At(iHit));
309  if (hit) {
310  // Compute non-persistent informations
311  hit->eDep = hit->eDepTimeBin.GetSum();
312  hit->_hitDetInfo = _GetDetectorInfo(_detectors[iDet].detInfoArrayIndex);
313  hit->_timeBins = _timeBins[iDet];
314  if (hit->_hitDetInfo)
315  hit->_hitVolInfo = (GGSTHitVolInfo*) (hit->_hitDetInfo->volumes.At(hit->_volumeIndex));
316  else
317  hit->_hitVolInfo = NULL;
318  if (_readPartHits[iDet]) {
319  hit->_partHits = (TClonesArray*) (_partHitArrays[iDet]->At(iHit));
320  }
321  if (_readPosHits[iDet]) {
322  // Set pointer to position hits collection for each particle hit
323  TClonesArray *partHits = hit->_partHits;
324  int nPartHits = partHits->GetEntries();
325  for (int iPartHit = 0; iPartHit < nPartHits; iPartHit++) {
326  GGSTPartHit *partHit = (GGSTPartHit*) (partHits->At(iPartHit));
327  partHit->_posHits = (TClonesArray*) (_posHitArrays[iDet]->At(partHit->_posHitIndex));
328  }
329  }
330  return hit;
331  }
332  }
333  return NULL;
334 }
335 
336 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
337 
338 int GGSTHitsReader::GetDetectorIndex(const char* detector) {
339  for (UInt_t i = 0; i < _detectors.size(); i++) {
340  if (!strcmp(_detectors[i].name.data(), detector))
341  return i;
342  }
343  return -1;
344 }
345 
346 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
347 
348 bool GGSTHitsReader::HasPartHits(const char* detector) {
349  if (_chain) {
350  TString branchName(detector);
351  branchName.Append("-GGSPartHits");
352  TBranch *branch = _chain->GetBranch(branchName);
353  if (branch)
354  return true;
355  else
356  return false;
357  }
358  else
359  return false;
360 }
361 
362 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
363 
364 bool GGSTHitsReader::HasPosHits(const char* detector) {
365  if (_chain) {
366  TString branchName(detector);
367  branchName.Append("-GGSPosHits");
368  TBranch *branch = _chain->GetBranch(branchName);
369  if (branch)
370  return true;
371  else
372  return false;
373  }
374  else
375  return false;
376 }
377 
378 float GGSTHitsReader::GetIntHitThreshold(const std::string &detector) {
379  const std::string routineName("GSTHitsReader::GetIntHitThreshold");
380  int detIndex = GetDetectorIndex(detector.c_str());
381  if (detIndex == -1) {
382  throw std::range_error(routineName + ": detector " + detector + " not found");
383  }
384 
385  if (_thresholds[detIndex]) {
386  return (*(_thresholds[detIndex]))[0];
387  }
388  else {
389  throw std::runtime_error(routineName + ": thresholds for integrated hits not available for detector " + detector);
390  }
391 }
392 
393 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
394 
395 float GGSTHitsReader::GetPartHitThreshold(const std::string &detector) {
396  const std::string routineName("GSTHitsReader::GetIntHitThreshold");
397  int detIndex = GetDetectorIndex(detector.c_str());
398  if (detIndex == -1) {
399  throw std::range_error(routineName + ": detector " + detector + " not found");
400  }
401 
402  if (_thresholds[detIndex]) {
403  return (*(_thresholds[detIndex]))[1];
404  }
405  else {
406  throw std::runtime_error(routineName + ": thresholds for particle hits not available for detector " + detector);
407  }
408 }
409 
410 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
411 
412 float GGSTHitsReader::GetPosHitThreshold(const std::string &detector) {
413  const std::string routineName("GSTHitsReader::GetIntHitThreshold");
414  int detIndex = GetDetectorIndex(detector.c_str());
415  if (detIndex == -1) {
416  throw std::range_error(routineName + ": detector " + detector + " not found");
417  }
418 
419  if (_thresholds[detIndex]) {
420  return (*(_thresholds[detIndex]))[2];
421  }
422  else {
423  throw std::runtime_error(routineName + ": thresholds for position hits not available for detector " + detector);
424  }
425 }
426 
427 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
428 
429 int GGSTHitsReader::_GetDetectorIndexFromStorage(const char* detector) {
430 
431  if (_detInfo) {
432  for (int iDet = 0; iDet < _detInfo->GetEntries(); iDet++) {
433  static GGSTHitDetInfo *det = NULL;
434  det = (GGSTHitDetInfo*) (_detInfo->At(iDet));
435  if (det && det->detectorName == detector)
436  return iDet;
437  }
438  }
439  return -1;
440 }
441 
442 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
443 
444 bool GGSTHitsReader::_CheckBranch(const char *branchName) {
445 
446  static const std::string routineName("GGSTHitsReader::_CheckBranch");
447  TBranch* branch = _chain->GetBranch(branchName);
448 
449  // Check whether the branch exists or not
450  if (!branch) {
451  //COUT << routineName << "Warning: branch " << branchName << " not found." << ENDL;
452  return false;
453  }
454 
455  // Check whether the branch is a TClonesArray or not
456  if (strcmp(branch->GetClassName(), "TClonesArray")) {
457  //COUT << routineName << "Warning: branch " << branchName << " is not a valid hit container (TClonesArray)." << ENDL;
458  return false;
459  }
460 
461  // Check whether the TClonesArray contains hit objects or not
462  char *oldBuffer = branch->GetAddress();
463  Long64_t oldReadEntry = branch->GetReadEntry();
464  TClonesArray *buffer = NULL;
465  branch->SetAddress(&buffer);
466  branch->GetEntry(0);
467  branch->SetAddress(oldBuffer);
468  branch->GetEntry(oldReadEntry);
469  std::string hitClassName(buffer->GetName());
470  hitClassName.erase(hitClassName.size() - 1); // Remove the trailing 's' that TClonesArray name places after the class name
471  TClass *clonesClass = TClass::GetClass(hitClassName.c_str());
472  if (!clonesClass) {
473  COUT(ERROR) << "No dictionary for class " << hitClassName << " inside the TCloneArray in branch " << branchName
474  << ENDL;
475  return false;
476  }
477  if (!(clonesClass->GetBaseClass("GGSTIntHit"))) {
478  COUT(ERROR) << "Class " << hitClassName << " inside the TCloneArray in branch " << branchName
479  << " does not inherit from GGSTIntHit" << ENDL;
480  return false;
481  }
482  return true;
483 
484 }
485 
486 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
487 
488 bool GGSTHitsReader::_CheckDetector(const char *detector) {
489 
490 // Check whether the detector has already been set or not
491  for (unsigned int i = 0; i < _detectors.size(); i++) {
492  if (_detectors[i].name == detector)
493  return false; // The branch has not to be added again.
494  }
495 
496  return true;
497 }
498 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
499 
500 TClonesArray* GGSTHitsReader::_GetHitArray(int iHitArray) {
501 
502  if (iHitArray > (int) (_intHitArrays.size() - 1) || iHitArray < 0)
503  return NULL;
504  return _intHitArrays[iHitArray];
505 }
506 
507 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
508 
509 GGSTHitDetInfo *GGSTHitsReader::_GetDetectorInfo(int iDet) {
510 
511  if (_detInfo) {
512  static GGSTHitDetInfo *det = NULL;
513  det = (GGSTHitDetInfo*) (_detInfo->At(iDet));
514  return det;
515  }
516  return NULL;
517 }
bool HasPartHits(const char *detector)
Check if particle hits data is available for the specified detector.
float GetIntHitThreshold(const std::string &detector)
Retrieves the thresholds used when saving the integrated hits.
Class to store detector informations.
float GetPartHitThreshold(const std::string &detector)
Retrieves the thresholds used when saving the particle hits.
Float_t eDep
Deposited energy (transient).
Definition: GGSTHits.h:164
#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
void ListDetectors()
Prints a list of detectors which are present in hits tree on standard output.
Class to store G4 particle hits.
Definition: GGSTHits.h:82
GGSTHitsReader()
Constructor.
GGSTIntHit * GetHit(const char *detector, unsigned int iHit)
Get the specified hit.
#define CCOUT(level)
Smart log utility which prints no header at the beginning of the line.
Definition: GGSSmartLog.h:88
TClonesArray volumes
Array of GGSTHitVolInfo objects.
Int_t GetNHits(const char *detector)
Gets the number of hits for the specified detector.
~GGSTHitsReader()
Destructor.
bool HasPosHits(const char *detector)
Check if position hits data is available for the specified detector.
TArrayF eDepTimeBin
Energy deposit in each time bin.
Definition: GGSTHits.h:165
Class to store G4 position hits.
Definition: GGSTHits.h:160
float GetPosHitThreshold(const std::string &detector)
Retrieves the thresholds used when saving the position hits.
bool SetChain(TChain *hitsChain)
Sets the chain.
int GetDetectorIndex(const char *detector)
Retrieves the index of requested detector.
bool DetectorExists(const char *detector)
Checks the existence of a given detector within the hits tree.
void GetEntry(Long64_t entry)
std::vector< TString > GetListOfDetectors()
Returns the list of detectors which are present in hits tree on standard output.
GGSTHitVolInfo.h GGSTHitVolInfo class declaration.
TString detectorName
Name of detector associated to integrated hits.
void SetDetector(const char *detector, bool readPartHits=false, bool readPosHits=false)
Enables reading hit informations of the specified detector.