11 #include <top/geometry/ChannelMapper.h>
12 #include <framework/database/DBImportArray.h>
13 #include <unordered_set>
14 #include <framework/logging/LogSystem.h>
26 ChannelMapper::ChannelMapper()
28 static_assert(c_numRows * c_numColumns == c_numAsics * c_numChannels,
29 "TOP::ChannelMapper: bug in coding (enum) - "
30 "number of channels and number of pixels disagree");
32 for (
auto& channels : m_channels) {
33 for (
auto& channel : channels) channel = 0;
35 for (
auto& pixels : m_pixels) {
36 for (
auto& pixel : pixels) pixel = 0;
41 ChannelMapper::~ChannelMapper()
43 if (m_mappingDB)
delete m_mappingDB;
46 void ChannelMapper::initialize(
const GearDir& channelMapping)
51 string path = channelMapping.
getPath();
52 auto i1 = path.rfind(
"type='") + 6;
53 auto i2 = path.rfind(
"']");
54 m_typeName = path.substr(i1, i2 - i1);
56 if (m_typeName ==
"IRS3B") {
58 }
else if (m_typeName ==
"IRSX") {
61 B2ERROR(
"TOP::ChannelMapper: unknown electronic type."
62 <<
LogVar(
"type", m_typeName));
67 std::vector<double> data = map.getArray(
"");
68 unsigned row = int(data[0]) - 1;
69 unsigned col = int(data[1]) - 1;
70 unsigned asic = int(data[2]);
71 unsigned chan = int(data[3]);
74 if (m_mapping.empty()) {
75 B2ERROR(
"TOP::ChannelMapper: mapping is not available in Gearbox");
80 if (m_mapping.size() != c_numAsics * c_numChannels)
81 B2FATAL(
"TOP::ChannelMapper: got incorrect map size from xml file for '"
82 << m_typeName <<
"' - expect " << c_numAsics * c_numChannels
83 <<
", got " << m_mapping.size());
87 unordered_set<unsigned> pixels;
88 unordered_set<unsigned> channels;
89 for (
unsigned ii = 0; ii < m_mapping.size(); ii++) {
90 const auto& map = m_mapping[ii];
91 unsigned row = map.getRow();
92 unsigned col = map.getColumn();
93 unsigned asic = map.getASICNumber();
94 unsigned chan = map.getASICChannel();
95 if (row >= c_numRows) {
96 B2ERROR(
"TOP::ChannelMapper: pixel row out of range."
101 <<
LogVar(
"channel", chan));
104 if (col >= c_numColumns) {
105 B2ERROR(
"TOP::ChannelMapper: pixel column out of range."
110 <<
LogVar(
"channel", chan));
113 if (asic >= c_numAsics) {
114 B2ERROR(
"TOP::ChannelMapper: ASIC number out of range."
119 <<
LogVar(
"channel", chan));
122 if (chan >= c_numChannels) {
123 B2ERROR(
"TOP::ChannelMapper: ASIC channel number out of range."
128 <<
LogVar(
"channel", chan));
131 if (!pixels.insert(col + row * c_numColumns).second) {
132 B2ERROR(
"TOP::ChannelMapper: pixel already mapped."
137 <<
LogVar(
"channel", chan));
140 if (!channels.insert(chan + asic * c_numChannels).second) {
141 B2ERROR(
"TOP::ChannelMapper: channel already mapped."
146 <<
LogVar(
"channel", chan));
151 B2FATAL(
"TOP::ChannelMapper: errors detected in xml file for '"
152 << m_typeName <<
"'");
157 for (
const auto& map : m_mapping) {
158 m_channels[map.getRow()][map.getColumn()] = ↦
159 m_pixels[map.getASICNumber()][map.getASICChannel()] = ↦
163 B2INFO(
"TOP::ChannelMapper: " << m_mapping.size() <<
164 " channels of carrier board of type '" << m_typeName
165 <<
"' mapped to pixels.");
168 const auto& logSystem = LogSystem::Instance();
169 if (logSystem.isLevelEnabled(LogConfig::c_Debug, 100,
"top")) {
176 void ChannelMapper::initialize()
180 if (m_mappingDB)
delete m_mappingDB;
183 if (!m_mappingDB->isValid()) {
189 m_mappingDB->addCallback(
this, &ChannelMapper::update);
191 const auto& logSystem = LogSystem::Instance();
192 if (logSystem.isLevelEnabled(LogConfig::c_Debug, 100,
"top")) {
202 for (
const auto& map : m_mapping) {
209 unsigned ChannelMapper::getChannel(
int pixel)
const
211 if (!isPixelIDValid(pixel))
return c_invalidChannel;
213 unsigned pix = pixel - 1;
214 unsigned pixRow = pix / c_numPixelColumns;
215 unsigned pixCol = pix % c_numPixelColumns;
217 unsigned carrier = pixRow / c_numRows;
218 unsigned row = pixRow % c_numRows;
219 unsigned boardstack = pixCol / c_numColumns;
220 unsigned col = pixCol % c_numColumns;
222 const auto& map = m_channels[row][col];
224 B2WARNING(
"TOP::ChannelMapper: no channel mapped to pixel. Return invalid channel."
225 <<
LogVar(
"pixelID", pixel));
226 return c_invalidChannel;
228 unsigned asic = map->getASICNumber();
229 unsigned chan = map->getASICChannel();
231 return getChannel(boardstack, carrier, asic, chan);
235 void ChannelMapper::splitChannelNumber(
unsigned channel,
236 unsigned& boardstack,
239 unsigned& chan)
const
241 chan = channel % c_numChannels;
242 channel /= c_numChannels;
243 asic = channel % c_numAsics;
244 channel /= c_numAsics;
245 carrier = channel % c_numCarrierBoards;
246 boardstack = channel / c_numCarrierBoards;
250 int ChannelMapper::getPixelID(
unsigned channel)
const
253 if (!isChannelValid(channel))
return c_invalidPixelID;
255 unsigned boardstack = 0;
256 unsigned carrier = 0;
259 splitChannelNumber(channel, boardstack, carrier, asic, chan);
261 const auto& map = m_pixels[asic][chan];
263 B2ERROR(
"TOP::ChannelMapper: no pixel mapped to channel. Return invalid pixel."
264 <<
LogVar(
"channel", channel));
265 return c_invalidPixelID;
267 unsigned row = map->getRow();
268 unsigned col = map->getColumn();
269 unsigned pixRow = row + carrier * c_numRows;
270 unsigned pixCol = col + boardstack * c_numColumns;
272 return pixCol + pixRow * c_numPixelColumns + 1;
276 int ChannelMapper::getPmtID(
int pixel)
const
278 if (not isPixelIDValid(pixel))
return 0;
280 int pmtRow = pixel / 256;
281 int pmtCol = (pixel % 64) / 4;
282 return pmtRow * 16 + pmtCol + 1;
285 void ChannelMapper::print()
const
287 std::vector<std::string> what;
288 what.push_back(
string(
"Boardstack numbers (view from the back):"));
289 what.push_back(
string(
"Carrier board numbers (view from the back):"));
290 what.push_back(
string(
"ASIC numbers (view from the back):"));
291 what.push_back(
string(
"ASIC channel numbers (view from the back):"));
292 unsigned value[4] = {0, 0, 0, 0};
294 std::string xaxis(
"+------phi--------->");
295 std::string yaxis(
"|ohr|||^");
298 cout <<
" Mapping of TOP electronic channels to pixels";
299 if (!m_typeName.empty()) cout <<
" for " << m_typeName;
300 cout << endl << endl;
302 for (
int i = 0; i < 4; i++) {
303 cout <<
" " << what[i] << endl << endl;
304 for (
int row = c_numPixelRows - 1; row >= 0; row--) {
305 cout <<
" " << yaxis[row] <<
" ";
306 for (
int col = 0; col < c_numPixelColumns; col++) {
307 int pixel = col + c_numPixelColumns * row + 1;
308 auto channel = getChannel(pixel);
309 if (channel != c_invalidChannel) {
310 splitChannelNumber(channel, value[0], value[1], value[2], value[3]);
318 cout <<
" " << xaxis << endl << endl;
323 void ChannelMapper::test()
const
325 for (
int pixel = 1; pixel <= c_numPixels; pixel++)
326 if (pixel != getPixelID(getChannel(pixel)))
327 B2ERROR(
"TOP::ChannelMapper: bug, getPixelID is not inverse of getChannel");
329 for (
unsigned channel = 0; channel < c_numPixels; channel++)
330 if (channel != getChannel(getPixelID(channel)))
331 B2ERROR(
"TOP::ChannelMapper: bug, getChannel is not inverse of getPixelID");
335 void ChannelMapper::clear()
338 for (
auto& channels : m_channels) {
339 for (
auto& channel : channels) channel = 0;
341 for (
auto& pixels : m_pixels) {
342 for (
auto& pixel : pixels) pixel = 0;
349 void ChannelMapper::update()
352 if (!m_mappingDB->isValid())
return;
354 for (
const auto& map : *m_mappingDB) {
355 m_channels[map.getRow()][map.getColumn()] = ↦
356 m_pixels[map.getASICNumber()][map.getASICChannel()] = ↦