def slf_base(args): with Serafin.Read(args.in_slf, args.lang) as resin: resin.read_header() logger.info(resin.header.summary()) resin.get_time() output_header = resin.header.copy() # Shift mesh coordinates if necessary if args.shift: output_header.transform_mesh([Transformation(0, 1, 1, args.shift[0], args.shift[1], 0)]) # Set mesh origin coordinates if args.set_mesh_origin: output_header.set_mesh_origin(args.set_mesh_origin[0], args.set_mesh_origin[1]) # Toggle output file endianness if necessary if args.toggle_endianness: output_header.toggle_endianness() # Convert to single precision if args.to_single_precision: if resin.header.is_double_precision(): output_header.to_single_precision() else: logger.warn('Input file is already single precision! Argument `--to_single_precision` is ignored') # Remove variables if necessary if args.var2del: output_header.empty_variables() for var_ID, var_name, var_unit in zip(resin.header.var_IDs, resin.header.var_names, resin.header.var_units): if var_ID not in args.var2del: output_header.add_variable(var_ID, var_name, var_unit) # Add new derived variables if args.var2add is not None: for var_ID in args.var2add: if var_ID in output_header.var_IDs: logger.warn('Variable %s is already present (or asked)' % var_ID) else: output_header.add_variable_from_ID(var_ID) us_equation = get_US_equation(args.friction_law) necessary_equations = get_necessary_equations(resin.header.var_IDs, output_header.var_IDs, is_2d=resin.header.is_2d, us_equation=us_equation) with Serafin.Write(args.out_slf, args.lang, overwrite=args.force) as resout: resout.write_header(output_header) for time_index, time in tqdm(resin.subset_time(args.start, args.end, args.ech), unit='frame'): values = do_calculations_in_frame(necessary_equations, resin, time_index, output_header.var_IDs, output_header.np_float_type, is_2d=output_header.is_2d, us_equation=us_equation, ori_values={}) resout.write_entire_frame(output_header, time, values)
def test_FROPT_equation(self): self.assertEqual(eq_name(get_necessary_equations(['US', 'MU'], ['FROTP'], True, None)), ['TAU', 'FROTP']) self.assertEqual(eq_name(get_necessary_equations(['U', 'MU', 'H', 'W', 'TAU', 'US'], ['FROTP'], True, None)), ['FROTP']) self.assertEqual(eq_name(get_necessary_equations(['U', 'V', 'J', 'W', 'H', 'MU', 'I'], ['FROTP'], True, get_US_equation(CHEZY_ID))), ['M', 'US', 'TAU', 'FROTP']) self.assertEqual(eq_name(get_necessary_equations(['U', 'MU', 'M', 'B', 'Q', 'W', 'S'], ['FROTP', 'DMAX', 'H', 'Q', 'TAU', 'U', 'V'], True, get_US_equation(STRICKLER_ID))), ['H', 'US', 'TAU', 'DMAX', 'FROTP']) self.assertEqual(eq_name(get_necessary_equations(['US', 'I', 'H', 'MU', 'V'], ['M', 'DMAX', 'Q', 'FROTP'], True, None)), ['M', 'J', 'Q', 'TAU', 'DMAX', 'FROTP']) self.assertEqual(eq_name(get_necessary_equations(['US', 'MU', 'H', 'U', 'V'], ['FROTP', 'M', 'DMAX', 'Q'], True, None)), ['M', 'I', 'J', 'Q', 'TAU', 'DMAX', 'FROTP'])
def test_TAU_equation(self): self.assertEqual(eq_name(get_necessary_equations(['U', 'V', 'J', 'W', 'H', 'B', 'I'], ['TAU'], True, get_US_equation(CHEZY_ID))), ['M', 'US', 'TAU']) self.assertEqual(eq_name(get_necessary_equations(['U', 'V', 'M', 'Q', 'W', 'H'], ['TAU', 'Q', 'U', 'V'], True, get_US_equation(NIKURADSE_ID))), ['US', 'TAU']) self.assertEqual(eq_name(get_necessary_equations(['U', 'V', 'M', 'US', 'Q', 'W', 'H'], ['I', 'TAU', 'Q', 'U', 'V'], True, get_US_equation(STRICKLER_ID))), ['I', 'TAU']) self.assertEqual(eq_name(get_necessary_equations(['U', 'V', 'M', 'US', 'W', 'H'], ['Q', 'TAU', 'US'], True, get_US_equation(MANNING_ID))), ['I', 'J', 'Q', 'TAU']) self.assertEqual(eq_name(get_necessary_equations(['U', 'V', 'M', 'US', 'W', 'S', 'B'], ['Q', 'TAU'], True, get_US_equation(STRICKLER_ID))), ['H', 'I', 'J', 'Q', 'TAU'])
def slf_sedi_chain(args): # Check that float parameters are positive (especially ws!) for arg in ('Cmud', 'ws', 'C', 'M'): if getattr(args, arg) < 0: logger.critical('The argument %s has to be positive' % args) sys.exit(1) with Serafin.Read(args.in_slf, args.lang) as resin: resin.read_header() logger.info(resin.header.summary()) resin.get_time() us_equation = get_US_equation(args.friction_law) necessary_equations = get_necessary_equations(resin.header.var_IDs, ['TAU'], is_2d=True, us_equation=us_equation) if resin.header.nb_frames < 1: logger.critical('The input file must have at least one frame!') sys.exit(1) output_header = resin.header.copy() # Shift mesh coordinates if necessary if args.shift: output_header.transform_mesh( [Transformation(0, 1, 1, args.shift[0], args.shift[1], 0)]) # Toggle output file endianness if necessary if args.toggle_endianness: output_header.toggle_endianness() # Convert to single precision if args.to_single_precision: if resin.header.is_double_precision(): output_header.to_single_precision() else: logger.warn( 'Input file is already single precision! Argument `--to_single_precision` is ignored' ) output_header.empty_variables() output_header.add_variable_from_ID('B') output_header.add_variable_from_ID('EV') with Serafin.Write(args.out_slf, args.lang, overwrite=args.force) as resout: resout.write_header(output_header) prev_time = None prev_tau = None initial_bottom = resin.read_var_in_frame(0, 'B') bottom = copy(initial_bottom) for time_index, time in enumerate(resin.time): tau = do_calculations_in_frame(necessary_equations, resin, time_index, ['TAU'], output_header.np_float_type, is_2d=True, us_equation=us_equation, ori_values={})[0] if prev_time is not None: dt = time - prev_time mean_tau = (prev_tau + tau) / 2 if args.Tcd > 0: bottom += args.Cmud * args.ws * args.C * \ (1 - np.clip(mean_tau/args.Tcd, a_min=None, a_max=1.)) * dt if args.Tce > 0: bottom -= args.Cmud * args.M * (np.clip( mean_tau / args.Tce, a_min=1., a_max=None) - 1.) * dt evol_bottom = bottom - initial_bottom resout.write_entire_frame(output_header, time, np.vstack((bottom, evol_bottom))) prev_time = time prev_tau = tau
def slf_bottom_friction(args): # Check argument consistency if args.in_strickler_zones is not None or args.in_strickler_attr is not None: if args.in_strickler_zones is None or args.in_strickler_attr is None: logger.critical( 'Both arguments `--in_strickler_zones` and `--in_strickler_attr` have to be defined.' ) sys.exit(2) # Read polygons to compute volume if not args.in_polygons.endswith('.shp'): logger.critical('File "%s" is not a shp file.' % args.in_polygons) sys.exit(3) polygons = [] try: for polygon in Shapefile.get_polygons(args.in_polygons): polygons.append(polygon) except ShapefileException as e: logger.error(e) sys.exit(3) if not polygons: logger.error('The file does not contain any polygon.') sys.exit(1) logger.debug('The file contains {} polygon{}.'.format( len(polygons), 's' if len(polygons) > 1 else '')) names = ['Polygon %d' % (i + 1) for i in range(len(polygons))] varIDs = ['US', 'TAU'] out_varIDs = ['W'] + varIDs pos_TAU = out_varIDs.index('TAU') with Serafin.Read(args.in_slf, args.lang) as resin: resin.read_header() if not resin.header.is_2d: logger.critical('The file has to be a 2D Serafin!') sys.exit(3) in_varIDs = resin.header.var_IDs # Compute Strickler values if necessary ori_values = {} if args.in_strickler_zones is not None: if not args.in_strickler_zones.endswith('.shp'): logger.critical('File "%s" is not a shp file.' % args.in_strickler_zones) sys.exit(3) attributes = Shapefile.get_numeric_attribute_names( args.in_strickler_zones) try: index_attr = [attr for _, attr in attributes ].index(args.in_strickler_attr) except ValueError: logger.critical('Attribute "%s" is not found.' % args.in_strickler_attr) sys.exit(1) strickler_zones = [] try: for zone in Shapefile.get_polygons(args.in_strickler_zones): strickler_zones.append(zone) except ShapefileException as e: logger.error(e) sys.exit(3) if not strickler_zones: logger.error('The file does not contain any friction zone.') sys.exit(1) logger.debug('Recomputing friction coefficient values from zones') friction_coeff = np.full( resin.header.nb_nodes_2d, 0.0) # default value for nodes not included in any zone for i, (x, y) in enumerate( zip(tqdm(resin.header.x), tqdm(resin.header.y))): point = Point(x, y) for zone in strickler_zones: if zone.contains(point): friction_coeff[i] = zone.attributes()[index_attr] exit in_varIDs.append('W') ori_values['W'] = friction_coeff else: if 'W' not in resin.header.varIDs: logger.critical('The variable W is missing.') sys.exit(1) us_equation = None if args.friction_law: us_equation = get_US_equation(args.friction_law) resin.get_time() necessary_equations = get_necessary_equations(in_varIDs, out_varIDs, is_2d=True, us_equation=us_equation) calculator = VolumeCalculator(VolumeCalculator.NET, 'TAU', None, resin, names, polygons, 1) calculator.construct_triangles(tqdm) calculator.construct_weights(tqdm) output_header = resin.header.copy() output_header.empty_variables() for var_ID in out_varIDs: output_header.add_variable_from_ID(var_ID) with Serafin.Write(args.out_slf, args.lang, args.force) as resout: resout.write_header(output_header) mode = 'w' if args.force else 'x' with open(args.out_csv, mode, newline='') as csvfile: csvwriter = csv.writer(csvfile, delimiter=args.sep) csvwriter.writerow(['time'] + names) for time_index, time in enumerate(tqdm(resin.time)): values = do_calculations_in_frame( necessary_equations, resin, time_index, out_varIDs, resin.header.np_float_type, is_2d=True, us_equation=strickler_equation, ori_values=ori_values) resout.write_entire_frame(output_header, time, values) row = [time] for j in range(len(calculator.polygons)): weight = calculator.weights[j] volume = calculator.volume_in_frame_in_polygon( weight, values[pos_TAU], calculator.polygons[j]) row.append(volume) csvwriter.writerow(row)
import csv import numpy as np from shapefile import ShapefileException from shapely.geometry import Point import sys from tqdm import tqdm from pyteltools.geom import Shapefile from pyteltools.slf import Serafin from pyteltools.slf.variables import do_calculations_in_frame, get_necessary_equations from pyteltools.slf.variable.variables_2d import FRICTION_LAWS, get_US_equation, STRICKLER_ID from pyteltools.slf.volume import VolumeCalculator from pyteltools.utils.cli_base import logger, PyTelToolsArgParse strickler_equation = get_US_equation(STRICKLER_ID) def slf_bottom_friction(args): # Check argument consistency if args.in_strickler_zones is not None or args.in_strickler_attr is not None: if args.in_strickler_zones is None or args.in_strickler_attr is None: logger.critical( 'Both arguments `--in_strickler_zones` and `--in_strickler_attr` have to be defined.' ) sys.exit(2) # Read polygons to compute volume if not args.in_polygons.endswith('.shp'): logger.critical('File "%s" is not a shp file.' % args.in_polygons) sys.exit(3)