def implement(self): dwi = self.__linkDwiImage() bVals= self.getCorrectionImage('grad', None, 'bvals') bVecs= self.getCorrectionImage('grad', None, 'bvecs') bEnc = self.getCorrectionImage('grad', None, 'benc') if not bVals or not bVecs: bVals= self.getPreparationImage('grad', None, 'bvals') bVecs= self.getPreparationImage('grad', None, 'bvecs') bEnc= self.getPreparationImage('grad', None, 'benc') bVals = util.symlink(bVals, self.workingDir) bVecs = util.symlink(bVecs, self.workingDir) bEnc = util.symlink(bEnc, self.workingDir) if self.get('skipUpsampling'): dwiUpsample = self.rename(os.path.join(self.workingDir, os.path.basename(dwi)), self.buildName(dwi, "upsample")) else: interp = self.get('interp') template = self.getParcellationImage('anat','freesurfer','nii.gz') voxelSize = mriutil.getMriVoxelSize(template) # Get t1 voxel size to upsample voxelSize = str(voxelSize).translate(None, '[],') # Remove specific caracteres dwiUpsample= self.__upsampling(dwi, voxelSize, interp, self.buildName(dwi, "upsample")) b0Upsample = os.path.join(self.workingDir, os.path.basename(dwiUpsample).replace(self.get("prefix", 'dwi'), self.get("prefix", 'b0'))) self.info(mriutil.extractFirstB0FromDwi(dwiUpsample, b0Upsample, bVals))
def implement(self): dwiNative = self.getPreparationImage('dwi') #Extract b0 from dwiNative bVals= self.getPreparationImage('grad', None, 'bvals') if not bVals: bVals= self.getCorrectionImage('grad', None, 'bvals') b0Basename = os.path.basename(dwiNative).replace(self.get('prefix', 'dwi'), self.get('prefix', 'b0')) b0 = os.path.join(self.workingDir, b0Basename) self.info(mriutil.extractFirstB0FromDwi(dwiNative, b0, bVals)) #Brain in native space #brainResample = self.getImage(self.registrationDir, 'anat', ['brain', 'resample']) #brainNative = self.__resampling(brainResample, b0) maskBrain = self.getRegistrationImage('mask', 'resample') #Noise mask computation #dwiNativeNoiseMask = self.__computeNoiseMask(brainNative) #Corpus Callosum mask computation #aparcAseg = self.getImage(self.registrationDir, 'aparc_aseg', 'resample') #self.info(mriutil.mrcalc(aparcAseg, '253', self.buildName('aparc_aseg', ['253', 'mask'], 'nii.gz'))) cCResample = self.getMaskingImage('aparc_aseg', ['253', 'mask']) dwiNativeCcMask = self.__resampling(cCResample, b0)
def implement(self): dwi = self.__getDwiImage() bVals = self.__getBValsImage() norm= self.getParcellationImage('norm') parcellationMask = self.getParcellationImage('mask') b0 = os.path.join(self.workingDir, os.path.basename(dwi).replace(self.get("prefix", 'dwi'), self.get("prefix", 'b0'))) self.info(mriutil.extractFirstB0FromDwi(dwi, b0, bVals)) self.info("create a suitable mask for the dwi") extraArgs = "" if self.get("parcellation", "intrasubject"): extraArgs += " -usesqform -dof 6" mask = mriutil.computeDwiMaskFromFreesurfer(b0, norm, parcellationMask, self.buildName(parcellationMask, 'temporary'), extraArgs) target = self.buildName(dwi, "denoise") if self.get("algorithm") == "nlmeans": dwiImage = nibabel.load(dwi) dwiData = dwiImage.get_data() self.sigmaVector, sigma, maskNoise = self.__computeSigmaAndNoiseMask(dwiData) self.info("sigma value that will be apply into nlmeans = {}".format(sigma)) denoisingData = dipy.denoise.nlmeans.nlmeans(dwiData, sigma) nibabel.save(nibabel.Nifti1Image(denoisingData.astype(numpy.float32), dwiImage.get_affine()), target) nibabel.save(nibabel.Nifti1Image(maskNoise.astype(numpy.float32), dwiImage.get_affine()), self.buildName(target, "noise_mask")) elif self.get('general', 'matlab_available'): dwi = self.__getDwiImage() dwiUncompress = self.uncompressImage(dwi) tmp = self.buildName(dwiUncompress, "tmp", 'nii') scriptName = self.__createMatlabScript(dwiUncompress, tmp) self.__launchMatlabExecution(scriptName) self.info("compressing {} image".format(tmp)) tmpCompress = util.gzip(tmp) self.rename(tmpCompress, target) if self.get("cleanup"): self.info("Removing redundant image {}".format(dwiUncompress)) os.remove(dwiUncompress) else: self.matlabWarning = True self.warning("Algorithm {} is set but matlab is not available for this server.\n" "Please configure matlab or set denoising algorithm to nlmeans or none" .format(self.get("algorithm")))
def __computeFieldmap(self, dwi, bVals, mag, phase, norm, parcellationMask, freesurferAnat): # extract a b0 from the dwi image b0 = os.path.join(self.workingDir, os.path.basename(dwi).replace(self.get("prefix", 'dwi'), "b0_fieldmap_tmp")) self.info(mriutil.extractFirstB0FromDwi(dwi, b0, bVals)) self.info("rescaling the phase image") phaseRescale = self.__rescaleFieldMap(phase) self.info('Coregistring magnitude image with the anatomical image produce by freesurfer') fieldmapToAnat = self.__coregisterFieldmapToAnat(mag, freesurferAnat) extraArgs = " -dof 6 " if self.get("methodology", "intrasession"): extraArgs += " -usesqform -dof 6" interpolateMask, fm2anat, anat2fm = mriutil.computeDwiMaskFromFreesurfer( mag, norm, parcellationMask, self.buildName(parcellationMask, 'interpolate'), extraArgs) self.info('Resampling the anatomical mask into the phase image space') # interpolateMask = self.__interpolateAnatMaskToFieldmap(anat, phaseRescale, invertFielmapToAnat, mask) fieldmap = self.__computePhaseFieldmap(phaseRescale, interpolateMask) self.info('Generate a lossy magnitude file with signal loss and distortion') lossy = self.__simulateLossyMap(fieldmap, interpolateMask) magnitudeMask = self.__computeMap(mag, interpolateMask, 'brain') lossyMagnitude = self.__computeMap(magnitudeMask, lossy, 'lossy') warped = self.__computeForwardDistorsion(fieldmap, lossyMagnitude, interpolateMask) self.info('Coregister the simulated lossy fieldmap with the EPI') matrixName = self.get("epiTo_b0fm") self.__coregisterEpiLossyMap(b0, warped, matrixName, lossy) self.info('Reslice magnitude and fieldmap in the EPI space') invertMatrixName = self.buildName(matrixName, 'inverse', 'mat') self.info(mriutil.invertMatrix(matrixName, invertMatrixName)) magnitudeIntoDwiSpace = self.__interpolateFieldmapInEpiSpace(warped, b0, invertMatrixName) magnitudeIntoDwiSpaceMask = self.__mask(parcellationMask, b0, anat2fm, invertMatrixName) interpolateFieldmap = self.__interpolateFieldmapInEpiSpace(fieldmap, b0, invertMatrixName) self.info('Create the shift map') saveshift = self.__performDistortionCorrection(b0, interpolateFieldmap, magnitudeIntoDwiSpaceMask) self.info('Perform distortion correction of EPI data') dwiUnwarp = self.__performDistortionCorrectionToDWI(dwi, magnitudeIntoDwiSpaceMask, saveshift) return dwiUnwarp
def implement(self): dwi = self.__linkDwiImage() bVals= self.getCorrectionImage('grad', None, 'bvals') bVecs= self.getCorrectionImage('grad', None, 'bvecs') bEnc = self.getCorrectionImage('grad', None, 'benc') if not bVals or not bVecs: bVals= self.getPreparationImage('grad', None, 'bvals') bVecs= self.getPreparationImage('grad', None, 'bvecs') bEnc= self.getPreparationImage('grad', None, 'benc') bVals = util.symlink(bVals, self.workingDir) bVecs = util.symlink(bVecs, self.workingDir) bEnc = util.symlink(bEnc, self.workingDir) dwiUpsample= self.__upsampling(dwi, self.get('voxel_size'), self.buildName(dwi, "upsample")) b0Upsample = os.path.join(self.workingDir, os.path.basename(dwiUpsample).replace(self.get("prefix", 'dwi'), self.get("prefix", 'b0'))) self.info(mriutil.extractFirstB0FromDwi(dwiUpsample, b0Upsample, bVals))
def __computeFieldmap(self, dwi, bVals, mag, phase, norm, parcellationMask, freesurferAnat): # extract a b0 from the dwi image b0 = os.path.join( self.workingDir, os.path.basename(dwi).replace(self.get("prefix", 'dwi'), "b0_fieldmap_tmp")) self.info(mriutil.extractFirstB0FromDwi(dwi, b0, bVals)) self.info("rescaling the phase image") phaseRescale = self.__rescaleFieldMap(phase) self.info( 'Coregistring magnitude image with the anatomical image produce by freesurfer' ) fieldmapToAnat = self.__coregisterFieldmapToAnat(mag, freesurferAnat) extraArgs = " -dof 6 " if self.get("methodology", "intrasession"): extraArgs += " -usesqform -dof 6" interpolateMask = mriutil.computeDwiMaskFromFreesurfer( mag, norm, parcellationMask, self.buildName(parcellationMask, 'interpolate'), extraArgs) self.info('Resampling the anatomical mask into the phase image space') # interpolateMask = self.__interpolateAnatMaskToFieldmap(anat, phaseRescale, invertFielmapToAnat, mask) fieldmap = self.__computePhaseFieldmap(phaseRescale, interpolateMask) self.info( 'Generate a lossy magnitude file with signal loss and distortion') lossy = self.__simulateLossyMap(fieldmap, interpolateMask) magnitudeMask = self.__computeMap(mag, interpolateMask, 'brain') lossyMagnitude = self.__computeMap(magnitudeMask, lossy, 'lossy') warped = self.__computeForwardDistorsion(fieldmap, lossyMagnitude, interpolateMask) self.info('Coregister the simulated lossy fieldmap with the EPI') matrixName = self.get("epiTo_b0fm") self.__coregisterEpiLossyMap(b0, warped, matrixName, lossy) self.info('Reslice magnitude and fieldmap in the EPI space') invertMatrixName = self.buildName(matrixName, 'inverse', 'mat') self.info(mriutil.invertMatrix(matrixName, invertMatrixName)) magnitudeIntoDwiSpace = self.__interpolateFieldmapInEpiSpace( warped, b0, invertMatrixName) magnitudeIntoDwiSpaceMask = self.__mask(magnitudeIntoDwiSpace) interpolateFieldmap = self.__interpolateFieldmapInEpiSpace( fieldmap, b0, invertMatrixName) self.info('Create the shift map') saveshift = self.__performDistortionCorrection( b0, interpolateFieldmap, magnitudeIntoDwiSpaceMask) self.info('Perform distortion correction of EPI data') dwiUnwarp = self.__performDistortionCorrectionToDWI( dwi, magnitudeIntoDwiSpaceMask, saveshift) return dwiUnwarp
def implement(self): dwi = self.getDenoisingImage('dwi', 'denoise') if not dwi: dwi = self.getPreparationImage('dwi') b0AP = self.getPreparationImage('b0_ap') b0PA = self.getPreparationImage('b0_pa') bEnc = self.getPreparationImage('grad', None, 'b') bVals = self.getPreparationImage('grad', None, 'bvals') bVecs = self.getPreparationImage('grad', None, 'bvecs') norm = self.getParcellationImage('norm') parcellationMask = self.getParcellationImage('mask') # Fieldmap only mag = self.getPreparationImage("mag") phase = self.getPreparationImage("phase") freesurferAnat = self.getParcellationImage('anat', 'freesurfer') self.info("extract b0 image from the dwi") b0 = os.path.join( self.workingDir, os.path.basename(dwi).replace(self.get("prefix", 'dwi'), self.get("prefix", 'b0'))) self.info(mriutil.extractFirstB0FromDwi(dwi, b0, bVals)) self.info( "look if all images have the same voxel size and dimension scale") self.__validateSizeAndDimension(dwi, b0, b0AP, b0PA) # Generate a missing b0 image if we could. --> 0 = P>>A, 1 = A>>P if self.get("phase_enc_dir") == "0" and b0AP and b0PA is False: b0PA = b0 if self.get("phase_enc_dir") == "1" and b0PA and b0AP is False: b0AP = b0 [dwi, b0, b0AP, b0PA] = self.__oddEvenNumberOfSlices(dwi, b0, b0AP, b0PA) self.set('method', None) if b0AP is False or b0PA is False: topupBaseName = None b0Image = b0 self.set('method', 'fieldmap') else: # Concatenate B0 image together if self.get("phase_enc_dir") == "0": concatenateB0Image = self.__concatenateB0( b0PA, b0AP, self.buildName("b0pa_b0ap", None, "nii.gz")) elif self.get("phase_enc_dir") == "1": concatenateB0Image = self.__concatenateB0( b0AP, b0PA, self.buildName("b0ap_b0pa", None, "nii.gz")) # Create the acquisition parameter file acqpTopup = self.__createAcquisitionParameterFile('topup') # Run topup on concatenate B0 image [topupBaseName, topupImage] = self.__topup(concatenateB0Image, acqpTopup, self.get('b02b0_filename')) b0Image = self.__fslmathsTmean( os.path.join(self.workingDir, topupImage)) self.set('method', 'topup') self.info("create a suitable mask for the dwi") extraArgs = " -dof 6 " # same subject if self.get("methodology", "intrasession"): extraArgs += " -usesqform " mask = mriutil.computeDwiMaskFromFreesurfer( b0Image, norm, parcellationMask, self.buildName(parcellationMask, 'temporary'), extraArgs) # Create the acquisition parameter file for eddy acqpEddy = self.__createAcquisitionParameterFile('eddy') # Create an index file indexFile = self.__createIndexFile(mriutil.getNbDirectionsFromDWI(dwi)) outputImage = self.__correctionEddy(dwi, mask, topupBaseName, indexFile, acqpEddy, bVecs, bVals) eddyParameterFiles = self.getImage('dwi', None, 'eddy_parameters') if eddyParameterFiles: self.info( "Apply eddy movement correction to gradient encodings directions" ) bEnc = mriutil.applyGradientCorrection( bEnc, eddyParameterFiles, self.buildName(outputImage, None, 'b')) self.info( mriutil.mrtrixToFslEncoding( outputImage, bEnc, self.buildName(outputImage, None, 'bvecs'), self.buildName(outputImage, None, 'bvals'))) # Proceed with fieldmap if provided if mag and phase and not self.__topupCorrection: # OutputImage is now used for fieldmap correction outputImage = self.__computeFieldmap(outputImage, bVals, mag, phase, norm, parcellationMask, freesurferAnat) self.set('method', 'fieldmap') # Produce a valid b0 and mask for QA b0Corrected = self.buildName(b0, 'corrected') self.info( mriutil.extractFirstB0FromDwi(outputImage, b0Corrected, bVals)) maskCorrected = mriutil.computeDwiMaskFromFreesurfer( b0Corrected, norm, parcellationMask, self.buildName(parcellationMask, 'corrected'), extraArgs) self.rename(outputImage, self.buildName(outputImage, 'corrected'))
def implement(self): dwi = self.getDenoisingImage('dwi', 'denoise') if not dwi: dwi = self.getPreparationImage('dwi') b0AP = self.getPreparationImage('b0_ap') b0PA = self.getPreparationImage('b0_pa') bEnc = self.getPreparationImage('grad', None, 'b') bVals = self.getPreparationImage('grad', None, 'bvals') bVecs = self.getPreparationImage('grad', None, 'bvecs') norm = self.getParcellationImage('norm') parcellationMask = self.getParcellationImage('mask') # Fieldmap only mag = self.getPreparationImage("mag") phase = self.getPreparationImage("phase") freesurferAnat = self.getParcellationImage('anat', 'freesurfer') self.info("extract b0 image from the dwi") b0 = os.path.join(self.workingDir, os.path.basename(dwi).replace(self.get("prefix", 'dwi'), self.get("prefix", 'b0'))) self.info(mriutil.extractFirstB0FromDwi(dwi, b0, bVals)) self.info("look if all images have the same voxel size and dimension scale") self.__validateSizeAndDimension(dwi, b0, b0AP, b0PA) # Generate a missing b0 image if we could. --> 0 = P>>A, 1 = A>>P if self.get("phase_enc_dir") == "0" and b0AP and b0PA is False: b0PA = b0 if self.get("phase_enc_dir") == "1" and b0PA and b0AP is False: b0AP = b0 [dwi, b0, b0AP, b0PA] = self.__oddEvenNumberOfSlices(dwi, b0, b0AP, b0PA) self.set('method', None) if b0AP is False or b0PA is False: topupBaseName = None b0Image = b0 self.set('method', 'fieldmap') else: # Concatenate B0 image together if self.get("phase_enc_dir") == "0": concatenateB0Image = self.__concatenateB0(b0PA, b0AP, self.buildName("b0pa_b0ap", None, "nii.gz")) elif self.get("phase_enc_dir") == "1": concatenateB0Image = self.__concatenateB0(b0AP, b0PA, self.buildName("b0ap_b0pa", None, "nii.gz")) # Create the acquisition parameter file acqpTopup = self.__createAcquisitionParameterFile('topup') # Run topup on concatenate B0 image [topupBaseName, topupImage] = self.__topup(concatenateB0Image, acqpTopup, self.get('b02b0_filename')) b0Image = self.__fslmathsTmean(os.path.join(self.workingDir, topupImage)) self.set('method', 'topup') self.info("create a suitable mask for the dwi") extraArgs = " -dof 6 " # same subject if self.get("methodology", "intrasession"): extraArgs += " -usesqform " mask = mriutil.computeDwiMaskFromFreesurfer(b0Image, norm, parcellationMask, self.buildName(parcellationMask, 'temporary'), extraArgs) # Create the acquisition parameter file for eddy acqpEddy = self.__createAcquisitionParameterFile('eddy') # Create an index file indexFile = self.__createIndexFile(mriutil.getNbDirectionsFromDWI(dwi)) outputImage = self.__correctionEddy(dwi, mask, topupBaseName, indexFile, acqpEddy, bVecs, bVals) eddyParameterFiles = self.getImage('dwi', None, 'eddy_parameters') if eddyParameterFiles: self.info("Apply eddy movement correction to gradient encodings directions") bEnc = mriutil.applyGradientCorrection(bEnc, eddyParameterFiles, self.buildName(outputImage, None, 'b')) self.info(mriutil.mrtrixToFslEncoding(outputImage, bEnc, self.buildName(outputImage, None, 'bvecs'), self.buildName(outputImage, None, 'bvals'))) # Proceed with fieldmap if provided if mag and phase and not self.__topupCorrection: # OutputImage is now used for fieldmap correction outputImage = self.__computeFieldmap(outputImage, bVals, mag, phase, norm, parcellationMask, freesurferAnat) self.set('method', 'fieldmap') # Produce a valid b0 and mask for QA b0Corrected = self.buildName(b0, 'corrected') self.info(mriutil.extractFirstB0FromDwi(outputImage, b0Corrected, bVals)) maskCorrected = mriutil.computeDwiMaskFromFreesurfer(b0Corrected, norm, parcellationMask, self.buildName(parcellationMask, 'corrected'), extraArgs) self.rename(outputImage, self.buildName(outputImage, 'corrected'))
def implement(self): dwi = self.getPreparationImage("dwi") bVals = self.getPreparationImage('grad', None, 'bvals') norm= self.getParcellationImage('norm') parcellationMask = self.getParcellationImage('mask') b0 = os.path.join(self.workingDir, os.path.basename(dwi).replace(self.get("prefix", 'dwi'), self.get("prefix", 'b0'))) self.info(mriutil.extractFirstB0FromDwi(dwi, b0, bVals)) self.info("create a suitable mask for the dwi") extraArgs = " -dof 6 " if self.get("methodology", "intrasession"): extraArgs += " -usesqform " mask = mriutil.computeDwiMaskFromFreesurfer(b0, norm, parcellationMask, self.buildName(parcellationMask, 'resample'), extraArgs) target = self.buildName(dwi, "denoise") if self.get("algorithm") == "mp-pca": targetNoise = self.buildName(dwi, "noise") self.algorithm = "mp-pca" #cmd = "dwidenoise {} {} -mask {} -noise {} -extent {} -nthreads {} -quiet".format(dwi, target, mask, targetNoise, self.get('extent'), self.getNTreadsMrtrix()) cmd = "dwidenoise {} {} -noise {} -extent {} -nthreads {} -quiet".format(dwi, target, targetNoise, self.get('extent'), self.getNTreadsMrtrix()) self.launchCommand(cmd) elif self.get("algorithm") == "nlmeans": self.algorithm = "nlmeans" dwiImage = nibabel.load(dwi) dwiData = dwiImage.get_data() #if self.get('number_array_coil') == "32": noiseMask = mriutil.computeNoiseMask(mask, self.buildName(mask, 'noise_mask')) noiseMaskImage = nibabel.load(noiseMask) noiseMaskData = noiseMaskImage.get_data() sigma = numpy.std(dwiData[noiseMaskData > 0]) self.info("sigma value that will be apply into nlmeans = {}".format(sigma)) denoisingData = dipy.denoise.nlmeans.nlmeans(dwiData, sigma) #else: #self.sigmaVector, sigma, piesnoNoiseMask = self.__computeSigmaAndNoiseMask(dwiData) #self.info("sigma value that will be apply into nlmeans = {}".format(sigma)) #denoisingData = dipy.denoise.nlmeans.nlmeans(dwiData, sigma) #nibabel.save(nibabel.Nifti1Image(piesnoNoiseMask.astype(numpy.float32),dwiImage.get_affine()), self.buildName(target, "piesno_noise_mask")) nibabel.save(nibabel.Nifti1Image(denoisingData.astype(numpy.float32), dwiImage.get_affine()), target) elif self.get('general', 'matlab_available'): dwiUncompress = self.uncompressImage(dwi) tmp = self.buildName(dwiUncompress, "tmp", 'nii') scriptName = self.__createMatlabScript(dwiUncompress, tmp) self.__launchMatlabExecution(scriptName) self.info("compressing {} image".format(tmp)) tmpCompress = util.gzip(tmp) self.rename(tmpCompress, target) if self.get("cleanup"): self.info("Removing redundant image {}".format(dwiUncompress)) os.remove(dwiUncompress) else: self.matlabWarning = True self.warning("Algorithm {} is set but matlab is not available for this server.\n" "Please configure matlab or set denoising algorithm to nlmeans or none" .format(self.get("algorithm")))