Skip to content
Snippets Groups Projects
page1_simulation.py 17.4 KiB
Newer Older
#
# This file is part of Shalava.
#
# Copyright (C) 2019 Noe Bernabeu <Noe.Bernabeu@gmail.com>
#
# Shalava is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Shalava is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Shalava; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
# 
# =========================================================================
Noe Bernabeu's avatar
Noe Bernabeu committed
PKGDATADIR="."
EXT noe bernabeu's avatar
EXT noe bernabeu committed
PKGLIBDIR="."
Pierre Saramito's avatar
Pierre Saramito committed
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
Pierre Saramito's avatar
Pierre Saramito committed
import os
import functools
EXT noe bernabeu's avatar
EXT noe bernabeu committed
import PIL.Image
import PIL.ImageTk 
Noe Bernabeu's avatar
Noe Bernabeu committed

import importlib.machinery
pymap = importlib.machinery.SourceFileLoader('pymap',PKGDATADIR+'/pymap.py').load_module()
vertical_canvas = importlib.machinery.SourceFileLoader('vertical_canvas',PKGDATADIR+'/vertical_canvas.py').load_module()
lavaview_variable = importlib.machinery.SourceFileLoader('lavaview_variable',PKGDATADIR+'/lavaview_variable.py').load_module()
from vertical_canvas import *
from lavaview_variable import *
Pierre Saramito's avatar
Pierre Saramito committed

dark_grey = "#282827"
light_grey = "#484845"

class page1():
	"""
	A class to create the first page about the domain
	"""
	def __init__(self, parent, mytitle, *args, **kw):
		self.parent=parent
		f = parent.n.add(mytitle)
		parent.n.tab(mytitle).configure(background=dark_grey,fg="white")
		self.scrollable_canvas  = VerticalScrolledFrame(f)
		self.scrollable_canvas.pack(fill = 'both', expand = 1)
		parent.n.tab(mytitle).bind('<1>',self.reset_the_view,add="+") #reset the view after click on tabs
		main_window = self.scrollable_canvas.interior
		# Create a frame to center all widgets
		center_Frame = Frame(main_window)
		center_Frame.pack()
		center_Frame.configure(borderwidth=0, bg=dark_grey)
EXT noe bernabeu's avatar
EXT noe bernabeu committed
		# load DEM file
		Label(center_Frame, text="Load DEM file :", bg=dark_grey, fg="white").grid(sticky="E", row = 0, column = 0, padx = 5, pady = 5)
		self.load_file = PhotoImage(file=PKGDATADIR+'/load_file_icone_36px.png')
		self.frame_load_DEM = Frame(center_Frame, bg=dark_grey, padx = 5, pady = 5)
		self.frame_load_DEM.grid(row = 0, column = 1)
		self.DEM_filename = "none"
		self.DEM_Var = StringVar()
		self.DEM_Var.set("none")
		self.load_DEM_button = Button(self.frame_load_DEM, text="Load DEM file", image=self.load_file, borderwidth=0, highlightthickness=0, command = self.open_DEM_file)
		self.variable_DEM_entry = Entry(self.frame_load_DEM,textvariable=self.DEM_Var, width=10, font=("Helvetica", 16), state="disabled")
		self.variable_DEM_entry.grid(row=0, column=1)
		self.load_DEM_button.grid(row=0, column=2, sticky = W)
		"""Label(center_Frame,text="Simulation domain setting",font=("Helvetica", 16, "bold"), bg=dark_grey, fg= "white").grid(row=0,column=0,columnspan=3,padx = 5, pady = 5)
Pierre Saramito's avatar
Pierre Saramito committed
		Label(center_Frame,text="Select DEM", bg=dark_grey, fg= "white").grid(row=1,column=0,padx = 5, pady = 5)
		self.select_map = Listbox(center_Frame,height=3,exportselection=False,selectmode='single')
		self.select_map.insert('end', "Reunion island (2008)")
		self.select_map.insert('end', "Kilauea lava flow (1974)")
		self.select_map.insert('end', "Etna (2001)")
		self.select_map.grid(sticky = "w", row=1, column=1, columnspan = 2, padx = 5, pady = 5)
		self.selected_item = IntVar()
		self.selected_item.set(0)
		self.select_map.select_set(self.selected_item.get())
EXT noe bernabeu's avatar
EXT noe bernabeu committed
		self.select_map.bind("<<ListboxSelect>>", self.updateLabel)"""
Pierre Saramito's avatar
Pierre Saramito committed
		self.xmin = 0
		self.xmax = 0
		self.ymin = 0
		self.ymax = 0
