Skip to content

Session

Package


session

session

Experiment orchestration.

This subpackage provides: - ExperimentSession : a high-level controller that coordinates data collection, model fitting, posterior updates, and adaptive trial placement.

MVP implementation
  • Wraps model, inference engine, and placement strategy.
  • Stores data in a ResponseData object.
  • Provides initialize(), update(), and next_batch() methods.
Full WPPM mode
  • Will support richer workflows:
  • Batch vs online updates.
  • Integration with live experimental computers (e.g., resuming sessions after breaks).

Classes:

Name Description
ExperimentSession

High-level experiment orchestrator.

ExperimentSession

ExperimentSession(
    model, inference, placement, init_placement=None
)

High-level experiment orchestrator.

Parameters:

Name Type Description Default
model WPPM

(Psychophysical) model instance.

required
inference InferenceEngine

Inference engine (MAP, Langevin, etc.).

required
placement TrialPlacement

Adaptive trial placement strategy.

required
init_placement TrialPlacement

Initial placement strategy (e.g., Sobol exploration).

None

Attributes:

Name Type Description
data ResponseData

Stores all collected trials.

posterior Posterior or None

Current posterior estimate (None before initialization).

Methods:

Name Description
initialize

Fit an initial posterior before any adaptive placement.

next_batch

Propose the next batch of trials.

update

Refit posterior with accumulated data.

Source code in src/psyphy/session/experiment_session.py
def __init__(self, model, inference, placement, init_placement=None):
    self.model = model
    self.inference = inference
    self.placement = placement
    self.init_placement = init_placement

    # Data store starts empty
    self.data = ResponseData()

    # Posterior will be set after initialize() or update()
    self.posterior = None

data

data = ResponseData()

inference

inference = inference

init_placement

init_placement = init_placement

model

model = model

placement

placement = placement

posterior

posterior = None

initialize

initialize()

Fit an initial posterior before any adaptive placement.

Returns:

Type Description
Posterior

Posterior object wrapping fitted parameters.

Notes

MVP: Posterior is fitted to empty data (prior only). Full WPPM mode: Could use pilot data or pre-collected trials along grid etc.

Source code in src/psyphy/session/experiment_session.py
def initialize(self):
    """
    Fit an initial posterior before any adaptive placement.

    Returns
    -------
    Posterior
        Posterior object wrapping fitted parameters.

    Notes
    -----
    MVP:
        Posterior is fitted to empty data (prior only).
    Full WPPM mode:
        Could use pilot data or pre-collected trials along grid etc.
    """
    self.posterior = self.inference.fit(self.model, self.data)
    return self.posterior

next_batch

next_batch(batch_size: int)

Propose the next batch of trials.

Parameters:

Name Type Description Default
batch_size int

Number of trials to propose.

required

Returns:

Type Description
TrialBatch

Batch of proposed (reference, probe) stimuli.

Notes

MVP: Always calls placement.propose() on current posterior. Full WPPM mode: Could support hybrid placement (init strategy -> adaptive strategy).

Source code in src/psyphy/session/experiment_session.py
def next_batch(self, batch_size: int):
    """
    Propose the next batch of trials.

    Parameters
    ----------
    batch_size : int
        Number of trials to propose.

    Returns
    -------
    TrialBatch
        Batch of proposed (reference, probe) stimuli.

    Notes
    -----
    MVP:
        Always calls placement.propose() on current posterior.
    Full WPPM mode:
        Could support hybrid placement (init strategy -> adaptive strategy).
    """
    if self.posterior is None:
        raise RuntimeError("Posterior not initialized. Call initialize() first.")
    return self.placement.propose(self.posterior, batch_size)

update

update()

Refit posterior with accumulated data.

Returns:

Type Description
Posterior

Updated posterior.

Notes

MVP: Re-optimizes from scratch using all data. Full WPPM mode: Could support warm-start or online parameter updates.

Source code in src/psyphy/session/experiment_session.py
def update(self):
    """
    Refit posterior with accumulated data.

    Returns
    -------
    Posterior
        Updated posterior.

    Notes
    -----
    MVP:
        Re-optimizes from scratch using all data.
    Full WPPM mode:
        Could support warm-start or online parameter updates.
    """
    self.posterior = self.inference.fit(self.model, self.data)
    return self.posterior

Experiment Session


experiment_session

experiment_session.py

