Skip to content

Commit 5c63efa

Browse files
author
Szymon Pulawski
committed
Introduce shared lookup table
1 parent 1183f52 commit 5c63efa

3 files changed

Lines changed: 174 additions & 0 deletions

File tree

DataFormats/Detectors/FIT/FT0/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ o2_add_library(DataFormatsFT0
1919
src/CTF.cxx
2020
src/LookUpTable.cxx
2121
src/SlewingCoef.cxx
22+
src/PMLookupTable.cxx
2223

2324
PUBLIC_LINK_LIBRARIES O2::FT0Base
2425
O2::DataFormatsFIT
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#ifndef O2_FT0_PMLOOKUPTABLE_H_
13+
#define O2_FT0_PMLOOKUPTABLE_H_
14+
15+
#include <array>
16+
#include <cstddef>
17+
#include <cstdint>
18+
#include <map>
19+
20+
#include "FT0Base/Constants.h"
21+
22+
namespace o2::ft0
23+
{
24+
25+
/// Cached mapping between FT0 channels and PM modules.
26+
///
27+
/// The mapping is constructed once from SingleLUT and can then be reused by
28+
/// digitization, reconstruction, trigger and QA code without reparsing the LUT.
29+
class PMLookupTable
30+
{
31+
public:
32+
using ChannelID = uint16_t;
33+
using PMHash = uint8_t;
34+
using PMMap = std::map<PMHash, bool>; // PM hash -> true for A side, false for C side
35+
36+
/// Return the process-wide immutable lookup table.
37+
static const PMLookupTable& Instance();
38+
39+
/// Return the PM hash assigned to a detector channel.
40+
PMHash getPMHash(ChannelID channelID) const;
41+
42+
/// Return true for an A-side PM and false for a C-side PM.
43+
bool isASide(PMHash pmHash) const;
44+
45+
/// Return all PM hashes and their sides. TCM entries are not included.
46+
const PMMap& getPMs() const noexcept { return mPMHash2IsASide; }
47+
48+
private:
49+
PMLookupTable();
50+
51+
std::array<PMHash, Constants::sNCHANNELS_PM> mChannelID2PMHash{};
52+
std::array<bool, Constants::sNCHANNELS_PM> mChannelIsMapped{};
53+
PMMap mPMHash2IsASide;
54+
};
55+
56+
} // namespace o2::ft0
57+
58+
#endif // O2_FT0_PMLOOKUPTABLE_H_
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#include "DataFormatsFT0/PMLookupTable.h"
13+
14+
#include "DataFormatsFT0/LookUpTable.h"
15+
#include "Framework/Logger.h"
16+
17+
#include <algorithm>
18+
#include <charconv>
19+
#include <map>
20+
#include <limits>
21+
#include <string>
22+
#include <system_error>
23+
24+
namespace o2::ft0
25+
{
26+
27+
const PMLookupTable& PMLookupTable::Instance()
28+
{
29+
static const PMLookupTable table;
30+
return table;
31+
}
32+
33+
PMLookupTable::PMLookupTable()
34+
{
35+
std::map<std::string, PMHash> moduleName2Hash;
36+
37+
auto lut = SingleLUT::Instance().getVecMetadataFEE();
38+
std::sort(lut.begin(), lut.end(), [](const auto& lhs, const auto& rhs) {
39+
return lhs.mModuleName < rhs.mModuleName;
40+
});
41+
42+
unsigned int nextHash = 0;
43+
44+
for (const auto& entry : lut) {
45+
const auto& moduleName = entry.mModuleName;
46+
const auto& moduleType = entry.mModuleType;
47+
const auto& channelString = entry.mChannelID;
48+
49+
if (nextHash > static_cast<unsigned int>(std::numeric_limits<PMHash>::max())) {
50+
LOG(fatal) << "Too many FT0 FEE modules to represent with PMHash";
51+
}
52+
53+
auto [moduleIt, inserted] = moduleName2Hash.emplace(moduleName, static_cast<PMHash>(nextHash));
54+
55+
if (inserted) {
56+
const auto moduleHash = moduleIt->second;
57+
if (moduleName.find("PMA") != std::string::npos) {
58+
mPMHash2IsASide.emplace(moduleHash, true);
59+
} else if (moduleName.find("PMC") != std::string::npos) {
60+
mPMHash2IsASide.emplace(moduleHash, false);
61+
} else if (moduleType != "TCM") {
62+
LOG(fatal) << "Unknown FT0 module in LUT: " << moduleName
63+
<< " (type " << moduleType << ")";
64+
}
65+
++nextHash;
66+
}
67+
68+
int channelID = -1;
69+
const char* begin = channelString.data();
70+
const char* end = begin + channelString.size();
71+
const auto [ptr, error] = std::from_chars(begin, end, channelID);
72+
const bool isNumericChannel = error == std::errc{} && ptr == end;
73+
74+
if (isNumericChannel) {
75+
if (channelID < 0 || channelID >= Constants::sNCHANNELS_PM) {
76+
LOG(fatal) << "Incorrect FT0 LUT entry: channel " << channelString
77+
<< " | module " << moduleName;
78+
}
79+
80+
mChannelID2PMHash[channelID] = moduleIt->second;
81+
mChannelIsMapped[channelID] = true;
82+
} else if (moduleType != "TCM") {
83+
LOG(fatal) << "Non-TCM FT0 module without numerical channel ID: channel "
84+
<< channelString << " | module " << moduleName;
85+
}
86+
}
87+
88+
for (ChannelID channelID = 0; channelID < Constants::sNCHANNELS_PM; ++channelID) {
89+
if (!mChannelIsMapped[channelID]) {
90+
LOG(fatal) << "FT0 channel " << channelID << " is not mapped to a PM in the LUT";
91+
}
92+
}
93+
}
94+
95+
PMLookupTable::PMHash PMLookupTable::getPMHash(ChannelID channelID) const
96+
{
97+
if (channelID >= Constants::sNCHANNELS_PM) {
98+
LOG(fatal) << "FT0 channel ID outside valid range: " << channelID;
99+
}
100+
if (!mChannelIsMapped[channelID]) {
101+
LOG(fatal) << "FT0 channel is not mapped to a PM: " << channelID;
102+
}
103+
return mChannelID2PMHash[channelID];
104+
}
105+
106+
bool PMLookupTable::isASide(PMHash pmHash) const
107+
{
108+
const auto it = mPMHash2IsASide.find(pmHash);
109+
if (it == mPMHash2IsASide.end()) {
110+
LOG(fatal) << "Unknown FT0 PM hash: " << static_cast<unsigned int>(pmHash);
111+
}
112+
return it->second;
113+
}
114+
115+
} // namespace o2::ft0

0 commit comments

Comments
 (0)