From a0926eb64ea357b7e58489bc0449412a1f705609 Mon Sep 17 00:00:00 2001 From: "Ayres, Andrew" Date: Thu, 27 Mar 2025 00:39:32 -0500 Subject: [PATCH 1/3] change copier to tutorial template --- episodes/06-Advanced-Data-Modeling.md | 2 +- episodes/07-Advanced-Visualizations.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/episodes/06-Advanced-Data-Modeling.md b/episodes/06-Advanced-Data-Modeling.md index c98e32f6..ca36f7b5 100755 --- a/episodes/06-Advanced-Data-Modeling.md +++ b/episodes/06-Advanced-Data-Modeling.md @@ -65,7 +65,7 @@ Let\'s start by setting up a new application from the template. To clone the template application, run the following command: ```bash -copier copy https://code.ornl.gov/ndip/project-templates/nova-application-template.git advanced_pydantic +copier copy https://code.ornl.gov/ndip/project-templates/nova-application-template-tutorial.git advanced_pydantic ``` This command will download the template to a directory called `advanced_pydantic`. Copier will prompt you with a series of questions. Please answer the questions as follows: diff --git a/episodes/07-Advanced-Visualizations.md b/episodes/07-Advanced-Visualizations.md index c9bb217b..a669ca7f 100755 --- a/episodes/07-Advanced-Visualizations.md +++ b/episodes/07-Advanced-Visualizations.md @@ -38,7 +38,7 @@ The complete code for this episode is available in the `code/episode_7` director Let\'s start by setting up a new application from the template. When answering the `copier` questions, make sure you select "no" for installing Mantid and set up a Trame-based, multi-tab view based on MVVM. ```bash -copier copy https://code.ornl.gov/ndip/project-templates/nova-application-template.git viz_tutorial +copier copy https://code.ornl.gov/ndip/project-templates/nova-application-template-tutorial.git viz_tutorial ``` * **What is your project name?** -- GitLab From f4eec4efe848f074ba8e420081afc57aa065a05c Mon Sep 17 00:00:00 2001 From: "Ayres, Andrew" Date: Thu, 27 Mar 2025 03:12:36 -0500 Subject: [PATCH 2/3] Minor fixes to episodes --- episodes/04-MVVM-Design-Pattern.md | 2 +- episodes/05-Working-with-Trame.md | 4 ++++ episodes/06-Advanced-Data-Modeling.md | 2 +- episodes/07-Advanced-Visualizations.md | 28 +++++++++++++------------- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/episodes/04-MVVM-Design-Pattern.md b/episodes/04-MVVM-Design-Pattern.md index 06ba11d5..1005f036 100755 --- a/episodes/04-MVVM-Design-Pattern.md +++ b/episodes/04-MVVM-Design-Pattern.md @@ -213,6 +213,7 @@ This is the UI for our Fractal interaction. It includes a button that calls the ```python from trame.widgets import vuetify3 as vuetify +from nova.trame.view.components import InputField from nova_tutorial.app.view_models.main import MainViewModel class FractalTab: @@ -221,7 +222,6 @@ class FractalTab: self.create_ui() def create_ui(self) -> None: - InputField(v_model="config.fractal.fractal_type") vuetify.VBtn( "Run Fractal", click=self.view_model.run_fractal diff --git a/episodes/05-Working-with-Trame.md b/episodes/05-Working-with-Trame.md index 8e7aac5c..779c93fe 100755 --- a/episodes/05-Working-with-Trame.md +++ b/episodes/05-Working-with-Trame.md @@ -349,6 +349,10 @@ We will need to add a data binding for `running`, as well. We choose to place th **8. `src/nova_tutorial/app/view_models/main.py` (Modify):** ```python +from asyncio import create_task, sleep +from threading import Thread + # ... (rest of the file) ... + def __init__(self, model: MainModel, binding: BindingInterface): self.model = model self.running = False diff --git a/episodes/06-Advanced-Data-Modeling.md b/episodes/06-Advanced-Data-Modeling.md index ca36f7b5..89f9e81e 100755 --- a/episodes/06-Advanced-Data-Modeling.md +++ b/episodes/06-Advanced-Data-Modeling.md @@ -282,7 +282,7 @@ Now, let\'s create a simple Trame-based GUI application. To clone the template application, run the following command: ```bash -copier copy https://code.ornl.gov/ndip/project-templates/nova-application-template.git pydantic_mvvm +copier copy https://code.ornl.gov/ndip/project-templates/nova-application-template-tutorial.git pydantic_mvvm ``` This command will download the template to a directory called `pydantic_mvvm`. Copier will prompt you with a series of questions. Please answer the questions as follows: diff --git a/episodes/07-Advanced-Visualizations.md b/episodes/07-Advanced-Visualizations.md index a669ca7f..32a9e7b6 100755 --- a/episodes/07-Advanced-Visualizations.md +++ b/episodes/07-Advanced-Visualizations.md @@ -91,7 +91,7 @@ The pandas install is only necessary for loading example data from Plotly, which Now, we can create a view that displays a Plotly figure. -**1. `PlotlyView` View Class (`src/viz_examples/views/plotly.py`) (Create):** +**1. `PlotlyView` View Class (`src/viz_examples/app/views/plotly.py`) (Create):** * **Imports**: Pay special attention to the plotly import. This module contains a Trame widget that will allow us to quickly add a Plotly chart to our view. @@ -218,7 +218,7 @@ class PlotlyConfig(BaseModel): First, let's add replace the sample tabs from the template with the following: -**3. `src/app/viz_examples/app/views/tab_content_panel.py` (Modify):** +**3. `src/viz_examples/app/views/tab_content_panel.py` (Modify):** * **Import `PlotlyView`** @@ -242,7 +242,7 @@ And add the corresponding import: We also need to update the tabs to show an option for the Plotly view. -**4. `src/viz_examples/views/tabs_panel.py` (Modify):** +**4. `src/viz_examples/app/views/tabs_panel.py` (Modify):** ```python def create_ui(self) -> None: @@ -252,7 +252,7 @@ We also need to update the tabs to show an option for the Plotly view. Finally, we'll need to update the view model to bind our new classes. -**5. `src/viz_examples/view_models/main.py` (Modify):** +**5. `src/viz_examples/app/view_models/main.py` (Modify):** * **Import `PlotlyConfig`** @@ -297,7 +297,7 @@ PyVista contains built-in Trame support, but we still need to install the Trame Now we can set up our view. -**6. `PyVistaView` View Class (`src/viz_examples/views/pyvista.py`):** +**6. `PyVistaView` View Class (`src/viz_examples/app/views/pyvista.py`):** * **Imports:** `plotter_ui` contains the Trame widget for PyVista. @@ -355,7 +355,7 @@ class PyVistaView: self.view_model.update_pyvista_volume(self.plotter) ``` -**7. `PyVistaConfig` Model Class (`src/viz_examples/models/pyvista.py`):** +**7. `PyVistaConfig` Model Class (`src/viz_examples/app/models/pyvista.py`):** * **Imports:** `download_knee_full` yields a 3D dataset that is suitable for volume rendering. You can find more datasets in PyVista\'s [Dataset Gallery](https://docs.pyvista.org/api/examples/dataset_gallery). @@ -403,7 +403,7 @@ PyVista\'s volume rendering engine isn\'t currently suitable for large data. If This is very similar to the Plotly setup. -**8. `src/viz_examples/views/tab_content_panel.py` (Modify):** +**8. `src/viz_examples/app/views/tab_content_panel.py` (Modify):** * **Import `PyVistaView`** @@ -425,7 +425,7 @@ from ..views.pyvista import PyVistaView PyVistaView(self.view_model) ``` -**9. `src/viz_examples/views/tabs_panel.py` (Modify):** +**9. `src/viz_examples/app/views/tabs_panel.py` (Modify):** ```python def create_ui(self) -> None: @@ -434,7 +434,7 @@ from ..views.pyvista import PyVistaView vuetify.VTab("PyVista", value=2) ``` -**10. `src/viz_examples/view_models/main.py` (Modify):** +**10. `src/viz_examples/app/view_models/main.py` (Modify):** * **Import `PyVistaConfig`** @@ -483,7 +483,7 @@ PyVista isn't compatible with VTK 9.4, yet. If you are not using PyVista, there Once more, let's setup a view and model. -**11. `VTKView` View Class (`src/viz_examples/views/vtk.py`):** +**11. `VTKView` View Class (`src/viz_examples/app/views/vtk.py`):** * **Imports:** The `vtkRenderingVolumeOpenGL2` import is necessary despite being unreferenced. @@ -544,7 +544,7 @@ class VTKView: self.render_window.Render() ``` -**12. `VTKConfig` Model Class (`src/viz_examples/models/vtk.py`):** +**12. `VTKConfig` Model Class (`src/viz_examples/app/models/vtk.py`):** * **Imports:** We are only using PyVista to get an example dataset. There are two references to it as we use `KNEE_DATA` to compute min/max bounds for the data and `KNEE_DATAFILE` to pass the data file into a VTK reader. The FixedPointVolumeRayCastMapper is CPU-based, but other mappers are available if you need GPU support. @@ -676,7 +676,7 @@ class VTKConfig: This is very similar to the Plotly and PyVista setup. -**13. `src/viz_examples/views/tab_content_panel.py` (Modify):** +**13. `src/viz_examples/app/views/tab_content_panel.py` (Modify):** * **Import `VTKView`** @@ -700,7 +700,7 @@ from ..views.vtk import VTKView VTKView(self.view_model) ``` -**14. `src/viz_examples/views/tabs_panel.py` (Modify):** +**14. `src/viz_examples/app/views/tabs_panel.py` (Modify):** ```python def create_ui(self) -> None: @@ -710,7 +710,7 @@ from ..views.vtk import VTKView vuetify.VTab("VTK", value=3) ``` -**15. `src/viz_examples/view_models/main.py` (Modify):** +**15. `src/viz_examples/app/view_models/main.py` (Modify):** * **Import `VTKConfig`** -- GitLab From d0efe555d0387ba26832190b64c649c0627e8b72 Mon Sep 17 00:00:00 2001 From: "Ayres, Andrew" Date: Thu, 27 Mar 2025 09:47:20 -0500 Subject: [PATCH 3/3] Change async code sample --- episodes/03-Nova-Galaxy.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/episodes/03-Nova-Galaxy.md b/episodes/03-Nova-Galaxy.md index cd3c9663..778e6e61 100755 --- a/episodes/03-Nova-Galaxy.md +++ b/episodes/03-Nova-Galaxy.md @@ -201,11 +201,19 @@ The Outputs can be used by the rest of your application, saved, or simply discar At times, it may be desirable to execute a tool or workflow without waiting on the result. The class Tool method run has an optional `wait` parameter. The default is true so that the tool is run in a blocking manner. However, by setting the parameter to false, the tool will be run asynchronously in a non-blocking manner. It is beyond the scope of this episode, but if you were to attempt modify the example to run the tool asynchronously, your code might look something like this. ```python - tool.run(data_store, params, wait=False) + params1 = Parameters() + params1.add_input(name="option", "mandelbrot") + tool1.run(data_store, params1, wait=False) - def check_for_output(self, tool): - if(tool.get_results()): - output.get_dataset("output").download("image.png") + params2 = Parameters() + params2.add_input(name="option", "julia") + tool2.run(data_store, params2, wait=False) + + # wait on both tools to finish + while(!tool1.get_results() || !tool2.get_results()) + await sleep(1) + + # do stuff ``` Note, when run in this manner, the output of tool.run() will be `None`. In order to retrieve results, you can use `tool.get_results()`. If the tool has not finished execution, this will also return `None`. As soon as results are available, the method will provide the results, exactly like the blocking execution. -- GitLab