|
| 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