Metadata-Version: 2.4
Name: vcti-dataspace
Version: 1.0.0
Summary: Data space for organizing, loading, and working with hierarchical data from multiple file sources
Author: Visual Collaboration Technologies Inc.
Requires-Python: <3.15,>=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Requires-Dist: vcti-fileloader>=1.0.0
Requires-Dist: vcti-array-tree>=1.0.0
Provides-Extra: hdf5-export
Requires-Dist: h5py>=3.0; extra == "hdf5-export"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: pytest-cov; extra == "test"
Requires-Dist: h5py>=3.0; extra == "test"
Provides-Extra: lint
Requires-Dist: ruff; extra == "lint"
Provides-Extra: typecheck
Requires-Dist: mypy; extra == "typecheck"
Requires-Dist: numpy; extra == "typecheck"
Dynamic: license-file

# Data Space

Data space for organizing, loading, and working with hierarchical data from multiple file sources.

## Installation

```bash
pip install vcti-dataspace>=1.0.0
```

With HDF5 export support:

```bash
pip install vcti-dataspace[hdf5-export]>=1.0.0
```

---

## Quick Start

```python
import numpy as np
from pathlib import Path
from vcti.dataspace import FilesProject

# Context manager ensures clean resource cleanup
with FilesProject("Analysis", registry=registry) as project:
    # Add file sources (auto-loads, creates immutable source DataSpaces)
    project.add_path_source("sim", Path("results.h5"))

    # Access source DataSpace (immutable, mirrors file)
    sim = project.get_path_source("sim")
    tree = sim.dataspace.tree
    info = sim.dataspace.get_node_info_all()

    # Open workspace and create user DataSpace (mutable)
    ws = project.open_workspace()
    user_space = ws.create_dataspace("output")

    # Copy data from source, add custom groups and datasets
    user_space.copy_node_from(sim.dataspace, node_id=5)
    grp = user_space.create_group("custom")
    user_space.create_dataset("values", np.array([1.0, 2.0]), parent_id=grp)

    # Delete nodes when no longer needed
    user_space.delete_node(grp, recursive=True)

    # Export to HDF5
    user_space.export_hdf5(Path("output.h5"))
```

---

## Error Handling

All exceptions inherit from `DataSpaceError`, so you can catch broadly or narrowly:

```python
from vcti.dataspace import DataSpaceError, ImmutableDataSpaceError, NodeNotFoundError

try:
    space.delete_node(999)
except NodeNotFoundError:
    print("Node does not exist")
except DataSpaceError:
    print("Catch-all for any DataSpace error")
```

---

## Core API

### DataSpace

| Method | Description |
|--------|-------------|
| `build_from_loader(loader, handle)` | Build from file loader (source only) |
| `create_group(name, parent_id)` | Create group node (user only) |
| `create_dataset(name, data, parent_id)` | Create dataset node (user only) |
| `delete_node(node_id, recursive)` | Delete node and optionally its children |
| `copy_node_from(source, node_id)` | Copy node from another DataSpace |
| `get_dataset(node_id)` | Get dataset (lazy-loads for sources) |
| `get_node_info(node_id)` | Get node metadata |
| `export_hdf5(path)` | Export to HDF5 file |
| `clear_dataset_cache()` | Free cached lazy datasets |
| `node_count` | Total number of nodes (property) |
| `dataset_count` | Number of datasets (property) |

### PathSource, Workspace, FilesProject

| Class | Purpose |
|-------|---------|
| `PathSource` | File + loader + source DataSpace |
| `Workspace` | Session with user DataSpaces |
| `FilesProject` | Orchestrates sources + workspaces |

---

## Dependencies

- [numpy](https://numpy.org/) (>=1.24)
- [vcti-fileloader](https://pypi.org/project/vcti-fileloader/) (>=1.0.0)
- [vcti-array-tree](https://pypi.org/project/vcti-array-tree/) (>=1.0.0) — DataNode
- [h5py](https://www.h5py.org/) — optional, for HDF5 export
