Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add download workflow for server generated assets #23

Open
zachsa opened this issue Nov 3, 2022 · 1 comment
Open

Add download workflow for server generated assets #23

zachsa opened this issue Nov 3, 2022 · 1 comment

Comments

@zachsa
Copy link
Collaborator

zachsa commented Nov 3, 2022

It would be nice to be able to download python (and other language) generated assets using the CROCO output. For example giffs. To do this the website needs to implement some UI controls for requesting these assets (and generating them), as well as a mechanism for running scripts that may take too long for the duration of a single request (email notifications, or simple file management for logged in users, etc)

@zachsa
Copy link
Collaborator Author

zachsa commented Nov 3, 2022

Here is the Python script (from @mattcarr03) to create the example output:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Feb 25 18:07:52 2022

@author: matthew
"""
#! /usr/bin/env python
#
# a script to animate croco surface currents with parcels particles
#

from matplotlib import pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation
from netCDF4 import Dataset
import cartopy
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from datetime import timedelta, date, datetime
import sys
#sys.path.insert(1, '/home/osboxes/2001_DEA/models/parcels/croco_test')
#import croco_tools_visualisation as croco
import xarray as xr
from shapely.geometry import Point, Polygon
import netCDF4 as nc

# %%

def v2rho_3d(var_v):
     [T,M,Lp]=var_v.shape
     var_rho=np.zeros((T,M+1,Lp))
     var_rho[:,1:M-1,:]=0.5*np.squeeze([var_v[:,0:M-2,:]+var_v[:,1:M-1,:]])
     var_rho[:,0,:]=var_rho[:,1,:]
     var_rho[:,M,:]=var_rho[:,M-1,:]
     return var_rho


def u2rho_3d(var_u):
     [T,Mp,L]=var_u.shape
     var_rho=np.zeros((T,Mp,L+1))
     var_rho[:,:,1:L-1]=0.5*np.squeeze([var_u[:,:,0:L-2]+var_u[:,:,1:L-1]])
     var_rho[:,:,0]=var_rho[:,:,1]
     var_rho[:,:,L]=var_rho[:,:,L-1]
     return var_rho
 
def remove_child(lon_parent,lat_parent,data_parent,lon_child,lat_child):
    # assign missing values for parent data inside child domain
    # only works for regular grids
    
    # get the lon lat coordinates along the boundary of the model (actually 1 grid cell in to ensure some overlap between parent and child grids)
    lon_bry=lon_child[:,1].tolist()+lon_child[-2,:].tolist()+lon_child[-2:1:-1,-2].tolist()+lon_child[1,-2:1:-1].tolist()
    lat_bry=lat_child[:,1].tolist()+lat_child[-2,:].tolist()+lat_child[-2:1:-1,-2].tolist()+lat_child[1,-2:1:-1].tolist()
    #lon_bry=lon_child[:,0].tolist()+lon_child[-1,:].tolist()+lon_child[-1:0:-1,-1].tolist()+lon_child[0,-1:0:-1].tolist()
    #lat_bry=lat_child[:,0].tolist()+lat_child[-1,:].tolist()+lat_child[-1:0:-1,-2].tolist()+lat_child[0,-1:0:-1].tolist()

    bry = [(i,j) for i,j in zip(lon_bry,lat_bry)]
    poly = Polygon(bry)
    ny,nx=np.shape(lat_parent)
    for j in range(ny):
        for i in range(nx):
            p = Point(lon_parent[j,i], lat_parent[j,i])
            if p.within(poly):
                data_parent[j,i]=np.nan
                
    return data_parent    
 
# %% define file names

path = '/home/matthew/confs/False_bay_forecast/croco/forecast/'
#child_path = '/home/matthew/confs/False_bay_forecast/croco/scratch/'
child_path = '/home/matthew/Downloads/'

# define file names
grdfile='grd.nc'
#avgchildfile='avg_20220225.nc.1'
avgchildfile = 'false-bay-forecast-20221101.nc'

#Loading reference dataset to find surface level index
ds_child = xr.open_dataset(child_path+avgchildfile) 

# %% Loading variables from dataset 

#Child 
lon_child = ds_child.lon_rho.values 
lat_child = ds_child.lat_rho.values 

U_child = ds_child.u[:,19,:,:].values  
V_child = ds_child.v[:,19,:,:].values 

U_child = u2rho_3d(U_child)
V_child = v2rho_3d(V_child)

# %% Loading temperature 

SST_child = ds_child.temperature[:,39,:,:].values 

SST_child[np.where(SST_child==0)]=np.nan

# %% Loading time

# get the time
nc_id_avg = Dataset(child_path+avgchildfile, 'r')
time = nc_id_avg.variables['time'][:]
# time origin (needs to be hard coded here as it is not written to the croco output file)
date_ref=datetime(2000,1,1,0,0,0)
#generate a list of dates
dates=[]
for t in time:
    date_now=date_ref + timedelta(seconds=np.float64(t))
    dates.append(date_now)

# %% UV animation figure 

skip = 2

# # setup figure object
fig = plt.figure(figsize=(12,8))
#ax = fig.add_axes([0, 0, 1, 1], projection=ccrs.PlateCarree())
ax = plt.axes(projection=ccrs.PlateCarree())
#ax.set_extent([25.55,26.55,-34.1,-33.65])
ax.add_feature(cfeature.LAND, zorder=0, edgecolor='black')
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
                  linewidth=1, color='gray', alpha=0.5, linestyle=':')
gl.left_labels = False
gl.top_labels = False
# add the vectors
U = U_child[0,:,:]
V = V_child[0,:,:]
qf=ax.quiver(lon_child[::skip,::skip], lat_child[::skip,::skip], U_child[0,::skip,::skip], V_child[0,::skip,::skip], scale=8, transform=ccrs.PlateCarree())
fig.tight_layout()
qk=ax.quiverkey(qf,0.7, 0.7, -0.5, '0.5 m s$^{-1}$', coordinates = 'figure', transform=ccrs.PlateCarree())
# show the time stamp
time_lon=18.6; time_lat=-34.00
tx=ax.text(time_lon, time_lat, str(dates[0]),
         horizontalalignment='left',
         transform=ccrs.PlateCarree())

# animation function
def animate(i):
    #cont.remove()
    Uchd = U_child[i,::skip,::skip]
    Vchd = V_child[i,::skip,::skip]
    qf.set_UVC(Uchd, Vchd) 
    tx.set_text(str(dates[i]))


anim = FuncAnimation(
    fig, animate, interval=200, frames=range(0,240,1)) #len(time)-48

anim.save('Forecast_UV_child_test_processed.gif', writer='imagemagick')


# %% Temperature animations 
levels = np.linspace(10,22,20,endpoint=True)

skip = 2

# # setup figure object
fig = plt.figure(figsize=(12,8))
#ax = fig.add_axes([0, 0, 1, 1], projection=ccrs.PlateCarree())
ax = plt.axes(projection=ccrs.PlateCarree())
#plt.contourf(lon_child, lat_child, SST_child[0,:,:])
ax.set_extent([np.nanmin(lon_child),np.nanmax(lon_child),np.nanmin(lat_child),np.max(lat_child)])
ax.add_feature(cfeature.LAND, zorder=0, edgecolor='black')
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
                  linewidth=1, color='gray', alpha=0.5, linestyle=':')
gl.left_labels = False
gl.top_labels = False
# add the vectors
SST = SST_child[0,:,:]
cont = ax.contourf(lon_child, lat_child, SST,cmap='RdYlBu_r'); 
cont1 = ax.contour(lon_child, lat_child, SST,levels,colors='k'); 
ax.contourf(lon_child, lat_child, SST_child[0,:,:],cmap='RdYlBu_r')
cont3 = ax.contour(lon_child, lat_child, SST_child[0,:,:],levels,colors='k')
fig.tight_layout()
# show the time stamp
time_lon=18.6; time_lat=-34.00
tx=ax.text(time_lon, time_lat, str(dates[0]),
         horizontalalignment='left',
         transform=ccrs.PlateCarree())

# animation function
def animate(i):
    global cont
    for c in cont.collections:
        c.remove()  # removes only the contours, leaves the rest intact
        #cont.remove()
    SST = SST_child[i,:,:]
    cont = ax.contourf(lon_child, lat_child, SST,levels,cmap='RdYlBu_r');
    global cont1
    for c in cont1.collections:
        c.remove()  # removes only the contours, leaves the rest intact
        #cont.remove()
    cont1 = ax.contour(lon_child, lat_child, SST,levels,colors='k')
    
    global cont3
    for c in cont3.collections:
        c.remove()  # removes only the contours, leaves the rest intact
        #cont.remove()
    cont3 = ax.contour(lon_child, lat_child, SST_child[i,:,:],levels,colors='k')
    ax.contourf(lon_child, lat_child, SST_child[i,:,:],levels,cmap='RdYlBu_r')
    tx.set_text(str(dates[i]))

    return cont


anim = FuncAnimation(
    fig, animate, interval=200, frames=range(0,240,1)) #len(time)-48

anim.save('Forecast_test_processed.gif', writer='imagemagick')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant