CYCLUS
discovery.cc
Go to the documentation of this file.
1 #include "discovery.h"
2 
3 #include <fstream>
4 #include <iostream>
5 #include <streambuf>
6 #include <vector>
7 
8 #include <boost/filesystem.hpp>
9 #include <boost/foreach.hpp>
10 #include <boost/algorithm/string.hpp>
11 #include <boost/algorithm/string/predicate.hpp>
12 
13 #include "agent.h"
14 #include "context.h"
15 #include "dynamic_module.h"
16 #include "env.h"
17 #include "platform.h"
18 #include "recorder.h"
19 #include "timer.h"
20 
21 namespace cyclus {
22 
23 std::set<std::string> DiscoverArchetypes(const std::string s) {
24  // Note that 9 is the length of the word "Construct"
25  using std::string;
26  std::set<string> archs;
27  size_t offset = 0;
28  size_t end_offset = 0;
29  const string words = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_"
30  "abcdefghijklmnopqrstuvwxyz";
31  string construct = "Construct";
32  if (SUFFIX == ".dylib")
33  construct = "_Construct";
34  size_t lenconstruct = construct.length();
35  while ((offset = s.find(construct, offset)) != string::npos) {
36  end_offset = s.find_first_not_of(words, offset+lenconstruct);
37  if (words.find(s[offset-1]) != string::npos || offset+lenconstruct == end_offset) {
38  // make sure construct starts the word
39  offset += lenconstruct;
40  continue;
41  }
42  archs.insert(string(s, offset+lenconstruct, end_offset - offset - lenconstruct));
43  offset = end_offset;
44  }
45  return archs;
46 }
47 
48 std::set<std::string> DiscoverSpecs(std::string p, std::string lib) {
49  using std::string;
50  using std::set;
51  namespace fs = boost::filesystem;
52  // find file
53  string libpath = (fs::path(p) / fs::path("lib" + lib + SUFFIX)).string();
54  libpath = Env::FindModule(libpath);
55 
56  // read in file, pre-allocates space
57  std::ifstream f (libpath.c_str());
58  std::string s;
59  f.seekg(0, std::ios::end);
60  s.reserve(f.tellg());
61  f.seekg(0, std::ios::beg);
62  s.assign((std::istreambuf_iterator<char>(f)),
63  std::istreambuf_iterator<char>());
64 
65  // find specs
66  set<string> archs = DiscoverArchetypes(s);
67  set<string> specs;
68  string spec;
69  AgentSpec agentspec;
70  for (set<string>::iterator it = archs.begin(); it != archs.end(); ++it) {
71  spec = p + ":" + lib + ":" + (*it);
72  agentspec = AgentSpec(spec);
73  if (DynamicModule::Exists(agentspec)) {
74  specs.insert(spec);
75  }
76  }
77  return specs;
78 }
79 
80 std::set<std::string> DiscoverSpecsInDir(std::string d) {
81  using std::string;
82  using std::set;
83  namespace fs = boost::filesystem;
84  set<string> specs;
85  set<string> libspecs;
86  fs::path pth;
87  boost::system::error_code errc;
88  boost::system::error_code no_err;
89  pth = d;
90  fs::recursive_directory_iterator it(pth, errc);
91  fs::recursive_directory_iterator last;
92  for (; it != last; it.increment(errc)) {
93  if (errc != no_err) {
94  if (it.level() > 0) {
95  it.pop();
96  }
97  continue;
98  }
99  pth = it->path();
100  string pthstr = pth.string();
101  bool irf = fs::is_regular_file(pth, errc);
102  if (errc != no_err || !irf) {
103  it.no_push();
104  if (it.level() > 0) {
105  it.pop();
106  }
107  continue;
108  } else if (fs::is_directory(pth, errc)) {
109  continue;
110  } else if (!boost::algorithm::ends_with(pthstr, SUFFIX)) {
111  continue;
112  }
113  string p = pth.parent_path().string();
114  string lib = pth.filename().string();
115  if (d.length() < p.length())
116  p = p.substr(d.length()+1, string::npos);
117  else
118  p = "";
119  lib = lib.substr(3, lib.rfind(".") - 3); // remove 'lib' prefix and suffix
120  try {
121  libspecs = DiscoverSpecs(p, lib);
122  } catch (cyclus::IOError& e) {}
123  for (set<string>::iterator ls = libspecs.begin(); ls != libspecs.end(); ++ls) {
124  specs.insert(*ls);
125  }
126  }
127  return specs;
128 }
129 
130 std::set<std::string> DiscoverSpecsInCyclusPath() {
131  using std::string;
132  using std::set;
133  using std::vector;
134  set<string> specs;
135  set<string> dirspecs;
136  vector<string> cycpath = Env::cyclus_path();
137  for (vector<string>::iterator it = cycpath.begin(); it != cycpath.end(); ++it) {
138  dirspecs = DiscoverSpecsInDir((*it).length() == 0 ? "." : (*it));
139  for (set<string>::iterator ds = dirspecs.begin(); ds != dirspecs.end(); ++ds) {
140  specs.insert(*ds);
141  }
142  }
143  return specs;
144 }
145 
147  std::set<std::string> specs = cyclus::DiscoverSpecsInCyclusPath();
152  Recorder rec;
153  Timer ti;
154  Context* ctx = new Context(&ti, &rec);
155  std::string s;
156  std::set<std::string>::iterator it;
157 
158  for (it = specs.begin(); it != specs.end(); ++it) {
159  s = *it;
160  Agent* m = DynamicModule::Make(ctx, s);
161  spec.append(s);
162  anno[s] = m->annotations();
163  schm[s] = m->schema();
164  ctx->DelAgent(m);
165  }
166  delete ctx;
167 
168  root["specs"] = spec;
169  root["annotations"] = anno;
170  root["schema"] = schm;
171 
172  return root;
173 }
174 
175 } // namespace cyclus
std::set< std::string > DiscoverSpecsInDir(std::string d)
Discover archetype specifications that live recursively in modules in a dir.
Definition: discovery.cc:80
Json::Value DiscoverMetadataInCyclusPath()
Discover archetype metadata in cyclus path.
Definition: discovery.cc:146
#define SUFFIX
Definition: platform.h:1
static bool Exists(AgentSpec spec)
Tests that an agent spec really exists.
std::set< std::string > DiscoverArchetypes(const std::string s)
This function returns a vector of archetype names in a given string that is the binary represnetation...
Definition: discovery.cc:23
static const std::vector< std::string > cyclus_path()
Definition: env.cc:152
Represents a JSON value.
Definition: pyne.h:3224
static std::string FindModule(std::string path)
Returns the full path to a module by searching through default install and CYCLUS_PATH directories...
Definition: env.cc:176
virtual std::string schema()
Returns an agent&#39;s xml rng schema for initializing from input files.
Definition: agent.h:335
object value (collection of name/value pairs).
Definition: pyne.h:3145
std::set< std::string > DiscoverSpecs(std::string p, std::string lib)
Discover archetype specifications for a path and library.
Definition: discovery.cc:48
for failed reading/writing to files, network connections, etc..
Definition: error.h:59
std::set< std::string > DiscoverSpecsInCyclusPath()
Discover archetype specifications that live recursively in CYCLUS_PATH directories.
Definition: discovery.cc:130
virtual Json::Value annotations()
Returns an agent&#39;s json annotations for all state variables and any other information the developer w...
Definition: agent.h:342
static std::string words
string of all valid word characters for variable names in programing languages.
Definition: pyne.h:128
Collects and manages output data generation for the cyclus core and agents during a simulation...
Definition: recorder.h:45
A simulation context provides access to necessary simulation-global functions and state...
Definition: context.h:130
The abstract base class used by all types of agents that live and interact in a simulation.
Definition: agent.h:51
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or.org/Osi/browser/trunk.
Definition: agent.cc:14
static Agent * Make(Context *ctx, AgentSpec spec)
Returns a newly constructed agent for the given module spec.
enable_if< has_const_iterator< T >::value, typename T::const_iterator >::type end(const T &c)
Value & append(const Value &value)
Append value to array at the end.
Definition: pyne.cc:15536
int offset(int dz, int da, int ds=0)
A helper function to compute nuclide id offsets from z-, a-, and s- deltas.
Definition: pyne.h:1455
void DelAgent(Agent *m)
Destructs and cleans up m (and it&#39;s children recursively).
Definition: context.cc:98
array value (ordered list)
Definition: pyne.h:3144
Controls simulation timestepping and inter-timestep phases.
Definition: timer.h:22