source: TOOLS/MOSAIX/RunoffWeights.py @ 6064

Last change on this file since 6064 was 6064, checked in by omamce, 2 years ago

O.M. : changes in MOSAIX

  • Correct ocean mask to remove periodic duplicated points, to have full conservation of run-off
  • Suppress creation of corc mask, which is not used
  • Put SVN keywords in make_mosaic
  • Update nemo.py with somùe additionnal utilities
  • Adapt RunOffWeights?.py to new nemo module
  • Adapt CalvingWeights?.py to new ORCA configurations
  • Property svn:keywords set to Date Revision HeadURL Author Id
File size: 22.3 KB
Line 
1# -*- Mode: python -*-
2### ===========================================================================
3###
4### Compute runoff weights.
5### For LMDZ only. Not suitable for DYNAMICO
6###
7### ===========================================================================
8##
9##  Warning, to install, configure, run, use any of Olivier Marti's
10##  software or to read the associated documentation you'll need at least
11##  one (1) brain in a reasonably working order. Lack of this implement
12##  will void any warranties (either express or implied).
13##  O. Marti assumes no responsability for errors, omissions,
14##  data loss, or any other consequences caused directly or indirectly by
15##  the usage of his software by incorrectly or partially configured
16##  personal.
17##
18# SVN information
19__Author__   = "$Author$"
20__Date__     = "$Date$"
21__Revision__ = "$Revision$"
22__Id__       = "$Id$"
23__HeadURL__  = "$HeadURL$"
24__SVN_Date__ = "$SVN_Date: $"
25##
26
27## Modules
28import netCDF4
29import numpy as np
30import nemo
31from scipy import ndimage
32import sys, os, platform, argparse, textwrap, time
33
34## Useful constants
35zero    = np.dtype('float64').type(0.0)
36zone    = np.dtype('float64').type(1.0)
37epsfrac = np.dtype('float64').type(1.0E-10)
38pi      = np.pi
39rad     = pi/np.dtype('float64').type(180.0)  # Conversion from degrees to radian
40ra      = np.dtype('float64').type(6371229.0) # Earth radius
41
42## Functions
43def geodist (plon1, plat1, plon2, plat2) :
44      """Distance between two points (on sphere)"""
45      zs = np.sin (rad*plat1) * np.sin (rad*plat2) +  np.cos (rad*plat1) * np.cos (rad*plat2) * np.cos(rad*(plon2-plon1))
46      zs = np.maximum (-zone, np.minimum (zone, zs))
47      geodist =  np.arccos (zs)
48      return geodist
49
50### ===== Reading command line parameters ==================================================
51# Creating a parser
52parser = argparse.ArgumentParser (
53    description = """Compute calving weights""",
54    epilog='-------- End of the help message --------')
55
56# Adding arguments
57parser.add_argument ('--oce'          , help='oce model name', type=str, default='eORCA1.2', choices=['ORCA2.3', 'eORCA1.2', 'eORCA025', 'eORCA025.1'] )
58parser.add_argument ('--atm'          , help='atm model name', type=str, default='LMD9695'    )
59parser.add_argument ('--atmCoastWidth', help='width of the coastal band in atmosphere (in grid points)', type=int, default=1 )
60parser.add_argument ('--oceCoastWidth', help='width of the coastal band in ocean (in grid points)'     , type=int, default=2 )
61parser.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'] )
62parser.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'] )
63parser.add_argument ('--searchRadius' , help='max distance to connect a land point to an ocean point (in km)', type=float, default=600.0 )
64parser.add_argument ('--grids' , help='grids file name', default='grids.nc' )
65parser.add_argument ('--areas' , help='masks file name', default='areas.nc' )
66parser.add_argument ('--masks' , help='areas file name', default='masks.nc' )
67parser.add_argument ('--o2a'   , help='o2a file name'  , default='o2a.nc'   )
68parser.add_argument ('--output', help='output rmp file name', default='rmp_tlmd_to_torc_runoff.nc' )
69parser.add_argument ('--fmt'   , help='NetCDF file format, using nco syntax', default='netcdf4', choices=['classic', 'netcdf3', '64bit', '64bit_data', '64bit_data', 'netcdf4', 'netcdf4_classsic'] )
70parser.add_argument ('--ocePerio'   , help='periodicity of ocean grid', type=int, default=0 )
71
72# Parse command line
73myargs = parser.parse_args()
74
75#
76grids = myargs.grids
77areas = myargs.areas
78masks = myargs.masks
79o2a   = myargs.o2a
80
81# Model Names
82atm_Name = myargs.atm
83oce_Name = myargs.oce
84# Width of the coastal band (land points) in the atmopshere
85atmCoastWidth = myargs.atmCoastWidth
86# Width of the coastal band (ocean points) in the ocean
87oceCoastWidth = myargs.oceCoastWidth
88searchRadius  = myargs.searchRadius * 1000.0 # From km to meters
89# Netcdf format
90if myargs.fmt == 'classic'         : FmtNetcdf = 'CLASSIC'
91if myargs.fmt == 'netcdf3'         : FmtNetcdf = 'CLASSIC'
92if myargs.fmt == '64bit'           : FmtNetcdf = 'NETCDF3_64BIT_OFFSET'
93if myargs.fmt == '64bit_data'      : FmtNetcdf = 'NETCDF3_64BIT_DATA'
94if myargs.fmt == '64bit_offset'    : FmtNetcdf = 'NETCDF3_64BIT_OFFSET'
95if myargs.fmt == 'netcdf4'         : FmtNetcdf = 'NETCDF4'
96if myargs.fmt == 'netcdf4_classic' : FmtNetcdf = 'NETCDF4_CLASSIC'
97
98#
99if atm_Name.find('LMD') >= 0 : atm_n = 'lmd' ; atmDomainType = 'rectilinear'
100if atm_Name.find('ICO') >= 0 : atm_n = 'ico' ; atmDomainType = 'unstructured'
101
102print ('atmQuantity : ' + str (myargs.atmQuantity) )
103print ('oceQuantity : ' + str (myargs.oceQuantity) )
104
105# Ocean grid periodicity
106oce_perio=myargs.ocePerio
107
108### Read coordinates of all models
109###
110
111diaFile    = netCDF4.Dataset ( o2a   )
112gridFile   = netCDF4.Dataset ( grids )
113areaFile   = netCDF4.Dataset ( areas )
114maskFile   = netCDF4.Dataset ( masks )
115
116o2aFrac             = diaFile ['OceFrac'][:].squeeze()
117o2aFrac = np.where ( np.abs(o2aFrac) < 1E10, o2aFrac, 0.0)
118
119(atm_nvertex, atm_jpj, atm_jpi) = gridFile['t'+atm_n+'.clo'][:].shape
120atm_grid_size = atm_jpj*atm_jpi
121atm_grid_rank = len(gridFile['t'+atm_n+'.lat'][:].shape)
122
123atm_grid_center_lat = gridFile['t'+atm_n+'.lat'][:].ravel()
124atm_grid_center_lon = gridFile['t'+atm_n+'.lon'][:].ravel()
125atm_grid_corner_lat = np.reshape ( gridFile['t'+atm_n+'.cla'][:], (atm_nvertex, atm_grid_size) )
126atm_grid_corner_lon = np.reshape ( gridFile['t'+atm_n+'.clo'][:], (atm_nvertex, atm_grid_size) )
127atm_grid_area       = areaFile['t'+atm_n+'.srf'][:].ravel()
128atm_grid_imask      = 1-maskFile['t'+atm_n+'.msk'][:].squeeze().ravel()
129atm_grid_dims       = gridFile['t'+atm_n+'.lat'][:].shape
130
131atm_perio = 0
132atm_grid_pmask = atm_grid_imask
133atm_address = np.arange(atm_jpj*atm_jpi)
134
135(oce_nvertex, oce_jpj, oce_jpi) = gridFile['torc.cla'][:].shape ; jpon=oce_jpj*oce_jpj
136oce_grid_size = oce_jpj*oce_jpi
137oce_grid_rank = len(gridFile['torc.lat'][:].shape)
138
139oce_grid_center_lat = gridFile['torc.lat'][:].ravel()
140oce_grid_center_lon = gridFile['torc.lon'][:].ravel()
141oce_grid_corner_lat = np.reshape( gridFile['torc.cla'][:], (oce_nvertex, oce_grid_size) )
142oce_grid_corner_lon = np.reshape( gridFile['torc.clo'][:], (oce_nvertex, oce_grid_size) )
143oce_grid_area       = areaFile['torc.srf'][:].ravel()
144oce_grid_imask      = 1-maskFile['torc.msk'][:].ravel()
145oce_grid_dims       = gridFile['torc.lat'][:].shape
146if oce_perio == 0 :
147    if oce_jpi ==  182 : oce_perio = 4 # ORCA 2
148    if oce_jpi ==  362 : oce_perio = 6 # ORCA 1
149    if oce_jpi == 1442 : oce_perio = 6 # ORCA 025
150print ("Oce NPERIO parameter : {:d}".format(oce_perio))
151oce_grid_pmask = nemo.lbc_mask (np.reshape(oce_grid_imask, (oce_jpj,oce_jpi)), nperio=oce_perio, cd_type='T', sval=0).ravel()
152oce_address = np.arange(oce_jpj*oce_jpi)
153
154print ("Fill closed sea with image processing library")
155oce_grid_imask2D = np.reshape(oce_grid_pmask,(oce_jpj,oce_jpi))
156oce_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 )
157oce_grid_imask = oce_grid_imask2D.ravel()
158##
159print ("Computes an ocean coastal band")
160
161oceLand2D  = np.reshape ( np.where (oce_grid_pmask[:] < 0.5, True, False), (oce_jpj, oce_jpi) )
162oceOcean2D = np.reshape ( np.where (oce_grid_pmask[:] > 0.5, True, False), (oce_jpj, oce_jpi) )
163
164NNocean = 1+2*oceCoastWidth
165oceOceanFiltered2D = ndimage.uniform_filter(oceOcean2D.astype(float), size=NNocean)
166oceCoast2D = np.where (oceOceanFiltered2D<(1.0-0.5/(NNocean**2)),True,False) & oceOcean2D
167oceCoast2D = nemo.lbc_mask (np.reshape(oceCoast2D,(oce_jpj,oce_jpi)), nperio=oce_perio, cd_type='T').ravel()
168
169oceOceanFiltered = oceOceanFiltered2D.ravel()
170oceLand  = oceLand2D.ravel()
171oceOcean = oceOcean2D.ravel()
172oceCoast = oceCoast2D.ravel()
173
174print ('Number of points in oceLand  : {:8d}'.format (oceLand.sum())  )
175print ('Number of points in oceOcean : {:8d}'.format (oceOcean.sum()) )
176print ('Number of points in oceCoast : {:8d}'.format (oceCoast.sum()) )
177
178# Arrays with coastal points only
179oceCoast_grid_center_lon = oce_grid_center_lon[oceCoast]
180oceCoast_grid_center_lat = oce_grid_center_lat[oceCoast]
181oceCoast_grid_area       = oce_grid_area      [oceCoast]
182oceCoast_grid_imask      = oce_grid_imask     [oceCoast]
183oceCoast_grid_pmask      = oce_grid_pmask     [oceCoast]
184oceCoast_address         = oce_address        [oceCoast]
185
186print ("Computes an atmosphere coastal band " )
187atmLand      = np.where (o2aFrac[:] < epsfrac       , True, False)
188atmLandFrac  = np.where (o2aFrac[:] < zone-epsfrac  , True, False)
189atmFrac      = np.where (o2aFrac[:] > epsfrac       , True, False) & np.where (o2aFrac[:] < (zone-epsfrac), True, False)
190atmOcean     = np.where (o2aFrac[:] < (zone-epsfrac), True, False)
191atmOceanFrac = np.where (o2aFrac[:] > epsfrac       , True, False)
192
193## For LMDZ only !!
194if atmDomainType == 'rectilinear' :
195    print ("Extend coastal band " )
196    NNatm = 1+2*atmCoastWidth
197    atmLand2D = np.reshape ( atmLand, ( atm_jpj, atm_jpi) )
198
199    atmLandFiltered2D = ndimage.uniform_filter(atmLand2D.astype(float), size=NNatm)
200    atmCoast2D = np.where (atmLandFiltered2D<(1.0-0.5/(NNatm**2)),True,False) & atmLandFrac
201   
202    atmLandFiltered = atmLandFiltered2D.ravel()
203    atmCoast = atmCoast2D.ravel()
204
205    print ('Number of points in atmLand  : {:8d}'.format (atmLand.sum())  )
206    print ('Number of points in atmOcean : {:8d}'.format (atmOcean.sum()) )
207    print ('Number of points in atmCoast : {:8d}'.format (atmCoast.sum()) )
208
209else :
210    atmCoast = atmFrac
211   
212   
213# Arrays with coastal points only
214atmCoast_grid_center_lon = atm_grid_center_lon[atmCoast]
215atmCoast_grid_center_lat = atm_grid_center_lat[atmCoast]
216atmCoast_grid_area       = atm_grid_area      [atmCoast]
217atmCoast_grid_imask      = atm_grid_imask     [atmCoast]
218atmCoast_grid_pmask      = atm_grid_pmask     [atmCoast]
219atmCoast_address         = atm_address        [atmCoast]
220
221# Initialisations before the loop
222remap_matrix = np.empty ( shape=(0), dtype=np.float64 )
223atm_address  = np.empty ( shape=(0), dtype=np.int32   )
224oce_address  = np.empty ( shape=(0), dtype=np.int32   )
225
226## Loop on atmosphere coastal points
227if searchRadius > 0. :
228    print ("Loop on atmosphere coastal points")
229    for ja in np.arange(len(atmCoast_grid_pmask)) :
230        z_dist = geodist ( atmCoast_grid_center_lon[ja], atmCoast_grid_center_lat[ja], oceCoast_grid_center_lon, oceCoast_grid_center_lat)
231        z_mask = np.where (z_dist*ra < searchRadius, True, False)
232        num_links = int(z_mask.sum())
233        if num_links == 0 : continue
234        z_area = oceCoast_grid_area[z_mask].sum()
235        poids = np.ones ((num_links),dtype=np.float64) / z_area
236        if myargs.atmQuantity == 'Surfacic' : poids = poids * atm_grid_area[ja]
237        if myargs.oceQuantity == 'Quantity' : poids = poids * oceCoast_grid_area[z_mask]
238        if  ja % (len(atmCoast_grid_pmask)//50) == 0 : # Control print
239            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() ) )
240        #
241        matrix_local = poids
242        atm_address_local = np.ones(num_links, dtype=np.int32 ) * atmCoast_address[ja]
243        # Address on destination grid
244        oce_address_local = oceCoast_address[z_mask]
245        # Append to global arrays
246        remap_matrix = np.append ( remap_matrix, matrix_local      )
247        atm_address  = np.append ( atm_address , atm_address_local )
248        oce_address  = np.append ( oce_address , oce_address_local )
249
250    print ('End of loop')
251
252num_links = remap_matrix.shape[0]
253
254print ("Write output file")
255runoff = myargs.output
256f_runoff = netCDF4.Dataset ( runoff, 'w', format=FmtNetcdf )
257print ('Output file: ' + runoff )
258
259f_runoff.Conventions     = "CF-1.6"
260f_runoff.source          = "IPSL Earth system model"
261f_runoff.group           = "ICMC IPSL Climate Modelling Center"
262f_runoff.Institution     = "IPSL https.//www.ipsl.fr"
263f_runoff.Ocean           = oce_Name + " https://www.nemo-ocean.eu"
264f_runoff.Atmosphere      = atm_Name + " http://lmdz.lmd.jussieu.fr"
265f_runoff.associatedFiles = grids + " " + areas + " " + masks
266f_runoff.directory       = os.getcwd ()
267f_runoff.description     = "Generated with RunoffWeights.py"
268f_runoff.title           = runoff
269f_runoff.Program         = "Generated by " + sys.argv[0] + " with flags " + str(sys.argv[1:])
270f_runoff.atmCoastWidth   = "{:d} grid points".format(atmCoastWidth)
271f_runoff.oceCoastWidth   = "{:d} grid points".format(oceCoastWidth)
272f_runoff.searchRadius    = "{:.0f} km".format(searchRadius/1000.)
273f_runoff.atmQuantity     = myargs.atmQuantity
274f_runoff.oceQuantity     = myargs.oceQuantity
275f_runoff.gridsFile       = grids
276f_runoff.areasFile       = areas
277f_runoff.masksFile       = masks
278f_runoff.o2aFile         = o2a
279f_runoff.timeStamp       = time.asctime()
280f_runoff.HOSTNAME        = platform.node()
281#f_runoff.LOGNAME         = os.getlogin()
282f_runoff.Python          = "Python version " +  platform.python_version()
283f_runoff.OS              = platform.system()
284f_runoff.release         = platform.release()
285f_runoff.hardware        = platform.machine()
286f_runoff.conventions     = "SCRIP"
287f_runoff.source_grid     = "curvilinear"
288f_runoff.dest_grid       = "curvilinear"
289f_runoff.Model           = "IPSL CM6"
290f_runoff.SVN_Author      = "$Author$"
291f_runoff.SVN_Date        = "$Date$"
292f_runoff.SVN_Revision    = "$Revision$"
293f_runoff.SVN_Id          = "$Id$"
294f_runoff.SVN_HeadURL     = "$HeadURL$"
295
296d_num_links = f_runoff.createDimension ('num_links'       , num_links )
297d_num_wgts  = f_runoff.createDimension ('num_wgts'        ,         1 )
298
299d_atm_grid_size    = f_runoff.createDimension ('src_grid_size'   , atm_grid_size )
300d_atm_grid_corners = f_runoff.createDimension ('src_grid_corners', atm_grid_corner_lon.shape[0]  )
301d_atm_grid_rank    = f_runoff.createDimension ('src_grid_rank'   , atm_grid_rank  )
302
303d_oce_grid_size    = f_runoff.createDimension ('dst_grid_size'   , oce_grid_size )
304d_oce_grid_corners = f_runoff.createDimension ('dst_grid_corners', oce_grid_corner_lon.shape[0] )
305d_oce_grid_rank    = f_runoff.createDimension ('dst_grid_rank'   , oce_grid_rank  )
306
307v_remap_matrix = f_runoff.createVariable ( 'remap_matrix', 'f8', ('num_links', 'num_wgts') )
308
309v_atm_address  = f_runoff.createVariable ( 'src_address' , 'i4', ('num_links',) )
310v_atm_address.convention = "Fortran style addressing, starting at 1"
311v_oce_address  = f_runoff.createVariable ( 'dst_address' , 'i4', ('num_links',) )
312v_oce_address.convention = "Fortran style addressing, starting at 1"
313
314v_remap_matrix[:] = remap_matrix
315v_atm_address [:] = atm_address + 1 # OASIS uses Fortran style indexing, starting at one
316v_oce_address [:] = oce_address + 1
317
318v_atm_grid_dims       = f_runoff.createVariable ( 'src_grid_dims'      , 'i4', ('src_grid_rank',) )
319v_atm_grid_center_lon = f_runoff.createVariable ( 'src_grid_center_lon', 'i4', ('src_grid_size',) )
320v_atm_grid_center_lat = f_runoff.createVariable ( 'src_grid_center_lat', 'i4', ('src_grid_size',) )
321v_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"
322v_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"
323v_atm_grid_corner_lon = f_runoff.createVariable ( 'src_grid_corner_lon', 'f8', ('src_grid_size', 'src_grid_corners')  )
324v_atm_grid_corner_lat = f_runoff.createVariable ( 'src_grid_corner_lat', 'f8', ('src_grid_size', 'src_grid_corners')  )
325v_atm_grid_corner_lon.units="degrees_east"
326v_atm_grid_corner_lat.units="degrees_north"
327v_atm_grid_area       = f_runoff.createVariable ( 'src_grid_area'      , 'f8', ('src_grid_size',)  )
328v_atm_grid_area.long_name="Grid area" ; v_atm_grid_area.standard_name="cell_area" ; v_atm_grid_area.units="m2"
329v_atm_grid_imask      = f_runoff.createVariable ( 'src_grid_imask'     , 'i4', ('src_grid_size',)  )
330v_atm_grid_imask.long_name="Land-sea mask" ; v_atm_grid_imask.units="Land:1, Ocean:0"
331v_atm_grid_pmask      = f_runoff.createVariable ( 'src_grid_pmask'     , 'i4', ('src_grid_size',)  )
332v_atm_grid_pmask.long_name="Land-sea mask (periodicity removed)" ; v_atm_grid_pmask.units="Land:1, Ocean:0"
333
334v_atm_grid_dims      [:] = atm_grid_dims
335v_atm_grid_center_lon[:] = atm_grid_center_lon[:]
336v_atm_grid_center_lat[:] = atm_grid_center_lat[:]
337v_atm_grid_corner_lon[:] = np.transpose(atm_grid_corner_lon)
338v_atm_grid_corner_lat[:] = np.transpose(atm_grid_corner_lat)
339v_atm_grid_area      [:] = atm_grid_area[:]
340v_atm_grid_imask     [:] = atm_grid_imask[:]
341v_atm_grid_pmask     [:] = atm_grid_pmask[:]
342
343# --
344
345v_oce_grid_dims       = f_runoff.createVariable ( 'dst_grid_dims'      , 'i4', ('dst_grid_rank',) )
346v_oce_grid_center_lon = f_runoff.createVariable ( 'dst_grid_center_lon', 'i4', ('dst_grid_size',) )
347v_oce_grid_center_lat = f_runoff.createVariable ( 'dst_grid_center_lat', 'i4', ('dst_grid_size',) )
348v_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"
349v_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"
350v_oce_grid_corner_lon = f_runoff.createVariable ( 'dst_grid_corner_lon', 'f8', ('dst_grid_size', 'dst_grid_corners')  )
351v_oce_grid_corner_lat = f_runoff.createVariable ( 'dst_grid_corner_lat', 'f8', ('dst_grid_size', 'dst_grid_corners')  )
352v_oce_grid_corner_lon.units="degrees_east"
353v_oce_grid_corner_lat.units="degrees_north"
354v_oce_grid_area       = f_runoff.createVariable ( 'dst_grid_area'  , 'f8', ('dst_grid_size',) )
355v_oce_grid_area.long_name="Grid area" ; v_oce_grid_area.standard_name="cell_area" ; v_oce_grid_area.units="m2"
356v_oce_grid_imask      = f_runoff.createVariable ( 'dst_grid_imask'     , 'i4', ('dst_grid_size',)  )
357v_oce_grid_imask.long_name="Land-sea mask" ; v_oce_grid_imask.units="Land:1, Ocean:0"
358v_oce_grid_pmask      = f_runoff.createVariable ( 'dst_grid_pmask'     , 'i4', ('dst_grid_size',)  )
359v_oce_grid_pmask.long_name="Land-sea mask (periodicity removed)" ; v_oce_grid_pmask.units="Land:1, Ocean:0"
360
361v_oce_grid_dims      [:] = oce_grid_dims
362v_oce_grid_center_lon[:] = oce_grid_center_lon[:]
363v_oce_grid_center_lat[:] = oce_grid_center_lat[:]
364v_oce_grid_corner_lon[:] = np.transpose(oce_grid_corner_lon)
365v_oce_grid_corner_lat[:] = np.transpose(oce_grid_corner_lat)
366v_oce_grid_area      [:] = oce_grid_area[:]
367v_oce_grid_imask     [:] = oce_grid_imask[:]
368v_oce_grid_pmask     [:] = oce_grid_pmask[:]
369
370v_atm_lon_addressed   = f_runoff.createVariable ( 'src_lon_addressed'  , 'f8', ('num_links',) )
371v_atm_lat_addressed   = f_runoff.createVariable ( 'src_lat_addressed'  , 'f8', ('num_links',) )
372v_atm_area_addressed  = f_runoff.createVariable ( 'src_area_addressed' , 'f8', ('num_links',) )
373v_atm_imask_addressed = f_runoff.createVariable ( 'src_imask_addressed', 'i4', ('num_links',) )
374v_atm_pmask_addressed = f_runoff.createVariable ( 'src_pmask_addressed', 'i4', ('num_links',) )
375
376v_oce_lon_addressed   = f_runoff.createVariable ( 'dst_lon_addressed'  , 'f8', ('num_links',) )
377v_oce_lat_addressed   = f_runoff.createVariable ( 'dst_lat_addressed'  , 'f8', ('num_links',) )
378v_oce_area_addressed  = f_runoff.createVariable ( 'dst_area_addressed' , 'f8', ('num_links',) )
379v_oce_imask_addressed = f_runoff.createVariable ( 'dst_imask_addressed', 'i4', ('num_links',) )
380v_oce_pmask_addressed = f_runoff.createVariable ( 'dst_pmask_addressed', 'i4', ('num_links',) )
381
382v_atm_lon_addressed.long_name="Longitude" ; v_atm_lon_addressed.standard_name="longitude" ; v_atm_lon_addressed.units="degrees_east"
383v_atm_lat_addressed.long_name="Latitude"  ; v_atm_lat_addressed.standard_name="latitude"  ; v_atm_lat_addressed.units="degrees_north"
384v_atm_lon_addressed  [:] = atm_grid_center_lon[atm_address]
385v_atm_lat_addressed  [:] = atm_grid_center_lat[atm_address]
386v_atm_area_addressed [:] = atm_grid_area[atm_address]
387v_atm_imask_addressed[:] = 1-atm_grid_imask[atm_address]
388v_atm_pmask_addressed[:] = 1-atm_grid_pmask[atm_address]
389
390v_oce_lon_addressed.long_name="Longitude" ; v_oce_lon_addressed.standard_name="longitude" ; v_oce_lon_addressed.units="degrees_east"
391v_oce_lat_addressed.long_name="Latitude"  ; v_oce_lat_addressed.standard_name="latitude"  ; v_oce_lat_addressed.units="degrees_north"
392v_oce_lon_addressed  [:] = oce_grid_center_lon[oce_address]
393v_oce_lat_addressed  [:] = oce_grid_center_lat[oce_address]#.ravel()
394v_oce_area_addressed [:] = oce_grid_area[oce_address]
395v_oce_imask_addressed[:] = 1-oce_grid_imask[oce_address]
396v_oce_pmask_addressed[:] = 1-oce_grid_pmask[oce_address]
397
398if atmDomainType == 'rectilinear' :
399    v_atmLand         = f_runoff.createVariable ( 'atmLand'        , 'i4', ('src_grid_size',) )
400    v_atmLandFiltered = f_runoff.createVariable ( 'atmLandFiltered', 'f4', ('src_grid_size',) )
401    v_atmLandFrac     = f_runoff.createVariable ( 'atmLandFrac'    , 'i4', ('src_grid_size',) )
402    v_atmFrac         = f_runoff.createVariable ( 'atmFrac'        , 'i4', ('src_grid_size',) )
403    v_atmOcean        = f_runoff.createVariable ( 'atmOcean'       , 'i4', ('src_grid_size',) )
404    v_atmOceanFrac    = f_runoff.createVariable ( 'atmOceanFrac'   , 'i4', ('src_grid_size',) )
405   
406    v_atmLand[:]         = atmLand.ravel()
407    v_atmLandFrac[:]     = atmLandFrac.ravel()
408    v_atmLandFiltered[:] = atmLandFiltered.ravel()
409    v_atmFrac[:]         = atmFrac.ravel()
410    v_atmOcean[:]        = atmOcean.ravel()
411    v_atmOceanFrac[:]    = atmOceanFrac.ravel()
412
413v_atmCoast         = f_runoff.createVariable ( 'atmCoast'        , 'i4', ('src_grid_size',) ) 
414v_atmCoast[:]      = atmCoast
415
416v_oceLand          = f_runoff.createVariable ( 'oceLand'         , 'i4', ('dst_grid_size',) )
417v_oceOcean         = f_runoff.createVariable ( 'oceOcean'        , 'i4', ('dst_grid_size',) )
418v_oceOceanFiltered = f_runoff.createVariable ( 'oceOceanFiltered', 'f4', ('dst_grid_size',) )
419v_oceCoast         = f_runoff.createVariable ( 'oceCoast'        , 'i4', ('dst_grid_size',) )
420 
421v_oceLand[:]          = oceLand
422v_oceOcean[:]         = oceOcean
423v_oceOceanFiltered[:] = oceOceanFiltered
424v_oceCoast[:]         = oceCoast
425
426f_runoff.sync ()
427
428##
429f_runoff.close ()
430
431print ('That''s all folks !')
432
433## ======================================================================================
Note: See TracBrowser for help on using the repository browser.