File NPInputParser.cxx
File List > core > NPInputParser.cxx
Go to the documentation of this file
#include "NPInputParser.h"
#include "NPException.h"
#include "NPFunction.h"
#include "NPSystemOfUnits.h"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
nptool::BlockPtr nptool::InputBlock::Copy() {
auto res = std::make_shared<nptool::InputBlock>();
res->m_Level = this->m_Level;
res->m_MainToken = this->m_MainToken;
res->m_MainValue = this->m_MainValue;
res->m_Token = this->m_Token;
res->m_Value = this->m_Value;
return res;
}
std::vector<nptool::BlockPtr> nptool::InputBlock::GetSubBlock(std::string Token) {
std::vector<nptool::BlockPtr> res;
for (auto it = m_SubBlock.begin(), end = m_SubBlock.end(); it != end; it++) {
if ((*it)->GetMainToken() == Token) {
res.push_back(*it);
}
}
return res;
}
std::string nptool::StripSpaces(std::string line) {
// Remove preceding spaces
while (*line.begin() == ' ')
line = line.substr(1, line.length());
// Remove trailing spaces
if (line.length() > 0)
while (*line.rbegin() == ' ')
line = line.substr(0, line.length() - 1);
// Remove preceding tabs
while (*line.begin() == '\t')
line = line.substr(1, line.length());
// Remove trailing tabs
if (line.length() > 0)
while (*line.rbegin() == '\t')
line = line.substr(0, line.length() - 1);
return line;
}
unsigned int nptool::GetLevel(std::string line) {
unsigned int level = 0;
if (line.length() == 0)
return 1000;
for (unsigned int i = 0; i < line.length(); i++) {
if (line.compare(i, 1, " ") == 0)
level++;
else
break;
}
return level;
}
std::string nptool::ToLower(std::string line) {
std::transform(line.begin(), line.end(), line.begin(), ::tolower);
return line;
}
nptool::InputBlock::InputBlock(std::string line) {
m_Level = GetLevel(line);
m_MainToken = StripSpaces(ExtractToken(line, " "));
m_MainValue = StripSpaces(ExtractValue(line, " "));
}
std::string nptool::InputBlock::ExtractToken(std::string line, std::string separator) {
// Find the separator
if (separator == "")
separator = nptool::token_separator;
std::size_t pos = line.find(separator.c_str());
return line.substr(0, pos);
}
std::string nptool::InputBlock::ExtractValue(std::string line, std::string separator) {
// Find the separator
if (separator == "")
separator = nptool::token_separator;
std::size_t pos = line.find(separator.c_str());
if (pos != std::string::npos)
return line.substr(pos + 1);
else
return "";
}
void nptool::InputBlock::AddLine(std::string line) {
m_Token.push_back(ToLower(StripSpaces(ExtractToken(line))));
m_Value.push_back(StripSpaces(ExtractValue(line)));
m_Lines.push_back(StripSpaces(line));
}
void nptool::InputBlock::AddLine(std::string token, std::string value) {
m_Token.push_back(ToLower(token));
m_Value.push_back(value);
m_Lines.push_back(token + ": " + value);
}
void nptool::InputBlock::Dump() {
std::cout << "//////////// Block ////////////" << std::endl;
std::cout << " * Main Token: " << m_MainToken << std::endl;
std::cout << " * Main Value: " << m_MainValue << std::endl;
std::cout << " * Number of Line: " << GetSize() << std::endl;
for (unsigned int i = 0; i < GetSize(); i++)
std::cout << " - " << i + 1 << " " << m_Token[i] << ": " << m_Value[i] << std::endl;
}
bool nptool::InputBlock::HasTokenList(std::vector<std::string> Token) {
if (m_Token.size() == 0)
return false;
bool res = true;
for (unsigned int i = 0; i < Token.size(); i++)
res = res && HasToken(Token[i]);
return res;
}
bool nptool::InputBlock::HasToken(std::string Token) {
for (unsigned int i = 0; i < m_Token.size(); i++) {
if (m_Token[i] == ToLower(Token)) {
return true;
}
}
return false;
}
std::string nptool::InputBlock::GetValue(std::string Token) {
for (unsigned int i = 0; i < m_Token.size(); i++) {
if (m_Token[i] == ToLower(Token))
return m_Value[i];
}
return "";
}
double nptool::InputBlock::GetDouble(std::string Token, std::string default_unit, bool silent) {
std::stringstream iss(GetValue(Token));
double val;
std::string unit;
iss >> val >> unit;
if (unit == "") {
if (default_unit != "void")
std::cout << "WARNING: Using default units for token " << Token << std::endl;
val = ApplyUnit(val, default_unit);
}
else {
val = ApplyUnit(val, unit);
}
if (!silent)
printf(" %s (%s): %.4f\n", Token.c_str(), default_unit.c_str(), val / ApplyUnit(1, default_unit));
return val;
}
int nptool::InputBlock::GetInt(std::string Token, bool silent) {
std::stringstream iss(GetValue(Token));
int val;
iss >> val;
if (!silent)
printf(" %s: %d\n", Token.c_str(), val);
return val;
}
bool nptool::InputBlock::GetBool(std::string Token, bool silent) {
std::stringstream iss(GetValue(Token));
bool val;
std::string buffer;
iss >> buffer;
ToLower(buffer);
if (buffer == "true" || buffer == "1")
val = true;
if (buffer == "false" || buffer == "0")
val = false;
if (!silent) {
if (val)
printf(" %s: %s\n", Token.c_str(), "true");
else
printf(" %s: %s\n", Token.c_str(), "false");
}
return val;
}
std::string nptool::InputBlock::GetString(std::string Token, bool silent) {
if (!silent)
printf(" %s: %s\n", Token.c_str(), GetValue(Token).c_str());
return GetValue(Token);
}
std::vector<double> nptool::InputBlock::GetVector3(std::string Token, std::string default_unit, bool silent) {
std::stringstream iss(GetValue(Token));
double x, y, z;
std::string unit;
iss >> x >> y >> z >> unit;
if (unit == "") {
if (default_unit != "void")
std::cout << "WARNING: Using default units for token " << Token << std::endl;
x = ApplyUnit(x, default_unit);
y = ApplyUnit(y, default_unit);
z = ApplyUnit(z, default_unit);
}
else {
x = ApplyUnit(x, unit);
y = ApplyUnit(y, unit);
z = ApplyUnit(z, unit);
}
if (!silent)
printf(" %s (%s): (%.4f;%.4f;%.4f)\n", Token.c_str(), default_unit.c_str(), x / ApplyUnit(1, default_unit),
y / ApplyUnit(1, default_unit), z / ApplyUnit(1, default_unit));
std::vector<double> v = {x, y, z};
return v;
}
std::vector<std::string> nptool::InputBlock::GetVectorString(std::string Token, bool silent) {
std::stringstream iss(GetValue(Token));
std::vector<std::string> val;
std::string buffer;
while (iss >> buffer)
val.push_back(buffer);
if (!silent) {
printf(" %s: ", Token.c_str());
for (unsigned int i = 0; i < val.size(); i++)
printf("%s ", val[i].c_str());
printf("\n");
}
return val;
}
std::vector<double> nptool::InputBlock::GetVectorDouble(std::string Token, std::string default_unit, bool silent) {
std::stringstream iss(GetValue(Token));
std::vector<double> val;
double buffer;
while (iss >> buffer)
val.push_back(buffer);
// Try to read the unit
iss.clear();
std::string unit;
iss >> unit;
if (unit == "") {
if (default_unit != "void")
std::cout << "WARNING: Using default units for token " << Token << std::endl;
for (unsigned int i = 0; i < val.size(); i++)
val[i] = ApplyUnit(val[i], default_unit);
}
else {
for (unsigned int i = 0; i < val.size(); i++)
val[i] = ApplyUnit(val[i], unit);
}
if (!silent) {
printf(" %s (%s): ", Token.c_str(), default_unit.c_str());
for (unsigned int i = 0; i < val.size(); i++)
printf("%f ", val[i] / ApplyUnit(1, default_unit));
printf("\n");
}
return val;
}
std::vector<int> nptool::InputBlock::GetVectorInt(std::string Token, bool silent) {
std::stringstream iss(GetValue(Token));
std::vector<int> val;
int buffer;
while (iss >> buffer)
val.push_back(buffer);
if (!silent) {
printf(" %s: ", Token.c_str());
for (unsigned int i = 0; i < val.size(); i++)
printf(" %d: ", val[i]);
std::cout << std::endl;
}
return val;
}
void nptool::InputParser::Dump() {
for (unsigned int i = 0; i < m_Block.size(); i++)
m_Block[i]->Dump();
}
bool nptool::InputParser::IsNotComment(std::string line) {
line = StripSpaces(line);
if (line.length() == 0)
return false;
std::size_t pos = line.find("%");
if (pos == std::string::npos)
return true;
else
return false;
}
std::vector<nptool::BlockPtr> nptool::InputParser::GetAllBlocksWithToken(std::string Token) {
std::vector<nptool::BlockPtr> res;
for (unsigned int i = 0; i < m_Block.size(); i++) {
if (m_Block[i]->GetMainToken() == Token) {
res.push_back(m_Block[i]);
}
}
return res;
}
std::vector<nptool::BlockPtr> nptool::InputParser::GetAllBlocksWithTokenAndValue(std::string Token, std::string Value) {
std::vector<nptool::BlockPtr> res;
for (unsigned int i = 0; i < m_Block.size(); i++) {
if (m_Block[i]->GetMainToken() == Token) {
if (m_Block[i]->GetMainValue() == Value)
res.push_back(m_Block[i]);
}
}
return res;
}
std::vector<std::string> nptool::InputParser::GetAllBlocksToken() {
std::vector<std::string> token;
for (unsigned int i = 0; i < m_Block.size(); i++) {
token.push_back(m_Block[i]->GetMainToken());
}
return token;
}
std::vector<std::string> nptool::InputParser::GetAllBlocksValues(std::string token) {
std::vector<std::string> value;
std::vector<nptool::BlockPtr> blocks = GetAllBlocksWithToken(token);
unsigned int size = blocks.size();
for (unsigned int i = 0; i < size; i++) {
value.push_back(blocks[i]->GetMainValue());
}
return value;
}
void nptool::InputParser::SuppressAllBlocksWithToken(std::string Token) {
for (auto it = m_Block.begin(); it != m_Block.end();) {
if ((*it)->GetMainToken() == Token) {
it = m_Block.erase(it);
}
else {
it++;
}
}
}
void nptool::InputParser::TreatAliases() {
// Call the alias block
auto alias = GetAllBlocksWithToken("alias");
// List of token:
std::vector<std::string> token = {"name", "action", "value"};
// - Action
// -> Split : create new block for each value
// -> Inplace : Replace the value in existing alias
// - Value -> The list of value to be used
for (unsigned int i = 0; i < alias.size(); i++) {
if (!alias[i]->HasTokenList(token)) {
// nptool::SendErrorAndExit("nptool::InputParser", "Alias block syntax incorrect");
exit(1);
}
std::cout << "//// Using Alias : " << std::endl;
std::string name = "@";
name += alias[i]->GetString("name");
std::string action = alias[i]->GetString("action");
std::vector<std::string> value = alias[i]->GetVectorString("value");
if (action == "replace" && value.size() != 1)
exit(1);
// nptool::SendErrorAndExit("nptool::InputParser", "Inplace alias can only take one value");
// Scan all blocks for aliases
for (unsigned int b = 0; b < m_Block.size(); b++) {
unsigned int size = m_Block[b]->GetSize();
size_t pos;
// In place case loop over each value and replace them
if (action == "replace") {
for (unsigned int v = 0; v < size; v++) {
while ((pos = m_Block[b]->GetValue(v).find(name)) != std::string::npos) {
std::string val = m_Block[b]->GetValue(v);
val.replace(pos, name.length(), value[0]);
m_Block[b]->SetValue(v, val);
}
}
}
else if (action == "copy") {
bool check = false;
// first pass identify if the block use an alias
for (unsigned int v = 0; v < size; v++) {
if (m_Block[b]->GetValue(v).find(name) != std::string::npos)
check = true;
}
if (check) {
auto originalBlock = m_Block[b]->Copy();
for (unsigned int a = 0; a < value.size(); a++) {
auto newBlock = originalBlock->Copy();
for (unsigned int v = 0; v < size; v++) {
while ((pos = newBlock->GetValue(v).find(name)) != std::string::npos) {
std::string val = newBlock->GetValue(v);
val.replace(pos, name.length(), value[a]);
newBlock->SetValue(v, val);
}
}
if (a == 0) {
m_Block[b] = newBlock;
}
else {
auto it = m_Block.begin();
m_Block.insert(it + b + a, newBlock);
}
}
}
}
}
}
SuppressAllBlocksWithToken("alias");
}
nptool::BlockPtr nptool::InputParser::ProcessBlock(YAML::const_iterator it) {
BlockPtr block = std::make_shared<nptool::InputBlock>(it->first.as<std::string>());
for (YAML::const_iterator itt = it->second.begin(); itt != it->second.end(); ++itt) {
if (itt->second.size() == 0) {
block->AddLine(itt->first.as<std::string>(), itt->second.as<std::string>());
}
else {
auto sub_block = ProcessBlock(itt);
block->AddSubBlock(sub_block);
}
}
return block;
}
void nptool::InputParser::ReadFile(std::string filename, bool silent) {
// Clear from previous blocks
Clear();
try {
YAML::Node config = YAML::LoadFile(filename);
if (!silent)
message("green", "core", "nptool::InputParser", "Reading file " + filename);
// loop through the block and display them
std::vector<std::string> line;
for (YAML::const_iterator it = config.begin(); it != config.end(); ++it) {
auto block = ProcessBlock(it);
m_Block.push_back(block);
}
TreatAliases();
}
catch (YAML::BadFile& badfile) {
throw(nptool::Error("InputParser", "File " + filename + " does not exist"));
}
catch (YAML::ParserException& badfile) {
throw(nptool::Error("InputParser", "File " + filename + " is not a valid yaml file"));
}
catch (...) {
throw;
}
}
void nptool::InputParser::Clear() {
m_Block.clear();
m_Aliases.clear();
}
double nptool::ApplyUnit(double value, std::string unit) {
if (unit == "void") // apply no unit
return value;
else if (unit == "g/cm3") {
return value * nptool::g / nptool::cm3;
}
else if (unit == "kg/cm3") {
return value * nptool::kg / nptool::cm3;
}
else if (unit == "millimeter") {
return value * nptool::millimeter;
}
else if (unit == "millimeter2") {
return value * nptool::millimeter2;
}
else if (unit == "millimeter3") {
return value * nptool::millimeter3;
}
else if (unit == "centimeter") {
return value * nptool::centimeter;
}
else if (unit == "centimeter2") {
return value * nptool::centimeter2;
}
else if (unit == "centimeter3") {
return value * nptool::centimeter3;
}
else if (unit == "meter") {
return value * nptool::meter;
}
else if (unit == "meter2") {
return value * nptool::meter2;
}
else if (unit == "meter3") {
return value * nptool::meter3;
}
else if (unit == "kilometer") {
return value * nptool::kilometer;
}
else if (unit == "kilometer2") {
return value * nptool::kilometer2;
}
else if (unit == "kilometer3") {
return value * nptool::kilometer3;
}
else if (unit == "parsec") {
return value * nptool::parsec;
}
else if (unit == "micrometer") {
return value * nptool::micrometer;
}
else if (unit == "nanometer") {
return value * nptool::nanometer;
}
else if (unit == "angstrom") {
return value * nptool::angstrom;
}
else if (unit == "fermi") {
return value * nptool::fermi;
}
else if (unit == "barn") {
return value * nptool::barn;
}
else if (unit == "millibarn") {
return value * nptool::millibarn;
}
else if (unit == "microbarn") {
return value * nptool::microbarn;
}
else if (unit == "nanobarn") {
return value * nptool::nanobarn;
}
else if (unit == "picobarn") {
return value * nptool::picobarn;
}
else if (unit == "mm") {
return value * nptool::mm;
}
else if (unit == "um") {
return value * nptool::um;
}
else if (unit == "nm") {
return value * nptool::nm;
}
else if (unit == "mm2") {
return value * nptool::mm2;
}
else if (unit == "mm3") {
return value * nptool::mm3;
}
else if (unit == "cm") {
return value * nptool::cm;
}
else if (unit == "cm2") {
return value * nptool::cm2;
}
else if (unit == "cm3") {
return value * nptool::cm3;
}
else if (unit == "m") {
return value * nptool::m;
}
else if (unit == "m2") {
return value * nptool::m2;
}
else if (unit == "m3") {
return value * nptool::m3;
}
else if (unit == "km") {
return value * nptool::km;
}
else if (unit == "km2") {
return value * nptool::km2;
}
else if (unit == "km3") {
return value * nptool::km3;
}
else if (unit == "pc") {
return value * nptool::pc;
}
else if (unit == "radian") {
return value * nptool::radian;
}
else if (unit == "milliradian") {
return value * nptool::milliradian;
}
else if (unit == "degree") {
return value * nptool::degree;
}
else if (unit == "steradian") {
return value * nptool::steradian;
}
else if (unit == "rad") {
return value * nptool::rad;
}
else if (unit == "mrad") {
return value * nptool::mrad;
}
else if (unit == "sr") {
return value * nptool::sr;
}
else if (unit == "deg") {
return value * nptool::deg;
}
else if (unit == "nanosecond") {
return value * nptool::nanosecond;
}
else if (unit == "second") {
return value * nptool::second;
}
else if (unit == "millisecond") {
return value * nptool::millisecond;
}
else if (unit == "microsecond") {
return value * nptool::microsecond;
}
else if (unit == "picosecond") {
return value * nptool::picosecond;
}
else if (unit == "hertz") {
return value * nptool::hertz;
}
else if (unit == "kilohertz") {
return value * nptool::kilohertz;
}
else if (unit == "megahertz") {
return value * nptool::megahertz;
}
else if (unit == "ns") {
return value * nptool::ns;
}
else if (unit == "us") {
return value * nptool::us;
}
else if (unit == "ms") {
return value * nptool::ms;
}
else if (unit == "eplus") {
return value * nptool::eplus;
}
else if (unit == "e_SI") {
return value * nptool::e_SI;
}
else if (unit == "coulomb") {
return value * nptool::coulomb;
}
else if (unit == "megaelectron") {
return value * nptool::megaelectronvolt;
}
else if (unit == "electronvolt") {
return value * nptool::electronvolt;
}
else if (unit == "kiloelectron") {
return value * nptool::kiloelectronvolt;
}
else if (unit == "gigaelectron") {
return value * nptool::gigaelectronvolt;
}
else if (unit == "teraelectron") {
return value * nptool::teraelectronvolt;
}
else if (unit == "petaelectron") {
return value * nptool::petaelectronvolt;
}
else if (unit == "joule") {
return value * nptool::joule;
}
else if (unit == "MeV") {
return value * nptool::MeV;
}
else if (unit == "eV") {
return value * nptool::eV;
}
else if (unit == "keV") {
return value * nptool::keV;
}
else if (unit == "GeV") {
return value * nptool::GeV;
}
else if (unit == "TeV") {
return value * nptool::TeV;
}
else if (unit == "PeV") {
return value * nptool::PeV;
}
else if (unit == "kilogram") {
return value * nptool::kilogram;
}
else if (unit == "gram") {
return value * nptool::gram;
}
else if (unit == "milligram") {
return value * nptool::milligram;
}
else if (unit == "kg") {
return value * nptool::kg;
}
else if (unit == "g") {
return value * nptool::g;
}
else if (unit == "mg") {
return value * nptool::mg;
}
else if (unit == "watt") {
return value * nptool::watt;
}
else if (unit == "newton") {
return value * nptool::newton;
}
else if (unit == "hep_pascal") {
return value * nptool::hep_pascal;
}
else if (unit == "bar") {
return value * nptool::bar;
}
else if (unit == "atmosphere") {
return value * nptool::atmosphere;
}
else if (unit == "ampere") {
return value * nptool::ampere;
}
else if (unit == "milliampere") {
return value * nptool::milliampere;
}
else if (unit == "microampere") {
return value * nptool::microampere;
}
else if (unit == "nanoampere") {
return value * nptool::nanoampere;
}
else if (unit == "megavolt") {
return value * nptool::megavolt;
}
else if (unit == "kilovolt") {
return value * nptool::kilovolt;
}
else if (unit == "volt") {
return value * nptool::volt;
}
else if (unit == "ohm") {
return value * nptool::ohm;
}
else if (unit == "farad") {
return value * nptool::farad;
}
else if (unit == "millifarad") {
return value * nptool::millifarad;
}
else if (unit == "microfarad") {
return value * nptool::microfarad;
}
else if (unit == "nanofarad") {
return value * nptool::nanofarad;
}
else if (unit == "picofarad") {
return value * nptool::picofarad;
}
else if (unit == "weber") {
return value * nptool::weber;
}
else if (unit == "tesla" || unit == "T") {
return value * nptool::tesla;
}
else if (unit == "gauss") {
return value * nptool::gauss;
}
else if (unit == "kilogauss") {
return value * nptool::kilogauss;
}
else if (unit == "henry") {
return value * nptool::henry;
}
else if (unit == "kelvin") {
return value * nptool::kelvin;
}
else if (unit == "mole") {
return value * nptool::mole;
}
else if (unit == "becquerel") {
return value * nptool::becquerel;
}
else if (unit == "curie") {
return value * nptool::curie;
}
else if (unit == "gray") {
return value * nptool::gray;
}
else if (unit == "kilogray") {
return value * nptool::kilogray;
}
else if (unit == "milligray") {
return value * nptool::milligray;
}
else if (unit == "microgray") {
return value * nptool::microgray;
}
else if (unit == "candela") {
return value * nptool::candela;
}
else if (unit == "lumen") {
return value * nptool::lumen;
}
else if (unit == "lux") {
return value * nptool::lux;
}
else if (unit == "perCent") {
return value * nptool::perCent;
}
else if (unit == "perThousand") {
return value * nptool::perThousand;
}
else if (unit == "perMillion") {
return value * nptool::perMillion;
}
else {
std::cout << "WARNING: Unknown unit " << unit << std::endl;
return value;
}
}