CYCLUS
Loading...
Searching...
No Matches
xml_file_loader.cc
Go to the documentation of this file.
1// Implements file reader for an XML format
2#include "xml_file_loader.h"
3
4#include <algorithm>
5#include <fstream>
6#include <set>
7#include <streambuf>
8
9#include <boost/filesystem.hpp>
10#include <libxml++/libxml++.h>
11
12#include "agent.h"
13#include "blob.h"
14#include "context.h"
15#include "cyc_std.h"
16#include "env.h"
17#include "error.h"
18#include "exchange_solver.h"
20#include "greedy_solver.h"
21#include "infile_tree.h"
22#include "logger.h"
23#include "sim_init.h"
25
26namespace cyclus {
27
28namespace fs = boost::filesystem;
29
30void LoadRawStringstreamFromFile(std::stringstream& stream, std::string file) {
31 std::ifstream file_stream(file.c_str());
32 if (!file_stream) {
33 throw IOError("The file '" + file + "' could not be loaded.");
34 }
35
36 stream << file_stream.rdbuf();
37 file_stream.close();
38}
39
40void LoadStringstreamFromFile(std::stringstream& stream, std::string file, std::string format) {
41 std::string inext;
42 if (format == "none") {
44 inext = fs::path(file).extension().string();
45 } else {
46 stream << file;
47 }
48 if (inext == ".json" || format == "json") {
49 std::string inxml = cyclus::toolkit::JsonToXml(stream.str());
50 stream.str(inxml);
51 } else if (inext == ".py" || format == "py") {
52 std::string inxml = cyclus::toolkit::PyToXml(stream.str());
53 stream.str(inxml);
54 }
55}
56
57std::string LoadStringFromFile(std::string file, std::string format) {
58 std::stringstream input;
60 return input.str();
61}
62
63std::vector<AgentSpec> ParseSpecs(std::string infile, std::string format) {
64 std::stringstream input;
66 XMLParser parser_;
67 parser_.Init(input);
68 InfileTree xqe(parser_);
69
70 std::vector<AgentSpec> specs;
71 std::set<std::string> unique;
72
73 std::string p = "/simulation/archetypes/spec";
74 int n = xqe.NMatches(p);
75 for (int i = 0; i < n; ++i) {
76 AgentSpec spec(xqe.SubTree(p, i));
77 if (unique.count(spec.str()) == 0) {
78 specs.push_back(spec);
79 unique.insert(spec.str());
80 }
81 }
82
83 if (specs.size() == 0) {
84 throw ValidationError("failed to parse archetype specs from input file");
85 }
86
87 return specs;
88}
89
90std::string BuildMasterSchema(std::string schema_path, std::string infile, std::string format) {
91 Timer ti;
93 Context ctx(&ti, &rec);
94
95 std::stringstream schema("");
97 std::string master = schema.str();
98
99 std::vector<AgentSpec> specs = ParseSpecs(infile, format);
100
101 std::map<std::string, std::string> subschemas;
102
103 // force element types to exist so we always replace the config string
104 subschemas["region"] = "";
105 subschemas["inst"] = "";
106 subschemas["facility"] = "";
107
108 for (int i = 0; i < specs.size(); ++i) {
109 Agent* m = DynamicModule::Make(&ctx, specs[i]);
110 subschemas[m->kind()] += "<element name=\"" + specs[i].alias() + "\">\n";
111 subschemas[m->kind()] += m->schema() + "\n";
112 subschemas[m->kind()] += "</element>\n";
113 ctx.DelAgent(m);
114 }
115
116 // replace refs in master rng template file
117 std::map<std::string, std::string>::iterator it;
118 for (it = subschemas.begin(); it != subschemas.end(); ++it) {
119 std::string search_str = std::string("@") + it->first + std::string("_REFS@");
120 size_t pos = master.find(search_str);
121 if (pos != std::string::npos) {
122 master.replace(pos, search_str.size(), it->second);
123 }
124 }
125
126 return master;
127}
128
130 bool atom_basis;
131 std::string basis_str = qe->GetString("basis");
132 if (basis_str == "atom") {
133 atom_basis = true;
134 } else if (basis_str == "mass") {
135 atom_basis = false;
136 } else {
137 throw IOError(basis_str + " basis is not 'mass' or 'atom'.");
138 }
139
140 double value;
141 int key;
142 std::string query = "nuclide";
143 int nnucs = qe->NMatches(query);
144 CompMap v;
145 for (int i = 0; i < nnucs; i++) {
147 key = pyne::nucname::id(nuclide->GetString("id"));
148 value = strtod(nuclide->GetString("comp").c_str(), NULL);
149 v[key] = value;
150 CLOG(LEV_DEBUG3) << " Nuclide: " << key << " Value: " << v[key];
151 }
152
153 if (atom_basis) {
155 } else {
157 }
158}
159
162 std::string schema_file,
163 const std::string input_file,
164 const std::string format, bool ms_print) : b_(b), rec_(r) {
165 ctx_ = new Context(&ti_, rec_);
166
169 format_ = format;
170 std::stringstream input;
172 parser_ = boost::shared_ptr<XMLParser>(new XMLParser());
173 parser_->Init(input);
175 std::stringstream ss;
176 parser_->Document()->write_to_stream_formatted(ss);
177 ctx_->NewDatum("InputFiles")
178 ->AddVal("Data", Blob(ss.str()))
179 ->Record();
180}
181
185
189
191 std::stringstream ss(master_schema());
192 if(ms_print_){
193 std::cout << master_schema() << std::endl;
194 }
195 parser_->Validate(ss);
196 LoadControlParams(); // must be first
197 LoadSolver();
198 LoadRecipes();
199 LoadPackages();
201 LoadSpecs();
202 LoadInitialAgents(); // must be last
204 rec_->Flush();
205}
206
208 using std::string;
210 InfileTree* qe;
211 std::string query = "/*/commodity";
212
213 std::map<std::string, double> commod_priority;
214 std::string name;
215 double priority;
216 int num_commods = xqe.NMatches(query);
217 for (int i = 0; i < num_commods; i++) {
218 qe = xqe.SubTree(query, i);
219 name = qe->GetString("name");
220 priority = OptionalQuery<double>(qe, "solution_priority", -1);
222 }
223
225 std::map<std::string, double>::iterator it;
226 for (it = commod_priority.begin(); it != commod_priority.end(); ++it) {
227 ctx_->NewDatum("CommodPriority")
228 ->AddVal("Commodity", it->first)
229 ->AddVal("SolutionPriority", it->second)
230 ->Record();
231 }
232
233 // now load the solver info
234 string config = "config";
235 string greedy = "greedy";
236 string coinor = "coin-or";
237 string solver_name = greedy;
238 bool exclusive = ExchangeSolver::kDefaultExclusive;
239 if (xqe.NMatches("/*/control/solver") == 1) {
240 qe = xqe.SubTree("/*/control/solver");
241 if (qe->NMatches(config) == 1) {
242 solver_name = qe->SubTree(config)->GetElementName(0);
243 }
244 exclusive = cyclus::OptionalQuery<bool>(qe, "allow_exclusive_orders",
245 exclusive);
246
247 // @TODO remove this after release 1.5
248 // check for deprecated input values
249 if (qe->NMatches(std::string("exclusive_orders_only")) != 0) {
250 std::stringstream ss;
251 ss << "Use of 'exclusive_orders_only' is deprecated."
252 << " Please see http://fuelcycle.org/user/input_specs/control.html";
254 }
255 }
256
257 if (!exclusive) {
258 std::stringstream ss;
259 ss << "You have set allow_exclusive_orders to False."
260 << " Many archetypes (e.g., :cycamore:Reactor) will not work"
261 << " as intended with this feature turned off.";
262 Warn<VALUE_WARNING>(ss.str());
263 }
264
265 ctx_->NewDatum("SolverInfo")
266 ->AddVal("Solver", solver_name)
267 ->AddVal("ExclusiveOrders", exclusive)
268 ->Record();
269
270 // now load the actual solver
271 if (solver_name == greedy) {
272 query = string("/*/control/solver/config/greedy/preconditioner");
274 ctx_->NewDatum("GreedySolverInfo")
275 ->AddVal("Preconditioner", precon_name)
276 ->Record();
277 } else if (solver_name == coinor) {
278 query = string("/*/control/solver/config/coin-or/timeout");
280 query = string("/*/control/solver/config/coin-or/verbose");
281 bool verbose = cyclus::OptionalQuery<bool>(&xqe, query, false);
282 query = string("/*/control/solver/config/coin-or/mps");
283 bool mps = cyclus::OptionalQuery<bool>(&xqe, query, false);
284 ctx_->NewDatum("CoinSolverInfo")
285 ->AddVal("Timeout", timeout)
286 ->AddVal("Verbose", verbose)
287 ->AddVal("Mps", mps)
288 ->Record();
289 } else {
290 throw ValueError("unknown solver name: " + solver_name);
291 }
292}
293
295 std::map<std::string, double>* commod_priority) {
296 double max = std::max_element(
297 commod_priority->begin(),
298 commod_priority->end(),
299 SecondLT< std::pair<std::string, double> >())->second;
300 if (max < 1) {
301 max = 0; // in case no priorities are specified
302 }
303
304 std::map<std::string, double>::iterator it;
305 for (it = commod_priority->begin();
306 it != commod_priority->end();
307 ++it) {
308 if (it->second < 1) {
309 it->second = max + 1;
310 }
311 CLOG(LEV_INFO1) << "Commodity priority for " << it->first
312 << " is " << it->second;
313 }
314}
315
318
319 std::string query = "/*/recipe";
320 int num_recipes = xqe.NMatches(query);
321 for (int i = 0; i < num_recipes; i++) {
323 std::string name = qe->GetString("name");
324 CLOG(LEV_DEBUG3) << "loading recipe: " << name;
326 comp->Record(ctx_);
327 ctx_->AddRecipe(name, comp);
328 }
329}
330
333
335
336 std::string query = "/*/package";
337 int num_packages = xqe.NMatches(query);
338 for (int i = 0; i < num_packages; i++) {
340 std::string name = cyclus::OptionalQuery<std::string>(qe, "name", "default");
341 CLOG(LEV_DEBUG3) << "loading package: " << name;
342
343 double fill_min = cyclus::OptionalQuery<double>(qe, "fill_min", eps());
344 double fill_max = cyclus::OptionalQuery<double>(qe, "fill_max", std::numeric_limits<double>::max());
345
346 std::string strategy = cyclus::OptionalQuery<std::string>(qe, "strategy", "first");
347
348 ctx_->AddPackage(name, fill_min, fill_max, strategy);
349 }
350}
351
354
355 std::string query = "/*/transportunit";
356 int num_transport_units = xqe.NMatches(query);
357 for (int i = 0; i < num_transport_units; i++) {
359 std::string name = cyclus::OptionalQuery<std::string>(qe, "name", "default");
360 CLOG(LEV_DEBUG3) << "loading transport unit: " << name;
361
362 double fill_min = cyclus::OptionalQuery<double>(qe, "fill_min", eps());
363 double fill_max = cyclus::OptionalQuery<double>(qe, "fill_max", std::numeric_limits<double>::max());
364
365 std::string strategy = cyclus::OptionalQuery<std::string>(qe, "strategy", "first");
366
367 ctx_->AddTransportUnit(name, fill_min, fill_max, strategy);
368 }
369}
370
372 std::vector<AgentSpec> specs = ParseSpecs(file_, format_);
373 for (int i = 0; i < specs.size(); ++i) {
374 specs_[specs[i].alias()] = specs[i];
375 }
376}
377
379 std::map<std::string, std::string> schema_paths;
380 schema_paths["Region"] = "/*/region";
381 schema_paths["Inst"] = "/*/region/institution";
382 schema_paths["Facility"] = "/*/facility";
383
385
386 // create prototypes
387 std::string prototype; // defined here for force-create AgentExit tbl
388 std::map<std::string, std::string>::iterator it;
389 for (it = schema_paths.begin(); it != schema_paths.end(); it++) {
390 int num_agents = xqe.NMatches(it->second);
391 for (int i = 0; i < num_agents; i++) {
392 InfileTree* qe = xqe.SubTree(it->second, i);
393 prototype = qe->GetString("name");
394 std::string alias = qe->SubTree("config")->GetElementName(0);
395 AgentSpec spec = specs_[alias];
396
397 Agent* agent = DynamicModule::Make(ctx_, spec);
398
399 // call manually without agent impl injected to keep all Agent state in a
400 // single, consolidated db table
401 agent->Agent::InfileToDb(qe, DbInit(agent, true));
402
403 agent->InfileToDb(qe, DbInit(agent));
404 rec_->Flush();
405
406 std::vector<Cond> conds;
407 conds.push_back(Cond("SimId", "==", rec_->sim_id()));
408 conds.push_back(Cond("SimTime", "==", static_cast<int>(0)));
409 conds.push_back(Cond("AgentId", "==", agent->id()));
411 PrefixInjector pi(&ci, "AgentState");
412
413 // call manually without agent impl injected
414 agent->Agent::InitFrom(&pi);
415
416 pi = PrefixInjector(&ci, "AgentState" + spec.Sanitize());
417 agent->InitFrom(&pi);
418 ctx_->AddPrototype(prototype, agent);
419 }
420 }
421
422 // build initial agent instances
423 int nregions = xqe.NMatches(schema_paths["Region"]);
424 for (int i = 0; i < nregions; ++i) {
425 InfileTree* qe = xqe.SubTree(schema_paths["Region"], i);
426 std::string region_proto = qe->GetString("name");
428
429 int ninsts = qe->NMatches("institution");
430 for (int j = 0; j < ninsts; ++j) {
431 InfileTree* qe2 = qe->SubTree("institution", j);
432 std::string inst_proto = qe2->GetString("name");
434
435 int nfac = qe2->NMatches("initialfacilitylist/entry");
436 for (int k = 0; k < nfac; ++k) {
437 InfileTree* qe3 = qe2->SubTree("initialfacilitylist/entry", k);
438 std::string fac_proto = qe3->GetString("prototype");
439
440 int number = atoi(qe3->GetString("number").c_str());
441 for (int z = 0; z < number; ++z) {
443 }
444 }
445 }
446 }
447}
448
451 m->Build(parent);
452 if (parent != NULL) {
453 parent->BuildNotify(m);
454 }
455 return m;
456}
457
460 std::string query = "/*/control";
462
463 std::string handle;
464 if (qe->NMatches("simhandle") > 0) {
465 handle = qe->GetString("simhandle");
466 }
467
468 // get duration
469 std::string dur_str = qe->GetString("duration");
470 int dur = strtol(dur_str.c_str(), NULL, 10);
471 // get start month
472 std::string m0_str = qe->GetString("startmonth");
473 int m0 = strtol(m0_str.c_str(), NULL, 10);
474 // get start year
475 std::string y0_str = qe->GetString("startyear");
476 int y0 = strtol(y0_str.c_str(), NULL, 10);
477 // get decay mode
478 std::string d = OptionalQuery<std::string>(qe, "decay", "manual");
479
480 SimInfo si(dur, y0, m0, handle, d);
481
482 si.explicit_inventory = OptionalQuery<bool>(qe, "explicit_inventory", false);
483 si.explicit_inventory_compact = OptionalQuery<bool>(qe, "explicit_inventory_compact", false);
484
485 // get time step duration
487
488 // get epsilon
489 double eps_ = OptionalQuery<double>(qe, "tolerance_generic", 1e-6);
490 cy_eps = si.eps = eps_;
491
492 // get epsilon resources
493 double eps_rsrc_ = OptionalQuery<double>(qe, "tolerance_resource", 1e-6);
494 cy_eps_rsrc = si.eps_rsrc = eps_rsrc_;
495
496 // get seed
497 si.seed = OptionalQuery<int>(qe, "seed", kDefaultSeed);
498
499 // get stride
500 si.stride = OptionalQuery<int>(qe, "stride", kDefaultStride);
501
502 ctx_->InitSim(si);
503}
504
505} // namespace cyclus
std::string Sanitize()
std::string str()
The abstract base class used by all types of agents that live and interact in a simulation.
Definition agent.h:49
virtual void InitFrom(QueryableBackend *b)
Intializes an agent's internal state from the database.
Definition agent.cc:45
virtual void Build(Agent *parent)
Called when the agent enters the smiulation as an active participant and is only ever called once.
Definition agent.cc:153
virtual std::string schema()
Returns an agent's xml rng schema for initializing from input files.
Definition agent.h:333
virtual void InfileToDb(InfileTree *qe, DbInit di)
Translates info for the agent from an input file to the database by reading parameters from the passe...
Definition agent.cc:36
const std::string kind() const
Returns a string that describes the agent subclass (e.g.
Definition agent.h:364
virtual const int id() const
The agent instance's unique ID within a simulation.
Definition agent.h:352
A type to represent variable-length array of bytes for dumping to a cyclus output database.
Definition blob.h:9
static Ptr CreateFromMass(CompMap v)
Creates a new composition from v with its components having appropriate mass-based ratios.
boost::shared_ptr< Composition > Ptr
Definition composition.h:43
static Ptr CreateFromAtom(CompMap v)
Creates a new composition from v with its components having appropriate atom-based ratios.
Wrapper class for QueryableBackends that injects a set of Cond's into every query before being execut...
Represents a condition used to filter rows returned by a query.
A simulation context provides access to necessary simulation-global functions and state.
Definition context.h:145
T * CreateAgent(std::string proto_name)
Create a new agent by cloning the named prototype.
Definition context.h:195
Datum * NewDatum(std::string title)
See Recorder::NewDatum documentation.
Definition context.cc:351
void AddPrototype(std::string name, Agent *m)
Adds a prototype to a simulation-wide accessible list, a prototype can not be added more than once.
Definition context.cc:150
void DelAgent(Agent *m)
Destructs and cleans up m (and it's children recursively).
Definition context.cc:111
void AddRecipe(std::string name, Composition::Ptr c)
Adds a composition recipe to a simulation-wide accessible list.
Definition context.cc:179
void AddTransportUnit(std::string name, int fill_min=0, int fill_max=std::numeric_limits< int >::max(), std::string strategy="first")
Adds a transport unit type to a simulation-wide accessible list.
Definition context.cc:227
void AddPackage(std::string name, double fill_min=0, double fill_max=std::numeric_limits< double >::max(), std::string strategy="first")
Adds a package type to a simulation-wide accessible list.
Definition context.cc:194
void RecordPackage(Package::Ptr)
Records package information.
Definition context.cc:205
void InitSim(SimInfo si)
Initializes the simulation time parameters.
Definition context.cc:263
Datum * AddVal(const char *field, boost::spirit::hold_any val, std::vector< int > *shape=NULL)
Add an arbitrary field-value pair to the datum.
Definition datum.cc:22
void Record()
Record this datum to its Recorder.
Definition datum.cc:35
DbInit provides an interface for agents to record data to the output db that automatically injects th...
Definition db_init.h:14
static Agent * Make(Context *ctx, AgentSpec spec)
Returns a newly constructed agent for the given module spec.
static const bool kDefaultExclusive
default value to allow exclusive orders or not
for failed reading/writing to files, network connections, etc..
Definition error.h:59
A class for extracting information from a given XML parser.
Definition infile_tree.h:22
InfileTree * SubTree(std::string query, int index=0)
populates a child infile based on a query and index
virtual std::string GetString(std::string query, int index=0)
investigates the current status and returns a string representing the content of a query at a given i...
static Ptr & unpackaged()
Definition package.cc:24
Wrapper class for QueryableBackends that injects prefix in front of the title/table for every query b...
Interface implemented by backends that support rudimentary querying.
Collects and manages output data generation for the cyclus core and agents during a simulation.
Definition recorder.h:45
boost::uuids::uuid sim_id()
returns the unique id associated with this cyclus simulation.
Definition recorder.cc:49
void Flush()
Flushes all buffered Datum objects and flushes all registered backends.
Definition recorder.cc:92
Container for a static simulation-global parameters that both describe the simulation and affect its ...
Definition context.h:45
static void Snapshot(Context *ctx)
Records a snapshot of the current state of the simulation being managed by ctx into the simulation's ...
Definition sim_init.cc:76
Controls simulation timestepping and inter-timestep phases.
Definition timer.h:22
For validating files received via IO.
Definition error.h:71
For values that are too big, too small, etc.
Definition error.h:41
XMLFileLoader(Recorder *r, QueryableBackend *b, std::string schema_file, const std::string input_file="", const std::string format="none", bool ms_print=false)
Create a new loader reading from the xml simulation input file and writing to and initializing the ba...
void LoadPackages()
Loads packages.
void LoadRecipes()
Method to load recipes from either the primary input file or a recipeBook catalog.
std::string format_
the input file format
void LoadControlParams()
Method to load the simulation control parameters.
boost::shared_ptr< XMLParser > parser_
the parser
void LoadSolver()
Method to load the simulation exchange solver.
void LoadSpecs()
Load agent specs from the input file to a map by alias.
bool ms_print_
flag to indicate printing master schema
virtual std::string master_schema()
QueryableBackend * b_
std::string schema_path_
filepath to the schema
void LoadTransportUnits()
Loads Transport Units.
std::map< std::string, AgentSpec > specs_
virtual void LoadInitialAgents()
Creates all initial agent instances from the input file.
Agent * BuildAgent(std::string proto, Agent *parent)
Creates and builds an agent, notifying its parent.
void ProcessCommodities(std::map< std::string, double > *commodity_priority)
Processes commodity priorities, such that any without a defined priority (i.e., are nonpositive),...
std::string file_
the input file name
virtual void LoadSim()
Load an entire simulation from the inputfile.
A helper class to hold xml file data and provide automatic validation.
Definition xml_parser.h:15
void Init(const std::stringstream &input)
initializes a parser with an xml snippet
Definition xml_parser.cc:49
const uint64_t kDefaultSeed
Definition context.h:25
const uint64_t kDefaultStride
Definition context.h:27
const uint64_t kDefaultTimeStepDur
Definition context.h:23
Code providing rudimentary logging capability for the Cyclus core.
#define CLOG(level)
Definition logger.h:39
std::string JsonToXml(std::string s)
Converts a JSON string into an equivalent XML string.
std::string PyToXml(std::string s)
Converts a Python string into an equivalent XML string.
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or....
Definition agent.cc:14
void LoadRawStringstreamFromFile(std::stringstream &stream, std::string file)
Reads the given file path into the passed stream without modification.
Composition::Ptr ReadRecipe(InfileTree *qe)
Creates a composition from the recipe in the query engine.
double cy_eps_rsrc
epsilon values to be used by resources
Definition context.cc:18
double cy_eps
generic epsilon values
Definition context.cc:17
void LoadStringstreamFromFile(std::stringstream &stream, std::string file, std::string format)
Reads the given file path as XML into the passed stream.
@ LEV_DEBUG3
debugging information
Definition logger.h:60
@ LEV_INFO1
Information helpful for simulation users and developers alike - least verbose.
Definition logger.h:53
std::string BuildMasterSchema(std::string schema_path, std::string infile, std::string format)
Builds and returns a master cyclus input xml schema that includes the sub-schemas defined by all inst...
std::map< Nuc, double > CompMap
a raw definition of nuclides and corresponding (dimensionless quantities).
Definition composition.h:17
std::string LoadStringFromFile(std::string file, std::string format)
Reads the given file path and returns an XML string.
double eps()
a generic epsilon value
Definition cyc_limits.h:12
std::vector< AgentSpec > ParseSpecs(std::string infile, std::string format)
Returns a list of the full module+agent spec for all agents in the given input file.
T OptionalQuery(InfileTree *tree, std::string query, T default_val)
a query method for optional parameters
int id(int nuc)
Definition pyne.cc:2716
a less-than comparison for pairs
Definition cyc_std.h:12