parameter_info - Documenting algorithm parameters¶
When evaluating algorithm performance, it is crucial to keep track of the parameterization used for each run. Otherwise, when looking at a growing set of results for different parameterization of the algorithm, it can be very hard to find out what the actual differences were, and maybe even to reproduce a good result I got earlier on before trying out a gazillion of other parameterizations.
For for information, please see https://www.fme.lan/x/TYMBAg.
parameter_info¶
- class parameter_info.parameter_info.ParameterInfo(dict=None, /, **kwargs)[source]¶
Bases:
UserDict
Currently just a dict.
- clear() None. Remove all items from D. ¶
- get(k[, d]) D[k] if k in D, else d. d defaults to None. ¶
- items() a set-like object providing a view on D's items ¶
- keys() a set-like object providing a view on D's keys ¶
- pop(k[, d]) v, remove specified key and return the corresponding value. ¶
If key is not found, d is returned if given, otherwise KeyError is raised.
- popitem() (k, v), remove and return some (key, value) pair ¶
as a 2-tuple; but raise KeyError if D is empty.
- setdefault(k[, d]) D.get(k,d), also set D[k]=d if k not in D ¶
- update([E, ]**F) None. Update D from mapping/iterable E and F. ¶
If E present and has a .keys() method, does: for k in E: D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v
- values() an object providing a view on D's values ¶
indirect_info¶
- class parameter_info.indirect_info.IndirectParameterInfo(information_source)[source]¶
Bases:
ParameterInfo
Extension of ParameterInfo which is basically an adapter for data retrieved from a user-defined information source. As writing to a remote source usually makes no sense, any attempts to write items will result in an AssignmentOnReadOnlyKeyError.
NOTE: Mixed dictionaries containing both queries and elemental values that may also be written could be supported, but that would make this class more complex, so it will not be done without a concrete use case.
- exception AssignmentOnReadOnlyKeyError[source]¶
Bases:
RuntimeError
Raised if value assignment is tried on a read-only key.
- add_note()¶
Exception.add_note(note) – add a note to the exception
- with_traceback()¶
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
- to_dict()[source]¶
DEPRECATED: Deprecated, use parameter_info.utils.to_dict() instead.
- Returns:
pure dict
- register_key(key, source_key=None, default=None)[source]¶
Adds a source query for the given source_key into the dict under the given key (overwriting any pre-existing entry for that key).
- Parameters:
key – External key, use to access data in self
source_key – Key relayed to self._information_source. If None, the external key is also used internally.
default – Default value to assign if the key is not supported (and no exception is raised by self._information_source)
- Returns:
None
- register_keys(keys=None)[source]¶
Adds given keys without values to the dictionary, overwriting any pre-existing keys of the same name. If keys is a dictionary, it is interpreted as a mapping of external keys (those to be used with self) and internal keys (those to be interpreted by self._information_source). See register_key() for further info.
- Parameters:
keys – Keys to be supported (must be supported by information source at time of read access). If None is given, all keys declared as supported by self._information_source are registered.
- Returns:
None
- copy()[source]¶
Unlike the other methods below, this one will actually copy references to the queries
- clear() None. Remove all items from D. ¶
- keys() a set-like object providing a view on D's keys ¶
- pop(k[, d]) v, remove specified key and return the corresponding value. ¶
If key is not found, d is returned if given, otherwise KeyError is raised.
- popitem() (k, v), remove and return some (key, value) pair ¶
as a 2-tuple; but raise KeyError if D is empty.
- update([E, ]**F) None. Update D from mapping/iterable E and F. ¶
If E present and has a .keys() method, does: for k in E: D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v
- class parameter_info.indirect_info.InformationSource(source_key_failure_handler=<function raise_InformationSourceKeyError>, **source_query_data)[source]¶
Bases:
object
Wrapper for some information source for indirect/lazy data retrieval. Once set up, new query objects can be created with create_query( source_key[, default] ). The query returned can be executed via (), resulting in actual value computation via _get_from_source.
- create_query(source_key=None, default=None)[source]¶
Returns a query object for the given source_key using the currently set query_class and source data.
- Parameters:
source_key – Key to query the source for (once executed).
default – If key_failure_handler does not raise an exception, this is the value returned when the query is executed, but the key does not exist at that time.
- Returns:
Object of type query_class encapsulating all information to retrieve the data when executed.
- get_supported_keys()[source]¶
Should return a comprehensive list of all supported keys. As it may not be possible to know all supported keys in advance (i.e. before requesting them from the actual source), there is no guarantee to the caller to receive ALL supported keys. However, all returned keys MUST be supported.
- Returns:
Tuple with all (known) supported keys.
- classmethod get_from_source(source_key, default=None, key_failure_handler=<function raise_InformationSourceKeyError>, **source_query_data)[source]¶
Queries a value from the information source. Is also used by the query objects. If self._get_from_source() is not successful, the key_failure_handler will be called with the received InformationSourceKeyError. If this does not raise an exception, default is returned.
- Parameters:
source_key – Key to query from source
default – Value to return if source_key is not found (and no exception is raised by key_failure_handler)
key_failure_handler – What to do with the InformationSourceKeyError thrown by _get_from_source on key not found.
source_query_data – Additional arguments the source may need.
- Returns:
Queried value for source_key
- Raises:
cls.InformationSourceValueRetrievalError if key was valid, but value could not be computed, or whatever exception key_failure_handler raises on key error.
- exception InformationSourceKeyError[source]¶
Bases:
RuntimeError
Raised if a key could not be retrieved by the information source.
- add_note()¶
Exception.add_note(note) – add a note to the exception
- with_traceback()¶
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
- exception InformationSourceValueRetrievalError(source_key, **source_query_data)[source]¶
Bases:
RuntimeError
Raised if a value could not be retrieved from the information source, although the key was valid
- add_note()¶
Exception.add_note(note) – add a note to the exception
- with_traceback()¶
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
cached_info¶
- class parameter_info.cached_info.CachedParameterInfo(default_information_source_query)[source]¶
Bases:
IndirectParameterInfo
Extension of IndirectParameterInfo providing a cache for data retrieved from a user-defined information source.
- clear_cached_values()[source]¶
Clears all cached values, forcing to update from source on next request. Works recursively, as long as the child CachedParameterInfo is a direct child.
- Returns:
None
- update_cache_from_source()[source]¶
Refreshes (overwrites) all (possibly cached) values with those from the information source. Works recursively, as long as the child CachedParameterInfo is a direct child.
- Returns:
None
- exception AssignmentOnReadOnlyKeyError¶
Bases:
RuntimeError
Raised if value assignment is tried on a read-only key.
- add_note()¶
Exception.add_note(note) – add a note to the exception
- with_traceback()¶
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
- clear() None. Remove all items from D. ¶
- copy()¶
Unlike the other methods below, this one will actually copy references to the queries
- get(k[, d]) D[k] if k in D, else d. d defaults to None. ¶
- items() a set-like object providing a view on D's items ¶
- keys() a set-like object providing a view on D's keys ¶
- pop(k[, d]) v, remove specified key and return the corresponding value. ¶
If key is not found, d is returned if given, otherwise KeyError is raised.
- popitem() (k, v), remove and return some (key, value) pair ¶
as a 2-tuple; but raise KeyError if D is empty.
- register_key(key, source_key=None, default=None)¶
Adds a source query for the given source_key into the dict under the given key (overwriting any pre-existing entry for that key).
- Parameters:
key – External key, use to access data in self
source_key – Key relayed to self._information_source. If None, the external key is also used internally.
default – Default value to assign if the key is not supported (and no exception is raised by self._information_source)
- Returns:
None
- register_keys(keys=None)¶
Adds given keys without values to the dictionary, overwriting any pre-existing keys of the same name. If keys is a dictionary, it is interpreted as a mapping of external keys (those to be used with self) and internal keys (those to be interpreted by self._information_source). See register_key() for further info.
- Parameters:
keys – Keys to be supported (must be supported by information source at time of read access). If None is given, all keys declared as supported by self._information_source are registered.
- Returns:
None
- setdefault(k[, d]) D.get(k,d), also set D[k]=d if k not in D ¶
- to_dict()¶
DEPRECATED: Deprecated, use parameter_info.utils.to_dict() instead.
- Returns:
pure dict
- update([E, ]**F) None. Update D from mapping/iterable E and F. ¶
If E present and has a .keys() method, does: for k in E: D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v
- values() an object providing a view on D's values ¶
- class parameter_info.cached_info.CachedInformationSource(source_key_failure_handler=<function raise_InformationSourceKeyError>, **source_query_data)[source]¶
Bases:
InformationSource
Convenience class, just exchanging the query_class with one supporting caching.
- exception InformationSourceKeyError¶
Bases:
RuntimeError
Raised if a key could not be retrieved by the information source.
- add_note()¶
Exception.add_note(note) – add a note to the exception
- with_traceback()¶
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
- exception InformationSourceValueRetrievalError(source_key, **source_query_data)¶
Bases:
RuntimeError
Raised if a value could not be retrieved from the information source, although the key was valid
- add_note()¶
Exception.add_note(note) – add a note to the exception
- with_traceback()¶
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
- create_query(source_key=None, default=None)¶
Returns a query object for the given source_key using the currently set query_class and source data.
- Parameters:
source_key – Key to query the source for (once executed).
default – If key_failure_handler does not raise an exception, this is the value returned when the query is executed, but the key does not exist at that time.
- Returns:
Object of type query_class encapsulating all information to retrieve the data when executed.
- classmethod get_from_source(source_key, default=None, key_failure_handler=<function raise_InformationSourceKeyError>, **source_query_data)¶
Queries a value from the information source. Is also used by the query objects. If self._get_from_source() is not successful, the key_failure_handler will be called with the received InformationSourceKeyError. If this does not raise an exception, default is returned.
- Parameters:
source_key – Key to query from source
default – Value to return if source_key is not found (and no exception is raised by key_failure_handler)
key_failure_handler – What to do with the InformationSourceKeyError thrown by _get_from_source on key not found.
source_query_data – Additional arguments the source may need.
- Returns:
Queried value for source_key
- Raises:
cls.InformationSourceValueRetrievalError if key was valid, but value could not be computed, or whatever exception key_failure_handler raises on key error.
- get_supported_keys()¶
Should return a comprehensive list of all supported keys. As it may not be possible to know all supported keys in advance (i.e. before requesting them from the actual source), there is no guarantee to the caller to receive ALL supported keys. However, all returned keys MUST be supported.
- Returns:
Tuple with all (known) supported keys.
network_info¶
- class parameter_info.network_info.MlabNetworkInfoSource(context, field_not_found_error_handler=<function raise_InformationSourceKeyError>, **source_query_data)[source]¶
Bases:
InformationSource
Can query a MeVisLab network for field values. Do not inherit CachedInformationSourceQ since it currently does not support automatic cache invalidation on (field) value change. Also, it is usually not necessary, as field value computation is cheap.
- exception InformationSourceKeyError¶
Bases:
RuntimeError
Raised if a key could not be retrieved by the information source.
- add_note()¶
Exception.add_note(note) – add a note to the exception
- with_traceback()¶
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
- exception InformationSourceValueRetrievalError(source_key, **source_query_data)¶
Bases:
RuntimeError
Raised if a value could not be retrieved from the information source, although the key was valid
- add_note()¶
Exception.add_note(note) – add a note to the exception
- with_traceback()¶
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
- create_query(source_key=None, default=None)¶
Returns a query object for the given source_key using the currently set query_class and source data.
- Parameters:
source_key – Key to query the source for (once executed).
default – If key_failure_handler does not raise an exception, this is the value returned when the query is executed, but the key does not exist at that time.
- Returns:
Object of type query_class encapsulating all information to retrieve the data when executed.
- classmethod get_from_source(source_key, default=None, key_failure_handler=<function raise_InformationSourceKeyError>, **source_query_data)¶
Queries a value from the information source. Is also used by the query objects. If self._get_from_source() is not successful, the key_failure_handler will be called with the received InformationSourceKeyError. If this does not raise an exception, default is returned.
- Parameters:
source_key – Key to query from source
default – Value to return if source_key is not found (and no exception is raised by key_failure_handler)
key_failure_handler – What to do with the InformationSourceKeyError thrown by _get_from_source on key not found.
source_query_data – Additional arguments the source may need.
- Returns:
Queried value for source_key
- Raises:
cls.InformationSourceValueRetrievalError if key was valid, but value could not be computed, or whatever exception key_failure_handler raises on key error.
- get_supported_keys()¶
Should return a comprehensive list of all supported keys. As it may not be possible to know all supported keys in advance (i.e. before requesting them from the actual source), there is no guarantee to the caller to receive ALL supported keys. However, all returned keys MUST be supported.
- Returns:
Tuple with all (known) supported keys.
- parameter_info.network_info.createMlabNetworkInfo(context, field_not_found_error_handler=<function raise_InformationSourceKeyError>)[source]¶
Convenience method to create an IndirectParameterInfo (non-cached, as caching does not make sense for field values) from the provided network context wrapped by a MlabNetworkInfoSource object.
- Parameters:
context – Network context to look for the keys (=field names) in.
field_not_found_error_handler – Executed on query execution if the field does not exist in the contect.
utils¶
- parameter_info.utils.dump_dict(d, msg_prefix=' ')[source]¶
Just for nicer debug printing
- Parameters:
d – Dictionary to print
msg_prefix – Additional message prefix
- Returns:
None
- parameter_info.utils.to_ParameterInfo(kv)[source]¶
Recursively converts given key value store kv (possibly a dict) into a new “ParameterInfo” object.
- Returns:
ParameterInfo with the same keys and values as the given source dictionary
- parameter_info.utils.to_dict(kv)[source]¶
Recursively converts given key value store kv (possibly a ParameterInfo object) into an “ordinary” dict. Use especially if kv contains nodes with keys with indirect value access to replace those with the actual values.
- Returns:
Pure dict with “scalar” (non-query) values
- parameter_info.utils.to_flat_dict(kv, general_prefix='', group_prefix='', group_postfix='.', omitEmptyDictionaries=False)[source]¶
Returns a flattened (i.e. depth 1) version of the given dictionary, combining keys so that the descend path is clear. Example:
to_flat_dict( { "a":1, "b": { "x":10, "y":{ "z": 20 }}, c:{} ) -> { "a":1, "b.x": 10, "b.y.z": 20 "c": {} }
Note that the empty dictionary c would be omitted if omitEmptyDictionaries were set to False.
- Parameters:
kv – Dictionary to flatten
general_prefix – Prefix for each key of the resulting dict
group_prefix – Prefix for each group’s key in combined keys
group_postfix – Postfix for each group’s key in combined keys
omitEmptyDictionaries – If set to True, an entry with an empty dictionary does not show up in the flat version
- Returns:
Flat dict containing the composed keys and their values
- parameter_info.utils.to_flat_ordered_dict(kv, general_prefix='', group_prefix='', group_postfix='.')[source]¶
Like to_flat_dict, but returning an OrderedDict sorted by keys
- Parameters:
kv – Dictionary to flatten
general_prefix – Prefix for each key of the resulting dict
group_prefix – Prefix for each group’s key in combined keys
group_postfix – Postfix for each group’s key in combined keys
- Returns:
OrderedDict containing the composed keys in alphabetical order (and their values)
- parameter_info.utils.to_ordered_dict(kv)[source]¶
Convenience method to convert a dictionary to an OrderedDict sorted by key, but without recursing into dictionary children.
- Parameters:
kv – Source dictionary
- Returns:
Ordered dictionary
- parameter_info.utils.get_ordered_copy(kv)[source]¶
Convenience method to convert any kind of dictionary (could also be a ParameterInfo) into an ordered copy of itself sorted by key, with recursing into the dictionary’s children
- Parameters:
kv – Source dictionary
- Returns:
Copied dictionary
- class parameter_info.utils.SelectiveNoIndentEncoder(*args, **kwargs)[source]¶
Bases:
JSONEncoder
Replacement for the default JSONEncoder that will prevent indentation for values wrapped in a SelectiveNoIndentEncoder.NoIndent object. Note that using a NoIndent on a composed object, none of the children in its subtree will be indented (additional NoIndent objects there will be tolerated). Adapted from https://stackoverflow.com/a/25935321/5226368 NOTE: Only works correctly with json.dumps, not json.dump! In the latter case, it will have no effect.
- class NoIndent(value)[source]¶
Bases:
object
Use this class to wrap values that you want to exclude from indentation.
- default(o)[source]¶
Implement this method in a subclass such that it returns a serializable object for
o
, or calls the base implementation (to raise aTypeError
).For example, to support arbitrary iterators, you could implement default like this:
def default(self, o): try: iterable = iter(o) except TypeError: pass else: return list(iterable) # Let the base class default method raise the TypeError return super().default(o)
- encode(o)[source]¶
Return a JSON string representation of a Python data structure.
>>> from json.encoder import JSONEncoder >>> JSONEncoder().encode({"foo": ["bar", "baz"]}) '{"foo": ["bar", "baz"]}'
- iterencode(o, _one_shot=False)¶
Encode the given object and yield each string representation as available.
For example:
for chunk in JSONEncoder().iterencode(bigobject): mysocket.write(chunk)
- class parameter_info.utils.IndentOnlyNestedSequencesJsonEncoder(*args, **kwargs)[source]¶
Bases:
SelectiveNoIndentEncoder
Replacement for the default JSONEncoder that will write non-nested lists, tuples or sets in a single line even with indent > 0. NOTE: Only works correctly with json.dumps, not json.dump! In the latter case, it will have no effect.
- class MarkElementarySequences[source]¶
Bases:
TypeCleaner
Modifies the TypeCleaner to mark all non-nested sequences by encapsulating them in the NoIndent wrapper.
- classmethod get_json_compatible_copy(value, key='', raiseOnError=False)[source]¶
Creates a copy of the provided data structure, which may be any composition of elementary and container types. Will convert known types that are not supported by Json.dumps() into something that is.
- Parameters:
value – Value to copy (elementary or container)
key – Optional key identifier used only for error logging (simplifies finding unexpected datatypes in a container)
raiseOnError – If enabled, a TypeError is raised for each conversion error. Otherwise, only an info message is printed, and the unconvertible value is put out as a string with a _unsupported_type_<typename> postfix.
- Returns:
(hopefully) json compatible copy of the provided data structure
- encode(o)[source]¶
Return a JSON string representation of a Python data structure.
>>> from json.encoder import JSONEncoder >>> JSONEncoder().encode({"foo": ["bar", "baz"]}) '{"foo": ["bar", "baz"]}'
- class NoIndent(value)¶
Bases:
object
Use this class to wrap values that you want to exclude from indentation.
- default(o)¶
Implement this method in a subclass such that it returns a serializable object for
o
, or calls the base implementation (to raise aTypeError
).For example, to support arbitrary iterators, you could implement default like this:
def default(self, o): try: iterable = iter(o) except TypeError: pass else: return list(iterable) # Let the base class default method raise the TypeError return super().default(o)
- iterencode(o, _one_shot=False)¶
Encode the given object and yield each string representation as available.
For example:
for chunk in JSONEncoder().iterencode(bigobject): mysocket.write(chunk)