<commit_before>// Implements file reader for an XML format
#include "xml_file_loader.h"

#include <algorithm>
#include <fstream>
#include <set>
#include <streambuf>

#include <boost/filesystem.hpp>

#include "agent.h"
#include "blob.h"
#include "context.h"
#include "cyc_std.h"
#include "env.h"
#include "error.h"
#include "exchange_solver.h"
#include "greedy_preconditioner.h"
#include "greedy_solver.h"
#include "infile_tree.h"
#include "logger.h"
#include "sim_init.h"
#include "toolkit/infile_converters.h"

namespace cyclus {

namespace fs = boost::filesystem;

void LoadRawStringstreamFromFile(std::stringstream& stream, std::string file) {
  std::ifstream file_stream(file.c_str());
  if (!file_stream) {
    throw IOError("The file '" + file + "' could not be loaded.");
  }

  stream << file_stream.rdbuf();
  file_stream.close();
}

void LoadStringstreamFromFile(std::stringstream& stream, std::string file) {
  LoadRawStringstreamFromFile(stream, file);
  std::string inext = fs::path(file).extension().string();
  if (inext == ".json") {
    std::string inxml = cyclus::toolkit::JsonToXml(stream.str());
    stream.str(inxml);
  }
}

std::vector<AgentSpec> ParseSpecs(std::string infile) {
  std::stringstream input;
  LoadStringstreamFromFile(input, infile);
  XMLParser parser_;
  parser_.Init(input);
  InfileTree xqe(parser_);

  std::vector<AgentSpec> specs;
  std::set<std::string> unique;

  std::string p = "/simulation/archetypes/spec";
  int n = xqe.NMatches(p);
  for (int i = 0; i < n; ++i) {
    AgentSpec spec(xqe.SubTree(p, i));
    if (unique.count(spec.str()) == 0) {
      specs.push_back(spec);
      unique.insert(spec.str());
    }
  }

  if (specs.size() == 0) {
    throw ValidationError("failed to parse archetype specs from input file");
  }

  return specs;
}

std::string BuildMasterSchema(std::string schema_path, std::string infile) {
  Timer ti;
  Recorder rec;
  Context ctx(&ti, &rec);

  std::stringstream schema("");
  LoadStringstreamFromFile(schema, schema_path);
  std::string master = schema.str();

  std::vector<AgentSpec> specs = ParseSpecs(infile);

  std::map<std::string, std::string> subschemas;

  // force element types to exist so we always replace the config string
  subschemas["region"] = "";
  subschemas["inst"] = "";
  subschemas["facility"] = "";

  for (int i = 0; i < specs.size(); ++i) {
    Agent* m = DynamicModule::Make(&ctx, specs[i]);
    subschemas[m->kind()] += "<element name=\"" + specs[i].alias() + "\">\n";
    subschemas[m->kind()] += m->schema() + "\n";
    subschemas[m->kind()] += "</element>\n";
    ctx.DelAgent(m);
  }

  // replace refs in master rng template file
  std::map<std::string, std::string>::iterator it;
  for (it = subschemas.begin(); it != subschemas.end(); ++it) {
    std::string search_str = std::string("@") + it->first + std::string("_REFS@");
    size_t pos = master.find(search_str);
    if (pos != std::string::npos) {
      master.replace(pos, search_str.size(), it->second);
    }
  }

  return master;
}

Composition::Ptr ReadRecipe(InfileTree* qe) {
  bool atom_basis;
  std::string basis_str = qe->GetString("basis");
  if (basis_str == "atom") {
    atom_basis = true;
  } else if (basis_str == "mass") {
    atom_basis = false;
  } else {
    throw IOError(basis_str + " basis is not 'mass' or 'atom'.");
  }

  double value;
  int key;
  std::string query = "nuclide";
  int nnucs = qe->NMatches(query);
  CompMap v;
  for (int i = 0; i < nnucs; i++) {
    InfileTree* nuclide = qe->SubTree(query, i);
    key = pyne::nucname::id(nuclide->GetString("id"));
    value = strtod(nuclide->GetString("comp").c_str(), NULL);
    v[key] = value;
    CLOG(LEV_DEBUG3) << "  Nuclide: " << key << " Value: " << v[key];
  }

  if (atom_basis) {
    return Composition::CreateFromAtom(v);
  } else {
    return Composition::CreateFromMass(v);
  }
}

XMLFileLoader::XMLFileLoader(Recorder* r,
                             QueryableBackend* b,
                             std::string schema_file,
                             const std::string input_file) : b_(b), rec_(r) {
  ctx_ = new Context(&ti_, rec_);

  schema_path_ = schema_file;
  file_ = input_file;
  std::stringstream input;
  LoadStringstreamFromFile(input, file_);
  parser_ = boost::shared_ptr<XMLParser>(new XMLParser());
  parser_->Init(input);

  std::stringstream orig_input;
  LoadRawStringstreamFromFile(orig_input, file_);
  ctx_->NewDatum("InputFiles")
      ->AddVal("Data", Blob(orig_input.str()))
      ->Record();
}

XMLFileLoader::~XMLFileLoader() {
  delete ctx_;
}

std::string XMLFileLoader::master_schema() {
  return BuildMasterSchema(schema_path_, file_);
}

void XMLFileLoader::LoadSim() {
  std::stringstream ss(master_schema());
  parser_->Validate(ss);
  LoadControlParams();  // must be first
  LoadSolver();
  LoadRecipes();
  LoadSpecs();
  LoadInitialAgents();  // must be last
  SimInit::Snapshot(ctx_);
  rec_->Flush();
}

void XMLFileLoader::LoadSolver() {
  using std::string;
  InfileTree xqe(*parser_);
  InfileTree* qe;
  std::string query = "/*/commodity";

  std::map<std::string, double> commod_priority;
  std::string name;
  double priority;
  int num_commods = xqe.NMatches(query);
  for (int i = 0; i < num_commods; i++) {
    qe = xqe.SubTree(query, i);
    name = qe->GetString("name");
    priority = OptionalQuery<double>(qe, "solution_priority", -1);
    commod_priority[name] = priority;
  }

  ProcessCommodities(&commod_priority);
  std::map<std::string, double>::iterator it;
  for (it = commod_priority.begin(); it != commod_priority.end(); ++it) {
    ctx_->NewDatum("CommodPriority")
        ->AddVal("Commodity", it->first)
        ->AddVal("SolutionPriority", it->second)
        ->Record();
  }

  // now load the solver info
  string config = "config";
  string greedy = "greedy";
  string coinor = "coin-or";
  string solver_name = greedy;
  bool exclusive = ExchangeSolver::kDefaultExclusive;
  if (xqe.NMatches("/*/control/solver") == 1) {
    qe = xqe.SubTree("/*/control/solver");
    if (qe->NMatches(config) == 1) {
      solver_name = qe->SubTree(config)->GetElementName(0);
    }
    exclusive = cyclus::OptionalQuery<bool>(qe, "allow_exclusive_orders",
                                            exclusive);
  }

  if (!exclusive) {
    std::stringstream ss;
    ss << "You have set allow_exclusive_orders to False."
       << " Many archetypes (e.g., :cycamore:Reactor will not work"
       << " as intended with this feature turned off.";
    Warn<VALUE_WARNING>(ss.str());
  }

  ctx_->NewDatum("SolverInfo")
      ->AddVal("Solver", solver_name)
      ->AddVal("ExclusiveOrders", exclusive)
      ->Record();

  // @TODO remove this after release 1.5
  // check for deprecated input values
  if (qe->NMatches("exclusive_orders_only") > 0) {
    std::stringstream ss;
    ss << "Use of 'exclusive_orders_only' is deprecated."
       << " Please see http://fuelcycle.org/user/input_specs/control.html";
    Warn<DEPRECATION_WARNING>(ss.str());
  }

  // now load the actual solver
  if (solver_name == greedy) {
    query = string("/*/control/solver/config/greedy/preconditioner");
    string precon_name = cyclus::OptionalQuery<string>(&xqe, query, greedy);
    ctx_->NewDatum("GreedySolverInfo")
      ->AddVal("Preconditioner", precon_name)
      ->Record();
  } else if (solver_name == coinor) {
    query = string("/*/control/solver/config/coin-or/timeout");
    double timeout = cyclus::OptionalQuery<double>(&xqe, query, -1);
    query = string("/*/control/solver/config/coin-or/verbose");
    bool verbose = cyclus::OptionalQuery<bool>(&xqe, query, false);
    query = string("/*/control/solver/config/coin-or/mps");
    bool mps = cyclus::OptionalQuery<bool>(&xqe, query, false);
    ctx_->NewDatum("CoinSolverInfo")
      ->AddVal("Timeout", timeout)
      ->AddVal("Verbose", verbose)
      ->AddVal("Mps", mps)
      ->Record();
  } else {
    throw ValueError("unknown solver name: " + solver_name);
  }
}

void XMLFileLoader::ProcessCommodities(
  std::map<std::string, double>* commod_priority) {
  double max = std::max_element(
                 commod_priority->begin(),
                 commod_priority->end(),
                 SecondLT< std::pair<std::string, double> >())->second;
  if (max < 1) {
    max = 0;  // in case no priorities are specified
  }

  std::map<std::string, double>::iterator it;
  for (it = commod_priority->begin();
       it != commod_priority->end();
       ++it) {
    if (it->second < 1) {
      it->second = max + 1;
    }
    CLOG(LEV_INFO1) << "Commodity priority for " << it->first
                    << " is " << it->second;
  }
}

void XMLFileLoader::LoadRecipes() {
  InfileTree xqe(*parser_);

  std::string query = "/*/recipe";
  int num_recipes = xqe.NMatches(query);
  for (int i = 0; i < num_recipes; i++) {
    InfileTree* qe = xqe.SubTree(query, i);
    std::string name = qe->GetString("name");
    CLOG(LEV_DEBUG3) << "loading recipe: " << name;
    Composition::Ptr comp = ReadRecipe(qe);
    comp->Record(ctx_);
    ctx_->AddRecipe(name, comp);
  }
}

void XMLFileLoader::LoadSpecs() {
  std::vector<AgentSpec> specs = ParseSpecs(file_);
  for (int i = 0; i < specs.size(); ++i) {
    specs_[specs[i].alias()] = specs[i];
  }
}

void XMLFileLoader::LoadInitialAgents() {
  std::map<std::string, std::string> schema_paths;
  schema_paths["Region"] = "/*/region";
  schema_paths["Inst"] = "/*/region/institution";
  schema_paths["Facility"] = "/*/facility";

  InfileTree xqe(*parser_);

  // create prototypes
  std::string prototype;  // defined here for force-create AgentExit tbl
  std::map<std::string, std::string>::iterator it;
  for (it = schema_paths.begin(); it != schema_paths.end(); it++) {
    int num_agents = xqe.NMatches(it->second);
    for (int i = 0; i < num_agents; i++) {
      InfileTree* qe = xqe.SubTree(it->second, i);
      prototype = qe->GetString("name");
      std::string alias = qe->SubTree("config")->GetElementName(0);
      AgentSpec spec = specs_[alias];

      Agent* agent = DynamicModule::Make(ctx_, spec);

      // call manually without agent impl injected to keep all Agent state in a
      // single, consolidated db table
      agent->Agent::InfileToDb(qe, DbInit(agent, true));

      agent->InfileToDb(qe, DbInit(agent));
      rec_->Flush();

      std::vector<Cond> conds;
      conds.push_back(Cond("SimId", "==", rec_->sim_id()));
      conds.push_back(Cond("SimTime", "==", static_cast<int>(0)));
      conds.push_back(Cond("AgentId", "==", agent->id()));
      CondInjector ci(b_, conds);
      PrefixInjector pi(&ci, "AgentState");

      // call manually without agent impl injected
      agent->Agent::InitFrom(&pi);

      pi = PrefixInjector(&ci, "AgentState" + spec.Sanitize());
      agent->InitFrom(&pi);
      ctx_->AddPrototype(prototype, agent);
    }
  }

  // build initial agent instances
  int nregions = xqe.NMatches(schema_paths["Region"]);
  for (int i = 0; i < nregions; ++i) {
    InfileTree* qe = xqe.SubTree(schema_paths["Region"], i);
    std::string region_proto = qe->GetString("name");
    Agent* reg = BuildAgent(region_proto, NULL);

    int ninsts = qe->NMatches("institution");
    for (int j = 0; j < ninsts; ++j) {
      InfileTree* qe2 = qe->SubTree("institution", j);
      std::string inst_proto = qe2->GetString("name");
      Agent* inst = BuildAgent(inst_proto, reg);

      int nfac = qe2->NMatches("initialfacilitylist/entry");
      for (int k = 0; k < nfac; ++k) {
        InfileTree* qe3 = qe2->SubTree("initialfacilitylist/entry", k);
        std::string fac_proto = qe3->GetString("prototype");

        int number = atoi(qe3->GetString("number").c_str());
        for (int z = 0; z < number; ++z) {
          Agent* fac = BuildAgent(fac_proto, inst);
        }
      }
    }
  }
}

Agent* XMLFileLoader::BuildAgent(std::string proto, Agent* parent) {
  Agent* m = ctx_->CreateAgent<Agent>(proto);
  m->Build(parent);
  if (parent != NULL) {
    parent->BuildNotify(m);
  }
  return m;
}

void XMLFileLoader::LoadControlParams() {
  InfileTree xqe(*parser_);
  std::string query = "/*/control";
  InfileTree* qe = xqe.SubTree(query);

  std::string handle;
  if (qe->NMatches("simhandle") > 0) {
    handle = qe->GetString("simhandle");
  }

  // get duration
  std::string dur_str = qe->GetString("duration");
  int dur = strtol(dur_str.c_str(), NULL, 10);
  // get start month
  std::string m0_str = qe->GetString("startmonth");
  int m0 = strtol(m0_str.c_str(), NULL, 10);
  // get start year
  std::string y0_str = qe->GetString("startyear");
  int y0 = strtol(y0_str.c_str(), NULL, 10);
  // get decay mode
  std::string d = OptionalQuery<std::string>(qe, "decay", "manual");

  SimInfo si(dur, y0, m0, handle, d);

  // get time step duration
  si.dt = OptionalQuery<int>(qe, "dt", kDefaultTimeStepDur);

  ctx_->InitSim(si);
}

}  // namespace cyclus
<commit_msg>correctly checks old exclusive flag when query engine exists in scope<commit_after>// Implements file reader for an XML format
#include "xml_file_loader.h"

