andreped commited on
Commit
092699f
·
1 Parent(s): c649395

Added support for all preop brain tumor types

Browse files
Files changed (2) hide show
  1. neukit/gui.py +46 -9
  2. neukit/inference.py +43 -36
neukit/gui.py CHANGED
@@ -4,7 +4,7 @@ from .inference import run_model
4
 
5
 
6
  class WebUI:
7
- def __init__(self, model_name:str = None, class_name:str = "meningioma", cwd:str = "/home/user/app/"):
8
  # global states
9
  self.images = []
10
  self.pred_images = []
@@ -13,9 +13,25 @@ class WebUI:
13
  self.nb_slider_items = 150
14
 
15
  self.model_name = model_name
16
- self.class_name = class_name
17
  self.cwd = cwd
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  # define widgets not to be rendered immediantly, but later on
20
  self.slider = gr.Slider(1, self.nb_slider_items, value=1, step=1, label="Which 2D slice to show")
21
  self.volume_renderer = gr.Model3D(
@@ -24,6 +40,10 @@ class WebUI:
24
  visible=True,
25
  elem_id="model-3d",
26
  ).style(height=512)
 
 
 
 
27
 
28
  def combine_ct_and_seg(self, img, pred):
29
  return (img, [(pred, self.class_name)])
@@ -33,7 +53,7 @@ class WebUI:
33
 
34
  def load_mesh(self, mesh_file_name):
35
  path = mesh_file_name.name
36
- run_model(path, model_path=self.cwd + "resources/models/")
37
  nifti_to_glb("prediction.nii.gz")
38
 
39
  self.images = load_ct_to_numpy(path)
@@ -56,25 +76,42 @@ class WebUI:
56
  height: 512px;
57
  margin: auto;
58
  }
 
 
 
59
  """
60
  with gr.Blocks(css=css) as demo:
61
 
62
  with gr.Row():
63
- file_output = gr.File(
64
- file_count="single"
65
- ).style(full_width=False, size="sm")
66
  file_output.upload(self.upload_file, file_output, file_output)
67
 
68
- run_btn = gr.Button("Run analysis").style(full_width=False, size="sm")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  run_btn.click(
70
  fn=lambda x: self.load_mesh(x),
71
  inputs=file_output,
72
- outputs=self.volume_renderer
73
  )
74
 
75
  with gr.Row():
76
  gr.Examples(
77
- examples=[self.cwd + "RegLib_C01_2.nii"],
78
  inputs=file_output,
79
  outputs=file_output,
80
  fn=self.upload_file,
 
4
 
5
 
6
  class WebUI:
7
+ def __init__(self, model_name:str = None, cwd:str = "/home/user/app/"):
8
  # global states
9
  self.images = []
10
  self.pred_images = []
 
13
  self.nb_slider_items = 150
14
 
15
  self.model_name = model_name
 
16
  self.cwd = cwd
17
 
18
+ self.class_name = "meningioma" # default - but can be updated based on which task is chosen from dropdown
19
+ self.class_names = {
20
+ "meningioma": "MRI_Meningioma",
21
+ "low-grade": "MRI_LGGlioma",
22
+ "metastasis": "MRI_Metastasis",
23
+ "high-grade": "MRI_GBM",
24
+ "brain": "MRI_Brain",
25
+ }
26
+
27
+ self.result_names = {
28
+ "meningioma": "Tumor",
29
+ "low-grade": "Tumor",
30
+ "metastasis": "Tumor",
31
+ "high-grade": "Tumor",
32
+ "brain": "Brain",
33
+ }
34
+
35
  # define widgets not to be rendered immediantly, but later on
36
  self.slider = gr.Slider(1, self.nb_slider_items, value=1, step=1, label="Which 2D slice to show")
37
  self.volume_renderer = gr.Model3D(
 
40
  visible=True,
41
  elem_id="model-3d",
42
  ).style(height=512)
43
+
44
+ def set_class_name(self, value):
45
+ print("Changed task to:", value)
46
+ self.class_name = value
47
 
48
  def combine_ct_and_seg(self, img, pred):
49
  return (img, [(pred, self.class_name)])
 
53
 
54
  def load_mesh(self, mesh_file_name):
55
  path = mesh_file_name.name
56
+ run_model(path, model_path=self.cwd + "resources/models/", task=self.class_names[self.class_name], name=self.result_names[self.class_name])
57
  nifti_to_glb("prediction.nii.gz")
58
 
59
  self.images = load_ct_to_numpy(path)
 
76
  height: 512px;
77
  margin: auto;
78
  }
79
+ #upload {
80
+ height: 120px;
81
+ }
82
  """
