CbmRoot
Loading...
Searching...
No Matches
CbmFsdAddress.cxx
Go to the documentation of this file.
1/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Volker Friese, Andrey Lebedev, Lukas Chlad [committer] */
4
13#include "CbmFsdAddress.h"
14
15#include "CbmDefs.h" // for kFsd
16
17#include <cassert> // for assert
18#include <sstream> // for operator<<, basic_ostream, stringstream
19
20#include "AlgoFairloggerCompat.h" // for Logger, LOG
21
22// ----- Construct address from element Ids ------------------------------
23int32_t CbmFsdAddress::GetAddress(uint32_t Unit, uint32_t Module, uint32_t PhotoDet, uint32_t Version)
24{
25 using namespace Detail;
26
27 assert(Version <= kCurrentVersion);
28
29 // Catch overrun of allowed ranges
30 if (Unit > static_cast<uint32_t>(kMask[Version][static_cast<int32_t>(CbmFsdAddress::Level::Unit)])) {
31 LOG(error) << "Unit Id " << Unit << " exceeds maximum "
32 << kMask[Version][static_cast<int32_t>(CbmFsdAddress::Level::Unit)];
33 return 0;
34 }
35 if (Module > static_cast<uint32_t>(kMask[Version][static_cast<int32_t>(CbmFsdAddress::Level::Module)])) {
36 LOG(error) << "Module Id " << Module << " exceeds maximum "
37 << kMask[Version][static_cast<int32_t>(CbmFsdAddress::Level::Module)];
38 return 0;
39 }
40 if (PhotoDet > static_cast<uint32_t>(kMask[Version][static_cast<int32_t>(CbmFsdAddress::Level::PhotoDet)])) {
41 LOG(error) << "PhotoDetector Id " << PhotoDet << " exceeds maximum "
42 << kMask[Version][static_cast<int32_t>(CbmFsdAddress::Level::PhotoDet)];
43 return 0;
44 }
45
46 return ToIntegralType(ECbmModuleId::kFsd) << kShift[Version][static_cast<uint32_t>(CbmFsdAddress::Level::System)]
47 | Unit << kShift[Version][static_cast<int32_t>(CbmFsdAddress::Level::Unit)]
48 | Module << kShift[Version][static_cast<int32_t>(CbmFsdAddress::Level::Module)]
49 | PhotoDet << kShift[Version][static_cast<int32_t>(CbmFsdAddress::Level::PhotoDet)] | Version << kVersionShift;
50}
51// ---------------------------------------------------------------------------
52
53
54// ----- Construct address from address of descendant element ------------
55int32_t CbmFsdAddress::GetMotherAddress(int32_t address, int32_t level)
56{
57 using namespace Detail;
58 if (!(level >= static_cast<int32_t>(CbmFsdAddress::Level::System)
59 && level < static_cast<int32_t>(CbmFsdAddress::Level::NumLevels))) {
60 throw std::out_of_range(std::string("CbmFsdAddress: Illegal element level ") + std::to_string(level));
61 return 0;
62 }
63 if (level == static_cast<uint32_t>(CbmFsdAddress::Level::NumLevels) - 1) return address;
64 uint32_t version = GetVersion(address);
65 int32_t motherAdd = (address & ((1 << kShift[version][level + 1]) - 1));
66 motherAdd = motherAdd | (version << kVersionShift);
67 return motherAdd;
68}
69// ---------------------------------------------------------------------------
70
71
72// ----- Get the index of an element -------------------------------------
73uint32_t CbmFsdAddress::GetElementId(int32_t address, int32_t level)
74{
75 using namespace Detail;
76 if (!(level >= static_cast<int32_t>(CbmFsdAddress::Level::System)
77 && level < static_cast<int32_t>(CbmFsdAddress::Level::NumLevels))) {
78 throw std::out_of_range(std::string("CbmFsdAddress: Illegal element level ") + std::to_string(level));
79 return 0;
80 }
81 uint32_t version = GetVersion(address);
82 return (address & (kMask[version][level] << kShift[version][level])) >> kShift[version][level];
83}
84// ---------------------------------------------------------------------------
85
86
87// ----- Get System ID ---------------------------------------------------
88uint32_t CbmFsdAddress::GetSystemId(int32_t address)
89{
90 return GetElementId(address, static_cast<uint32_t>(CbmFsdAddress::Level::System));
91}
92// ---------------------------------------------------------------------------
93
94
95// ----- Get the version number from the address -------------------------
96uint32_t CbmFsdAddress::GetVersion(int32_t address)
97{
98 return uint32_t((address & (kVersionMask << kVersionShift)) >> kVersionShift);
99}
100// ---------------------------------------------------------------------------
101
102
103// ----- Construct address by changing the index of an element ------------
104int32_t CbmFsdAddress::SetElementId(int32_t address, int32_t level, uint32_t newId)
105{
106 using namespace Detail;
107 if (!(level >= static_cast<int32_t>(CbmFsdAddress::Level::System)
108 && level < static_cast<int32_t>(CbmFsdAddress::Level::NumLevels))) {
109 throw std::out_of_range(std::string("CbmFsdAddress: Illegal element level ") + std::to_string(level));
110 return 0;
111 }
112 uint32_t version = GetVersion(address);
113 uint32_t maxId = (1 << kBits[version][level]) - 1;
114 if (newId > maxId) {
115 LOG(fatal) << "Id " << newId << " for FSD level " << level << " exceeds maximum " << maxId;
116 return 0;
117 }
118 return (address & (~(kMask[version][level] << kShift[version][level]))) | (newId << kShift[version][level]);
119}
120// -------------------------------------------------------------------------
121
122// ----- String output -------------------------------------------------
123std::string CbmFsdAddress::ToString(int32_t address)
124{
125 std::stringstream ss;
126
127 ss << "FsdAddress: address " << address << " (version " << GetVersion(address) << ")"
128 << ": system " << GetElementId(address, static_cast<int32_t>(CbmFsdAddress::Level::System)) << ", unit "
129 << GetElementId(address, static_cast<int32_t>(CbmFsdAddress::Level::Unit)) << ", module "
130 << GetElementId(address, static_cast<int32_t>(CbmFsdAddress::Level::Module)) << ", photo detector "
131 << GetElementId(address, static_cast<int32_t>(CbmFsdAddress::Level::PhotoDet));
132 return ss.str();
133}
134// -------------------------------------------------------------------------
XPU_D constexpr auto ToIntegralType(T enumerator) -> typename std::underlying_type< T >::type
Definition CbmDefs.h:29
@ kFsd
Forward spectator detector.
uint32_t GetSystemId(int32_t address)
Get system Id (should be integer value of ECbmModuleId::kFsd)
int32_t GetAddress(uint32_t Unit=0, uint32_t Module=0, uint32_t PhotoDet=0, uint32_t Version=kCurrentVersion)
Construct address.
uint32_t GetVersion(int32_t address)
Extract version number.
constexpr int32_t kVersionShift
uint32_t GetElementId(int32_t address, int32_t level)
Get the index of an element.
int32_t SetElementId(int32_t address, int32_t level, uint32_t newId)
Set the index of an element, leaving the other element levels untouched.
int32_t GetMotherAddress(int32_t address, int32_t level)
Construct the address of an element from the address of a descendant element.
constexpr uint32_t kCurrentVersion
constexpr int32_t kVersionMask
std::string ToString(int32_t address)
String output.