fMRI預處理之DICOM格式轉NII格式——SPM12批次碼

z_s_s發表於2024-07-24

執行說明:subjectsdir換成自己的資料夾地址, 有多少個受試者的DICOM就有多少個subjects子元素 。

%-----------------------------------------------------------------------
% Job saved on 02-Sep-2019 18:21:16 by cfg_util (rev $Rev: 6942 $)
% spm SPM - SPM12 (7219)
% cfg_basicio BasicIO - Unknown
%-----------------------------------------------------------------------
%%
% 這個m檔案用來執行spm的matlabbatch
% 該檔案中的檔案位置是基於linux系統的,如果是windows系統需要修改/為\
clear
% spm_path = '~\spm12';      %設定spm12的位置(這裡填的是安裝=spm12的絕對位置) 我這裡已經安裝好了
% addpath(spm_path);
spm('defaults', 'fmri');
spm_jobman('initcfg');

%%
subjectsdir = {'B:\fMRI\preprocess_for_batch\CN'};% 這裡是data資料夾的絕對位置
subjects = {'sbj01','sbj02','sbj03','sbj04','sbj05','sbj06','sbj07','sbj08','sbj09','sbj10','sbj11','sbj12','sbj13','sbj14','sbj15','sbj16','sbj17','sbj18','sbj19','sbj20','sbj21','sbj22','sbj23','sbj24','sbj25','sbj26','sbj27','sbj28','sbj29','sbj30','sbj31','sbj32','sbj33','sbj34','sbj35','sbj36'};          % 單個或多個被試的資料夾
funcdir  =  fullfile('fMRI_DICOM');              % 第一個Session的資料夾(由於preprocessing.mat中只新增了一個Session,所以這裡也只使用一個Session。)
%   F = fullfile(FOLDERNAME1, FOLDERNAME2, ..., FILENAME) builds a full
%   file specification F from the folders and file name specified. Input
%   arguments FOLDERNAME1, FOLDERNAME2, etc. and FILENAME can be strings,
%   character vectors, or cell arrays of character vectors. Non-scalar
%   strings and cell arrays of character vectors must all be the same size.

%   FULLFILE collapses inner repeated file separators unless they appear at 
%   the beginning of the full file specification. FULLFILE also collapses 
%   relative folders indicated by the dot symbol, unless they appear at 
%   the end of the full file specification. Relative folders indicated 
%   by the double-dot symbol are not collapsed.
%


% funcdir2  =  fullfile('Session2');             % 第二個Session的資料夾
anatdir =  fullfile('MRI_DICOM');              % 結構像的資料夾

nsubj = length(subjects);   % 被試的數量
jobs_fMRI = cell(1,1);       % job的數量,每個被試一個job
jobs_MRI = cell(1,1);
nsubj =2;
inputs = cell(0,1);

