CbmRoot
Loading...
Searching...
No Matches
CbmStsElement.cxx
Go to the documentation of this file.
1/* Copyright (C) 2013-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Volker Friese [committer], Florian Uhlig */
4
9#include "CbmStsElement.h"
10
11#include "CbmStsModule.h" // for CbmStsModule
12#include "CbmStsSetup.h" // for CbmStsSetup
13
14#include <Logger.h> // for Logger, LOG
15
16#include <TGeoManager.h> // for gGeoManager
17#include <TGeoNode.h> // for TGeoNode
18#include <TGeoPhysicalNode.h> // for TGeoPhysicalNode
19#include <TNamed.h> // for TNamed
20
21#include <cassert> // for assert
22#include <iomanip> // for setw, __iom_t6
23#include <ios> // for left, right
24
25using std::left;
26using std::right;
27using std::setw;
28
29// ----- Default constructor -------------------------------------------
31 : TNamed()
32 , fAddress(0)
33 , fLevel(kStsNofLevels)
34 , fNode(nullptr)
35 , fDaughters()
36 , fMother(nullptr)
37{
38}
39// -------------------------------------------------------------------------
40
41
42// ----- Standard constructor ------------------------------------------
43CbmStsElement::CbmStsElement(Int_t address, Int_t level, TGeoPhysicalNode* node, CbmStsElement* mother)
44 : TNamed()
45 , fAddress(address)
46 , fLevel(kStsSystem)
47 , fNode(node)
48 , fDaughters()
49 , fMother(mother)
50{
51 SetLevel(level);
52 SetName(ConstructName(address, fLevel).Data());
53}
54// -------------------------------------------------------------------------
55
56
57// ----- Construct the name of an element --------------------------------
59{
60
61 // Set the name for the STS system
62 if (GetLevel() == kStsSystem) {
63 SetName("STS");
64 return;
65 }
66
67 // Special case half-ladder ("U"p or "D"own)
68 if (GetLevel() == kStsHalfLadder) {
69 TString label;
71 case 0: label = "U"; break;
72 case 1: label = "D"; break;
73 default: break;
74 }
75 SetName(fMother->GetName() + label);
76 return;
77 }
78
79 // For other levels: Expand the name of the mother
80 TString label;
81 switch (GetLevel()) {
82 case kStsUnit: label = "_U"; break;
83 case kStsLadder: label = "_L"; break;
84 case kStsModule: label = "_M"; break;
85 case kStsSensor: label = "_S"; break;
86 default: break;
87 }
88 label += Form("%02i", CbmStsAddress::GetElementId(fAddress, GetLevel()) + 1);
89 SetName(fMother->GetName() + label);
90}
91// -------------------------------------------------------------------------
92
93
94// ----- Construct name from address -----------------------------------
96{
97
98 TString result = "STS";
99 if (level >= kStsUnit) {
100 Int_t unit = CbmStsAddress::GetElementId(address, kStsUnit);
101 result += Form("_U%02i", unit + 1);
102 if (level >= kStsLadder) {
103 Int_t ladder = CbmStsAddress::GetElementId(address, kStsLadder);
104 result += Form("_L%02i", ladder + 1);
105 if (level >= kStsHalfLadder) {
106 Int_t hladder = CbmStsAddress::GetElementId(address, kStsHalfLadder);
107 result += (hladder == 0 ? "U" : "D");
108 if (level >= kStsModule) {
109 Int_t module = CbmStsAddress::GetElementId(address, kStsModule);
110 result += Form("_M%02i", module + 1);
111 if (level >= kStsSensor) {
112 Int_t sensor = CbmStsAddress::GetElementId(address, kStsSensor);
113 result += Form("_S%02i", sensor + 1);
114 } //? sensor
115 } //? module
116 } //? halfladder
117 } //? ladder
118 } //? unit
119
120 return result;
121}
122// -------------------------------------------------------------------------
123
124
125// ----- Get a daughter element ----------------------------------------
127{
128 if (index < 0 || index >= GetNofDaughters()) return nullptr;
129 return fDaughters[index];
130}
131// -------------------------------------------------------------------------
132
133
134// ----- Get number of elements at lower hierarchy levels --------------
135Int_t CbmStsElement::GetNofElements(Int_t level) const
136{
137
138 Int_t nElements = 0;
139 if (level <= fLevel) nElements = 0;
140 else if (level == fLevel + 1)
141 nElements = GetNofDaughters();
142 else
143 for (Int_t iDaughter = 0; iDaughter < GetNofDaughters(); iDaughter++)
144 nElements += GetDaughter(iDaughter)->GetNofElements(level);
145
146 return nElements;
147}
148// -------------------------------------------------------------------------
149
150
151// ----- Recursively read daughters from geometry ----------------------
153{
154
155 // --- Catch absence of TGeoManager
156 assert(gGeoManager);
157
158 // --- No daughter elements below sensor level
159 if (fLevel > kStsSensor) return;
160
161 // --- Catch physical node not being set
162 if (!fNode) {
163 LOG(error) << fName << ": physical node is not set!";
164 return;
165 }
166
167 TGeoNode* mNode = fNode->GetNode(); // This node
168 TString mPath = fNode->GetName(); // Full path to this node
169
170 for (Int_t iNode = 0; iNode < mNode->GetNdaughters(); iNode++) {
171
172 // Check name of daughter node for level name
173 TString dName = mNode->GetDaughter(iNode)->GetName();
174 if (dName.Contains(CbmStsSetup::Instance()->GetLevelName(fLevel + 1), TString::kIgnoreCase)) {
175
176 // Create physical node
177 TString dPath = mPath + "/" + dName;
178 TGeoPhysicalNode* pNode = new TGeoPhysicalNode(dPath.Data());
179
180 // Create element and add it as daughter
182 CbmStsElement* dElement = nullptr;
183 switch (fLevel) {
184 case kStsHalfLadder: dElement = new CbmStsModule(address, pNode, this); break;
185 default: dElement = new CbmStsElement(address, fLevel + 1, pNode, this); break;
186 }
187 fDaughters.push_back(dElement);
188
189 // Call init method recursively for the daughter elements
190 dElement->InitDaughters();
191
192 } // name of daughter node
193
194 } // daughter node loop
195}
196// -------------------------------------------------------------------------
197
198
199// ----- Print ---------------------------------------------------------
200void CbmStsElement::Print(Option_t* opt) const
201{
202 LOG(info) << setw(10) << right << fAddress << " " << setw(12) << left << fName << " type " << setw(22) << fTitle
203 << " path " << fNode->GetName() << " " << fNode->GetTitle();
204 if (opt[0] == 'R') {
205 for (Int_t iDaughter = 0; iDaughter < GetNofDaughters(); iDaughter++)
206 GetDaughter(iDaughter)->Print("R");
207 }
208}
209// -------------------------------------------------------------------------
210
211
212// ----- Set element level ---------------------------------------------
213void CbmStsElement::SetLevel(Int_t level)
214{
215 switch (level) {
216 case kStsSystem: fLevel = kStsSystem; break;
217 case kStsUnit: fLevel = kStsUnit; break;
218 case kStsLadder: fLevel = kStsLadder; break;
219 case kStsHalfLadder: fLevel = kStsHalfLadder; break;
220 case kStsModule: fLevel = kStsModule; break;
221 case kStsSensor: fLevel = kStsSensor; break;
222 default: LOG(fatal) << fName << ": Illegal element level " << level; break;
223 }
224}
225// -------------------------------------------------------------------------
226
227
ClassImp(CbmConverterManager)
EStsElementLevel
@ kStsModule
@ kStsLadder
@ kStsSystem
@ kStsNofLevels
@ kStsHalfLadder
@ kStsSensor
@ kStsUnit
Class representing an element of the STS setup.
std::vector< CbmStsElement * > fDaughters
Array of daughters.
void SetLevel(Int_t level)
TGeoPhysicalNode * fNode
Pointer to geometry.
Int_t fAddress
Unique element address.
virtual void Print(Option_t *opt="") const
Int_t GetNofDaughters() const
CbmStsElement * fMother
Mother element.
Int_t GetNofElements(Int_t level) const
EStsElementLevel fLevel
Level in hierarchy.
virtual void InitDaughters()
CbmStsElement * GetDaughter(Int_t index) const
EStsElementLevel GetLevel() const
Class representing an instance of a readout unit in the CBM-STS.
const char * GetLevelName(Int_t level) const
static CbmStsSetup * Instance()
int32_t SetElementId(int32_t address, int32_t level, uint32_t newId)
Set the index of an element, leaving the other element levels untouched.
uint32_t GetElementId(int32_t address, int32_t level)
Get the index of an element.