EXT noe bernabeu's avatar
EXT noe bernabeu committed
		self.utm_zone = Lavaview_variable(center_Frame,"UTM grid zone", "UTM grid zone (<< longitudinal zone number >><< latitudinal zone letter >>, \n ex: the southern end of South America is 19F)","40K",1,0,dark_grey)
		self.btnUTMMap = ttk.Button(center_Frame, text='?', command = self.add_sidemenu) #self.tl_UTM_Map)
		self.btnUTMMap.grid(row=1, column=2, padx=5, pady=5, sticky = W)
		self.main_vent_xe_variable = Lavaview_scale_variable(center_Frame,0,1000,1,1,"main vent position E (UTM coordinates)","the main vent position E in UTM coordinates (m)", 0,2,0,dark_grey)
		self.main_vent_ye_variable = Lavaview_scale_variable(center_Frame,0,1000,1,1,"main vent position N (UTM coordinates)","the main vent position N in UTM coordinates (m)", 0,3,0,dark_grey)
		self.south_variable = Lavaview_scale_variable(center_Frame,0,1000,100,1,"south","south extension", 1000,4,0,dark_grey)
		self.est_variable = Lavaview_scale_variable(center_Frame,0,1000,100,1,"est","est extension",1000,5,0,dark_grey)
		self.north_variable = Lavaview_scale_variable(center_Frame,0,1000,100,1,"north","north extension", 1000,6,0,dark_grey)
		self.west_variable = Lavaview_scale_variable(center_Frame,0,1000,100,1,"west", "west extension", 1000,7,0,dark_grey)
Pierre Saramito's avatar
Pierre Saramito committed
		self.main_vent_xe_variable.Myvar.trace("w", self.callback_trace_xe)
		self.main_vent_ye_variable.Myvar.trace("w", self.callback_trace_ye)
		self.south_variable.Myvar.trace("w", self.callback_trace_south)
		self.est_variable.Myvar.trace("w", self.callback_trace_est)
		self.north_variable.Myvar.trace("w", self.callback_trace_north)
		self.west_variable.Myvar.trace("w", self.callback_trace_west)
		self.main_vent_xe_variable.Myscale.config(command=self.callback_scale_xe)
		self.main_vent_ye_variable.Myscale.config(command=self.callback_scale_ye)
		self.south_variable.Myscale.config(command=self.callback_scale_south)
		self.est_variable.Myscale.config(command=self.callback_scale_est)
		self.north_variable.Myscale.config(command=self.callback_scale_north)
		self.west_variable.Myscale.config(command=self.callback_scale_west)
		self.main_vent_xe_variable.MyEntry.bind('<FocusOut>', self.controle_value_xe)
		self.main_vent_ye_variable.MyEntry.bind('<FocusOut>', self.controle_value_ye)
		self.south_variable.MyEntry.bind('<FocusOut>', functools.partial(self.controle_value, variable=self.south_variable))
		self.est_variable.MyEntry.bind('<FocusOut>', functools.partial(self.controle_value, variable=self.est_variable))
		self.north_variable.MyEntry.bind('<FocusOut>', functools.partial(self.controle_value, variable=self.north_variable))
		self.west_variable.MyEntry.bind('<FocusOut>', functools.partial(self.controle_value, variable=self.west_variable))
EXT noe bernabeu's avatar
EXT noe bernabeu committed
		self.reso_variable = Lavaview_variable(center_Frame,"resolution", "resolution of DEM (m)", 10,8,0,dark_grey)
Pierre Saramito's avatar
Pierre Saramito committed
		self.message_Label=Label(main_window, bg=dark_grey, fg= "white")
		self.updateLabel() #default value (reunion volcano)
		Frame_for_button=Frame(main_window,bg=dark_grey)
		Frame_for_button.pack(padx = 5, pady = 5)
		generate_mesh_button = ttk.Button(Frame_for_button, text = 'Generate mesh and DEM files', command =  lambda:self.generate_mesh_command(parent))
		generate_mesh_button.grid(row=0,column=0, padx = 5, pady = 5)
		view_DEM_button = ttk.Button(Frame_for_button, text = 'View DEM with Paraview', command = self.view_DEM)
		view_DEM_button.grid(row=0,column=1, padx = 5, pady = 5)
		view_map_button = ttk.Button(center_Frame, text = 'View map', command = self.view_map)
EXT noe bernabeu's avatar
EXT noe bernabeu committed
		view_map_button.grid(row=8,column=2, padx = 5, pady = 5)
