Skip to content

Commit

Permalink
Update data structure and fix bug retrieving trajectories
Browse files Browse the repository at this point in the history
Retrieving trajectories to data/trajectories
moving flow files to data/flow
  • Loading branch information
chraibi committed Sep 29, 2024
1 parent 2c1ac32 commit 95e3e18
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 73 deletions.
File renamed without changes.
File renamed without changes.
23 changes: 13 additions & 10 deletions src/classes/datafactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,31 @@ class Direction:
class DataConfig:
"""Datastructure for the app."""

# trajectories
directory: Path
trajectories_directory: Path
flow_directory: Path
# results
processed_directory: Path
files: List[str] = field(default_factory=list)
# data: Dict[str, List] = field(default_factory=lambda: defaultdict(list))
url: str = "https://go.fzj.de/madras-data"

def __post_init__(self) -> None:
"""Initialize the DataConfig instance by retrieving files for each country."""
self.directory.parent.mkdir(parents=True, exist_ok=True)
# self.data.parent.mkdir(parents=True, exist_ok=True)
logging.info(f"Create {self.processed_directory}")
self.processed_directory.mkdir(parents=True, exist_ok=True)
self.retrieve_files()

def retrieve_files(self) -> None:
"""Retrieve the files for each country specified in the countries list."""
if not self.directory.exists():
st.warning(f"{self.directory} does not exist yet!")
with st.status("Downloading ...", expanded=True):
download_and_unzip_files(self.url, "data.zip", self.directory)
logging.info("Retrieve data ...")
if not self.trajectories_directory.exists():
st.warning(f"{self.trajectories_directory} does not exist yet!")
with st.status("Downloading ...", expanded=False):
download_and_unzip_files(self.url, "data.zip", self.trajectories_directory)

self.files = sorted(glob.glob(f"{self.directory}/*.txt"))
else:
logging.info("Found trajectory directory. Nothing to retrieve!")
self.files = sorted(glob.glob(f"{self.trajectories_directory}/*.txt"))


def increment_frame_start(page_size: int) -> None:
Expand Down Expand Up @@ -96,6 +98,7 @@ def init_session_state() -> None:
"""Init session_state throughout the app."""
path = Path(__file__)
trajectories_directory = path.parent.parent.parent.absolute() / "data" / "trajectories"
flow_directory = path.parent.parent.parent.absolute() / "data" / "flow"
processed_directory = path.parent.parent.parent.absolute() / "data" / "processed"

logging.info(f"{trajectories_directory = }")
Expand Down Expand Up @@ -127,7 +130,7 @@ def init_session_state() -> None:
if not hasattr(st.session_state, "trajectory_data"):
st.session_state.trajectoryData = pedpy.TrajectoryData

dataconfig = DataConfig(trajectories_directory, processed_directory)
dataconfig = DataConfig(trajectories_directory=trajectories_directory, processed_directory=processed_directory, flow_directory=flow_directory)
st.session_state.files = dataconfig.files
st.session_state.config = dataconfig

