Workspace

The AnalysisWorkspace class provides HDF5-based persistence for analysis sessions. It can save and load SpikeData, RateData, pairwise matrices, slice stacks, and associated metadata in a single file.

AnalysisWorkspace — named, namespaced container for analysis results.

Stores IAT data class objects and numpy arrays under two-level keys (namespace, key). Supports save/load to disk (.h5 data + .json index). Individual items can be loaded selectively from disk without loading the full workspace.

class spikelab.workspace.workspace.AnalysisWorkspace(name=None)[source]

Bases: object

Named, namespaced container for storing analysis results.

Results are organised under two-level keys: a namespace (typically the name of a recording or comparison group) and a key (the specific result within that namespace). Supports saving and loading the full workspace to and from disk.

workspace_id

UUID identifying this workspace instance.

Type:

str

name

Optional human-readable label.

Type:

str | None

created_at

POSIX timestamp of creation time.

Type:

float

__init__(name=None)[source]

Create a new empty workspace.

Parameters:

name (str | None) – Optional human-readable label for the workspace.

store(namespace, key, obj, note=None)[source]

Store an object under (namespace, key).

Parameters:
  • namespace (str) – Namespace grouping related results (e.g., a recording name).

  • key (str) – Human-readable key identifying this result within the namespace.

  • obj (Any) – Object to store. Supported types: SpikeData, RateData, RateSliceStack, SpikeSliceStack, PairwiseCompMatrix, PairwiseCompMatrixStack, np.ndarray. Other types are accepted and stored, but their summary will only contain the class name.

  • note (str | None) – Optional free-text annotation attached to the index entry.

Return type:

None

Notes

  • Storing under an existing (namespace, key) overwrites the previous value and refreshes the index entry.

get(namespace, key)[source]

Retrieve a stored object.

Parameters:
  • namespace (str) – Namespace the object was stored under.

  • key (str) – Key the object was stored under.

Returns:

The stored object, or None if not found.

Return type:

obj

get_info(namespace, key)[source]

Return the index entry for an item without loading the object itself.

Parameters:
  • namespace (str) – Namespace to look up.

  • key (str) – Key to look up.

Returns:

Summary dict (type, shape/attributes, note,

created_at), or None if not found.

Return type:

info (dict | None)

describe()[source]

Return the full index as a JSON-serializable dict.

Returns:

Nested dict {namespace: {key: summary_dict}}.

Return type:

index (dict)

list_keys(namespace=None)[source]

List stored keys, optionally filtered to a single namespace.

Parameters:

namespace (str | None) – If provided, returns the list of keys for that namespace. If None, returns a dict mapping each namespace to its list of keys.

Returns:

{namespace: [keys]} when namespace is

None, otherwise [keys].

Return type:

keys (dict | list)

list_namespaces()[source]

Return the names of all top-level namespaces in the workspace.

Returns:

List of namespace names in insertion order.

Return type:

namespaces (list[str])

rename(namespace, old_key, new_key, overwrite=False)[source]

Rename a key within a namespace.

Parameters:
  • namespace (str) – Namespace containing the key.

  • old_key (str) – Existing key name.

  • new_key (str) – New key name.

  • overwrite (bool) – If False (default) and new_key already exists, a warning is printed and the rename is aborted. Set to True to silently overwrite the existing entry.

Returns:

True if renamed, False if namespace or

old_key not found or rename was blocked by existing key.

Return type:

success (bool)

add_note(namespace, key, note)[source]

Add or replace the note attached to a stored item.

Parameters:
  • namespace (str) – Namespace of the item.

  • key (str) – Key of the item.

  • note (str) – Note text to attach.

Returns:

True if updated, False if item not found.

Return type:

success (bool)

delete(namespace, key=None)[source]

Delete a single item or an entire namespace.

Parameters:
  • namespace (str) – Namespace to delete from.

  • key (str | None) – Key to delete. If None, the entire namespace and all its contents are deleted.

Returns:

True if deleted, False if not found.

Return type:

success (bool)

merge_from(other, overwrite=False)[source]

Copy all items from another workspace into this one.

