Index: TOOLS/MOSAIX/RunoffWeights.py
===================================================================
--- TOOLS/MOSAIX/RunoffWeights.py	(revision 6064)
+++ TOOLS/MOSAIX/RunoffWeights.py	(revision 6066)
@@ -26,6 +26,5 @@
 
 ## Modules
-import netCDF4
-import numpy as np
+import numpy as np, xarray as xr
 import nemo
 from scipy import ndimage
@@ -55,10 +54,13 @@
 
 # Adding arguments
-parser.add_argument ('--oce'          , help='oce model name', type=str, default='eORCA1.2', choices=['ORCA2.3', 'eORCA1.2', 'eORCA025', 'eORCA025.1'] )
+parser.add_argument ('--oce'          , help='oce model name', type=str, default='eORCA1.2',
+                         choices=['ORCA2.3', 'eORCA1.2', 'eORCA1.4', 'eORCA1.4.2', 'eORCA025', 'eORCA025.1', 'eORCA025.4'] )
 parser.add_argument ('--atm'          , help='atm model name', type=str, default='LMD9695'    )
 parser.add_argument ('--atmCoastWidth', help='width of the coastal band in atmosphere (in grid points)', type=int, default=1 )
 parser.add_argument ('--oceCoastWidth', help='width of the coastal band in ocean (in grid points)'     , type=int, default=2 )
-parser.add_argument ('--atmQuantity'  , help='Quantity if atm provides quantities (m/s), Surfacic if atm provided flux (m/s/m2)'  , type=str, default='Quantity', choices=['Quantity', 'Surfacic'] )
-parser.add_argument ('--oceQuantity'  , help='Quantity if oce requires quantities (ks/s), Surfacic if oce requires flux (m/s/m2)' , type=str, default='Surfacic', choices=['Quantity', 'Surfacic'] )
+parser.add_argument ('--atmQuantity'  , help='Quantity if atm provides quantities (m/s), Surfacic if atm provided flux (m/s/m2)' , type=str,
+                         default='Quantity', choices=['Quantity', 'Surfacic'] )
+parser.add_argument ('--oceQuantity'  , help='Quantity if oce requires quantities (ks/s), Surfacic if oce requires flux (m/s/m2)', type=str,
+                         default='Surfacic', choices=['Quantity', 'Surfacic'] )
 parser.add_argument ('--searchRadius' , help='max distance to connect a land point to an ocean point (in km)', type=float, default=600.0 )
 parser.add_argument ('--grids' , help='grids file name', default='grids.nc' )
@@ -67,5 +69,6 @@
 parser.add_argument ('--o2a'   , help='o2a file name'  , default='o2a.nc'   )
 parser.add_argument ('--output', help='output rmp file name', default='rmp_tlmd_to_torc_runoff.nc' )
-parser.add_argument ('--fmt'   , help='NetCDF file format, using nco syntax', default='netcdf4', choices=['classic', 'netcdf3', '64bit', '64bit_data', '64bit_data', 'netcdf4', 'netcdf4_classsic'] )
+parser.add_argument ('--fmt'   , help='NetCDF file format, using nco syntax', default='netcdf4',
+                         choices=['classic', 'netcdf3', '64bit', '64bit_data', '64bit_data', 'netcdf4', 'netcdf4_classsic'] )
 parser.add_argument ('--ocePerio'   , help='periodicity of ocean grid', type=int, default=0 )
 
@@ -104,15 +107,15 @@
 
 # Ocean grid periodicity
-oce_perio=myargs.ocePerio
+oce_perio = myargs.ocePerio
 
 ### Read coordinates of all models
 ###
 
-diaFile    = netCDF4.Dataset ( o2a   )
-gridFile   = netCDF4.Dataset ( grids )
-areaFile   = netCDF4.Dataset ( areas )
-maskFile   = netCDF4.Dataset ( masks )
-
-o2aFrac             = diaFile ['OceFrac'][:].squeeze()
+diaFile    = xr.open_dataset ( o2a   )
+gridFile   = xr.open_dataset ( grids )
+areaFile   = xr.open_dataset ( areas )
+maskFile   = xr.open_dataset ( masks )
+
+o2aFrac             = diaFile ['OceFrac'].squeeze()
 o2aFrac = np.where ( np.abs(o2aFrac) < 1E10, o2aFrac, 0.0)
 
@@ -121,11 +124,27 @@
 atm_grid_rank = len(gridFile['t'+atm_n+'.lat'][:].shape)
 
