nstat.extras.decoding.place_field_decoder

High-level place-field encoding + decoding wrapper.

Encapsulates the canonical pattern from example08_real_place_cells.py: fit a B-spline Poisson GLM per cell (encoding), refit a quadratic CIF per cell (so PPDecode_update can call CIF.evalLambdaDelta efficiently), and run PPDecodeFilterLinear with the history-free fast path (PR #198).

Functions

fit_place_field_decoder(trial, position, *)

Fit a place-cell encoding + decoding pipeline for a single Trial.

Classes

PlaceFieldDecoderConfig([bin_width_s, ...])

Configuration for the place-field encoding + decoding wrapper.

PlaceFieldDecoderResult(decoded_position, ...)

Output of fit_place_field_decoder().

class nstat.extras.decoding.place_field_decoder.PlaceFieldDecoderConfig(bin_width_s=0.02, n_basis_per_dim=8, spline_order=4, cif_kind='quadratic', decode_filter='linear', min_n_spikes_per_cell=10)[source]

Bases: object

Configuration for the place-field encoding + decoding wrapper.

Parameters:
  • bin_width_s (float) – Time-discretisation bin (seconds). Default 0.020 (20 ms — matches example08).

  • n_basis_per_dim (int) – Number of B-spline basis functions per spatial dimension for encoding. Default 8 (8x8 = 64 coefficients per cell).

  • spline_order (int) – B-spline order (degree + 1) for encoding. Default 4 (cubic).

  • cif_kind ({"quadratic", "linear"}) – CIF family for decoding refit. Default “quadratic”.

  • decode_filter ({"linear", "nonlinear"}) – Which PPDecodeFilter variant to use. “linear” exercises the PR #198 O(C*T) fast path; “nonlinear” is provided for parity but is O(C*T^2) for history-free CIFs (i.e., always, in this wrapper, since none of the place-cell CIFs carry history). Default “linear”.

  • min_n_spikes_per_cell (int) – Skip cells with fewer total spikes; they cannot fit a stable place field. Default 10.

bin_width_s: float = 0.02
n_basis_per_dim: int = 8
spline_order: int = 4
cif_kind: str = 'quadratic'
decode_filter: str = 'linear'
min_n_spikes_per_cell: int = 10
class nstat.extras.decoding.place_field_decoder.PlaceFieldDecoderResult(decoded_position, decoded_covariance, decoding_error, mean_decoding_error, cell_indices_kept, cell_indices_skipped, spline_coefs, quadratic_coefs, n_basis_per_dim, bin_width_s)[source]

Bases: object

Output of fit_place_field_decoder().

Variables:
  • decoded_position ((n_time, 2) ndarray) – Posterior mean position from PPAF filter.

  • decoded_covariance ((n_time, 2, 2) ndarray) – Per-bin posterior covariance.

  • decoding_error ((n_time,) ndarray) – Per-bin Euclidean distance between decoded and true position.

  • mean_decoding_error (float) – Average decoding error (the headline summary).

  • cell_indices_kept (list[int]) – Indices of cells that contributed (passed min_spike filter, GLM converged).

  • cell_indices_skipped (list[int]) – Indices of cells that were dropped (with reason logged via UserWarning).

  • spline_coefs (list[ndarray]) – B-spline coefficient vectors for kept cells; shape (n_basis_per_dim**2 + 1,) — first entry is the GLM intercept.

  • quadratic_coefs (list[ndarray]) – Quadratic CIF coefficient vectors for kept cells; shape (6,) ordered as [intercept, x, y, x^2, y^2, x*y] (or shape (3,) ordered as [intercept, x, y] when cif_kind == "linear").

  • n_basis_per_dim (int) – Echoed from config.

  • bin_width_s (float) – Echoed from config.

Parameters:
decoded_position: ndarray
decoded_covariance: ndarray
decoding_error: ndarray
mean_decoding_error: float
cell_indices_kept: list[int]
cell_indices_skipped: list[int]
spline_coefs: list[ndarray]
quadratic_coefs: list[ndarray]
n_basis_per_dim: int
bin_width_s: float
nstat.extras.decoding.place_field_decoder.fit_place_field_decoder(trial, position, *, config=None)[source]

Fit a place-cell encoding + decoding pipeline for a single Trial.

Wraps the canonical 4-step pipeline from examples/paper/example08_real_place_cells.py (lines 270-420):

  1. Build a tensor-product 2-D B-spline basis on the trial’s position range and fit a per-cell Poisson GLM (encoding).

  2. Refit a quadratic (or linear) CIF per cell on a position design matrix — the decoder needs an analytical CIF whose CIF.evalLambdaDelta() is cheap.

  3. Build the per-cell CIF collection with Xnames = ["1", "x", "y", "x^2", "y^2", "x*y"], stimNames = ["x", "y"], fitType = "binomial".

  4. Run DecodingAlgorithms.PPDecodeFilterLinear() (history-free fast path) on the same trial; compute per-bin Euclidean error.

Parameters:
  • trial (Trial) – Training trial. Must carry a SpikeTrainCollection.

  • position (NDArray[float64]) – Training-trial 2-D position over time, shape (n_time, 2), aligned to the trial’s sample grid.

  • config (PlaceFieldDecoderConfig | None) – Configuration. Defaults to PlaceFieldDecoderConfig.

Return type:

PlaceFieldDecoderResult