| 1 | |
| 2 | == Interpolation with CDO == |
| 3 | |
| 4 | |
| 5 | '''You can find here an example of bash script to interpolate forcing core2 files.[[BR]] |
| 6 | |
| 7 | To interpolate files you need to do 3 steps:[[BR]] |
| 8 | |
| 9 | 1. have good grid description file (if not you can create it, see instructions 1.) below)[[BR]] |
| 10 | |
| 11 | 2. prepare files to be interpolated ((see 2.) below)[[BR]] |
| 12 | |
| 13 | 3. remapping on ORCA2 grid ((see 3.) below)'''[[BR]] |
| 14 | |
| 15 | |
| 16 | NOTE: This script works with cdo version 1.4.0.1 |
| 17 | |
| 18 | |
| 19 | |
| 20 | == 1) Prepare grid description file for the ORCA curvilinear grid == |
| 21 | |
| 22 | You need to prepare a netCDF grid description file for the ORCA curvilinear grid.[[BR]] |
| 23 | This file must contain:[[BR]] |
| 24 | - a longitude variable with exactly 2 dimensions and the attribute: units = "degrees_east"[[BR]] |
| 25 | - a latitude variable with exactly 2 dimensions and the attribute: units = "degrees_north"[[BR]] |
| 26 | - a dummy variable with the attribute: coordinates = "xxx yyy" where xxx and yyy are the name of the longitude and latitude variables mentioned just above[[BR]] |
| 27 | |
| 28 | There is an example of a [http://www.unidata.ucar.edu/software/netcdf/ netCDF] grid description file for the T grid of ORCA2:[[BR]] |
| 29 | |
| 30 | |
| 31 | {{{ |
| 32 | netcdf grid_ORCA2_T { |
| 33 | dimensions: |
| 34 | y = 149 ; |
| 35 | x = 182 ; |
| 36 | variables: |
| 37 | byte dummy(y, x) ; |
| 38 | dummy:coordinates = "glamt gphit" ; |
| 39 | double glamt(y, x) ; |
| 40 | glamt:units = "degrees_east" ; |
| 41 | double gphit(y, x) ; |
| 42 | gphit:units = "degrees_north" ; |
| 43 | } |
| 44 | }}} |
| 45 | |
| 46 | There is an example of nco commands to create this file from coordinates.nc (input file used by NEMO for its grid description)[[BR]] |
| 47 | |
| 48 | |
| 49 | {{{ |
| 50 | # select glamt and gphit variables from the coordinates file |
| 51 | ncks -O -C -a -v glamt,gphit coordinates_ORCA_R2.nc grid_ORCA2_T.nc |
| 52 | |
| 53 | }}} |
| 54 | |
| 55 | make sure that coordinates variables contains only 2 dimension. Use ncwa -a to remove degenerated dimensions (with a size of 1) for example:[[BR]] |
| 56 | |
| 57 | |
| 58 | {{{ |
| 59 | # remove degenerated dimention time (if existing) |
| 60 | ncwa -O -a time grid_ORCA2_T.nc grid_ORCA2_T.nc |
| 61 | # remove degenerated dimention z (if existing) |
| 62 | ncwa -O -a z grid_ORCA2_T.nc grid_ORCA2_T.nc |
| 63 | }}} |
| 64 | |
| 65 | {{{ |
| 66 | # add a dummy variable |
| 67 | ncap2 -O -s 'dummy[y,x]=1b' grid_ORCA2_T.nc grid_ORCA2_T.nc |
| 68 | # add needed attributes |
| 69 | ncatted -a coordinates,dummy,c,c,'glamt gphit' \ |
| 70 | -a units,glamt,c,c,'degrees_east' \ |
| 71 | -a units,gphit,c,c,'degrees_north' grid_ORCA2_T.nc |
| 72 | }}} |
| 73 | |
| 74 | |
| 75 | == |
| 76 | 2) Prepare file to be interpolated == |
| 77 | |
| 78 | for a curvilinear grid:[[BR]] |
| 79 | |
| 80 | - you have to follow above spefication[[BR]] |
| 81 | |
| 82 | For a regular lon/lat grid:[[BR]] |
| 83 | |
| 84 | - The coordinate variables must have the same name as the dimensions. You can chose any name. If you use the name x for the dimension then you have to use also x for the coordinate variable.[[BR]] |
| 85 | - The coordinate variable must also have the attribute units = "degrees_east" or "degrees_north" to identify the lon/lat variables:[[BR]] |
| 86 | |
| 87 | {{{ |
| 88 | netcdf etopo5 { |
| 89 | dimensions: |
| 90 | x = 4320 ; |
| 91 | y = 2161 ; |
| 92 | variables: |
| 93 | float x(x) ; |
| 94 | x:units = "degree_east" ; |
| 95 | float y(y) ; |
| 96 | y:units = "degree_north" ; |
| 97 | float bath(y, x) ; |
| 98 | } |
| 99 | }}} |
| 100 | |
| 101 | |
| 102 | == 3) Remapping on ORCA2 == |
| 103 | |
| 104 | '''Generate weights with bilinear interpolation, and then remapping for a scalar field:'''[[BR]] |
| 105 | |
| 106 | |
| 107 | {{{ |
| 108 | |
| 109 | cdo genbil,grid_ORCA2_T.nc $file bil_orca2_weights.nc |
| 110 | cdo remap,grid_ORCA2_T.nc,bil_orca2_weights.nc $file_fill.nc $file_orca2.nc |
| 111 | }}} |
| 112 | |
| 113 | |
| 114 | where[[BR]] |
| 115 | |
| 116 | - $file_fill.nc is a file whose missing values is filled (see below interpolation_loop.sh)[[BR]] |
| 117 | |
| 118 | - $file_orca2.nc is the output[[BR]] |
| 119 | |
| 120 | - and bil_orca2_weights.nc is a weight file generated (see below)[[BR]] |
| 121 | |
| 122 | |
| 123 | ''Generate weights with bilinear interpolation, and then remapping for a vectorial field:'''[[BR]] |
| 124 | |
| 125 | |
| 126 | {{{ |
| 127 | |
| 128 | cdo genbic,grid_ORCA2_T.nc $file bic_orca2_weights.nc |
| 129 | cdo remap,grid_ORCA2_T.nc,bic_orca2_weights.nc $file_fill.nc $file_orca2.nc |
| 130 | }}} |
| 131 | |
| 132 | |
| 133 | where[[BR]] |
| 134 | |
| 135 | - $file_fill.nc is a file whose missing values is filled (see below interpolation_loop.sh)[[BR]] |
| 136 | |
| 137 | - $file_orca2.nc is the output[[BR]] |
| 138 | |
| 139 | - and bic_orca2_weights.nc is a weight file generated (see below)[[BR]] |
| 140 | |
| 141 | |
| 142 | == Example of "interpolation_loop.sh" script == |
| 143 | |
| 144 | This script needs to have input directory in your execution's directory to copy *.nc files and it calls 4 others sub-scripts: "create_orca2.sh", "prepare_mask.sh", "bilweights.sh" and "bicweights.sh"[[BR]] |
| 145 | |
| 146 | |
| 147 | NOTE: Before running "interpolation_loop.sh", you nedd to checks different things:[[BR]] |
| 148 | |
| 149 | 1. control latitude of your mask file. If it goes from north to south and latitude in your file goes from south to north you have to invert it:[[BR]] |
| 150 | |
| 151 | {{{ |
| 152 | cdo invertlat ${file_mask_land}.nc ${file_mask_land}.SN.nc |
| 153 | }}} |
| 154 | |
| 155 | |
| 156 | 2. control format of land variable, if it is short and your file has float format you will have problems with cdo created missing values, and filling missing values |
| 157 | |
| 158 | {{{ |
| 159 | #convert in float (from short) land variable |
| 160 | ncap -O -s "land=float(land)" ${file_mask_land}.SN.nc ${file_mask_land}.SN.float.nc |
| 161 | }}} |
| 162 | |
| 163 | 3. control values of your land variable, if it is 1 on earth and 0 on ocean is not good if you are interpolating files for ocean forcing |
| 164 | |
| 165 | {{{ |
| 166 | #convert land=0 on earth, 1 on ocean |
| 167 | ncap -O -s 'land=1-land' mask.nc mask.nc |
| 168 | }}} |
| 169 | |
| 170 | {{{ |
| 171 | #rename "land" in "mask" |
| 172 | ncrename -v land,mask mask.nc |
| 173 | }}} |
| 174 | |
| 175 | |
| 176 | 4. control values of calendar's attribute in your file, if it is "NOLEAP" it is better to convert it in a recognized format by nccated (ex. 365_day) |
| 177 | |
| 178 | {{{ |
| 179 | ncatted -a calendar,${variable},m,c,365_day ${file}.nc ${file}_365.nc |
| 180 | }}} |
| 181 | |
| 182 | |
| 183 | '''main programm: interpolation_loop.sh ''' |
| 184 | |
| 185 | {{{ |
| 186 | #!/bin/bash |
| 187 | #script to interpolate files on ORCA2 grids |
| 188 | |
| 189 | set -u |
| 190 | LC_ALL=C; export LC_ALL |
| 191 | |
| 192 | type cdo |
| 193 | status_cdo=${?} |
| 194 | if [ ${status_cdo} != 0 ] ; then |
| 195 | echo "ERROR: cdo not found in your PATH" |
| 196 | exit 1 |
| 197 | fi |
| 198 | |
| 199 | file_orca2="grid_ORCA2_T.nc" |
| 200 | #build ORCA2_grid if necessary |
| 201 | if [ ! -f ${file_orca2} ] ; then |
| 202 | /bin/sh create_orca2.sh |
| 203 | fi |
| 204 | |
| 205 | #preparing mask file if necessary |
| 206 | if [ ! -f mask.nc ] ; then |
| 207 | /bin/sh prepare_mask.sh |
| 208 | fi |
| 209 | |
| 210 | dir=/PATH/FILES/TO/BE/INTERPOLATED |
| 211 | |
| 212 | `cp ${dir}/*.nc input/.` |
| 213 | cd input |
| 214 | |
| 215 | for file in $(echo `ls *.nc | sed -e "s/\.nc//"`) ; do |
| 216 | |
| 217 | # create missing values over land with e.g. 'ifthen': |
| 218 | echo "create missing values ifthen mask" |
| 219 | cdo ifthen ../mask.nc ${file}_365.nc ${file}_mask.nc |
| 220 | status_ifthen=${?} |
| 221 | if [ ${status_ifthen} != 0 ] ; then |
| 222 | echo "ERROR ifthen mask" |
| 223 | exit 1 |
| 224 | fi |
| 225 | |
| 226 | |
| 227 | # fill missing value (here over land): |
| 228 | echo "fill missing values" |
| 229 | cdo fillmiss ${file}_mask.nc ${file}_fill.nc |
| 230 | status_fillmiss=${?} |
| 231 | if [ ${status_fillmiss} != 0 ] ; then |
| 232 | echo "ERRORE cdo fillmiss" |
| 233 | exit 1 |
| 234 | fi |
| 235 | |
| 236 | |
| 237 | #remapping on ORCA2 grid |
| 238 | echo "remapping " |
| 239 | cd .. |
| 240 | # looking for first part of filename, to see if it is vectorial field, for interannual files |
| 241 | name=$(echo $file | awk -F \_ {'print $1'} ) |
| 242 | if [ ${name} = "u" -o ${name} = "v" ] ; then |
| 243 | echo "vectorial field" |
| 244 | /bin/sh bicweights.sh input/${file}_fill.nc |
| 245 | cdo remap,grid_ORCA2_T.nc,bic_orca2_weights.nc input/${file}_fill.nc input/${file}_orca2.nc |
| 246 | else |
| 247 | echo "scalar field" |
| 248 | /bin/sh bilweights.sh input/${file}_fill.nc |
| 249 | cdo remap,grid_ORCA2_T.nc,bil_orca2_weights.nc input/${file}_fill.nc input/${file}_orca2.nc |
| 250 | fi |
| 251 | status_remap=${?} |
| 252 | if [ ${status_remap} != 0 ] ; then |
| 253 | echo "ERROR cdo remap" |
| 254 | exit 1 |
| 255 | fi |
| 256 | echo "status remap: ${status_remap}" |
| 257 | cd input |
| 258 | done |
| 259 | }}} |
| 260 | |
| 261 | '''first sub-programm: file create_orca2.sh''' |
| 262 | {{{ |
| 263 | #!/bin/bash |
| 264 | #script to create ORCA2 grid |
| 265 | |
| 266 | set -u |
| 267 | LC_ALL=C ; export LC_ALL |
| 268 | |
| 269 | echo "create orca2 grid" |
| 270 | ncks -O -C -a -v glamt,gphit coordinates.nc grid_ORCA2_T.nc |
| 271 | |
| 272 | #remove not necessar axes: |
| 273 | ncwa -O -a time,z grid_ORCA2_T.nc grid_ORCA2_T.nc |
| 274 | |
| 275 | #add dummy variable: |
| 276 | ncap -O -s 'dummy[y,x]=1b' grid_ORCA2_T.nc grid_ORCA2_T.nc |
| 277 | |
| 278 | #add needed attributes |
| 279 | ncatted -a coordinates,dummy,c,c,'glamt gphit' \ |
| 280 | -a units,glamt,c,c,'degrees_east' \ |
| 281 | -a units,gphit,c,c,'degrees_north' grid_ORCA2_T.nc |
| 282 | }}} |
| 283 | |
| 284 | '''Second sub-programm: prepare_mask.sh''' |
| 285 | {{{ |
| 286 | #!/bin/bash |
| 287 | #preparing mask file |
| 288 | |
| 289 | set -u |
| 290 | LC_ALL=C ; export LC_ALL |
| 291 | |
| 292 | file_mask_land="land.sfc.gauss" |
| 293 | # invert latitude (from SOUTH to NORTH) |
| 294 | cdo invertlat ${file_mask_land}.nc ${file_mask_land}.SN.nc |
| 295 | |
| 296 | #convert in float (from short) land variable |
| 297 | ncap -O -s "land=float(land)" ${file_mask_land}.SN.nc ${file_mask_land}.SN.float.nc |
| 298 | |
| 299 | # remove all attribute to land |
| 300 | ncatted -a ,land,d,, ${file_mask_land}.SN.float.nc ${file_mask_land}.SN.float.miss.nc |
| 301 | |
| 302 | # extract land |
| 303 | #ncks -O -v land land.sfc.gauss.SN.float.nc mask.nc |
| 304 | ncks -O -v land ${file_mask_land}.SN.float.miss.nc mask.nc |
| 305 | ncwa -O -a time mask.nc mask.nc |
| 306 | |
| 307 | #convert land=0 on earth, 1 on ocean |
| 308 | ncap -O -s 'land=1-land' mask.nc mask.nc |
| 309 | |
| 310 | #rename "land" in "mask" |
| 311 | ncrename -v land,mask mask.nc |
| 312 | chmod 755 mask.nc |
| 313 | }}} |
| 314 | |
| 315 | |
| 316 | '''Third sub-programm: bicweights.sh''' |
| 317 | {{{ |
| 318 | #!/bin/bash |
| 319 | |
| 320 | #remapping on ORCA2 grid |
| 321 | echo "gen bicubic WEIGHTS" |
| 322 | export REMAP_EXTRAPOLATE=on |
| 323 | cdo genbic,grid_ORCA2_T.nc $1 bic_orca2_weights.nc |
| 324 | }}} |
| 325 | |
| 326 | |
| 327 | '''Forth sub-programm: bicweights.sh''' |
| 328 | {{{ |
| 329 | #!/bin/bash |
| 330 | |
| 331 | #remapping on ORCA2 grid |
| 332 | echo "gen bilinear WEIGHTS" |
| 333 | export REMAP_EXTRAPOLATE=on |
| 334 | cdo genbil,grid_ORCA2_T.nc $1 bil_orca2_weights.nc |
| 335 | }}} |
| 336 | |
| 337 | |
| 338 | |
| 339 | |