def step_3(topo_nc, list_with_synoptic_nc, dictionary_4, nc_out, create_davit_netcdf=True, log=False): ''' Procedure creates unstructured grid NetCDF file under `nc_out` fname. Args: ----- topo_nc (str): path to netcdf file with x,y vectors and "bathymetry" variable for mask list_with_synoptic_nc (list(str)): paths to netcdf with synoptic data. At first position should be the main data-file dictionary_1 (str): path to txt file with dictionary to suggest standart mossco-baw variable name correlation dictionary_2 (str): path to txt file after scanning variables dictionary_3 (str): path to cdl file with standard variables dictionary_4 (str): path to cdl file to be created Return: ------- nc_out (str): path to netcdf to be created ''' sprint('{0}{0}{1}{0}{0}'.format(' '*20+'+'*30+'\n', ' '*20+'+'*10+' STEP 3 '+'+'*10+'\n'), log=log) # -------------------------------------------------- # 1) Read, x any y vectors from the netcdf # -------------------------------------------------- sprint('searching x, y, bathymetry ...', log=log) #coords = process_mossco_netcdf.find_coordinate_vars(topo_nc, log=log) structGrid = process_mixed_data.containerForGridGeneration(topo_nc, log=log) coords = structGrid.get_data() meta = structGrid.get_metadata() # -------------------------------------------------- # 2) Create mask # -------------------------------------------------- sprint('creating mask...', log=log) #m = process_mossco_netcdf.make_mask_array_from_mossco_bathymetry(topo_nc, varname=coords['bName'], fillvalue=None, transpose=True, log=log) m = structGrid.get_mask(transpose=False, log=log) # -------------------------------------------------- # 3) Create grid, and unpack values # -------------------------------------------------- start_index = 0 sprint('Generating uGrid... (be patient, this may take a while)') dims, topo, nodes, edges, faces, bounds = make_grid.make_2d_qudratic_grid_or_curvilinear(coords['x'], coords['y'], data_location=meta['x']['points_location'], mask=m, log=log, startingindex=start_index) nMesh2_node = dims[0] nMesh2_edge = dims[1] nMesh2_face = dims[2] nMaxMesh2_face_nodes = dims[3] Mesh2_edge_nodes = topo[0] Mesh2_edge_faces = topo[1] Mesh2_face_nodes = topo[2] Mesh2_face_edges = topo[3] Mesh2_node_x = nodes[0] Mesh2_node_y = nodes[1] Mesh2_edge_x = edges[0] Mesh2_edge_y = edges[1] Mesh2_face_x = faces[0] Mesh2_face_y = faces[1] Mesh2_face_center_x = faces[2] Mesh2_face_center_y = faces[3] Mesh2_face_area = faces[4] Mesh2_edge_x_bnd = bounds[0] Mesh2_edge_y_bnd = bounds[1] Mesh2_face_x_bnd = bounds[2] Mesh2_face_y_bnd = bounds[3] # -------------------------------------------------- # 4) Get bumber of vertical layers, dimensions from MOSSCO # -------------------------------------------------- nLayers, layer_fname = process_mossco_netcdf.get_number_of_depth_layer_from_mossco(list_with_synoptic_nc, dimname='getmGrid3D_getm_3') # -------------------------------------------------- # 5) Create netcdf # -------------------------------------------------- if not create_davit_netcdf: print "\nAbortig here...\nNetcdf has not been created, switch flag 'create_davit_netcdf' to True." sys.exit(0) process_davit_ncdf.create_uGrid_ncdf(nc_out, nMesh2_node, nMesh2_edge, nMesh2_face, nMaxMesh2_face_nodes, Mesh2_edge_nodes, Mesh2_edge_faces, Mesh2_face_nodes, Mesh2_face_edges, Mesh2_node_x, Mesh2_node_y, Mesh2_edge_x, Mesh2_edge_y, Mesh2_face_x, Mesh2_face_y, Mesh2_face_center_x, Mesh2_face_center_y, Mesh2_face_area=Mesh2_face_area, Mesh2_edge_x_bnd=Mesh2_edge_x_bnd, Mesh2_edge_y_bnd=Mesh2_edge_y_bnd, Mesh2_face_x_bnd=Mesh2_face_x_bnd, Mesh2_face_y_bnd=Mesh2_face_y_bnd, coord_type=meta['x']['coordinate_type'], dim_nMesh2_layer2d=1, dim_nMesh2_layer3d=nLayers, dim_nMesh2_class_names_strlen=20, dim_nMesh2_suspension_classes=1, start_index=start_index, log=log) if log: print 'grid created', '\n', '-'*100, '\n', 'Now adding data', '\n', '-'*100 # -------------------------------------------------- # 6) fill netcdf with time variables (TIME and DATATIME) # -------------------------------------------------- if log: print '-'*100 time_added = False for nc_file in list_with_synoptic_nc: try: process_davit_ncdf.append_Time_andDatetime_to_netcdf(nc_out, nc_file, time_var_name='time', log=log) if log: print 'added "nMesh2_data_time" from file ', nc_file time_added = True break except KeyError: # if var is not found in current file => skip to next file pass if not time_added: print 'WARNING! added dummy "nMesh2_data_time"' process_davit_ncdf.append_Time_andDatetime_to_netcdf(nc_out, dummy_values=True, log=log) if log: print '-'*100 # --------------------------------------------------------------------------- # 7) Layer thicness # --------------------------------------------------------------------------- # now moved to the very bottom, since we want to use dictionary VARS # that is generated by processing Dict4 # -------------------------------------------------- # 8) fill netcdf with SYNOPTIC data!!! # -------------------------------------------------- if log: print '-'*100+'\n+Now adding data based on Dictionary 4.\n'+'-'*100 # -------------------------------------------------- # -- 8.1) fill netcdf with SYNOPTIC data!!! # -------------------------------------------------- VARS = process_cdl.read_file_with_only_variables(process_cdl.read_file_delete_comments(dictionary_4, comments='//')) # ----------------------------------------------------------------------------------------------- # -- 8.2) cycle through found variables # ----------------------------------------------------------------------------------------------- for var_name, var in VARS.iteritems(): sprint('Variable read from Dictionary 4:', var.get_name(), log=log) varExt = process_mixed_data.cdlVariableExt(var) #var is an instance of type <cdlVariable> source = varExt.get_source_metadata() # ----------------------------------------------------------------------------------------------- # 8.2.4) add data # ----------------------------------------------------------------------------------------------- if source['nNonOneDims'] not in [0, 1, 2, 3, 4]: ui.promt('WARNING! Skipping variable: <{0}> with dimensions <{1}> of shape <{2}>. It has <{3}> non-one dimensions. Currently <=4 is supported. Press ENTER to continue'.format( source['name'], source['dims'], source['shape']), source['nNonOneDims'], color='yellow', pause=True) break raw_data = process_mossco_netcdf.read_mossco_nc_rawvar(source['fname'], source['name']) var_data = process_mixed_data.flatten_xy_data(raw_data, mask=m) # ----------------------------------------------------------------------------------------------- # 8.2.6) append data variable to nc_out... # ----------------------------------------------------------------------------------------------- process_davit_ncdf.append_VariableData_to_netcdf(nc_out, var, var_data, fv=source['fillvalue'], log=log) sprint('\n', log=log) del varExt # ----------------------------------------------------------------------------------------------- # 9) Layer thickness # ----------------------------------------------------------------------------------------------- sprint('-'*100, log=log) sprint('Now adding vertical layer information', log=log) sprint('-'*100, log=log) vertical_coord_mode = 'sigma' if nLayers > 1: #if a real 3d is here LAYERS_ADDED = False if vertical_coord_mode == 'sigma': add_eta = 'Mesh2_face_Wasserstand_2d' in VARS.keys() add_depth = 'Mesh2_face_depth_2d' in VARS.keys() try: process_davit_ncdf.append_sigma_vertical_coord_vars(list_with_synoptic_nc, nLayers, nc_out, add_eta=add_eta, add_depth=add_depth, mask=m, log=log) LAYERS_ADDED = True except Exception as exp: sprint(exp, mode='fail') traceback.print_exc(file=sys.stderr) else: raise NotImplementedError() if not LAYERS_ADDED: ui.promt('Now i will try to add dummy vertical data. Press ENTER to see info about these values', pause=True) sprint(process_davit_ncdf.append_test_Mesh2_face_z_3d_and_Mesh2_face_z_3d_bnd.__doc__) if ui.promtYesNo('Do you want to proceed?', quitonno=True): try: process_davit_ncdf.append_test_Mesh2_face_z_3d_and_Mesh2_face_z_3d_bnd(nc_out, nx=meta['b']['shape'][-1], ny=meta['b']['shape'][-2], mask=m, log=log) except Exception as exp: sprint(exp, mode='fail') traceback.print_exc(file=sys.stderr) ui.promt('Failed to find any vertical-layer information. Will proceed without any. Press ENTER', color='yellow', pause=True) if log: print '-'*100 if create_davit_netcdf: print 'File created:', os.path.abspath(nc_out)
def append_sigma_vertical_coord_vars(list_with_filenames, nLayers, nc_out_fname, add_eta=False, add_depth=False, mask=None, sigma_varname='level', log=False): ''' Appends variables that define vertical position of layers... - nMesh2_layer_3d >>> 1d sigma coords of cell center - Mesh2_face_z_face_3d >>> elevation cell center values - Mesh2_face_z_face_3d_bnd >>> elevation cell border values - (optionaly) Mesh2_face_Wasserstand_2d >>> water level - (optionaly) Mesh2_face_depth_2d >>> bottom depth ... to passed `nc_out_fname` netcdf file Args: ----- list_with_filenames (list of str): list with names of netcdf files. The var `sigma_varname` will be searched within this files nLayers (int): number of vertical layers nc_out_fname (str): filename of the output netcdf file add_eta (bool): flag to add variable "Mesh2_face_Wasserstand_2d" to file `nc_out_fname`. This is useful because, most likely this var is already appended or will be appended to file based on DICTIONARY4 add_depth (bool): flag to add variable "Mesh2_face_depth_2d" to file `nc_out_fname` This is useful because, most likely this var is already appended or will be appended to file based on DICTIONARY4 mask (2D array of bool): 2d array of (y, x) dimensions with boolean mask (to treat NaN cells) sigma_varname (str): name of the varable to get sigma-layer info from log (bool): flag to print output ''' _i = '\t' _n = 'append_sigma_vertical_coord_vars()' sprint(_n, 'Appending sigma_vertical coordinates ...', log=log, mode='bold') # ---------------------------------------- # ---------------------------------------- # --------------- SIGMA --------------- # ---------------------------------------- # ---------------------------------------- var = process_cdl.cdlVariable() var.set_name('nMesh2_layer_3d') var.set_dtype('double') var.set_dims(('nMesh2_layer_3d', )) var.set_fillvalue(False) var.set_attr('standard_name', 'ocean_sigma_coordinate') var.set_attr('long_name', "sigma at layer midpoints") var.set_attr('positive', 'up') var.set_attr('formula_terms', 'sigma: nMesh2_layer_3d eta: Mesh2_face_Wasserstand_2d depth: Mesh2_face_depth_2d') sigma, sigma_type = process_mossco_netcdf.get_sigma_coordinates(list_with_filenames, nLayers, sigma_varname=sigma_varname, waterdepth_varname='water_depth_at_soil_surface', layerdepth_varname='getmGrid3D_getm_layer', indent=_i, log=log) if sigma_type == 'center': pass elif sigma_type == 'border': sigma = process_mixed_data.create_sigma_coords_of_layer_center(sigma) append_VariableData_to_netcdf(nc_out_fname, var, sigma, fv=var.get_fillvalue(), log=log, indent=_i) del var bathymetry = None for nc_file in list_with_filenames: root_grp = Dataset(nc_file, mode='r') if 'bathymetry' in root_grp.variables.keys() and bathymetry is None: bathymetry = process_mossco_netcdf.read_mossco_nc_rawvar(nc_file, 'bathymetry') root_grp.close() del root_grp # ---------------------------------------- # ---------------------------------------- # --------------- ETA ----------------- # ---------------------------------------- # ---------------------------------------- var_e = process_cdl.cdlVariable() var_e.set_name('Mesh2_face_Wasserstand_2d') var_e.set_dtype('float') var_e.set_dims(('nMesh2_data_time', 'nMesh2_face')) var_e.set_fillvalue(False) var_e.set_attr('long_name', "Wasserstand, Face (Polygon)") var_e.set_attr('standard_name', 'sea_surface_height') var_e.set_attr('units', 'm') var_e.set_attr('name_id', 3) var_e.set_attr('cell_measures', 'area: Mesh2_face_wet_area') var_e.set_attr('cell_measures', 'nMesh2_data_time: point area: mean') var_e.set_attr('coordinates', 'Mesh2_face_x Mesh2_face_y Mesh2_face_lon Mesh2_face_lat') var_e.set_attr('grid_mapping', 'Mesh2_crs') var_e.set_attr('mesh', 'Mesh2') var_e.set_attr('location', 'face') sprint(_n, ' Get waterlevel ...', log=log, mode='bold') water_level = process_mossco_netcdf.get_water_level(list_with_filenames, wl_vname='water_level', water_depth_at_soil_surface_vname='water_depth_at_soil_surface', bathymetry_vname='bathymetry', log=log, indent=_i) # append var after # ---------------------------------------- # ---------------------------------------- # -------------- DEPTH ---------------- # ---------------------------------------- # ---------------------------------------- var_d = process_cdl.cdlVariable() var_d.set_name('Mesh2_face_depth_2d') var_d.set_dtype('double') var_d.set_dims(('nMesh2_time', 'nMesh2_face')) var_d.set_fillvalue(False) var_d.set_attr('long_name', "Topographie") var_d.set_attr('standard_name', 'sea_floor_depth_below_geoid') var_d.set_attr('units', 'm') var_d.set_attr('name_id', 17) var_d.set_attr('cell_measures', 'area: Mesh2_face_area') var_d.set_attr('cell_measures', 'nMesh2_time: mean area: mean') var_d.set_attr('coordinates', 'Mesh2_face_x Mesh2_face_y Mesh2_face_lon Mesh2_face_lat') var_d.set_attr('grid_mapping', 'Mesh2_crs') var_d.set_attr('mesh', 'Mesh2') var_d.set_attr('location', 'face') # append var after # ---------------------------------------- # ---------------------------------------- # ------------ ELEVATION -------------- # ---------------------------------------- # ---------------------------------------- # FACE cell center values..... # ---------------------------------------- var1 = process_cdl.cdlVariable() var1.set_name('Mesh2_face_z_face_3d') var1.set_dtype('float') var1.set_dims(('nMesh2_data_time', 'nMesh2_layer_3d', 'nMesh2_face')) var1.set_fillvalue(None) var1.set_attr('long_name', 'z_face [ face ]') var1.set_attr('units', 'm') var1.set_attr('positive', 'up') var1.set_attr('name_id', 1702) var1.set_attr('bounds', 'Mesh2_face_z_face_bnd_3d') var1.set_attr('standard_name', 'depth') # ---------------------------------------- # FACE cell border values..... # ---------------------------------------- var2 = process_cdl.cdlVariable() var2.set_name('Mesh2_face_z_face_bnd_3d') var2.set_dtype('float') var2.set_dims(('nMesh2_data_time', 'nMesh2_layer_3d', 'nMesh2_face', 'two')) var2.set_fillvalue(None) var2.set_attr('long_name', 'elevations of lower and upper layer-boundaries') var2.set_attr('units', 'm') sprint(_n, ' Get elevation of cell centers and cell borders ...', log=log, mode='bold') elev, elev_borders = process_mixed_data.create_layer_elevation_from_sigma_coords(water_level, sigma, bathymetry, log=log, indent=_i) var_data1 = process_mixed_data.flatten_xy_data(elev, mask=mask) var_data2 = process_mixed_data.flatten_xy_data(elev_borders, mask=mask) append_VariableData_to_netcdf(nc_out_fname, var1, var_data1, fv=var1.get_fillvalue(), log=log, indent=_i) append_VariableData_to_netcdf(nc_out_fname, var2, var_data2, fv=var2.get_fillvalue(), log=log, indent=_i) del var1, var2 if add_depth: var_data = process_mixed_data.flatten_xy_data(bathymetry, mask=mask) append_VariableData_to_netcdf(nc_out_fname, var_d, var_data, fv=var_d.get_fillvalue(), log=log, indent=_i) del var_d if add_eta: var_data = process_mixed_data.flatten_xy_data(water_level, mask=mask) append_VariableData_to_netcdf(nc_out_fname, var_e, var_data, fv=var_e.get_fillvalue(), log=log, indent=_i) del var_e if log: print '-'*25+'\n'