CbmRoot
CbmStsAddress.cxx
Go to the documentation of this file.
1 
6 #include "CbmStsAddress.h"
7 
8 #include "CbmDefs.h" // for kSts
9 
10 #include <FairLogger.h> // for Logger, LOG
11 
12 #include <cassert> // for assert
13 #include <sstream> // for operator<<, basic_ostream, stringstream
14 
15 namespace CbmStsAddress {
16 
17  // ----- Definition of address bit field ------------------------------
18  const UShort_t kBits[kCurrentVersion + 1][kStsNofLevels] = {
19 
20  // Version 0 (until 23 August 2017)
21  {
22  4, // system
23  4, // unit / station
24  4, // ladder
25  1, // half-ladder
26  3, // module
27  2, // sensor
28  1 // side
29  },
30 
31  // Version 1 (current, since 23 August 2017)
32  {
33  4, // system
34  6, // unit
35  5, // ladder
36  1, // half-ladder
37  5, // module
38  4, // sensor
39  1 // side
40  }
41 
42  };
43  // -------------------------------------------------------------------------
44 
45 
46  // ----- Bit shifts -----------------------------------------------------
47  const Int_t kShift[kCurrentVersion + 1][kStsNofLevels] = {
48  {0,
49  kShift[0][0] + kBits[0][0],
50  kShift[0][1] + kBits[0][1],
51  kShift[0][2] + kBits[0][2],
52  kShift[0][3] + kBits[0][3],
53  kShift[0][4] + kBits[0][4],
54  kShift[0][5] + kBits[0][5]},
55 
56  {0,
57  kShift[1][0] + kBits[1][0],
58  kShift[1][1] + kBits[1][1],
59  kShift[1][2] + kBits[1][2],
60  kShift[1][3] + kBits[1][3],
61  kShift[1][4] + kBits[1][4],
62  kShift[1][5] + kBits[1][5]}};
63  // -------------------------------------------------------------------------
64 
65 
66  // ----- Bit masks -----------------------------------------------------
67  const Int_t kMask[kCurrentVersion + 1][kStsNofLevels] = {
68  {(1 << kBits[0][0]) - 1,
69  (1 << kBits[0][1]) - 1,
70  (1 << kBits[0][2]) - 1,
71  (1 << kBits[0][3]) - 1,
72  (1 << kBits[0][4]) - 1,
73  (1 << kBits[0][5]) - 1,
74  (1 << kBits[0][6]) - 1},
75 
76  {(1 << kBits[1][0]) - 1,
77  (1 << kBits[1][1]) - 1,
78  (1 << kBits[1][2]) - 1,
79  (1 << kBits[1][3]) - 1,
80  (1 << kBits[1][4]) - 1,
81  (1 << kBits[1][5]) - 1,
82  (1 << kBits[1][6]) - 1}};
83  // -------------------------------------------------------------------------
84 
85 
86 } // Namespace CbmStsAddress
87 
88 
89 // ----- Construct address from element Ids ------------------------------
90 Int_t CbmStsAddress::GetAddress(UInt_t unit,
91  UInt_t ladder,
92  UInt_t halfladder,
93  UInt_t module,
94  UInt_t sensor,
95  UInt_t side,
96  UInt_t version) {
97 
98  assert(version <= kCurrentVersion);
99 
100  // Catch overrun of allowed ranges
101  UInt_t maxUnit = (1 << kBits[version][kStsUnit]) - 1;
102  if (unit > maxUnit) {
103  LOG(error) << "Unit Id " << unit << " exceeds maximum " << maxUnit;
104  return 0;
105  }
106  UInt_t maxLadder = (1 << kBits[version][kStsLadder]) - 1;
107  if (ladder > maxLadder) {
108  LOG(error) << "Ladder Id " << ladder << " exceeds maximum " << maxLadder;
109  return 0;
110  }
111  UInt_t maxHalfLadder = (1 << kBits[version][kStsHalfLadder]) - 1;
112  if (halfladder > maxHalfLadder) {
113  LOG(error) << "HalfLadder Id " << halfladder << " exceeds maximum "
114  << maxHalfLadder;
115  return 0;
116  }
117  UInt_t maxModule = (1 << kBits[version][kStsModule]) - 1;
118  if (module > maxModule) {
119  LOG(error) << "Module Id " << module << " exceeds maximum " << maxModule;
120  return 0;
121  }
122  UInt_t maxSensor = (1 << kBits[version][kStsSensor]) - 1;
123  if (sensor > maxSensor) {
124  LOG(error) << "Sensor Id " << sensor << " exceeds maximum " << maxSensor;
125  return 0;
126  }
127  UInt_t maxSide = (1 << kBits[version][kStsSide]) - 1;
128  if (side > maxSide) {
129  LOG(error) << "Side Id " << side << " exceeds maximum " << maxSide;
130  return 0;
131  }
132 
134  | unit << kShift[version][kStsUnit]
135  | ladder << kShift[version][kStsLadder]
136  | halfladder << kShift[version][kStsHalfLadder]
137  | module << kShift[version][kStsModule]
138  | sensor << kShift[version][kStsSensor]
139  | side << kShift[version][kStsSide] | version << kVersionShift;
140 }
141 // ---------------------------------------------------------------------------
142 
143 
144 // ----- Construct address from array of element Ids ----------------------
145 Int_t CbmStsAddress::GetAddress(UInt_t* elementId, UInt_t version) {
146 
147  assert(version <= kCurrentVersion);
148 
149  Int_t address = ToIntegralType(ECbmModuleId::kSts)
150  << kShift[version][kStsSystem];
151  for (Int_t level = 1; level < kStsNofLevels; level++) {
152  UInt_t maxId = (1 << kBits[version][level]) - 1;
153  if (elementId[level] > maxId) {
154  LOG(error) << "Id " << elementId[level] << " for STS level " << level
155  << " exceeds maximum " << maxId;
156  return 0;
157  }
158  address = address | (elementId[level] << kShift[version][level]);
159  }
160  address = address | (version << kVersionShift);
161 
162  return address;
163 }
164 // ---------------------------------------------------------------------------
165 
166 
167 // ----- Construct address from address of descendant element ------------
168 Int_t CbmStsAddress::GetMotherAddress(Int_t address, Int_t level) {
169  assert(level >= kStsSystem && level < kStsNofLevels);
170  if (level == kStsNofLevels - 1) return address;
171  UInt_t version = GetVersion(address);
172  Int_t motherAdd = (address & ((1 << kShift[version][level + 1]) - 1));
173  motherAdd = motherAdd | (version << kVersionShift);
174  return motherAdd;
175 }
176 // ---------------------------------------------------------------------------
177 
178 
179 // ----- Get the index of an element -------------------------------------
180 UInt_t CbmStsAddress::GetElementId(Int_t address, Int_t level) {
181  assert(level >= kStsSystem && level < kStsNofLevels);
182  UInt_t version = GetVersion(address);
183  return (address & (kMask[version][level] << kShift[version][level]))
184  >> kShift[version][level];
185 }
186 // ---------------------------------------------------------------------------
187 
188 
189 // ----- Get System ID ---------------------------------------------------
191  return static_cast<ECbmModuleId>(GetElementId(address, kStsSystem));
192  // return GetElementId(address, kStsSystem);
193 }
194 // ---------------------------------------------------------------------------
195 
196 
197 // ----- Get the version number from the address -------------------------
198 UInt_t CbmStsAddress::GetVersion(Int_t address) {
199  return UInt_t((address & (kVersionMask << kVersionShift)) >> kVersionShift);
200 }
201 // ---------------------------------------------------------------------------
202 
203 
204 // ----- Construct address by changing the index of an element ------------
205 Int_t CbmStsAddress::SetElementId(Int_t address, Int_t level, UInt_t newId) {
206  assert(level >= kStsSystem && level < kStsNofLevels);
207  UInt_t version = GetVersion(address);
208  UInt_t maxId = (1 << kBits[version][level]) - 1;
209  if (newId > maxId) {
210  LOG(fatal) << "Id " << newId << " for STS level " << level
211  << " exceeds maximum " << maxId;
212  return 0;
213  }
214  return (address & (~(kMask[version][level] << kShift[version][level])))
215  | (newId << kShift[version][level]);
216 }
217 // -------------------------------------------------------------------------
218 
219 
220 // ----- String output -------------------------------------------------
221 std::string CbmStsAddress::ToString(Int_t address) {
222  std::stringstream ss;
223 
224  ss << "StsAddress: address " << address << " (version " << GetVersion(address)
225  << ")"
226  << ": system " << GetElementId(address, kStsSystem) << ", unit "
227  << GetElementId(address, kStsUnit) << ", ladder "
228  << GetElementId(address, kStsLadder) << ", half-ladder "
229  << GetElementId(address, kStsHalfLadder) << ", module "
230  << GetElementId(address, kStsModule) << ", sensor "
231  << GetElementId(address, kStsSensor) << ", side "
232  << GetElementId(address, kStsSide);
233  return ss.str();
234 }
235 // -------------------------------------------------------------------------
kStsHalfLadder
@ kStsHalfLadder
Definition: CbmStsAddress.h:20
CbmStsAddress::GetAddress
Int_t GetAddress(UInt_t unit=0, UInt_t ladder=0, UInt_t halfladder=0, UInt_t module=0, UInt_t sensor=0, UInt_t side=0, UInt_t version=kCurrentVersion)
Construct address.
Definition: CbmStsAddress.cxx:90
CbmStsAddress::kVersionMask
const Int_t kVersionMask
Definition: CbmStsAddress.h:53
ECbmModuleId
ECbmModuleId
Definition: CbmDefs.h:33
CbmStsAddress::kCurrentVersion
const UInt_t kCurrentVersion
Definition: CbmStsAddress.h:47
kStsSystem
@ kStsSystem
Definition: CbmStsAddress.h:17
CbmStsAddress::kBits
const UShort_t kBits[kCurrentVersion+1][kStsNofLevels]
Definition: CbmStsAddress.cxx:18
CbmStsAddress::GetSystemId
ECbmModuleId GetSystemId(Int_t address)
Get system Id (should be ECbmModuleId::kSts)
Definition: CbmStsAddress.cxx:190
kStsModule
@ kStsModule
Definition: CbmStsAddress.h:21
CbmStsAddress::SetElementId
Int_t SetElementId(Int_t address, Int_t level, UInt_t newId)
Set the index of an element, leaving the other element levels untouched.
Definition: CbmStsAddress.cxx:205
CbmStsAddress::GetElementId
UInt_t GetElementId(Int_t address, Int_t level)
Get the index of an element.
Definition: CbmStsAddress.cxx:180
CbmStsAddress
Functions to encode or decode the address field of STS data.
Definition: CbmStsAddress.cxx:15
kStsSide
@ kStsSide
Definition: CbmStsAddress.h:23
CbmStsAddress::kMask
const Int_t kMask[kCurrentVersion+1][kStsNofLevels]
Definition: CbmStsAddress.cxx:67
kStsNofLevels
@ kStsNofLevels
Definition: CbmStsAddress.h:24
kStsUnit
@ kStsUnit
Definition: CbmStsAddress.h:18
ToIntegralType
constexpr auto ToIntegralType(T enumerator) -> typename std::underlying_type< T >::type
Definition: CbmDefs.h:24
kStsSensor
@ kStsSensor
Definition: CbmStsAddress.h:22
CbmStsAddress.h
kStsLadder
@ kStsLadder
Definition: CbmStsAddress.h:19
CbmStsAddress::GetVersion
UInt_t GetVersion(Int_t address)
Extract version number.
Definition: CbmStsAddress.cxx:198
CbmStsAddress::kVersionShift
const Int_t kVersionShift
Definition: CbmStsAddress.h:52
CbmStsAddress::GetMotherAddress
Int_t GetMotherAddress(Int_t address, Int_t level)
Construct the address of an element from the address of a descendant element.
Definition: CbmStsAddress.cxx:168
ECbmModuleId::kSts
@ kSts
Silicon Tracking System.
CbmStsAddress::ToString
std::string ToString(Int_t address)
String output.
Definition: CbmStsAddress.cxx:221
CbmStsAddress::kShift
const Int_t kShift[kCurrentVersion+1][kStsNofLevels]
Definition: CbmStsAddress.cxx:47
CbmDefs.h