prepare_oras5_paraso.sh 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #!/bin/bash
  2. set -u
  3. # This script takes ORAS5 ocean reanalyses, reinterpolates them to the NEMO grid so that BDY data can be generated from it afterwards.
  4. # As of July 2021, input ORAS5 can be downloaded from <https://www.cen.uni-hamburg.de/icdc/data/ocean/easy-init-ocean/ecmwf-oras5.html>
  5. # Author: C. Pelletier
  6. # Inclusive year range
  7. year_start=1979
  8. year_stop=2018
  9. # Input folder where input data files (in .tar.gz format) are.
  10. # This script expects member 'opa1' but you can change it below.
  11. in_folder="/mfast/pelletie/oras5/raw"
  12. # Folder where pre-interpolated datafiles will be
  13. dest_folder="/mfast/pelletie/oras5/preinterp"
  14. mkdir -p ${dest_folder}
  15. cd ${dest_folder}
  16. # min_lon, max_lon, min_lat, max_lat
  17. # To precut the input data prior to interpolation (not required, but less expensive if your source code is much bigger than the destination one, which is the case from global ORAS5 to the Southern Ocean (we d
  18. # Take a good margin (4-5 nodes bigger than the destination grid limit)
  19. latlon_cut="-180,180,-90,-28"
  20. # Script for converting EOS80 to TEOS-10 (look at the script comments for why it exists and what it does).
  21. eos10_script="/elic/home/pelletie/oras5/convert_eos10_new.py"
  22. # NEMO destination CDO grid description (see `cdo_get_griddes.sh`).
  23. dest_gridfile="/mfast/pelletie/oras5/eORCA025-SO_corners.grid"
  24. pid="$$"
  25. for((year=year_start;year<=year_stop;year++)); do
  26. # Loop over input years.
  27. module purge
  28. module load 2018b CDO
  29. # 1) Uncompress, concatenate, pre-cut and merge temperatures and salinities.
  30. tar -xvf ${in_folder}/votemper_ORAS5_1m_${year}_opa1.tar.gz
  31. cdo -O copy votemper_ORAS5_1m_${year}??_grid_T_02.nc tmp_pid${pid}.nc
  32. rm -f votemper_ORAS5_1m_${year}??_grid_T_02.nc
  33. cdo -O sellonlatbox,${latlon_cut} tmp_pid${pid}.nc tmp2_pid${pid}.nc
  34. tar -xvf ${in_folder}/vosaline_ORAS5_1m_${year}_opa1.tar.gz
  35. cdo -O copy vosaline_ORAS5_1m_${year}??_grid_T_02.nc tmp_pid${pid}.nc
  36. rm -f vosaline_ORAS5_1m_${year}??_grid_T_02.nc
  37. cdo -O sellonlatbox,${latlon_cut} tmp_pid${pid}.nc tmp3_pid${pid}.nc
  38. cdo -O merge tmp2_pid${pid}.nc tmp3_pid${pid}.nc tmp_pid${pid}.nc
  39. # 2) Convert EOS8 thermodynamics to TEOS-10 ones (look at the script to get why/what).
  40. module purge;
  41. module load ESMValTool;
  42. PYTHONPATH="/elic/home/pelletie/.local/lib/python3.6/site-packages:${PYTHONPATH}"
  43. python ${eos10_script} tmp_pid${pid}.nc tmp2_pid${pid}.nc
  44. # 3) Uncompress, concatenate, pre-cut and merge ssh with TEOS-10 temperatures and salinities.
  45. module purge
  46. module load 2018b CDO
  47. tar -xvf ${in_folder}/sossheig_ORAS5_1m_${year}_opa1.tar.gz
  48. cdo -O copy sossheig_ORAS5_1m_${year}??_grid_T_02.nc tmp_pid${pid}.nc
  49. rm -f sossheig_ORAS5_1m_${year}??_grid_T_02.nc
  50. cdo -O sellonlatbox,${latlon_cut} tmp_pid${pid}.nc tmp3_pid${pid}.nc
  51. cdo -O merge tmp3_pid${pid}.nc tmp2_pid${pid}.nc tmp_pid${pid}.nc
  52. # 4) Remap (bilinear) and drown all "T points" variables (temp/sal/ssh) to your NEMO grid.
  53. cdo remapbil,${dest_gridfile} tmp_pid${pid}.nc tmp2_pid${pid}.nc
  54. # For this interpolation, I have not put a src_gridfile, because this particular dataset (ORAS5) has 'good' netCDF attributes.
  55. # IF the input data has:
  56. # - a longitude variable with netCDF attributes standard_name="longitude", units="degrees East"
  57. # - a latitude variable with netCDF attributes standard_name="latitude", units="degrees North"
  58. # - at least one variable with a a netCDF attribute coordinates='<time> <depth> <lat> <lon>', where <time> is the name of the time variable; <depth> is the name of the depth variable (if the field is 3D); <lat> is the name of the latitude variable; <lon> is the name of the longitude variable.
  59. # THEN things go well, CDO recognizes the input grid.
  60. # And this happens to be the case with ORAS5 because it's a reanalysis from ECMWF, and they're standardized.
  61. # ELSE, you need to explicitly generate (see `get_cdo_griddes.sh`) and specify the input grid description in the remap call, which would have been: `cdo remapbil,${dest_gridfile} -setgrid,${src_gridfile} tmp_pid${pid}.nc tmp2_pid${pid}.nc`
  62. # Drown output fields. This is super lengthy because it computes distances (in kilometers).
  63. # There are other much more efficient ways to do it (discrete nearest-neighbor would be fine), but I'm too lazy.
  64. # I do have a function for doing it in nn_interp.py, though. Feel free to plug it in somehow.
  65. # Else, do it overnight/the weekend, I guess...
  66. cdo setmisstonn tmp2_pid${pid}.nc ORAS5_preinterp_opa1_grid_T_${year}.nc
  67. module load NCO
  68. # 5) Uncompress, concatenate, pre-cut U velocities.
  69. tar -xvf ${in_folder}/vozocrtx_ORAS5_1m_${year}_opa1.tar.gz
  70. cdo -O copy vozocrtx_ORAS5_1m_${year}??_grid_U_02.nc tmp_pid${pid}.nc
  71. rm -f vozocrtx_ORAS5_1m_${year}??_grid_U_02.nc
  72. cdo -O sellonlatbox,${latlon_cut} tmp_pid${pid}.nc tmp3_pid${pid}.nc
  73. # 6) Get barotropic U velocities from full 3D velocities.
  74. # vozocrtx(t,z,y,x) = u_barotropic(t,y,x) + u_baroclinic(t,z,y,x), where u_barotropic is the vertical average of u_3d(t,z,y,x).
  75. # First, we get u_barotropic by vertical averaging, then we get u_baroclinic by removing it from vozocrtx.
  76. cdo vertmean tmp3_pid${pid}.nc tmp2_pid${pid}.nc
  77. ncks -C -v vozocrtx tmp2_pid${pid}.nc -O tmp_pid${pid}.nc
  78. ncwa -O -a depthu tmp_pid${pid}.nc tmp2_pid${pid}.nc
  79. ncrename -v vozocrtx,uobarotropic tmp2_pid${pid}.nc
  80. ncatted -a standard_name,uobarotropic,o,c,"barotropic_currents_in_x_direction" -a long_name,uobarotropic,o,c,"barotropic currents in x direction" tmp2_pid${pid}.nc
  81. ncks tmp2_pid${pid}.nc -A tmp3_pid${pid}.nc
  82. ncap2 -O -s 'uobaroclinic=vozocrtx-uobarotropic;' tmp3_pid${pid}.nc tmp2_pid${pid}.nc
  83. ncks -x -v vozocrtx tmp2_pid${pid}.nc -O tmp3_pid${pid}.nc
  84. ncatted -a standard_name,'baroclinic_currents_in_x_direction' -a long_name,uobaroclinic,o,c,"baroclinic currents in x direction" -a units,uobaroclinic,o,c,"m s-1" -a coordinates,uobaroclinic,o,c,"time_counter depthu nav_lat nav_lon" tmp3_pid${pid}.nc
  85. # 7) Remap both u velocities (barotropic and baroclinic) to destination grid, and drown.
  86. # Here they're remapped to T nodes, which is not correct (but it's not a big deal).
  87. # All interpolations and shifted by half a cell in the x direction, sorry.
  88. # If you want to correct that, you should generate a ${dest_gridfile} which points to U nodes.
  89. cdo remapbil,${dest_gridfile} tmp3_pid${pid}.nc tmp2_pid${pid}.nc
  90. cdo setmisstonn tmp2_pid${pid}.nc ORAS5_preinterp_opa1_grid_U_${year}.nc
  91. # 8) Uncompress, concatenate, pre-cut u velocities.
  92. tar -xvf ${in_folder}/vomecrty_ORAS5_1m_${year}_opa1.tar.gz
  93. cdo -O copy vomecrty_ORAS5_1m_${year}??_grid_V_02.nc tmp_pid${pid}.nc
  94. rm -f vomecrty_ORAS5_1m_${year}??_grid_V_02.nc
  95. cdo -O sellonlatbox,${latlon_cut} tmp_pid${pid}.nc tmp3_pid${pid}.nc
  96. # 9) Get barotropic V velocities from full 3D velocities.
  97. # vomecrty(t,z,y,x) = v_barotropic(t,y,x) + v_baroclinic(t,z,y,x), where v_barotropic is the vertical average of vomecrty(t,z,y,x).
  98. # First, we get v_barotropic by vertical averaging, then we get v_baroclinic by removing it from vomecrty.
  99. cdo vertmean tmp3_pid${pid}.nc tmp2_pid${pid}.nc
  100. ncks -C -v vomecrty tmp2_pid${pid}.nc -O tmp_pid${pid}.nc
  101. ncwa -O -a depthv tmp_pid${pid}.nc tmp2_pid${pid}.nc
  102. ncrename -v vomecrty,vobarotropic tmp2_pid${pid}.nc
  103. ncatted -a standard_name,vobarotropic,o,c,"barotropic_currents_in_x_direction" -a long_name,vobarotropic,o,c,"barotropic currents in x direction" tmp2_pid${pid}.nc
  104. ncks tmp2_pid${pid}.nc -A tmp3_pid${pid}.nc
  105. ncap2 -O -s 'vobaroclinic=vomecrty-vobarotropic;' tmp3_pid${pid}.nc tmp2_pid${pid}.nc
  106. ncks -x -v vomecrty tmp2_pid${pid}.nc -O tmp3_pid${pid}.nc
  107. ncatted -a standard_name,'baroclinic_currents_in_x_direction' -a long_name,vobaroclinic,o,c,"baroclinic currents in x direction" -a units,vobaroclinic,o,c,"m s-1" -a coordinates,vobaroclinic,o,c,"time_counter depthv nav_lat nav_lon" tmp3_pid${pid}.nc
  108. # 10) Remap both v velocities (barotropic and baroclinic) to destination grid, and drown.
  109. # Here they're remapped to T nodes, which is not correct (but it's not a big deal).
  110. # All interpolations and shifted by half a cell in the y direction, sorry.
  111. # If you want to correct that, you should generate a ${dest_gridfile} which points to V nodes.
  112. cdo remapbil,${dest_gridfile} tmp3_pid${pid}.nc tmp2_pid${pid}.nc
  113. cdo setmisstonn tmp2_pid${pid}.nc ORAS5_preinterp_opa1_grid_V_${year}.nc
  114. done
  115. rm -f ./*pid${pid}*