File size: 6,691 Bytes
a1912fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5c8b9cf
4299f4d
 
5c8b9cf
 
 
8bb5d86
5c8b9cf
 
 
8bb5d86
 
 
 
 
 
 
 
5c8b9cf
 
 
 
 
 
 
8bb5d86
 
 
5c8b9cf
a1912fe
 
 
 
 
 
 
6591f63
 
a1912fe
 
 
 
 
72b85f1
5c8b9cf
 
ddf6840
72b85f1
 
 
 
a1912fe
72b85f1
 
 
 
 
 
a1912fe
ddf6840
 
 
 
 
 
 
 
2c2263f
 
 
96095b3
 
a1912fe
72b85f1
 
 
ddf6840
 
72b85f1
a1912fe
ddf6840
a1912fe
72b85f1
 
a1912fe
8bb5d86
a1912fe
 
 
5c8b9cf
 
 
 
 
2c2263f
96095b3
 
a1912fe
1dc42d2
 
 
 
 
2777d26
1dc42d2
5c8b9cf
72b85f1
5c8b9cf
 
2c2263f
96095b3
 
1dc42d2
72b85f1
 
 
 
5c8b9cf
a1912fe
5c8b9cf
 
2c2263f
96095b3
 
a1912fe
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import gradio as gr
import plotly.graph_objects as go
from huggingface_hub import hf_hub_download
from datasets import load_dataset
import pathlib
import json
import pandas as pd
from evaluation import load_boundary, load_boundaries
from constellaration import forward_model, initial_guess
from constellaration.boozer import boozer
from constellaration.utils import (
    file_exporter,
    visualization,
    visualization_utils,
)


organization = 'proxima-fusion'
results_repo = f'{organization}/constellaration-bench-results'

def read_result_from_hub(filename):
    local_path = hf_hub_download(
        repo_id=results_repo,
        repo_type="dataset",
        filename=filename,
    )
    return local_path

def make_boundary_plot(boundary):
    boundary_ax = visualization.plot_boundary(boundary)
    boundary_plot = boundary_ax.get_figure()
    return boundary_plot

def make_interactive_plot(boundary):
    interactive_plot = visualization.plot_surface(boundary)
    return interactive_plot

def make_boozer_plot(boundary):
    settings = forward_model.ConstellarationSettings.default_high_fidelity_skip_qi()
    boundary_metrics, boundary_equilibrium = forward_model.forward_model(
        boundary, settings=settings
    )
    boozer_settings = boozer.BoozerSettings(normalized_toroidal_flux=[0.0, 0.25, 1])
    boozer_plot = visualization.plot_boozer_surfaces(
        boundary_equilibrium, settings=boozer_settings
    )
    return

def make_flux_surface_plot(boundary):
    settings = forward_model.ConstellarationSettings.default_high_fidelity_skip_qi()
    boundary_metrics, boundary_equilibrium = forward_model.forward_model(
        boundary, settings=settings
    )
    flux_surface_plot = visualization.plot_flux_surfaces(
        boundary_equilibrium, boundary
    )
    return flux_surface_plot

def gradio_interface() -> gr.Blocks:
    with gr.Blocks() as demo:
        gr.Markdown("""
                    # Welcome to the ConStellaration Boundary Explorer!

                    ### Here, you can visualize submissions to the ConStellaration Leaderboard, generate and visualize new random boundaries, or upload and visualize your own!

                    If you want to explore additional visualizations, like Boozer plots and flux surface plots, check out the `constellaration` library's [visualization tools](https://github.com/proximafusion/constellaration/blob/main/notebooks/boundary_explorer.ipynb).
                    """)
        
        ds = load_dataset(results_repo, split='train')
        full_df = pd.DataFrame(ds)
        filenames = full_df['result_filename'].to_list()

        boundary = gr.State()

        mode_selector = gr.Radio(choices=["Generate", "Leaderboard", "Upload"],
                                 label="Select input method:",
                                 value="Leaderboard")


        with gr.Row():
            with gr.Column(visible=False) as generate_ui:
                aspect_ratio = gr.Number(label="Aspect Ratio", value=3)
                elongation = gr.Number(label="Elongation", value=0.5)
                rotational_transform = gr.Number(label="Rotational Transform", value=0.4)
                n_field_periods = gr.Number(label="Number of Period Fields", value=3)
                generate_btn = gr.Button(value="Generate")

            with gr.Column(visible=True) as leaderboard_ui:
                dropdown = gr.Dropdown(choices=filenames, label="Choose a leaderboard entry", value=filenames[0])
                rld_btn = gr.Button(value="Reload")

            with gr.Column(visible=False) as upload_ui:
                upload_box = gr.File(file_types=[".json"], label="Upload your boundary file")
            
            
            with gr.Column(visible=True):
                interactive_plot = gr.Plot()
                boundary_plot = gr.Plot()
            #    boozer_plot = gr.Plot()
            #    flux_surface_plot = gr.Plot()

        def update_ui(mode):
            return (
                gr.update(visible=(mode == "Generate")),
                gr.update(visible=(mode == "Leaderboard")),
                gr.update(visible=(mode == "Upload")),  
            )

        mode_selector.change(update_ui, inputs=[mode_selector], outputs=[generate_ui, leaderboard_ui, upload_ui])

        def get_boundary_from_leaderboard(selected_file):
            row = full_df[full_df['result_filename'] == selected_file].iloc[0]
            if row['problem_type'] == 'mhd_stable':
                raise gr.Error("Sorry this isn't implemented for files with multiple boundaries yet!")
            else:
                boundary = load_boundary(row['boundary_json'])

            return boundary

        # dropdown.change(get_boundary_from_leaderboard, dropdown, [boundary_plot, interactive_plot, boozer_plot, flux_surface_plot])
        rld_btn.click(get_boundary_from_leaderboard, dropdown, boundary) \
            .then(make_interactive_plot, boundary, interactive_plot) \
            .then(make_boundary_plot, boundary, boundary_plot) \
            # .then(make_boozer_plot, boundary, boozer_plot) \
            # .then(make_flux_surface_plot, boundary, flux_surface_plot)


        def get_boundary_vis_from_upload(uploaded_file):
            if uploaded_file is None:
                raise gr.Error("Please upload a file.")
            with open(uploaded_file.name, 'r') as f:
                data = f.read()
            boundary = load_boundary(data)
            return boundary
        
        upload_box.change(get_boundary_vis_from_upload, inputs=[upload_box], outputs=boundary) \
            .then(make_interactive_plot, boundary, interactive_plot) \
            .then(make_boundary_plot, boundary, boundary_plot) \
            # .then(make_boozer_plot, boundary, boozer_plot) \
            # .then(make_flux_surface_plot, boundary, flux_surface_plot)

        def generate_random_boundary(aspect_ratio, elongation, rotational_transform, n_field_periods):
            boundary = initial_guess.generate_rotating_ellipse(
                aspect_ratio=aspect_ratio, elongation=elongation, rotational_transform=rotational_transform, n_field_periods=n_field_periods
            )
            return boundary
        
        generate_btn.click(generate_random_boundary, [aspect_ratio, elongation, rotational_transform, n_field_periods], boundary) \
            .then(make_interactive_plot, boundary, interactive_plot) \
            .then(make_boundary_plot, boundary, boundary_plot) \
            # .then(make_boozer_plot, boundary, boozer_plot) \
            # .then(make_flux_surface_plot, boundary, flux_surface_plot)

    return demo


if __name__ == "__main__":
    gradio_interface().launch()