#include <algorithm>
#include <fstream>
#include <set>
#include <streambuf>

#include <boost/filesystem.hpp>

#include "agent.h"
#include "blob.h"
#include "context.h"
#include "cyc_std.h"
#include "env.h"
#include "error.h"
#include "exchange_solver.h"
#include "greedy_preconditioner.h"
#include "greedy_solver.h"
#include "infile_tree.h"
#include "logger.h"
#include "sim_init.h"
#include "toolkit/infile_converters.h"

namespace cyclus {

namespace fs = boost::filesystem;

void LoadRawStringstreamFromFile(std::stringstream& stream, std::string file) {
  std::ifstream file_stream(file.c_str());
  if (!file_stream) {
    throw IOError("The file '" + file + "' could not be loaded.");
  }

  stream << file_stream.rdbuf();
  file_stream.close();
}

void LoadStringstreamFromFile(std::stringstream& stream, std::string file) {
  LoadRawStringstreamFromFile(stream, file);
  std::string inext = fs::path(file).extension().string();
  if (inext == ".json") {
    std::string inxml = cyclus::toolkit::JsonToXml(stream.str());
    stream.str(inxml);
  }
}

std::vector<AgentSpec> ParseSpecs(std::string infile) {
  std::stringstream input;
  LoadStringstreamFromFile(input, infile);
  XMLParser parser_;
  parser_.Init(input);
  InfileTree xqe(parser_);

  std::vector<AgentSpec> specs;
  std::set<std::string> unique;

  std::string p = "/simulation/archetypes/spec";
  int n = xqe.NMatches(p);
  for (int i = 0; i < n; ++i) {
    AgentSpec spec(xqe.SubTree(p, i));
    if (unique.count(spec.str()) == 0) {
      specs.push_back(spec);
      unique.insert(spec.str());
    }
  }

  if (specs.size() == 0) {
    throw ValidationError("failed to parse archetype specs from input file");
  }

  return specs;
}

std::string BuildMasterSchema(std::string schema_path, std::string infile) {
  Timer ti;
  Recorder rec;
  Context ctx(&ti, &rec);

  std::stringstream schema("");
  LoadStringstreamFromFile(schema, schema_path);
  std::string master = schema.str();

  std::vector<AgentSpec> specs = ParseSpecs(infile);

  std::map<std::string, std::string> subschemas;

  // force element types to exist so we always replace the config string
  subschemas["region"] = "";
  subschemas["inst"] = "";
  subschemas["facility"] = "";

  for (int i = 0; i < specs.size(); ++i) {
    Agent* m = DynamicModule::Make(&ctx, specs[i]);
    subschemas[m->kind()] += "<element name=\"" + specs[i].alias() + "\">\n";
    subschemas[m->kind()] += m->schema() + "\n";
    subschemas[m->kind()] += "</element>\n";
    ctx.DelAgent(m);
  }

  // replace refs in master rng template file
  std::map<std::string, std::string>::iterator it;
  for (it = subschemas.begin(); it != subschemas.end(); ++it) {
    std::string search_str = std::string("@") + it->first + std::string("_REFS@");
    size_t pos = master.find(search_str);
    if (pos != std::string::npos) {
      master.replace(pos, search_str.size(), it->second);
    }
  }

  return master;
}

Composition::Ptr ReadRecipe(InfileTree* qe) {
  bool atom_basis;
  std::string basis_str = qe->GetString("basis");
  if (basis_str == "atom") {
    atom_basis = true;
  } else if (basis_str == "mass") {
    atom_basis = false;
  } else {
    throw IOError(basis_str + " basis is not 'mass' or 'atom'.");
  }

  double value;
  int key;
  std::string query = "nuclide";
  int nnucs = qe->NMatches(query);
  CompMap v;
  for (int i = 0; i < nnucs; i++) {
    InfileTree* nuclide = qe->SubTree(query, i);
    key = pyne::nucname::id(nuclide->GetString("id"));
    value = strtod(nuclide->GetString("comp").c_str(), NULL);
    v[key] = value;
    CLOG(LEV_DEBUG3) << "  Nuclide: " << key << " Value: " << v[key];
  }

  if (atom_basis) {
    return Composition::CreateFromAtom(v);
  } else {
    return Composition::CreateFromMass(v);
  }
}

XMLFileLoader::XMLFileLoader(Recorder* r,
                             QueryableBackend* b,
                             std::string schema_file,
                             const std::string input_file) : b_(b), rec_(r) {
  ctx_ = new Context(&ti_, rec_);

  schema_path_ = schema_file;
  file_ = input_file;
  std::stringstream input;
  LoadStringstreamFromFile(input, file_);
  parser_ = boost::shared_ptr<XMLParser>(new XMLParser());
  parser_->Init(input);

  std::stringstream orig_input;
  LoadRawStringstreamFromFile(orig_input, file_);
  ctx_->NewDatum("InputFiles")
      ->AddVal("Data", Blob(orig_input.str()))
      ->Record();
}

XMLFileLoader::~XMLFileLoader() {
  delete ctx_;
}

std::string XMLFileLoader::master_schema() {
  return BuildMasterSchema(schema_path_, file_);
}

void XMLFileLoader::LoadSim() {
  std::stringstream ss(master_schema());
  parser_->Validate(ss);
  LoadControlParams();  // must be first
  LoadSolver();
  LoadRecipes();
  LoadSpecs();
  LoadInitialAgents();  // must be last
  SimInit::Snapshot(ctx_);
  rec_->Flush();
}

void XMLFileLoader::LoadSolver() {
  using std::string;
  InfileTree xqe(*parser_);
  InfileTree* qe;
  std::string query = "/*/commodity";

  std::map<std::string, double> commod_priority;
  std::string name;
  double priority;
  int num_commods = xqe.NMatches(query);
  for (int i = 0; i < num_commods; i++) {
    qe = xqe.SubTree(query, i);
    name = qe->GetString("name");
    priority = OptionalQuery<double>(qe, "solution_priority", -1);
    commod_priority[name] = priority;
  }

  ProcessCommodities(&commod_priority);
  std::map<std::string, double>::iterator it;
  for (it = commod_priority.begin(); it != commod_priority.end(); ++it) {
    ctx_->NewDatum("CommodPriority")
        ->AddVal("Commodity", it->first)
        ->AddVal("SolutionPriority", it->second)
        ->Record();
  }

  // now load the solver info
  string config = "config";
  string greedy = "greedy";
  string coinor = "coin-or";
  string solver_name = greedy;
  bool exclusive = ExchangeSolver::kDefaultExclusive;
  if (xqe.NMatches("/*/control/solver") == 1) {
    qe = xqe.SubTree("/*/control/solver");
    if (qe->NMatches(config) == 1) {
      solver_name = qe->SubTree(config)->GetElementName(0);
    }
    exclusive = cyclus::OptionalQuery<bool>(qe, "allow_exclusive_orders",
                                            exclusive);

    // @TODO remove this after release 1.5
    // check for deprecated input values
    if (qe->NMatches(std::string("exclusive_orders_only")) != 0) {
      std::stringstream ss;
      ss << "Use of 'exclusive_orders_only' is deprecated."
         << " Please see http://fuelcycle.org/user/input_specs/control.html";
      Warn<DEPRECATION_WARNING>(ss.str());
    }
  }

  if (!exclusive) {
    std::stringstream ss;
    ss << "You have set allow_exclusive_orders to False."
       << " Many archetypes (e.g., :cycamore:Reactor will not work"
       << " as intended with this feature turned off.";
    Warn<VALUE_WARNING>(ss.str());
  }

  ctx_->NewDatum("SolverInfo")
      ->AddVal("Solver", solver_name)
      ->AddVal("ExclusiveOrders", exclusive)
      ->Record();

  // now load the actual solver
  if (solver_name == greedy) {
    query = string("/*/control/solver/config/greedy/preconditioner");
    string precon_name = cyclus::OptionalQuery<string>(&xqe, query, greedy);
    ctx_->NewDatum("GreedySolverInfo")
      ->AddVal("Preconditioner", precon_name)
      ->Record();
  } else if (solver_name == coinor) {
    query = string("/*/control/solver/config/coin-or/timeout");
    double timeout = cyclus::OptionalQuery<double>(&xqe, query, -1);
    query = string("/*/control/solver/config/coin-or/verbose");
    bool verbose = cyclus::OptionalQuery<bool>(&xqe, query, false);
    query = string("/*/control/solver/config/coin-or/mps");
    bool mps = cyclus::OptionalQuery<bool>(&xqe, query, false);
    ctx_->NewDatum("CoinSolverInfo")
      ->AddVal("Timeout", timeout)
      ->AddVal("Verbose", verbose)
      ->AddVal("Mps", mps)
      ->Record();
  } else {
    throw ValueError("unknown solver name: " + solver_name);
  }
}

void XMLFileLoader::ProcessCommodities(
  std::map<std::string, double>* commod_priority) {
  double max = std::max_element(
                 commod_priority->begin(),
                 commod_priority->end(),
                 SecondLT< std::pair<std::string, double> >())->second;
  if (max < 1) {
    max = 0;  // in case no priorities are specified
  }

  std::map<std::string, double>::iterator it;
  for (it = commod_priority->begin();
       it != commod_priority->end();
       ++it) {
    if (it->second < 1) {
      it->second = max + 1;
    }
    CLOG(LEV_INFO1) << "Commodity priority for " << it->first
                    << " is " << it->second;
  }
}

void XMLFileLoader::LoadRecipes() {
  InfileTree xqe(*parser_);

  std::string query = "/*/recipe";
  int num_recipes = xqe.NMatches(query);
  for (int i = 0; i < num_recipes; i++) {
    InfileTree* qe = xqe.SubTree(query, i);
    std::string name = qe->GetString("name");
    CLOG(LEV_DEBUG3) << "loading recipe: " << name;
    Composition::Ptr comp = ReadRecipe(qe);
    comp->Record(ctx_);
    ctx_->AddRecipe(name, comp);
  }
}

void XMLFileLoader::LoadSpecs() {
  std::vector<AgentSpec> specs = ParseSpecs(file_);
  for (int i = 0; i < specs.size(); ++i) {
    specs_[specs[i].alias()] = specs[i];
  }
}

void XMLFileLoader::LoadInitialAgents() {
  std::map<std::string, std::string> schema_paths;
  schema_paths["Region"] = "/*/region";
  schema_paths["Inst"] = "/*/region/institution";
  schema_paths["Facility"] = "/*/facility";

  InfileTree xqe(*parser_);

  // create prototypes
  std::string prototype;  // defined here for force-create AgentExit tbl
  std::map<std::string, std::string>::iterator it;
  for (it = schema_paths.begin(); it != schema_paths.end(); it++) {
    int num_agents = xqe.NMatches(it->second);
    for (int i = 0; i < num_agents; i++) {
      InfileTree* qe = xqe.SubTree(it->second, i);
      prototype = qe->GetString("name");
      std::string alias = qe->SubTree("config")->GetElementName(0);
      AgentSpec spec = specs_[alias];

      Agent* agent = DynamicModule::Make(ctx_, spec);

      // call manually without agent impl injected to keep all Agent state in a
      // single, consolidated db table
      agent->Agent::InfileToDb(qe, DbInit(agent, true));

      agent->InfileToDb(qe, DbInit(agent));
      rec_->Flush();

      std::vector<Cond> conds;
      conds.push_back(Cond("SimId", "==", rec_->sim_id()));
      conds.push_back(Cond("SimTime", "==", static_cast<int>(0)));
      conds.push_back(Cond("AgentId", "==", agent->id()));
      CondInjector ci(b_, conds);
      PrefixInjector pi(&ci, "AgentState");

      // call manually without agent impl injected
      agent->Agent::InitFrom(&pi);

      pi = PrefixInjector(&ci, "AgentState" + spec.Sanitize());
      agent->InitFrom(&pi);
      ctx_->AddPrototype(prototype, agent);
    }
  }

  // build initial agent instances
  int nregions = xqe.NMatches(schema_paths["Region"]);
  for (int i = 0; i < nregions; ++i) {
    InfileTree* qe = xqe.SubTree(schema_paths["Region"], i);
    std::string region_proto = qe->GetString("name");
    Agent* reg = BuildAgent(region_proto, NULL);

    int ninsts = qe->NMatches("institution");
    for (int j = 0; j < ninsts; ++j) {
      InfileTree* qe2 = qe->SubTree("institution", j);
      std::string inst_proto = qe2->GetString("name");
      Agent* inst = BuildAgent(inst_proto, reg);

      int nfac = qe2->NMatches("initialfacilitylist/entry");
      for (int k = 0; k < nfac; ++k) {
        InfileTree* qe3 = qe2->SubTree("initialfacilitylist/entry", k);
        std::string fac_proto = qe3->GetString("prototype");

        int number = atoi(qe3->GetString("number").c_str());
        for (int z = 0; z < number; ++z) {
          Agent* fac = BuildAgent(fac_proto, inst);
        }
      }
    }
  }
}

Agent* XMLFileLoader::BuildAgent(std::string proto, Agent* parent) {
  Agent* m = ctx_->CreateAgent<Agent>(proto);
  m->Build(parent);
  if (parent != NULL) {
    parent->BuildNotify(m);
  }
  return m;
}

void XMLFileLoader::LoadControlParams() {
  InfileTree xqe(*parser_);
  std::string query = "/*/control";
  InfileTree* qe = xqe.SubTree(query);

  std::string handle;
  if (qe->NMatches("simhandle") > 0) {
    handle = qe->GetString("simhandle");
  }

  // get duration
  std::string dur_str = qe->GetString("duration");
  int dur = strtol(dur_str.c_str(), NULL, 10);
  // get start month
  std::string m0_str = qe->GetString("startmonth");
  int m0 = strtol(m0_str.c_str(), NULL, 10);
  // get start year
  std::string y0_str = qe->GetString("startyear");
  int y0 = strtol(y0_str.c_str(), NULL, 10);
  // get decay mode
  std::string d = OptionalQuery<std::string>(qe, "decay", "manual");

  SimInfo si(dur, y0, m0, handle, d);

  // get time step duration
  si.dt = OptionalQuery<int>(qe, "dt", kDefaultTimeStepDur);

  ctx_->InitSim(si);
}

}  // namespace cyclus
<|endoftext|>


