Skip to content

Commit 7d3cca7

Browse files
Merge pull request #16 from pnlbwh/fix-force
Fix force
2 parents dbdf148 + 3334353 commit 7d3cca7

11 files changed

Lines changed: 241 additions & 114 deletions

lib/buildTemplate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def antsMult(caselist, outPrefix):
9595
print(f'See {logFile} for details of template construction')
9696

9797

98-
N_core=os.getenv('TEMPLATE_CONSTRUCT_CORE')
98+
N_core=getenv('TEMPLATE_CONSTRUCT_CORE')
9999
check_call((' ').join([pjoin(SCRIPTDIR, 'antsMultivariateTemplateConstruction2_fixed_random_seed.sh'),
100100
'-d', '3',
101101
'-g', '0.2',

lib/debug_fa.py

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,30 @@
1818
import multiprocessing
1919
from util import *
2020

21-
SCRIPTDIR= os.path.dirname(__file__)
22-
ROOTDIR= os.path.abspath(os.path.join(SCRIPTDIR, '..'))
23-
mniTmp = os.path.join(ROOTDIR, 'IITAtlas', 'IITmean_FA.nii.gz')
21+
SCRIPTDIR= dirname(__file__)
22+
ROOTDIR= abspath(pjoin(SCRIPTDIR, '..'))
23+
mniTmp = pjoin(ROOTDIR, 'IITAtlas', 'IITmean_FA.nii.gz')
2424

2525
config = ConfigParser()
26-
config.read(f'/tmp/harm_config_{os.getpid()}.ini')
26+
config.read(f'/tmp/harm_config_{getpid()}.ini')
2727
N_proc = int(config['DEFAULT']['N_proc'])
2828
diffusionMeasures = [x for x in config['DEFAULT']['diffusionMeasures'].split(',')]
2929
bshell_b = int(config['DEFAULT']['bshell_b'])
3030

3131
def register_reference(imgPath, warp2mni, trans2mni, templatePath):
3232

3333
print(f'Warping {imgPath} diffusion measures to standard space')
34-
directory = os.path.dirname(imgPath)
34+
directory = dirname(imgPath)
3535
inPrefix = imgPath.split('.nii')[0]
3636
prefix = basename(inPrefix)
3737

3838
for dm in diffusionMeasures:
3939

40-
output = os.path.join(templatePath, prefix + f'_InMNI_{dm}.nii.gz')
40+
output = pjoin(templatePath, prefix + f'_InMNI_{dm}.nii.gz')
4141

4242
# reference site have been already warped to reference template space in buildTemplate.py: warp_bands()
43-
# warped data are os.path.join(templatePath, prefix, prefix + f'_WarpedFA.nii.gz')
44-
moving = os.path.join(templatePath, prefix + f'_Warped{dm}.nii.gz')
43+
# warped data are pjoin(templatePath, prefix, prefix + f'_WarpedFA.nii.gz')
44+
moving = pjoin(templatePath, prefix + f'_Warped{dm}.nii.gz')
4545

4646
# so warp diffusion measure to MNI space directly
4747
antsApplyTransforms[
@@ -56,22 +56,22 @@ def register_reference(imgPath, warp2mni, trans2mni, templatePath):
5656
def register_target(imgPath, templatePath):
5757

5858
print(f'Warping {imgPath} diffusion measures to standard space')
59-
directory = os.path.dirname(imgPath)
59+
directory = dirname(imgPath)
6060
inPrefix = imgPath.split('.nii')[0]
6161
prefix = basename(inPrefix)
6262

63-
dmImg = os.path.join(directory, 'dti', prefix + f'_FA.nii.gz')
64-
outPrefix = os.path.join(templatePath, prefix.replace(f'_b{bshell_b}','') + '_FA_ToMNI')
63+
dmImg = pjoin(directory, 'dti', prefix + f'_FA.nii.gz')
64+
outPrefix = pjoin(templatePath, prefix.replace(f'_b{bshell_b}','') + '_FA_ToMNI')
6565
warp2mni = outPrefix + '1Warp.nii.gz'
6666
trans2mni = outPrefix + '0GenericAffine.mat'
6767
# unprocessed target data is given, so in case multiple debug is needed, pass the registration
68-
if not os.path.exists(warp2mni):
68+
if not exists(warp2mni):
6969
antsReg(mniTmp, None, dmImg, outPrefix)
7070

7171
for dm in diffusionMeasures:
72-
output = os.path.join(templatePath, prefix + f'_InMNI_{dm}.nii.gz')
72+
output = pjoin(templatePath, prefix + f'_InMNI_{dm}.nii.gz')
7373

74-
moving = os.path.join(directory, 'dti', prefix + f'_{dm}.nii.gz')
74+
moving = pjoin(directory, 'dti', prefix + f'_{dm}.nii.gz')
7575
# warp diffusion measure to template space first, then to MNI space
7676
antsApplyTransforms[
7777
'-d', '3',
@@ -85,25 +85,25 @@ def register_target(imgPath, templatePath):
8585
def register_harmonized(imgPath, warp2mni, trans2mni, templatePath, siteName):
8686

8787
print(f'Warping {imgPath} diffusion measures to standard space')
88-
directory = os.path.dirname(imgPath)
88+
directory = dirname(imgPath)
8989
inPrefix = imgPath.split('.nii')[0]
9090
prefix = basename(inPrefix)
9191

92-
dmImg = os.path.join(directory, 'dti', prefix + f'_FA.nii.gz')
93-
dmTmp = os.path.join(templatePath, f'Mean_{siteName}_FA_b{bshell_b}.nii.gz')
94-
maskTmp = os.path.join(templatePath, f'{siteName}_Mask.nii.gz')
95-
outPrefix = os.path.join(templatePath, prefix.replace(f'_b{bshell_b}','') + '_FA')
92+
dmImg = pjoin(directory, 'dti', prefix + f'_FA.nii.gz')
93+
dmTmp = pjoin(templatePath, f'Mean_{siteName}_FA_b{bshell_b}.nii.gz')
94+
maskTmp = pjoin(templatePath, f'{siteName}_Mask.nii.gz')
95+
outPrefix = pjoin(templatePath, prefix.replace(f'_b{bshell_b}','') + '_FA')
9696
warp2tmp = outPrefix + '1Warp.nii.gz'
9797
trans2tmp = outPrefix + '0GenericAffine.mat'
9898

9999
# check existence of transforms created with _b{bmax}
100-
if not os.path.exists(warp2tmp):
100+
if not exists(warp2tmp):
101101
antsReg(dmTmp, maskTmp, dmImg, outPrefix)
102102

103103
for dm in diffusionMeasures:
104-
output = os.path.join(templatePath, prefix + f'_InMNI_{dm}.nii.gz')
104+
output = pjoin(templatePath, prefix + f'_InMNI_{dm}.nii.gz')
105105

106-
moving = os.path.join(directory, 'dti', prefix + f'_{dm}.nii.gz')
106+
moving = pjoin(directory, 'dti', prefix + f'_{dm}.nii.gz')
107107
# warp diffusion measure to template space first, then to MNI space
108108
antsApplyTransforms[
109109
'-d', '3',
@@ -117,14 +117,14 @@ def register_harmonized(imgPath, warp2mni, trans2mni, templatePath, siteName):
117117
def sub2tmp2mni(templatePath, siteName, caselist, ref= False, tar_unproc= False, tar_harm= False):
118118

119119
# obtain the transform
120-
moving = os.path.join(templatePath, f'Mean_{siteName}_FA_b{bshell_b}.nii.gz')
120+
moving = pjoin(templatePath, f'Mean_{siteName}_FA_b{bshell_b}.nii.gz')
121121

122-
outPrefix= os.path.join(templatePath, f'TemplateToMNI_{siteName}')
122+
outPrefix= pjoin(templatePath, f'TemplateToMNI_{siteName}')
123123
warp2mni= outPrefix+'1Warp.nii.gz'
124124
trans2mni= outPrefix+'0GenericAffine.mat'
125125

126126
# check existence of transforms created with _b{bmax}
127-
if not os.path.exists(warp2mni):
127+
if not exists(warp2mni):
128128
antsReg(mniTmp, None, moving, outPrefix)
129129

130130
imgs, _= read_caselist(caselist)
@@ -160,7 +160,7 @@ def analyzeStat(file, templatePath):
160160
:return: mean of the images
161161
'''
162162

163-
skel= load(os.path.join(ROOTDIR, 'IITAtlas', 'IITmean_FA_skeleton.nii.gz'))
163+
skel= load(pjoin(ROOTDIR, 'IITAtlas', 'IITmean_FA_skeleton.nii.gz'))
164164
skel_mask= (skel.get_data()>0)*1.
165165

166166
imgs, _ = read_caselist(file)
@@ -170,7 +170,7 @@ def analyzeStat(file, templatePath):
170170
inPrefix = imgPath.split('.nii')[0]
171171
prefix = basename(inPrefix)
172172

173-
faImg= os.path.join(templatePath, prefix + f'_InMNI_FA.nii.gz')
173+
faImg= pjoin(templatePath, prefix + f'_InMNI_FA.nii.gz')
174174
data= load(faImg).get_data()
175175
temp= data*skel_mask
176176
meanAttr.append(temp[temp>0].mean())

lib/harm_plot.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#!/usr/bin/env python
2+
3+
import numpy as np
4+
import matplotlib
5+
matplotlib.use('Agg')
6+
import matplotlib.pyplot as plt
7+
import pandas as pd
8+
from conversion import read_imgs_masks
9+
from os.path import isfile, basename
10+
11+
XERR=0.1
12+
ELINEWIDTH=3
13+
CAPSIZE=5
14+
CAPTHICK=3
15+
FMT='cD'
16+
17+
def harm_plot(ydata, labels, outPrefix, bshell_b):
18+
'''
19+
:param ydata: list of [y1, y2, y3, ...] where each yi is a list
20+
:param labels: list of strings
21+
:param outPrefix:
22+
:return:
23+
'''
24+
outPrefix += f'_b{bshell_b}'
25+
labels= list(labels)
26+
27+
num_series, num_sub= np.shape(ydata)
28+
29+
iter_obj= [i for i in range(num_series)]
30+
31+
# errorbar plot
32+
plt.figure(1)
33+
plt.grid(True)
34+
for i in iter_obj:
35+
x= list(i*np.ones((num_sub,)))
36+
y= ydata[i]
37+
plt.plot(x, y, 'r*')
38+
39+
plt.errorbar([i], np.mean(y), xerr=XERR, yerr=np.std(y),
40+
ecolor='k', capsize=CAPSIZE, capthick=CAPTHICK, elinewidth=ELINEWIDTH, fmt=FMT)
41+
42+
plt.xticks(iter_obj, labels)
43+
plt.title('Comparison of meanFA before and after harmonization')
44+
plt.ylabel('meanFA over IIT_mean_FA_skeleton')
45+
plt.savefig(outPrefix+'_ebarplot.png')
46+
# plt.show()
47+
48+
# box plot
49+
# plt.figure(2)
50+
# plt.grid(True)
51+
# for i in iter_obj:
52+
# x = list(i * np.ones((num_sub,)))
53+
# y = ydata[i]
54+
# plt.plot(x, y, 'r*')
55+
#
56+
# plt.boxplot(ydata, labels=labels, positions=iter_obj,
57+
# boxprops=dict(linewidth=4),
58+
# medianprops=dict(linewidth=4),
59+
# whiskerprops=dict(linewidth=2))
60+
#
61+
#
62+
# plt.title(f'Comparison of boxplot before and after harmonization for b{bshell_b}')
63+
# plt.ylabel('meanFA over IIT_mean_FA_skeleton')
64+
# plt.savefig(outPrefix+'_boxplot.png')
65+
# plt.show()
66+
# return (outPrefix+'_ebarplot.png', outPrefix+'_boxplot.png')
67+
68+
return outPrefix+'_ebarplot.png'
69+
70+
71+
def generate_csv(imgs, site_means, outPrefix, bshell_b):
72+
73+
try:
74+
imgs, _= read_imgs_masks(imgs)
75+
except:
76+
pass
77+
78+
statFile = outPrefix + '_stat.csv'
79+
80+
if isfile(statFile):
81+
df= pd.read_csv(statFile)
82+
df= df.assign(**{f'meanFA b{bshell_b}':site_means})
83+
else:
84+
stat = {'subject': [basename(f) for f in imgs], f'meanFA b{bshell_b}': site_means}
85+
df = pd.DataFrame(stat)
86+
87+
df.to_csv(statFile, index=False)
88+
89+
90+
if __name__=='__main__':
91+
92+
sub=['hi','hello','go','come']
93+
ref_mean= [0.46, 0.49, 0.44, 0.40]
94+
target_mean_before= [0.42, 0.58, 0.43, 0.66]
95+
target_mean_after= [0.5 , 0.45, 0.40, 0.55]
96+
labels=['Reference','Target before','Target after']
97+
bshell_b= 2000
98+
99+
harm_plot([ref_mean, target_mean_before, target_mean_after], labels, '/tmp/abc', bshell_b)
100+
# harm_plot([ref_mean], ['Reference'], '/tmp/abc', bshell_b)
101+
102+
generate_csv(sub, ref_mean, '/tmp/abc', bshell_b)
103+
104+

lib/harmonization.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from plumbum import cli
1717
from distutils.spawn import find_executable
1818
import multiprocessing, psutil
19+
import io
1920

2021
from determineNshm import verifyNshmForAll, determineNshm
2122
from util import *
@@ -254,13 +255,12 @@ def harmonizeData(self):
254255
if not exists(self.templatePath):
255256
raise NotADirectoryError(f'{self.templatePath} does not exist')
256257
else:
257-
if not os.listdir(self.templatePath):
258+
if not listdir(self.templatePath):
258259
raise ValueError(f'{self.templatePath} is empty')
259260

260261
# go through each file listed in csv, check their existence, create dti and harm directories
261262
check_csv(self.target_csv, self.force)
262263

263-
264264
# target data is not manipulated in multi-shell-dMRIharmonization i.e. bvalMapped, resampled, nor denoised
265265
# this block may be uncommented in a future design
266266
# from preprocess import dti_harm
@@ -281,13 +281,10 @@ def harmonizeData(self):
281281

282282
# read target image list
283283
moving= pjoin(self.templatePath, f'Mean_{self.target}_FA_b{self.bshell_b}.nii.gz')
284-
imgs, masks= read_caselist(self.target_csv)
284+
imgs, masks= read_caselist(self.tar_unproc_csv)
285285

286-
preFlag= 1 # omit preprocessing of target data again
287-
if self.target_csv.endswith('.modified'):
288-
preFlag= 0
289-
else:
290-
# this file will be used later for debugging
286+
fm= None
287+
if not self.target_csv.endswith('.modified'):
291288
self.target_csv += '.modified'
292289
fm = open(self.target_csv, 'w')
293290

@@ -297,12 +294,12 @@ def harmonizeData(self):
297294
pool = multiprocessing.Pool(self.N_proc)
298295
res= []
299296
for imgPath, maskPath in zip(imgs, masks):
300-
res.append(pool.apply_async(func= reconst, args= (imgPath, maskPath, moving, self.templatePath, preFlag, )))
297+
res.append(pool.apply_async(func= reconst, args= (imgPath, maskPath, moving, self.templatePath,)))
301298

302299
for r in res:
303300
imgPath, maskPath, harmImg, harmMask= r.get()
304301

305-
if preFlag:
302+
if isinstance(fm, io.IOBase):
306303
fm.write(imgPath + ',' + maskPath + '\n')
307304
fh.write(harmImg + ',' + harmMask + '\n')
308305

@@ -314,17 +311,17 @@ def harmonizeData(self):
314311
# loop for debugging
315312
# res= []
316313
# for imgPath, maskPath in zip(imgs, masks):
317-
# res.append(reconst(imgPath, maskPath, moving, self.templatePath, preFlag))
314+
# res.append(reconst(imgPath, maskPath, moving, self.templatePath))
318315
#
319316
# for r in res:
320317
# imgPath, maskPath, harmImg, harmMask= r
321318
#
322-
# if preFlag:
319+
# if isinstance(fm, io.IOBase):
323320
# fm.write(imgPath + ',' + maskPath + '\n')
324321
# fh.write(harmImg + ',' + harmMask + '\n')
325322

326323

327-
if preFlag:
324+
if isinstance(fm, io.IOBase):
328325
fm.close()
329326
fh.close()
330327

@@ -486,7 +483,7 @@ def main(self):
486483

487484

488485
# write config file to temporary directory
489-
configFile= f'/tmp/harm_config_{os.getpid()}.ini'
486+
configFile= f'/tmp/harm_config_{getpid()}.ini'
490487
with open(configFile,'w') as f:
491488
f.write('[DEFAULT]\n')
492489
f.write(f'N_shm = {self.N_shm}\n')
@@ -498,6 +495,7 @@ def main(self):
498495
f.write(f'denoise = {1 if self.denoise else 0}\n')
499496
f.write(f'travelHeads = {1 if self.travelHeads else 0}\n')
500497
f.write(f'debug = {1 if self.debug else 0}\n')
498+
f.write(f'force = {1 if self.force else 0}\n')
501499
f.write(f'verbose = {1 if self.verbose else 0}\n')
502500
f.write('diffusionMeasures = {}\n'.format((',').join(self.diffusionMeasures)))
503501

@@ -506,6 +504,13 @@ def main(self):
506504

507505
if self.create:
508506
self.createTemplate()
507+
import fileinput
508+
for line in fileinput.input(configFile, inplace=True):
509+
if 'force' in line:
510+
print('force = 0')
511+
else:
512+
print(line)
513+
self.force= False
509514

510515
if self.process:
511516
self.harmonizeData()
@@ -514,7 +519,7 @@ def main(self):
514519
self.post_debug()
515520

516521

517-
os.remove(configFile)
522+
remove(configFile)
518523

519524

520525
if __name__ == '__main__':

0 commit comments

Comments
 (0)