1#ifndef UTOPIA_CORE_SELECT_HH
2#define UTOPIA_CORE_SELECT_HH
6#include <unordered_set>
12#include <yaml-cpp/yaml.h>
13#include <spdlog/spdlog.h>
21#include "../data_io/cfg_utils.hh"
145 if (
m.second == mode) {
151 throw std::invalid_argument(
"The given entity selection mode is not "
152 "available! Are all SelectionMode values represented in the map?");
167 std::is_same_v<Cell<typename M::Entity::Traits>,
178 std::is_same_v<
Agent<
typename M::Entity::Traits,
222 throw std::invalid_argument(
"The given selection mode string ('"
223 +
mode_str +
"') is invalid! For available modes, consult the "
224 "EntitySelection group in the doxygen documentation.");
228 mngr.log()->debug(
"Selecting entities using mode '{}' ...",
mode_str);
248 std::vector<typename Manager::SpaceVec>
positions{};
252 "Could not select cells by positions!");
256 using SpaceVec =
typename Manager::SpaceVec;
257 using ET =
typename Manager::SpaceVec::elem_type;
259 const auto vec =
pos_node.as<std::array<ET, Manager::dim>>();
285 auto perm = std::pair<double, double>{0., 0.};
300 auto gate_width = std::pair<unsigned, unsigned>{0, 0};
339 throw std::invalid_argument(
"The selection mode '"
341 "manager type or via the configuration!");
358 class Condition = std::function<
bool(
const std::shared_ptr<typename Manager::Entity>&)>,
359 typename std::enable_if_t<mode == SelectionMode::condition, int> = 0
365 std::copy_if(
mngr.entities().begin(),
mngr.entities().end(),
385 typename std::enable_if_t<mode == SelectionMode::sample, int> = 0
393 throw std::invalid_argument(
"Argument num_entities need be in the "
394 "interval [0, entity container size]!");
401 std::sample(
mngr.entities().begin(),
mngr.entities().end(),
421 typename std::enable_if_t<mode == SelectionMode::probability, int> = 0
431 return mngr.entities();
434 throw std::invalid_argument(
"Entity selection in mode 'probability' "
435 "failed due to probability argument outside of interval [0., 1.]");
439 std::uniform_real_distribution<>
dist(0., 1.);
445 [&,
dist{std::move(
dist)}](
const auto&)
mutable {
467 typename std::enable_if_t<mode == SelectionMode::position, int> = 0
470 const std::vector<typename Manager::SpaceVec>&
positions)
490 typename std::enable_if_t<mode == SelectionMode::boundary, int> = 0
538 typename std::enable_if_t<mode == SelectionMode::lanes, int> = 0
544 const std::pair<double, double>
permeability = {0., 0.},
545 const std::pair<unsigned int, unsigned int>
gate_width = {0, 0}
548 static_assert(Manager::Space::dim == 2,
"Only 2D space is supported.");
549 using SpaceVec =
typename Manager::SpaceVec;
550 using MultiIndex =
typename Manager::MultiIndex;
553 const auto grid =
mngr.grid();
554 const MultiIndex shape = grid->shape();
555 const auto num_cells = grid->num_cells();
556 const SpaceVec extent = grid->space()->extent;
561 throw std::invalid_argument(
"Given number of vertical and/or "
562 "horizontal lanes is equal or larger to the number of cells along "
563 "that dimension! Choose a smaller value.");
568 throw std::invalid_argument(fmt::format(
569 "Permeability in horizontal lanes needs to be in interval "
574 throw std::invalid_argument(fmt::format(
575 "Permeability in vertical lanes needs to be in interval "
582 "Selecting cells for lanes ...\n"
583 " num: {} horizontal, \t{} vertical\n"
584 " permeability: {} horizontal, \t{} vertical\n"
585 " gate width: {} horizontal, \t{} vertical\n",
599 if (grid->is_periodic()) {
632 if (grid->is_periodic()) {
666 grid->midx_of(grid->cell_at(
proxy_pos))[0]
675 grid->midx_of(grid->cell_at(
proxy_pos))[1]
680 catch (std::invalid_argument&
exc) {
681 throw std::invalid_argument(fmt::format(
682 "Failed to determine gate cells for lane selection, presumably "
683 "because the gate width was chosen larger than the compartment "
684 "size. Check that the gate width (h: {:d}, v: {:d}) fits into the "
685 "compartment. Grid shape: ({:d} x {:d}, {}). "
686 "Number of lanes: (h: {:d}, v: {:d}).",
689 grid->is_periodic() ?
"periodic" :
"non-periodic",
699 std::uniform_real_distribution<>
dist(0., 1.);
752 mngr.log()->debug(
"Selected {:d} / {:d} cells using mode 'lanes'.",
778 typename std::enable_if_t<mode == SelectionMode::clustered_simple, int> = 0
786 throw std::invalid_argument(
"Argument p_attach needs to be a "
787 "probability, i.e. be in interval [0., 1.]!");
790 mngr.log()->debug(
"Selecting cell clusters ... (p_seed: {}, p_attach: {}, "
797 mngr.log()->debug(
"Selected {} clustering seeds.",
seeds.size());
811 std::uniform_real_distribution<>
dist(0., 1.);
832 mngr.log()->debug(
"Finished pass {}. Have {} cells selected now.",
838 mngr.entity_pointers_from_ids(
An agent is a slightly specialized state container.
Definition agent.hh:47
For access to a dict-like structure with a bad key.
Definition exceptions.hh:67
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition types.hh:71
std::string to_string(const Config &node)
Given a config node, returns a string representation of it.
Definition cfg_utils.hh:110
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition select.hh:213
std::string selection_mode_to_string(const SelectionMode &mode)
Given a SelectionMode enum value, return the corresponding string key.
Definition select.hh:143
SelectionMode
Possible selection modes; availability depends on choice of manager.
Definition select.hh:78
const std::map< std::string, SelectionMode > selection_mode_map
A map from strings to Select enum values.
Definition select.hh:124
@ lanes
(For CellManager only) Selects horizontal or vertical lanes of cells
@ condition
Select if a condition is fulfilled.
@ position
(For CellManager only) Selects cells at given positions in space
@ sample
Select a random sample of entities with a known sample size.
@ probability
Select an entity with a given probability.
@ boundary
(For CellManager only) Select the boundary cells of a grid
@ clustered_simple
Select entity clusters using a simple neighborhood-based algorithm.
std::vector< std::shared_ptr< EntityType > > EntityContainer
Type of the variably sized container for entities.
Definition types.hh:22
unsigned short DimType
Type for dimensions, i.e. very small unsigned integers.
Definition types.hh:34
std::size_t IndexType
Type for indices, i.e. values used for container indexing, agent IDs, ...
Definition types.hh:40
Metafunction to determine whether a Manager is an AgentManager.
Definition select.hh:176
static constexpr bool value
Definition select.hh:177
Metafunction to determine whether a Manager is a CellManager.
Definition select.hh:165
static constexpr bool value
Definition select.hh:166