Skip to content

barracuda.scans

Cumulative-prefix Bayes-factor scans for count and trajectory workflows. Adjacent sample sizes within a scenario/replicate share one simulated dataset and are not independent.

Cumulative sample-size Bayes-factor scans and sensitivity planning.

Each scan simulates one maximum-size dataset per scenario and replicate. A requested size N then fits frame.iloc[:N] from that same dataset. Consequently, sample sizes within a scenario/replicate are nested cumulative prefixes, not independently simulated datasets. Independent replicates are obtained with the replicates argument.

Attributes

COUNT_MODEL_KEYS module-attribute

COUNT_MODEL_KEYS: Final[tuple[str, ...]] = ('homo', 'z2p', 'dis2p', 'hetero3')

COUNT_SCENARIOS module-attribute

COUNT_SCENARIOS: Final[tuple[EventCountScenario, ...]] = (EventCountScenario('No1', 'No1: sigma_lambda=3, p_zero=0.2', 4.0, 3.0, 0.2, 'hetero3', 1), EventCountScenario('No2', 'No2: sigma_lambda=0, p_zero=0.2', 4.0, 0.0, 0.2, 'z2p', 2), EventCountScenario('No3', 'No3: sigma_lambda=3, p_zero=0', 4.0, 3.0, 0.0, 'dis2p', 3), EventCountScenario('No4', 'No4: sigma_lambda=0, p_zero=0', 4.0, 0.0, 0.0, 'homo', 4))

TRAJECTORY_MODEL_KEYS module-attribute

TRAJECTORY_MODEL_KEYS: Final[tuple[str, ...]] = tuple(trajectories.TRAJECTORY_MODEL_SPECS)

TRAJECTORY_SCENARIOS module-attribute

TRAJECTORY_SCENARIOS: Final[tuple[TrajectoryScenario, ...]] = (TrajectoryScenario('No1', 'No1: sigma_eta=1, beta=(0.8,-0.8)', 4.0, 2.0, 0.25, 1.0, 0.8, -0.8, 'heterogeneous_history_dependent', 1), TrajectoryScenario('No2', 'No2: sigma_eta=1, beta=(0,0)', 4.0, 2.0, 0.25, 1.0, 0.0, 0.0, 'heterogeneous_history_independent', 2), TrajectoryScenario('No3', 'No3: sigma_eta=0, beta=(0.8,-0.8)', 4.0, 2.0, 0.25, 0.0, 0.8, -0.8, 'homogeneous_history_dependent', 3), TrajectoryScenario('No4', 'No4: sigma_eta=0, beta=(0,0)', 4.0, 2.0, 0.25, 0.0, 0.0, 0.0, 'homogeneous_history_independent', 4))

ScanProgressCallback module-attribute

ScanProgressCallback = Callable[[int, int, str], None]

LOG_10 module-attribute

LOG_10: Final[float] = float(np.log(10.0))

_SCAN_COLUMNS module-attribute

_SCAN_COLUMNS: Final[list[str]] = ['workflow', 'scenario', 'scenario_label', 'replicate', 'simulation_seed', 'inference_seed', 'n_cells', 'model_key', 'true_model', 'best_model', 'log_evidence', 'log_bf_model_vs_true', 'log10_bf_model_vs_true', 'log_bf_model_vs_best', 'log10_bf_model_vs_best', 'is_best']

simulate_event_count_data module-attribute

simulate_event_count_data = event_counts.simulate_event_counts

fit_event_count_models module-attribute

fit_event_count_models = event_counts.run_count_models

simulate_trajectory_data module-attribute

simulate_trajectory_data = trajectories.simulate_trajectory_frame

fit_trajectory_models module-attribute

fit_trajectory_models = trajectories.run_trajectory_conditions

__all__ module-attribute

__all__ = ['ScanProgressCallback', 'fit_event_count_models', 'fit_trajectory_models', 'plan_count_ground_truth_grid', 'run_count_bf_scan', 'run_trajectory_bf_scan', 'simulate_event_count_data', 'simulate_trajectory_data', 'summarize_bf_scan', 'validate_bf_scan_schema']

Classes

EventCountScenario dataclass

EventCountScenario(scenario: str, label: str, mu_lambda: float, sigma_lambda: float, p_zero: float, true_model: str, seed_offset: int = 0)

Typed ground truth for one canonical event-count experiment.

TrajectoryScenario dataclass

