API reference¶
The public API. Import these from the top-level pilotr package, for example
from pilotr import simulate, power.
Simulation¶
pilotr.simulate.simulate ¶
simulate(spec) -> Dataset
Simulate a data set from a design specification.
Build a linear predictor from the fixed effect sizes (categorical contrasts, continuous predictors and their interactions) plus the crossed by-subject and by-item random intercepts and slopes, then map it through the chosen response family.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
dict or str
|
A design specification, either an already-parsed |
required |
Returns:
| Type | Description |
|---|---|
Dataset
|
A table with one row per observation: a |
pilotr.simulate.load_spec ¶
load_spec(path)
Load a JSON design specification from a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Path to a JSON design-specification file. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
The parsed specification, ready for |
pilotr.examples.pilotr_example ¶
pilotr_example(name: Optional[str] = None) -> Union[list[str], str]
List the bundled example specifications, or return the path to one.
pilotr ships one ready-to-run specification per design family, as JSON. These are the same files that drive the R twin and the no-code app.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The base name of an example, with or without the |
None
|
Returns:
| Type | Description |
|---|---|
list of str, or str
|
When |
pilotr.simulate.Dataset ¶
A simulated data set: named columns and a list of row dicts.
Returned by simulate. Lightweight and dependency-free; build a pandas DataFrame
from dataset.rows when you need one.
Attributes:
| Name | Type | Description |
|---|---|---|
columns |
list of str
|
Column names, in order. |
rows |
list of dict
|
One dict per observation, keyed by column name. |
Power and design analysis¶
pilotr.power.power ¶
power(spec, n_sims=1000, alpha=0.05, workers=1)
Simulation-based power and design analysis for a two-group Gaussian design.
Repeatedly simulate from the specification, apply a two-sample t-test, and report power together with the Type S (sign) and Type M (magnitude) errors of Gelman and Carlin (2014), computed over the significant replicates.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
dict or str
|
A two-group Gaussian design specification (dict or path to a JSON file). |
required |
n_sims
|
int
|
Number of Monte Carlo replicates (default 1000). |
1000
|
alpha
|
float
|
Two-sided significance level (default 0.05). |
0.05
|
workers
|
int
|
Number of local worker processes over which to spread the replicates (default 1, serial). Each replicate seeds the shared RNG from its own index, so any worker count returns results identical to a serial run. |
1
|
Returns:
| Type | Description |
|---|---|
dict
|
Keys: |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If the design is not a single two-level between-subjects Gaussian factor. |
Notes
Requires scipy (imported lazily, in each worker process when parallel); install the
power or dev extra.
pilotr.power.power_curve ¶
power_curve(spec, subject_ns, n_sims=1000, alpha=0.05, workers=1)
Power curve over sample size for a two-group Gaussian design.
Sweep the number of subjects and compute power at each grid point.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
dict or str
|
A two-group Gaussian design specification. |
required |
subject_ns
|
iterable of int
|
Subject counts to evaluate. |
required |
n_sims
|
int
|
Replicates per grid point (default 1000). |
1000
|
alpha
|
float
|
Significance level (default 0.05). |
0.05
|
workers
|
int
|
Number of local worker processes over which to spread the replicates at each grid point (default 1, serial). One process pool is started and reused across the whole sweep, and any worker count returns results identical to a serial run. |
1
|
Returns:
| Type | Description |
|---|---|
list of dict
|
One dict per grid point, with keys |
pilotr.power.power_mixed ¶
power_mixed(spec, n_sims=50, alpha=0.05, workers=1)
Crossed mixed-effects simulation-based power in Python, via statsmodels MixedLM with by-subject and by-item random intercepts and slopes as (independent) variance components.
This is pilotr's own simulation loop over the portable design specification, not a
wrapper around an existing power package. It covers territory pioneered by simr (Green
and MacLeod, 2016, doi:10.1111/2041-210x.12504) and mixedpower (Kumle, Vo and Draschkow,
2021, doi:10.3758/s13428-021-01546-0); pilotr differs in being driven by the portable
cross-language spec, in reporting Type S and Type M errors and in built-in
parallelisation via workers (default 1, serial), which returns results identical to a
serial run for any worker count.
Accuracy caveat (verified behaviour, not a bug). statsmodels fits crossed random effects
as independent variance components and, in our tests, substantially overstates random-slope
variance (for example, a by-subject slope SD of about 0.12 estimated against 0.04 true).
This inflates the fixed-effect standard error. For designs with by-subject or by-item random
slopes, the backend is therefore markedly conservative. On the crossed RT design it
reports power around 0.48, against the R/lme4 reference of about 0.73. It still recovers the
fixed effect (mean estimate about 0.048 against 0.05 true) and the Type S and Type M
quantities correctly, and it is reliable for random-intercept designs. We recommend treating
its output as a conservative lower bound and using the R/lme4 power_mixed as the reference
whenever random slopes or random-effect correlations matter. Data generation is identical
across R and Python. This discrepancy arises solely in the Python LMM estimator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
dict or str
|
A design specification (dict or path to a JSON file) with exactly one within-unit factor and a crossed design with an item unit. |
required |
n_sims
|
int
|
Number of Monte Carlo replicates (default 50, smaller than |
50
|
alpha
|
float
|
Two-sided significance level (default 0.05). |
0.05
|
workers
|
int
|
Number of local worker processes over which to spread the replicates (default 1, serial). Each replicate seeds the shared RNG from its own index, so any worker count returns results identical to a serial run. |
1
|
Returns:
| Type | Description |
|---|---|
dict
|
Keys: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the spec has no item unit ( |
NotImplementedError
|
If the design does not have exactly one within-unit factor. |
Notes
Requires the mixed extra (statsmodels and pandas, imported lazily in each worker
process when parallel).
Numerical core¶
pilotr.core.RNG ¶
Shared cross-language random-number generator.
The combined linear congruential generator of L'Ecuyer (1988), implemented identically
in R and Python so that a given seed yields the same stream in both. All intermediate
products stay below 2**53, so the arithmetic is exact in IEEE-754 doubles. The
draw-order contract is documented in the specification at
https://github.com/pablobernabeu/pilotr/blob/main/spec/SPEC.md.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seed
|
int
|
Seed for the generator (coerced to a non-negative integer). |
required |
pilotr.core.as241 ¶
as241(p: float) -> float
Inverse standard-normal CDF (quantile function), Wichura's (1988) Algorithm AS 241.
The PPND16 routine underlying R's qnorm, accurate to full double precision.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
p
|
float
|
A probability in the open interval (0, 1). |
required |
Returns:
| Type | Description |
|---|---|
float
|
The standard-normal quantile for |
pilotr.core.inv_logit ¶
inv_logit(x: float) -> float
Logistic (inverse-logit) link 1 / (1 + exp(-x)), evaluated stably for large |x|.