Skip to content

Experimental-design and scalar-inference schema v1

The inference layer separates open observation metadata from the small set of relationships needed for valid resampling. It does not impose a neuroscience ontology: animal, fly, well, or organoid can all be declared units.

from fiberphotometry import Factor, ObservationTable, StudyDesign, Unit

observations = ObservationTable.from_columns(
    {
        "event_id": ["e1", "e2", "e3", "e4"],
        "animal": ["a", "a", "b", "b"],
        "condition": ["control", "drug", "control", "drug"],
        "outcome": [0.1, 0.4, -0.1, 0.3],
        "virus": ["GCaMP", "GCaMP", "GCaMP", "GCaMP"],
    }
)
design = StudyDesign(
    observation_id="event_id",
    units=(
        Unit("animal", "animal"),
        Unit("event", "event_id", nested_within="animal"),
    ),
    factors=(Factor("condition", "condition", "categorical", assignment_unit="event"),),
)

The undeclared virus column is preserved. Only metadata used in inference needs typed semantics. validate_design() checks unique observations, functional nesting, factor assignment levels, missing declarations, and severe imbalance before an inferential function runs.

StudyDesign serializes to versioned JSON. Version 1 supports strictly nested units and categorical or continuous factors. Crossed units, arbitrary formulas, and missing-data models are rejected or deferred rather than guessed.

Initial inference operations

For already-derived scalar or vector outcomes, PopulationUnitEstimate provides the common animal boundary. It retains the source sessions and observation count before a paired or independent population contrast is computed. Peri-event inference is the first end-to-end integration; other method families will adopt the contract without replacing their domain-specific denominators.

  • hierarchical_bootstrap recursively samples a declared unit path and retains distinct identities for duplicate sampled units.
  • permutation_test supports paired sign flips and label shuffling at an explicitly declared assignment unit, optionally within blocks.
  • Estimand currently represents a scalar, two-level difference of unit-level means. Unit-level aggregation prevents animals with more trials from silently receiving more population weight.

Both operations are experimental. Percentile, basic, and BCa intervals are available and must be selected explicitly; Monte Carlo permutation p-values and exact paired sign-flip tests are supported. Results retain the random seed and full sampled distribution. Paired inference rejects incomplete units instead of silently dropping them. No multiple-comparison correction or time-resolved simultaneous interval is implied. Calibration results are in benchmarks/results-v0.5.md.

unit_t_interval() provides Welch and paired-t comparators on aggregation-unit means. These encode stronger distributional assumptions than randomization inference but showed appropriate finite-sample Gaussian coverage in benchmarks/results-v0.7.md.

recommend_inference() is advisory and never executes a test. It uses declared assignment and aggregation levels but requires randomized=True, False, or None; it never infers randomization from balanced-looking data. Exact tests are recommended only when both the design claim and supported enumeration permit it.

create_analysis_plan() binds the estimand and recommendation into versioned JSON. Plans remain executable=False until every method-specific assumption is acknowledged. welch_power_sensitivity() reports a power range over supplied effect and animal-SD ranges, avoiding a single unqualified pilot plug-in value.

Missingness requires an estimand decision. The observed-data contrast describes available events; a complete-data contrast requires assumptions or a model for unobserved outcomes. The library does not relabel observed-data coverage as recovery of a complete-data effect.

An end-to-end public IBL example converts acquired-sample DMS feedback responses from four animals into 2,507 event observations. The declared animal→session→event hierarchy validates successfully while retaining the imbalanced 1,850 correct and 657 incorrect trials. The script does not claim that feedback is randomized or that this four-animal contrast supports population inference; it demonstrates the data/design boundary. See benchmarks/ibl-observation-table-v0.1.json.