> This is part 1 of 2 of the full documentation (pages 1–100 of 124).
> The content is paginated: fetch every part to see all of it.
> Next part: https://docs.rhinofcp.com/llms-full.txt/1
> Page index: https://docs.rhinofcp.com/llms.txt

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
This site has an agentic ask interface you may use to query the documentation dynamically by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.rhinofcp.com/index.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

---

# About Rhino Federated Computing

General information about Rhino Federated Computing.

Rhino Federated Computing was founded with the vision of transforming how organizations collaborate with data. Rhino’s roots are in healthcare, where data are fragmented, heterogenous, and sensitive. This combination has historically made collaboration difficult, and has stunted the ability to improve health outcomes through data. Rhino is now changing that paradigm with Federated Computing.

* For more information Rhino Federated Computing and our work, check out the [Rhino Federated Computing Homepage](https://www.rhinofcp.com/).
* Take a look at our [Case Studies](https://www.rhinofcp.com/case-studies) as well as [White Papers and Publications](https://www.rhinofcp.com/publications) for examples on how our platform is being used.
* For compliance and control information, check out our [Trust Center](https://security.rhinofcp.com).

For more information, feel free to contact us at [support@rhinofcp.com](mailto:support@rhinohealth.com)


# Quick Start Guide

Learn the basics of Rhino FCP in less than two hours

Do you want to get started with Rhino Federated Computing Platform (FCP), but you only have a little time? Use this guide to get started quickly! In about 90 minutes, you'll learn how to create a project, access data and create a dataset, create and run code objects, and export data.

## Prerequisites

Before you begin:

* Make sure your account has been set up.
* Verify that the FCP Client is installed and online by checking the 'Your Rhino Client' section under 'Settings > My Account'. It should match the appearance in the screenshot below: ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/Zu6pz7DTEO5UE9tN2bzu/26100213965469)
* Your [environment has been configured](/getting-started/quick-start-guide/fcp-client-installation-and-environment-configuration).

{% hint style="info" %}
Contact Rhino Support for help to complete these tasks if needed.
{% endhint %}

## What is Rhino FCP?

Learn about Federated Computing and get a basic walkthrough of Rhino FCP in just five minutes. Read the following topics.&#x20;

* [The Rhino Federated Computing Platform (FCP)](/introduction-to-the-rhino-federated-computing-platform-fcp/the-rhino-federated-computing-platform-fcp)
* [Federated Datasets](/datasets/what-is-a-federated-dataset)
* [Federated Learning Overview](/introduction-to-the-rhino-federated-computing-platform-fcp/federated-learning-overview)

## Quick Start Steps

The following are the quick start steps.  Each step includes the amount of time it should take for you to complete task.

{% stepper %}
{% step %}

### Create a Project

Time to complete: 15 minutes

After installing the FCP client, you’ll need to create a project and set permissions. Click the following links to learn to do these things.

1. Read the following to learn more about the concept of a *project*: [What is a Project](/projects/what-is-a-project).
2. Watch the Create a Project video.

{% embed url="<https://app.guidde.com/share/playbooks/2YSj3FLqborxzBUiMPAVDw>" %}

3. Use the following links for step-by-step information on how to set up your new project and set up permissions.

* [Creating a New Project and Setting Up Permissions](/projects/creating-a-new-project)
* [Persona and Permissions Policies Reference](/projects/persona-and-permissions-policies-reference)

4. (Optional) If you want to dig a little deeper, read the following.  Otherwise, move on to the next step.

* [Typical Project Workflows](/projects/what-is-a-project#typical-project-workflow)
* [Viewing the Project Dashboard](/projects/project-overview-dashboard)
  {% endstep %}

{% step %}

### Access Data and Create a Dataset

Time to Complete: 30 Minutes

Now that your project has been set up, you’ll need to do two things:

* Access data using SFTP, SMB, S3 (AWS), GCP/CS or SQL.
* Create a dataset from DICOM, CSV, or SQL data sources.

Complete the following steps.

1. Learn about datasets by reading this aritcle: [What is a Dataset?](/datasets/what-is-a-dataset)
2. Learn how to access data from SMB, AWS (S3), or Google (GCP)/CS, by reading [Client Mounted Storage: How to access data in AWS S3, GCP CS or the SMB network files](/settings/mounting-storage-to-your-rhino-client).
3. Next, you'll need to access and import the data using SFTP.  To do this:
   1. Find your Rhino Client SFTP credentials in the Setting page, see more details in [Viewing Your Account, SFTP, Container and Artifact Settings](/settings/viewing-and-adjusting-your-settings).&#x20;
   2. Watch the Upload data via SFTP video.

{% embed url="<https://app.guidde.com/share/playbooks/vFFwPTuZNU1HdtqDyFkdo4>" %}

4. The next step is to access and import data from SQL.  To learn how to do this, watch the following video.

{% embed url="<https://app.guidde.com/share/playbooks/bZRFdQGsWVGexsgZwLf2S8>" %}

5. To import a dataset from data in your client (stored in /rhino\_data), do one of the following.
   1. To create a dataset from DICOM files, watch the following video.

{% embed url="<https://app.guidde.com/share/playbooks/aSBo3smBPHuAPhzHcFdM2d>" %}

&#x20;     b. To import a dataset from a CSV file, watch the following video.

{% embed url="<https://app.guidde.com/share/playbooks/67TpzqADC5jg7f5zqeLtnM>" %}

6. If you want to dig a little deeper, read the following.&#x20;

* [Importing, Viewing a Dataset's Configuration, and Exporting a Datasets](/datasets/registering-configuring-and-exporting-datasets)
* [How can I find my SFTP Server Name/IP Address, SFTP Username, SFTP Password, ECR Workgroup Repository Name, ECR Access Key ID, ECR Secret Access Key?](/settings/viewing-and-adjusting-your-settings)
* [Pushing Containers to the ECR](/getting-started/quick-start-guide/pushing-containers-to-the-ecr)
* [Using SQL to Extract Metrics and Import Data From a Database](/getting-started/quick-start-guide/using-sql-to-extract-metrics-and-import-data-from-a-database)
  {% endstep %}

{% step %}

### Create and Run Code Objects (Optional)

Time to complete: 15-45 minutes

After you’ve imported the data and created a data set, you can create code objects. This is an optional step.  If you don't want to do this, go to the next step (Export Data).

1. First, read the following to understand the basics of a code object.

* [What is a Code Object?](/creating-and-running-code-objects/what-is-a-code-object)

2. Next, watch the video for the code object that you'd like to create.  See the links below.

* [How to create a new Python Code Object](https://app.guidde.com/share/playbooks/kSd9QrBdKg93kfG8KKRR3h?origin=Xo3sT2LCAnYIwwxJmCUOfCQoS4n1)
* [How to create a new Generalized Compute Object](https://app.guidde.com/share/playbooks/cMpQPd8crrd49BqYnmSiUa?origin=Xo3sT2LCAnYIwwxJmCUOfCQoS4n1)
* [How to create a new Interactive Container Object](https://app.guidde.com/share/playbooks/4K7WPD2W3a2gMUSrngMgQL?origin=Xo3sT2LCAnYIwwxJmCUOfCQoS4n1)
* [How to create a new NVIDIA FLARE Code Object](https://app.guidde.com/share/playbooks/nTnNRJNCmkAYJHz9hxtWHR?origin=Xo3sT2LCAnYIwwxJmCUOfCQoS4n1)

3. If you want to dive deeper, see the following.&#x20;

* [Creating and Running a Python Code Object](/creating-and-running-code-objects/creating-and-running-a-python-code-object)
* [Creating and Running a New Generalized Compute Code Object](/creating-and-running-code-objects/creating-and-running-a-new-generalized-compute-code-object)
* [Creating and Running NVFlare Code and Running Inference](/creating-and-running-code-objects/creating-and-running-nvflare-code-and-running-inference)
* [Creating and Running Interactive Container Code](/creating-and-running-code-objects/creating-and-running-interactive-container-code)
  {% endstep %}

{% step %}

### Export Data

Time to complete: 5 minutes.

As our last step in this Quick Start Guide, you will learn how to export data.&#x20;

1. Watch the following video.

{% embed url="<https://app.guidde.com/share/playbooks/diWHTRPEHDxGGB5mnYefMw>" %}
{% endstep %}
{% endstepper %}

&#x20;            2\. If you want more information on how to export a dataset, see [Importing and Exporting Datasets to and from Your Network Storage](/getting-started/quick-start-guide/importing-and-exporting-datasets-to-and-from-your-network-storage).

## Next Steps

Now that you’ve completed the quick start guide, you are ready to explore other features of FCP or dig deeper into the ones you. Here are a few resources to get you started.

#### Other Features

Watch or read the following resources to learn more about how to use FCP.&#x20;

* [Viewing a Datasets UID](https://app.guidde.com/share/playbooks/jc2x7uUZq8mXTPsFkQDwcA?origin=Xo3sT2LCAnYIwwxJmCUOfCQoS4n1)
* [How to Set Up Pre-Approved Code](https://app.guidde.com/share/playbooks/cgLsY9ePCUBxoZDcEkexzT?origin=Xo3sT2LCAnYIwwxJmCUOfCQoS4n1)
* [Create a Secure Access List](https://app.guidde.com/share/playbooks/5CS7rgyfqUagg69aX7tvcP?origin=Xo3sT2LCAnYIwwxJmCUOfCQoS4n1)
* [Download Model Parameters](https://app.guidde.com/share/playbooks/gmDHucXpDML6FEXDqq7ywo?origin=Xo3sT2LCAnYIwwxJmCUOfCQoS4n1)
* [How to access model run logs](https://app.guidde.com/share/playbooks/nC1wiem2hJxS1ezKYL6zQf?origin=Xo3sT2LCAnYIwwxJmCUOfCQoS4n1)
* [How to use 3D Slicer on the Rhino Platform](https://app.guidde.com/share/playbooks/gemqngwELzSsRcwin8AjBZ?origin=Xo3sT2LCAnYIwwxJmCUOfCQoS4n1)

#### Other Resources

* To learn about how to programmatically access FCP, check the article [What is the Rhino SDK?](/rhino-sdk/what-is-the-rhino-sdk)
* To learn about new features and updates, check the article [Rhino FCP Release Notes](/release-notes/release-notes)
* To learn about Rhino, check the [Rhino Federated Computing Company Website](https://rhinofcp.com/)

## Getting Help

If you have received an error or run into any issues throughout the process, please reach out to <support@rhinofcp.com> for more assistance.


# FCP Client Installation and Environment Configuration

Access the FCP client installation guide and configure your local environment for Rhino FCP.

Use this page to install the FCP client and prepare your local environment.

## Access the FCP client installation guide

To access the client installation guide, follow [this link](https://security.rhinofcp.com/?requestAccessOpen=true\&requestedResources=67bfc0ee7b9933d5d87c0a2e) to request access.

## Install the required dependencies

{% stepper %}
{% step %}
Install these dependencies in your local development environment before you push code to ECR:

* [Docker](https://docs.docker.com/engine/install/)
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
* [AWS ECR Credential Helper](https://github.com/awslabs/amazon-ecr-credential-helper)
  {% endstep %}

{% step %}
Make sure the ECR Credential Helper is installed and configured correctly.
{% endstep %}

{% step %}
Run this command and confirm the version is at least `0.7.0`.

```bash
docker-credential-ecr-login -v
```

{% endstep %}

{% step %}
If the version is too old, the command fails, or nothing happens, reinstall the helper.
{% endstep %}

{% step %}
Download the latest executable for your platform from [the GitHub releases page](https://github.com/awslabs/amazon-ecr-credential-helper/releases).
{% endstep %}

{% step %}
Make the executable runnable.

```bash
chmod +x ./docker-credential-ecr-login
```

{% endstep %}

{% step %}
Copy it to a location on your `PATH`, such as `/usr/local/bin/`.
{% endstep %}

{% step %}
If needed, change the owner.

```bash
sudo chown root:root /usr/local/bin/docker-credential-ecr-login
```

{% endstep %}

{% step %}
Edit `~/.docker/config.json` and add `"credsStore": "ecr-login"` at the top level.

If the file does not exist or is empty, create it with this content:

```json
{
  "credsStore": "ecr-login"
}
```

{% endstep %}
{% endstepper %}

For more detail, see [Amazon ECR Docker Credential Helper configuration](https://github.com/awslabs/amazon-ecr-credential-helper#configuration).

## Open your user profile

{% stepper %}
{% step %}
Log in to Rhino FCP. For instructions, see [Log in to Rhino FCP](/getting-started/quick-start-guide/log-in-to-rhino-fcp)**.**&#x20;
{% endstep %}

{% step %}
In the bottom-left corner, select the circle with your initials or profile image.
{% endstep %}

{% step %}
This opens your user profile.
{% endstep %}
{% endstepper %}

## Retrieve your SFTP and ECR credentials

In your user profile, you can find:

* **Rhino Client IP Address** — use this as your SFTP server name or IP address.
* **SFTP credentials** — select **Reveal Credentials** to view your SFTP username and password.
* **ECR credentials** — select **Reveal Credentials** to view your ECR access key ID and secret access key.
* **Workgroup ECR repository** — use this as your ECR workgroup.

If any credentials are missing, contact <support@rhinofcp.com>.

## Configure AWS CLI for ECR access

{% stepper %}
{% step %}
Open a terminal and run:

```bash
aws configure
```

{% endstep %}

{% step %}
Enter these values when prompted:

```bash
aws configure
AWS Access Key ID [None]: YOUR_AWS_ACCESS_KEY_ID
AWS Secret Access Key [None]: YOUR_AWS_SECRET_ACCESS_KEY
Default region name [None]: us-east-1
Default output format [None]: json
```

Use these values:

* **AWS Access Key ID** — the access key ID from your FCP profile
* **AWS Secret Access Key** — the secret access key from your FCP profile
* **Default region name** — `us-east-1`
* **Default output format** — `json`
  {% endstep %}
  {% endstepper %}


# Hardware Configurations

The Rhino Client has been successfully installed on a wide range of hardware configurations, including dedicated rhino-provided servers (Rhino Boxes), VMs provisioned on existing servers on-prem, and cloud-based instances.

We have minimal requirements for hardware specifications, but they heavily depend on the kind of computation task the user is looking to perform (i.e. GPU is not required for a Rhino Client installation).

For cloud environments, we currently offer support for Amazon (AWS), Google (GCP), Azure, and Oracle (OCI).

For more information, please contact us at <support@rhinofcp.com>


# Log in to Rhino FCP

Learn how to sign in to Rhino FCP using your email and password, Google SSO, or Microsoft Azure SSO.

Navigate to <https://dashboard.rhinohealth.com/login>.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FYO30ylFx50Uk1SetkZ4s%2Fimage.png?alt=media&amp;token=e270b0a7-dbfd-4f64-a2b4-068d8deb009b" alt=""><figcaption></figcaption></figure>

There are three login options:

{% stepper %}
{% step %}

#### Username and password

* If this is your first login, you must change the temporary password from onboarding.
* If you did not receive credentials, contact <support@rhinofcp.com>.
  {% endstep %}

{% step %}

#### Google SSO

Click **Google Single Sign-on** and follow the prompts.
{% endstep %}

{% step %}

#### Azure SSO

Click **Azure Single Sign-on** and follow the prompts.
{% endstep %}
{% endstepper %}

If you're unable to sign in with an email/password account, try [resetting your password](/getting-started/quick-start-guide/resetting-your-rhino-fcp-password). If the issue persists, contact <support@rhinofcp.com>.


# Resetting Your Rhino FCP Password

Follow these steps to securely reset your Rhino FCP account password.

{% stepper %}
{% step %}
On the sign-in page, click **Can't login?**

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FqeCUTSHIbW1Q5r3q8MXW%2Fimage.png?alt=media&amp;token=04f90beb-9ee1-4a6b-8d1c-e774a7516620" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}
Enter the email associated with your account and click **Reset Password.**

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FEjEhHb6ZHbxcGpPmQkQX%2Fimage.png?alt=media&amp;token=79ce7ee2-2d70-4f87-9d18-396b221fbe91" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}
Check your email for a reset link and follow it to set a new password.

*Note: SSO users (Google/Azure) should sign in via those providers instead - this flow is for email/password accounts.*&#x20;
{% endstep %}
{% endstepper %}

If login fails, contact <support@rhinofcp.com>.


# The FCP Dashboard

A brief tour of the FCP Dashboard

To view the FCP dashboard, do the following.

{% stepper %}
{% step %}

### Log into FCP

The first page that appears is the FCP Dashboard.
{% endstep %}

{% step %}

### Open the projects view

The projects view is presented, which shows all Rhino projects currently associated with your account.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/so2Dule2obF7jqPgVHwk/24985146543005)
{% endstep %}

{% step %}

### Review each project tab

Each project tab contains the following information:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/1B8kXnBLU5MyXNecX188/24985146544029)

* Project status icons indicate whether specific items have been added to the project (green icon) or not yet added to the project (grey icons):

<table><thead><tr><th width="148.47265625">Icon</th><th>Meaning</th></tr></thead><tbody><tr><td><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/kv3606I4R8IyFAKZP4JW/24985146544925" alt="" data-size="original"></td><td>Collaborator(s)</td></tr><tr><td><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ilWl1tyHakNBBdOCQiM5/24985171629213" alt="" data-size="original"></td><td>Data Schema(s)</td></tr><tr><td><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/gr5LUBkiiF0gZwZKn5sg/24985146547229" alt="" data-size="original"></td><td>Dataset(s)</td></tr><tr><td><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/kLKBjmJblIDNKRkCEuOd/24985171631261" alt="" data-size="original"></td><td>Code Object(s)</td></tr><tr><td><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/1QRNdlyVhBJsZeUW6FkT/24985171632029" alt="" data-size="original"></td><td>Code Run(s)</td></tr></tbody></table>
{% endstep %}

{% step %}

### Use the left menu ribbon

There is also a menu ribbon on the left that has six icons.

|                                                                                                         |                                                                                                     |
| ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Icon                                                                                                    | Description                                                                                         |
| ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/30N44JExPhAWzFmgaY1j/24985171635101) | Home icon.                                                                                          |
| ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/l4hkIR8sV0iheowWqg3x/24985146550941) | Projects icon. Select it to see the projects you have access to.                                    |
| ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/l4cKr2WDXSJ4e7cFX90l/24985146551709) | Federated Datasets icon. Select it to see the federated datasets you have access to.                |
| ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/auMBSnqpifxKp7zo7Qky/24985171637917) | Notification icon. Select it to see a list of notifications of actions that occurred in the system. |
| ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/L0NZmLflMH9piyXtjGZT/24985171638557) | Help icon. Select this icon to see the documentation page.                                          |
| ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/rQ0hAFtPppzDIVWp9iFE/24985146561053) | Profile icon. Select it to see the your profile page.                                               |
| {% endstep %}                                                                                           |                                                                                                     |
| {% endstepper %}                                                                                        |                                                                                                     |


# Importing and Exporting Datasets to and from Your Network Storage

Explains how to import and export datasets on the Rhino FCP from selected storage platforms.

You can import and export datasets on the Rhino FCP to and from the following places:

* Amazon Web Services (AWS) S3
* Google Cloud Platform's (GCP) Cloud Storage (CS)
* Server Message Block (SMB) network file sharing protocol
* Azure Blob Storage

## Prerequisite

Before you can complete these instructions, you will need to mount the bucket or directory that contains the data you want to access. To do this, follow the steps in [Mounting Storage to Your Rhino Client](/settings/mounting-storage-to-your-rhino-client).

## Import Datasets

[Import a new dataset](/datasets/registering-configuring-and-exporting-datasets) and point the data location to your cloud storage data relative to the Client Mount Paths, see more detail in the Example below.

The integration is available at the workgroup level. Each workgroup can set up their own buckets or network share. Those buckets or network shares are not accessible to other workgroups.

### Example: Importing a file from AWS S3

Suppose you want to import file that is located in a S3 bucket. Here is how you would do this.

{% stepper %}
{% step %}
Find your data by navigating to your organization storage (click on the S3 arrow button)

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/oA3y0IzZviko0da4uEqC/30126360170141)
{% endstep %}

{% step %}
Find the data you want to import, e.g., **automapper/ORGDataSet.csv**.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/sj5QArycd6p3uXQawl7t/30126389110429)
{% endstep %}

{% step %}
Go to Settings > Client Mounted Storage.
{% endstep %}

{% step %}
In the Client Mounted Storage page, find the Client Mount Path that has the file, in this case **/rhino\_data/external/s3**. Click the blue rectangle next to it to copy it.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/AI94EAmHlO7CQH7OQBPs/30126389110685)
{% endstep %}

{% step %}
In the Datasets page, on the Overview tab, select **Import New Dataset** and follow the instructions in [Importing a New Dataset in the Rhino FCP GUI](/datasets/registering-configuring-and-exporting-datasets).
{% endstep %}

{% step %}
Set the data location as **Client Mounted Path/Relative Path to Your Data in S3**. Following the example in steps 2 and 4, it'd would look like as follows:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/AkzXFrZB0DN7DrhPBia3/30126389110941)
{% endstep %}

{% step %}
Select Import New Dataset.
{% endstep %}
{% endstepper %}

## Export Datasets

To export an existing dataset, follow the steps described in [Exporting a Dataset](/datasets/registering-configuring-and-exporting-datasets). The Rhino integration with your network storage should be configured as `Is read only` = `False` to allow your Rhino Client to save the exported files in your network storage. (If you are not sure if `Is read only` = `False` in your configuration, please contact the Rhino support team.)

Datasets will be exported to the file storage path set in the integration. For the AWS import example above, datasets would exported to your AWS S3 bucket named `my_bucket`.


# Registering Data to your Rhino Federated Computing Platform (FCP) Client using SFTP

Explains how to add data to your FCP Client using SFTP.

{% hint style="info" %}
NOTE: If you want to learn how to add data using SFTP, see [Adding Data to your FCP Client using Rhino SDK and SQL](/rhino-sdk/adding-data-to-your-fcp-client-using-rhino-sdk-and-sql).
{% endhint %}

### Registering Data to your Rhino FCP Client via SFTP

The process of moving data from your local environment to your Rhino FCP client using SFTP depends on the operating system of your local machine.

{% stepper %}
{% step %}

#### Getting data into your project on the FCP

Getting data into your project on the FCP generally requires two steps:

1. Transferring data into storage that your Rhino FCP Client can access. This step is most commonly done using SFTP, as described below.
2. Importing your data as a *Dataset* in your project. Once the data is accessible to the Rhino FCP Client, you can follow the steps in [Importing a New Dataset in the Rhino FCP GUI](/datasets/registering-configuring-and-exporting-datasets) to import the data into your project. One exception to this flow is when the data is extracted from a SQL database; in this case, extracting the data and creating the *Dataset* is done as a single step (described below)
   {% endstep %}
   {% endstepper %}

### Connecting to your Rhino FCP Client via SFTP from MacOS, Linux & Windows 10+

{% stepper %}
{% step %}

#### Open a terminal or command prompt

Open a terminal or command prompt on your respective operating system, and navigate to the folder where the data that you would like to upload are located.
{% endstep %}

{% step %}

#### Connect to your Rhino FCP Client via SFTP

* Retrieve your SFTP server IP and credentials from your Rhino FCP profile page. If you need a quick refresher, see [Viewing and Adjusting Your Settings](/settings/viewing-and-adjusting-your-settings).
* Connect to your Rhino FCP client via SFTP, by entering the following.

{% hint style="info" %}
Ensure to replace RHINO\_CLIENT\_IP\_ADDRESS in the below command with the credentials found in your profile.
{% endhint %}

```bash
> sftp rhinosftp@RHINO_CLIENT_IP_ADDRESS
```

{% endstep %}

{% step %}

#### Enter your SFTP password

Next, you will be prompted to enter your SFTP password, and if everything is entered properly you will be connected to your Rhino FCP client and your command line should change to look like the following:

```bash
sftp>
```

**For additional help with common commands within the SFTP terminal interface, check out** [**Common Commands when SFTP'ing Data**](#common-commands-when-sftping-data) **.**
{% endstep %}
{% endstepper %}

#### Connecting to your Rhino FCP Client via SFTP from Other Operating Systems

{% stepper %}
{% step %}

#### Install an SFTP client

To SFTP data from other Operating Systems to your Rhino FCP client, you will need to first install an SFTP client, like [Cyberduck](https://cyberduck.io/), [WinSCP](https://winscp.net/eng/index.php), etc.
{% endstep %}

{% step %}

#### Configure a new SFTP connection

Once your SFTP client has been installed, you can configure a new SFTP connection.

* Retrieve your SFTP server IP and credentials from your Rhino FCP profile page. If you need a quick refresher, see [Viewing and Adjusting Your Settings](/settings/viewing-and-adjusting-your-settings).
* If you are successfully connected to your SFTP client, you should see two separate panels, one displaying your local machines file system and a second showing your Rhino FCP client's filesystem.
  {% endstep %}

{% step %}

#### Upload your data

Using the STFP client to upload your data:

* On the local machine file system panel, navigate to the folder where your data is located.
* On the Rhino FCP client file system panel, navigate to where you would like to place the data.

  <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>It is recommended that you create folders for your datasets to keep things organized.</p></div>
* Drag the files from the local machine file system panel to the Rhino FCP client file system panel to upload your data to the Rhino FCP client server.
  {% endstep %}
  {% endstepper %}

### Common Commands when SFTP'ing Data

Use the following commands to create folders, navigate to different folders, view folder contents, and upload data.

**Create a new folder called DIRECTORY\_NAME within your Rhino FCP client**

```bash
sftp> mkdir DIRECTORY_NAME
```

**Change to the specified directory, DIRECTORY\_NAME within your Rhino FCP client**

```bash
sftp> cd DIRECTORY_NAME
```

**List all files within the current directory on your Rhino FCP client**

```bash
sftp> ls
```

**Upload the specified file FILE\_NAME on your local machine to the current directory of your Rhino FCP client**

```bash
sftp> put FILE_NAME
```

**Upload the folder and all of its contents on your local machine to the current directory of your Rhino FCP client**

```bash
sftp> put -r DIRECTORY_NAME
```

**Exit out of the SFTP connection**

```bash
sftp> exit
```


# Setting up and Changing ECR Credentials

Before starting, please ensure you have completed all the steps within [FCP Client Installation and Environment Configuration](/getting-started/quick-start-guide/fcp-client-installation-and-environment-configuration). This will ensure that your dependencies have been installed. It will also show you how to retrieve your ECR credentials. To setup or re-configure your ECR your will need your **AWS Access Key ID** and your **AWS Secret Access Key**.

#### Configuring your AWS CLI with your ECR Credentials

{% stepper %}
{% step %}

#### Open a terminal or command prompt.

Type in the command:

```bash
aws configure
```

{% endstep %}

{% step %}

#### Enter your credentials.

The code block below shows what you will need to enter at each step of the prompt.

```bash
> aws configure
AWS Access Key ID [None]: YOUR_AWS_ACCESS_KEY_ID
AWS Secret Access Key [None]: YOUR_AWS_SECRET_ACCESS_KEY
Default region name [None]: us-east-1
Default output format [None]: json
```

As a reminder of what each value should be:

* **AWS Access Key ID** - The AWS Access Key ID from your FCP profile
* **AWS Secret Access Key** - The AWS Secret Access Key from your FCP profile
* **Default region name** - us-east-1
* **Default output format** - json
  {% endstep %}
  {% endstepper %}


# Pushing Containers to the ECR

Provides technical information required to push containers to the Amazon ECR (Elastic Container Registry)

## Prerequisites

Complete the following before you begin.

* Before starting, complete all steps in [FCP Client Installation and Environment Configuration](/getting-started/quick-start-guide/fcp-client-installation-and-environment-configuration).  This will ensure that your dependencies have been installed, your AWS CLI has been configured and you are able to connect to your specific ECR workspace.
* Make sure that the docker daemon has been started as a prerequisite to pushing containers to the ECR.
* Make note of the following:
  * For both methods below, the variable **myapplication** is the name you are assigning your container. It can be whatever you choose to make it, but it must be unique to each container that is pushed to your ECR. We recommend adding some kind of versioning to your container name.
  * Your **workgroup\_repository\_name** can be found within your user profile. Read [Viewing and Adjusting Your Settings](/settings/viewing-and-adjusting-your-settings) for more details.

## Production Environment URIs

For users in our production environments pushing container images to their workgroup's repo on Rhino FCP, here are the URIs they need to use for AWS and GCP.

{% tabs %}
{% tab title="AWS" %}
In environments using a Rhino Orchestrator on AWS (currently [dashboard.rhinohealth.com](http://dashboard.rhinohealth.com/)):

```
{AWS_ACCOUNT_ID}.dkr.ecr.{AWS_REGION}.amazonaws.com/{WORKGROUP_REPO_NAME}:{TAG}
```

{% endtab %}

{% tab title="GCP" %}
In environments using a Rhino Orchestrator on GCP (currently [dashboard.rhinofcp.com](http://dashboard.rhinofcp.com/)):

```
{GCP_REGION}-docker.pkg.dev/{GCP_PROJECT_ID}/{WORKGROUP_REPO_NAME}/images:{TAG}
```

{% endtab %}
{% endtabs %}

### About Variables

Here are some details about the variables in the above templates:

* AWS\_ACCOUNT\_ID: Our production AWS account ID: `865551847959`
* AWS\_REGION: Our production AWS resources are in: `us-east-1`
* GCP\_REGION: Our production GCP resources are in: `europe-west4`
* GCP\_PROJECT\_ID: Our production GCP project ID: `rhino-health-prod`
* WORKGROUP\_REPO\_NAME: Configured for each workgroup in our database, and available for users in our dashboard under "Settings" -> "Containers & Artifacts".
* TAG: Arbitrarily chosen by users to label each container image. Unique in each workgroup's repo, and immutable, i.e. after pushing one container image with a given tag, no other may be pushed with that tag.

### Examples

The following examples show how to build and push containers, and also list and pull images.

{% tabs %}
{% tab title="Using the Rhino Util docker-push.sh" %}
The [docker-push.sh](https://github.com/RhinoHealth/user-resources/blob/main/rhino-utils/docker-push.sh) script can be found in the [user-resources](https://github.com/RhinoHealth/user-resources/) GitHub repository under the rhino\_utils folder. Using a terminal or command line navigate to the directory where your Dockerfile and other relevant files are found. Copy the docker-push.sh script into that folder and make it executable by running

```bash
chmod +x docker-push.sh
```

cd to the directory where your Dockerfile and other relevant code files are found.

```bash
./docker-push.sh <workgroup_repository_name> myapplication
```

{% endtab %}

{% tab title="Using Only Docker" %}
cd to the directory where your Dockerfile and other relevant files are found.

#### Build Container Command

```bash
DOCKER_BUILDKIT=1 docker build --platform linux/amd64 -t 865551847959.dkr.ecr.us-east-1.amazonaws.com/<workgroup_repository_name>:myapplication .
```

**Note: the period at the end of the above build command.**

#### Push Container Command

```bash
docker push 865551847959.dkr.ecr.us-east-1.amazonaws.com/<workgroup_repository_name>:myapplication
```

{% endtab %}
{% endtabs %}

#### List Local Images Example

```auto
> docker images 865551847959.dkr.ecr.us-east-1.amazonaws.com/<workgroup_repository_name>
```

#### List Remote Images Example

```auto
> aws ecr list-images --registry-id 865551847959 --repository-name <workgroup_repository_name>
```

#### Pull a Container Image from a Remote Repository Example

```auto
> docker pull 865551847959.dkr.ecr.us-east-1.amazonaws.com/<workgroup_repository_name>:myapplication
```


# Using SQL to Extract Metrics and Import Data From a Database

Metric extraction and import example.

{% hint style="info" %}
NOTE: Importing a cohort from SQL is currently only supported via the Rhino SDK.
{% endhint %}

## Prerequisites

1. Have an SQL DB that is open to connections from a Rhino Client, with access credentials for read-only access to this DB.
2. Have a project where you are either part of the project's lead workgroup and the DB is within your site, or where there is a collaborator in the project that has the DB at their site.
3. Ensure the required site-level permissions for SQL querying (Import and export Datasets, View Dataset analytics) are enabled for the site that has the DB.
4. Ensure that you have the Rhino SDK installed on your computer (*pip install rhino\_health*).

To import a Dataset directly from a SQL DB, follow the following steps:

## Import your Python Dependencies

```python
import rhino_health as rh
from rhino_health.lib.endpoints.sql_query.sql_query_dataclass import (
    SQLQueryImportInput,
    SQLQueryInput,
    SQLServerTypes,
    ConnectionDetails,
)
import getpass
```

Remember to change all lines with CHANGE\_ME comments above them in all the blocks below.

## Log into the Rhino SDK using your FCP Credentials

Your username will be the email address you log into the Rhino FCP platform with.

```python
print("Logging In")

# CHANGE_ME: MY_USERNAME
my_username = "MY_USERNAME"

session = rh.login(username=my_username, password=getpass.getpass())
print("Logged In")
```

## Get Supporting FCP Information Needed to Import Your Dataset

At this point, you will need the name of your project to retrieve your Project's UUID and subsequently your Workgroup UUID. You can also retrieve each object's UUID by following the instructions here: [How do I retrieve a UID?](/frequently-asked-questions/frequently-asked-questions-faqs#how-do-i-find-a-uid-for-an-object-data-schema-dataset-code-object-or-code-run)

```python
# CHANGE_ME: YOUR_FCP_PROJECT_NAME
project = session.project.get_project_by_name('YOUR_FCP_PROJECT_NAME')

workgroup = session.project.get_collaborating_workgroups(project.uid)[0]
```

## Connection Setup

When specifying the connection details, ensure that you provide the server\_type using the approved SQLServerTypes enum. This step ensures that your server is supported and compatible with the querying process. For a complete list of supported & compatible servers, refer to the SDK documentation here: [SQL Server Types](https://rhinohealth.github.io/rhino_sdk_docs/html/autoapi/rhino_health/lib/endpoints/sql_query/sql_query_dataclass/index.html#rhino_health.lib.endpoints.sql_query.sql_query_dataclass.SQLServerTypes). Replace the following variables below:

* *sql\_db\_user* - Your SQL database username. **Make sure that the user has read-only permissions**
* *sql\_db\_password* - Your SQL database password. **For better security, consider using an environment variable (e.g. os.getenv("DB\_PASSWORD")), or using getpass.getpass() to type in the password**
* *external\_server\_url* **-** Your SQL database url & port (i.e. "{url}:{port}")
* db\_name - Your SQL database name

```python
# CHANGE_ME: SQL_DATABASE_USERNAME
sql_db_user = "SQL_DATABASE_USERNAME"

# CHANGE_ME: SQL_DATABASE_PASSWORD
sql_db_password = "SQL_DATABASE_PASSWORD"

# CHANGE_ME: EXTERNAL_SERVER_URL
external_server_url = "EXTERNAL_SERVER_URL"

# CHANGE_ME: DB_NAME
db_name = "DB_NAME" # Replace this with your DB name.
connection_details = ConnectionDetails(
    server_user=sql_db_user,
    password=sql_db_password,

    # CHANGE_ME: Replace POSTGRESQL with one of the supported SQL Server Types outlined in the documentation above
    server_type=SQLServerTypes.POSTGRESQL,
    server_url=external_server_url,
    db_name=db_name
)
```

## \[Optional] Running Exploratory Queries

You can run SQL queries on the remote DB and receive aggregate statistics on the results of the query.

This involves two inputs.

1. Define the query you want to run (note that the RHP does not limit the SQL code that is run - always connect with a DB user that has read-only permissions)
2. Define the metrics you would like to calculate on the query results (See the SDK documentation for more information about what Metrics you can calculate: [rhino\_health.lib.metrics](https://rhinohealth.github.io/rhino_sdk_docs/html/autoapi/rhino_health/lib/metrics/index.html#module-rhino_health.lib.metrics))

```python
# CHANGE_ME: QUERY_STRING, Replace with query you want to run, e.g. "SELECT * FROM <your_table> WHERE <condition>"
starting_query = "QUERY_STRING"

# CHANGE_ME: ["METRICS"], # Define a list of metrics (e.g. [Mean(variable="Height")], etc.) outlined in the documentation above
metric_definitions = ["METRICS"]
```

### Define the Exploratory Query Run Parameters

When defining your SQLQueryInput, your project & workgroup will be used to validate permissions that were set at the project and site level (i.e. k-anonymization value). For more information on permissions, please refer to [Permissions](broken://pages/63383231bd8dd9d38f4611e8df98d25fffcca478).

```auto
query_run_params = SQLQueryInput(
    session=session,
    project=project.uid,
    workgroup=workgroup.uid,
    connection_details=connection_details,
    sql_query=starting_query,
    timeout_seconds=600,
    metric_definitions=metric_definitions
)
```

### Run the Exploratory Query

Run the query on your SQL database and get the metric results.

```python
response = session.sql_query.run_sql_query(query_run_params)
print(response.results)
```

## Import Query Results as a Dataset in the Rhino FCP

You can run SQL queries on the remote database and then have the results of the query stored as a Dataset on the Rhino FCP allowing further processing, analysis, etc.

This involves two inputs:

1. The query you want to run (note that the RHP does not limit the SQL code that is run - always connect with a DB user that has read-only permissions)
2. Data needed for the Dataset creation (e.g. Dataset name)

```python
# CHANGE_ME: QUERY_STRING, Replace with query you want to run to generate the data for the Dataset, e.g. "SELECT * FROM <your_table> WHERE <condition>"
query = "QUERY_STRING"

# CHANGE_ME: COHORT_NAME
cohort_name = "COHORT_NAME"

# CHANGE_ ME: False, Can be either True or False depending on whether the data being queried is de-identifed
is_data_deidentified = False #

# CHANGE_ME: SCHEMA_NAME & Possibly Version Number too. To auto-generate your schema, set this variable to None
dataschema_uid = session.project.get_data_schema_by_name('SCHEMA_NAME', project_uid=project.uid, version=1).uid
```

### Define the Dataset Import Parameters

Same as when defining your SQLQueryInput, when creating your SQLQueryImportInput, your project & workgroup will be used to validate permissions that were set at the project and site level (i.e. k-anonymization value). For more information on permissions, please refer to [Permissions](broken://pages/63383231bd8dd9d38f4611e8df98d25fffcca478).

```auto
import_run_params = SQLQueryImportInput(
    session=session,
    project=project.uid,
    workgroup=workgroup.uid,
    connection_details=connection_details,
    dataset_name=dataset_name,
    data_schema_uid=dataschema_uid
    timeout_seconds=600,
    is_data_deidentified=is_data_deidentified,
    sql_query=query
)
```

### Trigger the Query to Import your Dataset

Run the query on your SQL database and the results will be imported into the Rhino FCP as a Dataset.

```python
response = session.sql_query.import_dataset_from_sql_query(import_run_params)
print(response.results)
```


# Federated Training Example with Tabular Data

Federated Training Example

Tabular data, such as electronic health records (EHR) or financial transaction data, can be used for both horizontal and vertical federated learning applications. In this article, we will use XGBoost to demonstrate the Federated Training flow.

XGBoost ([website](https://xgboost.readthedocs.io/en/stable/)) is a software library for training gradient-boosted trees for both classification and regression machine learning problems. It is widely accepted as a performant, cost-effective model for numeric and categorical tabular data applications.

In the Horizontal FL setting, each collaborator has distinct data samples (rows), and each row has the same set of features and is labeled. This contrasts with Vertical FL, in which only one collaborator possesses labels and the features may differ between collaborators’ datasets.

To implement Horizontal FL with [XGBoost](https://github.com/RhinoHealth/user-resources/blob/0b4916c11a61f8764d1b2ab8c077beb9437a94fc/examples/nvflare/xgboost/xgboost-fhe/README.md), users may take advantage of tree-based model collaboration.

### Tree-Based Collaboration

Tree-based federated XGBoost is implemented as the following (see Figure 1):

1. Each collaborator performs 1 round of XGBoost training on their own data
2. Each collaborator shares the learned tree with the FL Server
3. The FL Server bags the locally-trained trees to produce a global model
4. The global model is shared with each of the collaborators
5. Each collaborator performs 1 round of boosting to obtain a new tree, and repeats…

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/B1JpZwPryMOVUWHX9vZc/26100731307421)

**Figure 1.** Illustrative schematic of tree-based collaboration for Federated XGBoost.

In this paradigm, only learned trees are ever shared with the FL Server/Rhino Orchestrator. The final set of aggregated trees (i.e., the final global model), can be stored on the FL server for future use (e.g., model evaluation on test sets and model inference).

For a comprehensive code example for how to implement Tree-Based XGBoost on the Rhino FCP, please visit our [user resources](https://github.com/RhinoHealth/user-resources/tree/main/tutorials/advanced/federated-training/xgboost-horizontal).


# The Rhino Federated Computing Platform (FCP)

The Rhino Federated Computing Platform (FCP) is a cutting-edge software platform designed specifically for distributed computing and federated learning across diverse data environments, both across organizational walls and within enterprise data silos. Our platform empowers data scientists, AI modelers, data engineers, and non-technical users to gather insights and run any computational workload on sensitive data while ensuring privacy, security, and governance are preserved.

### Features

Rhino FCP has many essential features, including:

* **Data Privacy and Accessibility, Facilitated Regulatory Compliance, and Enhanced Security Layers:** The paramount advantage of Federated Learning lies in its unwavering commitment to data privacy. By keeping data localized and never moving it from its source, Federated Learning ensures that sensitive information remains at rest within the secure boundaries of each institution, safeguarding patient privacy and confidential information. This privacy-preserving characteristic eliminates the need to centralize data, minimizing the risk of breaches and ensuring compliance with stringent data protection regulations. Rhino FCP, as a distributed MLOps platform, fortifies the security of Federated Learning by adding an additional layer of security through institutional firewalls. This can foster efficient multi-institutional research collaborations while adhering to stringent data protection regulations.
* **Secure Collaboration and Efficient Knowledge Sharing:** Federated Learning introduces a secure paradigm for collaboration across institutions. Data scientists can use Rhino FCP to collaboratively train machine learning models without sharing the raw data. The exchange of model parameters instead of data samples enables secure collaboration while upholding the confidentiality of sensitive information. Each participating institution installs a Rhino FCP client on their premises, granting them secure access to their data. These clients communicate with the centralized Rhino FCP server, acting as the orchestrating hub for distributed computing, ensuring data privacy remains intact within their firewalls. This not only enhances the development of advanced machine learning models but also ensures that data remains under appropriate governance, fostering trust and accountability within the ecosystem.

  This approach facilitates the creation of a global model that captures insights from diverse datasets, enhancing the overall performance and accuracy of the machine learning model. Rhino FCP's orchestration capabilities further streamline the knowledge-sharing process, allowing a seamless exchange of model parameters and iterative improvements.
* **Scalability, Diversity and Faster Iterative Learning:** The distributed nature of Federated Learning enables global scalability. This scalability fosters the development of robust and versatile machine-learning models that can cater to a wide range of scenarios and challenges within landscapes. Federated Learning's iterative training process accelerates the learning curve of machine learning models. With each iteration, the global model improves by incorporating collective knowledge from different sites. Rhino FCP integration with Tensorboard allows data scientists to visualize these improvements, enabling them to fine-tune the models more effectively and efficiently.
* **Dual User Interfaces:** The Rhino FCP provides two user interfaces to cater to diverse user preferences: an SDK and a Graphical User Interface (GUI). Users can choose between a user-friendly web-based graphical interface and a versatile Python library, both of which are built on top of the same robust backend API. This flexibility allows users to interact with the platform seamlessly according to their specific needs and expertise.
* **Distributed Data Annotation Workflows for Multi-Site Annotation Projects:** Through federated learning capabilities, the FCP enables collaborative data annotation across multiple sites, aiding in large-scale multi-site annotation projects while maintaining data privacy.
* **Workflow Enablement:** The Rhino FCP is designed to empower users to build customized workflows on top of the platform. By leveraging container images, users can securely run their custom code on distributed data. These container images are uploaded to an online repository, and the Rhino FCP server handles the orchestration of these containers across various participating sites.

### Use Cases

You can use Rhino FCP to perform tasks like:

* Building persistent pipelines with hospitals, biobanks, and other data partners to facilitate longitudinal analysis of multimodal datasets.
* Facilitating partnerships with other biopharmas, biotechs, and model developers to train, fine tune, and validate AI models while protecting IP.
* Bridging internal silos by allowing you to work with data distributed across geographies or cloud providers as if it were centralized.
* Analyzing real-time health data securely, detecting disease signals and linking datasets without transferring sensitive information​.
* Securely training models on diverse, distributed datasets, ensuring privacy, reducing bias, with the ability to test and validate efficacy across populations​.
* Enabling collaboration across sites to harmonize data, run analytics, and train models, advancing development of quality and safety measures while ensuring data privacy​.
* Creating, maintaining, and provisioning access to multimodal datasets residing across multiple data custodian organizations without requiring data transfer.
* Providing a platform that can process complex, confidential collaboration among multiple organizations where data sharing is challenging such as banks, regulators, and law enforcement.
* Improving models for credit scoring, capital markets, marketing, and more by working with previously inaccessible data partners.
* Generating real-time insights for regulators, credit rating agencies, risk managers, and investors.

You can use Rhino FCP to perform other tasks as well. It is the perfect fit for many use cases where federated learning, collaboration, security, and privacy are needed.

### Example Workflows

The Rhino FCP has been instrumental in enabling several groundbreaking workflows. Some exemplary use cases include:

* **Data Preprocessing and Harmonization Pipelines for Distributed Registries**: The FCP facilitates the seamless aggregation and preprocessing of distributed data across institutions, enhancing the efficiency and accuracy of distributed registry projects.
* **Distributed Data Annotation Workflows for Multi-Site Annotation Projects**: Through federated learning capabilities, the FCP enables collaborative data annotation across multiple sites, aiding in large-scale multi-site annotation projects while maintaining data privacy.
* **Federated ML Model Training and Validation Pipelines**: Data scientists can employ the FCP to fine-tune machine learning models using multi-site, distributed data. This capability ensures the development of robust models while keeping sensitive data securely within the respective institutions.


# Federated Learning Overview

## About Federated Learning

Federated Learning (FL), also known as Collaborative Learning, is a privacy-preserving machine learning technique that aims at training a machine learning algorithm, for instance, deep neural networks, on multiple local datasets contained in local nodes without explicitly exchanging data samples. The general principle consists of training local *model* s on local data samples and exchanging parameters (e.g., the weights of a neural network) between these local nodes at some frequency to generate a global *model* shared by all nodes.

There are several flavors of FL, including Centralized FL (where there is a single server coordinating and orchestrating the training process), Decentralized FL (where there is no centralized server and nodes are able to coordinate themselves to obtain a global *model*), and Heterogeneous FL (addressing the challenges of training across many heterogeneous clients with different hardware and networking capabilities).

Here is an example of a Centralized FL.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FHz2zKNaXeTDQgi3S6RPY%2FChatGPT%20Image%20Jul%209%2C%202026%2C%2006_14_21%20PM.png?alt=media&amp;token=926312d8-2421-4664-81bf-d166f0104107" alt=""><figcaption></figcaption></figure>

1. The process begins with a proposed *model* to be trained on local datasets at different sites.
2. The *model* is sent to each of the sites, where a number of iterations (epochs) of training are performed with the local data to generate a local *model* at each site.
3. The *model* parameters (e.g., weights of a neural network) are sent to the federated server, which merges these parameters (e.g., using Federated Averaging, Federated SGD, or other aggregation algorithms) to create a new version of the proposed *model*.
4. The new version of the proposed *model* is sent to the sites, repeating steps 2 and 3 a predefined number of times, or until the *model* has reached a certain performance threshold or the improvement achieved in each iteration has diminished below a certain threshold.
5. The latest version of the proposed *model* is defined as the global *model,* which is the output of the FL process.

Federated Learning was proposed by [Google in 2016](https://research.google/pubs/pub45648/) and has been increasingly used across many industries, from mobile devices (e.g., for predicting the next word typed on a mobile device keyboard), to IoT, autonomous vehicles, and even oil rigs.

Digital health is a natural fit for Federated Learning. Healthcare AI is being held back by a lack of access to clinically relevant data from a diverse patient population collected in different places and updated over time. The privacy-preserving characteristics of FL, where the underlying data is never moved, help overcome these challenges. The federated learning approach makes it possible for developers and researchers to collaborate across institutions without ever moving data, transferring ownership, or risking patient privacy. This approach to utilizing larger, more diverse datasets enables AI-based healthcare solutions to scale globally at an unprecedented pace. This powers AI *model* s that perform more consistently and improve the standard of care. With federated learning, data remains at rest behind institutional firewalls to provide an additional physical layer of security to preserve patient privacy.

## Advantages of Federated Learning

Federated Learning (FL) stands as a pioneering approach to machine learning with distinct advantages that have propelled it into diverse industries, including the healthcare domain. This section highlights the key benefits of adopting Federated Learning within the context of Rhino FCP.

#### Privacy Preservation

The paramount advantage of Federated Learning lies in its unwavering commitment to data privacy. By keeping data localized and never moving it from its *source*, FL ensures that sensitive information remains within the secure boundaries of each institution. This privacy-preserving characteristic eliminates the need to centralize data, minimizing the risk of breaches and ensuring compliance with stringent data protection regulations.

#### Secure Collaboration

Federated Learning introduces a secure paradigm for collaboration across institutions. With FL, data scientists can collaboratively train machine learning *model* s without sharing the raw data. The exchange of *model* parameters instead of data samples enables secure collaboration while upholding the confidentiality of sensitive information. Rhino FCP takes this advantage further by facilitating secure communication throughout the Rhino network architecture, ensuring data integrity throughout the collaboration process.

#### Efficient Knowledge Sharing

Federated Learning empowers institutions to pool their collective knowledge without centralizing their data. This approach facilitates the creation of a global *model* that captures insights from diverse datasets, enhancing the overall performance and accuracy of the machine learning *model*. Rhino FCP's orchestration capabilities further streamline the knowledge-sharing process, allowing a seamless exchange of *model* parameters and iterative improvements.

#### Scalability and Diversity

The distributed nature of Federated Learning enables scalability on a global scale. Institutions with diverse datasets can contribute their unique insights without compromising their data security. This scalability fosters the development of robust and versatile machine-learning *model* s that can cater to a wide range of scenarios and challenges within the healthcare landscape.

#### Faster Iterative Learning

Federated Learning's iterative training process accelerates the learning curve of machine learning *model* s. With each iteration, the global *model* improves by incorporating collective knowledge from different sites. Rhino FCP's integration with Tensorboard allows data scientists to visualize these improvements, enabling them to fine-tune the *model* s more effectively and efficiently.

#### Facilitating Regulatory Compliance

In the realm of healthcare, adhering to data privacy regulations is of utmost importance. Federated Learning introduces an approach that empowers *model* developers and data custodians to align with regulatory requirements seamlessly. By preserving data within institutional boundaries, Federated Learning makes it inherently easier for stakeholders to comply with data privacy regulations. This approach not only enhances the development of advanced machine learning *model* s but also ensures that data remains under appropriate governance, fostering trust and accountability within the healthcare ecosystem.

#### Enhanced Security Layers

Rhino FCP, as a distributed MLOps platform, fortifies the security of Federated Learning by adding an additional layer of security through institutional firewalls. The platform ensures that data remains at rest within the secured boundaries of each institution, safeguarding patient privacy and confidential information.

## Summary

Federated Learning redefines collaboration and knowledge sharing by preserving data privacy, enabling secure collaboration, and fostering efficient *model* improvements. Rhino FCP's integration of these advantages empowers data scientists to embark on groundbreaking research and innovation within the healthcare sector while upholding the highest standards of data security and compliance.


# Workflow Introduction

In the sections below, we outline various Federated Learning (FL) use cases in which the Rhino Federated Computing Platform (FCP) can be applied. The Rhino FCP enables numerous FL workflows, including horizontal and vertical FL model training from scratch, model fine-tuning, and model inference. Rhino allows one to adapt traditional machine learning and deep learning workflows, such as PyTorch, TensorFlow, Scikit-learn, XGBoost, and more, into a federated paradigm. Rhino FCP helps build the container image - using GUI or CLI that encapsulates adapted Nvidia Flare code, along with required dependencies. Then, pushes the container images to a private artifact registry, which makes the adapted training code available for model training and evaluation.

Here we describe a reference model training workflow for code development to code run using Rhino FCP product features and AI code development best practices.

1. Develop and test local training code - In a local development environment, develop model training code and test against a small dummy dataset - same schema that you have in a real environment.
2. Federated Trainer Code - Adapt the model training code to federated training. We will provide step by step guidance on how to code this step.
3. Create Federated Training Configuration - Multiple federated training tasks can be started to train different variations of the model, or use different optimization hyperparameters. With the Rhino FCP, one can run multiple experiments with different model versions, perform hyper-parameter tuning, store multiple checkpoints/params, halt model runs, or run validation using different model params and/or different validation datasets at sites.
4. Build the NVFlare container image: One may use Rhino FCP UI or SDK - auto containerization or utilize docker CLI to build and push containers into a container registry.
5. Run Model Training - Run model training code at the selected clients by choosing training and validation datasets. Under the hood, the Rhino FCP automates and orchestrates the entire Federated Training process.

The client performs the model training using its local training data. Then, the clients produce a new set of model parameters and send their updates to the Rhino Orchestrator FL server. The FL server aggregates the models from each FL client using the selected federated aggregation method ( e.g. FedAvg, FedProx) and produces a new global model. The global model, then, gets evaluated using validation data. One can track and visualize the global model metrics (loss, accuracy etc.) against validation data using TensorBoard. The process repeats until a specified number of federated rounds are finished or until some termination condition is met (e.g., convergence of the model weights).

For a hands-on example using XGBoost with tabular data, see [Part 1: Federated Training Example with Tabular Data](/getting-started/quick-start-guide/federated-training-example-with-tabular-data).


# Glossary of Terminology

Terms used in Rhino FCP

#### Amazon Web Services (AWS)

Amazon Web Services is a comprehensive cloud computing platform provided by Amazon. It offers a wide range of services, such as computing power, storage, databases, networking, analytics, machine learning, and more. AWS allows businesses and developers to access and utilize these services on a pay-as-you-go basis, avoiding the need for upfront infrastructure investment.

#### Applications Programming Interface (API)

An API is a set of protocols and tools that allow different software applications to communicate and interact with each other. It defines the methods and data structures that developers can use to create functionalities without needing to understand the internal workings of the systems they are integrating.

#### Dataset

A dataset refers to a group of individuals who share a common characteristic or experience within a specific timeframe. Datasets are often used in research and healthcare contexts to study patterns, trends, or effects that might be specific to that group.

#### Container

A container is a lightweight and portable software package that encapsulates an application, its dependencies, and its runtime environment. Containers provide a consistent and isolated environment for applications to run, ensuring that they can run consistently across different computing environments. They offer a standardized way to package, deploy, and manage software applications, making it easier to build, ship, and scale applications across different platforms and infrastructures.

#### Container Image

A container image is a standalone, executable package that includes everything needed to run a piece of software within a container. It contains the application code, runtime environment, libraries, and dependencies required for the application to function properly. Container images are typically built from a base image and can be easily shared, replicated, and deployed across different containerization platforms, allowing for consistent and reproducible application deployments.

#### Data Schema

A data schema is a structure or blueprint that defines the organization, format, and relationships of data within a database or data system. It defines the rules and constraints for how data is organized and represented, including the data types, fields, and their relationships. A *data schema* provides a standardized framework for data storage, retrieval, and manipulation, ensuring the consistency and integrity of the data.

#### De-identification (De-ID)

De-identification is the process of removing or modifying personal and sensitive information from data sets to protect individuals' privacy. This is typically done by removing identifiable elements such as names, addresses, and other direct identifiers while retaining the data's usefulness for analysis and research.

#### Digital Imaging and Communications in Medicine (DICOM)

DICOM is a standard format used for storing and transmitting medical images and related information. It enables medical devices and systems to share and interpret images, such as X-rays, MRI scans, and ultrasounds, in a consistent manner across different platforms.

#### Docker

Docker is an open- *source* platform that enables developers to automate the deployment and management of applications within containers. It provides a simple and efficient way to package applications and their dependencies into portable container images. Docker allows for easy and consistent deployment across different environments, ensuring that applications run reliably and consistently regardless of the underlying infrastructure. It has become a widely adopted tool in the software development industry, simplifying application deployment and promoting scalability and flexibility.

#### Elastic Container Registry (ECR)

Amazon Elastic Container Registry (ECR) is a fully managed container registry service provided by Amazon Web Services (AWS). It allows users to store, manage, and deploy container images, making it easier to run containerized applications on AWS. It provides secure and scalable storage for Docker container images and supports private repositories, access control, and image lifecycle management. Developers and organizations can use Amazon ECR to build, store, and share container images to streamline their container-based workflows.

#### Federated Learning (FL)

Federated learning is a privacy-preserving machine learning technique that trains *model* s across multiple decentralized devices or nodes while keeping the data localized. *Model* updates are exchanged between nodes rather than raw data, enhancing privacy and security and making them valuable in scenarios where data cannot be centralized or shared due to privacy concerns.

#### Institution

A hospital, medical imaging network, or other Rhino collaborator.

#### Payment Card Industry (PCI) Sensitive Data

Security-related information used to verify cardholders and authorize payment card transactions. (Adapted from the Payment Card Industry Security Standards Council glossary.)

#### Personally Identifiable Information (PII) Data

Information that can be used to identify or trace an individual’s identity, either on its own or when combined with other linked or linkable data.

#### Project

Within the Rhino System, a Project represents a collaboration between different entities with the goal of performing FL or validation of a *model*.

#### Protected Health Information (PHI)

Protected health information refers to any individually identifiable health-related information that is created, received, stored, or transmitted by healthcare providers. PHI includes personal details like names, medical records, test results, and other health-related data that is protected under regulations like HIPAA to ensure patient privacy.

#### Representational State Transfer REST (REST)

is an architectural style for designing networked applications that use HTTP as the communication protocol. It emphasizes a stateless client-server interaction where re *source*s (e.g., data) are identified by URLs, and the client can perform actions (GET, POST, PUT, DELETE) on these re *source* s using the standard HTTP methods.

#### Rhino Box

A physical server that is provided to an institution by Rhino for the purposes of running the Rhino Client.

#### Secure File Transfer Protocol (SFTP)

Secure File Transfer Protocol (SFTP) is a network protocol that provides a secure and encrypted method for transferring files between remote systems. SFTP is commonly used as a secure alternative to FTP (File Transfer Protocol) and allows for secure file transfers over SSH (Secure Shell) connections. It ensures data confidentiality and integrity during file transfers, making it suitable for secure file exchange and remote file management.

#### Sensitive Data

Information that must be kept confidential because unauthorized access could pose risks. This includes categories such as Personally Identifiable Information (PII), Protected Health Information (PHI), Payment Card Industry (PCI) data, and other personal data protected by various regulations.

#### Sensitive Dataset

A dataset that contains at least one sensitive field.

#### Sensitive Field

A field within a dataset that may contain sensitive data.

#### Software Development Kit (SDK)

A software development kit is a set of tools, libraries, documentation, and guidelines provided by a software company to developers. It enables developers to build applications or integrations that work with the company's software, platform, or hardware. SDKs simplify the development process by providing pre-built components and standardized methods.

#### User Interface (UI)

A user interface is the visual and interactive part of a software application or system that users interact with. It includes elements such as menus, buttons, forms, and visual displays that allow users to input data, make selections, and navigate through the software. The goal of a well-designed UI is to provide a user-friendly experience and efficient interaction.

#### Virtual Private Cloud (VPC)

A virtual private cloud is a cloud computing environment within a public cloud provider's infrastructure that provides isolated and customizable re *source* s. It enables users to create private networks, virtual servers, storage, and other services while maintaining control over security settings, IP addresses, and network configurations.


# What is a Project?

A brief explanation of basic project concepts

A **project** in the Rhino Federated Computing Platform (FCP) is the main way to organize a data analysis or research effort. It gives you one secure place to manage work, people, and resources.

A project acts as a container for the key parts of your work, including Datasets, Code Objects, Code Runs, Collaborators, and Data Schemas. This structure helps teams work together while protecting data privacy and security.

## Key Components of a Project

Here are the key components of a project.

* **Name:** The name of the project.
* **Description:** The description of the project.
* **UUID:** The unique identifier for a specific project within the Rhino FCP.
* **Permissions Policy:** A set of project permissions and privacy settings that can be applied to actions at the project and site levels.&#x20;
* **Data** **Schema(s):** Data schemas play a crucial role in projects where specific data models need to be enforced. This feature allows users to define the structure and relationships within the data for standardized analysis.&#x20;
* **Dataset(s):** Datasets that participate in the project. A project on the FCP can include Datasets from multiple collaborating sites. Further information about datasets is covered later in the [Datasets section](/datasets/what-is-a-dataset) of the User Guides.
* **Code:** Code objects are the computational units within your project. A Code Object can be as simple as a single line of Python code or as complex as a multi-file pipeline for federated learning.
* **Code Runs:** Code Runs provides you with access to runtime logs and additional information about the executions of your code.&#x20;
* **Collaborator(s):** Collaborators are key contributors to your project. You can invite external partners to participate, fostering a collaborative environment where insights and expertise can be shared securely.&#x20;

## Typical Project Workflow

After logging in, you will arrive at the FCP Dashboard, which serves as the central location for project management. A typical project follows the steps outlined below. Depending on the scope and pace of your work, this process may take days, weeks, or months.

{% stepper %}
{% step %}

### Project Creation

From the dashboard, you can create a new project. Provide a clear name and description that define the project’s purpose and scope. You must also configure the project and site permissions.
{% endstep %}

{% step %}

### Define Data Schemas (Optional)

If your project requires standardized data models, configure data schemas to enforce structured data relationships and formats.
{% endstep %}

{% step %}

### Add Datasets

Depending on your project's scope, import the relevant datasets. These datasets will be the foundation for your analyses and initiatives.
{% endstep %}

{% step %}

### Incorporate Code

Integrate your code objects — machine learning models, preprocessing code, or analysis algorithms — to drive the core functions of your project.
{% endstep %}

{% step %}

### Manage Code Runs

Monitor and assess the outcomes of your Code Runs within the designated Code Runs section. This is where you can access logs and insights from the computational executions.
{% endstep %}

{% step %}

### Invite Collaborators

You can invite collaborators to participate in the project at any time. This supports knowledge sharing and allows contributors to work together securely. Depending on the project permissions policy, collaborators may import their own datasets and contribute their own code objects.
{% endstep %}

{% step %}

### Managing and Monitoring Projects

Once a project has been created, the FCP Dashboard provides a range of tools and features to support ongoing project management. These include cohort analytics, workflow orchestration, and federated learning management, which help teams manage work efficiently and collaborate effectively.
{% endstep %}
{% endstepper %}


# Project Overview Dashboard

A walk-through of the project overview dashboard

When you select a project, the Project Overview dashboard is shown.  The dashboard has two sections:  **Projects Steps** and **Recent Activities**.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FT8DKNbM3olB84IZfPTxu%2FScreenshot%202026-06-30%20at%205.32.21%E2%80%AFPM.png?alt=media&amp;token=a84989ae-c094-4d78-a505-6cb626da00e0" alt=""><figcaption></figcaption></figure>

## Project Steps

Project steps show the six major components of a typical project: Project Definition, Collaborator, Data Schemas, Datasets, Code Objects, and Code Runs.  As a component's project items are completed, the icon turns blue and the text below it is updated with the number of project items completed.  Steps that have not been implemented remain gray.  Note that not all projects have all six steps implemented.  For example, you might have a project that does not have collaborators or a code run.

* **Project Definition:** This step was completed when the project was created.
* **Collaborator:** Indicates whether one or more individuals or organizations were added to the project.  The number in parenthesis below the icon shows the number of collaborators (individuals or organizations) that are part of the project.  Once collaborators are added, team members that have the appropriate permissions can work with collaborators to perform federated actions. &#x20;
* **Data Schemas:** Shows whether there are one or more Data Schemas or structures for the data  to be imported as a cohort into the project. The number in parenthesis below the step icon shows the number of data schemas in the project. &#x20;
* **Datasets:** Indicates whether one or more datasets have been imported into the project.  Datasets are often used for analysis, annotation, or ML model training.  The number in parenthesis below the step icon indicates how many datasets are in the project.
* **Code:**  Shows how many code objects are in the project.  A code object is the basic computational building block of a project.  A Code Object can be as simple as a single line of Python code intended to run on a single input dataset, or as complex as a fully custom pipeline for federated training across multiple sites. The number in parenthesis below the step icon indicates how many code objects are in the project.&#x20;
* **Code Runs:** Indicates how many code runs are in the project.  A code run is the execution of a code object.  Logs and output datasets are produced during this step. The number in parenthesis below the step icon indicates how many code runs are in the project.&#x20;

## Recent Activities

The Recent Activities section shows actions that have been performed within the project. Each item shows what was performed, who performed it, and when the activity happened. This is a great traceability tool.


# Creating a New Project

How to Create a New Project, Specify Permission Policies, and Edit Permission Policies

In the Rhino Federated Computing Platform (FCP), a Project forms the core organizational unit that encapsulates a distinct data analysis or research initiative. To create a project, you'll need to ensure that you are logged into Rhino FCP, then enter the details of the project, including permissions.

## Prerequisites

Before you begin, complete the following.

* Ensure that you have a login for Rhino FCP.
* Optionally, review the site level and project level permission information (see the information later in this article) so that you'll know what to select when you create your project.

## Logging into Rhino FCP

To log into the Rhino FCP, navigate to the login page in your web browser. There are three ways to login to the FCP.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FXVS02fw4uOrqEJOi6DDP%2Fimage.png?alt=media&amp;token=2f2bd90f-27e7-4f62-b635-50414d6c7951" alt=""><figcaption></figcaption></figure>

You can log into Rhino FCP using three different methods.

* To log in using a user name and password, enter the information in the login screen. If this is your first time logging into the platform, you will be required to change your password from the temporary one sent to you during onboarding.
* To log in using Google Single Sign-on (SSO), click the button and follow the prompts to log in with your Google credentials.
* To log in using Azure Single Sign-on (SSO), click the button and follow the prompts to log in with your Azure credentials.
* To reset your password, click **Can't login?** on the sign-in screen, enter the email associated with your account, and click **Reset Password**. Check your email for a reset link to set a new password.

{% hint style="info" %}
**If you have not received your credentials, are not prompted to change your password, or if you encounter other issues while attempting to login, please contact** [**support@rhinohealth.com**](mailto:support@rhinohealth.com)**.**
{% endhint %}

## Creating a New Project (Step-by-Step Instruction)

To create a new project, complete the following:

{% stepper %}
{% step %}

### Select Projects

Select **Projects** on the left side of the screen to open the Projects screen.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/YQd9jOuTgzbBLxKVdwA6/29850507233053)
{% endstep %}

{% step %}

### Open the Create a New Project screen

Select the **Add New Project** button in the upper right corner of the screen to open the **Create a New Project** screen.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/Aip2OdnwH8W4obnxd8hX/29850507237277)
{% endstep %}

{% step %}

### Add project details

Add a name and a description.
{% endstep %}

{% step %}

### Expand Permissions Policy

Select **Permissions Policy** to expand the screen.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/moUjZ5T6O4XzU2fubFg4/29850507237533)
{% endstep %}

{% step %}

### Configure permissions

Project leads configure permissions during project creation. There are two levels of project permissions:

* **Project-level permissions:** These are privacy settings and permissions configured at the project level for all participants. Rhino configures default project-level permissions, but the project lead can modify them.

Select the following expandable box to see project-level permission policy definitions.

<details>

<summary><strong>Project-Level Permission Definitions</strong></summary>

<table><thead><tr><th>Action</th><th width="223.66796875">Description</th><th>Default Policy</th></tr></thead><tbody><tr><td>Differential Privacy Setting</td><td>(Privacy filter) - Control the level of noise (if any) is added to data when calculating metrics:<br>- <strong>None</strong>: Noise is never added.<br>- <strong>Low</strong>: Noise is only added when calculating percentiles.<br>- <strong>Medium</strong>: Noise is added for percentiles and other standard metrics when the number of unique values is small.<br>- <strong>High</strong>: Noise is always added when calculating metrics.</td><td>Medium</td></tr><tr><td>K-Anonymization Parameter</td><td>(Privacy filter) - Subgroups smaller than K will be excluded from summary statistics</td><td>5</td></tr><tr><td>Download Model Parameters</td><td>Download model parameters for models trained as part of the project.</td><td>PLA, PLM</td></tr><tr><td>Hide Collaborators</td><td>Indicates whether to allow collaborators in this project to view information (e.g. names, activities) about other collaborators. Selecting No allows the collaborators to see each other's information. Selecting Yes, hides collaborator information from other collaborators, including what would be shown in the recent activities list, notifications, and the list of collaborators in the project. Note that if you hide collaborators, and you set other permissions to include CA and/or CM, you will see a message indicating that CA/CM cannot be used in permissions when the project is set to use hidden collaborators.</td><td>No</td></tr><tr><td>Manage Code Objects</td><td>Create, modify, and remove Code Objects.</td><td>PLA, PLM</td></tr><tr><td>Manage Code Runs</td><td>Modify and remove Code Runs associated with this site.</td><td>PLA, PLM</td></tr><tr><td>Manage Data Schemas</td><td>Create, modify, and remove Data Schemas in the project.</td><td>CA, CM, PLA, PLM</td></tr><tr><td>Require Confidential Computing</td><td>Setting this permission to Yes allows your code to run on a Rhino Client within a Trusted Execution Environment(s) (TEEs). For the list of supported confidential computing VMs, see <a href="/settings/confidential-computing">Confidential Computing Supported Environments and Permission Settings</a>.</td><td>No</td></tr><tr><td>Run Code</td><td>Run code in the project.</td><td>PLA, PLM</td></tr></tbody></table>

</details>

* **Site-level permissions:** These permissions are configured at the site level and can be reviewed and adjusted by each collaborator. Site-level permissions require approval before a collaborator can join the project. Project leads and other authorized personnel can create templates for site-level permissions.

  \
  Templates streamline the process of customizing site-level permissions. For example, a site might want to enforce k-anonymization with a k-parameter of 100. Including this setting in a template ensures consistency across new projects. You will know if you have templates available if an option for templates appears on the screen.&#x20;

  * If the expanded **Create a New Project** screen does not display template options, the default template is available, and you can modify project-level and site-level permission policies as needed.
  * If the expanded **Create a New Project** screen does display template options, select the desired permission policy template. The default template is displayed.

Select the following expandable boxes to see site-level permission policy definitions and notes.

<details>

<summary><strong>Site-Level Permission Definitions</strong></summary>

<table><thead><tr><th>Actions</th><th width="227.8046875">Description</th><th>Default Policy</th></tr></thead><tbody><tr><td>Manage This Site's Datasets</td><td>Import, export, modify, and remove Datasets associated with this site</td><td>MA, MM</td></tr><tr><td>Manage Data Mappings</td><td>Create, modify, and remove data mappings and vocabularies from this site.</td><td>PLA, PLM, MA, MM</td></tr><tr><td>Manage Secure Access Lists</td><td>Create, modify, and remove Secure Access Lists for Datasets from this site</td><td>MA, MM</td></tr><tr><td>Manage This Site's Code Runs</td><td>Modify and remove Code Runs associated with this site</td><td>MA, MM</td></tr><tr><td>Pre-approved Code Only</td><td>Only allow pre-approved code to be run on your site's data. You will be able to specify/update the pre-approved code on this page</td><td>No</td></tr><tr><td>Run Code On This Site</td><td>Run code on Datasets from this site</td><td>MA, MM, PLA, PLM</td></tr><tr><td>Share Secure Access Lists</td><td>Share Secure Access Lists for Datasets from this site</td><td>MA, MM</td></tr><tr><td>View Client-Side Logs</td><td>View logs from code run on Datasets from this site</td><td>MA, MM, PLA, PLM</td></tr><tr><td>View Code Objects and Code Runs</td><td>Determines who can view workgroup code objects and code runs. Users without this permission only see code objects and code runs published to all project participants. See note below this table for more details.</td><td>CA, CM, MA, MM, PLA, PLM</td></tr><tr><td>View Datasets and Data Schemas</td><td>Allows you to view all workgroup Datasets and Data Schemas. Anyone without these permissions will only be able to view Datasets and Data Schemas that have been published to all project participants.</td><td>CA, CM, MA, MM, PLA, PLM</td></tr><tr><td>View Dataset Analytics</td><td>View aggregated analytics and metrics for Datasets from this site</td><td>MA, MM, PLA, PLM</td></tr><tr><td>View Datasets via Secure Access</td><td>Access data from this site via zero-footprint viewers (e.g. tabular data viewer, and interactive containers, OHIF)</td><td>MA, MM</td></tr><tr><td>View Client Side Logs with Sensitive Data</td><td>View logs from code runs on sensitive datasets from this site. This is included because code runs could write sensitive data to logs.</td><td>MA, MM</td></tr><tr><td>View Sensitive Datasets via Secure Access</td><td>Access sensitive data from this site via zero-footprint viewers such as a tabular data viewer and OHIF or interactive containers. This also includes fields marked as 'local only'.</td><td>MA, MM</td></tr></tbody></table>

</details>

<details>

<summary><strong>Site-Level Permission Definitions Notes</strong></summary>

{% hint style="info" %}
NOTE: If the personas for the View Code Objects and Code Runs setting are the default (PLA, PLM, MA, MM, CA, CM), then all members of the workgroup can see code objects and code runs. If you initially remove personas from the list, all code object and run versions will start as unpublished and are only visible to the included personas. Code runs are only visible to users who can see the code object.

You can change personas as you would for any other permissions setting. The personas in the permission list must include an MA or MM persona so site members can view and publish their own objects and runs.

The workgroup of the code object is the primary workgroup of the person who created the code object.

The workgroup of the code run is the primary workgroup of the person who triggered the code run.

Note: Code Runs are only visible to users for whom the Code Object is also visible. One edge case in which this might not automatically happen, is when there is an unpublished Code Object created by Collaborator A, with “View Code Object/Run” permissions set to PLA, PLM, MA, MM (so without CA/CM). And then a user in the Project Lead workgroup (who can view the Code Object) runs the Code Object. If the Project Lead’s “View Code Object/Run” settings are set to full visibility, then the Code Run would be visible to everyone in the project. However, users from another collaborator won’t be able to see the Code Object since it’s unpublished, and thus aren’t allowed to see the Code Run.
{% endhint %}

</details>
{% endstep %}

{% step %}

### Create the project

Once you've adjusted the permission policies, click the **Create Project** button to create your project. The project appears on the **Projects** screen.
{% endstep %}
{% endstepper %}

## Editing Site-Level Permission Policies

To edit site-level permission policies, complete the following steps.

{% stepper %}
{% step %}

### In the project whose permissions you want to edit

Select **Collaborators** from the menu to the left.
{% endstep %}

{% step %}

### Select Permission Policy

Select **Permission Policy** option near the top of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/QePbRGwP9ieb8fV7p1OO/34676259766301)
{% endstep %}

{% step %}

### Select the down arrow next to the Site Level section

Select the down arrow next to the **Site Level** section, near the bottom of the page. Site-level permission policies appear.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/9MYD7cqJABIITGA6949j/34676259766941)
{% endstep %}

{% step %}

### Select the Edit button

Select the **Edit** button.
{% endstep %}

{% step %}

### Make the changes

Make the changes to the Privacy Parameters and Actions, as needed.  If needed, review the permission policy details in the following expandable box.

<details>

<summary><strong>Site-Level Permission Definitions</strong></summary>

<table><thead><tr><th>Actions</th><th width="227.8046875">Description</th><th>Default Policy</th></tr></thead><tbody><tr><td>Manage This Site's Datasets</td><td>Import, export, modify, and remove Datasets associated with this site</td><td>MA, MM</td></tr><tr><td>Manage Data Mappings</td><td>Create, modify, and remove data mappings and vocabularies from this site.</td><td>PLA, PLM, MA, MM</td></tr><tr><td>Manage Secure Access Lists</td><td>Create, modify, and remove Secure Access Lists for Datasets from this site</td><td>MA, MM</td></tr><tr><td>Manage This Site's Code Runs</td><td>Modify and remove Code Runs associated with this site</td><td>MA, MM</td></tr><tr><td>Pre-approved Code Only</td><td>Only allow pre-approved code to be run on your site's data. You will be able to specify/update the pre-approved code on this page</td><td>No</td></tr><tr><td>Run Code On This Site</td><td>Run code on Datasets from this site</td><td>MA, MM, PLA, PLM</td></tr><tr><td>Share Secure Access Lists</td><td>Share Secure Access Lists for Datasets from this site</td><td>MA, MM</td></tr><tr><td>View Client-Side Logs</td><td>View logs from code run on Datasets from this site</td><td>MA, MM, PLA, PLM</td></tr><tr><td>View Code Objects and Code Runs</td><td>Determines who can view workgroup code objects and code runs. Users without this permission only see code objects and code runs published to all project participants. See note below this table for more details.</td><td>CA, CM, MA, MM, PLA, PLM</td></tr><tr><td>View Datasets and Data Schemas</td><td>Allows you to view all workgroup Datasets and Data Schemas. Anyone without these permissions will only be able to view Datasets and Data Schemas that have been published to all project participants.</td><td>CA, CM, MA, MM, PLA, PLM</td></tr><tr><td>View Dataset Analytics</td><td>View aggregated analytics and metrics for Datasets from this site</td><td>MA, MM, PLA, PLM</td></tr><tr><td>View Datasets via Secure Access</td><td>Access data from this site via zero-footprint viewers (e.g. tabular data viewer, and interactive containers, OHIF)</td><td>MA, MM</td></tr><tr><td>View Client Side Logs with Sensitive Data</td><td>View logs from code runs on sensitive datasets from this site. This is included because code runs could write sensitive data to logs.</td><td>MA, MM</td></tr><tr><td>View Sensitive Datasets via Secure Access</td><td>Access sensitive data from this site via zero-footprint viewers such as a tabular data viewer and OHIF or interactive containers. This also includes fields marked as 'local only'.</td><td>MA, MM</td></tr></tbody></table>

</details>

<details>

<summary><strong>Site-Level Permission Definitions Notes</strong></summary>

{% hint style="info" %}
NOTE: If the personas for the View Code Objects and Code Runs setting are the default (PLA, PLM, MA, MM, CA, CM), then all members of the workgroup can see code objects and code runs. If you initially remove personas from the list, all code object and run versions will start as unpublished and are only visible to the included personas. Code runs are only visible to users who can see the code object.

You can change personas as you would for any other permissions setting. The personas in the permission list must include an MA or MM persona so site members can view and publish their own objects and runs.

The workgroup of the code object is the primary workgroup of the person who created the code object.

The workgroup of the code run is the primary workgroup of the person who triggered the code run.

Note: Code Runs are only visible to users for whom the Code Object is also visible. One edge case in which this might not automatically happen, is when there is an unpublished Code Object created by Collaborator A, with “View Code Object/Run” permissions set to PLA, PLM, MA, MM (so without CA/CM). And then a user in the Project Lead workgroup (who can view the Code Object) runs the Code Object. If the Project Lead’s “View Code Object/Run” settings are set to full visibility, then the Code Run would be visible to everyone in the project. However, users from another collaborator won’t be able to see the Code Object since it’s unpublished, and thus aren’t allowed to see the Code Run.
{% endhint %}

</details>
{% endstep %}

{% step %}

### Save the changes

When finished, select the **Save** button from the bottom right part of the screen to save the changes.
{% endstep %}
{% endstepper %}

## Getting Help

If you have received an error or run into any issues throughout the process, please reach out to <support@rhinofcp.com> for more assistance.


# Persona and Permissions Policies Reference

Descriptions of each persona and permission policies

Permission polices are vital tools to master access control in collaborative settings. Permissions allow you to optimize data security and workflow efficiency through effective user permission management. &#x20;

When defining a new project, you will need to specify which user personas can perform actions at both the **Project** and **Site** levels. You will also need to indicate whether certain parameters (such as whether collaborators on a project can view certain information about another collaborator).  While project-level and site-level permissions are set up when you create a project, site-level permissions can be edited after project creation.

## Personas

User personas define a set of predefined privileges and access rights that are assigned to a particular category of users within the Rhino FCP. These roles streamline permission management by grouping users based on their responsibilities, ensuring that each user has appropriate access levels to perform their tasks while maintaining security and data integrity.

| Persona                    | Description                                                                             |
| -------------------------- | --------------------------------------------------------------------------------------- |
| PLA - Project Lead, Admin  | The workgroup admin for the workgroup that created the project                          |
| PLM - Project Lead, Member | Every non-admin member of the workgroup that created the project                        |
| MA - My site, Admin        | The workgroup admin for your workgroup (relevant only to site-level permissions)        |
| MM - My site, Member       | Every non-admin member from your workgroup (relevant only to site-level permissions)    |
| CA - Collaborator, Admin   | The workgroup admin for a workgroup that has been invited to collaborate on a project   |
| CM - Collaborator, Member  | Every non-admin member of a workgroup that has been invited to collaborate on a project |

## Project-Level and Site-Level Permission Policies

When defining a new project, you will also need to specify which user personas can perform actions at both the **Project** and **Site**.  You cannot edit project-level permission policies after project creation.  But, you can edit site-level permission policies.

### Project-Level Permission Policies

Project-Level permissions policies define who has the ability to perform certain actions within the Project. It also allows you to define certain project-level parameters. The Project Lead can enable and limit access to certain functions for specific personas in the Project.&#x20;

<table><thead><tr><th>Action</th><th width="223.66796875">Description</th><th>Default Policy</th></tr></thead><tbody><tr><td>Differential Privacy Setting</td><td>(Privacy filter) - Control the level of noise (if any) is added to data when calculating metrics:<br>- <strong>None</strong>: Noise is never added.<br>- <strong>Low</strong>: Noise is only added when calculating percentiles.<br>- <strong>Medium</strong>: Noise is added for percentiles and other standard metrics when the number of unique values is small.<br>- <strong>High</strong>: Noise is always added when calculating metrics.</td><td>Medium</td></tr><tr><td>K-Anonymization Parameter</td><td>(Privacy filter) - Subgroups smaller than K will be excluded from summary statistics</td><td>5</td></tr><tr><td>Download Model Parameters</td><td>Download model parameters for models trained as part of the project.</td><td>PLA, PLM</td></tr><tr><td>Hide Collaborators</td><td>Indicates whether to allow collaborators in this project to view information (e.g. names, activities) about other collaborators. Selecting No allows the collaborators to see each other's information. Selecting Yes, hides collaborator information from other collaborators, including what would be shown in the recent activities list, notifications, and the list of collaborators in the project. Note that if you hide collaborators, and you set other permissions to include CA and/or CM, you will see a message indicating that CA/CM cannot be used in permissions when the project is set to use hidden collaborators.</td><td>No</td></tr><tr><td>Manage Code Objects</td><td>Create, modify, and remove Code Objects.</td><td>PLA, PLM</td></tr><tr><td>Manage Code Runs</td><td>Modify and remove Code Runs associated with this site.</td><td>PLA, PLM</td></tr><tr><td>Manage Data Schemas</td><td>Create, modify, and remove Data Schemas in the project.</td><td>CA, CM, PLA, PLM</td></tr><tr><td>Require Confidential Computing</td><td>Setting this permission to Yes allows your code to run on a Rhino Client within a Trusted Execution Environment(s) (TEEs). For the list of supported confidential computing VMs, see <a href="/settings/confidential-computing">Confidential Computing Supported Environments and Permission Settings</a>.</td><td>No</td></tr><tr><td>Run Code</td><td>Run code in the project.</td><td>PLA, PLM</td></tr></tbody></table>

### Site-Level Permission Policies

Site-Level permissions policies define what project participants may do with your site's resources. It also allows you to define certain site-level parameters. When the Project Lead creates the project, they also set the Site-Level permissions policies for their site. Each invited Collaborator will be presented with the Site-level Permissions Policy suggested by the Project Lead, but they may also change their Site-level permissions policy before accepting the invitation.&#x20;

<table><thead><tr><th>Actions</th><th width="227.8046875">Description</th><th>Default Policy</th></tr></thead><tbody><tr><td>Manage This Site's Datasets</td><td>Import, export, modify, and remove Datasets associated with this site</td><td>MA, MM</td></tr><tr><td>Manage Data Mappings</td><td>Create, modify, and remove data mappings and vocabularies from this site.</td><td>PLA, PLM, MA, MM</td></tr><tr><td>Manage Secure Access Lists</td><td>Create, modify, and remove Secure Access Lists for Datasets from this site</td><td>MA, MM</td></tr><tr><td>Manage This Site's Code Runs</td><td>Modify and remove Code Runs associated with this site</td><td>MA, MM</td></tr><tr><td>Pre-approved Code Only</td><td>Only allow pre-approved code to be run on your site's data. You will be able to specify/update the pre-approved code on this page</td><td>No</td></tr><tr><td>Run Code On This Site</td><td>Run code on Datasets from this site</td><td>MA, MM, PLA, PLM</td></tr><tr><td>Share Secure Access Lists</td><td>Share Secure Access Lists for Datasets from this site</td><td>MA, MM</td></tr><tr><td>View Client-Side Logs</td><td>View logs from code run on Datasets from this site</td><td>MA, MM, PLA, PLM</td></tr><tr><td>View Code Objects and Code Runs</td><td>Determines who can view workgroup code objects and code runs. Users without this permission only see code objects and code runs published to all project participants. See note below this table for more details.</td><td>CA, CM, MA, MM, PLA, PLM</td></tr><tr><td>View Datasets and Data Schemas</td><td>Allows you to view all workgroup Datasets and Data Schemas. Anyone without these permissions will only be able to view Datasets and Data Schemas that have been published to all project participants.</td><td>CA, CM, MA, MM, PLA, PLM</td></tr><tr><td>View Dataset Analytics</td><td>View aggregated analytics and metrics for Datasets from this site</td><td>MA, MM, PLA, PLM</td></tr><tr><td>View Datasets via Secure Access</td><td>Access data from this site via zero-footprint viewers (e.g. tabular data viewer, and interactive containers, OHIF)</td><td>MA, MM</td></tr><tr><td>View Client Side Logs with Sensitive Data</td><td>View logs from code runs on sensitive datasets from this site. This is included because code runs could write sensitive data to logs.</td><td>MA, MM</td></tr><tr><td>View Sensitive Datasets via Secure Access</td><td>Access sensitive data from this site via zero-footprint viewers such as a tabular data viewer and OHIF or interactive containers. This also includes fields marked as 'local only'.</td><td>MA, MM</td></tr></tbody></table>

{% hint style="info" %}
NOTE: If the personas for the View Code Objects and Code Runs setting are the default (PLA, PLM, MA, MM, CA, CM), then all members of the workgroup can see code objects and code runs. If you initially remove personas from the list, all code object and run versions will start as unpublished and are only visible to the included personas. Code runs are only visible to users who can see the code object.

You can change personas as you would for any other permissions setting. The personas in the permission list must include an MA or MM persona so site members can view and publish their own objects and runs.

The workgroup of the code object is the primary workgroup of the person who created the code object.

The workgroup of the code run is the primary workgroup of the person who triggered the code run.

Note: Code Runs are only visible to users for whom the Code Object is also visible. One edge case in which this might not automatically happen, is when there is an unpublished Code Object created by Collaborator A, with “View Code Object/Run” permissions set to PLA, PLM, MA, MM (so without CA/CM). And then a user in the Project Lead workgroup (who can view the Code Object) runs the Code Object. If the Project Lead’s “View Code Object/Run” settings are set to full visibility, then the Code Run would be visible to everyone in the project. However, users from another collaborator won’t be able to see the Code Object since it’s unpublished, and thus aren’t allowed to see the Code Run.
{% endhint %}

## Data Schema Permissions

When defining a new Data Schema, you will have the ability to select the permissions for each variable defined within the Data Schema.  For each variable defined within a schema, one of the following permission profiles can be applied.

<table><thead><tr><th width="214.23046875">Variable</th><th>Description</th></tr></thead><tbody><tr><td>Default</td><td>The variable's underlying data only persists on-prem, and aggregate statistics can be viewed in the cloud. This field can be viewed via secure access given the proper permissions.</td></tr><tr><td>No Aggregate Statistics</td><td>The variable's underlying data only persists on-prem, and <strong>no aggregate statistics</strong> can be viewed in the cloud. This field can be viewed via secure access given the proper permissions.</td></tr><tr><td>No Secure Access</td><td>The variable's underlying data only persists on-prem, and aggregate statistics can be viewed in the cloud. <strong>This field isn’t viewable via secure access.</strong></td></tr><tr><td>Local Only</td><td>The variable's underlying data only persists on-prem, and <strong>no aggregate statistics</strong> can be viewed in the cloud. <strong>This field isn’t viewable via secure access.</strong></td></tr></tbody></table>


# Run Pre-approved Code Only

This article explains how to set up your Site Permissions to limit collaborators to run pre-approved code only. See the video below for a guide through and below for a step by step description.

This Site-level permissions setting enables you to limit the code that Collaborators may run using your data. Once **Pre-approved Code Only** is set to **Yes,** you will be able to manage a list or container images that your collaborators can use.

To add or remove a container image from the pre-approved code list, follow these steps:

1. Make sure you know your Collaborator's workgroup name and the exact name of the container image they wish to run.
2. In your FCP project, navigate to the **Collaborators View** and click on the **Permissions Policy** tab.
3. Under your site's Site-level Permission section, click on the gear icon next to the pre-approved code permission:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/7U2WplwGMIZMaH13l9wM/30755734139805)

4. Click the **+ Add Container Image** button

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/26pzfE1NZjcoXMehpHMD/30755729373853)

5. A new row will be added to the table. Select your Collaborator's workgroup name, and type the Container Image name in the new row.
6. Click **Submit** to save changes. If the Container Image name does not exist in the collaborator's ECR, this step will fail.


# Deleting a Project

Follow these steps to delete a project.

{% stepper %}
{% step %}
**Open the Projects page**

Go to the page that lists your projects.
{% endstep %}

{% step %}
**Find the project**

If needed, use the search fields at the top right.

* Use **Search Name** to search by project name.
* Use **Search Description** to search by project description.
  {% endstep %}

{% step %}
**Open the menu for the project**

Find the project you want to delete. Then select the three-dot menu on the right side of the project, as shown below.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/n1w6Zdk3t2rXuru3vm9P/12987186774557)
{% endstep %}

{% step %}
**Remove the project**

Select **Remove**.

Projects do not have versions. Removing the project deletes the project itself.
{% endstep %}
{% endstepper %}


# What is a Collaborator?

In the Rhino FCP, collaboration is set up around workgroups. Each workgroup has a lead and several members. To add collaborators to projects, you simply add their workgroups. This method helps keep collaboration straightforward and maintains controlled access.

### Collaborative Workgroups and Workgroup Leads

Workgroups are the foundational units of collaboration in the Rhino FCP. Each workgroup is led by a designated workgroup lead, responsible for overseeing project access and permissions within the workgroup.

### Enabling Controlled Collaboration

This workgroup-based approach ensures that collaboration is structured, controlled, and aligned with project goals. The **workgroup lead** plays a pivotal role in managing access and fostering effective teamwork.

### Guided Collaboration in Action

Imagine you're launching a multi-institutional research initiative. By adding the workgroups of researchers from each institution, you establish a collaborative framework. The lead of each workgroup approves project access, facilitating seamless collaboration while maintaining control.

## Summary

Collaboration in the Rhino FCP revolves around workgroups, each led by a lead. Adding collaborators means adding entire workgroups, streamlining access, and promoting controlled collaboration. This approach enhances project collaboration and accelerates collective insights.

## Key Components of a Collaborator

### **Attributes**

1. **Workgroup Name:** The name of the collaborating workgroup. A workgroup is usually a lab or smaller team that is part of a larger organization.
2. **Workgroup Lead:** The person who is leading the workgroup. The workgroup lead must approve all Collaboration requests
3. **Site Name:** The name of the site where the remote data will live
4. **Number of Members:** The number of team members at a site, inclusive of the Workgroup Lead
5. **CPU Usage:** The CPU usage at a specific Rhino Client
6. **Storage Usage:** The disk storage usage at a specific Rhino Client
7. **Memory Usage:** The memory (RAM) usage at a specific Rhino Client
8. **GPU Usage:** Where applicable, the GPU usage at a specific Rhino Client. Not all Rhino Clients are required to have GPUs attached
9. **VRAM Utilization:** Where applicable, the VRAM utilization at a specific Rhino Client. Not all Rhino Clients are required to have GPUs attached
10. **UUID:** The unique identifier for a specific Code Object version within the Rhino FCP
11. **Secure Access:** An optional set of abilities that can be granted to a collaborator to visualize raw data, view Code Run logs, etc. For more information about Secure Access, please refer to [What is Secure Access?](/secure-access/what-is-secure-access)


# Adding or Removing a Collaborator from a Project

Explains how to add and remove collaborators in your project.

This article explains how to add and remove collaborators in your project. Adding collaborators means adding workgroups, streamlining access, and promoting controlled collaboration. For more information on collaborators, see [What is a Collaborator?](/collaborators/what-is-a-collaborator)

{% hint style="info" %}
NOTE: You must be a Workgroup Administrator to complete these tasks.
{% endhint %}

## Adding a Collaborator

{% stepper %}
{% step %}
**Open the Collaborator page.**

Open a project by selecting it from the main project screen.

<figure><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/YQd9jOuTgzbBLxKVdwA6/29850507233053" alt=""><figcaption></figcaption></figure>

Select **Collaborators** menu item from the left-hand menu of the main screen.

<div align="left"><figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FeXWVpkCP8U0dVmqgWoHD%2FScreenshot%202026-07-07%20at%2012.20.09%E2%80%AFPM.png?alt=media&amp;token=0a957f49-dcbc-4480-9d2b-258216ff5163" alt="" width="75%"><figcaption></figcaption></figure></div>
{% endstep %}

{% step %}
**Add a new collaborator.**

Select the **Add Collaborator** button in the top right corner of the screen.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FXXdcsnMG9LDvgfvLOqSe%2FScreenshot%202026-07-07%20at%2012.34.04%E2%80%AFPM.png?alt=media&amp;token=66c1a375-1d74-47dc-bef9-5fa02034562d" alt="" width="75%"><figcaption></figcaption></figure>
{% endstep %}

{% step %}
**Find and add your collaborator to your project.**

Search or scroll through the list of potential **Collaborators** until you find the collaborator(s) you would like to add to your project. In the **Add Collaborator** screen, select the checkbox next to their name.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FlYofXY8iug4j68LQS6kQ%2FScreenshot%202026-07-07%20at%2012.36.42%E2%80%AFPM.png?alt=media&amp;token=82cd94e1-209e-4b34-9511-574efdafbefe" alt="" width="75%"><figcaption></figcaption></figure>

When you have finished selecting all your Collaborators, scroll to the bottom of screen. Check the box **I approve inviting selected collaborators to this project.**

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2Fnlk3t5HVEbAlS87vXeEb%2FScreenshot%202026-07-07%20at%2012.40.40%E2%80%AFPM.png?alt=media&amp;token=ab36a9e0-4ac0-420e-984b-9f5e62f9e978" alt=""><figcaption></figcaption></figure>

Press the button **Add Collaborator** to initiate the collaboration invitation process, in which both parties will need to accept the collaboration on the project.

When you add a collaborator to a project, you're essentially adding their entire workgroup. The Lead of the collaborator's workgroup receives an invitation email. To gain access to the project, the workgroup Lead must approve the project's permissions policy. To learn more, see the [information about the project's permission's policy.](/projects/creating-a-new-project)
{% endstep %}
{% endstepper %}

## Responding to the Collaboration Request

If you've been invited as a collaborator, you will receive an email about the collaboration request.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/5xf5Cksigv5XhZjRAuvp/13115054266141)

Also, every Workgroup Admin that was selected for collaboration, will receive an email inviting them to collaborate on the project. The email instructs each potential collaborator to open the project in the Rhino FCP and review the project's permissions.

## Viewing and Accepting the Project Permissions Policy in a Potential Collaboration

After the prospective collaborator clicks the link in the email, the FCP dashboard is where the new Project will appear. The collaborator selects the project, then is taken to a screen that shows the Collaborating Project's Permissions Policy. To accept, the collaborator clicks the **Accept** button.  For more information about the permissions policies see [Persona and Permissions Policies Reference](/projects/persona-and-permissions-policies-reference).

Upon accepting the permission policy defined for the Project, the collaborator can see other parts of the project. You will also see your own site and your collaborators on the Collaborator's page.

### Removing a Collaborator

These steps apply to data schemas, datasets, code objects, and code runs. To delete a version of these things, make sure you are on the page that contains the original object with the version you would like to delete. If you need to search for data schemas, code objects, or code runs, use the text boxes located at the top right corner of the page. To search by name enter the full name or part of the name in the Search Name text box. To search by description, enter part of the description in the Search Description text box.

In the box where your original object is, there is a row for each version. Navigate to the version you want to delete and select the three-dot menu button, shown here below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/nbRfRwOZ43x7VQO02if5/13002763034909)

The menu button is on the right-hand side of the row. Click it to view a new menu. The new menu should have an option to remove that object's version, click on that to delete the object's version. To completely remove an object repeat the process to delete all versions, once the last version has been deleted the object will be deleted.

In the case of a project or a collaborator, there is no concept of a version so you will just navigate to the object and then select the three-dot menu button and choose the remove button from the menu.


# Closed-Membership Workgroups

High-trust projects sometimes require strict, pre-approved membership. To enforce collaboration boundaries (thus creating “closed cohort governance”), you can create closed-membership workgroups for the project. Once created, you can add the closed-membership workgroup for a high-trust project.

This article explains what a closed-membership workgroup is and how to create one.

### About Closed-Membership Workgroups

In Rhino FCP, a *workgroup* is a foundational unit of collaboration, which is often a lab or a small team within a larger organization. You can also add other collaborators, who might be outside of your organization, to the workgroup so that you can collaborate on federated research projects. For a brief primer on workgroups, see [What is a Collaborator?](/collaborators/what-is-a-collaborator).

By default, a *default* workgroup is **not** set up as a closed-membership workgroup. A *closed-membership workgroup* is a workgroup where Rhino administrators and Workgroup Admins cannot add members.

### Prerequisite

Before you complete this procedure, do the following.

* The Workgroup Administrator must send a request to the Rhino Administrator to create a new Closed-Membership Workgroup. The Rhino Administrator will add workgroup members and set the *Closed-Membership Workgroup* flag to true.
* Once complete, the Rhino Admin notifies the Collaborating Workgroup Admin.

{% hint style="warning" %}
Once a workgroup is designated as closed-membership, it cannot be changed back to the default workgroup. At this time, only Rhino Administrators are able to set a workgroup.
{% endhint %}

### Overview

After the prerequisite has been met, the steps for setting up a closed-membership workgroup in Rhino FCP involves three steps and two roles. The roles are: Collaborating Workgroup Administrator and Project Lead Administrator.

Here are the three steps:

1. The Project Lead creates a new project and in the permission policy, sets *“Allow Only Closed-Membership Collaborators”* to “Yes”.
2. An admin member of the Project Lead’s group creates a project and adds the closed-membership collaborator(s).
3. An invitation is sent to the Collaborating Workgroup Admin. The admin accepts the invitation.

Here are a few additional details.

* Once a workgroup is established as *Closed-Membership*, it can be added as a collaborator to a project that is configured to *“Allow Only Closed-Membership Collaborators”*.
* Once a Workgroup is set by a Rhino Administrator as a *Closed-Membership Workgroup* and that Workgroup joins a project with “ *Allow Only Closed-Membership Collaborators”*, this setting becomes locked and cannot be changed.
* The *Closed-Membership* option is enabled by the Rhino Admin setting the *Closed-Membership* flag to true. Establishing a *Closed-Membership Workgroup* can only be done by Rhino administrators with approval from the Workgroup Administrator.

### Creating Project and Setting the Closed-Membership Collaboration Policies

To set up a closed-membership workgroup, complete the following steps. Note that this should be done by the Project Lead.

{% stepper %}
{% step %}

### From the main screen, create a project

From the main screen, select the Create a Project button, then add the name of the project and a description.

Select the Permissions Policy downward arrow to view policies.

In the Project Level permissions, set the Allow Only Closed-Membership Collaborators policy to Yes.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/1h1AZRfbpc0sKcjmGwYF/33675972780317)

Finish entering the rest of the permissions. For more details, see [Creating a New Project](/projects/creating-a-new-project).
{% endstep %}

{% step %}

### Create the project

Select Create Project to create the project.
{% endstep %}
{% endstepper %}

### Adding a Closed-Membership Workgroup as a Collaborator

To designate a closed-membership workgroup as a collaborator, complete the following steps.

{% stepper %}
{% step %}

### Open the collaborator list

In the project that you want to add the collaborator to, select the Collaborator button.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/T7VFxuM2PuIhhS2Cyfcm/33675972781085)
{% endstep %}

{% step %}

### Select the closed-membership workgroup

Select the closed membership workgroup you want to add.
{% endstep %}

{% step %}

### Approve the invitation

Scroll to the bottom of the screen and select the checkbox to approve inviting selected collaborators to this project.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/rWYUF0rxSJuEdRUEOEtF/33675972783389)
{% endstep %}

{% step %}

### Wait for collaborator approval

A message appears in the collaborator’s box on the collaborator’s screen that indicates that it is waiting for the collaborator to approve joining the project.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ik6APJR0TJHej9XHZ6UV/33675972784157)
{% endstep %}

{% step %}

### Begin collaboration

Once the collaborator approves, the closed-membership workgroup members can interact in the group as they would normally.
{% endstep %}
{% endstepper %}

{% hint style="warning" %}
Once a *Closed-Membership* workgroup has been added to a project, no additional members can be added to that workgroup, only removed (unless it is one of the Project Lead’s workgroups).
{% endhint %}


# Viewing a Collaborator's Hardware Metrics

How to view a hardware metrics for your collaborators.

At a minimum, you will see your own Rhino Client with all your available hardware metrics. If you have multiple collaborators in your projects, and you wan to see their available hardware metrics, select Collaborator from the left side of the screen.  A box for each collaborator, along with their hardware metrics appears on the screen.

{% hint style="info" %}
NOTE: The metrics shown on the Collaborators page are not dynamic; you will need to refresh the page for updated metrics.
{% endhint %}

If a collaborator is missing GPU metrics or they are not updating upon refresh of the page, please refer to [Why are GPU metrics not present or updating within the Collaborators page?](/frequently-asked-questions/frequently-asked-questions-faqs#other-questions)&#x20;


# What is Secure Access?

**Secure Access** enables direct access to row-level data via a zero-footprint mechanism implemented within the FCP. This allows a user to view data loaded onto their Rhino Client through the Rhino FCP cloud application without having the data leave the Rhino Client. Secure access can be extremely useful for use cases such as annotation on distributed data. By default, a user can only use Secure Access on data that belongs to their workgroup.

You'll need enable to Secure Access to view and/or annotate a dataset's tabular data or to view and/or annotate a dataset's image data within the OHIF view.

However, if a user would like to access a collaborator's data, they should ask their collaborators to create a **Secure Access List** and grant them time-limited access to the data. A remote Collaborator can select exactly which rows from a Dataset they would like to share, with whom they share the data, and for how long they would like to share it.&#x20;


# What is a Secure Access list?

A **Secure Access List** is a Data Custodian's Dataset or a subset of a Dataset that has been selected for sharing with one or more Collaborator(s) for a potentially limited amount of time. A Dataset can have one or many Secure Access Lists that can be of all different sizes and durations for sharing with different Collaborators.

When a Data Custodian creates a Secure Access List, they will select exactly which rows to share through the tabular view of a Dataset. The custodian will then decide who to share the list with and for how long. When the custodian shares the list, a Collaborator may view the data from their own FCP dashboard within the Dataset's Secure Access tab.

### Key Components of a Secure Access List

#### Attributes

* **Name:** The name of the defined Dataset. All Datasets within the platform must have a unique name and version combination
* **# of Cases:** The number of rows that were selected for sharing
* **Date Created:** The date the *Secure Access List* was created
* **Owner:** The Data Custodian, more specifically the Workgroup Admin for a site

### Interfaces

Below are a series of screenshots that detail how you can interact with Secure Access Lists within the Rhino FCP.

#### Main Datasets Page

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/0Tu5gDaPEBt2FAcSerGA/13266297762077)

The main interface for selecting the **Dataset** that you will create **Secure Access List** for.

#### Selecting Data from a Dataset to Share as a Secure Access List

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/InlTtNdLPVxxk1oRbecR/13266297762717)

For more information about selecting data from a **Dataset** to share as a **Secure Access List**, please refer to [How to Create a Secure Access List to Share with your Collaborators as a Data Custodian](/secure-access/how-to-create-a-secure-access-list-to-share-with-your-collaborators-as-a-data-custodian).

#### Naming Your Secure Access List Before Sharing

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/DReUMbc6r1qfuXAwjbKQ/13266297765789)

For more information about naming your **Secure Access** list before sharing, please refer to [How to Create a Secure Access List to Share with your Collaborators as a Data Custodian](/secure-access/how-to-create-a-secure-access-list-to-share-with-your-collaborators-as-a-data-custodian).

#### Selecting Which of Your Collaborators to Share Your Secure Access List With

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/tvcCqd3xsps8RJoFJUmP/13266314537885)

For more information about selecting which of your **Collaborators** to share your **Secure Access List** with, please refer to [How to Create a Secure Access List to Share with your Collaborators as a Data Custodian](/secure-access/how-to-create-a-secure-access-list-to-share-with-your-collaborators-as-a-data-custodian).

#### Selecting The Duration of Expiration for Your Secure Access List

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/SEojt7jdtDAoLfUN9KUF/13266297769629)

For more information about selecting the **Expiration** of sharing for your **Secure Access List**, please refer to [How to Create a Secure Access List to Share with your Collaborators as a Data Custodian](/secure-access/how-to-create-a-secure-access-list-to-share-with-your-collaborators-as-a-data-custodian).

#### Viewing Secure Access Lists You Have Shared With Your Collaborators

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/7EUDQhiCGU7J1kwMxXtU/13266297770909)

For more information about viewing **Secure Access Lists** you have shared with your **Collaborators**, please refer to [Viewing Data within a Secure Access List](/secure-access/viewing-data-within-a-secure-access-list).

#### Reviewing Row-Level Data That Has Been Shared as Part of a Secure Access List

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/w77VuFsk5jxEdX7btUaX/13266297774493)

For more information about reviewing row-level data that has been shared as part of a **Secure Access List**, please refer to [Viewing Data within a Secure Access List](/secure-access/viewing-data-within-a-secure-access-list).

#### The Dataset Analytics Tab for Remote Datasets That You Have Been Granted Access to via a Secure Access List

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ALWrgsQZBgFswqRQnvQE/13266314546589)

For more information about the **Dataset Analytics** tab for remote **Datasets** that you have been granted access to via a **Secure Access List**, please refer to [Viewing Data within a Secure Access List](/secure-access/viewing-data-within-a-secure-access-list).

#### The Dataset Data Tab for Remote Datasets That You Have Been Granted Access to via a Secure Access List

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/runjM5RkpuRjdevA6LuR/13266314550941)

For more information about the **Dataset Data** tab for remote **Datasets** that you have been granted access to via a **Secure Access List**, please refer to [Viewing Data within a Secure Access List](/secure-access/viewing-data-within-a-secure-access-list).

#### The Dataset Secure Access Tab for Remote Datasets That You Have Been Granted Access to via a Secure Access List

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/Zx4LbAPMIzmYC1xnbKhz/13266297780637)

For more information about the **Dataset Secure Access** tab for remote **Datasets** that you have been granted access to via a **Secure Access List**, please refer to [Viewing Data within a Secure Access List](/secure-access/viewing-data-within-a-secure-access-list).

#### Viewing Row-Level Data for Remote Datasets That You Have Been Granted Access to via a Secure Access List

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/DIvHxH59DOuuKcAnPVaZ/13266297783325)

For more information about viewing row-level data for remote **Datasets** that you have been granted access to via a **Secure Access List**, please refer to [Viewing Data within a Secure Access List](/secure-access/viewing-data-within-a-secure-access-list).

#### Viewing Image Data for Remote Datasets That You Have Been Granted Access to via a Secure Access List Using the Embedded OHIF Viewer

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/LvxsZRX1qsXwDncE72XU/13266297787037)

For more information about viewing image data for remote **Datasets** that you have been granted access to via a **Secure Access List** using the **Embedded OHIF viewer**, please refer to [Viewing Data within a Secure Access List](/secure-access/viewing-data-within-a-secure-access-list).


# How to Create a Secure Access List to Share with your Collaborators as a Data Custodian

{% stepper %}
{% step %}
**Navigate to the Datasets Page.**

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/L56UNPRuzh2gGy8ayOJf/13267138694173)

Use the left-hand navigation menu to click on the **Datasets** menu item
{% endstep %}

{% step %}
**Select the dataset you want to create a Secure Access List for.**

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/W5Zvym4vCDsW8OC7G7w6/13267153681693)

Select the **Dataset** you would like to create the **Secure Access List** for by pressing on the specific **Dataset** and Version row to view the details
{% endstep %}

{% step %}
**Select the row-level data you want to share as part of your Secure Access List.**

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/GXJkmHC0DoLqpr0thANc/13267153682717)

Once within the **Dataset**, navigate to the **Data** tab. Hover over the rows you would like to add; a checkbox should appear on the left-hand side of each data row. Check each box for each piece of data you would like to share. If you want to just share the complete **Dataset** you can select the checkbox within the heading of the data table to select all rows.

When you have finished selecting all the data you would like to share, click **Create List** to create your **Secure Access List**
{% endstep %}

{% step %}
**Name your Secure Access List.**

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/u7TBs5EItobm3Rawp1Wp/13267138699421)

Enter the name of your new **Secure Access List** list into the input field within the new modal window. If you are not ready to share your list yet, you can select the **Save List** button. This will create your list, but it will not be shared with anyone. You can later share this list with **Collaborators** through the **Secure Access** tab in the dataset view. If you are ready to share your list, select the checkbox labeled **Share list after creating**, then select the **Save and Share** button, and you will be taken to the next screen below
{% endstep %}

{% step %}
**Select which collaborators to share your Secure Access List with.**

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/WL2ICA3YKcU3DtXllCng/13267153687837)

Use the search bar to find the **Collaborators** you would like to share your **Secure Access List** with. Select one or more **Collaborators** to share your list with
{% endstep %}

{% step %}
**For each selected collaborator, indicate how long you want to share your Secure Access List.**&#x20;

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/7blWYwFh18TfiOYc6x7W/13267138703261)

For each of your selected **Collaborators**, you will see a drop-down for **Expiration** on the right-hand side of each row. Choose the appropriate **Expiration** time for each **Collaborator**. The **Expiration** options are **Unlimited**, **1 day**, **3 days**, or **Custom**. When you have finished selecting the appropriate **Expiration** time for each **Collaborator** with whom you will share your **Secure Access List**, you will need to confirm that you want to grant access to this list by selecting the checkbox labeled **I agree to provide secure access to this list**. Once you have confirmed that you agree to grant access to the **Secure Access List**, select the **Grant Access** button to grant the **Collaborators** access
{% endstep %}

{% step %}
**View your newly created Secure Access List.**

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/1fQAeYtfJDW6THSTvUeh/13267153690269)

You should now have a new row within the table on the **Secure Access** tab in your **Dataset**
{% endstep %}
{% endstepper %}

## Getting Help

If you have received an error or run into any issues throughout the process, please reach out to <support@rhinohealth.com> for more assistance.


# Viewing Data within a Secure Access List

## As a Data Custodian

{% stepper %}
{% step %}

### Navigate to the Datasets Page

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/qZQ1ogZHs38LmNb6mqKO/13267968269085)

Use the left-hand navigation menu to click on the **Datasets** menu item.
{% endstep %}

{% step %}

### Select the Dataset You Want to View the Secure Access List(s) For

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/o6cq0HKbTnXinqLT4Oml/13267968271133)

Select the **Dataset** you would like to view the **Secure Access List(s)** for by pressing on the specific **Dataset + Version** row to view the details. Then navigate to the **Secure Access** tab within the **Dataset**.
{% endstep %}

{% step %}

### View Your Secure Access List(s)

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/roB6fhl70MtuEqCqM2lV/13267968274845)

You should see a table populated with all the **Secure Access Lists** you have created for the **Dataset**. Click on a **Secure Access List** name in the table to be taken to the row-level data that is being shared as part of the **Secure Access List**.
{% endstep %}

{% step %}

### Reviewing the Row-Level Data with a Secure Access List

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/qd4WEAv8n4XkHfeohdxd/13267906886941)

You will now see a very similar view to your **Data** tab, but the row-level data will only be the data that has been shared as part of the **Secure Access List**. From here, you similarly have the option to view image data, if it is contained in the **Dataset**, within the **Embedded OHIF Viewer**. To do so, select one of the DICOM or image links within the **Dataset**.
{% endstep %}

{% step %}

### Viewing Image Data within a Secure Access List Using the Embedded OHIF Viewer

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/DfSQVqRznwhyPgod1mR9/13267906890013)

For more information about capabilities within the **Embedded OHIF Viewer**, please refer to [Viewing and/or Annotating Datasets and Dataset Images](/datasets/viewing-and-or-annotating-datasets-and-dataset-images)
{% endstep %}
{% endstepper %}

## As a User who Has Been Granted Access to a Remote Dataset via a Secure Access List

{% stepper %}
{% step %}

### Navigate to the Datasets Page

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/MVPD8uW3XhAmgTLSdpd2/13267968280349)

Use the left-hand navigation menu to click on the **Datasets** menu item.
{% endstep %}

{% step %}

### Select the Dataset You Have been Granted Access To via the Secure Access List

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/rBhDfm13cwmCWQLqHFbu/13267906893213)

Select the **Dataset** you have been granted access to by pressing on the specific **Dataset + Version** row to view the details. When you are granted access to a **Dataset** through a **Secure Access List**, the **Datasets** page will be a bit different than if you had imported the **Dataset** yourself. We will review the various tabs within the **Datasets** interface to demonstrate the differences.
{% endstep %}

{% step %}

### The Dataset Analytics Tab for Remote Datasets That You Have Been Granted Access to via a Secure Access List

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ViT7O20NbVC9dyvoiwEl/13267906901661)

Depending on the **Permissions Policy** specified by your **Collaborator**, you may or may not have permission to view the **Dataset Analytics**. In this case, the Project's **Permissions Policy** does not allow for this capability. For more information on project permissions, please refer to [Persona and Permissions Policies Reference](/projects/persona-and-permissions-policies-reference).
{% endstep %}

{% step %}

### The Dataset Data Tab for Remote Datasets That You Have Been Granted Access to via a Secure Access List

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/eUahTBFeg6qbwCtVoiQX/13267968283677)

When you have been granted access to a **Dataset** via a **Secure Access List**, the **Data** tab will always show " *You do not have permission to perform this action.*" This is because the data has not been imported by you; you will need to use the **Secure Access** function to view the data.
{% endstep %}

{% step %}

### The Dataset Secure Access Tab for Remote Datasets That You Have Been Granted Access to via a Secure Access List

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/wqASHFezs1AY81TW6G3s/13267906908061)

You should have at least one list within the table on the **Secure Access** tab within the **Dataset**. Similar to if you had created the **Secure Access list**, you can select the name of the list to view row-level data, assuming the **Project's** **Permissions Policy** allows you to do so.
{% endstep %}

{% step %}

### Viewing Row-Level Data for Remote Datasets That You Have Been Granted Access to via a Secure Access List

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/D2GdwhTLyWNFHoqfBiSQ/13267968289309)

Once you have clicked on the name of the **Secure Access List** you should see the tabular data view. You will only see the data that you have been granted permission to, and only in a way in line with the **Project's Permissions Policy**. For a complete reference on the **Permissions Policy** within the Rhino FCP, please refer to [Permissions](/projects/persona-and-permissions-policies-reference).

From here, you similarly have the option to view image data, if available, within the **Embedded OHIF Viewer**. To do so, select one of the DICOM or image links within the **Dataset**.
{% endstep %}

{% step %}

### Viewing Image Data for Remote Datasets That You Have Been Granted Access to via a Secure Access List Using the Embedded OHIF Viewer

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/AIyUcKQ2ryzaPmsUEDoe/13267968290077)

For more information about capabilities within the **Embedded OHIF Viewer**, please refer to [Viewing and/or Annotating Datasets and Dataset Images](/datasets/viewing-and-or-annotating-datasets-and-dataset-images)
{% endstep %}
{% endstepper %}


# What is a Dataset?

Explains what a dataset is and its key components.

## About Datasets

In the Rhino FCP, a dataset is an immutable representation of a collection of data points associated with a specific project. Each dataset is owned by a Workgroup. Data is stored in the Rhino Client for that Workgroup (behind the institutional firewall). Only aggregate information, such as summary statistics, is stored in the Rhino Orchestrator.

* Each dataset has a unique name and version combination, as well as a unique identifier (UID).
* A dataset may include tabular data, file data, or a combination of both. The FCP supports files of any format within a dataset; however, there is additional functionality built into the FCP for DICOM files.
* Each dataset is associated with a [Data Schema](/data-schemas/what-is-a-data-schema), which describes the format in which the data is organized within the dataset (e.g., features, data types, units, schema-level permissions, etc.).

In Rhino FCP you can import a dataset or create a new version of an existing dataset, view the dataset's UID, perform schema-based de-identification for sensitive data, and view analytics on the data.

You can view datasets in tabular form. You can also view and annotate DICOM image data within the built-in OHIF view. You can also export datasets, publish and unpublish them, or even remove them if they are no longer needed. You can also view or add to secure access lists.

You can do many of these things as well with the Rhino SDK. For more information see [Importing a New Dataset or Dataset Version Using Rhino SDK and SQL.](/rhino-sdk/registering-a-new-dataset-or-dataset-version-using-rhino-sdk-and-sql)

## Key Components of a Dataset

Datasets have the following components.

* **Name:** The name of the defined dataset. All datasets within the platform must have a unique name and version combination.
* **Description (Optional):** The description of the dataset.
* **Version(s):** The version of the dataset. After creating the initial dataset you can edit the existing dataset configuration and create a new version instead of creating a whole new dataset.
* **Data Schema:** The data schema that was used when importing the particular version of the dataset.
* **Date Created:** The date the dataset was created.
* **Number of Rows:** The number of rows that were imported from the tabular, DICOM, and/or file data.
* **Source:** The creator of the dataset version.
* **UID:** The unique identifier for a specific dataset version within the Rhino FCP.
* **Data:** The underlying tabular data that defines the cohort. This can be simply a list of DICOMs, filenames, or a CSV-style data table that contains multiple variables.
* **Secure Access List:** A list that defines access you have been granted to a collaborator's remote dataset or access you have granted in your dataset to your collaborators. For more information about collaborators or Secure Access, please refer to [What is a Collaborator?](/collaborators/what-is-a-collaborator) or [What is Secure Access?](/secure-access/what-is-secure-access) respectively.


# What is a Federated Dataset?

Explains what a Federated Dataset is and its main benefits.

## About Federated Datasets

Federated Datasets are part of the Rhino Federated Computing Platform (FCP). They help organizations explore shared data, work with partners, and speed up research. The sections below explain the main benefits of using FCP with Federated Datasets.

### Accelerates Collaborative Research

Federated Datasets empowers collaborative research by making it easy to explore distributed data and collaborate across institutions. Whether you are a data strategist seeking to put your data assets to good use or an FCP user looking for additional relevant data to use in your work, Federated Datasets provide a powerful and flexible solution to kickstart and enhance your collaborative research endeavors.

### Facilitates Research Advancement and Data Monetization for Healthcare Institutions

Hospitals and healthcare institutions, particularly those focusing on research advancements and looking for additional ways to generate passive income through data, can significantly benefit from Rhino's Federated Datasets. This platform enables key decision-makers like Chief Innovation Officers, Chief Data Officers, CEOs, and Directors of Medical Innovation to strategically share and manage their data assets. By creating and publishing Federated Datasets, your institution can offer selective data assets to external researchers and industry partners. This facilitates collaborative studies and potentially lucrative licensing opportunities. The process is designed to maintain the highest privacy standards, giving you full control over who accesses your data and how it is used. This approach not only fuels scientific discovery but also opens new revenue streams, all while ensuring data privacy and compliance.

### Efficient Data Exploration with Analytics

Navigate Federated Datasets effortlessly with keyword search and analytics, empowering users to evaluate the feasibility of integrating datasets into diverse projects. The platform's search and discovery functionalities make it easy to find relevant Federated Datasets, while the dynamic filters accessible under the "Analytics" section serve to easily define your inclusion and exclusion criteria for comprehensive feasibility analysis. Detailed datasheets allow for informed decision-making, providing valuable insights into the composition of each Dataset.

### Learn more

For step-by-step instructions on how to explore the available datasets or how to create your own, see  [Federated Datasets](/datasets/creating-and-exploring-federated-datasets).


# Registering, Configuring, and Exporting Datasets

Explains how to register, configure and export datasets in Rhino FCP.

## Registering Datasets

Rhino FCP allows you to easily and securely register datasets that you can use in your project. This article explains how you can register datasets from the following:

* *Tabular Data files* that are in the Rhino Client File System (such as a CSV or Parquet file) or a supported database.
* *File Data* that is in the the Rhino Client File System such as a client mount directory (or subdirectory) rhino\_data directory (or subdirectory). These files are typically non-tabular files, such as code, images, or generic data in files or a folder.
* *DICOM Data* stored on a DICOM Server or DICOM files that are in the Rhino Client File System.

{% hint style="info" %}
If you'd like to register datasets using Rhino SDK, see [Creating a New Dataset or Dataset Version.](/rhino-sdk/registering-a-new-dataset-or-dataset-version-using-rhino-sdk-and-sql)
{% endhint %}

### Prerequisites

Before you register your dataset, you’ll need to do the following:

* If you are planning to register your dataset directly from a database, make sure that the database is supported (see [Import Tabular Data from an SQL Server](#h_01K8NZH645W3S593NNTK7V1DX9) for more details.) If not, you can export the file from your database and register it as a flat file. You’ll also need database access credentials like the database username and password for your account, as well as your database name, port, and URL.
* If you are planning to register from one or more files (tabular, DICOM, or other files), you’ll want to upload them to the Rhino Client File System.
* If you are planning to register from a DICOM Server, you’ll need the host, port, and prefix, as well as your username and password.

You will also need to determine whether you have sensitive data in your dataset. By default, sensitive data is selected; to learn more about how sensitive data is handled in Rhino FCP see [Sensitive Datasets.](/datasets/sensitive-datasets)

### Open the Dataset Page

To open the dataset page, do the following.

{% stepper %}
{% step %}
**Select Datasets**

Select **Datasets** from the left-side menu.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/TKwSPNfvyzqHIjxQ2lUc/32220670145437)
{% endstep %}

{% step %}
**Open the Datasets page**

The **Datasets** page appears. The **Overview** link should already be selected.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/12uYCiYAY8hBlbM4NiPm/32220686888989)
{% endstep %}
{% endstepper %}

The name of each dataset, along with the version, data schema, date created, number of rows (or failed registration status), and creator appear for each version of the dataset. A three-dot menu appears to the right side of each version of each dataset entry.

| Item           | Description                                                                                                                                                                                          | Notes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Name           | Name of the Dataset. Dataset versions are auto-numbered sequentially in the order of creation. If you see gaps in version numbers, numbers that do not appear were deleted by a user.                | <p>- Dataset versions are auto-numbered sequentially in the order of creation. If you see gaps in version numbers, numbers that do not appear were deleted by a user.<br>- A pink background and an icon (eye with a lock) indicates that the dataset contains sensitive data. A blue background indicates that the dataset does not contain sensitive data.<br>- The publish icon appears if the dataset has been published. For more information, see <a href="/datasets/publishing-and-unpublishing-datasets">Publishing Datasets.</a></p> |
| Version        | Version of the dataset, starting with 0. Also indicates whether the dataset has been marked as having sensitive data. An exclamation mark appears if an error occurred with registering the dataset. | Troubleshooting information can appear here.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| Data Schema    | Indicates the name of the data schema. If you’ve auto-generated, the name of the schema includes the version number.                                                                                 |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Date Created   | Indicates the date the dataset was generated in Rhino FCP..                                                                                                                                          |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Number of Rows | Indicates the number of rows in the dataset. If there was an issue with registration, a message appears instead.                                                                                     |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Creator        | Indicates the name of the creator.                                                                                                                                                                   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Three-Dot Menu | Provides additional actions that can be performed on the dataset record.                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |

### Open the New Dataset Page

To open the New Dataset page, do the following.

{% stepper %}
{% step %}
**Open the New Dataset screen**

In **Datasets** page, select **Import New Dataset** to open the New Dataset screen.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/R0lrmoND7XvJMOazXVdc/31357013299997)
{% endstep %}

{% step %}
**Enter dataset details**

Enter your name and a description of your dataset.
{% endstep %}

{% step %}
**Select a workgroup**

Select your workgroup.
{% endstep %}

{% step %}
**Choose schema generation**

Indicate whether you want to auto-generate the schema from the data or select one from the list (if there is one available).
{% endstep %}

{% step %}
**Choose the dataset location**

Indicate the location of the dataset that you want to register.
{% endstep %}

{% step %}
**Use the table below for the next step**

|                                                                                                                                                                |                                                         |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| To do this ...                                                                                                                                                 | Go to the following subsection ....                     |
| Select tabular data from a SQL Server, like data from a SQL table. To use this option, you'll need the database type, name, URL, port, and access credentials. | Register Tabular Data from an SQL Server                |
| Register data from the Rhino Client File System. To use this option, you'll need to know the path to the file.                                                 | Register Tabular Data from the Rhino Client File System |
| Register non-tabular file data such as images or other types of data. To use this option, you'll need to know the path to the file.                            | Register File Data (Non-Tabular)                        |
| Register DICOM Data. To use this option, you'll need to know the credentials to the DICOM system.                                                              | Register DICOM Data                                     |
| {% endstep %}                                                                                                                                                  |                                                         |
| {% endstepper %}                                                                                                                                               |                                                         |

### Register Tabular Data from an SQL Server

You can register tabular data from a SQL Server. Supported databases are: IRIS, MariaDB, MSSQL (Microsoft SQL), MySQL, Oracle, PostgreSQL, and SQLite.

{% stepper %}
{% step %}
**Open the New Dataset page**

Open the New Dataset page.
{% endstep %}

{% step %}
**Enter dataset details**

Enter your name and a description of your dataset.
{% endstep %}

{% step %}
**Select a workgroup**

Select your workgroup.
{% endstep %}

{% step %}
**Choose schema generation**

Indicate whether you want to auto-generate the schema from the data or select one from the list (if there is one available).
{% endstep %}

{% step %}
**Choose the location type**

In the New Dataset section, in the Location section, slide the **Tabular Data** to the right, then select **SQL Server**.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/oNkxwUWkH341uoqtdho6/31357013300381)
{% endstep %}

{% step %}
**Enter database details**

Enter the following details so that Rhino FCP can connect to your database.

* Database Type - Select the type from the drop down list.
* Database Name - Enter the database name.
* Database Port - Enter the port.
* Database URL - Enter the database URL.
* Username - Username to gain access to your database.
* Password - Password to gain access to your database.
* Timeout Seconds - The number of seconds for the timeout. The default number is typically adequate, but you can adjust this as needed.
  {% endstep %}

{% step %}
**Enter a SQL query**

Enter a SQL query to pull data from the database. You will want to create a simple query that will enable you to test your credentials, such as `SELECT * FROM [enter_table_name_here] LIMIT 10;` Note that other types of queries, such as determining the name of the database that you are connecting are not supported.
{% endstep %}

{% step %}
**Register the dataset**

Select the **Import New Dataset** button. The New Dataset page closes, and the dataset appears in the Datasets page.
{% endstep %}

{% step %}
**Use the three-dot menu**

If you click on the three-dot menu, there are several options that are available.
{% endstep %}
{% endstepper %}

### Register Tabular Data from the Rhino Client File System

To register tabular data from a CSV or Parquet file, complete the following steps.

{% stepper %}
{% step %}
**Choose the file location type**

In the New Dataset section, in the Location section, slide the **Tabular Data** to the right, then select **File**.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/Yxty24ZP74WSpp7qEo1d/31357013302173)
{% endstep %}

{% step %}
**Enter the file path**

Enter the path to your file. The path should be in the Rhino Client File system. For more information, see: [Mounting Storage to Your Rhino Client,](/settings/mounting-storage-to-your-rhino-client) [Importing to and Exporting Datasets from Your Network Storage](/getting-started/quick-start-guide/importing-and-exporting-datasets-to-and-from-your-network-storage), and [Example 2: Defining a Dataset with File Data.](/datasets/example-2-defining-a-dataset-with-file-data)
{% endstep %}

{% step %}
**Register the dataset**

Select the **Import New Dataset** button. The New Dataset page closes, and the record of the dataset appears in the Datasets page.
{% endstep %}
{% endstepper %}

### Register File Data (Non-Tabular)

To register file data from non-CSV files, complete the following steps.

{% stepper %}
{% step %}
**Choose the Rhino Client File System location**

In the New Dataset section, in the Location section, do the following:

* Slide the **Tabular Data** to the right and select **Rhino Client File System**. The File Data and DICOM Data sliders become active.
* Slide the **Tabular Data** slide to the left.
  {% endstep %}

{% step %}
**Open File Data**

Next, slide the **File Data** slider to the right. The File Data section opens.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/n1xQ7GX1HqlhAXxJYrIW/31357013302557)
{% endstep %}

{% step %}
**Enter the file path**

Enter the path to your file. The path should be in the Rhino Client File system. For more information, see: [Mounting Storage to Your Rhino Client,](/settings/mounting-storage-to-your-rhino-client) [Importing to and Exporting Datasets from Your Network Storage](/getting-started/quick-start-guide/importing-and-exporting-datasets-to-and-from-your-network-storage), and [Example 2: Defining a Dataset with File Data.](/datasets/example-2-defining-a-dataset-with-file-data)
{% endstep %}

{% step %}
**Register the dataset**

Select the **Import New Dataset** button. The New Dataset page closes, and the record of the dataset appears in the Datasets page.
{% endstep %}
{% endstepper %}

### Register DICOM Data

To register DICOM Data, complete the following steps.

{% stepper %}
{% step %}
**Choose DICOM Data**

In the New Dataset section, in the Location section, slide the **DICOM Data** slider to the right. You can choose to provide the path to the DICOM Files or connect to the DICOM Server.
{% endstep %}

{% step %}
**Enter a DICOM file path or choose the server option**

By default the Files option appears. If you want to register DICOM files by specifying the file path, enter the path in the DICOM PATH text box. You’ll need to have already downloaded the files to a path that is part of the Rhino Client File system. For more information, see: [Mounting Storage to Your Rhino Client,](/settings/mounting-storage-to-your-rhino-client) [Importing to and Exporting Datasets from Your Network Storage](/getting-started/quick-start-guide/importing-and-exporting-datasets-to-and-from-your-network-storage), and [Example 2: Defining a Dataset with File Data.](/datasets/example-2-defining-a-dataset-with-file-data) ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/gIWC1MTUcSyV6BwS5c24/31357013303709)
{% endstep %}

{% step %}
**Select DICOM Server**

If you would prefer to enter the DICOM Data from the DICOM Server, select the DICOM Server button. ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/xM8A4GonbqfYu26wpAg5/31357028503197)
{% endstep %}

{% step %}
**Enter DICOM server details**

Enter the Host, DICOM Web Port, DICOM Web Prefix, as well as the Username and Password for access.
{% endstep %}

{% step %}
**Register the dataset**

Select the **Import New Dataset** button. The New Dataset page closes, and the record of the dataset appears in the Datasets page.
{% endstep %}
{% endstepper %}

### Troubleshooting Dataset Registration

To troubleshoot data registration, complete the following steps.

{% stepper %}
{% step %}
**View the error message**

Hover the pointer over the exclamation point to view the error message. The error message provides information that can help you troubleshoot.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/4azVxco2j2RXGa78rPPy/31357013304989)
{% endstep %}

{% step %}
**View the dataset configuration**

Select the three-dot menu, then select **Show dataset configuration** to view the setup information.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/heGyq7DN1Ym6SSkK1UuM/31357013305117)
{% endstep %}

{% step %}
**Check your configuration**

* Is your username correct?
* Are your connection details correct?
* Are your file paths correct?
* If you are connecting using a SQL query, make sure that table names and fields are spelled correctly. If needed, try a different query.
  {% endstep %}

{% step %}
**Test the connection directly**

If a SQL query seems to be correct, try connecting to the database directly using the same credentials that you used in Rhino FCP. Also, try running the query against the database to ensure that the credentials and queries are correct.
{% endstep %}

{% step %}
**Try the import again**

If needed, try creating a new version of the import and running it again.
{% endstep %}

{% step %}
**Contact support**

Contact us if you have any other issues.
{% endstep %}
{% endstepper %}

### Registering Datasets at a Collaborating Site

Given the right permissions, it is possible for users to register Datasets at other sites (and not just their own site). This is useful in case collaborators prefer to only prepare the data and not perform the Dataset import operation on the Rhino FCP.

To perform a remote Dataset registration, a user’s role must have the “Import and export Datasets” permission for that site. For example, if you are the Workgroup Admin of the site that created the project (hence you are the Project Lead Admin, or PLA), then the collaborating site must enable the “Import and export Datasets” permission for the PLA persona.

To trigger the Dataset registration at the collaborating site via the UI, follow the same process for importing a Dataset to your own site via the UI, and in the Select Workgroup dropdown, select the Workgroup of the collaborator. Make sure to input the data file locations on the collaborator’s Rhino Client.

To trigger the Dataset registration at the collaborating site via the SDK, follow the same process for registering a Dataset to your own site via the SDK, and in the “workgroup\_uid” field pass in the UID of the collaborator’s workgroup.

## Viewing a Dataset's Configuration

To get an object's configuration, make sure you are on the page containing the original object you would like to view the configuration of. In the box where your original object is, there should be a row for each version. Navigate to the version you would like to view the configuration for and select the three-dot menu button, shown below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/R52q1fV79ne19BOIFsO6/12987205451293)

The menu button is on the right-hand side of the row, click it to view a new menu. The new menu should have an option to show that object's configuration, click on that to see the object's configuration.

## Exporting Datasets

Exporting a dataset makes it accessible in your `/rhino_data` directory in your Rhino Client. You can then access the dataset via SFTP or client-mounted storage. Then, you can use the data outside of the Rhino platform. You can only export datasets that belong to your workgroup if you have the Manage This Site's Datasets Permission. For more information, see [Persona and Permissions Policies Reference](/projects/persona-and-permissions-policies-reference)

### Exporting a Dataset

To export a dataset, do the following.

{% stepper %}
{% step %}
**In the Dataset page, on the overview page, select the three-dot menu for the dataset that you want to export.**

<img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/hR9XzguvJ5feZ5LuxKeP/32247885815325" alt="" width="50%">
{% endstep %}

{% step %}
**Select Export Dataset. The Export Dataset window opens.**

<div align="left"><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/zOmncaTHSBhUqL9mOI7a/32247885817373" alt="" width="60%"></div>
{% endstep %}

{% step %}
**Type where you want to export the dataset, then select the Export button.**

```auto
/rhino_data/export_folder
```

{% endstep %}
{% endstepper %}

### Structure of your exported dataset

Your exported dataset will be structured similarly to how datasets are structured for code run inputs and outputs. In particular, your dataset will have a directory structure that resembles:

```auto
.
|___ dataset.csv
|___ metadata.json
|___ dicom_data/
|______ ...
|___ file_data/
|______ ...
```

Inside this directory, you will find some (or all) of the following elements:

* **dataset.csv** - a comma-separated value file with the tabular data from your dataset
* **metadata.json** - a json containing information about the dataset (e.g., which workgroup it belonged to, when it was created)
* **dicom\_data/**- a directory containing any DICOM files associated with your dataset
* **file\_data/**- a directory containing any generic files associated with your dataset (e.g., jpegs)

### Metadata Structure

The **metadata.json** file contains the following key-value pairs:

```auto
dataset_uid: str
dataset_name: str
dataset_version: int
data_schema_uid: str
data_schema_name: str
workgroup_uid: str
workgroup_name: str
creation_time: str
num_rows: int
num_fields: int
fields: List[str]
```

See an example below:

```auto
{
  "dataset_uid": "a186342e-7a0d-46cd-819d-b751f361108d",
  "dataset_name": "Clinic Dataset",
  "dataset_version": 0,
  "data_schema_uid": "51ee196b-f978-4ca9-9583-6c0309bc3a4a",
  "data_schema_name": "Diabetes Schema",
  "workgroup_uid": "5a2eee3b-dbf2-492d-93fa-1175ae2ad7a9",
  "workgroup_name": "Clinic",
  "creation_time": "2022-09-28 11:51:57.070000+00:00",
  "num_rows": 275,
  "num_fields": 10,
  "fields": [
    "Pregnancies",
    "Age",
    "Height",
    "Weight",
    "Glucose",
    "BloodPressure",
    "SkinThickness",
    "Insulin",
    "DiabetesPedigreeFunction",
    "Outcome"
  ]
}
```

### Access to your exported dataset

Once exported, the exported dataset can be accessed using the instructions below.

#### **SFTP**

Log into the client via SFTP and run the following command.

```auto
sftp> get export_folder
```

Need more help? See [Adding Data to your Rhino Federated Computing Platform (FCP) Client using SFTP](/getting-started/quick-start-guide/registering-data-to-your-rhino-federated-computing-platform-fcp-client-using-sftp)

#### **AWS S3, GCP Cloud Storage, SMB**

Find your files (see above) in your cloud or external storage.

Need more help? See [Importing and Exporting Datasets to and from Your Network Storage](/getting-started/quick-start-guide/importing-and-exporting-datasets-to-and-from-your-network-storage)


# Importing data in my local environment onto my Rhino FCP client using SFTP

The process of moving data from your local environment to your Rhino FCP client using SFTP depends on the operating system of your local machine.

#### Connecting to your Rhino FCP Client via SFTP from MacOS, Linux & Windows 10+

{% stepper %}
{% step %}
Open a terminal or command prompt on your respective operating system, and navigate to the folder where the data that you would like to upload are located.
{% endstep %}

{% step %}
Connect to your Rhino FCP Client via SFTP

* Retrieve your SFTP server IP and credentials from your Rhino FCP profile page. If you need a quick refresher on how to do that, see [Viewing and Adjusting Your Settings](/settings/viewing-and-adjusting-your-settings).
* Connect to your Rhino FCP client via SFTP, by entering the following.

Note: Ensure to replace `RHINO_CLIENT_IP_ADDRESS` in the below command with the credentials found in your profile.

```bash
> sftp rhinosftp@RHINO_CLIENT_IP_ADDRESS
```

{% endstep %}

{% step %}
Next, you will be prompted to enter your SFTP password, and if everything is entered properly you will be connected to your Rhino FCP client and your command line should change to look like the following:

```bash
sftp>
```

**For additional help with common commands within the SFTP terminal interface, check out the section** [**Common Commands when SFTP'ing Data**](#01H7BJ37P6X1GA3C4DXHDHEFB0) **.**
{% endstep %}
{% endstepper %}

#### Connecting to your Rhino FCP Client via SFTP from Other Operating Systems

{% stepper %}
{% step %}
To SFTP data from other Operating Systems to your Rhino FCP client, you will need to first install an SFTP client, like [Cyberduck](https://cyberduck.io/), [WinSCP](https://winscp.net/eng/index.php), etc.
{% endstep %}

{% step %}
Once your SFTP client has been installed, you can configure a new SFTP connection.

* Retrieve your SFTP server IP and credentials from your Rhino FCP profile page. If you need a quick refresher on how to do that, see [Viewing and Adjusting Your Settings](/settings/viewing-and-adjusting-your-settings).
* If you are successfully connected to your SFTP client, you should see two separate panels, one displaying your local machines file system and a second showing your Rhino FCP client's filesystem.
  {% endstep %}

{% step %}
Using the STFP client to upload your data:

* On the local machine file system panel, navigate to the folder where your data is located.
* On the Rhino FCP client file system panel, navigate to where you would like to place the data.

  Note: It is recommended that you create folders for your datasets to keep things organized.
* Drag the files from the local machine file system panel to the Rhino FCP client file system panel to upload your data to the Rhino FCP client server.
  {% endstep %}
  {% endstepper %}

#### Common Commands when SFTP'ing Data

Use the following commands to create folders, navigate to different folders, view folder contents, and upload data.

**Create a new folder called DIRECTORY\_NAME within your Rhino FCP client**

```bash
sftp> mkdir DIRECTORY_NAME
```

**Change to the specified directory, DIRECTORY\_NAME within your Rhino FCP client**

```bash
sftp> cd DIRECTORY_NAME
```

**List all files within the current directory on your Rhino FCP client**

```bash
sftp> ls
```

**Upload the specified file FILE\_NAME on your local machine to the current directory of your Rhino FCP client**

```bash
sftp> put FILE_NAME
```

**Upload the folder and all of its contents on your local machine to the current directory of your Rhino FCP client**

```bash
sftp> put -r DIRECTORY_NAME
```

**Exit out of the SFTP connection**

```bash
sftp> exit
```


# Creating and Exploring Federated Datasets

{% hint style="info" %}
If your dataset contains sensitive data, then by default, all output datasets are considered to be sensitive. For more information on this, including how to mark which data is sensitive and which is not, please see [Sensitive Datasets](/datasets/sensitive-datasets).
{% endhint %}

### Introduction

The **Federated Datasets (FDs)** feature enhances the discoverability of data available via the FCP, enabling users to explore and share datasets in a more accessible manner. Whether you are a data owner or a data scientist, this guide will help you navigate the process of creating and exploring Federated Datasets.

### Creating a New Federated Dataset

If you are responsible for data strategy and want to make your organization’s data assets more accessible, follow these steps to create and publish a new Federated Dataset:

{% stepper %}
{% step %}

### Create a Project

* Log into Rhino FCP and create the project.
* Make sure to add permissions to each Federated Dataset site.
  1. For each site, select the Project > Collaborators > Permission Policy.
  2. Ensure that Manage This Site's Datasets is added for the Federated Dataset. So for example, if a Federated Dataset is comprised of 3 datasets from 3 sites, you will need to make sure that the Manage This Site's Datasets permission is set for each site. See more information in [Specifying a Project's Permissions Policy](broken://spaces/ydySyCBmy6F7NnGn4bPa/pages/542db722fc131c962accea9c3aff99908978a7ff).
* Import relevant data into the project.
  {% endstep %}

{% step %}

### Prepare your data for publishing

* The Rhino FCP enables you to run custom code for data preprocessing (e.g. feature extraction, data cleaning, etc.).
* If needed, read [Creating and Running Code Objects](/creating-and-running-code-objects/what-is-a-code-object) for more information.
  {% endstep %}

{% step %}

### Create Federated Dataset

* Select the dataset you wish to publish and click "Create Federated Dataset."
* The Create Federated Dataset page opens.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/jG3DZxUkN2itsdkaI7GQ/15483007105437)

* Define Access and Privacy Settings.
  * Public name for the FD.
  * Set viewing privileges for data analytics. Selecting "Limited" will require users to submit an access request for your approval.
  * Specify privacy settings (k-anonymization, differential privacy).
  * Optionally provide an alternative contact email address. The default email address will be the one you use to log into the FCP.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/D6fWYVaDQ5vexOQAZhWw/15483038852637)

* Define a "Datasheet" for the FD with the following sections:

  * *Motivation*
  * *Composition*
  * *Geography*
  * *Data type*
  * *Modality*
  * *Disease Group*
  * *Body Part*
  * *Collection Process*
  * *Preprocessing / cleaning / labeling*
  * *Uses*
  * *Distribution*
  * *Maintenance*

  **Note: This information will help users find your dataset via keyword search.**

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/kUQb5ky1qX9Z4HskVFRb/15483007110045)
{% endstep %}

{% step %}

### Publish your Federated Dataset

* Click "Publish" to make the FD accessible.
* Find your published FD under the "Datasets" section in FCP.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/qPLHaUhqF5lyHjVeT5Uq/15483038856093)
{% endstep %}

{% step %}

### Managing access

* Access requests will be delivered by email, and will also be visible on the FCP under the specific datasets:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/6O3KLiWplisJjYPo9YFo/15483007114141)

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/FDFJPoTqLkm7KJxPJAQ5/15483007115805)

* To review requests and grant/deny access, navigate to the Access view inside the relevant dataset.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/viTvQPkmogalgNxyvW7Y/15483038863261)
{% endstep %}
{% endstepper %}

### Exploring an Existing Federated Dataset

As an FCP user interested in exploring datasets for your project, follow these steps to explore an existing Federated Dataset:

{% stepper %}
{% step %}

### Log into the Rhino FCP

* Log into Rhino FCP.
  {% endstep %}

{% step %}

### Navigate to the Datasets view by clicking the Datasets icon

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/jITreYTFTJZoWvnSCWlC/15483007120541)
{% endstep %}

{% step %}

### Search for Datasets

* Use the "Search by keyword" feature to find relevant datasets.
  {% endstep %}

{% step %}

### View Datasheet

* Click on a dataset.
* The Datasheet and Data Schema defined by the publisher opens.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/1vGt0v0eYhmE53h5N79F/15483007122461)
{% endstep %}

{% step %}

### Explore Analytics

* The ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/QvbK8SUkAhS4Yl2VlWgZ/15483007123357) icon indicates that access to the data analytics must be approved by the publisher.
* Click on Analytics to fill and submit an access request. You will need to provide:
  * Name of affiliation (Academic Institution, Company)
  * Type of affiliation (Academic, Commercial)
  * Purpose for querying the data - a brief description of your goals for the publisher's consideration.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/iQkCpZqiftAjcBgBpN5M/15483038877597)

* Once you submit the request, a notification will be sent to the publisher. Upon approval, you will be notified and can view Analytics for the dataset.
  {% endstep %}

{% step %}

### Using a Federated Dataset in your project

* Reach out to the data publisher in order to gain full access to the data, enabling you to run your code using the data via the Rhino FCP. You can also do so by reaching out to us at <support@rhinohealth.com> and we will be happy to assist!
* Once agreements have been achieved by you and the data publisher, a project will be created for you with the publisher as a collaborator and the relevant dataset will be imported into that project.
  {% endstep %}
  {% endstepper %}

You are now ready to explore Federated Datasets on Rhino FCP. If you have any further questions or need assistance, feel free to refer to our comprehensive documentation or reach out to our support team.


# Sensitive Datasets

Importing, Reviewing, Viewing, and De-Identifying Sensitive Datasets

Rhino FCP safeguards sensitive data. Sensitive data is information that must be kept confidential because unauthorized access could pose risks. This includes categories such as Personally Identifiable Information (PII), Protected Health Information (PHI), Payment Card Industry (PCI) data, and other personal data protected by various regulations. Examples of sensitive data are a patient’s social security number, a client’s full name, or a person’s credit card number and security code.

## Background

Our Data Security Principles, which are listed below, keep data (including sensitive data) secure. Here is a summary of our principles.

* **De-identified individual data is persisted within the institution’s firewall and can be provided for temporary remote access with proper authorization.** De-identified data about individual people (regardless of data type) is always stored behind the institution's firewall, in the Rhino Client. It is shared within the Rhino Client with models for training/validation. It can only be shared with users transiently, meaning it does not persist outside of the firewall, and after obtaining required approvals from the data custodian.
* **De-identified aggregate data can be stored outside the institution’s firewall.** Aggregate statistics of de-identified data can be stored outside of the institution's firewall, such as in the cloud, and provided to authorized users based on their permission settings, so long as they are aggregated enough to sufficiently reduce the risk of re-identification (e.g. using k-anonymization with ‘k’ defined by the institution).
* **Sensitive data (such as PII/PHI) is only persisted within the institution’s firewall, including derived aggregate statistics, and can be provided for temporary remote access with proper authorization.** Sensitive data (such as PII and PHI) is only stored behind the institution's firewall, in the Rhino Client. Aggregate statistics of sensitive data are also only stored behind the institutional firewall. The sensitive data is shared (within the Rhino Client) with code/models for processing, and all outputs of such processing are also considered as potentially containing sensitive data. Sensitive data can only be shared with users transiently and after obtaining required approvals from the data custodian, such as ensuring that a Business Associate Agreement (BAA) is in place.

## Importing and Reviewing Sensitive Datasets

Rhino FCP securely handles sensitive information in datasets. You can explicitly indicate which fields contain (or could potentially contain) secure data, such as a Patient ID that might be based on a Social Security number or a payment field that includes a credit card number.

Rhino FCP employs [Safe Harbor to de-identify secure data](/datasets/dataset-de-identification); what happens to the data depends on the [datatypes of the data fields indicated in the schema.](/data-schemas/supported-data-schema-data-types)

When you import a dataset with sensitive data, you will need to do several things before you use it.

* View the available datasets.
* Import a dataset and select whether to autogenerate a schema for it or use an existing schema.
* Review the dataset. This includes tailoring the schema for the dataset if needed, reviewing fields that contain sensitive data, and determining whether to make sensitive information available to collaborators.

### Viewing Available Datasets

{% stepper %}
{% step %}

#### View datasets

Select the Dataset from the main menu in your project. Available datasets appear on the page. Use the Filter options in the top right sections to filter by creator or schema.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ZLiE8Ku8vVCRPDMKt6eO/27535799467805)
{% endstep %}

{% step %}

#### Identify sensitive datasets

When a dataset has sensitive information, it is highlighted in pink and has an icon, as shown below.

<div align="left"><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/tG2hge0CsTcRzT0eMBOt/27535799468061" alt=""></div>
{% endstep %}
{% endstepper %}

### Importing a Dataset

{% stepper %}
{% step %}

#### Open the import flow

In the Datasets page, on the Overview tab, select the Import New Dataset button located in the top right corner of the page.
{% endstep %}

{% step %}

#### Enter dataset information

In the Import New Dataset page, enter the following information:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/RkoZAMuyMt9Mo7F3T1Zh/27535799468829) ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/d0pWvjJ6VYo4AOwLOnhO/27535777279261)

* Name: Name of the dataset.
* Description: Description of the dataset.
* Workgroup: The name of the workgroup that the dataset belongs to.
* Data Schema: Indicates the name of the schema for the dataset. If you do not want to use an existing schema, you can choose to auto-generate a schema from the data. Otherwise, choose a schema from the selections offered.
* DICOM Data Location (if needed) - Indicate the import method (DICOM Server or File System)
* DICOM Path (if needed): Indicate path where the DICOM data is stored.
* File Data Location: Indicate the path of the file data.
* Sensitive Data - Indicates whether the dataset contains sensitive data. Note that when you import a new dataset, you select Auto-generate schema from data in the Data Schema field, and you select the Sensitive Data field, you will need to review the schema by clicking the Review Schema button. If you import a new dataset, but select a schema (and do not autogenerate it), you can select the Sensitive Data field and then select the Import New Dataset button. Rhino FCP behaves this way because it is assumed that you've already indicated which fields are sensitive in the schema you chose.
  {% endstep %}

{% step %}

#### Import the dataset

Select Import New Dataset.
{% endstep %}
{% endstepper %}

### Reviewing the Schema of Sensitive Dataset

To review the schema, examine the schema and review the analytics, then review project settings.

#### **Examine the Schema and Mark Sensitive Data**

{% stepper %}
{% step %}

#### Open the schema

Select Data Schema, then select the schema that your dataset uses. The Schema page opens.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/BALgJV3Vfyo8djm3wYre/32679895555869)
{% endstep %}

{% step %}

#### Review the fields

Review the information in these fields:

* **Name:** Name of the field.
* **Identifier**: The string by which this field is identified in the input data. If empty, the Name field will be used for identification.
* **Description**: Description of the field.
* **Type**: The field's data type, like Float or String. Please refer to the Supported Data Schema Data Types for a full list of supported data types within the Rhino FCP. If you decide to de-identify sensitive data, Rhino FCP employs [Safe Harbor.](/datasets/dataset-de-identification) You will want to familiarize yourself with what happens to the data depends on the [datatypes of the data fields indicated in the schema.](/data-schemas/supported-data-schema-data-types)
* **Type Params**: Any parameters for the field type (e.g., min/max values for a ContrainedInt type). Please refer to the Supported Data Schema Data Types for a full list of supported parameters for each data type within the Rhino FCP.
* **Unit**: The Unit in which the values of this field are expected to be. These units will also appear in charts showing aggregate values from this field in the Rhino user interface.
* **Required:** Indicates whether the schema field is required or not.
* **Sensitive Data**: Information that must be kept confidential because unauthorized access could pose risks. This includes categories such as Personally Identifiable Information (PII), Protected Health Information (PHI), Payment Card Industry (PCI) data, and other personal data protected by various regulations. Move the slider to the right if the data in the field is sensitive (contains PHI, PII, PCI, or other information that must be safeguarded).
* **Aggregate Statistics**: Move the slider to the right (Enabled) if the field should be included in aggregate statistics in the data analytics page or in federated analytics via the Rhino SDK. Note that if the field contains sensitive data, aggregate statistics cannot be able to be enabled to avoid inadvertent exposure of sensitive data.
* **Secure Access**: Indicates whether the field should be included in data shared via secure access lists, which is under the Secure Access tab for your dataset. (You can do this only if you have permission to do this.) To do this, move the slider to the right to enable this option. If it is disabled, no one will be able to see the data; if it is enabled, then those with the secure access permission will be able to view the data.

Use care as you adjust the Sensitive Data setting. If you indicate that a field contains Sensitive Data, it will automatically disable aggregate statistics. If you set Sensitive Data to "No" again, the aggregate statistics setting will still be disabled, so you might need to enable it again if needed.
{% endstep %}
{% endstepper %}

#### **Examine Analytics Data**

When you select the Analytics tab, which appears when the Dataset menu option is selected, sensitive data is omitted from the Data Completeness and field sections. However, if you have permissions to view sensitive data and the secure access option is enabled, you will see the omitted data.

## **Review Project Settings**

If necessary, you will need to review the project settings for collaborators. To do this, complete the following steps.

{% stepper %}
{% step %}

#### Open collaborator permissions

In your project, go to Collaborators > Site Level > Action.
{% endstep %}

{% step %}

#### Set the appropriate personas

Indicate which personas can do the following:

* Manage Secure Access Lists
* Share Secure Access Lists
* View Datasets via Secure Access View Client Side Logs with Sensitive Data
* View Sensitive Datasets via Secure Access.
* View Client Side Logs with Sensitive Data - Allows collaborators to view logs from code runs on Sensitive Databases from the site. If collaborator personas are not added, collaborators will not be able to see logs from sensitive datasets.

{% hint style="info" %}
For more information on how to make changes to Site Level permissions, see [Persona and Permissions Policies Reference](/projects/persona-and-permissions-policies-reference). Note the following: View Sensitive Datasets via Secure Access - Allows collaborators to access sensitive data from this site with views such as the tabular data view. It also allows access from interactive containers, including fields marked as local only.
{% endhint %}
{% endstep %}
{% endstepper %}

## De-Identifying a Dataset with Sensitive Data

De-identification is the process of removing or modifying personal and sensitive information from data sets to protect individuals' privacy. This is typically done by removing identifiable elements such as names, addresses, and other direct identifiers while retaining the data's usefulness for analysis and research. Note that if you choose to de-identify data, this could result in data loss. Rhino FCP employs [Safe Harbor.](/datasets/dataset-de-identification) You will want to familiarize yourself with what happens to the data is based on the [datatypes of the data fields indicated in the schema.](/data-schemas/supported-data-schema-data-types)

To de-identify the dataset, complete the following steps.

{% stepper %}
{% step %}

#### Open the dataset

Select Datasets from your project's menu, then select the Overview tab.
{% endstep %}

{% step %}

#### Select the sensitive dataset

Select a dataset that has sensitive data. A sensitive data dataset is highlighted in pink and has the sensitive data icon.
{% endstep %}

{% step %}

#### Inspect the data

Inspect the data by doing the following.

* Select the Analytics link; ensure that no sensitive data is shown and that the data looks as expected.
* Select the Data link; ensure that sensitive data appears and that data looks as expected.
* If needed, also select secure access.
* If the information does not look as expected (for example, if something that should be marked as Sensitive Data, but is not), select Data Schemas from the main menu, then select the schema for the dataset. In the data schema for the dataset, review the type, whether it is marked as Sensitive Data, whether it should be in aggregate statistics, and whether secure access should be enabled.
  {% endstep %}

{% step %}

#### Open the dataset actions menu

Next, select Datasets and in the Overview tab, select the three-dot menu to the right of the dataset.
{% endstep %}

{% step %}

#### Optionally run schema-based de-identification

Optionally, select Perform schema-based de-identification if you want to perform the schema-based de-identification on Safe Harbor. Keep in mind hat if you do this, there could be data loss. You might choose to do this if you are testing or writing code, but might not choose to do this in production.

<div align="left"><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/AQC39d8UyevZhhqVhzII/27622142137629" alt=""></div>
{% endstep %}

{% step %}

#### Choose whether to mark the result

In the pop-up window that appears, select the Mark resulting dataset as de-identified if you want to indicate that Safe Harbor was applied without further checking. If you want to review it, leave the checkbox unchecked. Select Confirm to close.

<div align="left"><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/XQDy4V4V6ogqHnR2kBNC/27622158855325" alt=""></div>
{% endstep %}

{% step %}

#### Review the new dataset

A new dataset is created. If you select it and view analytics, the de-identified data now appears in the analytics.
{% endstep %}

{% step %}

#### Mark the dataset as de-identified

If you did not check the checkbox in the pop-up window (marking the dataset), select the three-dot menu to the right of the dataset entry in the Dataset Overview tab, and select Mark as de-identified if you want to mark the dataset as de-identified.
{% endstep %}
{% endstepper %}


# Dataset De-identification

On overview for dataset de-identification.

There are several methods for Dataset de-identification using Rhino FCP:

* De-identifying data before importing
* HIPAA Safe Harbor De-identification using the Rhino FCP's built-in capabilities
* De-identification using custom Code Objects
* Interactive de-identification using *Interactive Containers*

## De-identifying Data Before Importing

This doesn’t involve Rhino FCP directly, but users always have the option of de-identifying data before making it accessible on the Rhino FCP using any methods or utilities.

The de-identified data can then be made accessible to the Rhino Client (e.g., via client-mounted storage or SFTP) and then imported as a Dataset into the FCP. For more information see [Mounting Storage to Your Rhino Client.](/settings/mounting-storage-to-your-rhino-client)

## HIPAA Safe Harbor De-identification

FCP supports [HIPAA Safe Harbor De-identification](https://www.hhs.gov/hipaa/for-professionals/privacy/special-topics/de-identification/index.html#safeharborguidance) on some Dataset data types. This is implemented via the field types defined in the Data *Schema*. Each field type can have specific de-identification logic associated with it. For example, fields specified as being type Age will be de-identified by setting all values ≥90 to 90. A full list of FCP data types and their associated de-identification logic is listed in the [Supported Data *Schema* Data Types](/data-schemas/supported-data-schema-data-types) page.

To apply HIPAA Safe Harbor De-identification, complete the following steps:

When reviewing the data schema, set the **Sensitive Data** options for each field. When finished, select the dataset's three-dot menu and select **Perform schema-based de-identification** option. This triggers the de-identification process. When complete, right click the menu again, select the Mark as de-identified. For detailed instructions see [Sensitive Datasets](/datasets/sensitive-datasets) article for detailed information on how to do this.

* Any field that is marked in the Data S *chema* with **Sensitive Data** as No, will simply be copied over to the de-identified data.
* Any field that is marked in the Data S *chema* with **Sensitive Data** as Yes, and the field type has associated de-identification logic (e.g., Age—See [Supported Data *Schema* Data Types](/data-schemas/supported-data-schema-data-types)), will have that de-identification logic applied to produce the de-identified data for the field.
* Any field that is marked in the Data S *chema* with **Sensitive Data** as Yes, and whose field type does not have any associated de-identification logic (e.g., String—See [Supported Data *Schema* Data Types](/data-schemas/supported-data-schema-data-types)) will be omitted from the de-identified data (the entire column will be removed).

Any information that is important for the reverse translation between de-identified and raw data (e.g., reverse crosswalk tables for newly generated de-identified UIDs) will be stored by RHP along with the raw Dataset data (this data is treated as sensitive).

## De-identification with Custom Code Objects

Users can apply custom de-identification logic using any library they desire using Rhino's Generalized Compute (GC) Code capability. Users could utilize open *source* software, 3rd party tools, or code that they wrote, build a container that includes this software, and run it on the FCP.

The code should be written such that it reads the raw Dataset from `/input/` (within the container) and writes the clean (de-identified) Dataset to `/output/` (within the container).&#x20;

Secure Access could be used to review the de-identified Dataset and verify that no sensitive data was accidentally left intact. This could be performed either by members of the site from which the Dataset was imported or by another collaborator (after the owner has provided access via a Secure Access List).

It is also possible to limit visibility to the raw Dataset and/or the de-identified Dataset before it has been reviewed or approved. No one will have access to the patient-level data unless they have been granted access via Secure Access.

In order to further limit access to aggregate statistical information about the Dataset before it has been approved (e.g., Categorical fields where sensitive data may have been left):

1. Users can set the default permissions for viewing Dataset analytics to just their own site, and then the project lead and other project collaborators will not be able to view aggregate statistics about their Datasets.
2. Users can create a separate project in which they will interact with the Dataset before it has been validated as being de-identified. Then, once the Dataset has been validated as being sufficiently de-identified, the de-identified data can be exported from the “de-identification” project and re-imported into the “real” project.

## Interactive De-identification with Interactive Containers

In addition to applying custom de-identification logic that will run remotely using GC, users can utilize the FCP's Interactive Container capability to create Code Objects that enable them to perform de-identification in an interactive session.

Users can take the application they want to use, as long as it can run on Linux, and build a container that includes this application. Then, this container can be run in an interactive session on the FCP.

Users can connect to the UI of this interactive session and use the application to perform de-identification. The raw Dataset will be available at `/input`, and after de-identification, users can store the clean (de-identified) Dataset to `/output`.

Similar to de-identification with GC, Secure Access can be used to review the de-identified Dataset and verify that no sensitive data was accidentally left intact. It is also possible to limit visibility to the Dataset before de-identification has been verified in the same way as with using GC for de-identification.


# Publishing and Unpublishing Datasets

How to share (publishing) and stop sharing (unpublishing) with collaborators.

When you import a dataset, it is unpublished by default. You can choose to publish it to share with other collaborators that have the View Datasets and Data Schema policy set. To learn more, see [Viewing Your Project's Permissions Policy.](/projects/creating-a-new-project#configure-permissions) Also, if you have sensitive data, review the options you have for sharing that data before continuing. For more information, see [Sensitive Datasets](/datasets/sensitive-datasets).

### Publishing Datasets

To publish a dataset, complete the following steps.

{% stepper %}
{% step %}

#### Select publish from the three-dot menu.

<div align="left"><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/dSMEgo6zfFDlO02OYSoM/31972854474141" alt=""></div>
{% endstep %}

{% step %}

#### A message appears asking if you would like to publish the dataset.

If you want to unpublish previously published versions of the dataset, leave the button for that option selected. Otherwise, deselect it.

<div align="left"><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/XRkPfSqna38qnhSdfPpH/31972821475741" alt=""></div>
{% endstep %}

{% step %}

#### Select the Publish Dataset button.

All other participants granted permission to view published datasets will be able to see the dataset. The Publish badge appears on the dataset entry in the Datasets screen.

<div align="left"><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/aa4WcWvfrraX6PgwXUXy/31972821477661" alt=""></div>
{% endstep %}
{% endstepper %}

### Unpublishing a Dataset

To unpublish a dataset, complete the following steps.

{% stepper %}
{% step %}

#### Select unpublish dataset from the three-dot menu.

<div align="left"><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/xF7zrTFmIaYkUtdfuD5s/31972854475549" alt=""></div>
{% endstep %}

{% step %}

#### A message appears asking you if you want to unpublish the dataset.

{% endstep %}

{% step %}

#### Select Unpublish Dataset.

All other participants are no longer able to see the dataset.
{% endstep %}
{% endstepper %}

### Troubleshooting Publishing Issues

This section addresses common errors encountered when attempting to publish datasets or data schemas.

<details>

<summary>The "Publish" option is not on the menu</summary>

* **Cause:** The project's site-level permission for **"View Datasets and Data Schemas"** is likely set to **Full Visibility**(all of the personas have access to the dataset or data schema).
* **Solution:** In Full Visibility mode, all objects are shared with all project members by default; therefore, manual publishing is not required or available. To enable private drafting, a Project Lead must change the permission setting to **Partial Visibility**(only some of the personas have access to the dataset or data schema).

</details>

<details>

<summary>Error: "Cannot Publish Dataset" (Schema Ownership)</summary>

* **The Issue:** You are trying to publish a dataset, but the action is blocked.
* **The Message:** *"The associated Data Schema version \[Name] is currently unpublished and is owned by another workgroup."*
* **Why this happens:** To ensure data integrity, a dataset cannot be public if its schema is private. Because the schema belongs to a different workgroup, you do not have the authority to publish it yourself.
* **How to fix:**
  1. Identify the owner of the Data Schema.
  2. Request that they **Publish** the specific schema version.
  3. Once the schema is published, retry publishing your dataset.

</details>

<details>

<summary>The Data Schema published automatically</summary>

* **The Scenario:** You published a dataset, and its associated schema status changed to "Published" without manual intervention.
* **Explanation:** If your workgroup owns both the dataset and the unpublished schema version, the Rhino FCP automatically publishes the schema to prevent broken dependencies.
* **System Prompt:** You should receive a confirmation dialog stating: *"Publishing this dataset will automatically publish the associated Data Schema version. Do you wish to proceed?"*

</details>

<details>

<summary>The Code Object or Dataset suddenly became "Unpublished"</summary>

* **Cause:** A user (likely a Data Custodian or Schema Owner) has **Unpublished the underlying Data Schema**.
* **The Logic:** Data Schemas are foundational. If a schema is pulled from public view, all "downstream" objects—such as Datasets that follow that schema or Code Objects that use it for input/output—are automatically unpublished to maintain privacy and system consistency.
* **Solution:** Republish the Data Schema to restore visibility to the associated datasets and code.

</details>


# Removing a Dataset Version

How to remove a dataset version

Follow these steps to delete a dataset version.

{% stepper %}
{% step %}

#### Open the Datasets page

Go to the page that lists your datasets.
{% endstep %}

{% step %}

#### Find the dataset version

If needed, use the search fields at the top right.

* Use **Search Name** to search by dataset name.
* Use **Search Description** to search by dataset description.

Each dataset appears with a row for each version. Find the version you want to delete.
{% endstep %}

{% step %}

#### Open the menu for the version

Select the three-dot menu on the right side of the version row, shown below.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/6x6eIJpSpDL2eZ09jT5K/12987199149213)
{% endstep %}

{% step %}

#### Remove the dataset version

Select **Remove dataset**.

Repeat these steps for each version you want to remove. When you delete the last version, the dataset is fully deleted.
{% endstep %}
{% endstepper %}

#### Remove from the object page

You can also remove a dataset or dataset version directly from the **Datasets** page by selecting **Remove dataset**.


# Working with Dataset Analytics

Rhino FCP allows you to view descriptive statistical data as well as actual data values for datasets that you have access to. Sensitive datasets require additional access -- for more information on this type of data, see [Sensitive Datasets](/datasets/sensitive-datasets).

### Viewing Dataset Analytics

To view dataset analytics, complete the following steps.

{% stepper %}
{% step %}

#### Select the Analytics link at the top of the Datasets window.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/DJLpr7Qnxzky7E6WktWv/32512986601629)
{% endstep %}

{% step %}

#### The datasets displayed by default show aggregated, descriptive statistical data that allows you to see the shape of the data for initial assessment.

* *Data Completeness* shows a summary of the data for each field. ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/6nBXQIY6L3KiyAVzB7C2/32512940653085)
* *Fields* show basic descriptive statistics for each field. For some fields there are sort options. In the following example, you can sort by Name or Value.![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/u7edTP9hYhQTy48H3yXR/32512940653341)
* Hovering over an *information icon* allows you to see additional detail, such as the mean and standard deviation of the data.

<div align="left"><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ruMDZw5SdCIb8N0FPhzD/32512940653981" alt="" width="75%"></div>
{% endstep %}
{% endstepper %}

## Adding Filters

To filter specific datasets, complete the following steps.

{% stepper %}
{% step %}

#### Choose the Select Datasets drop down menu. Then select the datasets you want to view.

Note that to see more than one dataset at one time, each dataset must share the same schema.

<img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/XgzyuJJmEc1uEBWEm7PG/32512940654493" alt="" width="75%">
{% endstep %}

{% step %}

#### Next, choose the fields you want to see by selecting the Select Fields drop down menu.

<img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/2RDRKhdtI0CtYgabSPYm/32512986603805" alt="" width="75%">
{% endstep %}

{% step %}

#### To add a filter, make sure the filter icon is selected (it looks like a funnel and is to the right of the Select Datasets button).

When selected, the background of the icon is dark. An entry appears under the Selected datasets section that shows the number of filters already selected and an ADD button.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/gVcIkKZI4BZRwUKn4JFH/32512940655773)
{% endstep %}

{% step %}

#### Select the ADD button, then type the filter name or select it from the list.

<img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/LmEpfxDdN5iDRBd765v3/32512940656541" alt="" width="75%">
{% endstep %}

{% step %}

#### Some filters allow you to indicate which values you want to focus on.

Make your selection, then select Apply.

<img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/y5raHBdwkK59MyRz194A/32512940656925" alt="" width="75%">

The data is filtered.
{% endstep %}
{% endstepper %}

## Viewing Sensitive Data

To view sensitive data, complete the following steps.

{% stepper %}
{% step %}

#### If you have a sensitive data in the dataset, select the dataset that you want to see from the Select Dataset drop down menu.

Or, you can view the data by mousing over the dataset, then selecting the View secure access data pop up that appears.

<img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/CiaqTacgcLjBFGxDw9uc/32512940657437" alt="" width="75%">
{% endstep %}

{% step %}

#### A note appears that indicates that detailed, row-level data will be shown.

Select Continue.

<img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/qi3Ygp8S2kIrwKTlhXAM/32512940657821" alt="" width="75%">
{% endstep %}

{% step %}

#### The secure data appears (if you have access).

{% endstep %}

{% step %}

#### Select the dataset that you want to see from the Select Dataset drop down menu.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/bqQeW0qwjikq3zk9L93b/32512986607389)
{% endstep %}

{% step %}

#### If data is underlined with a hyperlink, clicking it reveals more detail.

{% endstep %}
{% endstepper %}


# Viewing and/or Annotating Datasets and Dataset Images

Explains how to view and/or annotate a dataset's tabular data and image data.

## Viewing and/or Annotating a Dataset's Tabular Data

Viewing and adding text notes to datasets.

### Viewing a Dataset via Secure Access

When you click on a Dataset name, the dataset's page that opens contains two tabs: Analytics and Data. The Analytics tab is identical to the general analytics tab except it is limited to showing only the specific Dataset’s summary statistics. The Data tab can be used to directly view the Dataset's tabular data via Rhino's [Secure Access feature.](/secure-access/what-is-secure-access) This feature provides zero-footprint visualization of tabular and image data, based on the project’s permissions policy. By default, a user can only use Secure Access on data that belongs to their workgroup.

### Adding text notes to Datasets

Rhino FCP enables you to add case-level textual notes when Secure Access is enabled. Secure Access is enabled by default for Datasets from your own workgroup. Secure Access to remote cohorts must be provided by users from that remote workgroup by using the [“Secure Access List” feature](/secure-access/what-is-a-secure-access-list).

* To add text notes to a Dataset from your own workgroup - open the tabular viewer by clicking on your Dataset of interest in the Datasets view, then clicking the DATA tab.
* To add text notes to a Dataset from another workgroup - open the tabular viewer by clicking the relevant Secure Access List.
* The right-most column is always called **Notes**. This is an auto-generated column created whenever a Dataset is imported, unless one already exists.
* You can edit the text in the **Notes** column to add case-level notes. As these notes will be added to the Dataset, they can be used downstream as input for your code, e.g. as ground-truth labels.
* Saving notes: Once you add/edit a note, a bar will appear at the bottom of the screen indicating that there are unsaved changes. Simply click “ADD NOTES” to save your changes. You can make changes to multiple rows before saving.

{% hint style="info" %}
NOTE: Saving changes to notes will produce a new Dataset version. When this happens, the platform will automatically make all previous versions (except the original V.0) inactive. The previous versions will be invisible to the user.
{% endhint %}

## Viewing and/or Annotating a Dataset's Image Data within the Integrated OHIF Viewer

You can use this feature to add pixel-level annotations on DICOM.

### Annotating a Dataset in Your Workgroup

To annotate a dataset from your workgroup, complete the following steps.

1. Open the integrated OHIF DICOM viewer from the tabular viewer by selecting your dataset of interest in the datasets view.
2. Select the Data tab, then click the DICOM UID for your study, series, or instance of interest.
3. The Open Health Imaging Foundation DICOM Image viewer appears.

### Annotating a Dataset from a Different Workgroup

To annotate a dataset from a different workgroup, complete the following steps.

1. Open the tabular viewer by selecting the relevant Secure Access List.
2. Select the DICOM UID for your study, series, or instance of interest.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ZCNZ9puAUA1R5IX0ZPY1/32513088748189)

3. The Open Health Imaging Foundation DICOM Image viewer appears.

### Adding Pixel-Level annotation

DICOM visualization and annotation via the Rhino FCP is facilitated by an integrated version of the Open Health Imaging Foundation (OHIF) viewer, which comes equipped with standard tooling for visualization and manipulation of DICOM images.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/tBKhEcjUowid3dtBUY0M/32217310975901)

The following annotation types supported:

* Rectangle
* Line/Length
* Arrow
* Angle
* Ellipse

To add a pixel-level annotation to a DICOM file, open the file using the OHIF viewer, select your preferred annotation, and create your annotation on the image. To save the annotation(s), click on Measurements -> Save measurements.

{% hint style="info" %}
NOTE: Saving an annotation on the OHIF viewer will create a new DICOM SR file which references the original DICOM file and produce a new Dataset version. When this happens, the platform will automatically make all previous versions inactive (and invisible to the user) except the original V.0 and any other version that is already associated with a specific Code Run.
{% endhint %}

For more information on how to use the viewer, see the Open Health Imaging Foundation Viewer Guide: <https://docs.ohif.org/user-guide/viewer/>


# Example 1: Defining a Dataset with DICOM Data

Explains how to define a dataset with DICOM Data.

## The Data Schema

The Data Schema can be uploaded as a CSV to the Rhino Web UI or added directly to the Rhino Web UI through the built-in Data Schema editor. For this example, we will create this Dataset within the UI and name it Stroke Schema.

| Field Name               | StudyInstanceUID  | SpO2              | Stroke Present    | Number of Points  | Gender                        |
| ------------------------ | ----------------- | ----------------- | ----------------- | ----------------- | ----------------------------- |
| **Identifier**           |                   |                   |                   | (5000, 0010)      |                               |
| **Description**          |                   |                   |                   |                   |                               |
| **Type**                 | DicomStudyUID     | Percent           | Boolean           | DicomTag          | Enum                          |
| **Type Parameters**      |                   |                   |                   |                   | {"choices": \["m", "f", "o"]} |
| **Sensitive Data**       | No                | No                | No                | No                | No                            |
| **Aggregate Statistics** | Allowed (Enabled) | Allowed (Enabled) | Allowed (Enabled) | Allowed (Enabled) | Allowed (Enabled)             |
| **Secure Access**        | Allowed (Enabled) | Allowed (Enabled) | Allowed (Enabled) | Allowed (Enabled) | Allowed (Enabled)             |

## The Dataset's Tabular Data

The tabular data CSV file is prepared within the institutional firewall from data in clinical systems and then copied via SFTP to the Rhino Client.

| StudyInstanceUID                                      | Gender | SpO2 | Stroke Present? |
| ----------------------------------------------------- | ------ | ---- | --------------- |
| 1.3.12.2.1107.5.4.3.11540117440512.19970422.140030.45 | m      | 0.97 | True            |
| 1.3.12.2.1107.5.4.3.123456789012345.19950922.121803.6 | m      | 0.98 | False           |
| 1.3.12.2.1107.5.4.3.4975316777216.19951114.94101.16   | f      | 0.95 | True            |
| ...                                                   | ...    | ...  | ...             |

For this example: Let’s say this tabular CSV file was copied via SFTP to the following location on your Rhino Client: `/rhino_data/uploads/stroke/dataset1.csv`

## The Dataset's DICOM Data

All DICOM files associated with the studies in the tabular data file are queried from the PACS, de-identified, and then copied via SFTP to the Rhino Client.

The Rhino Client doesn’t require or expect any specific file structure, so all `.dcm` files can be put under the same directory, under sub-directories (e.g., for each study or series), or a mix of the two.

For this example, let's say we place our DICOM data in the following locations on our Rhino Client:

* `/rhino_data/uploads/dicom_data/`

`1.3.12.2.1107.5.4.3.11540117440512.19970422.140030.46.dcm`

* `/rhino_data/uploads/dicom_data/another.dcm`
* `/rhino_data/uploads/dicom_data/1.dcm`
* `/rhino_data/uploads/dicom_data/study1/1.dcm`
* `/rhino_data/uploads/dicom_data/study1/2.dcm`
* `/rhino_data/uploads/dicom_data/study2/1.dcm`

## The Dataset's File Data

No file data exists in this Dataset

## Importing the Dataset into the FCP

1. **Name:** Example 1 Dataset
2. **Description:** Example 1 Dataset
3. **Data** ***Schema*** **:** Stroke *Schema* v0
4. ***Tabular Data File Path*** **:** `/rhino_data/uploads/stroke/dataset1.csv`
5. ***DICOM Data Path*** **:**
   * **Import Method:** Filesystem
   * **Path:** `/rhino_data/uploads/dicom_data`
6. ***File Data Path*** **:** `/rhino_data/` (Default Value: Do not change)
7. **Is Data De-identified?:** Yes


# Example 2: Defining a Dataset with File Data

Defining a dataset with file data.

## The Data Schema

{% hint style="info" %}
NOTE: You can skip this step using [Auto-Generated Data Schemas](/data-schemas/auto-generated-data-schemas) if you don't have specific requirements for the dataset schema.
{% endhint %}

The Data Schema can be uploaded as a CSV to the Rhino Web UI or added directly to the Rhino Web UI through the built-in Data Schema editor. For this example, we will create this Dataset within the UI and name it SpO2 Schema.

|                          |                   |                        |                               |                   |
| ------------------------ | ----------------- | ---------------------- | ----------------------------- | ----------------- |
| **Field Name**           | Image             | Age                    | Gender                        | SpO2              |
| **Identifier**           |                   |                        |                               |                   |
| **Description**          |                   |                        |                               |                   |
| **Type**                 | Filename          | Age                    | Enum                          | Percent           |
| **Type Parameters**      |                   |                        | {"choices": \["m", "f", "o"]} |                   |
| **Sensitive Data**       | No                | Yes                    | No                            | No                |
| **Aggregate Statistics** | Allowed (Enabled) | Not Allowed (Disabled) | Allowed (Enabled)             | Allowed (Enabled) |
| **Secure Access**        | Allowed (Enabled) | Not Allowed (Disabled) | Allowed (Enabled)             | Allowed (Enabled) |

## The Dataset's Tabular Data

{% hint style="info" %}
NOTE: You can skip providing tabular data if you don't need metadata (e.g., your dataset is a list of files for inference) and want to use all files in the specific folder defined `File Data Path`. [See example below](#01HY15T3XWZG01N0JN3Y282T6S).
{% endhint %}

The tabular data CSV file is prepared within the institutional firewall from data in clinical systems and then copied via SFTP to the Rhino Client.

| Image           | Age | Gender | SpO2 |
| --------------- | --- | ------ | ---- |
| males/123.png   | 52  | m      | 0.97 |
| males/456.png   | 38  | m      | 0.98 |
| females/789.png | 45  | f      | 0.98 |

For this example: Let’s say this tabular CSV file was copied via SFTP to the following location on your Rhino Client: `/rhino_data/uploads/spo2/dataset1.csv`

### The Dataset's DICOM Data

No DICOM data exists in this Dataset

### The Dataset's File Data

All image files associated with the cases in the tabular data file are queried from the clinical data systems, de-identified, and then copied via SFTP to the Rhino Client.

The Rhino Client expects the files to be located precisely at the relative path that is specified in the tabular data file, where these paths are relative to a base path provided during Dataset import.

For this example, let's say we place our file data in the following locations on our Rhino Client:

* `/rhino_data/uploads/image_data/males/123.png`
* `/rhino_data/uploads/image_data/males/456.png`
* `/rhino_data/uploads/image_data/females/789.png`

### Example 2: Load Specific Files

**Dataset Import parameters:**

1. **Name:** Example 2 Dataset
2. **Description:** Example 2 Dataset
3. **Data Schema:** SpO2 Schema v0
4. **Tabular Data File Path:** `/rhino_data/uploads/spo2/dataset1.csv`
5. **DICOM Data Path:**
   * **Import Method:** Filesystem
   * **Path:** `/rhino_data/` (Default Value: Do not change)
6. **File Data Path:** `/rhino_data/uploads/images`
7. **Is Data De-identified?:** Yes

### Example 2 Simplified: Load All Files Under a Folder

**Dataset Import parameters:**

1. **Name:** Example 2 Dataset
2. **Description:** Example 2 Dataset
3. **Data Schema:** SpO2 Schema v0
4. **Tabular Data File Path:** `LEAVE EMPTY`
5. **DICOM Data Path:**
   * **Import Method:** Filesystem
   * **Path:** `LEAVE EMPTY`
6. **File Data Path:** `/rhino_data/uploads/images`
7. **Is Data De-identified?:** Yes


# What is a Data Schema?

A **Data Schema** is a fundamental aspect of the Rhino Federated Computing Platform (FCP) that defines the structure, attributes, and organization of data within a dataset. It serves as a blueprint, outlining the characteristics of individual data fields and their roles, ensuring a consistent and standardized format for interpreting and analyzing data.

## Implicit vs. Explicit Data Schema Specification

Every dataset in the Rhino FCP inherently possesses a Data Schema, even if not explicitly defined by the user. The platform is equipped to automatically infer basic data types, like strings, floats, and files, from the data content. This means that users can start working with their data without the immediate need to specify an explicit Data Schema.

## Advantages of Explicit Data Schema Definition

While an explicit Data Schema is not mandatory, there are cases where defining a Data Schema offers distinct benefits:

1. **Validation:** Explicit Data Schemas enable users to enforce specific validation rules on their data. This ensures that the data adheres to predefined standards, minimizing errors and inconsistencies.
2. **Interpretability:** Clearly defined Data Schemas enhance the interpretability of the data. Knowing the intended role and meaning of each field improves collaboration and understanding among researchers.
3. **Customization:** Explicit Data Schemas empower users to tailor data structures to their specific research needs, accommodating unique requirements and analysis objectives.

## Attributes

1. **Name:** The name of the defined Data Schema. All Data Schemas within the platform must have a unique name and version combination
2. **Description (Optional):** The description of the Data Schema
3. **Version(s):** The version of the Data Schema. After creating the initial Data Schema you are able to edit the existing Data Schema and create a new version instead of creating a whole new Data Schema.
4. **Date Created:** The date the Data Schema version was created
5. **Number of Fields:** The number of fields or features that are defined within the Data Schema version. Note that this number will always be 1 larger than the number of fields you have defined during the creation of a Data Schema. The extra field is the **notes** field, which is created by default in every Data Schema for users to use as they would like
6. **UUID:** The unique identifier for a specific Data Schema version within the Rhino FCP
7. **Fields(s):** Contained within a Data Schema, a field is a column of data that is being defined in your data set. These are often referred to as features within the data science community. There are several components that make up a field within a Data Schema. For more information please refer to [Data Schema Field Attributes](/data-schemas/data-schema-field-attributes-and-field-permissions). If you are curious about the data types that a field can take on within the FCP, please refer to [Supported Data Schema Data Types](/data-schemas/supported-data-schema-data-types)
8. **Number of Datasets:** The number of datasets that are currently using this Data Schema version to define a dataset's structure
9. **Creator:** The creator of the Data Schema version

## Summary

In the Rhino FCP, Data Schemas play a pivotal role in maintaining data organization, consistency, and accuracy. The platform's ability to infer basic data types allows users to seamlessly begin working with their data. Meanwhile, the option to explicitly define a Data Schema provides greater control, validation, and customization, enabling effective and insightful research endeavors.

## Related Pages

* [Creating a New Data Schema or Data Schema Version](/data-schemas/creating-a-new-data-schema-or-data-schema-version)
* [Example Data Schema Definition](/data-schemas/example-data-schema-definition)
* [Data Schema Field Attributes](/data-schemas/data-schema-field-attributes-and-field-permissions)
* [Supported Data Schema Data Types](/data-schemas/supported-data-schema-data-types)
* [Specifying Data Schema Field Permissions](/data-schemas/data-schema-field-attributes-and-field-permissions)
* [Editing a Data Schema](/data-schemas/editing-a-data-schema)
* [Exporting an Existing Schema](/data-schemas/exporting-an-existing-schema)
* [Auto-Generated Data Schemas](/data-schemas/auto-generated-data-schemas)
* [Deleting a Data Schema or Data Schema Version](/data-schemas/deleting-a-data-schema)
* [Creating a New Data Schema using the Rhino SDK](/rhino-sdk/creating-a-new-data-schema-using-the-rhino-sdk)


# Example Data Schema Definition

Below is an example Data *Schema* definition for use in the Rhino Federated Computing Platform (FCP). A CSV version of the file is also available to download at the bottom of this article. This CSV file can serve as a template for you if you would like to create your Data *Schema* by uploading it from a file.

| Field Name           | CT Input        | Time Interval between PCR and CT                                                   | Presence of Consolidation                                          | Gender                                                                      | Age                    | Scanner Model                                                |
| -------------------- | --------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------- | ---------------------- | ------------------------------------------------------------ |
| Identifier           |                 |                                                                                    |                                                                    |                                                                             |                        |                                                              |
| Description          | Input CT Series | The difference in hours between the PCR test and the time when the CT was acquired | Presence or absence of COVID-19-related consolidation in the study | The gender of the patient as "m" for male, "f" for female, or "o" for other | The age of the patient | The CT scanner model                                         |
| Type                 | DicomSeriesUID  | PositiveFloat                                                                      | Boolean                                                            | EAggrenum                                                                   | Age                    | ConstrainedString                                            |
| Type Parameters      |                 |                                                                                    |                                                                    | {"choices": \["m", "f", "o"]}                                               |                        | {"regex": "(Siemens\|GE\|Philip s) \\\\\w+ version \\\\\d+"} |
| Units                |                 | hours                                                                              |                                                                    |                                                                             | years                  |                                                              |
| Sensitive Data       | Yes             | No                                                                                 | No                                                                 | Yes                                                                         | Yes                    | No                                                           |
| Aggregate Statistics | Disabled        | Enabled                                                                            | Enabled                                                            | Disabled                                                                    | Disabled               | Enabled                                                      |
| Secure Access        | Disabled        | Enabled                                                                            | Enabled                                                            | Disabled                                                                    | Disabled               | Enabled                                                      |

Use the table above as a template when creating your CSV upload file.  Also, here is an example schema file.

{% file src="/files/AkuMb5uW0dAQAUscZojv" %}


# Creating a New Data Schema or Data Schema Version

This article explains how to create a new data schema using the Rhino FCP UI.

> NOTE: To learn how to create a new data schema using the Rhino SDK, see [Creating a New Data Schema using the Rhino SDK.](/rhino-sdk/creating-a-new-data-schema-using-the-rhino-sdk)

### Opening the Data Schemas Screen

{% stepper %}
{% step %}
**Select Data Schemas**

Select **Data Schemas** from the main menu. The Data Schemas window opens.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/InJA12vxuYVvzsHNKr4o/35166489649821)
{% endstep %}

{% step %}
**Review existing data schemas**

Data schemas that have already been created appear on the screen. The version, date the schema was created, the number of fields in the schema, number of datasets associated with the schema, and the creator of the schema are shown.
{% endstep %}

{% step %}
**Search for a data schema**

To search for a data schema, use the text boxes located at the top right corner of the page. To search by name enter the full name or part of the name in the **Search Name** text box. To search by description, enter part of the schema's description in the **Search Description** text box. (The description is what was entered when the schema was created.)
{% endstep %}

{% step %}
**View more details**

To see more details about the data schema, select it. The details for the selected data schema is shown.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ml3Cd1wJnNtLw5D7R0eE/33266068257949)
{% endstep %}
{% endstepper %}

### Creating New Data Schema

{% stepper %}
{% step %}
**Open the create screen**

In the Data Schemas window, select the **Create New Data Schema** button in the upper right hand corner of the screen.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/0AG3emkKLCx2lIAqV3ht/33266060517405)

The **Create a New Data Schema** screen opens.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/TReErk6FrbEQNAEoLyyi/34843063014941)
{% endstep %}

{% step %}
**Enter schema details**

Enter a name for the data schema.

Enter a description. While a description that will help you understand the nature of the Data Schema, this is an optional field.
{% endstep %}

{% step %}
**Choose how to create the schema**

Indicate whether you want to create a blank data schema or upload a data schema from a file.

* **If you chose to create a blank data schema:**
  * Select **Create a New Data Schema**. A blank schema appears that you can define and customize.
  * Add fields by selecting the **Add Field** button to the right of the table.
  * If you need to delete a variable (or column) from your data *schema*, click on the circle icon with the X inside ( ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/RdctFh1QoyvPlPxBB6Cb/13006459493661)) located at the top of each column.
  * Select the blue cell in the schema field row. Enter the name of the field.
  * Next, enter the unique identifier for the record in the identifier field (if needed)
  * Enter a description, select a type, indicate type parameters (if needed), and units.
  * To add another field, select Add Field button to the right of the table - and repeat these steps again. If there is an issue, an error appears. You’ll need to address it before the schema is created.
  * When complete, click **Save**.

> NOTE: If needed, visit the following links to view additional information on [Data Schema Field Attributes](/data-schemas/data-schema-field-attributes-and-field-permissions), [Supported Data Schema Data Types](/data-schemas/supported-data-schema-data-types).

* **If you chose to upload a data schema from a file:** Select the file that you want to upload (it should be a CSV file), then click **Open**. Here is an example of a CSV File with a structure that can be uploaded. If you chose to upload a data and are errors, fix the errors and try to upload again.

```plaintext
Variable Name,Age,Test Result A,TEST RESULT B,TEST RESULT C
Identifier,,,,
Description,Age of the patient,Result of test a,Result of test b,Result of test c
Type,Age,Percent,Percent,String
Type Parameters,,,,
Units,INT,Decimal,Decimal,STRING
Contains Sensitive Data?,FALSE,FALSE,FALSE,FALSE
Permissions,Default,Default,Default,Default
Required,TRUE,TRUE,TRUE,FALSE
```

{% endstep %}

{% step %}
**Finish creating the schema**

When the schema is created, the schema entry and high-level details appears in the Data Schemas screen. If you want to see the schema fields, click the entry.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/vnFPDNKwmyY33XzXs9IV/33266068260509)
{% endstep %}
{% endstepper %}

### Creating a New Data Schema Version

{% stepper %}
{% step %}
**Open the new version screen**

In the Data Schemas screen, select the **New Version** button of the Data Schema that you want to create a new version of.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/OceTw5LHIAOn09GOmaSC/33266060518685)

The **Create a New Schema Version** screen appears.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/RslJkmDx0Qn5DFwzq5qC/33266060519453) ![](https://docs.rhinohealth.com/hc/article_attachments/34843063015197)
{% endstep %}

{% step %}
**Add a description**

Add a description (optional).
{% endstep %}

{% step %}
**Choose how to create the version**

Choose to **Edit Latest Schema**, **Create Blank Data Schema**, or **Upload from File**.

* If you chose **Edit Latest Schema**, do the following.
  1. Select **Create New Schema Version**.
  2. Edit the schema, then select **Save**.
  3. On the Data Schemas page, a new version appears.
* If you chose create a blank data schema or upload the file, see step 5 of the [Creating New Data Schema topic in this article.](#h_01KF1XB2JG9ZDNCASTB95Z7M1C)
  {% endstep %}
  {% endstepper %}

### **Getting Help**

If you have received an error or run into any issues throughout the process, please reach out to <support@rhinohealth.com> for more assistance.


# Editing a Data Schema

To edit a data schema, complete the following steps.

{% stepper %}
{% step %}

### Select Data Schemas

Select **Data Schemas** from the menu on the left.
{% endstep %}

{% step %}

### Select the data schema

Select the Data Schema that you want to edit.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/NzEtpmbGvRzycpeHDSm4/32674419658909)
{% endstep %}

{% step %}

### Open the editor

A screen that shows the data schema appears. Click the **Edit Data Schema** button.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/SgVjs9it3Zm4cgRyu3Ko/32674419660189)
{% endstep %}

{% step %}

### Confirm the new version

A note appears indicating that editing the schema will automatically create a new version. Select **Edit**.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/NOsB7G0O10aTSeSU33yd/32674450855453)
{% endstep %}

{% step %}

### Edit the fields

Edit the fields as needed. Note that the fields are marked as required or optional. (By default, all fields are set as required.)

To make the field required, push the slider to the right ("Yes" will appear). To make the field optional, push the slider to the left ("No" will appear).

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/sZSOnSCPYm1OZkf3yZnf/32674419663261)
{% endstep %}

{% step %}

### Save your changes

After you've made the changes, select **Save** in the upper right corner of the screen.
{% endstep %}

{% step %}

### Review the new version

A new version of the data schema appears.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/6sSdCzkUKm2MmqQHvojw/32674419664029)
{% endstep %}
{% endstepper %}

{% hint style="info" %}
If you import a dataset with a specific data schema (not “Auto-generate schema from data”) and if any optional field does not exist in the data, this will not fail the import and will not generate any warning. If you import a dataset with an inferred data schema (“Auto-generate schema from data”), all fields in the generated schema will be set as required.
{% endhint %}


# Exporting an Existing Schema

This article explains how to export an existing schema.

### Exporting a Schema

To export a schema to your device, complete the following steps.

{% stepper %}
{% step %}

### In the Data Schemas screen, select the schema that you want to export.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/iCo65K0MRzbVGlPDlzL0/33266015574813)
{% endstep %}

{% step %}

### The data schema opens.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/RkdQxP6buAZwmCVaz0uh/33266015575325)
{% endstep %}

{% step %}

### Select the Export Schema button.

{% endstep %}

{% step %}

### Confirm that you want to download the schema when the message appears.

{% endstep %}

{% step %}

### The schema is downloaded to your device.

{% endstep %}
{% endstepper %}


# Publishing and Unpublishing Data Schemas

Rhino FCP allows you to securely publish data schemas so that they are visible to selected collaborators. You can control which versions to publish or unpublish. You can also manage collaborator permissions. Publishing different versions aids model training and refinement, allows version control, and supports development of variations for specific purposes.

Collaborators with access to a dataset using a published data schemas can view inference results. This maintains security and privacy while still allowing result sharing.

### About Publishing and Unpublishing

Publishing makes data schemas visible to all collaborators *who do not already* have permission to view them in the "View Datasets and Data Schemas". When you unpublish a data schema, it will stop being visible to all users except those indicated in the "View Datasets and Data Schemas" permission.

### Prerequisites

Data Schemas are available to all personas listed in the View Datasets and Data Schemas persona in the Site-Level Permissions.

* *If all personas can view datasets and data schemas*, the publishing and unpublishing options *will not be* available because it won't be needed.
* *If some personas do not have the permission to view datasets and data schemas*, the publishing and unpublishing options *will be* available.

For more details, see the [Permissions documentation (View Datasets and Data Schemas Setting)](/projects/persona-and-permissions-policies-reference).

### Data Schemas

The following instructions explain how to publish and unpublish a data schema.

### Publishing a Data Schema

{% stepper %}
{% step %}
**Select Data Schema.**

Select Data Schema from the menu on the left side of the screen.
{% endstep %}

{% step %}
**Open the schema menu.**

Right-click the three-dot menu next to the data schema you want to publish, then select Publish Schema.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/tnmiVe3fp9xiD80zMP43/35604905566237)
{% endstep %}

{% step %}
**Confirm publishing.**

A message appears asking whether you would like to publish the data schema. If you want to unpublish all previous versions of the data schema, click the “Unpublish any previously published versions of this schema” checkbox.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/9s6iia8lboiOczKh1PXh/35604889080605)

> NOTE: If you choose to unpublish a data schema, it will stop being visible to all users without the “View Dataset and Data Schema” permission, and all published data schema will be unpublished.
> {% endstep %}

{% step %}
**Publish the schema.**

Select Publish Schema. The data schema is published and can be viewed by collaborators with the appropriate permissions.

* If you publish a data schema, you can choose to automatically unpublish all previously published versions of the same data schema.
* When you unpublish a data schema, this data schema will stop being visible to all users who do not have the “View Datasets and Data Schemas” permission.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/24CuTbFjQPyGtaTO7vBS/35604905567645)
{% endstep %}
{% endstepper %}

### Unpublishing a Data Schema

{% stepper %}
{% step %}
**Select Data Schema.**

Select Data Schema from the menu on the left side of the screen.
{% endstep %}

{% step %}
**Open the schema menu.**

Right-click the three-dot menu next to a data schema that has a highlighted publish icon.
{% endstep %}

{% step %}
**Choose Unpublish.**

Select Unpublish data schema. A prompt that confirms that you want to unpublish the data schema opens.
{% endstep %}

{% step %}
**Confirm unpublishing.**

Select Unpublish data schema.
{% endstep %}
{% endstepper %}

### Troubleshooting Publishing Issues

<details>

<summary>The "Publish" option is not on the menu</summary>

* **Cause:** The project's site-level permission for **"View Datasets and Data Schemas"** is likely set to **Full Visibility**(all of the personas have access to the dataset or data schema).
* **Solution:** In Full Visibility mode, all objects are shared with all project members by default; therefore, manual publishing is not required or available. To enable private drafting, a Project Lead must change the permission setting to **Partial Visibility**(only some of the personas have access to the dataset or data schema).

</details>

<details>

<summary>Error: "Cannot Publish Dataset" (Schema Ownership)</summary>

* **The Issue:** You are trying to publish a dataset, but the action is blocked.
* **The Message:** *"The associated Data Schema version \[Name] is currently unpublished and is owned by another workgroup."*
* **Why this happens:** To ensure data integrity, a dataset cannot be public if its schema is private. Because the schema belongs to a different workgroup, you do not have the authority to publish it yourself.
* **How to fix:**
  1. Identify the owner of the Data Schema.
  2. Request that they **Publish** the specific schema version.
  3. Once the schema is published, retry publishing your dataset.

</details>

<details>

<summary>The Data Schema published automatically</summary>

* **The Scenario:** You published a dataset, and its associated schema status changed to "Published" without manual intervention.
* **Explanation:** If your workgroup owns both the dataset and the unpublished schema version, the Rhino FCP automatically publishes the schema to prevent broken dependencies.
* **System Prompt:** You should receive a confirmation dialog stating: *"Publishing this dataset will automatically publish the associated Data Schema version. Do you wish to proceed?"*

</details>

<details>

<summary>The Code Object or Dataset suddenly became "Unpublished"</summary>

* **Cause:** A user (likely a Data Custodian or Schema Owner) has **Unpublished the underlying Data Schema**.
* **The Logic:** Data Schemas are foundational. If a schema is pulled from public view, all "downstream" objects—such as Datasets that follow that schema or Code Objects that use it for input/output—are automatically unpublished to maintain privacy and system consistency.
* **Solution:** Republish the Data Schema to restore visibility to the associated datasets and code.

</details>


# Deleting a Data Schema

Explains how to delete a data schema

This article explains how to delete a data schema or data schema version.

## Prerequisite

Make sure that you've reviewed all associated datasets that use the schema you want to delete. It is important to do this because **if a schema is deleted, all associated datasets will be deleted as well**.

## Deleting a Data Schema or Version

{% stepper %}
{% step %}

#### Open the Data Schemas page

Go to the page that lists your data schemas.
{% endstep %}

{% step %}

#### Find the schema or schema version

If needed, use the search fields at the top right.

* Use **Search Name** to search by schema name.
* Use **Search Description** to search by schema description.

Each schema appears with a row for each version. Find the version you want to delete.
{% endstep %}

{% step %}

#### Open the menu for the version

Select the three-dot menu on the right side of the version row, shown below.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/iB6nRtCEemB9p93cFKIH/12987189101725)
{% endstep %}

{% step %}

#### Remove the schema version

Select **Remove schema**.

Repeat these steps for each version you want to remove. When you delete the last version, the data schema is fully deleted.
{% endstep %}
{% endstepper %}

## Remove From the Object Page

You can also remove a schema or schema version directly from the **Data Schemas** page by selecting **Remove schema**.


# Auto-Generated Data Schemas

Experience the effortless integration of various data types within the Rhino FCP using the ***Auto-Generate Data Schema from Data*** feature. This functionality adapts to your data type, eliminating the need for manual *Data schema* definition and ensuring smooth compatibility for your projects.

### How It Works

* **Importing Datasets:** When importing datasets, select ***Auto-generate Data Schema from Data*** to automatically create an inferred Data *Schema* that suits your data's characteristics.
* **Defining Code Outputs:** When defining your Code Object, opt for "*Auto-Generate Schema from Data*" for the *output Data Schema*. The system will create an inferred Data *Schema* to match your output data, ensuring compatibility.
* **Via the SDK:** If you are importing Datasets or defining Code Objects via the SDK, pass in `data_schema_uid = None` (for Datasets) or `output_data_schema_uid = None` (for Code Objects) to Auto-generate the Data S *chema*.

### Fully Supported Cases

* **Data is limited to a tabular File** - Simply provide the **Tabular Data File Path** when importing the dataset. If the tabular file is the output of a code object, the FCP expects it to be placed under `/output/dataset.csv`.
* **Data is limited to files in a folder** - Simply provide the path where the files are located.
  * The FCP will recursively search for all files under that path.
* **A combination of tabular and file data:** make sure to reference the file name in its appropriate line in the tabular file, e.g.:

|         |            |                     |
| ------- | ---------- | ------------------- |
| **Age** | **Gender** | **Filename**        |
| 64      | F          | /file\_data/F64.txt |
| 75      | M          | /file\_data/M75.txt |

#### A "Special" Case

* **Data is a combination of DICOM files and other file types with no tabular data** - In this case, the FCP will not be able to import the dataset as it would not know which DICOM file to associate with which of the other files. To resolve this, you need to create a csv file with the corresponding file paths, e.g.:

|               |                 |
| ------------- | --------------- |
| SeriesUID     | DiagnosticNotes |
| 2.24.1234.dcm | 1.txt           |
| 3.32.6543.dcm | 2.txt           |
| 1.45.6122.dcm | 3.txt           |

### Streamlined Integration

Discover the advantages of using ***Auto-Generate Data Schema from Data*** for your data integration needs:

* **Effortless Handling:** Import datasets or run code without the hassle of defining Data *Schemas* manually.
* **Adaptable Compatibility:** Inferred Data *Schemas* accommodate diverse data types, facilitating a unified data analysis environment.
* **Data Privacy Management:** Adjusts **Sensitive Data** settings based on dataset de-identification status, ensuring data security compliance. Allows for quick review of data schemas to protect privacy in data fields. See [Sensitive Datasets](/datasets/sensitive-datasets) for more information.
* **Efficient Data Transformation:** Seamlessly apply different code objects to your data without the need for manual Data *Schema* adjustments.

Leverage the ***Auto-Generate Data Schema from Data*** feature to simplify data integration and elevate your analysis within the Rhino FCP.


# Data Schema Field Attributes and Field Permissions

Provides information on data schema field attributes and field permissions

## Data Schema Field Attributes

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/uF4HEPLDhnjMN6OYk15i/27765396062237)

For each field in the Data Schema, the following attributes are defined:

* **Name:** the name of this field
* **Identifier:** the string by which this field should be identified in the input data (if empty, the Name field will be used for identification)
* **Description:** a description of the field (including any information that can help collaborators put the data in the correct format)
* **Type:** the name of the field type. Please refer to [Supported Data Schema Data Types](/data-schemas/supported-data-schema-data-types) for a full list of supported data types within the Rhino FCP
* **Type Params:** any parameters for the field type (e.g., min/max values for a ContrainedInt type). Please refer to [Supported Data Schema Data Types](/data-schemas/supported-data-schema-data-types) for a full list of supported parameters for each data type within the Rhino FCP
* **Units:** the units in which the values of this field are expected to be. These units will also appear in charts showing aggregate values from this field in the Rhino UI
* **Sensitive Data:** whether or not this field may contain sensitive data
* **Aggregate Statistics:** the field's underlying data is only persisted on-prem, and **NO** aggregate statistics can be viewed in the cloud. This field can be viewed via Secure Access, given the proper permissions.
* **Secure Access:** the field's underlying data is only persisted on-prem, and aggregate statistics can be viewed in the cloud. **This field isn’t viewable via Secure Access.**

## Data Schema Field Permissions

For each variable defined within a schema, one of the following permission profiles can be applied:

* **Default:** The variable's underlying data only persists on-prem, and aggregate statistics can be viewed in the cloud. This field can be viewed via secure access given the proper permissions.
* **No Aggregate Statistics:** The variable's underlying data only persists on-prem, and **no aggregate statistics** can be viewed in the cloud. This field can be viewed via secure access given the proper permissions.
* **No Secure Access:** The variable's underlying data only persists on-prem, and aggregate statistics can be viewed in the cloud. **This field isn’t viewable via secure access.**
* **Local Only:** The variable's underlying data only persists on-prem, and **no aggregate statistics** can be viewed in the cloud. **This field isn’t viewable via secure access.**


# Supported Data Schema Data Types

The Rhino Federated Computing Platform (FCP) supports over 50 different data types within its Data *Schema* definition. Similar to the attributes of a Data *Schema*, as defined in the [Data *Schema* Field Attributes](/data-schemas/data-schema-field-attributes-and-field-permissions) article, each data type has the following attributes:

* **Validation:** The validation method outlined will be used when a dataset is imported into the FCP. Each value will be validated to ensure it meets the criteria set for the data type. If the criteria are not met, the dataset will fail to import into the FCP.
* **De-identification:** On import of a dataset into the FCP, if a column or feature within the Data *Schema* is marked as **Sensitive Data** = True, the system will trigger a de-identification transformation over the columns that may contain Sensitive Data. De-identification transformations are unique to each data type.
* **Type Parameters:** Type Parameters are constraints that can be passed into certain data types to restrict potential values when importing a dataset into the FCP. If a value fails to meet the type parameter constraints, the dataset will fail to import.

### Supported Data Types in FCP

#### Age

**Validation:** Equivalent to a ConstrainedInteger in the range 0 to 130

**De-Identification:** Any ages below 90 are unchanged, and any ages 90+ are changed to 90

**Type Parameters:** None

#### Birthdate

**Validation:** Any valid date (see supported Date formats: [Date](#h_01H5WY7BYN9RC48G77F4C3Q5C8) and [DateTime](#h_01H5WY7NCBC8P2TZAPDZXDH7S0))

**De-Identification:** Only the year of birth is left (dropping the day and month). If the birth year is 90+ years ago, the birth year is set to 1900.

**Type Parameters:** None

#### Boolean

**Validation:** One of the following values: True, true, t, yes, y, 1, False, false, f, no, n, 0

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### Bytes

**Validation:** Bytes converted from a string using `str.encode()`

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### ConstrainedBytes

**Validation:** Bytes that can have additional constraints defined in the parameters

**De-Identification:** Drop Value (None)

**Type Parameters:**

* **min\_length**: (Type: Integer, Default Value: None) - the minimum length of the byte string
* **max\_length**: (Type: integer, Default Value: None) - the maximum length of the byte string

#### ConstrainedDecimal

**Validation:** A Decimal that can have additional constraints defined in the parameters

**De-Identification:** Drop Value (None)

**Type Parameters:**

* **gt**: (Type: Decimal, Default Value: None) - enforces the decimal to be greater than the set value
* ge: (Type: Decimal, Default Value: None) - enforces the decimal to be greater than or equal to the set value
* **lt**: (Type: Decimal, Default Value: None) - enforces the decimal to be less than the set value
* **le:** (Type: Decimal, Default Value: None) - enforces the decimal to be less than or equal to the set value
* **max\_digits**: (Type: Integer, Default Value: None) - the maximum number of digits in the decimal, excluding leading zeros before the decimal point or trailing zeros after the decimal point
* **decimal\_places**: (Type: Integer, Default Value: None) - the maximum number of decimal places allowed, excluding trailing zeros after the decimal point
* **multiple\_of**: (Type: Decimal, Default Value: None) - enforces the decimal to be a multiple of the set value

#### ConstrainedFloat

**Validation:** A float that can have additional constraints defined in the parameters

**De-Identification:** Drop Value (None)

**Type Parameters:**

* **gt**: (Type: Float, Default Value: None) - enforces the float to be greater than the set value
* **ge**: (Type: Float, Default Value: None) - enforces the float to be greater than or equal to the set value
* **lt**: (Type: Float, Default Value: None) - enforces the float to be less than the set value
* **le**: (Type: Float, Default Value: None) - enforces the float to be less than or equal to the set value
* **multiple\_of**: (Type: Float, Default Value: None) - enforces the float to be a multiple of the set value

#### ConstrainedInt

**Validation:** An integer that can have additional constraints defined in the params

**De-Identification:** Drop Value (None)

**Type Parameters:**

* **gt**: (Type: Integer, Default Value: None) - enforces the integer to be greater than the set value
* **ge**: (Type: Integer, Default Value: None) - enforces the integer to be greater than or equal to the set value
* **lt**: (Type: Integer, Default Value: None) - enforces the integer to be less than the set value
* **le**: (Type: Integer, Default Value: None) - enforces the integer to be less than or equal to the set value
* **multiple\_of**: (Type: Integer, Default Value: None) - enforces the integer to be a multiple of the set value

#### ConstrainedString

**Validation:** A string that can have additional constraints defined in the params

**De-Identification:** Drop Value (None)

**Type Parameters:**

* **min\_length**: (Type: Integer, Default Value: None) - the minimum length of the string
* **max\_length**: (Type: Integer, Default Value: None) - the maximum length of the string
* **regex:** (Type: String, Default Value: None) - a regular expression to validate the string against

#### Date

**Validation:** Either a string in `YYYY-MM-DD` format, or a number (integer or float) that represents a Unix timestamp in seconds (if -2e10 < value < 2e10) or milliseconds (otherwise). (Timestamp is in UTC.)

**De-Identification:** A random date shift is applied. This shift is at least plus or minus 1 year

**Type Parameters:** None

#### DateTime

**Validation:** Either a string in `YYYY-MM-DD[T]HH:MM[:SS[.fff fff]][Z or [±]HH[:]MM]]]` format, or a number (integer or float) that represents a Unix timestamp in seconds (if -2e10 < value < 2e10) or milliseconds (otherwise). (Timestamp is in UTC.)

**De-Identification:** A random date+time shift is applied. This shift is at least plus or minus 1 year

**Type Parameters:** None

#### Decimal

**Validation:** A decimal number

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### DicomInstanceUID

**Validation:** Any string (not strictly enforcing valid DICOM UID formats)

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### DicomSeriesUID

**Validation:** Any string (not strictly enforcing valid DICOM UID formats)

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### DicomStudyUID

**Validation:** Any string (not strictly enforcing valid DICOM UID formats)

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### DicomTag

**Validation:** No validation is performed on DicomTags - they are added to the Data S *chema* to include specific tags in dataset and code analysis. Within a Data S *chema*, the DicomTag field can be used to inform the Rhino FCP which DICOM metadata tags to include in the dataset and code analysis

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### Enum

**Validation:** The value must be one of those specified in the **choices** param

**De-Identification:** Drop Value (None)

**Type Parameters:**

* **choices:** List, required - with a list of valid values for this field

#### Filename

**Validation:** The value must be a path to a file that exists and is accessible to the Rhino Agent

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### Float

**Validation:** A floating point number

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### Integer

**Validation:** An integer

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### Json

**Validation:** A string that can be parsed as valid JSON

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### NegativeFloat

**Validation:** A float that is less than 0

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### NegativeInt

**Validation:** An integer that is less than 0

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### NonNegativeFloat

**Validation:** A float that is greater than or equal to 0

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### NonNegativeInt

**Validation:** An integer that is greater than or equal to 0

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### NonPositiveFloat

**Validation:** A float that is less than or equal to 0

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### NonPositiveInt

**Validation:** An integer that is less than or equal to 0

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### Path

**Validation:** A valid path

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### Percent

**Validation:** Equivalent to a ConstrainedFloat in the range 0 to 1

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### PositiveFloat

**Validation:** A float that is greater than 0

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### PositiveInt

**Validation:** An integer that is greater than 0

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### String

**Validation:** Any string

**De-Identification:** Drop Value (None)

**Type Parameters:** None

#### Time

**Validation:** A string in `HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]]]` format. (Timestamp is in UTC.)

**De-Identification:** A random time shift is applied

**Type Parameters:** None

#### UID

**Validation:** Any String

**De-Identification:** A new value will be generated using SHA-5121 (with salting). Two identical UIDs will always generate the same de-identified value

**Type Parameters:** None

#### UUID

**Validation:** A hexadecimal UUID string

**De-Identification:** A new value will be generated using SHA-5121 (with salting). Two identical UUIDs will always generate the same de-identified value

**Type Parameters:** None

1 - The approved hashing method based on <http://csrc.nist.gov/groups/ST/hash/>


# Overview

The Rhino FCP's Data Harmonization Engine (RhinoDHE) enables users to remotely harmonize complex datasets into standardized data models using AI-assisted mapping and human-in-the-loop review.

***

### What is it?

The process of **data harmonization** involves integrating, transforming, and standardizing data from disparate sources to create a unified and consistent dataset that can be readily analyzed and utilized.&#x20;

Traditional data harmonization approaches are often time-consuming, labor-intensive, and prone to error. Rhino's **Data Harmonization Engine (RhinoDHE)** streamlines this process by using AI to enable complex extract-transform-load (ETL) workflows that can be executed remotely. With RhinoDHE, users can complete data transformations in hours rather than the weeks traditionally required.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2F6F58TedLqzyqDwiwTDCS%2Frhino_dhe_white_vertical.gif?alt=media&amp;token=2f37f33d-25ad-4e2a-8298-46d126d521d7" alt=""><figcaption></figcaption></figure>

***

### Why is it useful?

Data collected across different sites, systems, and organizations rarely arrives in the same format. Field names differ, coding systems vary, and data structures conflict — creating barriers to reliable analysis. Data harmonization addresses this challenge whether you're preparing data for research, meeting regulatory and compliance requirements, or running analytics across a federated network.

Rhino customers have applied the DHE to a wide range of use cases, including:

* Transforming complex local data warehouses into clean, standardized databases based on common data models such as **OMOP** or **i2b2** for research use.
* Mapping local, non-standard codes to standardized terminologies and vocabularies such as **LOINC**.
* Generating **FHIR resources** to support healthcare interoperability initiatives and patient care.
* Aligning a research collaborator's data with the format required by a machine learning model for **external validation**.

***

### How does it work?

In short, the RhinoDHE works by transmitting non-sensitive metadata to an LLM, which then recommends the required logic to transform the source data into the target data model.&#x20;

**As always is the case on the Rhino FCP, raw row-level data never leaves the local network boundary.** RhinoDHE runs on-premises on each Rhino Client.

<div data-with-frame="true"><figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2F21FJOs3mLoz1XNRBfEBL%2FHow%20DHE%20works.png?alt=media&amp;token=4ef02ea5-361d-4419-8116-df2cdd6d7a60" alt=""><figcaption></figcaption></figure></div>

#### *Step 1: Non-Sensitive Data Is Sent to the Frontier LLM*

[Data Schemas](/data-schemas/what-is-a-data-schema) for both the source data and the target data model are transmitted to the LLM. This ensures that the LLM can accurately represent the dimensionality and content of each data table. Moreover, histograms constrained by [Rhino's privacy filters](/datasets/sensitive-datasets) are also sent to the LLM. This ensures that the LLM can sample actual data values without compromising data security.&#x20;

#### *Step 2: Frontier LLM Recommends Data Transformations*

The LLM that powers Rhino's DHE uses the non-sensitive metadata to generate a set of recommended transformations. The agentic harness that Rhino uses ensures that the recommended transformations will lead to data that is consistent with the target data model. The output of the LLM is a [JSON configuration file](/data-harmonization/syntactic-mapping/syntactic-mapping-configuration) that represents the recommended transformations. This file can be saved for later use.&#x20;

#### *Step 3: Review LLM Recommendations via User Interface*

The Rhino platform provides an intuitive user interface in which to review the recommended transformation. We sometimes like to compare this to Level 3 self-driving cars, wherein the machine will do the brunt of the work while the human provides supervision. This is especially important in the realm of real-world data, where subject matter expertise is often required to ensure accuracy.

#### *Step 4: Execute ETL on the edge client*

Once the transformation has been reviewed and approved by a human, the edge client translates the LLM's recommendations into a code object, which can be run remotely using the Rhino user interface, the Rhino SDK, or MCP server.

***

### Important Terms and Concepts

There are several important concepts to understand before you create a data mapping using the RhinoDHE.

* **Custom Vocabulary**: A non-standard language used to describe clinical data fields. It can be useful if a standard vocabulary, such as OMOP, is not appropriate.
* **EHR/DW**: *(Electronic Health Record/Data Warehouse)* Stores and serves EHR/DW data.
* **FHIR**: *(Fast Healthcare Interoperability Resources)* A standard that defines how healthcare information should be exchanged using a common format and language.
* **LLM**: *(Large Language Model)* A type of machine learning model that can understand and generate natural text. LLMs are used in the RhinoDHE to make recommendations for data mappings.
* **OMOP**: *(Observational Medical Outcomes Partnership)* A standard common data model that standardizes the content and structure of observational data.
* [**Semantic Mapping**](/data-harmonization/semantic-mapping): *(SeM)* Also known as vocabulary mapping, this is the mapping of values with the columns of interest.
* [**Syntactic Mapping**](/data-harmonization/syntactic-mapping): Also known as schematic or ontology-based mapping, this is the mapping of table/column names to target table/column names (e.g., OMOP).
* **SNOMED**: *(Systematized Nomenclature of Medicine)* An organized collection of clinical/medical terms that provide codes, synonyms, definitions, and codes for clinical reporting and documentation.

***

### Related Pages

* [Getting Started](/data-harmonization/getting-started)
* [Harmonization via MCP](/using-the-rhino-mcp-server/harmonization-via-mcp)
* **Tutorials**:&#x20;
  * [RhinoDHE w/ OMOP](/tutorials-recipes-and-demos/omop-etl-via-the-rhino-data-harmonization-engine-rhinodhe)
  * [RhinoDHE w/ FHIR](/tutorials-recipes-and-demos/fhir-etl-via-the-rhino-data-harmonization-engine-rhinodhe)
  * [RhinoDHE w/ Custom Data Model](/tutorials-recipes-and-demos/harmonizing-complex-rwd-to-a-custom-data-model)


# Getting Started

How to use Rhino's Data Harmonization Engine (RhinoDHE)

Transforming data with the **RhinoDHE** involves **four key steps**: Data Ingestion, Semantic Mapping, Syntactic Mapping, and ETL Execution. All these steps can be managed from any of Rhino's interfaces, including the [web interface](/getting-started/quick-start-guide/the-fcp-dashboard), [Python SDK](/rhino-sdk/what-is-the-rhino-sdk), [MCP server](/using-the-rhino-mcp-server/mcp-getting-started), or Rest API.&#x20;

<div data-with-frame="true"><figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FDEwmZESQLTPzlXfJ4jwo%2FScreenshot%202026-08-13%20at%205.26.37%E2%80%AFPM.png?alt=media&amp;token=5a5f0f86-5276-426a-9969-356fc1940f12" alt=""><figcaption></figcaption></figure></div>

#### Step 1: Data Ingestion

**Data ingestion** is the first step in the RhinoDHE data harmonization workflow, where a source dataset is loaded into the platform and profiled before any transformation begins. During ingestion, the RhinoDHE inspects the incoming file(s) to detect the data schema — tables, columns, and data types — and generates an initial data profile, surfacing row counts, unique values, and basic data quality signals for each field.&#x20;

For more information, see [this page](/datasets/registering-configuring-and-exporting-datasets).

***

#### Step 2: Semantic Mapping

After data ingestion, the next task is to perform **semantic mapping.** This process involves associating local terms (*aka* codes) from a source dataset to a standardized target vocabulary. For example, a hospital might want to transform their laboratory test named `Albumin Blood Test` to the LOINC code `1751-7` (Albumin \[Mass/volume] in Serum or Plasma). Rhino allows users to select which vocabulary they want to map their local terms to, and then AI-generated recommended mappings are presented to human reviewers for review and approval.

For more information, see [Semantic Mapping](/data-harmonization/semantic-mapping)

***

#### Step 3: Syntactic Mapping

**Syntactic mapping** defines how the structure of a source dataset — its tables, columns, and field types — must be transformed to conform to the target data model. While semantic mapping handles the *values* within a column (e.g., `Albumin Blood Test` to LOINC `1751-7`), syntactic mapping handles the *shape* of the data itself: renaming columns, reformatting data types, splitting or combining fields, and restructuring tables so they align with the target schema. This process should follow semantic mapping, as local-to-standard term mappings are often incorporated into the syntactic mappings.

For more information, see [Syntactic Mapping](/data-harmonization/syntactic-mapping)

***

#### Step 4: Execute the Transformation

Once syntactic and semantic mappings have been reviewed and approved, a self-contained transformation script that encodes every mapping decision (structural and semantic) into executable logic is created. These are called *Data Harmonization Code Objects*, which are a special type of a [Code Object](/creating-and-running-code-objects/what-is-a-code-object).  **Execution** occurs when the code object is run, either via the Rhino dashboard, MCP Server, or Python SDK. Users may also automate execution using Rhino's Python SDK and an orchestration tool such as Airflow or Prefect.io.&#x20;

For more information, see [Executing the Transformation](/data-harmonization/executing-the-transformation)

{% hint style="info" %}
Reviewers do not need to write any code to create Data Harmonization Code Objects. Rhino FCP automatically generates them based on the mapping choices made through the review interface. The underlying ETL code is managed by Rhino FCP and cannot be accessed or exported by users.
{% endhint %}

\
\
\
\ <br>

\ <br>


# Semantic Mapping

***

## Overview

**Semantic Mapping** (aka. Terminology Mapping, Code Mapping) streamlines the process of mapping values in your local data to standardized coding systems or vocabularies. It takes all unique values from a chosen source field and maps each one to a standardized dictionary entry that includes a **concept ID**, a **display name**, or both.&#x20;

Rhino's built-in model generates **mapping** **recommendations** for each unique value. Since accuracy in data mapping is critical, the process is designed with a human-in-the-loop approach — you review, correct, and approve each recommendation before it is applied.&#x20;

Rhino FCP includes built-in support for OMOP and FHIR-related standard vocabularies. When these don't cover your data, you can define a [Custom Vocabulary](/data-harmonization/semantic-mapping/custom-vocabularies) and use it as the mapping target.

Once reviewed, Semantic Mappings can be incorporated into a **Syntactic Mapping** and used as part of a **Data Harmonization ETL** to transform values in datasets imported to your Rhino Client.

{% hint style="info" %}
**Use this when:** Your source field contains free-text or coded values that need to be translated to a standard or custom vocabulary.
{% endhint %}

{% hint style="warning" %}
**Note**: if strict privacy protections are needed, the project's K-Anonymization parameter should be set to a value greater than 1 at the time of project creation. This controls which source values can be sent to external services during recommendation generation — only values that appear at least K times in the field will be eligible.
{% endhint %}

***

## Accessing Semantic Mappings

{% stepper %}
{% step %}

#### Select Semantic Mappings

Select **Data Mappings** from the **Main Menu**. The **Data Mappings** page appears.
{% endstep %}

{% step %}

#### Open the Semantic Mappings page

Select the **Semantic Mappings** tab. The **Semantic Mappings** page appears. To search for a Semantic Mapping, use the text box located at the top right corner of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/KMIuwAzixfysndqEPmXT/35166543202845)
{% endstep %}
{% endstepper %}

The table below defines each field in this page.

| Field                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Semantic Mapping Name       | Name of the semantic mapping, such as "Normalize Service Type", "Condition", or "Drug \[OMOP]"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Version                     | Version of the semantic mapping. This increments each time you make a change to the semantic mapping.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| Information Icon (on hover) | The information icon shows a summary of the semantic mapping information. Information shown includes the Dataset, Field, Target, Status, Mapping Coverage and Creator. It also includes the number of unique values and approved mappings, as well as the percentage of approved mappings and mapping coverage.                                                                                                                                                                                                                                                                                                                                                                    |
| Status                      | <p>Status of the recommendation and approval process. </p><p></p><p>Statuses are:<br>- <strong>Queued</strong>: The recommendation generation task will begin as soon as resources are available on the Rhino Client.<br>- <strong>Processing</strong>: Recommendations for mapping source dataset field values to the target vocabulary are being generated.<br>- <strong>Needs Review</strong>: Recommendations have been generated and are ready for your review, and not all entries have been approved.<br>- <strong>Approved</strong>: All entries in the Semantic Mapping have been approved.<br>- <strong>Error</strong>: There was some error in the mapping process.</p> |
| Sources                     | Name of the original dataset(s) and field(s) used as sources for mapping.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| Target                      | Name of the Target Vocabulary to map to. For OMOP, this will also list the target domain (e.g., OMOP - Person).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Mapping Coverage            | <p>Percent of values with approved mappings, calculated as the number of non-empty values that have an approved mapping divided by the number of non-empty values. </p><p></p><p>In order to preserve K-Anonymity, if there are \<K non-empty values, this percent will be omitted. </p><p></p><p>K is set by the K-Anonymization parameter configured at the project level in the project permissions.</p>                                                                                                                                                                                                                                                                        |
| Creator                     | Name of the person who created the mapping.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Three-Dot Menu              | The three-dot menu (also known as the “context menu”) provides access to other options: Copy UID, Show Configuration, Export Semantic Mapping, and Remove Semantic Mapping.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |

***

## Creating a New Semantic Mapping

#### Prerequisites

* You must have the "Manage Data Mappings" permission.
* The dataset that you want to use must have been imported into FCP.

#### Steps

{% stepper %}
{% step %}

#### Create the Semantic Mapping

In the **Data Mapping** > **Semantic Mappings** page, select the **Create Semantic Mapping** button.
{% endstep %}

{% step %}

#### Open the Create Semantic Mapping page

The **Create Semantic Mapping** page appears.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FXzw7XD0CU5NyUybESWnM%2Fimage.png?alt=media&amp;token=0ccd029a-172f-46aa-927c-720f31c2b908" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Enter the mapping information

Enter the following information.

* **Name** of the semantic mapping.
* **Description** of the semantic mapping. This is optional, but highly encouraged to improve the quality of recommendations.
* **Dataset** that has the field you want to use as the source for mapping. The dataset should have already been imported into FCP.
* **Field to Map**. The field that you want to use as the source for the semantic mapping.
* **Target** vocabulary that you want to map the field to. Options are:
  * OMOP v5.4
  * FHIR HDP\_0.4.0
  * Custom Vocabulary
* **Target Domain** within OMOP v5.4 to map the field to. This option is not available for Custom Vocabulary mapping.
* **Custom Vocabulary** to map the field to. This option is not available for OMOP mapping.
  {% endstep %}

{% step %}

#### Create the mapping

When complete, select **Create Data Mapping**. The page closes and the **Semantic Mappings** page is displayed again, with an entry for the mapping you just created.&#x20;

**Here is what happens next:**

* The FCP sends a request to your Rhino Client to generate a new Semantic Mapping with recommendations.
* The Rhino Client calculates the unique terms within the source dataset field, and for each term uses a Generative AI model to find the top five mapping recommendations to the selected target vocabulary and domain.
  * In the case of OMOP mapping, the proposed recommendations include target concept names and target concept IDs.
  * In the case of Custom Vocabulary mapping, the proposed recommendations include the target term and the target identifier (if your custom vocabulary includes identifiers).
  * The automatic generation of the mapping recommendations **runs on the Rhino Client**, where the dataset is stored.
  * If during this process, any queries are required to a Rhino service that isn’t hosted on that Rhino Client, only source values that appear at least K times in the field can be sent to this external service so as to preserve K-Anonymity.
* The status changes to “Processing”. The amount of processing time depends on the number of terms to map and the other workloads running on the Rhino Client. For example, a small vocabulary might take a few minutes, but a large one could take several hours.
* The number of times each source value appears in the field is calculated.
* The confidence of the model recommendation for each of the **top 5** recommended mapping values is calculated.
* Once processing is complete, the mapping suggestions are ready for review.
  {% endstep %}
  {% endstepper %}

***

## Editing a Semantic Mapping

#### Prerequisites

* You must have the "Manage Data Mappings" permission.
* A semantic mapping must have already been created. This is covered in the [Creating a New Semantic Mapping](https://app.gitbook.com/o/SKrkLtXReIPmOZjXnWZA/s/ydySyCBmy6F7NnGn4bPa/~/edit/~/changes/333/data-harmonization/semantic-mapping#creating-a-new-semantic-mapping) section above.

#### Steps

{% stepper %}
{% step %}

#### Open the Semantic Mapping Review page

In the **Data Mappings** > **Semantic Mappings** page, click the entry for the semantic mapping that you would like to review. The **Semantic Mapping Review** page appears. In the example below, the Semantic Mapping being reviewed is called "Procedures". A list of unique source values and their selected target values appears.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/DCszjuYmMSxGg1T45xSy/20128602183709)

The following information appears for each mapping entry:

* **Frequency** indicates how many times the source value appears in the source data.
* **Source Value** is the unique term in the source dataset that requires mapping.
* **Selected Target Value** is the currently selected value to map the source value to. The FCP generates mapping recommendations and shows you the top five recommendations. The top recommendation appears first and is selected by default to be the Target Value. To see the other recommendations, click on the drop down menu.
* **Status**: Indicates whether the recommendation has been approved. Click on the slider to approve the recommendation.
* **Confidence** is a number, expressed as a percentage, that represents the likelihood that the mapping recommendation is accurate. Higher percentages indicate a higher likelihood of accuracy than lower percentages. The confidence number reflects the likelihood for the selected target value.

You can also use the filters to view a subset of records, based on the values you specify.
{% endstep %}
{% endstepper %}

***

## Reviewing Semantic Mapping Recommendations

After [Creating a New Semantic Mapping](https://app.gitbook.com/o/SKrkLtXReIPmOZjXnWZA/s/ydySyCBmy6F7NnGn4bPa/~/edit/~/changes/333/data-harmonization/semantic-mapping#creating-a-new-semantic-mapping), the Rhino FCP can generate mapping recommendations for each unique value in the selected source dataset field. Once generated, you can review, edit, and approve the proposed mappings.

Mapping recommendations can be reviewed and approved **individually or in bulk**. Bulk review is especially useful when working with a large number of mapping entries.

### Supported Languages

The Semantic Mapping recommendation engine generates recommendations in the same language as the source terminology. Cross-language translation is not currently supported.

Currently supported languages:

* **English** – for source and target terminology in English
* **Hebrew** – for source and target terminology in Hebrew

{% hint style="info" %}
Need support for another language? Contact us at [support@rhinofcp.com](mailto:support@rhinohealth.com)!
{% endhint %}

### Reviewing Recommendations Individually

Before you review an entry, first look at its frequency, source value, and confidence value. The higher the value, the more confident the FCP is that the recommended mapping is correct. Do one or more of the following steps to review and select a recommendation.

{% stepper %}
{% step %}

#### Approve the top recommendation

By default, the top recommendation is shown in the Target Value field. Examine the recommendation; if you decide to approve it, move the status slider to the right. It turns green, and the status changes to Approved.
{% endstep %}

{% step %}

#### Select another recommendation

To see other recommendations, click the arrow in the Target Value field and select another recommendation. Once you select the other recommendation, the status automatically changes to Approved.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/qWcSEupY7TSPAAulmspv/20059335104797)
{% endstep %}

{% step %}

#### Enter your own target value

If you do not see the recommendation that you want, add your own by typing information into the field. Once you type at least 3 letters, you will see values from the target vocabulary that contain the letters that you typed. You must select a valid value from the target vocabulary. Once a value is selected, the status of the mapping entry automatically changes to Approved.
{% endstep %}

{% step %}

#### Repeat for remaining entries

Repeat this process for each remaining "In Review" entry.
{% endstep %}
{% endstepper %}

### Reviewing Recommendations in Bulk

Sometimes, you might have many semantic mapping entries that you want to review in bulk to streamline the process. To do so, complete the following steps.

{% stepper %}
{% step %}

#### Filter the entries

Use the filters at the top of the table to filter your view to the mapping entires you want to change. For example, you might choose to show only entries that have a confidence below 97%.
{% endstep %}

{% step %}

#### Select the entries

Select the mapping entries you would like to change by clicking the checkboxes at the beginning of each line. To select all entries on a page, click the checkbox next to **Frequency** header at the top of the table.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/8BRxf3piqoKazzqmet9Q/20230462347165)
{% endstep %}

{% step %}

#### Choose an action

You can now select an action to perform on all selected mapping entries from the action ribbon that appears at the bottom of the page:

* **Approve All** will set the status of all selected entries to Approved
* **Set to in review** will set the status of all selected entries to In review
* **Set Target Value** will open a page in which you can search for a target value from the target vocabulary. The selected target value will be set for all selected mappings, and their status will be set to Approved.
  {% endstep %}
  {% endstepper %}

***

## Exporting a Semantic Mapping

To export a semantic mapping to a CSV or JSON file, complete the following steps.

{% stepper %}
{% step %}

#### Open Export Semantic Mapping

In your project, select Data Mappings, then the Semantic Mappings tab.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/qhnOh6saXLfnLiMONNoM/27231422810781)

Select the three-dot menu on the right side of a Semantic Mapping with a status of **Needs Review** or **Accepted**.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/OjPXYKSZ47gDLJqrAIEG/27231468840349)

Select **Export Semantic Mapping** to open the Export Semantic Mapping page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/vFLxQHNd5qyANWJsOJkm/27231468841117)
{% endstep %}

{% step %}

#### Choose the export location

Note the Export Location. You can adjust this if you need to.&#x20;

([Mounting Storage to Your Rhino Client](/settings/mounting-storage-to-your-rhino-client) explains how to create or review client mounted storage that you can use for your export location)
{% endstep %}

{% step %}

#### Export the file

Select the format (CSV or JSON), then select Export Semantic Mapping.&#x20;

When complete, a note appears indicating that the mapping has been exported.
{% endstep %}

{% step %}

#### Download the exported mapping

Go to the place where you exported the semantic mapping and download it.&#x20;

Use a tool of your choice to view the CSV or JSON file.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/XqUzHWkC9gUesNBLpgii/27231422815517)

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/rTSs1bcgoLRcQLWKzTGL/27231422816541)
{% endstep %}
{% endstepper %}

***

## Creating a New Semantic Mapping Version

You can create a new version of an **existing** Semantic Mapping from new data that was not originally used to create the current version of the mapping. This is particularly helpful because it allows you to quickly make updates without you having to review the entire mapping again.

Once you've created the new version:

* Already approved mappings are kept as is and are not re-run by the Large Language Model.
* Unique values and mapping coverage are recalculated.
* Source terms that didn’t exist in the previous version of the mapping are added with mapping recommendations.
* You can continue to edit the mapping until a code object is created.

{% stepper %}
{% step %}

#### Open the Create New Version page

In the Semantic Mapping page, select the New Version button for the mapping that you want. The Create New Version page opens.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ZyV96tMvaCbZxMknIHzA/24170593499421)

|                     |                                                                                                                             |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| Field/Button        | Description                                                                                                                 |
| Name                | Name of the Semantic Mapping. This cannot be changed.                                                                       |
| Description         | Description of the mapping. The description is optional but can be useful, particularly to document changes to the version. |
| Dataset             | Indicates the dataset that you want to use. You can select a different dataset for the new version.                         |
| Select Field to Map | Should include terms from a single vocabulary, target set, or target OMOP Domain.                                           |
| Target              | Target vocabulary or data model to map to. This cannot be changed.                                                          |
| Target Domain       | Target domain; this cannot be changed.                                                                                      |
| {% endstep %}       |                                                                                                                             |

{% step %}

#### Enter version details

Enter information in the Description field, if desired.
{% endstep %}

{% step %}

#### Select the dataset and field

Select the dataset from the drop down menu.

Select the field to map.
{% endstep %}

{% step %}

#### Create the new version

When complete, click Create New Version.
{% endstep %}
{% endstepper %}

***

## Removing a Semantic Mapping

To remove a semantic mapping that was previously created, complete the following steps.

1. In the **Data Mappings** > **Semantic Mappings** page locate the Semantic Mapping you want to remove. Click the three-dot (meatball) menu at the end of the entry and select **Remove semantic mapping**.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/KxsLPGW9XyCNQrtdSoBd/24071477569821)

2. You will be prompted with a message asking whether you want to delete the mapping. Select **Yes**. The semantic mapping is removed.


# Custom Vocabularies

## Overview

A **custom vocabulary** is a user-defined set of standardized terms or concepts that can be used as mapping targets when an existing standard vocabulary, such as those provided by OMOP, does not meet your needs.

For example, if your organization uses its own classification system for procedures, you can create a custom vocabulary containing those terms and then use **Semantic Mapping** to map values from your source datasets to the appropriate custom terms.

Your custom vocabulary can contain up to 1 million entries.

{% hint style="info" %}
**Use this when**: your data requires a vocabulary beyond Rhino FCP's built-in options (e.g., OMOP, FHIR).
{% endhint %}

***

## Accessing Custom Vocabularies

To open the **Custom Vocabularies** page, complete the following steps.

1. Select **Data Mappings** from the Main Menu. The **Data Mappings** page appears.
2. Select the **Custom Vocabularies** tab. The **Custom Vocabularies** page appears. To search for a custom mapping, use the Search Custom Map text box located at the top right corner of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/stgwvfdXEMyKLDSVNdXX/35166537597597)

The table below defines each field in this page.

|                        |                                                                                                                                               |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| **Field**              | **Description**                                                                                                                               |
| Custom Vocabulary Name | Name of the custom vocabulary name, such as “Encounters” or “Billing Codes”.                                                                  |
| Version                | Version of the custom vocabulary. This increments each time you make a change to the custom vocabulary.                                       |
| Date Created           | Date the mapping was created.                                                                                                                 |
| # of Terms             | Number of terms for this custom vocabulary.                                                                                                   |
| Creator                | Name of the person who created the mapping.                                                                                                   |
| Status                 | Status of the Custom Vocabulary                                                                                                               |
| Three-Dot Menu         | The three-dot menu (also known as the “context menu”) provides access to additional options: Copy UID, Show Configuration, Remove Vocabulary. |

***

## Creating a New Custom Vocabulary

{% stepper %}
{% step %}
In the **Data Mapping > Custom Vocabularies** page, click **Create Custom Vocabulary**.
{% endstep %}

{% step %}
The **Create Custom Vocabulary** page appears.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/EjmhxEnmHQdRHU6xdutz/30455864515997)
{% endstep %}

{% step %}
Enter a name for your vocabulary and optionally add a description.
{% endstep %}

{% step %}
You can either manually enter terms for your vocabulary or upload a file that contains the terms.&#x20;

Note that there are **two supported formats** for the terms that you enter (or upload):

* **Codes and Terms:** if you have terms that have specific codes (e.g. "C01" for "Approved" and "C02" for "Denied"), enter the codes and the terms in CSV format or manually, with a comma separating between the code and the term. Each term should be entered on a different line. For example:

  ```auto
  C01,Approved
  C02,Denied
  ```
* **Terms-only (without codes)**: If you have terms that don't have special codes, then you can enter each term on a separate line. For example:

  ```auto
  Approved
  Denied
  ```

{% hint style="warning" %}
In both cases, any commas in your term display text should be escaped using a slash (\\).\
Do not include a header row.
{% endhint %}

**Uploading a file**

* Select Upload File button on the Create Custom Vocabulary page.
* Upload a comma delimited (CSV) file from your device by clicking the Upload File button. Do not include a header row. Each term should be entered on a different line. If you have terms with specific codes, separate them with commas.
  {% endstep %}

{% step %}
When complete, click **Create Custom Vocabulary**. The page closes and the custom vocabulary page is displayed, with an entry for the vocabulary that you just created.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Once you've created a custom vocabulary, you can use [Creating a New Semantic Mapping](https://app.gitbook.com/o/SKrkLtXReIPmOZjXnWZA/s/ydySyCBmy6F7NnGn4bPa/~/edit/~/changes/333/data-harmonization/semantic-mapping#creating-a-new-semantic-mapping) to map values from a dataset field to entries in your custom vocabulary.
{% endhint %}

***

## Editing a Custom Vocabulary

#### Prerequisites

* You must have the "Manage Data Mappings" permission.
* A custom vocabulary must have already been created.

#### Steps

To edit an existing custom vocabulary, you will need to [remove it](#removing-a-custom-vocabulary), then create it again with the updated terms.

***

## Removing a Custom Vocabulary

#### Prerequisites

* You must have the "Manage Data Mappings" permission.
* A custom vocabulary must have already been created.

{% hint style="warning" %}
You cannot remove a custom vocabulary while semantic mapping recommendations are being generated.
{% endhint %}

#### Steps

1. In the **Data Mappings > Custom Vocabularies** page locate the custom vocabulary you want to remove.
2. Click the three-dot (meatball) menu at the end of the entry and select **Remove Custom Vocabulary**.
3. When prompted about removing the vocabulary, select **Yes**.
4. The vocabulary is removed.

{% hint style="info" %}
After removing a custom vocabulary, any Semantic Mappings associated with this vocabulary will also be removed.
{% endhint %}


# Benchmark Performance

**Semantic (Terminology) Mapping Benchmark Performance**

Rhino's self-hosted terminology mapping pipeline was benchmarked against frontier hosted LLMs across a 2,312-query biomedical test set spanning nine cross-vocabulary mapping tasks.&#x20;

<div data-with-frame="true"><figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2F1M4pUTVW7B41fkAyHIUt%2FSemantic%20Benchmarks%20Overview.png?alt=media&amp;token=c78732e6-8a7e-4c40-9e2e-ed6616747d4a" alt=""><figcaption></figcaption></figure></div>

Running entirely inside the customer's firewall, the self-hosted pipeline (Rhino OSS) achieved 67.5% top-1 accuracy and 84.9% top-5 accuracy (the correct concept appears among the first five suggestions), at roughly 7.8x the speed of frontier hosted LLMs on the same task.

Against hosted frontier models using the same candidate lists and prompts, Rhino OSS lands within about five points of the strongest configurations tested: Rhino + Claude Opus (72.1% top-1 / 90.0% top-5) and Rhino + GPT (71.3% top-1 / 89.3% top-5). Frontier models performed comparably only when paired with Rhino's retrieval pipeline — on their own, general-purpose LLMs struggled with this task. This gives customers a self-hosted option that closes most of the gap to frontier-assisted mapping without sending terminology data outside the site, at a fraction of the per-query cost.

A follow-on evaluation added a MedGemma-27B classifier reranking stage over embedding-retrieved candidates (4-way fusion plus synonym expansion, k=30), scored across the same nine datasets. Accuracy varies meaningfully by vocabulary pair: strongest on ICD-O-3→SNOMED and OPCS-4→SNOMED (93–95% top-5/top-10), and weakest on ICD-10-CM→SNOMED (63.7% top-5, 68.5% top-10) and Sheba Labs→LOINC (76.4% top-5, 80.3% top-10). Across all nine sets, unweighted average accuracy was 83.4% top-5 and 86.6% top-10.

<div data-with-frame="true"><figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FQZKsxHMdC1cTwATONkR3%2FDetailed%20Semantic%20Benchmarks.png?alt=media&amp;token=89b87065-9d4f-4894-ab10-2c2cb3f53658" alt=""><figcaption></figcaption></figure></div>

*Methodology note: both benchmarks score 1:1 mappings only. The first benchmark held candidate lists and prompts identical across all three model configurations; the second reflects classifier-stage accuracy on top of embedding retrieval rather than a standalone LLM comparison. Because accuracy is pair-dependent, results should be cited per-vocabulary-pair rather than as a single blended figure when responding to RFP evaluation criteria.*


# Syntactic Mapping

## Overview

A **Syntactic Mapping** (aka. Schema Mapping, Ontology Mapping) defines how the structure of a local source dataset—including its tables, columns, and field types—should be transformed to conform to a target data model, such as OMOP or FHIR.&#x20;

In the **Rhino Data Harmonization Engine** (DHE), AI-assisted recommendations and human review are used to define these transformations, which can incorporate existing Semantic Mappings and ultimately be used to generate a Data Harmonization ETL.

{% hint style="info" %}
**Use this when:** You need to map source columns to target columns, change data types or formats, combine fields, apply logic during transformation, or apply a semantic mapping as part of the transformation.
{% endhint %}

{% hint style="warning" %}
**Note**: When defining a Syntactic Mapping, you will always be working with source and target **schemas**, rather than individual datasets. This allows a Syntactic Mapping to be **reusable** across multiple datasets that share the same schemas, rather than being tied to specific data.
{% endhint %}

***

## Accessing Syntactic Mappings

To access the **Syntactic Mappings** page:

1. Select **Data Mappings** from the main menu.
2. In the Data Mappings page, select the **Syntactic Mappings** tab.

The Syntactic Mappings tab shows all the active syntactic mappings that have been created.&#x20;

To search for a syntactic mapping, use the **Seach** Syntactic Mapping text box located at the top right corner of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ncyo3JHNJY624fcImVDc/35166477558045)

The fields in the screenshot above are defined in the table below.

| Button or Field                                                                                                                            | Description                                                                                                                                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Create Syntactic Mapping                                                                                                                   | Click this button to create a new syntactic mapping.                                                                                                                                                                                           |
| New version                                                                                                                                | Click this button to create a new version of an existing syntactic mapping.                                                                                                                                                                    |
| Syntactic Mapping Name                                                                                                                     | Name of the mapping.                                                                                                                                                                                                                           |
| Version                                                                                                                                    | Indicates the version of the Syntactic Mapping. The first version of a Syntactic Mapping is the number 0.                                                                                                                                      |
| Information icon (on hover)                                                                                                                | Displays additional information about the syntactic mapping, such as the description provided during creation of the syntactic mapping.                                                                                                        |
| Date Created                                                                                                                               | Indicates the date the syntactic mapping was created.                                                                                                                                                                                          |
| Target Data Model                                                                                                                          | Indicates the target data model for the mapping, such as OMOP v5.4.                                                                                                                                                                            |
| Source Data Schemas                                                                                                                        | Indicates the source data schemas of the datasets that you would like to map. If there is more than one, the number of source schemas will appear (e.g. “3 Schemas”). If there is more than one schema, hover to see the names of the schemas. |
| Target Tables                                                                                                                              | Indicates the target tables for the transformation. If there is more than one, the number of target tables will appear (e.g. "2 Tables"). If there is more than one table, hover to see the names of the tables.                               |
| Creator                                                                                                                                    | Name of the person who created the syntactic mapping.                                                                                                                                                                                          |
| <p>3 Dot Menu<br><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/UdzfTldjw1Vhw3q2Fo0X/23459070768669" alt=""></p> | The three dot menu (also known as the "context menu") provides access to additional options: Copy UID, Show Configuration, Download Mapping Config, and Remove Syntactic Mapping.                                                              |

***

## Creating a New Syntactic Mapping

#### Prerequisites

* You must have the "Manage Data Mappings" permission.
* The dataset that you want to harmonize must have been imported into FCP.

{% stepper %}
{% step %}

#### Enter the mapping details

In the Syntactic Mappings page, select Create Syntactic Mapping.

The **Create Syntactic Mapping** page appears.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2Fp0ghfkIz4T7eO4H7Qhgr%2Fimage.png?alt=media&amp;token=bce4633b-b420-47d7-8c6c-20897368bbe5" alt=""><figcaption></figcaption></figure>

Enter the **name** of the syntactic mapping.

Optionally, enter the **description** of the syntactic mapping.&#x20;

{% hint style="info" %}
We encourage you to provide as detailed a description as possible, as this additional context helps the LLM generate more accurate and relevant recommendations.
{% endhint %}

Select the **Target Data Model** from the drop down menu.&#x20;

Options are:

* **OMOP v5.4**
* **FHIR R4** — a second dropdown appears for **Target Data Model Version**: choose FHIR R4 IL Core or FHIR R4 IL HDP.
* **Custom** — use for any non-standard or internal data model.
  {% endstep %}

{% step %}

#### Configure

You can either create the configuration via the UI or upload a configuration from a file (in JSON format).

{% tabs %}
{% tab title="Manually Configure" %}
To create the configuration in the UI, click **Manually Configure**, then select the source data schema(s) from the drop-down menu under Source Data Schemas. You can select more than one. Next, select the Target Table(s) from the drop down menu. You can select more than one.

For FHIR R4 IL HDP, there are 20 tables (also called profiles) available: *IL Core Device, IL Core Encounter, IL Core Immunization, IL Core Procedure, IL HDP Allergy Intolerance, IL HDP Condition, IL HDP Device Dispense, IL HDP Device Request, IL HDP Document Reference, IL HDP Medication, IL HDP Medication Administration, IL HDP Medication Dispense, IL HDP Medication Request, IL HDP Medication Statement, IL HDP Observation Lab, IL HDP Organization, IL HDP Patient, IL HDP Practitioner, IL HDP Service Request, IL HDP Vital Signs*. For more information on these tables, see [this link](https://simplifier.net/hdp-il).

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/8UriCDtAAIAFWTiCVBxG/23780511853085)
{% endtab %}

{% tab title="Upload from File" %}
To upload a configuration from a file (supported for all target data models), click **Upload from File**, then click or drag and drop a JSON file into the shaded area or select "Browse" to select a JSON file from your computer. Once uploaded, the name of the file will appear.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/WhSkLgiYteHYSUpnlTd4/23780529863965)

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/lA6rNsQHOjXJf71qQCHB/23780529864349)
{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

#### Create the mapping

Click **Create Syntactic Mapping**.

Your new mapping appears in the Data Mapping page under the Syntactic Mappings tab.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/GmcRI6KwXVZKmMKb6RuO/23780511853981)
{% endstep %}
{% endstepper %}

***

## Editing a Syntactic Mapping

Once you have created the syntactic mapping, you can review and edit the mapping from source to target fields, and their associated transformations.

#### Prerequisites

* You must have the "Manage Data Mappings" permission.
* The dataset that you want to harmonize must have been imported into FCP.
* The syntactic mapping you want to edit must already exist.

#### Steps

{% stepper %}
{% step %}

#### Open the mapping

Click on the syntactic mapping in the Syntactic Mappings page. The **Edit Syntactic Mapping** page appears.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/C3h8eFyzUdkNbaEsmse6/24099990321565)

{% hint style="info" %}
If you created a new syntactic mapping and selected to **manually configure** it in the UI, then you will automatically be brought to this page to set up your new syntactic mapping.
{% endhint %}
{% endstep %}

{% step %}

#### Review the target fields

All target tables for the syntactic mapping and their fields appear in the Target Field column. A red asterisk indicates that the target field is required.
{% endstep %}

{% step %}

#### Map source fields

For each target field, you can select one or more source fields to map to the target field. Click on the source field dropdown and you can select fields from any input data schemas for the syntactic mapping. If you select more than one field, make sure that you select fields from the same schema, and note that you will be required to configure a transformation to define how to generate the value for the target field from the different source fields.
{% endstep %}

{% step %}

#### Edit transformations

You can edit the transformations each target field by clicking the pencil icon in the Transformations column.&#x20;
{% endstep %}

{% step %}

#### Save your work

At any time, you can click the Save button to save your work. Syntactic Mappings can be updated as you work through the different source to target field mappings and transformations.

{% hint style="info" %}
**Once you run** a Rhino Data Harmonization (RhinoDHE) Code Object that references a Syntactic Mapping, **it can no longer be edited** (to ensure reproducibility), and you must create a new version of the Syntactic Mapping to continue editing it.
{% endhint %}
{% endstep %}
{% endstepper %}

***

## Reviewing Syntactic Mapping Recommendations

The Rhino FCP can auto-generate syntactic mapping recommendations and their associated transformations using AI to speed up the initial mapping process. After the suggested recommendations are made, you can review and adjust them as necessary.

#### Prerequisites

* The syntactic mapping must already be created using "Custom" as the target data model.
* If a Rhino Data Harmonization (RhinoDHE) Code Object references syntactic mapping, it must not have been executed (run). If it has, the mapping can no longer be edited (to ensure reproducibility). If that has happened, create a new version of the Syntactic Mapping to continue editing it.

{% hint style="warning" %}
**Note**: Make sure the **Description** field is populated for each field in both your source and target schemas. These descriptions provide important context to the LLM when generating mapping recommendations. Without them, the LLM may not have enough information to generate the Syntactic Mapping successfully.
{% endhint %}

#### Steps

{% stepper %}
{% step %}

#### Review Source & Target Fields

In the Syntactic Mappings page, the Source Fields appear in the Source Fields column. All target tables for the syntactic mapping and their fields appear in the Target Field column. A red asterisk indicates that the target field is required.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/b1USDhe1fW57s5FF1lZO/33676103083165)
{% endstep %}

{% step %}

#### Generate recommendations

Select the "Generate Recommendations" button in the top right section of the screen to suggest source mappings for the target field automatically. A pop up note appears in the bottom right corner of the screen indicating that recommendations are being generated. While recommendations are being generated, you can go to other screens in Rhino FCP to work.
{% endstep %}

{% step %}

#### Review the AI output

When the recommendations have been made, review each field to determine the accuracy of each mapping. AI recommendations have icons next to them to indicate that a row was populated by AI. The icon disappears after a user edits and saves changes. Note that some rows will be populated with recommendations, while others might not be.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ad60JWTq8l68pJZibgGf/33676103083549)
{% endstep %}

{% step %}

#### Handle errors

When AI fails to generate relevant recommendation, an error message appears on the corresponding row.
{% endstep %}

{% step %}

#### Make manual changes

Make changes to mappings manually if needed. As you do this, click the **Save** button to save your work. Syntactic Mappings can be updated as you work through the different source to target field mappings and transformations.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/eccbeneCphezBE1mK4cp/33676088813213)
{% endstep %}

{% step %}

#### Review transformations

Review and address transformations as well.&#x20;
{% endstep %}

{% step %}

#### Regenerate if needed

If needed, you can choose to generate LLM recommendations again. The fields that you already populated will remain as is and the LLM will generate recommendations for remaining fields only.
{% endstep %}
{% endstepper %}

{% hint style="warning" %}
**NOTE**: If you need to start all over again, select the "Clear All" button at the top right corner of the screen, then select Remove all Mappings in the message that appears. If you do this, it will clear all current mappings and reset the table, so proceed with caution. This change cannot be undone.
{% endhint %}

***

## Creating a New Syntactic Mapping Version

Before you create a new version, it is helpful to understand that when a new version is created, the system uses the most recent existing version of the same Syntactic Mapping for preservation.&#x20;

The following table shows the schema change and the user interface behavior in the new version.

| Field                             | Description                                                                                                                           |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Schema Change                     | User Interface Behavior in the New Mapping Version                                                                                    |
| Unchanged Target or Source Fields | Previously defined Source Fields and Transformations are preserved. You can edit preserved mappings as needed.                        |
| New Target Fields                 | Appear as empty, editable rows in the Syntactic Mapping panel, ready for you to define a new mapping.                                 |
| New Source Fields                 | Become available in the Source Field selection dropdowns.                                                                             |
| Deleted or Renamed Target Fields  | Corresponding mapping rows are removed and will not be displayed in the new version.                                                  |
| Deleted Source Fields             | Mappings referencing these fields are cleared, and the affected rows will appear empty and editable if the Target Field still exists. |

* **Preservation Logic:** Mappings are preserved only when the Target Field exists in the new Target Schema version AND all referenced Source Fields exist in the new Source Schema version.
* **Matching:** Field preservation requires an exact match on the field name.
* **Scope:** Preservation applies only within the same Syntactic Mapping object; it does not support copying mappings between different mapping objects.
* **No Automatic Remapping:** No automatic or heuristic remapping is performed for renamed fields. If a field is renamed, the mapping is cleared or removed, ensuring you explicitly review and redefine any mappings where schema semantics have changed.

#### Steps

{% stepper %}
{% step %}

#### Open the new version flow

In the Syntactic Mapping page, click the New Version button of the Syntactic Mapping you want to create a new version of.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/IDhoRiDkg3WmG0O2MioI/23782406678045)
{% endstep %}

{% step %}

#### Review the version details

The Create New Syntactic Mapping Version page appears.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FAXPQBYsuuixKnCsBXQyf%2Fimage.png?alt=media&amp;token=c985bcd7-6820-4533-8959-6622d9429c88" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Keep required fields unchanged

The name and target data model cannot be changed - they must be consistent for all versions of the same Syntactic Mapping. If you would like to select a different name or target data model, you can create a new Syntactic Mapping instead of creating a new version.
{% endstep %}

{% step %}

#### Update the description

The description can be updated. Update it to indicate changes, if desired.
{% endstep %}

{% step %}

#### Update source data schemas

Update the source data schemas if needed. For more information on how to do this, see the Creating a Syntactic Mapping article.
{% endstep %}

{% step %}

#### Update target tables

To streamline data harmonization when Source and Target Schemas evolve (e.g., due to regulatory updates or new source data), Syntactic Mapping definitions are automatically preserved. This feature allows you to focus only on mapping new or changed fields (schema deltas) without redoing your completed work. Update the target tables if needed. For more information on how to do this, see the Creating a Syntactic Mapping article.
{% endstep %}

{% step %}

#### Create the new version

Click the Create New Version button. The new version of the syntactic mapping appears on the Syntactic Mappings page.
{% endstep %}
{% endstepper %}

***

## Removing a Syntactic Mapping

#### Prerequisites

* You must have the "Manage Data Mappings" permission.
* The syntactic mapping must exist.

#### Steps

{% stepper %}
{% step %}

#### Select the mapping you want to remove

Go to **Data Mappings → Syntactic Mappings**

On the **Syntactic Mapping** page, select the three-dot menu for version of the syntactic mapping you want to remove.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/KMs6Iur10VUWcPy0Hc3o/23778534444317)
{% endstep %}

{% step %}

#### Select the option to remove syntactic mapping

Select “Remove syntactic mapping”.&#x20;

A message will appear indicating that the mapping has been removed.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/hinqsWGvbrgrAjX3xa4h/23778534447773)
{% endstep %}
{% endstepper %}


# Column Transformations

## Overview

Once you have [created a syntactic mapping](/data-harmonization/syntactic-mapping), you can apply one or more transformations to it.&#x20;

**Transformations** are essential for cleaning, organizing, and standardizing source data so that its information is preserved and accurately represented in the target vocabulary or coding system.

For example, imagine that you have a source field called `ethnic_background` and you need to map it to a target field named `race_concept_id`. You could use the "Custom Mapping" type of transformation to do this. Here is an example of what that could look like:

| Source (ethnic\_background) | Target (OMOP)(race\_concept\_id) |
| --------------------------- | -------------------------------- |
| 1                           | 8527                             |
| 2                           | 4212311                          |
| 3                           | 8515                             |
| 4                           | 38003598                         |
| 5                           | 38003579                         |

When the transformation is run, the value in the source is mapped to the corresponding value in the target. Using the table above, a value of "1" would be transformed to "8527."

***

## Transformation Fields

A transformation consists of the following fields.&#x20;

Note that not all transformations will require all fields to be populated.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/CiqlvdCBPWvRHVsBOdJh/23963516711837)

* **Transformation Type**: This specifies the kind of transformation you're using. See [here](https://app.gitbook.com/o/SKrkLtXReIPmOZjXnWZA/s/ydySyCBmy6F7NnGn4bPa/~/edit/~/changes/340/data-harmonization/syntactic-mapping/column-transformations#transformation-types) for more detail.
* **Transformation Input(s) and Output**: Lists the names of source fields and their corresponding target output.
* **Description**: Offers a concise explanation of the transformation type.
* **Error Message**: Shows any error messages related to the transformation.
* **Transformation Configuration**: Displays any configuration/code for the transformation.
* **Error Handling**: Specifies actions to take if there's a failure, like a missing source value or code error, and sets a default value in such cases.

***

## Editing a Transformation

#### Prerequisites

* You must have the "Manage Data Mappings" permission.
* A syntactic mapping should have already been created.

#### Steps

{% stepper %}
{% step %}

#### Select the syntactic mapping

In the Syntactic Mappings page, select the mapping that you want to edit transformations for.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/zRTI58LZxPXjgjlXTxg8/23781590210589)
{% endstep %}

{% step %}

#### Open the transformation editor

Find the mapping entry you want to edit, then click the pencil icon in the Transformation column. The Transformations Panel will appear.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FLVJSr8XtQRu09C74k4lu%2Fimage.png?alt=media&amp;token=d9a0fcf1-f8c3-44f3-8510-97615d5e7c22" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Add / Edit a transformation

Click the dropdown menu to select the desired transformation type and edit the transformation as desired.

Note the **Transformation Input** (source) and **Transformation Output** (target)**.** It should reflect what you already chose in the syntactic mapping entry.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FJ0c6kiEheOHX3VSVpqxI%2Fimage.png?alt=media&amp;token=52403ec9-ed5c-4429-a84c-3e51c662f5d8" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Reorder Transformations

Click the transformation's handle (six domino-looking dots), and drag the transformation in the order you want it to run. Do this for each transformation that you want to reorder.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/EhrICFQuF1d4AexGLxEd/23781746888605)

{% hint style="info" %}
When code runs, configured transformations are executed one after another for a given syntactic mapping entry.
{% endhint %}
{% endstep %}

{% step %}

#### Save the changes

When complete, click the "Save" button.
{% endstep %}
{% endstepper %}

{% hint style="warning" %}
Values that cannot be converted are left empty in the output. See the code run logs for a breakdown of conversion failures.
{% endhint %}

***

## Transformation Types

| Transformation Type                                       | Description                                                                                                                                                                                                                                                                                                                                |
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [Custom Mapping](#transformation-type-custom-mapping)     | <p>Maps values from the source dataset to corresponding values in the target dataset</p><p></p><p>e.g., mapping a number to the day of the week</p>                                                                                                                                                                                        |
| [Semantic Mapping](#transformation-type-semantic-mapping) | <p>Applies a semantic mapping to transform values</p><p></p><p>e.g., mapping an input text to an OMOP concept ID</p>                                                                                                                                                                                                                       |
| [Set Value](#transformation-type-set-value)               | <p>Assigns a specific value to all rows in the field</p><p></p><p>e.g., setting all values to the number 1</p>                                                                                                                                                                                                                             |
| [Convert Date](#transformation-type-convert-date)         | <p>Changes the date to a different format</p><p></p><p>e.g., convert a date from MM/DD/YY format to YYYY-MM-DD.</p>                                                                                                                                                                                                                        |
| [Stable UUID](#transformation-type-stable-uuid)           | Generates an encrypted unique identifier based on the input. The same input will always generate the same unique identifier.                                                                                                                                                                                                               |
| [Row Level Code](#transformation-type-row-level-code)     | <p>Applies Python code to each row of input in order to generate the output field value. The input row is available in the "row" dictionary, and the code is expected to generate an "output" variable with the output.</p><p></p><p>e.g., this can be used to transform the output of a specific source field to uppercase characters</p> |
| [Table Level Code](#transformation-type-table-level-code) | Applies Python code to generate an entire column with the output field values. Has access to all input tables and fields, and can utilize Python code to generate the output column.                                                                                                                                                       |
| [VLookup](#transformation-type-vlookup)                   | Looks up each source value in the lookup table, matches a row in the lookup table based on the lookup key field, and returns the value from the matching row in the lookup value field.                                                                                                                                                    |

### <mark style="color:$info;">**Transformation Type:**</mark> Custom Mapping

A **Custom Mapping** transformation looks up each source value (input field value) in a custom mapping dictionary to find the target value (output field value). This custom mapping dictionary is defined in the transformation configuration, and makes it easy to create quick lookup tables for fixed value transformations.

{% stepper %}
{% step %}
Follow the steps [here](#steps) to access the transformation panel.
{% endstep %}

{% step %}
Select the **Custom Mapping** transformation.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FkkUA6fVtN8mg3kAbiYIy%2Fimage.png?alt=media&amp;token=702ebb79-7538-4a88-ad84-317eac6e2a51" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}
Add the custom mapping to the code section. We currently support CSV or JSON.

* **CSV** - the syntax is: ***input value,output value.*** Place each set of values on a separate line. For example:

  ```
  m,Male
  f,Female
  o,Other
  ```
* **JSON** - should be a valid JSON dictionary. For example:

  ```
  {
    "m": "Male",
    "f": "Female",
    "o": "Other"
  }
  ```

{% endstep %}

{% step %}
Indicate what happens if the mapping from the source value is **not found**.&#x20;

You can choose to:

* **Skip the row** - this entire row will be omitted from the output table.
* **Fail** - the entire code run is failed.
* **Use the source value** - the output value will be set to the source value without any changes
* **Set to default** - set the output to a default value (e.g. "" or "0" or "MISSING"). If you select "Set to default", another input appears for you to fill in the desired default value.
  {% endstep %}

{% step %}
When complete, click the "Save" button.
{% endstep %}
{% endstepper %}

### <mark style="color:$info;">**Transformation Type:**</mark> Semantic Mapping

A **Semantic Mapping** transformation applies a [semantic mapping](/data-harmonization/semantic-mapping) to the input field value to set the output field value. This means that each value in the input field is looked up in the semantic mapping, and the matching output value is set in the output field.

{% stepper %}
{% step %}
Follow the steps [here](#steps) to access the transformation panel.
{% endstep %}

{% step %}
Select the **Semantic Mapping** transformation.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/THMTqhDibVKbfWHIjQY5/23782159686813)
{% endstep %}

{% step %}
Select the target vocabulary of the semantic mapping that you'd like to use in this transformation: OMOP V5.4 or Custom Vocabulary.

* **For OMOP** - Select the Target Domain.
* **For Custom Vocabularies**, select the specific Custom Vocabulary to use
  {% endstep %}

{% step %}
Indicate the transformation output type, which means the type of output to use from the matched term.&#x20;

The output type can be:

* **Concept ID or Code** - use the matched term's concept ID or code (e.g. "35816080") as the output. For custom vocabularies with no distinction between the term display name and code, the code will be identical to the display name.
* **Concept Name or Display Name** - use the matched term's concept name or display name (e.g. "Aspirin") as the output.
  {% endstep %}

{% step %}
Indicate what should happen if the source value matches an entry in the semantic mapping that has **not yet been approved** in FCP (more information on how to [approve semantic mapping entries is here](/data-harmonization/semantic-mapping)).&#x20;

You can choose to:

* Use the top recommendation from the semantic mapping recommendations generated by FCP
* Treat such values as missing from the mapping.
  {% endstep %}

{% step %}
Indicate what should happen if the source value is **missing** from the semantic mapping.&#x20;

You can choose to:

* **Skip the row** - this entire row will be omitted from the output table
* **Fail** - the entire code run is failed
* **Use the source value** - the output value will be set to the source value without any changes
* **Set to default** - set the output to a default value (e.g. "" or "0" or "MISSING"). If you select "Set to default", another input appears for you to fill in the desired default value.
  {% endstep %}

{% step %}
When complete, click the "Save" button.
{% endstep %}
{% endstepper %}

### <mark style="color:$info;">**Transformation Type:**</mark> Set Value

A **Set Value** transformation sets a specific value in all rows of the output field.

{% stepper %}
{% step %}
Follow the steps [here](#steps) to access the transformation panel.
{% endstep %}

{% step %}
Select the **Set Value** transformation.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/lLdcfxsMsll5RI1eLhGn/23782073983901)
{% endstep %}

{% step %}
Enter the transformation output value as the value that you would like to be set in the output field for **ALL** output rows. It should be a number or string.
{% endstep %}

{% step %}
When complete, click the "Save" button.
{% endstep %}
{% endstepper %}

### <mark style="color:$info;">**Transformation Type:**</mark> Convert Date

A **Convert Date** transformation converts an input value that is a date in one format into an output date in a different format.&#x20;

**For Example:**

| Input        | Input Format | Output Format | Output       |
| ------------ | ------------ | ------------- | ------------ |
| `01/15/2023` | `MM/DD/YYYY` | `YYYY-MM-DD`  | `2023-01-15` |
| `15-Jan-23`  | `DD-MMM-YY`  | `YYYY-MM-DD`  | `2023-01-15` |

{% hint style="info" %}
The same can be achieved using a Row Level Code transformation, but this transformation makes it easier to avoid common pitfalls in python date transformation code.
{% endhint %}

{% stepper %}
{% step %}
Follow the steps [here](#steps) to access the transformation panel.
{% endstep %}

{% step %}
Select the **Convert Date** transformation.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/8EYl3O53GkYCgbF3Ku6h/23782013464861)
{% endstep %}

{% step %}
Enter the **Input** and **Output** **date formats**.&#x20;

These should both be in the python **arrow library format** ([see supported tokens](https://arrow.readthedocs.io/en/latest/guide.html#supported-tokens)). For example, if your input is something like "Dec 31, 2024" and you'd like to transform it to something like "2024-12-31", you could use the input format "MMM D, YYYY" and the output format "YYYY-MM-DD".
{% endstep %}

{% step %}
When complete, click the "Save" button.
{% endstep %}
{% endstepper %}

### <mark style="color:$info;">**Transformation Type:**</mark> Stable UUID

A **Stable UUID** transformation returns a unique output value for each input value by encrypting the input value. The encryption is "stable" in the sense that for the same input value, the same output value will always be generated.

{% stepper %}
{% step %}
Follow the steps [here](#steps) to access the transformation panel.
{% endstep %}

{% step %}
Select the **Stable UUID** transformation.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FYC4sBlHefPUoWRJKmiRt%2Fimage.png?alt=media&amp;token=c65f66dc-7f8a-4057-8164-33c98b0f65a0" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}
There is no additional configuration required for the Stable UUID transformation.
{% endstep %}

{% step %}
When complete, click the "Save" button.
{% endstep %}
{% endstepper %}

### <mark style="color:$info;">**Transformation Type:**</mark> Row Level Code

A **Row Level Code** transformation applies python code to each row of data to transform the input values into the output that will be placed in the output field for that row.

{% stepper %}
{% step %}
Follow the steps [here](#steps) to access the transformation panel.
{% endstep %}

{% step %}
Select the **Row Level Code** transformation.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/H41DBwR8ctcN95VfuWT5/23782031369629)
{% endstep %}

{% step %}
Enter a **Python code snippet** that you want to apply to each row.

* The code snippet has access to the input fields in a special "**row**" variable. This is a dictionary with each field name mapped to the field value. For example, if there is a "gender" source field, your code can access its value for the input row via:

  ```python
  row["gender"]
  ```
* The code snippet should set the desired output value to a special "**output**" variable. For example, if you'd like to take the input value of the "gender" field, and set the output to be the first letter of the input value in uppercase, your code could look like this:

  ```python
  output = row["gender"][:1].upper()
  ```

{% endstep %}

{% step %}
Indicate what happens if the code **fails** (e.g. there is an exception when executing the code).&#x20;

You have three options:

* **Skip row** - this entire row is omitted from the output.
* **Fail** - the Data Harmonization code run fails - you will see the error message in the detailed log of the code run.
* **Set to default** - set a specific value (e.g. "" or "ERROR") to the output value in rows in which the error occurred. If you select to set to a default value, a new input appears that allows you to enter the default value. The value can be a string or a number.
  {% endstep %}

{% step %}
When complete, click the "Save" button.
{% endstep %}
{% endstepper %}

### <mark style="color:$info;">**Transformation Type:**</mark> Table Level Code

A **Table Level Code** transformation applies python code to process input field values and generate an entire column of output values.

{% stepper %}
{% step %}
Follow the steps [here](#steps) to access the transformation panel.
{% endstep %}

{% step %}
Select the **Table Level Code** transformation.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/yVO3oyfqiu2uCnZBe3p3/24099997628573)
{% endstep %}

{% step %}
Enter a **Python code snippet** that you want to run in order to generate the **entire column** of output values.

* The code snippet has access to all fields in all input data sources.
  * Each **input data source** is available in a variable with a name matching the schema name in snake case. For example, if the source data schema is called "Patient Table", the matching variable will be "patient\_table".
  * Each **data source variable** is a dictionary with each field name mapped to the field value. For example, if there is a "gender" field in the "Patient Table" dataset, your code can access its values via:

    ```
    patient_table["gender"]
    ```
* The code snippet can use methods from pandas (imported as pd), numpy (imported as np), and arrow.
* The code snippet should set the desired output values to a special "**output**" variable. The output should be a one-dimensional Pandas Series or array, and its length should be the number of rows in the output table. The values in the output will be set directly as the column values in the output table in the order provided by the code snippet. For example, if you would like to set the output value to be the element-wise maximum between two input fields (assuming that they are of the same length, matching order, and you'd like the output to be of the same length and in the same order), you could use something like the following:

  ```
  date_of_service = pd.to_datetime(encounters["DateOfService"], format="%Y-%m-%d")
  procedure_end_date = pd.to_datetime(procedures["ProcedureEndDate"], format="%Y-%m-%d")
  output = np.maximum(date_of_service, procedure_end_date)
  ```

{% endstep %}

{% step %}
Indicate what happens if the code **fails**

You have two options: **fail** the entire code run or set the output to a **default** value.

The default value can be a string or a number and it will be set in the output field for all rows.
{% endstep %}

{% step %}
When complete, click the "Save" button.
{% endstep %}
{% endstepper %}

### <mark style="color:$info;">**Transformation Type:**</mark>  VLookup

A **VLookup** transformation performs a Vertical Lookup. This means that for each value in the source field, it looks up a matching value in the lookup table within the lookup key field. If a match is found, the output is set to the value of the lookup value field in the matching row. This is similar to the VLookup functionality in spreadsheets.

{% stepper %}
{% step %}
Follow the steps [here](#steps) to access the transformation panel.
{% endstep %}

{% step %}
Select the **VLookup** transformation.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ijTLgcDsXGSCfH1BXjUV/24099997689117)
{% endstep %}

{% step %}
Fill in the **Lookup Table** - this is a source data schema in which you want to match values from the source field.
{% endstep %}

{% step %}
Fill in the **Lookup Key Field** - this is the field in the Lookup Table that should have values that match the values in the source field.
{% endstep %}

{% step %}
Fill in the **Lookup Value Field** - this is the field in the Lookup Table from which the output will be filled in, if a matching row is found.
{% endstep %}

{% step %}
Indicate what should happen **if no match is found** when looking up a specific source field value in the lookup key field.&#x20;

There are several options available: skip the row, cause the code run to fail, use the source value or set the output to a default value (return a number of string).
{% endstep %}

{% step %}
Indicate what should happen **if multiple matches are found** when looking up a specific source field value in the lookup key field.&#x20;

There are several options available: use the first match, use the last match, fail the code run, or set to a default value (return a number or string).
{% endstep %}

{% step %}
When complete, click the "Save" button.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Note that source field values don't need to be unique (the same value can appear multiple times in the source field and will be transformed to the same value in the output consistently).
{% endhint %}


# Custom Data Models

### Overview

The RhinoDHE allows you to harmonize data to a **custom data model** rather than a predefined standard such as OMOP. This is useful when your project has a only requires a specific subset or structure of data and performing a full mapping to a standard data model would be unnecessary.

For example, you may want to prepare a dataset for a machine learning model that expects a specific set of fields, create a standardized research dataset containing only the variables needed for an analysis, or transform data into a common ontology agreed upon by multiple collaborators.

### Prerequisites

You must have the "Manage Data Mappings" permission.

**Before you begin**:

* The source data you want to use should already be available in Rhino FCP.
  * The schema for this will be auto-generated if you do not explicitly define it.
* Determine which fields you want to include in your custom data model.
* Determine how you want to transform your fields from source to target.

### Steps

To define the structure of your custom data model, you first create a **Data Schema** specifying the fields, data types, and other properties that the resulting dataset should contain. You then create a **Syntactic Mapping** that defines how data from your source dataset should be transformed to match that schema.

{% stepper %}
{% step %}

#### Select the project

Select the project that contains the syntactic mapping of the data.
{% endstep %}

{% step %}

#### Open Data Schemas

Select **Data Schemas** from the menu on the left.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/pptmtOn65GLJORejsMce/26968416144157)
{% endstep %}

{% step %}

#### Create a new data schema

Select **Create New Data Schema** button in the upper right corner.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/Om3tgRmVQyfq6TPGZMDd/26968416144413)
{% endstep %}

{% step %}

#### Enter schema details

Enter the name and description of the target data schema.
{% endstep %}

{% step %}

#### Choose how to create the schema

Select the **Create Blank Data Schema** or **Upload From File** button.&#x20;

If you want to create your own schema from scratch, select create blank data schema.&#x20;

If you have a CSV file, select Upload from File and select the file from your computer or device.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/DKDuQHxoGIxW5yyxFZpW/26968446357149)
{% endstep %}

{% step %}

#### Create the schema

Select the **Create New Data Schema** button. The schema appears.&#x20;

If you selected the **Create Blank Data Schema** button, a blank schema will appear like the following.&#x20;

If you chose **Upload From File** button, you’ll see the fields from your CSV file.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/plnS0Pz0BOLbwPqsyT50/26968416144925)
{% endstep %}

{% step %}

#### Add fields

For each tabular column, add the Name, Identifier, Description, Role, Type, Type Params, Units, May Contain PHI, and Permissions.

To add additional fields, select the **Add Fields** button.
{% endstep %}

{% step %}

#### Save the schema

When complete, click **Save**.
{% endstep %}

{% step %}

#### Create the syntactic mapping

Create a new Syntactic Mapping by following instructions in [Syntactic Mapping](/data-harmonization/syntactic-mapping).&#x20;

Make sure that the target data model is **Custom**.&#x20;

Select the **new schema** **that you created** in the previous steps for the Target field.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ZEFVqSX8tFABYGSJUCj6/26968446357405)
{% endstep %}
{% endstepper %}


# Syntactic Mapping Configuration

## Overview

This topic explains how to work with RhinoDHE **Syntactic Mapping configurations** in **JSON** format.

A [Syntactic Mapping](/data-harmonization/syntactic-mapping) defines how source fields map to target fields, including any [transformations](/data-harmonization/syntactic-mapping/column-transformations) that should be applied during the harmonization process. You can create and edit these mappings directly in the Rhino FCP UI or view, download, edit, and upload the same configuration in JSON format.

{% hint style="info" %}
The JSON format is simply an alternative representation of the Syntactic Mapping configuration and supports the same mapping and transformation capabilities available in the FCP UI.
{% endhint %}

## Prerequisites

You must have the "Manage Data Mappings" permission.

## Accessing a Syntactic Mapping Configuration

You can view a syntactic mapping configuration in JSON format, by completing the following steps.

1. In the **Syntactic Mappings** page, select the three-dot menu for the version of the syntactic mapping you want to view and select "Show configuration".
2. The **Syntactic Mapping Configuration** page appears. Scroll down to see the Mapping Configuration if it is not visible.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/HpWiGY426GQOdcAiHvtA/23780144543773)

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/3nbW8oLLOwYOrj9AEek5/23780144544413)

If you want to **copy** the configuration mapping to your computer's clipboard, select the rectangle on the right side of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/lYIYoUohzRlHruVzfUWD/23780144544797)

3. Select **Close**.

## Downloading a Syntactic Mapping Configuration&#x20;

1. In the **Syntactic Mappings** page, click the three-dot menu for the version of the syntactic mapping you want to download and click "**Download mapping config**".
2. The configuration file downloads to your local computer.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2Fni0LmCEsSIeUznW6MfRY%2Fimage.png?alt=media&amp;token=087a8778-d96c-45ea-bdb2-0348b53c0f4f" alt=""><figcaption></figcaption></figure>

## Creating a Syntactic Mapping from JSON Configuration

1. In the **Syntactic Mappings** page, click the "**Create Syntactic Mapping**" button. The Create Syntactic Mapping Page appears.
2. Enter a name, optionally also a description, and select your target data model.
3. Under configuration, select "Upload From File", and then **select your JSON configuration file**.
4. Click **Create Syntactic Mapping**.


# Executing the Transformation

## Overview

The **Rhino Data Harmonization Engine (RhinoDHE)** automatically converts [Syntactic Mappings](/data-harmonization/syntactic-mapping) (and any associated [Semantic Mappings](/data-harmonization/semantic-mapping)) into reusable ETL workflows. These workflows run directly on your Rhino Client, in accordance with the principles of federated computing, to transform datasets from a source format into the defined target format.

**Syntactic Mappings** can be used to generate **Data Harmonization Code Objects**, which function like other Code Objects in Rhino FCP and can be executed remotely on a Rhino Client.

When a **Data Harmonization Code Object** is run, the Syntactic Mapping is applied to the input dataset, mapping source fields to target fields and applying any configured transformations. The resulting harmonized dataset is stored on the same Rhino Client and can then be used like any other dataset in Rhino FCP.

## Prerequisites

* You must have the "**Manage Data Mappings**" permission.
* You must have the "**Run Code on This Site**" permission for the site on which the harmonization is to be run.
* The datasets that you want to harmonize must have been imported into FCP.
* The [syntactic mapping](/data-harmonization/syntactic-mapping) you want to edit must exist.
* Any [semantic mappings](/data-harmonization/semantic-mapping) referenced by the syntactic mapping must exist.

## Running a Data Harmonization Code Object

{% stepper %}
{% step %}
On **Projects** page, click on the project that contains your data mappings and datasets to select it.
{% endstep %}

{% step %}
Select the **Code** option from the navigation menu on the left-hand side of the page.
{% endstep %}

{% step %}
Locate the code object for your syntactic mapping. It has the same name as the mapping and type **Data Harmonization**.

{% hint style="info" %}
A code object is *automatically generated* for each syntactic mapping created.&#x20;
{% endhint %}

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/MOloZ6WmkB9e8a6p71VP/23456568252701)
{% endstep %}

{% step %}
Select the **Run** button to the right of the code object to open the Run Settings page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/pC52AsmaOFsfkcLlAX1J/24099997741725)
{% endstep %}

{% step %}
Select the **Workgroup** on which you want to run the code object.
{% endstep %}

{% step %}
Select the **Input** datasets.

There should be one for each input data schema.&#x20;

An initial selection is already made for you, but you can change it by selecting the dataset dropdown menu and selecting a different dataset.&#x20;

If there are no datasets that match a given source data schema, the text "NO OPTIONS" will appear. In this case, please close this dialog, import a matching dataset (from the Datasets menu option on the left-hand side navigation menu), then try again.
{% endstep %}

{% step %}
Select the **Semantic Mappings**.

One for each vocabulary or OMOP domain referenced by the syntactic mapping in different transformations.&#x20;

An initial selection will already be made for you, but you can change it by clicking on the semantic mapping dropdown menu and selecting a different semantic mapping.&#x20;

If there are no semantic mappings that match a given target vocabulary or OMOP domain, the text "NO OPTIONS" will appear. In this case, please close this dialog, create a matching semantic mapping (from the Data Mappings -> Semantic Mappings page), then try again.
{% endstep %}

{% step %}
Click **Run** to start the code run.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ImC3wit5LNH3SUQRHjHB/23456594328477)
{% endstep %}

{% step %}
Click **Code Runs** from the menu on the left to see the code run entry.

You will see the status of the code run here.&#x20;

Click on the status of the code run to see a detailed log from the code run (only visible if you have the required permissions.
{% endstep %}

{% step %}
Once the code has finished running, you will see the **status** change to Completed if the run completed successfully or Error if there was any error.

If the run completed successfully, you will see the number of output datasets under the **Output Datasets** field.&#x20;

If there was an **Error**, click on the status to see the detailed logs with a description of the error encountered.
{% endstep %}
{% endstepper %}

## Troubleshooting

| Symptom                                   | Likely Cause                                               | Resolution                                                                                                |
| ----------------------------------------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| **NO OPTIONS** for input dataset          | No imported dataset matches the source schema              | Import a dataset with the correct schema from the Datasets page                                           |
| **NO OPTIONS** for semantic mapping       | No semantic mapping matches the required vocabulary/domain | Create and approve a semantic mapping for that vocabulary/domain                                          |
| Run status: **Error**                     | Configuration or data issue                                | Click the status to view detailed logs; review the error message for the affected field or transformation |
| Output dataset is empty                   | All rows failed transformation                             | Check error handling settings on transformations; review logs for per-row errors                          |
| Syntactic mapping is locked / cannot edit | The mapping was already run                                | Create a new version of the mapping — see \[\[Editing a Syntactic Mapping]]                               |


# What is a Code Object?

Explains what a code object is and the supported code object types on Rhino FCP.

## Code Objects Overview

In the Rhino FCP, a **Code Object** is the basic computational building block of a project. A Code Object can be as simple as a single line of Python code intended to run on a single input dataset, or as arbitrarily complex as a fully custom pipeline for federated training across multiple sites.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/y9Iwct0cjFwkc0cQyZvh/15533584393501)

***

## Example Use Cases

* **Data Transformation:** This is the most common use for Code Objects in the FCP—as a tool for pre-processing and harmonization of distributed datasets.
* **Federated Training:** Once your data is harmonized, you can use NVIDIA's FLARE framework to train ML *models* with federated training across the distributed data in your project.
* **Application of 3rd-Party software:** Open- *source* tools that can be containerized can be run securely on the FCP as a Code Object, which can be especially useful for very specific uses (e.g., image annotation with 3D Slicer or QuPath, direct interaction with data via Jupyter Notebook, and others).

**Note**: This capability requires permission to directly access case-level data. This is only possible for data belonging to your workgroup and Secure Access Lists shared with you by your collaborators.

***

## Code Object Types

When defining your Code Object, you will need to select a Code Object type based on the code you will be running:

* For running Python code, use the **Python Code** option ([See more details here](/creating-and-running-code-objects/creating-and-running-a-python-code-object)).
* For code that utilizes a pre-built container image with non-interactive code, use the **Generalized Compute** Code Object type ([See more details here](/creating-and-running-code-objects/creating-and-running-a-new-generalized-compute-code-object))
* To run a pre-built container image that provides an interactive interface, use the **Interactive Container** option ([See more details here](/creating-and-running-code-objects/creating-and-running-interactive-container-code)).
* For federated training, use the **NVIDIA FLARE** option ([See more details here](/creating-and-running-code-objects/creating-and-running-nvflare-code-and-running-inference)).
* If you have created semantic and syntactic mappings using FCP's Rhino Data Harmonization Engine feature, use the **Data Harmonization** option. ([See more details here](/data-harmonization/executing-the-transformation#running-a-data-harmonization-code-object)).

### <mark style="color:$info;">Python</mark> Code Objects

#### **Overview**

In Rhino Federated Computing Platform (FCP), Python Code Objects offer a powerful way to execute Python code scripts effortlessly, eliminating the need to locally containerize your code. Building and deploying code becomes a seamless process, with FCP handling container image creation and storage on your workgroup's ECR (Elastic Container Registry).

#### **Key Aspects and Advantages**

With Python Code Objects, FCP streamlines code deployment process, allowing you to concentrate on code development and analysis. Whether you're performing sophisticated data manipulations or running custom algorithms, Python Code Objects empower you to leverage the full capabilities of Python while benefiting from FCP's containerization and deployment efficiency.

#### **Summary**

Python Code Objects on FCP bring simplicity and power to your code development endeavors. By offering options for both code snippets and standalone files, FCP adapts to your needs, allowing you to focus on creating impactful software. Embrace the convenience of executing Python code directly within the platform, while FCP takes care of the intricate details of containerization, image creation, and deployment. Elevate your workflow and unlock new dimensions of development possibilities with Rhino FCP.

### <mark style="color:$info;">Generalized Compute</mark> Code Objects

In the Rhino Federated Computing Platform (FCP), the Generalized Compute (GC) Code Object represents a versatile and powerful way to execute pre-built container images within the FCP environment. This Code type enables you to run custom code, computations, or processes that are encapsulated within container images. With GC, you can harness the full potential of distributed computing while tailoring your computations to suit your specific needs.

#### **Key Aspects and Advantages**

* **Flexible Container Execution:** GC empowers you to execute container images containing diverse computational tasks, irrespective of programming language or complexity. This allows you to leverage existing tools, libraries, and applications within the FCP ecosystem.
* **Batch Processing:** Ideal for tasks that do not require real-time interactivity, GC excels at batch processing scenarios. You can execute computationally intensive tasks, data transformations, or complex analyses efficiently across distributed datasets.
* **Secure Data Access:** GC can only access data provided via the FCP, with no external internet connectivity. GC accesses input Datasets located under the `/input` directory and generates output Datasets under the `/output` directory. This ensures secure data access and maintains the privacy of sensitive healthcare information.

#### **Use Cases**

* **Data Transformation:** Execute data transformation and normalization tasks across distributed healthcare datasets.
* **Custom Analytics:** Run complex statistical analyses, machine learning processes, or custom algorithms on distributed data.
* **Scientific Simulations:** Perform large-scale scientific simulations or simulations requiring substantial computational resources.
* **Resource-Intensive Tasks:** Process resource-intensive tasks, such as image processing, signal analysis, or simulations.

Some benefits of Generalized Compute are:

* **Adaptability:** Leverage various programming languages and tools within your container, ensuring flexibility in your computational tasks.
* **Distributed Processing:** Distribute computation tasks across multiple sites, enhancing efficiency and reducing processing time.
* **Customization:** Craft computations tailored to your project's unique requirements, enhancing the depth of insights you can derive.

Generalized Compute empowers you to harness the versatility and power of containerized computations within the Rhino FCP. By executing custom code across distributed datasets, you can streamline tasks, gain valuable insights, and contribute to advanced healthcare research in a secure and privacy-preserving manner

### <mark style="color:$info;">NVFlare</mark> Code Objects

#### **Overview**

The FCP includes a seamless integration of [NVIDIA's Federated Learning framework (NVFlare)](https://developer.nvidia.com/flare), enabling you to train machine learning models collaboratively across distributed health data sources. This revolutionary approach brings privacy-preserving training to the forefront, allowing healthcare organizations to pool their insights without compromising the security of sensitive data.

#### **Key Aspects and Advantages**

* **Secure Distributed Training:** NVFlare empowers users to conduct Federated Training across a network of healthcare institutions, each contributing their data insights without sharing raw data. This distributed approach ensures that sensitive patient information remains secure behind institutional firewalls.
* **NVIDIA GPU Acceleration:** NVFlare taps into the computational prowess of NVIDIA GPUs, expediting model training and optimization. This acceleration is a game-changer, reducing training time and enhancing the accuracy of models trained on massive healthcare datasets.
* **Versatility Across ML Frameworks:** NVFlare's framework compatibility extends to major machine learning frameworks such as PyTorch and TensorFlow. Adapt your existing machine learning code to NVFlare, ensuring seamless integration into the Federated Learning ecosystem.

#### **Unlocking Secure Federated Training**

To harness the capabilities of NVFlare Code Objects within Rhino FCP, follow these steps:

* **Adaptation to NVFlare Framework:** Align your machine learning code with NVFlare's Federated Learning framework. This step ensures your models are primed to operate collaboratively across distributed data. (see our [Rhino "user resources" GitHub repository](https://github.com/RhinoHealth/user-resources) for examples)
* **Container Image Integration:** Build a container image that encapsulates your adapted NVFlare code, along with the required dependencies. These images are the vessels for efficient, privacy-preserving training across distributed health data.
* **ECR Repository Integration:** Push your container images to your workgroup's Elastic Container Registry (ECR) repository. This makes the NVFlare images available within the FCP ecosystem for execution via NVFlare Code Objects.
* **Create and Collaborate:** Access the Code Objects view within your project on the FCP Dashboard. Create an NVFlare Code Object, specifying your container image and configurations. Collaborate securely across institutions to train ML models and/or run model inference.
* **Elevate Federated Training:** Launch Federated Training using NVFlare Code Objects, and the FCP takes care of orchestrating the federated network and communication aspects. You can even simulate federated training using multiple datasets from your workgroup.

#### **Championing Secure Insights and Collaborative Progress**

NVFlare Code Objects redefine the paradigm of Federated Training, emphasizing secure and collaborative healthcare insights. By utilizing the power of NVIDIA GPUs and preserving data privacy, NVFlare empowers healthcare organizations to collaborate, innovate, and drive transformative advancements in predictive modeling.

#### **Summary**

NVFlare Code Objects within Rhino FCP signify a groundbreaking approach to Federated Training. Embrace the synergy of distributed health data, NVIDIA GPU acceleration, and Federated Learning framework compatibility to unlock secure, efficient, and impactful insights. Experience the future of collaborative healthcare research with NVFlare Objects, as you safeguard sensitive data while unlocking the full potential of Federated Training in the digital health landscape.

### <mark style="color:$info;">Interactive Container</mark> Code Objects

#### **Exploring Interactive Container Code**

In the realm of the Rhino Federated Computing Platform (FCP), Interactive Container Code opens the door to a unique dimension of computation. This Code Object type empowers you to run pre-built container images that include interactive graphical user interfaces (GUIs) or applications. With Interactive Containers, you can execute visualization and third-party tools including Jupyter Notebooks directly on your on-premises data, enhancing interactivity while preserving data security.

#### **Key Aspects and Advantages**

* **Interactive GUIs:** Unlike other Code Objects, Interactive Containers enable you to execute containers with interactive graphical user interfaces. This facilitates real-time interaction and data visualization within the FCP environment.
* **On-Premises Interaction:** Interactive Containers offer the capability to interact with on-premises data while leveraging the computational power of the FCP. This integration is particularly useful for scenarios where data remains within internal networks.
* **Third-Party Applications:** With Interactive Container Code Objects, you can run third-party applications that are containerized and can be executed within the FCP ecosystem, with no need to install them at each site.

{% hint style="info" %}
NOTE: This capability is limited to third-party applications that can run within a single Linux-based container with no internet connectivity.
{% endhint %}

#### **Use Cases**

* **Real-Time Data Exploration:** Utilize interactive visualizations and tools to explore and analyze on-premises healthcare data within the FCP ecosystem.
* **Third-Party Applications:** Run containerized third-party applications such as medical image annotation tools or specialized analysis software.
* **Collaborative Workshops:** Conduct collaborative workshops or training sessions that involve hands-on exercises and interactive activities.

#### **Benefits**

* **Interactive Experience:** Gain the ability to interact with GUIs and applications in real-time, fostering dynamic exploration of your data.
* **On-Premises Compatibility:** Execute containerized applications on your on-premises data while utilizing the computational resources of the FCP.
* **Secure Collaboration:** Enable secure collaboration by running third-party tools and applications within the FCP environment, ensuring data privacy.

#### **Summary**

Interactive Containers offer an innovative pathway to engage with interactive graphical interfaces and applications within the Rhino FCP. By merging on-premises data with containerized interactivity, you can delve deeper into data exploration, collaboration, and visualization while maintaining the highest levels of security and privacy.


# What is a Code Run?

A Code Run object encapsulates vital information pertaining to a specific run within the Rhino FCP. The Code Run provides relevant information about ongoing and terminated runs, providing a comprehensive view of the run's execution and outcomes.

### Key Aspects and Functions

{% stepper %}
{% step %}

#### Code Run Logs

One of the primary functions of the Code Run object is to provide seamless access to Code Run logs. These logs offer a detailed record of the run's execution at each relevant Rhino Client, facilitating troubleshooting, validation, and performance evaluation.
{% endstep %}

{% step %}

#### Input and Output Datasets

The Code Run object provides clear visibility into the input Datasets used for the run, as well as the naming conventions for the generated output Datasets. This transparency promotes effective traceability.
{% endstep %}

{% step %}

#### Runtime Insights

Access runtime information within the Code Run, including the time taken for the model to complete its execution. This insight aids in gauging performance and optimizing future runs.
{% endstep %}

{% step %}

#### Report Creation and Accessibility

Users have the flexibility to generate reports related to the model run and make them accessible via the *Code Runs* object. This feature aids in sharing insights and outcomes with collaborators or stakeholders.
{% endstep %}
{% endstepper %}

### Leveraging Code Runs for Insights and Collaboration

To make the most of Code Runs within the Rhino FCP, consider the following:

{% stepper %}
{% step %}

#### Comprehensive Analysis

Code Runs provide a holistic view of code executions, enabling you to analyze the effectiveness and outcomes of various runs.
{% endstep %}

{% step %}

#### Troubleshooting and Validation

Access Code Run logs to identify and address issues, ensuring the integrity and accuracy of your analyses.
{% endstep %}

{% step %}

#### Collaborative Sharing

Generate reports from the Code Run object to share insights with collaborators, enhancing collaborative research efforts.
{% endstep %}
{% endstepper %}

### About Usage Limits

Usage limits are placed on the number of input rows (inferences) a workgroup can process per model within a certain timeframe. This helps protect intellectual property by mitigating the risk of model weight reconstruction. Usage limits also control cloud costs by enabling sites to cap usage and control variable cloud costs associated with ad-hoc Code Runs that project collaborators could possibly trigger. All accrued usage counters reset to zero at 00:00 UT on the first day of every calendar month. Contact Rhino if you would like to enable this feature in your project.

### Practical Application

Imagine you've run complex federated training with the NVFlare Code Object. By accessing the Code Run object associated with this run, you can review the input Datasets, configuration details, and execution time and delve into the Code Run logs. This comprehensive understanding empowers you to make informed decisions, validate results, and optimize future model runs.

### Summary

Code Runs serve as the cornerstone of informed data analysis within the Rhino FCP. By encapsulating run configurations, runtime insights, logs, and reporting capabilities, the Code Run object empowers you to derive meaningful insights, troubleshoot effectively, and collaborate seamlessly with others. It's your gateway to unlocking the potential of your model executions.

### Key Components of a Code Run

**Attributes**

{% stepper %}
{% step %}

#### Name

The name of the relevant Code Object
{% endstep %}

{% step %}

#### Description (Optional)

The description of the Code Run
{% endstep %}

{% step %}

#### Type

The type of Code Object that has been run to produce the Code Run. In the case of NVFlare Code Runs, this will designate whether the Code Run row represents NVFlare Training (T) or NVFlare Validation (V).
{% endstep %}

{% step %}

#### Run Time (UTC)

The two timestamps for when the Code Run was started and ended in the UTC timezone
{% endstep %}

{% step %}

#### Status

The status of the Code Run, the value can be one of the following: Running, Complete: Success, Complete: Error, Halted: Success, Halted: Failure
{% endstep %}

{% step %}

#### Code Object Version

The version of the Code Object that was run to produce the Code Run
{% endstep %}

{% step %}

#### Input Datasets

A link to the Dataset Analytics view within the Datasets page showing all the input Datasets that were selected to run during the code's execution. If you hover over the link, you will see a list of the names of each input Dataset as well
{% endstep %}

{% step %}

#### Output Datasets

A link to the Dataset Analytics view within the Datasets page showing all the output Datasets that were selected to run during the code's execution. If you hover over the link, you will see a list of the names of each output Dataset as well
{% endstep %}

{% step %}

#### Report

A link to a report for the Code Run. Reports by default are blank and meant to be a playground for users to output performance metrics they are especially interested in. Reports are created using the Rhino SDK. For more information, refer to the workflow for creating and viewing a code run report.
{% endstep %}

{% step %}

#### Logs

The logs that were produced during the execution of the code. By default, the logs show stdout and stderr. If you are running code using a collaborator's Dataset, you might need to be granted special permissions to view the logs. They are extremely helpful for debugging.
{% endstep %}

{% step %}

#### UUID

The unique identifier for a specific Code Run within the Rhino FCP
{% endstep %}
{% endstepper %}


# Finding and Copying an Object's UID

To find and copy an object's UID, open the page for that object. If the object has versions, go to the version you want. Then open the three-dot menu for that row, as shown below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/9Wx9jAdCLsmzaVi3tRi5/13006603448989)

The menu is on the right side of the row. Select it, then choose **Copy UID**.

Projects and collaborators do not have versions. Open the object, then use the same three-dot menu to copy its UID.


# Creating and Running a Python Code Object

How to create, configure, run, and remove python code objects via the FCP UI.

{% hint style="info" %}
**NOTE**: To learn how to create a Python Code Object using the Rhino SDK, see [Creating a Python Code Object Using the Rhino SDK.](/rhino-sdk/creating-a-python-code-object-using-the-rhino-sdk)
{% endhint %}

## What is a Python Code Object?

In the Rhino Federated Computing Platform (FCP), **Python Code Objects** offer a powerful way to execute Python code scripts effortlessly, eliminating the need to locally containerize your code. Building and deploying code becomes a seamless process, with FCP handling container image creation and storage on your workgroup's **Elastic Container Registry** (ECR).

With Python Code Objects, FCP streamlines code deployment process, allowing you to concentrate on code development and analysis. Whether you're performing sophisticated data manipulations or running custom algorithms, Python Code Objects empower you to leverage the full capabilities of Python while benefiting from FCP's containerization and deployment efficiency.

Python Code Objects on FCP bring simplicity and power to your code development endeavors. By offering options for both code snippets and standalone files, FCP adapts to your needs, allowing you to focus on creating impactful software. Embrace the convenience of executing Python code directly within the platform, while FCP takes care of the intricate details of containerization, image creation, and deployment. Elevate your workflow and unlock new dimensions of development possibilities with Rhino FCP.

## Prerequisites

If your code will use external files, complete the following steps before you create your python code object.

Your workgroup has a unique cloud storage (an S3 bucket on Rhino Orchestrator) to upload non-sensitive data that might be needed during code run, e.g., open-source large LLM model weights.

{% hint style="warning" %}
Cloud storage (specified in *Workgroup code and model artifacts storage* section in the instructions that follow) is owned by Rhino. **Please DO NOT upload sensitive information such as proprietary datasets.** For sensitive data, please use the instructions in [Importing, Viewing a Dataset's Configuration, and Exporting Datasets](/datasets/registering-configuring-and-exporting-datasets) instead.
{% endhint %}

#### Overview

For your code to be able to access files while running in your agent we need do 4 steps:

#### Find the bucket to upload your files

{% stepper %}
{% step %}
In your project, select the settings button (it looks like a sprocket at the bottom left side of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/4u8WYSy0sa9q2HlrHo1O/34593373401629)
{% endstep %}

{% step %}
In the Settings menu, which is near the top of the screen on the left side of the window, select Containers & Artifacts.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/CdMN4MNmiJMWrQAzYeHs/34593373402397)
{% endstep %}

{% step %}
Your storage bucket and bucket prefix appear in the *Workgroup code and model artifacts storage* part of the page.
{% endstep %}
{% endstepper %}

#### Upload files to your designated bucket

AWS offers many alternative ways to upload files to an S3 bucket. We've also provided a script in our user\_resource repository you can use: [upload-file-to-s3.sh](https://github.com/RhinoHealth/user-resources/blob/main/rhino-utils/upload-file-to-s3.sh).

You need to define your S3 credentials and then you can call the script like this:

```bash
./upload-file-to-s3.sh the_folder_to_upload storage_bucket bucket_prefix your_path_in_bucket
```

For the example above, if you wanted to upload files in a local folder (called "local\_folder" in the below example) and store them in a folder in FCP called "my\_files", the command would be:

```bash
./upload-file-to-s3.sh ./local_folder external-files-rhino-health-dev my_files
```

#### Reference your files in your code

When creating your code object, you can reference your external files by referencing them in the following path:

```
/external_data/the_folder_in_s3_you_want_to_upload_to/filename
```

For the example above, assuming you uploaded `model_params.txt` file under `my_files`, the file would be accessible during runtime in

```
/external_data/my_files/model_params.txt
```

An example of Python code to read your file data into a `text` variable would look like as follows:

```python
from pathlib import Path
     text = Path('/external_data/my_files/model_params.txt').read_text()
```

#### Use your files in a specific run

Once your code points to your external files, and the code object is created, you can run the code and specify the files you want to use in your code run. In the UI, you can simply select them from a dropdown

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/JdWjzEPWJdU9VEuhOWNr/19768498689565)

Alternatively, you can also use the SDK. See this [notebook to use external files via SDK](https://github.com/RhinoHealth/user-resources/blob/main/examples/rhino-sdk/runtime_external_files.ipynb) for more details.

## Creating a Python Code Object

To create a new code object, follow these steps.

{% stepper %}
{% step %}
**Go to your project**

Go to the main project's page and select your project.
{% endstep %}

{% step %}
**Open the Code Objects page**

Select **Code** from the menu on the left to open the **Code Objects** page. To search for code objects, use the text boxes located at the top right corner of the page. To search by name enter the full name or part of the name in the Search Name text box. To search by description, enter part of the description in the Search Description text box.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/5FhCFgRwkAMta5xy1ogj/35166594879261)
{% endstep %}

{% step %}
**Create a new code object**

Select the **Create New Code Object** button to open the **Create New Code Object** page. You might need to scroll down to see the entire page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/n0Xvl8ECLEYt1zjHsWBz/32670380336669)
{% endstep %}

{% step %}
**Enter the code object details**

*Before you enter information in the fields (see table below), read the following about input and outputs*

*Multiple input and output datasets are supported in Python, Generalized, and Interactive Container Code Objects. While NVFlare Code Objects do not support multiple datasets, they can still be used as before for learning and inference across multiple sites.*

*Code objects usually require that you know the number of inputs and outputs your code needs. Those inputs and outputs are provided as data schemas. For example, if your code splits one dataset into two (like a train/test split), you will have to create a code object with one input schema and two output schemas. For more detail into how to structure your code to run on FCP, see* [*Accessing your datasets in Code Objects*](/creating-and-running-code-objects/accessing-your-datasets-in-code-objects)*.*

{% hint style="info" %}
**NOTE:** If you don't need this level of control, you can:

* Set any input or output as optional, which will allow to provide or generate no datasets respectively
* Set any input or output as a list, which will allow to select 1 or more datasets
* Select "ANY" as input schema, which will allow code object re-use across any input dataset schema.
* Let the system automatically determine the output schemas with [Auto-Generated Data Schemas](/data-schemas/auto-generated-data-schemas).
  {% endhint %}

Enter the following:

* Ensure that Python Code is selected as the **Code Object Type**.
* Enter **Details** about this code object, including the name you would like to provide for your code object and optionally, a description. The description that will help you and others understand the nature of this Code Object.
* Add the **inputs**, which are what the Data Schema(s) for the Datasets this Code Object will accept as input. Your selection here will affect which Datasets can be selected as input when triggering a Code Run with this Code Object.
* Enter the **outputs** for the Data Schema(s) for the Datasets that will be created as output when triggering a Code Run with this Code Object. You can also select the option to *\[Auto-generate Data Schema from Data]*. For more information about Auto-generating Data Schemas, please refer to [Auto-Generated Data Schemas](/data-schemas/auto-generated-data-schemas).
* Enter the **container details**. This is where you can specify parameters that will define your Code Object container:
  * Python and CUDA Versions, or conversely
  * Pre-existing Container Base Image (from Dockerhub). By default, the FCP will use the `python:3.9.7-slim-bullseye` docker image. This means your code will run within a Python 3.9 environment. You are free to select whichever docker base image makes the most sense for your use case (i.e. an image that supports GPU operations).
    {% endstep %}

{% step %}
**Provide your code**

Your code can be provided as a code snippet, standalone file, or an upload file. The information about each appears below.

* **Code Snippet** - Ideal for relatively straightforward scripts that primarily utilize basic Python packages, along with Pandas and Numpy. FCP automatically provides access to your cohort data as a Pandas Dataframe named **df.** Additionally, it generates the output cohort of your model from this same Dataframe. This setup facilitates elementary Pandas-based operations on your raw input data, such as feature extraction and value normalization.

  As an example, consider this Python code snippet:

  ```python
  normalized_df = (df-df.mean())/df.std()
  df = normalized_df
  ```

  Executing this code snippet yields an output cohort with z-normalized numerical features, all without requiring any additional code.
* **Standalone File** - This option grants you the freedom to execute varied Python code with custom dependencies, extending beyond Pandas and Numpy. The Standalone File option lets you specify your code's prerequisites, which will be automatically installed within the image generated by FCP. If your code necessitates a specific environment – for instance, to support GPU operations - you can define the Container Base Image that supports it. Use this option for more complex code, which can still be run as a single file. Unlike the ***Code Snippet***, no additional "hidden" functionality is included here.
* **Upload File(s)** - This option is similar to "Standalone File", but allows you to provide your code in more than one file, e.g., multiple Python files and/or shell scripts. Files can include non-Python files of any format, such as configuration files, model parameter files, and so forth. You just have to upload the files you need, or a folder(s), and select the entry point in the text box that appears when this option is selected. The entry point is the file that you'd like your container to run. Be sure to specify code requirements and the container environment as needed.

{% hint style="info" %}
NOTE: To see how you adapt your code to access your data, see [Accessing your datasets in Code Objects](/creating-and-running-code-objects/accessing-your-datasets-in-code-objects)
{% endhint %}
{% endstep %}

{% step %}
**Enter requirements**

Enter the requirements. This field enables you to specify Python libraries that are required to run your *code*. This capability is enabled for all Python Code types except for *Code Snippet* which has two locked dependencies—Pandas and NumPy. Paste all Python dependencies that are necessary for running your previously specified Python code. These dependencies will automatically be installed by the Rhino FCP when it builds your container in the background. Alternatively, click **Upload File** to load a requirements file from your local computer. The Rhino FCP supports both Pip and Conda as package management frameworks.
{% endstep %}

{% step %}
**Set compute resources if needed**

If you will be running your code object on the Google Cloud Platform (GCP) and you want to set minimum CPU, RAM, VRAM, and GPU resources, see [Autoscaling and Compute Resources](/creating-and-running-code-objects/autoscaling-and-compute-resources) for more information. If not, go to the next step.
{% endstep %}

{% step %}
**Finish**

When complete, click Create New Code Object or start a Code Run.
{% endstep %}
{% endstepper %}

## Viewing a Code Object's Configuration

To get an object's configuration, make sure you are on the page containing the original object you would like to view the configuration of. In the box where your original object is, there should be a row for each version. Navigate to the version you would like to view the configuration for and select the three-dot menu button, shown below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/BgQM5mGOLbhuUwL3JgI0/13002096256797)

The menu button is on the right-hand side of the row, click it to view a new menu. The new menu should have an option to show that object's configuration, click on that to see the object's configuration.

For Code Objects and Code Runs, if you chose the Use VM Pool option, you will use the pool that was indicated during the Code Object or Code Run configurations.  Selecting this option shows the resources, including the number of VMs and vCPUs that will be allocated, as well as the amount of RAM, the size of the disk, the number of GPUs, the GPU type/mode&#x6C;*,* and the amount of VRAM.

## Creating a New Version of a Python Code Object

To create a new version, complete the following steps.

1. Go to the page that has the original object you want to create a new version of.
2. In the upper right corner of the box where your original object is, select the **+ New Version** button.
3. A new window appears that allows you to create a new version of your object.

## Removing a Code Object

To remove a code object, complete the following steps.

{% stepper %}
{% step %}
**Open the Code Objects page**

Go to the page that lists your code objects.
{% endstep %}

{% step %}
**Find the code object version**

If needed, use the search fields at the top right.

* Use **Search Name** to search by code object name.
* Use **Search Description** to search by code object description.

Each code object appears with a row for each version. Find the version you want to delete.
{% endstep %}

{% step %}
**Open the menu for the version**

Select the three-dot menu on the right side of the version row, shown below.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/4DgRiNLSEzRn8aP9B9FL/13002670465821)
{% endstep %}

{% step %}
**Remove the code object version**

Select **Remove code object**.

Repeat these steps for each version you want to remove. When you delete the last version, the code object is fully deleted.
{% endstep %}
{% endstepper %}

## Running a Python Code Object

{% hint style="info" %}
NOTE: For information on how to run a Python Code Object using the Rhino SDK, see [Running a Python Code Object using the Rhino SDK.](/rhino-sdk/running-a-python-code-object-using-the-rhino-sdk)
{% endhint %}

After you've created a Python code object, complete the following steps to run it.

{% stepper %}
{% step %}
**Go to the main project's page**

Select your project.
{% endstep %}

{% step %}
**Open the Code Objects page**

Select **Code** from the menu on the left to open the **Code Objects** page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/GKTy355CXz83xhU34msh/35166650030493)
{% endstep %}

{% step %}
**Select the Run button**

Select the **Run** button for the code object you'd like to run. The Run Model Training page opens.
{% endstep %}

{% step %}
**Fill in the Code Run configuration fields**

Fill in the following fields within the new Code Run configuration window. These steps are the same for the Python Snippet, Standalone File, and Upload File(s) options:

* Enter the Input Dataset(s). This is one or more Datasets to be used as input to your Code Run. If multiple Datasets are selected, each will be run separately. If a Dataset happens to be a collaborator's Dataset, the code will be run on that collaborator's Rhino Client. In other words, the data never moves outside your collaborator's Rhino Client
* Enter the Output Dataset Name Suffix. A suffix that is appended onto the name of each input Dataset to define the name of the output Dataset that will be created during your Code Run
* Adjust the Timeout in Seconds if needed. This is the number of seconds that must elapse before a Code Run is automatically halted. This is to avoid zombie tasks that run perpetually within a Rhino client.
* Add Run Parameters (Optional). Here you can paste a JSON object that defines additional parameters to be provided to your Code Run. This can be used for specifying hyper-parameters for model validation or any parameter provided to the code. Run parameters are made available to the container code in a file located at `/input/run_params.json`

{% hint style="info" %}
Files that you want to run at run-time should be uploaded to the Rhino Orchestrator. See [Frequently Asked Questions (FAQs)](/frequently-asked-questions/frequently-asked-questions-faqs) for more details.
{% endhint %}

To add run time files to your code run, select the run time files from the list of the workgroup run files that appears. You will want to only include the ones you need for the code run, like in the example that follows.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/9UCMUvBGP59R0hzBRM8o/30678327447965)

*Selecting Run Time Files During Code Run Set Ups*

If you are part of a workgroup that has collaborators, you will be able to see files that are 1) in your active workgroup that are part of the project, whether they are published or not and 2) from a collaborator’s workgroup that are part of the project only *if they are published*.

To better understand this, let's take a look at the following scenario. **Project PRIME** is led by **workgroup Alpha**. **Workgroup Beta** has been added as a collaborator. Each workgroup has uploaded run time files.

* **If YOUR active workgroup is Alpha**, here is what you see when you open the Run Time Files screen in Project PRIME.
  * **All Workgroup Alpha's files are shown.** This is because Project PRIME is led by workgroup Alpha, so all of workgroup Alpha’s files that are part of the project are shown whether they are published or not.
  * **Only Workgroup Beta’s published files are shown.** Workgroup Beta’s files that are not part of the project or that are unpublished are not shown.
* **If YOUR active workgroup is Beta**, here is what happens when you open the Run Time Files screen in Project PRIME.
  * **Workgroup Beta's files are all shown.** This is because Beta members can see their own workgroup’s files that are part of the project, whether there are published or not.
  * **Only Workgroup Alpha’s files that have been published to PRIME are shown.** Workgroup Alpha’s unpublished files that are not part of the project are not shown.

{% hint style="info" %}
NOTE: See [Managing Run Time Files](/creating-and-running-code-objects/managing-run-time-files) to learn how to manage, publish and unpublish run time files.
{% endhint %}
{% endstep %}

{% step %}
**Run the code**

When you have completed adding all your Code Run details, either set the required compute resources by following the instruction in [Autoscaling and Compute Resources](/creating-and-running-code-objects/autoscaling-and-compute-resources), or click the **Run** button to run your code.
{% endstep %}
{% endstepper %}

## Reviewing Code Run Logs

Code run logs provide details about what happened during a run, as well as the outcome. &#x20;

To view these logs, complete the following steps.

{% stepper %}
{% step %}
**Select Code Run.**

In the Code Runs page, select the code run that you want to see logs for.  (If you cannot find the code run, enter the name, UID, or description of the code run in the boxes in the top right corner of the page.)

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FD5E5es8xp9I0KtrEzrJB%2FScreenshot%202026-09-17%20at%202.34.59%E2%80%AFPM.png?alt=media&amp;token=a020a9d3-9ade-4605-8a5b-689492ac729e" alt=""><figcaption></figcaption></figure>

The logs page for the Code Run is shown.  The start and finish time and date of the run, as well as the status of the run appears.  Logs can be accessed while the Code Run is active and after the Code Run has completed. While the code is running, an auto-refresh option is available. Details are shown under the details tab; reports (if any) are shown under the reports tab.  Reports are generated using the Rhino SDK.&#x20;
{% endstep %}

{% step %}
**Select the Details Tab.**

Select the Details tab if needed (it should be selected by default).

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FNllxhZsZ3389w7O8lMYr%2FScreenshot%202026-08-20%20at%2010.43.42%E2%80%AFAM.png?alt=media&amp;token=be89985c-7b2e-4bd3-afaa-08f409d41a2b" alt=""><figcaption></figcaption></figure>

The Details tab provides the following:

* General Info - information about the Code Run, including
  * Code Object name and type
  * Code Object version
  * Code Object description
  * Input and Output Datasets
  * Compute Resources Mode including the requested resources at run time (if applicable).&#x20;
  * Show Code Object Configuration button.  Click this button to see the code object configuration.\
    Show Code Run Configuration button.  Click this button to see the code run configuration.
  * View in TensorBoard button. Click this button to view results in TensorBoard.
* System Logs.  These can include errors or warnings that occurred from the FCP side, e.g. Dataset import errors.
* FL server logs (for NVIDIA FLARE runs)
* FL client logs (for NVIDIA FLARE runs)
  * Each federated client's logs will appear separately
* Client-specific logs (for all other run types).
  {% endstep %}
  {% endstepper %}

{% hint style="info" %}
The Reports tab is a workspace associated with the run where you can output performance metrics you care about. Reports are blank by default as they are created using the Rhino SDK. &#x20;
{% endhint %}

### Troubleshooting Code Runs

**Error Message that Usage Limit Has Been Exceeded**

If you get an error message indicating that the usage limit has been exceeded, your administrator has set usage limits on the number of input rows a workgroup can process per model within a certain timeframe. Getting this message means that the entire run has been cancelled. Please contact your administrator for more details and help with resolving the issue.

## Viewing a Code Run's Configuration

To get an object's configuration, make sure you are on the page containing the original object you would like to view the configuration of. In the box where your original object is, there should be a row for each version. Navigate to the version you would like to view the configuration for and select the three-dot menu button, shown below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/BgQM5mGOLbhuUwL3JgI0/13002096256797)

The menu button is on the right-hand side of the row, click it to view a new menu. The new menu should have an option to show that object's configuration, click on that to see the object's configuration.

For Code Objects and Code Runs, if you chose the Use VM Pool option, you will use the pool that was indicated during the Code Object or Code Run configurations.  Selecting this option shows the resources, including the number of VMs and vCPUs that will be allocated, as well as the amount of RAM, the size of the disk, the number of GPUs, the GPU type/mode&#x6C;*,* and the amount of VRAM.

## Deleting a Code Run

Follow these steps to delete a code run.

{% stepper %}
{% step %}
**Open the Code Runs page**

Go to the page that lists your code runs.
{% endstep %}

{% step %}
**Find the code run**

If needed, use the search fields at the top right.

* Use **Search Name, UID** to search by code run name or the UID.
* Use **Search Description** to search by code run description.

Find the code run you want to delete.
{% endstep %}

{% step %}
**Open the menu for the code run**

Select the three-dot menu on the right side of the row, shown below.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/2zj9RDThMEzCyZ4nwExT/13002586504093)
{% endstep %}

{% step %}
**Remove the code run**

Select **Remove code run**.
{% endstep %}
{% endstepper %}


# Using a Python Code Snippet or Standalone File

* **Code Snippet** - Ideal for relatively straightforward scripts that primarily utilize basic Python packages, along with Pandas and Numpy. FCP automatically provides access to your cohort data as a Pandas Dataframe named **df.** Additionally, it generates the output cohort of your model from this same Dataframe. This setup facilitates elementary Pandas-based operations on your raw input data, such as feature extraction and value normalization.

As an example, consider this Python code snippet:

```python
normalized_df = (df-df.mean())/df.std()
df = normalized_df
```

Executing this code snippet yields an output cohort with z-normalized numerical features, all without requiring any additional code.

* **Standalone File** - This option grants you the freedom to execute varied Python code with custom dependencies, extending beyond Pandas and Numpy. The Standalone File option lets you specify your code's prerequisites, which will be automatically installed within the image generated by FCP. If your code necessitates a specific environment – for instance, to support GPU operations - you can define the Container Base Image that supports it. Use this option for more complex code, which can still be run as a single file. Unlike the ***Code Snippet***, no additional "hidden" functionality is included here.
* **Upload File(s)** - This option is similar to "Standalone File", but allows you to provide your code in more than one file, e.g., multiple Python files and/or shell scripts. Files can include non-Python files of any format, such as configuration files, model parameter files, and so forth. You just have to upload the files you need, or a folder(s), and select the entry point in the text box that appears when this option is selected. The entry point is the file that you'd like your container to run. Be sure to specify code requirements and the container environment as needed.


# Creating and Running a New Generalized Compute Code Object

Explains what a generalized compute code object is, how to create and run it, and how to adapt your code to run as a generalized code object.

## What is a Generalized Compute Code Object?

In the Rhino Federated Computing Platform (FCP), the Generalized Compute (GC) Code Object represents a versatile and powerful way to execute pre-built container images within the FCP environment. This Code type enables you to run custom code, computations, or processes that are encapsulated within container images. With GC, you can harness the full potential of distributed computing while tailoring your computations to suit your specific needs.

**Key Features of Generalized Compute**

* **Flexible Container Execution:** GC empowers you to execute container images containing diverse computational tasks, irrespective of programming language or complexity. This allows you to leverage existing tools, libraries, and applications within the FCP ecosystem.
* **Batch Processing:** Ideal for tasks that do not require real-time interactivity, GC excels at batch processing scenarios. You can execute computationally intensive tasks, data transformations, or complex analyses efficiently across distributed datasets.
* **Secure Data Access:** GC can only access data provided via the FCP, with no external internet connectivity. GC accesses input Datasets located under the `/input` directory and generates output Datasets under the `/output` directory. This ensures secure data access and maintains the privacy of sensitive healthcare information.

**Use Cases for Generalized Compute**

* **Data Transformation:** Execute data transformation and normalization tasks across distributed healthcare datasets.
* **Custom Analytics:** Run complex statistical analyses, machine learning processes, or custom algorithms on distributed data.
* **Scientific Simulations:** Perform large-scale scientific simulations or simulations requiring substantial computational resources.
* **Resource-Intensive Tasks:** Process resource-intensive tasks, such as image processing, signal analysis, or simulations.

**Benefits of Generalized Compute**

* **Adaptability:** Leverage various programming languages and tools within your container, ensuring flexibility in your computational tasks.
* **Distributed Processing:** Distribute computation tasks across multiple sites, enhancing efficiency and reducing processing time.
* **Customization:** Craft computations tailored to your project's unique requirements, enhancing the depth of insights you can derive.

In summary, Generalized Compute empowers you to harness the versatility and power of containerized computations within the Rhino FCP. By executing custom code across distributed datasets, you can streamline tasks, gain valuable insights, and contribute to advanced healthcare research in a secure and privacy-preserving manner

{% hint style="info" %}
If your dataset contains sensitive data, then by default, all output datasets are considered to be sensitive. For more information on this, including how to mark which data is sensitive and which is not, please see [Sensitive Datasets](/datasets/sensitive-datasets).
{% endhint %}

In the Rhino Federated Computing Platform (FCP), the Generalized Compute (GC) Code Object represents a versatile and powerful way to execute pre-built container images within the FCP environment. This Code type enables you to run custom code, computations, or processes that are encapsulated within container images. With GC, you can harness the full potential of distributed computing while tailoring your computations to suit your specific needs.

**Key Features of Generalized Compute**

* **Flexible Container Execution:** GC empowers you to execute container images containing diverse computational tasks, irrespective of programming language or complexity. This allows you to leverage existing tools, libraries, and applications within the FCP ecosystem.
* **Batch Processing:** Ideal for tasks that do not require real-time interactivity, GC excels at batch processing scenarios. You can execute computationally intensive tasks, data transformations, or complex analyses efficiently across distributed datasets.
* **Secure Data Access:** GC can only access data provided via the FCP, with no external internet connectivity. GC accesses input Datasets located under the `/input` directory and generates output Datasets under the `/output` directory. This ensures secure data access and maintains the privacy of sensitive healthcare information.

**Use Cases for Generalized Compute**

* **Data Transformation:** Execute data transformation and normalization tasks across distributed healthcare datasets.
* **Custom Analytics:** Run complex statistical analyses, machine learning processes, or custom algorithms on distributed data.
* **Scientific Simulations:** Perform large-scale scientific simulations or simulations requiring substantial computational resources.
* **Resource-Intensive Tasks:** Process resource-intensive tasks, such as image processing, signal analysis, or simulations.

**Benefits of Generalized Compute**

* **Adaptability:** Leverage various programming languages and tools within your container, ensuring flexibility in your computational tasks.
* **Distributed Processing:** Distribute computation tasks across multiple sites, enhancing efficiency and reducing processing time.
* **Customization:** Craft computations tailored to your project's unique requirements, enhancing the depth of insights you can derive.

In summary, Generalized Compute empowers you to harness the versatility and power of containerized computations within the Rhino FCP. By executing custom code across distributed datasets, you can streamline tasks, gain valuable insights, and contribute to advanced healthcare research in a secure and privacy-preserving manner.

## Prerequisites

If your code will use external files, complete the following steps before you create your python code object.

Your workgroup has a unique cloud storage (an S3 bucket on Rhino Orchestrator) to upload non-sensitive data that might be needed during code run, e.g., open-source large LLM model weights.

{% hint style="warning" %}
Cloud storage (specified in *Workgroup code and model artifacts storage* section in the instructions that follow) is owned by Rhino. **Please DO NOT upload sensitive information such as proprietary datasets.** For sensitive data, please use the instructions in [Importing, Viewing a Dataset's Configuration, and Exporting Datasets](/datasets/registering-configuring-and-exporting-datasets) instead.
{% endhint %}

#### Overview

For your code to be able to access files while running in your agent we need do 4 steps:

#### Find the bucket to upload your files

{% stepper %}
{% step %}
In your project, select the settings button (it looks like a sprocket at the bottom left side of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/4u8WYSy0sa9q2HlrHo1O/34593373401629)
{% endstep %}

{% step %}
In the Settings menu, which is near the top of the screen on the left side of the window, select Containers & Artifacts.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/CdMN4MNmiJMWrQAzYeHs/34593373402397)
{% endstep %}

{% step %}
Your storage bucket and bucket prefix appear in the *Workgroup code and model artifacts storage* part of the page.
{% endstep %}
{% endstepper %}

#### Upload files to your designated bucket

AWS offers many alternative ways to upload files to an S3 bucket. We've also provided a script in our user\_resource repository you can use: [upload-file-to-s3.sh](https://github.com/RhinoHealth/user-resources/blob/main/rhino-utils/upload-file-to-s3.sh).

You need to define your S3 credentials and then you can call the script like this:

```bash
./upload-file-to-s3.sh the_folder_to_upload storage_bucket bucket_prefix your_path_in_bucket
```

For the example above, if you wanted to upload files in a local folder (called "local\_folder" in the below example) and store them in a folder in FCP called "my\_files", the command would be:

```bash
./upload-file-to-s3.sh ./local_folder external-files-rhino-health-dev my_files
```

#### Reference your files in your code

When creating your code object, you can reference your external files by referencing them in the following path:

```
/external_data/the_folder_in_s3_you_want_to_upload_to/filename
```

For the example above, assuming you uploaded `model_params.txt` file under `my_files`, the file would be accessible during runtime in

```
/external_data/my_files/model_params.txt
```

An example of Python code to read your file data into a `text` variable would look like as follows:

```python
from pathlib import Path
     text = Path('/external_data/my_files/model_params.txt').read_text()
```

#### Use your files in a specific run

Once your code points to your external files, and the code object is created, you can run the code and specify the files you want to use in your code run. In the UI, you can simply select them from a dropdown

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/JdWjzEPWJdU9VEuhOWNr/19768498689565)

Alternatively, you can also use the SDK. See this [notebook to use external files via SDK](https://github.com/RhinoHealth/user-resources/blob/main/examples/rhino-sdk/runtime_external_files.ipynb) for more details.

## Creating a New Generalized Compute Code Object

{% hint style="info" %}
If you want to create a new Generalized Compute Code Object using the SDK, see [Creating a Generalized Compute Code Object Using the Rhino SDK.](/rhino-sdk/running-a-generalized-compute-code-object-using-the-rhino-sdk/creating-a-generalized-compute-code-object-using-the-rhino-sdk)
{% endhint %}

Follow these steps to use the UI to create a new Generalized Compute Code Object.

{% stepper %}
{% step %}
**Go to the main project's page and select your project.**
{% endstep %}

{% step %}
**Select Code from the menu on the left to open the Code Objects page.**

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/HmRBoFlCfbsuQN32sD53/24602667716765)
{% endstep %}

{% step %}
**Select the Create New Code Object button to open the Create New Code Object page.**

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/As8V57OFZnBoPIIgBW0h/24602646430877)
{% endstep %}

{% step %}
**Select Generalized Compute as the Code Object Type.**

The page changes to show the fields needed for this object type.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/d3WoyWCr7E7ohM8Xwop2/24602667717661)
{% endstep %}

{% step %}
**Enter information in the following fields.**

*Before you enter information in the fields (see table below), read the following about input and outputs*

*Multiple input and output datasets are supported in Python, Generalized, and Interactive Container Code Objects. While NVFlare Code Objects do not support multiple datasets, they can still be used as before for learning and inference across multiple sites.*

*Code objects usually require that you know the number of inputs and outputs your code needs. Those inputs and outputs are provided as data schemas. For example, if your code splits one dataset into two (like a train/test split), you will have to create a code object with one input schema and two output schemas. For more detail into how to structure your code to run on FCP, see* [*Accessing your datasets in Code Objects*](/creating-and-running-code-objects/accessing-your-datasets-in-code-objects)*.*

{% hint style="info" %}
**NOTE:** If you don't need this level of control, you can:

* Set any input or output as optional, which will allow to provide or generate no datasets respectively
* Set any input or output as a list, which will allow to select 1 or more datasets
* Select "ANY" as input schema, which will allow code object re-use across any input dataset schema.
* Let the system automatically determine the output schemas with [Auto-Generated Data Schemas](/data-schemas/auto-generated-data-schemas).
  {% endhint %}

Enter your information in the following fields.

| Field/Button                           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Name                                   | Indicates the name you want to provide for the code object.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Description                            | Provides a brief summary of what the code object does.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| Input (including three-dot menu items) | <p>Indicates the file(s) needed for the code object to run properly. Your selection here will affect which Dataset(s) can be selected as input when triggering a Code Run with this Code Object You can enter one or more input files, such as schemas, configuration files, or others. File(s) can be in DICOM, JSON, and or text formats.<br>- If your input doesn't require a schema, select Any.<br>- Select the Add button to the right of the input entry to add another input. You can add as many as you like.<br>- If your input includes more than a single dataset, select the three dot menu to the right of the Input field, then select Input is a list.<br>- If the input is optional, select the three-dot menu to the right of the Input field, then select Optional Input.</p>                                                                |
| Output                                 | <p>Indicates the output file(s) produced when the code object run. You can enter one or more output files. Files can be in DICOM, JSON, and or text formats.<br>- You can also select the option to <em>\[</em> <em>Auto-generate Data Schema from Data</em> <em>]</em>. For more information about Auto-generating Data S <em>chema</em> s, please refer to <a href="/data-schemas/auto-generated-data-schemas">Auto-Generated Data <em>Schema</em> s</a>.<br>- Select the Add button to the right of the output entry to add another output. You can add as many as you like.<br>- If your output includes more than a single dataset, select the three dot menu to the right of the Output field, then select Output is a list.<br>- If the output is optional, select the three-dot menu to the right of the Output field, then select Optional Output.</p> |
| Container                              | Specifies the name of the Docker container you would like to execute when running this Code Object. This will either be a container image created by someone from your workgroup that is available on your ECR or an image provided by Rhino. If you need a refresher on pushing containers to your ECR, please refer to [Pushing Containers to the ECR](/getting-started/quick-start-guide/pushing-containers-to-the-ecr).                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| {% endstep %}                          |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |

{% step %}
**After you've completed your details, you can choose to set required compute resources.**

If you want to do this, see [Autoscaling and Compute Resources](/creating-and-running-code-objects/autoscaling-and-compute-resources) for more information.
{% endstep %}

{% step %}
**When complete, select the Create New Code button to create the new Code Object.**
{% endstep %}

{% step %}
**The code object appears on the Code Object page.**
{% endstep %}
{% endstepper %}

## Viewing a Code Object's Configuration

To get an object's configuration, make sure you are on the page containing the original object you would like to view the configuration of. In the box where your original object is, there should be a row for each version. Navigate to the version you would like to view the configuration for and select the three-dot menu button, shown below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/BgQM5mGOLbhuUwL3JgI0/13002096256797)

The menu button is on the right-hand side of the row, click it to view a new menu. The new menu should have an option to show that object's configuration, click on that to see the object's configuration.

For Code Objects and Code Runs, if you chose the Use VM Pool option, you will use the pool that was indicated during the Code Object or Code Run configurations.  Selecting this option shows the resources, including the number of VMs and vCPUs that will be allocated, as well as the amount of RAM, the size of the disk, the number of GPUs, the GPU type/mode&#x6C;*,* and the amount of VRAM.

## Creating a New Generalized Compute Code Object Version

To create a new version, complete the following steps.

{% stepper %}
{% step %}
**Go to the page for the original object you want to version.**
{% endstep %}

{% step %}
**In the upper right corner of the box where your original object is, select the + New Version button.**
{% endstep %}

{% step %}
**A new window appears that allows you to create a new version of your object.**
{% endstep %}
{% endstepper %}

## Removing a Code Object

To remove a code object, complete the following steps.

{% stepper %}
{% step %}
**Open the Code Objects page**

Go to the page that lists your code objects.
{% endstep %}

{% step %}
**Find the code object version**

If needed, use the search fields at the top right.

* Use **Search Name** to search by code object name.
* Use **Search Description** to search by code object description.

Each code object appears with a row for each version. Find the version you want to delete.
{% endstep %}

{% step %}
**Open the menu for the version**

Select the three-dot menu on the right side of the version row, shown below.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/4DgRiNLSEzRn8aP9B9FL/13002670465821)
{% endstep %}

{% step %}
**Remove the code object version**

Select **Remove code object**.

Repeat these steps for each version you want to remove. When you delete the last version, the code object is fully deleted.
{% endstep %}
{% endstepper %}

## Running a Generalized Compute Code Object

{% hint style="info" %}
Note: To learn how to use the Rhino SDK to run a generalized compute code object see [Running a Generalized Compute Code Object using the Rhino SDK.](/rhino-sdk/running-a-generalized-compute-code-object-using-the-rhino-sdk)
{% endhint %}

Create a Generalized Compute code object before you complete these steps.

{% stepper %}
{% step %}
**Go to your project and open Code Objects.**

Go to the main project's page and select your project.

Select **Code** from the menu on the left to open the **Code Objects** page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/WDDdPpCJ0KfTl4q06Czl/35166644457757)
{% endstep %}

{% step %}
**Select the code object to run.**

Select the Run button for the code object you'd like to run.
{% endstep %}

{% step %}
**Review the Run Settings page.**

In the Run Settings page, do the following.
{% endstep %}

{% step %}
**Fill in the Code Run fields.**

Fill in the following fields using the table below for reference.

<table><thead><tr><th width="238">Field</th><th>Description</th></tr></thead><tbody><tr><td><strong>Input Dataset(s)</strong></td><td>One or more Datasets to be used as input to your Code Run. If multiple Datasets are selected, each will be run separately. If a Dataset happens to be a collaborator's Dataset, the code will be run on that collaborator's Rhino Client. In other words, the data never moves outside your collaborator's Rhino Client.</td></tr><tr><td><strong>Output Dataset Name Suffix</strong></td><td>A suffix that is appended onto the name of each input Dataset to define the name of the output Dataset that will be created during your Code Run.</td></tr><tr><td><strong>Timeout in Seconds</strong></td><td>The number of seconds that must elapse before a Code Run is automatically halted. This is to avoid zombie tasks that run perpetually within a Rhino client.</td></tr><tr><td><strong>Run Parameters (Optional)</strong></td><td>Here you can paste a JSON object that defines additional parameters to be provided to your Code Run. This can be used for specifying hyper-parameters for <em>model</em> validation or any parameter provided to the code. <em>Run parameter</em> s are made available to the container code in a file located at <code>/input/run_params.json</code></td></tr></tbody></table>

{% hint style="info" %}
NOTE: Files that you want to run at run-time should be uploaded to the Rhino Orchestrator.
{% endhint %}

* To add run time files to your code run, select the run time files from the list of the workgroup run files that appears. You will want to only include the ones you need for the code run, like in the example that follows.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/vXi0bGK3uzTuhlGqWdIE/34176131109917)

*Selecting Run Time Files During Code Run Set Ups*

If you are part of a workgroup that has collaborators, you will be able to see files that are 1) in your active workgroup that are part of the project, whether they are published or not and 2) from a collaborator’s workgroup that are part of the project only *if they are published*.

To better understand this, let's take a look at the following scenario. **Project PRIME** is led by **workgroup Alpha**. **Workgroup Beta** has been added as a collaborator. Each workgroup has uploaded run time files.

* **If YOUR active workgroup is Alpha**, here is what you see when you open the Run Time Files screen in Project PRIME.
  * **All Workgroup Alpha's files are shown.** This is because Project PRIME is led by workgroup Alpha, so all of workgroup Alpha’s files that are part of the project are shown whether they are published or not.
  * **Only Workgroup Beta’s published files are shown.** Workgroup Beta’s files that are not part of the project or that are unpublished are not shown.
* **If YOUR active workgroup is Beta**, here is what happens when you open the Run Time Files screen in Project PRIME.
  * **Workgroup Beta's files are all shown.** This is because Beta members can see their own workgroup’s files that are part of the project, whether there are published or not.
  * **Only Workgroup Alpha’s files that have been published to PRIME are shown.** Workgroup Alpha’s unpublished files that are not part of the project are not shown.

{% hint style="info" %}
NOTE: See [Managing Run Time Files](/creating-and-running-code-objects/managing-run-time-files) to learn how to manage, publish and unpublish run time files.
{% endhint %}
{% endstep %}

{% step %}
**Set the required compute resources (if needed).**

When you have completed adding all your Code Run details, either set the required compute resources by following the instruction in [Autoscaling and Compute Resources](/creating-and-running-code-objects/autoscaling-and-compute-resources), or click the **Run** button to run your code.
{% endstep %}
{% endstepper %}

## Reviewing Code Run Logs

Code run logs provide details about what happened during a run, as well as the outcome. &#x20;

To view these logs, complete the following steps.

{% stepper %}
{% step %}
**Select Code Run.**

In the Code Runs page, select the code run that you want to see logs for.  (If you cannot find the code run, enter the name, UID, or description of the code run in the boxes in the top right corner of the page.)

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FD5E5es8xp9I0KtrEzrJB%2FScreenshot%202026-09-17%20at%202.34.59%E2%80%AFPM.png?alt=media&amp;token=a020a9d3-9ade-4605-8a5b-689492ac729e" alt=""><figcaption></figcaption></figure>

The logs page for the Code Run is shown.  The start and finish time and date of the run, as well as the status of the run appears.  Logs can be accessed while the Code Run is active and after the Code Run has completed. While the code is running, an auto-refresh option is available. Details are shown under the details tab; reports (if any) are shown under the reports tab.  Reports are generated using the Rhino SDK.&#x20;
{% endstep %}

{% step %}
**Select the Details Tab.**

Select the Details tab if needed (it should be selected by default).

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FNllxhZsZ3389w7O8lMYr%2FScreenshot%202026-08-20%20at%2010.43.42%E2%80%AFAM.png?alt=media&amp;token=be89985c-7b2e-4bd3-afaa-08f409d41a2b" alt=""><figcaption></figcaption></figure>

The Details tab provides the following:

* General Info - information about the Code Run, including
  * Code Object name and type
  * Code Object version
  * Code Object description
  * Input and Output Datasets
  * Compute Resources Mode including the requested resources at run time (if applicable).&#x20;
  * Show Code Object Configuration button.  Click this button to see the code object configuration.\
    Show Code Run Configuration button.  Click this button to see the code run configuration.
  * View in TensorBoard button. Click this button to view results in TensorBoard.
* System Logs.  These can include errors or warnings that occurred from the FCP side, e.g. Dataset import errors.
* FL server logs (for NVIDIA FLARE runs)
* FL client logs (for NVIDIA FLARE runs)
  * Each federated client's logs will appear separately
* Client-specific logs (for all other run types).
  {% endstep %}
  {% endstepper %}

{% hint style="info" %}
The Reports tab is a workspace associated with the run where you can output performance metrics you care about. Reports are blank by default as they are created using the Rhino SDK. &#x20;
{% endhint %}

### Troubleshooting Code Runs

**Error Message that Usage Limit Has Been Exceeded**

If you get an error message indicating that the usage limit has been exceeded, your administrator has set usage limits on the number of input rows a workgroup can process per model within a certain timeframe. Getting this message means that the entire run has been cancelled. Please contact your administrator for more details and help with resolving the issue.

## Viewing a Code Run's Configuration

To get an object's configuration, make sure you are on the page containing the original object you would like to view the configuration of. In the box where your original object is, there should be a row for each version. Navigate to the version you would like to view the configuration for and select the three-dot menu button, shown below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/BgQM5mGOLbhuUwL3JgI0/13002096256797)

The menu button is on the right-hand side of the row, click it to view a new menu. The new menu should have an option to show that object's configuration, click on that to see the object's configuration.

For Code Objects and Code Runs, if you chose the Use VM Pool option, you will use the pool that was indicated during the Code Object or Code Run configurations.  Selecting this option shows the resources, including the number of VMs and vCPUs that will be allocated, as well as the amount of RAM, the size of the disk, the number of GPUs, the GPU type/mode&#x6C;*,* and the amount of VRAM.

## Deleting a Code Run

Follow these steps to delete a code run.

{% stepper %}
{% step %}
**Open the Code Runs page**

Go to the page that lists your code runs.
{% endstep %}

{% step %}
**Find the code run**

If needed, use the search fields at the top right.

* Use **Search Name, UID** to search by code run name or the UID.
* Use **Search Description** to search by code run description.

Find the code run you want to delete.
{% endstep %}

{% step %}
**Open the menu for the code run**

Select the three-dot menu on the right side of the row, shown below.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/2zj9RDThMEzCyZ4nwExT/13002586504093)
{% endstep %}

{% step %}
**Remove the code run**

Select **Remove code run**.
{% endstep %}
{% endstepper %}

## Adapting your code to run as a Generalized Code Object

For your code to successfully run on the FCP do the following things.

**Modify Where You Are Reading and Writing From in Your Code**

{% stepper %}
{% step %}
**All inputs should be read from the `/input` folder.**

Datasets will be zero-indexed within the `/input` folder (i.e. Input Dataset 1 - `/input/0/`, Input Dataset 2 - `/input/1/`, etc.)

* For Tabular Data: `/input/0/dataset.csv`. If you would like to work with the data as a Pandas DataFrame you can load the Dataset using the following example:

```python
df = pd.read_csv(“/input/0/dataset.csv”)
```

* For file data (data that has been defined in the Data Schema as type Filename): If there is any file data associated with the Dataset, it will be under the `/input/file_data/` directory, structured in the same subdirectory structure as was specified when importing the Dataset. Example:

`/input/0/file_data/`

* For DICOM data (data that has been defined in the Data Schema as type DicomStudyUID, DicomSeriesUID, or DicomInstanceUID.): If there is any DICOM data associated with the Dataset, it will be under the `/input/dicom_data/` directory, structured in the same subdirectory structure as was specified when importing the Dataset. Example:

`/input/0/dicom_data/`
{% endstep %}

{% step %}
**All output should be written to the `/output` mount.**

* For Tabular Data: `/output/0/dataset.csv`. To write your data as a Pandas DataFrame you can use the following example:

```python
df.to_csv(“/output/0/dataset.csv”, index=False)
```

* For file data: `/output/0/file_data/`
* For DICOM data: `/output/0/dicom_data/`
  {% endstep %}
  {% endstepper %}

**\[If applicable] Modify where you are reading your runtime parameters**

Any run parameters that have been specified shall be in a file named `/input/run_params.json`

**Create the Dockerfile**

Create a Dockerfile with the configuration necessary for your code. You may use the example provided in the user-resources github repository as a template and make changes as needed where there are comments beginning with **"# !! EDIT THIS:"**

**Ensure any files that might be downloaded at runtime are pre-downloaded and copied to the container in the Dockerfile**

Copy files that might need to be downloaded at runtime as pre-downloaded copy statements within the Dockerfile

**Optional recommendations**

We recommend that you build and test your container locally. There is a utility script called `docker-run.sh` in the `gc-docker-utils` folder to assist with this. It can be used by running:

```bash
./docker-run.sh path/to/input path/to/output
```


# Creating and Running NVFlare Code and Running Inference

Create NVFlare code objects and run them in Rhino FCP.  Inference is also addressed.

{% hint style="info" %}
To create and run NVFlare code using the Rhino SDK, see [Creating a New NVFlare Code Object Using the Rhino SDK](/rhino-sdk/creating-a-new-nvflare-code-object-using-the-rhino-sdk) and [Running NVFlare Code using the Rhino SDK](/rhino-sdk/running-nvflare-code-using-the-rhino-sdk).
{% endhint %}

## What is an NVFlare Code Object?

An NVFlare code object packages your NVFlare-ready application as a container image and makes it runnable in Rhino FCP.

NVFlare, short for NVIDIA Federated Learning Application Runtime Environment, is a groundbreaking software solution designed to revolutionize the world of federated machine learning. Built as an open-source and versatile SDK, NVFlare empowers researchers, data scientists, and platform developers to seamlessly transition their machine learning and deep learning workflows into the federated paradigm.

Use an NVFlare code object when you want to:

* Train a model across multiple institutions.
* Keep source data behind each institution's firewall.
* Reuse existing ML code with minimal changes.

### Key Features and Components

The FCP includes a seamless integration of [NVIDIA's Federated Learning framework (NVFlare)](https://developer.nvidia.com/flare), enabling you to train machine learning models collaboratively across distributed health data sources. This approach allows healthcare organizations to pool insights without compromising the security of sensitive data.

NVFlare's strength lies in its comprehensive features and components that enable efficient and secure federated learning:

* **Adapt Existing Workflows:** NVFlare allows you to adapt traditional machine learning and deep learning workflows, such as PyTorch, TensorFlow, Scikit-learn, XGBoost, and more, into a federated paradigm.
* **Componentized Architecture:** Built upon a componentized architecture, NVFlare provides flexibility from research and simulation to real-world deployment.
* **Federated Learning Algorithms:** NVFlare integrates key federated algorithms like FedAvg, FedProx, FedOpt, Scaffold, and Ditto.
* **Customizable Workflows:** With support for horizontal and vertical federated learning, NVFlare caters to a range of use cases.
* **Privacy Preservation:** NVFlare prioritizes data privacy through differential privacy and homomorphic encryption.
* **Secure Management:** NVFlare offers tools for secure provisioning, orchestration, and management.
* **Extensibility and Customization:** NVFlare's specification-based APIs allow researchers and developers to extend and customize the platform according to specific needs.

### Design Principles

NVFlare is built upon several core design principles:

* **Simplicity:** NVFlare adheres to a "less is more" approach, focusing on essential components and enabling others to customize and extend the platform.
* **Specification-Based:** Every component and API in NVFlare is specification-based, allowing alternative implementations to be developed by following the specifications.
* **Real-World Focus:** The platform is designed to address real-world challenges, with the ability to handle unexpected events and misbehaving code gracefully.
* **General Purpose:** NVFlare's general-purpose design ensures it's versatile and adaptable, catering to various federated computing use cases.
* **Client-Friendly:** NVFlare is built to be client-system-friendly, running with minimal environmental dependencies and integration interference.

### NVFlare Code Objects in Rhino FCP

An NVFlare Code Object is the way you package and run NVFlare-based workloads in Rhino FCP. It lets you execute federated training across a network of healthcare institutions, with each site contributing data insights without sharing raw data.

#### Key Aspects and Advantages

1. **Secure Distributed Training:** Each institution keeps sensitive patient information behind its own firewall while participating in Federated Training.
2. **NVIDIA GPU Acceleration:** NVFlare taps into the computational power of NVIDIA GPUs, which can reduce training time and improve model performance on large healthcare datasets.
3. **Versatility Across ML Frameworks:** NVFlare works with major machine learning frameworks such as PyTorch and TensorFlow, so you can adapt existing code for federated learning.

#### Unlocking Secure Federated Training

To use NVFlare Code Objects within Rhino FCP, follow these steps:

1. **Adaptation to NVFlare Framework:** Align your machine learning code with NVFlare's Federated Learning framework. See the [Rhino user resources GitHub repository](https://github.com/RhinoHealth/user-resources) for examples.
2. **Container Image Integration:** Build a container image that includes your adapted NVFlare code and required dependencies.
3. **ECR Repository Integration:** Push your container images to your workgroup's Elastic Container Registry (ECR) repository.
4. **Create and Collaborate:** In your project, create an NVFlare Code Object and specify your container image and configuration.
5. **Elevate Federated Training:** Launch Federated Training using NVFlare Code Objects. The FCP orchestrates the federated network and communication aspects for you.

#### Championing Secure Insights and Collaborative Progress

NVFlare Code Objects redefine the paradigm of Federated Training, emphasizing secure and collaborative healthcare insights. By utilizing the power of NVIDIA GPUs and preserving data privacy, NVFlare empowers healthcare organizations to collaborate, innovate, and drive transformative advancements in predictive modeling.

#### Summary

NVFlare Code Objects within Rhino FCP signify a powerful approach to Federated Training. They combine distributed health data, NVIDIA GPU acceleration, and federated learning framework compatibility to support secure and efficient model training.

### Where can I find more information about NVFlare?

* [The NVFlare Documentation Page](https://nvflare.readthedocs.io/en/main/index.html)
* [NVFlare's Official GitHub](https://github.com/NVIDIA/NVFlare)

## Creating an NVFlare Code Object

To create a new NVFlare Code object, do the following.

{% stepper %}
{% step %}
**Go to the Code Objects page**

Go to the main project's page and select your project.

Select **Code** from the menu on the left to open the **Code Objects** page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/2FmXIkixkWgZJddhkkqD/34427033643549)
{% endstep %}

{% step %}
**Open the Create New Code Object page**

Select the **Create New Code Object** button to open the **Create New Code Object** page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/q4RUhjmMRfLvklq9amef/34427066004893)
{% endstep %}

{% step %}
**Select the code object type.**

Select **NVIDIA Flare** as the **Code Object Type**. The page changes to show the fields needed for this object type.

{% hint style="info" %}
**NOTE** : This code depends on NVFlare. Unless a specific version is required for compatibility, we recommend using the latest available release.
{% endhint %}

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/5VfLr0nYAwBpsMOvlXfG/34427066005021) ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/n01bT68heT3015blcPQ7/34427033644317)
{% endstep %}

{% step %}
**Fill in the fields**

*Before you enter information in the fields (see table below), read the following about input and outputs*

*Code objects usually require that you know the number of inputs and outputs your code needs. Those inputs and outputs are provided as data schemas. For example, if your code splits one dataset into two (like a train/test split), you will have to create a code object with one input schema and two output schemas. For more detail into how to structure your code to run on FCP, see* [*Accessing your datasets in Code Objects*](/creating-and-running-code-objects/accessing-your-datasets-in-code-objects)*.*

*Multiple input and output datasets are supported in Python, Generalized, and Interactive Container Code Objects. While NVFlare Code Objects do not support multiple datasets, they can still be used as before for learning and inference across multiple sites.*

{% hint style="info" %}
**NOTE:** If you don't need this level of control, you can:

* Set any input or output as optional, which will allow to provide or generate no datasets respectively
* Set any input or output as a list, which will allow to select 1 or more datasets
* Select "ANY" as input schema, which will allow code object re-use across any input dataset schema.
* Let the system automatically determine the output schemas with [Auto-Generated Data Schemas](/data-schemas/auto-generated-data-schemas).
  {% endhint %}

Fill in the following fields.

| Field              | Description                                                                                                                                                                                                                          |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Name               | Name of the code object.                                                                                                                                                                                                             |
| Description        | Description of the code object.                                                                                                                                                                                                      |
| Type               | Version of the NVIDIA FLARE code.                                                                                                                                                                                                    |
| Input Data Schema  | Data schema for the input datasets used by this code object. This selection determines which datasets are available when you run the code object.                                                                                    |
| Output Data Schema | Data schema for the output dataset produced by this code object. You can also select **\[Auto-generate Data Schema from Data]**. For more information, see [Auto-Generated Data Schemas](/data-schemas/auto-generated-data-schemas). |
| {% endstep %}      |                                                                                                                                                                                                                                      |

{% step %}
**Select your container.**

Next select your **container**. The Docker container you would like to execute when running this *Code*. This will either be a container you have created yourself and pushed to your ECR or a stock ECR image provided by Rhino. If you need a refresher on pushing containers to your ECR, see [Pushing Containers to the ECR](/getting-started/quick-start-guide/pushing-containers-to-the-ecr).

When you click on the drop-down to select your container, you will be presented with two different sections that contain various container images:

* **Workgroup Images:** These will be all the containers you have pushed to your workgroup's ECR. If you have not pushed anything to your workgroup's ECR, this will be blank.
* **Rhino Images:** These are a few container images that Rhino provides to users as utilities to help users. Currently, there are no NVFlare images that are provided by default from Rhino. For more information on the containers that Rhino provides, contact Rhino support.
  {% endstep %}

{% step %}
**Set required compute resources**

After you've completed your details, you can choose to set required compute resources. If you want to do this, see [Autoscaling and Compute Resources](/creating-and-running-code-objects/autoscaling-and-compute-resources) for more information.
{% endstep %}

{% step %}
**Create the code object**

When complete, select the **Create New Code** button to create the new **Code Object**.

The code object appears on the **Code Object** page.
{% endstep %}
{% endstepper %}

## View a Code Object's Configuration

To get an object's configuration, make sure you are on the page containing the original object you would like to view the configuration of. In the box where your original object is, there should be a row for each version. Navigate to the version you would like to view the configuration for and select the three-dot menu button, shown below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/BgQM5mGOLbhuUwL3JgI0/13002096256797)

The menu button is on the right-hand side of the row, click it to view a new menu. The new menu should have an option to show that object's configuration, click on that to see the object's configuration.

For Code Objects and Code Runs, if you chose the Use VM Pool option, you will use the pool that was indicated during the Code Object or Code Run configurations.  Selecting this option shows the resources, including the number of VMs and vCPUs that will be allocated, as well as the amount of RAM, the size of the disk, the number of GPUs, the GPU type/mode&#x6C;*,* and the amount of VRAM.

## Creating a New Version of a NVFlare Code Object

To create a new version, complete the following steps.

1. Go to the page that has the original object you want to create a new version of.
2. In the upper right corner of the box where your original object is, select the **+ New Version** button.
3. A new window appears that allows you to create a new version of your object.

## Removing a Code Object

To remove a code object, complete the following steps.

{% stepper %}
{% step %}
**Open the Code Objects page**

Go to the page that lists your code objects.
{% endstep %}

{% step %}
**Find the code object version**

If needed, use the search fields at the top right.

* Use **Search Name, UID** to search by code object name or UID.
* Use **Search Description** to search by code object description.

Each code object appears with a row for each version. Find the version you want to delete.
{% endstep %}

{% step %}
**Open the menu for the version**

Select the three-dot menu on the right side of the version row, shown below.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/4DgRiNLSEzRn8aP9B9FL/13002670465821)
{% endstep %}

{% step %}
**Remove the code object version**

Select **Remove code object**.

Repeat these steps for each version you want to remove. When you delete the last version, the code object is fully deleted.
{% endstep %}
{% endstepper %}

## Running a NVFlare Code Object

To run NVFlare code, complete the following steps.

{% stepper %}
{% step %}
**Go to the main project's page and select your project.**
{% endstep %}

{% step %}
**Select Code from the menu on the left to open the Code Objects page.**
{% endstep %}

{% step %}
**Select the Run button for the code object you'd like to run.**
{% endstep %}

{% step %}
**Fill in the following fields within the Code Run page.**

{% hint style="info" %}
**Note:** These steps are the same for all NVIDIA FLARE Code Object versions.
{% endhint %}

<table><thead><tr><th width="236.08203125">Field</th><th>Description</th></tr></thead><tbody><tr><td>Training Datasets</td><td>One or many already imported Dataset to be used as input to your Code. If a Dataset happens to be a Collaborator's Dataset, the code will be run by your Collaborator's Rhino Client. In other words, the data never moves outside your collaborator's Rhino Client. If your Datasets all reside on your Rhino Client, make sure to check the below checkbox to simulate federated learning.</td></tr><tr><td>Simulated FL - One FL Client Per Training Dataset</td><td>Check this box to run simulated federated learning. When checked, your Rhino Client will spin up each Dataset as its own federation network, with each Dataset being its own "remote client," and perform federated training.</td></tr><tr><td>Validation Datasets (Optional)</td><td>An optional one or many Dataset that the newly trained federated model will be validated against.</td></tr><tr><td>Output Dataset Name Suffix</td><td>A suffix that is appended to the name of each input validation Dataset. This name will serve as the output validation Dataset that will be created during your validation run and then will be re-imported back into the system to display the results of your training validation.</td></tr><tr><td>Details</td><td>Provide details about the code run.</td></tr><tr><td>Required Compute Resources</td><td>Set the required compute resources.  See <a data-mention href="/creating-and-running-code-objects/autoscaling-and-compute-resources">Autoscaling and Compute Resources</a> for more details.</td></tr><tr><td>Configuration: Federated Server Config Override (Optional)</td><td>Copy and paste the contents of your <code>config_fed_server.json</code> file here. This will override <code>config_fed_server.json</code> in the config directory of the initial container image you pushed to your workspace's ECR. You can use this to dynamically set values for training, like hyper-parameters.</td></tr><tr><td>Configuration: Federated Server Client Override (Optional)</td><td>Copy and paste the contents of your <code>config_fed_client.json</code> file here. This will override <code>config_fed_client.json</code> in the config directory of the initial container image you pushed to your workspace's ECR. You can use this to dynamically set values for training, like hyper-parameters.</td></tr><tr><td>Configuration:  Federated Server Secrets</td><td>Allows you to add a secret to pass into the federated server.</td></tr><tr><td>Configuration: Federated Client Secrets</td><td>Allows you to add a secret to pass to the client.</td></tr><tr><td>Enable Homomorphic Encryption</td><td>Select the checkbox to allow computations and analytical functions to be run on encrypted data, without first having to decrypt it.</td></tr><tr><td>Timeout (seconds)</td><td>The number of seconds that must elapse before a Code run is killed. This is to avoid zombie tasks that run perpetually within a Rhino client. The default is 1 hour.</td></tr><tr><td>Run Parameters</td><td>Optional parameters for the run. These are for validation only.</td></tr><tr><td>Run Secrets</td><td>Optional for the run. For validation only.</td></tr><tr><td>Include Runtime Files</td><td>Select the runtime files that you want to use in this run.  See Selecting Run Time Files During Code Run Set Ups below for more information on including run time files.</td></tr><tr><td>Extra Data</td><td>Add metadata for the run.</td></tr></tbody></table>
{% endstep %}

{% step %}
Select the **Run** button to run your Code.

*Selecting Run Time Files During Code Run Set Ups*

If you are part of a workgroup that has collaborators, you will be able to see files that are 1) in your active workgroup that are part of the project, whether they are published or not and 2) from a collaborator’s workgroup that are part of the project only *if they are published*.

To better understand this, let's take a look at the following scenario. **Project PRIME** is led by **workgroup Alpha**. **Workgroup Beta** has been added as a collaborator. Each workgroup has uploaded run time files.

* **If YOUR active workgroup is Alpha**, here is what you see when you open the Run Time Files screen in Project PRIME.
  * **All Workgroup Alpha's files are shown.** This is because Project PRIME is led by workgroup Alpha, so all of workgroup Alpha’s files that are part of the project are shown whether they are published or not.
  * **Only Workgroup Beta’s published files are shown.** Workgroup Beta’s files that are not part of the project or that are unpublished are not shown.
* **If YOUR active workgroup is Beta**, here is what happens when you open the Run Time Files screen in Project PRIME.
  * **Workgroup Beta's files are all shown.** This is because Beta members can see their own workgroup’s files that are part of the project, whether there are published or not.
  * **Only Workgroup Alpha’s files that have been published to PRIME are shown.** Workgroup Alpha’s unpublished files that are not part of the project are not shown.

{% hint style="info" %}
NOTE: See [Managing Run Time Files](/creating-and-running-code-objects/managing-run-time-files) to learn how to manage, publish and unpublish run time files.
{% endhint %}
{% endstep %}
{% endstepper %}

## Reviewing Code Run Logs

Logs that are produced during a Code Run can be viewed by clicking on the Status link in the Code Runs view. If you need to search for a specific code run, use the text boxes located at the top right corner of the page. To search by name enter the full name/UID or part of the name/UID in the Search Name, UID text box. To search by description, enter part of the code run's description in the Search Description text box.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/BNdbkDphVbVBSXyosjch/14685236815389)

Clicking the Status link will open the Logs view for a particular run:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/GzUeQkpPEuw9OgL98pBS/14685231381661)

Logs can be accessed while the Code Run is active and after the Code Run has completed. While the code is running, an auto-refresh option is available.

This Logs view provides the following information:

* General Info - information about the Code Run, including
  * Code Object name and type
  * Code Object version
  * Code Object description
  * Input and Output Datasets
  * Code Object configuration
  * Code Run configuration
* System Logs
  * Errors or warnings that occurred from the FCP side, e.g. Dataset import errors.
* FL server logs (for NVIDIA FLARE runs)
* FL client logs (for NVIDIA FLARE runs)
  * Each federated client's logs will appear separately
* Client-specific logs (for all other run types)

### Troubleshooting Code Runs

**Error Message that Usage Limit Has Been Exceeded**

If you get an error message indicating that the usage limit has been exceeded, your administrator has set usage limits on the number of input rows a workgroup can process per model within a certain timeframe. Getting this message means that the entire run has been cancelled. Please contact your administrator for more details and help with resolving the issue.

## Viewing a Code Run's Configuration

To get an object's configuration, make sure you are on the page containing the original object you would like to view the configuration of. In the box where your original object is, there should be a row for each version. Navigate to the version you would like to view the configuration for and select the three-dot menu button, shown below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/BgQM5mGOLbhuUwL3JgI0/13002096256797)

The menu button is on the right-hand side of the row, click it to view a new menu. The new menu should have an option to show that object's configuration, click on that to see the object's configuration.

For Code Objects and Code Runs, if you chose the Use VM Pool option, you will use the pool that was indicated during the Code Object or Code Run configurations.  Selecting this option shows the resources, including the number of VMs and vCPUs that will be allocated, as well as the amount of RAM, the size of the disk, the number of GPUs, the GPU type/mode&#x6C;*,* and the amount of VRAM.

## Running Inference (NVFlare Code Runs)

{% hint style="info" %}
NOTE: Running Inference is available for NVFlare Code Runs only.
{% endhint %}

Once you’ve trained your model, you can use it to make inferences on other datasets. To do this, complete the following steps.

{% stepper %}
{% step %}
Select Code Runs from the menu to the left of the screen. &#x20;
{% endstep %}

{% step %}
Right-click on the three-dot menu on the code you want to use to run inference, then select Run Inference.  If you can't find the code run, type the code run name, UID, or description in the text boxes in the top right corner of the screen.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/vz6rWEElVhl8FsriPCsc/31259139473053)
{% endstep %}

{% step %}
The Run Inference screen opens.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/qxOCCNVaAAvtaoMzbsxU/31259139473821)
{% endstep %}

{% step %}
Select the validation dataset and indicate the output dataset name suffix if desired.
{% endstep %}

{% step %}
Under additional parameters, select the Model Parameters File.
{% endstep %}

{% step %}
If you need to adjust the timeout, which is the number of seconds that must elapse before a code run is automatically halted. This is an optional step.
{% endstep %}

{% step %}
Select Run Inference.
{% endstep %}
{% endstepper %}

## Deleting a Code Run

Follow these steps to delete a code run.

{% stepper %}
{% step %}
**Open the Code Runs page**

Go to the page that lists your code runs. &#x20;
{% endstep %}

{% step %}
**Find the code run**

If needed, use the search fields at the top right.

* Use **Search Name, UID** to search by code run name or UID.
* Use **Search Description** to search by code run description.

Find the code run you want to delete.
{% endstep %}

{% step %}
**Open the menu for the code run**

Select the three-dot menu on the right side of the row, shown below.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/2zj9RDThMEzCyZ4nwExT/13002586504093)
{% endstep %}

{% step %}
**Remove the code run**

Select **Remove code run**.
{% endstep %}
{% endstepper %}


# Creating and Running Interactive Container Code

Explains how to create and run code in an interactive container.

## What is an Interactive Container Code Object?

Interactive Container Code lets you run pre-built container images with interactive apps or graphical interfaces. You can use tools like Jupyter Notebooks directly on your on-premises data while keeping that data secure.

### Key Attributes of Interactive Container Code

* **Interactive GUIs:** Unlike other Code Objects, Interactive Containers enable you to execute containers with interactive graphical user interfaces. This facilitates real-time interaction and data visualization within the FCP environment.
* **On-Premises Interaction:** Interactive Containers offer the capability to interact with on-premises data while leveraging the computational power of the FCP. This integration is particularly useful for scenarios where data remains within internal networks.
* **Third-Party Applications:** With Interactive Container Code Objects, you can run third-party applications that are containerized and can be executed within the FCP ecosystem, with no need to install them at each site.

{% hint style="info" %}
NOTE: This capability is limited to third-party applications that can run within a single Linux-based container with no internet connectivity.
{% endhint %}

### Use Cases of Interactive Containers

* **Real-Time Data Exploration:** Utilize interactive visualizations and tools to explore and analyze on-premises healthcare data within the FCP ecosystem.
* **Third-Party Applications:** Run containerized third-party applications such as medical image annotation tools or specialized analysis software.
* **Collaborative Workshops:** Conduct collaborative workshops or training sessions that involve hands-on exercises and interactive activities.

### Benefits of Interactive Containers

* **Interactive Experience:** Gain the ability to interact with GUIs and applications in real-time, fostering dynamic exploration of your data.
* **On-Premises Compatibility:** Execute containerized applications on your on-premises data while utilizing the computational resources of the FCP.
* **Secure Collaboration:** Enable secure collaboration by running third-party tools and applications within the FCP environment, ensuring data privacy.

### Summary

In summary, Interactive Containers offer an innovative pathway to engage with interactive graphical interfaces and applications within the Rhino FCP. By merging on-premises data with containerized interactivity, you can delve deeper into data exploration, collaboration, and visualization while maintaining the highest levels of security and privacy.

## Creating New Interactive Container Code

{% stepper %}
{% step %}
**Go to the main project's page and select your project.**
{% endstep %}

{% step %}
**Select `Code` from the menu on the left to open the `Code Objects` page.**

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/S6VrI53xhcaCFoo43FAa/24602867570973)
{% endstep %}

{% step %}
**Select the `Create New Code Object` button to open the `Create New Code Object` page.**

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/vqlIXEvqbCL9OWgOCALN/24602898072093)
{% endstep %}

{% step %}
**Select the Interactive Container as the Code Object Type.**

The page changes to show the fields needed for this object type.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/WOX2ueyYDuIE0CWZuOXd/24602867572893)
{% endstep %}

{% step %}
**Enter information in the following fields.**

*Before you enter information in the fields (see table below), read the following about input and outputs*

*Code objects usually require that you know the number of inputs and outputs your code needs. Those inputs and outputs are provided as data schemas. For example, if your code splits one dataset into two (like a train/test split), you will have to create a code object with one input schema and two output schemas. For more detail into how to structure your code to run on FCP, see* [*Accessing your datasets in Code Objects*](/creating-and-running-code-objects/accessing-your-datasets-in-code-objects)*.*

*Multiple input and output datasets are supported in Python, Generalized, and Interactive Container Code Objects. While NVFlare Code Objects do not support multiple datasets, they can still be used as before for learning and inference across multiple sites.*

{% hint style="info" %}
**NOTE:** If you don't need this level of control, you can:

* Set any input or output as optional, which will allow to provide or generate no datasets respectively
* Set any input or output as a list, which will allow to select 1 or more datasets
* Select "ANY" as input schema, which will allow code object re-use across any input dataset schema.
* Let the system automatically determine the output schemas with [Auto-Generated Data Schemas](/data-schemas/auto-generated-data-schemas).
  {% endhint %}

<table><thead><tr><th width="264.5390625">Field/Button</th><th>Description</th></tr></thead><tbody><tr><td>Name</td><td>Indicates the name you want to provide for the code object.</td></tr><tr><td>Description</td><td>Provides a brief summary of what the code object does.</td></tr><tr><td>Input (including three-dot menu items)</td><td>Indicates the file(s) needed for the code object to run properly. Your selection here will affect which Dataset(s) can be selected as input when triggering a Code Run with this Code Object. You can enter one or more input files, such as schemas, configuration files, or others. File(s) can be in DICOM, JSON, and or text formats.<br>- If your input doesn't require a schema, select Any.<br>- Select the Add button to the right of the input entry to add another input. You can add as many as you like.<br>- If your input includes more than a single dataset, select the three dot menu to the right of the Input field, then select Input is a list.<br>- If the input is optional, select the three-dot menu to the right of the Input field, then select Optional Input.</td></tr><tr><td>Output</td><td>Indicates the output file(s) produced when the code object run. You can enter one or more output files. Files can be in DICOM, JSON, and or text formats.<br>- You can also select the option to <em>[ Auto-generate Data Schema from Data ]</em>. For more information about Auto-generating Data Schemas, please refer to <a href="/data-schemas/auto-generated-data-schemas">Auto-Generated Data Schemas</a>.<br>- Select the Add button to the right of the output entry to add another output. You can add as many as you like.<br>- If your output includes more than a single dataset, select the three dot menu to the right of the Output field, then select Output is a list.<br>- If the output is optional, select the three-dot menu to the right of the Output field, then select Optional Output.</td></tr><tr><td>Container</td><td>Specifies the name of the Docker container you would like to execute when running this Code Object. This will either be a container image created by someone from your workgroup that is available on your ECR or an image provided by Rhino. If you need a refresher on pushing containers to your ECR, please refer to <a href="/getting-started/quick-start-guide/pushing-containers-to-the-ecr">Pushing Containers to the ECR</a>.</td></tr></tbody></table>
{% endstep %}

{% step %}
**After you've completed your details, you can choose to set required compute resources.**

If you want to do this, see [Autoscaling and Compute Resources](/creating-and-running-code-objects/autoscaling-and-compute-resources) for more information.
{% endstep %}

{% step %}
**Select the Create New Code button to create the new Code Object.**
{% endstep %}

{% step %}
**The Code Object appears in the Code Object page.**

When you have completed adding all your Interactive Container *Code* details, click the **Create New Code** button to create your new *Code Object.*
{% endstep %}
{% endstepper %}

## Viewing a Code Object's Configuration

To get an object's configuration, make sure you are on the page containing the original object you would like to view the configuration of. In the box where your original object is, there should be a row for each version. Navigate to the version you would like to view the configuration for and select the three-dot menu button, shown below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/BgQM5mGOLbhuUwL3JgI0/13002096256797)

The menu button is on the right-hand side of the row, click it to view a new menu. The new menu should have an option to show that object's configuration, click on that to see the object's configuration.

For Code Objects and Code Runs, if you chose the Use VM Pool option, you will use the pool that was indicated during the Code Object or Code Run configurations.  Selecting this option shows the resources, including the number of VMs and vCPUs that will be allocated, as well as the amount of RAM, the size of the disk, the number of GPUs, the GPU type/mode&#x6C;*,* and the amount of VRAM.

## Creating a New Interactive Container Code Version

1. Go to the page that has the original object you want to create a new version of.
2. In the upper right corner of the box where your original object is, select the **+ New Version** button.
3. A new window appears that allows you to create a new version of your object.

## Removing a Code Object

To remove a code object, complete the following steps.

{% stepper %}
{% step %}
**Open the Code Objects page**

Go to the page that lists your code objects.
{% endstep %}

{% step %}
**Find the code object version**

If needed, use the search fields at the top right.

* Use **Search Name** to search by code object name.
* Use **Search Description** to search by code object description.

Each code object appears with a row for each version. Find the version you want to delete.
{% endstep %}

{% step %}
**Open the menu for the version**

Select the three-dot menu on the right side of the version row, shown below.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/4DgRiNLSEzRn8aP9B9FL/13002670465821)
{% endstep %}

{% step %}
**Remove the code object version**

Select **Remove code object**.

Repeat these steps for each version you want to remove. When you delete the last version, the code object is fully deleted.
{% endstep %}
{% endstepper %}

To run interactive container code, you'll need to go to the Code Objects page, then fill out the run details.

## Running Interactive Container Code

After you have created a Interactive Container code object, do the following to run the interactive container code.

{% stepper %}
{% step %}
**Go to the main project's page and select your project.**
{% endstep %}

{% step %}
**Select `Code` from the menu on the left to open the `Code Objects` page.**

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/sRTn5V6pmIH93vQq2fGm/35166644483357)
{% endstep %}

{% step %}
**Select the Run button for the code object you'd like to run.**
{% endstep %}

{% step %}
**In the Code Object Interactive Settings page, specify the Input Dataset(s).**

This is one or more Datasets to be used as input to your Code Run. If multiple Datasets are selected, each will be run separately. If a Dataset happens to be a collaborator's Dataset, the code will be run on that collaborator's Rhino Client. In other words, the data never moves outside your collaborator's Rhino Client.

{% hint style="info" %}
Interactive containers require Secure Access to be enabled on the input dataset. For more information about Secure Access, please refer to [What is Secure Access?](/secure-access/what-is-secure-access)
{% endhint %}
{% endstep %}

{% step %}
**Add the Output Dataset Template.**

Indicate the output dataset template for the session.
{% endstep %}

{% step %}
**Add a Description**\
Add a description for the interactive session.&#x20;
{% endstep %}

{% step %}
**Indicate the Timeout in Seconds.**\
The number of seconds that must elapse before a Code Run is automatically killed. This is to avoid zombie tasks that run perpetually within a Rhino client.
{% endstep %}

{% step %}
**Specify the Run Parameters (Optional).**

Here you can paste a JSON object that defines additional parameters to be provided to your Code Run. This can be used for specifying hyper-parameters for *model* validation or any parameter provided to the code. Run parameters are made available to the container code in a file located at `/input/run_params.json`.
{% endstep %}

{% step %}
**Specify Run Secrets (Optional).**

Here you can paste a JSON object that defines the run secret; it is optional.
{% endstep %}

{% step %}
**Include runtime files and extra data (Optional).**

{% hint style="info" %}
Files that you want to run at run-time should be uploaded to the Rhino Orchestrator.
{% endhint %}

Select the runtime files that you would like to include in the run.  To add run time files to your code run, select the run time files from the list of the workgroup run files that appears. You will want to only include the ones you need for the code run, like in the example that follows.  For more information on this, see Selecting Run Time Files during Code Run Setups.\
\
When complete, add the metadata in the Extra Data section if needed.
{% endstep %}
{% endstepper %}

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/14uXGkKA0nlDd3pxgaCJ/30678413082013)

*Selecting Run Time Files During Code Run Set Ups*

If you are part of a workgroup that has collaborators, you will be able to see files that are 1) in your active workgroup that are part of the project, whether they are published or not and 2) from a collaborator’s workgroup that are part of the project only *if they are published*.

To better understand this, let's take a look at the following scenario. **Project PRIME** is led by **workgroup Alpha**. **Workgroup Beta** has been added as a collaborator. Each workgroup has uploaded run time files.

* **If YOUR active workgroup is Alpha**, here is what you see when you open the Run Time Files screen in Project PRIME.
  * **All Workgroup Alpha's files are shown.** This is because Project PRIME is led by workgroup Alpha, so all of workgroup Alpha’s files that are part of the project are shown whether they are published or not.
  * **Only Workgroup Beta’s published files are shown.** Workgroup Beta’s files that are not part of the project or that are unpublished are not shown.
* **If YOUR active workgroup is Beta**, here is what happens when you open the Run Time Files screen in Project PRIME.
  * **Workgroup Beta's files are all shown.** This is because Beta members can see their own workgroup’s files that are part of the project, whether there are published or not.
  * **Only Workgroup Alpha’s files that have been published to PRIME are shown.** Workgroup Alpha’s unpublished files that are not part of the project are not shown.

{% hint style="info" %}
NOTE: See [Managing Run Time Files](/creating-and-running-code-objects/managing-run-time-files) to learn how to manage, publish and unpublish run time files.
{% endhint %}

When you have completed adding all your Code Run details, either set the required compute resources by following the instructions in [Autoscaling and Compute Resources](/creating-and-running-code-objects/autoscaling-and-compute-resources), or click the **Run** button to run your code.

## Reviewing Code Run Logs

Code run logs provide details about what happened during a run, as well as the outcome. &#x20;

To view these logs, complete the following steps.

{% stepper %}
{% step %}
**Select Code Run.**

In the Code Runs page, select the code run that you want to see logs for.  (If you cannot find the code run, enter the name, UID, or description of the code run in the boxes in the top right corner of the page.)

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FD5E5es8xp9I0KtrEzrJB%2FScreenshot%202026-09-17%20at%202.34.59%E2%80%AFPM.png?alt=media&amp;token=a020a9d3-9ade-4605-8a5b-689492ac729e" alt=""><figcaption></figcaption></figure>

The logs page for the Code Run is shown.  The start and finish time and date of the run, as well as the status of the run appears.  Logs can be accessed while the Code Run is active and after the Code Run has completed. While the code is running, an auto-refresh option is available. Details are shown under the details tab; reports (if any) are shown under the reports tab.  Reports are generated using the Rhino SDK.&#x20;
{% endstep %}

{% step %}
**Select the Details Tab.**

Select the Details tab if needed (it should be selected by default).

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FNllxhZsZ3389w7O8lMYr%2FScreenshot%202026-08-20%20at%2010.43.42%E2%80%AFAM.png?alt=media&amp;token=be89985c-7b2e-4bd3-afaa-08f409d41a2b" alt=""><figcaption></figcaption></figure>

The Details tab provides the following:

* General Info - information about the Code Run, including
  * Code Object name and type
  * Code Object version
  * Code Object description
  * Input and Output Datasets
  * Compute Resources Mode including the requested resources at run time (if applicable).&#x20;
  * Show Code Object Configuration button.  Click this button to see the code object configuration.\
    Show Code Run Configuration button.  Click this button to see the code run configuration.
  * View in TensorBoard button. Click this button to view results in TensorBoard.
* System Logs.  These can include errors or warnings that occurred from the FCP side, e.g. Dataset import errors.
* FL server logs (for NVIDIA FLARE runs)
* FL client logs (for NVIDIA FLARE runs)
  * Each federated client's logs will appear separately
* Client-specific logs (for all other run types).
  {% endstep %}
  {% endstepper %}

{% hint style="info" %}
The Reports tab is a workspace associated with the run where you can output performance metrics you care about. Reports are blank by default as they are created using the Rhino SDK. &#x20;
{% endhint %}

### Troubleshooting Code Runs

**Error Message that Usage Limit Has Been Exceeded**

If you get an error message indicating that the usage limit has been exceeded, your administrator has set usage limits on the number of input rows a workgroup can process per model within a certain timeframe. Getting this message means that the entire run has been cancelled. Please contact your administrator for more details and help with resolving the issue.

## Viewing a Code Run's Configuration

To get an object's configuration, make sure you are on the page containing the original object you would like to view the configuration of. In the box where your original object is, there should be a row for each version. Navigate to the version you would like to view the configuration for and select the three-dot menu button, shown below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/BgQM5mGOLbhuUwL3JgI0/13002096256797)

The menu button is on the right-hand side of the row, click it to view a new menu. The new menu should have an option to show that object's configuration, click on that to see the object's configuration.

For Code Objects and Code Runs, if you chose the Use VM Pool option, you will use the pool that was indicated during the Code Object or Code Run configurations.  Selecting this option shows the resources, including the number of VMs and vCPUs that will be allocated, as well as the amount of RAM, the size of the disk, the number of GPUs, the GPU type/mode&#x6C;*,* and the amount of VRAM.

## Deleting a Code Run

Follow these steps to delete a code run.

{% stepper %}
{% step %}
**Open the Code Runs page**

Go to the page that lists your code runs.
{% endstep %}

{% step %}
**Find the code run**

If needed, use the search fields at the top right.

* Use **Search Name, UID** to search by code run name or the UID.
* Use **Search Description** to search by code run description.

Find the code run you want to delete.
{% endstep %}

{% step %}
**Open the menu for the code run**

Select the three-dot menu on the right side of the row, shown below.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/2zj9RDThMEzCyZ4nwExT/13002586504093)
{% endstep %}

{% step %}
**Remove the code run**

Select **Remove code run**.
{% endstep %}
{% endstepper %}

## Running an Interactive Container and Accessing Workspace Files

Interactive Containers allow you to run entire containerized applications such as Jupyter Notebook (and not just containerized code) remotely and interact with them. You can use Jupyter Notebook, QuPath, 3D Slider, R Studio and LibreOffice. R Studio and LibreOffice require more custom setup information: if you choose to use them, please contact us for help.

An Interactive Container similar to connecting to a remote desktop, but you do not have the ability to exfiltrate any data. (This is governed by permissions policies, requires approval from the data owner, and is logged and auditable.)

### Running an Interactive Container

{% stepper %}
{% step %}
**In the Code Runs page, select a code run that has the row of type "IC" and shows a status of "Running".**
{% endstep %}

{% step %}
**Connect to the active session by clicking the arrow icon.**

It appears under the Type column for interactive container entries.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/c5RI7b4R5rMGDRYGqbsG/35550620057757)
{% endstep %}

{% step %}
**A new tab opens with the interactive session.**

This tab runs your Interactive Container on the remote client.
{% endstep %}

{% step %}
**Click the desktop icon and interact with the application as you would normally.**

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/XBH5U27LtrKHU9ZfvR9E/35764979165213)
{% endstep %}
{% endstepper %}

### Working with Files in the Workspace Folder

In your interactive session, files such as code run outputs are stored in the `/workspace` folder, by default. This folder keeps your work saved across multiple interactive sessions, so you don’t have to manually save and import files as input/output datasets.

{% stepper %}
{% step %}
**If you are unfamiliar with the Rhino FCP Workspace, review the steps below before continuing.**
{% endstep %}

{% step %}
**Navigate to the `/workspace` folder using the file explorer or navigator for your IC platform.**

If you performed a code run, results are stored, by default, in this folder.
{% endstep %}

{% step %}
**If you do not want the files to be overwritten, copy them in another folder so that you can interact with them.**

Note that if you overwrite a file in the `/workspace` folder, the changes will be in any other Interactive Container session that you have running (provided it is under your account and it is in the same workgroup).
{% endstep %}
{% endstepper %}

### Saving Output Data&#x20;

With the Interactive Container running do the following.

* Save the data file.  For tabular data, the output is saved to `/output/0/dataset.csv`.  For file data, save the output to `/output/0/file_data/`. &#x20;
* After you have saved all your files, click the desktop icon named Create Output Dataset. This will run a local script that looks for files under `/output/0/file_data/` and populates a new `/output/0/dataset.csv` file with the file names so they can be imported as a dataset.

{% hint style="info" %}
NOTE: If you save a data file (or other data files) multiple times, each time files are generated they are written to a new folder named with the next number in the sequence (0, 1, 2, ...).  Example:   `/output/1/dataset.csv`.
{% endhint %}

When you terminate the interactive session, the FCP will attempt to import the output dataset defined in the `/output/0/dataset.csv` file. If you did not create this file, the Code Run will show an “Error: failure to import dataset” message.

### Exporting Files from the Workspace Folder

After you've saved your output data using the directions in [Saving Output Data](#saving-output-data), you can extract files from your `/workspace` folder to a location outside the Rhino Client.  To do this, export the dataset(s) to client-mounted storage or to `/rhino_data` by following the instructions in [Importing and Exporting Datasets to and from Your Network Storage](/getting-started/quick-start-guide/importing-and-exporting-datasets-to-and-from-your-network-storage).


# Accessing your datasets in Code Objects

Code Objects use numbered inputs to read data and numbered outputs to write data. The numbering corresponds to the order you set when creating the code object. See the relevant code object creation guide for your code type.

You can easily see these input and output numbers in the dataset selection dropdowns when running your code:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/gPzu8V8Gmyd1mGTipgAx/26098898159005)

To ensure seamless access, FCP stores all imported data in a consistent format, regardless of the original file names or folder structure. This allows any code object to read and write data reliably. The following sections provide examples of how to access your data for reading and writing, tailored to different code object types and input/output configurations.

### GC, Interactive Containers, and Python Auto-containers

In these Code Object types, inputs are accessible in `/input/`, and outputs are accessible in `/output/`. Accessing datasets will depend on the configuration for each Input or Output, see below.

#### Default (mandatory) Input

```python
df = pandas.read_csv("/input/0/dataset.csv") # reads input 0 dataset
```

#### Optional Input

If input 1 was not provided, the `/input/1` directory will be empty. If it is provided, read your dataset as described below:

```python
df = pandas.read_csv("/input/1/dataset.csv") # reads input 1 dataset
```

#### List Input

Datasets in a list input are accessible in subfolders (using their uid) within the main input folder. For example, the datasets in list input 0 would be each accessible in `/input/0/{uid}`. If Input 2 were set as a list input, you could use the example code below in your Code Object to read all datasets provided in input 2:

```python
import pandas as pd
from pathlib import Path

input_dirs = [p for p in Path("/input/2").iterdir() \\
                if p.is_dir() and (p / "dataset.csv").exists()]
input_dfs = [pd.read_csv(dir_path / "dataset.csv") for dir_path in input_dirs]
```

#### Default (mandatory) Output

```python
df.to_csv("/output/0/dataset.csv", index=False) # writes output 0 dataset
```

#### Optional Output

If output 1 is set as optional, you can leave `/output/1` empty, or write to it as described below:

```python
df.to_csv("/output/1/dataset.csv", index=False) # writes output 1 dataset
```

#### List Output

Use a folder within the output to separate your datasets. For example, you could use the code below in your Code Object to write in output 1 a list of 2 datasets:

```python
os.mkdir("/output/1/part1")
df1.to_csv("/output/1/part1/dataset.csv")

os.mkdir("/output/1/part2")
df2.to_csv("/output/1/part2/dataset.csv")
```

### Snippet Python Auto-container

The Python Snippet Code Object simplifies data handling by automatically loading your datasets into Pandas DataFrames and saving your output as FCP datasets directly from Pandas DataFrames. More detailed information is provided in the sections below.

#### Default (mandatory) Input

All of the input datasets will be loaded as pandas dataframes into an inputs variable, which will be a doubly nested list. The first level of nesting will be the different inputs of the Code Object, and the second level will be the list of datasets passed into each input.

```python
df = inputs[0][0] # access a dataset in mandatory input 0
```

```python
[[df0], [df1], [df2]] = inputs # access a dataset in mandatory inputs 0, 1, and 2
```

To maintain compatibility with older code, if you provide only one input dataset, it will automatically be loaded into the `df` variable (as `inputs[0][0]`).

**Optional Input**

```python
[[], [], [df]] = inputs # ignore inputs 0 and 1 if they were to be optional and not needed by your code
```

#### List Input

```python
[[df0], [df1, df2, df3]] = inputs # access a dataset in input 0, and a list with 3 datasets in input 2. Note that number of datasets in a list is arbitrary, so you might want to add code to handle for that case.
```

#### Default (mandatory) Output

All of the output datasets can be provided as pandas dataframes in an outputs variable, which is also a doubly nested list with the first level being the different outputs of the Code Object, and the second level being the list of datasets for each output.

```python
outputs[1][0] = out_df # save `out_df` into the Output 1 dataset
```

To maintain compatibility with older code, if you don't specify any outputs, the contents of the `df` variable will be saved as a single output dataset (`outputs[0][0]`).

#### Optional Output

```python
outputs = [[], [df]] # don't return output 1 if it were to be optional and not needed
```

#### List Output

```python
outputs = [[df1], [df2, df3, df4, df5]] # return 4 datasets in list output 2
```

### NVFlare

NVFlare Clients only support a single list input (multiple or optional inputs are not supported). In contrast to GC list inputs which are accessible under `/input/0/{uid}`, NVFlare Clients' data is accessible in `/input/datasets/{uid}`. NVFlare Clients can't write any outputs (other than logs and [TensorBoard](/creating-and-running-code-objects/visualizing-and-measuring-machine-learning-model-performance-with-tensorboard) logs).

#### Read Training Datasets (on FL Clients)

Read the dataset using their UUIDs as:

```python
df = pandas.read_csv("/input/datasets/{uid}/dataset.csv")
```

See full NVFlare code examples in [User Resources](https://github.com/RhinoHealth/user-resources/blob/main/examples/nvflare/xgboost/xgboost-sag/custom/bcw_executor.py).

#### Write Trained Model Parameters (on FL server)

* Write checkpoints to files under the `/output/model_parameters/` directory (needs to be created first)
* Write final/best model weights to a file `/output/model_parameters.*` , for example `/output/model_parameters.pt` for PyTorch models.

#### Run Inference

Same as for GC and its variants (see above), but with a single input and a single output. Specifically:

* Input: `/input/dataset.csv` or `/input/0/dataset.csv`
* Output : `/output/dataset.csv` or `/output/0/dataset.csv`

#### Access the Model Weights

NVFlare model weights can be downloaded by users that have "Manage Code Objects" permission in the project. See the following article for detailed steps: [Frequently Asked Questions (FAQs)](/frequently-asked-questions/frequently-asked-questions-faqs)


# Publishing and Unpublishing Code Objects and Code Runs

Rhino FCP allows you to securely publish code objects and code runs so that they are visible to selected collaborators. You can control which versions to publish or unpublish. You can also manage collaborator permissions. Publishing different versions aids model training and refinement, allows version control, and supports development of variations for specific purposes.

Collaborators with access to a dataset using a published code object and initiating the code run can view inference results. This maintains security and privacy while still allowing result sharing.

### About Publishing and Unpublishing

Publishing makes Code Objects and Code Runs visible to all collaborators who have the appropriate permissions.

* *Code Objects:* When you unpublish a Code Object, it will stop being visible to all users without the “View Code Objects and Code Runs” permission, and all published Code Runs for this Code Object will be unpublished. You can publish and unpublish different versions of the code object.
* *Code Runs:* When you publish a code run version, it also publishes the associated code object version, if it’s unpublished. This ensures that the information about the code object such as the name, version, inputs/outputs, etc. are available to the user when interacting with the code run. Unpublishing hides the code run from collaborators. When you unpublish a code run, it will stop being visible to all users without the “View Code Objects and Code Runs” permission. You can publish and unpublish different versions of the code run.

### Prerequisites

Ensure that the View Code Objects and Code Runs permission is set appropriately. For more details, see the [Permissions documentation (View Code Objects and Code Runs Setting)](/projects/persona-and-permissions-policies-reference).

### Code Objects

The following instructions explain how to publish and unpublish a code object.

#### Publishing a Code Object

To publish a code object, do the following.

{% stepper %}
{% step %}
Select Code from the menu on the left side of the screen.
{% endstep %}

{% step %}
Right-click the three-dot menu next to the code object you want to publish, then select Publish code object.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/rSK4nD2L9oBafRYjFlZ8/30380789669149)
{% endstep %}

{% step %}
A message appears asking whether you would like to publish the code object. If you want to unpublish all previous versions of the code object, click the “Unpublish any previously published versions of this code object” checkbox.

{% hint style="info" %}
Note: If you choose to unpublish a Code Object, it will stop being visible to all users without the “View Code Objects and Code Runs” permission, and all published Code Runs for this Code Object will be unpublished. This is to ensure that the information about the Code Object (e.g. name, version, inputs/outputs, etc.) are available to the user when interacting with the Code Run.
{% endhint %}
{% endstep %}

{% step %}
Select Publish Code Object. The code object is published and can be viewed by collaborators with the appropriate permissions.

* If you publish a Code Object/Run version, you can choose to automatically unpublish all previously published versions of the same Code Object/Run.
* When you unpublish a Code Run, this Code Run will stop being visible to all users who do not have the “View Code Objects and Code Runs” permission.
* When unpublishing a Code Object, it will stop being visible to all users without the “View Code Objects and Code Runs” permission, and all published Code Runs for this Code Object will be unpublished. This is in order to ensure that the information about the Code Object (e.g. name, version, inputs/outputs, etc.) are available to the user when interacting with the Code Run.
  {% endstep %}
  {% endstepper %}

#### Unpublishing a Code Object

To unpublish a code object, complete the following steps.

{% stepper %}
{% step %}
Select Code from the menu on the left side of the screen.
{% endstep %}

{% step %}
Right-click the three-dot menu next to a code object that has a highlighted publish icon.
{% endstep %}

{% step %}
Select Unpublish code object. A prompt that confirms that you want to unpublish the code object opens.
{% endstep %}

{% step %}
Select Unpublish Code Object.
{% endstep %}
{% endstepper %}

### Code Runs

The following instructions explain how to publish and unpublish a code run.

#### Publishing a Code Run

To publish a code run, do the following.

{% stepper %}
{% step %}
Select Code Runs from the menu on the left side of the screen.
{% endstep %}

{% step %}
Right-click the three-dot menu next to the code run you want to and select Publish code run.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/clRQadUiyMntkn2loI3T/30453816011549)
{% endstep %}

{% step %}
A message appears asking whether you would like to publish the code run. Select Publish Code Run. If you want to unpublish all previous versions of the code object, click the “Unpublish any previously published versions of this code object” checkbox.

{% hint style="info" %}
Note: If you choose to unpublish a Code Run, it will stop being visible to all users without the “View Code Objects and Code Runs” permission.
{% endhint %}
{% endstep %}

{% step %}
Select Publish Code Object to publish the selected code run.

{% hint style="info" %}
Note: If the Code Object belongs to a different workgroup than the Code Run, and that Code Object is unpublished and the Code Object’s workgroup has “View Code Object/Run” permissions that don’t provide full visibility, then publishing the Code Run will return an error message stating that the Code Object for the Code Run isn’t published. If this happens, ask someone who is part of the Code Object’s primary workgroup to publish it.
{% endhint %}
{% endstep %}
{% endstepper %}

#### Unpublishing a Code Run

To unpublish a code run, complete the following steps.

{% stepper %}
{% step %}
Select Code Runs from the menu on the left side of the screen.
{% endstep %}

{% step %}
Right-click the three-dot menu next to a code run that has a highlighted publish icon. Select Unpublish code run.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/5z0r4lgOISXxHyINgafI/30453800444573)
{% endstep %}

{% step %}
A prompt that confirms that you want to unpublish the code run opens. Select Unpublish Code Run.
{% endstep %}
{% endstepper %}


# Managing Run Time Files

How to view, add, publish, unpublish, and delete external run time files.

**Run Time Files** are external files that can be used when you run code objects.&#x20;

The **Run Time Files** page lists the run time files that have been uploaded to the shared space for your workgroup, showing the folders they are stored in, and whether they are unpublished or published.

***

### Viewing Run Time Files

To **View** run time files for your workgroup, select **Code** from the menu on the left, then select the **Run Time Files** tab.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/g8lAUHCsQVbvlS7TRbuH/30677601767837)

Folders and run-time files are listed.

<table><thead><tr><th width="80.8125">Icon</th><th>Description</th></tr></thead><tbody><tr><td><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FrecACTGw0Aj4LLj1h7Cr%2FIcon_Unpublished.png?alt=media&amp;token=390fe619-d52a-4561-a3a4-55fdfaf86a14" alt="" data-size="line"></td><td>The file is unpublished. If this icon appears next to a folder, then all files in that folder are unpublished.</td></tr><tr><td><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FAnxLN2D4pZ7PuEDkyeAF%2FIcon_Published.png?alt=media&amp;token=b0dba261-aa55-47bd-a572-380c98925da1" alt="" data-size="line"></td><td>The file is published. If this icon appears next to a folder, then all files in that folder are published.</td></tr><tr><td><img src="https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/7ygEygctpDYgskhuP8eQ/30677594171037" alt="" data-size="line"></td><td>The folder contains published and unpublished files.</td></tr></tbody></table>

{% hint style="info" %}
**Note:** If you belong to [multiple workgroups](/settings/about-multiple-workgroups), the **Runtime Files** page will only display files from your **currently active workgroup**, regardless of whether those files have been published or not.

Runtime files **published by collaborators** in other workgroups may still be available for use in your project. You will be able to select these files when running a Code Object, but they will **not** appear on the Runtime Files page unless you have access to the Code Artifacts bucket where they are stored.
{% endhint %}

***

### Accessing the Code Artifacts Bucket

Runtime files are stored in your workgroup's **code artifacts bucket**.

The S3 code artifacts bucket is created by Rhino (on client request) as part of the onboarding process - you don't create or manage this bucket yourself.

If you don't already have one and would like one created, contact us at <support@rhinofcp.com>.

{% hint style="warning" %}
The code artifacts bucket is owned by Rhino. **Please DO NOT upload sensitive information such as proprietary datasets.** For sensitive data, please use the instructions in [Registering, Configuring, and Exporting Datasets](/datasets/registering-configuring-and-exporting-datasets) instead.
{% endhint %}

You can find the code artifacts bucket in your settings page under **Containers & Artifacts**:

{% stepper %}
{% step %}
In your project, select the **Settings** button (it looks like a sprocket at the bottom left side of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/4u8WYSy0sa9q2HlrHo1O/34593373401629)
{% endstep %}

{% step %}
In the Settings menu, which is near the top of the screen on the left side of the window, select **Containers & Artifacts**.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/CdMN4MNmiJMWrQAzYeHs/34593373402397)
{% endstep %}

{% step %}
Your **storage bucket** and **bucket prefix** appear in the *Workgroup code and model artifacts storage* part of the page.&#x20;

Under *Container Registry Access***,** you can also **Reveal Credentials** to see your AWS ID and secret access key.
{% endstep %}
{% endstepper %}

***

### Adding Runtime Files

Add external runtime files by adding them to the code artifacts bucket.

There are many different ways to [upload files to an AWS S3 bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html). For convenience, Rhino has created a utility script, which is accessible via our user-resources repo: [upload-file-to-s3.sh](https://github.com/RhinoHealth/user-resources/blob/f2d3107eb85ab2abb4fb68ef25bd3f92538d0ed1/utils/upload-file-to-s3.sh)

**How to Use this Script**:

{% stepper %}
{% step %}

### Configure

Set your AWS S3 credentials as environment variables in your terminal (these can be found on the FCP UI under **Settings -> Containers & Artifacts -> Container Registry Access**):

```bash
export AWS_ACCESS_KEY_ID=<ENTER_YOUR_ID>
export AWS_SECRET_ACCESS_KEY=<ENTER_YOUR_KEY>
```

{% endstep %}

{% step %}

### Run Script

From the `utils/` directory the script is located in, call it with 4 arguments:

```bash
./upload-file-to-s3.sh <upload_directory> <storage_bucket> <bucket_prefix> <path_in_bucket>
```

* `<upload_directory>` - the local folder whose contents you want to upload.
* `<storage_bucket>` - the name of your workgroup's S3 bucket.
* `<bucket_prefix>` - your workgroup's fixed prefix inside that bucket.
* `<path_in_bucket>` - the subfolder, under your prefix, to upload into. **This is the path you'll reference in your code objects**

For example, uploading a local folder `./original_location` into a subfolder called `my_files`:

```bash
./upload-file-to-s3.sh ./original_location <storage_bucket> <bucket_prefix> my_files
```

{% endstep %}
{% endstepper %}

***

### Referencing Runtime Files in Your Code

When creating your code object, you can reference your external files by referencing them in the following path:

```
/external_data/the_folder_in_s3_storage_bucket/filename
```

For the example above, assuming you uploaded `model_params.txt` file under `my_files`, the file would be accessible during runtime in

```
/external_data/my_files/model_params.txt
```

An example of Python code to read your file data into a `text` variable would look like as follows:

```python
from pathlib import Path
     text = Path('/external_data/my_files/model_params.txt').read_text()
```

Once your code points to your external files, and the code object is created, you can run the code and specify the files you want to use in your code run.&#x20;

In the **FCP** **UI**, you can simply select them from a dropdown:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/JdWjzEPWJdU9VEuhOWNr/19768498689565)

Alternatively, you can also reference them via **SDK**. See this [notebook](https://github.com/RhinoHealth/user-resources/blob/main/examples/rhino-sdk/runtime_external_files.ipynb) for an example.

***

### Checkpoints

{% hint style="info" %}
As you train your NVFlare models, checkpoint and model parameter files are added to the Run Time Files page automatically.
{% endhint %}

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/y9eMmDSab3wk7BlDTu78/31364001984925)

**Checkpoint files** are complete snapshots of a federated learning training run, shown as a list.&#x20;

Each file contains model parameters, internal optimizer states, and training metadata such as the current training round. You will also see a models parameter file.&#x20;

You can publish, unpublish, or delete these files, as you would any other file.

***

### Adding Descriptions or Notes to Runtime Files

If you want to add a description or note to a runtime file, move your pointer over the file. A box appears; select the pencil to enter the description, then click Save.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/rfgmKxqthmJ7fgzxLYjm/31364050783389) ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/75eEY4FAqJ2emBjG0kHo/31364050784925)

***

### Publishing Run Time Files

{% stepper %}
{% step %}
**Open the Run Time Files page.**

Select Code from the left menu, then clicking the run time files link.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/pOrGHtj8Eegw7SkeHiwK/30677601773085)
{% endstep %}

{% step %}
**Select the files and publish them.**

Click the check box next to the files you want to publish, then click the **Publish** button.
{% endstep %}
{% endstepper %}

***

### Unpublishing Run Time Files

{% stepper %}
{% step %}
**Open the Run Time Files page.**

Select Code from the left menu, then clicking the run time files link.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/PldpadLuVYshAFhb6qbt/30677601774877)
{% endstep %}

{% step %}
**Select the files and unpublish them.**

Select the checkbox next to the file(s) you want to unpublish, then select the **Unpublish** button.
{% endstep %}
{% endstepper %}

***

### Deleting Run Time Files

{% stepper %}
{% step %}
**Open the Run Time Files page.**

Select Code from the left menu, then clicking the run time files link.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/PldpadLuVYshAFhb6qbt/30677601774877)
{% endstep %}

{% step %}
**Select the files and delete them.**

Select the checkbox next to the file(s) you want to delete, then select the **Delete Files** button.
{% endstep %}
{% endstepper %}


# Autoscaling and Compute Resources

## Autoscaling

**Autoscaling** allows Rhino to run Code Runs on additional compute resources when the default Rhino Client capacity is not sufficient. This capability is designed to support resource‑intensive, "bursty"(processing tasks occur in short, intense or irregular spurts), or GPU‑based workloads while improving isolation, reliability, and cost efficiency.&#x20;

With autoscaling enabled, Rhino provisions temporary cloud VMs on demand, executes workloads on those VMs, and automatically terminates them when execution completes. This can help you make more efficient use of your computing resources and save on costs.

{% hint style="info" %}
**NOTE**: This feature is only available if you are running on the Google Cloud Platform (GCP).&#x20;

*For NVFlare code objects and code runs, you can adjust autoscaling methods for both the NVFlare Server and the NVFlare Client. For the NVFlare Server, you can only specify the CPU and RAM.*
{% endhint %}

***

## Compute Options

There are **3 ways** to specify compute for a code object run:&#x20;

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2F9EXC49vWSrdWSbfNgfRC%2Fimage.png?alt=media&amp;token=e6594ee2-35db-4511-9ffd-7065611c5353" alt=""><figcaption></figcaption></figure>

{% stepper %}
{% step %}

### Use Client Resources

Uses the available client settings and resources.

**How To**:

1. Select the Use Client Resources button. It should be selected by default.
2. When complete, select Create New Code Object or start a Code Run.
   {% endstep %}

{% step %}

### Set Minimum

Allows you to set the minimum number of resources that must be available. If you choose the Set Minimum option, you can indicate the minimum number of CPUs, amount of RAM, the disk size (VRAM), as well as the type and number of GPUs. You can adjust these settings when you create a code object and also when you run your code.&#x20;

{% hint style="info" %}
Adjustments do not persist and will need to be reset with each run.
{% endhint %}

**How To**:

1. In the Required Compute Resources section, select Set Minimum.
2. Next, make changes to the settings as needed. The settings are explained below.

| Setting       | Description                                                                                         | Usage Note                                                                                                                                                                                                                |
| ------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CPU MIN       | The minimum number of CPU cores on which your code will be run.                                     | If the CPU MIN is too low, you might see slow code execution or throttling.                                                                                                                                               |
| RAM MIN       | The minimum amount of RAM (main memory) that you want to allocate to running your code.             | If this is too low, you might see an out-of-memory crash or slowness in execution due to disk swapping.                                                                                                                   |
| DISK SIZE     | Amount of storage allocated to the instance.                                                        | Increasing this setting increases capacity (not necessarily speed)                                                                                                                                                        |
| GPU TYPE      | The model of GPU hardware. The number of GPUs indicate the number of GPUs attached to the instance. | If your code isn’t written to use multiple GPUs, extra GPUs might not be used. Note that GPU availability depends on the selected cloud region, Project‑level GPU quotas, and the current capacity at the cloud provider. |
| {% endstep %} |                                                                                                     |                                                                                                                                                                                                                           |

{% step %}

### Use VM Pool

Allows you to select a Pre-allocated Virtual Machine (VM) Pool. Pre-allocated VM Pools allow you to indicate which dedicated compute resource you want to use for your code run, ensuring guaranteed availability for high-demand workloads such as GPU-intensive AI training and inference. This feature provides availability of critical compute resources and offers predictable costs through fixed capacity reservations.

{% hint style="info" %}
A *VM Pool* selection is part of the code object's configuration.
{% endhint %}

**How To**:&#x20;

See [Using VM Pools](/creating-and-running-code-objects/autoscaling-and-compute-resources/using-vm-pools)
{% endstep %}
{% endstepper %}

***

## **Table Summary**

**In the table below**, we review the tradeoffs of each option.

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Option</th><th>Capacity Comes From</th><th>Startup</th><th>Cost Shape</th><th>Best For</th></tr></thead><tbody><tr><td><strong>Use Client Resources</strong></td><td>The Rhino Client's own default capacity</td><td>Immediate</td><td>Included</td><td>Routine work that fits existing client capacity</td></tr><tr><td><strong>Set Minimum</strong></td><td>A temporary cloud VM provisioned on demand, then terminated</td><td>Waits for provisioning</td><td>Varies per run</td><td>Bursty or irregular workloads; experimentation where shape changes run to run</td></tr><tr><td><strong>Use VM Pool</strong></td><td>A reservation of VMs held ready in advance</td><td>Faster — the VM already exists</td><td>Fixed, from the reservation</td><td>Recurring, high-demand, or GPU-intensive workloads where availability matters</td></tr></tbody></table>


# Using VM Pools

## What is a VM Pool?

A pre-allocated **VM Pool** is a set of virtual machines (VMs) reserved for your organization in advance and held ready for code runs. Instead of provisioning a machine when a run starts, the run claims a slot on a machine that already exists.

***

## Why use a VM Pool?

* **Guaranteed availability**
  * High-demand workloads — GPU-intensive AI training and inference in particular — do not compete with other workloads for capacity that may not be there when you need it.
* **Predictable cost**
  * Capacity is a fixed reservation rather than a variable, per-run provisioning charge.

{% hint style="info" %}
The tradeoff is that a VM pool is a **fixed** size. A pool's configuration (vCPUs, RAM, disk, and GPUs per VM) is set when the pool is created and cannot be overridden by an individual code object or code run.&#x20;
{% endhint %}

See [Compute Options](/creating-and-running-code-objects/autoscaling-and-compute-resources) to explore alternatives.

***

## Prerequisites and Availability

Pre-allocated VM Pools are currently available for any code object that run on Google Cloud Platform **(GCP) Rhino-hosted agents**, and are supported for Generalized Compute, Python Code, and NVIDIA FLARE code objects.

If you do not see a Use VM Pool option, either no pools have been configured for your organization or your code object is not running on a GCP Rhino-hosted agent.&#x20;

{% hint style="info" %}
Pre-allocated VMs **must be configured by a Rhino administrator** before use. Contact your administrator or your Rhino representative for more information.
{% endhint %}

***

## How Agents Claim Pool Capacity

A federated run executes at more than one Rhino Client, and each participating agent needs a slot. How those slots are claimed depends on the code object type:

* **Generalized Compute and Python Code** — each agent claims its slot independently. An agent that finds capacity begins work without waiting for the others.
* **NVIDIA FLARE** — a two-phase claim. All agents must secure pending slots before any job dispatches. A FLARE job therefore starts only when every participating site has capacity reserved.

{% hint style="info" %}
For FLARE, a single site short on pool capacity will hold up the whole job.&#x20;

When sizing pools for a FLARE collaboration, size for **simultaneous** participation rather than average use.
{% endhint %}

***

## Selecting VM Pools for a Code Object

A code object can be associated with **more than one** pre-allocated VM pool. Where you maintain separate pools — CPU and GPU variants, or pools dedicated to particular projects or sites — a single code object can target each pool that suits it, without duplicating the code object per pool.

{% hint style="info" %}
When a VM pool is selected, you cannot manually set individual compute resource specifications (CPU, RAM, GPU), because these are governed by the pool's fixed configuration.&#x20;
{% endhint %}

{% hint style="warning" %}
System validation will prevent the creation of a Code Object if the requirements do not match the selected pool's capabilities (for example, requesting a non-GPU job on a GPU-only pool).
{% endhint %}

{% stepper %}
{% step %}

### Open the compute resources section

In the Required Compute Resources section of the code object or code run, choose Use VM Pool.&#x20;

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2FpD0fmbbIcLr7IJQgjXOC%2Fimage.png?alt=media&amp;token=2d3d21b2-6363-45b5-b237-e7ea27176c04" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Review the available pools

Each pool is listed with its name and current available resources:

* Number of VMs (if any)
* Number of vCPUs per VM
* Amount of RAM per VM
* Disk size per VM
* Whether GPUs are available, and how many and their specifications
  {% endstep %}

{% step %}

### Select the pools you want

Select one or more pools.
{% endstep %}

{% step %}

### Create the code object or start the run

Select Create New Code Object or start a Code Run. The code object or code run shows an icon indicating that it will run on a pre-allocated VM pool.&#x20;

If you hover over the icon, the name of the selected VM pool is shown.&#x20;

&#x20;![](https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2Foj6FqJhR18ybIjNr5FCI%2Fimage.png?alt=media\&token=ba5a8628-5e06-451a-9beb-d8c8c9a014d4)
{% endstep %}
{% endstepper %}

***

## Tracking VM Pool Status

You can track the performance, health, and availability of your VM Pool project resources in the **Virtual Machine Pools** tab. This dedicated subpage provides a comprehensive view of your environment, including total pool capacity, current utilization (number of running VMs), and queue length. &#x20;

To learn more about the status of the VM Pools in your project, do the following.

1. Select **Code** from the main menu, then select the **Virtual Machine Pools** tab at the top of the page.

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2F0Htztka6dYe17KDqpD03%2FScreenshot%202026-08-20%20at%2011.37.50%E2%80%AFAM.png?alt=media&amp;token=d1957e91-ede1-4c89-b584-8321817d7f08" alt=""><figcaption></figcaption></figure>

2. **Review the information** about the pools.

* Total Pools - Number of VM Pools available across the project.
* Total Capacity - Number of VMs, including how many are in use and how many are idle.
* Queued Jobs - Number of jobs waiting for processing across all pools.
* Health - How many VM pools are active, as well as a brief description of the inactive VM Pools. &#x20;
* Running Jobs - There is also a listing that contains pool information for running jobs.  This includes the pool name, compute specs (number of CPUs, amount of ram, GPUs), utilization, how many jobs are in the queue, and the status of the job.

{% hint style="info" %}
If a pool undergoes maintenance, a banner will appear on the Code Run page indicating that jobs will remain queued until the maintenance is complete.
{% endhint %}

***

## Confirming Which Resources a Run Used

**Code run details** show the VM pools a run requested alongside the resources it actually claimed. This is the authoritative record of what a run executed on, and the first place to look when:

* A run started more slowly than expected — it may have queued or fallen back.
* You are reconciling compute cost against reserved capacity.
* A FLARE job did not dispatch — check whether every agent secured a slot.

The **Details** tab of a code run's logs also displays the compute resource mode and the requested specifications.

***

## VM Execution & Capacity Exhaustion

When a job is triggered against a pre-allocated pool, it follows a more efficient execution path compared to standard auto-scaling.  Jobs are submitted to the chosen pool and transition rapidly from a "**Queued**" phase directly into a "**Running**" state as resources are already primed for use.

If a pool's capacity is exhausted, jobs are placed into a First-in-First-Out (**FIFO**) queue rather than failing. You can monitor the "Queued (VM Pool)" status and your job's position on the Code Run page. Once a slot frees, the job is automatically assigned and dispatched.

***

## Troubleshooting

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Symptom</th><th>Likely Cause</th><th>What to Check</th></tr></thead><tbody><tr><td>Use VM Pool is not offered</td><td>No pools configured, or the code object is not on a GCP Rhino-hosted agent</td><td>Confirm with your administrator</td></tr><tr><td>Code object will not save with a pool selected</td><td>Validation mismatch between the code object's requirements and the pool's configuration</td><td>Compare the code object's GPU and resource requirements against the pool's fixed configuration</td></tr><tr><td>Job sits in Queued (VM Pool)</td><td>Pool capacity exhausted</td><td>Check queue position on the Code Run page and pool utilization on the Virtual Machine Pools tab</td></tr><tr><td>A FLARE job does not dispatch while some agents appear ready</td><td>Two-phase claim — not all agents have secured pending slots</td><td>Identify which participating site lacks capacity</td></tr><tr><td>A run used different resources than the pool provides</td><td>The run fell back to an ad hoc VM</td><td>Check requested pools against claimed resources in the run details</td></tr></tbody></table>

<br>


# Visualizing and Measuring Machine Learning Model Performance with Tensorboard

To help you improve a machine learning model, you can visualize and monitor performance metrics like accuracy and loss on various datasets, such as the training and test sets. Rhino FCP integrates Tensorboard, which is an industry-standard tool for visualization. Tensorboard lets you compare different model versions to select the best-performing candidate, debug poor performance by identifying potential hyperparameter issues, and monitor the training process in real-time to decide when to halt a training run, such as when the model fails to converge over a long period.

With Tensorboard you can:

* Track and visualize metrics such as loss and accuracy
* View model graphs
* Examine histograms of weights, biases, or other tensors
* Display images, text, and audio data

You can securely visualize data from a single Rhino FCP client, from multiple clients, and from the server. You can also view aggregated data from multiple training runs.

### Prerequisites

You will need to the following view Tensorboard on FCP:

* Access to the workgroup
* Access to the project
* Permission to view the analytics of code runs

{% stepper %}
{% step %}

### Specify What Data To Display in Tensorboard

To specify what you want to appear in Tensorboard, you'll need to add a few lines to your code. Typically, we recommend that you import SummaryWriter from the tensorboardX library because it is lightweight, provides only tools for writing TensorBoard logs, and does not require that you install TensorFlow.

{% hint style="info" %}
NOTE: If you are coding NVFlare, it has built-in support for Tensorboard logs (as well as MLFlow and Weights and Biases), so you will not need to complete these steps. Since NVFlare's implementation sends logs to an external server, and Rhino FCP considers the data in these logs to be potentially sensitive, so it is stored locally and is protected by our Secure Access features. For an example of how to specify data to display using NVFlare, see our example in the user resources in the Rhino FCP NVFlare (MIMIC CXR NVFLARE for versions 2.3, 2.4, and 2.5).
{% endhint %}

For an example of how to use SummaryWriter from tensorboardX in your library, see the following.

{% stepper %}
{% step %}
Define a writer that points to the folder where you want the logs to be written, like this.

```auto
from tensorboardX import SummaryWriter

def __init__():
   #add this additional line
   self.tb_writer = SummaryWriter("/tb-logs")
```

{% endstep %}

{% step %}
Add the items you want to see on TensorBoard using the summary writer. In the following example, the items are added using the writer's add\_scalar function.

```auto
def model_training_function():
   #add logging during training for each epoch, and optionally flush at the end of training
   for epoch in range(self._epochs):
      self.tb_writer.add_scalar("local_train_loss_per_epoch", running_loss / images_count,
   self.epoch_global)
   self.tb_writer.flush()

def model_validation_function():
   #add logging for specific model validation metric, e.g.,
   self.tb_writer.add_scalar("global_model_test_loss_per_round", average_loss, current_round)
```

{% endstep %}

{% step %}
Finally, run the code, using one of the following instructions for running a code object: [Python](/creating-and-running-code-objects/creating-and-running-a-python-code-object), [Generalized Compute](/creating-and-running-code-objects/creating-and-running-a-new-generalized-compute-code-object), [Interactive Container](/creating-and-running-code-objects/creating-and-running-interactive-container-code).

For a more comprehensive guide, see this [Tensorboardx Tutorial.](https://tensorboardx.readthedocs.io/en/latest/tutorial.html)
{% endstep %}
{% endstepper %}
{% endstep %}

{% step %}

### Use Tensorboard to View Data from Code Runs

After you've run the code successfully, complete the following steps to view the results on Tensorboard.

{% stepper %}
{% step %}
Create a code object and run the code. Use the guide for your code type.
{% endstep %}

{% step %}
After the code run is completed, select Code Runs from the menu on the left. See one of the following instructions for running a code object: [Python](/creating-and-running-code-objects/creating-and-running-a-python-code-object), [Generalized Compute](/creating-and-running-code-objects/creating-and-running-a-new-generalized-compute-code-object), [Interactive Container](/creating-and-running-code-objects/creating-and-running-interactive-container-code). [Running a Code Object](broken://spaces/ydySyCBmy6F7NnGn4bPa/pages/431e7a0d75a3d7b5e8ccbeea32a5a0e48cfe8695) for more information.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/RX8VwvKxnnV8lSPp3xCZ/25067116137501)
{% endstep %}

{% step %}
Select the Open Tensorboard button on the upper right corner of the page. The Tensorboard page opens. It might take a few seconds for the dashboard to appear.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/64J543b6Obt5WYCexkm2/25067126098589)
{% endstep %}

{% step %}
There are two different dashboards that you can choose.

* **Time Series** - Displays metrics in each iteration. Choose Time Series if you want to analyze and compare multiple time series data.
* **Scalars** - Displays information at the end of each epoch. Choose Scalars if you need to monitor individual scalar metrics.
  {% endstep %}

{% step %}
Select the code runs you want to review from the options on the left. The top-most option allows you to select all of them at once.
{% endstep %}

{% step %}
Choose whether you want to see scalars, images, or histograms (or some combination of the three.) If you want to see all of them, select All.
{% endstep %}

{% step %}
For more information on individual options, see the [Tensorboard Guide](https://www.tensorflow.org/tensorboard/get_started).
{% endstep %}

{% step %}
Note that the connection to the Rhino FCP Tensorboard is available for two hours after the last time that you interact with it.
{% endstep %}
{% endstepper %}
{% endstep %}
{% endstepper %}


# Passing and Using Run Time Parameters in Your Code

If you want to re-use your code, but need to make some small changes without hardcoding them, **Run Parameters** and **Run Secrets** can be very helpful.

#### Passing Run Parameters

When you are ready to run your code, you'll be able to provide parameters in either **RUN PARAMETERS** or **RUN SECRETS**, see a screenshot below and more detail in [What is a Code Object?](/creating-and-running-code-objects/what-is-a-code-object).

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/WCrcpa9jZV8PcEl10bzK/19771670256925)

#### Loading/Using Run Parameters

To use the parameters, simply access them by reading the JSON file in which they are stored. The parameters will be stored in "/input/run\_params.json" and in "/input/secret\_run\_params.json" for **RUN PARAMETERS** and **RUN SECRETS PARAMETERS** respectively. For example, let's say you want to pass "my\_parameter" = 55555, in RUN PARAMETERS. In the UI, you'll set the following RUN PARAMETER:

```json
{"my_parameter": 55555}
```

If you were to write Python code, in your code first you'd read /input/run\_params.json:

```python
parameter_key = "my_parameter"

run_params = {}
run_params_filename = "/input/run_params.json"
try:
  with open(run_params_filename, "r") as run_params_file:
  run_params = json.load(run_params_file)
except IOError:
  logging.error("No params file found")
  sys.exit(1)
except json.JSONDecodeError:
  logging.error("Invalid JSON found in params file")
  sys.exit(1)

if parameter_key not in run_params:
  logging.error(f"Key '{parameter_key}' not found in run parameters")
  sys.exit(1)
```

and last you'd access the value of your parameter as follows:

```python
my_parameter_value = run_params[parameter_key]
```

For RUN SECRETS PARAMETERS the process would be almost identical except that you would set the parameters in the RUN SECRET PARAMETERS input form, and you would read them from /input/secret\_run\_params.json.


# Using External Files at Runtime

This article explains how to use external files in your code run. Your workgroup has a unique cloud storage (an S3 bucket on Rhino Orchestrator) to upload non-sensitive data that might be needed during code run, e.g., open-source large LLM model weights.&#x20;

### Important Sensitive Data Instructions <a href="#id-1-important-sensitive-data-instructions" id="id-1-important-sensitive-data-instructions"></a>

Cloud storage (specified in *Workgroup code and model artifacts storage* section in the instructions that follow) is owned by Rhino.  **Please DO NOT upload sensitive information such as proprietary datasets.** For sensitive data, please use the instructions in [Creating a New Dataset or Dataset Version](https://docs.rhinohealth.com/hc/en-us/articles/12385893636509) instead.

### Overview <a href="#id-2-overview" id="id-2-overview"></a>

For your code to be able to access files while running in your agent we need do 4 steps:

1. Set up a bucket to upload your files
2. Upload files to your designated bucket
3. Reference your files in your code
4. Use your files in a specific run

#### Find the bucket to upload your files <a href="#id-3-find-the-bucket-to-upload-your-files" id="id-3-find-the-bucket-to-upload-your-files"></a>

The bucket is created as part of the onboarding process into the FCP by client request, you can find it in your settings page under Containers & Artifacts.  Here is how to find it.

1. In your project, select the settings button (it looks like a sprocket at the bottom left side of the page.
2. In the Settings menu, which is near the top of the screen on the left side of the window, select Containers & Artifacts. &#x20;
3. Your storage bucket and bucket prefix appear in the *Workgroup code and model artifacts storage* part of the page.

#### Upload files to your designated bucket <a href="#id-4-upload-files-to-your-designated-bucket" id="id-4-upload-files-to-your-designated-bucket"></a>

AWS offers many alternative ways to upload files to an S3 bucket.  We've also provided a script in our user\_resource repository you can use: [upload-file-to-s3.sh](https://github.com/RhinoHealth/user-resources/blob/main/rhino-utils/upload-file-to-s3.sh).

You need to define your S3 credentials and then you can call the script like this:

```auto
./upload-file-to-s3.sh the_folder_to_upload storage_bucket bucket_prefix your_path_in_bucket
```

For the example above, if you wanted to upload files in a local folder (called "local\_folder" in the below example) and store them in a folder in FCP called "my\_files", the command would be:

```auto
./upload-file-to-s3.sh ./local_folder external-files-rhino-health-dev my_files
```

#### Reference your files in your code <a href="#id-5-reference-your-files-in-your-code" id="id-5-reference-your-files-in-your-code"></a>

When creating your code object, you can reference your external files by referencing them in the following path:

```auto
/external_data/the_folder_in_s3_you_want_to_upload_to/filename
```

For the example above, assuming you uploaded \`model\_params.txt\` file under \`my\_files\`, the file would be accessible during runtime in

```auto
/external_data/my_files/model_params.txt
```

An example of Python code to read your file data into a \`text\` variable would look like as follows:

```auto
from pathlib import Path
     text = Path('/external_data/my_files/model_params.txt').read_text()
```

#### Use your files in a specific run <a href="#id-6-use-your-files-in-a-specific-run" id="id-6-use-your-files-in-a-specific-run"></a>

Once your code points to your external files, and the code object is created, you can run the code and specify the files you want to use in your code run. In the UI, you can simply select them from a dropdown

[![](https://docs.rhinohealth.com/hc/article_attachments/19768498689565)](https://docs.rhinohealth.com/hc/article_attachments/19768498689565)

Alternatively, you can also use the SDK. See this [notebook to use external files via SDK](https://github.com/RhinoHealth/user-resources/blob/main/examples/rhino-sdk/runtime_external_files.ipynb) for more details.

<br>


# Viewing and Adjusting Your Settings

The settings section of Rhino FCP allows you to easily view basic information about your account, as well as client mounted storage and SFTP access details. You can also view information about containers and artifacts. If you have administrative access, you can view user management details as well.

## Opening the Settings Screen

To open the settings screen, do the following.

{% stepper %}
{% step %}

#### Select the Profile icon

Select the Profile icon from the bottom left corner in the menu bar.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/qy3niXZAbffWnPf0IBab/35203907556765)
{% endstep %}

{% step %}

#### View the My Account page

By default the My Account page appears. Your name and profile icon appears at the top of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/woX4C9jXC7PFIHryI4uo/35203918044189)
{% endstep %}

{% step %}

#### Review the menu items

You will also see the following menu items.

| Menu Item              | Description                                                                                                                                                                                         |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| My Account             | Contains information about your profile - including your organization and primary workgroup. Allows you to set your Email Password Authentication Settings, and allows you to change your password. |
| Client Mounted Storage | Provides information on your client mounted storage (storage for your data, such as an AWS bucket).                                                                                                 |
| SFTP Access            | Provides details about SFTP access.                                                                                                                                                                 |
| Containers & Artifacts | Provides information on your containers and artifacts.                                                                                                                                              |
| User Management        | Provides information on the users in Rhino FCP (if you have the appropriate accessses).                                                                                                             |
| {% endstep %}          |                                                                                                                                                                                                     |
| {% endstepper %}       |                                                                                                                                                                                                     |

## Viewing Information About Your Account

You can view your organization, primary workgroup, security settings, and Rhino Client information from the My Account page. You can also change your password as well.

* Your profile appears in the My Account page.
* Your initials, organization name, and your primary workgroup appear in the profile section. The primary workgroup is the name that you’ll use for project collaboration and for identifying team datasets and code that belongs to the team.

### Changing Your Password and Enabling Two-Factor Authentication

{% stepper %}
{% step %}

#### Change your password

In the My Account page, in the Email Password Authentication section, there is an option to change the password. To do this select the change password button to open the Change Password page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/EdgGihJURIoInPq4fZ9t/24432720099869)
{% endstep %}

{% step %}

#### Enable two-factor authentication

**\[OPTIONAL]** It is recommended that you enable two-factor authentication (2FA) for additional security. To do this, slide the switch to the right. **ONLY FOR USERNAME/PASSWORD AUTH:** This setting only affects username/password authentication, when authenticating via SSO, 2FA is set by the settings from your SSO provider, which are managed by your IT Admin.
{% endstep %}
{% endstepper %}

## Viewing Your Rhino Client Information

To view information about your Rhino Client including the IP address, complete the following steps.

* In the My Account page, information about your Rhino Client appears in the Your Rhino Client section. If your client is offline, you’ll see a note indicating that you’ll need to contact your IT staff or Rhino support.
* The IP address appears if the Rhino Client is online.

## Viewing and Specifying Client Mounted Storage

For detailed information on how to view and specify client mounted storage, see [Mounting Storage to Your Rhino Client.](/settings/mounting-storage-to-your-rhino-client)

## Viewing Connection Details for SFTP Access

To copy data to or from your Rhino Client, to import datasets, or to access exported datasets and model weights, you’ll need your SFTP connection details. To access them complete the following steps.

{% stepper %}
{% step %}

#### Open the Profile menu

Select the Profile icon from the bottom left corner of any page in the menu bar.
{% endstep %}

{% step %}

#### View the My Account page

By default the My Account page appears. Your name and profile icon appears at the top of the page.
{% endstep %}

{% step %}

#### Open SFTP Access

Select the SFTP Access link on the left side of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/7F33aelczdcjGgNvcggD/35203907557021)
{% endstep %}

{% step %}

#### Check the IP address

The IP Address appears if the Rhino Client is online.
{% endstep %}

{% step %}

#### Reveal credentials

Your credentials used for SFTP data transfer appear under the Credentials heading. Select the button “Reveal Credentials” to view them. The username and password appear.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/etR0xjcp1gKUWSSMLyOh/24432720101917)
{% endstep %}

{% step %}

#### Copy the credentials

Select the copy buttons to the left, one at a time, to copy them to your clipboard.
{% endstep %}
{% endstepper %}

## Viewing Container and Artifact Credentials

Containers & Artifacts show the container registry so that you can run containerized code. You can also obtain artifact credentials.

To view the credentials, complete the following steps.

{% stepper %}
{% step %}

#### Open the Profile menu

Select the Profile icon from the bottom left corner of any page in the menu bar.
{% endstep %}

{% step %}

#### View the My Account page

By default the My Account page appears. Your name and profile icon appears at the top of the page
{% endstep %}

{% step %}

#### Open Containers & Artifacts

Select the Containers & Artifacts link to the left of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/GhnSMJS1frHUn3FZudv1/35203918044829)
{% endstep %}

{% step %}

#### Reveal container registry credentials

To view the credentials, select the Reveal Credentials button under Container Registry Access. The Access Key ID and Secret Access Key appear.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/y7zJCamyNjRt1f3I0n2I/24432720103709)
{% endstep %}

{% step %}

#### Copy the credentials

Select the copy buttons, one at a time, to copy them to your clipboard.
{% endstep %}

{% step %}

#### Access workgroup artifacts

To access data within your code objects, look under the Workgroup code and model artifacts bucket.
{% endstep %}
{% endstepper %}

## Managing Users (User Management)

To learn how to manage users, see [Managing User Accounts in Your Workgroup.](/settings/managing-user-accounts)


# Managing User Accounts

This article explains how to add, edit, and remove user accounts within a workgroup. Users can be part of more than one workgroup. If a user belongs to multiple workgroups, making changes to their account in one workgroup won’t impact their accounts in the others.

## Prerequisite

You must be assigned to the workgroup admin role.

## Select the Workgroup

To choose the workgroup where you'd like to manage user accounts, follow these steps.

{% stepper %}
{% step %}
Select the Workgroups icon from the bottom of the page to see the Select Workgroup switch control. (This is only visible if you are in more than one workgroup.) In the Select Workgroup switch control, the currently-selected workgroup has a check mark next to it.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/e8FwUbtwRyC9PPSA35NX/36091761377821)
{% endstep %}

{% step %}
Select another option to switch workgroups. Note that project lists, federated datasets and other FCP application views/screens will be filtered and scoped to the currently active workgroup.
{% endstep %}
{% endstepper %}

## View User Accounts in the Workgroup

To view user accounts in the workgroup, complete the following steps.

{% stepper %}
{% step %}
Select the sprocket near the bottom of the window to see the Settings menu.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/FNrh4Jkg3qeR0wf2ZRcq/25984799678749)
{% endstep %}

{% step %}
Select **User Management** to open the User Management page. The first and last name, email address, and role for each user in your workgroup is listed.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/FJtgw0W0l922CHRLTJlH/25984619110813)
{% endstep %}

{% step %}
Use the controls at the bottom of the page (arrows) to move forward and backward through the result pages.
{% endstep %}
{% endstepper %}

## Search for a User

If you need to search for a user, go to the User Management page. Then, type any part of the user's first name, last name, email address, or role in the appropriate field in the first row of User Management page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/3T0MgpCkScXGA5v18Uah/25984625609885)

Search results that match what you typed appear in the list.

### Adding a User

To add a user, complete the following steps.

{% stepper %}
{% step %}
Select the **Add User** button, near the top right part of the screen.
{% endstep %}

{% step %}
The Add User screen opens.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/7DpmBgU0uZBcEM8pdX0O/25984625610397)
{% endstep %}

{% step %}
Add the first name, last name, email address, and the role that you want the user to have. Note that all fields must be filled in, the email address must be formed correctly and must not duplicate any other email address in the workgroup.
{% endstep %}

{% step %}
Select **Create** to create the user.
{% endstep %}

{% step %}
When this is complete, an onboarding email is sent to the user.
{% endstep %}
{% endstepper %}

### Editing a User

To edit a user, do the following.

{% stepper %}
{% step %}
Select the three-dot menu for the user, then select **Edit User**. The three-dot menu is on the right side of the user’s role.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/tbAHfCFdiPiu0TgBdx0B/25984619112605)
{% endstep %}

{% step %}
The Edit User screen opens. You can edit the first name, last name, and/role for the user. You cannot edit the email address.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/xqD7R6vs8jJizFkhGvuL/25984619112861)
{% endstep %}

{% step %}
When finished, select **Save**.
{% endstep %}
{% endstepper %}

### Removing a User

To remove a user, do the following.

{% stepper %}
{% step %}
Select the three-dot menu for the user, then select **Remove User**. The three-dot menu is on the right side of the user’s role.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/tbAHfCFdiPiu0TgBdx0B/25984619112605)
{% endstep %}

{% step %}
The Remove User pop up opens. Select **Remove User**.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/aTq45H8RZWmGZRavOus7/25984625612445)
{% endstep %}

{% step %}
The user is removed from the list.
{% endstep %}
{% endstepper %}

### Copying the UID

Copying the UID can be quite helpful if you are using the SDK. To copy the unique identifier (UID) for a user, select the three-dot menu for the user, then select **Copy UID**. The three-dot menu is on the right side of the user’s role.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/tbAHfCFdiPiu0TgBdx0B/25984619112605)


# About Multiple Workgroups

Rhino FCP users can be members of multiple workgroups. A workgroup is the foundational unit of collaboration in the Rhino FCP. When a user is assigned an account by their administrator, they are assigned to a primary workgroup and a role. Once the initial workgroup has been assigned, a workgroup administrator can assign that user to more than one workgroup.

Users who are members of multiple workgroups can:

* Manage different project roles or collaborate with different teams without needing to provision and log out of multiple accounts.
* Be assigned different roles in different workgroups.
* Dynamically switch between active workgroups without requiring a full re-login or re-authentication.

This streamlines the process of switching between workgroups so that you can work more efficiently.

## Switching Between Multiple Workgroups

If you belong to more than one workgroup, select a different workgroup by doing the following.

{% stepper %}
{% step %}
Select the Workgroups icon from the bottom of the page to see the Select Workgroup switch control. (This is only visible if you are in more than one workgroup.) In the Select Workgroup switch control, the currently-selected workgroup has a check mark next to it.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/1q19tbTSxyhuSIlXlm1c/35840696230045)
{% endstep %}

{% step %}
Select another option to switch workgroups. Note that project lists, federated datasets and other FCP application views/screens will be filtered and scoped to the currently active workgroup.
{% endstep %}
{% endstepper %}

## What is the Impact of Switching Between Multiple Workgroups?

If you're part of more than one workgroup, here’s a simple overview of how external mounted storage, SFTP credentials, secure access, hidden collaborators, and privacy are managed.

<details>

<summary>Can Users Be Part of Different Workgroups in Different Organizations?</summary>

Yes. Users belong to workgroups, not organizations. For more information on how to manage user accounts, see [Managing User Accounts.](/settings/managing-user-accounts)

</details>

<details>

<summary>How Do Client-Mounted Storage and SFTP Credentials Work with Multiple Workgroups?</summary>

Each workgroup has its own Rhino Agent. Sometimes a workgroup shares a Rhino Agent with others, and sometimes it doesn’t. If you belong to multiple workgroups, the information you see in the FCP will come from the *workgroup you’re currently active in*.

#### SFTP

If your workgroups use *different* Rhino Agents, you’ll see different SFTP details. If they share the *same* Rhino Agent, the SFTP information might be the same. For more information see [Adding Data to your Rhino Federated Computing Platform (FCP) Client using SFTP.](/getting-started/quick-start-guide/registering-data-to-your-rhino-federated-computing-platform-fcp-client-using-sftp)

#### Client-Mounted Storage

If your workgroups have *different* client-mounted storage destinations, the client-mounted storage details will differ. If they use the *same* client-mounted storage, you’ll see the same information. For more information see [Importing and Exporting Datasets to and from Your Network Storage.](/getting-started/quick-start-guide/importing-and-exporting-datasets-to-and-from-your-network-storage)

</details>

<details>

<summary>How Does Secure Access Work with Multiple Workgroups?</summary>

Secure Access works only if the active workgroup you’re using has access to the data you need. For more information see [What is Secure Access?](/secure-access/what-is-secure-access)

</details>

<details>

<summary>How Do Hidden Collaborators Work with Multiple Workgroups?</summary>

Hiding collaborators is set at the project level. If it’s enabled, you’ll only see your own workgroup and the primary workgroup within a project, based on which workgroup you’re active in. Otherwise, you’ll be able to see all collaborators as usual. For more information see [Permissions.](/projects/persona-and-permissions-policies-reference)

</details>

<details>

<summary>How Does Privacy Work with Multiple Workgroups?</summary>

By default, users are part of only one workgroup. To join another workgroup, a Rhino Staff member or the second workgroup’s Workgroup Admin needs to add you. For more information, see [Managing User Accounts.](/settings/managing-user-accounts)

When you view objects in the system, your permissions depend on the workgroup you’re acting as. For example, if you’re in a project with two workgroups (A and B), and you’re an Admin of A but a Member of B, you won’t be able to perform admin actions on objects belonging to workgroup B.

</details>


# Confidential Computing

Confidential computing is a technology that secures data during processing by preventing unauthorized access or modification. It uses hardware-based Trusted Execution Environments (TEEs) to create isolated, secure areas within a processor for computations. This technology often incorporates attestation, where the TEE provides cryptographic proof that the executing code is authentic and untampered, ensuring only authorized code can access and process the data.

## Configuring Confidential Computing Setting

To use this feature, set the Require Confidential Computing Policy to Yes. For more information on how to do this, see [Specifying a Project's Permissions Policy.](/projects/persona-and-permissions-policies-reference)  After you do this, your code runs will only be executed on your TEE.

## Supported Cloud Environments

Rhino FCP currently offers support for the following cloud environments:

* Amazon Web Services (AWS) [Elastic Cloud Compute ](https://aws.amazon.com/pm/ec2/)(EC2)
* [Google Cloud Platform](https://cloud.google.com/products/compute) (GCP)
* [Microsoft Azure](https://azure.microsoft.com/en-us)
* [Oracle Cloud Infrastructure ](https://www.oracle.com/cloud/)(OCI)


# Mounting Storage to Your Rhino Client

Explains how to mount to supported storage types.

## What is Mounting and Which Types of Storage are Supported?

"Mounting" is the process that an operating system follows to make files and directories in storage (such as a hard drive, network share, or a cloud-based bucket) easily accessible through a system's directory tree. Once mounted, you can easily access the items in the bucket or directory using a client mount path that starts with `/rhino_data`.

You can perform the mount process to the following types of storage:

* Amazon Web Services (AWS) S3 Bucket
* Google Cloud Platform's (GCP) Cloud Storage (CS) Bucket
* Azure Blob Storage (AZ)
* Server Message Block (SMB) network file sharing protocol directories

In addition to mounting storage, this article  explains how to:

* View mount storage configuration
* Test connection and access to the client-mounted storage
* Perform basic troubleshooting for connection and access problems
* How to unmount storage

## Prerequisites

Before you complete these steps, you should have:

* An AWS S3 Bucket, Google Cloud Bucket, Azure Blob container, or an SMB directory already created
* Credentials to connect to the bucket or directory
* Read or Read-Write access for the bucket or directory you want to mount

{% hint style="info" %}
NOTE:  We highly recommend that you verify your access credentials and permissions before completing the steps below.
{% endhint %}

## Mounting an AWS S3 Bucket

To mount an AWS S3 bucket, do the following.

{% stepper %}
{% step %}

#### Select Client Mounted Storage

Select the sprocket from the bottom left corner of the Rhino FCP main page, then select **Client Mounted Storage** from the Settings menu.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/9MqzJPZBNSouf5G51WUT/35204313823773)
{% endstep %}

{% step %}

#### Open Mount Storage

In the **Client Mounted Storage** page, select the **Mount Storage** button from the upper right side of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/AC26G5LHHESJ1nq1UK56/25630299881885)
{% endstep %}

{% step %}

#### Confirm the default type

The **Mount Storage** page opens. The **Type** field has AWS S3 chosen by default.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/WLtlnq1xolnOgtJSq366/25630326459933)
{% endstep %}

{% step %}

#### Enter bucket details

Enter the S3 bucket name in the **Bucket Name** field.

Enter a description. This is optional, but it can help you to remember details about the bucket in the future.

Indicate the path in the **Client Mount Path** field that includes the subfolder to access your cloud data within the Rhino Client (if needed), such as *my\_cloud\_storage\_folder*. The provided bucket will be mapped to the following path: */rhino\_data/external/file storage type/my\_cloud\_storage\_folder*.
{% endstep %}

{% step %}

#### Enter credentials and permissions

Next, indicate the credentials needed to access the AWS S3 bucket. Note that storage hosted in the same VPC as your Rhino Client might not require credentials. You have two choices:

* enter an access key if you've set one up
* access the AWS Profile

If you choose access key, enter the **Access Key ID** and the **Secret Access Key**. You can click the eye icon next to each field to see what you've entered.

Finally, indicate the access permissions by selecting the radio-button: **Read-write** or **Read-only**.
{% endstep %}

{% step %}

#### Create the mount

When finished, click **Create**. An entry appears that shows the **Client Mount Path**, **Access Permission**, and **Test Results**. If there is a problem, an error message will appear.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/oHe8MQYyFTYGFd3eLSim/25630912182685)
{% endstep %}
{% endstepper %}

## Mounting a Google Cloud Storage Bucket

To connect to the Google Cloud Storage bucket, do the following.

{% stepper %}
{% step %}

#### Select Client Mounted Storage

Select the sprocket from the bottom left corner of the Rhino FCP main page, then select **Client Mounted Storage** from the Settings menu.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/9MqzJPZBNSouf5G51WUT/35204313823773)
{% endstep %}

{% step %}

#### Open Mount Storage

In the **Client Mounted Storage** page, select the **Mount Storage** button from the upper right side of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/AC26G5LHHESJ1nq1UK56/25630299881885)
{% endstep %}

{% step %}

#### Confirm the default type

The **Mount Storage** page opens. The **Type** field has AWS S3 chosen by default.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/WLtlnq1xolnOgtJSq366/25630326459933)
{% endstep %}

{% step %}

#### Select Google Cloud Storage

Select **Google Cloud Storage** in the **Type** field.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/ts42nC4LRhq7X7j7A5bE/25630326460189)
{% endstep %}

{% step %}

#### Enter bucket details

Enter the Google Cloud bucket name in the **Bucket Name** field.

Enter a description. This is optional, but it can help you to remember details about the bucket in the future.

Indicate the path in the **Client Mount Path** field that includes the subfolder to access your cloud data within the Rhino Client (if needed), such as *my\_cloud\_storage\_folder*. The provided bucket will be mapped to the following path: */rhino\_data/external/file storage type/my\_cloud\_storage\_folder*.
{% endstep %}

{% step %}

#### Enter credentials and permissions

Next, indicate the credentials that are needed to access the Google Cloud bucket. Note that storage hosted in the same VPC as your Rhino Client might not require credentials. You can click the eye icon next to the field to see what you've entered.

Finally, indicate the access permissions by selecting the radio-button: **Read-write** or **Read-only**.
{% endstep %}

{% step %}

#### Create the mount

When finished, click **Create**. An entry appears that shows the **Client Mount Path**, **Access Permission**, and **Test Results**.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/1ycgSQC75dOhHLD4Sg1Y/25832574822813)
{% endstep %}
{% endstepper %}

## Mounting an Azure Blob Storage Container

To connect to the Azure Cloud Blob Storage container, do the following.

{% stepper %}
{% step %}

#### Open Client Mounted Storage

Select the sprocket icon from the bottom left corner of the Rhino FCP main page, then choose **Client Mounted Storage** from the Settings menu.
{% endstep %}

{% step %}

#### Open Mount Storage

Click **Mount Storage**.
{% endstep %}

{% step %}

#### Select Azure Blob Storage

Select **Azure Blob Storage** in the **Type** field.
{% endstep %}

{% step %}

#### Enter container and account details

Enter the **Container Name**.

Enter the **Storage Account Name**.

Optionally, enter a **Description**.
{% endstep %}

{% step %}

#### Enter mount path and credentials

Indicate the **Client Mount Path**.

Fill out the credentials details (**Account Name**, **Key**, **Resource Group**, and **Subscription ID**) if needed.
{% endstep %}

{% step %}

#### Set permissions and create the mount

Set **Read-write** or **Read-only** permissions.

Click **Create**. ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/mMZYLD8qDLGxMVeylWDB/29441642871069)

An entry appears showing **Client Mount Path**, **Access Permission**, and **Test Results**.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/0vXJCljXSK38T9uSF9rL/29441656789789)
{% endstep %}
{% endstepper %}

## Mounting an SMB Directory

To connect to an SMB directory, do the following.

{% stepper %}
{% step %}

#### Select Client Mounted Storage

Select the sprocket from the bottom left corner of the Rhino FCP main page, then select **Client Mounted Storage** from the Settings menu.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/9MqzJPZBNSouf5G51WUT/35204313823773)
{% endstep %}

{% step %}

#### Open Mount Storage

In the **Client Mounted Storage** page, select the **Mount Storage** button from the upper right side of the page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/AC26G5LHHESJ1nq1UK56/25630299881885)
{% endstep %}

{% step %}

#### Confirm the default type

The **Mount Storage** page opens. The **Type** field has AWS S3 chosen by default.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/WLtlnq1xolnOgtJSq366/25630326459933)
{% endstep %}

{% step %}

#### Select SMB

Select **SMB** in the **Type** field.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/JsMfChfG77npV9YZ4LeN/25630299886749)
{% endstep %}

{% step %}

#### Enter SMB details

Enter the name of the SMB Host device.

Enter the shared folder path.

Enter a description. This is optional but can help you remember details about this storage option in the future.

Indicate the path in the **Client Mount Path** field that includes the subfolder to access your data within the Rhino Client (if needed), such as *my\_smb\_storage\_folder*. The provided bucket will be mapped to the following path in rhino\_data: */rhino\_data/external/file storage type/my\_smb\_storage\_folder*.
{% endstep %}

{% step %}

#### Enter credentials and permissions

Next, indicate the credentials if needed. Storage hosted in the same VPC as your Rhino Client might not require credentials. Enter the username and password in the text fields. You can click the eye icon next to the fields if you want to see what you've entered.

Finally, indicate the access permissions by selecting the radio-button: **Read-write** or **Read-only**.
{% endstep %}

{% step %}

#### Create the mount

When finished, click **Create**. An entry appears that shows the **Client Mount Path**, **Access Permission**, and **Test Results**. If there is a problem, an error message will appear.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/oHe8MQYyFTYGFd3eLSim/25630912182685)
{% endstep %}
{% endstepper %}

## Showing Configuration

To show the configuration for the client mount storage, do the following.

{% stepper %}
{% step %}

#### Open the entry menu

Select the three-dot menu on the right side of the entry.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/hOlCFXfLAWM4jjonrirA/25630912183197)
{% endstep %}

{% step %}

#### Show the configuration

Select **Show Configuration** to show the Mount Storage Configuration page.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/K1ryxvR3XLlAGRtXCFZC/25832574823325)
{% endstep %}
{% endstepper %}

## Testing Data Access

To test access to the client mount storage point, do the following.

{% stepper %}
{% step %}

#### Open the entry menu

Select the three-dot menu on the right side of the entry.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/hOlCFXfLAWM4jjonrirA/25630912183197)
{% endstep %}

{% step %}

#### Test access

Select **Test Access** to start the test. The test results are updated. Results can be one of the following.
{% endstep %}
{% endstepper %}

* The green circle with a checkmark, as shown below, indicates that Rhino FCP can connect to the bucket or folder. It also indicates that it can access file data at the level of permission you indicated (either read or read-write).

  ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/1ycgSQC75dOhHLD4Sg1Y/25832574822813)
* The yellow circle with an exclamation mark, as shown below, indicates that Rhino FCP can connect to the bucket or folder. But, it cannot access that bucket or folder's file data at the level of permission you indicated (either read or read-write).

  ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/5G464GT5rsf9x84hp6W0/25832574824605)
* The red circle with an exclamation mark, as shown below, indicates that Rhino FCP cannot connect to the bucket or folder.

  ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/uwds16glGQEh206cipA6/25832601742237)

## Troubleshooting

Here are some steps for troubleshooting connection and permissions issues.

{% stepper %}
{% step %}

#### Check the configuration

Select the three-dot menu to the right, then select **Show Configuration**. Ensure that the bucket or folder name is correct. If it is incorrect, follow the instructions to unmount client storage then mount the bucket or directory again.
{% endstep %}

{% step %}

#### Test your credentials and permissions

Test your credentials. Using the credentials you entered in Rhino FCP, use another method to access the bucket or folder. For example, use Amazon CLI or the Amazon and the credentials that you provided to access an S3 bucket or use the Google Cloud Console or CLI and the credentials you provided to access a Google Cloud bucket.

* If you cannot connect, verify the credentials, then try to access it again.
* Next, check permissions. Try reading a file once you have connected, then if you want to write to mounted storage, try writing to a file.
  {% endstep %}

{% step %}

#### Mount again with updated configurations

Once you have successfully completed these steps, follow the instructions to mount the bucket or directory again, updating your configurations based on your findings in the first and second steps. Note that you will need to follow the instructions to unmount client storage. Then, you will need to mount the bucket or directory again.
{% endstep %}

{% step %}

#### Review other references

Other troubleshooting references are:

* Troubleshooting Google Cloud Platform, Google Cloud bucket connection issues:

  <https://cloud.google.com/storage/docs/troubleshooting>.
* Troubleshooting AWS S3 bucket connection issues:

  <https://docs.aws.amazon.com/AmazonS3/latest/userguide/troubleshoot-403-errors.html>.
* You can also contact Rhino Support for more help.
  {% endstep %}
  {% endstepper %}

## Unmounting Storage

To remove the mount to the storage, complete the following steps.

{% stepper %}
{% step %}

#### Open the entry menu

Select the three-dot menu on the right side of the entry.

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/hOlCFXfLAWM4jjonrirA/25630912183197)
{% endstep %}

{% step %}

#### Unmount storage

Select **Unmount** to remove the mount point for the storage.
{% endstep %}
{% endstepper %}


# Security at Rhino FCP

Security and privacy are foundational to the **Rhino Federated Computing Platform (Rhino FCP)**. Rhino FCP is designed to enable organizations to collaborate on sensitive data while allowing data custodians to maintain control over their data and computing environments.

## Federated Approach

Unlike traditional approaches that require organizations to centralize or transfer data to a shared environment, Rhino FCP brings computation to where the data already resides.

Data is processed locally within the data custodian's environment, whether deployed on-premises or in the cloud. This allows organizations to collaborate on analytics, AI, machine learning, and other computational workloads without requiring raw data to be transferred to collaborators or centrally stored by Rhino.

This architecture allows organizations to maintain their existing security controls and data governance practices while participating in collaborative workflows.

## Defense in Depth

Rhino FCP uses multiple layers of security and privacy controls to protect data, workloads, and platform resources.

Key capabilities include:

* **Role-based access control (RBAC)** to govern access to data, workloads, and platform functionality.
* **Encryption** to protect sensitive information and platform resources.
* **Comprehensive audit logging** to provide visibility and accountability for activity within the platform.
* **Secure containerized execution**, allowing custom workloads to execute close to the data while providing an isolated environment for processing.
* **Privacy-enhancing technologies**, including support for techniques such as [differential privacy](/security-and-data-protections/differential-privacy), k-anonymization, and [homomorphic encryption](/security-and-data-protections/fully-homomorphic-encryption).

Together, these controls help organizations limit access to sensitive resources and maintain oversight of how data and workloads are used.

For more information, see [Platform Security Measures](/security-and-data-protections/platform-security-measures).

## Data Sovereignty and Privacy

Rhino FCP is designed around the principle that organizations should retain control of their data.

Because workloads execute where the data resides, organizations can participate in multi-site and cross-organizational projects without first moving their raw data into a centralized repository. Only the permitted outputs of a computation need to be shared between participating environments.

This approach can help organizations reduce unnecessary data movement and support data sovereignty requirements across different organizations, cloud environments, and geographic regions.

## Compliance

Rhino maintains an information security and compliance program designed to support organizations operating in highly regulated environments.

Rhino FCP adheres to security and privacy standards and frameworks including:

* **ISO 27001**
* **SOC 2 Type II**
* **HIPAA**
* **GDPR**

## Learn More

For additional information about Rhino's security practices, compliance program, and available security documentation, visit the **Rhino Federated Computing Trust Center** at [**trust.rhinofcp.com**](https://trust.rhinofcp.com).

Or contact us at <security@rhinofcp.com>&#x20;


# Platform Security Measures

The Rhino Client typically resides behind the institution firewall (in the case of installation in a VPC, the institution firewall is considered to be inclusive of the VPC).

The Rhino Client can be installed on a virtual machine (VM), physical server, or cloud instance provided by the institution, or it can be installed on a physical server provided to the institution by Rhino (a Rhino Box). With Rhino Boxes, Rhino has more control over the security measures that are defined at the hardware and OS level.

### No Direct Server Access

The server on which the Rhino Client is installed does not allow any users to login locally or via SSH. The only users configured on the host OS are for copying data to the server using SFTP to specific directories within the server (e.g. to provide the Rhino Client access to cohort data that was prepared by someone at the institution), and for system maintenance.

Users of the Rhino Platform have no direct access to the server on which the Rhino Client is installed.

This security measure is enforced for ‘Rhino Boxes’, and is strongly recommended for VMs, servers, cloud instances provided to Rhino by an institution, but is ultimately defined by the institution IT.

### No Inbound Ports

The Rhino Client does not require any inbound ports to be opened in the institution firewall. All communication is performed outbound from the Rhino Client to the Rhino Orchestrator.

### Data Encrypted at Rest

The server on which the Rhino Client is installed has hard-drive encryption such that all data is encrypted at rest.

This security measure is enforced for ‘Rhino Boxes’, and is strongly recommended for VMs, servers, cloud instances provided to Rhino by an institution, but is ultimately defined by the institution IT.

### Data Encrypted in Transit

All communication between the Rhino Client and the Rhino Orchestrator is encrypted using strong industry standard TLS based encryption methods.

### Anti-Malware

Customers can apply the anti-malware solution of their choice to the Rhino Client, so long as it can be installed on the server that is hosting the Rhino Client (usually running Ubuntu Server 20.04 LTS or RHEL 8). Good general practice should be exercised to ensure there is minimal impact on the performance of the Rhino Client.

### Code/Model Guardrails

The code (e.g. models or Generalized Compute code) run in the Rhino Client are run as docker containers that are tightly locked down. No communication is allowed, neither inbound or outbound, except for communication with the Federated Server for FL. This Federated Server is provisioned by Rhino for each FL training run and provided with SSL certificates to securely authorize the Federated Clients that are allowed to connect to it.

All inputs and outputs from the code/models are controlled by the Rhino Client and are all stored only within the Rhino Client except for: model weights shared during the FL process (see below for additional security measures used to prevent patient data from being exposed through model weights), and aggregate data from the resulting cohort/training results.

## Rhino Orchestrator Security

The Rhino Orchestrator runs on AWS, utilizing many of the security capabilities provided by AWS (e.g. IAM, KMS, Secrets Manager, Shield, Network Firewall).

### Data Encrypted at Rest

Databases and physical disks utilized in the Rhino Orchestrator are encrypted at rest.

### Data Encrypted in Transit

All communication with the Rhino Orchestrator (both inbound and outbond) is encrypted using strong industry standard TLS based encryption methods.

All communication between the Rhino Web UI and the Rhino Orchestrator happens over HTTPS.

### User Identity and Access Management

Accounts for new users of the Rhino Platform are provisioned by Rhino. Users are assigned specific roles in specific workgroups based on a list of users/roles provided by the institution. Role based permissions are applied in each project in which the user participates. User activity is logged within the system and major user actions like creating a new project, adding a collaborator to a project, importing cohort data, etc. are displayed in a visual log.

### User Authentication

End user access to the Rhino Orchestrator is controlled using username/password with a secure policy:

1. Users must change their passwords every 90 days without reusing recent passwords.
2. Passwords must be at least 8 characters in length and must include at least one upper case letter, one lower case letter, one numeric character, and one special symbol.
3. Two-Factor Authentication (2FA) can be enabled/required using any authentication app.
4. The last 10 passwords cannot be reused.
5. Repeated unsuccessful login attempts are logged and monitored. An incrementally longer backoff period is applied after every unsuccessful login attempt.
6. Platform sessions timeout automatically after 12 hours.

It is also possible to use SSO to authenticate users with 3rd party authentication providers such as Google and Azure AD.

### Role Based Permissions

Each project in the Rhino Platform defines a set of role based user permissions, usually defined by the project lead and agreed to by all participants. For example - which users are allowed to train a model, which users are allowed to view the results of model training, etc. These permissions are enforced in the Rhino Orchestrator such that each user only has access to data and actions that are allowed by the project permissions.

Project participants are allowed to opt-out of specific project permissions. For example - even if the project permissions define that aggregate data from cohorts will be sent from the Rhino Client to the Rhino Orchestrator , a participant can opt-out of this such that aggregate data from their cohorts will not be sent to the Rhino Orchestrator .

Users do not have any access to projects in which they are not a participant.

### Data Schema Permissions

Each data schema in the Rhino Platform can include field-level permissions. For example - defining that a cohort field corresponding with a specific data schema field will never send aggregate data from the Rhino Client to the Rhino Orchestrator.

### Event Logging

Rhino logs user actions within the system for security and auditability. Major actions like creating a new project, adding a collaborator to a project, importing cohort data, etc. are logged and displayed in a visual log. Security events like failed login attempts are logged and these logs are reviewed regularly by Rhino staff.

### Cloud Server/Service Access

Access to the AWS servers and services on which the Rhino Orchestrator is run is controlled by AWS IAM roles with strict policies around authentication (password strength, 2FA, etc.) and is only provided to the Rhino employees who need access to maintain these services. These employees must use a VPN in order to connect to AWS.

Note that no patient data is ever stored in the cloud, so this only provides these Rhino employees with access to project config/metadata.

### Intrusion Detection System (IDS)

The Rhino Orchestrator utilizes an Intrusion Detection System (Guard Duty) to identify suspicious activity on the Rhino Orchestrator and notify the Rhino admins.

### Vulnerability Scanning and Penetration Testing

All Rhino servers are scanned for vulnerabilities using AWS Inspector on an ongoing basis. All container images used by Rhino and provided to Rhino by users are scanned for vulnerabilities using AWS Inspector on an ongoing basis.

In addition, vulnerability scans are performed regularly on the Rhino user interfaces

An external penetration test is performed periodically to identify any potential vulnerabilities.

### Software Supply Chain Defense

The Rhino Platform’s code is hosted on Github where access is limited to the engineers developing the platform and MFA is required. 3rd party libraries are validated against specific signatures to prevent library injection attacks. The build process is executed on self-hosted runners, which helps protect against supply chain attacks on the build process.


# Differential Privacy

#### Overview

Differential privacy is a technique that adds "noise" to data to protect the privacy of individual records. It makes it challenging to extract information about specific individuals while still providing useful statistical insights. Using the FCP, you can set the level of noise added by your chosen privacy settings, depending on the sensitivity of the data.

#### Differential Privacy Enforcement Levels

{% hint style="info" %}
These differential privacy levels apply specifically to rhino-specific **aggregated statistics**.&#x20;

For **federated model training**, differential privacy is handled separately through NVIDIA FLARE (NVFlare).
{% endhint %}

Rhino FCP offers four privacy enforcement levels:

* **None:** No noise will be added. Suitable for projects where no privacy constraints are required.
* **Low:** Single-element metrics (e.g., percentiles) will always have noise added, but aggregate statistics (e.g., mean, standard deviation) will not. Suitable for projects with a moderate privacy requirement while allowing accurate aggregate statistics.
* **Medium:** Single-element metrics (e.g., percentiles) will always have noise added, and aggregate statistics (e.g., mean, standard deviation) will have noise added if the unique values they are based on aren't diverse (`num_unique_values < k`). Suitable for most common projects.
* **High:** All values will have some noise added, even if they are sufficiently aggregated. Suitable for projects with a strong privacy requirement, sacrificing some data accuracy for increased privacy.

| Metric                                            | None           | Low                                                                                                                                                                                                                               | Medium                                                                                                                                                                                                                            | High                                      |
| ------------------------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
| Percentile                                        | No noise added | Noise added                                                                                                                                                                                                                       | Noise added                                                                                                                                                                                                                       | Noise added                               |
| <p>Mean<br>Standard Deviation<br>Sum<br>Count</p> | No noise added | No noise added                                                                                                                                                                                                                    | Noise is added if `num_unique_values` is smaller than the project's *k anonymity factor*                                                                                                                                          | Noise added                               |
| Kaplan Meier                                      | No noise added | Noise is added to the time values, solely to aggregated times which are created by combining time intervals when the number of events falls below the *k anonymity factor*. For more details, see the Kaplan Meier documentation. | Noise is added to the time vector, solely to aggregated times which are created by combining time intervals when the number of events falls below the *k anonymity factor*. For more details, see the Kaplan Meier documentation. | Noise is added to all of the time values. |

#### Configuring Differential Privacy

To configure the differential privacy enforcement level for a project:

1. **Create a New Project**: When creating a new project, select the desired "Differential Privacy Enforcement" setting (None, Low, Medium, High).
2. **Existing Projects**: Existing projects have a DP enforcement level of "Medium" unless configured otherwise.


# Fully Homomorphic Encryption

The Rhino Federated Computing platform supports **Fully Homomorphic Encryption** (FHE) via the NVFlare framework (and the TenSEAL package).&#x20;

To enable FHE in your model training, you will need to perform **two actions**:

1. Install NVFlare with FHE support in your container image, by installing `nvflare[HE]` rather than plain `nvflare` (see details in [the NVFlare docs](https://nvflare.readthedocs.io/en/main/installation.html#optional-dependencies)).
2. Modify your NVFlare configurations to include FHE filters and / or arguments (see examples from NVFlare for [PyTorch](https://github.com/NVIDIA/NVFlare/blob/main/examples/tutorials/self-paced-training/part-3_security_and_privacy/chapter-5_Privacy_In_Federated_Learning/05.3_homomorphic_encryption/05.3.1_privacy_with_homormorphic_encryption.ipynb) and [XGBoost](https://github.com/NVIDIA/NVFlare/tree/main/examples/advanced/xgboost/fedxgb_secure))
3. Enable homomorphic encryption in your Code Runs below
4. You can find a notebook with an example in the [Rhino FCP User-Resources](https://github.com/RhinoHealth/user-resources/tree/main/examples/nvflare/xgboost/xgboost-fhe)

## Enabling homomorphic encryption in Rhino FCP Code Runs

{% stepper %}
{% step %}

#### Navigate to your Code Objects page

{% endstep %}

{% step %}

#### Select “run” for an NVFlare Code Object, expand the configuration options

{% endstep %}

{% step %}

#### Select “enable homomorphic encryption” and enter parameters (use “{}” to use defaults)

{% endstep %}

{% step %}

#### Select “Run Training”

{% endstep %}
{% endstepper %}


# How To Use the Secrets Manager with Rhino FCP

To ensure the Rhino FCP can retrieve the correct secret for a Code Run, the secret's key ID in the Secrets Manager **must exactly match the tag of the container image** being executed. *Example:* If your container image is tagged `v1`, the corresponding secret in the Secrets Manager must also have the tag `v1`.

During a Code Run execution, the Rhino FCP dynamically injects the retrieved secret into the running container at a specific, standardized location:

* **Injection Path:** The secret is provided as a JSON file named `secret_run_params.json` at the absolute path: `/input/secret_run_params.json`.
* **Runtime Access:** The container's code, e.g. `decrypt_weights` function, accesses this file at runtime to securely retrieve the necessary keys (e.g., `decrypt_key` or `encrypt_key`). Note that the function used here (`decrypt_weights`) is just an example. But, there should be a file inside the container should be used for decrypting.


# MCP Getting Started

The Rhino FCP MCP Server connects any AI assistant directly to the Rhino Federated Computing Platform. Through natural language, you can run federated analytics, explore datasets, execute code, and monitor jobs — all without raw data ever leaving your sites.

This section covers everything you need to get started and use the MCP server effectively.

***

### What You Can Do

The MCP server exposes 8 capability areas, each mapped to a set of tools your AI assistant can invoke:

| Capability Area    | What You Can Do                                                                                              |
| ------------------ | ------------------------------------------------------------------------------------------------------------ |
| **Authentication** | Login, confirm identity, verify connectivity                                                                 |
| **Projects**       | List, inspect, create, and delete federated projects                                                         |
| **Datasets**       | Register, sync, profile, compare, and delete datasets — including federated datasets spanning multiple sites |
| **Queries**        | Run mean, Kaplan-Meier, Cox PH, Table 1, chi-square, SQL, and more via a single unified tool                 |
| **Execution**      | Upload Python code objects, execute them across sites, launch NVFlare training jobs                          |
| **Monitoring**     | Check run status, stream logs, list recent runs, halt jobs                                                   |
| **Collaboration**  | List, invite, and remove collaborators; check site connectivity and workgroup health                         |
| **Harmonization**  | Manage schemas, browse vocabularies, apply semantic and syntactic mappings, run full pipelines               |

***

### Privacy and Data Safety

Privacy is enforced at the platform level. All results returned by the MCP server are **aggregated** — raw patient data never leaves hospital sites. You will never see individual patient records through any MCP tool.

The MCP server enforces the same access permissions as the Rhino FCP platform itself. Each user authenticates with their own account and sees only the projects and data they are authorised to access.

***

### Base URL

The MCP server endpoint is:

```auto
https://mcp.rhinohealth.com/mcp
```


# Prerequisites and Authentication

This article covers authentication and, for some clients, an optional software prerequisite. Authentication uses OAuth 2.1 with PKCE — your credentials never appear in the AI chat and the assistant never sees your password.

***

### Optional: Install Node.js

Node.js is **not required to use the Rhino FCP MCP server**. Most recommended clients — including Claude Desktop, Claude Code CLI, Cursor IDE, and VS Code — connect via native HTTP and have no additional dependencies.

Node.js v18 or higher is only needed if you are connecting via **Windsurf** or another stdio-only client that uses the `mcp-remote` bridge. If none of the clients you are using require it, skip this section entirely.

{% tabs %}
{% tab title="macOS" %}

```auto
# Using Homebrew:
brew install node

# Or download the installer from:
# https://nodejs.org/en/download
```

{% endtab %}

{% tab title="Windows" %}

```auto
# Using winget:
winget install OpenJS.NodeJS

# Or download the .msi installer from:
# https://nodejs.org/en/download
```

{% endtab %}

{% tab title="Linux (Ubuntu / Debian)" %}

```auto
sudo apt update
sudo apt install nodejs npm

# Or use nvm:
# https://github.com/nvm-sh/nvm
```

{% endtab %}
{% endtabs %}

#### Verify your installation

Run the following in your terminal. You should see **v18 or higher**.

```auto
node --version
```

***

### How Authentication Works

The MCP server uses **OAuth 2.1 with PKCE** — the same secure standard used by Google, GitHub, and other major platforms. The flow is automatic and works the same way across all supported clients:

1. **Add the server URL** — Configure your AI client with the MCP endpoint (see [Supported Clients](/using-the-rhino-mcp-server/supported-clients)).
2. **Browser login** — On the first tool call, OAuth opens your default browser and presents the Rhino Health login page.
3. **Token issued** — A secure token is returned to your AI client automatically.
4. **Ready to use** — All subsequent tool calls use the token without any further action needed.

Your credentials never appear in the AI chat window. The AI assistant never sees your password.

***

### Token Expiry

If your session token expires, you will see a `NOT_AUTHENTICATED` error. To resolve this, restart your AI client — the OAuth login flow will trigger automatically on the next tool call. No configuration changes are needed.


# Supported Clients

The Rhino FCP MCP server supports any AI client that implements the Model Context Protocol. This article provides step-by-step setup instructions for each supported client.

All clients use the same production endpoint: `https://mcp.rhinohealth.com/mcp`

For environment-specific URLs (staging, QA, dev), see [Environments, Troubleshooting & FAQ](/using-the-rhino-mcp-server/mcp-environments-troubleshooting-faqs).

### Claude Desktop

**Transport:** Native HTTP | **Node.js required:** No | **Difficulty:** Easiest

Claude Desktop has a built-in connector UI — no config file needed.

{% stepper %}
{% step %}

#### Open Settings

Open Claude and click your user icon in the bottom left. Click **Settings → Connectors**. Alternatively, click **Customize → Connectors**.
{% endstep %}

{% step %}

#### Add a custom connector

Click the **+** icon and select *Add custom connector*. Enter the following details and click **Save**:

* **Name:** `Rhino FCP`
* **URL:** `https://mcp.rhinohealth.com/mcp`
  {% endstep %}

{% step %}

#### Authenticate

Click **Connect**. A browser window will open — first connecting to Claude on the web, then presenting the Rhino Health login page. Enter your credentials.
{% endstep %}
{% endstepper %}

### Claude Desktop — Dev Mode (Config File)

**Transport:** Native HTTP via mcp-remote | **Node.js required:** Yes | **Difficulty:** Intermediate

For advanced users who prefer editing the config file directly.

{% stepper %}
{% step %}

#### Locate the config file

Find `claude_desktop_config.json` in the following location for your operating system:

* **macOS:** `~/Library/Application Support/Claude/`
* **Windows:** `%APPDATA%\Claude\`
* **Linux:** `~/.config/Claude/`
  {% endstep %}

{% step %}

#### Add the server entry

Edit `claude_desktop_config.json` and add the following block:

```json
{
  "mcpServers": {
    "rhino-health": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://mcp.rhinohealth.com/mcp"
      ]
    }
  }
}
```

{% endstep %}

{% step %}

#### Restart and authenticate

Quit Claude Desktop (**Cmd+Q** on macOS) and reopen it. Look for the **hammer icon** in the chat input. Ask *"List my Rhino Health projects"* — your browser will open for OAuth login.
{% endstep %}
{% endstepper %}

### Claude Code CLI

**Transport:** HTTP | **Node.js required:** No | **Difficulty:** Easy

No config file needed — everything is managed via the CLI.

{% stepper %}
{% step %}

#### Add the server

Run the following command in your terminal. Use `--scope user` to make the server available globally across all projects:

```bash
claude mcp add \
     --transport http \
     rhino-health \
     https://mcp.rhinohealth.com/mcp

# Scope options:
#   --scope user     (global — available in all projects)
#   --scope project  (default — current project only)
```

{% endstep %}

{% step %}

#### Verify registration

Run the following to confirm `rhino-health` appears in your server list:

```bash
claude mcp list
```

{% endstep %}

{% step %}

#### Authenticate

Start a Claude session and ask a Rhino question. Your browser will open automatically for OAuth login:

```bash
claude
> "List my Rhino Health projects"
```

{% endstep %}
{% endstepper %}

### Cursor IDE

**Transport:** Native HTTP (Streamable HTTP) | **Node.js required:** No | **Difficulty:** Easy

{% stepper %}
{% step %}

#### Open MCP Settings

Go to Cursor Settings → MCP → click *"+ Add new global MCP server"*. Select type: **Streamable HTTP**.
{% endstep %}

{% step %}

#### Add the server

Alternatively, create or edit the config file directly:

* Global config: `~/.cursor/mcp.json`
* Per-project config: `.cursor/mcp.json`

```json
{
  "mcpServers": {
    "rhino-health": {
      "url": "https://mcp.rhinohealth.com/mcp"
    }
  }
}
```

{% endstep %}

{% step %}

#### Restart and authenticate

Quit and reopen Cursor. Open Agent mode (**Cmd+L**) and ask *"List my Rhino Health projects"*. A **green indicator** in MCP settings confirms you are connected.
{% endstep %}
{% endstepper %}

### VS Code + GitHub Copilot

**Transport:** HTTP | **Node.js required:** No | **Requires:** VS Code 1.99+ and an active GitHub Copilot subscription

{% stepper %}
{% step %}

#### Create the config file

Create `.vscode/mcp.json` in your workspace root. Alternatively, use the Command Palette → *MCP: Open Workspace Folder MCP Config*:

```json
{
  "servers": {
    "rhino-health": {
      "type": "http",
      "url": "https://mcp.rhinohealth.com/mcp"
    }
  }
}
```

{% endstep %}

{% step %}

#### Restart VS Code

Restart VS Code to load the new MCP configuration.
{% endstep %}

{% step %}

#### Enable Agent mode

Open Copilot Chat (**Ctrl+Shift+I**) and switch to **Agent mode** using the dropdown at the top of the chat panel.
{% endstep %}
{% endstepper %}

### Windsurf

**Transport:** mcp-remote bridge | **Node.js required:** Yes (npx must be on PATH) | **Difficulty:** Intermediate

Windsurf uses the `mcp-remote` bridge. Ensure Node.js is installed before proceeding (see [Prerequisites and Authentication](/using-the-rhino-mcp-server/prerequisites-and-authentication)).

{% stepper %}
{% step %}

#### Open MCP Config

Click the hammer icon in the Cascade toolbar → **Configure**. Or edit the config file directly:

* **macOS:** `~/.codeium/windsurf/mcp_config.json`

```json
{
  "mcpServers": {
    "rhino-health": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://mcp.rhinohealth.com/mcp"
      ]
    }
  }
}
```

{% endstep %}

{% step %}

#### Restart and authenticate

Restart the IDE. Open Cascade chat and ask a Rhino question — mcp-remote will open your browser for OAuth login.
{% endstep %}
{% endstepper %}

<details>

<summary>Using a Different Client?</summary>

The clients listed above are the ones Rhino officially documents and tests against. However, the MCP server uses the open Model Context Protocol standard, so it is compatible with a much broader range of AI assistants and coding tools.

If your client is not listed here, the general connection details are:

* **Server URL:** `https://mcp.rhinohealth.com/mcp`
* **Transport:** Streamable HTTP (preferred) or stdio via `mcp-remote`
* **Authentication:** OAuth 2.1 with PKCE — handled automatically on first use

Consult your client's documentation for instructions on adding a custom MCP server. Most clients that support MCP will have a settings panel, config file, or CLI command for this.

If you run into issues connecting a client that isn't listed above, contact <support@rhinohealth.com> and include your client name, the error message, and the result of the health check (`curl https://mcp.rhinohealth.com/health`).

</details>


# Projects, Collaboration Datasets, and Data Schemas

This article describes what you can do with the Rhino MCP connection in the **Projects** and **Datasets** capability areas, with example prompts for each action. For Authentication, see [Prerequisites and Authentication](/using-the-rhino-mcp-server/prerequisites-and-authentication).

***

### Projects

Projects are the top-level organisational unit in Rhino FCP. Each project contains datasets, code objects, runs, and a set of collaborating sites. You can list, inspect, create, and delete projects through natural language.

#### Listing and viewing projects

Ask your AI assistant to show you the projects you have access to, or to get details on a specific project.

* *"List my Rhino projects."*
* *"What projects do I have access to?"*
* *"Show me the details for the Multi-site Oncology Study project."*
* *"How many sites are in my cardiology project?"*

#### Creating a project

Ask your assistant to create a new project in your workgroup. You can provide a name and an optional description.

* *"Create a new project called 'Diabetes Cohort Study'."*
* *"Set up a new Rhino project for our Q3 multi-site trial. Give it a description explaining it covers sites in the EU and US."*

#### Deleting a project

Project deletion is permanent — all job history, collaborator settings, and configuration will be lost. Datasets stored at sites are not affected.

* *"Delete the 'Pilot Study 2023' project."*

***

### Datasets

Datasets represent data files registered within a project. They can be local (single-site) or federated (spanning multiple sites). The MCP server lets you list, register, sync, profile, compare, and remove datasets through conversation.

#### Listing and exploring datasets

Ask your assistant to show datasets available in a project, or to retrieve the schema of a specific dataset.

* *"What datasets are available in the oncology project?"*
* *"What are the column names and types in the 'patient\_cohort\_2024' dataset?"*
* *"Show me the schema for the admissions dataset."*

#### Registering a dataset

You can register a file that already exists at a site as a dataset in the platform, or create a federated dataset that spans multiple sites.

* *"Register the file at '/data/cohort\_jan2025.csv' as a new dataset called 'Cohort Jan 2025' in the oncology project."*

#### Profiling a dataset

Generate a statistical profile to understand your data before running analytics. Profiling returns null rates, value distributions, and summary statistics without exposing any raw rows.

* *"Profile the 'patient\_cohort\_2024' dataset."*
* *"Give me a statistical summary of the age, gender, and diagnosis columns in the admissions dataset."*
* *"What percentage of values are missing in each column of the trial dataset?"*

#### Comparing datasets

Compare datasets — or the same dataset across sites — to check for distribution drift, schema differences, or cohort divergence before running federated analytics.

* *"Compare the baseline and follow-up datasets for distribution differences."*
* *"Check whether the admissions data is consistent across all three sites."*
* *"Are there any schema mismatches between the two cohort datasets?"*

#### Deleting a dataset

Deleting a dataset removes the platform record only — the underlying file at the site is not affected.

* *"Delete the 'old\_cohort\_2022' dataset from the project."*
* *"Remove the federated admissions dataset."*

***

### Collaboration

Collaboration tools let you manage who has access to a project and check the health of your federated network before running jobs.<br>

#### Viewing and managing collaborators

List all collaborators on a project, invite new users or sites, or remove access for someone who should no longer be on the project.

* "Who has access to the oncology project?"

#### Checking workgroup and site connectivity

Before submitting a long-running federated job, check that all required sites are online and reachable.

* "Are all sites in project Xmy workgroup online?"
* "Check the connectivity status of the sites in the oncology project before I run the analysis."


# Harmonization via MCP

Provides a basic overview of available harmonization capabilities and how to accomplish them using the Rhino MCP.

This article describes what you can do in the **Harmonization** capability area, with example prompts for each action.

Rhino's [Harmonization](/data-harmonization/overview) tools allow you to map source datasets from participating sites to a target schema or standard medical vocabulary (e.g., OMOP, FHIR), and perform transformations in a federated manner. The raw and transformed data stay at each site — no data is centralised at any point.

{% hint style="warning" %}
If you do not have the required permissions, you will not be able to perform the following actions.
{% endhint %}

## Managing schemas

[Schemas](/data-schemas/what-is-a-data-schema) define the structure that source and target data are mapped to. You can list, inspect, create, and delete schemas through conversation.

* *"What data schemas are available in my workgroup?"*
* *"Show me the columns defined in the OMOP patient target."*
* *"Create a new target schema called 'Standard Admissions' with columns for patient\_id, admission\_date, diagnosis\_code, and los\_days."*
* *"Delete the 'Draft Schema v1' schema."*

## Browsing custom vocabularies

Look up standard custom concepts that have been added before constructing mappings. Or, you can upload your own [custom vocabulary](/data-harmonization/semantic-mapping/custom-vocabularies). Some example vocabularies that you might want to add include OMOP CDM, SNOMED CT, ICD-10, LOINC, and RxNorm.

* *"Find the SNOMED concept ID for 'type 2 diabetes mellitus'."*
* *"Look up ICD-10 codes related to heart failure."*
* *"What is the LOINC code for serum creatinine?"*
* *"Search the RxNorm vocabulary for metformin."*

## Creating semantic mappings

Use AI-assisted [semantic mapping](/data-harmonization/semantic-mapping) to generate suggested mappings from your source dataset column values to standard vocabulary concepts. Suggestions come with confidence scores for you to review before applying.

* *"Which columns in my dataset need vocabulary-based term mapping to fit the target schema?"*
* *"Create a semantic mapping for the diagnosis\_code column using the ICD vocabulary."*
* *"Is my semantic mapping for the diagnosis codes ready to use?"*

## Creating syntactic mappings

[Syntactic mapping](/data-harmonization/syntactic-mapping) defines the structural field-level mapping between your source dataset's columns and the target schema's columns, independent of medical concept meaning.

* *"Create a syntactic mapping from my admissions dataset to the Standard Admissions schema."*
* *"Auto-generate the field transformations for the Standard Admissions syntactic mapping."*
* *"Show me the current configuration of the Standard Admissions syntactic mapping."*
* *"The date format transformation is wrong - change it to use ISO 8601 format in the Standard Admissions mapping."*
* *"Update the description of the Standard Admissions mapping to 'Admissions to OMOP v2'."*

## Running the harmonization pipeline

Once your semantic and syntactic mappings are in place, [run the full harmonization pipeline](/data-harmonization/executing-the-transformation) to transform the source dataset to the target schema across all sites.

* *"Run the harmonization on the admissions dataset using the Standard Admissions mapping."*
* *"Transform the admissions data and check the status of the harmonization run."*


# Collaboration via MCP

Provides a basic overview of available collaboration capabilities and how to accomplish them using the Rhino MCP.

This article describes what you can do in the **Collaboration** capability area, with example prompts for each action.

Collaboration tools let you manage who has access to a project and check the health of your federated network before running jobs.

{% hint style="warning" %}
If you do not have the required permissions, you will not be able to perform the following actions.
{% endhint %}

## Viewing and managing collaborators

List all [collaborators](/collaborators/what-is-a-collaborator) on a project, invite new users or sites, or remove access for someone who should no longer be on the project.  This capability allows you to answer questions like *"who has access to the oncology project?"*

## Checking workgroup and site connectivity

Before submitting a long-running federated job, check that all required sites are online and reachable.

* *"Are all sites in project X online?"*
* *"Check the connectivity status of the sites in the oncology project before I run the analysis."*


# Queries, Execution & Monitoring

This article describes what you can do in the **Queries**, **Execution**, and **Monitoring** capability areas, with example prompts for each action.

{% hint style="info" %}
The underlying tool names and implementation details in this section are subject to change as the MCP server evolves. You do not need to know the tool names to use the MCP server — simply describe what you want to do in natural language and your AI assistant will handle the rest.
{% endhint %}

### Queries

The MCP server supports a range of federated analytics methods. All computation happens locally at each participating site — only the aggregated results are returned to you. You never see raw patient-level data.

#### Descriptive statistics

Compute summary statistics such as means, counts, and standard deviations across your federated dataset.

* *"What is the mean age of patients in the oncology dataset?"*
* *"Give me the count and gender distribution for the trial cohort."*
* *"Calculate the average BMI and standard deviation across all sites."*

#### Statistical Overview

Generate a publication-ready Statistical Overview summarising patient demographics and key variables — the standard baseline characteristics table used in clinical research papers.

* *"Create a baseline characteristics table for my trial dataset, stratified by treatment arm."*

#### Kaplan-Meier survival analysis

Run federated Kaplan-Meier survival curves with optional stratification and confidence intervals.

* *"Run a Kaplan-Meier analysis on the oncology dataset using survival\_days and event\_occurred."*
* *"Plot survival curves for the trial dataset stratified by treatment arm."*
* *"What is the median survival time in the control group?"*

#### Cox Proportional Hazards regression

Run federated Cox PH regression to estimate hazard ratios for one or more covariates.

* *"Run a Cox regression on the trial dataset with age, BMI, and comorbidity score as covariates."*
* *"What is the hazard ratio for the treatment variable after adjusting for age and gender?"*
* *"Run a federated Cox PH analysis across all three sites."*

#### Chi-square test

Test for statistical independence between categorical variables across the federated dataset.

* *"Is there a significant association between treatment group and readmission status?"*
* *"Run a chi-square test between gender and diagnosis category in the admissions dataset."*

#### SQL queries

Run federated SQL queries against your dataset. Results are aggregated before being returned — no raw rows are exposed.

* *"How many patients in the dataset are over 65 and have a diabetes diagnosis?"*
* *"What is the distribution of admission types across all sites?"*

### Execution

For more advanced analyses, you can upload custom Python code objects and run them federatedly across all participating sites. You can also launch federated machine learning training jobs using NVFlare.

#### Managing and running code objects

List existing code objects in a project, upload new ones, execute them, and remove ones you no longer need.

* *"What code objects are available in the oncology project?"*
* *"Upload this Python script as a new code object called 'ROC Analysis' in the trial project."*
* *"Run the 'ROC Analysis' code object against the trial dataset."*
* *"Delete the 'old\_preprocessing' code object."*

#### Federated training

Launch a federated machine learning training job using NVFlare. The model trains locally at each site — only model weights are aggregated, never raw data.

* *"Start a federated training job for the chest X-ray classifier using FedAvg across all sites."*
* *"Launch an NVFlare training run with 20 rounds using the config I uploaded."*

### Monitoring

Once a job is running, you can check its progress, retrieve logs, and manage its lifecycle.

#### Checking job status

* *"What is the status of the Kaplan-Meier run I just started?"*
* *"Is the training job still running?"*
* *"Show me the most recent runs in the oncology project."*
* *"Which jobs completed successfully this week?"*

#### Retrieving logs

* *"Show me the logs for the last code execution run."*
* *"Were there any errors in the training job?"*

#### Halting and cleaning up

You can stop a running job at any time. Halting is irreversible — partial results from sites that had already completed are preserved, but the job cannot be resumed.

* *"Stop the training job that's currently running."*
* *"Halt the code execution run."*
* *"Delete the run record for the completed ROC analysis."*


# MCP Environments, Troubleshooting, FAQs

This article covers environment-specific server URLs, solutions for common connection errors, and answers to frequently asked questions.

### Environments

Each Rhino FCP environment has a dedicated MCP endpoint. The production URL connects only to production — there is no cross-environment access.

| Environment        | Cloud | URL                                     |
| ------------------ | ----- | --------------------------------------- |
| **Production**     | AWS   | `https://mcp.rhinohealth.com/mcp`       |
| **Production**     | GCP   | `https://mcp.rhinofcp.com/mcp`          |
| **Production US2** | GCP   | `https://mcp-prod-us2.rhinofcp.com/mcp` |

#### Health check

To verify that a specific environment is operational, run:

```
curl https://mcp.rhinohealth.com/health
# → {"status":"ok","version":"1.0.0"}
```

Replace the hostname with the relevant environment URL from the table above.

### Troubleshooting

| Error or symptom                         | Resolution                                                                                                                        |
| ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| **Browser doesn't open for login**       | Check your default browser settings. Fully quit and reopen the AI client.                                                         |
| **Server not responding / timeout**      | Verify the URL ends with `/mcp`. Run the curl health check above to confirm the server is reachable.                              |
| **Invalid Host / 421 error**             | Ensure the full `https://` URL is used. Update `mcp-remote` to the latest version.                                                |
| **OAuth succeeds but tools fail**        | Restart the client to refresh the OAuth token. Verify that your account has access to the relevant project in the Rhino platform. |
| **NOT\_AUTHENTICATED error**             | Your session token has expired. Restart the AI client — the OAuth flow will trigger automatically on the next tool call.          |
| **Tools appear but no data is returned** | Confirm your project access in the Rhino platform and check your workgroup membership.                                            |

If you are still experiencing issues, contact <support@rhinohealth.com> with your client name, the full error message, and the result of the health check.

### Frequently Asked Questions

<details>

<summary>Do I need to install anything to use the MCP server?</summary>

No. The MCP server runs entirely on Rhino's cloud infrastructure — there is nothing to install or update on your end. For most clients (Cursor, Claude Desktop, VS Code) you simply configure the server URL. The only exception is Windsurf and other stdio-only clients, which require Node.js for the `mcp-remote` bridge. See [Prerequisites and Authentication](/using-the-rhino-mcp-server/prerequisites-and-authentication) for details.

</details>

<details>

<summary>Is my data safe?</summary>

Yes. The MCP server enforces the same permissions as the Rhino FCP platform itself. Raw data never leaves hospital sites — all results are aggregated before being returned to your AI client. You will never see individual patient records through any MCP tool.

</details>

<details>

<summary>Can multiple people use the MCP server at the same time?</summary>

Yes. The MCP server is multi-tenant. Each user authenticates with their own Rhino Health account and sees only the projects and data they are authorised to access. There is no shared session between users.

</details>

<details>

<summary>Which environment am I connected to?</summary>

Each environment has its own dedicated URL — the production URL connects only to production, staging to staging, and so on. You can verify the environment and server version at any time by running the health check or by using `rhino_check_connection`.

</details>

<details>

<summary>How do I disconnect or remove the server?</summary>

Remove the `rhino-health` entry from your client's config file and restart the client. For Claude Code CLI, run:

```
claude mcp remove rhino-health
```

</details>

<details>

<summary>My token expired — how do I re-authenticate?</summary>

Simply restart your AI client. The OAuth flow will trigger automatically on the next tool call. No configuration changes are required.

</details>

<details>

<summary>Does the MCP server work with non-Claude AI assistants?</summary>

Yes. The Rhino MCP server supports any client that implements the Model Context Protocol, including the OpenAI Responses API, Cursor, VS Code Copilot, Windsurf, and any custom MCP-compatible client. For HTTP-native clients, use the URL directly. For stdio-only clients, use the `mcp-remote` bridge as described in [Supported Clients](/using-the-rhino-mcp-server/supported-clients).

</details>


# Tutorial, Recipe, and Demo Overview

Lists the tutorials, recipes, and demos in this section.

This section contains tutorials, recipes and demos.

* Tutorials walk you through the steps to perform a basic set of tasks. &#x20;
* Recipes walk you through more complicated procedures.
* Demos show you how to perform a set of tasks using video.

Here are the list of tutorials, recipes, and demos in this section.  Not sure where to start?  Try Tutorial #1 - Basic Usage.

* [Tutorial #1 - Basic Usage](/tutorials-recipes-and-demos/tutorial-1-basic-usage)
* [Tutorial #2 - Using the SDK](/tutorials-recipes-and-demos/tutorial-2-using-the-sdk)
* [Model and Code Encryption for Federated Computing Scenarios](/tutorials-recipes-and-demos/model-and-code-encryption-for-federated-computing-scenarios)
* [FHIR ETL via the Rhino Data Harmonization Engine (RhinoDHE)](/tutorials-recipes-and-demos/fhir-etl-via-the-rhino-data-harmonization-engine-rhinodhe)
* [OMOP ETL via the Rhino Data Harmonization Engine (RhinoDHE)](/tutorials-recipes-and-demos/omop-etl-via-the-rhino-data-harmonization-engine-rhinodhe)
* [Demo: Social Media and Mental Health Psychological Study](/tutorials-recipes-and-demos/demo-social-media-and-mental-health-psychological-study)


# Tutorial #1 - Basic Usage

Learn how to set up a project, prepare data, import it as a data set, and produce visualizations.

This document will guide you through the process of setting up a new project on the Rhino Federated Computing Platform (FCP).

By following the step-by-step instructions in this document, you will learn how to:

1. Set up a new project.
2. Prepare data, import it as a Dataset, and explore data metrics.
3. Containerize your code and run it using our distributed computing platform.
4. Produce visualizations of the results and create a report within the project.

We are excited to see what you will do with the platform, so let’s get started!

{% embed url="<https://www.youtube.com/watch?v=PdUzUf_sJ9I>" %}

### Step 1: Getting Started

#### FCP Credentials

You will need your FCP credentials (email and password) to log in to the Rhino FCP platform using this link: [Rhino FCP Platform](https://dashboard.rhinohealth.com/login).

If you have not received those credentials, please contact [Rhino Support](mailto:support@rhinofcp.com).

#### Important Concepts to Understand

* **Container:** A container is a lightweight and portable software package that encapsulates an application, its dependencies, and its runtime environment. Containers provide a consistent and isolated environment for applications to run, ensuring that they can run consistently across different computing environments. They offer a standardized way to package, deploy, and manage software applications, making it easier to build, ship, and scale applications across different platforms and infrastructures.
  * **Why is this important?** In many cases, you will need to build a container to execute code on the FCP.
* **Container Image:** A container image is a standalone, executable package that includes everything needed to run a piece of software within a container. It contains the application code, runtime environment, libraries, and dependencies required for the application to function properly. Container images are typically built from a base image and can be easily shared, replicated, and deployed across different containerization platforms, allowing for consistent and reproducible application deployments.
  * **Why is this important?** Container images are what the FCP will execute in order to run your code on your FCP client or remote FCP clients.
* **Docker:** Docker is an open-source platform that enables developers to automate the deployment and management of applications within containers. It provides a simple and efficient way to package applications and their dependencies into portable container images. Docker allows for easy and consistent deployment across different environments, ensuring that applications run reliably and consistently regardless of the underlying infrastructure. It has become a widely adopted tool in the software development industry, simplifying application deployment and promoting scalability and flexibility.
  * **Why is this important?** The FCP uses Docker to help build your containers in your development environment and then run your containers locally, on your FCP client, or other remote FCP clients
* **AWS Elastic Container Registry (ECR):** ECR is a fully managed container registry service provided by Amazon Web Services (AWS). It allows users to store, manage, and deploy container images, making it easier to run containerized applications on AWS. It provides secure and scalable storage for Docker container images and supports private repositories, access control, and image lifecycle management. Developers and organizations can use Amazon ECR to build, store, and share container images to streamline their container-based workflows.
  * **Why is this important?** The ECR is where you will push your container images to be run within the FCP.
* **AWS S3 Bucket:** An AWS S3 Bucket is a scalable and secure cloud storage resource provided by Amazon Web Services (AWS). It serves as a container for storing and organizing data objects, including files, images, videos, and structured datasets. S3 buckets allow users to store and retrieve data over the internet with high durability, availability, and security. They support various storage classes, versioning, and access control mechanisms to optimize cost and performance.
  * **Why is this important?** AWS S3 Buckets are commonly used to store and manage large datasets, backups, and application assets. In the context of FCP, an S3 bucket may be used to store input datasets, container images, or processed results, ensuring efficient data sharing and accessibility across distributed environments.
* **Secure File Transfer Protocol (SFTP):** SFTP is a network protocol that provides a secure and encrypted method for transferring files between remote systems. SFTP is commonly used as a secure alternative to FTP (File Transfer Protocol) and allows for secure file transfers over SSH (Secure Shell) connections. It ensures data confidentiality and integrity during file transfers, making it suitable for secure file exchange and remote file management.
  * **Why is this important?** SFTP will be used to move data from your local computer to your FCP client to be imported by the system for exploitation by your containerized code.
* **Data Schema:** A Data Schema is a structure or blueprint that defines the organization, format, and relationships of data within a database or data system. It defines the rules and constraints for how data is organized and represented, including the data types, fields, and their relationships. A Data Schema provides a standardized framework for data storage, retrieval, and manipulation, ensuring the consistency and integrity of the data.
  * **Why is this important?** Data Schemas are used to describe the structure and format of the data you will import into your FCP client as Datasets.

#### Configuring Your Environment

To configure your environment, please follow the steps on this [page](/getting-started/quick-start-guide/fcp-client-installation-and-environment-configuration). Once you have completed those steps, please return here and continue the tutorial.

#### Tutorial 1: Project Resources

[Click here](https://github.com/RhinoHealth/user-resources) to access the GitHub repository that holds a whole host of resources that will be helpful on your journey with the Rhino FCP. It also hosts all the external files you will need for this tutorial. Download or clone the repository on your local computer.

For this tutorial, you will be using the resources inside this folder:

[`user-resources/tutorials/0_Foundational/1_tutorial_one`](https://github.com/RhinoHealth/user-resources/tree/main/tutorials/0_Foundational/1_tutorial_one)

This folder includes:

* **containers/**
  * **data-prep/** - This folder contains a Python script (`dataprep_gc.py`), and several additional files that are required to create the Docker container that will run the script on the FCP (to be used in [Step 5: Running Python Code with Custom Dependencies via the FCP UI](#h_01H1SG30A8K8KQMNV8ZV63Q16M)).
  * **prediction-model/** - This folder contains code for a federated learning (FL) model. The model utilizes PyTorch and has been wrapped for NVFlare (Nvidia’s FL framework). Additionally, the folder contains the files required to create the Docker container to run the model training on the FCP (to be used in [Step 6: Running Federated Training with NVFlare on the FCP UI](#h_01H1SG26AJY30DAB928R0G34PM)).
* **data/**
  * **input/** - This folder is part of the system's structure as you utilize the FCP features mentioned above. It contains the input data for the tutorial.
    * **dataset.csv** - This file defines the dataset you will use as input for this project. Each row in this file represents a case (meaning a study or patient). For each case, there is a DICOM series UID, which is similar to a file path, and the related metadata as described in the Data Schema.
    * **dicom\_data/** - This folder contains the DICOM imaging files, specifically chest X-ray (CXR) images, referenced in the `dataset.csv` file. When using files as input for your project, it is best practice to keep the files in a dedicated folder separate from the `dataset.csv` file.
* **notebooks/**
  * **Tutorial 1 - Results Analysis Notebook.ipynb** - This Jupyter notebook is a step-by-step tutorial for producing code run visualizations using the Rhino Python SDK (to be used in [Step 7: Producing Visualizations of Your Model Results with the Rhino SDK](#h_01H5N4NPE6NSCX8A2R9QFG26MA)).

Another important directory is this folder:

`user-resources/utils/`

This folder contains several utility scripts the Rhino team has created to help simplify the process of pushing your containers to the platform, testing your containers locally, and simulating training and inference in a local simulated FL environment. A subset of these scripts will be used in both [Step 5: Running Python Code with Custom Dependencies via the FCP UI](#h_01H1SG30A8K8KQMNV8ZV63Q16M) and [Step 6: Running Federated Training with NVFlare on the FCP UI](#h_01H1SG26AJY30DAB928R0G34PM).

{% stepper %}
{% step %}

### Step 2: Preparing Your Data

To make your data available in the FCP, you’ll first need to transfer the required files from the `data/` folder to your Rhino client.

To do this, download the following two resources from the [user-resources directory](https://github.com/RhinoHealth/user-resources/tree/main/tutorials/0_Foundational/1_tutorial_one/data/input) and then upload them from your local machine to your Rhino client:<br>

1. `user-resources/tutorials/0_Foundational/1_tutorial_one/data/input/dataset.csv`
2. `user-resources/tutorials/0_Foundational/1_tutorial_one/data/input/dicom_data/`

If you're new to SFTP or need help, refer to this support article: [How can I move data from my local environment to my Rhino client using SFTP?](/getting-started/quick-start-guide/registering-data-to-your-rhino-federated-computing-platform-fcp-client-using-sftp)

**Connecting to your SFTP Server for MacOS, Linux & Windows 10+**

1. Open a terminal or command prompt on your respective operating system, navigate to the folder `user-resources/tutorials/0_Foundational/tutorial_1/data/input/`.
2. Connect to your client via SFTP using the following command:

`sftp rhinosftp@``RHINO_CLIENT_IP_ADDRESS`

* **Note: Ensure to replace** **RHINO\_CLIENT\_IP\_ADDRESS** **in the above command with the credentials found in your profile. If you need help finding your SFTP details, check out the following article:** [**Viewing and Adjusting Your Settings**](/settings/viewing-and-adjusting-your-settings)

3. Copy the `dataset.csv` and `dicom_data/` files from your local machine into a new folder you create on your Rhino client by running the commands below:

```auto
sftp> mkdir tutorial_1
sftp> cd tutorial_1
sftp> put dataset.csv
sftp> mkdir dicom_data
sftp> put -r dicom_data/
sftp> exit
```

**Other Operating Systems**

1. If you have downloaded and configured your SFTP client, skip to the next step. Otherwise, please follow steps 1 and 2 outlined in the following support article under the heading [Adding Data to your Rhino Federated Computing Platform (FCP) Client using SFTP](/getting-started/quick-start-guide/registering-data-to-your-rhino-federated-computing-platform-fcp-client-using-sftp)
2. Open your SFTP client and connect to your Rhino Client
3. Using the SFTP client to upload your data:
   * On the local machine file system panel, navigate to the folder `user-resources/tutorials/0_Foundational/tutorial_1/data/input/`.
   * On your Rhino Client file system panel, create a new folder called `tutorial_1` and navigate inside of it
4. Drag the `dataset.csv` and `dicom_data/` files from your local machine file system panel to the Rhino Client file system panel in order to upload them to your Rhino Client.

Wait until your files have successfully been uploaded to the Rhino Client before proceeding to the next step.

Before running code or uploading large datasets, it's essential to verify that your **Rhino Client is online** and has access to the correct storage.

**How to Check If Your Rhino Client is Online**

1. Click the **gear icon** in the bottom-left of the Rhino FCP interface.
2. Under **My Account**, scroll to the **Your Rhino Client** section.
3. You should see:
   * A **status badge** like ✅ Online – Your Rhino Client is Online.
   * The **IP Address** of your client (used for SFTP and configuration).

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/XL5rLkgzYpcOSPQV7N0M/26275425682589)

If it says ❌ Offline, your code and data operations won’t work until your client is back online. For that, you need to reach out to [Rhino Support](mailto:support@rhinofcp.com).

{% hint style="info" %}
To ensure your code can access the correct data paths and you’re not hitting permission or connectivity errors:

1. In **Settings**, go to the **Client Mounted Storage** tab.
2. You’ll see all mounted storage resources (e.g., `import-external-datasets-staging`) with:
   * The **Client Mount Path** (e.g., `/rhino_data/external/gcp`)
   * **Test Results** showing a ✅ green checkmark if everything is working.
     {% endhint %}

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/bpStEFH2yV6vCReIbu52/26275425683357)

> If the Test Result shows an ❌ or is missing, reach out to [Rhino Support.](mailto:support@rhinofcp.com)
> {% endstep %}

{% step %}

### Step 3: Set Up Your Project on the FCP UI

#### Creating a New Project within the FCP UI

In this section of the tutorial, you will create a new Project within the Rhino FCP UI that will host your tutorial. If you are interested in learning more about Projects within the context of the Rhino FCP, please follow one of the links to the [Projects](/projects/what-is-a-project) section of our [User Guides](https://docs.rhinohealth.com/hc/en-us).

1. Log in to the [Rhino Platform](https://dashboard.rhinofcp.com/login). If this is your first time logging in, you will be required to change your initial password and sign the EULA.
2. Create a new project by clicking on the **Add New Project** button in the top-right corner.
3. Fill in the following fields within the new modal window:
   1. **Name:** Tutorial 1 - YOUR\_NAME
   2. **Description**: This is my first project on the Rhino FCP
   3. **Permissions Policy:** Expand this section to explore the various configurable permission policies and personas that are available to you. For this tutorial, you can leave the default Permissions Policy.
4. Click the **Create Project** button to create your project. Once clicked, you will be navigated back to the project screen, where you will see your newly created project.

#### Understanding Configuration and Collaborator Access

When you create a project, the platform automatically links it to your **Primary Workgroup** (visible under the **My Account** page in Settings). Your workgroup determines who can collaborate with you.

The **Permissions Policy** section defines which roles (Viewer, Editor, Admin) can:

* Manage datasets, schemas, and code
* View logs and analytics
* Run jobs or access site resources

#### Importing a New Dataset within the FCP UI

In this section of the tutorial, you will import a new Dataset within your Project that will contain the data you will use with other aspects of your Project. If you are interested in learning more about Datasets within the context of the Rhino FCP, please follow one of the links to the [Datasets](/datasets/what-is-a-dataset) section of our [User Guides](https://docs.rhinohealth.com/hc/en-us).

1. Click the **Datasets** menu item within the left-hand navigation menu.
2. Import a new Dataset by clicking on the **Import New Dataset** button in the top-right corner.
3. Fill in the following fields within the new modal window:
   1. **Name:** Site 1 Dataset
   2. **Description**: Pneumonia Site 1 Dataset
   3. **Select Workgroup:** Do not modify the default option. The current workgroup is correct for this tutorial.
   4. **Data Schema:** \[Auto-generate Data Schema from Data] - *Do not modify*
   5. **Tabular Data File Location:** /rhino\_data/tutorial\_1/dataset.csv
   6. **DICOM Data Location:** /rhino\_data/tutorial\_1/dicom\_data
      * **Import method:** *Do not modify.* The default option, **Filesystem,** is correct for this tutorial
   7. **File Data Location**: *Do not modify.* You have no file data to import in this tutorial since the Data Schema and accompanying dataset.csv only define DICOM data. So you only need to fill in the DICOM Data Path.
   8. **Data Privacy:** By default, the **Sensitive Data** checkbox is selected during dataset import. For the purpose of this tutorial, which uses only de-identified data, you should **uncheck** this option before proceeding.
      * *Note:* If you are working with datasets that may include sensitive data (e.g., PHI, PII, PCI), you **must** keep the checkbox selected and review the auto-generated schema to mark any fields that potentially contain sensitive data. For more details, refer to the [Sensitive Datasets](/datasets/sensitive-datasets) article.
4. Finally, click the **Import New Dataset** button to import your new dataset.
5. Within the **Datasets** page, you should now have a new dataset object defined with the message "Importing New Dataset". Once the Dataset has been imported completely, your **Datasets** page should look similar to the screenshot shown below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/nt4UbQiZoNUx2WUssfDs/17609938404253)
{% endstep %}

{% step %}

### Step 4: Running Simple Python Code via the FCP UI

The FCP provides an easy way to perform simple data operations that require only basic Python code and standard libraries such as NumPy and Pandas. In this step, you will use this functionality to produce a new Dataset with a new derived feature (or Schema Field in the FCP) from your previously imported Dataset.

#### Creating a New Data Schema with the Definition of the New Field

1. Click the **Data Schemas** menu item within the left-hand navigation menu.
2. Place your mouse anywhere within the bounds of the white box surrounding the *Site 1 Dataset schema* you created within the last step; this should reveal a new button in the top-right corner labeled **+ New Version**.
3. Click the **+ New Version** button to create a new version of the Data Schema in which you will define the new field you would like to derive.
4. Within the new dialog, ensure that the radio button **Edit Latest Schema** is checked. Leaving all other fields untouched.
5. Click the **Create New Schema Version** button; this will take you to the FCP's Data Schema editing tool. Here you should see a tabular format of the Data Schema that you defined in the previous step.
6. To add the new field's definition, click the **+ Add Field** button next to the **Notes** Schema field column.
7. Fill in the following inputs within the new Schema Field column:
   * **Schema Field:** BMI
   * **Identifier:** Leave blank
   * **Description:** Weight / Height\*\*2
   * **Type:** Float
   * **Type Params:** Leave blank
   * **Units:** Leave Blank
   * **Sensitive Data:** No
   * **Aggregate Statistics:** Toggle to **Enable** if it is currently disabled.
   * **Secure Access**: Do not modify. The default option is correct for this tutorial.
8. Once you have completed entering all your details for the new BMI field, click **Save** in the top right corner. You should now have two versions of your Data Schema, and your **Data Schemas** page should look similar to the screenshot below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/KnFszN8rY1o39hdLyM2W/17609938406045)

#### Creating a New Python Code Object within the FCP UI

In this section of the tutorial, you will create a new Python Code Object within your Project to process the Dataset you imported. If you are interested in learning more about Python Code Objects within the context of the Rhino FCP, please follow one of the links to [Creating and Running a Python Code Object](/creating-and-running-code-objects/creating-and-running-a-python-code-object) in the [Creating and Running Code Objects](/creating-and-running-code-objects/what-is-a-code-object) section of our [User Guides](https://docs.rhinohealth.com/hc/en-us).

1. Click the **Code** menu item within the left-hand navigation menu.
2. Create a new Code Object by clicking on the **Create New Code Object** button in the top-left corner.
3. Fill in the following fields within the new modal window:
   1. **Type:** Python Code
   2. **Name:** My First Code
   3. **Description:** Python code for computing BMI
   4. **Inputs:** Site 1 Dataset schema (v0)
   5. **Outputs:** Site 1 Dataset schema (v1)
   6. **Container:** Do not modify. Keep **Select Python and CUDA** Versions selected with
      1. **Python:** Select the latest available version above 3.9, unless your code requires a specific version.
      2. **CUDA:** NONE
   7. **Code:** Keep **Code Snippet** selected and enter the BMI calculation in the text box:

```auto
df['BMI'] = df.Weight / (df.Height ** 2)
```

8. **Requirements:** Keep **PIP** selected and the default requirements unchanged.
9. Next, click the **Create New Code Object** button to create your new Code Object within your project. Once the Code Object creation is complete, your **Code** page should now look similar to the screenshot below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/z4UyPd8GYAW6depAlavk/17609938410781)

#### Running your New Python Code within the FCP UI

In this section of the tutorial, you will run the newly created Python Code which will produce a Code Run after running. If you are interested in learning more about Code Runs within the context of the Rhino FCP, please follow one of the links to [What is a Code Run?](/creating-and-running-code-objects/what-is-a-code-run) in our [User Guides](https://docs.rhinohealth.com/hc/en-us).

1. Navigate to the Code Object you created in the last step, and click the **Run** button in the row corresponding to Version 0 of *My First Code*
2. Fill in the following fields within the new modal window:
   1. **Input Datasets:** Site 1 Dataset (v0)
   2. **Output Dataset Name Template:** Append `_addBMI` to the existing value, so it looks like:

```auto
{{ input_dataset_names.0 }}_addBMI
```

3. **Additional Parameters:** Do not modify
4. Once you have completed entering all the details of your Code Run, click the **Run** button to send your code to be run on your Rhino Client.
5. To monitor your Code Run's progress, click the **Code Runs** menu item within the left-hand navigation menu.
6. Click on the **Code Runs** link in the left menu. You should now see a new Code Run entitled *My First Code* with a single row in it showing a status of "Running". Once your Code Run has completed running, you should see a green checkmark and the words "Completed: Success" next to it. Your **Code Runs** page should look similar to the screenshot shown below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/nBpWLHeTvCLC4eQlDzcg/17609921651101)

#### Reviewing the Code

To review the output of your Code Run, click on the link entitled *1 Dataset* under the **Output Datasets** heading within the first row of the *My First Code* card. This link will take you back to the **Datasets** page, but now on the **Analytics** tab. There you will see summary statistics about your newly created Dataset, *Site 1 Dataset\_addBMI*, produced by the latest run of *My First Code*.

* A few things of note on the Dataset analytics page:
  * The new field, *BMI*, is present and has been calculated using the code you provided during the creation of *My First Code*.
  * The table under the **Data Completeness** heading shows that the new field, *BMI*, has a comparatively low data completeness score, only 64%. This is because it was created using other fields with missing values.

#### Pro Tip: Viewing Code Run Logs for Troubleshooting

A common misstep for new users is not realizing they can view detailed logs for each Code Run. These logs are essential when debugging errors or understanding the output of your code, especially if something goes wrong during execution.

To access and explore your logs:

1. Navigate to the **Code Runs** section in the left-hand menu of the FCP UI.
2. Click on the specific Code Run entry you'd like to investigate.
3. In the top menu of the Code Run window, select the **“Details”** tab next to **“Reports.”**
4. Scroll through the log output to see:
   * System Logs
   * Any printed messages or errors
   * Messages from custom containers or Python scripts

<figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2F0NRh3ozEqF2KLd71Sp2c%2Fimage.png?alt=media&amp;token=b0f24ad9-33f6-41b4-bdb8-24c7c2d29514" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Step 5: Running Python Code with Custom Dependencies via the FCP UI

After discovering new insights about the output Dataset in [Step 4: Running Simple Python code via the FCP UI](#h_01GXEDS3BZSXMS4NGTHKXDF6D7), you would like to improve your data completeness metric by adding a preliminary data imputation step. Additionally, you would like to convert the DICOM CXR images into JPEG versions. As data preparation becomes more and more complex it is often better to collect all the steps in a single script that can be run on the platform, rather than perform a series of smaller steps.

We have provided such a script in our [GitHub Resources](https://github.com/RhinoHealth/user-resources/tree/main/tutorials/tutorial_1/containers/data-prep) named [dataprep\_gc.py](https://github.com/RhinoHealth/user-resources/blob/main/tutorials/0_Foundational/1_tutorial_one/containers/data-prep/dataprep_gc.py). This script has a few additional dependencies, which are included in the [requirements.txt](https://github.com/RhinoHealth/user-resources/blob/main/tutorials/0_Foundational/1_tutorial_one/containers/data-prep/requirements.txt) file. Go ahead and take a look now.

To run this code on the FCP, simply upload your Python script and specify any additional dependencies in the Requirements field or upload [requirements.txt](https://github.com/RhinoHealth/user-resources/blob/main/tutorials/0_Foundational/1_tutorial_one/containers/data-prep/requirements.txt) file, the platform will automatically create the container environment for you using auto-containers.

If you prefer to build and push a custom container image manually, [follow this guide](/getting-started/quick-start-guide/pushing-containers-to-the-ecr) instead.

#### Create a New Data Schema Version that Includes your New Output Schema Fields

1. Return to the FCP to create another new version of the original *Site 1 Dataset schema*. This new Data Schema will serve as the output of your newly created container. You will do this by repeating Steps 1-6 in [Step 4: Running Simple Python Code via the FCP UI](#h_01GXEDS3BZSXMS4NGTHKXDF6D7).
2. Fill in the following inputs within the new Schema Field column:

**NOTE:** Schema Field values are case-sensitive and must match what is in your code.

* **Schema Field:** JPG file
* **Identifier:** Leave blank
* **Description:** JPG representation of the input DICOM image
* **Type:** Filename
* **Type Parameters:** Leave blank
* **Units:** Leave Blank
* **Sensitive Data:** No
* **Aggregate Statistics:** Toggle to **Enable** if it is currently disabled.
* **Secure Access**: Do not modify. The default option is correct for this tutorial.

3. Once you have completed entering all your details for the new JPG file field, click **Save** in the top right corner. You should now have three versions of your Data Schema, and your **Data Schemas** page should look similar to the screenshot below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/t58NyYMFYiivYWunxU1C/25621826584477)

#### Creating a New Python Code Object with Custom Dependencies

1. Click the **Code** menu item within the left-hand navigation menu.
2. Create a new Code Object by clicking on the **Create New Code Object** button in the top left corner.
3. Fill in the following fields within the new modal window:
   1. **Type:** Python Code
   2. **Name:** Data Prep
   3. **Description:** Data Imputation, BMI Calculation, & DICOM file conversion to JPG
   4. **Inputs:** Site 1 Dataset schema (v0)
   5. **Outputs:** Site 1 Dataset schema (v2)
   6. **Container:** Select **Python and CUDA Versions** to use auto-container. Set:
      1. **Python**: Select the latest available version above 3.9, unless your code requires a specific version.
      2. **CUDA**: `NONE`
   7. **Code:** Select **Standalone file** and paste the entire contents of the `dataprep_gc.py` script into the input field.
   8. **Requirements:** Keep **Pip** selected and paste the entire contents of the `requirements.txt` file into the input field
4. Next, click the **Create New Code Object** button to create your new Code Object within your project. Once the Code Object is created, your **Code** page should now look similar to the screenshot below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/B94yuOyLIraPgUBvw0B1/25621826587037)

#### Running your New Python Code Object to Prepare the Data

1. Navigate to the Code Object you created in the last step, and click the **Run** button in the row corresponding to Version 0 of Data Prep.
2. Fill in the following fields within the new modal window:
   1. **Input Datasets:** Site 1 Dataset (v0)
   2. **Output Dataset Name Template:** Append `_complete` to the existing value, so it looks like:

```auto
{{ input_dataset_names.0 }}_complete
```

3. **Additional Parameters:** Do not modify
4. Once you have completed entering all the details of your Code Run, click the **Run** button to send your code to be run on your Rhino Client.
5. To monitor your Code Run's progress, click the **Code Runs** menu item within the left-hand navigation menu.
6. On the **Code Runs** page, you should now see a new Code Run entitled *Data Prep* with a single row in it showing a status of "Running". Once your Code Run has completed running, you should see a green checkmark and the words "Completed: Success" next to it.
7. To review the output of your Code Run, click the **Datasets** menu item within the left-hand navigation menu.
8. You should now have a new Dataset listed on the page with the name Site 1 Dataset\_complete. Your **Datasets** page should now look similar to the screenshot below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/d3Fet8MieNTUwmnDvgWK/25621837655069)

8. Click on the row representing Version 0 within the *Site 1 Dataset\_complete* Dataset card to view the new Dataset analytics after we have successfully run our *Data Prep* Python Code. Your Dataset **Analytics** tab within the **Datasets** page should now look similar to the screenshot below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/jkfCidcfhnv5EuzMWTER/25621826590365)

* A few things of note on the **Analytics** tab within the **Datasets** page:

  * The *Data Prep* Code has added 2 new fields to the Dataset - **BMI**, and **JPG file.**
  * The Code performed data imputation so your **Data Completeness** metrics for all fields should now be 100%.
  * If you navigate to the **Secure Access Data** tab, you can directly access the tabular data within the Dataset. Your  **Secure Access Data** tab within the **Datasets** page should now look similar to the screenshot below:

  <figure><img src="https://2949362692-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FydySyCBmy6F7NnGn4bPa%2Fuploads%2F6EoY3wohYdKUpejszOet%2Fimage.png?alt=media&amp;token=12480833-da20-4eb0-a25f-bd4a7c5a5571" alt=""><figcaption></figcaption></figure>

* Permission Note: You are permitted to view this data in this way because you have imported this Dataset from your workgroup’s client. When working with Datasets from other workgroups, the other workgroups will need to grant you explicit permission to be able to access their data at this level. For more information, please refer to [Secure Access Lists](/secure-access/what-is-a-secure-access-list) within the [User Guides](https://docs.rhinohealth.com/hc/en-us).
  {% endstep %}

{% step %}

### Step 6: Running Federated Training with NVFlare on the FCP UI

First of all, you should create a new data schema for the output of your NVFlare code.

#### Creating output schema

For this tutorial, you can either:

* **Create a Blank Data Schema** using the details outlined below, or
* **Upload from File** using the provided file: `user-resources/tutorials/0_Foundational/1_tutorial_one/schemas/Pneumonia Output Schema.csv.`

For creating a new Schema you can follow the steps in [Creating a New Data Schema within the FCP UI](#h_01H2GM043CQ8VFX32K30J15GDP) within [Step 3: Set Up Your Project on the FCP UI](#h_01H267VEYK4XYQRAT9N5Z35J4W) to create a new Data Schema called "Pneumonia Results Schema".

The schema looks like this:

|                          |                             |                      |                |                          |                                          |                  |               |                                 |                                          |
| ------------------------ | --------------------------- | -------------------- | -------------- | ------------------------ | ---------------------------------------- | ---------------- | ------------- | ------------------------------- | ---------------------------------------- |
| **Field Name**           | **SeriesUID**               | **Height**           | **Weight**     | **Gender**               | **Pneumonia**                            | **BMI**          | **JPG file**  | ***Model*****&#x20;Score**      | ***Notes***                              |
| **Identifier**           |                             |                      |                |                          |                                          |                  |               |                                 |                                          |
| **Description**          | DICOM Series UID of the CXR | Patient Height       | Patient Weight | Patient Gender           | Whether or not the patient had pneumonia | Patient BMI      | CXR JPG image | *Model* score on validation set | *System generated column for user notes* |
| **Type**                 | DicomSeriesUID              | ConstrainedFloat     | PositiveFloat  | Enum                     | Boolean                                  | NonNegativeFloat | Filename      | Float                           | String                                   |
| **Type Parameters**      |                             | {"gt": 0, "le": 2.3} |                | {"choices": \["M", "F"]} |                                          |                  |               |                                 |                                          |
| **Units**                |                             | m                    | kg             |                          |                                          | kg/m^2           |               |                                 |                                          |
| **Sensitive Data**       | No                          | No                   | No             | No                       | No                                       | No               | No            | No                              | No                                       |
| **Aggregate Statistics** | Allowed                     | Allowed              | Allowed        | Allowed                  | Allowed                                  | Allowed          | Allowed       | Allowed                         | Allowed                                  |
| **Secure Access**        | Allowed                     | Allowed              | Allowed        | Allowed                  | Allowed                                  | Allowed          | Allowed       | Allowed                         | Allowed                                  |

#### Creating a New NVFlare Code Object Using the Autocontainer Feature

Before starting with NVFlare in this step, you might want to explore the official documentation for the federated learning frameworks used in this tutorial:

* [NVFlare Documentation](https://nvflare.readthedocs.io/en/latest/)

In this section of the tutorial, you will create a new NVFlare Code Object within your Project to train and validate a model to predict the likelihood of pneumonia in the Dataset you imported and then preprocessed. If you are interested in learning more about NVFlare Code Objects within the context of the Rhino FCP, please follow one of the links to [Creating and Running NVFlare Code and Running Inference](/creating-and-running-code-objects/creating-and-running-nvflare-code-and-running-inference) in the Code section of our [User Guides](https://docs.rhinofcp.com/).

1. Click the **Code** menu item within the left-hand navigation menu.
2. Create a new code model by clicking on the **Create New Code Object** button in the top left corner.
3. Fill in the following fields within the new modal window:
   1. **Type:** NVIDIA Flare
   2. **NVFLARE Version:** 2.6 (Ensure compatibility with your Python version; NVFlare 2.6 requires Python 3.10. or later)
   3. **Name:** Prediction Model
   4. **Description:** PyTorch Classification Model for Predicting Pneumonia within Patients
   5. **Input Data Schema:** Site 1 Dataset Schema (v2)
   6. **Output Data Schema:** Pneumonia Results Schema (v0)
   7. **Container:** Select the **New container image** button
      1. **Python:** 3.11 *(Ensure compatibility with your NVFLARE version; NVFlare 2.6 requires Python 3.10 or later.)*
      2. **CUDA:** NONE
      3. **Code:** The order and method of selecting the files is important as it must maintain the directory structure.
         1. Select **browse files** and navigate to

            `user-resources/tutorials/tutorial_1/containers/prediction-model`
         2. Select the `infer.py` file and click Open.
         3. Click the **+ Add more** button on the top right of the panel.
         4. Select **browse files** and in the same folder select `meta.json` and upload it.
         5. Click again the **+ Add more** and now select **browse folders.**
            * If you use NVFlare **NVFlare 2.4** and above, you can upload the entire `app` folder at once.
              * Select the `app` directory and click **Upload**.
            * If you use NVFlare **2.3 and earlier**, the configuration required two separate directories: `config` and `custom`.
              * Select the `config` directory and click Upload.
              * A pop-up window asking to upload all files. Click **Upload**.
              * Again, click the **+ Add more** button.
              * Select **browse folders.**
              * Select the `custom` directory and click Upload.
              * Click Upload again on the popup.
         6. Finally, below the pane of files, click the **Upload Files** button.
4. In the Requirements pane, click the **Upload File** button.
5. Select the `requirements.txt` file from

`user-resources/tutorials/tutorial_1/containers/prediction-model`

and click **Open**. 6. Finally, click the **Create New Code Object** button to create your new Code Object within your project.

#### Running your New NVFlare Code Object to Predict Pneumonia

1. Navigate to the Code Object you created in the last step, and click the **Run** button in the row corresponding to Version 0 of the *Prediction Model*.
2. Fill in the following fields within the new modal window:
   1. **Training Datasets:** Site 1 Dataset\_complete (v0)
   2. **Validation Datasets:** Site 1 Dataset\_complete(v0)
      * **Note:** In a real-world scenario you would not select the same Datasets for both training and validation, rather you would split the Datasets into training and validation Datasets first.
   3. **Output Dataset Name Suffix:** `_results`
   4. **Configuration:** Do not modify.
   5. **Additional Parameters:** Do not modify.
3. Once you have completed entering all the details of your Code Run, click the **Run** button to send your code to be run on your Rhino Client.
   * Training should take between 10-30 minutes to complete (depending on your Rhino Client’s hardware) - The training is only performing a single epoch, so model performance will likely be less than stellar.
   * Once training has been completed, the system will automatically run inference with your validation Dataset and your newly trained model to produce a new output Dataset with the results of the validation.
4. After the training and validation steps have successfully completed, you should have a new Dataset within the **Datasets** page entitled *Site 1 Dataset\_complete\_results.* Your **Datasets** page should now look similar to the screenshot below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/d3Fet8MieNTUwmnDvgWK/25621837655069)
{% endstep %}

{% step %}

### Step 7: Producing Visualizations of Your Code Run with the Rhino SDK

In this section of the tutorial, you will create a report to visualize the output of your NVFlare Code's Inference results. If you are interested in learning more about the Rhino SDK, please follow one of the links to the [Rhino SDK](/rhino-sdk/where-to-find-rhino-sdk-documentation) section of the user-resources and the [Rhino SDK Documentation](https://rhinohealth.github.io/rhino_sdk_docs/html/index.html#) to learn how to interact with the FCP using Python.

{% embed url="<https://www.youtube.com/watch?v=SVVa6apBkRc>" %}

1. If you do not have Python installed with your development environment, please download and install Python here: [Python](https://www.python.org/downloads/)
2. If you do not have Jupyter Notebook installed within your development environment, please follow the steps outlined here: [Jupyter Notebook Installation](https://jupyter.org/install)
3. Using your terminal or command prompt, navigate to your `user-resources/tutorials/0_Foundational/1_tutorial_one/notebooks` folder.
4. Run the following command to start the Jupyter Notebook, `Tutorial 1 - Results Analysis Notebook.ipynb`:

```auto
jupyter notebook
```

5. Follow the step-by-step tutorial for producing Code Run visualizations using the Rhino SDK by running each of the cells contained within the notebook.
6. Once you have completed running the entire notebook, switch back over to the FCP. Navigate to the **Code Runs** page, clicking the report icon at first row labeled **V**, for validation. ![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/Vn5i8rnsPdgOUyqFec5c/30126143994141)
7. You will be taken to a new page with two tabs, **Report**, and **Logs**. Through the previous steps, we have populated the **Report** tab. You should now see various charts and your **Reports** tab within the **Code Runs** page should now look similar to the screenshot below:

![](https://content.gitbook.com/content/ydySyCBmy6F7NnGn4bPa/blobs/QGmQ7vW8XjuQjVLBBKsW/30126143994653)
{% endstep %}
{% endstepper %}

**Congratulations on completing your first tutorial on the Rhino FCP!**

You should now have a good understanding of:

1. The important concepts of: Container, Docker, AWS ECR, AWS S3, SFTP, Data Schema.
2. How to access the FCP and locate your credentials from your profile page
3. How to create a new project
4. What a Data Schema is and how to create a new Data Schema
5. How to import new Datasets to your project
6. How to create several different Code Objects (Python Code, Generalized Compute & NVFlare) and run them
7. How to use the Rhino SDK to create custom reports for visualizing the output of Code Runs

### Things to try next

* **Adjust the code to produce different results:**
  * Change the units for Height and/or Weight
  * Extract new fields from the data
* **Check out the tabular viewer’s advanced features:**
  * The tabular viewer (accessible by clicking on a Dataset you have access to, then clicking on the Data tab) includes a few advanced features, such as a fully functional DICOM viewer with annotation capabilities, an auto-generated editable **Notes** column you can use to append free-text notes to each case, and a viewer for standard image formats such as .jpg and .png.

    You can read about these features in [Viewing and/or Annotating Datasets and Dataset Images](/datasets/viewing-and-or-annotating-datasets-and-dataset-images) and test them in your Hello World project.
* **Use TensorBoard to visualize and measure model performance.**
  * [Visualizing and Measuring Machine Learning Model Performance with Tensorboard.](/creating-and-running-code-objects/visualizing-and-measuring-machine-learning-model-performance-with-tensorboard)
* **Try to break things, for example:**
  * Mismatches between the Data Schema and the data in the `dataset.csv` file will produce validation errors when attempting to import the Dataset. We recommend you try altering the Dataset and Data Schema to see what happens.
  * Try adding faulty code to the Python Code Object and running it. This will help you learn how the FCP produces different error messages and how you can use the platform to debug your code.

Thanks again for investing your time in learning how to use the FCP, we can't wait to see what you will do with it! If you need support at any time, reach out to us at [Rhino Support](mailto:support@rhinofcp.com).




---

[Next Page](https://docs.rhinofcp.com/llms-full.txt/1)

