Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 55 additions & 51 deletions applications/pipeline_visualization/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ This example demonstrates real-time visualization of data from Holoscan applicat

The example consists of three main components:

1. **C++ Data Producer**: A Holoscan application that generates data (sine waves) and publishes it to NATS
2. **NATS Server**: A message broker that handles real-time data streaming
3. **Python Web Visualizers**: Dash-based web applications that subscribe to NATS streams and display live plots
* **C++ Data Producer**: A Holoscan application that generates data (sine waves) and publishes it to NATS
* **NATS Server**: A message broker that handles real-time data streaming
* **Python Web Visualizers**: Dash-based web applications that subscribe to NATS streams and display live plots

## Quick Start

Expand Down Expand Up @@ -41,16 +41,20 @@ The web interface will be available at: [http://localhost:8050](http://localhost

In a third terminal, run the application:

```bash
# Run the Python version (default when --language is not specified)
./holohub run pipeline_visualization
1. Run the Python version (default when `--language` is not specified):

# Or explicitly specify the language:
./holohub run pipeline_visualization --language python
./holohub run pipeline_visualization --language cpp
```
```bash
./holohub run pipeline_visualization
```

1. Or explicitly specify the language:

```bash
./holohub run pipeline_visualization --language python
./holohub run pipeline_visualization --language cpp
```

**Command-line Options:**
Command-line options for `pipeline_visualization`:

```text
Usage: ./pipeline_visualization [options]
Expand All @@ -63,18 +67,18 @@ Options:
-r, --publish_rate Publish rate in Hz (default: 2.0)
```

**Example with custom settings:**
Example with custom settings:

```bash
./holohub run pipeline_visualization --nats_url nats://0.0.0.0:4222 --subject_prefix my_demo --publish_rate 5.0
```

### Step 4: Visualize the Data

1. Open your web browser to [http://localhost:8050](http://localhost:8050)
2. Enter the subject name (default: `nats_demo`)
3. Click **Connect**
4. Watch the real-time data plots update!
1. Open your web browser to [http://localhost:8050](http://localhost:8050).
2. Enter the subject name (default: `nats_demo`).
3. Click **Connect**.
4. Watch the real-time data plots update.

The visualizer will display:

Expand All @@ -87,7 +91,7 @@ The visualizer will display:

### NATS Logger Configuration (`pipeline_visualization.yaml`)

The NATS logger behavior can be configured via YAML:
The NATS logger behavior can be configured using YAML:

```yaml
nats_logger:
Expand Down Expand Up @@ -134,7 +138,7 @@ flowchart TB

### Application (`cpp/` and `python/`)

The C++ and Python applications demonstrates a simple Holoscan pipeline with data logging:
The C++ and Python applications demonstrates a basic Holoscan pipeline with data logging:

- **SourceOp**: Generates sine waves with varying frequencies (10-20 Hz)
- **ModulateOp**: Adds high-frequency modulation (300 Hz) to the signal
Expand All @@ -145,31 +149,33 @@ The applications log both inputs and outputs of operators, allowing visualizatio

### Python Visualizers (`visualizer/`)

Two visualization options are provided:
There are two Python visualizers. One is [static](#static-visualizer-visualizer_staticpy) and one is [dynamic](#dynamic-visualizer-visualizer_dynamicpy) and they both display:

#### 1. Static Visualizer (`visualizer_static.py`)
- Real-time line plots of tensor data
- Stream name (operator.port format)
- IO type (Input/Output)
- Acquisition timestamp (nanoseconds)
- Publish timestamp (nanoseconds)

Use `start_visualizer.sh` to set the required Python path to the [flatbuffers](#flatbuffers-schemas-schemas) definitions and starts the visualizer. The script takes one parameter, its values are:

- `dynamic`, to start the dynamic visualizer.
- `static`, to start the static visualizer.

#### Static Visualizer (`visualizer_static.py`)

The static visualizer can be used when the output data and format of the Holoscan pipeline is known or some data needs special formatting.

- Displays predefined data streams: `source.out`, `modulate.in`, `modulate.out`, `sink.in`
- Best for applications with known, fixed operator topology
- All graphs are created upfront and updated as data arrives

The static visualizer can be used when the output data and format of the Holoscan pipeline is known or some data needs special formatting.

#### 2. Dynamic Visualizer (`visualizer_dynamic.py`)
#### Dynamic Visualizer (`visualizer_dynamic.py`)

- Automatically discovers and creates graphs for new data streams
- Ideal for applications with dynamic or unknown operator configurations
- Graphs are created on-the-fly as new unique IDs are detected

There is a script `start_visualizer.sh` which sets the required Python path to the flatbuffers definitions and starts the visualizer. The script takes a parameter, `dynamic` starts the dynamic visualizer and `static` starts the static visualizer.

Both visualizers display:

- Real-time line plots of tensor data
- Stream name (operator.port format)
- IO type (Input/Output)
- Acquisition timestamp (nanoseconds)
- Publish timestamp (nanoseconds)

### FlatBuffers Schemas (`schemas/`)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section had my brain asking questions....the sort of: how does this work, why do I care about this for visualization, and do i need to install the dependencies before or after using the visualizer? the data format for what? Then to be honest my brain just started pinging me with other random and less relevant questions.


Expand All @@ -178,13 +184,11 @@ The data format is defined using FlatBuffers for efficient serialization:
- **message.fbs**: Top-level message structure with metadata
- **tensor.fbs**: Tensor data structure based on DLPack

## Prerequisites
## Visualizer Python Prerequisites
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a shot at what these prereq's were for. Please verify.


All dependencies to run the application are installed automatically when using the `holohub run` command inside
the Holohub container. Since the visualizer is run outside the Holohub container, its dependencies must be
installed separately. See the next section for details.

### Visualizer Python Dependencies
the Holohub container. Because the visualizer is run outside the Holohub container, its [dependencies](#visualizer-python-dependencies) must be
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix broken link fragment.

Line 190 references #visualizer-python-dependencies, but the section heading is "Visualizer Python Prerequisites" which generates the anchor #visualizer-python-prerequisites. Update the link to match the correct anchor.

🔗 Proposed fix
- Because the visualizer is run outside the Holohub container, its [dependencies](#visualizer-python-dependencies) must be
+ Because the visualizer is run outside the Holohub container, its [dependencies](#visualizer-python-prerequisites) must be
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
the Holohub container. Because the visualizer is run outside the Holohub container, its [dependencies](#visualizer-python-dependencies) must be
the Holohub container. Because the visualizer is run outside the Holohub container, its [dependencies](#visualizer-python-prerequisites) must be
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

190-190: Link fragments should be valid

(MD051, link-fragments)

🤖 Prompt for AI Agents
In @applications/pipeline_visualization/README.md at line 190, Update the broken
link fragment in the README by changing the reference from
#visualizer-python-dependencies to the actual anchor
#visualizer-python-prerequisites so the phrase referring to the Visualizer
Python dependencies points to the "Visualizer Python Prerequisites" section;
locate the link text in the same paragraph referencing the Holohub container and
replace the fragment accordingly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

broken internal link - the anchor #visualizer-python-dependencies doesn't exist. The section is titled "Visualizer Python Prerequisites" which generates anchor #visualizer-python-prerequisites

Suggested change
the Holohub container. Because the visualizer is run outside the Holohub container, its [dependencies](#visualizer-python-dependencies) must be
the Holohub container. Because the visualizer is run outside the Holohub container, its [dependencies](#visualizer-python-prerequisites) must be

installed separately.

Install the required Python packages:

Expand All @@ -205,7 +209,7 @@ Required packages:

### NATS Message Structure

Messages are published to the subject: `<subject_prefix>.data` (e.g., `nats_demo.data`)
Messages are published to the subject: `<subject_prefix>.data` (for example, `nats_demo.data`)

Each message is a FlatBuffer-serialized `Message` containing:

Expand Down Expand Up @@ -250,7 +254,7 @@ Examples:

1. Check that the C++ application is running
2. Verify the subject name matches (default: `nats_demo`)
3. Click the "Connect" button in the web interface
3. Click the **Connect** button in the web interface
4. Check browser console for JavaScript errors

### FlatBuffers Import Errors
Expand All @@ -259,24 +263,24 @@ Examples:

**Solution**:

- Ensure the FlatBuffers files were generated during build
- Set PYTHONPATH correctly:
1. Ensure the FlatBuffers files were generated during build.
1. Set `PYTHONPATH` correctly:

```bash
export PYTHONPATH=$PYTHONPATH:/path/to/build/applications/pipeline_visualization/flatbuffers/
```
```bash
export PYTHONPATH=$PYTHONPATH:/path/to/build/applications/pipeline_visualization/flatbuffers/
```

- Verify the files exist in the build directory
1. Verify that the files exist in the build directory.

### No Data Displayed

**Problem**: Graphs are empty or show no data

**Solution**:

- Check that `log_tensor_data_content: true` in the YAML config
- Verify the operator names match between the app and visualizer
- For static visualizer, ensure the unique IDs in the code match your operators
- Verify that `log_tensor_data_content: true` is in the YAML config
- Verify that the operator names match, between the app and visualizer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awkward comma placement - "match, between" creates an unnecessary pause

Suggested change
- Verify that the operator names match, between the app and visualizer
- Verify that the operator names match between the app and visualizer

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

- For static visualizer, ensure that the unique IDs in the code match your operators
- For dynamic visualizer, wait a few seconds for auto-discovery

## Customization
Expand All @@ -301,7 +305,7 @@ To visualize data from your own Holoscan operators:
self._unique_ids = ["my_op.out", "my_other_op.in"]
```

3. For dynamic visualizer, no changes needed - it will auto-discover!
3. For dynamic visualizer, no changes needed - it will auto-discover.

### Customizing Visualizations

Expand Down Expand Up @@ -346,13 +350,13 @@ To access the visualizer from another machine:

1. Start the visualizer with host `0.0.0.0` (already configured)
2. Ensure port 8050 is accessible through firewall
3. Access via: `http://<server-ip>:8050`
3. Access using: `http://<server-ip>:8050`

### Multiple Applications

To run multiple Holoscan apps simultaneously:

1. Use different subject prefixes for each app
1. Use different subject prefixes for each app.
2. Start multiple visualizer instances on different ports:

```python
Expand Down