83
  with gr.Blocks(css=css) as demo:
84
 
85
  with gr.Row():
86
+
87
+ file_output = gr.File(file_count="single", elem_id="upload") # elem_id="upload"
 
88
  file_output.upload(self.upload_file, file_output, file_output)
89
 
90
+ # with gr.Column():
91
+
92
+ model_selector = gr.Dropdown(
93
+ list(self.class_names.keys()),
94
+ label="Task",
95
+ info="Which task to perform - one model for each brain tumor type and brain extraction",
96
+ multiselect=False,
97
+ size="sm",
98
+ )
99
+ model_selector.input(
100
+ fn=lambda x: self.set_class_name(x),
101
+ inputs=model_selector,
102
+ outputs=None,
103
+ )
104
+
105
+ run_btn = gr.Button("Run analysis").style(full_width=False, size="lg")
106
  run_btn.click(
107
  fn=lambda x: self.load_mesh(x),
108
  inputs=file_output,
109
+ outputs=self.volume_renderer,
110
  )
111
 
112
  with gr.Row():
113
  gr.Examples(
114
+ examples=[self.cwd + "RegLib_C01_1.nii", self.cwd + "RegLib_C01_2.nii"],
115
  inputs=file_output,
116
  outputs=file_output,
117
  fn=self.upload_file,
neukit/inference.py CHANGED
@@ -5,7 +5,7 @@ import logging
5
  import traceback
6
 
7
 
8
- def run_model(input_path: str, model_path: str, verbose: str = "info", task: str = "MRI_Meningioma"):
9
  logging.basicConfig()
10
  logging.getLogger().setLevel(logging.WARNING)
11
 
@@ -17,49 +17,56 @@ def run_model(input_path: str, model_path: str, verbose: str = "info", task: str
17
  logging.getLogger().setLevel(logging.ERROR)
18
  else:
19
  raise ValueError("Unsupported verbose value provided:", verbose)
20
-
21
- # create sequence folder, rename patient, and add to temporary patient directory
22
- filename = input_path.split("/")[-1]
23
- splits = filename.split(".")
24
- extension = ".".join(splits[1:])
25
- patient_directory = "./patient/"
26
- os.makedirs(patient_directory + "T0/", exist_ok=True)
27
- shutil.copy(input_path, patient_directory + "T0/" + splits[0] + "-t1gd." + extension)
28
 
29
- # define output directory to save results
30
- output_path = "./result/prediction-" + splits[0] + "/"
31
- os.makedirs(output_path, exist_ok=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
- # Setting up the configuration file
34
- rads_config = configparser.ConfigParser()
35
- rads_config.add_section('Default')
36
- rads_config.set('Default', 'task', 'neuro_diagnosis')
37
- rads_config.set('Default', 'caller', '')
38
- rads_config.add_section('System')
39
- rads_config.set('System', 'gpu_id', "-1")
40
- rads_config.set('System', 'input_folder', patient_directory)
41
- rads_config.set('System', 'output_folder', output_path)
42
- rads_config.set('System', 'model_folder', model_path)
43
- rads_config.set('System', 'pipeline_filename', os.path.join(model_path, task, 'pipeline.json'))
44
- rads_config.add_section('Runtime')
45
- rads_config.set('Runtime', 'reconstruction_method', 'thresholding') # thresholding, probabilities
46
- rads_config.set('Runtime', 'reconstruction_order', 'resample_first')
47
- rads_config.set('Runtime', 'use_preprocessed_data', 'False')
48
 
49
- with open("rads_config.ini", "w") as f:
50
- rads_config.write(f)
51
 
52
- # finally, run inference
53
- from raidionicsrads.compute import run_rads
54
 
55
- try:
56
  run_rads(config_filename='rads_config.ini')
 
 
 
 
57
  except Exception as e:
58
  print(e)
59
-
60
- # rename and move final result
61
- os.rename("./result/prediction-" + splits[0] + "/T0/" + splits[0] + "-t1gd_annotation-Tumor.nii.gz", "./prediction.nii.gz")
62
-
63
  # Clean-up
64
  if os.path.exists(patient_directory):
65
  shutil.rmtree(patient_directory)
 
5
  import traceback
6
 
7
 
8
+ def run_model(input_path: str, model_path: str, verbose: str = "info", task: str = "MRI_Meningioma", name: str = "Tumor"):
9
  logging.basicConfig()
10
  logging.getLogger().setLevel(logging.WARNING)
11
 
 
17
  logging.getLogger().setLevel(logging.ERROR)
18
  else:
19
  raise ValueError("Unsupported verbose value provided:", verbose)
 
 
 
 
 
 
 
 
20
 
21
+ # delete patient/result folder if they exist
22
+ if os.path.exists("./patient/"):
23
+ shutil.rmtree("./patient/")
24
+ if os.path.exists("./result/"):
25
+ shutil.rmtree("./result/")
26
+
27
+ try:
28
+ # create sequence folder, rename patient, and add to temporary patient directory
29
+ filename = input_path.split("/")[-1]
30
+ splits = filename.split(".")
31
+ extension = ".".join(splits[1:])
32
+ patient_directory = "./patient/"
33
+ os.makedirs(patient_directory + "T0/", exist_ok=True)
34
+ shutil.copy(input_path, patient_directory + "T0/" + splits[0] + "-t1gd." + extension)
35
+
36
+ # define output directory to save results
37
+ output_path = "./result/prediction-" + splits[0] + "/"
38
+ os.makedirs(output_path, exist_ok=True)
39
 
40
+ # Setting up the configuration file
41
+ rads_config = configparser.ConfigParser()
42
+ rads_config.add_section('Default')
43
+ rads_config.set('Default', 'task', 'neuro_diagnosis')
44
+ rads_config.set('Default', 'caller', '')
45
+ rads_config.add_section('System')
46
+ rads_config.set('System', 'gpu_id', "-1")
47
+ rads_config.set('System', 'input_folder', patient_directory)
48
+ rads_config.set('System', 'output_folder', output_path)
49
+ rads_config.set('System', 'model_folder', model_path)
50
+ rads_config.set('System', 'pipeline_filename', os.path.join(model_path, task, 'pipeline.json'))
51
+ rads_config.add_section('Runtime')
52
+ rads_config.set('Runtime', 'reconstruction_method', 'thresholding') # thresholding, probabilities
53
+ rads_config.set('Runtime', 'reconstruction_order', 'resample_first')
54
+ rads_config.set('Runtime', 'use_preprocessed_data', 'False')
55
 
56
+ with open("rads_config.ini", "w") as f:
57
+ rads_config.write(f)
58
 
59
+ # finally, run inference
60
+ from raidionicsrads.compute import run_rads
61
 
 
62
  run_rads(config_filename='rads_config.ini')
63
+
64
+ # rename and move final result
65
+ os.rename("./result/prediction-" + splits[0] + "/T0/" + splits[0] + "-t1gd_annotation-" + name + ".nii.gz", "./prediction.nii.gz")
66
+
67
  except Exception as e:
68
  print(e)
69
+
 
 
 
70
  # Clean-up
71
  if os.path.exists(patient_directory):
72
  shutil.rmtree(patient_directory)