|
import pandas as pd |
|
import plotly.express as px |
|
import streamlit as st |
|
|
|
from process_kpi.process_lte_capacity import process_lte_bh_report |
|
from utils.convert_to_excel import convert_lte_analysis_dfs |
|
from utils.kpi_analysis_utils import LteCapacity |
|
|
|
st.title("📊 LTE Capacity Analysis") |
|
doc_col, image_col = st.columns(2) |
|
|
|
with doc_col: |
|
st.write( |
|
""" |
|
The report analyzes LTE capacity based on: |
|
- Dump file required |
|
- BH Cell level KPI report in CSV format |
|
- Availability and PRB usage thresholds |
|
""" |
|
) |
|
|
|
with image_col: |
|
st.image("./assets/lte_capacity.png", width=250) |
|
|
|
file1, file2 = st.columns(2) |
|
|
|
with file1: |
|
uploaded_dump = st.file_uploader("Upload Dump file in xlsb format", type="xlsb") |
|
with file2: |
|
uploaded_bh_report = st.file_uploader( |
|
"Upload LTE Busy Hour Report in CSV format", type="csv" |
|
) |
|
|
|
|
|
param_col1, param_col2 = st.columns(2) |
|
param_col3, param_col4 = st.columns(2) |
|
param_col5, param_col6 = st.columns(2) |
|
|
|
with param_col1: |
|
num_last_days = st.number_input( |
|
"Number of last days for analysis", value=7, min_value=1 |
|
) |
|
|
|
with param_col2: |
|
num_threshold_days = st.number_input( |
|
"Number of days for threshold", value=3, min_value=1 |
|
) |
|
|
|
with param_col3: |
|
availability_threshold = st.number_input( |
|
"Availability threshold (%)", value=95.0, min_value=0.0, max_value=100.0 |
|
) |
|
|
|
with param_col4: |
|
prb_usage_threshold = st.number_input( |
|
"PRB usage threshold (%)", value=80.0, min_value=0.0, max_value=100.0 |
|
) |
|
|
|
with param_col5: |
|
prb_diff_between_cells = st.number_input( |
|
"Maximum PRB usage difference between cells (%)", |
|
value=20.0, |
|
min_value=0.0, |
|
max_value=100.0, |
|
) |
|
|
|
with param_col6: |
|
|
|
|
|
main_prb_to_use = st.selectbox( |
|
"Main PRB to use", |
|
["DL PRB Util p TTI Lev_10", "E-UTRAN Avg PRB usage per TTI DL"], |
|
index=1, |
|
) |
|
|
|
|
|
if uploaded_dump is not None and uploaded_bh_report is not None: |
|
if st.button("Analyze Data", type="primary"): |
|
with st.spinner("Processing data..."): |
|
results = process_lte_bh_report( |
|
dump_path=uploaded_dump, |
|
bh_report_path=uploaded_bh_report, |
|
num_last_days=num_last_days, |
|
num_threshold_days=num_threshold_days, |
|
availability_threshold=availability_threshold, |
|
prb_usage_threshold=prb_usage_threshold, |
|
prb_diff_between_cells_threshold=prb_diff_between_cells, |
|
main_prb_to_use=main_prb_to_use, |
|
) |
|
if results is not None: |
|
bh_report: pd.DataFrame = results[0] |
|
lte_analysis_df: pd.DataFrame = results[1] |
|
LteCapacity.final_results = convert_lte_analysis_dfs( |
|
[lte_analysis_df, bh_report], ["LTE_Analysis", "LTE_BH_Report"] |
|
) |
|
st.download_button( |
|
on_click="ignore", |
|
type="primary", |
|
label="Download the Analysis Report", |
|
data=LteCapacity.final_results, |
|
file_name="LTE_Analysis_Report.xlsx", |
|
mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", |
|
) |
|
st.write(lte_analysis_df) |
|
|
|
st.markdown("***") |
|
st.markdown(":blue[**Final comment distribution**]") |
|
final_comments_df = ( |
|
lte_analysis_df.groupby("final_comments") |
|
.size() |
|
.reset_index(name="count") |
|
.sort_values(by="count", ascending=False) |
|
) |
|
final_comments_col1, final_comments_col2 = st.columns((1, 3)) |
|
with final_comments_col1: |
|
st.write(final_comments_df) |
|
with final_comments_col2: |
|
fig = px.pie( |
|
final_comments_df, |
|
names="final_comments", |
|
values="count", |
|
hover_name="final_comments", |
|
hover_data=["count"], |
|
title="Final comment distribution", |
|
) |
|
fig.update_layout(height=600) |
|
fig.update_traces( |
|
texttemplate="%{label}: %{value}", |
|
textfont_size=15, |
|
textposition="outside", |
|
) |
|
st.plotly_chart(fig, use_container_width=True) |
|
|
|
st.markdown("***") |
|
st.markdown(":blue[**Congested cells distribution**]") |
|
congested_cells_df = ( |
|
lte_analysis_df[lte_analysis_df["num_congested_cells"] > 0] |
|
.groupby("final_comments") |
|
.size() |
|
.reset_index(name="count") |
|
.sort_values(by="count", ascending=False) |
|
) |
|
congested_cells_col1, congested_cells_col2 = st.columns((1, 3)) |
|
with congested_cells_col1: |
|
st.write(congested_cells_df) |
|
with congested_cells_col2: |
|
fig = px.pie( |
|
congested_cells_df, |
|
names="final_comments", |
|
values="count", |
|
hover_name="final_comments", |
|
hover_data=["count"], |
|
title="Congested cells distribution", |
|
) |
|
fig.update_layout(height=600) |
|
fig.update_traces( |
|
texttemplate="%{label}: %{value}", |
|
textfont_size=15, |
|
textposition="outside", |
|
) |
|
st.plotly_chart(fig, use_container_width=True) |
|
|
|
|
|
st.markdown("***") |
|
st.markdown(":blue[**Congested cells distribution per Region**]") |
|
congested_cells_region_df = ( |
|
lte_analysis_df[lte_analysis_df["num_congested_cells"] > 0] |
|
.groupby(["Region", "final_comments"]) |
|
.size() |
|
.reset_index(name="count") |
|
.sort_values(by="count", ascending=False) |
|
) |
|
congested_cells_region_col1, congested_cells_region_col2 = st.columns( |
|
(1, 3) |
|
) |
|
with congested_cells_region_col1: |
|
st.write(congested_cells_region_df) |
|
with congested_cells_region_col2: |
|
fig = px.bar( |
|
congested_cells_region_df, |
|
x="Region", |
|
y="count", |
|
color="final_comments", |
|
title="Congested cells distribution per Region", |
|
) |
|
fig.update_layout(height=600) |
|
fig.update_traces( |
|
texttemplate="%{value}", textfont_size=15, textposition="outside" |
|
) |
|
st.plotly_chart(fig, use_container_width=True) |
|
|
|
st.markdown("***") |
|
st.markdown( |
|
":blue[**Congested cells distribution per Region groupby Region**]" |
|
) |
|
congested_cells_region_groupby_region_df = ( |
|
lte_analysis_df[lte_analysis_df["num_congested_cells"] > 0] |
|
.groupby(["Region"]) |
|
.size() |
|
.reset_index(name="count") |
|
.sort_values(by="count", ascending=False) |
|
) |
|
( |
|
congested_cells_region_groupby_region_col1, |
|
congested_cells_region_groupby_region_col2, |
|
) = st.columns((1, 3)) |
|
with congested_cells_region_groupby_region_col1: |
|
st.write(congested_cells_region_groupby_region_df) |
|
with congested_cells_region_groupby_region_col2: |
|
fig = px.bar( |
|
congested_cells_region_groupby_region_df, |
|
x="Region", |
|
y="count", |
|
title="Congested cells distribution per Region groupby Region", |
|
) |
|
fig.update_layout(height=600) |
|
fig.update_traces( |
|
texttemplate="%{value}", textfont_size=15, textposition="outside" |
|
) |
|
st.plotly_chart(fig, use_container_width=True) |
|
|
|
st.markdown("***") |
|
st.markdown(":blue[**Final comments distribution**]") |
|
map_df = lte_analysis_df[ |
|
["code", "Longitude", "Latitude", "final_comments"] |
|
].dropna(subset=["code", "Longitude", "Latitude", "final_comments"]) |
|
|
|
map_df["size"] = 20 |
|
|
|
fig = px.scatter_map( |
|
map_df, |
|
lat="Latitude", |
|
lon="Longitude", |
|
color="final_comments", |
|
size="size", |
|
zoom=10, |
|
height=600, |
|
title="Final comments distribution", |
|
hover_data={ |
|
"code": True, |
|
"final_comments": True, |
|
}, |
|
hover_name="code", |
|
) |
|
fig.update_layout(mapbox_style="open-street-map") |
|
st.plotly_chart(fig, use_container_width=True) |
|
|