forked from BLAST-ImpactX/impactx
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added trame dashboard `impactx-dashboard` Co-authored-by: Axel Huebl <[email protected]>
- Loading branch information
Showing
29 changed files
with
2,119 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -68,6 +68,7 @@ Usage | |
usage/examples | ||
usage/python | ||
usage/parameters | ||
usage/dashboard | ||
usage/workflows | ||
|
||
Data Analysis | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
.. _usage-dashboard: | ||
|
||
Dashboard | ||
========= | ||
|
||
ImpactX Dashboard is a browser-based interface to ImpactX. | ||
It provides a graphical interface to a subset of ImpactX functionality. | ||
|
||
.. note:: | ||
|
||
ImpactX Dashboard is provided as a preview and continues to be developed. | ||
Let us know in GitHub `discussions <https://github.com/ECP-WarpX/impactx/discussions>`__ and `issues <https://github.com/ECP-WarpX/impactx/issues>`__ how it works for you and what kind of workflows you would like to run in it. | ||
|
||
|
||
Launching the Dashboard | ||
----------------------- | ||
|
||
The ImpactX Dashboard can be run in two modes, as a standalone browser application or inside a Jupyter notebook. | ||
|
||
1. **Standalone browser application:** | ||
After installation of ImpactX including the Python modules, launch: | ||
|
||
.. code-block:: bash | ||
impactx-dashboard | ||
2. **JupyterLab:** | ||
Start `JupyterLab <https://jupyter.org/install>`__, e.g., logging into a Jupyter service at an HPC center or locally on your computer using: | ||
|
||
.. code-block:: bash | ||
jupyter-lab | ||
Inside JupyterLab, run the following Python code in a notebook to initialize and display the dashboard: | ||
|
||
.. code-block:: python | ||
from impactx.dashboard import JupyterApp | ||
# Create new application instance | ||
app = JupyterApp() | ||
# Start the server and wait for the UI to be ready | ||
await app.ui.ready | ||
# Display the UI in the JupyterLab notebook | ||
app.ui | ||
Navigation | ||
---------- | ||
|
||
The user-friendly interface includes multiple tabs and menu options, intended to be navigated from top to bottom: | ||
|
||
- **Input Tab**: Allows to adjust simulation input parameters. | ||
- **Run Tab**: Enables to run simulations and monitor their progress. | ||
- **Analyze Tab**: Provides tools to visualize and analyze simulation results. | ||
|
||
.. figure:: https://gist.githubusercontent.com/ax3l/b56aa3c3261f9612e276f3198b34f771/raw/11bfe461a24e1daa7fd2d663c686b0fcc2b6e305/dashboard.png | ||
:align: center | ||
:width: 75% | ||
:alt: phase space ellipse | ||
|
||
Input section in the dashboard. | ||
|
||
|
||
Developers | ||
---------- | ||
|
||
Additional Dependencies | ||
""""""""""""""""""""""" | ||
|
||
Additional dependencies to ImpactX for the dashboard are included relative ImpactX source directory: | ||
|
||
.. code-block:: bash | ||
python -m pip install -r src/python/impactx/dashboard/requirements.txt | ||
Python Module | ||
""""""""""""" | ||
|
||
After installing only the ImpactX Python bindings, one can directly run the dashboard modules from the source tree during development, too. | ||
For this, navigate in the ImpactX source directory to the ``src/python/impactx`` directory and run: | ||
|
||
.. code-block:: bash | ||
python -m dashboard |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
101 changes: 101 additions & 0 deletions
101
src/python/impactx/dashboard/Analyze/analyzeFunctions.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
""" | ||
This file is part of ImpactX | ||
Copyright 2024 ImpactX contributors | ||
Authors: Parthib Roy, Axel Huebl | ||
License: BSD-3-Clause-LBNL | ||
""" | ||
|
||
import pandas as pd | ||
|
||
from ..trame_setup import setup_server | ||
|
||
server, state, ctrl = setup_server() | ||
|
||
# ----------------------------------------------------------------------------- | ||
# Content | ||
# ----------------------------------------------------------------------------- | ||
|
||
|
||
class AnalyzeFunctions: | ||
""" | ||
Helper functions for | ||
preparing the contents for the 'Analyze' page | ||
""" | ||
|
||
# ----------------------------------------------------------------------------- | ||
# Functions for Beam Characteristic and Ref particle data table | ||
# ----------------------------------------------------------------------------- | ||
|
||
@staticmethod | ||
def load_data(file_path): | ||
""" | ||
Reads data from the provided file path. | ||
:param file_path: The path to the file to be read. | ||
:return: A DataFrame containing the data from the file. | ||
""" | ||
|
||
df = pd.read_csv(file_path, sep=" ") | ||
return df | ||
|
||
@staticmethod | ||
def convert_to_dict(combined_data): | ||
""" | ||
Converts data to dictionary format | ||
for Vuetify data table. | ||
:param combined_data: The DataFrame to be converted. | ||
:return: A tuple containing the data as a list of dictionaries and the headers. | ||
""" | ||
|
||
dictionary = combined_data.to_dict(orient="records") | ||
columns = combined_data.columns | ||
headers = [ | ||
{"text": column.strip(), "value": column.strip()} for column in columns | ||
] | ||
return dictionary, headers | ||
|
||
@staticmethod | ||
def combine_files(file1_name, file2_name): | ||
""" | ||
Merges two files together. | ||
:param file1_name: The name of the first file. | ||
:param file2_name: The name of the second file. | ||
:return: A DataFrame containing the merged data from the two files. | ||
""" | ||
|
||
file1 = AnalyzeFunctions.load_data(file1_name) | ||
file2 = AnalyzeFunctions.load_data(file2_name) | ||
return pd.merge(file1, file2, how="outer") | ||
|
||
@staticmethod | ||
def filter_headers(allHeaders, selected_headers): | ||
""" | ||
Retrieves only user-selected headers. | ||
:param allHeaders: The list of all headers. | ||
:param selected_headers: The list of headers selected by the user. | ||
:return: A list of filtered headers based on user selection. | ||
""" | ||
|
||
filtered_headers = [] | ||
for selectedHeader in allHeaders: | ||
if selectedHeader["value"] in selected_headers: | ||
filtered_headers.append(selectedHeader) | ||
return filtered_headers | ||
|
||
@staticmethod | ||
def filter_data(allData, selected_headers): | ||
""" | ||
Retrieves data for user-selected headers. | ||
:param allData: The list of all data. | ||
:param selected_headers: The list of headers selected by the user. | ||
:return: A list of filtered data based on user selection. | ||
""" | ||
|
||
filtered_data = [] | ||
for row in allData: | ||
filtered_row = {} | ||
for key, value in row.items(): | ||
if key in selected_headers: | ||
filtered_row[key] = value | ||
filtered_data.append(filtered_row) | ||
return filtered_data |
44 changes: 44 additions & 0 deletions
44
src/python/impactx/dashboard/Analyze/plot_ParameterEvolutionOverS/overS.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
""" | ||
This file is part of ImpactX | ||
Copyright 2024 ImpactX contributors | ||
Authors: Parthib Roy, Axel Huebl | ||
License: BSD-3-Clause-LBNL | ||
""" | ||
|
||
import plotly.graph_objects as go | ||
|
||
|
||
def line_plot_1d(selected_headers, filtered_data): | ||
""" | ||
Generates a 1D line plot using Plotly based on selected headers and filtered data. | ||
""" | ||
|
||
x_axis = selected_headers[0] if len(selected_headers) > 1 else None | ||
y_axis = selected_headers[1:] if len(selected_headers) > 2 else None | ||
|
||
x = [row[x_axis] for row in filtered_data] if x_axis else [] | ||
|
||
figure_data = [] | ||
if y_axis: | ||
for column in y_axis: | ||
y = [row[column] for row in filtered_data] | ||
trace = go.Scatter( | ||
x=x, | ||
y=y, | ||
mode="lines+markers", | ||
name=column, | ||
line=dict(width=2), | ||
marker=dict(size=8), | ||
) | ||
figure_data.append(trace) | ||
|
||
return go.Figure( | ||
data=figure_data, | ||
layout=go.Layout( | ||
title="Plot Over S", | ||
xaxis=dict(title="s"), | ||
yaxis=dict(title=""), | ||
margin=dict(l=20, r=20, t=25, b=30), | ||
), | ||
) |
77 changes: 77 additions & 0 deletions
77
src/python/impactx/dashboard/Analyze/plot_PhaseSpaceProjections/phaseSpace.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
""" | ||
This file is part of ImpactX | ||
Copyright 2024 ImpactX contributors | ||
Authors: Parthib Roy, Axel Huebl | ||
License: BSD-3-Clause-LBNL | ||
""" | ||
|
||
from ...trame_setup import setup_server | ||
|
||
server, state, ctrl = setup_server() | ||
|
||
import base64 | ||
import io | ||
|
||
from impactx import Config, ImpactX | ||
|
||
from ...Input.distributionParameters.distributionMain import distribution_parameters | ||
from ...Input.latticeConfiguration.latticeMain import lattice_elements | ||
from ..plot_PhaseSpaceProjections.phaseSpaceSettings import adjusted_settings_plot | ||
|
||
# Call MPI_Init and MPI_Finalize only once: | ||
if Config.have_mpi: | ||
from mpi4py import MPI # noqa | ||
|
||
|
||
def fig_to_base64(fig): | ||
""" | ||
Puts png in trame-compatible form | ||
""" | ||
buf = io.BytesIO() | ||
fig.savefig(buf, format="png") | ||
buf.seek(0) | ||
return base64.b64encode(buf.read()).decode("utf-8") | ||
|
||
|
||
def run_simulation(): | ||
""" | ||
This tests using ImpactX and Pandas Dataframes | ||
""" | ||
sim = ImpactX() | ||
|
||
sim.particle_shape = state.particle_shape | ||
sim.space_charge = False | ||
sim.slice_step_diagnostics = True | ||
sim.init_grids() | ||
|
||
# init particle beam | ||
kin_energy_MeV = state.kin_energy_MeV | ||
bunch_charge_C = state.bunch_charge_C | ||
npart = state.npart | ||
|
||
# reference particle | ||
pc = sim.particle_container() | ||
ref = pc.ref_particle() | ||
ref.set_charge_qe(-1.0).set_mass_MeV(0.510998950).set_kin_energy_MeV(kin_energy_MeV) | ||
|
||
distribution = distribution_parameters() | ||
sim.add_particles(bunch_charge_C, distribution, npart) | ||
|
||
lattice_configuration = lattice_elements() | ||
|
||
sim.lattice.extend(lattice_configuration) | ||
|
||
# simulate | ||
sim.evolve() | ||
|
||
fig = adjusted_settings_plot(pc) | ||
fig_original = pc.plot_phasespace() | ||
|
||
if fig_original is not None: | ||
image_base64 = fig_to_base64(fig_original) | ||
state.image_data = f"data:image/png;base64, {image_base64}" | ||
|
||
sim.finalize() | ||
|
||
return fig |
Oops, something went wrong.