Commit b2e7eee1 authored by kraus's avatar kraus

revert changes from makeUpperCaseString to makeString otherwise the user...

revert changes from makeUpperCaseString to makeString otherwise the user always has to use upper case in order for Opal to find the string constants
parent 9b626590
......@@ -20,6 +20,7 @@
#include "Parser/Statement.h"
#include "Utilities/OpalException.h"
#include <boost/algorithm/string/join.hpp>
// Class AttributeHandler
// ------------------------------------------------------------------------
......@@ -94,6 +95,17 @@ void AttributeHandler::setReadOnly(bool flag) {
is_readonly = flag;
}
void AttributeHandler::setPredefinedValues(const std::set<std::string>& predefinedValues,
const std::string& defaultValue)
{
std::string validValues = " Valid values are " + boost::algorithm::join(predefinedValues, ", ") + ".";
if (defaultValue != "_HAS_NO_DEFAULT_") {
validValues += " Its default is " + defaultValue + ".";
}
std::string* help = const_cast<std::string*>(&itsHelp);
*help += validValues;
}
std::multimap<AttributeHandler::OwnerType, std::string> AttributeHandler::getOwner(const std::string &att) {
std::multimap<OwnerType, std::string> possibleOwners;
......
......@@ -23,6 +23,7 @@
#include "MemoryManagement/Pointer.h"
#include <string>
#include <map>
#include <set>
class Attribute;
class Statement;
......@@ -111,6 +112,9 @@ public:
// then [b]OpalException[/b] is thrown.
void setReadOnly(bool);
/// Add predefined strings values to the help
void setPredefinedValues(const std::set<std::string>&, const std::string&);
enum OwnerType {
ELEMENT,
COMMAND,
......
......@@ -207,7 +207,7 @@ namespace Expressions {
// When no string is seen, a ParseError is thrown with the message
// given as the second argument.
extern std::string parseString(Statement &, const char msg[]);
extern std::string parseStringValue(Statement &, const char msg[]);
// ARRAY EXPRESSION PARSERS.
......@@ -392,4 +392,4 @@ namespace Expressions {
// ======================================================================
};
#endif // OPAL_Expressions_HH
#endif // OPAL_Expressions_HH
\ No newline at end of file
......@@ -368,23 +368,18 @@ void MultiBunchHandler::setMode(const std::string& mbmode) {
<< " the limitation. The control parameter is set to "
<< coeffDBunches_m << endl;
mode_m = MB_MODE::AUTO;
} else
throw OpalException("MultiBunchHandler::setMode()",
"MBMODE name \"" + mbmode + "\" unknown.");
}
}
void MultiBunchHandler::setBinning(std::string binning) {
if ( binning.compare("BUNCH") == 0 ) {
*gmsg << "Use 'BUNCH' injection for binnning." << endl;
if ( binning.compare("BUNCH_BINNING") == 0 ) {
*gmsg << "Use 'BUNCH_BINNING' injection for binnning." << endl;
binning_m = MB_BINNING::BUNCH;
} else if ( binning.compare("GAMMA") == 0 ) {
*gmsg << "Use 'GAMMA' for binning." << endl;
} else if ( binning.compare("GAMMA_BINNING") == 0 ) {
*gmsg << "Use 'GAMMA_BINNING' for binning." << endl;
binning_m = MB_BINNING::GAMMA;
} else {
throw OpalException("MultiBunchHandler::setBinning()",
"MB_BINNING name \"" + binning + "\" unknown.");
}
}
......@@ -564,4 +559,4 @@ void MultiBunchHandler::updatePathLength(const std::vector<double>& lpaths) {
for (short b = 0; b < bunchCount_m; ++b) {
binfo_m[b].pathlength += lpaths[b];
}
}
}
\ No newline at end of file
......@@ -161,8 +161,7 @@ ParallelCyclotronTracker::ParallelCyclotronTracker(const Beamline &beamline,
stepper_m = stepper::INTEGRATOR::LF2;
} else if ( timeIntegrator == 2) {
stepper_m = stepper::INTEGRATOR::MTS;
} else
stepper_m = stepper::INTEGRATOR::UNDEFINED;
}
}
/**
......@@ -1220,11 +1219,6 @@ void ParallelCyclotronTracker::execute() {
std::placeholders::_4);
switch ( stepper_m ) {
case stepper::INTEGRATOR::RK4: {
*gmsg << "* 4th order Runge-Kutta integrator" << endl;
itsStepper_mp.reset(new RK4<function_t>(func));
break;
}
case stepper::INTEGRATOR::LF2: {
*gmsg << "* 2nd order Leap-Frog integrator" << endl;
itsStepper_mp.reset(new LF2<function_t>(func));
......@@ -1234,11 +1228,11 @@ void ParallelCyclotronTracker::execute() {
*gmsg << "* Multiple time stepping (MTS) integrator" << endl;
break;
}
case stepper::INTEGRATOR::UNDEFINED: {
default:
itsStepper_mp.reset(nullptr);
throw OpalException("ParallelCyclotronTracker::execute",
"Invalid name of TIMEINTEGRATOR in Track command");
case stepper::INTEGRATOR::RK4:
default: {
*gmsg << "* 4th order Runge-Kutta integrator" << endl;
itsStepper_mp.reset(new RK4<function_t>(func));
break;
}
}
......@@ -3515,4 +3509,4 @@ void ParallelCyclotronTracker::initPathLength() {
// we need to reset the path length of each bunch
itsDataSink->setMultiBunchInitialPathLengh(mbHandler_m.get());
}
}
}
\ No newline at end of file
......@@ -25,8 +25,9 @@
#include "Attributes/Real.h"
#include "Attributes/RealArray.h"
#include "Attributes/Reference.h"
#include "Attributes/opalstr.h"
#include "Attributes/String.h"
#include "Attributes/StringArray.h"
#include "Attributes/PredefinedString.h"
#include "Attributes/UpperCaseString.h"
#include "Attributes/UpperCaseStringArray.h"
#include "Attributes/TableRow.h"
......@@ -344,7 +345,8 @@ namespace Attributes {
AttributeBase *base = &attr.getBase();
std::string expr;
if(dynamic_cast<String *>(&attr.getHandler())
|| dynamic_cast<UpperCaseString *>(&attr.getHandler())) {
|| dynamic_cast<UpperCaseString *>(&attr.getHandler())
|| dynamic_cast<PredefinedString *>(&attr.getHandler())) {
expr = dynamic_cast<SValue<std::string> *>(base)->evaluate();
} else if(SValue<SRefAttr<std::string> > *ref =
dynamic_cast<SValue<SRefAttr<std::string> > *>(base)) {
......@@ -401,6 +403,42 @@ namespace Attributes {
}
// ----------------------------------------------------------------------
// Predefined string value.
Attribute makePredefinedString(const std::string &name,
const std::string &help,
const std::initializer_list<std::string>& predefinedStrings) {
return Attribute(new PredefinedString(name, help, predefinedStrings), nullptr);
}
Attribute
makePredefinedString(const std::string &name,
const std::string &help,
const std::initializer_list<std::string>& predefinedStrings,
const std::string &initial) {
return Attribute(new PredefinedString(name, help, predefinedStrings, initial),
new SValue<std::string>(Util::toUpper(initial)));
}
void setPredefinedString(Attribute &attr, const std::string &val) {
SValue<SRefAttr<std::string> > *ref;
std::string upperCaseVal = Util::toUpper(val);
if(dynamic_cast<const PredefinedString *>(&attr.getHandler())) {
attr.set(new SValue<std::string>(upperCaseVal));
} else if((attr.isBaseAllocated() == true) &&
(ref = dynamic_cast<SValue<SRefAttr<std::string> >*>(&attr.getBase()))) {
const SRefAttr<std::string> &value = ref->evaluate();
value.set(upperCaseVal);
} else {
throw OpalException("Attributes::setPredefinedString()", "Attribute \"" +
attr.getName() + "\" is not a supported string.");
}
}
// ----------------------------------------------------------------------
// Upper case string value.
......
......@@ -23,6 +23,7 @@
#include <list>
#include <string>
#include <vector>
#include <initializer_list>
class PlaceRep;
class RangeRep;
......@@ -139,6 +140,23 @@ namespace Attributes {
/// Set string value.
extern void setString(Attribute &attr, const std::string &val);
/// Make predefined string attribute.
// Initial value undefined.
extern Attribute makePredefinedString(const std::string &name,
const std::string &help,
const std::initializer_list<std::string>& predefinedStrings);
/// Make predefined string attribute.
// Initial value is defined.
extern Attribute
makePredefinedString(const std::string &name,
const std::string &help,
const std::initializer_list<std::string>& predefinedStrings,
const std::string &initial);
/// Set predefined string value.
extern void setPredefinedString(Attribute &attr, const std::string &val);
/// Make uppercase string attribute.
// Initial value undefined.
extern Attribute makeUpperCaseString(const std::string &name, const std::string &help);
......
......@@ -3,11 +3,12 @@ set (_SRCS
Bool.cpp
BoolArray.cpp
Place.cpp
PredefinedString.cpp
Range.cpp
Real.cpp
RealArray.cpp
Reference.cpp
opalstr.cpp
String.cpp
StringArray.cpp
TableRow.cpp
TokenList.cpp
......@@ -26,12 +27,13 @@ set (HDRS
Attributes.h
BoolArray.h
Bool.h
opalstr.h
Place.h
PredefinedString.h
Range.h
RealArray.h
Real.h
Reference.h
String.h
StringArray.h
TableRow.h
TokenListArray.h
......@@ -40,4 +42,4 @@ set (HDRS
UpperCaseStringArray.h
)
install (FILES ${HDRS} DESTINATION "${CMAKE_INSTALL_PREFIX}/include/Attributes")
install (FILES ${HDRS} DESTINATION "${CMAKE_INSTALL_PREFIX}/include/Attributes")
\ No newline at end of file
//
// Class PredefinedString
// This class is used to parse attributes of type string that should
// be contained in set of predefined strings.
//
// Copyright (c) 2021, Christof Metzger-Kraus, Open Sourcerer
// All rights reserved
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#include "Attributes/Attributes.h"
#include "Attributes/PredefinedString.h"
#include "AbstractObjects/Expressions.h"
#include "Utilities/ParseError.h"
#include "Utilities/Util.h"
using namespace Expressions;
namespace Attributes {
PredefinedString::PredefinedString(const std::string &name,
const std::string &help,
const std::initializer_list<std::string>& predefinedStrings,
const std::string& defaultValue):
AttributeHandler(name, help, 0)
{
for (const std::string& value: predefinedStrings) {
predefinedStrings_m.insert(Util::toUpper(value));
}
setPredefinedValues(predefinedStrings_m, defaultValue);
}
PredefinedString::~PredefinedString()
{}
const std::string &PredefinedString::getType() const {
static const std::string type("predefined string");
return type;
}
void PredefinedString::parse(Attribute &attr, Statement &stat, bool) const {
std::string value = Util::toUpper(parseStringValue(stat, "String value expected"));
if (predefinedStrings_m.count(value) == 0) {
throw ParseError("PredefinedString::parse", "Unsupported value '" + value + "'");
}
Attributes::setPredefinedString(attr, value);
}
};
\ No newline at end of file
//
// Class PredefinedString
// This class is used to parse attributes of type string that should
// be contained in set of predefined strings.
//
// Copyright (c) 2021, Christof Metzger-Kraus, Open Sourcerer
// All rights reserved
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#ifndef OPAL_PredefinedString_HH
#define OPAL_PredefinedString_HH
#include "AbstractObjects/Attribute.h"
#include "AbstractObjects/AttributeHandler.h"
#include <set>
namespace Attributes {
/// Parser for an attribute of type string.
class PredefinedString: public AttributeHandler {
public:
/// Constructor.
// Assign attribute name and help string.
PredefinedString(const std::string& name,
const std::string& help,
const std::initializer_list<std::string>& predefinedStrings,
const std::string& defaultValue = "_HAS_NO_DEFAULT_");
virtual ~PredefinedString();
/// Return attribute type string ``string''.
virtual const std::string &getType() const;
/// Parse the attribute.
virtual void parse(Attribute &, Statement &, bool) const;
private:
// Not implemented.
PredefinedString();
PredefinedString(const PredefinedString &);
void operator=(const PredefinedString &);
std::set<std::string> predefinedStrings_m;
};
};
#endif
\ No newline at end of file
......@@ -16,7 +16,7 @@
//
// ------------------------------------------------------------------------
#include "Attributes/opalstr.h"
#include "Attributes/String.h"
#include "AbstractObjects/Expressions.h"
#include "Expressions/SValue.h"
#include "Utilities/OpalException.h"
......@@ -46,7 +46,9 @@ namespace Attributes {
void String::parse(Attribute &attr, Statement &stat, bool) const {
attr.set(new SValue<std::string>(parseString(stat, "String value expected.")));
std::string result = parseStringValue(stat, "String value expected.");
attr.set(new SValue<std::string>(result));
}
};
};
\ No newline at end of file
......@@ -65,7 +65,7 @@ namespace Attributes {
}
array[index - 1] =
Expressions::parseString(statement, "String value expected.");
Expressions::parseStringValue(statement, "String value expected.");
Attributes::setStringArray(attr, array);
}
......
......@@ -44,7 +44,7 @@ namespace Attributes {
}
void UpperCaseString::parse(Attribute &attr, Statement &stat, bool) const {
Attributes::setUpperCaseString(attr, parseString(stat, "String value expected."));
Attributes::setUpperCaseString(attr, parseStringValue(stat, "String value expected."));
}
};
\ No newline at end of file
......@@ -64,7 +64,7 @@ namespace Attributes {
}
array[index - 1] =
Expressions::parseString(statement, "String value expected.");
Expressions::parseStringValue(statement, "String value expected.");
Attributes::setUpperCaseStringArray(attr, array);
}
......
......@@ -47,8 +47,8 @@ DumpEMFields::DumpEMFields() :
itsAttr[FILE_NAME] = Attributes::makeString
("FILE_NAME", "Name of the file to which field data is dumped");
itsAttr[COORDINATE_SYSTEM] = Attributes::makeUpperCaseString
("COORDINATE_SYSTEM", "Choose to use CARTESIAN (default) or CYLINDRICAL coordinates", "CARTESIAN");
itsAttr[COORDINATE_SYSTEM] = Attributes::makePredefinedString
("COORDINATE_SYSTEM", "Choose to use CARTESIAN or CYLINDRICAL coordinates", {"CARTESIAN", "CYLINDRICAL"}, "CARTESIAN");
itsAttr[X_START] = Attributes::makeReal
("X_START", "(Cartesian) Start point in the grid in x [m]");
......@@ -136,10 +136,6 @@ void DumpEMFields::parseCoordinateSystem() {
coordinates_m = CoordinateSystem::CYLINDRICAL;
} else if (coordStr == "CARTESIAN") {
coordinates_m = CoordinateSystem::CARTESIAN;
} else {
throw OpalException("DumpEMFields::parseCoordinateSystem",
"Failed to parse '" + coordStr +
"'. OPAL expected either CYLINDRICAL or CARTESIAN.");
}
}
......@@ -153,9 +149,9 @@ void DumpEMFields::execute() {
}
void DumpEMFields::buildGrid() {
std::vector<double> spacing(4);
std::vector<double> origin(4);
std::vector<int> gridSize(4);
std::vector<double> spacing(4);
std::vector<double> origin(4);
std::vector<int> gridSize(4);
parseCoordinateSystem();
if (coordinates_m == CoordinateSystem::CYLINDRICAL) {
......@@ -262,7 +258,7 @@ void DumpEMFields::writeFieldLine(Component* field,
Vector_t B(0., 0., 0.);
Vector_t point = pointIn;
if (coordinates_m == CoordinateSystem::CYLINDRICAL) {
// pointIn is r, phi, z
// pointIn is r, phi, z
point[0] = std::cos(pointIn[1])*pointIn[0];
point[1] = std::sin(pointIn[1])*pointIn[0];
}
......@@ -366,4 +362,4 @@ void DumpEMFields::print(std::ostream& os) const {
<< "* DT = " << Attributes::getReal(itsAttr[DT]) << " [ns]\n"
<< "* T_STEPS = " << Attributes::getReal(itsAttr[T_STEPS]) << '\n';
os << "* ********************************************************************************** " << std::endl;
}
}
\ No newline at end of file
......@@ -149,14 +149,14 @@ Option::Option():
"REMOTEPARTDEL times of the beam rms size, "
"its default values is 0 (no delete) ",remotePartDel);
itsAttr[PSDUMPFRAME] = Attributes::makeUpperCaseString
itsAttr[PSDUMPFRAME] = Attributes::makePredefinedString
("PSDUMPFRAME", "Controls the frame of phase space dump in "
"stat file and h5 file. If 'GLOBAL' OPAL will dump in the "
"lab (global) Cartesian frame; if 'BUNCH_MEAN' OPAL will "
"dump in the local Cartesian frame of the beam mean; "
"if 'REFERENCE' OPAL will dump in the local Cartesian "
"frame of the reference particle 0. Only available for "
"OPAL-cycl, its default value is 'GLOBAL'");
"stat file and h5 file. If 'GLOBAL' OPAL will dump in the "
"lab (global) Cartesian frame; if 'BUNCH_MEAN' OPAL will "
"dump in the local Cartesian frame of the beam mean; "
"if 'REFERENCE' OPAL will dump in the local Cartesian "
"frame of the reference particle 0. Only available for "
"OPAL-cycl.", {"BUNCH_MEAN", "REFERENCE", "GLOBAL"}, "GLOBAL");
itsAttr[SPTDUMPFREQ] = Attributes::makeReal
("SPTDUMPFREQ", "The frequency to dump single "
......@@ -203,9 +203,10 @@ Option::Option():
("CZERO", "If set to true a symmetric distribution is "
"created -> centroid == 0.0", cZero);
itsAttr[RNGTYPE] = Attributes::makeUpperCaseString
("RNGTYPE", "RANDOM (default), Quasi-random number "
"generators: HALTON, SOBOL, NIEDERREITER (Gsl ref manual 18.5)", rngtype);
itsAttr[RNGTYPE] = Attributes::makePredefinedString
("RNGTYPE", "Type of pseudo- or quasi-random number generator, "
"see also Quasi-Random Sequences, GSL reference manual.",
{"RANDOM", "HALTON", "SOBOL", "NIEDERREITER"}, rngtype);
itsAttr[CLOTUNEONLY] = Attributes::makeBool
("CLOTUNEONLY", "If set to true stop after "
......@@ -292,7 +293,7 @@ Option::Option(const std::string& name, Option* parent):
Attributes::setReal(itsAttr[PSDUMPFREQ], psDumpFreq);
Attributes::setReal(itsAttr[STATDUMPFREQ], statDumpFreq);
Attributes::setBool(itsAttr[PSDUMPEACHTURN], psDumpEachTurn);
Attributes::setUpperCaseString(itsAttr[PSDUMPFRAME], DumpFrameToString(psDumpFrame));
Attributes::setPredefinedString(itsAttr[PSDUMPFRAME], DumpFrameToString(psDumpFrame));
Attributes::setReal(itsAttr[SPTDUMPFREQ], sptDumpFreq);
Attributes::setReal(itsAttr[SCSOLVEFREQ], scSolveFreq);
Attributes::setReal(itsAttr[MTSSUBSTEPS], mtsSubsteps);
......@@ -307,7 +308,7 @@ Option::Option(const std::string& name, Option* parent):
Attributes::setReal(itsAttr[AUTOPHASE], autoPhase);
Attributes::setBool(itsAttr[CZERO], cZero);
Attributes::setBool(itsAttr[CLOTUNEONLY], cloTuneOnly);
Attributes::setUpperCaseString(itsAttr[RNGTYPE], std::string(rngtype));
Attributes::setPredefinedString(itsAttr[RNGTYPE], std::string(rngtype));
Attributes::setReal(itsAttr[NUMBLOCKS], numBlocks);
Attributes::setReal(itsAttr[RECYCLEBLOCKS], recycleBlocks);
Attributes::setReal(itsAttr[NLHS], nLHS);
......@@ -504,11 +505,6 @@ void Option::handlePsDumpFrame(const std::string& dumpFrame) {
psDumpFrame = BUNCH_MEAN;
} else if (dumpFrame == "REFERENCE") {
psDumpFrame = REFERENCE;
} else {
std::string msg = std::string("Did not recognise PSDUMPFRAME '")+\
dumpFrame+std::string("'. It should be one of 'GLOBAL',")+\
std::string(" 'BUNCH_MEAN' or 'REFERENCE'");
throw OpalException("Option::handlePsDumpFrame", msg);
}
}
......@@ -528,4 +524,4 @@ void Option::update(const std::vector<Attribute>& othersAttributes) {
for (int i = 0; i < SIZE; ++ i) {
itsAttr[i] = othersAttributes[i];
}
}
}
\ No newline at end of file
......@@ -369,9 +369,6 @@ void Cyclotron::setBFieldType() {
fieldType_m = BFieldType::BANDRF;
} else if (typeName_m == std::string("SYNCHROCYCLOTRON")) {
fieldType_m = BFieldType::SYNCHRO;
} else {
throw GeneralClassicException("Cyclotron::setBFieldType",
"TYPE " + typeName_m + " field reading function of CYCLOTRON is not defined!");
}
}
......@@ -958,7 +955,7 @@ void Cyclotron::getFieldFromFile_Ring(const double& scaleFactor) {
BP.Bfact = scaleFactor;
f = std::fopen(fmapfn_m.c_str(), "r");
CHECK_CYC_FSCANF_EOF(std::fscanf(f, "%lf", &BP.rmin));
*gmsg << "* Minimal radius of measured field map: " << BP.rmin << " [mm]" << endl;
BP.rmin *= 0.001; // mm --> m
......@@ -1539,4 +1536,4 @@ void Cyclotron::getFieldFromFile_Synchrocyclotron(const double& scaleFactor) {
void Cyclotron::getDimensions(double& /*zBegin*/, double& /*zEnd*/) const
{ }
#undef CHECK_CYC_FSCANF_EOF
#undef CHECK_CYC_FSCANF_EOF
\ No newline at end of file
......@@ -159,7 +159,7 @@ std::string Vacuum::getResidualGasName() {
}
default: {
throw GeneralClassicException("Vacuum::getResidualGasName",
"Residual gas not found");
"Residual gas not set");
}
}
}
......@@ -409,4 +409,4 @@ void Vacuum::getPressureFromFile(const double& scaleFactor) {
std::fclose(f);
}
#undef CHECK_VAC_FSCANF_EOF
#undef CHECK_VAC_FSCANF_EOF
\ No newline at end of file
......@@ -22,8 +22,6 @@
#include "Parser/Token.h"
#include <iostream>
extern Inform *gmsg;
// Class Statement
// ------------------------------------------------------------------------
......@@ -229,4 +227,11 @@ void Statement::printWhere(Inform &msg, bool withToken) const {
} else {
msg << ":\n";
}
}
std::string Statement::str() const {
std::ostringstream str;
print(str);
return str.str();
}
\ No newline at end of file
......@@ -166,6 +166,7 @@ public:
// stream. If [b]withToken[/b] is true, print also the last token parsed.
virtual void printWhere(Inform &msg, bool withToken) const;
std::string str() const;
protected:
// Line number where statement begins.
......
......@@ -25,14 +25,13 @@
#include "Utilities/FormatError.h"
#include <cctype>
// Class StringStream
// ------------------------------------------------------------------------
StringStream::StringStream(const std::string &str):
TokenStream("expression"),
line(str + '\n'),
curr_char(0)
line_m(str + '\n'),
currentChar_m(0)
{}
......@@ -47,17 +46,17 @@ Token StringStream::readToken() {
}
while(true) {
if(curr_char >= line.length() || line[curr_char] == '\n') {
if(currentChar_m >= line_m.length() || line_m[currentChar_m] == '\n') {
return Token("string", 1, Token::IS_EOF, "EOF");
} else if(isspace(line[curr_char])) {
curr_char++;
} else if(isspace(line_m[currentChar_m])) {
currentChar_m++;
} else {
break;
}
}