SModelsXMLManager.cc
Go to the documentation of this file.
1 #include <boost/lambda/lambda.hpp>
2 #include <boost/lexical_cast.hpp>
3 #include <sdet/SModelsXMLManager.h>
4 #include <utl/ErrorLogger.h>
5 #include <utl/TabulatedFunction.h>
6 #include <sdet/SDetector.h>
7 #include <sdet/SManagerRegister.h> // needed for registration macro
8 
9 using namespace sdet;
10 using namespace std;
11 using namespace utl;
12 using namespace det;
13 using namespace xercesc;
14 using namespace boost::lambda;
15 
16 
17 REGISTER_S_MANAGER("SModelsXMLManager", SModelsXMLManager)
18 
19 
20 void
21 SModelsXMLManager::Init(const string& configLink)
22 {
23  VManager::Init(configLink);
24  FillMaps();
25  AddAvailability<unsigned int>("scintillator");
26  AddAvailability<unsigned int>("electronics");
27 }
28 
29 
30 // Generic data getters
31 // --------------------
32 template<typename T>
35  const string& componentProperty,
36  const string& componentName,
37  const IndexMap& componentIndex)
38  const
39 {
40  // Find where requested data resides in DOM
41  Branch dataBranch =
42  FindBranch(componentProperty, componentName, componentIndex);
43 
44  if (!dataBranch)
45  return eNotFound;
46 
47  dataBranch.GetData(returnData);
48  return eFound;
49 }
50 
51 
54  const string& componentProperty,
55  const string& componentName,
56  const IndexMap& componentIndex)
57  const
58 {
59  // Find where requested data resides in DOM
60 
61  Branch dataBranch =
62  FindBranch(componentProperty, componentName, componentIndex);
63  if (!dataBranch)
64  return eNotFound;
65 
66  // Since this is tabulated data, retrieve the ordinate and abscissa
67  // NOTE THAT IT IS ASSUMED THAT THE ABSCISSA IS LABELED "x" AND
68  // THE ORDINATE IS LABELED "y"
69  Branch xB = dataBranch.GetChild("x");
70  if (!xB)
71  return eNotFound;
72 
73  vector<double> x;
74  xB.GetData(x);
75 
76  Branch yB = dataBranch.GetChild("y");
77  if (!yB)
78  return eNotFound;
79 
80  vector<double> y;
81  yB.GetData(y);
82 
83  // As a convenience, scale all ordinate values if a scale factor is given
84  double scaleY;
85  Branch scaleYB = dataBranch.GetChild("scaleY");
86  if (scaleYB) {
87  scaleYB.GetData(scaleY);
88  for_each(y.begin(), y.end(), _1 *= scaleY);
89  }
90 
91  const unsigned int n = x.size();
92  for (unsigned int i = 0; i < n; ++i)
93  returnData.PushBack(x[i], y[i]);
94 
95  return eFound;
96 }
97 
98 
107 Branch
108 SModelsXMLManager::FindBranch(const string& componentProperty,
109  const string& modelType,
110  const IndexMap& componentIndex)
111  const
112 {
113  /*
114  * Act on the Branch request based on the number of indices specified
115  * Number of indices can be:
116  * 1 (just the station id),
117  * 2 (station id and PMT id) or (station id and isuub),
118  * 3 (station id, isuub, PMT id)
119  */
120  const int nIndices = componentIndex.size();
121 
122  // The component attribute map is currently used in cases where a PMT index
123  // is specified (that is we have differing data applying to the 3 PMT's in
124  // a station). The commonest application for this is presumably specifying
125  // the PMT positions.
126  string stationId;
127  string hardwareVersion;
128  IndexMap componentAtts;
129 
130  Branch dataB;
131 
132  // stationId must be present in indices
133  const IndexMap::const_iterator stIt = componentIndex.find("stationId");
134  if (stIt == componentIndex.end()) {
135  if (IsReportingErrors())
136  INFO(string("Request with " + boost::lexical_cast<string>(nIndices) +
137  " indices, none of which specifies 'stationId'; ") +
138  QueryInfoMessage(componentProperty, modelType, componentIndex));
139  return dataB;
140  }
141  stationId = stIt->second;
142 
143  // isUUB must be present in indices
144  const IndexMap::const_iterator hardIt = componentIndex.find("isUUB");
145  if (hardIt == componentIndex.end()) {
146  if (IsReportingErrors())
147  INFO(string("Request with " + boost::lexical_cast<string>(nIndices) +
148  " indices, none of which specifies 'isUUB'; ") +
149  QueryInfoMessage(componentProperty, modelType, componentIndex));
150  return dataB;
151  }
152  hardwareVersion = hardIt->second;
153 
154  switch (nIndices) {
155  // Two indices must be stationId and isUUB. dataB is returned if this
156  // is not the case. As such, switch starts with case 3.
157  case 1:
158  case 2:
159  break;
160  case 3:
161  {
162  const IndexMap::const_iterator pmtIt = componentIndex.find("PMTId");
163  if (pmtIt == componentIndex.end()) {
164  if (IsReportingErrors())
165  INFO(string("Request with three indices, "
166  "none of which specifies 'PMTId'; ") +
167  QueryInfoMessage(componentProperty, modelType, componentIndex));
168  return dataB;
169  }
170  componentAtts["PMTId"] = pmtIt->second;
171  }
172  break;
173  case 4:
174  if (IsReportingErrors())
175  INFO(string("Three indices in query: not yet supported; ") +
176  QueryInfoMessage(componentProperty, modelType, componentIndex));
177  return dataB;
178 
179  default:
180  if (IsReportingErrors()) {
181  INFO(string("Invalid number of parameters; ") +
182  QueryInfoMessage(componentProperty, modelType, componentIndex));
183  }
184  return dataB;
185  }
186 
187  IndexIndexMap hardwareVersionsMap;
188  const std::map<std::string, IndexIndexMap>::const_iterator sHardwareVersions =
189  fStationModelMap.find(stationId);
190  if (sHardwareVersions != fStationModelMap.end())
191  hardwareVersionsMap = sHardwareVersions->second;
192  else if (!fAllStationsModelMap.empty())
193  hardwareVersionsMap = fAllStationsModelMap;
194  else {
195  ostringstream err;
196  err << "Cannot map station " << stationId << " to the list of known hardware "
197  "versions since hardware versions for 'all' does not exist.";
198  ERROR(err);
199  return dataB;
200  }
201 
202  // selecting modelMap based on hardware version
203  IndexMap modelMap;
204  const IndexIndexMap::const_iterator sModels =
205  hardwareVersionsMap.find(hardwareVersion);
206  if (sModels != hardwareVersionsMap.end())
207  modelMap = sModels->second;
208  else {
209  ostringstream err;
210  err << "cannot access model map for requested hardware version "
211  << hardwareVersion << " since this version "
212  << "does not exist for the specified station or 'all' station "
213  << "configuration if that was requested.";
214  ERROR(err);
215  return dataB;
216  }
217 
218  string modelId;
219  {
220  string modelTypeFull;
221  /*
222  * As different "models" are used for the same "type" in the case of
223  * PMTs (e.g. small PMT vs. scintillator PMT), and the mangager mapping
224  * machinery is not setup to hand such cases, the PMT models in the modelMap
225  * are matched to the the model being queried by a string where the model
226  * type has the PMTId concatenated to it's end.
227  */
228  if (modelType == "PMT" || modelType == "pmtElectronics") {
229  modelTypeFull = modelType+componentAtts["PMTId"];
230  } else {
231  modelTypeFull = modelType;
232  }
233  const IndexMap::const_iterator mIt = modelMap.find(modelTypeFull);
234  if (mIt != modelMap.end()) {
235  modelId = mIt->second;
236  }
237  }
238 
239  // Get the requested data from the DOM
240  //
241  IndexMap atts;
242  atts["id"] = modelId;
243 
244  Branch stationModelsB = fBranch.GetChild("stationModels");
245  if (!stationModelsB)
246  return stationModelsB;
247 
248  Branch modelTypeB = stationModelsB.GetChild(modelType, atts);
249  if (!modelTypeB) {
250  return modelTypeB;
251  }
252 
253  // First, attempt to find the dataB without providing componentAtts map
254  // to further specify a component. componentAtts is currently used to
255  // identify a particular PMT in a tank.
256  // If no attributes are present to specify, for example, a particular PMT,
257  // then the data are assumed to be valid for all PMTs associated with
258  // the particular model type. This should generally be the case. The only
259  // instance (I can think of) where this is not true is in specification
260  // of the PMT position, as the three PMT's are clearly located in three
261  // different places in the tank.
262 
263  dataB = modelTypeB.GetChild(componentProperty);
264 
265  // If no data found when no componentAtts specified, specify the componentAtts.
266  // This will find data unique to a PMT in the tank
267 
268  if (!dataB)
269  dataB = modelTypeB.GetChild(componentProperty, componentAtts);
270 
271  return dataB;
272 }
273 
274 
275 void
277 {
278  // fill fStationIdMap from DetectorConfig file
279  // Parse information between <stationConfig> tags and fill fStationModelMap
280  //
281  Branch stationConfigB = fBranch.GetChild("stationConfig");
282  for (Branch setB = stationConfigB.GetFirstChild();
283  setB; setB = setB.GetNextSibling()) {
284  /*
285  * If unique specifications were to be applied to individual stations,
286  * a loop over "generic" and "unique" branches would be added here.
287  * For now, all stations adhere to the two possible hardware versions
288  * (pre/post AugerPrime) with identical properties for each type of
289  * hardware (e.g. identical quantum efficiency for all PMTs with
290  * id="photonis-XP1805").
291  */
292  Branch hardwareVersionsB = setB.GetChild("hardwareVersions");
293 
294  std::map<std::string, IndexMap> hardwareVersionMap;
295 
296  for (Branch hardwareB = hardwareVersionsB.GetFirstChild();
297  hardwareB; hardwareB = hardwareB.GetNextSibling()) { // loop on hardware versions
298 
299  IndexMap modelMap;
300 
301  for (Branch modelB = hardwareB.GetFirstChild();
302  modelB; modelB = modelB.GetNextSibling()) { // loop on models
303 
304  const IndexMap atts(modelB.GetAttributes());
305  /*
306  * As different "models" are used for the same "type" in the case of
307  * PMTs (e.g. small PMT vs. scintillator PMT), and the mangager mapping
308  * machinery is not setup to hand such cases, the PMT models in the modelMap
309  * are matched to the the model being queried by a string where the model
310  * type has the PMTId concatenated to it's end.
311  */
312  if (modelB.GetName() == "PMT" || modelB.GetName() == "pmtElectronics") {
313  modelMap[modelB.GetName()+atts.find("PMTId")->second] = atts.find("id")->second;
314  } else {
315  modelMap[modelB.GetName()] = atts.find("id")->second;
316  }
317  }
318 
319  hardwareVersionMap[hardwareB.GetAttributes().find("isUUB")->second] = modelMap;
320 
321  }
322 
323  // check if these hardware versions apply to all stations
324  IndexMap optAtts;
325  optAtts["id"] = "all";
326  Branch allStationsB = setB.GetChild("stations", optAtts);
327  if (allStationsB)
328  fAllStationsModelMap = hardwareVersionMap;
329  else {
330  // if not get the station ids
331  Branch stationsB = setB.GetChild("stations");
332  if (stationsB)
333  // loop on stations (to which this model applies)
334  for (Branch stationB = stationsB.GetFirstChild();
335  stationB; stationB = stationB.GetNextSibling()) {
336 
337  const IndexMap atts(stationB.GetAttributes());
338  const string stationIdString(atts.find("id")->second);
339 
340  // write an entry in map<Id, map<model type, model id> >
341  fStationModelMap[stationIdString] = hardwareVersionMap;
342  }
343  }
344  }
345 }
346 
347 
350  const std::string& component,
351  const std::string& property,
352  const IndexMap& index)
353  const
354 {
355  if (!returnData.Is<unsigned int>())
356  return eNotFound;
357  if (!((property == "barCount" && component == "scintillator") ||
358  (property == "traceBins" && component == "electronics")))
359  return eNotFound;
360 
361  Branch dataBranch =
362  FindBranch(property, component, index);
363 
364  if (!dataBranch)
365  return eNotFound;
366 
367  returnData.Get<unsigned int>() = dataBranch.Get<unsigned int>();
368 
369  return eFound;
370 }
Status GetData(utl::TabulatedFunction &returnData, const std::string &componentProperty, const std::string &componentName, const IndexMap &componentIndex) const
Class to hold collection (x,y) points and provide interpolation between them.
bool Is() const
Definition: VManager.h:162
virtual Status GenericGetData(Handle &returnData, const std::string &component, const std::string &property, const IndexMap &index) const
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
void PushBack(const double x, const double y)
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
T Get() const
Definition: Branch.h:271
Branch GetNextSibling() const
Get next sibling of this branch.
Definition: Branch.cc:284
Manager for SD description in XML &quot;model&quot; files.
Class representing a document branch.
Definition: Branch.h:107
#define REGISTER_S_MANAGER(_name_, _Type_)
Status InternalGetData(T &returnData, const std::string &componentProperty, const std::string &componentName, const IndexMap &componentIndex) const
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
if(dataRoot)
Definition: XXMLManager.h:1003
std::map< std::string, std::string > IndexMap
Definition: VManager.h:133
Branch GetFirstChild() const
Get first child of this Branch.
Definition: Branch.cc:98
boost::add_reference< typename boost::remove_const< T >::type >::type Get()
Definition: VManager.h:150
utl::Branch FindBranch(const std::string &property, const std::string &modelType, const IndexMap &componentIndex) const
std::map< std::string, IndexMap > IndexIndexMap
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
Status
Specifies success or (eventually) various possible failure modes.
Definition: VManager.h:127

, generated on Tue Sep 26 2023.