Parameters:
  • other (AnalysisWorkspace) – Source workspace to merge from. May be a regular or lazy workspace.

  • overwrite (bool) – If True, existing (namespace, key) pairs in this workspace are replaced by the incoming values. If False (default), existing keys are kept and incoming duplicates are skipped.

Returns:

Summary with keys merged (int),

skipped (int), and skipped_keys (list[tuple[str, str]]).

Return type:

result (dict)

Notes

  • HDF5 does not support concurrent writes to the same file. When multiple processes (e.g. parallel Claude Code instances or MCP agents) need to store analysis results, each process should create its own workspace and save to a separate file. After all processes finish, a single orchestrator loads each file and calls merge_from to combine the results:

    ws_main = AnalysisWorkspace(name="combined")
    for path in agent_output_paths:
        ws_main.merge_from(AnalysisWorkspace.load(path))
    ws_main.save("path/to/combined_workspace")
    
  • Only object data and notes are copied. The source workspace’s workspace_id, name, and created_at are not transferred.

save(path)[source]

Save the workspace to disk.

Writes two files: {path}.h5 (full object data, HDF5) and {path}.json (index/metadata, human-readable). All stored objects are serialised to their constituent arrays so that individual items can be loaded selectively without reading the entire file.

Parameters:

path (str) – Base path without file extension.

Return type:

None

classmethod load(path)[source]

Load a workspace from disk, reconstructing all stored objects.

Parameters:

path (str) – Base path without file extension (the same value that was passed to save).

Returns:

Reconstructed workspace instance.

Return type:

workspace (AnalysisWorkspace)

classmethod load_item(path, namespace, key)[source]

Load a single item from a saved workspace file.

Loads only the requested item without reading the entire workspace into memory.

Parameters:
  • path (str) – Base path without file extension.

  • namespace (str) – Namespace the item was stored under.

  • key (str) – Key the item was stored under.

Returns:

Reconstructed IAT data object or numpy array.

Return type:

obj

static comparison_namespace(*namespaces)[source]

Build a conventional namespace string for cross-recording comparisons.

Parameters:

*namespaces (str) – Names of the recording namespaces involved in the comparison (in any order).

Returns:

A string of the form C_ns1_ns2_....

Return type:

name (str)

Notes

  • By convention, pass the same namespace strings used when storing the individual recording results.

class spikelab.workspace.workspace.LazyAnalysisWorkspace(name=None)[source]

Bases: AnalysisWorkspace

Disk-backed variant of AnalysisWorkspace for low-RAM environments.

Each stored object is immediately serialised to a temporary HDF5 file and removed from process memory. Only the lightweight index metadata is kept in RAM. Objects are deserialised from the temp file on each get() call.

Use this when working with large recordings and limited available RAM. The temp file is deleted automatically when the workspace is garbage-collected.

Notes

  • Requires h5py. If h5py is not installed, construction will raise ImportError.

  • Every get() call performs a disk read; repeated access to the same item is slower than with the default in-memory workspace.

  • save() copies the temp file to the destination path, so it is as fast as a file copy rather than a full re-serialisation.

__init__(name=None)[source]

Create a new empty lazy workspace backed by a temp HDF5 file.

Parameters:

name (str | None) – Optional human-readable label.

store(namespace, key, obj, note=None)[source]

Serialise an object to the temp HDF5 file and record it in the index.

Parameters:
  • namespace (str) – Namespace grouping related results.

  • key (str) – Key identifying this result within the namespace.

  • obj (Any) – Object to store.

  • note (str | None) – Optional free-text annotation.

Return type:

None

get(namespace, key)[source]

Deserialise and return a stored object from the temp HDF5 file.

Parameters:
  • namespace (str) – Namespace the object was stored under.

  • key (str) – Key the object was stored under.

Returns:

Reconstructed object, or None if not found.

Return type:

obj

list_keys(namespace=None)[source]

List stored keys from the index (no disk read required).

Parameters:

namespace (str | None) – If provided, returns the list of keys for that namespace. If None, returns a dict mapping each namespace to its list of keys.

Returns:

Key listing derived from the in-memory index.

