ViewNiftiAfni.m 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. function varargout = ViewNiftiAfni(varargin)
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. % Visualization HUB for viewing 3D or 4D NIFTI and AFNI files. %
  4. % Last modified: Feb. 26, 2014 %
  5. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6. % Copyright (C) 2013-2014, Michael J. Cheung
  7. %
  8. % This file is a part of the MEG & PLS Pipeline (MEGPLS). For more
  9. % details, see the documentation included with the software package.
  10. %
  11. % MEGPLS is free software: you can redistribute it and/or modify it under
  12. % the terms of the GNU General Public License version 2 as published by
  13. % the Free Software Foundation. This program is distributed in the hope
  14. % that it will be useful, but WITHOUT ANY WARRANTY; without even the
  15. % implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16. % See the GNU General Public License for more details.
  17. %
  18. % You should have received a copy of the GNU General Public License along
  19. % with this program. If not, you can download the license here:
  20. % <http://www.gnu.org/licenses/old-licenses/gpl-2.0>.
  21. % Last Modified by GUIDE v2.5 28-Nov-2013 16:27:01
  22. % Begin initialization code - DO NOT EDIT
  23. gui_Singleton = 1;
  24. gui_State = struct('gui_Name', mfilename, ...
  25. 'gui_Singleton', gui_Singleton, ...
  26. 'gui_OpeningFcn', @ViewNiftiAfni_OpeningFcn, ...
  27. 'gui_OutputFcn', @ViewNiftiAfni_OutputFcn, ...
  28. 'gui_LayoutFcn', [] , ...
  29. 'gui_Callback', []);
  30. if nargin && ischar(varargin{1})
  31. gui_State.gui_Callback = str2func(varargin{1});
  32. end
  33. if nargout
  34. [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
  35. else
  36. gui_mainfcn(gui_State, varargin{:});
  37. end
  38. % End initialization code - DO NOT EDIT
  39. %--- Executes just before ViewNiftiAfni is made visible. ---%
  40. %------------------------------------------------------------%
  41. function ViewNiftiAfni_OpeningFcn(hObject, eventdata, handles, varargin)
  42. % This function has no output args, see OutputFcn.
  43. % hObject handle to figure
  44. % eventdata reserved - to be defined in a future version of MATLAB
  45. % handles structure with handles and user data (see GUIDATA)
  46. % varargin command line arguments to ViewNiftiAfni (see VARARGIN)
  47. % Choose default command line output for ViewNiftiAfni
  48. handles.output = hObject;
  49. % Make sure toolbox paths are added:
  50. [PipelineDir, ~, ~] = fileparts(which('ViewNiftiAfni.m'));
  51. addpath(genpath(PipelineDir));
  52. rmpath([PipelineDir,'/DEFAULT_SETTINGS']); % Make sure its calling from AnalysisID
  53. rmpath([PipelineDir,'/TEMPORARY_FIXES']); % Make sure its calling from FT toolbox
  54. CheckToolboxPaths(PipelineDir);
  55. % Initialize variables:
  56. handles.paths.SelectedAnatFile = ...
  57. [PipelineDir,'/MEGPLS_TOOLBOX/Masks_Templates/template_ch2+tlrc.BRIK'];
  58. set(handles.TextboxAnatFile, 'String', handles.paths.SelectedAnatFile);
  59. handles.gui.NiftiAfniList = [];
  60. handles.paths.NiftiAfniDir = [];
  61. handles.paths.SelectedFuncFile = [];
  62. % Update handles structure
  63. guidata(hObject, handles);
  64. % UIWAIT makes ViewNiftiAfni wait for user response (see UIRESUME)
  65. % uiwait(handles.figure1);
  66. %--- Outputs from this function are returned to the command line. ---%
  67. %--------------------------------------------------------------------%
  68. function varargout = ViewNiftiAfni_OutputFcn(hObject, eventdata, handles)
  69. % varargout cell array for returning output args (see VARARGOUT);
  70. % hObject handle to figure
  71. % eventdata reserved - to be defined in a future version of MATLAB
  72. % handles structure with handles and user data (see GUIDATA)
  73. % Get default command line output from handles structure
  74. varargout{1} = handles.output;
  75. %====================================%
  76. % FUNCTIONS FOR ANATOMICAL UNDERLAY: %
  77. %====================================%
  78. %--- Textbox to display selected anatomical .BRIK file: ---%
  79. %----------------------------------------------------------%
  80. function TextboxAnatFile_Callback(hObject, eventdata, handles)
  81. EnteredText = get(handles.TextboxAnatFile, 'String');
  82. if ~isequal(EnteredText, handles.paths.SelectedAnatFile)
  83. set(handles.TextboxAnatFile, 'String', handles.paths.SelectedAnatFile);
  84. msgbox('Note: Use button to change anatomy file.');
  85. end
  86. %--- Executes on button press in ButtonAnatFile. ---%
  87. %---------------------------------------------------%
  88. function ButtonAnatFile_Callback(hObject, eventdata, handles)
  89. [AnatPath, ~, ~] = fileparts(handles.paths.SelectedAnatFile);
  90. [BrikFile, BrikPath] = uigetfile([AnatPath,'/*+tlrc.BRIK'], ...
  91. 'Select anatomical underlay .BRIK file.', 'MultiSelect', 'off');
  92. if BrikFile == 0
  93. return; % If user cancels
  94. end
  95. % Set anatomy file:
  96. handles.paths.SelectedAnatFile = [BrikPath,BrikFile];
  97. set(handles.TextboxAnatFile, 'String', handles.paths.SelectedAnatFile)
  98. % Save handles:
  99. guidata(hObject, handles);
  100. %=============================================%
  101. % FUNCTIONS FOR AFNI OR NIFTI FILE SELECTION: %
  102. %=============================================%
  103. %--- Textbox to display selected target directory: ---%
  104. %-----------------------------------------------------%
  105. function TextboxNiftiAfniDir_Callback(hObject, eventdata, handles)
  106. EnteredText = get(handles.TextboxNiftiAfniDir, 'String');
  107. if ~isequal(EnteredText, handles.paths.NiftiAfniDir)
  108. set(handles.TextboxNiftiAfniDir, 'String', handles.paths.NiftiAfniDir);
  109. msgbox('Note: Use button to change search directory.');
  110. end
  111. %--- Executes on selection change in ListboxNiftiAfniFiles. ---%
  112. %---------------------------------------------------------------%
  113. function ListboxNiftiAfniFiles_Callback(hObject, eventdata, handles)
  114. if isempty(handles.paths.NiftiAfniDir) || isempty(handles.gui.NiftiAfniList)
  115. return;
  116. end
  117. handles = DetectSelectedFiles(handles);
  118. guidata(hObject, handles);
  119. %--- Executes on button press in ButtonNiftiAfniDir. ---%
  120. %--------------------------------------------------------%
  121. function ButtonNiftiAfniDir_Callback(hObject, eventdata, handles)
  122. if ~isempty(handles.paths.NiftiAfniDir)
  123. [OneUpDir, ~, ~] = fileparts(handles.paths.NiftiAfniDir);
  124. else
  125. OneUpDir = [];
  126. end
  127. SelectedPath = uigetdir(OneUpDir, 'Select directory for AFNI or NIFTI files:');
  128. if SelectedPath == 0
  129. return; % If user cancels
  130. end
  131. % Get list of AFNI & NIFTI files:
  132. AfniFiles = dir([SelectedPath,'/*+tlrc.BRIK']);
  133. NiftiFiles = dir([SelectedPath,'/*.nii']);
  134. if isempty(AfniFiles) && isempty(NiftiFiles)
  135. msgbox('Error: No AFNI or NIFTI files found inside directory.', 'Error:')
  136. return;
  137. end
  138. % Set current path and available files:
  139. handles.paths.NiftiAfniDir = SelectedPath;
  140. set(handles.TextboxNiftiAfniDir, 'String', handles.paths.NiftiAfniDir);
  141. AfniFiles = {AfniFiles.name}';
  142. NiftiFiles = {NiftiFiles.name}';
  143. handles.gui.NiftiAfniList = [AfniFiles; NiftiFiles];
  144. handles = UpdateNiftiAfniListbox (handles);
  145. handles = DetectSelectedFiles (handles);
  146. % Save handles:
  147. guidata(hObject, handles);
  148. %--- Acquire currently selected NIFTI / AFNI file: ---%
  149. %-----------------------------------------------------%
  150. function OutputHandles = DetectSelectedFiles(InputHandles)
  151. handles = InputHandles;
  152. % Get selected file:
  153. SelectedIndex = get(handles.ListboxNiftiAfniFiles, 'Value');
  154. SelectedFile = handles.gui.NiftiAfniList{SelectedIndex};
  155. handles.paths.SelectedFuncFile = [];
  156. handles.paths.SelectedFuncFile = strcat([handles.paths.NiftiAfniDir,'/'], SelectedFile);
  157. % Set output handles:
  158. OutputHandles = handles;
  159. %--- Update NIFTI / AFNI settings: ---%
  160. %-------------------------------------%
  161. function OutputHandles = UpdateNiftiAfniListbox(InputHandles)
  162. handles = InputHandles;
  163. % Update AFNI / NIFTI listbox:
  164. set(handles.ListboxNiftiAfniFiles, 'String', handles.gui.NiftiAfniList);
  165. CurrentIndex = get(handles.ListboxNiftiAfniFiles, 'Value');
  166. MaxIndex = length(handles.gui.NiftiAfniList);
  167. if isempty(CurrentIndex) || CurrentIndex == 0 || CurrentIndex > MaxIndex
  168. set(handles.ListboxNiftiAfniFiles, 'Value', MaxIndex);
  169. end
  170. % Set output handles:
  171. OutputHandles = handles;
  172. %=========================%
  173. % FUNCTIONS FOR PLOTTING: %
  174. %=========================%
  175. %--- Executes on button press in ButtonTimeLegend. ---%
  176. %-----------------------------------------------------%
  177. function ButtonTimeLegend_Callback(hObject, eventdata, handles)
  178. if isempty(handles.paths.NiftiAfniDir)
  179. msgbox('Error: Directory for AFNI / NIFTI files not selected.', 'Error:')
  180. return;
  181. end
  182. [LegendFile, LegendPath] = uigetfile([handles.paths.NiftiAfniDir,'/*_TimeLegend.txt'], ...
  183. 'Select TimeLegend file to load:', 'MultiSelect', 'off');
  184. if LegendFile == 0
  185. return; % If user cancels
  186. else
  187. open([LegendPath,LegendFile]);
  188. end
  189. %--- Converts NIFTI file to temporary AFNI for viewing: ---%
  190. %----------------------------------------------------------%
  191. function OutputAfni = ConvertNifti2Afni(InputNifti)
  192. % Get parameters for conversion to AFNI:
  193. [NiiFolder, NiiName, ~] = fileparts(InputNifti);
  194. TempAfniFile = [NiiFolder,'/',NiiName,'+tlrc.BRIK'];
  195. prompt = {'Associate NIFTI file with what template for AFNI conversion?';
  196. 'Note: If file was generated by MEGPLS pipeline, choose MNI.'}
  197. AfniSpace = questdlg(prompt, 'Template?', 'mni', 'tlrc', 'orig', 'mni');
  198. PipeSettings.Afni4D.NaNFix = 'yes';
  199. PipeSettings.Afni4D.Template = AfniSpace;
  200. % Convert selected NIFTI file to AFNI:
  201. if exist(TempAfniFile, 'file')
  202. delete(TempAfniFile);
  203. delete([NiiFolder,'/',NiiName,'+tlrc.HEAD']);
  204. end
  205. CheckSavePath(TempAfniFile, 'ViewNiftiAfni');
  206. MEGpipeline_Nifti2Afni_Guts(PipeSettings, InputNifti, TempAfniFile);
  207. % Set output AFNI file:
  208. OutputAfni = TempAfniFile;
  209. %--- Executes on button press in ButtonView4DBRIK. ---%
  210. %-----------------------------------------------------%
  211. function ButtonView4DBRIK_Callback(hObject, eventdata, handles)
  212. if isempty(handles.paths.SelectedAnatFile)
  213. msgbox('Error: Anatomical underlay not selected.', 'Error:');
  214. return;
  215. end
  216. if isempty(handles.paths.NiftiAfniDir)
  217. msgbox('Error: AFNI / NIFTI directory not selected.', 'Error:');
  218. return;
  219. end
  220. if isempty(handles.paths.SelectedFuncFile)
  221. msgbox('Error: AFNI / NIFTI file not selected.', 'Error:');
  222. return;
  223. end
  224. % Check if paths have spaces in them (AFNI paths cannot support spaces):
  225. CheckSpaces1 = strfind(handles.paths.NiftiAfniDir, ' ');
  226. CheckSpaces2 = strfind(handles.paths.SelectedAnatFile, ' ');
  227. CheckSpaces3 = strfind(handles.paths.SelectedFuncFile, ' ');
  228. if ~isempty(CheckSpaces1) || ~isempty(CheckSpaces2) || ~isempty(CheckSpaces3)
  229. msgbox('Error: AFNI fcns cannot read folder & file paths containing spaces.', 'Error:')
  230. return;
  231. end
  232. % Update selected files:
  233. handles = UpdateNiftiAfniListbox (handles);
  234. handles = DetectSelectedFiles (handles);
  235. % Create temp viewing directory:
  236. TempViewFolder = [handles.paths.NiftiAfniDir,'/TEMP_VIEWER_FILES'];
  237. if ~exist(TempViewFolder, 'dir')
  238. status = mkdir(TempViewFolder);
  239. if status == 0
  240. msgbox('Error: Failed to create viewing folder in selected directory.');
  241. return;
  242. end
  243. end
  244. % Get temp file paths:
  245. [~, AnatFile, AnatExt] = fileparts(handles.paths.SelectedAnatFile);
  246. [~, FuncFile, FuncExt] = fileparts(handles.paths.SelectedFuncFile);
  247. TempAnatFile = [TempViewFolder,'/',AnatFile,AnatExt];
  248. TempFuncFile = [TempViewFolder,'/',FuncFile,FuncExt];
  249. if exist(TempAnatFile, 'file')
  250. delete(TempAnatFile);
  251. delete([TempViewFolder,'/',AnatFile,'.HEAD']);
  252. end
  253. if exist(TempFuncFile, 'file')
  254. delete(TempFuncFile);
  255. if strcmp(FuncExt, '.BRIK')
  256. delete([TempViewFolder,'/',FuncFile,'.HEAD']);
  257. end
  258. end
  259. % Copy func file to temp view folder & convert to AFNI if needed:
  260. if strcmp(FuncExt, '.nii')
  261. copyfile(handles.paths.SelectedFuncFile, TempFuncFile, 'f');
  262. TempFuncFile = ConvertNifti2Afni(TempFuncFile);
  263. elseif strcmp(FuncExt, '.BRIK')
  264. system(['3dcopy ',handles.paths.SelectedFuncFile,' ',TempFuncFile]);
  265. end
  266. % Copy anatomy file to temp view folder & resample if needed:
  267. system(['3dcopy ',handles.paths.SelectedAnatFile,' ',TempAnatFile]);
  268. TempAnatFile = MEGpipeline_AfniResampleAnat(TempAnatFile, TempFuncFile);
  269. if isempty(TempAnatFile)
  270. msgbox('Error: Failed to resample anatomy file.', 'Error:');
  271. return;
  272. end
  273. % Check if file is 4D:
  274. CurrentDir = pwd;
  275. Opt.format = 'vector';
  276. cd(TempViewFolder);
  277. [~, CheckFunc, ~, ~] = BrikLoad(TempFuncFile, Opt);
  278. cd(CurrentDir);
  279. if numel(size(CheckFunc)) ~= 4
  280. msgbox('Error: Selected file is not 4D file. Use "View in AFNI" instead.');
  281. return;
  282. end
  283. % Run View4D_BRIK:
  284. View4D_BRIK(TempAnatFile, TempFuncFile, [], []);
  285. %--- Executes on button press in ButtonViewAFNI. ---%
  286. %---------------------------------------------------%
  287. function ButtonViewAFNI_Callback(hObject, eventdata, handles)
  288. if isempty(handles.paths.SelectedAnatFile)
  289. msgbox('Error: Anatomical underlay not selected.', 'Error:');
  290. return;
  291. end
  292. if isempty(handles.paths.NiftiAfniDir)
  293. msgbox('Error: AFNI /NIFTI directory not selected.', 'Error:');
  294. return;
  295. end
  296. if isempty(handles.paths.SelectedFuncFile)
  297. msgbox('Error: AFNI / NIFTI file not selected.', 'Error:');
  298. return;
  299. end
  300. % Check if paths have spaces in them (AFNI paths cannot support spaces):
  301. CheckSpaces1 = strfind(handles.paths.NiftiAfniDir, ' ');
  302. CheckSpaces2 = strfind(handles.paths.SelectedAnatFile, ' ');
  303. CheckSpaces3 = strfind(handles.paths.SelectedFuncFile, ' ');
  304. if ~isempty(CheckSpaces1) || ~isempty(CheckSpaces2) || ~isempty(CheckSpaces3)
  305. msgbox('Error: AFNI fcns cannot read folder & file paths containing spaces.', 'Error:')
  306. return;
  307. end
  308. % Update selected files:
  309. handles = UpdateNiftiAfniListbox (handles);
  310. handles = DetectSelectedFiles (handles);
  311. % Create temp viewing directory:
  312. TempViewFolder = [handles.paths.NiftiAfniDir,'/TEMP_VIEWER_FILES'];
  313. if ~exist(TempViewFolder, 'dir')
  314. status = mkdir(TempViewFolder);
  315. if status == 0
  316. msgbox('Error: Failed to create viewing folder in selected directory.');
  317. return;
  318. end
  319. end
  320. % Get temp file paths:
  321. [~, AnatFile, AnatExt] = fileparts(handles.paths.SelectedAnatFile);
  322. [~, FuncFile, FuncExt] = fileparts(handles.paths.SelectedFuncFile);
  323. TempAnatFile = [TempViewFolder,'/',AnatFile,AnatExt];
  324. TempFuncFile = [TempViewFolder,'/',FuncFile,FuncExt];
  325. if exist(TempAnatFile, 'file')
  326. delete(TempAnatFile);
  327. delete([TempViewFolder,'/',AnatFile,'.HEAD']);
  328. end
  329. if exist(TempFuncFile, 'file')
  330. delete(TempFuncFile);
  331. if strcmp(FuncExt, '.BRIK')
  332. delete([TempViewFolder,'/',FuncFile,'.HEAD']);
  333. end
  334. end
  335. % Copy func file to temp view folder & convert to AFNI if needed:
  336. if strcmp(FuncExt, '.nii')
  337. copyfile(handles.paths.SelectedFuncFile, TempFuncFile, 'f');
  338. TempFuncFile = ConvertNifti2Afni(TempFuncFile);
  339. elseif strcmp(FuncExt, '.BRIK')
  340. system(['3dcopy ',handles.paths.SelectedFuncFile,' ',TempFuncFile]);
  341. end
  342. % Copy anatomy file to temp view folder & create resample if needed:
  343. % Note: Do not change TempAnatFile to resampled version (want high-res as default input).
  344. system(['3dcopy ',handles.paths.SelectedAnatFile,' ',TempAnatFile]);
  345. ResampledAnat = MEGpipeline_AfniResampleAnat(TempAnatFile, TempFuncFile);
  346. if isempty(ResampledAnat)
  347. msgbox('Warning: Failed to resample anatomy file.', 'Error:');
  348. end
  349. % Prepare file calls to AFNI:
  350. [~, AnatName, ~] = fileparts(TempAnatFile);
  351. AnatName(end-4:end) = []; % Remove +view label
  352. [~, FuncName, ~] = fileparts(TempFuncFile);
  353. FuncName(end-4:end) = [];
  354. % Set environmental variables:
  355. setenv('AFNI_SLAVE_FUNCTIME', 'YES'); % Locks overlay with time-index (Newer versions).
  356. setenv('AFNI_SLAVE_BUCKETS_TOO', 'YES'); % Locks overlay with time-index (Older versions).
  357. setenv('AFNI_SLAVE_THRTIME', 'YES'); % Locks threshold with time-index (Older versions).
  358. setenv('AFNI_SLAVE_THROLAY', 'OLay'); % Locks threshold with time-index (Newer versions).
  359. setenv('AFNI_LEFT_IS_LEFT', 'YES'); % Sets images to neurological view.
  360. setenv('AFNI_THRESH_AUTO', 'NO'); % Threshold slider does not change automatically.
  361. setenv('AFNI_THRESH_LOCK', 'VALUE');
  362. setenv('AFNI_FLOATSCAN', 'YES');
  363. if strcmp(getenv('AFNI_LEFT_IS_LEFT'), 'NO')
  364. msgbox('NOTE: "AFNI_LEFT_IS_LEFT" env. variable is now set to ''YES''.')
  365. end
  366. % Open AFNI command:
  367. CmdLine = ['afni -com ''' ...
  368. 'OPEN_WINDOW A.axialimage;' ...
  369. ' OPEN_WINDOW A.sagittalimage;' ...
  370. ' OPEN_WINDOW A.coronalimage;' ...
  371. ' SWITCH_UNDERLAY A.',AnatName,';' ... % Underlay .BRIK
  372. ' SWITCH_OVERLAY A.',FuncName,';' ... % Overlay .BRIK
  373. ' SET_SUBBRICKS A 1 1 1;' ... % Sets .BRIK index to 1
  374. ' SET_FUNC_AUTORANGE A.+;' ... % Turns ON autorange
  375. ' REDISPLAY;'' &'];
  376. CurrentDir = pwd;
  377. cd(TempViewFolder);
  378. system(CmdLine);
  379. cd(CurrentDir);
  380. %============================%
  381. % GUIDE CREATEFCN FUNCTIONS: %
  382. %============================%
  383. % --- Executes during object creation, after setting all properties.
  384. function TextboxAnatFile_CreateFcn(hObject, eventdata, handles)
  385. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  386. set(hObject,'BackgroundColor','white');
  387. end
  388. % --- Executes during object creation, after setting all properties.
  389. function TextboxNiftiAfniDir_CreateFcn(hObject, eventdata, handles)
  390. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  391. set(hObject,'BackgroundColor','white');
  392. end
  393. % --- Executes during object creation, after setting all properties.
  394. function ListboxNiftiAfniFiles_CreateFcn(hObject, eventdata, handles)
  395. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  396. set(hObject,'BackgroundColor','white');
  397. end