Skip to content

Commit

Permalink
feat: Multi link redundancy - adjust calculating diff_time o -diff_le…
Browse files Browse the repository at this point in the history
…ngth (#393)

* chore: difference in alt and base transport time is corrected

* chore: _row.get("avgspeed", None) added and row.get("length", None)

* chore: dict.get(key, None) introduced

* chore: (WeighingEnum.TIME.config_value not in columns added + edge_remove condition updated

---------

Co-authored-by: Carles S. Soriano Perez <[email protected]>
  • Loading branch information
sahand-asgarpour and Carsopre authored Mar 28, 2024
1 parent 0590208 commit c348912
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 20 deletions.
69 changes: 59 additions & 10 deletions ra2ce/analysis/indirect/multi_link_redundancy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import osmnx
import pandas as pd
from geopandas import GeoDataFrame
import geopandas as gpd

from ra2ce.analysis.analysis_config_data.analysis_config_data import (
AnalysisSectionIndirect,
Expand Down Expand Up @@ -39,6 +40,35 @@ def __init__(
self.output_path = analysis_input.output_path
self.hazard_names = analysis_input.hazard_names

def _update_time(self, gdf_calculated: pd.DataFrame, gdf_graph: gpd.GeoDataFrame):
"""
updates the time column with the calculated dataframe and updates the rest of the gdf_graph if time is None.
"""
if (
WeighingEnum.TIME.config_value not in gdf_graph.columns
or WeighingEnum.TIME.config_value not in gdf_calculated.columns
):
return gdf_graph
gdf_graph[WeighingEnum.TIME.config_value] = gdf_calculated[
WeighingEnum.TIME.config_value
]
for i, row in gdf_graph.iterrows():
row_avgspeed = row.get("avgspeed", None)
row_length = row.get("length", None)
if (
pd.isna(row[WeighingEnum.TIME.config_value])
and row_avgspeed
and row_length
):
gdf_graph.at[i, WeighingEnum.TIME.config_value] = (
row_length * 1e-3 / row_avgspeed
)
else:
gdf_graph.at[i, WeighingEnum.TIME.config_value] = row.get(
WeighingEnum.TIME.config_value, None
)
return gdf_graph

def execute(self) -> GeoDataFrame:
"""Calculates the multi-link redundancy of a NetworkX graph.
Expand All @@ -49,6 +79,15 @@ def execute(self) -> GeoDataFrame:
Returns:
aggregated_results (GeoDataFrame): The results of the analysis aggregated into a table.
"""

def _is_not_none(value):
return (
value is not None
and value is not pd.NA
and not pd.isna(value)
and not np.isnan(value)
)

results = []
master_graph = copy.deepcopy(self.graph_file_hazard.get_graph())
for hazard in self.hazard_names.names:
Expand All @@ -72,7 +111,15 @@ def execute(self) -> GeoDataFrame:
edges_remove = [
e
for e in edges_remove
if (e[-1][hazard_name] > float(self.analysis.threshold))
if (hazard_name in e[-1])
and (
_is_not_none(e[-1][hazard_name])
and (e[-1][hazard_name] > float(self.analysis.threshold))
and (
("bridge" not in e[-1])
or ("bridge" in e[-1] and e[-1]["bridge"] != "yes")
)
)
]

_graph.remove_edges_from(edges_remove)
Expand All @@ -82,6 +129,7 @@ def execute(self) -> GeoDataFrame:
"v",
f"alt_{self.analysis.weighing.config_value}",
"alt_nodes",
f"diff_{self.analysis.weighing.config_value}",
"connected",
]

Expand Down Expand Up @@ -109,11 +157,20 @@ def execute(self) -> GeoDataFrame:
alt_value = _weighing_analyser.calculate_distance()
alt_nodes, connected = np.NaN, 0

diff = round(
alt_value
- _weighing_analyser.weighing_data[
self.analysis.weighing.config_value
],
3,
)

data = {
"u": [u],
"v": [v],
f"alt_{self.analysis.weighing.config_value}": [alt_value],
"alt_nodes": [alt_nodes],
f"diff_{self.analysis.weighing.config_value}": diff,
"connected": [connected],
}
_weighing_analyser.extend_graph(data)
Expand All @@ -135,15 +192,7 @@ def execute(self) -> GeoDataFrame:
else:
gdf = gdf.merge(df_calculated, how="left", on=["u", "v"])

# calculate the differences in distance and time
# previously here you find if dist==dist which is a critical bug. Replaced by verifying dist is a value.
gdf[f"diff_{self.analysis.weighing.config_value}"] = [
round(alt - base, 2) if alt else np.NaN
for (alt, base) in zip(
gdf[f"alt_{self.analysis.weighing.config_value}"],
gdf[f"{self.analysis.weighing.config_value}"],
)
]
gdf = self._update_time(df_calculated, gdf)

gdf["hazard"] = hazard_name

Expand Down
35 changes: 25 additions & 10 deletions ra2ce/analysis/indirect/weighing_analysis/time_weighing_analysis.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import geopandas as gpd
import numpy as np
import pandas as pd

from ra2ce.analysis.analysis_config_data.enums.weighing_enum import WeighingEnum
from ra2ce.analysis.indirect.weighing_analysis.weighing_analysis_protocol import (
WeighingAnalysisProtocol,
Expand All @@ -13,21 +16,33 @@ def __init__(self) -> None:
self.time_list = []

def _calculate_time(self) -> float:
_calculated_time = round(
(self.weighing_data["length"] * 1e-3) / self.weighing_data["avgspeed"],
2,
) # in hours and avg speed in km/h
self.weighing_data[WeighingEnum.TIME.config_value] = _calculated_time
return round(_calculated_time, 2)
length = self.weighing_data.get("length", None)
avgspeed = self.weighing_data.get("avgspeed", None)
if length and avgspeed:
_calculated_time = round(
(length * 1e-3) / avgspeed,
3,
) # in hours and avg speed in km/h
self.weighing_data[WeighingEnum.TIME.config_value] = _calculated_time
return round(_calculated_time, 3)
else:
return np.nan

def calculate_distance(self) -> float:
self.time_list.append(self._calculate_time())
return self.time_list[-1]

def calculate_alternative_distance(self, alt_dist: float) -> float:
alt_time = (alt_dist * 1e-3) / self.weighing_data["avgspeed"] # in hours
self.time_list.append(self._calculate_time())
return alt_time
avgspeed = self.weighing_data.get("avgspeed", None)
if avgspeed:
alt_time = (alt_dist * 1e-3) / avgspeed # in hours
self.time_list.append(self._calculate_time())
return alt_time
else:
return np.nan

def extend_graph(self, gdf_graph: gpd.GeoDataFrame | dict) -> None:
gdf_graph[WeighingEnum.TIME.config_value] = self.time_list
if isinstance(gdf_graph, gpd.GeoDataFrame):
gdf_graph[WeighingEnum.TIME.config_value] = self.time_list
elif isinstance(gdf_graph, dict):
gdf_graph[WeighingEnum.TIME.config_value] = [self.time_list[-1]]

0 comments on commit c348912

Please sign in to comment.