Commit e386da07 authored by Anthony's avatar Anthony
Browse files

New version of Rviewer

parent cf46de6c
from tkinter import *
from tkinter import font
from tkinter import filedialog
import sys
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import cartopy.io.shapereader as shpreader
import cartopy.io.img_tiles as cimgt
import numpy as np
import matplotlib as mpl
from matplotlib import cm
# Add the location where the programs are located if necessary
#sys.path.append("/home/anthony/Documents/LOCAL/RoutingPP/ROUTING_Analysis_tools/Programs")
from class_Routing import routing
from Voronoi_grid import get_voronoi_polygons
import numpy.ma as ma
################################################
#
# Class Interface
# Main class of the program
class Interface(Frame):
def __init__(self, parent, **kwargs):
Frame.__init__(self, parent, width=768, height=576)
self.container = Frame(self)
self.container.pack(side="top", fill="both", expand = True)
self.container.grid_rowconfigure(0, weight=1)
self.container.grid_columnconfigure(0, weight=1)
self.parent = parent
self.loaded = False
self.grid = False
self.main = False
self.basin_id = 0
self.nbpt = 0
self.HTUview = "global" # or local
self.HTUneighbours = False
self.HTUarrow = False
self.initUI()
def initUI(self):
self.parent.title("RoutingPP Viewer")
self.pack(fill=BOTH, expand=1)
menubar = Menu(self.parent)
self.parent.config(menu=menubar)
fileMenu = Menu(menubar)
fileMenu.add_command(label="Open", command=self.onOpen)
fileMenu.add_command(label="Exit", command=self.parent.quit)
menubar.add_cascade(label="File", menu=fileMenu)
self.frames = {}
frame = BASINS(self.container, self)
frame.grid(row=0, column=0, sticky="nsew")
self.frames[BASINS] = frame
self.show_frame(BASINS)
def show_frame(self, cont):
frame = self.frames[cont]
frame.grid(row=0,column=0,sticky="nsew")
frame.tkraise()
def update_BASINS(self):
frame = BASINS(self.container, self, self.title)
frame.grid(row=0, column=0, sticky="nsew")
self.frames[BASINS] = frame
self.show_frame(BASINS)
def update_HTUS(self):
frame = HTUS(self.container, self, self.title)
frame.grid(row=0, column=0, sticky="nsew")
self.frames[HTUS] = frame
self.show_frame(HTUS)
def get_nbpt(self, nbpt):
self.nbpt = nbpt
self.update_HTUS()
def grid_button(self):
self.grid = not self.grid
self.update_BASINS()
def basin_plot(self):
self.update_BASINS()
def main_river(self):
self.main = not self.main
self.update_BASINS()
def local_global(self):
if self.HTUview == "global" :
self.HTUview = "local"
elif self.HTUview == "local" :
self.HTUview = "global"
self.update_HTUS()
def arrows(self):
self.HTUarrow = not self.HTUarrow
self.update_HTUS()
def neighbours(self):
self.HTUneighbours = not self.HTUneighbours
self.update_HTUS()
def onOpen(self):
ftypes = [('NetCDF Routing', '*.nc'), ('All files', '*')]
dlg = filedialog.Open(self, filetypes = ftypes)
fl = dlg.show()
# to test the program
#fl = "/home/anthony/Documents/LOCAL/RoutingPP/ROUTING_Analysis_tools/Originals/LC_Spain_test_graph_corr.nc"
#fl = "/home/anthony/Documents/LOCAL/RoutingPP/ROUTING_Analysis_tools/Originals/EuroSW_Mallorca.nc"
self.frames = {}
if fl != '':
self.rr = routing(fl)
self.loaded = True
self.title = fl.split("/")[-1]
frame = BASINS(self.container, self, self.title)
frame.grid(row=0, column=0, sticky="nsew")
self.frames[BASINS] = frame
self.show_frame(BASINS)
################################################
#
# Class BASIN
# Class of the page showing the basins
class BASINS(Frame):
def __init__(self, parent, controller, title = "River routing, select a file"):
Frame.__init__(self, parent)
label = Label(self, text=title)
label.pack(pady=10,padx=10)
self.controller = controller
if controller.loaded:
b1 = Label(self, text="Actual mode : Basin view")
b1.pack(pady=10,padx=10)
#b1.pack(side = TOP)
b2 = Button(self, text="Switch to HTUs view", command = controller.update_HTUS)
b2.pack(side = TOP)
self.main_fig(controller.rr.ext)
button1 = Button(self, text="Grid", command = controller.grid_button)
button1.pack(side = TOP)
readOnlyText = Text(self)
label1 = Label(self, text =" Select basin : ")
label1.pack(side = TOP)
OPTIONS = ["None"] + [b[0] for b in controller.rr.basin_list[0:30]]
self.variable = StringVar(parent)
if controller.basin_id == 0:
self.variable.set("None")
else:
self.variable.set(controller.basin_id)
w = OptionMenu(self, self.variable, *OPTIONS)
w.pack(side = TOP)
button2 = Button(self, text="Show basin", command = self.basin_id)
button2.pack(side = TOP)
if controller.basin_id != 0:
button3 = Button(self, text="Main river", command = controller.main_river)
button3.pack(side = TOP)
else:
self.main_fig()
def basin_id(self):
if self.variable.get() == "None":
self.controller.basin_id = 0
else:
self.controller.basin_id = self.variable.get()
self.controller.basin_plot()
def main_fig(self, extent = None):
df = draw_Figure(self, extent, self.controller.grid, self.controller.basin_id, self.controller.main)
canvas = FigureCanvasTkAgg(df.fig, master=self)
canvas.draw()
canvas.get_tk_widget().pack(side=LEFT, fill=BOTH, expand=True)
canvas._tkcanvas.pack(side=LEFT, fill=BOTH, expand=True)
################################################
#
# Class HTUs
# Class of the page showing the basins
class HTUS(Frame):
def __init__(self, parent, controller, title = ""):
Frame.__init__(self, parent)
label = Label(self, text=title)
label.pack(pady=10,padx=10)
self.controller = controller
b1 = Label(self, text="Actual mode : HTUs View", command = None)
b1.pack(pady=10,padx=10)
b2 = Button(self, text="Switch to Basin view", command = controller.update_BASINS)
b2.pack(side = TOP)
if controller.HTUview == "global": # or local
if controller.nbpt == 0:
self.main_fig(controller.rr.ext)
if controller.nbpt != 0:
self.main_fig(controller.rr.ext, True)
elif controller.HTUview == "local":
self.voronoi()
# Pour entrer le nbpt !
b1 = Label(self, text="Enter the grid point number")
b1.pack(pady=10,padx=10)
b1 = Label(self, text="(min: 1; max {0})".format(controller.rr.nbpt))
b1.pack(pady=10,padx=10)
self.e = Entry(self)
self.e.pack(pady=10,padx=10)
button1 = Button(self, text="Show selected grid point", command = self.get_nbpt)
button1.pack(side = TOP)
if controller.HTUview == "local":
text_button4 = "Switch to global map"
if controller.HTUneighbours:
text_button2 = "Hide neighbours"
else:
text_button2 = "Show neighbours"
button2 = Button(self, text=text_button2, command = self.neighbours)
button2.pack(side = TOP)
if controller.HTUarrow:
text_button3 = "Hide arrows"
else:
text_button3 = "Show arrows"
button3 = Button(self, text=text_button3, command = self.arrows)
button3.pack(side = TOP)
else:
text_button4 = "Switch to local map"
button4 = Button(self, text=text_button4, command = self.local_global_map)
button4.pack(side = TOP)
def get_nbpt(self):
nbpt = self.e.get()
if nbpt.isnumeric():
nbpt = int(nbpt)
if (nbpt>0) and (nbpt<=self.controller.rr.nbpt):
self.controller.get_nbpt(nbpt)
else:
print("error")
else:
print("error")
# error
return
def local_global_map(self):
self.controller.local_global()
def neighbours(self):
self.controller.neighbours()
def arrows(self):
self.controller.arrows()
def main_fig(self, extent = None, grid = False):
df = draw_Figure(self, extent, grid, pt = self.controller.nbpt)
canvas = FigureCanvasTkAgg(df.fig, master=self)
canvas.draw()
canvas.get_tk_widget().pack(side=LEFT, fill=BOTH, expand=True)
canvas._tkcanvas.pack(side=LEFT, fill=BOTH, expand=True)
def voronoi(self):
df = draw_Voronoi(self, nb = self.controller.nbpt, neighbour = self.controller.HTUneighbours, arrow = self.controller.HTUarrow)
canvas = FigureCanvasTkAgg(df.fig, master=self)
canvas.draw()
canvas.get_tk_widget().pack(side=LEFT, fill=BOTH, expand=True)
canvas._tkcanvas.pack(side=LEFT, fill=BOTH, expand=True)
################################################
#
# Class draw_figure
# Class of the map figures
class draw_Figure:
"""
Global map and local map of the basins
"""
def __init__(self, page, extent, grid, basin_id = 0 , main=False, pt = 0):
self.page = page
self.extent = extent
self.grid = grid
self.basin_id = basin_id
self.main = main
self.pt = pt
self.init_figure()
if self.extent is not None:
self.local_map()
self.draw_grid()
self.draw_basin()
self.main_river()
self.draw_nbpt_loc()
else:
self.global_map()
#####
def init_figure(self):
self.fig = plt.figure(figsize=(8,4), dpi=100)
self.ax = self.fig.add_axes([0.01, 0.01, 0.98, 0.98], projection=ccrs.PlateCarree())
def draw_grid(self):
if self.grid:
for l in self.page.controller.rr.GRID:
x, y = l.exterior.xy
plt.plot(x,y, color = "k")
def draw_basin(self):
if self.basin_id != 0 :
area = self.page.controller.rr.basin_area(int(self.basin_id))
area = [area[j,i]/self.page.controller.rr.var["area"][j,i]*100 for j,i in self.page.controller.rr.conv_land2ij]
cmap = cm.get_cmap('viridis', 12)
norm = mpl.colors.Normalize(vmin=0.,vmax=np.max(area))
for l, ar in zip(self.page.controller.rr.GRID, area):
if ar>0:
x, y = l.exterior.xy
plt.fill(x,y, color = cmap(norm(ar)))
plt.title("basin_id : {0}".format(int(self.basin_id)))
def draw_nbpt_loc(self):
if self.pt != 0:
l = self.page.controller.rr.GRID[self.pt-1]
x, y = l.exterior.xy
plt.fill(x,y, color = "r")
def global_map(self):
self.ax.set_global()
self.ax.stock_img()
self.ax.coastlines()
lw = 0.5
river_50m = cfeature.NaturalEarthFeature('physical', 'rivers_lake_centerlines', '10m', facecolor='none', edgecolor = "#011f4b", lw = lw)
self.ax.add_feature(river_50m)
def local_map(self):
self.ax.set_extent(self.extent)
if (self.basin_id != 0) or (self.pt != 0):
fc_coast = "none"
fc_ocean = "none"
else:
fc_coast ='#77ab59'
fc_ocean ='#99ccff'
coast = cfeature.NaturalEarthFeature('physical', 'coastline', '50m', facecolor=fc_coast, edgecolor = "k", lw = 1)
self.ax.add_feature(coast)
ocean = cfeature.NaturalEarthFeature('physical', 'ocean', '50m', facecolor=fc_ocean, edgecolor = "none")
self.ax.add_feature(ocean)
lw = 1
river_50m = cfeature.NaturalEarthFeature('physical', 'rivers_lake_centerlines', '10m', facecolor='none', edgecolor = "#011f4b", lw = lw)
self.ax.add_feature(river_50m)
def main_river(self):
if self.main:
pts_out = self.page.controller.rr.main_fetch(int(self.basin_id), p = 90)
outflow = self.page.controller.rr.outflow(int(self.basin_id))
x,y = self.page.controller.rr.inflow_outflow_htus(pts_out)
i=0
for xx, yy in zip(x,y):
if len(xx)>1:
plt.plot(xx,yy,ls = "-", color = "k")
for xx, yy in zip(x,y):
plt.plot(xx[0], yy[0], "bo", ms = 5)
x,y = self.page.controller.rr.inflow_outflow_htus([outflow[i][2] for i in range(len(outflow))])
for xx, yy in zip(x,y):
plt.plot(xx[0], yy[0], "ro", ms = 10)
plt.title("Basin {0} main htus".format(self.basin_id))
################################################
#
# Class draw_figure
# Class of the Voronoi diagram figures
class draw_Voronoi:
"""
Global map and local map of the basins
"""
def __init__(self, page, nb, neighbour, arrow):
if neighbour:
j,i = page.controller.rr.conv_land2ij[nb-1]
array = ma.array(page.controller.rr.var["nbpt_glo"][j-1:j+2, i-1:i+2]).astype(np.int32)
gridpts = list(ma.unique(array[(array.mask == False)]))
LNB = [pt for pt in gridpts if pt>0]
else:
LNB = [nb]
self.page = page
self.start_map()
self.get_limits(LNB)
for pt in LNB:
main = False
if pt == nb: main = True
self.plot_voronoi(pt, arrow, main)
x, y = page.controller.rr.GRID[nb-1].exterior.xy
plt.plot(x,y, color = "r")
cbaxes = self.fig.add_axes([0.82, 0.1, 0.03, 0.75])
cb1 = mpl.colorbar.ColorbarBase(ax = cbaxes, cmap=self.viridis,
norm=self.norm,
orientation='vertical', alpha = 0.6)
cb1.set_label('\% of total area of the grid box')
self.fig.subplots_adjust(left = 0.05, right = 0.8)
def start_map(self):
self.viridis = cm.get_cmap('Reds', 12)
self.norm = mpl.colors.Normalize(vmin=0.,vmax=100)
self.fig = plt.figure(figsize= (7,7))
self.ax = plt.subplot(1, 1, 1, projection=ccrs.PlateCarree())
geo_reg_shp = shpreader.natural_earth(resolution='10m', category='physical',\
name='coastline')
geo_reg = shpreader.Reader(geo_reg_shp)
self.ax.add_geometries(geo_reg.geometries(), ccrs.PlateCarree(), \
edgecolor="k", facecolor='none')
def get_limits(self, LNB):
ext = self.page.controller.rr.resh/2.
lat = []
lon = []
for pt in LNB:
j,i = self.page.controller.rr.conv_land2ij[pt-1]
lat = lat + list(self.page.controller.rr.var["lat_bnd"][:,j,i])
lon = lon + list(self.page.controller.rr.var["lon_bnd"][:,j,i])
limits = [np.min(lon)-ext, np.max(lon)+ext, np.min(lat)-ext, np.max(lat)+ext]
self.ax.set_extent(limits)
def plot_voronoi(self, nb, arrow = True, main = False):
rr = self.page.controller.rr
j,i = rr.conv_land2ij[nb-1]
nbas = int(rr.var["routenbintobas"][j,i])
outgrid = [g for g in rr.var["routetogrid"][:nbas,j,i]]
outbas = [b for b in rr.var["routetobasin"][:nbas,j,i]]
area = np.array([b for b in rr.var["basin_area"][:nbas,j,i]])
area =area/rr.var["area"][j,i]*100
htus = [[lon, lat] for lon, lat in zip(rr.var["CG_lon"][:nbas,j,i], rr.var["CG_lat"][:nbas,j,i])]
htus = np.array(htus)
X = []
Y = []
for l, htu in enumerate(htus):
jj,ii = rr.conv_land2ij[int(rr.var["routetogrid"][l,j,i]-1)]
k = int(rr.var["routetobasin"][l,j,i]-1)
if (k<rr.nbasmax):
x = [htu[0], rr.var["CG_lon"][k,jj,ii]]
y = [htu[1], rr.var["CG_lat"][k,jj,ii]]
X.append(x)
Y.append(y)
if arrow:
for x, y in zip(X, Y):
plt.arrow(x[0], y[0], x[1]-x[0], y[1]-y[0], "k", length_includes_head = True, head_length = 0.01, head_width = 0.01)
A, B = htus[:,0], htus[:,1]
plt.scatter(A, B, marker='.')
polygons = get_voronoi_polygons(htus, rr.GRID[nb-1])
for i,p in enumerate(polygons):
if p != []:
x,y = p.exterior.xy
plt.fill(x,y, color = self.viridis(self.norm(area[i])), alpha = 0.6)
plt.plot(x,y,color = "k")
x, y = rr.GRID[nb-1].exterior.xy
plt.plot(x,y, color = "k")
i = 0
for lon, lat in htus:
plt.plot(lon, lat, "o",alpha = 0.7, color = "b")
if outbas[i]>rr.nbasmax:
plt.plot(lon, lat, "o",alpha = 0.7, ms = 5, color = "r")
i+=1
def main():
root = Tk()
interface = Interface(root)
root.mainloop()
if __name__ == '__main__':
main()
#!/bin/bash
#
# Set the right Python 3 Anaconda environment
#
source ~/anaconda3/bin/activate
conda activate Rviewer
#
# Run on YYY procs
#
#cd ${PBS_O_WORKDIR}
pwd
python ./lib/main.py
#!/bin/bash
#
#########################################
#
# Script to build and maintain en environment to run
# the python code in this directory. We verify that
# all needed packages are available.
# This is based on the anaconda python system : https://www.anaconda.com/distribution/
#
# Usage : source Environment
#
#########################################
#
# Functions
#
conda create -y -n Rviewer mpi4py numba astropy netcdf4 matplotlib shapely scipy cartopy
############################
Selection des points par lon / lat dans class routing
self.G = [i for i in range(r.nbpt) if (r.var_land["lat"][i]>lat_min)*(r.var_land["lat"][i]<lat_max)*(r.var_land["lon"][i]>lon_min)*(r.var_land["lon"][i]<lon_max)]
############################
Polygone, line vector dans la classe vectors non ?
############################
Dictionnaire afin de définir les différentes couleurs !! Avec valeur par défault
############################
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>