<commit_before>#ifndef YQVMC_OBSERVER_PLAIN_HPP
#define YQVMC_OBSERVER_PLAIN_HPP

#include "impl_/mean_and_error.hpp"
#include <iostream>

namespace yqvmc {
  template <class M,
  class ACC = impl_::MeanAndErrorAcc<typename M::result_type> >
  class PlainObserver {
  public:
    typedef M Measure;
    typedef typename M::result_type input_type;
    typedef ACC Accumulator;

    PlainObserver(std::string name, Measure& measure)
    : m_name(name), m_measure(measure) {}

    template <typename Conf>
    void measure(const Conf& conf, std::size_t stamp) {
      m_measure.measure(conf, stamp);
    }

    void closeBin(std::size_t iBin) {
      auto result = m_measure.result();
      m_acc(result);
      std::cout << m_name << ": " << result << std::endl;
    }

    void report() const {
      auto mean = m_acc.mean();
      auto error = m_acc.error();

      std::cout << m_name << " : " << mean
                << " +/- " << error
                << std::endl;
    }

  private:
    std::string m_name;
    Measure& m_measure;
    Accumulator m_acc;
  };

  template <class M>
  PlainObserver<M> MakePlainObserver(std::string name, M& m) {
    return PlainObserver<M>(name, m);
  }