-atm_grid_center_lat = gridFile['t'+atm_n+'.lat'][:].ravel()
-atm_grid_center_lon = gridFile['t'+atm_n+'.lon'][:].ravel()
-atm_grid_corner_lat = np.reshape ( gridFile['t'+atm_n+'.cla'][:], (atm_nvertex, atm_grid_size) )
-atm_grid_corner_lon = np.reshape ( gridFile['t'+atm_n+'.clo'][:], (atm_nvertex, atm_grid_size) )
-atm_grid_area       = areaFile['t'+atm_n+'.srf'][:].ravel()
-atm_grid_imask      = 1-maskFile['t'+atm_n+'.msk'][:].squeeze().ravel()
+atm_grid_center_lat = gridFile['t'+atm_n+'.lat'].squeeze()
+atm_grid_center_lon = gridFile['t'+atm_n+'.lon'].squeeze()
+atm_grid_corner_lat = gridFile['t'+atm_n+'.cla'].squeeze()
+atm_grid_corner_lon = gridFile['t'+atm_n+'.clo'].squeeze()
+atm_grid_area       = areaFile['t'+atm_n+'.srf'].squeeze()
+atm_grid_imask      = 1-maskFile['t'+atm_n+'.msk'][:].squeeze()
 atm_grid_dims       = gridFile['t'+atm_n+'.lat'][:].shape
+
+if atmDomainType == 'unstructured' :
+    atm_grid_center_lat = atm_grid_center_lat.rename ({'ycell':'cell'})
+    atm_grid_center_lon = atm_grid_center_lon.rename ({'ycell':'cell'})
+    atm_grid_corner_lat = atm_grid_corner_lat.rename ({'ycell':'cell'})
+    atm_grid_corner_lon = atm_grid_corner_lon.rename ({'ycell':'cell'})
+    atm_grid_area       = atm_grid_area.rename  ({'ycell':'cell'})
+    atm_grid_imask      = atm_grid_imask.rename ({'ycell':'cell'})
+    
+if atmDomainType == 'rectilinear' :
+    atm_grid_center_lat = atm_grid_center_lat.stack (cell=['y', 'x'])
+    atm_grid_center_lon = atm_grid_center_lon.stack (cell=['y', 'x'])
+    atm_grid_corner_lat = atm_grid_corner_lat.stack (cell=['y', 'x']).rename({'nvertex_lmd':'nvertex'})
+    atm_grid_corner_lon = atm_grid_corner_lon.stack (cell=['y', 'x']).rename({'nvertex_lmd':'nvertex'})
+    atm_grid_area       = atm_grid_area.stack       (cell=['y', 'x'])
+    atm_grid_imask      = atm_grid_imask.stack      (cell=['y', 'x'])
 
 atm_perio = 0
@@ -137,28 +156,31 @@
 oce_grid_rank = len(gridFile['torc.lat'][:].shape)
 
-oce_grid_center_lat = gridFile['torc.lat'][:].ravel()
-oce_grid_center_lon = gridFile['torc.lon'][:].ravel()
-oce_grid_corner_lat = np.reshape( gridFile['torc.cla'][:], (oce_nvertex, oce_grid_size) )
-oce_grid_corner_lon = np.reshape( gridFile['torc.clo'][:], (oce_nvertex, oce_grid_size) )
-oce_grid_area       = areaFile['torc.srf'][:].ravel()
-oce_grid_imask      = 1-maskFile['torc.msk'][:].ravel()
+oce_grid_center_lat = gridFile['torc.lat'].stack(oce_grid_size=['y_grid_T', 'x_grid_T'])
+oce_grid_center_lon = gridFile['torc.lon'].stack(oce_grid_size=['y_grid_T', 'x_grid_T'])
+oce_grid_corner_lat = gridFile['torc.cla'].squeeze().stack(oce_grid_size=['y_grid_T', 'x_grid_T'])
+oce_grid_corner_lon = gridFile['torc.clo'].squeeze().stack(oce_grid_size=['y_grid_T', 'x_grid_T'])
+oce_grid_area       = areaFile['torc.srf'].stack(oce_grid_size=['y_grid_T', 'x_grid_T'])
+oce_grid_imask      = 1-maskFile['torc.msk'].stack(oce_grid_size=['y_grid_T', 'x_grid_T'])
 oce_grid_dims       = gridFile['torc.lat'][:].shape
+
 if oce_perio == 0 :
     if oce_jpi ==  182 : oce_perio = 4 # ORCA 2
     if oce_jpi ==  362 : oce_perio = 6 # ORCA 1
     if oce_jpi == 1442 : oce_perio = 6 # ORCA 025
+        
 print ("Oce NPERIO parameter : {:d}".format(oce_perio))
-oce_grid_pmask = nemo.lbc_mask (np.reshape(oce_grid_imask, (oce_jpj,oce_jpi)), nperio=oce_perio, cd_type='T', sval=0).ravel()
+oce_grid_pmask = nemo.lbc_mask (np.reshape(oce_grid_imask.values, (oce_jpj,oce_jpi)), nperio=oce_perio, cd_type='T', sval=0).ravel()
 oce_address = np.arange(oce_jpj*oce_jpi)
 
 print ("Fill closed sea with image processing library")
 oce_grid_imask2D = np.reshape(oce_grid_pmask,(oce_jpj,oce_jpi))
-oce_grid_imask2D = nemo.lbc_mask ( 1-ndimage.binary_fill_holes (1-nemo.lbc(oce_grid_imask2D, nperio=oce_perio, cd_type='T')), nperio=oce_perio, cd_type='T', sval=0 )
+oce_grid_imask2D = nemo.lbc_mask ( 1-ndimage.binary_fill_holes (1-nemo.lbc(oce_grid_imask2D, nperio=oce_perio, cd_type='T')),
+                                       nperio=oce_perio, cd_type='T', sval=0 )
 oce_grid_imask = oce_grid_imask2D.ravel()
 ## 
 print ("Computes an ocean coastal band")
 
