Skip to content

Commit

Permalink
ResourceMap: Add AddAsStringEnum service
Browse files Browse the repository at this point in the history
  • Loading branch information
jschueller committed Feb 10, 2025
1 parent 2f4a6b4 commit 94e1907
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 3 deletions.
30 changes: 29 additions & 1 deletion lib/src/Base/Common/ResourceMap.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "openturns/Path.hxx"
#include "openturns/Collection.hxx"
#include "openturns/XMLToolbox.hxx"

#ifdef OPENTURNS_HAVE_LIBXML2
#include <libxml/tree.h>
#endif
Expand Down Expand Up @@ -195,6 +196,11 @@ void ResourceMap::AddAsString(const String & key, const String & value)
GetInstance().lock().addAsString(key, value);
}

void ResourceMap::AddAsStringEnum(const String & key, const String & value, const std::vector<String> & enumValues)
{
GetInstance().lock().addAsStringEnum(key, value, enumValues);
}

void ResourceMap::AddAsBool(const String & key, const Bool value)
{
GetInstance().lock().addAsBool(key, value);
Expand Down Expand Up @@ -326,7 +332,11 @@ void ResourceMap::removeKey(const String & key)

const String keyType(getType(key));
if (keyType == "str")
{
mapString_.erase(mapString_.find(key));
if (mapStringEnum_.find(key) != mapStringEnum_.end())
mapStringEnum_.erase(mapStringEnum_.find(key));
}
else if (keyType == "float")
mapScalar_.erase(mapScalar_.find(key));
else if (keyType == "int")
Expand Down Expand Up @@ -453,6 +463,14 @@ void ResourceMap::setAsString(const String & key, const String & value)
const MapStringType::iterator it = mapString_.find(key);
if (it == mapString_.end())
throw InternalException(HERE) << "Key '" << key << "' is missing in ResourceMap as a String.";
const MapStringEnumType::iterator it2 = mapStringEnum_.find(key);
if (it2 != mapStringEnum_.end() && std::find(it2->second.begin(), it2->second.end(), value) == it2->second.end())
{
String possibleValues;
for (std::vector<String>::iterator it3 = it2->second.begin(); it3 != it2->second.end(); ++ it3)
possibleValues += *it3 + ", ";
throw InvalidArgumentException(HERE) << "Value for key '" << key << "' must be one of: " << possibleValues << " got '" << value << "'";
}
it->second = value;
}

Expand Down Expand Up @@ -487,6 +505,16 @@ void ResourceMap::addAsString(const String & key, const String & value)
mapString_[key] = value;
}

void ResourceMap::addAsStringEnum(const String & key, const String & value, const std::vector<String> & enumValues)
{
if (mapString_.find(key) != mapString_.end())
throw InternalException(HERE) << "Key '" << key << "' is already in ResourceMap as a String.";
mapString_[key] = value;
if (std::find(enumValues.begin(), enumValues.end(), value) == enumValues.end())
throw InternalException(HERE) << "Enum values do not contain value '" << value << "'";
mapStringEnum_[key] = enumValues;
}

void ResourceMap::addAsBool(const String & key, const Bool value)
{
if (mapBool_.find(key) != mapBool_.end())
Expand Down Expand Up @@ -718,7 +746,7 @@ void ResourceMap::loadDefaultConfiguration()
addAsUnsignedInteger("Contour-DefaultLevelsNumber", 10);
addAsBool("Contour-DefaultIsFilled", false);
addAsBool("Contour-DefaultDrawLabels", true);
addAsString("Contour-DefaultColorMapNorm", "linear");
addAsStringEnum("Contour-DefaultColorMapNorm", "linear", {"asinh", "linear", "log", "logit", "symlog", "rank"});
addAsString("Contour-DefaultColorMap", "viridis");
addAsString("Contour-DefaultColorBarPosition", "right");
addAsString("Contour-DefaultExtend", "both");
Expand Down
4 changes: 4 additions & 0 deletions lib/src/Base/Common/openturns/ResourceMap.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public:

/** Add a value in the maps */
static void AddAsString(const String & key, const String & value);
static void AddAsStringEnum(const String & key, const String & value, const std::vector<String> & enumValues);
static void AddAsBool(const String & key, const Bool value);
static void AddAsUnsignedInteger(const String & key, const UnsignedInteger value);
static void AddAsScalar(const String & key, const Scalar value);
Expand Down Expand Up @@ -220,6 +221,7 @@ protected:
* @param value The value written to a string
*/
void addAsString(const String & key, const String & value);
void addAsStringEnum(const String & key, const String & value, const std::vector<String> & enumValues);

/** Method for adding information into the resource map
* @param key The name under which the value is stored in the ResourceMap
Expand Down Expand Up @@ -280,11 +282,13 @@ private:
typedef std::map< String, Scalar > MapScalarType;
typedef std::map< String, UnsignedInteger > MapUnsignedIntegerType;
typedef std::map< String, Bool > MapBoolType;
typedef std::map< String, std::vector< String > > MapStringEnumType;

MapStringType mapString_;
MapScalarType mapScalar_;
MapUnsignedIntegerType mapUnsignedInteger_;
MapBoolType mapBool_;
MapStringEnumType mapStringEnum_;

friend struct ResourceMap_init;
}; /* class ResourceMap */
Expand Down
24 changes: 24 additions & 0 deletions python/src/ResourceMap_doc.i.in
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,30 @@ Examples

// ---------------------------------------------------------------------

%feature("docstring") OT::ResourceMap::AddAsStringEnum
"Add a new string enum parameter.

Similar to :meth:`AddAsString` except :meth:`SetAsString` calls will make sure the
value associated to that key is part of the list of possible supplied values.

Parameters
----------
key : str
An identifier associated to the parameter.
value : str
The value associated to that key. The key is added to the string map even if
it already exists in another map (float, int or bool).
enumValues : sequence of str
Possible values

Examples
--------
>>> import openturns as ot
>>> ot.ResourceMap.AddAsStringEnum('View-ImageFormat3', 'png', ['png', 'jpg', 'bmp'])
>>> ot.ResourceMap.RemoveKey('View-ImageFormat3')"

// ---------------------------------------------------------------------

%feature("docstring") OT::ResourceMap::GetAsString
"Access a string parameter.

Expand Down
5 changes: 3 additions & 2 deletions python/test/t_ResourceMap_missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
resourcemap_lines += f.read().splitlines()
resourcemap_content = {}
for line in resourcemap_lines:
match = re.search(r'addAs(\w+)\("([\w\-]+)",[ ]*([\w\d\.\-\"]+)\);', line)
match = re.search(r'addAs(\w+)\("([\w\-]+)",[ ]*([\w\d\.\-\"]+)[\),]', line)
if match is not None:
key, vtype, value = match.group(2), match.group(1), match.group(3)
print(key, vtype, value)
if key == "SymbolicParser-Backend":
continue
if vtype == "Scalar":
Expand All @@ -24,7 +25,7 @@
resourcemap_content[key] = int(value)
elif vtype == "Bool":
resourcemap_content[key] = {"true": True, "false": False}[value]
elif vtype == "String":
elif vtype.startswith("String"):
resourcemap_content[key] = value.strip('"')
else:
raise ValueError(f"got {key}")
Expand Down

0 comments on commit 94e1907

Please sign in to comment.