  template <typename M>
  class EmptyObserver {
  public:
    typedef M Measure;
    EmptyObserver(Measure& measure) : m_measure(measure) {}

    template <typename Conf>
    void measure(const Conf& conf, std::size_t stamp) {
      m_measure.measure(conf, stamp);
    }

    void closeBin(std::size_t iBin) {}

  private:
    Measure& m_measure;
  };

}

#endif
<commit_msg>new emptyobserver interface. needed by the SLEEP project.<commit_after>#ifndef YQVMC_OBSERVER_PLAIN_HPP
#define YQVMC_OBSERVER_PLAIN_HPP

#include "impl_/mean_and_error.hpp"
#include <iostream>

namespace yqvmc {
  template <class M,
  class ACC = impl_::MeanAndErrorAcc<typename M::result_type> >
  class PlainObserver {
  public:
    typedef M Measure;
    typedef typename M::result_type input_type;
    typedef ACC Accumulator;

    PlainObserver(std::string name, Measure& measure)
    : m_name(name), m_measure(measure) {}

    template <typename Conf>
    void measure(const Conf& conf, std::size_t stamp) {
      m_measure.measure(conf, stamp);
    }

    void closeBin(std::size_t iBin) {
      auto result = m_measure.result();
      m_acc(result);
      std::cout << m_name << ": " << result << std::endl;
    }

    void report() const {
      auto mean = m_acc.mean();
      auto error = m_acc.error();

      std::cout << m_name << " : " << mean
                << " +/- " << error
                << std::endl;
    }

  private:
    std::string m_name;
    Measure& m_measure;
    Accumulator m_acc;
  };

  template <class M>
  PlainObserver<M> MakePlainObserver(std::string name, M& m) {
    return PlainObserver<M>(name, m);
  }

  template <typename M>
  class EmptyObserver {
  public:
    typedef M Measure;
    EmptyObserver(Measure& measure) : m_measure(measure) {}

    template <typename Conf>
    void measure(const Conf& conf, std::size_t stamp) {
      m_measure.measure(conf, stamp);
    }

    void closeBin(std::size_t iBin) {}

  private:
    Measure& m_measure;
  };

  template <class M>
  EmptyObserver<M> MakeEmptyObserver(M& m) {
    return EmptyObserver<M>(m);
  }

}

#endif
<|endoftext|>


<commit_before>#include <gtk/gtk.h>

#include <gdk/gdk.h>

#include <openvibe/ov_directories.h>
#include <openvibe/ovCString.h>

#include <vrpn_Button.h>
#include <vrpn_Analog.h>
#include <vrpn_Connection.h>

#include <iostream>

#define _vrpn_peripheral_name_ "openvibe-vrpn@localhost"

// #define _DEBUG

::vrpn_Connection* g_pConnection=NULL;
::vrpn_Button_Server* g_pButtonServer=NULL;
::vrpn_Analog_Server* g_pAnalogServer=NULL;
long g_iAnalogCount=0;
long g_iButtonCount=0;

typedef union
{
	gpointer pUserData;
	int iData;
} TUserData;

void fScrollCB(::GtkRange* pRange, gpointer pUserData)
{
	TUserData  l_oUserData;
	l_oUserData.pUserData=pUserData;
	g_pAnalogServer->channels()[l_oUserData.iData]=gtk_range_get_value(pRange);

#if defined _DEBUG
	std::cout << (int)(pUserData) << " value changed\n";
#endif
}

void fSwitchCB(::GtkToggleButton* pTogglebutton, gpointer pUserData)
{
	TUserData  l_oUserData;
	l_oUserData.pUserData=pUserData;
	g_pButtonServer->set_button(l_oUserData.iData, gtk_toggle_button_get_active(pTogglebutton));

#if defined _DEBUG
	std::cout << (int)(pUserData) << " toggled\n";
#endif
}

void fConnectCB(::GtkWidget* pWidget, gpointer data)
{
	if(GTK_IS_RANGE(pWidget))
	{
		g_signal_connect(G_OBJECT(pWidget), "value-changed", G_CALLBACK(fScrollCB), (gpointer) g_iAnalogCount);
		g_iAnalogCount++;
	}

	if(GTK_IS_TOGGLE_BUTTON(pWidget))
	{
		g_signal_connect(G_OBJECT(pWidget), "toggled", G_CALLBACK(fSwitchCB), (void*)g_iButtonCount);
		g_iButtonCount++;
	}
}

gboolean fIdleApplicationLoop(gpointer pUserData)
{
	g_pButtonServer->mainloop();
	g_pAnalogServer->report_changes();
	g_pAnalogServer->mainloop();
	g_pConnection->mainloop();
	return TRUE;
}

