[434a55]: / feature_generator / HLQ_generator.py

Download this file

212 lines (170 with data), 6.9 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# -*- coding: utf-8 -*-
"""
The script to demo the infection volume and infection ratio procedure
Objective:
1. Read in the image from the resampled nii files (generated by the resize_volume.py)
the lung lobe segmentation files
the lesion segmentation files
2. Segment the lesion regions within certain lung lobe
3. Calculate the infection ratio(IR) and infection volume(IV) of different regions and different HU ranges
4. Run the manuscript in a multi-processing way
Input:
1. Resampled CT images
2. Lung lobe masks ()
3. Lesion masks ()
Output:
IV and IR list of each lung lobe within four HU ranges of each patient/image
"""
from __future__ import print_function
import numpy as np
import SimpleITK as sitk
from radiomics import featureextractor
import sys
import os
import os.path as osp
import shutil
from multiprocessing import Pool
from multiprocessing import TimeoutError as MP_TimeoutError
from time import sleep
import csv
START = "START"
FINISH = "FINISH"
WARNING = "WARNING"
ERROR = "ERROR"
LOG = "LOG"
# file locations
lobe_mask_loc = 'data_location' # lobe segmentation files
lesion_mask_loc = 'data_location' # lesion segmentation files
image_loc = 'data_location' # CT images
save_root_path = 'data_location' # file save location
# read nii file
def read_nii_file(file_loc):
reader = sitk.ImageFileReader()
reader.SetImageIO("NiftiImageIO")
reader.SetFileName(file_loc)
image = reader.Execute()
return image
# read dicom files
def read_dcm_file(file_loc):
reader = sitk.ImageSeriesReader()
dicom_names = reader.GetGDCMSeriesFileNames(file_loc)
reader.SetFileNames(dicom_names)
pcr_img = reader.Execute()
return pcr_img
def log_print(pid, comment, logs):
if type(logs) is str:
logs = [logs]
for log in logs:
print("# JOB %d : --%s-- %s" % (pid, comment, log))
sys.stdout.flush()
def result_scan(results):
unfinish = 1
while unfinish > 0:
unfinish = 0
for i, res in enumerate(results):
try:
res.get()
except Exception as e:
if type(e) == MP_TimeoutError:
unfinish += 1
continue
else:
print("\n\n\nERROR OCCUR: PID ##%d##, ERRORTYPE: %s\n\n\n" %(i, type(e)))
raise e
def extract_IV_IR_features(input_file_loc, mask_lobe_loc, mask_lesion_loc, output_file_name, pid, title_flag = 1):
# read input image
pcr_img = read_nii_file(input_file_loc)
pcr_img_np = sitk.GetArrayFromImage(pcr_img)
# read lung lobe seg
mask_lobe = read_nii_file(mask_lobe_loc)
mask_lobe_np = sitk.GetArrayFromImage(mask_lobe)
# read lesion seg
mask_lesion = read_nii_file(mask_lesion_loc)
mask_inter = mask_lobe * mask_lesion
mask_inter_np = sitk.GetArrayFromImage(mask_inter)
Lobe_num = 5 # number of lung lobe
# calculate WIV, WIR, LIV, LIR,
conditions = lambda x, y: {
x==0:np.where(y<=-750), \
x==1:np.where((y>-750) & (y<=-300)),\
x==2:np.where((y>-300) & (y<=50)), \
x==3:np.where(y>50)
}
HU_winow = lambda x: {
x==0:'(-Inf, -750]', \
x==1:'(-750, -300]',\
x==2:'(-300, 50]', \
x==3: '(50, +Inf]'
}
# Start to write the output file
log_print(pid, START, 'Vol:%s' % input_file_loc)
with open(output_file_name, 'w', newline='') as outfile:
# loop for 4 HU windows
for win_index in np.arange(4):
# win_index = 0
mask_win_np = np.zeros(shape=pcr_img_np.shape)
index = conditions(win_index, pcr_img_np)[True]
mask_win_np[index] = 1
#mask_lobe_np_win = mask_lobe_np*mask_win_np
mask_inter_np_win = mask_inter_np*mask_win_np
RV = np.array(np.where( (mask_lobe_np>=1) & (mask_lobe_np<=3) )).size
RIV = np.array(np.where( (mask_inter_np_win>=1) & (mask_inter_np_win<=3) )).size
RIR = RIV/RV
LV = np.array(np.where(mask_lobe_np>3)).size
LIV = np.array(np.where(mask_inter_np_win>3)).size
LIR = LIV/LV
WIV = RIV+LIV
WIR = WIV/(RV+LV)
Lobe_IV = np.zeros(5)
Lobe_IR = np.zeros(5)
for ii in np.arange(Lobe_num)+1:
# ii = 1
lesion_ROI = np.array(np.where(mask_inter_np_win == ii)) # calculate the voxel number of each lesion region
lung_ROI = np.array(np.where(mask_lobe_np == ii))
lesion_ROI_size = lesion_ROI.size
if lesion_ROI_size >= 27: # at least 9 voxels
Lobe_IR[ii-1] = lesion_ROI_size/(lung_ROI.size)
Lobe_IV[ii-1] = lesion_ROI_size
keys, values = ['EnergyWindow','WIV','WIR','LIV','LIR', 'RIV','RIR',\
'Lobe#1_IV', 'Lobe#1_IR', 'Lobe#2_IV', 'Lobe#2_IR', \
'Lobe#3_IV', 'Lobe#3_IR', 'Lobe#4_IV', 'Lobe#4_IR', 'Lobe#5_IV', 'Lobe#5_IR'],\
[HU_winow(win_index)[True], WIV, WIR, LIV, LIR, RIV, RIR,\
Lobe_IV[0], Lobe_IR[0], Lobe_IV[1], Lobe_IR[1],\
Lobe_IV[2], Lobe_IR[2], Lobe_IV[3], Lobe_IR[3], Lobe_IV[4], Lobe_IR[4]]
if title_flag == 1:
title_flag += 1
csvwriter = csv.writer(outfile)
csvwriter.writerow(keys)
csvwriter.writerow(values)
else:
csvwriter = csv.writer(outfile)
csvwriter.writerow(values)
log_print(pid, FINISH, 'Vol:%s' % input_file_loc)
_ = None
while _ not in ['y', 'n']:
_ = input('About to remove dir %s, START? [y/n]' % save_root_path).lower()
if _ == 'n':
exit()
shutil.rmtree(save_root_path, ignore_errors=True)
os.makedirs(save_root_path)
processes = 8
pool = Pool(processes)
results = list()
pid = 0
datasetList = os.listdir(image_loc)
datasetList.sort()
for filename in datasetList:
file = os.path.splitext(filename)[0]
# image location
input_file = os.path.join(image_loc, filename)
# lesion mask location
mask_lesion_file = os.path.join(lesion_mask_loc, filename)
save_file = osp.join(save_root_path, file+'.csv')
results.append(
pool.apply_async(
extract_IV_IR_features
args=(input_file, mask_lobe_file, mask_lesion_file, save_file, pid)))
pid += 1
pool.close()
result_scan(results)
pool.join()