> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dataerai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Pycroscopy

> Preserve pycroscopy analysis outputs as Dataerai assets with metadata and provenance links, using the Dataerai Python SDK.

When you process scientific data in [pycroscopy](https://pycroscopy.github.io/pycroscopy/), you can preserve each result as a Dataerai asset and link it back to the raw measurement it came from. You keep the scientific workflow in pycroscopy, and Dataerai stores the asset, its content, your metadata, and a typed provenance relationship to the upstream asset.

There is no separate pycroscopy package — you use the [Dataerai Python SDK](/sdks/python) directly. The pattern is always the same: **upload** the output, then **create a relationship** to its source.

## Requirements

* Python 3.10+
* `pycroscopy`
* The `dataerai` Python SDK (`pip install dataerai-sdk`)
* The `dataerai` binary on your `PATH` (install the [CLI](/cli/overview))
* Signed in with `dataerai auth login` (see [Authenticate](/cli/authenticate))

## Install

```bash theme={null}
pip install pycroscopy dataerai-sdk
```

## Preserve a result and link its provenance

Save your processed pycroscopy output to a file, upload it as a new asset, then link the new asset to the raw measurement with `create_relationship`:

```python theme={null}
import numpy as np
import sidpy

from dataerai import DataeraiClient

# A pycroscopy result you want to preserve.
cleaned = sidpy.Dataset.from_array(np.random.random((64, 64)))
cleaned.title = "Cleaned AFM image"
cleaned.data_type = "image"

path = "cleaned_afm.npy"
np.save(path, np.asarray(cleaned))

with DataeraiClient(binary_path="/usr/local/bin/dataerai") as client:
    # 1. Upload the processed output as a new asset.
    result = client.upload(
        path,
        title="Cleaned AFM image",
        owner_type="project",
        owner_id="proj-abc123",
        tags=["afm", "clean_svd"],
        metadata={
            "workflow": "clean_svd",
            "shape": list(cleaned.shape),
            "dtype": str(cleaned.dtype),
        },
    )

    # 2. Link the new asset back to the raw measurement it was derived from.
    relationship = client.create_relationship(
        result.asset_id,
        "raw-asset-id",
        "analysis_of",
        analysis_mode="non_destructive",
        qualifiers={"workflow": "clean_svd"},
    )

print("asset_id:", result.asset_id)
print("content_id:", result.content_id)
print("relationship:", relationship.type)
```

## What gets saved

* The processed file as the asset's **content**.
* The `title`, `tags`, and any `metadata` dict you pass — a natural place to record the workflow name, parameters, input shape, dtype, and other `sidpy.Dataset` summary fields.
* A directed provenance relationship from the new asset to its source asset.

The edge points **from** the preserved output **to** its source. Use `analysis_of` when the output is an analysis result, or `derived_from` for a processed output. See [Provenance & relationships](/organize/provenance) for the relationship model, and the [Python SDK reference](/sdks/python#provenance-relationships) for the full `create_relationship` signature.

## Next steps

<CardGroup cols={2}>
  <Card title="Python SDK" icon="circle" href="/sdks/python">
    Upload, download, metadata, and relationship methods.
  </Card>

  <Card title="Provenance & relationships" icon="git-fork" href="/organize/provenance">
    How relationships model data lineage.
  </Card>
</CardGroup>
