b0 to T1WIとT1WI to 標準脳のWarp Fieldを使って、拡散定量値マップを標準空間に移動
標準空間上にあるすべての被験者の拡散定量値マップをひとつの4D volume dataにまとめる
平均灰白質マスクmean_GM_maskで、3の拡散定量値マップをマスク処理
function gbss_2_DWIwpreproc() {
echo "Diffusion MAP preprocessing..."
# Diffusion MAP preprocessing
for SUBJ in ${SUBJ_LIST}; do
## Register b0 to MNI
### Register b0 to T1WI
epi_reg --epi=b0/${SUBJ} \
--t1=T1w/${SUBJ} --t1brain=T1w/${SUBJ}_skull_stripped \
--echospacing=${ECHOSPACING} --pedir=${PEDIR} \
--wmseg=T1w//${SUBJ}_fast_seg_2.nii.gz \
--out=b0/${SUBJ}_BBR
for MAP in ${MAP_LIST}; do
### applywarp to diffusion map and move it to T1w based on epi_reg
flirt -in ${MAP}/${SUBJ} \
-out ${MAP}/${SUBJ}_inT1 \
-ref T1w/${SUBJ}_skull_stripped \
-init b0/${SUBJ}_BBR.mat -applyxfm
### applywarp to dMAP in T1w and move it to MNI
applywarp --ref=${FSLDIR}/data/standard/MNI152_T1_2mm_brain \
--in=${MAP}/${SUBJ}_inT1 \
--warp=T1w/${SUBJ}_indiv2MNI_warp \
--out=${MAP}/${SUBJ}_inMNI
done
done
## 4D all_${dMAP}
for MAP in ${MAP_LIST}; do
### Merge dMAP in MNI into one volume, all_${MAP}
fslmerge -t stats/all_${MAP} $(imglob ${MAP}/*_inMNI.nii.gz)
### Masking dMAP in MNI using mean GM mask
fslmaths stats/all_${MAP} -mas stats/mean_GM_mask stats/all_${MAP}
done
}
clear all;clc;close all;
% Set path
% MEDI_set_path
% STEP 1: Import data
[iField,voxel_size,matrix_size,CF,delta_TE,TE,B0_dir,files]=Read_DICOM('AXL_QSM');
%%%% Generate the Magnitude image %%%%
iMag = sqrt(sum(abs(iField).^2,4));
%%%%% provide a Mask here if possible %%%%%%
if (~exist('Mask','var'))
% Mask = genMask(iField, voxel_size);
Mask = BET(iMag,matrix_size,voxel_size);
end
%%%%% provide a noise_level here if possible %%%%%%
if (~exist('noise_level','var'))
noise_level = calfieldnoise(iField, Mask);
end
%%%%% normalize signal intensity by noise to get SNR %%%
iField = iField/noise_level;
% STEP 2a: Field Map Estimation
%%%%%Estimate the frequency offset in each of the voxel using a
%%%%%complex fitting %%%%
[iFreq_raw N_std] = Fit_ppm_complex(iField);
% STEP 2b: Spatial phase unwrapping %%%%
iFreq = unwrapPhase(iMag, iFreq_raw, matrix_size);
% STEP 2c: Background Field Removal
%%%% Background field removal %%%%
[RDF shim] = PDF(iFreq, N_std, Mask,matrix_size,voxel_size, B0_dir);
% CSF Mask for zero referencing
R2s=arlo(TE,abs(iField));
Mask_CSF = extract_CSF(R2s, Mask, voxel_size);
% STEP 3: Dipole Inversion
save RDF.mat RDF iFreq iFreq_raw iMag N_std Mask matrix_size...
voxel_size delta_TE CF B0_dir Mask_CSF;
%%%% run MEDI %%%%%
QSM = MEDI_L1('lambda',1000, 'smv', 5, 'merit');
%%% save to DICOM
% ignore warnings...
Write_DICOM(QSM,files,'QSM')
function Write_DICOM(M,files,outdir,opts)
%WRITE_DICOM Summary of this function goes here
% Detailed explanation goes here
defopts.SeriesDescription = 'QSM';
defopts.SeriesInstanceUID = [];
defopts.SeriesNumber = [];
defopts.Convert = @(x) convert(x);
defopts.Window = 0.500;
defopts.Level = 0;
defopts.flag3D = 0;
% defopts.EchoNumber = [];
% defopts.EchoTime = 0.0;
if nargin<4; opts=struct; end
deffields=fieldnames(defopts);
for i=1:length(deffields)
if ~isfield(opts, deffields{i})
opts.(deffields{i})=defopts.(deffields{i});
end
end
if isfield(files,'M')
filenames=files.M;
elseif isfield(files,'R')
filenames=files.R;
elseif isfield(files, 'info3D')
opts.flag3D=1;
else
error('No filenames (M nor R) found.');
end
flag_signed=min(M(:))<0;
if ~opts.flag3D
if size(M,3) ~= size(filenames,1)
error([num2str(size(filenames,1)) ' filenames given for ' num2str(size(M,3)) ' slices.']);
end
end
if isempty(opts.SeriesInstanceUID)
opts.SeriesInstanceUID=dicomuid;
end
progress='';
mkdir(outdir);
warning('off','images:dicom_add_attr:invalidAttribChar');
load_flag=1;
insert_flag=~opts.flag3D;
for slice=1:size(M,3)
if load_flag
if opts.flag3D
filename=files.info3D.filename;
else
filename=filenames{slice,end};
end
info = dicominfo(filename);
info.SeriesDescription = opts.SeriesDescription;
info.SeriesInstanceUID = opts.SeriesInstanceUID;
if isempty(opts.SeriesNumber)
opts.SeriesNumber=info.SeriesNumber*100;
end
info.SeriesNumber = opts.SeriesNumber;
info.SOPInstanceUID = dicomuid;
info.InstanceNumber = slice;
if opts.flag3D
load_flag=0;
end
end
if opts.flag3D
item=files.info3D.slice2index{slice};
% info.PerFrameFunctionalGroupsSequence.(item).PlanePositionSequence.Item_1.ImagePositionPatient;
info.PerFrameFunctionalGroupsSequence.(item).Private_2005_140f.Item_1.SOPInstanceUID = dicomuid;
end
im = M(:,:,slice);
if (isfield(info, 'SmallestImagePixelValue'))
info.SmallestImagePixelValue=opts.Convert(min(im(:)));
end
if (isfield(info, 'LargestImagePixelValue'))
info.LargestImagePixelValue=opts.Convert(max(im(:)));
end
if (isfield(info, 'RescaleIntercept'))
info.RescaleIntercept=0;
end
if (isfield(info, 'RescaleSlope'))
info.RescaleSlope=1;
end
info.WindowCenter=opts.Convert(opts.Level);
info.WindowWidth=opts.Convert(opts.Window);
% if opts.flag3D
% info.PerFrameFunctionalGroupsSequence.Item_1.PixelValueTransformationSequence.Item_1.RescaleIntercept=0;
% info.PerFrameFunctionalGroupsSequence.Item_1.Private_2005_140f.Item_1.RescaleIntercept=0;
% info.PerFrameFunctionalGroupsSequence.Item_1.PixelValueTransformationSequence.Item_1.RescaleSlope=1;
% info.PerFrameFunctionalGroupsSequence.Item_1.Private_2005_140f.Item_1.RescaleSlope=1;
% info.PerFrameFunctionalGroupsSequence.Item_1.FrameVOILUTSequence.Item_1.WindowCenter=opts.Convert(opts.Level);
% info.PerFrameFunctionalGroupsSequence.Item_1.FrameVOILUTSequence.Item_1.WindowWidth=opts.Convert(opts.Window);
% end
info.SamplesPerPixel=1;
info.BitsAllocated=16;
info.BitsStored=16;
info.HighBit=15;
info.PixelRepresentation=flag_signed;
if size(M,3)==slice
insert_flag=1;
end
if insert_flag
outfile=fullfile(outdir,sprintf('IM%05d.dcm', slice));
print_progress(outfile);
if opts.flag3D
f=fieldnames(info.PerFrameFunctionalGroupsSequence);
f=setdiff(f,files.info3D.slice2index,'stable');
for i=1:length(f)
info.PerFrameFunctionalGroupsSequence=rmfield(info.PerFrameFunctionalGroupsSequence, f{i});
end
for i=1:length(files.info3D.slice2index)
item=files.info3D.slice2index{i};
info.PerFrameFunctionalGroupsSequence.(item).Private_2005_140f.Item_1.InstanceNumber=1;
info.PerFrameFunctionalGroupsSequence.(item).PixelValueTransformationSequence.Item_1.RescaleIntercept=0;
info.PerFrameFunctionalGroupsSequence.(item).Private_2005_140f.Item_1.RescaleIntercept=0;
info.PerFrameFunctionalGroupsSequence.(item).PixelValueTransformationSequence.Item_1.RescaleSlope=1;
info.PerFrameFunctionalGroupsSequence.(item).Private_2005_140f.Item_1.RescaleSlope=1;
info.PerFrameFunctionalGroupsSequence.(item).FrameVOILUTSequence.Item_1.WindowCenter=opts.Convert(opts.Level);
info.PerFrameFunctionalGroupsSequence.(item).FrameVOILUTSequence.Item_1.WindowWidth=opts.Convert(opts.Window);
end
info.NumberOfFrames=length(files.info3D.slice2index);
sz=size(M);
M=reshape(opts.Convert(M), sz(1), sz(2), 1, []);
M=permute(M, [2 1 3 4]);
if isfield(files, 'slices_added')
if files.slices_added
warning('Removing empty slice at bottom of volume');
M=M(:,:,1:end-1);
end
end
%dicomwrite(M,outfile, ...
% 'CreateMode', 'copy', 'WritePrivate', true, info);
dicomwrite(M,outfile, ...
'WritePrivate', true, info);
else
if isfield(files, 'slices_added')
if files.slices_added
warning('Removing empty slice at bottom of volume');
M=M(:,:,1:end-1);
end
end
%dicomwrite(opts.Convert(M(:,:,slice))',outfile, ...
% 'CreateMode', 'copy', 'WritePrivate', true, info);
%
dicomwrite(opts.Convert(M(:,:,slice))',outfile, ...
'WritePrivate', true, info);
end
end
end
fprintf('\n');
function print_progress(arg)
num=length(progress);
num=num-numel(regexp(progress, '\\\\'));
for ii=1:num; fprintf('\b'); end
progress=['Writing file ' arg];
progress=regexprep(progress,'\','\\\\');
fprintf(progress);
end
function y=convert(x)
if flag_signed
y=int16(x*1000);
else
y=uint16(x*1000);
end
end
end
clear all;clc;close all;
% change direct to study folder
selpath = uigetdir('Select the folder including all subject');
cd(selpath);
% list folder
folderlist = dir(selpath);
folderlist = folderlist(~ismember({folderlist.name}, {'.', '..'}));
folderlist = folderlist([folderlist.isdir]);
% run MEDI
for i = 1:length(folderlist)
disp(['processing ' folderlist(i).name ' ...'])
main(folderlist(i).name, selpath);
end
% define function of MEDI processings
function main(folder, basepath)
% initialize
clearvars -except selpath folderlist folder basepath i
% move to subject folder
cd(folder)
% STEP 1: Import data
[iField,voxel_size,matrix_size,CF,delta_TE,TE,B0_dir,files]=Read_DICOM('rawdata');
%%%% Generate the Magnitude image %%%%
iMag = sqrt(sum(abs(iField).^2,4));
%%%%% provide a Mask here if possible %%%%%%
if (~exist('Mask','var'))
% Mask = genMask(iField, voxel_size);
Mask = BET(iMag,matrix_size,voxel_size);
end
%%%%% provide a noise_level here if possible %%%%%%
if (~exist('noise_level','var'))
noise_level = calfieldnoise(iField, Mask);
end
%%%%% normalize signal intensity by noise to get SNR %%%
iField = iField/noise_level;
% STEP 2a: Field Map Estimation
%%%%%Estimate the frequency offset in each of the voxel using a
%%%%%complex fitting %%%%
[iFreq_raw N_std] = Fit_ppm_complex(iField);
% STEP 2b: Spatial phase unwrapping %%%%
iFreq = unwrapPhase(iMag, iFreq_raw, matrix_size);
% STEP 2c: Background Field Removal
%%%% Background field removal %%%%
[RDF shim] = PDF(iFreq, N_std, Mask,matrix_size,voxel_size, B0_dir);
% CSF Mask for zero referencing
R2s=arlo(TE,abs(iField));
Mask_CSF = extract_CSF(R2s, Mask, voxel_size);
% STEP 3: Dipole Inversion
save RDF.mat RDF iFreq iFreq_raw iMag N_std Mask matrix_size...
voxel_size delta_TE CF B0_dir Mask_CSF;
%%%% run MEDI %%%%%
QSM = MEDI_L1('lambda',1000, 'smv', 5, 'merit');
%%% save to DICOM
% ignore warnings...
Write_DICOM(QSM,files,'QSM')
% back to study folder
cd(basepath)
end
import numpy as np
import matplotlib.pyplot as plt
import dipy.reconst.dki as dki
from dipy.core.gradients import gradient_table
from dipy.io.gradients import read_bvals_bvecs
from dipy.io.image import load_nifti, save_nifti
from dipy.segment.mask import median_otsu