hooks Module
Domain-Specific Language for simulation hooks.
Overview
The hooks subpackage provides the core components for the declarative hook system.
Complete Module Reference
natal.hooks
Hook subsystem public API.
CompiledEventHooks
Per-event hook container used by lifecycle wrappers.
Holds one combined callable per event (first / early /
late / finish) plus a registry (HookProgram) for
CSR dispatch. This is a pure container — code generation and
lifecycle wrapper compilation live in
natal.engine.lifecycle_wrappers.
Slots
first / early / late / finish
Combined hook callables for each event.
registry
HookProgram — may be filtered for mixed events.
Initialise all event hooks to no-op and registry to None.
Source code in src/natal/hooks/compile/container.py
get_hook
set_hook
Set the combined callable for event_name (both dict and attr).
Op
Factory helpers for building declarative operations.
The methods here only build data objects and do not touch population state.
Compilation happens later in compile_declarative_hook.
scale
staticmethod
scale(genotypes: Union[str, List[str], Literal['*']] = '*', ages: Union[int, List[int], range, Literal['*']] = '*', sex: Literal['female', 'male', 'both'] = 'both', factor: float = 1.0, when: Optional[str] = None) -> HookOp
Create a scaling operation that multiplies counts by a factor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
genotypes
|
Union[str, List[str], Literal['*']]
|
Genotype selector ("*" for all, specific genotype, or list) |
'*'
|
ages
|
Union[int, List[int], range, Literal['*']]
|
Age selector ("*" for all, specific age, range, or list) |
'*'
|
sex
|
Literal['female', 'male', 'both']
|
Sex selector ("female", "male", or "both") |
'both'
|
factor
|
float
|
Scaling factor (e.g., 0.5 halves the count, 2.0 doubles it) |
1.0
|
when
|
Optional[str]
|
Optional condition expression (e.g., "tick >= 100") |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
HookOp |
HookOp
|
Operation descriptor for compilation |
Source code in src/natal/hooks/entry/declarative.py
set_count
staticmethod
set_count(genotypes: Union[str, List[str], Literal['*']] = '*', ages: Union[int, List[int], range, Literal['*']] = '*', sex: Literal['female', 'male', 'both'] = 'both', value: float = 0.0, when: Optional[str] = None) -> HookOp
Create an operation that sets counts to a specific value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
genotypes
|
Union[str, List[str], Literal['*']]
|
Genotype selector |
'*'
|
ages
|
Union[int, List[int], range, Literal['*']]
|
Age selector |
'*'
|
sex
|
Literal['female', 'male', 'both']
|
Sex selector |
'both'
|
value
|
float
|
Target count value (individuals will be added/removed to match) |
0.0
|
when
|
Optional[str]
|
Optional condition expression |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
HookOp |
HookOp
|
Operation descriptor for compilation |
Source code in src/natal/hooks/entry/declarative.py
add
staticmethod
add(genotypes: Union[str, List[str], Literal['*']] = '*', ages: Union[int, List[int], range, Literal['*']] = '*', sex: Literal['female', 'male', 'both'] = 'both', delta: float = 0.0, when: Optional[str] = None) -> HookOp
Create an operation that adds a fixed number of individuals.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
genotypes
|
Union[str, List[str], Literal['*']]
|
Genotype selector |
'*'
|
ages
|
Union[int, List[int], range, Literal['*']]
|
Age selector |
'*'
|
sex
|
Literal['female', 'male', 'both']
|
Sex selector |
'both'
|
delta
|
float
|
Number of individuals to add (can be negative to remove) |
0.0
|
when
|
Optional[str]
|
Optional condition expression |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
HookOp |
HookOp
|
Operation descriptor for compilation |
Source code in src/natal/hooks/entry/declarative.py
subtract
staticmethod
subtract(genotypes: Union[str, List[str], Literal['*']] = '*', ages: Union[int, List[int], range, Literal['*']] = '*', sex: Literal['female', 'male', 'both'] = 'both', delta: float = 0.0, when: Optional[str] = None) -> HookOp
Create an operation that subtracts a fixed number of individuals.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
genotypes
|
Union[str, List[str], Literal['*']]
|
Genotype selector |
'*'
|
ages
|
Union[int, List[int], range, Literal['*']]
|
Age selector |
'*'
|
sex
|
Literal['female', 'male', 'both']
|
Sex selector |
'both'
|
delta
|
float
|
Number of individuals to subtract |
0.0
|
when
|
Optional[str]
|
Optional condition expression |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
HookOp |
HookOp
|
Operation descriptor for compilation |
Source code in src/natal/hooks/entry/declarative.py
kill
staticmethod
kill(genotypes: Union[str, List[str], Literal['*']] = '*', ages: Union[int, List[int], range, Literal['*']] = '*', sex: Literal['female', 'male', 'both'] = 'both', prob: float = 0.0, when: Optional[str] = None) -> HookOp
Create a probabilistic killing operation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
genotypes
|
Union[str, List[str], Literal['*']]
|
Genotype selector |
'*'
|
ages
|
Union[int, List[int], range, Literal['*']]
|
Age selector |
'*'
|
sex
|
Literal['female', 'male', 'both']
|
Sex selector |
'both'
|
prob
|
float
|
Probability of killing each selected individual (0.0 to 1.0) |
0.0
|
when
|
Optional[str]
|
Optional condition expression |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
HookOp |
HookOp
|
Operation descriptor for compilation |
Raises:
| Type | Description |
|---|---|
ValueError
|
If probability is not in [0, 1] |
Source code in src/natal/hooks/entry/declarative.py
sample
staticmethod
sample(genotypes: Union[str, List[str], Literal['*']] = '*', ages: Union[int, List[int], range, Literal['*']] = '*', sex: Literal['female', 'male', 'both'] = 'both', size: int = 0, when: Optional[str] = None) -> HookOp
Create a sampling operation that selects individuals without replacement.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
genotypes
|
Union[str, List[str], Literal['*']]
|
Genotype selector |
'*'
|
ages
|
Union[int, List[int], range, Literal['*']]
|
Age selector |
'*'
|
sex
|
Literal['female', 'male', 'both']
|
Sex selector |
'both'
|
size
|
int
|
Number of individuals to sample |
0
|
when
|
Optional[str]
|
Optional condition expression |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
HookOp |
HookOp
|
Operation descriptor for compilation |
Source code in src/natal/hooks/entry/declarative.py
stop_if_zero
staticmethod
stop_if_zero(genotypes: Union[str, List[str], Literal['*']] = '*', ages: Union[int, List[int], range, Literal['*']] = '*', sex: Literal['female', 'male', 'both'] = 'both', when: Optional[str] = None) -> HookOp
Create an operation that stops the simulation if selected count reaches zero.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
genotypes
|
Union[str, List[str], Literal['*']]
|
Genotype selector |
'*'
|
ages
|
Union[int, List[int], range, Literal['*']]
|
Age selector |
'*'
|
sex
|
Literal['female', 'male', 'both']
|
Sex selector |
'both'
|
when
|
Optional[str]
|
Optional condition expression |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
HookOp |
HookOp
|
Operation descriptor for compilation |
Source code in src/natal/hooks/entry/declarative.py
stop_if_below
staticmethod
stop_if_below(genotypes: Union[str, List[str], Literal['*']] = '*', ages: Union[int, List[int], range, Literal['*']] = '*', sex: Literal['female', 'male', 'both'] = 'both', threshold: float = 1.0, when: Optional[str] = None) -> HookOp
Create an operation that stops the simulation if count falls below threshold.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
genotypes
|
Union[str, List[str], Literal['*']]
|
Genotype selector |
'*'
|
ages
|
Union[int, List[int], range, Literal['*']]
|
Age selector |
'*'
|
sex
|
Literal['female', 'male', 'both']
|
Sex selector |
'both'
|
threshold
|
float
|
Minimum count threshold |
1.0
|
when
|
Optional[str]
|
Optional condition expression |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
HookOp |
HookOp
|
Operation descriptor for compilation |
Source code in src/natal/hooks/entry/declarative.py
stop_if_above
staticmethod
stop_if_above(genotypes: Union[str, List[str], Literal['*']] = '*', ages: Union[int, List[int], range, Literal['*']] = '*', sex: Literal['female', 'male', 'both'] = 'both', threshold: float = 1000000.0, when: Optional[str] = None) -> HookOp
Create an operation that stops the simulation if count exceeds threshold.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
genotypes
|
Union[str, List[str], Literal['*']]
|
Genotype selector |
'*'
|
ages
|
Union[int, List[int], range, Literal['*']]
|
Age selector |
'*'
|
sex
|
Literal['female', 'male', 'both']
|
Sex selector |
'both'
|
threshold
|
float
|
Maximum count threshold |
1000000.0
|
when
|
Optional[str]
|
Optional condition expression |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
HookOp |
HookOp
|
Operation descriptor for compilation |
Source code in src/natal/hooks/entry/declarative.py
stop_if_extinction
staticmethod
Create an operation that stops the simulation if total population goes extinct.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
when
|
Optional[str]
|
Optional condition expression |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
HookOp |
HookOp
|
Operation descriptor for compilation |
Source code in src/natal/hooks/entry/declarative.py
HookExecutor
Python-layer coordinator for hook execution (Numba-disabled only).
When Numba is disabled, all hook types — CSR plans, njit functions, Python wrappers — must run through a single sequential path. This class holds descriptors sorted by priority and dispatches each one in order.
Initialise with a pre-built registry and descriptor map.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
registry
|
HookProgram
|
HookProgram for CSR operations (may be empty). |
required |
hooks_by_event
|
Dict[int, List[CompiledHookDescriptor]]
|
Descriptors grouped by event_id and sorted
by priority. Built by |
required |
Source code in src/natal/hooks/runtime/fallback.py
from_compiled_hooks
staticmethod
from_compiled_hooks(registry: HookProgram, compiled_hooks: List[CompiledHookDescriptor]) -> HookExecutor
Group descriptors by event_id and sort by priority.
Descriptors without a recognised event_id or without any execution payload are silently skipped.
Source code in src/natal/hooks/runtime/fallback.py
execute_event
Run all hooks for event_id in priority order.
For each descriptor, in priority order:
- CSR plan — unpacks arrays and calls
execute_csr_event_arrayswith a single-hook wrapper. Aborts onRESULT_STOP. - njit function — calls
desc.njit_fn(state, config, deme_id). - Python wrapper — calls with population (1-param) or
(state, config, deme_id)(3-param). Only allowed when Numba is disabled.
Returns:
| Type | Description |
|---|---|
int
|
|
Source code in src/natal/hooks/runtime/fallback.py
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | |
get_hooks_for_event
CompiledHookDescriptor
dataclass
CompiledHookDescriptor(name: str, event: str, priority: int = 0, deme_selector: DemeSelector = '*', plan: Optional[CompiledHookPlan] = None, selectors: Dict[str, ndarray] = _empty_selector_map(), static_arrays: Tuple[ndarray, ...] = tuple(), meta: Dict[str, int] = _empty_meta_map(), njit_fn: Optional[Callable[..., object]] = None, py_wrapper: Optional[Callable[..., object]] = None, ops: Optional[List[HookOp]] = None)
Unified descriptor for all hook modes.
Exactly one of plan, njit_fn, or py_wrapper is typically used
as the primary execution payload for a descriptor.
CompiledHookPlan
dataclass
CompiledHookPlan(n_ops: int, op_types: ndarray, zidx_offsets: ndarray, zidx_data: ndarray, age_offsets: ndarray, age_data: ndarray, sex_masks: ndarray, params: ndarray, condition_offsets: ndarray, condition_types: ndarray, condition_params: ndarray)
Compiled declarative plan with CSR-style flattened arrays.
Variable-length fields (genotypes/ages/conditions) are represented via
*_offsets + *_data to keep kernel inputs contiguous and compact.
to_tuple
Convert this plan to a flat tuple for HDF5 / array storage.
Returns:
| Type | Description |
|---|---|
Tuple[object, ...]
|
A tuple of all fields in declaration order. |
Source code in src/natal/hooks/types.py
HookOp
dataclass
HookOp(op_type: OpType, genotypes: Union[str, List[str], Literal['*']] = '*', ages: Union[int, List[int], range, Literal['*']] = '*', sex: Literal['female', 'male', 'both'] = 'both', param: float = 1.0, condition: Optional[str] = None)
Single declarative operation before compilation.
Fields in this class can still be symbolic (for example genotype labels). The compiler resolves all symbolic fields into concrete integer arrays.
HookProgram
Bases: NamedTuple
Event-grouped plain-data CSR representation for declarative hooks.
OpType
Bases: IntEnum
Operation opcodes consumed by the runtime kernel.
We intentionally keep integer values stable because these values are
serialized into CompiledHookPlan.op_types and interpreted in the
executor hot-loop.
compile_combined_hook
compile_combined_hook(njit_fns: List[HookCallable], deme_selectors: Optional[List[DemeSelector]] = None) -> HookCallable
Combine multiple njit hooks into a single generated njit function.
Generates Python source for a new module containing a function that
calls each hook in sequence. Each call is wrapped with an optional
if deme_id == X guard for spatial simulations.
The source is written to .numba_cache/ so Numba's cache=True
survives process restarts — this is not possible with runtime-composed
closures.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
njit_fns
|
List[HookCallable]
|
Njit-compiled hook functions to call in order. |
required |
deme_selectors
|
Optional[List[DemeSelector]]
|
Per-function deme target. |
None
|
Returns:
| Type | Description |
|---|---|
HookCallable
|
An |
HookCallable
|
|
HookCallable
|
first non-zero result ( |
Source code in src/natal/hooks/compile/codegen.py
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | |
compile_declarative_hook
compile_declarative_hook(ops: List[HookOp], pop: BasePopulation[Any], event: str, priority: int = 0, deme_selector: DemeSelector = '*', name: str = 'declarative_hook') -> CompiledHookDescriptor
Compile declarative ops into a CompiledHookDescriptor.
The compiler packs all per-op fields into parallel arrays. Offsets arrays
(*_offsets) define CSR spans for variable-length selector/condition
data and avoid Python object usage in runtime engine.
Source code in src/natal/hooks/entry/declarative.py
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 | |
hook
hook(event: Optional[str] = None, selectors: Optional[Dict[str, Any]] = None, priority: int = 0, custom: bool = False, deme: DemeSelector = '*', mode: str = 'auto') -> Callable[[Callable[..., Any]], DecoratedHookFn]
Decorator for all supported hook authoring styles.
The decorated function gains a .register(pop) method that
compiles and registers a CompiledHookDescriptor against a
population instance.
Hook type auto-detection (evaluated at .register() time):
selectors=is set → Selector hook (compile_selector_hook)custom=Trueor function has required parameters → Custom hook (njit or Python wrapper)- Otherwise → Declarative hook (function returns
List[HookOp], compiled viacompile_declarative_hook)
For custom and selector hooks, Numba compilation is automatic — you
do not need to stack @njit. When Numba is enabled the
function is wrapped with njit_switch automatically; when Numba
is disabled a pure-Python wrapper is used.
In spatial simulations the deme_id parameter receives the current
deme index, enabling one hook function to serve all demes with
per-deme branching.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
Optional[str]
|
Hook event name ( |
None
|
selectors
|
Optional[Dict[str, Any]]
|
Symbolic selectors for selector-mode hooks. |
None
|
priority
|
int
|
Execution priority — lower values run first. |
0
|
custom
|
bool
|
If |
False
|
deme
|
DemeSelector
|
Target deme(s). |
'*'
|
mode
|
str
|
Selector passing style. |
'auto'
|
Returns:
| Type | Description |
|---|---|
Callable[[Callable[..., Any]], DecoratedHookFn]
|
A decorator that transforms a function into a |
Callable[[Callable[..., Any]], DecoratedHookFn]
|
with |
Raises:
| Type | Description |
|---|---|
ValueError
|
If mode is not one of |
Examples:
Declarative hook (returns ops):
@hook(event="early", priority=0)
def cull_juveniles():
return [Op.scale(ages=[0,1], factor=0.9)]
Custom njit hook:
@hook(event="first", priority=1)
def release_males(state, config, deme_id=-1):
state.individual_count[1, 2, 0] += 100
return 0
Selector hook:
@hook(event="late", selectors={"target": "AA"})
def count_homozygotes(state, config, target, deme_id=-1):
...
Source code in src/natal/hooks/entry/decorator.py
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 | |
compile_selector_hook
compile_selector_hook(func: Callable[..., Any], pop: BasePopulation[Any], event: str, selectors_spec: Dict[str, SelectorSpec], priority: int = 0, deme_selector: DemeSelector = '*', mode: str = 'auto') -> CompiledHookDescriptor
Compile selector hook into njit or python descriptor.
resolved stores canonical selector arrays and is reused by both
execution paths.
For selector hooks, Numba compilation depends on: - If function is @njit decorated, use it directly - Otherwise, use global NUMBA_ENABLED setting (auto-wrap if enabled)
Source code in src/natal/hooks/entry/selector.py
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | |
build_hook_program
Return program unchanged (forward-compat hook point).
Exists as a hook for potential schema upgrades or validation logic. Currently a no-op.
Source code in src/natal/hooks/runtime/csr_kernel.py
deme_selector_matches
Return whether deme_id should execute under selector (Python path).
Supported forms: "*" (wildcard), int (single deme), or
list / tuple / range (set of demes).
Source code in src/natal/hooks/runtime/csr_kernel.py
execute_csr_event_arrays
execute_csr_event_arrays(n_events: int | integer[Any], n_hooks: int | integer[Any], hook_offsets: ndarray, n_ops_list: ndarray, op_offsets: ndarray, op_types_data: ndarray, zidx_offsets_data: ndarray, zidx_data: ndarray, age_offsets_data: ndarray, age_data: ndarray, sex_masks_data: ndarray, params_data: ndarray, condition_offsets_data: ndarray, condition_types_data: ndarray, condition_params_data: ndarray, deme_selector_types: ndarray, deme_selector_offsets: ndarray, deme_selector_data: ndarray, event_id: int, individual_count: ndarray, sperm_storage: ndarray, has_sperm_storage: bool, tick: int, stochastic: bool, continuous_sampling: bool, deme_id: int) -> int
Execute all hooks for one event from flattened CSR arrays.
Resolves event_id to a hook range via hook_offsets, then calls
_execute_single_csr_hook for each hook. The function signature
mirrors HookProgram fields positionally so callers can unpack
the NamedTuple directly.
Three-level CSR traversal::
event_id → hook_offsets[event_id] → hook range
hook_idx → op_offsets[hook_idx] → op range
op_idx → zidx/age/cond offsets → cell range
Returns:
| Type | Description |
|---|---|
int
|
|
int
|
|
Source code in src/natal/hooks/runtime/csr_kernel.py
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 | |
execute_csr_event_program
execute_csr_event_program(program: HookProgram, event_id: int, individual_count: ndarray, tick: int) -> int
Execute one event with deterministic defaults and no sperm storage.
Convenience wrapper for quick tests or simple discrete-generation
setups. For production use, prefer execute_csr_event_program_with_state
which exposes the full state flags.
Source code in src/natal/hooks/runtime/csr_kernel.py
execute_csr_event_program_with_state
execute_csr_event_program_with_state(program: HookProgram, event_id: int, individual_count: ndarray, sperm_storage: ndarray, tick: int, stochastic: bool, has_sperm_storage: bool, continuous_sampling: bool, deme_id: int = 0) -> int
Execute one event from a HookProgram, unpacking all fields.
Primary adapter between the HookProgram NamedTuple and the flat-array
interface of execute_csr_event_arrays. Lifecycle templates call
this function directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
program
|
HookProgram
|
Compiled HookProgram containing all declarative ops. |
required |
event_id
|
int
|
Which event to execute (EVENT_FIRST=0, EVENT_EARLY=1, …). |
required |
individual_count
|
ndarray
|
3-D array |
required |
sperm_storage
|
ndarray
|
3-D array |
required |
tick
|
int
|
Current simulation tick (used for |
required |
stochastic
|
bool
|
Whether to use stochastic survival sampling. |
required |
has_sperm_storage
|
bool
|
Whether sperm_storage contains real data. |
required |
continuous_sampling
|
bool
|
Whether to use continuous-Dirichlet sampling. |
required |
deme_id
|
int
|
Deme index for spatial models (0 for panmictic). |
0
|
Returns:
| Type | Description |
|---|---|
int
|
|