CModelsXMLManager.cc
Go to the documentation of this file.
1 #include <boost/lambda/lambda.hpp>
2 #include <boost/lexical_cast.hpp>
3 #include <cdet/CModelsXMLManager.h>
4 #include <utl/ErrorLogger.h>
5 #include <utl/TabulatedFunction.h>
6 #include <cdet/CDetector.h>
7 #include <cdet/CManagerRegister.h> // needed for registration macro
8 
9 using namespace cdet;
10 using namespace std;
11 using namespace utl;
12 using namespace det;
13 using namespace xercesc;
14 using namespace boost::lambda;
15 
16 REGISTER_C_MANAGER("CModelsXMLManager", CModelsXMLManager)
17 
18 void
19 CModelsXMLManager::Init(const string& configLink)
20 {
21  VManager::Init(configLink);
22  FillMaps();
23 }
24 
25 
26 // Generic data getters
27 // --------------------
28 template<typename T>
31  const string& componentProperty,
32  const string& componentName,
33  const IndexMap& componentIndex)
34  const
35 {
36 
37  // Find where requested data resides in DOM
38  Branch dataBranch =
39  FindBranch(componentProperty, componentName, componentIndex);
40 
41  if (!dataBranch)
42  return eNotFound;
43 
44  dataBranch.GetData(returnData);
45 
46  return eFound;
47 }
48 
49 
52  const string& componentProperty,
53  const string& componentName,
54  const IndexMap& componentIndex)
55  const
56 {
57  // Find where requested data resides in DOM
58 
59  Branch dataBranch =
60  FindBranch(componentProperty, componentName, componentIndex);
61  if (!dataBranch)
62  return eNotFound;
63 
64  // Since this is tabulated data, retrieve the ordinate and abscissa
65  // NOTE THAT IT IS ASSUMED THAT THE ABSCISSA IS LABELED "x" AND
66  // THE ORDINATE IS LABELED "y"
67  Branch xB = dataBranch.GetChild("x");
68  if (!xB)
69  return eNotFound;
70 
71  vector<double> x;
72  xB.GetData(x);
73 
74  Branch yB = dataBranch.GetChild("y");
75  if (!yB)
76  return eNotFound;
77 
78  vector<double> y;
79  yB.GetData(y);
80 
81  // As a convenience, scale all ordinate values if a scale factor is given
82  double scaleY;
83  Branch scaleYB = dataBranch.GetChild("scaleY");
84  if (scaleYB) {
85  scaleYB.GetData(scaleY);
86  for_each(y.begin(), y.end(), _1 *= scaleY);
87  }
88 
89  const unsigned int n = x.size();
90  for (unsigned int i = 0; i < n; ++i)
91  returnData.PushBack(x[i], y[i]);
92 
93  return eFound;
94 }
95 
96 
105 Branch
106 CModelsXMLManager::FindBranch(const string& componentProperty,
107  const string& modelType,
108  const IndexMap& componentIndex)
109  const
110 {
111  // Act on the Branch request based on the number of indices specified
112  // Number of indices can be 1 (just the station id), 2 (station and RPC id's)
113  // or 3 (station, Pad, channel)
114  const int nIndices = componentIndex.size();
115 
116  // The component attribute map is currently used in cases where a RPC index
117  // is specified (that is we have differing data applying to the RPC chambers in
118  // a station). The commonest application for this is presumably specifying
119  // the RPC positions.
120  string stationId;
121  IndexMap componentAtts;
122 
123  Branch dataB;
124 
125  switch (nIndices) {
126  case 1:
127  {
128  // If just 1 index, it had better be the station Id!
129  const IndexMap::const_iterator stIt = componentIndex.begin();
130  if (stIt->first == "stationId") {
131  stationId = stIt->second;
132  break;
133  }
134  if (IsReportingErrors())
135  INFO(string("If data request is made using 1 index, "
136  "that index must specify 'stationId'; ") +
137  QueryInfoMessage(componentProperty, modelType, componentIndex));
138  return dataB;
139  }
140  break;
141  case 2:
142  {
143  const IndexMap::const_iterator stIt = componentIndex.find("stationId");
144  if (stIt == componentIndex.end()) {
145  if (IsReportingErrors())
146  INFO(string("Request with two indices, "
147  "neither of which specifies 'stationId'; ") +
148  QueryInfoMessage(componentProperty, modelType, componentIndex));
149  return dataB;
150  }
151  stationId = stIt->second;
152 
153  const IndexMap::const_iterator rpcIt = componentIndex.find("RPCId");
154  if (rpcIt != componentIndex.end())
155  componentAtts["RPCId"] = rpcIt->second;
156  else
157  return dataB;
158  }
159  break;
160  case 3:
161  if (IsReportingErrors())
162  INFO(string("Three indices in query: not yet supported; ") +
163  QueryInfoMessage(componentProperty, modelType, componentIndex));
164  return dataB;
165 
166  default:
167  if (IsReportingErrors()) {
168  INFO(string("Invalid number of parameters; ") +
169  QueryInfoMessage(componentProperty, modelType, componentIndex));
170  }
171  return dataB;
172  }
173 
174  IndexMap modelMap;
175  const map<string, IndexMap>::const_iterator sModel =
176  fStationModelMap.find(stationId);
177  if (sModel != fStationModelMap.end())
178  modelMap = sModel->second;
179  else if (!fAllStationsModelMap.empty())
180  modelMap = fAllStationsModelMap;
181  else {
182  ostringstream err;
183  err << "Cannot map station " << stationId << " to the list of known models "
184  "since model for 'all' does not exist.";
185  ERROR(err);
186  return dataB;
187  }
188 
189  string modelId;
190  {
191  const IndexMap::const_iterator mIt = modelMap.find(modelType);
192  if (mIt != modelMap.end())
193  modelId = mIt->second;
194  }
195 
196  // Get the requested data from the DOM
197  //
198  IndexMap atts;
199  atts["id"] = modelId;
200 
201  Branch stationModelsB = fBranch.GetChild("stationModels");
202  if (!stationModelsB)
203  return stationModelsB;
204 
205  Branch modelTypeB = stationModelsB.GetChild(modelType, atts);
206  if (!modelTypeB)
207  return modelTypeB;
208 
209  // First, attempt to find the dataB without providing componentAtts map
210  // to further specify a component. componentAtts is currently used to
211  // identify a particular Pad in a tank.
212  // If no attributes are present to specify, for example, a particular Pad,
213  // then the data are assumed to be valid for all Pads associated with
214  // the particular model type. This should generally be the case. The only
215  // instance (I can think of) where this is not true is in specification
216  // of the Pad position, as the three Pad's are clearly located in three
217  // different places in the tank.
218  dataB = modelTypeB.GetChild(componentProperty);
219 
220  // If no data found when no componentAtts specified, specify the componentAtts.
221  // This will find data unique to a RPC in the tank
222 
223  if (!dataB)
224  dataB = modelTypeB.GetChild(componentProperty, componentAtts);
225 
226  return dataB;
227 }
228 
229 
230 void
232 {
233  // fill fStationIdMap from DetectorConfig file
234  // Parse information between <stationConfig> tags and fill fStationModelMap
235  //
236 
237  Branch stationConfigB = fBranch.GetChild("stationConfig");
238 
239  for (Branch protoB = stationConfigB.GetFirstChild();
240  protoB; protoB = protoB.GetNextSibling()) { // loop on prototypes
241 
242  Branch modelsB = protoB.GetChild("models");
243  IndexMap modelMap;
244  for (Branch modelB = modelsB.GetFirstChild();
245  modelB; modelB = modelB.GetNextSibling()) { // loop on models
246 
247  const IndexMap atts(modelB.GetAttributes());
248  modelMap[modelB.GetName()] = atts.find("id")->second;
249  }
250 
251  // check if this model applies to all stations
252  IndexMap optAtts;
253  optAtts["id"] = "all";
254  Branch allStationsB = protoB.GetChild("stations", optAtts);
255  if (allStationsB)
256 
257  fAllStationsModelMap = modelMap;
258 
259  else {
260 
261  // if not get the station ids
262  Branch stationsB = protoB.GetChild("stations");
263  if (stationsB)
264  // loop on stations (to which this model applies)
265  for (Branch stationB = stationsB.GetFirstChild();
266  stationB; stationB = stationB.GetNextSibling()) {
267 
268  const IndexMap atts(stationB.GetAttributes());
269  const string stationIdString(atts.find("id")->second);
270 
271  // write an entry in map<Id, map<model type, model id> >
272  fStationModelMap[stationIdString] = modelMap;
273  }
274 
275  }
276 
277  }
278 }
279 
280 
283  const std::string& component,
284  const std::string& property,
285  const IndexMap& index)
286  const
287 {
288  if (!returnData.Is<unsigned int>())
289  return eNotFound;
290  //if (!((property == "barCount" && component == "scintillator") ||
291  // (property == "traceBins" && component == "electronics")))
292  // return eNotFound;
293 
294  Branch dataBranch =
295  FindBranch(property, component, index);
296 
297  if (!dataBranch)
298  return eNotFound;
299 
300  returnData.Get<unsigned int>() = dataBranch.Get<unsigned int>();
301 
302  return eFound;
303 }
Status InternalGetData(T &returnData, const std::string &componentProperty, const std::string &componentName, const IndexMap &componentIndex) const
utl::Branch FindBranch(const std::string &property, const std::string &modelType, const IndexMap &componentIndex) const
Class to hold collection (x,y) points and provide interpolation between them.
bool Is() const
Definition: VManager.h:162
#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
Class representing a document branch.
Definition: Branch.h:107
REGISTER_C_MANAGER("CStationListXMLManager", CStationListXMLManager)
Status GetData(utl::TabulatedFunction &returnData, const std::string &componentProperty, const std::string &componentName, const IndexMap &componentIndex) const
Manager for MARTA station description in XML &quot;model&quot; files.
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
virtual Status GenericGetData(Handle &returnData, const std::string &component, const std::string &property, const IndexMap &index) const
#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.