aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
BIFXMLIDReader_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by 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(InfluenceDiagram< GUM_SCALAR >* infdiag,
37  const std::string& filePath) :
38  IDReader< GUM_SCALAR >(infdiag, filePath) {
39  GUM_CONSTRUCTOR(BIFXMLIDReader);
40  _infdiag_ = infdiag;
41  _filePath_ = filePath;
42  }
43 
44  /*
45  * Default destructor.
46  */
47  template < typename GUM_SCALAR >
48  INLINE BIFXMLIDReader< GUM_SCALAR >::~BIFXMLIDReader() {
49  GUM_DESTRUCTOR(BIFXMLIDReader);
50  }
51 
52  /*
53  * Reads the influence diagram from the file referenced by filePath given at
54  * the
55  * creation of class
56  * @return Returns the number of error during the parsing (0 if none).
57  */
58  template < typename GUM_SCALAR >
59  void BIFXMLIDReader< GUM_SCALAR >::proceed() {
60  try {
61  // Loading file
62  std::string status = "Loading File ...";
63  GUM_EMIT2(onProceed, 0, status);
64 
65  ticpp::Document xmlDoc(_filePath_);
66  xmlDoc.LoadFile();
67 
68  if (xmlDoc.NoChildren()) {
69  GUM_ERROR(IOError, ": Loading fail, please check the file for any syntax error.")
70  }
71 
72  // Finding BIF element
73  status = "File loaded. Now looking for BIF element ...";
74  GUM_EMIT2(onProceed, 4, status);
75 
76  ticpp::Element* bifElement = xmlDoc.FirstChildElement("BIF");
77 
78  // Finding network element
79  status = "BIF Element reached. Now searching network ...";
80  GUM_EMIT2(onProceed, 7, status);
81 
82  ticpp::Element* networkElement = bifElement->FirstChildElement("NETWORK");
83 
84  // Finding id variables
85  status = "Network found. Now proceeding variables instanciation...";
86  GUM_EMIT2(onProceed, 10, status);
87 
88  _parsingVariables_(networkElement);
89 
90  // Filling diagram
91  status = "All variables have been instancied. Now filling up diagram...";
92  GUM_EMIT2(onProceed, 55, status);
93 
94  _fillingDiagram_(networkElement);
95 
96  status = "Instanciation of network completed";
97  GUM_EMIT2(onProceed, 100, status);
98 
99  } catch (ticpp::Exception& tinyexception) { GUM_ERROR(IOError, tinyexception.what()) }
100  }
101 
102  template < typename GUM_SCALAR >
103  void BIFXMLIDReader< GUM_SCALAR >::_parsingVariables_(ticpp::Element* parentNetwork) {
104  // Counting the number of variable for the signal
105  int nbVar = 0;
106  ticpp::Iterator< ticpp::Element > varIte("VARIABLE");
107 
108  for (varIte = varIte.begin(parentNetwork); varIte != varIte.end(); ++varIte)
109  nbVar++;
110 
111  // Iterating on variable element
112  int nbIte = 0;
113 
114  for (varIte = varIte.begin(parentNetwork); varIte != varIte.end(); ++varIte) {
115  ticpp::Element* currentVar = varIte.Get();
116 
117  // Getting variable name
118  ticpp::Element* varNameElement = currentVar->FirstChildElement("NAME");
119  std::string varName = varNameElement->GetTextOrDefault("");
120 
121  // Getting variable description
122  ticpp::Element* varDescrElement = currentVar->FirstChildElement("PROPERTY");
123  std::string varDescription = varDescrElement->GetTextOrDefault("");
124 
125  // Instanciation de la variable
126  LabelizedVariable newVar(varName, varDescription, 0);
127 
128  // Getting variable outcomes
129  ticpp::Iterator< ticpp::Element > varOutComesIte("OUTCOME");
130 
131  for (varOutComesIte = varOutComesIte.begin(currentVar);
132  varOutComesIte != varOutComesIte.end();
133  ++varOutComesIte)
134  newVar.addLabel(varOutComesIte->GetTextOrDefault(""));
135 
136  // Getting variable type
137  std::string nodeType = currentVar->GetAttribute< std::string >("TYPE");
138 
139  // Add the variable to the id
140  if (nodeType.compare("decision") == 0)
141  _infdiag_->addDecisionNode(newVar);
142  else if (nodeType.compare("utility") == 0)
143  _infdiag_->addUtilityNode(newVar);
144  else
145  _infdiag_->addChanceNode(newVar);
146 
147  // Emitting progress.
148  std::string status = "Network found. Now proceedind variables instanciation...";
149  int progress = (int)((float)nbIte / (float)nbVar * 45) + 10;
150  GUM_EMIT2(onProceed, progress, status);
151  nbIte++;
152  }
153  }
154 
155  template < typename GUM_SCALAR >
156  void BIFXMLIDReader< GUM_SCALAR >::_fillingDiagram_(ticpp::Element* parentNetwork) {
157  // Counting the number of variable for the signal
158  int nbDef = 0;
159  ticpp::Iterator< ticpp::Element > definitionIte("DEFINITION");
160 
161  for (definitionIte = definitionIte.begin(parentNetwork); definitionIte != definitionIte.end();
162  ++definitionIte)
163  nbDef++;
164 
165  // Iterating on definition nodes
166  int nbIte = 0;
167 
168  for (definitionIte = definitionIte.begin(parentNetwork); definitionIte != definitionIte.end();
169  ++definitionIte) {
170  ticpp::Element* currentVar = definitionIte.Get();
171 
172  // Considered Node
173  std::string currentVarName = currentVar->FirstChildElement("FOR")->GetTextOrDefault("");
174  NodeId currentVarId = _infdiag_->idFromName(currentVarName);
175 
176  // Get Node's parents
177  ticpp::Iterator< ticpp::Element > givenIte("GIVEN");
178  List< NodeId > parentList;
179 
180  for (givenIte = givenIte.begin(currentVar); givenIte != givenIte.end(); ++givenIte) {
181  std::string parentNode = givenIte->GetTextOrDefault("");
182  NodeId parentId = _infdiag_->idFromName(parentNode);
183  parentList.pushBack(parentId);
184  }
185 
186  for (List< NodeId >::iterator_safe parentListIte = parentList.rbeginSafe();
187  parentListIte != parentList.rendSafe();
188  --parentListIte)
189  _infdiag_->addArc(*parentListIte, currentVarId);
190 
191  // Recuperating tables values
192  if (!_infdiag_->isDecisionNode(currentVarId)) {
193  ticpp::Element* tableElement = currentVar->FirstChildElement("TABLE");
194  std::istringstream issTableString(tableElement->GetTextOrDefault(""));
195  std::list< GUM_SCALAR > tablelist;
196  GUM_SCALAR value;
197 
198  while (!issTableString.eof()) {
199  issTableString >> value;
200  tablelist.push_back(value);
201  }
202 
203  std::vector< GUM_SCALAR > tablevector(tablelist.begin(), tablelist.end());
204 
205  // Filling tables
206  if (_infdiag_->isChanceNode(currentVarId)) {
207  const Potential< GUM_SCALAR >* table = &_infdiag_->cpt(currentVarId);
208  table->populate(tablevector);
209  } else if (_infdiag_->isUtilityNode(currentVarId)) {
210  const Potential< GUM_SCALAR >* table = &_infdiag_->utility(currentVarId);
211  table->populate(tablevector);
212  }
213  }
214 
215  // Emitting progress.
216  std::string status = "All variables have been instancied. Now filling up diagram...";
217  int progress = (int)((float)nbIte / (float)nbDef * 45) + 55;
218  GUM_EMIT2(onProceed, progress, status);
219  nbIte++;
220  }
221  }
222 
223 } /* namespace gum */
224 
225 #endif // DOXYGEN_SHOULD_SKIP_THIS