RModelsXMLManager.cc
Go to the documentation of this file.
1 #include <boost/lambda/lambda.hpp>
2 
3 #include <rdet/RDetector.h>
4 #include <rdet/RModelsXMLManager.h>
5 #include <rdet/RManagerRegister.h> // needed for registration macro
6 #include <rdet/RSimulationStationListManager.h>
7 
8 #include <utl/ErrorLogger.h>
9 #include <utl/TabulatedFunction.h>
10 #include <utl/TabulatedFunctionComplexLgAmpPhase.h>
11 #include <utl/ComplexLgAmpPhase.h>
12 
13 using namespace rdet;
14 using namespace std;
15 using namespace utl;
16 using namespace det;
17 using namespace xercesc;
18 using namespace boost::lambda;
19 
20 
21 REGISTER_R_MANAGER("RModelsXMLManager", RModelsXMLManager)
22 
23 
24 void
25 RModelsXMLManager::Init(const string& configLink)
26 {
27  VManager::Init(configLink);
28  FillMaps();
29 }
30 
31 
32 // Generic data getters
33 // --------------------
34 template<typename T>
37  const string& componentProperty,
38  const string& componentName,
39  const IndexMap& componentIndex)
40  const
41 {
42  if (componentName == "stationList")
43  return VManager::eNotFound;
44 
45  // this check is also repeated in RModelsXMLManager::FindBranch() taking into account componentIndex.size() == 0
46  if (componentIndex.size()) {
47  const IndexMap::const_iterator stIt = componentIndex.find("station");
48  if (stIt == componentIndex.end()) {
49  if (IsReportingErrors()) {
50  INFO(string("Request with two indices, "
51  "neither of which specifies 'stationId'; ") +
52  QueryInfoMessage(componentProperty, componentName, componentIndex));
53  }
54  }
55  else {
56  // returns eNotFound if the station description is not suppose to be from XML
57  if (RSimulationStationListManager::GetSourceType(componentIndex.find("station")->second) != "XML")
58  return eNotFound;
59  }
60  }
61  else {
62  if (componentProperty == "addSStationList") {
63  fBranch.GetChild("AddStationsFromSManager").GetData(returnData);
64  return eFound;
65  }
66  }
67 
68  // Find where requested data resides in DOM
69  Branch dataBranch =
70  FindBranch(componentProperty, componentName, componentIndex);
71 
72  if (!dataBranch) {
73  return eNotFound;
74  }
75 
76  dataBranch.GetData(returnData);
77 
78  return eFound;
79 }
80 
81 
84  const string& componentProperty,
85  const string& componentName,
86  const IndexMap& componentIndex)
87  const
88 {
89  // Find where requested data resides in DOM
90  Branch dataBranch =
91  FindBranch(componentProperty, componentName, componentIndex);
92 
93  if (!dataBranch)
94  return eNotFound;
95 
96  // Since this is tabulated data, retrieve the ordinate and abscissa
97  // NOTE THAT IT IS ASSUMED THAT THE ABSCISSA IS LABELED "x" AND
98  // THE ORDINATE IS LABELED "y"
99  Branch xB = dataBranch.GetChild("x");
100  if (!xB)
101  return eNotFound;
102 
103  vector<double> x;
104  xB.GetData(x);
105 
106  Branch lgAmpB = dataBranch.GetChild("LgAmp");
107  if (!lgAmpB)
108  return eNotFound;
109 
110  vector<double> lgAmp;
111  lgAmpB.GetData(lgAmp);
112 
113  Branch phaseB = dataBranch.GetChild("Phase");
114  if (!phaseB)
115  return eNotFound;
116 
117  vector<double> phase;
118  phaseB.GetData(phase);
119 
120  const unsigned int n = x.size();
121  returnData = TabulatedFunctionComplexLgAmpPhase();
122  for (unsigned int i = 0; i < n; ++i)
123  returnData.PushBack(x[i], ComplexLgAmpPhase(lgAmp[i],phase[i]));
124 
125  return eFound;
126 }
127 
128 
130 RModelsXMLManager::GetDataMap(std::map<std::string,double>& returnData,
131  const string& componentProperty,
132  const string& componentName,
133  const IndexMap& componentIndex)
134  const
135 {
136  // returns eNotFound if the station description is not suppose to be from XML
137  if (RSimulationStationListManager::GetSourceType(componentIndex.find("station")->second) != "XML")
138  return eNotFound;
139 
140  // Find where requested data, e.g. RResponseMapList, resides in DOM
141  Branch dataBranch =
142  FindBranch(componentProperty, componentName, componentIndex);
143 
144  if (!dataBranch)
145  return eNotFound;
146 
147  do {
148  string ResponseId;
149  dataBranch.GetChild("ResponseId").GetData(ResponseId);
150  double ResponseWeight;
151  dataBranch.GetChild("ResponseWeight").GetData(ResponseWeight);
152 
153  returnData[ResponseId] += ResponseWeight;
154  } while ((dataBranch = dataBranch.GetNextSibling()));
155 
156  return eFound;
157 }
158 
159 
168 Branch
169 RModelsXMLManager::FindBranch(const string& componentProperty,
170  const string& modelType,
171  const IndexMap& componentIndex)
172  const
173 {
174  // Act on the Branch request based on the number of indices specified
175  // Number of indices can be 1 (just the station id), 2 (channel and station id's)
176  const int nIndices = componentIndex.size();
177 
178  IndexMap componentAtts;
179 
180  Branch dataB;
181 
182 
183  switch (nIndices) {
184  case 1:
185  {
186  // FS: The following if block looks fishy...
187  // However I did not find a case where the only index is a station (id):
188  // This should be the case if this manager should return the answer, but it can
189  // very well be that a component with only one index is requested and a other manager
190  // is providing the answer!
191  const IndexMap::const_iterator stIt = componentIndex.begin();
192  if (stIt->first == "station") {
193  componentAtts["channel"] = stIt->second;
194  break;
195  }
196 
197  if (IsReportingErrors())
198  INFO(string("If data request is made using 1 index, "
199  "that index must specify 'station'; ") +
200  QueryInfoMessage(componentProperty, modelType, componentIndex));
201  return dataB;
202  }
203  break;
204  case 2:
205  {
206  const IndexMap::const_iterator stIt = componentIndex.find("station");
207  if (stIt == componentIndex.end()) {
208  if (IsReportingErrors()) {
209  INFO(string("Request with two indices, "
210  "neither of which specifies 'stationId'; ") +
211  QueryInfoMessage(componentProperty, modelType, componentIndex));
212  }
213  return dataB;
214  }
215  componentAtts["station"] = stIt->second;
216 
217  const IndexMap::const_iterator chIt = componentIndex.find("channel");
218  if (chIt != componentIndex.end())
219  componentAtts["channel"] = chIt->second;
220  else
221  return dataB;
222  }
223  break;
224  case 3:
225  if (IsReportingErrors())
226  INFO(string("Three indices in query: not yet supported; ") +
227  QueryInfoMessage(componentProperty, modelType, componentIndex));
228  return dataB;
229 
230  default:
231  if (IsReportingErrors()) {
232  INFO(string("Invalid number of parameters; ") +
233  QueryInfoMessage(componentProperty, modelType, componentIndex));
234  }
235  return dataB;
236  }
237 
238  IndexMap modelMap;
239  const map<pair<std::string, std::string>, IndexMap>::const_iterator sModel =
240  fStationChannelModelMap.find(make_pair(componentAtts["station"], componentAtts["channel"]));
241 
242  const map<std::string, IndexMap>::const_iterator sAugerPrimeModel =
243  fAugerPrimeStationsModelMap.find(componentAtts["channel"]);
244 
245  // FS: This is somewhat insecure. If we configure, in addition to AugerPrime stations,
246  // stations with and id > GetRdSdStationIdLink (30000), and do not provide a configuration for those stations,
247  // they would get configured like a AugerPrime stations. One clould explicitly query the Sd station list ...
248  bool isAugerPrimeStation =
249  std::atoi(componentAtts["station"].c_str()) > det::Detector::GetInstance().GetRDetector().GetRdSdStationIdLink();
250 
251  const map<std::string, IndexMap>::const_iterator sDefaultModel =
252  fDefaultStationsModelMap.find(componentAtts["channel"]);
253 
254  if (sModel != fStationChannelModelMap.end())
255  modelMap = sModel->second;
256  else if (isAugerPrimeStation && sAugerPrimeModel != fAugerPrimeStationsModelMap.end())
257  modelMap = sAugerPrimeModel->second;
258  else if (sDefaultModel != fDefaultStationsModelMap.end())
259  modelMap = sDefaultModel->second;
260  else if (IsReportingErrors()) {
261  ostringstream err;
262  err << "Cannot map channel " << componentAtts["channel"] << " to the list of known models "
263  "since model for 'default' does not exist.";
264  ERROR(err);
265  return dataB;
266  }
267 
268  string modelId;
269  {
270  const IndexMap::const_iterator mIt = modelMap.find(modelType);
271  if (mIt != modelMap.end())
272  modelId = mIt->second;
273  }
274 
275  Branch channelModelsB = fBranch.GetChild("channelModels");
276  if (!channelModelsB)
277  return channelModelsB;
278 
279  // Get the requested data from the DOM
280  IndexMap atts({{ "id", modelId }});
281  Branch modelTypeB = channelModelsB.GetChild(modelType, atts);
282  if (!modelTypeB)
283  return modelTypeB;
284 
285  // First, attempt to find the dataB without providing componentAtts map
286  // to further specify a component. componentAtts is currently used to
287  // identify a particular PMT in a tank.
288  // If no attributes are present to specify, for example, a particular PMT,
289  // then the data are assumed to be valid for all PMTs associated with
290  // the particular model type. This should generally be the case. The only
291  // instance (I can think of) where this is not true is in specification
292  // of the PMT position, as the three PMT's are clearly located in three
293  // different places in the tank.
294  dataB = modelTypeB.GetChild(componentProperty);
295 
296  // If no data found when no componentAtts specified, specify the componentAtts.
297  // This will find data unique to a PMT in the tank
298  if (!dataB)
299  dataB = modelTypeB.GetChild(componentProperty, componentAtts);
300 
301  return dataB;
302 }
303 
304 
305 void
307 {
308  // fill fChannelIdMap from DetectorConfig file
309  // Parse information between <channelConfig> tags and fill fChannelModelMap
310  //
311  Branch channelConfigB = fBranch.GetChild("channelConfig");
312 
313  for (Branch protoB = channelConfigB.GetFirstChild();
314  protoB; protoB = protoB.GetNextSibling()) { // loop on prototypes
315 
316  Branch modelsB = protoB.GetChild("models");
317  IndexMap modelMap;
318  for (Branch modelB = modelsB.GetFirstChild();
319  modelB; modelB = modelB.GetNextSibling()) { // loop on models
320 
321  const IndexMap atts(modelB.GetAttributes());
322  modelMap[modelB.GetName()] = atts.find("id")->second;
323  }
324 
325  // check if this model applies to default stations
326  IndexMap optAtts;
327  IndexMap optAtts2;
328 
329  optAtts["id"] = "default";
330  optAtts2["id"] = "AugerPrime";
331 
332  if (protoB.GetChild("stations", optAtts)) {
333  Branch channelsB = protoB.GetChild("channels");
334  if (channelsB){
335  // loop on channels (to which this model applies)
336  for (Branch channelB = channelsB.GetFirstChild();
337  channelB; channelB = channelB.GetNextSibling()) {
338 
339  const IndexMap atts(channelB.GetAttributes());
340  const string channelIdString(atts.find("id")->second);
341  fDefaultStationsModelMap[channelIdString] = modelMap;
342  }
343  }
344  } else if (protoB.GetChild("stations", optAtts2)) {
345  Branch channelsB = protoB.GetChild("channels");
346  if (channelsB){
347  // loop on channels (to which this model applies)
348  for (Branch channelB = channelsB.GetFirstChild();
349  channelB; channelB = channelB.GetNextSibling()) {
350 
351  const IndexMap atts(channelB.GetAttributes());
352  const string channelIdString(atts.find("id")->second);
353  fAugerPrimeStationsModelMap[channelIdString] = modelMap;
354  }
355  }
356  } else {
357  // get stations
358  Branch stationsB = protoB.GetChild("stations");
359  if (stationsB) {
360  // loop on stations (to which this model applies)
361  for (Branch stationB = stationsB.GetFirstChild();
362  stationB; stationB = stationB.GetNextSibling()) {
363 
364  const IndexMap atts(stationB.GetAttributes());
365  const string stationIdString(atts.find("id")->second);
366  Branch channelsB = protoB.GetChild("channels");
367  if (channelsB) {
368  // loop on channels (to which this model applies)
369  for (Branch channelB = channelsB.GetFirstChild();
370  channelB; channelB = channelB.GetNextSibling()) {
371  const IndexMap atts(channelB.GetAttributes());
372  const string channelIdString(atts.find("id")->second);
373  fStationChannelModelMap[pair<std::string, std::string>(stationIdString,channelIdString)] = modelMap;
374  }
375  }
376  }
377  }
378  }
379  }
380  /*
381  for (std::map<pair<std::string, std::string>, IndexMap>::const_iterator fSCMMiter = fStationChannelModelMap.begin();
382  fSCMMiter!=fStationChannelModelMap.end();++fSCMMiter) {
383  pair<std::string, std::string> tIndex = fSCMMiter->first;
384  cout << "IndexMap Controll-loop: "
385  << "Station " << tIndex.first
386  << "Channel " << tIndex.second
387  << endl;
388  }
389  */
390 }
Status GetDataMap(std::map< std::string, double > &returnData, const std::string &componentProperty, const std::string &componentName, const IndexMap &componentIndex) const
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
Branch GetNextSibling() const
Get next sibling of this branch.
Definition: Branch.cc:284
#define REGISTER_R_MANAGER(_name_, _Type_)
Class representing a document branch.
Definition: Branch.h:107
Class to hold collection (x,y) points and provide interpolation between them, where y are complex num...
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
A class to store complex numbers which are internally represented by log10(amplitude) and phase (and ...
if(dataRoot)
Definition: XXMLManager.h:1003
utl::Branch FindBranch(const std::string &property, const std::string &modelType, const IndexMap &componentIndex) const
void PushBack(const double x, const utl::ComplexLgAmpPhase &y)
std::map< std::string, std::string > IndexMap
Definition: VManager.h:133
Branch GetFirstChild() const
Get first child of this Branch.
Definition: Branch.cc:98
Status GetTFCLAPData(utl::TabulatedFunctionComplexLgAmpPhase &returnData, const std::string &componentProperty, const std::string &componentName, const IndexMap &componentIndex) const
Manager for RD description in XML &quot;model&quot; files.
#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
static std::string GetSourceType(const std::string stationIdstring)

, generated on Tue Sep 26 2023.