int main(int argc, char ** argv)
{
	gtk_init(&argc, &argv);
	// g_pConnection=new ::vrpn_Connection;
	g_pConnection=vrpn_create_server_connection();
	g_pButtonServer=new ::vrpn_Button_Server(_vrpn_peripheral_name_, g_pConnection, 10);
	g_pAnalogServer=new ::vrpn_Analog_Server(_vrpn_peripheral_name_, g_pConnection);
	g_pAnalogServer->setNumChannels(10);

	::GtkBuilder* l_pInterface=gtk_builder_new(); // glade_xml_new(OpenViBE::Directories::getDataDir() + "/openvibe-applications/vrpn-simulator/interface.ui", "window", NULL);
	gtk_builder_add_from_file(l_pInterface, OpenViBE::Directories::getDataDir() + "/openvibe-applications/vrpn-simulator/interface.ui", NULL);

	::GtkWidget* l_pMainWindow=GTK_WIDGET(gtk_builder_get_object(l_pInterface, "window"));
	::GtkWidget* l_pHBoxButton=GTK_WIDGET(gtk_builder_get_object(l_pInterface, "hbox_button"));
	::GtkWidget* l_pHBoxAnalog=GTK_WIDGET(gtk_builder_get_object(l_pInterface, "hbox_analog"));

	g_signal_connect(G_OBJECT(l_pMainWindow), "destroy", gtk_main_quit, NULL);
	gtk_container_foreach(GTK_CONTAINER(l_pHBoxButton), fConnectCB, NULL);
	gtk_container_foreach(GTK_CONTAINER(l_pHBoxAnalog), fConnectCB, NULL);
	gtk_builder_connect_signals(l_pInterface, NULL);

	std::cout << "got " << g_iAnalogCount << " analogs...\n";
	std::cout << "got " << g_iButtonCount << " buttons...\n";

	g_idle_add(fIdleApplicationLoop, NULL);

	gtk_widget_show(l_pMainWindow);
	gtk_main();

	delete g_pAnalogServer;
	delete g_pButtonServer;
	delete g_pConnection;

	return 0;
}
<commit_msg>openvibe-applications/vrpn-stimulator: + added #ifdef guard to check for VRPN library availability<commit_after>#if defined TARGET_HAS_ThirdPartyVRPN

#include <gtk/gtk.h>

#include <gdk/gdk.h>

#include <openvibe/ov_directories.h>
#include <openvibe/ovCString.h>

#include <vrpn_Button.h>
#include <vrpn_Analog.h>
#include <vrpn_Connection.h>

#include <iostream>

#define _vrpn_peripheral_name_ "openvibe-vrpn@localhost"

// #define _DEBUG

::vrpn_Connection* g_pConnection=NULL;
::vrpn_Button_Server* g_pButtonServer=NULL;
::vrpn_Analog_Server* g_pAnalogServer=NULL;
long g_iAnalogCount=0;
long g_iButtonCount=0;

typedef union
{
	gpointer pUserData;
	int iData;
} TUserData;

void fScrollCB(::GtkRange* pRange, gpointer pUserData)
{
	TUserData  l_oUserData;
	l_oUserData.pUserData=pUserData;
	g_pAnalogServer->channels()[l_oUserData.iData]=gtk_range_get_value(pRange);

#if defined _DEBUG
	std::cout << (int)(pUserData) << " value changed\n";
#endif
}

void fSwitchCB(::GtkToggleButton* pTogglebutton, gpointer pUserData)
{
	TUserData  l_oUserData;
	l_oUserData.pUserData=pUserData;
	g_pButtonServer->set_button(l_oUserData.iData, gtk_toggle_button_get_active(pTogglebutton));

#if defined _DEBUG
	std::cout << (int)(pUserData) << " toggled\n";
#endif
}

void fConnectCB(::GtkWidget* pWidget, gpointer data)
{
	if(GTK_IS_RANGE(pWidget))
	{
		g_signal_connect(G_OBJECT(pWidget), "value-changed", G_CALLBACK(fScrollCB), (gpointer) g_iAnalogCount);
		g_iAnalogCount++;
	}

	if(GTK_IS_TOGGLE_BUTTON(pWidget))
	{
		g_signal_connect(G_OBJECT(pWidget), "toggled", G_CALLBACK(fSwitchCB), (void*)g_iButtonCount);
		g_iButtonCount++;
	}
}

gboolean fIdleApplicationLoop(gpointer pUserData)
{
	g_pButtonServer->mainloop();
	g_pAnalogServer->report_changes();
	g_pAnalogServer->mainloop();
	g_pConnection->mainloop();
	return TRUE;
}

int main(int argc, char ** argv)
{
	gtk_init(&argc, &argv);
	// g_pConnection=new ::vrpn_Connection;
	g_pConnection=vrpn_create_server_connection();
	g_pButtonServer=new ::vrpn_Button_Server(_vrpn_peripheral_name_, g_pConnection, 10);
	g_pAnalogServer=new ::vrpn_Analog_Server(_vrpn_peripheral_name_, g_pConnection);
	g_pAnalogServer->setNumChannels(10);

	::GtkBuilder* l_pInterface=gtk_builder_new(); // glade_xml_new(OpenViBE::Directories::getDataDir() + "/openvibe-applications/vrpn-simulator/interface.ui", "window", NULL);
	gtk_builder_add_from_file(l_pInterface, OpenViBE::Directories::getDataDir() + "/openvibe-applications/vrpn-simulator/interface.ui", NULL);

	::GtkWidget* l_pMainWindow=GTK_WIDGET(gtk_builder_get_object(l_pInterface, "window"));
	::GtkWidget* l_pHBoxButton=GTK_WIDGET(gtk_builder_get_object(l_pInterface, "hbox_button"));
	::GtkWidget* l_pHBoxAnalog=GTK_WIDGET(gtk_builder_get_object(l_pInterface, "hbox_analog"));

	g_signal_connect(G_OBJECT(l_pMainWindow), "destroy", gtk_main_quit, NULL);
	gtk_container_foreach(GTK_CONTAINER(l_pHBoxButton), fConnectCB, NULL);
	gtk_container_foreach(GTK_CONTAINER(l_pHBoxAnalog), fConnectCB, NULL);
	gtk_builder_connect_signals(l_pInterface, NULL);

	std::cout << "got " << g_iAnalogCount << " analogs...\n";
	std::cout << "got " << g_iButtonCount << " buttons...\n";

	g_idle_add(fIdleApplicationLoop, NULL);

	gtk_widget_show(l_pMainWindow);
	gtk_main();

	delete g_pAnalogServer;
	delete g_pButtonServer;
	delete g_pConnection;

	return 0;
}

#endif // TARGET_HAS_ThirdPartyVRPN
<|endoftext|>


<commit_before>#include <catch/catch.hpp>

#include <Transform/Referential.hpp>

using namespace obe::Transform;
using FlipAxis = Referential::FlipAxis;

TEST_CASE("Flipping Referentials should give correct results",
    "[obe.Transform.Referential.flip]")
{
    SECTION("Flipping both axis of known referentials")
    {
        REQUIRE(Referential::TopLeft.flip() == Referential::BottomRight);
        REQUIRE(Referential::Top.flip() == Referential::Bottom);
        REQUIRE(Referential::TopRight.flip() == Referential::BottomLeft);
        REQUIRE(Referential::Left.flip() == Referential::Right);
        REQUIRE(Referential::Center.flip() == Referential::Center);
        REQUIRE(Referential::Right.flip() == Referential::Left);
        REQUIRE(Referential::BottomLeft.flip() == Referential::TopRight);
        REQUIRE(Referential::Bottom.flip() == Referential::Top);
        REQUIRE(Referential::BottomRight.flip() == Referential::TopLeft);
    }
    SECTION("Flipping only horizontal axis of known referentials")
    {
        REQUIRE(Referential::TopLeft.flip(FlipAxis::Horizontal) == Referential::TopRight);
        REQUIRE(Referential::Top.flip(FlipAxis::Horizontal) == Referential::Top);
        REQUIRE(Referential::TopRight.flip(FlipAxis::Horizontal) == Referential::TopLeft);
        REQUIRE(Referential::Left.flip(FlipAxis::Horizontal) == Referential::Right);
        REQUIRE(Referential::Center.flip(FlipAxis::Horizontal) == Referential::Center);
        REQUIRE(Referential::Right.flip(FlipAxis::Horizontal) == Referential::Left);
        REQUIRE(Referential::BottomLeft.flip(FlipAxis::Horizontal)
            == Referential::BottomRight);
        REQUIRE(Referential::Bottom.flip(FlipAxis::Horizontal) == Referential::Bottom);
        REQUIRE(Referential::BottomRight.flip(FlipAxis::Horizontal)
            == Referential::BottomLeft);
    }
    SECTION("Flipping only vertical axis of known referentials")
    {
        REQUIRE(Referential::TopLeft.flip(FlipAxis::Vertical) == Referential::BottomLeft);
        REQUIRE(Referential::Top.flip(FlipAxis::Vertical) == Referential::Bottom);
        REQUIRE(
            Referential::TopRight.flip(FlipAxis::Vertical) == Referential::BottomRight);
        REQUIRE(Referential::Left.flip(FlipAxis::Vertical) == Referential::Left);
        REQUIRE(Referential::Center.flip(FlipAxis::Vertical) == Referential::Center);
        REQUIRE(Referential::Right.flip(FlipAxis::Vertical) == Referential::Right);
        REQUIRE(Referential::BottomLeft.flip(FlipAxis::Vertical) == Referential::TopLeft);
        REQUIRE(Referential::Bottom.flip(FlipAxis::Vertical) == Referential::Top);
        REQUIRE(
            Referential::BottomRight.flip(FlipAxis::Vertical) == Referential::TopRight);
    }
    SECTION("Flipping both axis of random referentials")
    {
        REQUIRE(Referential(0.1, 0.4).flip() == Referential(0.9, 0.6));
        REQUIRE(Referential(0.4, 0.6).flip() == Referential(0.6, 0.4));
        REQUIRE(Referential(0.2, 0.2).flip() == Referential(0.8, 0.8));
        REQUIRE(Referential(0.3, 0.5).flip() == Referential(0.7, 0.5));
    }
}

