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

# Copyright 2018 John Harwell, All rights reserved.
#
#  SPDX-License-Identifier: MIT
#
"""
Functionality for mapping arena size -> swarm size to maintain a constant ratio.
"""
# 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.engine.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. """ def __init__( self, cli_arg: str, main_config: types.YAMLDict, batch_input_root: pathlib.Path, target_density: float, dimensions: 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() def computable_exp_scenario_name(self) -> bool: return True
[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())]) )
[docs] def parse(arg: str) -> types.CLIArgSpec: """Enforces specification of a :class:`ConstantDensity` derived batch criteria. 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 spec = ".".join(sections[1:]) regex = r"(\d+)p(\d+)\.I(\d+)\.C(\d+)" res = re.match(regex, spec) assert len(res.groups()) == 4, f"Spec must match {regex}, have {spec}" # groups(0) is always the full matched string; subsequent groups are the # captured groups from the () expressions. characteristic = float(res.group(1)) mantissa = float("0." + res.group(2)) ret["target_density"] = characteristic + mantissa ret["arena_size_inc"] = int(res.group(3)) ret["cardinality"] = int(res.group(4)) return ret
__all__ = ["ConstantDensity", "parse"]