-oceLand2D  = np.reshape ( np.where (oce_grid_pmask[:] < 0.5, True, False), (oce_jpj, oce_jpi) )
-oceOcean2D = np.reshape ( np.where (oce_grid_pmask[:] > 0.5, True, False), (oce_jpj, oce_jpi) )
+oceLand2D  = np.reshape ( np.where (oce_grid_pmask < 0.5, True, False), (oce_jpj, oce_jpi) )
+oceOcean2D = np.reshape ( np.where (oce_grid_pmask > 0.5, True, False), (oce_jpj, oce_jpi) )
 
 NNocean = 1+2*oceCoastWidth
@@ -168,5 +190,5 @@
 
 oceOceanFiltered = oceOceanFiltered2D.ravel()
-oceLand  = oceLand2D.ravel()
+oceLand  = oceLand2D.ravel ()
 oceOcean = oceOcean2D.ravel()
 oceCoast = oceCoast2D.ravel()
@@ -232,10 +254,11 @@
         num_links = int(z_mask.sum())
         if num_links == 0 : continue
-        z_area = oceCoast_grid_area[z_mask].sum()
+        z_area = oceCoast_grid_area[z_mask].sum().values
         poids = np.ones ((num_links),dtype=np.float64) / z_area
         if myargs.atmQuantity == 'Surfacic' : poids = poids * atm_grid_area[ja]
         if myargs.oceQuantity == 'Quantity' : poids = poids * oceCoast_grid_area[z_mask]
         if  ja % (len(atmCoast_grid_pmask)//50) == 0 : # Control print
-            print ( 'ja:{:8d}, num_links:{:8d},  z_area:{:8.4e},  atm area:{:8.4e},  weights sum:{:8.4e}  '.format(ja, num_links, z_area, atm_grid_area[ja], poids.sum() ) )
+            print ( 'ja:{:8d}, num_links:{:8d},  z_area:{:8.4e},  atm area:{:8.4e},  weights sum:{:8.4e}  '
+                        .format(ja, num_links, z_area, atm_grid_area[ja].values, poids.sum() ) )
         #
         matrix_local = poids
@@ -254,180 +277,173 @@
 print ("Write output file")
 runoff = myargs.output
-f_runoff = netCDF4.Dataset ( runoff, 'w', format=FmtNetcdf )
 print ('Output file: ' + runoff )
 
-f_runoff.Conventions     = "CF-1.6"
-f_runoff.source          = "IPSL Earth system model"
-f_runoff.group           = "ICMC IPSL Climate Modelling Center"
-f_runoff.Institution     = "IPSL https.//www.ipsl.fr"
-f_runoff.Ocean           = oce_Name + " https://www.nemo-ocean.eu"
-f_runoff.Atmosphere      = atm_Name + " http://lmdz.lmd.jussieu.fr"
-f_runoff.associatedFiles = grids + " " + areas + " " + masks
-f_runoff.directory       = os.getcwd ()
-f_runoff.description     = "Generated with RunoffWeights.py"
-f_runoff.title           = runoff
-f_runoff.Program         = "Generated by " + sys.argv[0] + " with flags " + str(sys.argv[1:])
-f_runoff.atmCoastWidth   = "{:d} grid points".format(atmCoastWidth)
-f_runoff.oceCoastWidth   = "{:d} grid points".format(oceCoastWidth)
-f_runoff.searchRadius    = "{:.0f} km".format(searchRadius/1000.)
-f_runoff.atmQuantity     = myargs.atmQuantity
-f_runoff.oceQuantity     = myargs.oceQuantity
-f_runoff.gridsFile       = grids
-f_runoff.areasFile       = areas
-f_runoff.masksFile       = masks
-f_runoff.o2aFile         = o2a
-f_runoff.timeStamp       = time.asctime()
-f_runoff.HOSTNAME        = platform.node()
-#f_runoff.LOGNAME         = os.getlogin()
-f_runoff.Python          = "Python version " +  platform.python_version()
-f_runoff.OS              = platform.system()
-f_runoff.release         = platform.release()
-f_runoff.hardware        = platform.machine()
-f_runoff.conventions     = "SCRIP"
-f_runoff.source_grid     = "curvilinear"
-f_runoff.dest_grid       = "curvilinear"
-f_runoff.Model           = "IPSL CM6"
-f_runoff.SVN_Author      = "$Author$"
-f_runoff.SVN_Date        = "$Date$"
-f_runoff.SVN_Revision    = "$Revision$"
-f_runoff.SVN_Id          = "$Id$"
-f_runoff.SVN_HeadURL     = "$HeadURL$"
-
-d_num_links = f_runoff.createDimension ('num_links'       , num_links )
-d_num_wgts  = f_runoff.createDimension ('num_wgts'        ,         1 )
-
-d_atm_grid_size    = f_runoff.createDimension ('src_grid_size'   , atm_grid_size )
-d_atm_grid_corners = f_runoff.createDimension ('src_grid_corners', atm_grid_corner_lon.shape[0]  )
-d_atm_grid_rank    = f_runoff.createDimension ('src_grid_rank'   , atm_grid_rank  )
-
-d_oce_grid_size    = f_runoff.createDimension ('dst_grid_size'   , oce_grid_size )
-d_oce_grid_corners = f_runoff.createDimension ('dst_grid_corners', oce_grid_corner_lon.shape[0] )
-d_oce_grid_rank    = f_runoff.createDimension ('dst_grid_rank'   , oce_grid_rank  )
-
-v_remap_matrix = f_runoff.createVariable ( 'remap_matrix', 'f8', ('num_links', 'num_wgts') )
-
-v_atm_address  = f_runoff.createVariable ( 'src_address' , 'i4', ('num_links',) )
-v_atm_address.convention = "Fortran style addressing, starting at 1"
-v_oce_address  = f_runoff.createVariable ( 'dst_address' , 'i4', ('num_links',) )
-v_oce_address.convention = "Fortran style addressing, starting at 1"
-
-v_remap_matrix[:] = remap_matrix
-v_atm_address [:] = atm_address + 1 # OASIS uses Fortran style indexing, starting at one
-v_oce_address [:] = oce_address + 1
-
-v_atm_grid_dims       = f_runoff.createVariable ( 'src_grid_dims'      , 'i4', ('src_grid_rank',) )
-v_atm_grid_center_lon = f_runoff.createVariable ( 'src_grid_center_lon', 'i4', ('src_grid_size',) )
-v_atm_grid_center_lat = f_runoff.createVariable ( 'src_grid_center_lat', 'i4', ('src_grid_size',) )
-v_atm_grid_center_lon.units='degrees_east'  ; v_atm_grid_center_lon.long_name='Longitude' ; v_atm_grid_center_lon.long_name='longitude' ; v_atm_grid_center_lon.bounds="src_grid_corner_lon"
-v_atm_grid_center_lat.units='degrees_north' ; v_atm_grid_center_lat.long_name='Latitude'  ; v_atm_grid_center_lat.long_name='latitude ' ; v_atm_grid_center_lat.bounds="src_grid_corner_lat"
-v_atm_grid_corner_lon = f_runoff.createVariable ( 'src_grid_corner_lon', 'f8', ('src_grid_size', 'src_grid_corners')  )
-v_atm_grid_corner_lat = f_runoff.createVariable ( 'src_grid_corner_lat', 'f8', ('src_grid_size', 'src_grid_corners')  )
-v_atm_grid_corner_lon.units="degrees_east"
-v_atm_grid_corner_lat.units="degrees_north"
-v_atm_grid_area       = f_runoff.createVariable ( 'src_grid_area'      , 'f8', ('src_grid_size',)  )
-v_atm_grid_area.long_name="Grid area" ; v_atm_grid_area.standard_name="cell_area" ; v_atm_grid_area.units="m2"
-v_atm_grid_imask      = f_runoff.createVariable ( 'src_grid_imask'     , 'i4', ('src_grid_size',)  )
-v_atm_grid_imask.long_name="Land-sea mask" ; v_atm_grid_imask.units="Land:1, Ocean:0"
-v_atm_grid_pmask      = f_runoff.createVariable ( 'src_grid_pmask'     , 'i4', ('src_grid_size',)  )
-v_atm_grid_pmask.long_name="Land-sea mask (periodicity removed)" ; v_atm_grid_pmask.units="Land:1, Ocean:0"
-
-v_atm_grid_dims      [:] = atm_grid_dims
-v_atm_grid_center_lon[:] = atm_grid_center_lon[:]
-v_atm_grid_center_lat[:] = atm_grid_center_lat[:]
-v_atm_grid_corner_lon[:] = np.transpose(atm_grid_corner_lon)
-v_atm_grid_corner_lat[:] = np.transpose(atm_grid_corner_lat)
-v_atm_grid_area      [:] = atm_grid_area[:]
-v_atm_grid_imask     [:] = atm_grid_imask[:]
-v_atm_grid_pmask     [:] = atm_grid_pmask[:]
+
+remap_matrix = xr.DataArray ( np.reshape(remap_matrix, (num_links, 1)), dims = ['num_links', 'num_wgts'] )
+
+# OASIS uses Fortran style indexing, starting at one
+src_address  = xr.DataArray ( atm_address.astype(np.int32)+1, dims = ['num_links'],
+                                 attrs={"convention": "Fortran style addressing, starting at 1"}) 
+dst_address  = xr.DataArray ( oce_address.astype(np.int32)+1, dims = ['num_links'],
+                                 attrs={"convention": "Fortran style addressing, starting at 1"})
+
+src_grid_dims       = xr.DataArray (np.array(atm_grid_dims, dtype=np.int32), dims = ['src_grid_rank',] )
+src_grid_center_lon = xr.DataArray (atm_grid_center_lon.values , dims = ['src_grid_size',] )
+src_grid_center_lat = xr.DataArray (atm_grid_center_lat.values , dims = ['src_grid_size',] )
+
+src_grid_center_lon.attrs['units']='degrees_east'  ; src_grid_center_lon.attrs['long_name']='Longitude'
+src_grid_center_lon.attrs['long_name']='longitude' ; src_grid_center_lon.attrs['bounds']="src_grid_corner_lon"
+src_grid_center_lat.attrs['units']='degrees_north' ; src_grid_center_lat.attrs['long_name']='Latitude'
+src_grid_center_lat.attrs['long_name']='latitude ' ; src_grid_center_lat.attrs['bounds']="src_grid_corner_lat"
+ 
+src_grid_corner_lon = xr.DataArray (atm_grid_corner_lon.values.transpose(), dims = [ 'src_grid_size', 'src_grid_corners'] )
+src_grid_corner_lat = xr.DataArray (atm_grid_corner_lat.values.transpose(), dims = [ 'src_grid_size', 'src_grid_corners'] )
+src_grid_corner_lon.attrs['units']="degrees_east"
+src_grid_corner_lat.attrs['units']="degrees_north"
+
+src_grid_area       =  xr.DataArray (atm_grid_area.values, dims = ['src_grid_size',] ) 
+src_grid_area.attrs['long_name']="Grid area" ; src_grid_area.attrs['standard_name']="cell_area" ; src_grid_area.attrs['units']="m2"
+
+src_grid_imask      =  xr.DataArray (atm_grid_imask.values, dims = ['src_grid_size',] ) 
+src_grid_imask.attrs['long_name']="Land-sea mask" ; src_grid_imask.attrs['units']="Land:1, Ocean:0"
+
+src_grid_pmask      =  xr.DataArray (atm_grid_pmask.values, dims = ['src_grid_size',] ) 
+src_grid_pmask.attrs['long_name']="Land-sea mask (periodicity removed)" ; src_grid_pmask.attrs['units']="Land:1, Ocean:0"
 
 # --
-
-v_oce_grid_dims       = f_runoff.createVariable ( 'dst_grid_dims'      , 'i4', ('dst_grid_rank',) )
-v_oce_grid_center_lon = f_runoff.createVariable ( 'dst_grid_center_lon', 'i4', ('dst_grid_size',) )
-v_oce_grid_center_lat = f_runoff.createVariable ( 'dst_grid_center_lat', 'i4', ('dst_grid_size',) )
-v_oce_grid_center_lon.units='degrees_east'  ; v_oce_grid_center_lon.long_name='Longitude' ; v_oce_grid_center_lon.long_name='longitude' ; v_oce_grid_center_lon.bounds="dst_grid_corner_lon"
-v_oce_grid_center_lat.units='degrees_north' ; v_oce_grid_center_lat.long_name='Latitude'  ; v_oce_grid_center_lat.long_name='latitude'  ; v_oce_grid_center_lat.bounds="dst_grid_corner_lat"
-v_oce_grid_corner_lon = f_runoff.createVariable ( 'dst_grid_corner_lon', 'f8', ('dst_grid_size', 'dst_grid_corners')  )
-v_oce_grid_corner_lat = f_runoff.createVariable ( 'dst_grid_corner_lat', 'f8', ('dst_grid_size', 'dst_grid_corners')  )
-v_oce_grid_corner_lon.units="degrees_east"
-v_oce_grid_corner_lat.units="degrees_north"
-v_oce_grid_area       = f_runoff.createVariable ( 'dst_grid_area'  , 'f8', ('dst_grid_size',) )
-v_oce_grid_area.long_name="Grid area" ; v_oce_grid_area.standard_name="cell_area" ; v_oce_grid_area.units="m2"
-v_oce_grid_imask      = f_runoff.createVariable ( 'dst_grid_imask'     , 'i4', ('dst_grid_size',)  )
-v_oce_grid_imask.long_name="Land-sea mask" ; v_oce_grid_imask.units="Land:1, Ocean:0"
-v_oce_grid_pmask      = f_runoff.createVariable ( 'dst_grid_pmask'     , 'i4', ('dst_grid_size',)  )
-v_oce_grid_pmask.long_name="Land-sea mask (periodicity removed)" ; v_oce_grid_pmask.units="Land:1, Ocean:0"
-
-v_oce_grid_dims      [:] = oce_grid_dims
-v_oce_grid_center_lon[:] = oce_grid_center_lon[:]
-v_oce_grid_center_lat[:] = oce_grid_center_lat[:]
-v_oce_grid_corner_lon[:] = np.transpose(oce_grid_corner_lon)
-v_oce_grid_corner_lat[:] = np.transpose(oce_grid_corner_lat)
-v_oce_grid_area      [:] = oce_grid_area[:]
-v_oce_grid_imask     [:] = oce_grid_imask[:]
-v_oce_grid_pmask     [:] = oce_grid_pmask[:]
-
-v_atm_lon_addressed   = f_runoff.createVariable ( 'src_lon_addressed'  , 'f8', ('num_links',) )
-v_atm_lat_addressed   = f_runoff.createVariable ( 'src_lat_addressed'  , 'f8', ('num_links',) )
-v_atm_area_addressed  = f_runoff.createVariable ( 'src_area_addressed' , 'f8', ('num_links',) )
-v_atm_imask_addressed = f_runoff.createVariable ( 'src_imask_addressed', 'i4', ('num_links',) )
-v_atm_pmask_addressed = f_runoff.createVariable ( 'src_pmask_addressed', 'i4', ('num_links',) )
-
-v_oce_lon_addressed   = f_runoff.createVariable ( 'dst_lon_addressed'  , 'f8', ('num_links',) )
-v_oce_lat_addressed   = f_runoff.createVariable ( 'dst_lat_addressed'  , 'f8', ('num_links',) )
-v_oce_area_addressed  = f_runoff.createVariable ( 'dst_area_addressed' , 'f8', ('num_links',) )
-v_oce_imask_addressed = f_runoff.createVariable ( 'dst_imask_addressed', 'i4', ('num_links',) )
-v_oce_pmask_addressed = f_runoff.createVariable ( 'dst_pmask_addressed', 'i4', ('num_links',) )
-
-v_atm_lon_addressed.long_name="Longitude" ; v_atm_lon_addressed.standard_name="longitude" ; v_atm_lon_addressed.units="degrees_east"
-v_atm_lat_addressed.long_name="Latitude"  ; v_atm_lat_addressed.standard_name="latitude"  ; v_atm_lat_addressed.units="degrees_north"
-v_atm_lon_addressed  [:] = atm_grid_center_lon[atm_address]
-v_atm_lat_addressed  [:] = atm_grid_center_lat[atm_address]
-v_atm_area_addressed [:] = atm_grid_area[atm_address]
-v_atm_imask_addressed[:] = 1-atm_grid_imask[atm_address]
-v_atm_pmask_addressed[:] = 1-atm_grid_pmask[atm_address]
-
-v_oce_lon_addressed.long_name="Longitude" ; v_oce_lon_addressed.standard_name="longitude" ; v_oce_lon_addressed.units="degrees_east"
-v_oce_lat_addressed.long_name="Latitude"  ; v_oce_lat_addressed.standard_name="latitude"  ; v_oce_lat_addressed.units="degrees_north"
-v_oce_lon_addressed  [:] = oce_grid_center_lon[oce_address]
-v_oce_lat_addressed  [:] = oce_grid_center_lat[oce_address]#.ravel()
-v_oce_area_addressed [:] = oce_grid_area[oce_address]
-v_oce_imask_addressed[:] = 1-oce_grid_imask[oce_address]
-v_oce_pmask_addressed[:] = 1-oce_grid_pmask[oce_address]
+dst_grid_dims       = xr.DataArray (np.array(oce_grid_dims, dtype=np.int32), dims = ['dst_grid_rank',] )
+dst_grid_center_lon = xr.DataArray (oce_grid_center_lon.values, dims = ['dst_grid_size',] )
+dst_grid_center_lat = xr.DataArray (oce_grid_center_lat.values, dims = ['dst_grid_size',] )
+
+dst_grid_center_lon.attrs['units']='degrees_east'  ; dst_grid_center_lon.attrs['long_name']='Longitude'
+dst_grid_center_lon.attrs['long_name']='longitude' ; dst_grid_center_lon.attrs['bounds']="dst_grid_corner_lon"
+dst_grid_center_lat.attrs['units']='degrees_north' ; dst_grid_center_lat.attrs['long_name']='Latitude'
+dst_grid_center_lat.attrs['long_name']='latitude ' ; dst_grid_center_lat.attrs['bounds']="dst_grid_corner_lat"
+
+dst_grid_corner_lon = xr.DataArray (np.transpose(oce_grid_corner_lon.values), dims = [ 'dst_grid_size', 'dst_grid_corners'] )
+dst_grid_corner_lat = xr.DataArray (np.transpose(oce_grid_corner_lat.values), dims = [ 'dst_grid_size', 'dst_grid_corners'] )
+dst_grid_corner_lon.attrs['units']="degrees_east"
+dst_grid_corner_lat.attrs['units']="degrees_north"
+
+dst_grid_area       =  xr.DataArray (oce_grid_area.values, dims = ['dst_grid_size',] ) 
+dst_grid_area.attrs['long_name']="Grid area" ; dst_grid_area.attrs['standard_name']="cell_area" ; dst_grid_area.attrs['units']="m2"
+
+dst_grid_imask      =  xr.DataArray (oce_grid_imask.astype(np.int32), dims = ['dst_grid_size',] ) 
+dst_grid_imask.attrs['long_name']="Land-sea mask" ; dst_grid_imask.attrs['units']="Land:1, Ocean:0"
+
+dst_grid_pmask      =  xr.DataArray (oce_grid_pmask, dims = ['dst_grid_size',] ) 
+dst_grid_pmask.attrs['long_name']="Land-sea mask (periodicity removed)" ; dst_grid_pmask.attrs['units']="Land:1, Ocean:0"
+
+src_lon_addressed   =  xr.DataArray (atm_grid_center_lon.values[atm_address]                  , dims = ['num_links'] )
+src_lat_addressed   =  xr.DataArray (atm_grid_center_lat.values[atm_address]                  , dims = ['num_links'] )
+src_area_addressed  =  xr.DataArray (atm_grid_area      .values[atm_address]                  , dims = ['num_links'] )
+src_imask_addressed =  xr.DataArray (1-atm_grid_imask   .values[atm_address].astype(np.int32) , dims = ['num_links'] )
+src_pmask_addressed =  xr.DataArray (1-atm_grid_pmask   .values[atm_address].astype(np.int32) , dims = ['num_links'] )
+
+dst_lon_addressed   =  xr.DataArray (oce_grid_center_lon.values[atm_address], dims = ['num_links'] )
+dst_lat_addressed   =  xr.DataArray (oce_grid_center_lat.values[oce_address], dims = ['num_links'] )
+dst_area_addressed  =  xr.DataArray (oce_grid_area.values[oce_address].astype(np.int32)      , dims = ['num_links'] )
+dst_imask_addressed =  xr.DataArray (1-oce_grid_imask[oce_address].astype(np.int32)   , dims = ['num_links'] )
+dst_pmask_addressed =  xr.DataArray (1-oce_grid_pmask[oce_address].astype(np.int32)   , dims = ['num_links'] )
+
+src_lon_addressed.attrs['long_name']="Longitude" ; src_lon_addressed.attrs['standard_name']="longitude" ; src_lon_addressed.attrs['units']="degrees_east"
+src_lat_addressed.attrs['long_name']="Latitude"  ; src_lat_addressed.attrs['standard_name']="latitude"  ; src_lat_addressed.attrs['units']="degrees_north"
+
+dst_lon_addressed.attrs['long_name']="Longitude" ; dst_lon_addressed.attrs['standard_name']="longitude" ; dst_lon_addressed.attrs['units']="degrees_east"
+dst_lat_addressed.attrs['long_name']="Latitude"  ; dst_lat_addressed.attrs['standard_name']="latitude"  ; dst_lat_addressed.attrs['units']="degrees_north"
 
 if atmDomainType == 'rectilinear' :
-    v_atmLand         = f_runoff.createVariable ( 'atmLand'        , 'i4', ('src_grid_size',) )
-    v_atmLandFiltered = f_runoff.createVariable ( 'atmLandFiltered', 'f4', ('src_grid_size',) )
-    v_atmLandFrac     = f_runoff.createVariable ( 'atmLandFrac'    , 'i4', ('src_grid_size',) )
-    v_atmFrac         = f_runoff.createVariable ( 'atmFrac'        , 'i4', ('src_grid_size',) )
-    v_atmOcean        = f_runoff.createVariable ( 'atmOcean'       , 'i4', ('src_grid_size',) )
-    v_atmOceanFrac    = f_runoff.createVariable ( 'atmOceanFrac'   , 'i4', ('src_grid_size',) )
-    
-    v_atmLand[:]         = atmLand.ravel()
-    v_atmLandFrac[:]     = atmLandFrac.ravel()
-    v_atmLandFiltered[:] = atmLandFiltered.ravel()
-    v_atmFrac[:]         = atmFrac.ravel()
-    v_atmOcean[:]        = atmOcean.ravel()
-    v_atmOceanFrac[:]    = atmOceanFrac.ravel()
-
-v_atmCoast         = f_runoff.createVariable ( 'atmCoast'        , 'i4', ('src_grid_size',) ) 
-v_atmCoast[:]      = atmCoast
-
-v_oceLand          = f_runoff.createVariable ( 'oceLand'         , 'i4', ('dst_grid_size',) )
-v_oceOcean         = f_runoff.createVariable ( 'oceOcean'        , 'i4', ('dst_grid_size',) )
-v_oceOceanFiltered = f_runoff.createVariable ( 'oceOceanFiltered', 'f4', ('dst_grid_size',) )
-v_oceCoast         = f_runoff.createVariable ( 'oceCoast'        , 'i4', ('dst_grid_size',) )
- 
-v_oceLand[:]          = oceLand
-v_oceOcean[:]         = oceOcean
-v_oceOceanFiltered[:] = oceOceanFiltered
-v_oceCoast[:]         = oceCoast
-
-f_runoff.sync ()
-
-## 
+    atmLand         = xr.DataArray ( atmLand.ravel()     , dims = ['src_grid_size',] )
+    atmLandFiltered = xr.DataArray ( atmLandFrac.ravel() , dims = ['src_grid_size',] )
+    atmLandFrac     = xr.DataArray ( atmFrac.ravel()     , dims = ['src_grid_size',] )
+    atmFrac         = xr.DataArray ( atmFrac.ravel()     , dims = ['src_grid_size',] )
+    atmOcean        = xr.DataArray ( atmOcean.ravel()    , dims = ['src_grid_size',] )
+    atmOceanFrac    = xr.DataArray ( atmOceanFrac.ravel(), dims = ['src_grid_size',] )
+
+atmCoast         = xr.DataArray (atmCoast.astype(np.int32)          , dims = ['src_grid_size',])
+oceLand          = xr.DataArray (oceLand.astype(np.int32)           , dims = ['dst_grid_size',])
+oceOcean         = xr.DataArray (oceOcean.astype(np.int32)          , dims = ['dst_grid_size',])
+oceOceanFiltered = xr.DataArray (oceOceanFiltered.astype(np.float32), dims = ['dst_grid_size',])
+oceCoast         = xr.DataArray (oceCoast.astype(np.int32)          , dims = ['dst_grid_size',])
+
+
+f_runoff = xr.Dataset ( {
+	'src_address'         : src_address,
+	'dst_address'         : dst_address,
+	'src_grid_dims'       : src_grid_dims,
+	'src_grid_center_lon' : src_grid_center_lon,
+	'src_grid_center_lat' : src_grid_center_lat,
+    'src_grid_corner_lon' : src_grid_corner_lon,
+    'src_grid_corner_lat' : src_grid_corner_lat,
+	'src_grid_area'       : src_grid_area,
+	'src_grid_area'       : src_grid_area,
+	'src_grid_pmask'      : src_grid_pmask,
+	'dst_grid_dims'       : dst_grid_dims,
+	'dst_grid_center_lon' : dst_grid_center_lon,
+	'st_grid_center_lat'  : dst_grid_center_lat,
+	'dst_grid_corner_lon' : dst_grid_corner_lon,
+	'dst_grid_corner_lat' : dst_grid_corner_lat,
+	'dst_grid_area'       : dst_grid_area,
+	'dst_grid_imask'      : dst_grid_imask,
+	'dst_grid_pmask'      : dst_grid_pmask,
+	'src_lon_addressed'   : src_lon_addressed,
+	'src_lat_addressed'   : src_lat_addressed,
+	'src_area_addressed'  : src_area_addressed,
+	'dst_lon_addressed'   : dst_lon_addressed,
+	'dst_lat_addressed'   : dst_lat_addressed,
+	'dst_area_addressed'  : dst_area_addressed,
+	'dst_imask_addressed' : dst_imask_addressed,
+	'dst_pmask_addressed' : dst_pmask_addressed,
+	'atmCoast'            : atmCoast,
+	'oceLand'             : oceLand,
+	'oceOcean'            : oceOcean,
+	'oceOceanFiltered'    : oceOceanFiltered,
+	'oceCoast'            : oceCoast
+    } )
+
+f_runoff.attrs['Conventions']     = "CF-1.6"
+f_runoff.attrs['source']          = "IPSL Earth system model"
+f_runoff.attrs['group']           = "ICMC IPSL Climate Modelling Center"
+f_runoff.attrs['Institution']     = "IPSL https.//www.ipsl.fr"
+f_runoff.attrs['Ocean']           = oce_Name + " https://www.nemo-ocean.eu"
+f_runoff.attrs['Atmosphere']      = atm_Name + " http://lmdz.lmd.jussieu.fr"
+f_runoff.attrs['associatedFiles'] = grids + " " + areas + " " + masks
+f_runoff.attrs['directory']       = os.getcwd ()
+f_runoff.attrs['description']     = "Generated with RunoffWeights.py"
+f_runoff.attrs['title']           = runoff
+args = ''
+for i in np.arange(1,len(sys.argv[1:])) : args += sys.argv[i] + ' '
+f_runoff.attrs['Program']         = "Generated by " + sys.argv[0] + " with flags " + args
+f_runoff.attrs['atmCoastWidth']   = "{:d} grid points".format(atmCoastWidth)
+f_runoff.attrs['oceCoastWidth']   = "{:d} grid points".format(oceCoastWidth)
+f_runoff.attrs['searchRadius']    = "{:.0f} km".format(searchRadius/1000.)
+f_runoff.attrs['atmQuantity']     = myargs.atmQuantity
+f_runoff.attrs['oceQuantity']     = myargs.oceQuantity
+f_runoff.attrs['gridsFile']       = grids
+f_runoff.attrs['areasFile']       = areas
+f_runoff.attrs['masksFile']       = masks
+f_runoff.attrs['o2aFile']         = o2a
+f_runoff.attrs['timeStamp']       = time.asctime()
+f_runoff.attrs['HOSTNAME']        = platform.node()
+f_runoff.attrs['LOGNAME']         = os.getlogin()
+f_runoff.attrs['Python']          = "Python version " +  platform.python_version()
+f_runoff.attrs['OS']              = platform.system()
+f_runoff.attrs['release']         = platform.release()
+f_runoff.attrs['hardware']        = platform.machine()
+f_runoff.attrs['conventions']     = "SCRIP"
+f_runoff.attrs['source_grid']     = "curvilinear"
+f_runoff.attrs['dest_grid']       = "curvilinear"
+f_runoff.attrs['Model']           = "IPSL CM6"
+f_runoff.attrs['SVN_Author']      = "$Author$"
+f_runoff.attrs['SVN_Date']        = "$Date$"
+f_runoff.attrs['SVN_Revision']    = "$Revision$"
+f_runoff.attrs['SVN_Id']          = "$Id$"
+f_runoff.attrs['SVN_HeadURL']     = "$HeadURL$"
+
+f_runoff.to_netcdf ( runoff, mode='w', format=FmtNetcdf )
 f_runoff.close ()
 
+##
+
 print ('That''s all folks !')
-
 ## ======================================================================================
