Metadata-Version: 2.4
Name: etiket_sync_agent_core_tools
Version: 0.3.0b1
Summary: Core-tools backend for eTiKeT sync agent
Author: QHarbor team
License-Expression: LicenseRef-Proprietary
Project-URL: Homepage, https://qharbor.nl
Project-URL: Documentation, https://docs.qharbor.nl
Keywords: etiket,sync,backend,core-tools,quantum
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: etiket_sync_agent>=0.3.0b1
Requires-Dist: pulse_lib
Requires-Dist: core_tools
Requires-Dist: psycopg2-binary
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: testcontainers; extra == "test"

# eTiKeT Sync Agent - Core Tools Backend

Backend for synchronizing core_tools datasets with the eTiKeT platform. This backend reads measurements from core_tools PostgreSQL databases and syncs them to the cloud.

## Installation

This backend depends on `core_tools` and `pulse_lib`, which are hosted on a private TU Delft GitLab repository. You must have these packages cloned locally and install them from their folder locations.

```python
from etiket_sdk.sync import Backends

# 1. Install dependencies from local folders
Backends.install_from_local("/path/to/pulse_lib")
Backends.install_from_local("/path/to/core_tools")

# 2. Install the backend
Backends.install_from_pypi("etiket-sync-agent-core-tools")
```

The package is automatically discovered by `etiket_sync_agent` through the entry-point system. Once installed, you can verify with:

```python
print(Backends.list())
backend = Backends.get("etiket_sync_agent_core_tools")
print(backend)
```

## What Gets Synchronized

When a core_tools measurement is synced, the following data is extracted and uploaded:

| core_tools Data | eTiKeT Field | Description |
|-----------------|--------------|-------------|
| `exp_uuid` | `alt_uid` | Unique identifier for the measurement |
| `name` | `name` | Name of the dataset |
| `run_timestamp` | `collected` | When the measurement was taken |
| `keywords` | `keywords` | Keywords associated with the measurement |
| `sample_name` | `attributes["sample"]` | Sample name for the measurement |
| `set_up` | `attributes["set-up"]` | Experimental setup name |
| xarray dataset | HDF5 file | The actual measurement data |

### Additional Metadata

The backend also extracts and synchronizes:

1. **Snapshot data**: Instrument settings stored in the measurement snapshot
2. **Pulses data**: AWG pulse sequences (if available in snapshot)
3. **Gates data**: Gate voltages (if available in snapshot)

## Configuration

The core_tools backend requires a `CoreToolsConfigData` configuration with the following fields:

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `dbname` | `str` | Yes | Name of the PostgreSQL database |
| `user` | `str` | Yes | Database username |
| `password` | `str` | Yes | Database password |
| `host` | `str` | No | Database host (default: `localhost`) |
| `port` | `int` | No | Database port (default: `5432`) |

### Example Configuration

```python
from etiket_sync_agent_core_tools import CoreToolsConfigData

config = CoreToolsConfigData(
    dbname="my_experiments",
    user="postgres",
    password="secret",
    host="localhost",
    port=5432
)
```

---

## Scope Mapping

Core_tools supports the concept of `scope` (or `project` in older versions) to organize measurements. When syncing, the backend maps core_tools scopes to eTiKeT scopes.

### How Scope Mapping Works

1. **If scope exists in core_tools**: The scope name is used as the `scopeIdentifier`
2. **If scope is `None`**: A generated identifier is used: `CT_PROJECT_{project_name}`

### Assigning Scope Mappings

After datasets are discovered, the user must map the `scopeIdentifier` to an actual eTiKeT scope. There are two ways to do this:

1. **Auto-assignment**: If the `scopeIdentifier` exactly matches an existing eTiKeT scope name, use the auto-assign feature
2. **Manual mapping**: Use the etiket_sdk or the DataQruiser GUI to manually map identifiers to scopes

For more information, see the [etiket_sdk documentation](../packages/etiket_sync_agent/README.md) or use our GUI application (DataQruiser).

---

## Features

- Direct integration with core_tools PostgreSQL databases
- Automatic metadata extraction from snapshots
- **Live sync support** for running measurements
- Pulse sequence extraction from AWG instruments
- Gate voltage extraction in the metadata of the hdf5 file.

## Live Measurement Sync

The core_tools backend supports live synchronization of in-progress measurements. When a measurement is detected as "running", the sync agent:

1. Creates the dataset entry in eTiKeT
2. Streams data points as they are written to the database
3. Uploads pulse metadata (if available)
4. Marks the dataset as complete when the measurement finishes

### Timeout Handling

If no new data is written for 30 minutes, the live sync assumes the measurement has stalled and raises a timeout error.

## Requirements

- Python >= 3.10
- core_tools (private package from TU Delft GitLab)
- PostgreSQL database with core_tools schema

## License

Copyright © 2025 QHarbor. All Rights Reserved. See [LICENCE](LICENCE) for details.