Pierre Saramito's avatar
Pierre Saramito committed
		next_from_1_to_2 = ttk.Button(Frame_for_button, text = 'Next', command = lambda:parent.n.nextpage())
		next_from_1_to_2.grid(row=1,column=0, columnspan=2, padx = 5, pady = 25)
EXT noe bernabeu's avatar
EXT noe bernabeu committed

	def tl_UTM_Map(self):
		tlUTMMap=Toplevel()
		PIUTMMap = PhotoImage(file=PKGDATADIR+'/load_buttom_100px.png')
		FUTMMap = Frame(tlUTMMap)
		FUTMMap.pack()
		Q_canvas = Canvas(FUTMMap, width=0, height=0, bg=light_grey,bd=0,highlightthickness=0)
		Q_canvas.pack()
		Q_canvas.config(width=1000, height=1000)#config(width=PIUTMMap.width(), height=PIUTMMap.height())
		Q_canvas.create_image(500,500,image=PIUTMMap)


	def open_DEM_file(self):
		filename=filedialog.askopenfilename(title="Open DEM file file", filetypes=[('xyz files','.xyz')], parent=self.parent)
		if not filename: # askopenfilename return `false` if dialog closed with "cancel".
			return
		self.DEM_filename = filename
		self.DEM_Var.set(filename.split("/")[-1])
		self.update_DEM_limit()
		self.update_vent_position()
		self.update_scale_cardinaux()

Pierre Saramito's avatar
Pierre Saramito committed
	def reset_the_view(self, event):
		self.scrollable_canvas.canvas.xview_moveto(0)
		self.scrollable_canvas.canvas.yview_moveto(0)
EXT noe bernabeu's avatar
EXT noe bernabeu committed
	def update_DEM_limit(self):  # update values of xmin,xmax,ymin,ymax
		self.xmin=float(os.popen("head -n 1 "+self.DEM_filename+" | awk \'{print $1}\'").read().rstrip())
		self.xmax=float(os.popen("tail -n 1 "+self.DEM_filename+" | awk \'{print $1}\'").read().rstrip())
		self.ymin=float(os.popen("tail -n 1 "+self.DEM_filename+" | awk \'{print $2}\'").read().rstrip())
		self.ymax=float(os.popen("head -n 1 "+self.DEM_filename+" | awk \'{print $2}\'").read().rstrip())
Pierre Saramito's avatar
Pierre Saramito committed
	def update_scale(self,variable,min_value,max_value):
		if (variable.min_scale_value.get()!=min_value) or (variable.max_scale_value.get()!=max_value):
			variable.min_scale_value.set(min_value)
			variable.max_scale_value.set(max_value)
			variable.my_interval = (max_value - min_value)/1.0
			variable.Myscale.config(from_=min_value, to=max_value,tickinterval=variable.my_interval)
			variable.Myvar.set(str(0.5*(max_value+min_value)))
	def update_vent_position(self):
		xmin=self.xmin
		xmax=self.xmax
		ymin=self.ymin
		ymax=self.ymax
		self.update_scale(self.main_vent_xe_variable,xmin,xmax)
		self.update_scale(self.main_vent_ye_variable,ymin,ymax)
	def update_scale_cardinaux(self):
		xe=float(self.main_vent_xe_variable.Myvar.get())
		ye=float(self.main_vent_ye_variable.Myvar.get())
		xmin=self.xmin
		xmax=self.xmax
		ymin=self.ymin
		ymax=self.ymax
		self.update_scale(self.south_variable,0,ye-ymin)
		self.update_scale(self.est_variable,0,xmax-xe)
		self.update_scale(self.north_variable,0,ymax-ye)
		self.update_scale(self.west_variable,0,xe-xmin)
	def updateLabel(self, event=None): # event when choose DEM
		print("change of DEM")
EXT noe bernabeu's avatar
EXT noe bernabeu committed
		#line = self.select_map.curselection()[0]
		#self.selected_item.set(line)
Noe Bernabeu's avatar
Noe Bernabeu committed
		#self.update_DEM_limit()