Return type:

keys (dict | list)

list_namespaces()[source]

Return the names of all top-level namespaces in the workspace.

Returns:

List of namespace names derived from

the in-memory index.

Return type:

namespaces (list[str])

rename(namespace, old_key, new_key, overwrite=False)[source]

Rename a key within a namespace.

Parameters:
  • namespace (str) – Namespace containing the key.

  • old_key (str) – Existing key name.

  • new_key (str) – New key name.

  • overwrite (bool) – If False (default) and new_key already exists, a warning is printed and the rename is aborted. Set to True to silently overwrite the existing entry.

Returns:

True if renamed, False if namespace or

old_key not found or rename was blocked by existing key.

Return type:

success (bool)

delete(namespace, key=None)[source]

Delete a single item or an entire namespace from the temp file and index.

Parameters:
  • namespace (str) – Namespace to delete from.

  • key (str | None) – Key to delete. If None, deletes the entire namespace.

Returns:

True if deleted, False if not found.

Return type:

success (bool)

save(path)[source]

Save the workspace to disk by copying the temp HDF5 file.

Parameters:

path (str) – Base path without file extension.

Return type:

None

class spikelab.workspace.workspace.WorkspaceManager[source]

Bases: object

Registry for multiple AnalysisWorkspace instances within a single process.

Provides create, retrieve, delete, list, save, and load operations. Use get_workspace_manager() to access the module-level singleton.

__init__()[source]

Initialize an empty WorkspaceManager.

create_workspace(name=None, lazy=False)[source]

Create and register a new empty workspace.

Parameters:
  • name (str | None) – Optional human-readable label.

  • lazy (bool) – If True, creates a disk-backed LazyAnalysisWorkspace that serialises each item to a temp HDF5 file on store() and deserialises on get(). Only index metadata is kept in RAM. Use this when working with large recordings and limited RAM. Requires h5py. Defaults to False (fully in-memory).

Returns:

UUID of the new workspace.

Return type:

workspace_id (str)

get_workspace(workspace_id)[source]

Retrieve a workspace by ID.

Parameters:

workspace_id (str) – UUID of the workspace.

Returns:

The workspace, or None

if not found.

Return type:

workspace (AnalysisWorkspace | None)

delete_workspace(workspace_id)[source]

Delete a workspace and all its contents.

Parameters:

workspace_id (str) – UUID of the workspace to delete.

Returns:

True if deleted, False if not found.

Return type:

success (bool)

list_workspaces()[source]

List all registered workspaces with summary information.

Returns:

Each entry contains workspace_id, name,

created_at, namespace_count, and item_count.

Return type:

workspaces (list[dict])

save_workspace(workspace_id, path)[source]

Save a workspace to disk.

Parameters:
  • workspace_id (str) – UUID of the workspace to save.

  • path (str) – Base path without file extension (passed through to AnalysisWorkspace.save).

Return type:

None

Notes

  • Raises KeyError if workspace_id is not registered.

load_workspace(path)[source]

Load a workspace from disk and register it in the manager.

Reconstructs all stored objects to their original IAT data class types.

Parameters:

path (str) – Base path without file extension (the same value that was passed to save).

Returns:

UUID of the loaded workspace.

Return type:

workspace_id (str)

Notes

  • If a workspace with the same ID is already registered, it will be overwritten by the loaded version.

load_workspace_item(path, namespace, key, workspace_id)[source]

Load a single item from a saved workspace file into a registered workspace.

Reconstructs the original IAT data class and stores it in the specified in-memory workspace.

Parameters:
  • path (str) – Base path without file extension.

  • namespace (str) – Namespace the item was stored under.

  • key (str) – Key the item was stored under.

  • workspace_id (str) – ID of the in-memory workspace to store the loaded item into.

Return type:

None

Notes

  • Raises KeyError if workspace_id is not registered.

  • Raises KeyError if namespace or key is not found in the file.

spikelab.workspace.workspace.get_workspace_manager()[source]

Return the global WorkspaceManager singleton.

Returns:

The global instance, created on first call.

Return type:

manager (WorkspaceManager)