BmnRoot
Loading...
Searching...
No Matches
BmnSsdAddress.cxx
Go to the documentation of this file.
1
7#include "BmnSsdAddress.h"
8
9#include <cassert>
10#include <sstream>
11#include "BmnModuleList.h"
12
13
14namespace BmnSsdAddress {
15
16 // ----- Definition of address bit field ------------------------------
18 {
19
20 // Version 0 (until 23 August 2017)
21 { 4, // system
22 4, // unit / station
23 4, // ladder
24 1, // half-ladder
25 3, // module
26 2, // sensor
27 1 // side
28 },
29
30 // Version 1 (current, since 23 August 2017)
31 { 4, // system
32 6, // unit
33 5, // ladder
34 1, // half-ladder
35 5, // module
36 4, // sensor
37 1 // side
38 }
39
40 };
41 // -------------------------------------------------------------------------
42
43
44 // ----- Bit shifts -----------------------------------------------------
46 {
47 { 0,
48 kShift[0][0] + kBits[0][0],
49 kShift[0][1] + kBits[0][1],
50 kShift[0][2] + kBits[0][2],
51 kShift[0][3] + kBits[0][3],
52 kShift[0][4] + kBits[0][4],
53 kShift[0][5] + kBits[0][5]
54 },
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
67
68 // ----- Bit masks -----------------------------------------------------
70 {
71 { ( 1 << kBits[0][0] ) -1,
72 ( 1 << kBits[0][1] ) -1,
73 ( 1 << kBits[0][2] ) -1,
74 ( 1 << kBits[0][3] ) -1,
75 ( 1 << kBits[0][4] ) -1,
76 ( 1 << kBits[0][5] ) -1,
77 ( 1 << kBits[0][6] ) -1
78 },
79
80 { ( 1 << kBits[1][0] ) -1,
81 ( 1 << kBits[1][1] ) -1,
82 ( 1 << kBits[1][2] ) -1,
83 ( 1 << kBits[1][3] ) -1,
84 ( 1 << kBits[1][4] ) -1,
85 ( 1 << kBits[1][5] ) -1,
86 ( 1 << kBits[1][6] ) -1
87 }
88 };
89 // -------------------------------------------------------------------------
90
91
92} // Namespace BmnSsdAddress
93
94
95// ----- Construct address from element Ids ------------------------------
96Int_t BmnSsdAddress::GetAddress(UInt_t unit,
97 UInt_t ladder,
98 UInt_t halfladder,
99 UInt_t module,
100 UInt_t sensor,
101 UInt_t side,
102 UInt_t version) {
103
104 assert ( version <= kCurrentVersion );
105
106 // Catch overrun of allowed ranges
107 if ( unit >= ( 1 << kBits[version][kSsdUnit] ) ) {
108 LOG(error) << "Unit Id " << unit << " exceeds maximum ("
109 << ( 1 << kBits[version][kSsdUnit] ) - 1 << ")";
110 return 0;
111 }
112 if ( ladder >= ( 1 << kBits[version][kSsdLadder]) ) {
113 LOG(error) << "Ladder Id " << ladder << " exceeds maximum ("
114 << ( 1 << kBits[version][kSsdLadder] ) - 1 << ")";
115 return 0;
116 }
117 if ( halfladder >= ( 1 << kBits[version][kSsdHalfLadder]) ) {
118 LOG(error) << "HalfLadder Id " << halfladder << " exceeds maximum ("
119 << ( 1 << kBits[version][kSsdHalfLadder] ) - 1 << ")";
120 return 0;
121 }
122 if ( module >= ( 1 << kBits[version][kSsdModule]) ) {
123 LOG(error) << "Module Id " << module << " exceeds maximum ("
124 << ( 1 << kBits[version][kSsdModule] ) - 1 << ")";
125 return 0;
126 }
127 if ( sensor >= ( 1 << kBits[version][kSsdSensor]) ) {
128 LOG(error) << "Sensor Id " << sensor << " exceeds maximum ("
129 << ( 1 << kBits[version][kSsdSensor] ) - 1 << ")";
130 return 0;
131 }
132 if ( side >= ( 1 << kBits[version][kSsdSide]) ) {
133 LOG(error) << "Side Id " << side << " exceeds maximum ("
134 << ( 1 << kBits[version][kSsdSide] ) - 1 << ")";
135 return 0;
136 }
137
138 return kSSD << kShift[version][kSsdSystem] |
139 unit << kShift[version][kSsdUnit ] |
140 ladder << kShift[version][kSsdLadder] |
141 halfladder << kShift[version][kSsdHalfLadder] |
142 module << kShift[version][kSsdModule] |
143 sensor << kShift[version][kSsdSensor] |
144 side << kShift[version][kSsdSide] |
145 version << kVersionShift;
146
147}
148// ---------------------------------------------------------------------------
149
150
151
152// ----- Construct address from array of element Ids ----------------------
153Int_t BmnSsdAddress::GetAddress(UInt_t* elementId, UInt_t version) {
154
155 assert ( version <= kCurrentVersion );
156
157 Int_t address = kSSD << kShift[version][kSsdSystem];
158 for (Int_t level = 1; level < kSsdNofLevels; level++) {
159 if ( elementId[level] >= ( 1 << kBits[version][level] ) ) {
160 LOG(error) << "Id " << elementId[level] << " for SSD level " << level
161 << " exceeds maximum (" << (1 << kBits[version][level]) - 1
162 << ")";
163 return 0;
164 }
165 address = address | ( elementId[level] << kShift[version][level] );
166 }
167 address = address | ( version << kVersionShift );
168
169 return address;
170}
171// ---------------------------------------------------------------------------
172
173
174
175// ----- Construct address from address of descendant element ------------
176Int_t BmnSsdAddress::GetMotherAddress(Int_t address, Int_t level) {
177 assert ( level >= kSsdSystem && level < kSsdNofLevels );
178 if ( level == kSsdNofLevels - 1 ) return address;
179 UInt_t version = GetVersion(address);
180 Int_t motherAdd = ( address & ( ( 1 << kShift[version][level+1] ) - 1 ) ) ;
181 motherAdd = motherAdd | ( version << kVersionShift );
182 return motherAdd;
183}
184// ---------------------------------------------------------------------------
185
186
187
188// ----- Get the index of an element -------------------------------------
189UInt_t BmnSsdAddress::GetElementId(Int_t address, Int_t level) {
190 assert ( level >= kSsdSystem && level < kSsdNofLevels );
191 UInt_t version = GetVersion(address);
192 return ( address & ( kMask[version][level] << kShift[version][level] ) )
193 >> kShift[version][level];
194}
195// ---------------------------------------------------------------------------
196
197
198
199// ----- Get System ID -------------------------------------------------
200UInt_t BmnSsdAddress::GetSystemId(Int_t address) {
201 return GetElementId(address, kSsdSystem);
202}
203// -------------------------------------------------------------------------
204
205
206
207// ----- Get the version number from the address -------------------------
208UInt_t BmnSsdAddress::GetVersion(Int_t address) {
209 return UInt_t( ( address & ( kVersionMask << kVersionShift ) )
210 >> kVersionShift );
211}
212// ---------------------------------------------------------------------------
213
214
215
216// ----- Construct address by changing the index of an element ------------
217Int_t BmnSsdAddress::SetElementId(Int_t address, Int_t level,
218 UInt_t newId) {
219 assert ( level >= kSsdSystem && level < kSsdNofLevels );
220 UInt_t version = GetVersion(address);
221 if ( newId >= ( 1 << kBits[version][level]) ) {
222 LOG(fatal) << "Id " << newId << " for SSD level " << level
223 << " exceeds maximum (" << (1 << kBits[version][level]) - 1
224 << ")";
225 return 0;
226 }
227 return ( address & (~ (kMask[version][level] << kShift[version][level]) ) )
228 | ( newId << kShift[version][level]);
229}
230// -------------------------------------------------------------------------
231
232
233
234// ----- String output -------------------------------------------------
235std::string BmnSsdAddress::ToString(Int_t address) {
236 std::stringstream ss;
237
238 ss << "SsdAddress: address " << address
239 << " (version " << GetVersion(address) << ")"
240 << ": system " << GetElementId(address, kSsdSystem)
241 << ", unit " << GetElementId(address, kSsdUnit)
242 << ", ladder " << GetElementId(address, kSsdLadder)
243 << ", half-ladder " << GetElementId(address, kSsdHalfLadder)
244 << ", module " << GetElementId(address, kSsdModule)
245 << ", sensor " << GetElementId(address, kSsdSensor)
246 << ", side " << GetElementId(address, kSsdSide);
247 return ss.str();
248}
249// -------------------------------------------------------------------------
250
251
252
253
254
@ kSsdLadder
@ kSsdUnit
@ kSsdNofLevels
@ kSsdSystem
@ kSsdSensor
@ kSsdSide
@ kSsdModule
@ kSsdHalfLadder
@ kSSD
Functions to encode or decode the address field of SSD data.
const Int_t kVersionShift
UInt_t GetVersion(Int_t address)
Extract version number.
UInt_t GetSystemId(Int_t address)
Get system Id (should be kSSD)
const Int_t kMask[kCurrentVersion+1][kSsdNofLevels]
UInt_t GetElementId(Int_t address, Int_t level)
Get the index of an element.
Int_t SetElementId(Int_t address, Int_t level, UInt_t newId)
Set the index of an element, leaving the other element levels untouched.
const Int_t kBits[kCurrentVersion+1][kSsdNofLevels]
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.
const UInt_t kCurrentVersion
std::string ToString(Int_t address)
String output.
Int_t GetMotherAddress(Int_t address, Int_t level)
Construct the address of an element from the address of a descendant element.
const Int_t kVersionMask
const Int_t kShift[kCurrentVersion+1][kSsdNofLevels]