Belle II Software development
ChannelMapper.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <top/geometry/ChannelMapper.h>
10#include <framework/database/DBImportArray.h>
11#include <unordered_set>
12#include <framework/logging/LogSystem.h>
13#include <iostream>
14
15using namespace std;
16
17namespace Belle2 {
22 namespace TOP {
23
25 {
27 "TOP::ChannelMapper: bug in coding (enum) - "
28 "number of channels and number of pixels disagree");
29
30 for (auto& channels : m_channels) {
31 for (auto& channel : channels) channel = 0;
32 }
33 for (auto& pixels : m_pixels) {
34 for (auto& pixel : pixels) pixel = 0;
35 }
36 }
37
38
40 {
41 if (m_mappingDB) delete m_mappingDB;
42 }
43
44 void ChannelMapper::initialize(const GearDir& channelMapping)
45 {
46
47 clear();
48
49 string path = channelMapping.getPath();
50 auto i1 = path.rfind("type='") + 6;
51 auto i2 = path.rfind("']");
52 m_typeName = path.substr(i1, i2 - i1);
53
54 if (m_typeName == "IRS3B") {
55 m_type = c_IRS3B;
56 } else if (m_typeName == "IRSX") {
57 m_type = c_IRSX;
58 } else {
59 B2ERROR("TOP::ChannelMapper: unknown electronic type."
60 << LogVar("type", m_typeName));
61 }
62
63 // get parameters from Gearbox
64 for (const GearDir& map : channelMapping.getNodes("map")) {
65 std::vector<double> data = map.getArray("");
66 unsigned row = int(data[0]) - 1;
67 unsigned col = int(data[1]) - 1;
68 unsigned asic = int(data[2]);
69 unsigned chan = int(data[3]);
70 m_mapping.push_back(TOPChannelMap(row, col, asic, chan));
71 }
72 if (m_mapping.empty()) {
73 B2ERROR("TOP::ChannelMapper: mapping is not available in Gearbox");
74 return;
75 }
76
77 // check the size of the mapping
78 if (m_mapping.size() != c_numAsics * c_numChannels)
79 B2FATAL("TOP::ChannelMapper: got incorrect map size from xml file for '"
80 << m_typeName << "' - expect " << c_numAsics * c_numChannels
81 << ", got " << m_mapping.size());
82
83 // check the mapping for consistency
84 bool ok = true;
85 unordered_set<unsigned> pixels;
86 unordered_set<unsigned> channels;
87 for (unsigned ii = 0; ii < m_mapping.size(); ii++) {
88 const auto& map = m_mapping[ii];
89 unsigned row = map.getRow();
90 unsigned col = map.getColumn();
91 unsigned asic = map.getASICNumber();
92 unsigned chan = map.getASICChannel();
93 if (row >= c_numRows) {
94 B2ERROR("TOP::ChannelMapper: pixel row out of range."
95 << LogVar("node", ii)
96 << LogVar("row", row)
97 << LogVar("column", col)
98 << LogVar("ASIC", asic)
99 << LogVar("channel", chan));
100 ok = false;
101 }
102 if (col >= c_numColumns) {
103 B2ERROR("TOP::ChannelMapper: pixel column out of range."
104 << LogVar("node", ii)
105 << LogVar("row", row)
106 << LogVar("column", col)
107 << LogVar("ASIC", asic)
108 << LogVar("channel", chan));
109 ok = false;
110 }
111 if (asic >= c_numAsics) {
112 B2ERROR("TOP::ChannelMapper: ASIC number out of range."
113 << LogVar("node", ii)
114 << LogVar("row", row)
115 << LogVar("column", col)
116 << LogVar("ASIC", asic)
117 << LogVar("channel", chan));
118 ok = false;
119 }
120 if (chan >= c_numChannels) {
121 B2ERROR("TOP::ChannelMapper: ASIC channel number out of range."
122 << LogVar("node", ii)
123 << LogVar("row", row)
124 << LogVar("column", col)
125 << LogVar("ASIC", asic)
126 << LogVar("channel", chan));
127 ok = false;
128 }
129 if (!pixels.insert(col + row * c_numColumns).second) {
130 B2ERROR("TOP::ChannelMapper: pixel already mapped."
131 << LogVar("node", ii)
132 << LogVar("row", row)
133 << LogVar("column", col)
134 << LogVar("ASIC", asic)
135 << LogVar("channel", chan));
136 ok = false;
137 }
138 if (!channels.insert(chan + asic * c_numChannels).second) {
139 B2ERROR("TOP::ChannelMapper: channel already mapped."
140 << LogVar("node", ii)
141 << LogVar("row", row)
142 << LogVar("column", col)
143 << LogVar("ASIC", asic)
144 << LogVar("channel", chan));
145 ok = false;
146 }
147 }
148 if (!ok) {
149 B2FATAL("TOP::ChannelMapper: errors detected in xml file for '"
150 << m_typeName << "'");
151 return;
152 }
153
154 // prepare conversion arrays
155 for (const auto& map : m_mapping) {
156 m_channels[map.getRow()][map.getColumn()] = &map;
157 m_pixels[map.getASICNumber()][map.getASICChannel()] = &map;
158 }
159 m_valid = true;
160
161 B2INFO("TOP::ChannelMapper: " << m_mapping.size() <<
162 " channels of carrier board of type '" << m_typeName
163 << "' mapped to pixels.");
164
165 // print mappings if debug level for package 'top' is set to 100 or larger
166 const auto& logSystem = LogSystem::Instance();
167 if (logSystem.isLevelEnabled(LogConfig::c_Debug, 100, "top")) {
168 print();
169 }
170
171 }
172
173
175 {
176 m_type = c_default;
177
178 if (m_mappingDB) delete m_mappingDB;
180
181 if (!m_mappingDB->isValid()) {
182 clear();
183 return;
184 }
185 update();
186
187 m_mappingDB->addCallback(this, &ChannelMapper::update);
188
189 const auto& logSystem = LogSystem::Instance();
190 if (logSystem.isLevelEnabled(LogConfig::c_Debug, 100, "top")) {
191 print();
192 }
193
194 }
195
196
198 {
200 for (const auto& map : m_mapping) {
201 array.appendNew(map);
202 }
203 array.import(iov);
204 }
205
206
207 unsigned ChannelMapper::getChannel(int pixel) const
208 {
209 if (!isPixelIDValid(pixel)) return c_invalidChannel;
210
211 unsigned pix = pixel - 1;
212 unsigned pixRow = pix / c_numPixelColumns;
213 unsigned pixCol = pix % c_numPixelColumns;
214
215 unsigned carrier = pixRow / c_numRows;
216 unsigned row = pixRow % c_numRows;
217 unsigned boardstack = pixCol / c_numColumns;
218 unsigned col = pixCol % c_numColumns;
219
220 const auto& map = m_channels[row][col];
221 if (!map) {
222 B2WARNING("TOP::ChannelMapper: no channel mapped to pixel. Return invalid channel."
223 << LogVar("pixelID", pixel));
224 return c_invalidChannel;
225 }
226 unsigned asic = map->getASICNumber();
227 unsigned chan = map->getASICChannel();
228
229 return getChannel(boardstack, carrier, asic, chan);
230 }
231
232
234 unsigned& boardstack,
235 unsigned& carrier,
236 unsigned& asic,
237 unsigned& chan) const
238 {
239 chan = channel % c_numChannels;
240 channel /= c_numChannels;
241 asic = channel % c_numAsics;
242 channel /= c_numAsics;
243 carrier = channel % c_numCarrierBoards;
244 boardstack = channel / c_numCarrierBoards;
245 }
246
247
248 int ChannelMapper::getPixelID(unsigned channel) const
249 {
250
251 if (!isChannelValid(channel)) return c_invalidPixelID;
252
253 unsigned boardstack = 0;
254 unsigned carrier = 0;
255 unsigned asic = 0;
256 unsigned chan = 0;
257 splitChannelNumber(channel, boardstack, carrier, asic, chan);
258
259 const auto& map = m_pixels[asic][chan];
260 if (!map) {
261 B2ERROR("TOP::ChannelMapper: no pixel mapped to channel. Return invalid pixel."
262 << LogVar("channel", channel));
263 return c_invalidPixelID;
264 }
265 unsigned row = map->getRow();
266 unsigned col = map->getColumn();
267 unsigned pixRow = row + carrier * c_numRows;
268 unsigned pixCol = col + boardstack * c_numColumns;
269
270 return pixCol + pixRow * c_numPixelColumns + 1;
271
272 }
273
274 int ChannelMapper::getPmtID(int pixel) const
275 {
276 if (not isPixelIDValid(pixel)) return 0;
277 pixel--;
278 int pmtRow = pixel / 256;
279 int pmtCol = (pixel % 64) / 4;
280 return pmtRow * 16 + pmtCol + 1;
281 }
282
284 {
285 std::vector<std::string> what;
286 what.push_back(string("Boardstack numbers (view from the back):"));
287 what.push_back(string("Carrier board numbers (view from the back):"));
288 what.push_back(string("ASIC numbers (view from the back):"));
289 what.push_back(string("ASIC channel numbers (view from the back):"));
290 unsigned value[4] = {0, 0, 0, 0};
291
292 std::string xaxis("+------phi--------->");
293 std::string yaxis("|ohr|||^");
294
295 cout << endl;
296 cout << " Mapping of TOP electronic channels to pixels";
297 if (!m_typeName.empty()) cout << " for " << m_typeName;
298 cout << endl << endl;
299
300 for (int i = 0; i < 4; i++) {
301 cout << " " << what[i] << endl << endl;
302 for (int row = c_numPixelRows - 1; row >= 0; row--) {
303 cout << " " << yaxis[row] << " ";
304 for (int col = 0; col < c_numPixelColumns; col++) {
305 int pixel = col + c_numPixelColumns * row + 1;
306 auto channel = getChannel(pixel);
307 if (channel != c_invalidChannel) {
308 splitChannelNumber(channel, value[0], value[1], value[2], value[3]);
309 cout << value[i];
310 } else {
311 cout << "?";
312 }
313 }
314 cout << endl;
315 }
316 cout << " " << xaxis << endl << endl;
317 }
318
319 }
320
322 {
323 for (int pixel = 1; pixel <= c_numPixels; pixel++)
324 if (pixel != getPixelID(getChannel(pixel)))
325 B2ERROR("TOP::ChannelMapper: bug, getPixelID is not inverse of getChannel");
326
327 for (unsigned channel = 0; channel < c_numPixels; channel++)
328 if (channel != getChannel(getPixelID(channel)))
329 B2ERROR("TOP::ChannelMapper: bug, getChannel is not inverse of getPixelID");
330 }
331
332
334 {
335 m_mapping.clear();
336 for (auto& channels : m_channels) {
337 for (auto& channel : channels) channel = 0;
338 }
339 for (auto& pixels : m_pixels) {
340 for (auto& pixel : pixels) pixel = 0;
341 }
342 m_valid = false;
343 m_fromDB = false;
344 }
345
346
348 {
349 clear();
350 if (!m_mappingDB->isValid()) return;
351
352 for (const auto& map : *m_mappingDB) {
353 m_channels[map.getRow()][map.getColumn()] = &map;
354 m_pixels[map.getASICNumber()][map.getASICChannel()] = &map;
355 }
356 m_valid = true;
357 m_fromDB = true;
358 }
359
360
361
362 } // TOP namespace
364} // Belle2 namespace
Class for accessing arrays of objects in the database.
Definition: DBArray.h:26
Class for importing array of objects to the database.
Definition: DBImportArray.h:25
T * appendNew()
Construct a new T object at the end of the array.
Definition: DBImportArray.h:67
bool import(const IntervalOfValidity &iov)
Import the object to database.
Definition: DBImportBase.cc:36
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:31
A class that describes the interval of experiments/runs for which an object in the database is valid.
@ c_Debug
Debug: for code development.
Definition: LogConfig.h:26
static LogSystem & Instance()
Static method to get a reference to the LogSystem instance.
Definition: LogSystem.cc:31
Map of pixels and channels within the carrier board.
Definition: TOPChannelMap.h:22
EType m_type
electornic type
void test() const
test that the conversion and inverse of it gives identity, if not B2ERROR
void initialize()
Initialize from database.
bool m_fromDB
true, if from database
std::vector< TOPChannelMap > m_mapping
mappings from gearbox
const TOPChannelMap * m_pixels[c_numAsics][c_numChannels]
conversion array
void splitChannelNumber(unsigned channel, unsigned &boardstack, unsigned &carrier, unsigned &asic, unsigned &chan) const
Splits hardware channel number into boardstack, carrier, asic and asic channel.
int getPixelID(unsigned channel) const
Converts hardware channel number to pixel ID (1-based)
bool isChannelValid(unsigned channel) const
Checks validity of hardware channel number.
@ c_numCarrierBoards
number of carrier boards per boardstack
Definition: ChannelMapper.h:34
@ c_numColumns
number of pixel columns per carrier board
Definition: ChannelMapper.h:38
@ c_numChannels
number of channels per ASIC
Definition: ChannelMapper.h:36
@ c_numRows
number of pixel rows per carrier board
Definition: ChannelMapper.h:37
@ c_invalidChannel
value of invalid channel number
Definition: ChannelMapper.h:42
@ c_invalidPixelID
value of invalid pixel ID
Definition: ChannelMapper.h:43
@ c_numAsics
number of ASIC's per carrier board
Definition: ChannelMapper.h:35
bool m_valid
true if mapping available
bool isPixelIDValid(int pixel) const
Checks validity of pixel ID.
int getPmtID(int pixel) const
Returns PMT ID (1-based)
DBArray< TOPChannelMap > * m_mappingDB
mappings from database
void update()
re-do conversion arrays when DBArray has changed
void importPayload(const IntervalOfValidity &iov) const
import mappings to database
void print() const
Print mappings to terminal screen.
const TOPChannelMap * m_channels[c_numRows][c_numColumns]
conversion array
unsigned getChannel(int pixel) const
Converts pixel to hardware channel number (0-based)
std::string m_typeName
electronic type name
std::string getPath() const
Return path of the current interface.
Definition: Interface.h:70
std::vector< GearDir > getNodes(const std::string &path="") const
Get vector of GearDirs which point to all the nodes the given path evaluates to.
Definition: Interface.cc:21
Class to store variables with their name which were sent to the logging service.
Abstract base class for different kinds of events.
STL namespace.