ds003604/code/func_qa/mv/art_global_bdl.m
2021-04-08 18:48:11 +00:00

626 lines
26 KiB (Stored with Git Annex)
Matlab

function art_global_jin(Images,RealignmentFile,HeadMaskType, RepairType, Percent_thresh, mv_thresh,MVMTTHRESHOLD)
% FORMAT art_global (v.2.6)
%
% Art_global allows visual inspection of average intensity and
% scan to scan motion of fMRI data, and offers methods to repair outliers
% in the data. Outliers are scans whose global intensity is very different
% from the mean, or whose scan-to-scan motion is large. Thresholds that
% define the outliers are shown, and they can be adjusted by the user.
% Margins are defined around the outliers to assure that the repaired
% data will satisfy the "slowly-varying" background assumption of GLM
% models. Outliers can also be defined by user manual edits. When all
% repair parameters are set, the user writes new repaired files by using
% the Repair button in the GUI. Repairs can be done by interpolation
% between the nearest non-repaired scans (RECOMMNEDED),
% or despike interpolation using the
% immediate before and after scans, or inserting the mean image in place
% of the image to be repaired. Repairs will change the scans marked by
% red vertical lines. Scans marked by green vertical lines are unchanged,
% but will be added to the deweighting text file.
% Repaired images have the prefix "v" and are written to the same
% folder as the input images. The input images are preserved in place.
% Unchanged images are copied to a "v" named file, so SPM can run with
% the "v" images. The program writes a file art_repaired.txt with a list
% of all repaired images, and art_deweighted.txt with a list of all images
% to be deweighted during estimation. Deweighting is recommended for both
% repaired images and margin images. Repairs bias contrasts lower, but
% informally, the effect seems small when fewer than 5-10% of scans are
% repaired. For deeper repairs, deweighting must be implemented in a
% batch script, e.g. as in the art_redo function.
% A set of default thresholds is suggested ( 1.3% variation in global
% intensity, 0.5 mm/TR scan-to-scan motion.) Informally, these values
% are OK for small to moderate repairs. The thresholds can be reduced for
% good data (motion -> 0.3) , and should be raised for severely noisy data
% (motion -> 1.0). The values of the intensity and motion thresholds are
% linked and will change together. As a default, all images with total
% movement > 3 mm will also be marked for repair. For special situations,
% the outlier edit feature can mark additional scans. When motion
% regressors will be used, suggest setting the motion threshold to 0.5
% and not applying the margins.
%
% For MULTIPLE SESSIONS, we suggest realigning each session separately,
% and repairing each session separately. This approach agrees more
% with SPM standard practice, and clinical subjects often move between
% sessions. This approach differs from previous versions of this program.
%
% For batch scripts, use
% FORMAT art_global(Images, RealignmentFile, HeadMaskType, RepairType)
% Images = Full path name of images to be repaired.
% For multiple sessions, all Images are in one array, e.g.SPM.xY.P
% RealignmentFile = Full path name of realignment file
% For multiple sessions, cell array with one name per session.
% HeadMaskType = 1 for SPM mask, = 4 for Automask
% RepairType = 1 for ArtifactRepair alone (0.5 movement and add margin).
% = 2 for Movement Adjusted images (0.5 movement, no margin)
% = 0 No repairs are done, bad scans are found.
% Listed in art_suspects.txt for motion adjustment.
% Hardcoded actions:
% Does repair, does not force repair of first scan.
% ----------------------------------------------------------------------
% v2.5, May 2009 pkm - adds SPM8, RepairType=0.
% v2.6, Dec 2014 supports SPM12.
% v2.4, Mar 2009 pkm
% Only one session allowed. Realign and repair each session separately.
% Increment global intensity at 0.05%, instead of 0.1 in z-score.
% Movement adaptive threshold now affects global threshold.
% v2.3, July 2008 PKM
% Allows automatic adaptive threshold for movement
% Compatible SPM5 and SPM2
% Lowered default thresholds, to catch more deep breath artifacts.
% v2.2, July 2007 PKM
% Also marks scan before a big movement for mv_out repair.
% Allows two kinds of RepairType in batch, with and without margin.
% Fixed logic for user masked mean
% Adds user GUI option to repair all scans with movement > 3 mm.
% small fix to subplots
% v2.1, Jan. 2007. PKM.
% Prints copy of art_global figure in batch mode.
% Allows multiple sessions in batch mode.
% Images is full path name of all sessions, e.g. SPM.xY.P
% Realignment file is one cell per session with full rp file name.
% For SPM5, finds size of VY.dim. ( Compatible with SPM2)
%
% Paul Mazaika, September 2006.
% -----------------------
% Initialize, begin loop
% -----------------------
pfig = [];
% Configure while preserving old SPM versions
spmv = spm('Ver'); spm_ver = 'spm5'; % chooses spm_select to read vols
if (strcmp(spmv,'SPM2')) spm_ver = 'spm2'; end
if (strcmp(spmv,'SPM2') || strcmp(spmv,'SPM5')) spm_defaults;
else spm('Defaults','fmri'); end
% ------------------------
% Default values for outliers
% ------------------------
% When std is very small, set a minimum threshold based on expected physiological
% noise. Scanners have about 0.1% error when fully in spec.
% Gray matter physiology has ~ 1% range, ~0.5% RMS variation from mean.
% For 500 samples, expect a 3-sigma case, so values over 1.5% are
% suspicious as non-physiological noise. Data within that range are not
% outliers. Set the default minimum percent variation to be suspicious...
%Percent_thresh = 1.3;
% Alternatively, deviations over 2*std are outliers, if std is not very small.
z_thresh = 2; % Currently not used for default.
% Large intravolume motion may cause image reconstruction
% errors, and fast motion may cause spin history effects.
% Guess at allowable motion within a TR. For good subjects,
% would like this value to be as low as 0.3. For clinical subjects,
% set this threshold higher.
%mv_thresh = 0.5; % try 0.3 for subjects with intervals with low noise
% try 1.0 for severely noisy subjects
% ------------------------
% Collect files
% ------------------------
if nargin > 0
% num_sess = 1; % Only one session;
num_sess = size(RealignmentFile,1);
global_type_flag = HeadMaskType;
realignfile = 1;
P{1} = Images;
M = [];
for i = 1:num_sess
%P{i} = Images{i};
mvmt_file = char(RealignmentFile(i,:));
M{i} = load(mvmt_file);
%[mv_path,mv_name,mv_ext] = fileparts(mvmt_file);
% M{1} = mv_data;
end
repair1_flag = 0; % Only repair scan 1 when necessary
%repair1_flag = 1; % Force repair scan 1 (Reisslab)
GoRepair = 1; % Automatic Repair
if nargin == 4 % To stay backward compatible with v2.1
if RepairType == 1
GoRepair = 1;
elseif RepairType == 2
mv_thresh = 0.5;
GoRepair = 2;
elseif RepairType == 0 % no repairs done, bad scans found.
mv_thresh = 0.5;
GoRepair = 4;
end
end
else
%num_sess = spm_input('How many sessions?',1,'n',1,1);
num_sess = 1;
global_type_flag = spm_input('Which global mean to use?', 1, 'm', ...
'Regular SPM mask | Auto ( Generates ArtifactMask and can Calculate Movement )| User Mask ( in same voxel space as functional images ) | Every Voxel',...
[1 4 3 2], 2);
if global_type_flag==3
if strcmp(spm_ver,'spm5')
mask = spm_select(1, 'image', 'Select mask image in functional space');
else % spm2 version
mask = spm_get(1, '.img', 'Select mask image in functional space');
end
end
% If there are no realignment files available, compute some instead.
realignfile = 1; % Default case is like artdetect4.
if global_type_flag == 4
realignfile = spm_input('Have realignment files?',1, 'b', ' Yes | No ', [ 1 0 ], 1);
end
M = []; P = [];
if strcmp(spm_ver,'spm5')
for i = 1:num_sess
P{i} = spm_select(Inf,'image',['Select data images for session' num2str(i) ':']);
if realignfile == 1
mvmt_file = spm_select(1,'any',['Select movement params file for session' num2str(i) ':']);
M{i} = load(mvmt_file);
end
end
else % spm2 version
for i = 1:num_sess
P{i} = spm_get(Inf,'.img',['Select data images for session' num2str(i) ':']);
if realignfile == 1
mvmt_file = spm_get(1,'.txt',['Select movement params file for session' num2str(i) ':']);
M{i} = load(mvmt_file);
end
end
end
repair1_flag = spm_input('Always repair 1st scan of each session?', '+1', 'y/n', [1 0], 1);
GoRepair = 0; % GUI repair
RepairType = 2; % Allows adaptive threshold
end % End of GUI loop
if global_type_flag==3
maskY = spm_read_vols(spm_vol(mask));
%maskXYZmm = maskXYZmm(:,find(maskY==max(max(max(maskY)))));
maskcount = sum(sum(sum(maskY))); % Number of voxels in mask.
voxelcount = prod(size(maskY)); % Number of voxels in 3D volume.
end
if global_type_flag == 4 % Automask option
disp('Generated mask image is written to file ArtifactMask.img.')
Pnames = P{1};
Automask = art_automask(Pnames(1,:),-1,1);
maskcount = sum(sum(sum(Automask))); % Number of voxels in mask.
voxelcount = prod(size(Automask)); % Number of voxels in 3D volume.
end
spm_input('!DeleteInputObj');
P = char(P);
%if nargin == 0
mv_data = [];
for i = 1:length(M)
mv_data = vertcat(mv_data,M{i});
end
%end
% -------------------------
% get file identifiers and Global values
% -------------------------
fprintf('%-4s: ','Mapping files...')
VY = spm_vol(P);
fprintf('%3s\n','...done')
temp = any(diff(cat(1,VY.dim),1,1),1);
if strcmp(spm_ver,'spm5')
% or could test length(temp) == 3
if ~isempty(find(diff(cat(1,VY.dim)) ~= 0 ))
error('images do not all have the same dimensions (SPM5)')
end
elseif length(temp) == 4 % SPM2 case
if any(any(diff(cat(1,VY.dim),1,1),1)&[1,1,1,0])
error('images do not all have the same dimensions')
end
end
nscans = size(P,1);
%keyboard;
% ------------------------
% Compute Global variate
%--------------------------
%GM = 100;
g = zeros(nscans,1);
fprintf('%-4s: %3s','Calculating globals...',' ')
if global_type_flag==1 % regular mean
for i = 1:nscans
g(i) = spm_global(VY(i));
end
elseif global_type_flag==2 % every voxel
for i = 1:nscans
g(i) = mean(mean(mean(spm_read_vols(VY(i)))));
end
elseif global_type_flag == 3 % user masked mean
Y = spm_read_vols(VY(1));
%voxelcount = prod(size(Y));
%vinv = inv(VY(1).mat);
%[dummy, idx_to_mask] = intersect(XYZmm', maskXYZmm', 'rows');
%maskcount = length(idx_to_mask);
for i = 1:nscans
Y = spm_read_vols(VY(i));
Y = Y.*maskY;
%Y(idx_to_mask) = [];
g(i) = mean(mean(mean(Y)))*voxelcount/maskcount;
%g(i) = mean(Y(idx_to_mask));
end
else % global_type_flag == 4 % auto mask
for i = 1:nscans
Y = spm_read_vols(VY(i));
Y = Y.*Automask;
if realignfile == 0
output = art_centroid(Y);
centroiddata(i,1:3) = output(2:4);
g(i) = output(1)*voxelcount/maskcount;
else % realignfile == 1
g(i) = mean(mean(mean(Y)))*voxelcount/maskcount;
end
end
% If computing approximate translation alignment on the fly...
% centroid was computed in voxels
% voxel size is VY(1).mat(1,1), (2,2), (3,3).
% calculate distance from mean as our realignment estimate
% set rotation parameters to zero.
if realignfile == 0 % change to error values instead of means.
centroidmean = mean(centroiddata,1);
for i = 1:nscans
mv0data(i,:) = - centroiddata(i,:) + centroidmean;
end
% THIS MAY FLIP L-R (x translation)
mv_data(1:nscans,1) = mv0data(1:nscans,1)*VY(1).mat(1,1);
mv_data(1:nscans,2) = mv0data(1:nscans,2)*VY(1).mat(2,2);
mv_data(1:nscans,3) = mv0data(1:nscans,3)*VY(1).mat(3,3);
mv_data(1:nscans,4:6) = 0;
end
end
% Convert rotation movement to degrees
mv_data(:,4:6)= mv_data(:,4:6)*180/pi;
fprintf('%s%3s\n','...done\n')
if global_type_flag==3
fprintf('\n%g voxels were in the user mask.\n', maskcount)
end
if global_type_flag==4
fprintf('\n%g voxels were in the auto generated mask.\n', maskcount)
end
% ------------------------
% Compute default out indices by z-score, or by Percent-level is std is small.
% ------------------------
% Consider values > Percent_thresh as outliers (instead of z_thresh*gsigma) if std is small.
gsigma = std(g);
gmean = mean(g);
pctmap = 100*gsigma/gmean;
mincount = Percent_thresh*gmean/100;
%z_thresh = max( z_thresh, mincount/gsigma );
z_thresh = mincount/gsigma; % Default value is PercentThresh.
z_thresh = 0.1*round(z_thresh*10); % Round to nearest 0.1 Z-score value
zscoreA = (g - mean(g))./std(g); % in case Matlab zscore is not available
glout_idx = (find(abs(zscoreA) > z_thresh))';
% ------------------------
% Compute default out indices from rapid movement
% ------------------------
% % Rotation measure assumes voxel is 65 mm from origin of rotation.
if realignfile == 1 | realignfile == 0
delta = zeros(nscans,1); % Mean square displacement in two scans
for i = 2:nscans
delta(i,1) = (mv_data(i-1,1) - mv_data(i,1))^2 +...
(mv_data(i-1,2) - mv_data(i,2))^2 +...
(mv_data(i-1,3) - mv_data(i,3))^2 +...
1.28*(mv_data(i-1,4) - mv_data(i,4))^2 +...
1.28*(mv_data(i-1,5) - mv_data(i,5))^2 +...
1.28*(mv_data(i-1,6) - mv_data(i,6))^2;
delta(i,1) = sqrt(delta(i,1));
end
end
% Also name the scans before the big motions (v2.2 fix)
deltaw = zeros(nscans,1);
for i = 1:nscans-1
deltaw(i) = max(delta(i), delta(i+1));
end
delta(1:nscans-1,1) = deltaw(1:nscans-1,1);
% Adapt the threshold (v2.3 fix)
if RepairType == 2 | GoRepair == 4
delsort = sort(delta);
if delsort(round(0.75*nscans)) > mv_thresh
mv_thresh = min(1.0,delsort(round(0.75*nscans)));
words = ['Automatic adjustment of movement threshold to ' num2str(mv_thresh)];
disp(words)
Percent_thresh = mv_thresh + 0.8; % v2.4
end
end
mvout_idx = find(delta > mv_thresh)';
% Total repair list
out_idx = unique([mvout_idx glout_idx]);
if repair1_flag == 1
out_idx = unique([ 1 out_idx]);
end
% Initial deweight list before margins
outdw_idx = out_idx;
% Initial clip list without removing large displacements
clipout_idx = out_idx;
% -----------------------
% Draw initial figure
% -----------------------
figure('Units', 'normalized', 'Position', [0.2 0.2 0.6 0.7]);
rng = max(g) - min(g); % was range(g);
pfig = gcf;
% Don't show figure in batch runs
if (nargin > 0); set(pfig,'Visible','off'); end
subplot(5,1,1);
plot(g);
%xlabel(['artifact index list [' int2str(out_idx') ']'], 'FontSize', 8, 'Color','r');
%ylabel(['Range = ' num2str(rng)], 'FontSize', 8);
ylabel('Global Avg. Signal');
xlabel('Red vertical lines are to depair. Green vertical lines are to deweight.');
title('ArtifactRepair GUI to repair outliers and identify scans to deweight');
%if ( global_type_flag == 1 ) title('Global Mean - Regular SPM'); end
%if ( global_type_flag == 2 ) title('Global Mean - Every Voxel'); end
%if ( global_type_flag == 3 ) title('Global Mean - User Defined Mask'); end
%if ( global_type_flag == 4 ) title('Global Mean - Generated ArtifactMask'); end
% Add vertical exclusion lines to the global intensity plot
axes_lim = get(gca, 'YLim');
axes_height = [axes_lim(1) axes_lim(2)];
for i = 1:length(outdw_idx) % Scans to be Deweighted
line((outdw_idx(i)*ones(1, 2)), axes_height, 'Color', 'g');
end
if GoRepair == 2
for i = 1:length(outdw_idx) % Scans to be Deweighted
line((outdw_idx(i)*ones(1, 2)), axes_height, 'Color', 'r');
end
end
subplot(5,1,2);
%thresh_axes = gca;
%set(gca, 'Tag', 'threshaxes');
zscoreA = (g - mean(g))./std(g); % in case Matlab zscore is not available
plot(abs(zscoreA));
ylabel('Std away from mean');
xlabel('Scan Number - horizontal axis for all plots');
thresh_x = 1:nscans;
thresh_y = z_thresh*ones(1,nscans);
line(thresh_x, thresh_y, 'Color', 'r');
% Mark global intensity outlier images with vertical lines
axes_lim = get(gca, 'YLim');
axes_height = [axes_lim(1) axes_lim(2)];
for i = 1:length(glout_idx)
line((glout_idx(i)*ones(1, 2)), axes_height, 'Color', 'r');
end
if realignfile == 1
subplot(5,1,3);
xa = [ 1:nscans];
plot(xa,mv_data(:,1),'b-',xa,mv_data(:,2),'g-',xa,mv_data(:,3),'r-',...
xa,mv_data(:,4),'r--',xa,mv_data(:,5),'b--',xa,mv_data(:,6),'g--');
%plot(,'--');
ylabel('ReAlignment');
xlabel('Translation (mm) solid lines, Rotation (deg) dashed lines');
%legend('x mvmt', 'y mvmt', 'z mvmt','pitch','roll','yaw',0);
legend('x mvmt', 'y mvmt', 'z mvmt','pitch','roll','yaw');
h = gca;
set(h,'Ygrid','on');
elseif realignfile == 0
subplot(5,1,3);
plot(mv0data(:,1:3));
ylabel('Alignment (voxels)');
xlabel('Scans. VERY APPROXIMATE EARLY-LOOK translation in voxels.');
%legend('x mvmt', 'y mvmt', 'z mvmt',0);
legend('x mvmt', 'y mvmt', 'z mvmt');
h = gca;
set(h,'Ygrid','on');
end
subplot(5,1,4); % Rapid movement plot
plot(delta);
ylabel('Motion (mm/TR)');
xlabel('Scan to scan movement (~mm). Rotation assumes 65 mm from origin');
y_lim = get(gca, 'YLim');
% legend('Fast motion',0);
legend('Fast motion');
h = gca;
set(h,'Ygrid','on');
thresh_x = 1:nscans;
thresh_y = mv_thresh*ones(1,nscans);
line(thresh_x, thresh_y, 'Color', 'r');
% Mark all movement outliers with vertical lines
subplot(5,1,4)
axes_lim = get(gca, 'YLim');
axes_height = [axes_lim(1) axes_lim(2)];
for i = 1:length(mvout_idx)
line((mvout_idx(i)*ones(1,2)), axes_height, 'Color', 'r');
end
%keyboard;
h_rangetext = uicontrol(gcf, 'Units', 'characters', 'Position', [10 10 18 2],...
'String', 'StdDev of data is: ', 'Style', 'text', ...
'HorizontalAlignment', 'left', ...
'BackgroundColor', [0.8 0.8 0.8]);
h_rangenum = uicontrol(gcf, 'Units', 'characters', 'Position', [29 10 10 2], ...
'String', num2str(gsigma), 'Style', 'text', ...
'HorizontalAlignment', 'left',...
'Tag', 'rangenum',...
'BackgroundColor', [0.8 0.8 0.8]);
h_threshtext = uicontrol(gcf, 'Units', 'characters', 'Position', [25 8 16 2],...
'String', 'Current threshold (std devs):', 'Style', 'text', ...
'HorizontalAlignment', 'center', ...
'BackgroundColor', [0.8 0.8 0.8]);
h_threshnum = uicontrol(gcf, 'Units', 'characters', 'Position', [44 8 10 2],...
'String', num2str(z_thresh), 'Style', 'text', ...
'HorizontalAlignment', 'left', ...
'BackgroundColor', [0.8 0.8 0.8],...
'Tag', 'threshnum');
h_threshmvtext = uicontrol(gcf, 'Units', 'characters', 'Position', [106 8 18 2],...
'String', 'Motion threshold (mm / TR):', 'Style', 'text', ...
'HorizontalAlignment', 'center', ...
'BackgroundColor', [0.8 0.8 0.8]);
h_threshnummv = uicontrol(gcf, 'Units', 'characters', 'Position', [126 8 10 2],...
'String', num2str(mv_thresh), 'Style', 'text', ...
'HorizontalAlignment', 'left', ...
'BackgroundColor', [0.8 0.8 0.8],...
'Tag', 'threshnummv');
h_threshtextpct = uicontrol(gcf, 'Units', 'characters', 'Position', [66 8 16 2],...
'String', 'Current threshold (% of mean):', 'Style', 'text', ...
'HorizontalAlignment', 'center', ...
'BackgroundColor', [0.8 0.8 0.8]);
h_threshnumpct = uicontrol(gcf, 'Units', 'characters', 'Position', [86 8 10 2],...
'String', num2str(z_thresh*pctmap), 'Style', 'text', ...
'HorizontalAlignment', 'left', ...
'BackgroundColor', [0.8 0.8 0.8],...
'Tag', 'threshnumpct');
h_deweightlist = uicontrol(gcf, 'Units', 'characters', 'Position', [150 6 1 1 ],...
'String', int2str(outdw_idx), 'Style', 'text', ...
'HorizontalAlignment', 'left', ...
'BackgroundColor', [0.8 0.8 0.8],...
'Tag', 'deweightlist');
h_clipmvmtlist = uicontrol(gcf, 'Units', 'characters', 'Position', [152 6 1 1 ],...
'String', int2str(clipout_idx), 'Style', 'text', ...
'HorizontalAlignment', 'left', ...
'BackgroundColor', [0.8 0.8 0.8],...
'Tag', 'clipmvmtlist');
h_indextext = uicontrol(gcf, 'Units', 'characters', 'Position', [10 3 15 2],...
'String', 'Outlier indices: ', 'Style', 'text', ...
'HorizontalAlignment', 'left', ...
'BackgroundColor', [0.8 0.8 0.8], ...
'ForegroundColor', 'r');
h_indexedit = uicontrol(gcf, 'Units', 'characters', 'Position', [25 3.25 40 2],...
'String', int2str(out_idx), 'Style', 'edit', ...
'HorizontalAlignment', 'left', ...
'Callback', 'art_outlieredit',...
'BackgroundColor', [0.8 0.8 0.8],...
'Tag', 'indexedit');
h_indexinst = uicontrol(gcf, 'Units', 'characters', 'Position', [66 3 40 2],...
'String', '[Hit return to update after editing]', 'Style', 'text',...
'HorizontalAlignment', 'left', ...
'BackgroundColor', [0.8 0.8 0.8]);
h_deweighttext = uicontrol(gcf, 'Units', 'characters', 'Position', [115 1 21 2],...
'String', 'Click to add margins for deweighting', 'Style', 'text', ...
'HorizontalAlignment', 'center', ...
'BackgroundColor', [0.8 0.8 0.8]);
h_clipmvmttext = uicontrol(gcf, 'Units', 'characters', 'Position', [94 1 21 2],...
'String', 'Mark > 3mm movments for repair', 'Style', 'text', ...
'HorizontalAlignment', 'center', ...
'BackgroundColor', [0.8 0.8 0.8]);
if realignfile == 1
h_repairtext = uicontrol(gcf, 'Units', 'characters', 'Position', [137 1 17 2],...
'String', 'Writes repaired volumes', 'Style', 'text', ...
'HorizontalAlignment', 'center', ...
'BackgroundColor', [0.8 0.8 0.8]);
else % realignfile == 0
h_repairtext = uicontrol(gcf, 'Units', 'characters', 'Position', [137 1 17 2],...
'String', 'WARNING!! DATA NOT REALIGNED', 'Style', 'text', ...
'HorizontalAlignment', 'center', ...
'BackgroundColor', [0.8 0.8 0.8]);
end
h_addmargin = uicontrol(gcf, 'Units', 'characters', 'Position', [120 3.25 10 2],...
'String', 'Margin', 'Style', 'pushbutton', ...
'Tooltipstring', 'Adds margins to deweight in estimation', ...
'BackgroundColor', [ 0.7 0.9 0.7], 'ForegroundColor','k',...
'Callback', 'art_addmargin');
h_clipmvmt = uicontrol(gcf, 'Units', 'characters', 'Position', [100 3.25 10 2],...
'String', 'Clip', 'Style', 'pushbutton', ...
'Tooltipstring', 'Marks displacements > 3 mm for repair', ...
'BackgroundColor', [ 0.7 0.7 0.8 ], 'ForegroundColor','k',...
'Callback', 'art_clipmvmt');
h_repair = uicontrol(gcf, 'Units', 'characters', 'Position', [140 3.25 10 2],...
'String', 'REPAIR', 'Style', 'pushbutton', ...
'Tooltipstring', 'Writes repaired images', ...
'BackgroundColor', [ 0.9 0.7 0.7], 'ForegroundColor','r',...
'Callback', 'art_repairvol');
h_up = uicontrol(gcf, 'Units', 'characters', 'Position', [10 8 10 2],...
'String', 'Up', 'Style', 'pushbutton', ...
'TooltipString', 'Raise threshold for outliers', ...
'Callback', 'art_threshup');
h_down = uicontrol(gcf, 'Units', 'characters', 'Position', [10 6 10 2],...
'String', 'Down', 'Style', 'pushbutton', ...
'TooltipString', 'Lower threshold for outliers', ...
'Callback', 'art_threshdown');
%guidata(gcf, g);
guidata(gcf,[g delta mv_data]);
setappdata(h_repair,'data',P);
setappdata(h_addmargin,'data2',repair1_flag);
setappdata(h_clipmvmt,'data3',repair1_flag);
%setappdata(h_repair,'data3',GoRepair);
% For GUI or RepairAlone, add deweighting margins to top plot
% Don't apply margins when motion adjustment was used.(v2.2)
if GoRepair == 0 | GoRepair == 1
art_clipmvmt_jin(MVMTTHRESHOLD); %(movement to the referenced images)
%art_addmargin;
end
if GoRepair == 1 | GoRepair == 2
ImageFile = P(1,:);
[imgpath, imagname] = fileparts(ImageFile);
[subjectpath, imagfold ] = fileparts(imgpath);
[uppath2, up1name ] = fileparts(subjectpath);
[uppath3, up2name ] = fileparts(uppath2);
[uppath4, up3name ] = fileparts(uppath3);
titlename = [ up3name, ' / ', up2name,' / ', up1name,' / ', imagfold ];
gcf; subplot(5,1,1);
title(titlename);
%figname = ['artglobal', subname, '.jpg'];
figname = ['artglobal', up1name, imagfold, '.jpg'];
temp = pwd;
cd(subjectpath);
try
saveas(gcf,figname);
catch
disp('Warning from art_global: Could not print figure');
end
cd(temp);
% Return to directory in use before writing the jpg.
art_repairvol(P);
end
if GoRepair == 4
%art_clipmvmt;
outall_idx = unique([out_idx]);
tempd = pwd;
cd(fileparts(P(1,:)));
save art_suspects.txt outall_idx -ascii
%art_addmargin;
cd(tempd)
end