45#ifndef DOXYGEN_SHOULD_SKIP_THIS
51# include <agrum/base/external/json/json.hpp>
52using json = nlohmann::json;
55 template < GUM_Numeric GUM_SCALAR >
57 std::string_view filename,
58 bool binary) :
MRFReader< GUM_SCALAR >(mrf, filename) {
59 GUM_CONSTRUCTOR(GumMRFReader)
61 _streamName_ = filename;
66 template < GUM_Numeric GUM_SCALAR >
67 GumMRFReader< GUM_SCALAR >::GumMRFReader(MarkovRandomField< GUM_SCALAR >* mrf) :
68 MRFReader< GUM_SCALAR >(mrf,
"") {
69 GUM_CONSTRUCTOR(GumMRFReader)
76 template < GUM_Numeric GUM_SCALAR >
77 GumMRFReader< GUM_SCALAR >::~GumMRFReader() {
78 GUM_DESTRUCTOR(GumMRFReader)
81 template < GUM_Numeric GUM_SCALAR >
82 template <
typename JsonType >
83 Size GumMRFReader< GUM_SCALAR >::_proceedFromJson_(
const JsonType& content) {
86 if (content.contains(
"type") && content[
"type"].template get< std::string >() !=
"MRF") {
87 addError(
"Invalid GUM file format: expected 'MRF' type, got '"
88 + content[
"type"].
template get< std::string >() +
"'",
95 if (!content.contains(
"nodes") || !content.contains(
"factors")) {
96 addError(
"Invalid GUM file format: missing 'nodes' or 'factors' sections",
104 MarkovRandomField< GUM_SCALAR > tmp;
107 for (
const auto& node: content[
"nodes"]) {
108 tmp.add(node.template get< std::string >());
113 std::vector< std::string > varnames;
114 std::vector< double > values;
117 std::vector< FactorData > factors;
118 factors.reserve(content[
"factors"].size());
119 for (
const auto& factor: content[
"factors"]) {
120 factors.push_back({factor[
"vars"].template get< std::vector< std::string > >(),
121 factor[
"values"].
template get< std::vector< double > >()});
124 tmp.beginTopologyTransformation();
125 for (
const auto& fd: factors)
126 tmp.addFactor(fd.varnames);
127 tmp.endTopologyTransformation();
129 for (
const auto& fd: factors)
130 tmp.factor(fd.varnames).fillWith(fd.values);
133 if (content.contains(
"properties")) {
134 for (
const auto& prop: content[
"properties"].items()) {
135 tmp.setProperty(prop.key(), prop.value().template get< std::string >());
139 *_mrf_ = std::move(tmp);
148 template < GUM_Numeric GUM_SCALAR >
149 Size GumMRFReader< GUM_SCALAR >::proceed() {
150 if (_parseDone_) {
return 0; }
151 if (_streamName_.empty()) {
153 "GumMRFReader was constructed without a filename: use proceedFromString() instead "
158 std::ifstream file(_streamName_, _binary_ ? std::ios::binary : std::ios::in);
159 if (!file.is_open()) {
160 addException(
"No such file " + _streamName_, _streamName_);
165 = _binary_ ? json::from_msgpack(
_readVector_(file)) : json::parse(file, nullptr, false);
167 if (content.is_discarded()) {
168 addException(
"Error parsing file", _streamName_);
171 return _proceedFromJson_(content);
172 }
catch (
const std::exception& e) {
173 addException(std::string(
"Error reading binary file: ") + e.what(), _streamName_);
178 template < GUM_Numeric GUM_SCALAR >
179 Size GumMRFReader< GUM_SCALAR >::proceedFromString(std::string_view content) {
180 if (_parseDone_) {
return 0; }
181 const auto j = json::parse(content,
nullptr,
false);
182 if (j.is_discarded()) {
183 addException(
"Invalid JSON string", _streamName_);
186 return _proceedFromJson_(j);
189 template < GUM_Numeric GUM_SCALAR >
190 void GumMRFReader< GUM_SCALAR >::showElegantErrorsAndWarnings(std::ostream& stream)
const {
191 if (_parseDone_ || count() > 0) {
192 elegantErrorsAndWarnings(stream);
198 template < GUM_Numeric GUM_SCALAR >
199 void GumMRFReader< GUM_SCALAR >::showErrorCounts(std::ostream& stream)
const {
200 if (_parseDone_ || count() > 0) {
201 syntheticResults(stream);
Shared binary I/O helpers for GUM (jgum/bgum) serialization.
Definition of class for reading a MarkovRandomField from a GUM (json) file.
Base class for all aGrUM's exceptions.
GUM_NODISCARD std::string errorContent() const
Returns the message content.
GumMRFReader(MarkovRandomField< GUM_SCALAR > *mrf, std::string_view filename, bool binary=false)
Constructor.
Pure virtual class for reading a MRF from a file.
Exception : operation not allowed.
#define GUM_ERROR(type, msg)
gum is the global namespace for all aGrUM entities
std::vector< uint8_t > _readVector_(std::istream &is)
Reads a length-prefixed byte vector from a binary stream (bgum format).