GGS(GenericGEANT4Simulation)Software  2.6.3
 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(nullptr), _firstEntryOfCurrentFile(-1), _detInfo(nullptr) {
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 = nullptr;
72  _detInfo = nullptr;
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 
128  if (_CheckBranch(detBranchName)) {
129 
130  int detIndex = GetDetectorIndex(detector); // detIndex == -1 if the detector has not been set
131  TBranch *partHitsBranch = _chain->GetBranch(std::string(detector).append("-GGSPartHits").c_str());
132  TBranch *posHitsBranch = _chain->GetBranch(std::string(detector).append("-GGSPosHits").c_str());
133 
134  std::string infoString("Set detector ");
135  infoString.append(detector);
136 
137  // Position hits
138  if (readPosHits) {
139  if (posHitsBranch) {
140  infoString.append(" (+PosHits)");
141  if (detIndex == -1) {
142  _posHitArrays.push_back(nullptr);
143  posHitsBranch->SetAddress(&(_posHitArrays.back()));
144  _readPosHits.push_back(true);
145  }
146  else {
147  posHitsBranch->SetAddress(&(_posHitArrays[detIndex]));
148  _readPosHits[detIndex] = true;
149  }
150  branches[2] = posHitsBranch;
151  }
152  else {
153  throw std::runtime_error(std::string("PosHits missing for detector ") + detector);
154  }
155  }
156  else {
157  if (detIndex == -1) {
158  _posHitArrays.push_back(nullptr);
159  _readPosHits.push_back(false);
160  }
161  else {
162  if (posHitsBranch) {
163  posHitsBranch->ResetAddress();
164  }
165  _posHitArrays[detIndex] = nullptr; // FIXME: should the element be deleted before this? Is it owned by the file/branch?
166  _readPosHits[detIndex] = false;
167  }
168  }
169 
170  // Particle hits
171  if (readPartHits) {
172  if (partHitsBranch) {
173  infoString.append(" (+PartHits)");
174  if (detIndex == -1) {
175  _partHitArrays.push_back(nullptr);
176  partHitsBranch->SetAddress(&(_partHitArrays.back()));
177  _readPartHits.push_back(true);
178  }
179  else {
180  partHitsBranch->SetAddress(&(_partHitArrays[detIndex]));
181  _readPartHits[detIndex] = true;
182  }
183  branches[1] = partHitsBranch;
184  }
185  else {
186  throw std::runtime_error(std::string("PartHits missing for detector ") + detector);
187  }
188  }
189  else {
190  if (detIndex == -1) {
191  _partHitArrays.push_back(nullptr);
192  _readPartHits.push_back(false);
193  }
194  else {
195  if (partHitsBranch) {
196  partHitsBranch->ResetAddress();
197  }
198  _partHitArrays[detIndex] = nullptr; // FIXME: should the element be deleted before this? Is it owned by the file/branch?
199  _readPartHits[detIndex] = false;
200  }
201  }
202 
203  if (detIndex == -1) {
204  _intHitArrays.push_back(nullptr);
205  _chain->SetBranchAddress(detBranchName, &(_intHitArrays.back()));
206  branches[0] = _chain->GetBranch(detBranchName);
207  _detInfo = (TClonesArray*) (_chain->GetFile()->Get("GGSHitDetInfo"));
208  _timeBins.push_back((TArrayF*) (_chain->GetFile()->Get(TString(detector) + "-GGSIntHits-TimeBins")));
209  _thresholds.push_back(
210  (std::vector<float>*) (_chain->GetFile()->Get(TString(detector) + "-GGSIntHits-Thresholds")));
211 
212  Detector det;
213  det.name = detector;
214  det.logVolName = detector;
215  det.logVolName = det.logVolName.substr(0, det.logVolName.find_first_of('.')); // remove names of scorer and sensitive detector
216  det.detInfoArrayIndex = _GetDetectorIndexFromStorage(det.logVolName.c_str());
217  _detectors.push_back(det);
218  }
219  COUT(INFO) << infoString << ENDL;
220  }
221  else {
222  throw std::runtime_error(std::string("IntHits missing for detector ") + detector);
223  }
224 
225  // Synchronize the branches that have just been set for reading
226  if (_chain->GetReadEntry() != -1) {
227  for (int iBranch = 0; iBranch < 3; ++iBranch) {
228  if (branches[iBranch]) {
229  branches[iBranch]->GetEntry(_chain->GetReadEntry());
230  }
231  }
232  }
233 }
234 
235 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
236 
237 bool GGSTHitsReader::DetectorExists(const char *detector) {
238 
239  if (_chain) {
240  TString detectorString(detector);
241  detectorString.Append("-GGSIntHits");
242  return _CheckBranch(detectorString.Data());
243  }
244 
245  return false;
246 
247 }
248 
249 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
250 
252 
253  static const std::string routineName("GGSTHitsReader::ListDetectors");
254 
255  if (_chain) {
256  TObjArray *branches = _chain->GetListOfBranches();
257  COUT(INFO) << "List of detectors in hits tree:" << ENDL;
258  for (int i = 0; i < branches->GetEntries(); i++) {
259  TBranch *branch = (TBranch*) (branches->At(i));
260  GGSSmartLog::MuteOutput();
261  bool isDetBranch = _CheckBranch(branch->GetName());
262  GGSSmartLog::UnmuteOutput();
263  if (isDetBranch) {
264  TString detName = branch->GetName();
265  detName.Remove(detName.Length() - 11); // Remove the trailing "-GGSIntHits"
266  std::string infoString(" ");
267  infoString.append(detName.Data());
268  if (_chain->GetBranch(detName + "-GGSPartHits"))
269  infoString.append(" (PartHits)");
270  if (_chain->GetBranch(detName + "-GGSPosHits"))
271  infoString.append(" (PosHits)");
272  CCOUT(INFO) << infoString << ENDL;
273  }
274  }
275 
276  }
277 }
278 
279 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
280 
281 std::vector<TString> GGSTHitsReader::GetListOfDetectors() {
282 
283  static const std::string routineName("GGSTHitsReader::GetListOfDetectors");
284 
285  std::vector<TString> _list;
286 
287  if (_chain) {
288  TObjArray *branches = _chain->GetListOfBranches();
289  for (int i = 0; i < branches->GetEntries(); i++) {
290  TBranch *branch = (TBranch*) (branches->At(i));
291  if (_CheckBranch(branch->GetName())) {
292  TString detName = branch->GetName();
293  detName.Remove(detName.Length() - 11); // Remove the trailing "-GGSIntHits"
294  _list.emplace_back(detName);
295  }
296  }
297 
298  }
299 
300  return _list;
301 }
302 
303 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
304 
305 Int_t GGSTHitsReader::GetNHits(const char *detector) {
306  static short int iHitArray;
307  iHitArray = GetDetectorIndex(detector);
308  if (iHitArray != -1)
309  return (_GetHitArray(iHitArray))->GetEntries();
310  else
311  return 0;
312 }
313 
314 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
315 
316 Int_t GGSTHitsReader::GetNHits(int iDet) {
317 
318  TClonesArray *detArray = _GetHitArray(iDet);
319  if (detArray)
320  return detArray->GetEntries();
321  else
322  return 0;
323 
324 }
325 
326 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
327 
328 GGSTIntHit* GGSTHitsReader::GetHit(const char *detector, unsigned int iHit) {
329  int iDet = GetDetectorIndex(detector);
330  if (iDet != -1)
331  return GetHit(iDet, iHit);
332  else
333  return nullptr;
334 }
335 
336 GGSTIntHit* GGSTHitsReader::GetHit(int iDet, unsigned int iHit) {
337  static TClonesArray *hitArray = nullptr;
338  hitArray = _GetHitArray(iDet);
339  if (hitArray) {
340  static GGSTIntHit *hit = nullptr;
341  hit = (GGSTIntHit*) (hitArray->At(iHit));
342  if (hit) {
343  // Compute non-persistent informations
344  hit->eDep = hit->eDepTimeBin.GetSum();
345  hit->_hitDetInfo = _GetDetectorInfo(_detectors[iDet].detInfoArrayIndex);
346  hit->_timeBins = _timeBins[iDet];
347  if (hit->_hitDetInfo)
348  hit->_hitVolInfo = (GGSTHitVolInfo*) (hit->_hitDetInfo->volumes.At(hit->_volumeIndex));
349  else
350  hit->_hitVolInfo = nullptr;
351  if (_readPartHits[iDet]) {
352  hit->_partHits = (TClonesArray*) (_partHitArrays[iDet]->At(iHit));
353  }
354  if (_readPosHits[iDet]) {
355  // Set pointer to position hits collection for each particle hit
356  TClonesArray *partHits = hit->_partHits;
357  int nPartHits = partHits->GetEntries();
358  for (int iPartHit = 0; iPartHit < nPartHits; iPartHit++) {
359  GGSTPartHit *partHit = (GGSTPartHit*) (partHits->At(iPartHit));
360  partHit->_posHits = (TClonesArray*) (_posHitArrays[iDet]->At(partHit->_posHitIndex));
361  }
362  }
363  return hit;
364  }
365  }
366  return nullptr;
367 }
368 
369 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
370 
371 int GGSTHitsReader::GetDetectorIndex(const char *detector) {
372  for (UInt_t i = 0; i < _detectors.size(); i++) {
373  if (!strcmp(_detectors[i].name.data(), detector))
374  return i;
375  }
376  return -1;
377 }
378 
379 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
380 
381 bool GGSTHitsReader::HasPartHits(const char *detector) {
382  if (_chain) {
383  TString branchName(detector);
384  branchName.Append("-GGSPartHits");
385  TBranch *branch = _chain->GetBranch(branchName);
386  if (branch)
387  return true;
388  else
389  return false;
390  }
391  else
392  return false;
393 }
394 
395 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
396 
397 bool GGSTHitsReader::HasPosHits(const char *detector) {
398  if (_chain) {
399  TString branchName(detector);
400  branchName.Append("-GGSPosHits");
401  TBranch *branch = _chain->GetBranch(branchName);
402  if (branch)
403  return true;
404  else
405  return false;
406  }
407  else
408  return false;
409 }
410 
411 float GGSTHitsReader::GetIntHitThreshold(const std::string &detector) {
412  const std::string routineName("GSTHitsReader::GetIntHitThreshold");
413  int detIndex = GetDetectorIndex(detector.c_str());
414  if (detIndex == -1) {
415  throw std::range_error(routineName + ": detector " + detector + " not found");
416  }
417 
418  if (_thresholds[detIndex]) {
419  return (*(_thresholds[detIndex]))[0];
420  }
421  else {
422  throw std::runtime_error(routineName + ": thresholds for integrated hits not available for detector " + detector);
423  }
424 }
425 
426 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
427 
428 float GGSTHitsReader::GetPartHitThreshold(const std::string &detector) {
429  const std::string routineName("GSTHitsReader::GetIntHitThreshold");
430  int detIndex = GetDetectorIndex(detector.c_str());
431  if (detIndex == -1) {
432  throw std::range_error(routineName + ": detector " + detector + " not found");
433  }
434 
435  if (_thresholds[detIndex]) {
436  return (*(_thresholds[detIndex]))[1];
437  }
438  else {
439  throw std::runtime_error(routineName + ": thresholds for particle hits not available for detector " + detector);
440  }
441 }
442 
443 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
444 
445 float GGSTHitsReader::GetPosHitThreshold(const std::string &detector) {
446  const std::string routineName("GSTHitsReader::GetIntHitThreshold");
447  int detIndex = GetDetectorIndex(detector.c_str());
448  if (detIndex == -1) {
449  throw std::range_error(routineName + ": detector " + detector + " not found");
450  }
451 
452  if (_thresholds[detIndex]) {
453  return (*(_thresholds[detIndex]))[2];
454  }
455  else {
456  throw std::runtime_error(routineName + ": thresholds for position hits not available for detector " + detector);
457  }
458 }
459 
460 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
461 
462 int GGSTHitsReader::_GetDetectorIndexFromStorage(const char *detector) {
463 
464  if (_detInfo) {
465  for (int iDet = 0; iDet < _detInfo->GetEntries(); iDet++) {
466  static GGSTHitDetInfo *det = nullptr;
467  det = (GGSTHitDetInfo*) (_detInfo->At(iDet));
468  if (det && det->detectorName == detector)
469  return iDet;
470  }
471  }
472  return -1;
473 }
474 
475 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
476 
477 bool GGSTHitsReader::_CheckBranch(const char *branchName) {
478 
479  static const std::string routineName("GGSTHitsReader::_CheckBranch");
480  TBranch *branch = _chain->GetBranch(branchName);
481 
482  // Check whether the branch exists or not
483  if (!branch) {
484  //COUT << routineName << "Warning: branch " << branchName << " not found." << ENDL;
485  return false;
486  }
487 
488  // Check whether the branch is a TClonesArray or not
489  if (strcmp(branch->GetClassName(), "TClonesArray")) {
490  //COUT << routineName << "Warning: branch " << branchName << " is not a valid hit container (TClonesArray)." << ENDL;
491  return false;
492  }
493 
494  // Check whether the TClonesArray contains hit objects or not
495  char *oldBuffer = branch->GetAddress();
496  Long64_t oldReadEntry = branch->GetReadEntry();
497  TClonesArray *buffer = nullptr;
498  branch->SetAddress(&buffer);
499  branch->GetEntry(0);
500  branch->SetAddress(oldBuffer);
501  branch->GetEntry(oldReadEntry);
502  std::string hitClassName(buffer->GetName());
503  hitClassName.erase(hitClassName.size() - 1); // Remove the trailing 's' that TClonesArray name places after the class name
504  TClass *clonesClass = TClass::GetClass(hitClassName.c_str());
505  if (!clonesClass) {
506  COUT(ERROR) << "No dictionary for class " << hitClassName << " inside the TCloneArray in branch " << branchName
507  << ENDL;
508  return false;
509  }
510  if (!(clonesClass->GetBaseClass("GGSTIntHit"))) {
511  COUT(ERROR) << "Class " << hitClassName << " inside the TCloneArray in branch " << branchName
512  << " does not inherit from GGSTIntHit" << ENDL;
513  return false;
514  }
515  return true;
516 
517 }
518 
519 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
520 
521 TClonesArray* GGSTHitsReader::_GetHitArray(int iHitArray) {
522 
523  if (iHitArray > (int) (_intHitArrays.size() - 1) || iHitArray < 0)
524  return nullptr;
525  return _intHitArrays[iHitArray];
526 }
527 
528 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
529 
530 GGSTHitDetInfo* GGSTHitsReader::_GetDetectorInfo(int iDet) {
531 
532  if (_detInfo) {
533  static GGSTHitDetInfo *det = nullptr;
534  det = (GGSTHitDetInfo*) (_detInfo->At(iDet));
535  return det;
536  }
537  return nullptr;
538 }
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:104
#define COUT(level)
Smart log macro. It writes on stdout only if the specified verbosity level is lesser than the maximum...
Definition: GGSSmartLog.h:77
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:99
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.