Source code for sierra.plugins.platform.argos.variables.constant_density

# Copyright 2018 John Harwell, All rights reserved.
#
#  SPDX-License-Identifier: MIT
#

# Core packages
import re
import typing as tp
import pathlib

# 3rd party packages

# Project packages
from sierra.core.variables import batch_criteria as bc
from sierra.core.utils import ArenaExtent
from sierra.plugins.platform.argos.variables.arena_shape import ArenaShape
from sierra.core import types


[docs]class ConstantDensity(bc.UnivarBatchCriteria): """Defines common functionality for all constant-density classes. Constant density = SOMETHING/arena size is held constant as arena size is increased. This class is a base class which should NEVER be used on its own. Attributes: target_density: The target density. dimensions: List of (X,Y) dimensions to use (creates rectangular arenas). scenario_tag: A scenario tag (presumably part of `--scenario`) to use to generate scenario names. changes: List of sets of changes to apply to generate the specified arena sizes. """
[docs] def __init__(self, cli_arg: str, main_config: types.YAMLDict, batch_input_root: pathlib.Path, target_density: float, dimensions: tp.List[ArenaExtent], scenario_tag: str) -> None: bc.UnivarBatchCriteria.__init__(self, cli_arg, main_config, batch_input_root) self.target_density = target_density self.dimensions = dimensions self.scenario_tag = scenario_tag self.attr_changes = ArenaShape(dimensions).gen_attr_changelist()
[docs] def exp_scenario_name(self, exp_num: int) -> str: """Given the exp number in the batch, compute a parsable scenario name. It is necessary to query this criteria after generating the changelist in order to create generator classes for each experiment in the batch with the correct name and definition in some cases. Normally controller+scenario are used to look up all necessary changes for the specified arena size, but for this criteria the specified scenario is the base scenario (i.e., the starting arena dimensions), and the correct arena dimensions for a given exp must be found via lookup with THIS function). """ dims = self.dimensions[exp_num] return self.scenario_tag + '.' + 'x'.join([str(dims.xsize()), str(dims.ysize()), str(dims.zsize())])
class Parser(): """Enforces specification of a :class:`ConstantDensity` derived batch criteria. """ def __call__(self, arg: str) -> types.CLIArgSpec: """ Parse the cmdline argument. Returns: Dict: target_density: Floating point value of parsed target density arena_size_inc: Integer increment for arena size """ ret = {} sections = arg.split('.') # remove variable name, leaving only the spec sections = sections[1:] # Need to have 2 dot/3 parts assert len(sections) == 3, \ (f"Spec must have 3 sections separated by '.'; have " f"{len(sections)} sections from '{arg}'") # Parse density res = re.search('[0-9]+', sections[0]) assert res is not None, \ f"Bad density characteristic spec in section '{sections[0]}'" characteristic = float(res.group(0)) res = re.search('p[0-9]+', sections[0]) assert res is not None, \ f"Bad density mantissa spec in section '{sections[0]}'" mantissa = float("0." + res.group(0)[1:]) ret['target_density'] = characteristic + mantissa # Parse arena size increment res = re.search('I[0-9]+', sections[1]) assert res is not None, \ f"Bad arena increment spec in section '{sections[1]}'" ret['arena_size_inc'] = int(res.group(0)[1:]) # Parse cardinality res = re.search('C[0-9]+', sections[2]) assert res is not None, \ f"Bad cardinality spec in section '{sections[2]}'" ret['cardinality'] = int(res.group(0)[1:]) return ret __api__ = [ 'ConstantDensity' ]