Pierre Saramito's avatar
Pierre Saramito committed
		self.update_vent_position()
		self.update_scale_cardinaux()
	def inside_callback_trace(self,variable):
		if (variable.Myvar.get()!=""):
			try:
				variable.Myscalevar.set(float(variable.Myvar.get()))
				self.update_xe_vents_p3(self.main_vent_xe_variable.Myscalevar.get())
				self.update_ye_vents_p3(self.main_vent_ye_variable.Myscalevar.get())
			except:
				variable.Myvar.set(str(variable.Myscalevar.get()))
	def callback_trace_xe(self,*args):
		if (self.main_vent_xe_variable.Myvar.get()!=""):
			try:
				self.main_vent_xe_variable.Myscalevar.set(float(self.main_vent_xe_variable.Myvar.get()))
				self.modif_from_xe(self.main_vent_xe_variable.Myscalevar.get())
			except:
				self.main_vent_xe_variable.Myvar.set(str(self.main_vent_xe_variable.Myscalevar.get()))
	def callback_trace_ye(self,*args):
		if (self.main_vent_ye_variable.Myvar.get()!=""):
			try:
				self.main_vent_ye_variable.Myscalevar.set(float(self.main_vent_ye_variable.Myvar.get()))
				self.modif_from_ye(self.main_vent_ye_variable.Myscalevar.get())
			except:
				self.main_vent_ye_variable.Myvar.set(str(self.main_vent_ye_variable.Myscalevar.get()))
	def callback_trace_south(self,*args):
		self.inside_callback_trace(self.south_variable)
	def callback_trace_est(self,*args):
		self.inside_callback_trace(self.est_variable)
	def callback_trace_north(self,*args):
		self.inside_callback_trace(self.north_variable)
	def callback_trace_west(self,*args):
		self.inside_callback_trace(self.west_variable)

	def controle_value(self,event=None,variable=None):
		if (event!='mouv_scale') and (float(variable.Myvar.get())==variable.Myscalevar.get()):
			return False
		else:
			variable.Myvar.set(str(variable.Myscalevar.get()))
			return True
	def callback_scale_xe(self,*args):
		self.controle_value_xe('mouv_scale')
	def callback_scale_ye(self,*args):
		self.controle_value_ye('mouv_scale')
	def callback_scale_south(self,*args):
		self.controle_value('mouv_scale',self.south_variable)
	def callback_scale_est(self,*args):
		self.controle_value('mouv_scale',self.est_variable)
	def callback_scale_north(self,*args):
		self.controle_value('mouv_scale',self.north_variable)
	def callback_scale_west(self,*args):
		self.controle_value('mouv_scale',self.west_variable)
	def update_xe_vents_p3(self,xe):
		est = float(self.est_variable.Myvar.get())
		west = float(self.west_variable.Myvar.get())
		xmin_value = xe-west
		xmax_value = xe+est
		for vent in self.parent.p3.hot_spot_Frame.vent_frame_list:
			self.update_scale(vent.xe_variable,xmin_value,xmax_value)
		self.parent.p3.hot_spot_Frame.vent_frame_list[0].xe_variable.Myvar.set(self.main_vent_xe_variable.Myvar.get())
	def modif_from_xe(self,xe):
		xmin=self.xmin
		xmax=self.xmax
		self.update_scale(self.west_variable,0,xe-xmin)
		self.update_scale(self.est_variable,0,xmax-xe)
		self.update_xe_vents_p3(xe)
	def update_ye_vents_p3(self,ye):
		south = float(self.south_variable.Myvar.get())
		north = float(self.north_variable.Myvar.get())
		ymin_value = ye-south
		ymax_value = ye+north
		for vent in self.parent.p3.hot_spot_Frame.vent_frame_list:
			self.update_scale(vent.ye_variable,ymin_value,ymax_value)
		self.parent.p3.hot_spot_Frame.vent_frame_list[0].ye_variable.Myvar.set(self.main_vent_ye_variable.Myvar.get())
	def modif_from_ye(self,ye):
		ymin=float(self.ymin)
		ymax=float(self.ymax)
		self.update_scale(self.south_variable,0,ye-ymin)
		self.update_scale(self.north_variable,0,ymax-ye)
		self.update_ye_vents_p3(ye)
	def controle_value_xe(self,event=None):
		if self.controle_value(event,self.main_vent_xe_variable):
			self.modif_from_xe(float(self.main_vent_xe_variable.Myvar.get()))
	def controle_value_ye(self,event=None):
		if self.controle_value(event,self.main_vent_ye_variable):
			self.modif_from_ye(float(self.main_vent_ye_variable.Myvar.get()))

	def write_domain_input(self):
		xe = float(self.main_vent_xe_variable.Myvar.get())
		ye = float(self.main_vent_ye_variable.Myvar.get())
		south = float(self.south_variable.Myvar.get())
		est = float(self.est_variable.Myvar.get())
		north = float(self.north_variable.Myvar.get())
		west = float(self.west_variable.Myvar.get())
		reso = float(self.reso_variable.Myvar.get())
		xmin = xe-west
		xmax = xe+est
		ymin = ye-south
		ymax = ye+north
		os.makedirs('tmp', exist_ok=True)
		my_file = open("tmp/domain_input.gdat", "w") # erase file
		my_file.write(str(xe)+" ")
		my_file.write(str(ye)+" ")
		my_file.write(str(south)+ " ")
		my_file.write(str(est)+ " ") 
		my_file.write(str(north)+ " ")
		my_file.write(str(west)+ " ")
		my_file.write(str(reso)+ " ")
		my_file.write(str(xmin)+ " ")
		my_file.write(str(xmax)+ " ")
		my_file.write(str(ymin)+ " ")
		my_file.write(str(ymax))
		my_file.close()
	def generate_mesh_command(self, parent):
		print("Generated of mesh (.geo) and DEM (.field)")
		self.message_Label.pack_forget()
		self.message_Label.config(text="It may take a few minutes ...")
		self.message_Label.pack()
		parent.configure(cursor='watch')
		parent.update_idletasks()
		parent.update()
		self.write_domain_input()
