Xcroco question

Hi,

I am currently trying to use Xcroco from croco_pytools-v2.0.1 and I encountered an issue regarding a missing variable.
Since I am using the default outputs from CROCO, I selected croco_native as the model in xcroco.ini. However, when I tried to run tuto_xcroco.ipynb, I received an error stating that the variable Cs_r does not exist. The error appears in gridop.py, and I assume directly modifying the template might lead to further issues, so I am looking for recommended workarounds or best practices.
Looking at the model.py, I see that the croco_native template does not define Cs_r (unlike croco_xios, which has “Cs_rho”: “Cs_r” in rename_vars). I tried different approaches to resolve the problem, but the error persists.
What is the best strategy to overcomes this issue for CROCO ouputs containing Cs_rho?

Thank you in advance.

Hi @Jellyfish,

It seems that the variable Cs_r is either missing from your file or has a different name.

This may occur if you have a former version of CROCO with a different naming convention, or if you did not write Cs_r in both history and grid files.

In case of a wrong naming convention the best practice is to edit model.py :

  • add a new model with a name ex: “old_croco_native” like if name == "old_croco_native":
  • copy the dictionary for naming convention that’s closest to your model here “croco_native”
self.rename_vars = {
                # surface wind stress
                "sustr": "xtau_sfc_u",  # x-wind stress component
                ...

  • add a line for misnamed variable “Cs_rho_wrong_name”: “Cs_r”

This is actually the way to deal with any naming convention issue. model.py is just a tool to rename CROCO variables to a standard naming convention.


In case where you do not have access to Cs_rho, you’ll have to recompute it somehow offline, and add it “manually” to croco xarray.dataset and it should be fine.

I hope this helps,
Best,
Jeremy

Hello !

Out of curiosity : Can you put a ncdump -h of your croco file here ?

If Cs_r is not at all in the file, it should be (I believe) computed automatically by the get_cs function within xcroco.

Enzo

Hi Jeremy,

Thanks for the advice.
I’m going to test it out to see if it works.

Best regards

Hi,

This is the output from the ncdump:
netcdf croco_his_Y2019M12 {
dimensions:
xi_rho = 902 ;
xi_u = 901 ;
eta_rho = 902 ;
eta_v = 901 ;
s_rho = 60 ;
s_w = 61 ;
time = UNLIMITED ; // (2 currently)
auxil = 4 ;
variables:
char spherical ;
spherical:long_name = “grid type logical switch” ;
spherical:option_T = “spherical” ;
spherical:option_F = “cartesian” ;
float xl ;
xl:long_name = “domain length in the XI-direction” ;
xl:units = “meter” ;
float el ;
el:long_name = “domain length in the ETA-direction” ;
el:units = “meter” ;
float xi_rho(xi_rho) ;
xi_rho:long_name = “x-dimension of the grid” ;
xi_rho:standard_name = “x_grid_index” ;
xi_rho:axis = “X” ;
xi_rho:c_grid_dynamic_range = “2:901” ;
float xi_u(xi_u) ;
xi_u:long_name = “x-dimension of the grid at u location” ;
xi_u:standard_name = “x_grid_index_at_u_location” ;
xi_u:axis = “X” ;
xi_u:c_grid_axis_shift = 0.5f ;
xi_u:c_grid_dynamic_range = “2:900” ;
float eta_rho(eta_rho) ;
eta_rho:long_name = “y-dimension of the grid” ;
eta_rho:standard_name = “y_grid_index” ;
eta_rho:axis = “Y” ;
eta_rho:c_grid_dynamic_range = “2:901” ;
float eta_v(eta_v) ;
eta_v:long_name = “y-dimension of the grid at v location” ;
eta_v:standard_name = “x_grid_index_at_v_location” ;
eta_v:axis = “Y” ;
eta_v:c_grid_axis_shift = 0.5f ;
eta_v:c_grid_dynamic_range = “2:900” ;
float Vtransform ;
Vtransform:long_name = “vertical terrain-following transformation equatio” ;
float s_rho(s_rho) ;
s_rho:long_name = “S-coordinate at RHO-points” ;
s_rho:axis = “Z” ;
s_rho:positive = “up” ;
s_rho:standard_name = “ocean_s_coordinate_g2” ;
s_rho:Vtransform = “2” ;
s_rho:formula_terms = “s: s_rho C: Cs_rho eta: zeta depth: h depth_c: hc” ;
float s_w(s_w) ;
s_w:long_name = “S-coordinate at W-points” ;
s_w:axis = “Z” ;
s_w:positive = “up” ;
s_w:c_grid_axis_shift = -0.5f ;
s_w:standard_name = “ocean_s_coordinate_g2_at_w_location” ;
s_w:Vtransform = “2” ;
s_w:formula_terms = “s: s_w C: Cs_w eta: zeta depth: h depth_c: hc” ;
float Cs_rho(s_rho) ;
Cs_rho:long_name = “S-coordinate stretching curves at RHO-points” ;
float Cs_w(s_w) ;
Cs_w:long_name = “S-coordinate stretching curves at W-points” ;
float hc ;
hc:long_name = “S-coordinate parameter, critical depth” ;
hc:units = “meter” ;
float h(eta_rho, xi_rho) ;
h:long_name = “bathymetry at RHO-points” ;
h:units = “meter” ;
h:field = “bath, scalar” ;
h:standard_name = “model_sea_floor_depth_below_geoid” ;
h:coordinates = “lat_rho lon_rho” ;
float f(eta_rho, xi_rho) ;
f:long_name = “Coriolis parameter at RHO-points” ;
f:units = “second-1” ;
f:field = “coriolis, scalar” ;
f:standard_name = “coriolis_parameter” ;
f:coordinates = “lat_rho lon_rho” ;
float pm(eta_rho, xi_rho) ;
pm:long_name = “curvilinear coordinates metric in X” ;
pm:units = “meter-1” ;
pm:field = “pm, scalar” ;
pm:coordinates = “lat_rho lon_rho” ;
pm:standard_name = “inverse_of_cell_x_size” ;
float pn(eta_rho, xi_rho) ;
pn:long_name = “curvilinear coordinates metric in ET” ;
pn:units = “meter-1” ;
pn:field = “pn, scalar” ;
pn:coordinates = “lat_rho lon_rho” ;
pn:standard_name = “inverse_of_cell_y_size” ;
float lon_rho(eta_rho, xi_rho) ;
lon_rho:long_name = “longitude of RHO-points” ;
lon_rho:units = “degree_east” ;
lon_rho:field = “lon_rho, scalar” ;
lon_rho:standard_name = “longitude” ;
float lat_rho(eta_rho, xi_rho) ;
lat_rho:long_name = “latitude of RHO-points” ;
lat_rho:units = “degree_north” ;
lat_rho:field = “lat_rho, scalar” ;
lat_rho:standard_name = “latitude” ;
float lon_u(eta_rho, xi_u) ;
lon_u:long_name = “longitude of U-points” ;
lon_u:units = “degree_east” ;
lon_u:field = “lon_u, scalar” ;
lon_u:standard_name = “longitude_at_u_location” ;
float lat_u(eta_rho, xi_u) ;
lat_u:long_name = “latitude of U-points” ;
lat_u:units = “degree_north” ;
lat_u:field = “lat_u, scalar” ;
lat_u:standard_name = “latitude_at_u_location” ;
float lon_v(eta_v, xi_rho) ;
lon_v:long_name = “longitude of V-points” ;
lon_v:units = “degree_east” ;
lon_v:field = “lon_v, scalar” ;
lon_v:standard_name = “longitude_at_v_location” ;
float lat_v(eta_v, xi_rho) ;
lat_v:long_name = “latitude of V-points” ;
lat_v:units = “degree_north” ;
lat_v:field = “lat_v, scalar” ;
lat_v:standard_name = “latitude_at_v_location” ;
float angle(eta_rho, xi_rho) ;
angle:long_name = “angle between XI-axis and EAST” ;
angle:units = “radians” ;
angle:field = “angle, scalar” ;
angle:coordinates = “lat_rho lon_rho” ;
float mask_rho(eta_rho, xi_rho) ;
mask_rho:long_name = “mask on RHO-points” ;
mask_rho:option_0 = “land” ;
mask_rho:option_1 = “water” ;
mask_rho:standard_name = “land_binary_mask” ;
mask_rho:coordinates = “lat_rho lon_rho” ;
int time_step(time, auxil) ;
time_step:long_name = “time step and record numbers from initialization” ;
double scrum_time(time) ;
scrum_time:long_name = “time since initialization” ;
scrum_time:units = “second” ;
scrum_time:field = “time, scalar, series” ;
scrum_time:standard_name = “time” ;
scrum_time:axis = “T” ;
double time(time) ;
time:long_name = “time since initialization” ;
time:units = “second” ;
time:field = “time, scalar, series” ;
time:standard_name = “time” ;
time:axis = “T” ;
float zeta(time, eta_rho, xi_rho) ;
zeta:long_name = “free-surface” ;
zeta:units = “meter” ;
zeta:field = “free-surface, scalar, series” ;
zeta:standard_name = “sea_surface_height” ;
zeta:coordinates = “lat_rho lon_rho” ;
float ubar(time, eta_rho, xi_u) ;
ubar:long_name = “vertically integrated u-momentum component” ;
ubar:units = “meter second-1” ;
ubar:field = “ubar-velocity, scalar, series” ;
ubar:standard_name = “barotropic_sea_water_x_velocity_at_u_location” ;
ubar:coordinates = “lat_u lon_u” ;
float vbar(time, eta_v, xi_rho) ;
vbar:long_name = “vertically integrated v-momentum component” ;
vbar:units = “meter second-1” ;
vbar:field = “vbar-velocity, scalar, series” ;
vbar:standard_name = “barotropic_sea_water_y_velocity_at_v_location” ;
vbar:coordinates = “lat_v lon_v” ;
float u(time, s_rho, eta_rho, xi_u) ;
u:long_name = “u-momentum component” ;
u:units = “meter second-1” ;
u:field = “u-velocity, scalar, series” ;
u:standard_name = “sea_water_x_velocity_at_u_location” ;
u:coordinates = “lat_u lon_u” ;
float v(time, s_rho, eta_v, xi_rho) ;
v:long_name = “v-momentum component” ;
v:units = “meter second-1” ;
v:field = “v-velocity, scalar, series” ;
v:standard_name = “sea_water_y_velocity_at_v_location” ;
v:coordinates = “lat_v lon_v” ;
float temp(time, s_rho, eta_rho, xi_rho) ;
temp:long_name = “potential temperature” ;
temp:units = “Celsius” ;
temp:field = “temperature, scalar, series” ;
temp:standard_name = “sea_water_potential_temperature” ;
temp:coordinates = “lat_rho lon_rho” ;
float salt(time, s_rho, eta_rho, xi_rho) ;
salt:long_name = “salinity” ;
salt:units = “PSU” ;
salt:field = “salinity, scalar, series” ;
salt:standard_name = “sea_water_salinity” ;
salt:coordinates = “lat_rho lon_rho” ;
float w(time, s_rho, eta_rho, xi_rho) ;
w:long_name = “vertical momentum component” ;
w:units = “meter second-1” ;
w:field = “w-velocity, scalar, series” ;
w:standard_name = “upward_sea_water_velocity” ;
w:coordinates = “lat_rho lon_rho” ;
float bostr(time, eta_rho, xi_rho) ;
bostr:long_name = “Kinematic bottom stress” ;
bostr:units = “N/m2” ;
bostr:coordinates = “lat_rho lon_rho” ;
float wstr(time, eta_rho, xi_rho) ;
wstr:long_name = “Kinematic wind stress” ;
wstr:units = “N/m2” ;
wstr:standard_name = “magnitude_of_surface_downward_stress” ;
wstr:coordinates = “lat_rho lon_rho” ;
float sustr(time, eta_rho, xi_u) ;
sustr:long_name = “Kinematic u wind stress component” ;
sustr:units = “N/m2” ;
sustr:standard_name = “surface_downward_eastward_stress” ;
sustr:coordinates = “lat_u lon_u” ;
float svstr(time, eta_v, xi_rho) ;
svstr:long_name = “Kinematic v wind stress component” ;
svstr:units = “N/m2” ;
svstr:standard_name = “surface_downward_northward_stress” ;
svstr:coordinates = “lat_v lon_v” ;
float AKt(time, s_w, eta_rho, xi_rho) ;
AKt:long_name = “temperature vertical diffusion coefficient” ;
AKt:units = “meter2 second-1” ;
AKt:field = “AKt, scalar, series” ;
AKt:standard_name = “ocean_vertical_heat_diffusivity_at_w_location” ;
AKt:coordinates = “lat_rho lon_rho” ;
float hbl(time, eta_rho, xi_rho) ;
hbl:long_name = “depth of planetary boundary layer” ;
hbl:units = “meter” ;
hbl:field = “hbl, scalar, series” ;
hbl:standard_name = “ocean_mixed_layer_thickness_defined_by_mixing_scheme” ;
hbl:coordinates = “lat_rho lon_rho” ;
float hbbl(time, eta_rho, xi_rho) ;
hbbl:long_name = “depth of bottom boundary layer” ;
hbbl:units = “meter” ;
hbbl:field = “hbbl, scalar, series” ;
hbbl:coordinates = “lat_rho lon_rho” ;
float shflux(time, eta_rho, xi_rho) ;
shflux:long_name = “surface net heat flux” ;
shflux:units = “Watts meter-2” ;
shflux:coordinates = “lat_rho lon_rho” ;
float swflux(time, eta_rho, xi_rho) ;
swflux:long_name = “surface freshwater flux (E-P)” ;
swflux:units = “centimeter day-1” ;
swflux:coordinates = “lat_rho lon_rho” ;
float radsw(time, eta_rho, xi_rho) ;
radsw:long_name = “Short-wave surface radiation” ;
radsw:units = “Watts meter-2” ;
radsw:coordinates = “lat_rho lon_rho” ;
float shflx_rlw(time, eta_rho, xi_rho) ;
shflx_rlw:long_name = “Long-wave surface radiation” ;
shflx_rlw:units = “Watts meter-2” ;
shflx_rlw:coordinates = “lat_rho lon_rho” ;
float shflx_lat(time, eta_rho, xi_rho) ;
shflx_lat:long_name = “Latent surface heat flux” ;
shflx_lat:units = “Watts meter-2” ;
shflx_lat:coordinates = “lat_rho lon_rho” ;
float shflx_sen(time, eta_rho, xi_rho) ;
shflx_sen:long_name = “Sensible surface heat flux” ;
shflx_sen:units = “Watts meter-2” ;
shflx_sen:coordinates = “lat_rho lon_rho” ;
It doesn’t have the Cs_r, but the Cs_rho.

Then I believe you can do as Jeremy said and add to the “croco_native” dict in model.py the line :
"Cs_rho": "Cs_r", # S-coordinates at mass points

I have the encountered the same error and resolved it by modifying
“Cs_rho”: “Cs_r”, # S-coordinates at mass points
in the gridop.py

Since i applied the "Cs_rho": "Cs_r", # S-coordinates at mass points everything is working fine.
I didn´t need to change anything in gridop.py yet.

Hi,
Where in gridop.py you applied that change?