Vamsi Thiriveedhi
commited on
Commit
·
fe0dee0
1
Parent(s):
00b3bae
enh: add summary, provide an option to search and sort
Browse files- filter_data_app.py +40 -4
filter_data_app.py
CHANGED
|
@@ -96,7 +96,7 @@ def main():
|
|
| 96 |
st.title("Qualitative Checks of TotalSegmentator Segmentations on NLST")
|
| 97 |
|
| 98 |
# Sidebar widgets for navigation and filtering
|
| 99 |
-
page = st.sidebar.selectbox("Choose a page", ["Summary", "Plots"], help='Change the selection here to view dynamically generated plots')
|
| 100 |
|
| 101 |
# Load the data
|
| 102 |
#df = load_data()
|
|
@@ -370,7 +370,15 @@ def main():
|
|
| 370 |
|
| 371 |
# Define the pages
|
| 372 |
if page == "Summary":
|
| 373 |
-
st.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 374 |
# Execute the SQL to get summary statistics
|
| 375 |
summary_df = duckdb.query("""
|
| 376 |
WITH Checks AS (
|
|
@@ -404,9 +412,37 @@ def main():
|
|
| 404 |
bodyPart, laterality;
|
| 405 |
""").pl()
|
| 406 |
summary_df = summary_df.to_pandas()
|
| 407 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 408 |
|
| 409 |
# elif page == "UpSet Plots":
|
| 410 |
|
| 411 |
if __name__ == "__main__":
|
| 412 |
-
main()
|
|
|
|
| 96 |
st.title("Qualitative Checks of TotalSegmentator Segmentations on NLST")
|
| 97 |
|
| 98 |
# Sidebar widgets for navigation and filtering
|
| 99 |
+
page = st.sidebar.selectbox("Choose a page", ["Summary", "Plots"], help='Change the selection here to view summary of hueristics or dynamically generated plots')
|
| 100 |
|
| 101 |
# Load the data
|
| 102 |
#df = load_data()
|
|
|
|
| 370 |
|
| 371 |
# Define the pages
|
| 372 |
if page == "Summary":
|
| 373 |
+
st.markdown('''
|
| 374 |
+
This dashboard presents a summary of four rule-based checks applied to over 9.5 million segmentations from
|
| 375 |
+
TotalSegmentator(v1) on 125k+ NLST CT scans, displaying the percentage of segmentations passing each check
|
| 376 |
+
to highlight potential quality issues
|
| 377 |
+
- segmentation completeness (ensuring empty slices above and below)
|
| 378 |
+
- laterality (confirming correct left/right labeling)
|
| 379 |
+
- connected components (verifying single, continuous regions)
|
| 380 |
+
- minimum volume from voxel summation (filtering out artifacts smaller than 5mL)
|
| 381 |
+
''')
|
| 382 |
# Execute the SQL to get summary statistics
|
| 383 |
summary_df = duckdb.query("""
|
| 384 |
WITH Checks AS (
|
|
|
|
| 412 |
bodyPart, laterality;
|
| 413 |
""").pl()
|
| 414 |
summary_df = summary_df.to_pandas()
|
| 415 |
+
|
| 416 |
+
# Create a copy of the dataframe for sorting
|
| 417 |
+
sort_df = summary_df.copy()
|
| 418 |
+
|
| 419 |
+
# Extract numeric values for sorting
|
| 420 |
+
for column in sort_df.columns[2:]:
|
| 421 |
+
sort_df[column] = sort_df[column].str.extract('(\d+.\d+)').astype(float)
|
| 422 |
+
|
| 423 |
+
# Add dropdown for column selection
|
| 424 |
+
col_to_sort = st.sidebar.selectbox('Select column to sort by:', sort_df.columns)
|
| 425 |
+
|
| 426 |
+
# Add checkbox for sorting order
|
| 427 |
+
if st.sidebar.checkbox('Sort in descending order'):
|
| 428 |
+
sort_order = sort_df.sort_values(col_to_sort, ascending=False).index
|
| 429 |
+
else:
|
| 430 |
+
sort_order = sort_df.sort_values(col_to_sort).index
|
| 431 |
+
|
| 432 |
+
# Apply the sorting order to the original dataframe
|
| 433 |
+
summary_df = summary_df.reindex(sort_order)
|
| 434 |
+
|
| 435 |
+
# Add text input for body part search
|
| 436 |
+
search_term = st.sidebar.text_input('Enter a body part to search:')
|
| 437 |
+
|
| 438 |
+
# Filter dataframe based on search term
|
| 439 |
+
summary_df = summary_df[summary_df['bodyPart'].str.contains(search_term, case=False, na=False)]
|
| 440 |
+
|
| 441 |
+
st.dataframe(summary_df, hide_index=True, use_container_width=True, height=1500)
|
| 442 |
+
|
| 443 |
+
|
| 444 |
|
| 445 |
# elif page == "UpSet Plots":
|
| 446 |
|
| 447 |
if __name__ == "__main__":
|
| 448 |
+
main()
|