Docker-in-Docker (DinD) capabilities of public runners deactivated. More info

Commit b0c64cb9 authored by Clément Haëck's avatar Clément Haëck
Browse files

Merge local and ciclad repos

Two repos were manually kept in sync with manual copy-paste
(one private for work on my pc, and one for ciclad)
To avoid this overhead, i will only work on this repo,
with possibly multiple branches
parent d3984481
......@@ -8,7 +8,15 @@ __pycache__/
from os import path
import logging
import numpy as np
import xarray as xr
from xarray_regex import FileFinder, library
from lib import root_data, get_args
log = logging.getLogger(__name__)
def main():
args = get_args(['region', 'date', 'fix'],
"Merge pigments images in daily files.")
def merge_pigments(args):'finding pigments')
odir = path.join(root_data, args['region'], 'SOM', 'Pig',
'{:d}days'.format(1), *args['date_str'])
idir = path.join(odir, 'tmp')
pregex = r'%(prefix)_%(time:x)_image_%(image:custom=\d\d\d:)\.nc%(var:char)\.nc'
finder = FileFinder(idir, pregex, prefix='Pig_BMUS_A')
files = finder.get_files()'found %d pigment files', len(files))
images_all =['region'],
images_grp ='found %d images', len(images_all))
modis_dir = path.dirname(images_all[0].filename)'opening modis file to get template')
ds = xr.open_dataset(images_all[0].filename)
ds = ds.drop_vars(ds.data_vars)
ds.attrs = {}'regrouping pigments images by date')
files_date = {}
variables = set()
for f in files:
matches = finder.get_matches(f, relative=False)
date = library.get_date(matches)
image_idx = int(matches['image']['match']) - 1
var = matches['char']['match']
if date not in files_date:
files_date[date] = []
files_date[date].append((image_idx, var, f))
encoding = {v: {'zlib': True} for v in variables}
for var in variables:
ds[var] = (['lat', 'lon'],
np.full((, ds.lon.size), np.nan))'reporting data')
for date, k in files_date.items():
ofile = path.join(odir, 'Pig_{}.nc'.format(date.strftime('%Y%m%d')))'file %s', ofile)
for var in variables:
ds[var][:] = np.nan
for image_idx, var, f in k:
modis_file = path.join(modis_dir,
image = images_grp[modis_file][image_idx]
pig = xr.open_dataset(f)[var]
ds[var][dict(lon=image.slice_x, lat=image.slice_y)] = pig.values
ds.to_netcdf(ofile, encoding=encoding)
if __name__ == '__main__':
"""Add H-Index to files.
Normalize each component by min/max values.
from import get_data
from lib import compute_hi, get_args
args = get_args(['region', 'days', 'year', 'scale', 'number'])
region = str(args['region'])
days = int(args['days'])
year = int(args['year'])
scale = float(args['scale'])
number = int(args['number'])
db = get_data(region, days, year, scale, number)
extremas = {'S': [0.0000, 8.6694],
'V': [0.0000, 1.0369],
'B': [0.0340, 1.4108]}
## Compute
for time_slice in db.avail.iter_slices('time', 3):
compute_hi.compute_hi(db, extremas)
db.write_add_variable('HI', 'V', kwargs={'zlib': True})
#!/usr/bin/env bash
export PYTHONPATH="/home/chaeck/Fronts/:$PYTHONPATH"
. "$HOME/"
conda activate py38
python "$HOME/Fronts/Compute/" \
--kwargs region:"'GS'" days:8 year:2003 \
scale:10. number:1
......@@ -8,19 +8,16 @@
# The averaged files are put in
# "${wd}/${rootdir}/climato/${varlist}/${n_clim}_${date}.\nc"
module load nco/4.7.x
if [[ "$typ" == "PFT"* ]]; then
varlist=(dtom dinflg galgae \
picoeuk pico prchlcus \
prokrt prymnsio)
prefixes=(dtom_ dinflg_ galgae_ picoeuk_ pico_ prchlcus_ prokrt_ \
if [[ "$typ" == "PFT_concentration" ]]; then
......@@ -44,7 +41,7 @@ if [[ "$typ" == "CHL_L4" ]]; then
if [[ "$typ" == "SST" ]]; then
......@@ -74,10 +71,14 @@ for ivar in "${!varlist[@]}"; do
echo "$fileout"
echo "$mean_files"
mkdir -p "${wd}/${rootdir}/climato/${var_2}"
nces -O ${mean_files} ${fileout}
exit 1
# -- MONTHLY --
files=($(ls "${wd}/${rootdir}/climato/${var_2}/46_"*.nc))
"""Compute cloud coverage for SST and CHL-L3."""
from os import path
import numpy as np
import netCDF4 as nc
from lib import root_data, get_args
args = get_args(['level'])
level = int(args['level'])
db_sst =
db_chl =
box_lat = [20, 52]
box_lon = [-82, -45]
range_time = [[2007, 1, 1], [2007, 12, 31]]
def get_land_mask_sst(db):
db.load_selected(var='SST_mask', time=0)
mask = db.view(var=0, time=0) != 1
return mask
def get_land_mask_chl(db):
db.load_selected(var='CHL_flags', time=0)
mask = db.view(var=0, time=0) == 9
return mask
def compute_cloud_cover(db, var, get_land_mask, var_load=None):
if var_load is None:
var_load = var
db.select_by_value('avail', time=slice(*range_time),
lat=slice(*box_lat), lon=slice(*box_lon), by_day=True)
land_mask = get_land_mask(db)
total = np.sum(~land_mask)
time = db.selected.time
axis = (1, 2)
cloud = np.zeros(time.size)
for time_slice in db.selected.iter_slices('time', 3):
db.load_selected(var=var_load, time=time_slice)
data = db[var].mask
cloud[time_slice] = np.sum(data*~land_mask, axis=axis) / total
# Write to disk
filename = path.join(db.filegroups[0].root, '')
with nc.Dataset(filename, 'w') as f:
f.createDimension('time', time.size)
vnc = f.createVariable('time', 'f', ['time'])
vnc[:] = time[:]
vnc.setncattr('units', time.units)
vnc = f.createVariable('cloud', 'f', ['time'])
vnc[:] = cloud[:]
compute_cloud_cover(db_sst, 'SST', get_land_mask_sst, ['SST', 'SST_error'])
compute_cloud_cover(db_chl, 'CHL', get_land_mask_chl)
#!/usr/bin/env bash
export PYTHONPATH="/home/chaeck/Fronts/:$PYTHONPATH"
. "$HOME/"
conda activate py38
python "$HOME/Fronts/Compute/" \
--kwargs level:3
from os import path
import matplotlib.pyplot as plt
import tol_colors as tc
import numpy as np
import pandas as pd
import xarray as xr
from lib import root_data
region = 'GS'
year = 2007
days = 1
fixes = dict()
scale = 30.
number = 1
n_bins = 800
bounds = [0., 20.]
cset = tc.tol_cset('high-contrast')
hi_dir = path.join(root_data, region, 'HI',
'HI_{:2.1f}_{:d}'.format(scale, number), 'HI',
'{:d}days'.format(days), str(year))
def get_extremas(bins, hist):
mins = {}
maxs = {}
for var in hist.keys():
mins[var], maxs[var] = get_extremas_(bins, hist[var])
return mins, maxs
def get_extremas_(bins, hist):
mask = hist != 0
vmin = bins[mask.argmax(axis=0)]
imin = hist.shape[0] - np.flip(mask, axis=0).argmax(axis=0) - 1
vmax = bins[imin]
return vmin, vmax
def plot_hist(bins, hist, mins, maxs, ofile):
fig, axes = plt.subplots(2, 2, figsize=(5, 5))
fig.subplots_adjust(left=0.05, bottom=0.05, right=0.98, top=0.92)
for var, ax in zip(['S', 'V', 'B'], axes.flat):
ax.plot(bins[:-1], hist[var], ds='steps-post', color='k')
# ax.set_xlim(bins[0], maxs[var]*1.2)
ax.set_xlim(bins[0], 5)
fig.savefig(ofile, dpi=150)
def apply_coef(ds, coef):
ds['HI'] = (coef['S'] * np.fabs(ds.S)
+ coef['V'] * ds.V
+ coef['B'] * ds.B)
return ds
def get_hists(images_mth, variables, bins, coef=None, plot=False):
hist = {v: np.zeros(n_bins) for v in variables}
for i, (m, im_day) in enumerate(groups):
hist_mth = {v: np.zeros(n_bins) for v in variables}
ofile = path.join(hi_dir, 'HIST_VSB_{}.png'.format(m.strftime('%F')))
for day, images in im_day.items():
print(day, end=': ')
hi_file = path.join(hi_dir, 'HI_{}.nc'.format(day.strftime('%Y%m%d')))
hi = xr.open_dataset(hi_file)
for j, image in enumerate(images):
print(j, end=', ')
hii = image.extract(hi)
if 'HI' in variables and coef is not None:
hii = apply_coef(hii, coef)
# Reject image
for var in variables:
h, _ = np.histogram(np.fabs(hii[var]),
bins=n_bins, range=bounds)
hist_mth[var] += h
for var in variables:
hist[var] += hist_mth[var]
hist_mth[var] /= np.sum(hist[var]*np.diff(bins))
mins, maxs = get_extremas(bins, hist_mth)
if plot:
plot_hist(bins, hist_mth, mins, maxs, ofile)
mins_mth[i] = mins
maxs_mth[i] = maxs
mins, maxs = get_extremas(bins, hist)
if plot:
plot_hist(bins, hist, mins, maxs, path.join(hi_dir, 'HIST_TOTAL.png')), 'bins.npy'), bins)
for v in variables:, f'hist_{v}.npy'), hist[v])
return hist
images_all =, year=year,
days=days, fixes=fixes)
images_day =
images_mth = pd.Series(list(images_day.values()), index=list(images_day.keys()))
groups = images_mth.groupby(pd.Grouper(freq='1M'))
mins_mth = [{} for _ in range(len(groups))]
maxs_mth = [{} for _ in range(len(groups))]
bins = np.linspace(*bounds, n_bins+1)
## Method 1
def get_coef(bins, hist):
vmin, vmax = get_extremas_(bins, hist)
fx = hist
bx = bins
by = (vmax-vmin)*bins + vmin
fy = hist / np.sum(hist*np.diff(by))
plot_fit(bx, by, fx, fy)
a = get_linear_fit_hist(bx, by, fx, fy)
return a
def get_linear_fit_hist(bx, by, fx, fy):
return 0
def plot_fit(bx, by, fx, fy):
fig, ax = plt.subplots(figsize=(5, 5))
fig.subplots_adjust(left=0.05, bottom=0.05, right=0.98, top=0.98)
ax.scatter(by[:-1], bx[:-1], s=np.log(np.fabs(fx)))
hist = {}
for v in ['S', 'V', 'B']:
hist[v] = np.load(path.join(hi_dir, f'hist_{v}.npy'))
bins = np.load(path.join(hi_dir, 'bins.npy'))
get_coef(bins, hist['V'])
## Method 2
def get_coef(bins, hist):
std = get_std(bins[:-1], hist)
return 1./std
def get_std(bins, hist):
N = get_N(hist)
mean = get_mean(bins, hist, N)
return np.sqrt(np.sum(hist*(bins-mean)**2)/N)
def get_mean(bins, hist, N):
return np.sum(bins*hist)/N
def get_N(hist):
return np.sum(hist)
hist = {}
for v in ['S', 'V', 'B']:
hist[v] = np.load(path.join(hi_dir, f'hist_{v}.npy'))
bins = np.load(path.join(hi_dir, 'bins.npy'))
for v in ['S', 'V', 'B']:
print(v, get_coef(bins, hist[v]))
## Compute HI hist
coef = dict(S=2.384/2., V=5.874, B=8.599)
hist = get_hists(images_mth, ['HI'], bins, coef)
## Reload
hist = np.load(path.join(hi_dir, 'hist_HI.npy'))
"""Compute stats. """
from os import path
import xarray as xr
import numpy as np
import pandas as pd
from scipy import ndimage
from lib import root_data, get_args
from lib.dask_client import make_client
import lib.zones
def get_data():
mask_lo =, days, year, scale, number, chl=True)
mask_lo = mask_lo.assign_coords(time=mask_lo.time.dt.floor("D"))
chl =, days, year)
zone_lo = lib.zones.get_data(region, 'lo')
ds_lo = xr.merge([mask_lo, chl, zone_lo], join='inner')
mask_hi =, days, year, scale, number, chl=False)
sst =, days, year)
sst = sst.rename(mask='sst_mask')
zone_hi = lib.zones.get_data(region, 'hi')
ds_hi = xr.merge([mask_hi, sst, zone_hi], join='inner')
ds_hi = ds_hi.assign_coords(time=ds_hi.time.dt.floor("D"))
ds_lo = add_land('lo', ds_lo)
ds_hi = add_land('hi', ds_hi)
ds_lo, ds_hi = xr.align(ds_lo, ds_hi, join='inner',
exclude=['lat', 'lon'])
ds_lo = to_pd_datetime(ds_lo)
ds_hi = to_pd_datetime(ds_hi)
return ds_lo, ds_hi
def get_stats(time):
variables = ['mean', 'q10', 'q25', 'q50', 'q75', 'q90', 'n']
coords = {
'variable': ['analysed_sst', 'CHL'],
'zone': zones_list,
'mask': ['front', 'background'],
'time': time
stats = xr.Dataset(data_vars={v: xr.DataArray(np.nan, coords, coords.keys())
for v in variables},
return stats
def add_land(kind, ds):
filename = path.join(root_data, 'land_mask_{}.nc'.format(kind))
land = xr.open_dataset(filename)['land']
land, _ = xr.align(land, ds, join='right')
land = land.astype('bool')
bermudes_lat = (32.20, 32.45)
bermudes_lon = (-64.95, -64.60)
lon=slice(*bermudes_lon))] = False
ds['land'] = land
return ds
def to_pd_datetime(ds):
ds = ds.assign_coords(time=pd.to_datetime(ds.time.values))
return ds
def extend_mask(mask, neighbors, repeat):
n = 2*neighbors+1
kernel = np.zeros((n, n))
for i in range(n):
for j in range(n):
kernel[i, j] = (i-(n-1)/2)**2 + (j-(n-1)/2)**2 <= (n/2)**2
for _ in range(repeat):
mask = np.clip(ndimage.convolve(mask, kernel), 0, 1)
return mask
def compute_stats(stats, loc, da, mask):
def add(var, func, *args):
stats[var].loc[loc] = getattr(da.where(mask), func)(*args, dim=['lat', 'lon'])
add('n', 'count')
add('mean', 'mean')
add('q10', 'quantile', 0.10)
add('q25', 'quantile', 0.25)
add('q50', 'quantile', 0.50)
add('q75', 'quantile', 0.75)
add('q90', 'quantile', 0.90)
return stats
def compute(ds, var, stats):
for m in ['front', 'background']:
mask = ds[m] * ~ds['land']
for zone in zones_list:
if zone == 'total':
mask_ = mask
mask_ = mask * ds[zone]