TEST_CASE("We should be able to test the position of referentials based on criterias",
    "[obe.Transform.Referential.isOn...]")
{
    SECTION("Testing if known referentials are on a corner")
    {
        REQUIRE(Referential::TopLeft.isOnCorner());
        REQUIRE(Referential::TopRight.isOnCorner());
        REQUIRE(Referential::BottomLeft.isOnCorner());
        REQUIRE(Referential::BottomRight.isOnCorner());
        REQUIRE_FALSE(Referential::Top.isOnCorner());
        REQUIRE_FALSE(Referential::Left.isOnCorner());
        REQUIRE_FALSE(Referential::Center.isOnCorner());
        REQUIRE_FALSE(Referential::Right.isOnCorner());
        REQUIRE_FALSE(Referential::Bottom.isOnCorner());
    }
    SECTION("Testing if known referentials are on a side")
    {
        REQUIRE_FALSE(Referential::TopLeft.isOnSide());
        REQUIRE_FALSE(Referential::TopRight.isOnSide());
        REQUIRE_FALSE(Referential::BottomLeft.isOnSide());
        REQUIRE_FALSE(Referential::BottomRight.isOnSide());
        REQUIRE(Referential::Top.isOnSide());
        REQUIRE(Referential::Left.isOnSide());
        REQUIRE_FALSE(Referential::Center.isOnSide());
        REQUIRE(Referential::Right.isOnSide());
        REQUIRE(Referential::Bottom.isOnSide());
    }
    SECTION("Testing if known referentials are on the left")
    {
        REQUIRE(Referential::TopLeft.isOnLeftSide());
        REQUIRE_FALSE(Referential::Top.isOnLeftSide());
        REQUIRE_FALSE(Referential::TopRight.isOnLeftSide());
        REQUIRE(Referential::Left.isOnLeftSide());
        REQUIRE_FALSE(Referential::Center.isOnLeftSide());
        REQUIRE_FALSE(Referential::Right.isOnLeftSide());
        REQUIRE(Referential::BottomLeft.isOnLeftSide());
        REQUIRE_FALSE(Referential::Bottom.isOnLeftSide());
        REQUIRE_FALSE(Referential::BottomRight.isOnLeftSide());
    }
    SECTION("Testing if known referentials are on the right")
    {
        REQUIRE_FALSE(Referential::TopLeft.isOnRightSide());
        REQUIRE_FALSE(Referential::Top.isOnRightSide());
        REQUIRE(Referential::TopRight.isOnRightSide());
        REQUIRE_FALSE(Referential::Left.isOnRightSide());
        REQUIRE_FALSE(Referential::Center.isOnRightSide());
        REQUIRE(Referential::Right.isOnRightSide());
        REQUIRE_FALSE(Referential::BottomLeft.isOnRightSide());
        REQUIRE_FALSE(Referential::Bottom.isOnRightSide());
        REQUIRE(Referential::BottomRight.isOnRightSide());
    }
    SECTION("Testing if known referentials are on the top")
    {
        REQUIRE(Referential::TopLeft.isOnTopSide());
        REQUIRE(Referential::Top.isOnTopSide());
        REQUIRE(Referential::TopRight.isOnTopSide());
        REQUIRE_FALSE(Referential::Left.isOnTopSide());
        REQUIRE_FALSE(Referential::Center.isOnTopSide());
        REQUIRE_FALSE(Referential::Right.isOnTopSide());
        REQUIRE_FALSE(Referential::BottomLeft.isOnTopSide());
        REQUIRE_FALSE(Referential::Bottom.isOnTopSide());
        REQUIRE_FALSE(Referential::BottomRight.isOnTopSide());
    }
    SECTION("Testing if known referentials are on the bottom")
    {
        REQUIRE_FALSE(Referential::TopLeft.isOnBottomSide());
        REQUIRE_FALSE(Referential::Top.isOnBottomSide());
        REQUIRE_FALSE(Referential::TopRight.isOnBottomSide());
        REQUIRE_FALSE(Referential::Left.isOnBottomSide());
        REQUIRE_FALSE(Referential::Center.isOnBottomSide());
        REQUIRE_FALSE(Referential::Right.isOnBottomSide());
        REQUIRE(Referential::BottomLeft.isOnBottomSide());
        REQUIRE(Referential::Bottom.isOnBottomSide());
        REQUIRE(Referential::BottomRight.isOnBottomSide());
    }
    SECTION("Testing random referentials and their positions")
    {
        REQUIRE(Referential(1, 0.33).isOnRightSide());
        REQUIRE(Referential(0, 0.66).isOnLeftSide());
        REQUIRE(Referential(0.22, 1).isOnBottomSide());
        REQUIRE(Referential(-0.11, 0).isOnTopSide());
        REQUIRE(Referential(0.99, 1).isOnSide());
        REQUIRE(Referential(0, 0).isOnCorner());
        REQUIRE_FALSE(Referential(0.999, 0.33).isOnRightSide());
        REQUIRE_FALSE(Referential(1, 0.66).isOnLeftSide());
        REQUIRE_FALSE(Referential(0.22, 0).isOnBottomSide());
        REQUIRE_FALSE(Referential(0.11, 1).isOnTopSide());
        REQUIRE_FALSE(Referential(0.99, 0.99).isOnSide());
        REQUIRE_FALSE(Referential(0.4, 0).isOnCorner());
    }
}

TEST_CASE("We should be able to represent a Referential as a string",
    "[obe.Transform.Referential.toString]")
{
    SECTION("Transforming known referentials to string with default formatter")
    {
        REQUIRE(Referential::TopLeft.toString() == "Referential<TopLeft>");
        REQUIRE(Referential::Top.toString() == "Referential<Top>");
        REQUIRE(Referential::TopRight.toString() == "Referential<TopRight>");
        REQUIRE(Referential::Left.toString() == "Referential<Left>");
        REQUIRE(Referential::Center.toString() == "Referential<Center>");
        REQUIRE(Referential::Right.toString() == "Referential<Right>");
        REQUIRE(Referential::BottomLeft.toString() == "Referential<BottomLeft>");
        REQUIRE(Referential::Bottom.toString() == "Referential<Bottom>");
        REQUIRE(Referential::BottomRight.toString() == "Referential<BottomRight>");
    }
    SECTION("Transforming known referentials to string with custom formatter")
    {
        REQUIRE(Referential::TopLeft.toString("A({})") == "A(TopLeft)");
        REQUIRE(Referential::Top.toString("+{}") == "+Top");
        REQUIRE(Referential::TopRight.toString("/{}/") == "/TopRight/");
        REQUIRE(Referential::Left.toString("Why did you {} me") == "Why did you Left me");
        REQUIRE(Referential::Center.toString("{} of the Earth") == "Center of the Earth");
        REQUIRE(Referential::Right.toString("You were actually {}")
            == "You were actually Right");
        REQUIRE(Referential::BottomLeft.toString("1+2={}") == "1+2=BottomLeft");
        REQUIRE(Referential::Bottom.toString("Bikini {}") == "Bikini Bottom");
        REQUIRE(Referential::BottomRight.toString("{0} == {0}")
            == "BottomRight == BottomRight");
    }
    SECTION("Transforming random referentials to string with default formatter")
    {
        REQUIRE(Referential(0.123, 0.456).toString() == "Referential<0.123, 0.456>");
        REQUIRE(Referential(0.6666, 0.9999).toString() == "Referential<0.6666, 0.9999>");
    }
    SECTION("Transforming random referentials to string with custom formatter")
    {
        REQUIRE(Referential(0.9, 0.1).toString("{}") == "0.9, 0.1");
        REQUIRE(Referential(0.1234, 0.5678).toString("Referential => {}")
            == "Referential => 0.1234, 0.5678");
        REQUIRE(Referential(0.666, 1).toString("The devil is == {1}")
            == "The devil is == 0.666");
        REQUIRE(Referential(0.1, 0.42).toString("I wonder why {2} is the answer")
            == "I wonder why 0.42 is the answer");
        REQUIRE(Referential(0.456, 0.123).toString("y = {2}, x = {1}")
            == "y = 0.123, x = 0.456");
    }
}

TEST_CASE("We should be able to load a Referential from a string",
    "[obe.Transform.Referential.FromString]")
{
    SECTION("Loading known referentials from a string")
    {
        REQUIRE(Referential::FromString("TopLeft") == Referential::TopLeft);
        REQUIRE(Referential::FromString("Top") == Referential::Top);
        REQUIRE(Referential::FromString("TopRight") == Referential::TopRight);
        REQUIRE(Referential::FromString("Left") == Referential::Left);
        REQUIRE(Referential::FromString("Center") == Referential::Center);
        REQUIRE(Referential::FromString("Right") == Referential::Right);
        REQUIRE(Referential::FromString("BottomLeft") == Referential::BottomLeft);
        REQUIRE(Referential::FromString("Bottom") == Referential::Bottom);
        REQUIRE(Referential::FromString("BottomRight") == Referential::BottomRight);
    }
    SECTION("Loading random referentials from a string")
    {
        REQUIRE(Referential::FromString("Referential<0.1, 0.666>")
            == Referential(0.1, 0.666));
        REQUIRE(
            Referential::FromString("Referential<-0.55, -1>") == Referential(-0.55, -1));
        REQUIRE_THROWS(Referential::FromString("?"));
    }
}<commit_msg>Fixed tests<commit_after>#include <catch/catch.hpp>

#include <Transform/Referential.hpp>

using namespace obe::Transform;

TEST_CASE("Flipping Referentials should give correct results",
    "[obe.Transform.Referential.flip]")
{
    SECTION("Flipping both axis of known referentials")
    {
        REQUIRE(Referential::TopLeft.flip() == Referential::BottomRight);
        REQUIRE(Referential::Top.flip() == Referential::Bottom);
        REQUIRE(Referential::TopRight.flip() == Referential::BottomLeft);
        REQUIRE(Referential::Left.flip() == Referential::Right);
        REQUIRE(Referential::Center.flip() == Referential::Center);
        REQUIRE(Referential::Right.flip() == Referential::Left);
        REQUIRE(Referential::BottomLeft.flip() == Referential::TopRight);
        REQUIRE(Referential::Bottom.flip() == Referential::Top);
        REQUIRE(Referential::BottomRight.flip() == Referential::TopLeft);
    }
    SECTION("Flipping only horizontal axis of known referentials")
    {
        REQUIRE(Referential::TopLeft.flip(FlipAxis::Horizontal) == Referential::TopRight);
        REQUIRE(Referential::Top.flip(FlipAxis::Horizontal) == Referential::Top);
        REQUIRE(Referential::TopRight.flip(FlipAxis::Horizontal) == Referential::TopLeft);
        REQUIRE(Referential::Left.flip(FlipAxis::Horizontal) == Referential::Right);
        REQUIRE(Referential::Center.flip(FlipAxis::Horizontal) == Referential::Center);
        REQUIRE(Referential::Right.flip(FlipAxis::Horizontal) == Referential::Left);
        REQUIRE(Referential::BottomLeft.flip(FlipAxis::Horizontal)
            == Referential::BottomRight);
        REQUIRE(Referential::Bottom.flip(FlipAxis::Horizontal) == Referential::Bottom);
        REQUIRE(Referential::BottomRight.flip(FlipAxis::Horizontal)
            == Referential::BottomLeft);
    }
    SECTION("Flipping only vertical axis of known referentials")
    {
        REQUIRE(Referential::TopLeft.flip(FlipAxis::Vertical) == Referential::BottomLeft);
        REQUIRE(Referential::Top.flip(FlipAxis::Vertical) == Referential::Bottom);
        REQUIRE(
            Referential::TopRight.flip(FlipAxis::Vertical) == Referential::BottomRight);
        REQUIRE(Referential::Left.flip(FlipAxis::Vertical) == Referential::Left);
        REQUIRE(Referential::Center.flip(FlipAxis::Vertical) == Referential::Center);
        REQUIRE(Referential::Right.flip(FlipAxis::Vertical) == Referential::Right);
        REQUIRE(Referential::BottomLeft.flip(FlipAxis::Vertical) == Referential::TopLeft);
        REQUIRE(Referential::Bottom.flip(FlipAxis::Vertical) == Referential::Top);
        REQUIRE(
            Referential::BottomRight.flip(FlipAxis::Vertical) == Referential::TopRight);
    }
    SECTION("Flipping both axis of random referentials")
    {
        REQUIRE(Referential(0.1, 0.4).flip() == Referential(0.9, 0.6));
        REQUIRE(Referential(0.4, 0.6).flip() == Referential(0.6, 0.4));
        REQUIRE(Referential(0.2, 0.2).flip() == Referential(0.8, 0.8));
        REQUIRE(Referential(0.3, 0.5).flip() == Referential(0.7, 0.5));
    }
}

TEST_CASE("We should be able to test the position of referentials based on criterias",
    "[obe.Transform.Referential.isOn...]")
{
    SECTION("Testing if known referentials are on a corner")
    {
        REQUIRE(Referential::TopLeft.isOnCorner());
        REQUIRE(Referential::TopRight.isOnCorner());
        REQUIRE(Referential::BottomLeft.isOnCorner());
        REQUIRE(Referential::BottomRight.isOnCorner());
        REQUIRE_FALSE(Referential::Top.isOnCorner());
        REQUIRE_FALSE(Referential::Left.isOnCorner());
        REQUIRE_FALSE(Referential::Center.isOnCorner());
        REQUIRE_FALSE(Referential::Right.isOnCorner());
        REQUIRE_FALSE(Referential::Bottom.isOnCorner());
    }
    SECTION("Testing if known referentials are on a side")
    {
        REQUIRE_FALSE(Referential::TopLeft.isOnSide());
        REQUIRE_FALSE(Referential::TopRight.isOnSide());
        REQUIRE_FALSE(Referential::BottomLeft.isOnSide());
        REQUIRE_FALSE(Referential::BottomRight.isOnSide());
        REQUIRE(Referential::Top.isOnSide());
        REQUIRE(Referential::Left.isOnSide());
        REQUIRE_FALSE(Referential::Center.isOnSide());
        REQUIRE(Referential::Right.isOnSide());
        REQUIRE(Referential::Bottom.isOnSide());
    }
    SECTION("Testing if known referentials are on the left")
    {
        REQUIRE(Referential::TopLeft.isOnLeftSide());
        REQUIRE_FALSE(Referential::Top.isOnLeftSide());
        REQUIRE_FALSE(Referential::TopRight.isOnLeftSide());
        REQUIRE(Referential::Left.isOnLeftSide());
        REQUIRE_FALSE(Referential::Center.isOnLeftSide());
        REQUIRE_FALSE(Referential::Right.isOnLeftSide());
        REQUIRE(Referential::BottomLeft.isOnLeftSide());
        REQUIRE_FALSE(Referential::Bottom.isOnLeftSide());
        REQUIRE_FALSE(Referential::BottomRight.isOnLeftSide());
    }
    SECTION("Testing if known referentials are on the right")
    {
        REQUIRE_FALSE(Referential::TopLeft.isOnRightSide());
        REQUIRE_FALSE(Referential::Top.isOnRightSide());
        REQUIRE(Referential::TopRight.isOnRightSide());
        REQUIRE_FALSE(Referential::Left.isOnRightSide());
        REQUIRE_FALSE(Referential::Center.isOnRightSide());
        REQUIRE(Referential::Right.isOnRightSide());
        REQUIRE_FALSE(Referential::BottomLeft.isOnRightSide());
        REQUIRE_FALSE(Referential::Bottom.isOnRightSide());
        REQUIRE(Referential::BottomRight.isOnRightSide());
    }
    SECTION("Testing if known referentials are on the top")
    {
        REQUIRE(Referential::TopLeft.isOnTopSide());
        REQUIRE(Referential::Top.isOnTopSide());
        REQUIRE(Referential::TopRight.isOnTopSide());
        REQUIRE_FALSE(Referential::Left.isOnTopSide());
        REQUIRE_FALSE(Referential::Center.isOnTopSide());
        REQUIRE_FALSE(Referential::Right.isOnTopSide());
        REQUIRE_FALSE(Referential::BottomLeft.isOnTopSide());
        REQUIRE_FALSE(Referential::Bottom.isOnTopSide());
        REQUIRE_FALSE(Referential::BottomRight.isOnTopSide());
    }
    SECTION("Testing if known referentials are on the bottom")
    {
        REQUIRE_FALSE(Referential::TopLeft.isOnBottomSide());
        REQUIRE_FALSE(Referential::Top.isOnBottomSide());
        REQUIRE_FALSE(Referential::TopRight.isOnBottomSide());
        REQUIRE_FALSE(Referential::Left.isOnBottomSide());
        REQUIRE_FALSE(Referential::Center.isOnBottomSide());
        REQUIRE_FALSE(Referential::Right.isOnBottomSide());
        REQUIRE(Referential::BottomLeft.isOnBottomSide());
        REQUIRE(Referential::Bottom.isOnBottomSide());
        REQUIRE(Referential::BottomRight.isOnBottomSide());
    }
    SECTION("Testing random referentials and their positions")
    {
        REQUIRE(Referential(1, 0.33).isOnRightSide());
        REQUIRE(Referential(0, 0.66).isOnLeftSide());
        REQUIRE(Referential(0.22, 1).isOnBottomSide());
        REQUIRE(Referential(-0.11, 0).isOnTopSide());
        REQUIRE(Referential(0.99, 1).isOnSide());
        REQUIRE(Referential(0, 0).isOnCorner());
        REQUIRE_FALSE(Referential(0.999, 0.33).isOnRightSide());
        REQUIRE_FALSE(Referential(1, 0.66).isOnLeftSide());
        REQUIRE_FALSE(Referential(0.22, 0).isOnBottomSide());
        REQUIRE_FALSE(Referential(0.11, 1).isOnTopSide());
        REQUIRE_FALSE(Referential(0.99, 0.99).isOnSide());
        REQUIRE_FALSE(Referential(0.4, 0).isOnCorner());
    }
}

