haritsahm commited on
Commit
096efa7
·
1 Parent(s): 4a8bcc3

Add filter file function and test script

Browse files
Files changed (2) hide show
  1. main.py +76 -1
  2. tests/test_file_filters.py +74 -0
main.py CHANGED
@@ -1,3 +1,4 @@
 
1
  from typing import List
2
 
3
  import cv2
@@ -20,6 +21,80 @@ BILATERAL_MODEL.eval()
20
 
21
  OUTPUT_GALLERY = gr.Gallery(
22
  label='Highlighted Area').style(grid=[2], height='auto')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
 
25
  def predict_bilateral(file: str) -> List:
@@ -87,7 +162,7 @@ def run():
87
  outputs=[OUTPUT_GALLERY, gr.Label(label='Cancer Type')]
88
  )
89
 
90
- demo.launch(server_name='0.0.0.0', server_port=7860)
91
  demo.close()
92
 
93
 
 
1
+ from pathlib import Path
2
  from typing import List
3
 
4
  import cv2
 
21
 
22
  OUTPUT_GALLERY = gr.Gallery(
23
  label='Highlighted Area').style(grid=[2], height='auto')
24
+ SUPPORTED_IMG_EXT = ['.png', '.jpg', '.jpeg']
25
+
26
+
27
+ def filter_files(files: List) -> List:
28
+ """Filter uploaded files.
29
+
30
+ The model requires a pair of CC-MLO view of the breast scan.
31
+ This function will filter and ensure the inputs are as expected.
32
+ FIlter:
33
+ - Not enough number of files
34
+ - Unsupported extensions
35
+ - Missing required pair or part
36
+
37
+ Parameters
38
+ ----------
39
+ files : List[tempfile._TemporaryFileWrapper]
40
+ List of path to downloaded files
41
+
42
+ Returns
43
+ -------
44
+ List[tempfile._TemporaryFileWrapper]
45
+ List of path to downloaded files
46
+
47
+ Raises
48
+ ------
49
+ gr.Error
50
+ If the files is not equal to 2,
51
+ gr.Error
52
+ If the extension is unsupported
53
+ gr.Error
54
+ If specific view or side of mammography is missing.
55
+ """
56
+ if len(files) != 2:
57
+ raise gr.Error(
58
+ f'Need exactly 2 images. Currently have {len(files)} images!')
59
+
60
+ file_paths = [Path(file.name) for file in files]
61
+
62
+ if not all([path.suffix in SUPPORTED_IMG_EXT for path in file_paths]):
63
+ raise gr.Error(f'There is a file with unsupported type. \
64
+ Make sure all files are in {SUPPORTED_IMG_EXT}!')
65
+
66
+ # Table to store view(row), side(column)
67
+ table = np.zeros((2, 2), dtype=bool)
68
+ bin_left = 0
69
+ bin_right = 0
70
+ for file in file_paths:
71
+
72
+ splits = file.name.split('_')
73
+
74
+ # Check if view is present
75
+ if any(['cc' in part.lower() for part in splits]):
76
+ table[0, :] = [True, True]
77
+ if any(['mlo' in part.lower() for part in splits]):
78
+ table[1, :] = [True, True]
79
+
80
+ # Check if side is present
81
+ if any(['left' in part.lower() for part in splits]):
82
+ table[:, 0] &= True
83
+ bin_left += 1
84
+ elif any(['right' in part.lower() for part in splits]):
85
+ table[:, 1] &= True
86
+ bin_right += 1
87
+
88
+ # Reset side that has not enough files
89
+ if bin_left < 2:
90
+ table[:, 0] &= False
91
+ if bin_right < 2:
92
+ table[:, 1] &= False
93
+
94
+ if not any([all(table[:, 0]), all(table[:, 1])]):
95
+ raise gr.Error('Missing bilateral-view pair for Left or Right side.')
96
+
97
+ return file_paths
98
 
99
 
100
  def predict_bilateral(file: str) -> List:
 
162
  outputs=[OUTPUT_GALLERY, gr.Label(label='Cancer Type')]
163
  )
164
 
165
+ demo.launch(server_name='0.0.0.0', server_port=7860) # nosec B104
166
  demo.close()
167
 
168
 
tests/test_file_filters.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+ from typing import List
3
+
4
+ import gradio as gr
5
+ import numpy as np
6
+ import pytest
7
+
8
+ SUPPORTED_IMG_EXT = ['.png', '.jpg', '.jpeg']
9
+
10
+
11
+ def filter_files(files: List[str]):
12
+ if len(files) != 2:
13
+ raise gr.Error(
14
+ f'Need exactly 2 images. Currently have {len(files)} images!')
15
+
16
+ file_paths = [Path(file) for file in files]
17
+
18
+ if not all([path.suffix in SUPPORTED_IMG_EXT for path in file_paths]):
19
+ raise gr.Error(f'There is a file with unsupported type. \
20
+ Make sure all files are in {SUPPORTED_IMG_EXT}!')
21
+
22
+ # Table to store view(row), side(column)
23
+ table = np.zeros((2, 2), dtype=bool)
24
+ bin_left = 0
25
+ bin_right = 0
26
+ for file in file_paths:
27
+
28
+ splits = file.name.split('_')
29
+
30
+ # Check if view is present
31
+ if any(['cc' in part.lower() for part in splits]):
32
+ table[0, :] = [True, True]
33
+ if any(['mlo' in part.lower() for part in splits]):
34
+ table[1, :] = [True, True]
35
+
36
+ # Check if side is present
37
+ if any(['left' in part.lower() for part in splits]):
38
+ table[:, 0] &= True
39
+ bin_left += 1
40
+ elif any(['right' in part.lower() for part in splits]):
41
+ table[:, 1] &= True
42
+ bin_right += 1
43
+
44
+ # Reset side that has not enough files
45
+ if bin_left < 2:
46
+ table[:, 0] &= False
47
+ if bin_right < 2:
48
+ table[:, 1] &= False
49
+
50
+ if not any([all(table[:, 0]), all(table[:, 1])]):
51
+ raise gr.Error('Missing bilateral-view pair for Left or Right side.')
52
+
53
+ return file_paths
54
+
55
+
56
+ @pytest.mark.parametrize('file_paths,expectation',
57
+ [
58
+ (['left_cc.png'], False),
59
+ (['left_cc.png', 'right_cc.png', 'left_mlo.png'], False),
60
+ (['left_cc.png', 'left_mlo.tiff'], False),
61
+ (['left_cc.png', 'left_cc.png'], False),
62
+ (['left_mlo.png', 'right_cc.png'], False),
63
+ (['no_mlo.png', 'left_cc.png'], False),
64
+ (['left_cc.png', 'left_mlo.png'], True),
65
+ (['right_cc.jpg', 'right_mlo.png'], True),
66
+ ]
67
+ )
68
+ def test_filter_files(file_paths, expectation):
69
+ if expectation:
70
+ filtered_paths = filter_files(file_paths)
71
+ assert len(filtered_paths) == 2
72
+ else:
73
+ with pytest.raises(Exception) as _:
74
+ _ = filter_files(file_paths)