9 #include <top/geometry/ChannelMapper.h>
10 #include <framework/database/DBImportArray.h>
11 #include <unordered_set>
12 #include <framework/logging/LogSystem.h>
24 ChannelMapper::ChannelMapper()
26 static_assert(c_numRows * c_numColumns == c_numAsics * c_numChannels,
27 "TOP::ChannelMapper: bug in coding (enum) - "
28 "number of channels and number of pixels disagree");
30 for (
auto& channels : m_channels) {
31 for (
auto& channel : channels) channel = 0;
33 for (
auto& pixels : m_pixels) {
34 for (
auto& pixel : pixels) pixel = 0;
39 ChannelMapper::~ChannelMapper()
41 if (m_mappingDB)
delete m_mappingDB;
44 void ChannelMapper::initialize(
const GearDir& channelMapping)
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);
54 if (m_typeName ==
"IRS3B") {
56 }
else if (m_typeName ==
"IRSX") {
59 B2ERROR(
"TOP::ChannelMapper: unknown electronic type."
60 <<
LogVar(
"type", m_typeName));
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]);
72 if (m_mapping.empty()) {
73 B2ERROR(
"TOP::ChannelMapper: mapping is not available in Gearbox");
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());
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."
99 <<
LogVar(
"channel", chan));
102 if (col >= c_numColumns) {
103 B2ERROR(
"TOP::ChannelMapper: pixel column out of range."
108 <<
LogVar(
"channel", chan));
111 if (asic >= c_numAsics) {
112 B2ERROR(
"TOP::ChannelMapper: ASIC number out of range."
117 <<
LogVar(
"channel", chan));
120 if (chan >= c_numChannels) {
121 B2ERROR(
"TOP::ChannelMapper: ASIC channel number out of range."
126 <<
LogVar(
"channel", chan));
129 if (!pixels.insert(col + row * c_numColumns).second) {
130 B2ERROR(
"TOP::ChannelMapper: pixel already mapped."
135 <<
LogVar(
"channel", chan));
138 if (!channels.insert(chan + asic * c_numChannels).second) {
139 B2ERROR(
"TOP::ChannelMapper: channel already mapped."
144 <<
LogVar(
"channel", chan));
149 B2FATAL(
"TOP::ChannelMapper: errors detected in xml file for '"
150 << m_typeName <<
"'");
155 for (
const auto& map : m_mapping) {
156 m_channels[map.getRow()][map.getColumn()] = ↦
157 m_pixels[map.getASICNumber()][map.getASICChannel()] = ↦
161 B2INFO(
"TOP::ChannelMapper: " << m_mapping.size() <<
162 " channels of carrier board of type '" << m_typeName
163 <<
"' mapped to pixels.");
166 const auto& logSystem = LogSystem::Instance();
167 if (logSystem.isLevelEnabled(LogConfig::c_Debug, 100,
"top")) {
174 void ChannelMapper::initialize()
178 if (m_mappingDB)
delete m_mappingDB;
181 if (!m_mappingDB->isValid()) {
187 m_mappingDB->addCallback(
this, &ChannelMapper::update);
189 const auto& logSystem = LogSystem::Instance();
190 if (logSystem.isLevelEnabled(LogConfig::c_Debug, 100,
"top")) {
200 for (
const auto& map : m_mapping) {
207 unsigned ChannelMapper::getChannel(
int pixel)
const
209 if (!isPixelIDValid(pixel))
return c_invalidChannel;
211 unsigned pix = pixel - 1;
212 unsigned pixRow = pix / c_numPixelColumns;
213 unsigned pixCol = pix % c_numPixelColumns;
215 unsigned carrier = pixRow / c_numRows;
216 unsigned row = pixRow % c_numRows;
217 unsigned boardstack = pixCol / c_numColumns;
218 unsigned col = pixCol % c_numColumns;
220 const auto& map = m_channels[row][col];
222 B2WARNING(
"TOP::ChannelMapper: no channel mapped to pixel. Return invalid channel."
223 <<
LogVar(
"pixelID", pixel));
224 return c_invalidChannel;
226 unsigned asic = map->getASICNumber();
227 unsigned chan = map->getASICChannel();
229 return getChannel(boardstack, carrier, asic, chan);
233 void ChannelMapper::splitChannelNumber(
unsigned channel,
234 unsigned& boardstack,
237 unsigned& chan)
const
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;
248 int ChannelMapper::getPixelID(
unsigned channel)
const
251 if (!isChannelValid(channel))
return c_invalidPixelID;
253 unsigned boardstack = 0;
254 unsigned carrier = 0;
257 splitChannelNumber(channel, boardstack, carrier, asic, chan);
259 const auto& map = m_pixels[asic][chan];
261 B2ERROR(
"TOP::ChannelMapper: no pixel mapped to channel. Return invalid pixel."
262 <<
LogVar(
"channel", channel));
263 return c_invalidPixelID;
265 unsigned row = map->getRow();
266 unsigned col = map->getColumn();
267 unsigned pixRow = row + carrier * c_numRows;
268 unsigned pixCol = col + boardstack * c_numColumns;
270 return pixCol + pixRow * c_numPixelColumns + 1;
274 int ChannelMapper::getPmtID(
int pixel)
const
276 if (not isPixelIDValid(pixel))
return 0;
278 int pmtRow = pixel / 256;
279 int pmtCol = (pixel % 64) / 4;
280 return pmtRow * 16 + pmtCol + 1;
283 void ChannelMapper::print()
const
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};
292 std::string xaxis(
"+------phi--------->");
293 std::string yaxis(
"|ohr|||^");
296 cout <<
" Mapping of TOP electronic channels to pixels";
297 if (!m_typeName.empty()) cout <<
" for " << m_typeName;
298 cout << endl << endl;
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]);
316 cout <<
" " << xaxis << endl << endl;
321 void ChannelMapper::test()
const
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");
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");
333 void ChannelMapper::clear()
336 for (
auto& channels : m_channels) {
337 for (
auto& channel : channels) channel = 0;
339 for (
auto& pixels : m_pixels) {
340 for (
auto& pixel : pixels) pixel = 0;
347 void ChannelMapper::update()
350 if (!m_mappingDB->isValid())
return;
352 for (
const auto& map : *m_mappingDB) {
353 m_channels[map.getRow()][map.getColumn()] = ↦
354 m_pixels[map.getASICNumber()][map.getASICChannel()] = ↦
Class for accessing arrays of objects in the database.
Class for importing array of objects to the database.
T * appendNew()
Construct a new T object at the end of the array.
bool import(const IntervalOfValidity &iov)
Import the object to database.
GearDir is the basic class used for accessing the parameter store.
A class that describes the interval of experiments/runs for which an object in the database is valid.
Map of pixels and channels within the carrier board.
std::string getPath() const
Return path of the current interface.
std::vector< GearDir > getNodes(const std::string &path="") const
Get vector of GearDirs which point to all the nodes the given path evaluates to.
Class to store variables with their name which were sent to the logging service.
Abstract base class for different kinds of events.