TEST_CASE("We should be able to represent a Referential as a string",
    "[obe.Transform.Referential.toString]")
{
    SECTION("Transforming known referentials to string with default formatter")
    {
        REQUIRE(Referential::TopLeft.toString() == "Referential<TopLeft>");
        REQUIRE(Referential::Top.toString() == "Referential<Top>");
        REQUIRE(Referential::TopRight.toString() == "Referential<TopRight>");
        REQUIRE(Referential::Left.toString() == "Referential<Left>");
        REQUIRE(Referential::Center.toString() == "Referential<Center>");
        REQUIRE(Referential::Right.toString() == "Referential<Right>");
        REQUIRE(Referential::BottomLeft.toString() == "Referential<BottomLeft>");
        REQUIRE(Referential::Bottom.toString() == "Referential<Bottom>");
        REQUIRE(Referential::BottomRight.toString() == "Referential<BottomRight>");
    }
    SECTION("Transforming known referentials to string with custom formatter")
    {
        REQUIRE(Referential::TopLeft.toString("A({})") == "A(TopLeft)");
        REQUIRE(Referential::Top.toString("+{}") == "+Top");
        REQUIRE(Referential::TopRight.toString("/{}/") == "/TopRight/");
        REQUIRE(Referential::Left.toString("Why did you {} me") == "Why did you Left me");
        REQUIRE(Referential::Center.toString("{} of the Earth") == "Center of the Earth");
        REQUIRE(Referential::Right.toString("You were actually {}")
            == "You were actually Right");
        REQUIRE(Referential::BottomLeft.toString("1+2={}") == "1+2=BottomLeft");
        REQUIRE(Referential::Bottom.toString("Bikini {}") == "Bikini Bottom");
        REQUIRE(Referential::BottomRight.toString("{0} == {0}")
            == "BottomRight == BottomRight");
    }
    SECTION("Transforming random referentials to string with default formatter")
    {
        REQUIRE(Referential(0.123, 0.456).toString() == "Referential<0.123, 0.456>");
        REQUIRE(Referential(0.6666, 0.9999).toString() == "Referential<0.6666, 0.9999>");
    }
    SECTION("Transforming random referentials to string with custom formatter")
    {
        REQUIRE(Referential(0.9, 0.1).toString("{}") == "0.9, 0.1");
        REQUIRE(Referential(0.1234, 0.5678).toString("Referential => {}")
            == "Referential => 0.1234, 0.5678");
        REQUIRE(Referential(0.666, 1).toString("The devil is == {1}")
            == "The devil is == 0.666");
        REQUIRE(Referential(0.1, 0.42).toString("I wonder why {2} is the answer")
            == "I wonder why 0.42 is the answer");
        REQUIRE(Referential(0.456, 0.123).toString("y = {2}, x = {1}")
            == "y = 0.123, x = 0.456");
    }
}

TEST_CASE("We should be able to load a Referential from a string",
    "[obe.Transform.Referential.FromString]")
{
    SECTION("Loading known referentials from a string")
    {
        REQUIRE(Referential::FromString("TopLeft") == Referential::TopLeft);
        REQUIRE(Referential::FromString("Top") == Referential::Top);
        REQUIRE(Referential::FromString("TopRight") == Referential::TopRight);
        REQUIRE(Referential::FromString("Left") == Referential::Left);
        REQUIRE(Referential::FromString("Center") == Referential::Center);
        REQUIRE(Referential::FromString("Right") == Referential::Right);
        REQUIRE(Referential::FromString("BottomLeft") == Referential::BottomLeft);
        REQUIRE(Referential::FromString("Bottom") == Referential::Bottom);
        REQUIRE(Referential::FromString("BottomRight") == Referential::BottomRight);
    }
    SECTION("Loading random referentials from a string")
    {
        REQUIRE(Referential::FromString("Referential<0.1, 0.666>")
            == Referential(0.1, 0.666));
        REQUIRE(
            Referential::FromString("Referential<-0.55, -1>") == Referential(-0.55, -1));
        REQUIRE_THROWS(Referential::FromString("?"));
    }
}<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : E2.cpp
 * Author  : Kazune Takahashi
 * Created : 6/17/2019, 12:04:14 AM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
typedef long long ll;
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
const int MAX_SIZE = 1000010;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a) { return (*this *= power(MOD - 2)); }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
mint inv[MAX_SIZE];
mint fact[MAX_SIZE];
mint factinv[MAX_SIZE];
void init()
{
  inv[1] = 1;
  for (int i = 2; i < MAX_SIZE; i++)
  {
    inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
  }
  fact[0] = factinv[0] = 1;
  for (int i = 1; i < MAX_SIZE; i++)
  {
    fact[i] = mint(i) * fact[i - 1];
    factinv[i] = inv[i] * factinv[i - 1];
  }
}
mint choose(int n, int k)
{
  if (n >= 0 && k >= 0 && n - k >= 0)
  {
    return fact[n] * factinv[k] * factinv[n - k];
  }
  return 0;
}
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// const double epsilon = 1e-10;
// const ll infty = 1000000000000000LL;
// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

int N, M;
int S[2010];
int T[2010];

mint dp0[2010][2010];
mint dp1[2010][2010];

int main()
{
  // init();
  cin >> N >> M;
  for (auto i = 0; i < N; i++)
  {
    cin >> S[i];
  }
  for (auto i = 0; i < M; i++)
  {
    cin >> T[i];
  }
  dp0[0][0] = 1;
  for (auto i = 0; i < N; i++)
  {
    for (auto j = 0; j < M; j++)
    {
      dp0[i + 1][j] += dp0[i][j];
      dp1[i][j + 1] += dp0[i][j];
      dp1[i][j + 1] += dp1[i][j];
      if (S[i] == T[j])
      {
        dp0[i + 1][j + 1] += dp1[i][j];
      }
    }
  }
  mint ans = dp1[N][M];
  cout << ans << endl;
}<commit_msg>submit E2.cpp to 'E - Common Subsequence' (abc130) [C++14 (GCC 5.4.1)]<commit_after>#define DEBUG 1
/**
 * File    : E2.cpp
 * Author  : Kazune Takahashi
 * Created : 6/17/2019, 12:04:14 AM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
typedef long long ll;
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
const int MAX_SIZE = 1000010;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a) { return (*this *= power(MOD - 2)); }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
mint inv[MAX_SIZE];
mint fact[MAX_SIZE];
mint factinv[MAX_SIZE];
void init()
{
  inv[1] = 1;
  for (int i = 2; i < MAX_SIZE; i++)
  {
    inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
  }
  fact[0] = factinv[0] = 1;
  for (int i = 1; i < MAX_SIZE; i++)
  {
    fact[i] = mint(i) * fact[i - 1];
    factinv[i] = inv[i] * factinv[i - 1];
  }
}
mint choose(int n, int k)
{
  if (n >= 0 && k >= 0 && n - k >= 0)
  {
    return fact[n] * factinv[k] * factinv[n - k];
  }
  return 0;
}
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// const double epsilon = 1e-10;
// const ll infty = 1000000000000000LL;
// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

int N, M;
int S[2010];
int T[2010];

mint dp0[2010][2010];
mint dp1[2010][2010];

int main()
{
  // init();
  cin >> N >> M;
  for (auto i = 0; i < N; i++)
  {
    cin >> S[i];
  }
  for (auto i = 0; i < M; i++)
  {
    cin >> T[i];
  }
  dp0[0][0] = 1;
  for (auto i = 0; i <= N; i++)
  {
    for (auto j = 0; j <= M; j++)
    {
      dp0[i + 1][j] += dp0[i][j];
      dp1[i][j] += dp0[i][j];
      dp1[i][j + 1] += dp1[i][j];
      if (i < N && j < M && S[i] == T[j])
      {
        dp0[i + 1][j + 1] += dp1[i][j];
      }
    }
  }
  mint ans = dp1[N][M];
  cout << ans << endl;
}<|endoftext|>