Beispiel #1
0
def network(
    trace_file: Path = typer.Argument(...,
                                      exists=True,
                                      dir_okay=False,
                                      help=TRACE_FILE_HELP),
    area_file: Path = typer.Argument(...,
                                     exists=True,
                                     dir_okay=False,
                                     help=AREA_FILE_HELP),
    snap_threshold: float = typer.Option(0.001, help=SNAP_THRESHOLD_HELP),
    determine_branches_nodes: bool = typer.Option(
        True,
        help=
        "Whether to determine branches and nodes as part of analysis. Recommended.",
    ),
    name: Optional[str] = typer.Option(
        None,
        help="Name for Network. Used when saving outputs and as plot titles."),
    circular_target_area: bool = typer.Option(
        False, help="Is/are target area(s) circles?"),
    truncate_traces: bool = typer.Option(
        True,
        help="Whether to cut traces at target area boundary. Recommended."),
    censoring_area: Optional[Path] = typer.Option(
        None,
        help=
        "Path to area data that delineates censored areas within target areas.",
    ),
    branches_output: Optional[Path] = typer.Option(
        None, help="Where to save branch data."),
    nodes_output: Optional[Path] = typer.Option(
        None, help="Where to save node data."),
    general_output: Optional[Path] = typer.Option(
        None,
        help="Where to save general network analysis outputs e.g. plots."),
    parameters_output: Optional[Path] = typer.Option(
        None, help="Where to save numerical parameter data from analysis."),
):
    """
    Analyze the geometry and topology of trace network.
    """
    network_name = name if name is not None else area_file.stem
    console = Console()

    console.print(
        Text.assemble("Performing network analysis of ",
                      (network_name, "bold green"), "."))

    network = Network(
        trace_gdf=read_geofile(trace_file),
        area_gdf=read_geofile(area_file),
        snap_threshold=snap_threshold,
        determine_branches_nodes=determine_branches_nodes,
        name=network_name,
        circular_target_area=circular_target_area,
        truncate_traces=truncate_traces,
        censoring_area=read_geofile(censoring_area)
        if censoring_area is not None else gpd.GeoDataFrame(),
    )
    (
        general_output_path,
        branches_output_path,
        nodes_output_path,
        parameters_output_path,
    ) = default_network_output_paths(
        network_name=network_name,
        general_output=general_output,
        branches_output=branches_output,
        nodes_output=nodes_output,
        parameters_output=parameters_output,
    )
    # Save branches and nodes
    console.print(
        Text.assemble(
            "Saving branches to ",
            (str(branches_output_path), "bold green"),
            " and nodes to ",
            (str(nodes_output_path), "bold green"),
            ".",
        ))
    network.branch_gdf.to_file(branches_output_path, driver="GPKG")
    network.node_gdf.to_file(nodes_output_path, driver="GPKG")

    console.print(rich_table_from_parameters(network.parameters))

    pd.DataFrame([network.numerical_network_description()
                  ]).to_csv(parameters_output_path)

    console.print(
        Text.assemble(
            "Saving extensive network parameter csv to path:\n",
            (str(parameters_output_path), "bold green"),
        ))

    # Plot ternary XYI-node proportion plot
    fig, _, _ = network.plot_xyi()
    save_fig(fig=fig, results_dir=general_output_path, name="xyi_ternary_plot")

    # Plot ternary branch proportion plot
    fig, _, _ = network.plot_branch()
    save_fig(fig=fig,
             results_dir=general_output_path,
             name="branch_ternary_plot")

    # Plot trace azimuth rose plot
    _, fig, _ = network.plot_trace_azimuth()
    save_fig(fig=fig, results_dir=general_output_path, name="trace_azimuth")

    # Plot trace length distribution plot
    _, fig, _ = network.plot_trace_lengths()
    save_fig(fig=fig,
             results_dir=general_output_path,
             name="trace_length_distribution")
Beispiel #2
0
def network_extensive_testing(
    network: Network,
    traces: gpd.GeoDataFrame,
    area: gpd.GeoDataFrame,
    snap_threshold: float,
):
    """
    Test Network attributes extensively.
    """
    # Test resetting
    copy_trace_gdf = network.trace_data._line_gdf.copy()
    copy_branch_gdf = network.branch_data._line_gdf.copy()

    # Test resetting
    network.reset_length_data()
    assert_frame_equal(copy_trace_gdf, network.trace_data._line_gdf)
    assert_frame_equal(copy_branch_gdf, network.branch_data._line_gdf)

    network_anisotropy = network.anisotropy
    assert isinstance(network_anisotropy, tuple)
    assert isinstance(network_anisotropy[0], np.ndarray)
    assert isinstance(network.trace_length_set_array, np.ndarray)
    assert isinstance(network.branch_length_set_array, np.ndarray)

    # Test passing old branch and node data
    branch_copy = network.branch_gdf.copy()
    network_test = Network(
        trace_gdf=traces,
        area_gdf=area,
        name="teeest_with_old",
        branch_gdf=branch_copy,
        node_gdf=network.node_gdf.copy(),
        determine_branches_nodes=False,
        truncate_traces=True,
        snap_threshold=snap_threshold,
    )

    assert_frame_equal(network_test.branch_gdf, branch_copy)

    # Test plotting
    fig_returns = network.plot_branch()
    assert fig_returns is not None
    fig, ax, tax = fig_returns
    assert isinstance(fig, Figure)
    assert isinstance(ax, Axes)
    assert isinstance(tax, TernaryAxesSubplot)
    plt.close("all")

    # Test plotting
    fig_returns = network.plot_xyi()
    assert fig_returns is not None
    fig, ax, tax = fig_returns
    assert isinstance(fig, Figure)
    assert isinstance(ax, Axes)
    assert isinstance(tax, TernaryAxesSubplot)
    plt.close("all")

    for plot in (
        "plot_parameters",
        "plot_anisotropy",
        "plot_trace_azimuth_set_count",
        "plot_branch_azimuth_set_count",
        "plot_trace_length_set_count",
        "plot_branch_length_set_count",
        "plot_trace_azimuth",
        "plot_branch_azimuth",
        "plot_trace_lengths",
        "plot_branch_lengths",
        "plot_trace_azimuth_set_lengths",
        "plot_branch_azimuth_set_lengths",
    ):
        # Test plotting
        fig_returns = getattr(network, plot)()
        assert fig_returns is not None
        if len(fig_returns) == 2:
            fig, ax = fig_returns
        elif len(fig_returns) == 3 and "length" in plot:
            other, fig, ax = fig_returns
            if not isinstance(other, powerlaw.Fit):
                # assume fits, figs, axes from plot_*_set_lengths
                assert isinstance(other, list)
                assert isinstance(other[0], powerlaw.Fit)
                # Check just the first value of returns
                assert len(other) == len(fig)
                assert len(other) == len(ax)
                assert len(other) == len(network.azimuth_set_names)
                other, fig, ax = other[0], fig[0], ax[0]
        elif len(fig_returns) == 3 and "azimuth" in plot:
            other, fig, ax = fig_returns
            assert isinstance(other, AzimuthBins)
        else:
            raise ValueError("Expected 3 max returns.")
        assert isinstance(fig, Figure)
        assert isinstance(ax, (Axes, PolarAxes))
        plt.close("all")