aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
BIFXMLIDReader_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 #ifndef DOXYGEN_SHOULD_SKIP_THIS
23 
24 # include <agrum/ID/io/BIFXML/BIFXMLIDReader.h>
25 # include <fstream>
26 # include <iostream>
27 # include <sstream>
28 
29 namespace gum {
30  /*
31  * Constructor
32  * A reader is created to reading a defined file.
33  * Note that an ID as to be created before and given in parameter.
34  */
35  template < typename GUM_SCALAR >
36  INLINE BIFXMLIDReader< GUM_SCALAR >::BIFXMLIDReader(
37  InfluenceDiagram< GUM_SCALAR >* infdiag,
38  const std::string& filePath) :
39  IDReader< GUM_SCALAR >(infdiag, filePath) {
40  GUM_CONSTRUCTOR(BIFXMLIDReader);
41  infdiag__ = infdiag;
42  filePath__ = filePath;
43  }
44 
45  /*
46  * Default destructor.
47  */
48  template < typename GUM_SCALAR >
49  INLINE BIFXMLIDReader< GUM_SCALAR >::~BIFXMLIDReader() {
50  GUM_DESTRUCTOR(BIFXMLIDReader);
51  }
52 
53  /*
54  * Reads the influence diagram from the file referenced by filePath given at
55  * the
56  * creation of class
57  * @return Returns the number of error during the parsing (0 if none).
58  */
59  template < typename GUM_SCALAR >
60  void BIFXMLIDReader< GUM_SCALAR >::proceed() {
61  try {
62  // Loading file
63  std::string status = "Loading File ...";
64  GUM_EMIT2(onProceed, 0, status);
65 
66  ticpp::Document xmlDoc(filePath__);
67  xmlDoc.LoadFile();
68 
69  if (xmlDoc.NoChildren()) {
70  GUM_ERROR(IOError,
71  ": Loading fail, please check the file for any syntax error.");
72  }
73 
74  // Finding BIF element
75  status = "File loaded. Now looking for BIF element ...";
76  GUM_EMIT2(onProceed, 4, status);
77 
78  ticpp::Element* bifElement = xmlDoc.FirstChildElement("BIF");
79 
80  // Finding network element
81  status = "BIF Element reached. Now searching network ...";
82  GUM_EMIT2(onProceed, 7, status);
83 
84  ticpp::Element* networkElement = bifElement->FirstChildElement("NETWORK");
85 
86  // Finding id variables
87  status = "Network found. Now proceeding variables instanciation...";
88  GUM_EMIT2(onProceed, 10, status);
89 
90  parsingVariables__(networkElement);
91 
92  // Filling diagram
93  status = "All variables have been instancied. Now filling up diagram...";
94  GUM_EMIT2(onProceed, 55, status);
95 
96  fillingDiagram__(networkElement);
97 
98  status = "Instanciation of network completed";
99  GUM_EMIT2(onProceed, 100, status);
100 
101  } catch (ticpp::Exception& tinyexception) {
102  GUM_ERROR(IOError, tinyexception.what());
103  }
104  }
105 
106  template < typename GUM_SCALAR >
107  void BIFXMLIDReader< GUM_SCALAR >::parsingVariables__(
108  ticpp::Element* parentNetwork) {
109  // Counting the number of variable for the signal
110  int nbVar = 0;
111  ticpp::Iterator< ticpp::Element > varIte("VARIABLE");
112 
113  for (varIte = varIte.begin(parentNetwork); varIte != varIte.end(); ++varIte)
114  nbVar++;
115 
116  // Iterating on variable element
117  int nbIte = 0;
118 
119  for (varIte = varIte.begin(parentNetwork); varIte != varIte.end(); ++varIte) {
120  ticpp::Element* currentVar = varIte.Get();
121 
122  // Getting variable name
123  ticpp::Element* varNameElement = currentVar->FirstChildElement("NAME");
124  std::string varName = varNameElement->GetTextOrDefault("");
125 
126  // Getting variable description
127  ticpp::Element* varDescrElement = currentVar->FirstChildElement("PROPERTY");
128  std::string varDescription = varDescrElement->GetTextOrDefault("");
129 
130  // Instanciation de la variable
131  LabelizedVariable newVar(varName, varDescription, 0);
132 
133  // Getting variable outcomes
134  ticpp::Iterator< ticpp::Element > varOutComesIte("OUTCOME");
135 
136  for (varOutComesIte = varOutComesIte.begin(currentVar);
137  varOutComesIte != varOutComesIte.end();
138  ++varOutComesIte)
139  newVar.addLabel(varOutComesIte->GetTextOrDefault(""));
140 
141  // Getting variable type
142  std::string nodeType = currentVar->GetAttribute< std::string >("TYPE");
143 
144  // Add the variable to the id
145  if (nodeType.compare("decision") == 0)
146  infdiag__->addDecisionNode(newVar);
147  else if (nodeType.compare("utility") == 0)
148  infdiag__->addUtilityNode(newVar);
149  else
150  infdiag__->addChanceNode(newVar);
151 
152  // Emitting progress.
153  std::string status
154  = "Network found. Now proceedind variables instanciation...";
155  int progress = (int)((float)nbIte / (float)nbVar * 45) + 10;
156  GUM_EMIT2(onProceed, progress, status);
157  nbIte++;
158  }
159  }
160 
161  template < typename GUM_SCALAR >
162  void BIFXMLIDReader< GUM_SCALAR >::fillingDiagram__(
163  ticpp::Element* parentNetwork) {
164  // Counting the number of variable for the signal
165  int nbDef = 0;
166  ticpp::Iterator< ticpp::Element > definitionIte("DEFINITION");
167 
168  for (definitionIte = definitionIte.begin(parentNetwork);
169  definitionIte != definitionIte.end();
170  ++definitionIte)
171  nbDef++;
172 
173  // Iterating on definition nodes
174  int nbIte = 0;
175 
176  for (definitionIte = definitionIte.begin(parentNetwork);
177  definitionIte != definitionIte.end();
178  ++definitionIte) {
179  ticpp::Element* currentVar = definitionIte.Get();
180 
181  // Considered Node
182  std::string currentVarName
183  = currentVar->FirstChildElement("FOR")->GetTextOrDefault("");
184  NodeId currentVarId = infdiag__->idFromName(currentVarName);
185 
186  // Get Node's parents
187  ticpp::Iterator< ticpp::Element > givenIte("GIVEN");
188  List< NodeId > parentList;
189 
190  for (givenIte = givenIte.begin(currentVar); givenIte != givenIte.end();
191  ++givenIte) {
192  std::string parentNode = givenIte->GetTextOrDefault("");
193  NodeId parentId = infdiag__->idFromName(parentNode);
194  parentList.pushBack(parentId);
195  }
196 
197  for (List< NodeId >::iterator_safe parentListIte = parentList.rbeginSafe();
198  parentListIte != parentList.rendSafe();
199  --parentListIte)
200  infdiag__->addArc(*parentListIte, currentVarId);
201 
202  // Recuperating tables values
203  if (!infdiag__->isDecisionNode(currentVarId)) {
204  ticpp::Element* tableElement = currentVar->FirstChildElement("TABLE");
205  std::istringstream issTableString(tableElement->GetTextOrDefault(""));
206  std::list< GUM_SCALAR > tablelist;
207  GUM_SCALAR value;
208 
209  while (!issTableString.eof()) {
210  issTableString >> value;
211  tablelist.push_back(value);
212  }
213 
214  std::vector< GUM_SCALAR > tablevector(tablelist.begin(), tablelist.end());
215 
216  // Filling tables
217  if (infdiag__->isChanceNode(currentVarId)) {
218  const Potential< GUM_SCALAR >* table = &infdiag__->cpt(currentVarId);
219  table->populate(tablevector);
220  } else if (infdiag__->isUtilityNode(currentVarId)) {
221  const Potential< GUM_SCALAR >* table = &infdiag__->utility(currentVarId);
222  table->populate(tablevector);
223  }
224  }
225 
226  // Emitting progress.
227  std::string status
228  = "All variables have been instancied. Now filling up diagram...";
229  int progress = (int)((float)nbIte / (float)nbDef * 45) + 55;
230  GUM_EMIT2(onProceed, progress, status);
231  nbIte++;
232  }
233  }
234 
235 } /* namespace gum */
236 
237 #endif // DOXYGEN_SHOULD_SKIP_THIS