%SedCTsplit MATLAB GUI for splitting mutiple sediment cores that have been
%run at the same time. Note, this is a beta version that is only tested on
%OSU data and only works with coronal/sagital slices. Error messages have
%not been added.
%Developed 2021, Brendan T. Reilly, Scripps Instiution of Oceanography


function varargout = SedCTsplit(varargin)

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @SedCTsplit_OpeningFcn, ...
                   'gui_OutputFcn',  @SedCTsplit_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before SedCTsplit is made visible.
function SedCTsplit_OpeningFcn(hObject, eventdata, handles, varargin)

handles.output = hObject;
guidata(hObject, handles);
set(gca, 'ytick', [], 'xtick', []);

function varargout = SedCTsplit_OutputFcn(hObject, eventdata, handles) 
varargout{1} = handles.output;


% --- Executes on button press in DICOMdir.
function DICOMdir_Callback(hObject, eventdata, handles)
d0 = uigetdir;
d = dir([d0 '/*.dcm']);
% d = dir(d0);
% d = d(3:end);
ord = nan(size(d));
for n = 1:length(d)
    c(n).data = dicomread([d0 '/' d(n).name]);
    c(n).info = dicominfo([d0 '/' d(n).name]);
    ord(n) = c(n).info.SeriesNumber + c(n).info.InstanceNumber/1000;
end
[~, i] = sort(ord);
c = c(i);
imshow(c(1).data, [])
set(handles.slider1, 'Value', 1);
set(handles.slider1, 'Min', 1);
set(handles.slider1, 'Max', length(c));
set(handles.slider1, 'SliderStep', [1/(length(c)-1) 0.1]);
set(handles.SliceNumberText, 'String', ['Slice: 1/' num2str(length(c))])
set(handles.BottomSlice, 'String', '1')
set(handles.TopSlice, 'String', num2str(length(c)));
handles.metricdata.c = c;
for n = 1:length(d)
    handles.metricdata.maxy(n) = length(c(n).data(:, 1));
    handles.metricdata.maxx(n) = length(c(n).data(1, :));
end
guidata(hObject, handles)


% --- Executes on slider movement to select slice
function slider1_Callback(hObject, eventdata, handles)
c = handles.metricdata.c;
pos = round(get(hObject,'Value'));
set(handles.SliceNumberText, 'String', ['Slice:' num2str(pos) '/' num2str(length(c))])
imshow(c(pos).data, [])
hold on
try
    x1 = handles.metricdata.x1;
    x2 = handles.metricdata.x2;
    y1 = handles.metricdata.y1;
    y2 = handles.metricdata.y2;
    scatter(x1, y1, 'ro', 'filled')
    scatter(x2, y2, 'ro', 'filled')
    plot([x1 x1], [y1 y2], 'r')
    plot([x2 x2], [y1 y2], 'r')
    plot([x1 x2], [y1 y1], 'r')
    plot([x1 x2], [y2 y2], 'r')
end
hold off
    
function slider1_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% Editable Strings for Pick top/Bottom Slice
function BottomSlice_Callback(hObject, eventdata, handles)
function BottomSlice_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function TopSlice_Callback(hObject, eventdata, handles)
function TopSlice_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% Push Bottons to Pick Top and Bottom Slices
function PickBottom_Callback(hObject, eventdata, handles)
pos = round(get(handles.slider1,'Value'));
set(handles.BottomSlice, 'String', pos);

function PickTop_Callback(hObject, eventdata, handles)
pos = round(get(handles.slider1,'Value'));
set(handles.TopSlice, 'String', pos);


% --- Executes on button press in DefineRectangle.
function DefineRectangle_Callback(hObject, eventdata, handles)
exT = get(handles.ExTop, 'Value');
exB = get(handles.ExBot, 'Value');
pos = round(get(handles.slider1,'Value'));
maxy = handles.metricdata.maxy(pos);
maxx = handles.metricdata.maxx(pos);

c = handles.metricdata.c;
pos = round(get(handles.slider1,'Value'));
set(handles.SliceNumberText, 'String', ['Slice:' num2str(pos) '/' num2str(length(c))])
imshow(c(pos).data, [])

hold on
[x1 y1] = ginput(1);
x1 = round(x1);
y1 = round(y1);
if exT == 1
    y1 = 1;
end
if x1 < 1
    x1 = 1;
end
if y1 < 1
    y1 = 1;
end
if x1 > maxx
    x1 = maxx;
end
if y1 > maxy
    y1 = maxy;
end
scatter(x1, y1, 'ro', 'filled')

[x2 y2] = ginput(1);
x2 = round(x2);
y2 = round(y2);
if exB == 1
    y2 = maxy;
end
if x2 < 1
    x2 = 1;
end
if y2 < 1
    y2 = 1;
end
if x2 > maxx
    x2 = maxx;
end
if y2 > maxy
    y2 = maxy;
end
scatter(x2, y2, 'ro', 'filled')

plot([x1 x1], [y1 y2], 'r')
plot([x2 x2], [y1 y2], 'r')
plot([x1 x2], [y1 y1], 'r')
plot([x1 x2], [y2 y2], 'r')
hold off
handles.metricdata.x1 = x1;
handles.metricdata.x2 = x2;
handles.metricdata.y1 = y1;
handles.metricdata.y2 = y2;
guidata(hObject, handles)


% Radio Buttons For Rectagle Selection
function ExTop_Callback(hObject, eventdata, handles)
function ExBot_Callback(hObject, eventdata, handles)


% --- Executes on button press in Export.
function Export_Callback(hObject, eventdata, handles)
d = uigetdir;
c = handles.metricdata.c;
x1 = handles.metricdata.x1;
x2 = handles.metricdata.x2;
y1 = handles.metricdata.y1;
y2 = handles.metricdata.y2;
ts = str2num(get(handles.TopSlice, 'String'));
bs = str2num(get(handles.BottomSlice, 'String'));
s = [ts bs];
s = sort(s);
bs = s(1);
ts = s(2);
if bs < 1
    bs = 1;
end
if ts > length(c)
    ts = length(c);
end

for n = bs:ts
    outdata = c(n).data;
    outinfo = c(n).info;
    
    outdata = outdata([y1:y2], [x1:x2]);
    
    l = length(num2str(n));
    IDnum = '000000';
    IDnum(end-l+1:end) = num2str(n);
    filename = [d '/SPLIT' IDnum '.dcm'];
    dicomwrite(outdata, filename, outinfo)
end
