# Asset

## class nominal.Asset

A physical or logical system under test.

Obtained from a client rather than constructed directly:

```matlab
a = c.getOrCreateAsset("engine-3");   % by name, creating if absent
a = c.assetByRid(rid);                % by RID
```

Example:

```matlab
ds = a.getOrCreateDataset("telemetry", "tlm");
r  = a.run("burn-12");
a.update(Labels=["production" "orbit"]);
```

> **See also**
>
> [`nominal.Client`](https://dev.nominal.io/matlab/ref/Client.md#nominal.Client "nominal.Client"), [`nominal.Dataset`](https://dev.nominal.io/matlab/ref/Dataset.md#nominal.Dataset "nominal.Dataset"), [`nominal.Run`](https://dev.nominal.io/matlab/ref/Run.md#nominal.Run "nominal.Run")

Constructor Summary

Property Summary
:   ### Rid

    Resource identifier.

    ### Name

    Display name.

    ### Description

    Description, or “” if it has none.

    ### Url

    Web URL in the Nominal app.

    ### Labels

    All labels, as a string array.

    ### Properties

    All properties, as a containers.Map.

Method Summary
:   ### property(key)

    Value of one property. Errors if the key is absent.

    Returns:
    :   *string* – The property’s value.

    ### setProperty(key, value)

    Set one property, keeping the rest.

    ```matlab
    a = a.setProperty("serial", "SN-0042");
    ```

    Re-reads the asset first, so properties set since this object
    was fetched are kept.

    Returns:
    :   *nominal.Asset* – The updated asset.

    ### removeProperty(key)

    Remove one property, keeping the rest.

    Errors if the asset has no such property.

    Returns:
    :   *nominal.Asset* – The updated asset.

    ### datasources(options)

    Everything attached to this asset, as a table.

    s = a.datasources(); % read once, then reused
    s = a.datasources(Refresh=true); % ask Nominal again
    tlm = s(s.Type == “dataset”, :); % datasets only
    s.Tags{1} % one source’s tag filter

    **The first call asks Nominal and keeps the answer, and later
    calls on this object reuse it.** A dataset attached since, by
    addDataset or from the web app, is not listed until you pass
    Refresh=true.

    Options:
    :   **Refresh** – Ask Nominal again. Costs one request.

    Returns:
    :   *table* – Variables RefName, Rid, Type, Tags and Offset,
        ordered by reference name. Type is “dataset”, “video”,
        “connection” or “other”, and only a dataset RID can open a
        stream. Tags holds each source’s tag filter as a
        containers.Map, empty when it sees the whole source.
        Offset is a duration.

    > **See also**
    >
    > [`nominal.Asset.fetch()`](https://dev.nominal.io/matlab/ref/Asset.md#nominal.Asset.fetch "nominal.Asset.fetch"), [`nominal.Asset.addDataset()`](https://dev.nominal.io/matlab/ref/Asset.md#nominal.Asset.addDataset "nominal.Asset.addDataset")

    ### addDataset(dataset, refName, options)

    Attach a dataset you already have to this asset.

    ```matlab
    a.addDataset(ds);
    a.addDataset(ds, "can");
    a.addDataset(ds, Tags=struct(UUT="A"));
    a.addDataset(ds, Tags=dictionary("test-stand", "3"));
    ```

    Write one shared dataset with a tag per unit under test, then
    give each unit’s asset its own slice:

    ```matlab
    assetA.addDataset(ds, Tags=struct(UUT="A"));
    assetB.addDataset(ds, Tags=struct(UUT="B"));
    ```

    An asset holds a dataset once per tag filter. Attaching the same
    dataset again with the same Tags *moves* it to the new reference
    name. Attaching it with different Tags adds it alongside, so one
    dataset can appear twice, split by tag:

    ```matlab
    a.addDataset(ds, "drone",  Tags=struct(source="drone"));
    a.addDataset(ds, "remote", Tags=struct(source="remote"));
    ```

    This asset object is a snapshot and will not show the new data
    source. Use a.datasources(Refresh=true) to see it.

    Parameters:
    :   - **dataset**

          Any dataset object: one fetched by RID, from a
          search, or from an ingest.
        - **refName**

          The dataset’s name within this asset, unique among
          its data sources. Spaces, dots and mixed case are fine.
          It matters when one asset carries two sources measuring
          the same thing, say a CAN log and a test rig both
          reporting “engine temp”. Omit it and one is chosen for
          you: “default” on an asset with none, otherwise the
          dataset’s own name, otherwise that with a number.

    Options:
    :   **Tags** – Limit this asset to the dataset’s series carrying
        every one of these tags. A struct, or a dictionary
        (R2022b+) for a key that is not a valid field name.
        Values are strings, and numbers are converted.

    > **See also**
    >
    > [`nominal.Asset.getOrCreateDataset()`](https://dev.nominal.io/matlab/ref/Asset.md#nominal.Asset.getOrCreateDataset "nominal.Asset.getOrCreateDataset"), [`nominal.Asset.datasources()`](https://dev.nominal.io/matlab/ref/Asset.md#nominal.Asset.datasources "nominal.Asset.datasources")

    ### removeDataset(refName)

    Detach the data source with this reference name.

    ```matlab
    a.removeDataset("can");
    ```

    The dataset itself is untouched, and stays on any other asset
    holding it. Everything else on this asset keeps its tag filter.
    Errors if nothing here has that reference name.

    > **See also**
    >
    > [`nominal.Asset.addDataset()`](https://dev.nominal.io/matlab/ref/Asset.md#nominal.Asset.addDataset "nominal.Asset.addDataset"), [`nominal.Asset.datasources()`](https://dev.nominal.io/matlab/ref/Asset.md#nominal.Asset.datasources "nominal.Asset.datasources")

    ### renameRefName(oldName, newName)

    Change the reference name a data source is under.

    ```matlab
    a.renameRefName("default", "flight-telemetry");
    ```

    Workbooks using this asset are updated to match. The tag
    filter, if any, is kept. Errors if oldName is not attached or
    newName already is.

    > **See also**
    >
    > [`nominal.Asset.datasources()`](https://dev.nominal.io/matlab/ref/Asset.md#nominal.Asset.datasources "nominal.Asset.datasources")

    ### fetch(channel, startTime, endTime, options)

    Read one channel as this asset sees it, as a timetable.

    ```matlab
    tt = a.fetch("rpm", t0, t1)
    tt = a.fetch("rpm", t0, t1, RefName="can", Buckets=2000)
    ```

    Reads through one of the asset’s data sources, so that
    source’s tag filter and time offset apply without being
    passed. Otherwise as nominal.Dataset.fetch.

    Parameters:
    :   - **startTime**

          Zoned datetime or int64 nanoseconds.
        - **endTime**

          Zoned datetime or int64 nanoseconds.

    Options:
    :   - **RefName** – Which data source. Defaults to “default”.
        - **Buckets** – Have Nominal decimate to roughly this many points.
        - **Tags** – Narrow further, if the source still holds several
          tag sets.

    Returns:
    :   *timetable* – One variable, named after the channel.

    > **See also**
    >
    > [`nominal.Asset.datasources()`](https://dev.nominal.io/matlab/ref/Asset.md#nominal.Asset.datasources "nominal.Asset.datasources"), [`nominal.Dataset.fetch()`](https://dev.nominal.io/matlab/ref/Dataset.md#nominal.Dataset.fetch "nominal.Dataset.fetch")

    ### getAttachedDataset(name)

    A dataset already on this asset, by name.

    ```matlab
    d = a.getAttachedDataset("telemetry");
    ```

    Read-only: it never creates or attaches anything.

    Errors when no dataset of that name is attached, and when more
    than one is. a.datasources() lists everything without erroring.

    Returns:
    :   *nominal.Dataset* – The attached dataset.

    > **See also**
    >
    > [`nominal.Asset.getOrCreateDataset()`](https://dev.nominal.io/matlab/ref/Asset.md#nominal.Asset.getOrCreateDataset "nominal.Asset.getOrCreateDataset"), [`nominal.Asset.datasources()`](https://dev.nominal.io/matlab/ref/Asset.md#nominal.Asset.datasources "nominal.Asset.datasources")

    ### getOrCreateDataset(name, refName, options)

    Ensure this asset has a dataset of that name.

    ```matlab
    d = a.getOrCreateDataset("telemetry");
    d = a.getOrCreateDataset("telemetry", "tlm");
    d = a.getOrCreateDataset("telemetry", AttachExisting=false);
    ```

    Dataset names are not unique in Nominal, so this resolves in
    three steps and prints which one it took:

    > 1. A dataset of that name already attached to this asset is
    >    returned as-is.
    > 2. Otherwise a dataset of that exact name elsewhere in the
    >    workspace is attached to this asset and returned.
    > 3. Otherwise one is created and attached.

    Step 2 finds the dataset a colleague already made, but it
    changes your asset based on a name match.

    Errors when several datasets share the name, listing their RIDs
    so you can pick one with client.datasetByRid.

    Parameters:
    :   **refName**

        The dataset’s name within this asset, used only
        when attaching. Omit it and a free one is chosen, as for
        addDataset.

    Options:
    :   **AttachExisting** – false skips step 2, going straight from
        step 1 to step 3. Defaults to true.

    Returns:
    :   *nominal.Dataset* – The dataset, attached to this asset.

    > **See also**
    >
    > [`nominal.Asset.addDataset()`](https://dev.nominal.io/matlab/ref/Asset.md#nominal.Asset.addDataset "nominal.Asset.addDataset"), [`nominal.Asset.getAttachedDataset()`](https://dev.nominal.io/matlab/ref/Asset.md#nominal.Asset.getAttachedDataset "nominal.Asset.getAttachedDataset")

    ### run(name, startTime)

    Create a run on this asset.

    ```matlab
    r = a.run("burn-12");                                 % starts now
    r = a.run("burn-12", datetime("now", TimeZone="UTC") - minutes(5));
    ```

    The run is left open. Close it with r.finish().

    Parameters:
    :   **startTime**

        Zoned datetime or int64 nanoseconds since the
        epoch. Omit it to start the run now. int64(0) is the
        epoch itself.

    Returns:
    :   *nominal.Run* – The new, open run.

    > **See also**
    >
    > [`nominal.Run.finish()`](https://dev.nominal.io/matlab/ref/Run.md#nominal.Run.finish "nominal.Run.finish")

    ### update(options)

    Apply metadata changes, returning the updated asset.

    ```matlab
    a2 = a.update(Name="x", Description="y", ...
                  Properties=struct(phase="burn"), ...
                  Labels=["a" "b"]);
    ```

    Options not passed are left alone. Labels and Properties
    REPLACE rather than merge: passing Labels discards whatever the
    asset had, so read a.Labels first and concatenate if you mean
    to add. setProperty changes one property and keeps the rest.

    Options:
    :   - **Name** – New display name.
        - **Description** – New description.
        - **Properties** – Struct of key-value pairs, replacing all of
          them. struct() clears them.
        - **Labels** – String array, replacing all of them. string.empty
          clears them.

    Returns:
    :   *nominal.Asset* – A new object with the changes applied. The
        original still shows the pre-update state.