Expand Down
80 changes: 22 additions & 58 deletions src/tabs/analysis_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ def calculate_or_load_classical_density(
if not Path(precalculated_density).exists():
trajectory_data = load_file(filename)
walkable_area = setup_walkable_area(trajectory_data)
classic_density = pedpy.compute_classic_density(
traj_data=trajectory_data, measurement_area=walkable_area
)
classic_density = pedpy.compute_classic_density(traj_data=trajectory_data, measurement_area=walkable_area)
with open(precalculated_density, "wb") as f:
pickle.dump(classic_density, f)
else:
Expand All @@ -69,9 +67,7 @@ def calculate_or_load_voronoi_diagrams(
if not Path(precalculated_voronoi_polygons).exists():
trajectory_data = load_file(filename)
walkable_area = setup_walkable_area(trajectory_data)
voronoi_polygons = pedpy.compute_individual_voronoi_polygons(
traj_data=trajectory_data, walkable_area=walkable_area
)
voronoi_polygons = pedpy.compute_individual_voronoi_polygons(traj_data=trajectory_data, walkable_area=walkable_area)

with open(precalculated_voronoi_polygons, "wb") as f:
pickle.dump(voronoi_polygons, f, pickle.HIGHEST_PROTOCOL)
Expand Down Expand Up @@ -133,9 +129,7 @@ def calculate_or_load_voronoi_density(
return voronoi_density, intersecting


def calculate_or_load_individual_speed(
precalculated_speed: Path, filename: str, dv: Optional[int]
) -> pd.DataFrame:
def calculate_or_load_individual_speed(precalculated_speed: Path, filename: str, dv: Optional[int]) -> pd.DataFrame:
"""Calculate speed or load precalculated values if exist."""
if not Path(precalculated_speed).exists():
trajectory_data = load_file(filename)
Expand All @@ -154,9 +148,7 @@ def calculate_or_load_individual_speed(
return individual_speed


def calculate_or_load_mean_speed(
precalculated_speed: Path, filename: str, dv: Optional[int]
) -> pd.DataFrame:
def calculate_or_load_mean_speed(precalculated_speed: Path, filename: str, dv: Optional[int]) -> pd.DataFrame:
"""Calculate mean speed per frame if not already done."""
speed = calculate_or_load_individual_speed(precalculated_speed, filename, dv)
trajectory_data = load_file(filename)
Expand Down Expand Up @@ -193,9 +185,7 @@ def calculate_time_series(
measurement_area=ma,
individual_speed=individual_speed,
)
classic_density = pedpy.compute_classic_density(
traj_data=trajectory_data, measurement_area=ma
)
classic_density = pedpy.compute_classic_density(traj_data=trajectory_data, measurement_area=ma)
fig = plot_time_series(classic_density, mean_speed, fps=30)
show_fig(fig, html=True, write=False)
# for plots
Expand Down Expand Up @@ -230,9 +220,7 @@ def calculate_fd_classical(dv: Optional[int]) -> None:
precalculated_density = Path(data_directory / f"density_{basename}.pkl")
precalculated_speed = Path(data_directory / f"speed_{basename}_{dv}.pkl")
speeds[basename] = calculate_or_load_mean_speed(precalculated_speed, filename, dv)
densities[basename] = calculate_or_load_classical_density(
precalculated_density, filename
)
densities[basename] = calculate_or_load_classical_density(precalculated_density, filename)
progress = int(100 * (i + 1) / len(st.session_state.files))
progress_bar.progress(progress)
progress_status.text(f"> {progress}%")
Expand Down Expand Up @@ -260,9 +248,7 @@ def calculate_fd_voronoi_local(dv: Optional[int]) -> None:
figname = data_directory / "fundamental_diagram_voronoi.pdf"
st.sidebar.divider()
msg = st.sidebar.empty()
calculate = msg.button(
"Calculate", type="primary", help="Calculate fundamental diagram Voronoi"
)
calculate = msg.button("Calculate", type="primary", help="Calculate fundamental diagram Voronoi")
if not is_running_locally():
st.warning(
"""
Expand All @@ -271,9 +257,7 @@ def calculate_fd_voronoi_local(dv: Optional[int]) -> None:
"""
)
st.code("streamlit run app.py")
st.warning(
"See [README](https://github.com/PedestrianDynamics/madras-data-app?tab=readme-ov-file#local-execution-guide) for more information."
)
st.warning("See [README](https://github.com/PedestrianDynamics/madras-data-app?tab=readme-ov-file#local-execution-guide) for more information.")

if is_running_locally() and calculate:
with st.status("Calculating Voronoi FD ...", expanded=True):
Expand All @@ -288,23 +272,17 @@ def calculate_fd_voronoi_local(dv: Optional[int]) -> None:
precalculated_voronoi_speed = data_directory / f"voronoi_speed_{basename}.pkl"
precalculated_voronoi_density = data_directory / f"voronoi_density_{basename}.pkl"
# saved files ============
voronoi_polygons[basename] = calculate_or_load_voronoi_diagrams(
precalculated_voronoi_polygons, filename
)
voronoi_polygons[basename] = calculate_or_load_voronoi_diagrams(precalculated_voronoi_polygons, filename)

individual_speed[basename] = calculate_or_load_individual_speed(
precalculated_speed, filename, dv
)
individual_speed[basename] = calculate_or_load_individual_speed(precalculated_speed, filename, dv)
# todo save to files
# trajectory_data = datafactory.load_file(filename)
# walkable_area = setup_walkable_area(trajectory_data)

voronoi_density[basename], intersecting[basename] = (
calculate_or_load_voronoi_density(
precalculated_voronoi_density,
voronoi_polygons[basename],
filename,
)
voronoi_density[basename], intersecting[basename] = calculate_or_load_voronoi_density(
precalculated_voronoi_density,
voronoi_polygons[basename],
filename,
)
voronoi_speed[basename] = calculate_or_load_voronoi_speed(
precalculated_voronoi_speed,
Expand Down Expand Up @@ -443,10 +421,7 @@ def calculate_density_profile(
# help="See [PedPy-documentation](https://pedpy.readthedocs.io/en/latest/user_guide.html#density-profiles).",
# )
with st.expander("Documentation"):
st.write(
"This profile is using 'Gaussian density profile' from [PedPy]"
+ "(https://pedpy.readthedocs.io/en/latest/user_guide.html#density-profiles)."
)
st.write("This profile is using 'Gaussian density profile' from [PedPy]" + "(https://pedpy.readthedocs.io/en/latest/user_guide.html#density-profiles).")
chose_method = "Gaussian"
chose_method = str(chose_method)
method = {
Expand Down Expand Up @@ -514,13 +489,9 @@ def calculate_density_profile(
ax.set_yticklabels([])
base_filename = Path(selected_file).stem
if chose_method == "Gaussian":
figname = Path(
f"density_profile_method_{chose_method}_width_{width}_grid_{grid_size}_{base_filename}.pdf"
)
figname = Path(f"density_profile_method_{chose_method}_width_{width}_grid_{grid_size}_{base_filename}.pdf")
else:
figname = Path(
f"density_profile_method_{chose_method}_grid_{grid_size}_{base_filename}.pdf"
)
figname = Path(f"density_profile_method_{chose_method}_grid_{grid_size}_{base_filename}.pdf")
path = Path(__file__)
data_directory = path.parent.parent.parent.absolute() / "data" / "processed"
figname = data_directory / figname
Expand All @@ -537,10 +508,7 @@ def calculate_speed_profile(
) -> None:
"""Calculate speed profile."""
with st.expander("Documentation"):
st.write(
"This profile is using 'Gaussian speed profile' from [PedPy]"
+ "(https://pedpy.readthedocs.io/en/latest/user_guide.html#speed-profiles)."
)
st.write("This profile is using 'Gaussian speed profile' from [PedPy]" + "(https://pedpy.readthedocs.io/en/latest/user_guide.html#speed-profiles).")
grid_size = st.sidebar.number_input(
"Grid size",
value=0.4,
Expand Down Expand Up @@ -752,9 +720,7 @@ def read_and_plot_outflow(filename: str, sigma: float):
# Preprocess and calculate time difference
df["time"] = pd.to_datetime(df["time"], format="%H:%M:%S")
df["date"] = pd.to_datetime("today").normalize()
df["datetime"] = pd.to_datetime(
df["date"].dt.date.astype(str) + " " + df["time"].dt.time.astype(str)
)
df["datetime"] = pd.to_datetime(df["date"].dt.date.astype(str) + " " + df["time"].dt.time.astype(str))
df["time_difference"] = df["datetime"] - df["datetime"].iloc[0]
df["seconds"] = df["time_difference"].dt.total_seconds()
df["time_difference"] = df["seconds"].diff().fillna(0)
Expand Down Expand Up @@ -789,9 +755,7 @@ def read_and_plot_outflow(filename: str, sigma: float):
def select_file() -> str:
"""Select a file from available options."""
file_name_to_path = {path.split("/")[-1]: path for path in st.session_state.files}
filename = str(
st.selectbox(":open_file_folder: **Select a file**", file_name_to_path, key="tab3_filename")
)
filename = str(st.selectbox(":open_file_folder: **Select a file**", file_name_to_path, key="tab3_filename"))
selected_file = file_name_to_path[filename]
st.session_state.selected_file = selected_file
return selected_file
Expand All @@ -800,8 +764,8 @@ def select_file() -> str:
def handle_outflow(sigma: float):
"""Handle outflow calculation and plotting."""
files = [
st.session_state.config.directory / "chenavard_2022_1210.csv",
st.session_state.config.directory / "constantine_2022_1210.csv",
st.session_state.config.flow_directory / "chenavard_2022_1210.csv",
st.session_state.config.flow_directory / "constantine_2022_1210.csv",
]
for _file in files:
figname = read_and_plot_outflow(_file, sigma)
Expand Down
8 changes: 3 additions & 5 deletions src/ui/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ def init_app_looks() -> None:
repo_name = f"[![Repo]({gh})]({repo})"
c1, c2 = st.sidebar.columns((1.2, 0.5))
c2.markdown(repo_name, unsafe_allow_html=True)
c1.write(
"[![DOI](https://zenodo.org/badge/760394097.svg)](https://zenodo.org/doi/10.5281/zenodo.10694866)"
)
c1.write("[![DOI](https://zenodo.org/badge/760394097.svg)](https://zenodo.org/doi/10.5281/zenodo.10694866)")
st.sidebar.image(str(logo_path), use_column_width=True)


Expand Down Expand Up @@ -87,7 +85,7 @@ def init_sidebar() -> Any:
"Contacts",
"Surveys",
# "Explorer",
"Geometry",
# "Geometry",
],
icons=[
"info-square",
Expand All @@ -97,7 +95,7 @@ def init_sidebar() -> Any:
"exclamation-triangle",
# "graph-up-arrow",
"bi bi-clipboard2-data",
"camera-reels-fill",
# "camera-reels-fill",
],
menu_icon="cast",
default_index=0,
Expand Down

0 comments on commit 95e3e18

Please sign in to comment.