nrun=1;  % session的數量
%ntimepoint=190;  %刪除了前面的10個時間點後剩餘的時間點
%%
for csubj_fMRI = 1:36
    subjdir = {spm_select('CPath',subjects{csubj_fMRI}, subjectsdir)};%Cpath 的c = canonical

    % Session1資料夾
    fdir =  {spm_select('CPath', funcdir, subjdir)};    %選擇當前被試(csubj_fMRI)的Session1資料夾
    ffiles = spm_select('List', fdir, '\\*.dcm');   %選擇這個資料夾中所有.nii結尾的檔案,即Session1的所有原始功能像檔案
    %如果沒有功能像檔案就報錯
    nimage = size(ffiles,1);
    if nimage == 0
        warning(sprintf('No functional file found for %s', subjects{csubj_fMRI}))
        return
    end

    cffiles = cellstr(ffiles);
    ntimepoint = length(cffiles);

    funcfiles = cell(1, nrun);
    sessionfiles = cell(nrun,ntimepoint);

    for i = 1:nrun
        for j = 1:ntimepoint
            sessionfiles{i,j}=strcat(fdir{1},'\',cffiles{j});   % 在這裡在每一個功能像檔案的絕對路徑後面新增,1
        end
        funcfiles{1,i} = {sessionfiles{i,:}}';    % 如果有多個Sessions,funcfiles中就會有多個sessionfiles
    end
    clear matlabbatch


    % preprocessing job
    display 'Creating preprocessing job'  %在matlab的命令列視窗顯示Creating preprocessing job
   
    goalDirectory = {'B:\fMRI\preprocess_for_batch\CN'};%這樣生成的cell 沒有'' ,沒有顯示內容的型別
    goalDirectory_subj = {spm_select('CPath', subjects{csubj_fMRI} ,goalDirectory)};% 這樣生成的也 沒有
    goalDirectory_subj = char(goalDirectory_subj);%這樣生成的也沒有'' 但是會顯示型別

    if ~exist(goalDirectory_subj, 'dir')
%         mkdir goalDirectory subjects{csubj_fMRI}%這裡十分可惡 goalDirectory 不能識別為變數
          goalDirectory = goalDirectory{1};
%           mkdir [goalDirectory] subjects{csubj_fMRI}
          mkdir([goalDirectory '\' subjects{csubj_fMRI}]);%這就是真理 上matlab 網站找著了 
%%     else
%         warning(sprintf('Folder has been created and make sure if files needed has exited', subjects{csubj_fMRI}))
%         return 
    end

    goalDirectory_subj = {goalDirectory_subj};%沒有前面一行程式碼 這樣顯示的會有''  ,加上前面一行的話 會變成""

    goalDirectory_subj_fMRI = {spm_select('CPath', 'fMRI' ,goalDirectory_subj)}; %這個會自動合併 connonical {'fMRI'} 把 {}去了
    goalDirectory_subj_fMRI = char(goalDirectory_subj_fMRI);%為什麼這裡要加1在花括號裡?為甚這樣就行?可能因為前面的程式碼,生成的就是一個cell。那更前面不也是嘛,為什麼就行?原因出來了在上一行。

    
    if ~exist(goalDirectory_subj_fMRI, 'dir')%經過這裡一手  就會把goalDirectory 變成cell下面就不能用了
        %string  = convertCharsToStrings(goalDirectory_subj_fMRI);
           goalDirectory_subj = goalDirectory_subj{1};
%           mkdir [goalDirectory] subjects{csubj_fMRI}
          mkdir([goalDirectory_subj '\' 'fMRI']);%這就是真理 上matlab 網站找著了 
    else
        warning(sprintf('Folder has been created and make sure if files needed has exited', subjects{csubj_fMRI}))
        return 
    end
     
    matlabbatch{1}.spm.util.import.dicom.data = funcfiles{1,1}(:,1);
    matlabbatch{1}.spm.util.import.dicom.root = 'flat';
    matlabbatch{1}.spm.util.import.dicom.outdir = {goalDirectory_subj_fMRI};
    matlabbatch{1}.spm.util.import.dicom.protfilter = '.*';
    matlabbatch{1}.spm.util.import.dicom.convopts.format = 'nii';
    matlabbatch{1}.spm.util.import.dicom.convopts.meta = 0;
    matlabbatch{1}.spm.util.import.dicom.convopts.icedims = 0;

    matfile = sprintf('preprocess_fMRI_%s.mat', subjects{csubj_fMRI});
%     save(matfile,'matlabbatch');
    jobs_fMRI{csubj_fMRI} = matfile;  %jobs這個變數中儲存了所有被試的matlabbatch
spm_jobman('run',matlabbatch);
end




for csubj_MRI = 1:36
    subjdir = {spm_select('CPath',subjects{csubj_MRI}, subjectsdir)};%Cpath 的c = canonical

    % Session1資料夾
    fdir =  {spm_select('CPath', anatdir, subjdir)};    %選擇當前被試(csubj_fMRI)的Session1資料夾
    ffiles = spm_select('List', fdir, '\\*.dcm');   %選擇這個資料夾中所有.nii結尾的檔案,即Session1的所有原始功能像檔案
    %如果沒有功能像檔案就報錯
    nimage = size(ffiles,1);
    if nimage == 0
        warning(sprintf('No functional file found for %s', subjects{csubj_MRI}))
        return
    end

    cffiles = cellstr(ffiles);
    ntimepoint = length(cffiles);

    funcfiles = cell(1, nrun);
    sessionfiles = cell(nrun,ntimepoint);

    for i = 1:nrun
        for j = 1:ntimepoint
            sessionfiles{i,j}=strcat(fdir{1},'\',cffiles{j});   % 在這裡在每一個功能像檔案的絕對路徑後面新增,1
        end
        funcfiles{1,i} = {sessionfiles{i,:}}';    % 如果有多個Sessions,funcfiles中就會有多個sessionfiles
    end
    clear matlabbatch


    % preprocessing job
    display 'Creating preprocessing job'  %在matlab的命令列視窗顯示Creating preprocessing job

    goalDirectory = {'B:\fMRI\preprocess_for_batch\CN'};
    goalDirectory_subj = {spm_select('CPath', subjects{csubj_MRI} ,goalDirectory)}; 
    goalDirectory_subj = char(goalDirectory_subj);

     
    if ~exist(goalDirectory_subj, 'dir')
        goalDirectory = goalDirectory{1};
        mkdir([goalDirectory '\' subjects{csubj_MRI}]);
    end

    goalDirectory_subj = {goalDirectory_subj};


    goalDirectory_MRI = {spm_select('CPath', 'MRI' ,goalDirectory_subj)}; 
    goalDirectory_MRI = char(goalDirectory_MRI);
    if ~exist(goalDirectory_MRI, 'dir')
       % mkdir 'B:\fMRI\preprocess_for_batch\AD' MRI
       goalDirectory_subj = goalDirectory_subj{1};
       mkdir([goalDirectory_subj '\' 'MRI']);
    else
        warning(sprintf('Folder has been created and make sure if files needed has exited', subjects{csubj_MRI}))
        return 
    end

    matlabbatch{1}.spm.util.import.dicom.data = funcfiles{1,1}(:,1);
    matlabbatch{1}.spm.util.import.dicom.root = 'flat';
    matlabbatch{1}.spm.util.import.dicom.outdir = {goalDirectory_MRI};
    matlabbatch{1}.spm.util.import.dicom.protfilter = '.*';
    matlabbatch{1}.spm.util.import.dicom.convopts.format = 'nii';
    matlabbatch{1}.spm.util.import.dicom.convopts.meta = 0;
    matlabbatch{1}.spm.util.import.dicom.convopts.icedims = 0;

    matfile = sprintf('preprocess_MRI_%s.mat', subjects{csubj_MRI});
%     save(matfile,'matlabbatch');

    jobs_MRI{csubj_MRI} = matfile;  %jobs這個變數中儲存了所有被試的matlabbatch
spm_jobman('run',matlabbatch);
end
  

  

相關文章