TrajectoryScenario(scenario: str, label: str, mu_lambda: float, sigma_lambda: float, p0: float, sigma_eta: float, beta_f: float, beta_s: float, true_model: str, seed_offset: int = 0)

Typed ground truth for one canonical contact-trajectory experiment.

Attributes

mu_eta property
mu_eta: float

Logit-scale population killing propensity implied by p0.

Functions:

stable_seed

stable_seed(*parts: Any, namespace: str = 'barracuda') -> int

Derive a reproducible non-zero uint32 seed from structured values.

Unlike Python's built-in hash, this value is stable across processes. Mappings are JSON encoded with sorted keys, so their insertion order does not affect the seed.

_finite

_finite(value: Any, name: str) -> float

_positive_int

_positive_int(value: Any, name: str) -> int

_base_seed

_base_seed(value: Any) -> int

_sample_sizes

_sample_sizes(values: Sequence[int]) -> tuple[int, ...]

_models

_models(values: Sequence[str] | str | None, available: Sequence[str]) -> tuple[str, ...]

_scenarios

_scenarios(values: Sequence[Any], expected_type: type) -> tuple[Any, ...]

_log_evidence

_log_evidence(results: Mapping[str, Any], model_keys: Sequence[str]) -> dict[str, float]

_comparison_rows

_comparison_rows(values: Mapping[str, float], *, true_model: str, metadata: Mapping[str, Any]) -> list[dict[str, Any]]

run_count_bf_scan

run_count_bf_scan(sample_sizes: Sequence[int], *, scenarios: Sequence[EventCountScenario] = COUNT_SCENARIOS, replicates: int = 1, observation_time: float = 1.0, base_seed: int = 2026, settings: InferenceSettings | None = None, model_keys: Sequence[str] | str | None = COUNT_MODEL_KEYS, progress_callback: ScanProgressCallback | None = None) -> DataFrame

Run the event-count models over nested cumulative sample-size prefixes.

One dataset with max(sample_sizes) cells is simulated for each scenario and replicate. Every smaller fit receives full_frame.iloc[:N]. The output is long form with one row per fitted model. In columns named log_bf_model_vs_*, positive values favour model_key over the model named after vs.

run_trajectory_bf_scan

run_trajectory_bf_scan(sample_sizes: Sequence[int], *, scenarios: Sequence[TrajectoryScenario] = TRAJECTORY_SCENARIOS, replicates: int = 1, observation_time: float = 1.0, base_seed: int = 2026, settings: TrajectorySettings | None = None, model_keys: Sequence[str] | str | None = TRAJECTORY_MODEL_KEYS, progress_callback: ScanProgressCallback | None = None) -> DataFrame

Run trajectory models over nested cumulative sample-size prefixes.

One maximum-size trajectory frame is generated for each scenario and replicate. Fits at smaller sample sizes use its first N cells, so the evidence trajectory reflects accumulating data rather than resimulation. Positive log_bf_model_vs_* values favour model_key.

_number_slug

_number_slug(value: float) -> str

_float_values

_float_values(values: Sequence[float], name: str) -> list[float]

plan_count_ground_truth_grid

plan_count_ground_truth_grid(*, mu_lambda: float = 4.0, baseline_sigma_lambda: float = 3.0, baseline_p_zero: float = 0.2, sigma_lambda_values: Sequence[float] = (0.0, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0), p_zero_values: Sequence[float] = (0.0, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5), reference_model: str = 'hetero3') -> DataFrame

Plan the canonical one-at-a-time count ground-truth sensitivity grid.

sigma_lambda varies while p_zero stays at its baseline, and p_zero varies while sigma_lambda stays at its baseline. The shared baseline is emitted once with membership in both slices; this is not a Cartesian product. Model identifiers are lowercase canonical keys.

validate_bf_scan_schema

validate_bf_scan_schema(frame: DataFrame, *, workflow: str | None = None, require_true_model: bool = True, require_consistent_models: bool = True) -> DataFrame

Validate and return a copy of a standardized long-form BF scan.

Direction is checked numerically: log_bf_model_vs_true must equal the row model's log evidence minus the true model's log evidence, and the analogous best-model columns must use the same numerator convention. By default, every replicate and sample-size fit for a scenario must contain the same candidate-model set.

summarize_bf_scan

summarize_bf_scan(frame: DataFrame, *, interval: tuple[float, float] = (0.025, 0.975)) -> DataFrame

Summarize replicate-wise evidence trajectories by scenario, N, and model.