Vamsi Thiriveedhi commited on
Commit
918617e
1 Parent(s): 72491f8

remove vertebra check

Browse files

add volume check
download parquet file from github instead of hf

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 = 'qual-checks-and-quant-values.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
- 'series_with_vertabra_on_every_slice',
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['series_with_vertabra_on_every_slice'] == 'pass') | df['series_with_vertabra_on_every_slice'].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,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['series_with_vertabra_on_every_slice'] == '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,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
- 'series_with_vertabra_on_every_slice': None,
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
- 'series_with_vertabra_on_every_slice': None,
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
- series_with_vertabra_on_every_slice_options = [""] + filtered_df['series_with_vertabra_on_every_slice'].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,12 +226,12 @@ def main():
226
  on_change=lambda: apply_filter('laterality_check', st.session_state.laterality_check)
227
  )
228
 
229
- series_with_vertabra_on_every_slice = st.selectbox(
230
- "Series with Vertebra on Every Slice",
231
- options=series_with_vertabra_on_every_slice_options,
232
- index=series_with_vertabra_on_every_slice_options.index(filters['series_with_vertabra_on_every_slice']) if filters['series_with_vertabra_on_every_slice'] else 0,
233
- key='series_with_vertabra_on_every_slice',
234
- on_change=lambda: apply_filter('series_with_vertabra_on_every_slice', st.session_state.series_with_vertabra_on_every_slice)
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", "seriesNumber","bodyPart","laterality", "segmentation_completeness","laterality_check", "series_with_vertabra_on_every_slice","connected_volumes","voxel_num", radiomics_feature),
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 series_with_vertabra_on_every_slice = 'pass' THEN 1 ELSE 0 END) AS vertabra_pass_count,
383
  SUM(CASE WHEN connected_volumes = '1' THEN 1 ELSE 0 END) AS volumes_pass_count
384
  FROM
385
- 'qual-checks-and-quant-values.parquet'
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((vertabra_pass_count * 100.0) / total_count, 2) || '% (' || vertabra_pass_count || '/' || total_count || ')' AS vertabra_check,
398
- ROUND((volumes_pass_count * 100.0) / total_count, 2) || '% (' || volumes_pass_count || '/' || total_count || ')' AS volumes_check
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