FCD-Solar-Demo / app.py
mervess
changed the sdk version
6761b20
Raw
History Blame Contribute Delete
8.45 kB
import gradio as gr
import os
os.environ['NUMBA_ENABLE_CUDASIM'] = '1'
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' # Suppress TensorFlow warnings unless fatal
# !! For now, because it is a private repo !!
from huggingface_hub import login, hf_hub_download
# login(token=os.environ.get("HF_AUTH_TOKEN"))
# from huggingface_hub import hf_hub_download
from tensorflow.keras.saving import load_model
import numpy as np
from numba import cuda
from scipy.io import readsav
import matplotlib.pyplot as plt
import time
from filters import GaussianFilter
from vec_metrics import get_pred_vis, mae_of_vectors
# ============================================= LOAD MODEL ===========================================
# Load your trained model
model_path = hf_hub_download(repo_id="mervess/FCD-Solar", filename="fcd.keras")
model = load_model(model_path,
custom_objects={'GaussianFilter': GaussianFilter},
compile=False)
print("#) Model loaded successfully.")
# Load the F matrix
f_matrix = np.load("data/fourier_matrix.npy")
print("#) STIX fourier matrix loaded successfully.")
# ============================================= PREDICT ==============================================
# Define a function for prediction
def predict_image(vis):
norm_vis = np.empty(vis.shape)
alphas = np.empty(vis.shape[0], dtype=np.float32)
threadsperblock = 32
blockspergrid = (alphas.size + (threadsperblock - 1)) // threadsperblock
calc_alphas_cpu[blockspergrid, threadsperblock](vis, alphas, norm_vis)
predicted_img = model.predict(norm_vis, batch_size=128, verbose=False)
predicted_img = predicted_img * alphas[:, np.newaxis, np.newaxis, np.newaxis]
output_image = np.squeeze(predicted_img)
return output_image
@cuda.jit
def calc_alphas_cpu(vis_arrays, alphas, norm_vis):
pos = cuda.grid(1)
if pos < alphas.size:
nvis = np.sqrt(
np.square(vis_arrays[pos, :24]) + np.square(vis_arrays[pos, 24:]))
alphas[pos] = np.max(nvis) * 0.5
for i in range(vis_arrays.shape[1]):
norm_vis[pos][i] = vis_arrays[pos][i] / alphas[pos]
# ============================================ READ FILES ============================================
def read_file( file_name, file_type='.npy' ):
if file_type == '.npy':
vis_array = np.load( file_name )
elif file_type == '.sav':
data = readsav( file_name, python_dict=True, verbose=False )
vis_structure = data['vis']
vis_components = vis_structure['OBSVIS']
vis_array = np.hstack( ( np.real(vis_components), np.imag(vis_components) ) )
return vis_array
# ========================================== EXAMPLE INPUTS ==========================================
# Provide sample data
# ===== 1 =====
vis_array = read_file('example_data/20211216_vis.sav', file_type='.sav')
# ===== 2 =====
vis_array_2 = read_file('example_data/20221231_vis.sav', file_type='.sav')
# ===== 3 =====
vis_array_3 = read_file('example_data/20220828_vis.sav', file_type='.sav')
sample_vectors = {
"20211216T233548-20211216T234036_10-15keV": vis_array,
"20221231T123044-20221231T123252_4-10keV": vis_array_2,
"20220828T155202-20220828T160950_25-50keV": vis_array_3,
}
print("#) Sample data loaded successfully.")
# ============================================ VISUALIZE =============================================
def plot_map( map_data, img_name='', color_map='turbo', is_minorticks_on=True, show_colorbar=True, save_plot=False, plot_title="plot.pdf" ):
fig, ax = plt.subplots(figsize=(3, 3))
cax = ax.imshow(map_data, cmap=color_map)
ax.set_title(img_name)
ax.axis("off")
if show_colorbar:
cbar = fig.colorbar(cax, ax=ax, orientation='horizontal',
fraction=0.046, pad=0.07, extend='both')
cbar.ax.tick_params(labelsize='large') # Increase colorbar font size
# Set the colorbar ticks to beginning, middle, and end, optimizing the formatting process
min_val = map_data.min()
max_val = map_data.max()
mid_val = (min_val + max_val) / 2
cbar.set_ticks([min_val, mid_val, max_val])
cbar.set_ticklabels([f'{min_val:.4f}', f'{mid_val:.4f}', f'{max_val:.4f}'])
if is_minorticks_on:
cbar.minorticks_on()
plt.tight_layout()
if save_plot:
f_format = os.path.splitext(plot_title)[-1][1:]
if show_colorbar:
plt.savefig(plot_title, format=f_format, bbox_inches='tight')
else:
plt.savefig(plot_title, format=f_format, bbox_inches='tight', pad_inches=0)
plt.show()
def to_html( msg, color='red' ):
return f"<html><p style='color:{color};'>{msg}</p></html>"
# =============================================== DEMO ===============================================
# Gradio interface
def demo( sample_choice, input_vector, uploaded_file ):
"""
Function to demonstrate the FCD model.
Parameters:
-----------
sample_choice: str
Sample choice from the dropdown list.
input_vector: str
Input vector from the textbox.
uploaded_file: file
Uploaded file.
Returns:
--------
numpy array (image)
Reconstructed image.
str
(-) Message to display. / (+) Prediction time.
str
Chi2 value.
"""
vis = None
# ==== SAMPLE CHOICE ====
if sample_choice != "" and \
sample_choice is not None and \
sample_choice in sample_vectors:
vis = sample_vectors[sample_choice]
# ==== INPUT VECTOR ====
elif input_vector != "" and input_vector is not None and \
isinstance(input_vector, str):
try:
vis = np.array( [ float(i) for i in input_vector.split(",") ], dtype=np.float32 )
if vis.shape != (48,):
return None, None, None, to_html("Please provide an input vector of 48 real numbers.")
except:
return None, None, None, to_html("Please provide an input consisting of real numbers.")
# ==== UPLOADED FILE ====
elif uploaded_file is not None:
try:
# Get the file name
file_name = uploaded_file.name
# Split the file name to get the extension
_, file_extension = os.path.splitext(file_name)
vis = read_file( file_name, file_type=file_extension )
except Exception as e:
return None, None, None, to_html(f"Error processing the uploaded file: {e}.")
# ==== PREDICT ====
if vis is None:
return None, None, None, to_html("Please provide a sample, input vector, or upload a file.")
else:
start_time = time.time()
image = predict_image(vis.reshape(1, -1))
prediction_time = time.time() - start_time
# Calculate MAE between predicted visibility and input visibility
pred_vis = get_pred_vis( image, f_matrix )
mae = mae_of_vectors( vis, pred_vis )
plot_map(image, save_plot=True, plot_title="fcd_image.png")
return "fcd_image.png", \
f"{prediction_time:.2f} seconds", \
f"{mae:.3f}", \
to_html("Image has been reconstructed.", color='green')
# =============================================== MAIN ===============================================
# Build Gradio Interface
interface = gr.Interface(
fn=demo,
inputs=[
gr.Dropdown(
choices=[""] + list(sample_vectors.keys()),
label="Select a sample vector (i.e., visibility, Fourier components):",
value="", # Placeholder
),
gr.Textbox(
label="Enter your vector (comma-separated 48 real numbers):",
placeholder="e.g., 0.1, 0.2, 0.3",
),
gr.File(
label="Upload your file (either a .sav or .npy file):",
type="filepath", # Accept file uploads
),
],
outputs=[
gr.Image(type="filepath", label="Reconstructed Image"),
gr.Textbox(label="Reconstruction Time"), # Line for prediction time
gr.Textbox(label="MAE Metric"), # Line for MAE metric
gr.HTML(label="Message"), # Line for messages
],
title="FCD Demo",
description="Select a sample, enter vector (visibility) values, or upload a file to see the reconstructed image.",
)
# Launch the app
interface.launch()