import matplotlib.
pyplot as plt
import math
import pandas as pd
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
from main3 import main3
from main7 import main7
from main8 import main8
def load_data(file_path):
"""Load the Excel data into a DataFrame."""
try:
return pd.read_excel(file_path)
except Exception as e:
print(f"Error loading data: {e}")
return pd.DataFrame()
def create_cube(x, y, z):
"""Create vertices and faces for a cube at the given position."""
vertices = [
[x, y, z], [x + 1, y, z], [x + 1, y + 1, z], [x, y + 1, z], # Bottom base
[x, y, z + 1], [x + 1, y, z + 1], [x + 1, y + 1, z + 1], [x, y + 1, z + 1]
# Top base
]
faces = [
[vertices[0], vertices[1], vertices[5], vertices[4]], # Front face
[vertices[1], vertices[2], vertices[6], vertices[5]], # Right face
[vertices[2], vertices[3], vertices[7], vertices[6]], # Back face
[vertices[3], vertices[0], vertices[4], vertices[7]], # Left face
[vertices[0], vertices[1], vertices[2], vertices[3]], # Bottom base
[vertices[4], vertices[5], vertices[6], vertices[7]] # Top base
]
return vertices, faces
def create_cubes(x_dim, y_dim, z_dim, total_cubes, spacing, type_mono, file_path):
"""Create cubes dynamically and store them in a dictionary based on their z
index."""
cubes_dict = {z: [] for z in range(1, z_dim + 1)} # Initialize empty lists for
each z index starting from 1
cubes_created = 0
data = pd.read_excel(file_path)
if 'x' in data.columns and 'y' in data.columns and 'z' in data.columns:
for index, row in data.iterrows():
x, y, z = row['x'], row['y'], row['z'] # Access columns by name
# Ensure z is an integer and adjusted to start from 1
z = int(z) - 1 # Adjust the z value to start from 1 (this subtracts 1
for internal indexing)
# Check if z exists in cubes_dict, otherwise initialize it
if z not in cubes_dict:
cubes_dict[z] = []
# Create cubes based on the monolith type and z dimension constraints
if type_mono in ["II", "III"] and z_dim <= 5:
if cubes_created >= total_cubes:
break
origin = (x * (1 + spacing), y * (1 + spacing), (z + 1) * (1 +
spacing)) # Adjust origin to start from z=1
vertices, faces = create_cube(*origin)
cubes_dict[z].append((vertices, faces))
cubes_created += 1
else:
print("Columns 'x', 'y', 'z' not found in the data.")
return cubes_dict
def on_key(event, selected_cube, x_dim, y_dim, z_dim, cubes_dict, ax1, data):
"""Handle keyboard events to navigate the selected cube."""
if event.key == 'up' and selected_cube[1] > 0:
selected_cube[1] -= 1
elif event.key == 'down' and selected_cube[1] < y_dim - 1:
selected_cube[1] += 1
elif event.key == 'right' and selected_cube[0] > 0:
selected_cube[0] -= 1
elif event.key == 'left' and selected_cube[0] < x_dim - 1:
selected_cube[0] += 1
elif event.key == 'n' and selected_cube[2] < z_dim - 1:
selected_cube[2] += 1
elif event.key == 'b' and selected_cube[2] > 0:
selected_cube[2] -= 1
# Redraw the stage with updated cube selection
draw_stage(ax1, 'cyan', selected_cube, 0.2, x_dim, y_dim, z_dim, cubes_dict,
data)
def draw_static_view(ax, cubes_dict, spacing, x_dim, y_dim, z_dim):
"""Draw the static full cube view using dose-based coloring."""
ax.clear()
cmap = plt.colormaps.get_cmap('Blues') # Use a blue colormap for dose
visualization
for stage in cubes_dict.values():
for faces, norm_dose in stage:
color = cmap(norm_dose) # Map normalized dose to colormap
ax.add_collection3d(Poly3DCollection(faces, facecolors=color,
edgecolors='black', alpha=0.7))
ax.set_xlim([0, x_dim * (1 + spacing)])
ax.set_ylim([0, y_dim * (1 + spacing)])
ax.set_zlim([0, z_dim * (1 + spacing)])
ax.set_title("Static Full Cube View (Dose Intensity)")
plt.draw()
def draw_stage(ax, stage_color, selected_cube, spacing, x_dim, y_dim, z_dim,
cubes_dict, data):
"""Draw cubes of the selected stage and display the selected cube's
position."""
ax.clear()
unique_id = selected_cube[2] * x_dim * y_dim + 1 # Start unique ID based on
the stage (z)
for z in cubes_dict:
if z == selected_cube[2]: # Only draw the selected layer
for i, (vertices, faces) in enumerate(cubes_dict[z]):
# Get the cube's position from the DataFrame based on its ID
cube_data = data.iloc[selected_cube[2] * x_dim * y_dim + i]
dose_value = cube_data['dose'] # Assuming the fourth column in the
Excel file is called 'dose'
# If we are in the last stage (z == z_dim - 1), check the dose
if z == z_dim - 1:
color = 'yellow' if dose_value > 100 else stage_color # Color
yellow if dose > 100 ##############################change
values################################################################
else:
color = stage_color # For other stages, use the regular color
if i == selected_cube[0] * y_dim + selected_cube[1]:
color = 'red' # Highlight the selected cube in red
# Add the cube to the plot
ax.add_collection3d(Poly3DCollection(faces, facecolors=color,
edgecolors='black', alpha=0.7))
# If this is the selected cube, show its position in the plot
if i == selected_cube[0] * y_dim + selected_cube[1]:
ax.text(
0.05, 0.95, 0.95, # Position of the text in 3D space
(relative coordinates)
f"Cube ID: {unique_id}\nPosition: ({cube_data['x']},
{cube_data['y']}, {cube_data['z']})\nDose: {dose_value} µSv/h",
color='white', fontsize=12, transform=ax.transAxes
)
# Increment the unique ID
unique_id += 1
ax.set_xlim([+1, x_dim * (1 + spacing) - spacing])
ax.set_ylim([+1, y_dim * (1 + spacing) - spacing])
ax.set_zlim([+1, z_dim * (1 + spacing) - spacing])
plt.draw()
def create_gui(fig):
"""Create the Tkinter GUI with matplotlib embedded and a table showing cubes
with dose > 100 in the last stage."""
window = tk.Tk()
window.title("Gestion des Déchets Radioactifs")
window.attributes('-fullscreen', True)
window.configure(bg='#2d2d2d') # Industrial dark theme
# Frame for the plot
plot_frame = tk.Frame(window, bg="#333", bd=5, relief="raised", borderwidth=3)
plot_frame.place(x=107, y=277, width=707, height=707)
# Canvas to display the matplotlib figure
canvas = FigureCanvasTkAgg(fig, master=window)
canvas_widget = canvas.get_tk_widget()
canvas_widget.place(x=110, y=280, width=700, height=700)
return window
def dose_rates_distribution():
"""Function to open main3.py"""
main3()
def dose_rates_distribution_Y():
"""Function to open main7.py"""
main7()
def dose_rates_distribution_X():
"""Function to open main8.py"""
main8()
def main():
file_path = "position_monolithe.xlsx"
data = load_data(file_path)
x_dim, y_dim = 12, 13 # Define the dimensions of the grid
spacing = 0.2
type_monolith = "II"
total_cubes = len(data)
z_dim = math.ceil(total_cubes / (x_dim * y_dim)) # Calculate z dimension based
on total cubes
cubes_dict = create_cubes(x_dim, y_dim, z_dim, total_cubes, spacing,
type_monolith, file_path)
fig = plt.figure(figsize=(6, 6))
ax1 = fig.add_subplot(121, projection='3d')
ax1.set_facecolor('darkgray')
ax1.set_position([0.0, 0.0, 1, 1])
ax1.view_init(elev=37, azim=37)
selected_cube = [0, 0, 0] # Ensure that we start with the first cube at the
first stage (z=0)
window = create_gui(fig)
# To display the first stage initially, you can directly call draw_stage with
the initial selection
draw_stage(ax1, 'cyan', selected_cube, spacing, x_dim, y_dim, z_dim,
cubes_dict, data)
fig.canvas.mpl_connect(
'key_press_event',
lambda event: on_key(event, selected_cube, x_dim, y_dim, z_dim, cubes_dict,
ax1, data)
)
# Create a button in the main window to open the new window
open_button = tk.Button(window, text="Visualization of the distribution of dose
rates - Surface", command=dose_rates_distribution, font=("Arial", 12))
open_button.pack(pady=50)
# Create a button in the main window to open the new window
open_button2 = tk.Button(window, text="Visualization of the distribution of
dose rates - Ligne Y", command=dose_rates_distribution_Y, font=("Arial", 12))
open_button2.pack(pady=50)
# Create a button in the main window to open the new window
open_button3 = tk.Button(window, text="Visualization of the distribution of
dose rates - Ligne X", command=dose_rates_distribution_X, font=("Arial", 12))
open_button3.pack(pady=50)
# Close event handler
window.protocol("WM_DELETE_WINDOW", lambda: window.destroy())
window.bind("<Escape>", lambda event: window.destroy())
window.mainloop()
if __name__ == "__main__":
main()