/** * @file * @author Christian Simon * @since 2017-07-28 */ #include "CbmTofWall.h" #include "CbmTofDigiTbPar.h" #include "CbmTofCounter.h" #include "CbmTofGeoHandler.h" #include "CbmDefs.h" #include "FairLogger.h" #include "TGeoManager.h" #include "TObjArray.h" #include #include // ----- initialisation of static member variables ----------------------- CbmTofWall* CbmTofWall::fgInstance = NULL; // --------------------------------------------------------------------------- // ----- definition of static member functions --------------------------- // --------------------------------------------------------------------------- CbmTofWall* CbmTofWall::Instance() { if(!fgInstance) { fgInstance = new CbmTofWall(); } return fgInstance; } // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- CbmTofWall::~CbmTofWall() { if(fGeoHandler) { delete fGeoHandler; } for(auto const & itCounter : fCounterMap) { delete itCounter.second; } } // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- CbmTofCounter* CbmTofWall::GetCounter(Int_t iAddress) { auto const & itCounter = fCounterMap.find(iAddress); if(itCounter != fCounterMap.end()) { return itCounter->second; } else { return NULL; } } // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Bool_t CbmTofWall::Initialize(CbmTofDigiTbPar* tDigiTbParSet) { if(fbIsInitialized) { return kTRUE; } if(!tDigiTbParSet) { LOG(ERROR)<<"Parameter container CbmTofDigiTbPar not available!"<Init(kFALSE); if(k12b > iGeoVersion) { LOG(ERROR)<<"ToF geometry version must at least be 'v12b'."<CdTop(); // Just in case a geometry file contains a TGeoManager with a 'tof' top node if(!TString(gGeoManager->GetCurrentNode()->GetName()).Contains("tof",TString::kIgnoreCase)) { // Normally, the top node should be a 'cave' by which the 'tof' node is contained TObjArray* tNodes = gGeoManager->GetCurrentNode()->GetNodes(); for(Int_t iNode = 0; iNode < tNodes->GetEntriesFast(); iNode++) { TGeoNode* tNode = dynamic_cast(tNodes->At(iNode)); if(TString(tNode->GetName()).Contains("tof",TString::kIgnoreCase)) { gGeoManager->CdDown(iNode); bFoundTofNode = kTRUE; break; } } if(!bFoundTofNode) { LOG(ERROR)<<"Could not retrieve 'tof' node from TGeoManager."<GetPath(); ExpandNode(gGeoManager->GetCurrentNode()); gGeoManager->CdTop(); for(auto itCounter = fCounterMap.cbegin(); itCounter != fCounterMap.cend(); ) { CbmTofCounter* tCounter = itCounter->second; if(!tCounter->Initialize(fDigiTbParSet)) { LOG(WARNING)<GetModuleType(), tCounter->GetModuleIndex(), tCounter->GetCounterIndex())<IsPadReadout()) { LOG(WARNING)<GetModuleType(), tCounter->GetModuleIndex(), tCounter->GetCounterIndex())<GetModuleType(), tCounter->GetModuleIndex(), tCounter->GetCounterIndex())<GetRelaxationTimeConstant()) { fMemoryCounterMap.insert(itCounter); LOG(INFO)<GetModuleType(), tCounter->GetModuleIndex(), tCounter->GetCounterIndex())<GetCounterDarkRate()) { fDarkRateCounterMap.insert(itCounter); LOG(INFO)<GetModuleType(), tCounter->GetModuleIndex(), tCounter->GetCounterIndex())<GetNodes(); for(Int_t iNode = 0; iNode < tDaughterNodesList->GetEntriesFast(); iNode++) { TGeoNode* tDaughterNode = dynamic_cast(tDaughterNodesList->At(iNode)); // Extract the current module type and module index from the module node if(TString(tDaughterNode->GetName()).Contains("module")) { fiCurrentModuleType = -1; fiCurrentModuleIndex = -1; fiCurrentCounterIndex = -1; fCurrentNodePath = fTofNodePath + "/" + (TString)tDaughterNode->GetName(); boost::regex rgx(".*_(\\d+)_.*"); boost::cmatch match; if( boost::regex_search(tDaughterNode->GetName(), match, rgx) ) { fiCurrentModuleType = boost::lexical_cast(match[1]); } fiCurrentModuleIndex = tDaughterNode->GetNumber(); fCurrentBoxNodePath = fCurrentNodePath; } // Extract the current counter index from the counter node and find the // central node in the counter volume (a glass plate OR a gap) to serve as // reference coordinate system else if(TString(tDaughterNode->GetName()).Contains("counter")) { fCurrentNodePath += "/" + (TString)tDaughterNode->GetName(); fiCurrentCounterIndex = tDaughterNode->GetNumber(); TString tCurrentCentralNodePath = fCurrentNodePath; Int_t iNGaps(0); for(Int_t iDaughter = 0; iDaughter < tDaughterNode->GetNdaughters(); iDaughter++) { if(TString(tDaughterNode->GetDaughter(iDaughter)->GetName()).Contains("Gap")) { iNGaps++; } } if(0 == iNGaps%2) { tCurrentCentralNodePath += TString::Format("/tof_glass_%d",iNGaps/2); } else { tCurrentCentralNodePath += TString::Format("/Gap_%d",(iNGaps-1)/2); } if(fDigiTbParSet->GetParametersAvailable(fiCurrentModuleType, fiCurrentModuleIndex, fiCurrentCounterIndex)) { if(kTRUE == *fDigiTbParSet->GetParametersAvailable(fiCurrentModuleType, fiCurrentModuleIndex, fiCurrentCounterIndex)) { // Create the unique counter ID to be found in FairMCPoint::fDetectorID CbmTofDetectorInfo tCounterInfo(kTof, fiCurrentModuleType, fiCurrentModuleIndex, fiCurrentCounterIndex, 0, 0); Int_t iUniqueCounterId = fGeoHandler->GetDetIdPointer()->SetDetectorInfo(tCounterInfo); CbmTofCounter* tCounter = new CbmTofCounter(fiCurrentModuleType, fiCurrentModuleIndex, fiCurrentCounterIndex); tCounter->SetCentralNodePath(tCurrentCentralNodePath.Data()); tCounter->SetBoxNodePath(fCurrentBoxNodePath.Data()); tCounter->SetCounterNode(tDaughterNode); tCounter->SetCounterAddress(iUniqueCounterId); fCounterMap.emplace(iUniqueCounterId, tCounter); } } } else { fCurrentNodePath += "/" + (TString)tDaughterNode->GetName(); } // Expand nodes recursively if(tDaughterNode->GetNdaughters() > 0) { ExpandNode(tDaughterNode); } // Remove a node's name from the current node path upon completing a // recursion step fCurrentNodePath.ReplaceAll("/"+(TString)tDaughterNode->GetName(), ""); } } // --------------------------------------------------------------------------- ClassImp(CbmTofWall)