Vamsi Thiriveedhi
commited on
Commit
•
918617e
1
Parent(s):
72491f8
remove vertebra check
Browse filesadd volume check
download parquet file from github instead of hf
- Dockerfile +3 -0
- filter_data_app.py +23 -21
- qual-checks-and-quant-values.parquet +0 -3
Dockerfile
CHANGED
@@ -20,6 +20,9 @@ RUN pip install --no-cache-dir --upgrade pip
|
|
20 |
# Copy the current directory contents into the container at $HOME/app setting the owner to the user
|
21 |
COPY --chown=user . $HOME/app
|
22 |
|
|
|
|
|
|
|
23 |
# Install any needed packages specified in requirements.txt
|
24 |
RUN pip install --no-cache-dir -r requirements.txt
|
25 |
|
|
|
20 |
# Copy the current directory contents into the container at $HOME/app setting the owner to the user
|
21 |
COPY --chown=user . $HOME/app
|
22 |
|
23 |
+
# Download the parquet file from github
|
24 |
+
RUN wget https://github.com/ImagingDataCommons/CloudSegmentatorResults/releases/download/0.0.1/qual_checks_and_quantitative_measurements-wip.parquet
|
25 |
+
|
26 |
# Install any needed packages specified in requirements.txt
|
27 |
RUN pip install --no-cache-dir -r requirements.txt
|
28 |
|
filter_data_app.py
CHANGED
@@ -12,19 +12,19 @@ import seaborn as sns
|
|
12 |
st.set_page_config(layout="wide")
|
13 |
|
14 |
# Local path to the Parquet file
|
15 |
-
LOCAL_PARQUET_FILE = '
|
16 |
|
17 |
@st.cache_data
|
18 |
def load_data(radiomics_feature='Volume from Voxel Summation'):
|
19 |
cols = [
|
20 |
'PatientID',
|
21 |
'StudyInstanceUID',
|
22 |
-
'
|
23 |
'bodyPart',
|
24 |
'laterality',
|
25 |
'segmentation_completeness',
|
26 |
'laterality_check',
|
27 |
-
'
|
28 |
'connected_volumes',
|
29 |
'voxel_num',
|
30 |
radiomics_feature # Include the selected radiomics feature column
|
@@ -62,7 +62,7 @@ def create_upset_plot_failures(df):
|
|
62 |
|
63 |
# Treat 'pass' and null values as passing
|
64 |
df = df.set_index(~((df['segmentation_completeness'] == 'pass') | df['segmentation_completeness'].isnull())).set_index(~((df['laterality_check'] == 'pass') | df['laterality_check'].isnull()), append=True)
|
65 |
-
df = df.set_index(~((df['
|
66 |
df = df.set_index(~((df['connected_volumes'] == 1) | df['connected_volumes'].isnull()), append=True)
|
67 |
df = df[df.index.to_frame().any(axis=1)] # Ignore the case when all conditions are false
|
68 |
|
@@ -75,7 +75,7 @@ def create_upset_plot_failures(df):
|
|
75 |
def create_upset_plot_passes(df):
|
76 |
df = df.to_pandas() # Convert to Pandas DataFrame
|
77 |
df = df.set_index(df['segmentation_completeness'] == 'pass').set_index(df['laterality_check'] == 'pass', append=True)
|
78 |
-
df = df.set_index(df['
|
79 |
df = df.set_index(df['connected_volumes'] == 1, append=True)
|
80 |
df = df[df.index.to_frame().any(axis=1)] # Ignore the case when all conditions are false
|
81 |
|
@@ -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"])
|
100 |
|
101 |
# Load the data
|
102 |
#df = load_data()
|
@@ -112,7 +112,7 @@ def main():
|
|
112 |
'bodyPart': None,
|
113 |
'segmentation_completeness': None,
|
114 |
'laterality_check': None,
|
115 |
-
'
|
116 |
'connected_volumes': None,
|
117 |
'laterality': None,
|
118 |
'radiomics_feature': 'Volume from Voxel Summation', # Default radiomics feature
|
@@ -127,7 +127,7 @@ def main():
|
|
127 |
filters.update({
|
128 |
'segmentation_completeness': None,
|
129 |
'laterality_check': None,
|
130 |
-
'
|
131 |
'connected_volumes': None,
|
132 |
'laterality': None,
|
133 |
#'radiomics_feature': 'Volume from Voxel Summation'
|
@@ -195,7 +195,7 @@ def main():
|
|
195 |
# Update options for other filters based on the current selection
|
196 |
segmentation_completeness_options = [""] + filtered_df['segmentation_completeness'].unique().to_list()
|
197 |
laterality_check_options = [""] + filtered_df['laterality_check'].unique().to_list()
|
198 |
-
|
199 |
connected_volumes_options = filtered_df['connected_volumes'].unique().to_list()
|
200 |
laterality_options = [""] + filtered_df['laterality'].unique().to_list()
|
201 |
voxel_num_options = filtered_df.filter(col('voxel_num').is_not_null()).select('voxel_num').unique().to_pandas().iloc[:, 0].tolist()
|
@@ -226,12 +226,12 @@ def main():
|
|
226 |
on_change=lambda: apply_filter('laterality_check', st.session_state.laterality_check)
|
227 |
)
|
228 |
|
229 |
-
|
230 |
-
"
|
231 |
-
options=
|
232 |
-
index=
|
233 |
-
key='
|
234 |
-
on_change=lambda: apply_filter('
|
235 |
)
|
236 |
|
237 |
connected_volumes = st.selectbox(
|
@@ -249,6 +249,7 @@ def main():
|
|
249 |
value=(min(voxel_num_options),max(voxel_num_options)),
|
250 |
on_change=lambda: apply_filter('voxel_num_values', st.session_state.voxel_num_values)
|
251 |
)
|
|
|
252 |
if min(radiomics_feature_values)!=max(radiomics_feature_values):
|
253 |
radiomics_num_values = st.slider(f"{radiomics_feature} Values",
|
254 |
min_value=min(radiomics_feature_values),
|
@@ -291,6 +292,7 @@ def main():
|
|
291 |
start_idx = (page_number - 1) * page_size
|
292 |
end_idx = min(start_idx + page_size, len(filtered_df)) # Ensure end_idx does not go beyond the dataframe length
|
293 |
paginated_df = filtered_df[start_idx:end_idx].to_pandas() # Convert to Pandas DataFrame
|
|
|
294 |
paginated_df['Viewer Url'] = 'https://viewer.imaging.datacommons.cancer.gov/v3/viewer/?StudyInstanceUIDs='+paginated_df['StudyInstanceUID']
|
295 |
|
296 |
# Display the paginated dataframe
|
@@ -302,10 +304,10 @@ def main():
|
|
302 |
column_config={
|
303 |
"Viewer Url":st.column_config.LinkColumn("StudyInstanceUID",
|
304 |
display_text=r"https:\/\/viewer\.imaging\.datacommons\.cancer\.gov\/v3\/viewer\/\?StudyInstanceUIDs=(.*)"
|
305 |
-
),
|
306 |
|
307 |
},
|
308 |
-
column_order=("PatientID", "Viewer Url", "
|
309 |
hide_index=True,
|
310 |
use_container_width=True
|
311 |
)
|
@@ -379,10 +381,10 @@ def main():
|
|
379 |
SUM(CASE WHEN segmentation_completeness = 'pass' THEN 1 ELSE 0 END) AS pass_count,
|
380 |
SUM(CASE WHEN laterality_check = 'pass' THEN 1 ELSE 0 END) AS laterality_pass_count,
|
381 |
SUM(CASE WHEN laterality_check is not null THEN 1 ELSE 0 END) AS laterality_check_total_count,
|
382 |
-
SUM(CASE WHEN
|
383 |
SUM(CASE WHEN connected_volumes = '1' THEN 1 ELSE 0 END) AS volumes_pass_count
|
384 |
FROM
|
385 |
-
'
|
386 |
GROUP BY
|
387 |
bodyPart, laterality
|
388 |
)
|
@@ -394,8 +396,8 @@ def main():
|
|
394 |
CASE WHEN laterality IS NOT NULL
|
395 |
THEN ROUND((laterality_pass_count * 100.0) / NULLIF(laterality_check_total_count, 0), 2) || '% (' || laterality_pass_count || '/' || laterality_check_total_count || ')'
|
396 |
ELSE 'N/A' END AS laterality_check,
|
397 |
-
ROUND((
|
398 |
-
ROUND((volumes_pass_count * 100.0) / total_count, 2) || '% (' || volumes_pass_count || '/' || total_count || ')' AS
|
399 |
FROM
|
400 |
Checks
|
401 |
ORDER BY
|
|
|
12 |
st.set_page_config(layout="wide")
|
13 |
|
14 |
# Local path to the Parquet file
|
15 |
+
LOCAL_PARQUET_FILE = 'qual_checks_and_quantitative_measurements-wip.parquet'
|
16 |
|
17 |
@st.cache_data
|
18 |
def load_data(radiomics_feature='Volume from Voxel Summation'):
|
19 |
cols = [
|
20 |
'PatientID',
|
21 |
'StudyInstanceUID',
|
22 |
+
'SeriesNumber',
|
23 |
'bodyPart',
|
24 |
'laterality',
|
25 |
'segmentation_completeness',
|
26 |
'laterality_check',
|
27 |
+
'volume_from_voxel_summation_check',
|
28 |
'connected_volumes',
|
29 |
'voxel_num',
|
30 |
radiomics_feature # Include the selected radiomics feature column
|
|
|
62 |
|
63 |
# Treat 'pass' and null values as passing
|
64 |
df = df.set_index(~((df['segmentation_completeness'] == 'pass') | df['segmentation_completeness'].isnull())).set_index(~((df['laterality_check'] == 'pass') | df['laterality_check'].isnull()), append=True)
|
65 |
+
df = df.set_index(~((df['volume_from_voxel_summation_check'] == 'pass') | df['volume_from_voxel_summation_check'].isnull()), append=True)
|
66 |
df = df.set_index(~((df['connected_volumes'] == 1) | df['connected_volumes'].isnull()), append=True)
|
67 |
df = df[df.index.to_frame().any(axis=1)] # Ignore the case when all conditions are false
|
68 |
|
|
|
75 |
def create_upset_plot_passes(df):
|
76 |
df = df.to_pandas() # Convert to Pandas DataFrame
|
77 |
df = df.set_index(df['segmentation_completeness'] == 'pass').set_index(df['laterality_check'] == 'pass', append=True)
|
78 |
+
df = df.set_index(df['volume_from_voxel_summation_check'] == 'pass', append=True)
|
79 |
df = df.set_index(df['connected_volumes'] == 1, append=True)
|
80 |
df = df[df.index.to_frame().any(axis=1)] # Ignore the case when all conditions are false
|
81 |
|
|
|
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()
|
|
|
112 |
'bodyPart': None,
|
113 |
'segmentation_completeness': None,
|
114 |
'laterality_check': None,
|
115 |
+
'volume_from_voxel_summation_check': None,
|
116 |
'connected_volumes': None,
|
117 |
'laterality': None,
|
118 |
'radiomics_feature': 'Volume from Voxel Summation', # Default radiomics feature
|
|
|
127 |
filters.update({
|
128 |
'segmentation_completeness': None,
|
129 |
'laterality_check': None,
|
130 |
+
'volume_from_voxel_summation_check': None,
|
131 |
'connected_volumes': None,
|
132 |
'laterality': None,
|
133 |
#'radiomics_feature': 'Volume from Voxel Summation'
|
|
|
195 |
# Update options for other filters based on the current selection
|
196 |
segmentation_completeness_options = [""] + filtered_df['segmentation_completeness'].unique().to_list()
|
197 |
laterality_check_options = [""] + filtered_df['laterality_check'].unique().to_list()
|
198 |
+
volume_from_voxel_summation_check_options = [""] + filtered_df['volume_from_voxel_summation_check'].unique().to_list()
|
199 |
connected_volumes_options = filtered_df['connected_volumes'].unique().to_list()
|
200 |
laterality_options = [""] + filtered_df['laterality'].unique().to_list()
|
201 |
voxel_num_options = filtered_df.filter(col('voxel_num').is_not_null()).select('voxel_num').unique().to_pandas().iloc[:, 0].tolist()
|
|
|
226 |
on_change=lambda: apply_filter('laterality_check', st.session_state.laterality_check)
|
227 |
)
|
228 |
|
229 |
+
volume_from_voxel_summation_check = st.selectbox(
|
230 |
+
"Minimum Volume of 5 mL",
|
231 |
+
options=volume_from_voxel_summation_check_options,
|
232 |
+
index=volume_from_voxel_summation_check_options.index(filters['volume_from_voxel_summation_check']) if filters['volume_from_voxel_summation_check'] else 0,
|
233 |
+
key='volume_from_voxel_summation_check',
|
234 |
+
on_change=lambda: apply_filter('volume_from_voxel_summation_check', st.session_state.volume_from_voxel_summation_check)
|
235 |
)
|
236 |
|
237 |
connected_volumes = st.selectbox(
|
|
|
249 |
value=(min(voxel_num_options),max(voxel_num_options)),
|
250 |
on_change=lambda: apply_filter('voxel_num_values', st.session_state.voxel_num_values)
|
251 |
)
|
252 |
+
|
253 |
if min(radiomics_feature_values)!=max(radiomics_feature_values):
|
254 |
radiomics_num_values = st.slider(f"{radiomics_feature} Values",
|
255 |
min_value=min(radiomics_feature_values),
|
|
|
292 |
start_idx = (page_number - 1) * page_size
|
293 |
end_idx = min(start_idx + page_size, len(filtered_df)) # Ensure end_idx does not go beyond the dataframe length
|
294 |
paginated_df = filtered_df[start_idx:end_idx].to_pandas() # Convert to Pandas DataFrame
|
295 |
+
paginated_df = paginated_df.rename(columns={"connected_volumes": "connected_components"})
|
296 |
paginated_df['Viewer Url'] = 'https://viewer.imaging.datacommons.cancer.gov/v3/viewer/?StudyInstanceUIDs='+paginated_df['StudyInstanceUID']
|
297 |
|
298 |
# Display the paginated dataframe
|
|
|
304 |
column_config={
|
305 |
"Viewer Url":st.column_config.LinkColumn("StudyInstanceUID",
|
306 |
display_text=r"https:\/\/viewer\.imaging\.datacommons\.cancer\.gov\/v3\/viewer\/\?StudyInstanceUIDs=(.*)"
|
307 |
+
),
|
308 |
|
309 |
},
|
310 |
+
column_order=("PatientID", "Viewer Url", "SeriesNumber","bodyPart","laterality", "segmentation_completeness","laterality_check", "volume_from_voxel_summation_check","connected_components","voxel_num", radiomics_feature),
|
311 |
hide_index=True,
|
312 |
use_container_width=True
|
313 |
)
|
|
|
381 |
SUM(CASE WHEN segmentation_completeness = 'pass' THEN 1 ELSE 0 END) AS pass_count,
|
382 |
SUM(CASE WHEN laterality_check = 'pass' THEN 1 ELSE 0 END) AS laterality_pass_count,
|
383 |
SUM(CASE WHEN laterality_check is not null THEN 1 ELSE 0 END) AS laterality_check_total_count,
|
384 |
+
SUM(CASE WHEN volume_from_voxel_summation_check = 'pass' THEN 1 ELSE 0 END) AS volume_check_pass_count,
|
385 |
SUM(CASE WHEN connected_volumes = '1' THEN 1 ELSE 0 END) AS volumes_pass_count
|
386 |
FROM
|
387 |
+
'qual_checks_and_quantitative_measurements-wip.parquet'
|
388 |
GROUP BY
|
389 |
bodyPart, laterality
|
390 |
)
|
|
|
396 |
CASE WHEN laterality IS NOT NULL
|
397 |
THEN ROUND((laterality_pass_count * 100.0) / NULLIF(laterality_check_total_count, 0), 2) || '% (' || laterality_pass_count || '/' || laterality_check_total_count || ')'
|
398 |
ELSE 'N/A' END AS laterality_check,
|
399 |
+
ROUND((volume_check_pass_count * 100.0) / total_count, 2) || '% (' || volume_check_pass_count || '/' || total_count || ')' AS volume_check_pass_count,
|
400 |
+
ROUND((volumes_pass_count * 100.0) / total_count, 2) || '% (' || volumes_pass_count || '/' || total_count || ')' AS connected_components_check
|
401 |
FROM
|
402 |
Checks
|
403 |
ORDER BY
|
qual-checks-and-quant-values.parquet
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:9cdb5ac665c8bedf906f07ba1ba05232cf9ab2eb9045caec7fa1a3343222e9f2
|
3 |
-
size 1157730459
|
|
|
|
|
|
|
|