Exemplo n.º 1
0
def slf_max_over_files(args):
    if args.vars is None:
        with Serafin.Read(args.in_slfs[0], args.lang) as resin:
            resin.read_header()
            var_IDs = resin.header.var_IDs if args.vars is None else args.vars
    else:
        var_IDs = args.vars

    if args.operation == 'max':
        fun = np.maximum
    elif args.operation == 'min':
        fun = np.minimum
    else:
        raise NotImplementedError

    # Read polygons
    if args.in_polygons is not None:
        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.info('The file contains {} polygon{}.'.format(len(polygons), 's' if len(polygons) > 1 else ''))
    else:
        polygons = None

    output_header = None
    out_values = None  # min or max values
    mask_nodes = None
    for i, in_slf in enumerate(args.in_slfs):
        with Serafin.Read(in_slf, args.lang) as resin:
            resin.read_header()
            logger.info(resin.header.summary())
            if not resin.header.is_2d:
                logger.critical('The file has to be a 2D Serafin!')
                sys.exit(3)
            resin.get_time()

            for var_ID in var_IDs:
                if var_ID not in resin.header.var_IDs:
                    logger.critical('The variable %s is missing in %s' % (var_ID, in_slf))
                    sys.exit(3)

            if i == 0:
                output_header = resin.header.copy()
                output_header.empty_variables()
                for var_ID in var_IDs:
                    output_header.add_variable_from_ID(var_ID)
                out_values = np.empty((output_header.nb_var, output_header.nb_nodes),
                                      dtype=output_header.np_float_type)
                if polygons is not None:
                    mask_nodes = np.zeros(output_header.nb_nodes, dtype=bool)
                    for idx_node, (x, y) in enumerate(zip(output_header.x, output_header.y)):
                        point = Point(x, y)
                        for polygon in polygons:
                            if polygon.contains(point):
                                mask_nodes[idx_node] = True
                                break
                    logger.info('Number of nodes inside polygon(s): %i (over %i)'
                                % (mask_nodes.sum(), output_header.nb_nodes))
                else:
                    mask_nodes = np.ones(output_header.nb_nodes, dtype=bool)
            else:
                if not resin.header.same_2d_mesh(output_header):
                    logger.critical('The mesh of %s is different from the first one' % in_slf)
                    sys.exit(1)

            for time_index, time in enumerate(resin.time):
                for j, var_ID in enumerate(var_IDs):
                    values = resin.read_var_in_frame(time_index, var_ID)
                    if time_index == 0 and i == 0:
                        out_values[j, :] = values
                    else:
                        out_values[j, mask_nodes] = fun(out_values[j, mask_nodes], values[mask_nodes])

    with Serafin.Write(args.out_slf, args.lang, overwrite=args.force) as resout:
        resout.write_header(output_header)
        resout.write_entire_frame(output_header, 0.0, out_values)
Exemplo n.º 2
0
                    help='upper variable',
                    metavar='VA',
                    required=True)
parser.add_argument('--lower_var',
                    help='lower variable',
                    metavar='VB',
                    default=None)
parser.add_argument('--detailed',
                    help='add positive and negative volumes',
                    action='store_true')

parser.add_known_argument('out_csv')
parser.add_group_general(['force', 'verbose'])

if __name__ == '__main__':
    args = parser.parse_args()

    try:
        slf_volume(args)
    except (Serafin.SerafinRequestError, Serafin.SerafinValidationError):
        # Message is already reported by slf logger
        sys.exit(1)
    except FileNotFoundError as e:
        logger.error('Input file %s not found.' % e.filename)
        sys.exit(3)
    except FileExistsError as e:
        logger.error(
            'Output file %s already exists. Remove it or add `--force` argument'
            % e.filename)
        sys.exit(3)
Exemplo n.º 3
0
def slf_volume(args):
    # Read set of lines from input file
    polygons = []
    if args.in_polygons.endswith('.i2s'):
        with BlueKenue.Read(args.in_polygons) as f:
            f.read_header()
            for poly in f.get_polygons():
                polygons.append(poly)
    elif args.in_polygons.endswith('.shp'):
        try:
            for polygon in Shapefile.get_polygons(args.in_polygons):
                polygons.append(polygon)
        except ShapefileException as e:
            logger.error(e)
            sys.exit(3)
    else:
        logger.error('File "%s" is not a i2s or shp file.' % args.in_polygons)
        sys.exit(2)

    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))]

    # Read Serafin file
    with Serafin.Read(args.in_slf, args.lang) as resin:
        resin.read_header()
        logger.info(resin.header.summary())
        resin.get_time()

        if not resin.header.is_2d:
            logger.error('The file has to be a 2D Serafin!')
            sys.exit(3)

        # Check variables consistency
        if args.upper_var not in resin.header.var_IDs:
            logger.error('Upper variable "%s" is not in Serafin file' %
                         args.upper_var)
            sys.exit(1)
        upper_var = args.upper_var
        lower_var = args.lower_var
        if args.lower_var is not None:
            if args.lower_var == 'init':
                lower_var = VolumeCalculator.INIT_VALUE
            else:
                if lower_var not in resin.header.var_IDs:
                    logger.error('Lower variable "%s" is not in Serafin file' %
                                 lower_var)
                    sys.exit(1)

        if args.detailed:
            volume_type = VolumeCalculator.POSITIVE
        else:
            volume_type = VolumeCalculator.NET
        calculator = VolumeCalculator(volume_type, upper_var, lower_var, resin,
                                      names, polygons, args.ech)
        calculator.construct_triangles(tqdm)
        calculator.construct_weights(tqdm)

        result = []
        for time_index in tqdm(calculator.time_indices, unit='frame'):
            i_result = [str(resin.time[time_index])]
            values = calculator.read_values_in_frame(time_index)

            for j in range(len(calculator.polygons)):
                weight = calculator.weights[j]
                volume = calculator.volume_in_frame_in_polygon(
                    weight, values, calculator.polygons[j])
                if calculator.volume_type == VolumeCalculator.POSITIVE:
                    for v in volume:
                        i_result.append(settings.FMT_FLOAT.format(v))
                else:
                    i_result.append(settings.FMT_FLOAT.format(volume))
            result.append(i_result)

        # Write CSV
        mode = 'w' if args.force else 'x'
        with open(args.out_csv, mode) as out_csv:
            calculator.write_csv(result, out_csv, args.sep)
Exemplo n.º 4
0
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)