ExperimentSession orchestrates the adaptive experiment loop.

Responsibilities
  1. Store trial data (ResponseData).
  2. Manage inference engine (MAP, Langevin, Laplace).
  3. Keep track of the current posterior.
  4. Delegate adaptive placement to a TrialPlacement strategy.

MVP implementation: - Data container starts empty and can be appended to. - initialize() fits a posterior once before trials. - update() refits posterior with accumulated data. - next_batch() proposes new trials from the placement strategy.

Full WPPM mode: - Will support batch vs online updates. - Integrate with lab software for live trial execution. - Save/load checkpoints for long experiments.

Classes:

Name Description
ExperimentSession

High-level experiment orchestrator.

ExperimentSession

ExperimentSession(
    model, inference, placement, init_placement=None
)

High-level experiment orchestrator.

Parameters:

Name Type Description Default
model WPPM

(Psychophysical) model instance.

required
inference InferenceEngine

Inference engine (MAP, Langevin, etc.).

required
placement TrialPlacement

Adaptive trial placement strategy.

required
init_placement TrialPlacement

Initial placement strategy (e.g., Sobol exploration).

None

Attributes:

Name Type Description
data ResponseData

Stores all collected trials.

posterior Posterior or None

Current posterior estimate (None before initialization).

Methods:

Name Description
initialize

Fit an initial posterior before any adaptive placement.

next_batch

Propose the next batch of trials.

update

Refit posterior with accumulated data.

Source code in src/psyphy/session/experiment_session.py
def __init__(self, model, inference, placement, init_placement=None):
    self.model = model
    self.inference = inference
    self.placement = placement
    self.init_placement = init_placement

    # Data store starts empty
    self.data = ResponseData()

    # Posterior will be set after initialize() or update()
    self.posterior = None

data

data = ResponseData()

inference

inference = inference

init_placement

init_placement = init_placement

model

model = model

placement

placement = placement

posterior

posterior = None

initialize

initialize()

Fit an initial posterior before any adaptive placement.

Returns:

Type Description
Posterior

Posterior object wrapping fitted parameters.

Notes

MVP: Posterior is fitted to empty data (prior only). Full WPPM mode: Could use pilot data or pre-collected trials along grid etc.

Source code in src/psyphy/session/experiment_session.py
def initialize(self):
    """
    Fit an initial posterior before any adaptive placement.

    Returns
    -------
    Posterior
        Posterior object wrapping fitted parameters.

    Notes
    -----
    MVP:
        Posterior is fitted to empty data (prior only).
    Full WPPM mode:
        Could use pilot data or pre-collected trials along grid etc.
    """
    self.posterior = self.inference.fit(self.model, self.data)
    return self.posterior

next_batch

next_batch(batch_size: int)

Propose the next batch of trials.

Parameters:

Name Type Description Default
batch_size int

Number of trials to propose.

required

Returns:

Type Description
TrialBatch

Batch of proposed (reference, probe) stimuli.

Notes

MVP: Always calls placement.propose() on current posterior. Full WPPM mode: Could support hybrid placement (init strategy -> adaptive strategy).

Source code in src/psyphy/session/experiment_session.py
def next_batch(self, batch_size: int):
    """
    Propose the next batch of trials.

    Parameters
    ----------
    batch_size : int
        Number of trials to propose.

    Returns
    -------
    TrialBatch
        Batch of proposed (reference, probe) stimuli.

    Notes
    -----
    MVP:
        Always calls placement.propose() on current posterior.
    Full WPPM mode:
        Could support hybrid placement (init strategy -> adaptive strategy).
    """
    if self.posterior is None:
        raise RuntimeError("Posterior not initialized. Call initialize() first.")
    return self.placement.propose(self.posterior, batch_size)

update

update()

Refit posterior with accumulated data.

Returns:

Type Description
Posterior

Updated posterior.

Notes

MVP: Re-optimizes from scratch using all data. Full WPPM mode: Could support warm-start or online parameter updates.

Source code in src/psyphy/session/experiment_session.py
def update(self):
    """
    Refit posterior with accumulated data.

    Returns
    -------
    Posterior
        Updated posterior.

    Notes
    -----
    MVP:
        Re-optimizes from scratch using all data.
    Full WPPM mode:
        Could support warm-start or online parameter updates.
    """
    self.posterior = self.inference.fit(self.model, self.data)
    return self.posterior