def dwiMask(dwImg, outPrefix, median_radius, num_pass): """See brain mask extraction documentaion at http://nipy.org/dipy/examples_built/brain_extraction_dwi.html""" inPrefix = dwImg.split('.')[0] img = load(dwImg) bvals, _ = read_bvals_bvecs(inPrefix + '.bval', None) # extract the first b0 ind = np.where(bvals < 50)[0][0] _, mask = median_otsu(img.get_data()[..., ind], median_radius, num_pass) save_nifti(outPrefix + '_mask.nii.gz', mask.astype('uint8'), img.affine, img.header)
def fillHoles(imgPath): with TemporaryDirectory() as tmpdir, local.cwd(tmpdir): img= load(imgPath) data= img.get_data() dataBin= (data>0.)*1 save_nifti('bin.nii.gz', dataBin.astype('uint8'), affine=img.affine, hdr=img.header) fslmaths['bin.nii.gz', '-fillh', 'bin_filled.nii.gz'] & FG dataBinFilled= load('bin_filled.nii.gz').get_data() dataDiff= dataBinFilled - dataBin dataFilled= data+ dataDiff*10e-8 save_nifti(imgPath, dataFilled, affine= img.affine, hdr= img.header)
def skeletonize(imgs, cases, args, skelDir, miFile): target = load(args.template) targetData = target.get_data() X, Y, Z = targetData.shape[0], targetData.shape[1], targetData.shape[2] # provide the user with allFA sequence so he knows which volume he is looking at while scrolling through allFA seqFile = pjoin(args.statsDir, f'all_{args.modality}_sequence.txt') with open(seqFile, 'w') as f: f.write('index,caseid\n') for i, c in enumerate(cases): f.write(f'{i},{c}\n') print(f'Calculating mean {args.modality} over all the cases ...') allFAdata, cumsumFA = calc_mean(imgs, (X, Y, Z), args.qc) if args.qc: allFA = pjoin(args.statsDir, f'all_{args.modality}.nii.gz') save_nifti(allFA, np.moveaxis(allFAdata, 0, -1), target.affine, target.header) print( f'''\n\nQC the warped {args.modality} images: {allFA}, view {seqFile} for index of volumes in all_FA.nii.gz. You may use fsleyes/fslview to load {allFA}. MI metric b/w the warped images and target are stored in {miFile} It might be helpful to re-run registration for warped images that are bad. Moving images are : {args.outDir}/preproc/ Target is : {args.template} Transform files are : {args.xfrmDir}/ Warped images are : {args.outDir}/warped/ Save any re-registered images in {args.outDir}/warped/ with the same name as before For re-registration of any subject, output the transform files to a temporary directory: mkdir /tmp/badRegistration/ antsRegistrationSyNQuick.sh -d 3 \\ -f TEMPLATE \\ -m FA/preproc/caseid_FA.nii.gz \\ -o /tmp/badRegistration/caseid_FA antsApplyTransforms -d 3 \\ -i FA/preproc/caseid_FA.nii.gz \\ -o FA/warped/caseid_[FA/MD/AD/RD]_to_target.nii.gz \\ -r TEMPLATE \\ -t /tmp/badRegistration/caseid_FA1Warp.nii.gz /tmp/badRegistration/caseid_FA0GenericAffine.mat Finally, if wanted, you can copy the transform files to {args.xfrmDir}/ directory. Note: Replace all the above directories with absolute paths.\n\n''') while input('Press Enter when you are done with QC/re-registration: '): pass allFAdata, cumsumFA = calc_mean(imgs, targetData.shape, args.qc) meanFAdata = cumsumFA / len(imgs) meanFA = pjoin(args.statsDir, 'mean_FA.nii.gz') # outDir should contain # all_{modality}.nii.gz # mean_FA.nii.gz # mean_FA_mask.nii.gz # mean_FA_skeleton.nii.gz # mean_FA_skeleton_mask.nii.gz # mean_FA_skeleton_mask_dst.nii.gz if args.modality == 'FA': if not args.templateMask: print('Creating template mask ...') args.templateMask = pjoin(args.statsDir, 'mean_FA_mask.nii.gz') meanFAmaskData = (meanFAdata > 0) * 1 save_nifti(args.templateMask, meanFAmaskData.astype('uint8'), target.affine, target.header) else: meanFAmaskData = load(args.templateMask).get_data() meanFAdata = meanFAdata * meanFAmaskData save_nifti(meanFA, meanFAdata, target.affine, target.header) # if skeleton is not given: # create all three of skeleton, skeletonMask, and skeletonMaskDst # if skeleton is given and (neither skeletonMask nor skeletonMaskDst is given): # create skeletonMask and skeletonMaskDst # if skeleton and skeletonMask is given and skeletonMaskDst is not given: # create skeletonMaskDst if not args.skeleton: print( 'Creating all three of skeleton, skeletonMask, and skeletonMaskDst ...' ) args.skeleton = pjoin(args.statsDir, 'mean_FA_skeleton.nii.gz') args.skeletonMask = pjoin(args.statsDir, 'mean_FA_skeleton_mask.nii.gz') args.skeletonMaskDst = pjoin(args.statsDir, 'mean_FA_skeleton_mask_dst.nii.gz') _create_skeleton(meanFA, args.skeleton) _create_skeletonMask(args.skeleton, args.SKEL_THRESH, args.skeletonMask) _create_skeletonMaskDst(args.templateMask, args.skeletonMask, args.skeletonMaskDst) if args.skeleton and not (args.skeletonMask or args.skeletonMaskDst): print('Creating skeletonMask and skeletonMaskDst ...') args.skeletonMask = pjoin(args.statsDir, 'mean_FA_skeleton_mask.nii.gz') args.skeletonMaskDst = pjoin(args.statsDir, 'mean_FA_skeleton_mask_dst.nii.gz') _create_skeletonMask(args.skeleton, args.SKEL_THRESH, args.skeletonMask) _create_skeletonMaskDst(args.templateMask, args.skeletonMask, args.skeletonMaskDst) if args.skeleton and not args.skeletonMask and args.skeletonMaskDst: print('Creating skeletonMask ...') args.skeletonMask = pjoin(args.statsDir, 'mean_FA_skeleton_mask.nii.gz') _create_skeletonMask(args.skeleton, args.SKEL_THRESH, args.skeletonMask) if (args.skeleton and args.skeletonMask) and not args.skeletonMaskDst: print('Creating skeletonMaskDst ...') args.skeletonMaskDst = pjoin(args.statsDir, 'mean_FA_skeleton_mask_dst.nii.gz') _create_skeletonMaskDst(args.templateMask, args.skeletonMask, args.skeletonMaskDst) # mask allFA, this step does not seem to have any effect on the pipeline, it should help the user to visualize only if args.qc: check_call( (' ').join(['fslmaths', allFA, '-mas', args.templateMask, allFA]), shell=True) # projecting all {modality} data onto skeleton pool = Pool(args.ncpu) for c, imgPath in zip(cases, imgs): pool.apply_async(project_skeleton, (c, imgPath, args, skelDir), error_callback=RAISE) pool.close() pool.join() if not args.noAllSkeleton: allFAskeletonized = pjoin(args.statsDir, f'all_{args.modality}_skeletonized.nii.gz') print('Creating ', allFAskeletonized) # this loop has been moved out of multiprocessing block to prevent memroy error allFAskeletonizedData = np.zeros((len(imgs), X, Y, Z), dtype='float32') for i, c in enumerate(cases): allFAskeletonizedData[i, :] = load( pjoin( skelDir, f'{c}_{args.modality}_to_target_skel.nii.gz')).get_data() save_nifti(allFAskeletonized, np.moveaxis(allFAskeletonizedData, 0, -1), target.affine, target.header) print( f'Created {allFAskeletonized} and corresponding index file: {seqFile}' ) return args