File size: 6,062 Bytes
0fd80de 63c1cc0 89f58c0 63c1cc0 0fd80de 63c1cc0 0fd80de 63c1cc0 0fd80de 63c1cc0 0fd80de 63c1cc0 89f58c0 63c1cc0 89f58c0 63c1cc0 52d6c73 63c1cc0 0fd80de 89f58c0 0fd80de 89f58c0 63c1cc0 89f58c0 63c1cc0 89f58c0 63c1cc0 89f58c0 63c1cc0 89f58c0 63c1cc0 89f58c0 63c1cc0 89f58c0 63c1cc0 89f58c0 63c1cc0 89f58c0 63c1cc0 |
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 |
# All the datasets will use the same format: a collection of HDF5 files with data cubes
# in t0_fields: scalar fields, like density, pressure, energy
# the data is of shape (n_trajectories, n_time_steps, x, y)
# in t1_fields: vector fields, like velocity (size=2 => vx, vy)
# the data is of shape (n_trajectories, n_time_steps, x, y, vx/vy)
# in t2_fields: tensor fields, like ???
# the data is of shape (n_trajectories, n_time_steps, x, y, d1, d2), with d1, d2 in [0, 1]
# ie, instead of 1 additional dimension for velocity: a (2,2) matrix where each component
# (0,0),(1,0),(0,1),(1,1) can be plotted
# Size:
# - n_trajectories: 8 to 256
# - n_time_steps: 101
# - x: 128 to 512
# - y: 128 to 512
# - physical fields: 2 to 8 (density, pressure, energy, velocity…)
from functools import lru_cache
import gradio as gr
import h5py
import numpy as np
from fsspec import url_to_fs
from matplotlib import cm
from PIL import Image
import av
import io
repo_id = "lhoestq/turbulent_radiative_layer_tcool_demo"
set_path = f"hf://datasets/{repo_id}/**/*.hdf5"
fs, _ = url_to_fs(set_path)
paths = fs.glob(set_path)
files = {path: h5py.File(fs.open(path, "rb", cache_type="none"), "r") for path in paths}
def get_scalar_fields(path: str) -> list[str]:
# TODO: support t1_fields (vector) and t2_fields (tensor)
return list(files[path]["t0_fields"].keys())
def get_trajectories(path: str, field: str) -> list[int]:
# The first dimension is the trajectory (8 to 256)
return list(range(len(files[path]["t0_fields"][field])))
@lru_cache(maxsize=4)
def get_images(path: str, scalar_field: str, trajectory: int) -> list[Image.Image]:
# The data is of shape (n_trajectories, n_time_steps, x, y)
out = files[path]["t0_fields"][scalar_field][trajectory]
out = np.log(out) # not sure why
out = (out - out.min()) / (out.max() - out.min())
out = np.uint8(cm.RdBu_r(out) * 255)
return [Image.fromarray(img) for img in out]
fps = 25
# @lru_cache(maxsize=4)
def get_video(path: str, scalar_field: str, trajectory: int) -> str:
video_filename = 'output_vid.webm'
out = files[path]["t0_fields"][scalar_field][trajectory]
out = np.log(out) # not sure why
out = (out - out.min()) / (out.max() - out.min())
out = np.uint8(cm.RdBu_r(out) * 255)
output = av.open(video_filename, 'w')
stream = output.add_stream('libvpx-vp9', str(fps))
width, height = out[0].shape[1], out[0].shape[0]
stream.width = width
stream.height = height
stream.pix_fmt = 'yuv444p' # or yuva420p
# stream.options = {'crf': '17'}
for img in out:
image = Image.fromarray(img)
frame = av.VideoFrame.from_image(image)
packet = stream.encode(frame)
output.mux(packet)
# Flush the encoder and close the "in memory" file:
packet = stream.encode(None)
output.mux(packet)
output.close()
return video_filename
# subprocess.run(["ffmpeg", "-y", "-framerate", "25", "-i", os.path.join(output_dir, "density_%d.png"), "-c:v", "libvpx-vp9", "-pix_fmt", "yuva420p", os.path.join(output_dir, "density.webm")])
default_scalar_fields = get_scalar_fields(paths[0])
default_trajectories = get_trajectories(paths[0], default_scalar_fields[0])
default_images = get_images(paths[0], default_scalar_fields[0], default_trajectories[0])
default_video = get_video(paths[0], default_scalar_fields[0], default_trajectories[0])
with gr.Blocks() as demo:
gr.Markdown(f"# 💠 HDF5 Viewer for the [{repo_id}](https://huggingface.co/datasets/{repo_id}) Dataset 🌊")
gr.Markdown(f"Showing files at `{set_path}`")
with gr.Row():
files_dropdown = gr.Dropdown(choices=paths, value=paths[0], label="File", scale=4)
scalar_fields_dropdown = gr.Dropdown(choices=default_scalar_fields, value=default_scalar_fields[0], label="Physical field")
trajectory_dropdown = gr.Dropdown(choices=default_trajectories, value=default_trajectories[0], label="Trajectory")
gallery = gr.Gallery(default_images, preview=False, selected_index=len(default_images) // 2)
gr.Markdown("_Tip: click on the image to go forward or backwards_")
video = gr.Video(default_video)
@files_dropdown.select(inputs=[files_dropdown], outputs=[scalar_fields_dropdown, trajectory_dropdown, gallery, video])
def _update_file(path: str):
scalar_fields = get_scalar_fields(path)
trajectories = get_trajectories(path, scalar_fields[0])
images = get_images(path, scalar_fields[0], trajectories[0])
vid = get_video(path, scalar_fields[0], trajectories[0])
yield {
scalar_fields_dropdown: gr.Dropdown(choices=scalar_fields, value=scalar_fields[0]),
trajectory_dropdown: gr.Dropdown(choices=trajectories, value=trajectories[0]),
gallery: gr.Gallery(images),
video: gr.Video(vid)
}
yield {gallery: gr.Gallery(selected_index=len(default_images) // 2)}
@scalar_fields_dropdown.select(inputs=[files_dropdown, scalar_fields_dropdown], outputs=[trajectory_dropdown, gallery, video])
def _update_scalar_field(path: str, scalar_field: str):
trajectories = get_trajectories(path, scalar_field)
images = get_images(path, scalar_field, trajectories[0])
vid = get_video(path, scalar_field, trajectories[0])
yield {
trajectory_dropdown: gr.Dropdown(choices=trajectories, value=trajectories[0]),
gallery: gr.Gallery(images),
video: gr.Video(vid)
}
yield {gallery: gr.Gallery(selected_index=len(default_images) // 2)}
@trajectory_dropdown.select(inputs=[files_dropdown, scalar_fields_dropdown, trajectory_dropdown], outputs=[gallery, video])
def _update_trajectory(path: str, scalar_field: str, trajectory: int):
images = get_images(path, scalar_field, trajectory)
vid = get_video(path, scalar_field, trajectory)
yield {gallery: gr.Gallery(images), video: gr.Video(vid)}
yield {gallery: gr.Gallery(selected_index=len(default_images) // 2)}
demo.launch() |