EXT noe bernabeu's avatar
EXT noe bernabeu committed
		os.system("sh "+PKGDATADIR+"/xyz2geofield.sh \""+self.DEM_filename+"\" \""+PKGLIBDIR+"\"")
		os.system(PKGLIBDIR+"/smooth_DEM grille.geo P1 5 DEM.field  > fh_smooth.field")
		"""if self.selected_item.get()==0:
Pierre Saramito's avatar
Pierre Saramito committed
			os.system("sh "+self.dir_path+"/simulation_domain_fournaise_5m.sh \""+self.dir_path+"\"")
			os.system(self.dir_path+"/smooth_DEM grille.geo P1 5 DEM_fournaise_5m.field  > fh_smooth.field")
		elif self.selected_item.get()==1:
			os.system("sh "+self.dir_path+"/simulation_domain_kilauea_2m.sh")
			os.system(self.dir_path+"/smooth_DEM grille.geo P1 5 DEM_hawaii_2m.field  > fh_smooth.field")
		elif self.selected_item.get()==2:
			os.system("sh "+self.dir_path+"/simulation_domain_etna2001_10m.sh")
EXT noe bernabeu's avatar
EXT noe bernabeu committed
			os.system(self.dir_path+"/smooth_DEM grille.geo P1 1 DEM_etna_10m.field  > fh_smooth.field")"""
Pierre Saramito's avatar
Pierre Saramito committed
		os.system("field fh_smooth.field -paraview -noclean -noexecute")
		os.system("rm fh_smooth.py")
		self.message_Label.config(text="mesh and DEM created")
		parent.configure(cursor='')
	def view_DEM(self):
		print("open DEM with paraview")
		os.system("paraview fh_smooth.vtk")
	def view_map(self):
EXT noe bernabeu's avatar
EXT noe bernabeu committed
		osm = pymap.mymap(self.utm_zone.Myvar.get(), self.xmin,self.xmax,self.ymin,self.ymax,self.south_variable,self.est_variable,\
			self.north_variable,self.west_variable,self.parent.p3.hot_spot_Frame.vent_frame_list, self.parent.p5.shape_filename, self.parent.p4.forest_characteristics_Frame)

	def add_sidemenu(self):
		self.sidemanu = SideMenu()

class SideMenu(object):
	def __init__(self):
		self.launch_sideMenu()

	def launch_sideMenu(self):
		sideWindow = Toplevel()
		sideWindow.title("UTM Grid Map")
		w = int(0.95*sideWindow.winfo_screenwidth())
		h = int(0.5*w) #int(0.8*sideWindow.winfo_screenheight())
		sideWindow.overrideredirect(0)
		sideWindow.resizable(False, False)
		#sideWindow.geometry("%dx%d+0+0" % (w, h))
EXT noe bernabeu's avatar
EXT noe bernabeu committed
		image = PIL.Image.open(PKGDATADIR+"/utm-zones.png")
EXT noe bernabeu's avatar
EXT noe bernabeu committed
		image_size = image.size
		image = image.resize((w,int(0.5*w)),PIL.Image.ANTIALIAS)
		photo = PIL.ImageTk.PhotoImage(image) 
		nframe = Frame(sideWindow)
		nframe.pack()
		cadredessin = Canvas(nframe, bg="dark grey",height=h,width=w) 
		cadredessin.create_image(w/2,h/2, image=photo)
		cadredessin.image=photo
		cadredessin.pack() 
		"""self.scrollable_canvas  = VerticalScrolledFrame(self._sideWindow)
		self.scrollable_canvas.pack(fill = 'both', expand = 1)
		main_window = self.scrollable_canvas.interior
		self.imageLabel2 = Label(main_window, image=photo)
		self.imageLabel2.pack()"""