Changeset 4186 for TOOLS/MOSAIX/cotes_etal.py
- Timestamp:
- 12/12/18 11:26:20 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TOOLS/MOSAIX/cotes_etal.py
r4172 r4186 37 37 epsfrac = np.dtype('float64').type(1.0E-10) 38 38 pi = np.pi 39 rad = pi/np.dtype('float64').type(180.0) 39 rad = pi/np.dtype('float64').type(180.0) # Conversion from degrees to radian 40 40 ra = np.dtype('float64').type(6371229.0) # Earth radius 41 41 … … 56 56 # Adding arguments 57 57 parser.add_argument ('--oce' , help='oce model name', type=str, default='eORCA1.2', choices=['ORCA2.3', 'eORCA1.2', 'eORCA025'] ) 58 parser.add_argument ('--atm' , help='atm model name (LMD*)', type=str, default='LMD9695' )58 parser.add_argument ('--atm' , help='atm model name', type=str, default='LMD9695' ) 59 59 parser.add_argument ('--atmCoastWidth', help='width of the coastal band in atmosphere (in grid points)', type=int, default=1 ) 60 60 parser.add_argument ('--oceCoastWidth', help='width of the coastal band in ocean (in grid points)' , type=int, default=2 ) 61 parser.add_argument ('--searchRadius' , help='max distance to connect a land point to an ocean point (in km)', type=float, default=600000.0) 61 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'] ) 62 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'] ) 63 parser.add_argument ('--searchRadius' , help='max distance to connect a land point to an ocean point (in km)', type=float, default=600.0 ) 62 64 parser.add_argument ('--grids' , help='grids file name', default='grids.nc' ) 63 65 parser.add_argument ('--areas' , help='masks file name', default='areas.nc' ) … … 93 95 if myargs.fmt == 'netcdf4_classic' : FmtNetcdf = 'NETCDF4_CLASSIC' 94 96 97 # 98 if atm_Name.find('LMD') >= 0 : atm_n = 'lmd' ; atmDomainType = 'rectilinear' 99 if atm_Name.find('ICO') >= 0 : atm_n = 'ico' ; atmDomainType = 'unstructured' 100 101 print ('atmQuantity : ' + str (myargs.atmQuantity) ) 102 print ('oceQuantity : ' + str (myargs.oceQuantity) ) 103 95 104 ### Read coordinates of all models 96 105 ### … … 104 113 o2aFrac = np.where ( np.abs(o2aFrac) < 1E10, o2aFrac, 0.0) 105 114 106 atm_grid_center_lat = gridFile['tlmd.lat'][:] 107 atm_grid_center_lon = gridFile['tlmd.lon'][:] 108 atm_grid_corner_lat = gridFile['tlmd.cla'][:] 109 atm_grid_corner_lon = gridFile['tlmd.clo'][:] 110 111 atm_grid_area = areaFile['tlmd.srf'][:] 112 atm_grid_imask = 1-maskFile['tlmd.msk'][:].squeeze() 113 atm_grid_dims = atm_grid_area.shape 114 (atm_nvertex, atm_jpj, atm_jpi) = atm_grid_corner_lat.shape 115 (atm_nvertex, atm_jpj, atm_jpi) = gridFile['t'+atm_n+'.clo'][:].shape 116 atm_grid_size = atm_jpj*atm_jpi 117 atm_grid_rank = len(gridFile['t'+atm_n+'.lat'][:].shape) 118 119 atm_grid_center_lat = gridFile['t'+atm_n+'.lat'][:].ravel() 120 atm_grid_center_lon = gridFile['t'+atm_n+'.lon'][:].ravel() 121 atm_grid_corner_lat = np.reshape ( gridFile['t'+atm_n+'.cla'][:], (atm_nvertex, atm_grid_size) ) 122 atm_grid_corner_lon = np.reshape ( gridFile['t'+atm_n+'.clo'][:], (atm_nvertex, atm_grid_size) ) 123 atm_grid_area = areaFile['t'+atm_n+'.srf'][:].ravel() 124 atm_grid_imask = 1-maskFile['t'+atm_n+'.msk'][:].squeeze().ravel() 125 atm_grid_dims = gridFile['t'+atm_n+'.lat'][:].shape 126 115 127 atm_perio = 0 116 atm_grid_pmask = nemo.lbc_mask (atm_grid_imask, 'T', atm_perio) 117 atm_address = np.reshape ( np.arange(atm_jpj*atm_jpi), (atm_jpj, atm_jpi) ) 118 atm_grid_size = atm_jpj*atm_jpi 119 120 oce_grid_center_lat = gridFile['torc.lat'][:] 121 oce_grid_center_lon = gridFile['torc.lon'][:] 122 oce_grid_corner_lat = gridFile['torc.cla'][:] 123 oce_grid_corner_lon = gridFile['torc.clo'][:] 124 oce_grid_area = areaFile['torc.srf'][:] 125 oce_grid_imask = 1-maskFile['torc.msk'][:] 126 oce_grid_dims = oce_grid_area.shape 127 (oce_nvertex, oce_jpj, oce_jpi) = oce_grid_corner_lat.shape ; jpon=oce_jpj*oce_jpj 128 atm_grid_pmask = atm_grid_imask 129 atm_address = np.arange(atm_jpj*atm_jpi) 130 131 132 (oce_nvertex, oce_jpj, oce_jpi) = gridFile['torc.cla'][:].shape ; jpon=oce_jpj*oce_jpj 133 oce_grid_size = oce_jpj*oce_jpi 134 oce_grid_rank = len(gridFile['torc.lat'][:].shape) 135 136 oce_grid_center_lat = gridFile['torc.lat'][:].ravel() 137 oce_grid_center_lon = gridFile['torc.lon'][:].ravel() 138 oce_grid_corner_lat = np.reshape( gridFile['torc.cla'][:], (oce_nvertex, oce_grid_size) ) 139 oce_grid_corner_lon = np.reshape( gridFile['torc.clo'][:], (oce_nvertex, oce_grid_size) ) 140 oce_grid_area = areaFile['torc.srf'][:].ravel() 141 oce_grid_imask = 1-maskFile['torc.msk'][:].ravel() 142 oce_grid_dims = gridFile['torc.lat'][:].shape 128 143 if oce_jpi == 182 : oce_perio = 4 # ORCA 2 129 144 if oce_jpi == 362 : oce_perio = 6 # ORCA 1 130 145 if oce_jpi == 1442 : oce_perio = 6 # ORCA 025 131 oce_grid_pmask = nemo.lbc_mask (oce_grid_imask, 'T', oce_perio) 132 oce_address = np.reshape ( np.arange(oce_jpj*oce_jpi), (oce_jpj, oce_jpi) ) 133 oce_grid_size = oce_jpj*oce_jpi 146 oce_grid_pmask = nemo.lbc_mask (np.reshape(oce_grid_imask, (oce_jpj,oce_jpi)), 'T', oce_perio).ravel() 147 oce_address = np.arange(oce_jpj*oce_jpi) 134 148 135 149 ## Fill closed sea with image processing library 136 oce_grid_imask = nemo.lbc_mask ( 1-ndimage.binary_fill_holes (1-nemo.lbc(oce_grid_imask, nperio=oce_perio, cd_type='T')), nperio=oce_perio, cd_type='T' ) 137 150 oce_grid_imask2D = np.reshape(oce_grid_pmask,(oce_jpj,oce_jpi)) 151 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' ) 152 oce_grid_imask = oce_grid_imask2D.ravel() 138 153 ## 139 154 print ("Determination d'une bande cotiere ocean") 140 155 141 oceLand = np.where (oce_grid_pmask[:] < 0.5, True, False)142 oceOcean = np.where (oce_grid_pmask[:] > 0.5, True, False)156 oceLand2D = np.reshape ( np.where (oce_grid_pmask[:] < 0.5, True, False), (oce_jpj, oce_jpi) ) 157 oceOcean2D = np.reshape ( np.where (oce_grid_pmask[:] > 0.5, True, False), (oce_jpj, oce_jpi) ) 143 158 144 159 NNocean = 1+2*oceCoastWidth 145 oceOceanFiltered = ndimage.uniform_filter(oceOcean.astype(float), size=NNocean) 146 oceCoast = np.where (oceOceanFiltered<(1.0-0.5/(NNocean**2)),True,False) & oceOcean 147 oceCoast = nemo.lbc_mask (oceCoast, oce_perio, 'T') 160 oceOceanFiltered2D = ndimage.uniform_filter(oceOcean2D.astype(float), size=NNocean) 161 oceCoast2D = np.where (oceOceanFiltered2D<(1.0-0.5/(NNocean**2)),True,False) & oceOcean2D 162 oceCoast2D = nemo.lbc_mask (np.reshape(oceCoast2D,(oce_jpj,oce_jpi)), oce_perio, 'T').ravel() 163 164 oceOceanFiltered = oceOceanFiltered2D.ravel() 165 oceLand = oceLand2D.ravel() 166 oceOcean = oceOcean2D.ravel() 167 oceCoast = oceCoast2D.ravel() 148 168 149 169 print ('Number of points in oceLand : ' + str(oceLand.sum()) ) … … 166 186 atmOceanFrac = np.where (o2aFrac[:] > epsfrac , True, False) 167 187 168 NNatm = 1+2*atmCoastWidth 169 atmLandFiltered = ndimage.uniform_filter(atmLand.astype(float), size=NNatm) 170 atmCoast = np.where (atmLandFiltered<(1.0-0.5/(NNatm**2)),True,False) & atmLandFrac 171 atmCoast = nemo.lbc_mask (atmCoast, 1, 'T') 172 173 print ('Number of points in atmLand : ' + str(atmLand.sum()) ) 174 print ('Number of points in atmOcean : ' + str(atmOcean.sum()) ) 175 print ('Number of points in atmCoast : ' + str(atmCoast.sum()) ) 176 188 ## La suite marche avec LMDZ seulement !! 189 if atmDomainType == 'rectilinear' : 190 NNatm = 1+2*atmCoastWidth 191 atmLand2D = np.reshape ( atmLand, ( atm_jpj, atm_jpi) ) 192 193 atmLandFiltered2D = ndimage.uniform_filter(atmLand2D.astype(float), size=NNatm) 194 atmCoast2D = np.where (atmLandFiltered2D<(1.0-0.5/(NNatm**2)),True,False) & atmLandFrac 195 196 atmLandFiltered = atmLandFiltered2D.ravel() 197 atmCoast = atmCoast2D.ravel() 198 199 print ('Number of points in atmLand : ' + str(atmLand.sum()) ) 200 print ('Number of points in atmOcean : ' + str(atmOcean.sum()) ) 201 print ('Number of points in atmCoast : ' + str(atmCoast.sum()) ) 202 203 else : 204 atmCoast = atmFrac 205 206 177 207 # Arrays with coastal points only 178 208 atmCoast_grid_center_lon = atm_grid_center_lon[atmCoast] … … 183 213 atmCoast_address = atm_address [atmCoast] 184 214 215 # Initialisations before the loop 185 216 remap_matrix = np.empty ( shape=(0), dtype=np.float64 ) 186 217 atm_address = np.empty ( shape=(0), dtype=np.int32 ) … … 191 222 z_dist = geodist ( atmCoast_grid_center_lon[ja], atmCoast_grid_center_lat[ja], oceCoast_grid_center_lon, oceCoast_grid_center_lat) 192 223 z_mask = np.where ( z_dist*ra < searchRadius, True, False) 193 num_links = z_mask.sum()224 num_links = np.int(z_mask.sum()) 194 225 if num_links == 0 : continue 195 226 z_area = oceCoast_grid_area[z_mask].sum() 196 poids = 1.0 / z_area 197 #print ( num_links, z_mask.sum(), z_area ) 227 poids = np.ones ((num_links),dtype=np.float64) / z_area 228 if myargs.atmQuantity == 'Surfacic' : poids = poids * atm_grid_area[ja] 229 if myargs.oceQuantity == 'Quantity' : poids = poids * oceCoast_grid_area[z_mask] 230 if ja % (len(atmCoast_grid_pmask)//50) == 0 : # Control print 231 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() ) ) 198 232 # 199 matrix_local = np.ones ((num_links),dtype=np.float64) * poids 200 # address on source grid : all links points to the same LMDZ point. 233 matrix_local = poids 201 234 atm_address_local = np.ones(num_links, dtype=np.int32 ) * atmCoast_address[ja] 202 # address on destination grid235 # Address on destination grid 203 236 oce_address_local = oceCoast_address[z_mask] 204 237 # Append to global tabs … … 252 285 f_runoff.SVN_HeadURL = "$HeadURL$" 253 286 254 d_num_links 255 d_num_wgts 287 d_num_links = f_runoff.createDimension ('num_links' , num_links ) 288 d_num_wgts = f_runoff.createDimension ('num_wgts' , 1 ) 256 289 257 290 d_atm_grid_size = f_runoff.createDimension ('src_grid_size' , atm_grid_size ) 258 291 d_atm_grid_corners = f_runoff.createDimension ('src_grid_corners', atm_grid_corner_lon.shape[0] ) 259 d_atm_grid_rank = f_runoff.createDimension ('src_grid_rank' , 2)292 d_atm_grid_rank = f_runoff.createDimension ('src_grid_rank' , atm_grid_rank ) 260 293 261 294 d_oce_grid_size = f_runoff.createDimension ('dst_grid_size' , oce_grid_size ) 262 295 d_oce_grid_corners = f_runoff.createDimension ('dst_grid_corners', oce_grid_corner_lon.shape[0] ) 263 d_oce_grid_rank = f_runoff.createDimension ('dst_grid_rank' , 2)296 d_oce_grid_rank = f_runoff.createDimension ('dst_grid_rank' , oce_grid_rank ) 264 297 265 298 v_remap_matrix = f_runoff.createVariable ( 'remap_matrix', 'f8', ('num_links', 'num_wgts') ) … … 289 322 290 323 v_atm_grid_dims [:] = atm_grid_dims 291 v_atm_grid_center_lon[:] = atm_grid_center_lon[:] .ravel()292 v_atm_grid_center_lat[:] = atm_grid_center_lat[:] .ravel()293 v_atm_grid_corner_lon[:] = atm_grid_corner_lon .reshape( (atm_jpi*atm_jpj, d_atm_grid_corners.__len__()) )294 v_atm_grid_corner_lat[:] = atm_grid_corner_lat .reshape( (atm_jpi*atm_jpj, d_atm_grid_corners.__len__()) )295 v_atm_grid_area [:] = atm_grid_area[:] .ravel()296 v_atm_grid_imask [:] = atm_grid_imask[:] .ravel()297 v_atm_grid_pmask [:] = atm_grid_pmask[:] .ravel()324 v_atm_grid_center_lon[:] = atm_grid_center_lon[:] 325 v_atm_grid_center_lat[:] = atm_grid_center_lat[:] 326 v_atm_grid_corner_lon[:] = atm_grid_corner_lon 327 v_atm_grid_corner_lat[:] = atm_grid_corner_lat 328 v_atm_grid_area [:] = atm_grid_area[:] 329 v_atm_grid_imask [:] = atm_grid_imask[:] 330 v_atm_grid_pmask [:] = atm_grid_pmask[:] 298 331 299 332 # -- … … 316 349 317 350 v_oce_grid_dims [:] = oce_grid_dims 318 v_oce_grid_center_lon[:] = oce_grid_center_lon[:] .ravel()319 v_oce_grid_center_lat[:] = oce_grid_center_lat[:] .ravel()320 v_oce_grid_corner_lon[:] = oce_grid_corner_lon .reshape( (oce_jpi*oce_jpj, d_oce_grid_corners.__len__()) )321 v_oce_grid_corner_lat[:] = oce_grid_corner_lon .reshape( (oce_jpi*oce_jpj, d_oce_grid_corners.__len__()) )322 v_oce_grid_area [:] = oce_grid_area[:] .ravel()323 v_oce_grid_imask [:] = oce_grid_imask[:] .ravel()324 v_oce_grid_pmask [:] = oce_grid_pmask[:] .ravel()351 v_oce_grid_center_lon[:] = oce_grid_center_lon[:] 352 v_oce_grid_center_lat[:] = oce_grid_center_lat[:] 353 v_oce_grid_corner_lon[:] = oce_grid_corner_lon 354 v_oce_grid_corner_lat[:] = oce_grid_corner_lon 355 v_oce_grid_area [:] = oce_grid_area[:] 356 v_oce_grid_imask [:] = oce_grid_imask[:] 357 v_oce_grid_pmask [:] = oce_grid_pmask[:] 325 358 326 359 v_atm_lon_addressed = f_runoff.createVariable ( 'src_lon_addressed' , 'f8', ('num_links',) ) … … 338 371 v_atm_lon_addressed.long_name="Longitude" ; v_atm_lon_addressed.standard_name="longitude" ; v_atm_lon_addressed.units="degrees_east" 339 372 v_atm_lat_addressed.long_name="Latitude" ; v_atm_lat_addressed.standard_name="latitude" ; v_atm_lat_addressed.units="degrees_north" 340 v_atm_lon_addressed [:] = atm_grid_center_lon .ravel()[atm_address].ravel()341 v_atm_lat_addressed [:] = atm_grid_center_lat .ravel()[atm_address].ravel()342 v_atm_area_addressed [:] = atm_grid_area .ravel()[atm_address].ravel()343 v_atm_imask_addressed[:] = 1-atm_grid_imask .ravel()[atm_address].ravel()344 v_atm_pmask_addressed[:] = 1-atm_grid_pmask .ravel()[atm_address].ravel()373 v_atm_lon_addressed [:] = atm_grid_center_lon[atm_address] 374 v_atm_lat_addressed [:] = atm_grid_center_lat[atm_address] 375 v_atm_area_addressed [:] = atm_grid_area[atm_address] 376 v_atm_imask_addressed[:] = 1-atm_grid_imask[atm_address] 377 v_atm_pmask_addressed[:] = 1-atm_grid_pmask[atm_address] 345 378 346 379 v_oce_lon_addressed.long_name="Longitude" ; v_oce_lon_addressed.standard_name="longitude" ; v_oce_lon_addressed.units="degrees_east" 347 380 v_oce_lat_addressed.long_name="Latitude" ; v_oce_lat_addressed.standard_name="latitude" ; v_oce_lat_addressed.units="degrees_north" 348 v_oce_lon_addressed [:] = oce_grid_center_lon.ravel()[oce_address].ravel() 349 v_oce_lat_addressed [:] = oce_grid_center_lat.ravel()[oce_address].ravel() 350 v_oce_area_addressed [:] = oce_grid_area.ravel()[oce_address].ravel() 351 v_oce_imask_addressed[:] = 1-oce_grid_imask.ravel()[oce_address].ravel() 352 v_oce_pmask_addressed[:] = 1-oce_grid_pmask.ravel()[oce_address].ravel() 353 354 v_atmLand = f_runoff.createVariable ( 'atmLand' , 'i4', ('src_grid_size',) ) 355 v_atmLandFiltered = f_runoff.createVariable ( 'atmLandFiltered', 'f4', ('src_grid_size',) ) 356 v_atmLandFrac = f_runoff.createVariable ( 'atmLandFrac' , 'i4', ('src_grid_size',) ) 357 v_atmFrac = f_runoff.createVariable ( 'atmFrac' , 'i4', ('src_grid_size',) ) 358 v_atmOcean = f_runoff.createVariable ( 'atmOcean' , 'i4', ('src_grid_size',) ) 359 v_atmOceanFrac = f_runoff.createVariable ( 'atmOceanFrac' , 'i4', ('src_grid_size',) ) 360 v_atmCoast = f_runoff.createVariable ( 'atmCoast' , 'i4', ('src_grid_size',) ) 361 362 v_atmLand[:] = atmLand.ravel() 363 v_atmLandFrac[:] = atmLandFrac.ravel() 364 v_atmLandFiltered[:] = atmLandFiltered.ravel() 365 v_atmFrac[:] = atmFrac.ravel() 366 v_atmOcean[:] = atmOcean.ravel() 367 v_atmOceanFrac[:] = atmOceanFrac.ravel() 368 v_atmCoast[:] = atmCoast.ravel() 381 v_oce_lon_addressed [:] = oce_grid_center_lon[oce_address] 382 v_oce_lat_addressed [:] = oce_grid_center_lat[oce_address]#.ravel() 383 v_oce_area_addressed [:] = oce_grid_area[oce_address] 384 v_oce_imask_addressed[:] = 1-oce_grid_imask[oce_address] 385 v_oce_pmask_addressed[:] = 1-oce_grid_pmask[oce_address] 386 387 if atmDomainType == 'rectilinear' : 388 v_atmLand = f_runoff.createVariable ( 'atmLand' , 'i4', ('src_grid_size',) ) 389 v_atmLandFiltered = f_runoff.createVariable ( 'atmLandFiltered', 'f4', ('src_grid_size',) ) 390 v_atmLandFrac = f_runoff.createVariable ( 'atmLandFrac' , 'i4', ('src_grid_size',) ) 391 v_atmFrac = f_runoff.createVariable ( 'atmFrac' , 'i4', ('src_grid_size',) ) 392 v_atmOcean = f_runoff.createVariable ( 'atmOcean' , 'i4', ('src_grid_size',) ) 393 v_atmOceanFrac = f_runoff.createVariable ( 'atmOceanFrac' , 'i4', ('src_grid_size',) ) 394 395 v_atmLand[:] = atmLand 396 v_atmLandFrac[:] = atmLandFrac 397 v_atmLandFiltered[:] = atmLandFiltered 398 v_atmFrac[:] = atmFrac 399 v_atmOcean[:] = atmOcean 400 v_atmOceanFrac[:] = atmOceanFrac 401 402 v_atmCoast = f_runoff.createVariable ( 'atmCoast' , 'i4', ('src_grid_size',) ) 403 v_atmCoast[:] = atmCoast 369 404 370 405 v_oceLand = f_runoff.createVariable ( 'oceLand' , 'i4', ('dst_grid_size',) ) … … 373 408 v_oceCoast = f_runoff.createVariable ( 'oceCoast' , 'i4', ('dst_grid_size',) ) 374 409 375 v_oceLand[:] = oceLand .ravel()376 v_oceOcean[:] = oceOcean .ravel()377 v_oceOceanFiltered[:] = oceOceanFiltered .ravel()378 v_oceCoast[:] = oceCoast .ravel()410 v_oceLand[:] = oceLand 411 v_oceOcean[:] = oceOcean 412 v_oceOceanFiltered[:] = oceOceanFiltered 413 v_oceCoast[:] = oceCoast 379 414 380 415 f_runoff.sync ()
Note: See TracChangeset
for help on using the changeset viewer.