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, int 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 for (unsigned int side = 0; side < m_nSides; side++) {
99 size_t srchIdx = key.find(m_sideLabels[side]);
100 if (srchIdx == 0) {
101 // Check to see whether the key length matches the
102 // side label length -- if it does, then we either
103 // have an array specifying the values for all channels
104 // or we have a single value that applies to all channels
105 //
106 if (key.size() == m_sideLabels[side].size()) {
107 int vsize = value.size();
108 if (vsize == 1 || vsize == paramSize) {
109 //
110 // We have per-side value that we set for all channels on that side,
111 // unless it already has had a specific value provided (handled by SetSideParameter)
112 //
113 if (!checkType(value, paramType)) {
114 result = false;
115 resultString = "Incorrect JSON type for parameter " + key;
116 break;
117 }
118
119 setPerSideParameter(side, paramKey, value);
120 break;
121 }
122 else if (paramType == JSON::value_t::array) {
123 int elementSize = value[0].size();
124 JSON::value_t elementType = value[0].type();
125 size_t arrayLength = value.size();
126
127 // If the array length is the same as the # channels and the
128 // type of each (tested with the first) element is the
129 // same as paramType, then we have a set of per-channel "values"
130 // the value could be an array or object
131 //
132 if (arrayLength == m_numChannelsPerSide && elementType == paramType && int(elementSize) == paramSize) {
133 //
134 // set the channel values
135 //
136 for (unsigned int chan = 0; chan < m_numChannelsPerSide; chan++) {
137 setChannelParameter(side, chan, paramKey, value[chan]);
138 }
139 }
140 else if (int(arrayLength) == paramSize || paramSize == -1) {
141 //
142 // We have a single array that is set for all channels
143 //
144 setPerSideParameter(side, paramKey, value);
145 }
146 else {
147 result = false;
148 resultString = "Invalid value format for array parameter " + paramKey + " on side " + m_sideLabels[side];
149 break;
150 }
151 }
152 else if (paramType == JSON::value_t::object) {
153 //
154 // For now do nothing -- need to work out how to handle objects
155 //
156 }
157 else {
158 //
159 // If we get here we must have an array of values
160 //
161 if (value.size() != m_numChannelsPerSide) {
162 result = false;
163 resultString = "Invalid array length for parameter " + paramKey + " on side " + m_sideLabels[side];
164 break;
165 }
166 else {
167 //
168 // The the values for each channel
169 //
170 for (unsigned int chan = 0; chan < m_numChannelsPerSide; chan++) {
171 if (!checkType(value[chan], paramType)) {
172 result = false;
173 resultString = "Incorrect JSON type for parameter " + paramKey + "paramType = " +
174 std::to_string((unsigned int) paramType) + ", value type = " + std::to_string((unsigned int) value[chan].type());
175 break;
176 }
177
178 setChannelParameter(side, chan, paramKey, value[chan]);
179 }
180 }
181 }
182 }
183 else {
184 // The key must be longer than the side label which should mean a specific channel
185 //
186 std::string keyRemainder = key.substr(m_sideLabels[side].size(), std::string::npos);
187 try {
188 int chanIndex = std::stoi(keyRemainder);
189 if (chanIndex < 0 || size_t(chanIndex) > m_numChannelsPerSide) {
190 result = false;
191 resultString = "Invalid channel specifier in values for parameter " + key;
192 break;
193 }
194
195 if (!checkType(value, paramType, paramSize)) {
196 result = false;
197 resultString = "Incorrect JSON type for parameter " + key;
198 break;
199 }
200
201 setChannelParameter(side, chanIndex, paramKey, value);
202 }
203 catch(...) {
204 result = false;
205 resultString = "Invalid channel specifier for parameter " + key;
206 break;
207 }
208 }
209 }
210
211 }
212 }
213 catch (...) {
214 result = false;
215 resultString = "Exception caught while parsing key " + key;
216 }
217 }
218
219 return {result, resultString};
220}
221
222
size_t size() const
Number of registered mappings.
std::pair< bool, std::string > ParseConfig(const JSON &config, const JSONParamList &JSONConfigParams)
std::map< std::string, JSONParamDescr > JSONParamList
std::pair< bool, std::string > ParsePerChannelParams(const std::string &paramKey, const T &paramValue, JSON::value_t paramType, int paramSize)
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)