ATLAS Offline Software
Loading...
Searching...
No Matches
ZDCJSONConfig.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7
8std::pair<bool, std::string>
9ZDCJSONConfig::ParseConfig(const JSON& config, const JSONParamList& configParamList)
10{
11 bool result = true;
12 std::string resultString = "success";
13
14 for (auto [key, value] : config.items()) {
15
16 if (value.is_null()) {
17 result = false;
18 resultString = "Found null value for parameter " + key;
19 break;
20 }
21
22 //
23 // First we look up the parameter in the provided parameter list
24 //
25 auto iter = configParamList.find(key);
26 if (iter == configParamList.end()) {
27 result = false;
28 resultString = "Found unknown parameter: " + key +": JSON=" + config.dump();
29 break;
30 }
31
32 auto paramType = std::get<0>(iter->second);
33 auto paramSize = std::get<1>(iter->second);
34 auto paramSingleOnly = !std::get<2>(iter->second); // the boolean indicates whether the parameter is per-channel settable
35
36 // For single value only, we can do a type check here
37 //
38 if (paramSingleOnly) {
39 if (!checkType(value, paramType, paramSize)) {
40 result = false;
41 resultString = "Incorrect JSON type for parameter " + key;
42 break;
43 }
44
45 //
46 // Set the value for all channels
47 //
48 setAllParameter(key, value);
49
50 // Add it to the list of "global" parameters
51 //
52 m_globalConfig[key] = value;
53 }
54 else {
55 //
56 // If the value is per-channel settable, then either the value is an object with
57 // key, value pairs that provide the per-side or per-channel settings or it's
58 // a "single" value (possible an array) that appplies to all channels
59 //
60 if (value.type() == JSON::value_t::object) {
61 auto [ppcResult, ppcResultString] = ParsePerChannelParams(key, value, paramType, paramSize);
62 if (!ppcResult) {
63 result = ppcResult;
64 resultString = std::move(ppcResultString);
65 break;
66 }
67 }
68 else {
69 if (!checkType(value, paramType, paramSize)) {
70 result = false;
71 resultString = "Incorrect JSON type for parameter " + key;
72 break;
73 }
74
75 //
76 // Set the value for all channels
77 //
78 setAllParameter(key, value);
79 }
80 }
81 }
82
83 if (result) m_haveConfig = true;
84 return {result, resultString};
85}
86
87template<typename T> std::pair<bool, std::string>
88ZDCJSONConfig::ParsePerChannelParams(const std::string& paramKey, const T& paramValue, JSON::value_t paramType, size_t paramSize)
89{
90 bool result = true;
91 std::string resultString = "success";
92
93 for (auto [key, value] : paramValue.items()) {
94 try {
95 //
96 // Compare the key against the side labels
97 //
98 //bool validKey = false;
99 for (unsigned int side = 0; side < m_nSides; side++) {
100 size_t srchIdx = key.find(m_sideLabels[side]);
101 if (srchIdx == 0) {
102 //validKey = true;
103
104 // Check to see whether the key length matches the
105 // side label length -- if it does, then we either
106 // have an array specifying the values for all channels
107 // or we have a single value that applies to all channels
108 //
109 if (key.size() == m_sideLabels[side].size()) {
110 if (value.size() == 1) {
111 //
112 // We have per-side value that we set for all channels on that side,
113 // unless it already has had a specific value provided (handled by SetSideParameter)
114 //
115 if (!checkType(value, paramType)) {
116 result = false;
117 resultString = "Incorrect JSON type for parameter " + key;
118 break;
119 }
120
121 setPerSideParameter(side, paramKey, value);
122 break;
123 }
124 else if (paramType == JSON::value_t::array) {
125
126 size_t elementSize = value[0].size();
127 size_t arrayLength = value.size();
128
129 if (arrayLength == m_numChannelsPerSide && elementSize == paramSize) {
130 for (unsigned int chan = 0; chan < m_numChannelsPerSide; chan++) {
131 setChannelParameter(side, chan, paramKey, value[chan]);
132 }
133 }
134 else if (arrayLength == paramSize) {
135 //
136 // We have a single array that is set for all channels
137 //
138 setPerSideParameter(side, paramKey, value);
139 }
140 else {
141 result = false;
142 resultString = "Invalid value format for array parameter " + paramKey + " on side " + m_sideLabels[side];
143 break;
144 }
145 }
146 else if (paramType == JSON::value_t::object) {
147 //
148 // For now do nothing -- need to work out how to handle objects
149 //
150 }
151 else {
152 //
153 // If we get here we must have an array of values
154 //
155 if (value.size() != m_numChannelsPerSide) {
156 result = false;
157 resultString = "Invalid array length for parameter " + paramKey + " on side " + m_sideLabels[side];
158 break;
159 }
160 else {
161 //
162 // The the values for each channel
163 //
164 for (unsigned int chan = 0; chan < m_numChannelsPerSide; chan++) {
165 if (!checkType(value[chan], paramType)) {
166 result = false;
167 resultString = "Incorrect JSON type for parameter " + paramKey + "paramType = " +
168 std::to_string((unsigned int) paramType) + ", value type = " + std::to_string((unsigned int) value[chan].type());
169 break;
170 }
171
172 setChannelParameter(side, chan, paramKey, value[chan]);
173 }
174 }
175 }
176 }
177 else {
178 // The key must be longer than the side label which should mean a specific channel
179 //
180 std::string keyRemainder = key.substr(m_sideLabels[side].size(), std::string::npos);
181 try {
182 int chanIndex = std::stoi(keyRemainder);
183 if (chanIndex < 0 || size_t(chanIndex) > m_numChannelsPerSide) {
184 result = false;
185 resultString = "Invalid channel specifier in values for parameter " + key;
186 break;
187 }
188
189 if (!checkType(value, paramType, paramSize)) {
190 result = false;
191 resultString = "Incorrect JSON type for parameter " + key;
192 break;
193 }
194
195 setChannelParameter(side, chanIndex, paramKey, value);
196 }
197 catch(...) {
198 result = false;
199 resultString = "Invalid channel specifier for parameter " + key;
200 break;
201 }
202 }
203 }
204
205 }
206 }
207 catch (...) {
208 result = false;
209 resultString = "Exception caught while parsing key " + key;
210 }
211 }
212
213 return {result, resultString};
214}
215
216
std::pair< bool, std::string > ParseConfig(const JSON &config, const JSONParamList &JSONConfigParams)
std::map< std::string, JSONParamDescr > JSONParamList
void setAllParameter(const std::string &key, T value)
bool checkType(T value, JSON::value_t paramType, int paramSize=-1)
void setChannelParameter(unsigned int side, unsigned int chanIndex, const std::string &key, T value)
size_t m_numChannelsPerSide
nlohmann::json JSON
std::vector< std::string > m_sideLabels
void setPerSideParameter(unsigned int side, std::string key, T value)
std::pair< bool, std::string > ParsePerChannelParams(const std::string &paramKey, const T &paramValue, JSON::value_t paramType, size_t paramSize)