From 1e080061f3486a31cb4c347bde254b710fa0f540 Mon Sep 17 00:00:00 2001 From: kcho Date: Thu, 12 Feb 2026 09:21:51 -0500 Subject: [PATCH 1/4] fix: fix to avoid IO error --- lib/buildTemplate.py | 2 +- lib/reconstSignal.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/buildTemplate.py b/lib/buildTemplate.py index 6d65a6a..1eadc32 100644 --- a/lib/buildTemplate.py +++ b/lib/buildTemplate.py @@ -115,7 +115,7 @@ def antsMult(caselist, outPrefix): '-o', outPrefix, caselist]), shell= True, stdout= f, stderr= sys.stdout) - if f.name!='': + if f is not sys.stdout: f.close() def dti_stat(siteName, imgs, masks, templatePath, templateHdr): diff --git a/lib/reconstSignal.py b/lib/reconstSignal.py index 891998e..a909dfe 100644 --- a/lib/reconstSignal.py +++ b/lib/reconstSignal.py @@ -61,7 +61,7 @@ def antsReg(img, mask, mov, outPrefix): '-e', '123456']), shell= True, stdout= f, stderr= sys.stdout) p.wait() - if f.name!='': + if f is not sys.stdout: f.close() From e7346b1e1225363b3699531e5badaf7b8c8c5c0e Mon Sep 17 00:00:00 2001 From: kcho Date: Tue, 31 Mar 2026 05:30:57 -0400 Subject: [PATCH 2/4] feat: reduce voxel size discrepancy threshold --- lib/consistencyCheck.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/consistencyCheck.py b/lib/consistencyCheck.py index 99ea05e..12923dc 100755 --- a/lib/consistencyCheck.py +++ b/lib/consistencyCheck.py @@ -66,7 +66,7 @@ def check_resolution(ref_imgs, ref_res): res= load(imgPath._path).header['pixdim'][1:4] - if (res-ref_res).sum()<=10e-6: + if (res-ref_res).sum()<=0.001: print('spatial resolution matched for', imgPath.name) else: From 067acc80f39778695b71147b75d08f78a1c2972b Mon Sep 17 00:00:00 2001 From: kcho Date: Sat, 11 Apr 2026 21:22:50 -0400 Subject: [PATCH 3/4] fix: check bval and bvec separately from nifti --- lib/separateBshells.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/separateBshells.py b/lib/separateBshells.py index 2b3a30b..d000859 100755 --- a/lib/separateBshells.py +++ b/lib/separateBshells.py @@ -51,13 +51,19 @@ def separateBshells(imgPath, ref_bvals_file=None, ref_bvals=None): if bval==0.: b0 = find_b0(dwi, ind) - if isfile(bPrefix + '.nii.gz'): - continue - + nii_file = bPrefix + '.nii.gz' + bval_file = bPrefix + '.bval' + bvec_file = bPrefix + '.bvec' + if bval==0.: - save_nifti(bPrefix + '.nii.gz', b0, img.affine, img.header) + if isfile(nii_file): + continue + save_nifti(nii_file, b0, img.affine, img.header) else: + if isfile(nii_file) and isfile(bval_file) and isfile(bvec_file): + continue + b0_bshell = np.zeros((dwi.shape[0],dwi.shape[1],dwi.shape[2],N_b+1), dtype='float32') b0_bshell[:,:,:,0]= b0 b0_bshell[:,:,:,1:]= dwi[:,:,:,ind] @@ -67,9 +73,12 @@ def separateBshells(imgPath, ref_bvals_file=None, ref_bvals=None): b0_bvecs= np.zeros((N_b+1,3), dtype='float32') b0_bvecs[1:,]= bvecs[ind,: ] - save_nifti(bPrefix+'.nii.gz', b0_bshell, img.affine, img.header) - write_bvals(bPrefix+'.bval', b0_bvals) - write_bvecs(bPrefix+'.bvec', b0_bvecs) + if not isfile(nii_file): + save_nifti(nii_file, b0_bshell, img.affine, img.header) + if not isfile(bval_file): + write_bvals(bval_file, b0_bvals) + if not isfile(bvec_file): + write_bvecs(bvec_file, b0_bvecs) From b4337a8b8cced379022bafc76a1b68f140a20147 Mon Sep 17 00:00:00 2001 From: Kevin Cho Date: Fri, 17 Apr 2026 15:22:19 -0400 Subject: [PATCH 4/4] Fix silent worker failure in multiprocessing Pool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace broken error_callback=RAISE pattern with result collection and r.get() after pool.join(). The RAISE callback ran in a Pool helper thread, so raising there killed the thread silently while pool.join() returned normally—causing the pipeline to continue with missing or corrupt output files from failed workers. Now any worker exception is re-raised in the main process, killing the pipeline immediately. --- lib/joinBshells.py | 9 ++++++--- lib/separateBshells.py | 10 +++++++--- lib/tests/shellEquate.py | 10 +++++++--- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/joinBshells.py b/lib/joinBshells.py index 9ee8a2b..7605d8a 100755 --- a/lib/joinBshells.py +++ b/lib/joinBshells.py @@ -16,7 +16,7 @@ from plumbum import cli, local from conversion import read_bvals, read_imgs, read_imgs_masks from nibabel import load -from util import abspath, pjoin, save_nifti, copyfile, RAISE, basename, dirname, isfile +from util import abspath, pjoin, save_nifti, copyfile, basename, dirname, isfile import numpy as np from multiprocessing import Pool from findBshells import BSHELL_MIN_DIST @@ -86,13 +86,16 @@ def joinAllBshells(tar_csv, ref_bvals_file, separatedPrefix=None, ncpu=4): imgs = read_imgs(tar_csv) pool = Pool(int(ncpu)) + results = [] for imgPath in imgs: - pool.apply_async(joinBshells, kwds=({'imgPath': imgPath, 'ref_bvals': ref_bvals, 'sep_prefix': separatedPrefix}), - error_callback=RAISE) + results.append(pool.apply_async(joinBshells, kwds=({'imgPath': imgPath, 'ref_bvals': ref_bvals, 'sep_prefix': separatedPrefix}))) pool.close() pool.join() + for r in results: + r.get() + class joinDividedShells(cli.Application): diff --git a/lib/separateBshells.py b/lib/separateBshells.py index d000859..1498bac 100755 --- a/lib/separateBshells.py +++ b/lib/separateBshells.py @@ -17,7 +17,7 @@ from plumbum import cli, local from conversion import read_bvals, read_bvecs, write_bvals, write_bvecs, read_imgs, read_imgs_masks from nibabel import load -from util import abspath, pjoin, save_nifti, RAISE, isfile +from util import abspath, pjoin, save_nifti, isfile import numpy as np from multiprocessing import Pool from findBshells import BSHELL_MIN_DIST @@ -93,13 +93,17 @@ def separateAllBshells(ref_csv, ref_bvals_file, ncpu=4, outPrefix= None): masks = None pool = Pool(int(ncpu)) + results = [] for imgPath in imgs: - pool.apply_async(separateBshells, - kwds={'imgPath': imgPath, 'ref_bvals': ref_bvals}, error_callback=RAISE) + results.append(pool.apply_async(separateBshells, + kwds={'imgPath': imgPath, 'ref_bvals': ref_bvals})) pool.close() pool.join() + for r in results: + r.get() + if outPrefix: outPrefix = abspath(outPrefix) diff --git a/lib/tests/shellEquate.py b/lib/tests/shellEquate.py index 5d8cc8a..1c311ed 100755 --- a/lib/tests/shellEquate.py +++ b/lib/tests/shellEquate.py @@ -17,7 +17,7 @@ from plumbum import cli, local from conversion import read_bvals, read_bvecs, write_bvals, write_bvecs, read_imgs, read_imgs_masks from nibabel import load -from util import abspath, pjoin, save_nifti, RAISE, isfile +from util import abspath, pjoin, save_nifti, isfile import numpy as np from multiprocessing import Pool from findBshells import BSHELL_MIN_DIST @@ -83,12 +83,16 @@ def separateAllBshells(ref_csv, ref_bvals_file, ncpu=4, outPrefix= None): masks = None pool = Pool(int(ncpu)) + results = [] for imgPath in imgs: - pool.apply_async(separateBshells, - kwds={'imgPath': imgPath, 'ref_bvals': ref_bvals}, error_callback=RAISE) + results.append(pool.apply_async(separateBshells, + kwds={'imgPath': imgPath, 'ref_bvals': ref_bvals})) pool.close() pool.join() + + for r in results: + r.get() if outPrefix: