Running rules

Worlds and runs: one world per seed, every rule on the same radio samples.

handoverlab.simulate

Running handover rules on simulated worlds.

run_world runs any number of rules on one world and on the same radio samples (common random numbers): each radio chunk goes to the engines of all rules before the next chunk is made. simulate does this for a list of seeds.

RunResult dataclass

Metrics of one rule on one seed.

fingerprint is the SHA-256 of the canonical event log (see handoverlab.eventlog) and is always set; events holds the log itself only if it was requested. key is the registry key of the rule ("a3", "cho", ...), so that the run can be repeated. trace holds the procedure trace at event-log level "full" (see handoverlab.eventlog).

spec() -> Dict[str, Any]

Rule specification that recreates this rule ({"rule": key, "name": ..., **params}).

row() -> Dict[str, Any]

Flat dictionary for a CSV row: seed, rule, parameters (prefixed param.) and metrics.

run_world(world: World, rules: Sequence[RuleSpec], log_events: Union[bool, str] = False, chunk_steps: int = 1000, debug: Optional[bool] = None, batch: bool = True, progress: Optional[Callable[[float], None]] = None) -> List[RunResult]

Run every rule of rules on world with identical radio samples.

log_events is the event-log level: "off" (or False), "summary" (or True: RunResult.events) or "full" (also RunResult.trace). progress is called after every radio chunk with the share of the run simulated so far (0 to 1).

debug turns on the invariant checks of the engine (see handoverlab.engine.invariants); results are the same either way. With batch (the default) the engines of all rules share one step loop (EngineBatch); results are bit-identical to running them one by one (batch=False), only faster. Engines in debug mode always run one by one.

simulate(scenario: Scenario, rules: Sequence[RuleSpec], seeds: Iterable[int] = (1,), log_events: Union[bool, str] = False, progress: Optional[Callable[[str], None]] = None, debug: Optional[bool] = None) -> List[RunResult]

Build one world per seed and run all rules on it.

rules are rule objects or specifications such as {"rule": "a3", "off_db": 3.0, "ttt_s": 0.16}.

run_experiment(exp: Experiment, log_events: Union[bool, str] = False, progress: Optional[Callable[[str], None]] = None, debug: Optional[bool] = None) -> List[RunResult]

Run an Experiment (scenario, seeds and rules).

handoverlab.world

A simulated world: everything that a scenario and a seed fix.

The world (layout, radio map, trajectories, services, background load) is built once per seed. Every handover rule compared on that seed runs on the same world and on the same radio samples, so differences between rules come only from their decisions.

World dataclass

n_cells: int property

Number of cells: one per site, or the cells of the extended radio model.

cell_sites: np.ndarray property

(M, 2) positions of the cells' sites [m].

nominal_cell property

Nominal best server at points (the operator's plan, see RadioMap).

cell_center(t: float) -> np.ndarray

(M, 2) reference locations of the cells at time t [m]: the sites, or the moving beam centres (NTN).

build_world(scenario: Scenario, seed: int) -> World

Layout, radio map, trajectories, services and background load of one seed.