diff --git a/IO/exportGUI_alsKlasse.m b/IO/exportGUI_alsKlasse.m new file mode 100644 index 000000000..23f0248cc --- /dev/null +++ b/IO/exportGUI_alsKlasse.m @@ -0,0 +1,447 @@ +classdef exportGUI_alsKlasse < handle + + properties + guiHandle + end + + methods + function this = exportGUI_alsKlasse + this.guiHandle = this.createLayout(); + + %assign guidata like in guide + handles = guihandles(this.guiHandle); + guidata(this.guiHandle,handles); + + this.initialize(); + + end + end + + methods + function guiHandle = createLayout(this) + h1 = figure(... + 'IntegerHandle','off',... + 'Renderer', 'painters',... + 'MenuBar','none',... + 'NumberTitle','off',... + 'PaperUnits','inches',... + 'Position', [450 170 480 600],... + 'Color',[0.5 0.5 0.5],... + 'Name','Export Patient',... + 'PaperSize',[8.5 11],... + 'Renderer', 'painters', ... + 'PaperType','usletter'); + + guiHandle = h1; + + %EXPORT BUTTON + h2 = uicontrol(... + 'BackgroundColor',[0.5 0.5 0.5],... + 'Parent',h1,... + 'Units','normalized',... + 'String','Export',... + 'UserData',[],... + 'Position',[0.4 0.07 0.2 0.07],... + 'Tag','btn_export',... + 'Callback',@(hObject,eventdata) this.btn_export_Callback(hObject,eventdata,guidata(hObject))); + + %CANCEL BUTTON + h3 = uicontrol(... + 'Parent',h1,... + 'BackgroundColor',[0.5 0.5 0.5],... + 'Units','normalized',... + 'String','Cancel',... + 'Position',[0.7 0.07 0.2 0.07],... + 'Callback',@(hObject,eventdata) this.btn_cancel_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','btn_cancel'); + + %CT CHECKBOX + h4 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'BackgroundColor',[0.5 0.5 0.5],... + 'String','CT',... + 'Style','checkbox',... + 'Position',[0.035 0.8 0.7 0.04],... + 'Callback',@(hObject,eventdata) this.checkbox_CT_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','checkbox_CT'); + + %Compress CHECKBOX + h14 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'BackgroundColor',[0.5 0.5 0.5],... + 'HorizontalAlignment','left',... + 'String','Compress',... + 'Style','checkbox',... + 'Value',1,... + 'Position',[0.035 0.15 0.7 0.04],... + 'Tag','checkbox_compress',... + 'Callback',@(hObject,eventdata) this.checkbox_Compress_Callback(hObject,eventdata,guidata(hObject))); + + + % RESULT CUBES CHECKBOX + h5 = uicontrol(... + 'Parent',h1,... + 'BackgroundColor',[0.5 0.5 0.5],... + 'HorizontalAlignment','left',... + 'Units','normalized',... + 'String','Result Cubes',... + 'Style','checkbox',... + 'Position',[0.035 0.55 0.7 0.04],... + 'Callback',@(hObject,eventdata) this.checkbox_dose_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','checkbox_dose'); + + %TEXT + h6 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'FontUnits',get(0,'defaultuicontrolFontUnits'),... + 'HorizontalAlignment','left',... + 'String','Select export folder:',... + 'Style','text',... + 'BackgroundColor',[0.5 0.5 0.5],... + 'Position',[0.035 0.9 0.7 0.04 ],... + 'Tag','label_dir_export'); + + %BROWSER PUSHBUTTON + h7 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Browse',... + 'BackgroundColor',[0.5 0.5 0.5],... + 'Position',[0.75 0.86 0.15 0.05],... + 'Callback',@(hObject,eventdata) this.pushbutton_dir_export_browse_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','pushbutton_dir_export_browse'); + + %EDIT TEXTFELD + h8 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'Style','edit',... + 'Position',[0.035 0.865 0.7 0.04 ],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,eventdata) this.edit_dir_export_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','edit_dir_export'); + + %EXTENSION TEXT + h9 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'BackgroundColor',[0.5 0.5 0.5],... + 'String','Extension',... + 'FontUnits',get(0,'defaultuicontrolFontUnits'),... + 'Style','text',... + 'Position',[0.035 0.25 0.7 0.04],... + 'Tag','text_extension'); + + % POP-UP MENU + h10 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String',{ '*.nrrd'; '*.vtk'; '*.mha' },... + 'Style','popupmenu',... + 'Value',1,... + 'Position',[0.035 0.21 0.75 0.03],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,eventdata) this.popupmenu_extension_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','popupmenu_extension'); + + h11 = uitable(... + 'Parent',h1,... + 'Units','normalized',... + 'BackgroundColor',[1 1 1;0.941176470588235 0.941176470588235 0.941176470588235],... + 'ColumnWidth',{ 20 278 },... + 'Visible','off',... + 'Position',[0.1 0.6 0.73 0.2],... + 'ColumnEditable',false,... + 'ColumnFormat',{ 'logical' 'char' },... + 'Tag','uitable_vois'); + + h12 = uitable(... + 'Parent',h1,... + 'Units','normalized',... + 'BackgroundColor',[1 1 1;0.941176470588235 0.941176470588235 0.941176470588235],... + 'ColumnName',blanks(0),... + 'ColumnWidth',{ 20 278 },... + 'RowName',blanks(0),... + 'Position',[0.1 0.32 0.73 0.2],... + 'Visible','off',... + 'ColumnEditable',false,... + 'ColumnFormat',{ 'logical' 'char' },... + 'Tag','uitable_doseCubes',... + 'UserData',[]); +% 'KeyPressFcn',blanks(0),... +% 'KeyReleaseFcn',blanks(0) + end + + function this = initialize(this) + + handles = guidata(this.guiHandle); + + %Fills structure export table + if evalin('base','exist(''cst'',''var'')') == 1 + cst = evalin( 'base', 'cst' ); + tableData = cell(numel(cst(:,2)),2); + tableData(:,2) = cst(:,2); + tableData(:,1) = {true}; + else + tableData = cell(0); + set(handles.checkbox_CT,'Enable','off'); + end + set(handles.uitable_vois,'data',tableData); + + %Fills result cubes export table + if evalin('base','exist(''resultGUI'',''var'')') + result = evalin( 'base', 'resultGUI' ); + cubeNames = fieldnames(result); + cubeIx = 1; + for f = 1:numel(cubeNames) + if ndims(result.(cubeNames{f})) < 3 + continue; + end + cubes{cubeIx} = cubeNames{f}; + cubeIx = cubeIx + 1; + end + numCubes = cubeIx - 1; + tableData = cell(numCubes,2); + tableData(:,2) = cubes; + tableData(:,1) = {true}; + else + tableData = cell(0); + set(handles.checkbox_dose,'Enable','off'); %CHANGED CODE!ALTE VERSION: set(handles.checkbox_dose,'Enable','off'); + end + set(handles.uitable_doseCubes,'data',tableData); + + % Update handles structure + guidata(this.guiHandle, handles); + end + end + + methods + %---------------CALLBACK FOR H2 BUTTON EXPORT + function this = btn_export_Callback(this, hObject, event, handles) + exportDir = get(handles.edit_dir_export,'String'); + + %Sanity check + if numel(exportDir) == 0 + errordlg('No Export folder selected!'); + return; + elseif ~exist(exportDir,'dir') + errordlg(['Folder ' exportDir ' does not exist!']); + return; + else + %Add file separator if necessary + if exportDir(end) ~= filesep + exportDir = [exportDir filesep]; + end + end + + %Get the file extension + extensionIndex = get(handles.popupmenu_extension,'Value'); + extensions = get(handles.popupmenu_extension,'String'); + extension = extensions{extensionIndex}; + extension = extension(2:end); + + saveCT = get(handles.checkbox_CT,'Value'); + saveResults = get(handles.checkbox_dose,'Value'); + + if (saveCT) + voiDir = [exportDir '/vois/']; + if ~exist(voiDir,'dir') + if ~mkdir(voiDir) + warndlg('Could not create subfolder for VOI masks. Masks will be stored in base folder.'); + voiDir = exportDir; + end + end + end + + %If we export results, try to create a subdirectory for VOIs + if (saveResults) + resultDir = [exportDir '/results/']; + if ~exist(resultDir,'dir') + if ~mkdir(resultDir) + warndlg('Could not create subfolder for resulting dose cubes. Cubes will be stored in base folder.'); + resultDir = exportDir; + end + end + end + + %prepare metadata + ct = evalin('base','ct'); + + metadata.resolution = [ct.resolution.x ct.resolution.y ct.resolution.z]; + metadata.compress = get(handles.checkbox_compress,'Value'); + + %Check if we have position information + if isfield(ct,'dicomInfo') + if isfield(ct.dicomInfo,'ImagePositionPatient') + metadata.imageOrigin = ct.dicomInfo.ImagePositionPatient; + if ~isrow(metadata.imageOrigin) + metadata.imageOrigin = transpose(metadata.imageOrigin); + end + end + end + + %This is only for the waitbar to get the number of cubes you wanna save + numExportCubes = 0; + if (saveCT) + if isfield(ct,'cubeHU') + numExportCubes = numExportCubes + 1; + end + + if isfield(ct,'cube') + numExportCubes = numExportCubes + 1; + end + voiNames = get(handles.uitable_vois,'Data'); + voiIndices = find([voiNames{:,1}] == true); + numExportCubes = numExportCubes + numel(voiIndices); + + else + numExportCubes = 0; + end + + if saveResults + cubeNames = get(handles.uitable_doseCubes,'data'); + cubeIndices = find([cubeNames{:,1}] == true); + numExportCubes = numExportCubes + numel(cubeIndices); + end + + %Give an error if nothing was selected + if numExportCubes == 0 + errordlg('No data was selected for export!'); + return; + end + + currentCube = 0; + + hWaitbar = waitbar(0,'Exporting...','WindowStyle', 'modal'); + cleanUp = onCleanup(@() close(hWaitbar)); + + %CT and Mask export + if saveCT + + if isfield(ct,'cube') + %Export the CT (ED suffix to clarify it is not in HU) + currentCube = currentCube + 1; + waitbar(currentCube/numExportCubes,hWaitbar,['Exporting CT Intensity values (' num2str(currentCube) '/' num2str(numExportCubes) ') ...']); + matRad_writeCube(fullfile(exportDir,['CT_ED' extension]),ct.cube{1},'double',metadata); + end + + if isfield(ct,'cubeHU') + currentCube = currentCube + 1; + waitbar(currentCube/numExportCubes,hWaitbar,['Exporting CT in HU (' num2str(currentCube) '/' num2str(numExportCubes) ') ...']); + matRad_writeCube(fullfile(exportDir,['CT_HU' extension]),ct.cubeHU{1},'double',metadata); + end + + %Export VOI masks + cst = evalin('base','cst'); + + for voiIx = voiIndices + %Waitbar + currentCube = currentCube + 1; + waitbar(currentCube/numExportCubes,hWaitbar,['Exporting Segmentation Mask (' num2str(currentCube) '/' num2str(numExportCubes) ') ...']); + + %Get the index list + voiRow = find(strcmp(voiNames{voiIx,2},cst(:,2))); + voiIndexList = cst{voiRow,4}{1}; + %Set up the full mask + voiMask = zeros(ct.cubeDim); + voiMask(voiIndexList) = 1; + %Export... + matRad_writeCube(fullfile(voiDir,[voiNames{voiIx,2} extension]),voiMask,'uint8',metadata); + end + + end + + %Results Export + if saveResults + results = evalin('base','resultGUI'); + cubeNames = get(handles.uitable_doseCubes,'data'); + + for cubeIx = cubeIndices + %Export + currentCube = currentCube + 1; + waitbar(currentCube/numExportCubes,hWaitbar,['Exporting Results (' num2str(currentCube) '/' num2str(numExportCubes) ') ...']); + matRad_writeCube(fullfile(resultDir,[cubeNames{cubeIx,2} extension]),results.(cubeNames{cubeIx,2}),'double',metadata); + end + end + + %close(data.figure1); + + end + + %------------CALLBACK FOR H3 BUTTON CANCEL + function this = btn_cancel_Callback(this, hObject, event, guidata) + close; + % close(handles.figure1); + end + + %------------CALLBACK FOR H4 BUTTON CHECKBOX CT + function this = checkbox_CT_Callback(this, hObject, event, guidata) + saveCT = get(hObject,'Value'); + %Show the VOI-table only if we want to save a CT + if (saveCT) + set(guidata.uitable_vois,'Visible', 'on', 'Enable','on'); + else + set(guidata.uitable_vois,'Visible', 'off', 'Enable','off'); + end + end + + %-------------CALLBACK FOR H5 BUTTON CHECKBOX DOSE + function this = checkbox_dose_Callback(this, hObject, event,guidata) + saveDose = get(hObject,'Value'); + if (saveDose) + set(guidata.uitable_doseCubes,'Visible', 'on', 'Enable','on'); + + else + set(guidata.uitable_doseCubes,'Visible', 'off', 'Enable','off'); + end + end + + %-------------CALLBACK FOR H7 PUSHBUTTON DIR EXPORT BROWSE + % CAN'T CHANGE THE VARIABLES BECAUSE OF GUIDATA LINE 415 + function this = pushbutton_dir_export_browse_Callback(this, hObject, event,data) + exportDir = uigetdir('', 'Choose the export directory...'); + if exportDir ~= 0 + exportDir = [exportDir filesep]; + set(data.edit_dir_export,'String',exportDir); + % Update handles structure + guidata(hObject, data); + end + end + + %------------CALLBACK FOR H8 EDIT DIR EXPORT + % SAME PROBLEM HERE!? + function this = edit_dir_export_Callback(this, hObject, event,handles) + exportDir = get(handles.edit_dir_export,'String'); + + %Add filesperator + if exportDir(end) ~= filesep + exportDir = [exportDir filesep]; + end + + %Check if the user specified an existing directory + if ~exist(exportDir,'dir') + warndlg(['Folder ' exportDir ' does not exist!']); + exportDir = ''; + end + + set(handles.edit_dir_export,'String',exportDir); + guidata(hObject, handles); + %guidata(src,data); + end + + %------------CALLBACK FOR H10 POP-UP MENU EXTENSION + function this = popupmenu_extension_Callback(this, hObject, event,guidata) + + end + + %------------CALLBACK FOR H14 CHECKBOX COMPRESS + function this = checkbox_Compress_Callback(this, hObject, event,guidata) + + end + end +end + diff --git a/IO/importGUI_alsKlasse.m b/IO/importGUI_alsKlasse.m new file mode 100644 index 000000000..3c58d0aec --- /dev/null +++ b/IO/importGUI_alsKlasse.m @@ -0,0 +1,318 @@ +classdef importGUI_alsKlasse + + properties + guiHandle + end + + methods + function this = importGUI_alsKlasse() + + this.guiHandle = this.createLayout(); + + % assign guidata like in guide + handles = guihandles(this.guiHandle); + guidata(this.guiHandle,handles); + + this.initialize(); + end + + function guiHandle = createLayout(this) + + h1 = figure(... + 'PaperUnits','inches',... + 'MenuBar','none',... + 'Units','characters',... + 'Position',[135.8 56.7692307692308 89.2 18.3846153846154],... + 'Color',[0.5 0.5 0.5],... + 'Name','Import Patient',... + 'HandleVisibility','callback',... + 'Tag','figure_importDialog',... + 'WindowStyle','normal',... + 'PaperSize',[8.5 11],... + 'PaperType','usletter'); + + guiHandle = h1; + + h2 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Patient CT file [HU]:',... + 'BackgroundColor', [0.5 0.5 0.5],... + 'HorizontalAlignment','left',... + 'Style','text',... + 'Position',[0.03 0.85 0.4 0.1],... + 'Tag','text2'); + + + h3 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'Style','edit',... + 'Position',[0.03 0.78 0.73 0.1],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,eventdata)this.edit_ctPath_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','edit_ctPath'); + + + h4 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Browse...',... + 'BackgroundColor', [0.5 0.5 0.5],... + 'Position',[0.78 0.78 0.2 0.1],... + 'Callback',@(hObject,eventdata)this.pushbutton_ctPath_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','pushbutton_ctPath'); + + + h5 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Binary Masks/Segmentations',... + 'HorizontalAlignment','left',... + 'BackgroundColor', [0.5 0.5 0.5],... + 'Style','text',... + 'Position',[0.03 0.435 0.5 0.1],... + 'Tag','text_masks'); + + + h6 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'Max',2,... + 'Style','listbox',... + 'Position',[0.03 0.15 0.73 0.32],... [1.8 3.38461538461539 66.2 4.69230769230769],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,eventdata)this.listbox_maskPaths_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','listbox_maskPaths',... + 'KeyPressFcn',@(hObject,eventdata)matRad_importGUI('listbox_maskPaths_KeyPressFcn',hObject,eventdata,guidata(hObject))); + + + h7 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Add File(s)...',... + 'Style',get(0,'defaultuicontrolStyle'),... + 'BackgroundColor', [0.5 0.5 0.5],... + 'Position',[0.78 0.37 0.2 0.1],... + 'Callback',@(hObject,eventdata)this.pushbutton_addMaskPaths_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','pushbutton_addMaskPaths'); + + + h8 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Import',... + 'BackgroundColor', [0.5 0.5 0.5],... + 'Position',[0.55 0.02 0.2 0.1],... + 'Callback',@(hObject,eventdata)this.pushbutton_import_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','pushbutton_import'); + + + h9 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Cancel',... + 'BackgroundColor', [0.5 0.5 0.5],... + 'Callback',@(hObject,eventdata)this.pushbutton_cancel_Callback(hObject,eventdata,guidatahObject),... + 'Position',[0.78 0.02 0.2 0.1],... + 'Tag','pushbutton_cancel'); + + + h10 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Add Folder...',... + 'BackgroundColor', [0.5 0.5 0.5],... + 'Position',[0.78 0.22 0.2 0.1],... + 'Callback',@(hObject,eventdata)this.pushbutton_addMaskFolders_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','pushbutton_addMaskFolders'); + + + h11 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Convert from HU?',... + 'BackgroundColor', [0.5 0.5 0.5],... + 'Style','checkbox',... + 'Position',[0.03 0.68 0.4 0.1],... + 'Callback',@(hObject, eventdata)this.checkbox_huConvert_Callback(hObject,eventdata,guidata(hObject)),... + 'Tooltip','If this is checked, the import assumes that this is a CT given in HU and will convert with the given (or the default) HLUT',... + 'TooltipString','If this is checked, the import assumes that this is a CT given in HU and will convert with the given (or the default) HLUT',... + 'Tag','checkbox_huConvert'); + + + h12 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','matRad_default.hlut',... + 'HorizontalAlignment','left',... + 'Style','edit',... + 'Position',[0.03 0.57 0.73 0.1],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,eventdata)this.edit_hlut_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','edit_hlut'); + + + h13 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','HLUT file...',... + 'BackgroundColor', [0.5 0.5 0.5],... + 'Position',[0.78 0.57 0.2 0.1],... [69.8 10.6923076923077 18.2 1.76923076923077],... + 'Callback',@(hObject,eventdata)this.pushbutton_hlutFile_Callback(hObject,eventdata,guidata(hObject)),... + 'Tag','pushbutton_hlutFile'); + end + +%OPENING/INITIALIZE FUNKTION + function this = initialize(this) + handles = guidata(this.guiHandle); % READ FROM GUIDATA + handles.output = this.guiHandle; + guidata(this.guiHandle, handles); + end + +%OUTPUT FUNKTION + function varargout = OutputFcn(hObject, eventdata, handles) + varargout{1} = handles.output; + end + +%CALLBACK FOR H3 EDIT CREATE PATH + function this = edit_ctPath_Callback(this, hObject, event,handles) + varargout{1} = handles.output; + + end + +%CALLBACK FOR H4 PUSHBUTTON CREATE PATH + function this = pushbutton_ctPath_Callback(this, hObject, event, handles) + [importCTFile,importCTPath,~] = uigetfile({'*.nrrd', 'NRRD-Files'}, 'Choose the CT file...'); + + if importCTFile ~= 0 + set(handles.edit_ctPath,'String',fullfile(importCTPath,importCTFile)); % NON EXISTING FIELD 'edit_ctPath' + % Update handles structure + guidata(hObject, handles); + end + end + +%CALLBACK FOR H6 LISTBOX MASK PATHS + function this = listbox_maskPaths_Callback(this, hObject, event, handles) + + end + +%CALLBACK FOR H7 PUSHBUTTON ADD MASKPATHS + function this = pushbutton_addMaskPaths_Callback(this, hObject, event, handles) + [importMaskFile,importMaskPath,~] = uigetfile({'*.nrrd', 'NRRD-Files'}, 'Choose the binary mask files...','MultiSelect','on'); + if ~isempty(importMaskFile) + if ~iscell(importMaskFile) + tmpName = importMaskFile; + importMaskFile = cell(1); + importMaskFile{1} = tmpName; + end + importMaskFile = cellfun(@(filename) fullfile(importMaskPath,filename),importMaskFile,'UniformOutput',false); + entries = get(handles.listbox_maskPaths,'String'); + newEntries = [entries importMaskFile]; + set(handles.listbox_maskPaths,'String',newEntries); + % Update handles structure + guidata(hObject, handles); + end + end + + function cst = showCheckDialog(this,cst) + + handle = dialog('Position', [100 100 400 250],'WindowStyle','modal','Name','Confirm Segmentations'); + + %Create Table + hTable = uitable('Parent',handle,'Units','normal','Position',[0.1 0.2 0.8 0.8]); + set(hTable,'Data',cst(:,2:3)); + set(hTable,'ColumnName',{'Name','Type'}); + set(hTable,'ColumnWidth',{150,'auto'}); + set(hTable,'RowName',char([])); + set(hTable,'ColumnEditable',[true true]); + set(hTable,'ColumnFormat',{'char',{'TARGET', 'OAR', 'IGNORED'}}); + + %Create Button + hButton = uicontrol(handle,'Style','pushbutton','String','Confirm','Units','normal','Position',[0.7 0.05 0.2 0.1],'Callback','uiresume(gcbf)');%{@pushbutton_confirm_vois_callback}); + try + uiwait(handle); + tmp = get(hTable,'Data'); + cst(:,2:3) = tmp(:,:); + catch + warning('Closed checkdialog without confirmation! Using default cst information!'); + end + delete(handle); + end + +%CALLBACK FOR H8 PUSHBUTTON IMPORT + function this = pushbutton_import_Callback(this, hObject, event, handles) + ctFile = get(handles.edit_ctPath,'String'); + maskFiles = get(handles.listbox_maskPaths,'String'); + + if isempty(ctFile) || isempty(maskFiles) + errordlg('Please sepecify a CT and at least one mask!'); + end + + convertHU = get(handles.checkbox_huConvert,'Value'); + + if convertHU + [ct,cst] = matRad_importPatient(ctFile,maskFiles,get(handles.edit_hlut,'String')); + else + [ct,cst] = matRad_importPatient(ctFile,maskFiles); + end + + cst = this.showCheckDialog(cst); + + assignin('base', 'ct', ct); + assignin('base', 'cst', cst); + + delete(handles.figure_importDialog); + end + +%CALLBACK FOR H9 PUSHBUTTON CANCEL + function this = pushbutton_cancel_Callback(this, hObject, event, handles) + delete(handles.figure_importDialog); + end + +%CALLBACK FOR H10 PUSHBUTTON ADD MASK FOLDERS + function this = pushbutton_addMaskFolders_Callback(this, hObject, event, handles) + importMaskPath = uigetdir('./', 'Choose the folder containing binary mask files...'); + importMaskPath = [importMaskPath filesep]; + if ~isempty(importMaskPath) + entries = get(handles.listbox_maskPaths,'String'); + newEntries = [entries cellstr(importMaskPath)]; + set(handles.listbox_maskPaths,'String',newEntries); + % Update handles structure + guidata(hObject, handles); + end + end + +%CALLBACK FOR H11 CHECKBOX HU CONVERT + function this = checkbox_huConvert_Callback(this, hObject, event, handles) + checked = get(hObject,'Value'); + + if checked + fieldState = 'on'; + else + fieldState = 'off'; + end + + set(handles.edit_hlut,'Enable',fieldState); + set(handles.pushbutton_hlutFile,'Enable',fieldState); + end + +%CALLBACK FOR H12 EDIT HLUT + function this = edit_hlut_Callback(this, hObject, event, handles) + %bleibt leer + end + +%CALLBACK FOR H13 PUSHBUTTON HLUT FILE + function this = pushbutton_hlutFile_Callback(this, hObject, event, handles) + [importHLUTFile,importHLUTPath,~] = uigetfile({'*.hlut', 'matRad HLUT-Files'}, 'Choose the HLUT file...'); + if importHLUTFile ~= 0 + set(handles.edit_hlut,'String',fullfile(importHLUTPath,importHLUTFile)); + % Update handles structure + guidata(hObject, handles); + end + end + + + end +end + diff --git a/IO/matRad_Widget.m b/IO/matRad_Widget.m index 328eef6fa..9367f1dbf 100644 --- a/IO/matRad_Widget.m +++ b/IO/matRad_Widget.m @@ -5,6 +5,10 @@ handles = []; %Holds all handles in parent handle end + events + workspaceChanged + end + methods %CONSTRUCTOR function this = matRad_Widget(handleParent) @@ -18,9 +22,47 @@ end %INITIALIZE FUNCTION - function this = initialize(this) + function this = initialize(this) + end + + function this = update(this) + end + + %{ + function this = disable(this) + end + + function this = enable(this) end + %} + + function showWarning(this,Message,ME) + handles = this.handles; + if nargin == 3 + %Add exception message + if isfield(handles,'devMode') && handles.devMode + meType = 'extended'; + else + meType = 'basic'; + end + Message = {Message,ME.message};%{Message,ME.getReport(meType,'hyperlinks','off')}; + end + + if isfield(handles,'ErrorDlg') + if ishandle(handles.ErrorDlg) + close(handles.ErrorDlg); + end + end + handles.ErrorDlg = errordlg(Message); + + this.handles = handles; + end + end + + %methods (Abstract) + % this = initialize(this); + %end methods (Access = protected) diff --git a/IO/matRad_exportWidget.m b/IO/matRad_exportWidget.m index a6b7e6649..9ca71879e 100644 --- a/IO/matRad_exportWidget.m +++ b/IO/matRad_exportWidget.m @@ -99,12 +99,13 @@ 'Parent',h1,... 'Units','normalized',... 'String','CT',... - 'BackgroundColor',[0.94 0.94 0.94],... + 'BackgroundColor',[0.5 0.5 0.5],...[0.94 0.94 0.94],... 'Style','checkbox',... 'Position',[0.035 0.7 0.7 0.04],... 'Callback',@this.checkbox_CT_Callback,... 'Tag','checkbox_CT'); + %Compress CHECKBOX h14 = uicontrol(... 'Parent',h1,... @@ -113,7 +114,7 @@ 'String','Compress',... 'Style','checkbox',... 'Value',1,... - 'BackgroundColor',[0.94 0.94 0.94],... + 'BackgroundColor',[0.5 0.5 0.5],... [0.94 0.94 0.94],... 'Position',[0.035 0.12 0.7 0.04],... 'Tag','checkbox_compress',... 'Callback',@this.checkbox_Compress_Callback); @@ -126,7 +127,7 @@ 'Units','normalized',... 'String','Result Cubes',... 'Style','checkbox',... - 'BackgroundColor',[0.94 0.94 0.94],... + 'BackgroundColor',[0.5 0.5 0.5],... [0.94 0.94 0.94],... 'Position',[0.035 0.45 0.7 0.04],... 'Callback',@this.checkbox_dose_Callback,... 'Tag','checkbox_dose'); @@ -138,7 +139,7 @@ 'FontUnits',get(0,'defaultuicontrolFontUnits'),... 'HorizontalAlignment','left',... 'String','Select export folder:',... - 'BackgroundColor',[0.94 0.94 0.94],... + 'BackgroundColor',[0.5 0.5 0.5],... 'Style','text',... 'Position',[0.035 0.9 0.7 0.04 ],... 'Tag','label_dir_export'); @@ -169,7 +170,7 @@ 'Units','normalized',... 'HorizontalAlignment','left',... 'String','Extension',... - 'BackgroundColor',[0.94 0.94 0.94],... + 'BackgroundColor',[0.5 0.5 0.5],... 'FontUnits',get(0,'defaultuicontrolFontUnits'),... 'Style','text',... 'Position',[0.035 0.25 0.7 0.04],... @@ -191,7 +192,7 @@ h11 = uitable(... 'Parent',h1,... 'Units','normalized',... - 'BackgroundColor',[1 1 1;0.941176470588235 0.941176470588235 0.941176470588235],... + 'BackgroundColor',[0.5 0.5 0.5],... [1 1 1;0.941176470588235 0.941176470588235 0.941176470588235],... 'ColumnWidth',{ 20 278 },... 'Visible','off',... 'Position',[0.1 0.5 0.73 0.2],... @@ -203,7 +204,7 @@ h12 = uitable(... 'Parent',h1,... 'Units','normalized',... - 'BackgroundColor',[1 1 1;0.941176470588235 0.941176470588235 0.941176470588235],... + 'BackgroundColor',[0.5 0.5 0.5],... [1 1 1;0.941176470588235 0.941176470588235 0.941176470588235],... 'ColumnName',blanks(0),... 'ColumnWidth',{ 20 278 },... 'RowName',blanks(0),... diff --git a/IO/matRad_importWidget.m b/IO/matRad_importWidget.m index a934ff4c6..aac0dc66e 100644 --- a/IO/matRad_importWidget.m +++ b/IO/matRad_importWidget.m @@ -54,7 +54,7 @@ 'Style','edit',... 'Position',[0.03 0.78 0.73 0.1],... 'BackgroundColor',[1 1 1],... - 'Callback',@this.edit_ctPath_Callback,... + 'Callback',@(hObject,event) edit_ctPath_Callback(this,hObject, event),... 'Tag','edit_ctPath'); @@ -195,7 +195,7 @@ end end - %CALLBACK FOR H6 LISTBOX MASK PATHS + %CALLBACK FOR H6 LISTBOX MASK PATHS LEER function this = listbox_maskPaths_Callback(this, hObject, event) end diff --git a/dicomImport/@matRad_importDicomWidget/createLayout.m b/dicomImport/@matRad_importDicomWidget/createLayout.m new file mode 100644 index 000000000..81dcead19 --- /dev/null +++ b/dicomImport/@matRad_importDicomWidget/createLayout.m @@ -0,0 +1,620 @@ +function this = createLayout(this,handleParent) + +h1 = this.widgetHandle; + +%Create all handles +% LOGO +h2 = axes(... + 'Parent',h1,... + 'CameraPosition',[0.5 0.5 9.16025403784439],... + 'CameraTarget',[0.5 0.5 0.5],... + 'CameraViewAngle',6.60861036031192,... + 'PlotBoxAspectRatio',[1 0.204545454545455 0.204545454545455],... + 'Colormap',[0.2422 0.1504 0.6603;0.250390476190476 0.164995238095238 0.707614285714286;0.257771428571429 0.181780952380952 0.751138095238095;0.264728571428571 0.197757142857143 0.795214285714286;0.270647619047619 0.21467619047619 0.836371428571429;0.275114285714286 0.234238095238095 0.870985714285714;0.2783 0.255871428571429 0.899071428571429;0.280333333333333 0.278233333333333 0.9221;0.281338095238095 0.300595238095238 0.941376190476191;0.281014285714286 0.322757142857143 0.957885714285714;0.279466666666667 0.344671428571429 0.971676190476191;0.275971428571429 0.366680952380952 0.982904761904762;0.269914285714286 0.3892 0.9906;0.260242857142857 0.412328571428571 0.995157142857143;0.244033333333333 0.435833333333333 0.998833333333333;0.220642857142857 0.460257142857143 0.997285714285714;0.196333333333333 0.484719047619048 0.989152380952381;0.183404761904762 0.507371428571429 0.979795238095238;0.178642857142857 0.528857142857143 0.968157142857143;0.176438095238095 0.549904761904762 0.952019047619048;0.168742857142857 0.570261904761905 0.935871428571428;0.154 0.5902 0.9218;0.146028571428571 0.609119047619048 0.907857142857143;0.13802380952381 0.627628571428572 0.897290476190476;0.124814285714286 0.645928571428571 0.888342857142857;0.111252380952381 0.6635 0.876314285714286;0.0952095238095238 0.679828571428571 0.859780952380952;0.0688714285714285 0.694771428571429 0.839357142857143;0.0296666666666667 0.708166666666667 0.816333333333333;0.00357142857142857 0.720266666666667 0.7917;0.00665714285714287 0.731214285714286 0.766014285714286;0.0433285714285715 0.741095238095238 0.739409523809524;0.096395238095238 0.75 0.712038095238095;0.140771428571429 0.7584 0.684157142857143;0.1717 0.766961904761905 0.655442857142857;0.193766666666667 0.775766666666667 0.6251;0.216085714285714 0.7843 0.5923;0.246957142857143 0.791795238095238 0.556742857142857;0.290614285714286 0.797290476190476 0.518828571428572;0.340642857142857 0.8008 0.478857142857143;0.3909 0.802871428571428 0.435447619047619;0.445628571428572 0.802419047619048 0.390919047619048;0.5044 0.7993 0.348;0.561561904761905 0.794233333333333 0.304480952380953;0.617395238095238 0.787619047619048 0.261238095238095;0.671985714285714 0.779271428571429 0.2227;0.7242 0.769842857142857 0.191028571428571;0.773833333333333 0.759804761904762 0.164609523809524;0.820314285714286 0.749814285714286 0.153528571428571;0.863433333333333 0.7406 0.159633333333333;0.903542857142857 0.733028571428571 0.177414285714286;0.939257142857143 0.728785714285714 0.209957142857143;0.972757142857143 0.729771428571429 0.239442857142857;0.995647619047619 0.743371428571429 0.237147619047619;0.996985714285714 0.765857142857143 0.219942857142857;0.995204761904762 0.789252380952381 0.202761904761905;0.9892 0.813566666666667 0.188533333333333;0.978628571428571 0.838628571428572 0.176557142857143;0.967647619047619 0.8639 0.164290476190476;0.961009523809524 0.889019047619048 0.153676190476191;0.959671428571429 0.913457142857143 0.142257142857143;0.962795238095238 0.937338095238095 0.126509523809524;0.969114285714286 0.960628571428571 0.106361904761905;0.9769 0.9839 0.0805],... + 'XTick',[0 0.2 0.4 0.6 0.8 1],... + 'XTickLabel',{ '0'; '0.2'; '0.4'; '0.6'; '0.8'; '1' },... + 'YTick',[0 0.5 1],... + 'YTickLabel',{ '0'; '0.5'; '1' },... + 'Position',[0.659070191431176 0.0833333333333333 0.320875113947129 0.13953488372093],... + 'ActivePositionProperty','position',... + 'LooseInset',[0.21882384176291 0.326703619171829 0.159909730519049 0.222752467617156],... + 'FontSize',8,... + 'SortMethod','childorder',... + 'Tag','axesDKFZLogo'); + +h3 = get(h2,'title'); +set(h3,... + 'Parent',h2,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0 0 0],... + 'Position',[0.500002438371832 1.03819444444444 0.5],... + 'PositionMode','auto',... + 'String',blanks(0),... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','Helvetica',... + 'FontSize',11,... + 'FontAngle','normal',... + 'FontWeight','bold',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','bottom',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + +h4 = get(h2,'xlabel'); +set(h4,... + 'Parent',h2,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[0.500000476837158 -0.224074068279178 0],... + 'PositionMode','auto',... + 'String',blanks(0),... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','Helvetica',... + 'FontSize',11,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','top',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + +h5 = get(h2,'ylabel'); + +set(h5,... + 'Parent',h2,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[-0.052462119942136 0.500000476837158 0],... + 'PositionMode','auto',... + 'String',blanks(0),... + 'Interpreter','tex',... + 'Rotation',90,... + 'RotationMode','auto',... + 'FontName','Helvetica',... + 'FontSize',11,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','bottom',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'ButtonDownFcn',blanks(0),... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + +h6 = get(h2,'zlabel'); + +set(h6,... + 'Parent',h2,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[0 0 0],... + 'PositionMode','auto',... + 'String',blanks(0),... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','Helvetica',... + 'FontSize',10,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','left',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','middle',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','off',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + +h7 = axes(... + 'Parent',h1,... + 'CameraPosition',[0.5 0.5 9.16025403784439],... + 'CameraTarget',[0.5 0.5 0.5],... + 'CameraViewAngle',6.60861036031192,... + 'PlotBoxAspectRatio',[1 0.301587301587302 0.301587301587302],... + 'Colormap',[0.2422 0.1504 0.6603;0.250390476190476 0.164995238095238 0.707614285714286;0.257771428571429 0.181780952380952 0.751138095238095;0.264728571428571 0.197757142857143 0.795214285714286;0.270647619047619 0.21467619047619 0.836371428571429;0.275114285714286 0.234238095238095 0.870985714285714;0.2783 0.255871428571429 0.899071428571429;0.280333333333333 0.278233333333333 0.9221;0.281338095238095 0.300595238095238 0.941376190476191;0.281014285714286 0.322757142857143 0.957885714285714;0.279466666666667 0.344671428571429 0.971676190476191;0.275971428571429 0.366680952380952 0.982904761904762;0.269914285714286 0.3892 0.9906;0.260242857142857 0.412328571428571 0.995157142857143;0.244033333333333 0.435833333333333 0.998833333333333;0.220642857142857 0.460257142857143 0.997285714285714;0.196333333333333 0.484719047619048 0.989152380952381;0.183404761904762 0.507371428571429 0.979795238095238;0.178642857142857 0.528857142857143 0.968157142857143;0.176438095238095 0.549904761904762 0.952019047619048;0.168742857142857 0.570261904761905 0.935871428571428;0.154 0.5902 0.9218;0.146028571428571 0.609119047619048 0.907857142857143;0.13802380952381 0.627628571428572 0.897290476190476;0.124814285714286 0.645928571428571 0.888342857142857;0.111252380952381 0.6635 0.876314285714286;0.0952095238095238 0.679828571428571 0.859780952380952;0.0688714285714285 0.694771428571429 0.839357142857143;0.0296666666666667 0.708166666666667 0.816333333333333;0.00357142857142857 0.720266666666667 0.7917;0.00665714285714287 0.731214285714286 0.766014285714286;0.0433285714285715 0.741095238095238 0.739409523809524;0.096395238095238 0.75 0.712038095238095;0.140771428571429 0.7584 0.684157142857143;0.1717 0.766961904761905 0.655442857142857;0.193766666666667 0.775766666666667 0.6251;0.216085714285714 0.7843 0.5923;0.246957142857143 0.791795238095238 0.556742857142857;0.290614285714286 0.797290476190476 0.518828571428572;0.340642857142857 0.8008 0.478857142857143;0.3909 0.802871428571428 0.435447619047619;0.445628571428572 0.802419047619048 0.390919047619048;0.5044 0.7993 0.348;0.561561904761905 0.794233333333333 0.304480952380953;0.617395238095238 0.787619047619048 0.261238095238095;0.671985714285714 0.779271428571429 0.2227;0.7242 0.769842857142857 0.191028571428571;0.773833333333333 0.759804761904762 0.164609523809524;0.820314285714286 0.749814285714286 0.153528571428571;0.863433333333333 0.7406 0.159633333333333;0.903542857142857 0.733028571428571 0.177414285714286;0.939257142857143 0.728785714285714 0.209957142857143;0.972757142857143 0.729771428571429 0.239442857142857;0.995647619047619 0.743371428571429 0.237147619047619;0.996985714285714 0.765857142857143 0.219942857142857;0.995204761904762 0.789252380952381 0.202761904761905;0.9892 0.813566666666667 0.188533333333333;0.978628571428571 0.838628571428572 0.176557142857143;0.967647619047619 0.8639 0.164290476190476;0.961009523809524 0.889019047619048 0.153676190476191;0.959671428571429 0.913457142857143 0.142257142857143;0.962795238095238 0.937338095238095 0.126509523809524;0.969114285714286 0.960628571428571 0.106361904761905;0.9769 0.9839 0.0805],... + 'XTick',[0 0.2 0.4 0.6 0.8 1],... + 'XTickLabel',{ '0'; '0.2'; '0.4'; '0.6'; '0.8'; '1' },... + 'YTick',[0 0.5 1],... + 'YTickLabel',{ '0'; '0.5'; '1' },... + 'Position',[0.296160877513711 0.836202830188679 0.229433272394881 0.147058823529412],... + 'ActivePositionProperty','position',... + 'LooseInset',[0.265885262648529 0.319135999073457 0.194300768858541 0.217592726640994],... + 'FontSize',8,... + 'SortMethod','childorder',... + 'Tag','axesMatRadLogo' ); + +h8 = get(h7,'title'); +set(h8,... + 'Parent',h7,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0 0 0],... + 'Position',[0.500001710558694 1.03618421052632 0.5],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','Helvetica',... + 'FontSize',11,... + 'FontAngle','normal',... + 'FontWeight','bold',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','bottom',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + +h9 = get(h7,'xlabel'); +set(h9,... + 'Parent',h7,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[0.500000476837158 -0.212280696264485 0],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','Helvetica',... + 'FontSize',11,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','top',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + +h10 = get(h7,'ylabel'); + +set(h10,... + 'Parent',h7,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[-0.0732804215064755 0.500000476837158 0],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',90,... + 'RotationMode','auto',... + 'FontName','Helvetica',... + 'FontSize',11,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','bottom',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + +h11 = get(h7,'zlabel'); + +set(h11,... + 'Parent',h7,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[0 0 0],... + 'PositionMode','auto',... + 'String',blanks(0),... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','Helvetica',... + 'FontSize',10,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','left',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','middle',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','off',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + +h12 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','RT Plan (SOPInstanceUID)',... + 'Style','text',... + 'Position',[0.319051959890611 0.697961527418892 0.152067622441369 0.0391903531438416],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Children',[],... + 'Tag','text11'); + +h13 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','RT Dose (SOPInstanceUID)',... + 'Style','text',... + 'Position',[0.660893345487694 0.697961527418892 0.126377724372255 0.0391903531438416],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Children',[],... + 'Tag','text10' ); + +h14 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','Directory',... + 'Style','text',... + 'Position',[0.0438756855575868 0.810661764705882 0.0722120658135283 0.0386029411764706],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Children',[],... + 'Tag','directory_label'); + +h15 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Browse',... + 'Position',[0.913162705667276 0.768382352941176 0.0630712979890311 0.0404411764705882],... + 'Callback',@(hObject,event) this.browse_button_Callback(this,hObject,event),... + 'Children',[],... + 'Tag','browse_button' ); + +h16 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','Patient ID',... + 'Style','text',... + 'Position',[0.0447897623400366 0.674632352941177 0.0557586837294333 0.059917312661499],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Children',[],... + 'Tag','patient_label' ); + +h17 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'Style','listbox',... + 'Value',1,... + 'Position',[0.0446672743846855 0.511627906976744 0.22971741112124 0.186046511627907],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,event) patient_listbox_Callback(this,hObject,event),... + 'Children',[],... + 'Tag','patient_listbox'); + +h18 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','CT ( ',... + 'Style','text',... + 'Position',[0.318223253501284 0.451622164800459 0.0464075578022706 0.0335917312661499],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Children',[],... + 'Tag','ct_label' ); + +h19 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'Style','listbox',... + 'Value',1,... + 'Position',[0.318140382862352 0.267441860465116 0.320875113947128 0.186046511627907],... + 'BackgroundColor',[1 1 1],... 'Callback',@(hObject,event) ctseries_listbox_Callback(this,hObject,event),... + 'Children',[],... + 'Tag','ctseries_listbox'); + +h20 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','RT Structure Set (SOPInstanceUID)',... + 'Style','text',... + 'Position',[0.66172205187702 0.446023542922768 0.179000580094473 0.0391903531438415],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Children',[],... + 'Tag','struct_label'); + +h21 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'Style','listbox',... + 'Value',1,... + 'Position',[0.660893345487694 0.265503875968992 0.320875113947129 0.186046511627907],... + 'BackgroundColor',[1 1 1],... 'Callback',@(hObject,event) rtseries_listbox_Callback(this,hObject,event),... + 'Children',[],... + 'Tag','rtseries_listbox'); + +h22 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Import',... + 'Position',[0.181403828623519 0.253875968992248 0.0628988149498633 0.0406976744186047],... + 'BackgroundColor',get(0,'defaultuicontrolBackgroundColor'),... + 'Callback',@(hObject,event) import_button_Callback(this,hObject,event),... + 'Children',[],... + 'Enable','off',... + 'Tag','import_button'); + +h23 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Cancel',... + 'Position',[0.181403828623519 0.195736434108527 0.0628988149498633 0.0406976744186047],... + 'Callback',@(hObject,event) cancel_button_Callback(this,hObject,event),... + 'Children',[],... + 'Tag','cancel_button' ); + +h24 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Series Instance UID /',... + 'Style','radiobutton',... + 'Value',1,... + 'Position',[0.339283500455788 0.454421475739305 0.113118422143035 0.0345248349124318],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Callback',@(hObject,event) SeriesUID_radiobutton_Callback(this,hObject,event),... + 'Children',[],... + 'Tag','SeriesUID_radiobutton' ); + +h25 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String','Series Number )',... + 'Style','radiobutton',... + 'Position',[0.44872826717494 0.452555268446741 0.0999864092152151 0.0345248349124318],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Callback',@(hObject,event) SeriesNumber_radiobutton_Callback(this,hObject,event),... + 'Children',[],... + 'Tag','SeriesNumber_radiobutton' ); + +h26 = uipanel(... + 'Parent',h1,... + 'Title','Resolution',... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Tag','uipanel1',... + 'Clipping','off',... + 'Position',[0.0446672743846855 0.151162790697674 0.103919781221513 0.174418604651163] ); + +h27 = uicontrol(... + 'Parent',h26,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','y step:',... + 'Style','text',... + 'Position',[0.0727272727272727 0.337349397590362 0.718181818181818 0.253012048192771],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Tag','text8' ); + +h28 = uicontrol(... + 'Parent',h26,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','z step:',... + 'Style','text',... + 'Position',[0.0727272727272727 0.0602409638554217 0.718181818181818 0.253012048192771],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Tag','text9' ); + +h29 = uicontrol(... + 'Parent',h26,... + 'Units','normalized',... + 'Style','edit',... + 'Position',[0.463636363636364 0.653846153846154 0.4 0.217948717948718],... + 'BackgroundColor',[1 1 1],... 'Callback',@(hObject,event) resx_edit_Callback(this,hObject,event),... + 'Tag','resx_edit'); + +h30 = uicontrol(... + 'Parent',h26,... + 'Units','normalized',... + 'Style','edit',... + 'Position',[0.463636363636364 0.385542168674699 0.4 0.216867469879518],... + 'BackgroundColor',[1 1 1],... 'Callback',@(hObject,event) resy_edit_Callback(this,hObject,event),... + 'Tag','resy_edit'); + +h31 = uicontrol(... + 'Parent',h26,... + 'Units','normalized',... + 'Style','edit',... + 'Position',[0.463636363636364 0.120481927710843 0.4 0.216867469879518],... + 'BackgroundColor',[1 1 1],... 'Callback',@(hObject,event) resz_edit_Callback(this,hObject,event),... + 'Tag','resz_edit'); + +h32 = uicontrol(... + 'Parent',h26,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','x step:',... + 'Style','text',... + 'Position',[0.0727272727272727 0.614457831325301 0.381818181818182 0.253012048192771],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Tag','text7' ); + +h33 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','DICOM Import',... + 'Style','text',... + 'Position',[0.510968921389397 0.828849889012209 0.209323583180987 0.0808823529411765],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Children',[],... + 'ForegroundColor',[0.0980392156862745 0.305882352941176 0.615686274509804],... + 'Tag','text12',... + 'FontSize',18,... + 'FontName','Century',... + 'FontWeight','bold' ); + +h34 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'Max',32,... + 'Style','listbox',... + 'Value',1,... + 'Position',[0.660893345487694 0.513565891472868 0.320875113947129 0.186046511627907],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,event) doseseries_listbox_Callback(this,hObject,event),... + 'Tag','doseseries_listbox'); + +h35 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'Max',2,... + 'Style','listbox',... + 'Value',1,... + 'Position',[0.318140382862352 0.513565891472868 0.320875113947128 0.186046511627907],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,event) rtplan_listbox_Callback(this,hObject,event),... + 'Tag','rtplan_listbox'); + +h36 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'Style','edit',... + 'Position',[0.0447897623400366 0.762867647058823 0.857404021937843 0.0477941176470588],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,event) dir_path_field_Callback(this,hObject,event),... + 'Tag','dir_path_field' ); + +h37 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String',{ 'Import patient name & DICOM meta information'; ' '; ' ' },... + 'Style','checkbox',... + 'Value',1,... + 'Position',[0.0446672743846855 0.415661785816824 0.228805834092981 0.0484496124031008],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Callback',@(hObject,event) checkPatientName_Callback(this,hObject,event),... + 'Tag','checkPatientName' ); + +h38 = uicontrol(... + 'Parent',h1,... + 'Units','normalized',... + 'String',{ 'Use RT Dose grid'; ' '; ' ' },... + 'Style','checkbox',... + 'Position',[0.0446672743846855 0.369150157909848 0.228805834092981 0.0484496124031008],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Callback',@(hObject,event) checkbox3_Callback(this,hObject,event),... + 'Enable','off',... + 'Tag','checkbox3' ); + + this.createHandles(); + +end + diff --git a/dicomImport/@matRad_importDicomWidget/matRad_importDicomWidget.m b/dicomImport/@matRad_importDicomWidget/matRad_importDicomWidget.m new file mode 100644 index 000000000..35e370538 --- /dev/null +++ b/dicomImport/@matRad_importDicomWidget/matRad_importDicomWidget.m @@ -0,0 +1,507 @@ +classdef matRad_importDicomWidget < matRad_Widget + + properties + end + + methods + + function this = matRad_importDicomWidget(handleParent) + %MATRAD_IMPORTDICOMWIDGET Construct an instance of this class + if nargin < 1 + handleParent = figure(... + 'IntegerHandle','off',... + 'Renderer', 'painters',... + 'Units','characters',... + 'MenuBar','none',... + 'NumberTitle','off',... + 'PaperUnits','inches',... + 'Position', [450 170 480 600],... + 'Color',[0.5 0.5 0.5],... + 'Name','Import Dicom',... + 'PaperSize',[8.5 11],... + 'Position',[135.8 21.6153846153846 219.4 39.6923076923077],... + 'Renderer', 'painters', ... + 'PaperType','usletter'); + end + this = this@matRad_Widget(handleParent); + end + + % INITIALIZE FUNCTION + function this = initialize(this) + handles = this.handles; + handles.output = handles; + + axes(handles.axesMatRadLogo) + [path,name,ext] = fileparts(mfilename('fullpath')); + + [im, ~, alpha] = imread([path filesep '..' filesep '..' filesep 'gfx/matrad_logo.png']); + q = image(im); + axis equal off + set(q, 'AlphaData', alpha); + % show dkfz logo + axes(handles.axesDKFZLogo) + [im, ~, alpha] = imread([path filesep '..' filesep '..' filesep 'gfx/DKFZ_Logo.png']); + p = image(im); + axis equal off + set(p, 'AlphaData', alpha); + + % Update handles structure + % guidata(hObject, handles); + this.handles = handles; + end + + % OUTPUT FUNCTION + function varargout = matRad_importDicomGUI_OutputFcn(this, hObject, eventdata) + handles = this.handles; + varargout{1} = handles.output; + this.handles = handles; + end + + end + + methods (Access = protected) + % CREATE FUNCTION + this = createLayout(this,handleParent); + end + + % CALLBACKS + methods + + % H15 BROWSER BUTTON CALLBACK + function patDir = browse_button_Callback(this, hObject, eventdata) + handles = this.handles; + patDir = uigetdir('', 'Choose the input directory...'); + if patDir ~= 0 + patDir = [patDir filesep]; + %handles.dir_path_field.String = patDir; + set(handles.dir_path_field,'String',patDir); + % Update handles structure + % guidata(hObject, handles); + this.handles = handles; + this.scan(hObject, eventdata) + end + end + + % H17 PATIENT LISTBOX CALLBACK + function this = patient_listbox_Callback(this, hObject, eventdata) + handles = this.handles; + if ~isempty(get(hObject,'String')) + % enable Import button + set(handles.import_button,'Enable','on'); + + % handles.filelist: + % 1. Filepath + % 2. Modality + % 3. PatientID + % 4. SeriesUID + % 5. SeriesNumber + % 9. res_x + % 10. res_y + % 11. res_z + % 12. detailed dose description - currently not in use for GUI user + patient_listbox = get(handles.patient_listbox,'String'); + selected_patient = patient_listbox(get(handles.patient_listbox,'Value')); + % this gets a list of rtss series for this patient + set(handles.rtseries_listbox,'Value',1); % set dummy value to one + set(handles.rtseries_listbox,'String',handles.fileList(strcmp(handles.fileList(:,2), 'RTSTRUCT') & strcmp(handles.fileList(:,3), selected_patient),4)); + % this gets a list of rt plan series for this patient + set(handles.rtplan_listbox,'Value',[]); % set dummy value to none + set(handles.rtplan_listbox,'String',handles.fileList(strcmp(handles.fileList(:,2), 'RTPLAN') & strcmp(handles.fileList(:,3), selected_patient),4)); + % this gets a list of dose series for this patient + set(handles.doseseries_listbox,'Value',[]); % set dummy value to none + set(handles.doseseries_listbox,'String',handles.fileList(strcmp(handles.fileList(:,2), 'RTDOSE') & strcmp(handles.fileList(:,3), selected_patient),4)); + % selectedDose + + if get(handles.SeriesUID_radiobutton,'Value') == 1 + % this gets a list of ct series for this patient + set(handles.ctseries_listbox,'Value',1); % set dummy value to one + set(handles.ctseries_listbox,'String',unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient),4))); + + selectedDoseSeriesString = get(handles.doseseries_listbox,'String'); + % this gets a resolution for this patient + selectedCtSeriesString = get(handles.ctseries_listbox,'String'); + if ~isempty(selectedCtSeriesString) + res_x = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,4), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),9)); + res_y = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,4), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),10)); + res_z = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,4), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),11)); + else + res_x = NaN; res_y = NaN; res_z = NaN; + end + else + set(handles.ctseries_listbox,'Value',1); % set dummy value to one + set(handles.ctseries_listbox,'String',unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient),5))); + selectedCtSeriesString = get(handles.ctseries_listbox,'String'); + if ~isempty(selectedCtSeriesString) + res_x = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,5), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),9)); + res_y = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,5), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),10)); + res_z = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,5), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),11)); + else + res_x = NaN; res_y = NaN; res_z = NaN; + end + end + set(handles.resx_edit,'String',res_x); + set(handles.resy_edit,'String',res_y); + if numel(res_z) > 1 + set(handles.resz_edit,'String','not equi'); + else + set(handles.resz_edit,'String',res_z); + end + % Update handles structure + % guidata(hObject, handles); + this.handles = handles; + end + end + + % H22 IMPORT BUTTON CALLBACK + function this = import_button_Callback(this, hObject, eventdata) + handles = this.handles; + patient_listbox = get(handles.patient_listbox,'String'); + ctseries_listbox = get(handles.ctseries_listbox,'String'); + rtplan_listbox = get(handles.rtplan_listbox,'String'); + doseseries_listbox = get(handles.rtplan_listbox,'String'); + if ~isempty(patient_listbox) + selected_patient = patient_listbox(get(handles.patient_listbox,'Value')); + end + if ~isempty(ctseries_listbox) + selected_ctseries = ctseries_listbox(get(handles.ctseries_listbox,'Value')); + end + if ~isempty(rtplan_listbox) + selected_rtplan = rtplan_listbox(get(handles.rtplan_listbox,'Value')); + end + + if get(handles.SeriesUID_radiobutton,'Value') == 1 + files.ct = handles.fileList(strcmp(handles.fileList(:,3), selected_patient) & ... + strcmp(handles.fileList(:,4), selected_ctseries),:); + + %files.rtss = handles.fileList(strcmp(handles.fileList(:,3), selected_patient) & ... + % strcmp(handles.fileList(:,4), selected_rtseries),:); + else + files.ct = handles.fileList(strcmp(handles.fileList(:,3), selected_patient) & ... + strcmp(cellfun(@num2str,handles.fileList(:,5),'UniformOutput',false), selected_ctseries) & strcmp(handles.fileList(:,2),'CT'),:); + + %files.rtss = handles.fileList(strcmp(handles.fileList(:,3), selected_patient) & ... + % strcmp(handles.fileList(:,5), selected_rtseries),:); + end + + allRtss = handles.fileList(strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,2),'RTSTRUCT'),:); + if ~isempty(allRtss) + files.rtss = allRtss(get(handles.rtseries_listbox,'Value'),:); + else + files.rtss = []; + end + + files.resx = str2double(get(handles.resx_edit,'String')); + files.resy = str2double(get(handles.resy_edit,'String')); + % check if valid assignment is made when z slices are not equi-distant + if strcmp(get(handles.resz_edit,'String'),'not equi') + msgbox('Ct data not sliced equi-distantly in z direction! Chose uniform resolution.', 'Error','error'); + return; + else + files.resz = str2double(get(handles.resz_edit,'String')); + end + % selected RT Plan + rtplan = handles.fileList(strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,2),'RTPLAN'),:); + if ~isempty(rtplan) && ~isempty(get(handles.rtplan_listbox,'Value')) + files.rtplan = rtplan(get(handles.rtplan_listbox,'Value'),:); + end + + % selected RT Dose + rtdose = handles.fileList(strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,2),'RTDOSE'),:); + if ~isempty(rtdose) && ~isempty(get(handles.doseseries_listbox,'Value')) + selectedRtDose = get(handles.doseseries_listbox,'String'); + selectedRtDoseIx = NaN*ones(1,numel(selectedRtDose)); + for i = 1:numel(selectedRtDose) + selectedRtDoseIx(i) = find(strcmp(rtdose(:,4),selectedRtDose{i})); + end + files.rtdose = rtdose(selectedRtDoseIx,:); + end + + % check if we should use the dose grid resolution + files.useDoseGrid = get(handles.checkbox3,'Value'); + + % dicomMetaBool: store complete DICOM information and patientName or not + dicomMetaBool = logical(get(handles.checkPatientName,'Value')); + matRad_importDicom(files, dicomMetaBool); + + this.handles = handles; + end + + % H23 CANCEL BUTTON CALLBACK + function this = cancel_button_Callback(this, hObject, eventdata) + + % handles = this.handles; + % close(handles.figure1); + %Maybe needs adaptation for use in figures + close; + % this.handles = handles; + end + + % H?? RESCAN BUTTON CALLBACK; NICHT IN CREATELAYOUT VORHANDEN + function this = rescan_button_Callback(this, hObject, eventdata) + end + + % H24 SERIES UID RADIOBUTTON CALLBACK + function this = SeriesUID_radiobutton_Callback(this, hObject, eventdata) + handles = this.handles; + if get(hObject,'Value') == 1 + set(handles.SeriesNumber_radiobutton,'Value',0); + else + set(hObject,'Value',1); + set(handles.SeriesNumber_radiobutton,'Value',0); + end + if isfield(handles, 'fileList') + patient_listbox = get(handles.patient_listbox,'String'); + selected_patient = patient_listbox(get(handles.patient_listbox,'Value')); + set(handles.ctseries_listbox,'String',unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient),4))); + set(handles.rtseries_listbox,'String',unique(handles.fileList(strcmp(handles.fileList(:,2), 'RTSTRUCT') & strcmp(handles.fileList(:,3), selected_patient),4))); + set(handles.doseseries_listbox,'String',handles.fileList(strcmp(handles.fileList(:,2), 'RTDOSE') & strcmp(handles.fileList(:,3), selected_patient),4)); + set(handles.rtplan_listbox,'String',unique(handles.fileList(strcmp(handles.fileList(:,2), 'RTPLAN') & strcmp(handles.fileList(:,3), selected_patient),4))); + else + fprintf('No patient loaded, so just switching default display option to SeriesUID. \n'); + end + %guidata(hObject, handles); + this.handles = handles; + end + + % H25 SERIESNUMBER RADIO BUTTON CALLBACK + function this = SeriesNumber_radiobutton_Callback(this, hObject, eventdata) + handles = this.handles; + + if get(hObject,'Value') == 1 + set(handles.SeriesUID_radiobutton,'Value',0); + else + set(hObject,'Value',1); + set(handles.SeriesUID_radiobutton,'Value',0); + end + if isfield(handles, 'fileList') + patient_listbox = get(handles.patient_listbox,'String'); + selected_patient = patient_listbox(get(handles.patient_listbox,'Value')); + % set(handles.ctseries_listbox,'String',unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient),5))); + set(handles.ctseries_listbox,'String',unique(cell2mat(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient),5)))); + + else + fprintf('No patient loaded, so just switching default display option to SeriesNumber. \n'); + end + % guidata(hObject, handles); + this.handles = handles; + end + + + % H34 DOSESERIES LISTBOX CALLBACK + function this = doseseries_listbox_Callback(this, hObject, eventdata) + handles = this.handles; + + if ~isempty(get(hObject,'Value')) + set(handles.checkbox3,'Enable','on'); + else + set(handles.checkbox3,'Value',0); + set(handles.checkbox3,'Enable','off'); + % retrieve and display resolution for DICOM ct cube + patient_listbox = get(handles.patient_listbox,'String'); + selected_patient = patient_listbox(get(handles.patient_listbox,'Value')); + selectedCtSeriesString = get(handles.ctseries_listbox,'String'); + if get(handles.SeriesUID_radiobutton,'Value') == 1 + if ~isempty(selectedCtSeriesString) + res_x = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,4), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),9)); + res_y = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,4), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),10)); + res_z = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,4), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),11)); + else + res_x = NaN; res_y = NaN; res_z = NaN; + end + else + if ~isempty(selectedCtSeriesString) + res_x = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,5), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),9)); + res_y = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,5), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),10)); + res_z = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,5), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),11)); + else + res_x = NaN; res_y = NaN; res_z = NaN; + end + end + set(handles.resx_edit,'String',res_x); + set(handles.resy_edit,'String',res_y); + if numel(res_z) > 1 + set(handles.resz_edit,'String','not equi'); + else + set(handles.resz_edit,'String',res_z); + end + + end + + this.handles = handles; + end + + % H35 RTPLAN LISTBOX CALLBACK + function this = rtplan_listbox_Callback(this, hObject, eventdata) + handles = this.handles; + + contents = cellstr(get(hObject,'String')); + if ~isempty(get(hObject,'Value')) && numel(get(hObject,'Value')) == 1 + + selectedPlan = contents{get(hObject,'Value')}; + % point at plan in listbox + selectedPlanLoc = strcmp(handles.fileList(:,4),selectedPlan); + + % show only the doses corresponding to the plan + corrDoses = [handles.fileList{selectedPlanLoc,13}]; + numOfDoses = numel(corrDoses); + corrDosesLoc = zeros(size(handles.fileList(:,1),1),1); + for j = 1:numOfDoses + if ~isnan(corrDoses{j}) + corrDosesLoc = corrDosesLoc | strcmp(handles.fileList(:,4),corrDoses{j}); + end + end + + if sum(corrDosesLoc) == 0 + warndlg('no rt dose file directly associated to plan file. showing all rt dose files.'); + corrDosesLoc = strcmp(handles.fileList(:,2),'RTDOSE'); + end + + set(handles.doseseries_listbox,'Value',[]); % set dummy value to one + set(handles.doseseries_listbox,'String',handles.fileList(corrDosesLoc,4)); + + % disable checkbox for use dose grid is currently checked + if get(handles.checkbox3,'Value') == 1 + set(handles.checkbox3,'Value',0); + checkbox3_Callback(handles.checkbox3,[], handles); + end + set(handles.checkbox3,'Enable','off'); + + elseif numel(get(hObject,'Value')) >=2 + warning('More than one RTPLAN selected. Unsetting selection ...'); + patient_listbox_Callback(this, hObject, eventdata); + else + patient_listbox_Callback(this, hObject, eventdata); + end + + this.handles = handles; + + end + + % H36 DIR PATH FIELD CALLBACK + function this = dir_path_field_Callback(this, hObject, eventdata) + handles = this.handles; + patDir = get(handles.dir_path_field,'String'); + if patDir(end) ~= filesep; + patDir = [patDir filesep]; + set(handles.dir_path_field,'String',patDir); + % guidata(hObject, handles); + this.handles = handles; + end + scan(hObject, eventdata); + end + + % H37 CHECK PATIENTNAME CALLBACK + function this = checkPatientName_Callback(this, hObject, eventdata) + handles = this.handles; + % hObject handle to checkPatientName (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + %A = get(hObject,'Value'); + + % Hint: get(hObject,'Value') returns toggle state of checkPatientName + %guidata(hObject, handles); + this.handles = handles; + + end + + % H?? CHECKBOX§ CALLBACK + function this = checkbox3_Callback(this, hObject, eventdata) + % hObject handle to checkbox3 (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hint: get(hObject,'Value') returns toggle state of checkbox3 + handles = this.handles; + + if get(hObject,'Value') + set(handles.resx_edit,'Enable', 'off'); + set(handles.resy_edit,'Enable', 'off'); + set(handles.resz_edit,'Enable', 'off'); + % retrieve and display resolution for DICOM dose cube + doseFilesInList = get(handles.doseseries_listbox,'String'); + selectedDoseFiles = get(handles.doseseries_listbox,'Value'); + if isempty(selectedDoseFiles) + set(hObject,'Value',0) + errordlg('no dose file selected'); + return; + end + for i = 1:numel(selectedDoseFiles) + selectedDoseFile = doseFilesInList{selectedDoseFiles(i)}; + if verLessThan('matlab','9') + dicomDoseInfo = dicominfo(handles.fileList{find(strcmp(handles.fileList(:,4),selectedDoseFile)),1}); + else + dicomDoseInfo = dicominfo(handles.fileList{find(strcmp(handles.fileList(:,4),selectedDoseFile)),1},'UseDictionaryVR',true); + end + res_x{i} = dicomDoseInfo.PixelSpacing(1); + res_y{i} = dicomDoseInfo.PixelSpacing(2); + res_z{i} = dicomDoseInfo.SliceThickness; + end + + if numel(unique(cell2mat(res_x)))*numel(unique(cell2mat(res_y)))*numel(unique(cell2mat(res_z))) ~= 1 + set(handles.checkbox3,'Value',0); + warndlg('Different resolutions in dose file(s)'); + set(handles.resx_edit,'Enable', 'on'); + set(handles.resy_edit,'Enable', 'on'); + set(handles.resz_edit,'Enable', 'on'); + else + set(handles.resx_edit,'String',num2str(res_x{1})); + set(handles.resy_edit,'String',num2str(res_y{1})); + set(handles.resz_edit,'String',num2str(res_z{1})); + end + + else + set(handles.resx_edit,'Enable', 'on'); + set(handles.resy_edit,'Enable', 'on'); + set(handles.resz_edit,'Enable', 'on'); + % retrieve and display resolution for DICOM ct cube + patient_listbox = get(handles.patient_listbox,'String'); + selected_patient = patient_listbox(get(handles.patient_listbox,'Value')); + selectedCtSeriesString = get(handles.ctseries_listbox,'String'); + if get(handles.SeriesUID_radiobutton,'Value') == 1 + if ~isempty(selectedCtSeriesString) + res_x = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,4), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),9)); + res_y = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,4), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),10)); + res_z = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,4), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),11)); + else + res_x = NaN; res_y = NaN; res_z = NaN; + end + else + if ~isempty(selectedCtSeriesString) + res_x = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,5), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),9)); + res_y = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,5), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),10)); + res_z = unique(handles.fileList(strcmp(handles.fileList(:,2), 'CT') & strcmp(handles.fileList(:,3), selected_patient) & strcmp(handles.fileList(:,5), selectedCtSeriesString{get(handles.ctseries_listbox,'Value')}),11)); + else + res_x = NaN; res_y = NaN; res_z = NaN; + end + end + set(handles.resx_edit,'String',res_x); + set(handles.resy_edit,'String',res_y); + if numel(res_z) > 1 + set(handles.resz_edit,'String','not equi'); + else + set(handles.resz_edit,'String',res_z); + end + end + + this.handles = handles; + end + + end + + methods (Access = private) + % SCAN FUNKTION + function this = scan(this, hObject, eventdata) + handles = this.handles; + [fileList, patient_listbox] = matRad_scanDicomImportFolder(get(handles.dir_path_field,'String')); + if iscell(patient_listbox) + handles.fileList = fileList; + %handles.patient_listbox.String = patient_listbox; + set(handles.patient_listbox,'String',patient_listbox,'Value',1); + % guidata(hObject, handles); + this.handles = handles; + end + end + end + + end + diff --git a/gui/matRad_CreateMainLayout.m b/gui/matRad_CreateMainLayout.m new file mode 100644 index 000000000..30c1f8c55 --- /dev/null +++ b/gui/matRad_CreateMainLayout.m @@ -0,0 +1,1550 @@ +function this = matRad_CreateMainLayout(this,handleParent) +h1 = this.widgetHandle; + +% Create all handles + +h2 = axes(... +'Parent',h1,... +'CameraPosition',[0.5 0.5 9.16025403784439],... +'CameraTarget',[0.5 0.5 0.5],... +'CameraViewAngle',6.60861036031192,... +'PlotBoxAspectRatio',[1 0.305555555555556 0.305555555555556],... +'FontName','CMU Serif',... +'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... +'XTick',[0 0.2 0.4 0.6 0.8 1],... +'XTickLabel',{ '0'; '0.2'; '0.4'; '0.6'; '0.8'; '1' },... +'YTick',[0 0.5 1],... +'YTickLabel',{ '0'; '0.5'; '1' },... +'Position',[0.444874274661509 0.893725992317542 0.184397163120567 0.0998719590268886],... +'ActivePositionProperty','position',... +'LooseInset',[0.182759687929063 0.112926163636008 0.133555156563546 0.0769951115700055],... +'FontSize',9.63,... +'SortMethod','childorder',... +'Tag','axesLogo'); + +h3 = get(h2,'title'); + +set(h3,... +'Parent',h2,... +'Units','data',... +'FontUnits','points',... +'Color',[0 0 0],... +'Position',[0.500002781550089 1.03439285714286 0.500000000000007],... +'PositionMode','auto',... +'Interpreter','tex',... +'Rotation',0,... +'RotationMode','auto',... +'FontName','CMU Serif',... +'FontSize',10.593,... +'FontAngle','normal',... +'FontWeight','bold',... +'HorizontalAlignment','center',... +'HorizontalAlignmentMode','auto',... +'VerticalAlignment','bottom',... +'VerticalAlignmentMode','auto',... +'EdgeColor','none',... +'LineStyle','-',... +'LineWidth',0.5,... +'BackgroundColor','none',... +'Margin',3,... +'Clipping','off',... +'XLimInclude','on',... +'YLimInclude','on',... +'ZLimInclude','on',... +'Visible','on',... +'HandleVisibility','off',... +'BusyAction','queue',... +'Interruptible','on',... +'HitTest','on',... +'PickableParts','visible'); + +h4 = get(h2,'xlabel'); + +set(h4,... +'Parent',h2,... +'Units','data',... +'FontUnits','points',... +'Color',[0.15 0.15 0.15],... +'Position',[0.500000476837158 -0.283480513287831 7.105427357601e-15],... +'PositionMode','auto',... +'Interpreter','tex',... +'Rotation',0,... +'RotationMode','auto',... +'FontName','CMU Serif',... +'FontSize',10.593,... +'FontAngle','normal',... +'FontWeight','normal',... +'HorizontalAlignment','center',... +'HorizontalAlignmentMode','auto',... +'VerticalAlignment','top',... +'VerticalAlignmentMode','auto',... +'EdgeColor','none',... +'LineStyle','-',... +'LineWidth',0.5,... +'BackgroundColor','none',... +'Margin',3,... +'Clipping','off',... +'XLimInclude','on',... +'YLimInclude','on',... +'ZLimInclude','on',... +'Visible','on',... +'HandleVisibility','off',... +'BusyAction','queue',... +'Interruptible','on',... +'HitTest','on',... +'PickableParts','visible'); + +h5 = get(h2,'ylabel'); + +set(h5,... +'Parent',h2,... +'Units','data',... +'FontUnits','points',... +'Color',[0.15 0.15 0.15],... +'Position',[-0.104158728029993 0.500000476837158 7.105427357601e-15],... +'PositionMode','auto',... +'Interpreter','tex',... +'Rotation',90,... +'RotationMode','auto',... +'FontName','CMU Serif',... +'FontSize',10.593,... +'FontAngle','normal',... +'FontWeight','normal',... +'HorizontalAlignment','center',... +'HorizontalAlignmentMode','auto',... +'VerticalAlignment','bottom',... +'VerticalAlignmentMode','auto',... +'EdgeColor','none',... +'LineStyle','-',... +'LineWidth',0.5,... +'BackgroundColor','none',... +'Margin',3,... +'Clipping','off',... +'XLimInclude','on',... +'YLimInclude','on',... +'ZLimInclude','on',... +'Visible','on',... +'HandleVisibility','off',... +'BusyAction','queue',... +'Interruptible','on',... +'HitTest','on',... +'PickableParts','visible'); + +h6 = get(h2,'zlabel'); + +set(h6,... +'Parent',h2,... +'Units','data',... +'FontUnits','points',... +'Color',[0.15 0.15 0.15],... +'Position',[0 0 0],... +'PositionMode','auto',... +'Interpreter','tex',... +'Rotation',0,... +'RotationMode','auto',... +'FontName','CMU Serif',... +'FontSize',10,... +'HorizontalAlignment','left',... +'HorizontalAlignmentMode','auto',... +'VerticalAlignment','middle',... +'VerticalAlignmentMode','auto',... +'EdgeColor','none',... +'LineStyle','-',... +'LineWidth',0.5,... +'BackgroundColor','none',... +'Margin',3,... +'Clipping','off',... +'XLimInclude','on',... +'YLimInclude','on',... +'ZLimInclude','on',... +'Visible','off',... +'HandleVisibility','off',... +'BusyAction','queue',... +'Interruptible','on',... +'HitTest','on',... +'PickableParts','visible'); + +h7 = axes(... +'Parent',h1,... +'CameraPosition',[0.5 0.5 9.16025403784439],... +'CameraTarget',[0.5 0.5 0.5],... +'CameraViewAngle',6.60861036031192,... +'PlotBoxAspectRatio',[1 0.155367231638418 0.155367231638418],... +'FontName','CMU Serif',... +'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... +'XTick',[0 0.2 0.4 0.6 0.8 1],... +'XTickLabel',{ '0'; '0.2'; '0.4'; '0.6'; '0.8'; '1' },... +'YTick',[0 0.5 1],... +'YTickLabel',{ '0'; '0.5'; '1' },... +'Position',[0.652482269503546 0.903969270166453 0.259187620889749 0.0717029449423816],... +'ActivePositionProperty','position',... +'LooseInset',[0.13 0.11 0.0950000000000001 0.0749999999999999],... +'FontSize',9.63,... +'SortMethod','childorder',... +'Tag','axesDKFZ'); + +h8 = get(h7,'title'); + +set(h8,... +'Parent',h7,... +'Units','data',... +'FontUnits','points',... +'Color',[0 0 0],... +'Position',[0.500002882574911 1.04815 0.5],... +'PositionMode','auto',... +'Interpreter','tex',... +'Rotation',0,... +'RotationMode','auto',... +'FontName','CMU Serif',... +'FontSize',10.593,... +'FontAngle','normal',... +'FontWeight','bold',... +'HorizontalAlignment','center',... +'HorizontalAlignmentMode','auto',... +'VerticalAlignment','bottom',... +'VerticalAlignmentMode','auto',... +'EdgeColor','none',... +'LineStyle','-',... +'LineWidth',0.5,... +'BackgroundColor','none',... +'Margin',3,... +'Clipping','off',... +'XLimInclude','on',... +'YLimInclude','on',... +'ZLimInclude','on',... +'Visible','on',... +'HandleVisibility','off',... +'BusyAction','queue',... +'Interruptible','on',... +'HitTest','on',... +'PickableParts','visible'); + +h9 = get(h7,'xlabel'); + +set(h9,... +'Parent',h7,... +'Units','data',... +'FontUnits','points',... +'Color',[0.15 0.15 0.15],... +'Position',[0.500000476837158 -0.396872718602964 0],... +'PositionMode','auto',... +'Interpreter','tex',... +'Rotation',0,... +'RotationMode','auto',... +'FontName','CMU Serif',... +'FontSize',10.593,... +'FontAngle','normal',... +'FontWeight','normal',... +'HorizontalAlignment','center',... +'HorizontalAlignmentMode','auto',... +'VerticalAlignment','top',... +'VerticalAlignmentMode','auto',... +'EdgeColor','none',... +'LineStyle','-',... +'LineWidth',0.5,... +'BackgroundColor','none',... +'Margin',3,... +'Clipping','off',... +'XLimInclude','on',... +'YLimInclude','on',... +'ZLimInclude','on',... +'Visible','on',... +'HandleVisibility','off',... +'BusyAction','queue',... +'Interruptible','on',... +'HitTest','on',... +'PickableParts','visible'); + +h10 = get(h7,'ylabel'); + +set(h10,... +'Parent',h7,... +'Units','data',... +'FontUnits','points',... +'Color',[0.15 0.15 0.15],... +'Position',[-0.074146891139995 0.500000476837156 0],... +'PositionMode','auto',... +'Interpreter','tex',... +'Rotation',90,... +'RotationMode','auto',... +'FontName','CMU Serif',... +'FontSize',10.593,... +'FontAngle','normal',... +'FontWeight','normal',... +'HorizontalAlignment','center',... +'HorizontalAlignmentMode','auto',... +'VerticalAlignment','bottom',... +'VerticalAlignmentMode','auto',... +'EdgeColor','none',... +'LineStyle','-',... +'LineWidth',0.5,... +'BackgroundColor','none',... +'Margin',3,... +'Clipping','off',... +'XLimInclude','on',... +'YLimInclude','on',... +'ZLimInclude','on',... +'Visible','on',... +'HandleVisibility','off',... +'BusyAction','queue',... +'Interruptible','on',... +'HitTest','on',... +'PickableParts','visible'); + +h11 = get(h7,'zlabel'); + +set(h11,... +'Parent',h7,... +'Units','data',... +'FontUnits','points',... +'Color',[0.15 0.15 0.15],... +'Position',[0 0 0],... +'PositionMode','auto',... +'Interpreter','tex',... +'Rotation',0,... +'RotationMode','auto',... +'FontName','CMU Serif',... +'FontSize',10,... +'FontAngle','normal',... +'FontWeight','normal',... +'HorizontalAlignment','left',... +'HorizontalAlignmentMode','auto',... +'VerticalAlignment','middle',... +'VerticalAlignmentMode','auto',... +'EdgeColor','none',... +'LineStyle','-',... +'LineWidth',0.5,... +'BackgroundColor','none',... +'Margin',3,... +'Clipping','off',... +'XLimInclude','on',... +'YLimInclude','on',... +'ZLimInclude','on',... +'Visible','off',... +'HandleVisibility','off',... +'BusyAction','queue',... +'Interruptible','on',... +'HitTest','on',... +'PickableParts','visible'); + +h12 = uipanel(... +'Parent',h1,... +'Title','Plan',... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','uipanel1',... +'Clipping','off',... +'Position',[0.00451321727917473 0.527528809218956 0.430689877498388 0.272727272727273],... +'FontName','Helvetica',... +'FontWeight','bold'); + +h13 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','bixel width in [mm]',... +'Style','text',... +'Position',[0.0347043701799486 0.859315589353612 0.17866323907455 0.0950570342205324],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtBixelWidth',... +'UserData',[],... +'FontName','Helvetica'); + +h14 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','5',... +'Style','edit',... +'Position',[0.219794344473008 0.889733840304182 0.161953727506427 0.0836501901140684],... +'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... +'Callback',@(hObject,eventdata) editBixelWidth_Callback(this.hObject,eventdata),... +'Children',[],... +'Tag','editBixelWidth',... +'FontWeight','bold'); + +h15 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','Gantry Angle in °',... +'Style','text',... +'Position',[0.032133676092545 0.752851711026616 0.176092544987147 0.0950570342205324],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Children',[],... +'Tag','txtGantryAngle' ); + +h16 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','0',... +'Style','edit',... +'Position',[0.219794344473008 0.779467680608365 0.161953727506427 0.0836501901140684],... +'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... +'Callback',@(hObject,eventdata)editGantryAngle_Callback(this,hObject,eventdata),... +'Tag','editGantryAngle',... +'FontWeight','bold'); + +h17 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','Couch Angle in °',... +'Style','text',... +'Position',[0.0347043701799486 0.64638783269962 0.173521850899743 0.0950570342205324],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtCouchAngle'); + +h18 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','0',... +'Style','edit',... +'Position',[0.219794344473008 0.669201520912547 0.161953727506427 0.0836501901140685],... +'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... +'Callback',@(hObject,eventdata) editCouchAngle_Callback(this,hObject,eventdata),... +'Tag','editCouchAngle',... +'FontWeight','bold'); + +h19 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String',{ 'photons'; 'protons'; 'carbon' },... +'Style','popupmenu',... +'Value',1,... +'Position',[0.219794344473008 0.52851711026616 0.161953727506427 0.114068441064639],... +'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... +'Callback',@(hObject,eventdata)popupRadMode_Callback(this.hObject,eventdata),... +'Tag','popupRadMode',... +'FontWeight','bold'); + + +h20 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','Radiation Mode',... +'Style','text',... +'Position',[0.051413881748072 0.539923954372624 0.146529562982005 0.0950570342205324],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtRadMode'); + +h21 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','# Fractions',... +'Style','text',... +'Position',[0.051413881748072 0.209125475285171 0.143958868894602 0.106463878326996],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtNumOfFractions'); + +h22 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','30',... +'Style','edit',... +'Position',[0.219794344473008 0.228136882129278 0.161953727506427 0.0836501901140684],... +'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... +'Callback',@(hObject,eventdata) editFraction_Callback(this.hObject,eventdata),... +'Tag','editFraction',... +'FontWeight','bold'); + +h23 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','IsoCenter in [mm]',... +'Style','text',... +'Position',[0.0282776349614396 0.330798479087452 0.201799485861183 0.091254752851711],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtIsoCenter',... +'UserData',[],... +'FontName','Helvetica'); + +h24 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','0 0 0',... +'Style','edit',... +'Position',[0.219794344473008 0.338403041825095 0.161953727506427 0.0836501901140684],... +'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... +'Callback',@(hObject,eventdata) editIsoCenter_Callback(this,hObject,eventdata),... +'Children',[],... +'Enable','off',... +'Tag','editIsoCenter',... +'FontWeight','bold'); + +h25 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','Auto.',... +'Style','checkbox',... +'Value',1,... +'Position',[0.38560411311054 0.338403041825095 0.0809768637532133 0.091254752851711],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Callback',@(hObject,eventdata) checkIsoCenter_Callback(this,hObject,eventdata),... +'Tag','checkIsoCenter'); + +h26 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','Run Sequencing',... +'Style','radiobutton',... +'Position',[0.553984575835475 0.628020880324805 0.173521850899743 0.140684410646388],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Callback',@(hObject,eventdata) btnRunSequencing_Callback(this,hObject,eventdata),... +'Enable','off',... +'Tag','btnRunSequencing'); + +h27 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','Run Direct Aperture Optimization',... +'Style','radiobutton',... +'Position',[0.553984575835475 0.32003608945028 0.294344473007712 0.140684410646388],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Callback',@(hObject,eventdata)btnRunDAO_Callback(this,hObject,eventdata),... +'Enable','off',... +'Tag','btnRunDAO' ); + +h28 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','Stratification Levels',... +'Style','text',... +'Position',[0.553984575835475 0.502545595153702 0.179948586118252 0.102661596958175],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtSequencing' ); + +h29 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','7',... +'Style','edit',... +'Position',[0.58611825192802 0.449313655990204 0.0668380462724936 0.0836501901140685],... +'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... +'Callback',@(hObject,eventdata)editSequencingLevel_Callback(this,hObject,eventdata),... +'Enable','off',... +'Tag','editSequencingLevel',... +'FontWeight','bold'); + +h30 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String',['Generic';' '],... +'Style','popupmenu',... +'Value',1,... +'Position',[0.219794344473008 0.418250950570342 0.161953727506427 0.114068441064639],... +'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... +'Callback',@(hObject,eventdata) popUpMachine_Callback(this,hObject,eventdata),... +'Tag','popUpMachine',... +'FontWeight','bold'); + +h31 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','Machine',... +'Style','text',... +'Position',[0.0732647814910026 0.433460076045627 0.106683804627249 0.0950570342205323],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtMachine' ); + +h32 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','Set Tissue',... +'Position',[0.401028277634961 0.110266159695817 0.109254498714653 0.0874524714828897],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) btnSetTissue_Callback(this,hObject,eventdata),... +'Enable','off',... +'Tag','btnSetTissue'); + +h33 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String',{ 'none'; 'const_RBExD'; 'LEMIV_effect'; 'LEMIV_RBExD' },... +'Style','popupmenu',... +'Value',1,... +'Position',[0.219794344473008 0.0760456273764259 0.165809768637532 0.11787072243346],... +'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... +'Callback',@(hObject,eventdata) popMenuBioOpt_Callback(this,hObject,eventdata),... +'Tag','popMenuBioOpt',... +'FontWeight','bold'); + +h34 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','Type of optimization',... +'Style','text',... +'Position',[0.0102827763496144 0.0988593155893536 0.201799485861183 0.091254752851711],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Interruptible','off',... +'Tag','text38',... +'FontName','Helvetica' ); + +h35 = uicontrol(... +'Parent',h12,... +'Units','normalized',... +'String','3D conformal',... +'Style','radiobutton',... +'Position',[0.553224553224553 0.757869249394673 0.212121212121212 0.0847457627118644],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Callback',@(hObject,eventdata) radiobutton3Dconf_Callback(this,hObject,eventdata),... +'Enable','off',... +'Tag','radiobutton3Dconf' ); + +h36 = uipanel(... +'Parent',h1,... +'Title',strtrim(strjoin({ 'Visualization'; ' ' })),... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','uipanel2',... +'Clipping','off',... +'Position',[0.00451321727917473 0.0460947503201024 0.430689877498388 0.203585147247119],... +'FontName','Helvetica',... +'FontWeight','bold'); + +h37 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String',{ 'coronal'; 'sagital'; 'axial' },... +'Style','popupmenu',... +'Value',3,... +'Position',[0.465315808689303 0.582191780821918 0.113636363636364 0.143835616438356],... +'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... +'Callback',@(hObject,eventdata) popupPlane_Callback(hObject,eventdata),... +'Tag','popupPlane',... +'FontWeight','bold'); + +h38 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String',{ 'Slider' },... +'Style','slider',... +'Position',[0.134961439588689 0.796610169491525 0.167095115681234 0.096045197740113],... +'BackgroundColor',[0.9 0.9 0.9],... +'Callback',@(hObject,eventdata) sliderSlice_Callback(this,hObject,eventdata),... +'BusyAction','cancel',... +'Interruptible','off',... +'Tag','sliderSlice'); + +h39 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'HorizontalAlignment','left',... +'String','Plane Selection',... +'Style','text',... +'Position',[0.34258853596203 0.589041095890411 0.11969696969697 0.116438356164384],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtPlanSelection'); + +h40 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'HorizontalAlignment','left',... +'String','Slice Selection',... +'Style','text',... +'Position',[0.00909090909090909 0.808219178082192 0.113636363636364 0.116438356164384],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','text9' ); + +h41 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','plot contour',... +'Style','radiobutton',... +'Value',1,... +'Position',[0.780445969125214 0.733212341197822 0.169811320754717 0.117241379310345],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Callback',@(hObject,eventdata) radiobtnContour_Callback(this,hObject,eventdata),... +'Tag','radiobtnContour' ); + +h42 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','plot dose',... +'Style','radiobutton',... +'Value',1,... +'Position',[0.780445969125214 0.466969147005444 0.169811320754717 0.117241379310345],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Callback',@(hObject,eventdata) radiobtnDose_Callback(this,hObject,eventdata),... +'Children',[],... +'Tag','radiobtnDose' ); + + +h43 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','plot isolines',... +'Style','radiobutton',... +'Value',1,... +'Position',[0.780445969125214 0.600907441016334 0.150943396226415 0.117241379310345],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Callback',@(hObject,eventdata) radiobtnIsoDoseLines_Callback(this,hObject,eventdata),... +'Tag','radiobtnIsoDoseLines'); + +h44 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'HorizontalAlignment','left',... +'String','Type of plot',... +'Style','text',... +'Position',[0.343053173241852 0.793103448275862 0.108061749571183 0.124137931034483],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtTypeOfPlot' ); + +h45 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String',{ 'intensity'; 'profile' },... +'Style','popupmenu',... +'Value',1,... +'Position',[0.465315808689303 0.801369863013699 0.113636363636364 0.143835616438356],... +'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... +'Callback',@(hObject,eventdata) popupTypeOfPlot_Callback(this,hObject,eventdata),... +'Tag','popupTypeOfPlot',... +'FontWeight','bold'); + +h46 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'HorizontalAlignment','left',... +'String','Display option',... +'Style','text',... +'Position',[0.34258853596203 0.39041095890411 0.128787878787879 0.102739726027397],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtDisplayOption' ); + +h47 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','Please select ... ',... +'Style','popupmenu',... +'Value',1,... +'Position',[0.465315808689303 0.36986301369863 0.196969696969697 0.136986301369863],... +'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... +'Callback',@(hObject,eventdata)popupDisplayOption_Callback(this,hObject,eventdata),... +'Tag','popupDisplayOption',... +'FontWeight','bold'); + +h48 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'HorizontalAlignment','left',... +'String','Beam Selection',... +'Style','text',... +'Position',[0.00857632933104631 0.503448275862069 0.118353344768439 0.186206896551724],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtBeamSelection' ); + +h49 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','SliderBeamSelection',... +'Style','slider',... +'Position',[0.134961439588689 0.542372881355932 0.167095115681234 0.096045197740113],... +'BackgroundColor',[0.9 0.9 0.9],... +'Callback',@(hObject,eventdata) sliderBeamSelection_Callback(this,hObject,eventdata),... +'Enable','off',... +'Tag','sliderBeamSelection'); + +h50 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','lateral',... +'Position',[0.658025928757913 0.794520547945205 0.0863636363636364 0.157534246575343],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) btnProfileType_Callback(this,hObject,eventdata),... +'Enable','off',... +'Tag','btnProfileType',... +'FontWeight','bold' ); + +h51 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','GoTo',... +'Style','text',... +'Position',[0.604795511376553 0.801369863013698 0.0454545454545454 0.123287671232877],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Children',[],... +'Tag','text16' ); + +h52 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','Show DVH/QI',... +'Position',[0.51413881748072 0.0677966101694915 0.123393316195373 0.129943502824859],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) btnDVH_Callback(this,hObject,eventdata),... +'Enable','off',... +'Tag','btnDVH',... +'FontWeight','bold'); + +h53 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','plot isolines labels',... +'Style','radiobutton',... +'Position',[0.780445969125214 0.343557168784029 0.202401372212693 0.117241379310345],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Callback',@(hObject,eventdata) radiobtnIsoDoseLinesLabels_Callback(this,hObject,eventdata),... +'Tag','radiobtnIsoDoseLinesLabels'); + +h54 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'HorizontalAlignment','left',... +'String','Offset',... +'Style','text',... +'Position',[0.00909090909090909 0.287104393008975 0.118181818181818 0.123287671232877],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','textOffset'); + +h55 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','SliderOffset',... +'Style','slider',... +'Position',[0.134961439588689 0.271186440677966 0.167095115681234 0.096045197740113],... +'BackgroundColor',[0.9 0.9 0.9],... +'Callback',@(hObject,eventdata) sliderOffset_Callback(this,hObject,eventdata),... +'Enable','off',... +'Tag','sliderOffset'); + + +h56 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','plot iso center',... +'Style','radiobutton',... +'Value',1,... +'Position',[0.780445969125214 0.205989110707804 0.169811320754717 0.117241379310345],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Callback',@(hObject,eventdata) radioBtnIsoCenter_Callback(this,hObject,eventdata),... +'Tag','radioBtnIsoCenter'); + + +h57 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','Open 3D-View',... +'Position',[0.595848595848596 0.578947368421053 0.148962148962149 0.157894736842105],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) btn3Dview_Callback(this,hObject,eventdata),... +'Enable','off',... +'Tag','btn3Dview',... +'FontWeight','bold'); + +h58 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','plot CT',... +'Style','radiobutton',... +'Value',1,... +'Position',[0.780445969125214 0.864791288566243 0.169811320754717 0.117241379310345],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Callback',@(hObject,eventdata) radiobtnCT_Callback(this,hObject,eventdata),... +'Tag','radiobtnCT'); + + +h59 = uicontrol(... +'Parent',h36,... +'Units','normalized',... +'String','visualize plan / beams',... +'Style','radiobutton',... +'Value',1,... +'Position',[0.78021978021978 0.0736842105263158 0.2002442002442 0.115789473684211],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Callback',@(hObject,eventdata) radiobtnPlan_Callback(this,hObject,eventdata),... +'Tag','radiobtnPlan'); + +h60 = uitoolbar(... +'Parent',h1,... +'Tag','uitoolbar1'); + +h61 = uipushtool(... +'Parent',h60,... +'Children',[],... +'BusyAction','cancel',... +'Interruptible','off',... +'Tag','toolbarLoad',... +'CData',mat{2},... +'ClickedCallback',@(hObject,eventdata) toolbarLoad_ClickedCallback(this,hObject,eventdata),... +'Separator','on',... +'TooltipString','Open File' ); + +h62 = uipushtool(... +'Parent',h60,... +'BusyAction','cancel',... +'Interruptible','off',... +'Tag','toolbarSave',... +'CData',mat{3},... +'ClickedCallback',@(hObject,eventdata) toolbarSave_ClickedCallback(this,hObject,eventdata),... +'Separator','on',... +'TooltipString','Save Figure'); + + +h63 = uipushtool(... +'Parent',h60,... +'Tag','uipushtool_screenshot',... +'CData',mat{4},... +'ClickedCallback',@(hObject,eventdata) uipushtool_screenshot_ClickedCallback(this,hObject,eventdata),... +'TooltipString','Take a screenshot of the current dose or profile plot' ); + +h64 = uitoggletool(... +'Parent',h60,... +'Tag','toolbarZoomIn',... +'CData',mat{5},... +'Separator','on',... +'TooltipString','Zoom In'); + +h65 = uitoggletool(... +'Parent',h60,... +'Children',[],... +'Tag','toolbarZoomOut',... +'CData',mat{6},... +'Separator','on',... +'TooltipString','Zoom Out'); + +h66 = uitoggletool(... +'Parent',h60,... +'Tag','toolbarPan',... +'CData',mat{7},... +'Separator','on',... +'TooltipString','Pan' ); + +h67 = uitoggletool(... +'Parent',h60,... +'Tag','toolbarCursor',... +'CData',mat{8},... +'Separator','on',... +'TooltipString','Data Cursor' ); + +h68 = uitoggletool(... +'Parent',h60,... +'Tag','toolbarLegend',... +'CData',mat{9},... +'Separator','on',... +'TooltipString','Insert Legend'); + +h69 = uitoggletool(... +'Parent',h60,... +'Tag','uitoggletool8',... +'CData',mat{10},... +'ClickedCallback',@(hObject,eventdata)matRadGUI('uitoggletool8_ClickedCallback',hObject,eventdata,guidata(hObject)),... +'Separator','on',... +'TooltipString','Insert Colorbar' ); + +h70 = uipanel(... +'Parent',h1,... +'Title',strtrim(strjoin({ 'Objectives & constraints'; ' '; ' ' })),... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','uipanel3',... +'Clipping','off',... +'Position',[0.00451321727917473 0.257362355953905 0.430689877498388 0.259923175416133],... +'FontName','Helvetica',... +'FontWeight','bold' ); + +h71 = uipanel(... +'Parent',h1,... +'ShadowColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Title','Workflow',... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','uipanel4',... +'Clipping','off',... +'Position',[0.00451321727917473 0.810499359795134 0.430045132172792 0.170294494238156],... +'FontName','Helvetica',... +'FontWeight','bold' ); + +h72 = uicontrol(... +'Parent',h71,... +'Units','normalized',... +'String','Status:',... +'Style','text',... +'Position',[0.318250377073907 0.107438016528926 0.120663650075415 0.12396694214876],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','text13',... +'FontWeight','bold' ); + +h73 = uicontrol(... +'Parent',h71,... +'Units','normalized',... +'String','no data loaded',... +'Style','text',... +'Position',[0.414781297134238 0.0247933884297521 0.371040723981901 0.214876033057851],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtInfo',... +'FontWeight','bold' ); + +h74 = uicontrol(... +'Parent',h71,... +'Units','normalized',... +'String','Load *.mat data',... +'Position',[0.151866151866152 0.810126582278481 0.178893178893179 0.145569620253165],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) btnLoadMat_Callback(this,hObject,eventdata),... +'Tag','btnLoadMat',... +'FontWeight','bold'); + +h75 = uicontrol(... +'Parent',h71,... +'Units','normalized',... +'String','Calc. influence Mx',... +'Position',[0.35006435006435 0.810126582278481 0.178893178893179 0.145569620253165],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) btnCalcDose_Callback(this,hObject,eventdata),... +'Tag','btnCalcDose',... +'FontWeight','bold'); + +h76 = uicontrol(... +'Parent',h71,... +'Units','normalized',... +'String','Optimize',... +'Position',[0.544401544401541 0.810126582278481 0.178893178893179 0.145569620253165],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) btnOptimize_Callback(this,hObject,eventdata),... +'Tag','btnOptimize',... +'FontWeight','bold'); + +h77 = uicontrol(... +'Parent',h71,... +'Units','normalized',... +'String','Load DICOM',... +'Position',[0.151866151866152 0.60126582278481 0.177606177606178 0.145569620253165],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) btnLoadDicom_Callback(this,hObject,eventdata),... +'Tag','btnLoadDicom',... +'FontWeight','bold' ); + +h78 = uicontrol(... +'Parent',h71,... +'Units','normalized',... +'String','Refresh',... +'Position',[0.0154440154440154 0.810126582278481 0.0849420849420849 0.145569620253165],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) btnRefresh_Callback(this,hObject,eventdata),... +'Tag','btnRefresh',... +'FontWeight','bold' ); + +h79 = uicontrol(... +'Parent',h71,... +'Units','normalized',... +'String','Recalc',... +'Position',[0.543114543114543 0.60126582278481 0.178893178893179 0.145569620253165],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) pushbutton_recalc_Callback(this,hObject,eventdata),... +'Tag','pushbutton_recalc',... +'FontWeight','bold' ); + +h80 = uicontrol(... +'Parent',h71,... +'Units','normalized',... +'String','Save to GUI',... +'Position',[0.738738738738737 0.810126582278481 0.178893178893179 0.145569620253165],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) btnSaveToGUI_Callback(this,hObject,eventdata),... +'Tag','btnSaveToGUI',... +'FontWeight','bold'); + + +h81 = uicontrol(... +'Parent',h71,... +'Units','normalized',... +'String','Export',... +'Position',[0.74002574002574 0.60126582278481 0.178893178893179 0.145569620253165],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) btn_export_Callback(this,hObject,eventdata),... +'Children',[],... +'Tag','btn_export',... +'FontWeight','bold'); + +h82 = uicontrol(... +'Parent',h71,... +'Units','normalized',... +'String','Import Dose',... +'Position',[0.738738738738738 0.392405063291139 0.178893178893179 0.145569620253165],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) importDoseButton_Callback(this, hObject,eventdata),... +'Tag','importDoseButton',... +'FontWeight','bold' ); + +h83 = uicontrol(... +'Parent',h71,... +'Units','normalized',... +'String','Import from Binary',... +'Position',[0.151866151866152 0.392405063291139 0.177606177606178 0.145569620253165],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) pushbutton_importFromBinary_Callback(this,hObject,eventdata),... +'TooltipString','Imports a patient data set from binary datafiles describing CT and segmentations',... +'Tag','pushbutton_importFromBinary',... +'FontWeight','bold'); + +h84 = uicontrol(... +'Parent',h1,... +'Units','normalized',... +'String','min value:',... +'Style','text',... +'Position',[0.899701069855255 0.87145643693108 0.0420862177470107 0.0253576072821847],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','text24',... +'FontSize',10,... +'FontWeight','bold'); + +h85 = uicontrol(... +'Parent',h1,... +'Units','normalized',... +'String','Set IsoDose Levels',... +'Position',[0.910792951541851 0.814995131450828 0.071035242290749 0.0223953261927945],... +'BackgroundColor',[0.8 0.8 0.8],... +'Callback',@(hObject,eventdata) btnSetIsoDoseLevels_Callback(this,hObject,eventdata),... +'Tag','btnSetIsoDoseLevels'); + +h86 = uipanel(... +'Parent',h1,... +'Title','Structure Visibilty',... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','uipanel10',... +'Clipping','off',... +'Position',[0.896397105097545 0.175812743823147 0.0991189427312775 0.304291287386216],... +'FontWeight','bold'); + +h87 = uicontrol(... +'Parent',h86,... +'Units','normalized',... +'Style','listbox',... +'Value',1,... +'Position',[0.02 0.01 0.97 0.98],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Callback',@(hObject,eventdata) legendTable_Callback(this,hObject,eventdata),... +'Tag','legendTable'); + +h88 = uipanel(... +'Parent',h1,... +'Title','Viewing',... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','uipanel11',... +'Clipping','off',... +'Position',[0.437782076079949 0.0460947503201025 0.451321727917473 0.842509603072983],... +'FontWeight','bold'); + + +h89 = axes(... +'Parent',h88,... +'CameraPosition',[0.5 0.5 9.16025403784439],... +'CameraTarget',[0.5 0.5 0.5],... +'CameraViewAngle',6.60861036031192,... +'PlotBoxAspectRatio',[0.946917808219178 1 0.946917808219178],... +'FontName','CMU Serif',... +'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... +'XTick',[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1],... +'XTickLabel',{ '0'; '0.1'; '0.2'; '0.3'; '0.4'; '0.5'; '0.6'; '0.7'; '0.8'; '0.9'; '1' },... +'YTick',[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1],... +'YTickLabel',{ '0'; '0.1'; '0.2'; '0.3'; '0.4'; '0.5'; '0.6'; '0.7'; '0.8'; '0.9'; '1' },... +'Position',[0.0718390804597701 0.0354391371340524 0.902298850574712 0.929121725731895],... +'ActivePositionProperty','position',... +'LooseInset',[0.199881557553276 0.118695547917832 0.146067292058163 0.0809287826712493],... +'FontSize',9.63,... +'SortMethod','childorder',... +'ButtonDownFcn',@(hObject,eventdata)axesFig_ButtonDownFcn(this,hObject,eventdata),... +'Tag','axesFig'); + +h90 = get(h89,'title'); + +set(h90,... +'Parent',h89,... +'Units','data',... +'FontUnits','points',... +'Color',[0 0 0],... +'Position',[0.500000554441759 1.00453467465753 0.5],... +'PositionMode','auto',... +'Interpreter','tex',... +'Rotation',0,... +'RotationMode','auto',... +'FontName','Helvetica',... +'FontSize',10.593,... +'FontAngle','normal',... +'FontWeight','normal',... +'HorizontalAlignment','center',... +'HorizontalAlignmentMode','auto',... +'VerticalAlignment','bottom',... +'VerticalAlignmentMode','auto',... +'EdgeColor','none',... +'LineStyle','-',... +'LineWidth',0.5,... +'BackgroundColor','none',... +'Margin',2,... +'Clipping','off',... +'XLimInclude','on',... +'YLimInclude','on',... +'ZLimInclude','on',... +'Visible','on',... +'HandleVisibility','off',... +'BusyAction','queue',... +'Interruptible','on',... +'HitTest','on',... +'PickableParts','visible'); + +h91 = get(h89,'xlabel'); + +set(h91,... +'Parent',h89,... +'Units','data',... +'FontUnits','points',... +'Color',[0.15 0.15 0.15],... +'Position',[0.500000476837158 -0.0373767115122652 0],... +'PositionMode','auto',... +'Interpreter','tex',... +'Rotation',0,... +'RotationMode','auto',... +'FontName','CMU Serif',... +'FontSize',10.593,... +'FontAngle','normal',... +'FontWeight','normal',... +'HorizontalAlignment','center',... +'HorizontalAlignmentMode','auto',... +'VerticalAlignment','top',... +'VerticalAlignmentMode','auto',... +'EdgeColor','none',... +'LineStyle','-',... +'LineWidth',0.5,... +'BackgroundColor','none',... +'Margin',3,... +'Clipping','off',... +'XLimInclude','on',... +'YLimInclude','on',... +'ZLimInclude','on',... +'Visible','on',... +'HandleVisibility','off',... +'BusyAction','queue',... +'Interruptible','on',... +'HitTest','on',... +'PickableParts','visible'); + +h92 = get(h89,'ylabel'); + +set(h92,... +'Parent',h89,... +'Units','data',... +'FontUnits','points',... +'Color',[0.15 0.15 0.15],... +'Position',[-0.0474647368237942 0.500000476837158 0],... +'PositionMode','auto',... +'Interpreter','tex',... +'Rotation',90,... +'RotationMode','auto',... +'FontName','CMU Serif',... +'FontSize',10.593,... +'FontAngle','normal',... +'FontWeight','normal',... +'HorizontalAlignment','center',... +'HorizontalAlignmentMode','auto',... +'VerticalAlignment','bottom',... +'VerticalAlignmentMode','auto',... +'EdgeColor','none',... +'LineStyle','-',... +'LineWidth',0.5,... +'BackgroundColor','none',... +'Margin',3,... +'Clipping','off',... +'XLimInclude','on',... +'YLimInclude','on',... +'ZLimInclude','on',... +'Visible','on',... +'HandleVisibility','off',... +'BusyAction','queue',... +'Interruptible','on',... +'HitTest','on',... +'PickableParts','visible'); + +h93 = get(h89,'zlabel'); + +set(h93,... +'Parent',h89,... +'Units','data',... +'FontUnits','points',... +'Color',[0.15 0.15 0.15],... +'Position',[0 0 0],... +'PositionMode','auto',... +'Interpreter','tex',... +'Rotation',0,... +'RotationMode','auto',... +'FontName','CMU Serif',... +'FontSize',10,... +'FontAngle','normal',... +'FontWeight','normal',... +'HorizontalAlignment','left',... +'HorizontalAlignmentMode','auto',... +'VerticalAlignment','middle',... +'VerticalAlignmentMode','auto',... +'EdgeColor','none',... +'LineStyle','-',... +'LineWidth',0.5,... +'BackgroundColor','none',... +'Margin',3,... +'Clipping','off',... +'XLimInclude','on',... +'YLimInclude','on',... +'ZLimInclude','on',... +'Visible','off',... +'HandleVisibility','off',... +'BusyAction','queue',... +'Interruptible','on',... +'HitTest','on',... +'PickableParts','visible'); + +h94 = uipanel(... +'Parent',h1,... +'Title','Info',... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','uipanel12',... +'Clipping','off',... +'Position',[0.896276240708709 0.0448143405889885 0.0991189427312775 0.12932138284251],... +'FontWeight','bold'); + + +h95 = uicontrol(... +'Parent',h94,... +'Units','normalized',... +'String','About',... +'Position',[0.238095238095238 0.134831460674157 0.563492063492063 0.280898876404494],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Callback',@(hObject,eventdata) btnAbout_Callback(hObject,eventdata),... +'Tag','btnAbout',... +'FontSize',7,... +'FontWeight','bold' ); + +h96 = uicontrol(... +'Parent',h94,... +'Units','normalized',... +'String','v3.0.0',... +'Style','text',... +'Position',[0.227106227106227 0.752808988764045 0.523809523809524 0.191011235955056],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','text15',... +'FontWeight','bold'); + +h97 = uicontrol(... +'Parent',h94,... +'Units','normalized',... +'String','github.com/e0404/matRad',... +'Style','text',... +'Position',[0.0384615384615385 0.528089887640449 0.942307692307693 0.168539325842697],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','text31',... +'FontWeight','bold' ); + +h98 = uipanel(... +'Parent',h1,... +'Title','Viewer Options',... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','uipanel_colormapOptions',... +'Clipping','off',... +'Position',[0.896397105097545 0.484330299089727 0.0991189427312775 0.318660598179457],... +'FontWeight','bold'); + +h99 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'HorizontalAlignment','left',... +'String','Window Center:',... +'Style','text',... +'Position',[0.0466666666666666 0.682461750109027 0.673333333333333 0.0699999999999998],... +'Tag','text_windowCenter'); + +h100 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'HorizontalAlignment','left',... +'String','Dose opacity:',... +'Style','text',... +'Position',[0.0466666666666667 0.0706370831711431 0.847328244274809 0.0714285714285714],... +'Tag','textDoseOpacity' ); + +h101 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'String',{ 'None'; 'CT (ED)'; 'Dose' },... +'Style','popupmenu',... +'Value',1,... +'Position',[0.0486486486486487 0.899328859060403 0.940540540540541 0.11744966442953],... +'BackgroundColor',[1 1 1],... +'Callback',@(hObject,eventdata) popupmenu_chooseColorData_Callback(this,hObject,eventdata),... +'Tag','popupmenu_chooseColorData'); + +h102 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'SliderStep',[0.01 0.05],... +'String','slider',... +'Style','slider',... +'Value',0.5,... +'Position',[0.0432432432432432 0.63758389261745 0.697297297297297 0.0536912751677853],... +'BackgroundColor',[0.9 0.9 0.9],... +'Callback',@(hObject,eventdata) slider_windowCenter_Callback(this,hObject,eventdata),... +'Tag','slider_windowCenter'); + +h103 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'HorizontalAlignment','left',... +'String','Window Width:',... +'Style','text',... +'Position',[0.0466666666666667 0.545761302394105 0.673333333333333 0.0700000000000001],... +'Tag','text_windowWidth'); + +h104 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'String','Choose Colormap...',... +'Style','popupmenu',... +'Value',1,... +'Position',[0.0362903225806452 0.278843516266481 0.939516129032258 0.0844686648501362],... +'BackgroundColor',[1 1 1],... +'Callback',@(hObject,eventdata) popupmenu_chooseColormap_Callback(this,hObject,eventdata),... +'Tag','popupmenu_chooseColormap'); + +h105 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'HorizontalAlignment','left',... +'String','Range:',... +'Style','text',... +'Position',[0.0403225806451613 0.387807911050966 0.274193548387097 0.0708446866485015],... +'Tag','text_windowRange'); + + +h106 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'String','0 1',... +'Style','edit',... +'Position',[0.323863636363636 0.399846781328902 0.653409090909091 0.0707395498392283],... +'BackgroundColor',[1 1 1],... +'Callback',@(hObject,eventdata)edit_windowRange_Callback(this,hObject,eventdata),... +'Tag','edit_windowRange'); + +h107 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'String','0.5',... +'Style','edit',... +'Value',1,... +'Position',[0.767567567567568 0.63758389261745 0.205405405405405 0.0704697986577181],... +'BackgroundColor',[1 1 1],... +'Callback',@(hObject,eventdata) edit_windowCenter_Callback(this,hObject,eventdata),... +'Tag','edit_windowCenter'); + +h108 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'String','1.0',... +'Style','edit',... +'Position',[0.772727272727273 0.518256759964609 0.204545454545455 0.0707395498392284],... +'BackgroundColor',[1 1 1],... +'Callback',@(hObject,eventdata)edit_windowWidth_Callback(this,hObject,eventdata),... +'Tag','edit_windowWidth'); + +h109 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'SliderStep',[0.01 0.05],... +'String','slider',... +'Style','slider',... +'Value',0.6,... +'Position',[0.147727272727273 0.0257234726688103 0.75 0.0546623794212219],... +'BackgroundColor',[0.9 0.9 0.9],... +'Callback',@(hObject,eventdata) sliderOpacity_Callback(this,hObject,eventdata),... +'Tag','sliderOpacity'); + +h110 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'HorizontalAlignment','left',... +'String','0',... +'Style','text',... +'Position',[0.0466666666666666 0.00599285798906697 0.0810810810810811 0.072463768115942],... +'Tag','txtDoseOpacity0Indicator',... +'FontName','Helvetica'); + +h111 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'HorizontalAlignment','right',... +'String','1',... +'Style','text',... +'Position',[0.8963482566536 0.00864864051690258 0.0810810810810811 0.072463768115942],... +'Tag','txtDoseOpacity1Indicator' ); + +h112 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'HorizontalAlignment','left',... +'String','Window Presets N/A',... +'Style','text',... +'Position',[0.0540540540540541 0.842281879194631 0.697297297297297 0.0704697986577181],... +'Tag','text_windowPreset' ); + +h113 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'String',{'Custom'; 'Full'; 'Abd/Med'; 'Head'; 'Liver'; 'Lung'; 'Spine'; 'Vrt/Bone' },... +'Style','popupmenu',... +'Value',1,... +'Position',[0.0486486486486487 0.73489932885906 0.940540540540541 0.11744966442953],... +'BackgroundColor',[1 1 1],... +'Callback',@(hObject,eventdata) popupmenu_windowPreset_Callback(this,hObject,eventdata),... +'Visible','off',... +'Tag','popupmenu_windowPreset'); + +h114 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'SliderStep',[0.01 0.05],... +'String','slider',... +'Style','slider',... +'Value',1,... +'Position',[0.0454545454545455 0.51140507995425 0.698863636363636 0.0546623794212219],... +'BackgroundColor',[0.9 0.9 0.9],... +'Callback',@(hObject,eventdata) slider_windowWidth_Callback(this,hObject,eventdata),... +'Tag','slider_windowWidth'); + +h115 = uicontrol(... +'Parent',h98,... +'Units','normalized',... +'String','Lock Settings',... +'Style','checkbox',... +'Position',[0.0486486486486487 0.151006711409396 0.940540540540541 0.0838926174496644],... +'BackgroundColor',[0.502 0.502 0.502],... +'Callback',@(hObject,eventdata) checkbox_lockColormap_Callback(this,hObject,eventdata),... +'Tag','checkbox_lockColormap' ); + +h116 = uicontrol(... +'Parent',h1,... +'Units','normalized',... +'String','max value:',... +'Style','text',... +'Position',[0.901903713027061 0.85370611183355 0.0420862177470107 0.0245123537061118],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','text39',... +'FontSize',10,... +'FontWeight','bold' ); + +h117 = uicontrol(... +'Parent',h1,... +'Units','normalized',... +'String','-',... +'Style','text',... +'Position',[0.955789804908748 0.879908972691808 0.0271397105097546 0.0160598179453836],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtMinVal',... +'FontSize',10,... +'FontWeight','bold' ); + +h118 = uicontrol(... +'Parent',h1,... +'Units','normalized',... +'String','-',... +'Style','text',... +'Position',[0.955789804908748 0.863003901170351 0.0271397105097546 0.0177503250975293],... +'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... +'Tag','txtMaxVal',... +'FontSize',10,... +'FontWeight','bold'); + +this.createHandles(); + + +end + diff --git a/gui/matRad_InfoWidget.m b/gui/matRad_InfoWidget.m new file mode 100644 index 000000000..a99b6ea36 --- /dev/null +++ b/gui/matRad_InfoWidget.m @@ -0,0 +1,74 @@ +classdef matRad_InfoWidget < matRad_Widget + + properties + + end + + methods + function this = matRad_InfoWidget(handleParent) + if nargin < 1 + handleParent = figure(... + 'Units','characters',... + 'Position',[138.4 -7.38461538461539 273.4 59.5384615384615],... + 'Visible','on',... + 'Color',[0.501960784313725 0.501960784313725 0.501960784313725],... 'CloseRequestFcn',@(hObject,eventdata) figure1_CloseRequestFcn(this,hObject,eventdata),... + 'IntegerHandle','off',... + 'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... + 'MenuBar','none',... + 'Name','matRadGUI',... + 'NumberTitle','off',... + 'HandleVisibility','callback',... + 'Tag','figure1',... + 'PaperSize',[20.99999864 29.69999902]); + + end + this = this@matRad_Widget(handleParent); + end + end + + methods (Access = protected) + function this = createLayout(this) + h94 = this.widgetHandle; + + h95 = uicontrol(... + 'Parent',h94,... + 'Units','normalized',... + 'String','About',... + 'Position',[0.238095238095238 0.134831460674157 0.563492063492063 0.280898876404494],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Callback',@(hObject,eventdata) btnAbout_Callback(hObject,eventdata),... + 'Tag','btnAbout',... + 'FontSize',7,... + 'FontWeight','bold' ); + + h96 = uicontrol(... + 'Parent',h94,... + 'Units','normalized',... + 'String','v3.0.0',... + 'Style','text',... + 'Position',[0.227106227106227 0.752808988764045 0.523809523809524 0.191011235955056],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','text15',... + 'FontWeight','bold'); + + h97 = uicontrol(... + 'Parent',h94,... + 'Units','normalized',... + 'String','github.com/e0404/matRad',... + 'Style','text',... + 'Position',[0.0384615384615385 0.528089887640449 0.942307692307693 0.168539325842697],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','text31',... + 'FontWeight','bold' ); + end + end + + methods (Access = protected) + + function btnAbout_Callback(this, hObject, event) + handles = this.handles; + msgbox({'https://github.com/e0404/matRad/' 'email: matrad@dkfz.de'},'About'); + this.handles = handles; + end + end +end diff --git a/gui/matRad_LogoWidget.m b/gui/matRad_LogoWidget.m new file mode 100644 index 000000000..194d58cd8 --- /dev/null +++ b/gui/matRad_LogoWidget.m @@ -0,0 +1,384 @@ +classdef matRad_LogoWidget < matRad_Widget + + properties + + end + + methods + function this = matRad_LogoWidget(handleParent) + if nargin < 1 + handleParent = figure(... + 'PaperUnits','inches',... + 'MenuBar','none',... + 'Units','characters',... + 'Position',[135.8 56.7692307692308 89.2 18.3846153846154],... + 'Color',[0.5 0.5 0.5],... + 'Name','LogoWidget',... + 'HandleVisibility','callback',... + 'Tag','figure_importDialog',... + 'WindowStyle','normal',... + 'PaperSize',[8.5 11],... + 'PaperType','usletter'); + end + this = this@matRad_Widget(handleParent); + end + + + end + + methods (Access = protected) + function this = createLayout(this) + mfile = which(mfilename); + [filepath] = fileparts(mfile); + + h1 = this.widgetHandle; + + + h2 = axes(... + 'Parent',h1,... + 'CameraPosition',[0.5 0.5 9.16025403784439],... + 'CameraTarget',[0.5 0.5 0.5],... + 'CameraViewAngle',6.60861036031192,... + 'PlotBoxAspectRatio',[1 0.305555555555556 0.305555555555556],... + 'FontName','CMU Serif',... + 'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... + 'XTick',[0 0.2 0.4 0.6 0.8 1],... + 'XTickLabel',{ '0'; '0.2'; '0.4'; '0.6'; '0.8'; '1' },... + 'YTick',[0 0.5 1],... + 'YTickLabel',{ '0'; '0.5'; '1' },... + 'Position',[- 0.304874274661509 -0.12225992317542 0.994397163120567 1.048719590268886],... + 'ActivePositionProperty','position',... + 'LooseInset',[0.182759687929063 0.112926163636008 0.133555156563546 0.0769951115700055],... + 'FontSize',9.63,... + 'SortMethod','childorder',... + 'Tag','axesLogo'); + + + + [im, ~, alpha] = imread([filepath filesep '..' filesep 'gfx' filesep 'matrad_logo.png']); + f = image(im,'Parent',h2); + axis(h2,'equal','off'); + set(f, 'AlphaData', alpha); + + %{ + h3 = get(h2,'title'); + + set(h3,... + 'Parent',h2,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0 0 0],... + 'Position',[0.500002781550089 1.03439285714286 0.500000000000007],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','CMU Serif',... + 'FontSize',10.593,... + 'FontAngle','normal',... + 'FontWeight','bold',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','bottom',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + + h4 = get(h2,'xlabel'); + + set(h4,... + 'Parent',h2,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[0.500000476837158 -0.283480513287831 7.105427357601e-15],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','CMU Serif',... + 'FontSize',10.593,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','top',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + + h5 = get(h2,'ylabel'); + + set(h5,... + 'Parent',h2,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[-0.104158728029993 0.500000476837158 7.105427357601e-15],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',90,... + 'RotationMode','auto',... + 'FontName','CMU Serif',... + 'FontSize',10.593,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','bottom',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + + h6 = get(h2,'zlabel'); + + set(h6,... + 'Parent',h2,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[0 0 0],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','CMU Serif',... + 'FontSize',10,... + 'HorizontalAlignment','left',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','middle',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','off',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + %} + + h7 = axes(... + 'Parent',h1,... + 'CameraPosition',[0.5 0.5 9.16025403784439],... + 'CameraTarget',[0.5 0.5 0.5],... + 'CameraViewAngle',6.60861036031192,... + 'PlotBoxAspectRatio',[1 0.155367231638418 0.155367231638418],... + 'FontName','CMU Serif',... + 'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... + 'XTick',[0 0.2 0.4 0.6 0.8 1],... + 'XTickLabel',{ '0'; '0.2'; '0.4'; '0.6'; '0.8'; '1' },... + 'YTick',[0 0.5 1],... + 'YTickLabel',{ '0'; '0.5'; '1' },... + 'Position',[0.29482269503546 0.053969270166453 0.799187620889749 0.6017029449423816],... + 'ActivePositionProperty','position',... + 'LooseInset',[0.13 0.11 0.0950000000000001 0.0749999999999999],... + 'FontSize',9.63,... + 'SortMethod','childorder',... + 'Tag','axesDKFZ'); + + + [im, ~, alpha] = imread([filepath filesep '..' filesep 'gfx' filesep 'DKFZ_Logo.png']); + f = image(im,'Parent',h7); + axis(h7,'equal','off'); + set(f, 'AlphaData', alpha); + + + %{ + h8 = get(h7,'title'); + + set(h8,... + 'Parent',h7,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0 0 0],... + 'Position',[0.500002882574911 1.04815 0.5],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','CMU Serif',... + 'FontSize',10.593,... + 'FontAngle','normal',... + 'FontWeight','bold',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','bottom',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + + h9 = get(h7,'xlabel'); + + set(h9,... + 'Parent',h7,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[0.500000476837158 -0.396872718602964 0],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','CMU Serif',... + 'FontSize',10.593,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','top',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + + h10 = get(h7,'ylabel'); + + set(h10,... + 'Parent',h7,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[-0.074146891139995 0.500000476837156 0],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',90,... + 'RotationMode','auto',... + 'FontName','CMU Serif',... + 'FontSize',10.593,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','bottom',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + + h11 = get(h7,'zlabel'); + + set(h11,... + 'Parent',h7,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[0 0 0],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','CMU Serif',... + 'FontSize',10,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','left',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','middle',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','off',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + %} + end + end + + % NO CALLBACKS +end + + diff --git a/gui/matRad_MainGUI.m b/gui/matRad_MainGUI.m new file mode 100644 index 000000000..e9f63fbf3 --- /dev/null +++ b/gui/matRad_MainGUI.m @@ -0,0 +1,312 @@ +classdef matRad_MainGUI + + properties + guiHandle + end + + properties (Access = private) + LogoWidget + WorkflowWidget + PlanWidget + OptimizationWidget + VisualizationWidget + ViewerOptionsWidget + StructureVisibilityWidget + InfoWidget + ViewingWidget + + eventListeners + end + + + + methods(Access = protected) + function this = createMenuBar(this) + % h1 = widgethandle; + h1 = this.guiHandle; + load('matRad_iconsGUI.mat'); + + h60 = uitoolbar(... + 'Parent',h1,... + 'Tag','uitoolbar1'); + + h61 = uipushtool(... + 'Parent',h60,... + 'Children',[],... + 'BusyAction','cancel',... + 'Interruptible','off',... + 'Tag','toolbarLoad',... + 'CData',icons{1},... + 'ClickedCallback',@(hObject,eventdata) toolbarLoad_ClickedCallback(this,hObject,eventdata),... + 'Separator','on',... + 'TooltipString','Open File' ); + + h62 = uipushtool(... + 'Parent',h60,... + 'BusyAction','cancel',... + 'Interruptible','off',... + 'Tag','toolbarSave',... + 'CData',icons{2},... + 'ClickedCallback',@(hObject,eventdata) toolbarSave_ClickedCallback(this,hObject,eventdata),... + 'Separator','on',... + 'TooltipString','Save Figure'); + + + h63 = uipushtool(... + 'Parent',h60,... + 'Tag','uipushtool_screenshot',... + 'CData',icons{3},... + 'ClickedCallback',@(hObject,eventdata)uipushtool_screenshot_ClickedCallback(this, hObject, eventdata),... + 'TooltipString','Take a screenshot of the current dose or profile plot' ); + + h64 = uitoggletool(... + 'Parent',h60,... + 'Tag','toolbarZoomIn',... + 'CData',icons{4},... + 'Separator','on',... + 'TooltipString','Zoom In'); + + h65 = uitoggletool(... + 'Parent',h60,... + 'Children',[],... + 'Tag','toolbarZoomOut',... + 'CData',icons{5},... + 'Separator','on',... + 'TooltipString','Zoom Out'); + + h66 = uitoggletool(... + 'Parent',h60,... + 'Tag','toolbarPan',... + 'CData',icons{6},... + 'Separator','on',... + 'TooltipString','Pan' ); + + h67 = uitoggletool(... + 'Parent',h60,... + 'Tag','toolbarCursor',... + 'CData',icons{7},... + 'Separator','on',... + 'TooltipString','Data Cursor' ); + + h68 = uitoggletool(... + 'Parent',h60,... + 'Tag','toolbarLegend',... + 'CData',icons{8},... + 'Separator','on',... + 'TooltipString','Insert Legend'); + + h69 = uitoggletool(... + 'Parent',h60,... + 'Tag','uitoggletool8',... + 'CData',icons{9},... + 'ClickedCallback',@(hObject, eventdata)uitoggletool8_ClickedCallback(this, hObject, eventdata),... + 'Separator','on',... + 'TooltipString','Insert Colorbar' ); + + end + end + + methods + function obj = matRad_MainGUI() +% obj.guiHandle = figure; + %Panel for Main Widget which contains label and titel etc. + %How to create Pnael which has to be as big as the figure + %itself +% p0 = uipanel(); + + obj.guiHandle = figure(... + 'Units','characters',... + 'Position',[138.4 30.38461538461539 273.4 59.5384615384615],... + 'Visible','on',... + 'Color',[0.501960784313725 0.501960784313725 0.501960784313725],... 'CloseRequestFcn',@(hObject,eventdata) figure1_CloseRequestFcn(this,hObject,eventdata),... + 'IntegerHandle','off',... + 'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... + 'MenuBar','none',... + 'Name','matRadGUI',... + 'NumberTitle','off',... + 'HandleVisibility','callback',... + 'Tag','figure1',... + 'PaperSize',[20.99999864 29.69999902]); + + p1 = uipanel(... + 'Parent',obj.guiHandle,... + 'ShadowColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Title','Workflow',... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','uipanel4',... + 'Clipping','off',... + 'Position',[0.00451321727917473 0.810499359795134 0.430045132172792 0.170294494238156],... + 'FontName','Helvetica',... + 'FontWeight','bold' ); + + p2 = uipanel(... + 'Parent',obj.guiHandle,... + 'Title','Plan',... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','uipanel1',... + 'Clipping','off',... + 'Position',[0.00451321727917473 0.527528809218956 0.430689877498388 0.272727272727273],... + 'FontName','Helvetica',... + 'FontWeight','bold'); + + p3 = uipanel(... + 'Parent',obj.guiHandle,... + 'Title',strtrim(strjoin({ 'Objectives & constraints'; ' '; ' ' })),... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','uipanel3',... + 'Clipping','off',... + 'Position',[0.00451321727917473 0.257362355953905 0.430689877498388 0.259923175416133],... + 'FontName','Helvetica',... + 'FontWeight','bold' ); + + p4 = uipanel(... + 'Parent',obj.guiHandle,... + 'Title',strtrim(strjoin({ 'Visualization'; ' ' })),... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','uipanel2',... + 'Clipping','off',... + 'Position',[0.00451321727917473 0.0460947503201024 0.430689877498388 0.203585147247119],... + 'FontName','Helvetica',... + 'FontWeight','bold'); + + p5 = uipanel(... + 'Parent',obj.guiHandle,... + 'Title','Viewer Options',... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','uipanel_colormapOptions',... + 'Clipping','off',... + 'Position',[0.896397105097545 0.434330299089727 0.0991189427312775 0.456],... + 'FontWeight','bold'); + + p6 = uipanel(... + 'Parent',obj.guiHandle,... + 'Title','Structure Visibilty',... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','uipanel10',... + 'Clipping','off',... + 'Position',[0.896397105097545 0.175812743823147 0.0991189427312775 0.254291287386216],... + 'FontWeight','bold'); + + p7 = uipanel(... + 'Parent',obj.guiHandle,... + 'Title','Info',... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','uipanel12',... + 'Clipping','off',... + 'Position',[0.896276240708709 0.0448143405889885 0.0991189427312775 0.12932138284251],... + 'FontWeight','bold'); + + p8 = uipanel(... + 'Parent',obj.guiHandle,... + 'Title','Viewing',... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','uipanel11',... + 'Clipping','off',... + 'Position',[0.437782076079949 0.0460947503201025 0.451321727917473 0.842509603072983],... + 'FontWeight','bold'); + + p9 = uipanel(... + 'Parent',obj.guiHandle,... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','uipanel13',... + 'Clipping','off',... + 'Position',[0.44 0.89 0.55 0.1],... + 'FontWeight','bold',... + 'HighLightColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'BorderType','none'); + + + obj.WorkflowWidget = matRad_WorkflowWidget(p1); + obj.eventListeners.workflow = addlistener(obj.WorkflowWidget,'workspaceChanged',@(src,hEvent) updateWidgets(obj,src,hEvent)); + + obj.PlanWidget = matRad_PlanWidget(p2); + obj.eventListeners.plan = addlistener(obj.PlanWidget,'workspaceChanged',@(src,hEvent) updateWidgets(obj,src,hEvent)); + + obj.OptimizationWidget = matRad_OptimizationWidget(p3); + obj.eventListeners.optimization = addlistener(obj.OptimizationWidget,'workspaceChanged',@(src,hEvent) updateWidgets(obj,src,hEvent)); + + obj.VisualizationWidget = matRad_VisualizationWidget(p4); + obj.eventListeners.visualization = addlistener(obj.VisualizationWidget,'workspaceChanged',@(src,hEvent) updateWidgets(obj,src,hEvent)); + + obj.ViewerOptionsWidget = matRad_ViewerOptionsWidget(p5); + obj.eventListeners.viewerOptions = addlistener(obj.ViewerOptionsWidget,'workspaceChanged',@(src,hEvent) updateWidgets(obj,src,hEvent)); + + obj.StructureVisibilityWidget = matRad_StructureVisibilityWidget(p6); + obj.eventListeners.structureVisibility = addlistener(obj.StructureVisibilityWidget,'workspaceChanged',@(src,hEvent) updateWidgets(obj,src,hEvent)); + + obj.InfoWidget = matRad_InfoWidget(p7); % does not need a listener + + obj.ViewingWidget = matRad_ViewingWidget(p8); + obj.eventListeners.viewing = addlistener(obj.ViewingWidget,'workspaceChanged',@(src,hEvent) updateWidgets(obj,src,hEvent)); + + obj.LogoWidget = matRad_LogoWidget(p9); % does not need a listener + + obj.createMenuBar(); + + + end + + function this = updateWidgets(this,src,hEvent) + %obj.PlanWidget.update(); + disp('Workspace Changed'); + end + + function matRadGUI_OpeningFcn(this, hObject, event) + %#ok<*DEFNU> + %#ok<*AGROW> + % This function has no output args, see OutputFcn. + % hObject handle to figure + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + % varargin command line arguments to matRadGUI (see VARARGIN) + + % variable to check whether GUI is opened or just refreshed / new data + % loaded, since resetGUI needs to distinguish at one point + handles = this.handles; + + handles.initialGuiStart = true; + + %If devMode is true, error dialogs will include the full stack trace of the error + %If false, only the basic error message is shown (works for errors that + %handle the MException object) + handles.devMode = true; + + set(handles.radiobtnPlan,'value',0); + + handles = resetGUI(hObject, handles); + + %% parse variables from base workspace + AllVarNames = evalin('base','who'); + handles.AllVarNames = AllVarNames; + try + if ismember('ct',AllVarNames) && ismember('cst',AllVarNames) + ct = evalin('base','ct'); + cst = evalin('base','cst'); + %cst = setCstTable(handles,cst); + cst = generateCstTable(handles,cst); + handles.State = 1; + cst = matRad_computeVoiContoursWrapper(cst,ct); + assignin('base','cst',cst); + + elseif ismember('ct',AllVarNames) && ~ismember('cst',AllVarNames) + handles = showError(handles,'GUI OpeningFunc: could not find cst file'); + elseif ~ismember('ct',AllVarNames) && ismember('cst',AllVarNames) + handles = showError(handles,'GUI OpeningFunc: could not find ct file'); + end + catch + handles = showError(handles,'GUI OpeningFunc: Could not load ct and cst file'); + end + + if ismember('ct',AllVarNames) && ismember('cst',AllVarNames) + handles = reloadGUI(hObject, handles, ct, cst); + else + handles = reloadGUI(hObject, handles); + end + + % guidata(hObject, handles); + this.handles = handles; + end + + end +end + diff --git a/gui/matRad_OptimizationWidget.m b/gui/matRad_OptimizationWidget.m new file mode 100644 index 000000000..30a2ce246 --- /dev/null +++ b/gui/matRad_OptimizationWidget.m @@ -0,0 +1,244 @@ +classdef matRad_OptimizationWidget < matRad_Widget + + properties + + end + + methods + function this = matRad_OptimizationWidget(handleParent) + if nargin < 1 + handleParent = figure(... + 'Units','characters',... + 'Position',[138.4 -7.38461538461539 273.4 59.5384615384615],... + 'Visible','on',... + 'Color',[0.501960784313725 0.501960784313725 0.501960784313725],... 'CloseRequestFcn',@(hObject,eventdata) figure1_CloseRequestFcn(this,hObject,eventdata),... + 'IntegerHandle','off',... + 'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... + 'MenuBar','none',... + 'Name','matRadGUI',... + 'NumberTitle','off',... + 'HandleVisibility','callback',... + 'Tag','figure1',... + 'PaperSize',[20.99999864 29.69999902]); + + end + this = this@matRad_Widget(handleParent); + end + + end + + methods (Access = protected) + function this = createLayout(this) + h1 = this.widgetHandle; + + + end + end + + methods + function cst = generateCstTable(handles,cst) + + handles = this.handles; + + cst = updateStructureTable(handles,cst); + cstPanel = handles.uipanel3; + + cstPanelPos = get(cstPanel,'Position'); + cstPanelPosUnit = get(cstPanel,'Units'); + set(cstPanel,'Units','pixels'); + cstPanelPosPix = get(cstPanel,'Position'); + set(cstPanel,'Units',cstPanelPosUnit); + aspectRatio = cstPanelPosPix(3) / cstPanelPosPix(4); + + %Parameters for line height + objHeight = 0.095;% 22; + lineHeight = 0.1; %25; %Height of a table line + yTopSep = 0.12;%40; %Separation of the first line from the top + %tableViewHeight = cstPanelPos(4) - yTopSep; %Full height of the view + tableViewHeight = 1 - yTopSep; + + %Widths of the fields + buttonW = objHeight / aspectRatio; % Make button squared + nameW = 3.5*buttonW;%60; + typeW = 3*buttonW;%70; + opW = buttonW;%objHeight; + functionW = 6*buttonW;%120; + penaltyW = 2*buttonW;%40; + paramTitleW = 4*buttonW;%120; + paramW = 2*buttonW;%30; + fieldSep = 0.25*buttonW; %Separation between fields horizontally + + %Scrollbar + cstPanelChildren = get(cstPanel,'Children'); + cstVertTableScroll = findobj(cstPanelChildren,'Style','slider'); + if isempty(cstVertTableScroll) + sliderPos = 0; + else + sliderPos = get(cstVertTableScroll,'Max') - get(cstVertTableScroll,'Value'); + end + %disp(num2str(sliderPos)); + ypos = @(c) tableViewHeight - c*lineHeight + sliderPos; + + delete(cstPanelChildren); + + %Creates a dummy axis to allow for the use of textboxes instead of uicontrol to be able to use the (la)tex interpreter + tmpAxes = axes('Parent',cstPanel,'units','normalized','position',[0 0 1 1],'visible','off'); + + organTypes = {'OAR', 'TARGET'}; + + %columnname = {'VOI name','VOI type','priority','obj. / const.'};%,'penalty','dose', 'EUD','volume','robustness'}; + + %Get all Classes & classNames + classNames = matRad_getObjectivesAndConstraints(); + % Collect Class-File & Display Names + %classNames = {classList.Name; p.DefaultValue}; + + %columnformat = {cst(:,2)',{'OAR','TARGET'},'numeric',... + % AllObjectiveFunction,... + % 'numeric','numeric','numeric','numeric',{'none','WC','prob'}}; + + numOfObjectives = 0; + for i = 1:size(cst,1) + if ~isempty(cst{i,6}) + numOfObjectives = numOfObjectives + numel(cst{i,6}); + end + end + + cnt = 0; + + newline = '\n'; + + %Setup Headlines + xPos = 0.01; %5 + + h = uicontrol(cstPanel,'Style','text','String','+/-','Units','normalized','Position',[xPos ypos(cnt) buttonW objHeight],'TooltipString','Remove or add Constraint or Objective'); + tmp_pos = get(h,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + h = uicontrol(cstPanel,'Style','text','String','VOI name','Units','normalized','Position',[xPos ypos(cnt) nameW objHeight],'TooltipString','Name of the structure with objective/constraint'); + tmp_pos = get(h,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + h = uicontrol(cstPanel,'Style','text','String','VOI type','Units','normalized','Position',[xPos ypos(cnt) typeW objHeight],'TooltipString','Segmentation Classification'); + tmp_pos = get(h,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + h = uicontrol(cstPanel,'Style','text','String','OP','Units','normalized','Position',[xPos ypos(cnt) opW objHeight],'TooltipString',['Overlap Priority' char(10) '(Smaller number overlaps higher number)']); + tmp_pos = get(h,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + h = uicontrol(cstPanel,'Style','text','String','Function','Units','normalized','Position',[xPos ypos(cnt) functionW objHeight],'TooltipString','Objective/Constraint function type'); + tmp_pos = get(h,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + h = uicontrol(cstPanel,'Style','text','String','p','Units','normalized','Position',[xPos ypos(cnt) penaltyW objHeight],'TooltipString','Optimization penalty'); + tmp_pos = get(h,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + h = uicontrol(cstPanel,'Style','text','String','| Parameters','Units','normalized','Position',[xPos ypos(cnt) paramTitleW objHeight],'TooltipString','List of parameters','HorizontalAlignment','left'); + tmp_pos = get(h,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + cnt = cnt + 1; + + %Create Objectives / Constraints controls + for i = 1:size(cst,1) + if strcmp(cst(i,3),'IGNORED')~=1 + %Compatibility Layer for old objective format + if isstruct(cst{i,6}) + cst{i,6} = num2cell(arrayfun(@matRad_DoseOptimizationFunction.convertOldOptimizationStruct,cst{i,6})); + end + for j=1:numel(cst{i,6}) + + obj = cst{i,6}{j}; + + %Convert to class if not + if ~isa(obj,'matRad_DoseOptimizationFunction') + try + obj = matRad_DoseOptimizationFunction.createInstanceFromStruct(obj); + catch ME + warning('Objective/Constraint not valid!\n%s',ME.message) + continue; + end + end + + %VOI + %data{Counter,1} = cst{i,2}; + %ypos = cstPanelPos(4) - (yTopSep + cnt*lineHeight); + xPos = 0.01;%5; + + %h = uicontrol(cstPanel,'Style','popupmenu','String',cst(:,2)','Position',[xPos ypos 100 objHeight]); + %h.Value = i; + h = uicontrol(cstPanel,'Style','pushbutton','String','-','Units','normalized','Position',[xPos ypos(cnt) buttonW objHeight],'TooltipString','Remove Objective/Constraint','Callback',{@btObjRemove_Callback,handles},... + 'UserData',[i,j]); + tmp_pos = get(h,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + h = uicontrol(cstPanel','Style','edit','String',cst{i,2},'Units','normalized','Position',[xPos ypos(cnt) nameW objHeight],'TooltipString','Name',... + 'Enable','inactive',... %Disable editing of name atm + 'UserData',[i,2],'Callback',{@editCstParams_Callback,handles}); %Callback added, however, editing is disabled atm + tmp_pos = get(h,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + h = uicontrol(cstPanel,'Style','popupmenu','String',organTypes','Value',find(strcmp(cst{i,3},organTypes)),'Units','normalized','Position',[xPos ypos(cnt) typeW objHeight],'TooltipString','Segmentation Classification',... + 'UserData',[i,3],'Callback',{@editCstParams_Callback,handles}); + tmp_pos = get(h,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + h = uicontrol(cstPanel,'Style','edit','String',num2str(cst{i,5}.Priority),'Units','normalized','Position',[xPos ypos(cnt) opW objHeight],'TooltipString',['Overlap Priority' newline '(Smaller number overlaps higher number)'],... + 'UserData',[i,5],'Callback',{@editCstParams_Callback,handles}); + tmp_pos = get(h,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + + h = uicontrol(cstPanel,'Style','popupmenu','String',classNames(2,:)','Value',find(strcmp(obj.name,classNames(2,:))),'Units','normalized','Position',[xPos ypos(cnt) functionW objHeight],'TooltipString','Select Objective/Constraint',... + 'UserData',{[i,j],classNames(1,:)},'Callback',{@changeObjFunction_Callback,handles}); + tmp_pos = get(h,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + + %Check if we have an objective to display penalty + if isa(obj,'DoseObjectives.matRad_DoseObjective') + h = uicontrol(cstPanel,'Style','edit','String',num2str(obj.penalty),'Units','normalized','Position',[xPos ypos(cnt) penaltyW objHeight],'TooltipString','Objective Penalty','UserData',[i,j,0],'Callback',{@editObjParam_Callback,handles}); + else + h = uicontrol(cstPanel,'Style','edit','String','----','Units','normalized','Position',[xPos ypos(cnt) penaltyW objHeight],'Enable','off'); + end + tmp_pos = get(h,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + + for p = 1:numel(obj.parameterNames) + %h = uicontrol(cstPanel,'Style','edit','String',obj.parameters{1,p},'Position',[xPos ypos(cnt) 100 objHeight],'Enable','inactive'); + %xPos = xPos + h.Position(3) + fieldSep; + h = text('Parent',tmpAxes,'String',['| ' obj.parameterNames{p} ':'],'VerticalAlignment','middle','Units','normalized','Position',[xPos ypos(cnt)+lineHeight/2],'Interpreter','tex','FontWeight','normal',... + 'FontSize',get(cstPanel,'FontSize'),'FontName',get(cstPanel,'FontName'),'FontUnits',get(cstPanel,'FontUnits'),'FontWeight','normal');%[xPos ypos(cnt) 100 objHeight]); + tmp_pos = get(h,'Extent'); + xPos = xPos + tmp_pos(3) + fieldSep; + %h = annotation(cstPanel,'textbox','String',obj.parameters{1,p},'Units','pix','Position', [xPos ypos(cnt) 100 objHeight],'Interpreter','Tex'); + + %Check if we have a cell and therefore a parameter list + if iscell(obj.parameterTypes{p}) + h = uicontrol(cstPanel,'Style','popupmenu','String',obj.parameterTypes{p}','Value',obj.parameters{p},'TooltipString',obj.parameterNames{p},'Units','normalized','Position',[xPos ypos(cnt) paramW*2 objHeight],'UserData',[i,j,p],'Callback',{@editObjParam_Callback,handles}); + else + h = uicontrol(cstPanel,'Style','edit','String',num2str(obj.parameters{p}),'TooltipString',obj.parameterNames{p},'Units','normalized','Position',[xPos ypos(cnt) paramW objHeight],'UserData',[i,j,p],'Callback',{@editObjParam_Callback,handles}); + end + + tmp_pos = get(h,'Extent'); + xPos = xPos + tmp_pos(3) + fieldSep; + end + + cnt = cnt +1; + end + end + end + xPos = 0.01; %5 + hAdd = uicontrol(cstPanel,'Style','pushbutton','String','+','Units','normalized','Position',[xPos ypos(cnt) buttonW objHeight],'TooltipString','Add Objective/Constraint','Callback',{@btObjAdd_Callback,handles}); + tmp_pos = get(hAdd,'Position'); + xPos = xPos + tmp_pos(3) + fieldSep; + h = uicontrol(cstPanel,'Style','popupmenu','String',cst(:,2)','Units','normalized','Position',[xPos ypos(cnt) nameW objHeight]); + set(hAdd,'UserData',h); + + %Calculate Scrollbar + lastPos = ypos(cnt); + firstPos = ypos(0); + tableHeight = abs(firstPos - lastPos); + + exceedFac = tableHeight / tableViewHeight; + if exceedFac > 1 + sliderFac = exceedFac - 1; + uicontrol(cstPanel,'Style','slider','Units','normalized','Position',[0.975 0 0.025 1],'Min',0,'Max',ceil(sliderFac)*tableViewHeight,'SliderStep',[lineHeight tableViewHeight] ./ (ceil(sliderFac)*tableViewHeight),'Value',ceil(sliderFac)*tableViewHeight - sliderPos,'Callback',{@cstTableSlider_Callback,handles}); + end + + this.handles = handles; + + end + + end +end diff --git a/gui/matRad_PlanWidget.m b/gui/matRad_PlanWidget.m new file mode 100644 index 000000000..55cdd9244 --- /dev/null +++ b/gui/matRad_PlanWidget.m @@ -0,0 +1,909 @@ +classdef matRad_PlanWidget < matRad_Widget + + properties + State = false + Machines + Optimizations + end + + properties (Constant) + Modalities = {'photons','protons','carbon'}; + % Optimizations = {'none','const_RBExD','LEMIV_effect','LEMIV_RBExD'}; + end + + methods + function this = matRad_PlanWidget(handleParent) + if nargin < 1 + handleParent = figure(... + 'Units','characters',... + 'Position',[138.4 -7.38461538461539 273.4 59.5384615384615],... + 'Visible','on',... + 'Color',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'IntegerHandle','off',... + 'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... + 'MenuBar','none',... + 'Name','matRadGUI',... + 'NumberTitle','off',... + 'HandleVisibility','callback',... + 'Tag','figure1',... + 'PaperSize',[20.99999864 29.69999902]); + + end + this = this@matRad_Widget(handleParent); + end + + function this = initialize(this) + this.update(); + end + + function this = update(this) + if evalin('base','exist(''pln'')') + getPlnFromWorkspace(this); + else + setPlnDefaultValues(); + updatePlnFromWorkspace(); + end + end + + function changeWorkspace(obj) + notify(obj, 'workspaceChanged'); + end + end + + methods(Access = protected) + function this = createLayout(this) + h12 = this.widgetHandle; + + h13 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','bixel width in [mm]',... + 'Style','text',... + 'Position',[0.0347043701799486 0.859315589353612 0.17866323907455 0.0950570342205324],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','txtBixelWidth',... + 'UserData',[],... + 'FontName','Helvetica'); + + h14 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','5',... + 'Style','edit',... + 'Position',[0.219794344473008 0.889733840304182 0.161953727506427 0.0836501901140684],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata) standardCallback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','editBixelWidth',... + 'FontWeight','bold'); + + h15 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','Gantry Angle in °',... + 'Style','text',... + 'Position',[0.032133676092545 0.752851711026616 0.176092544987147 0.0950570342205324],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Children',[],... + 'Tag','txtGantryAngle' ); + + h16 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','0',... + 'Style','edit',... + 'Position',[0.219794344473008 0.779467680608365 0.161953727506427 0.0836501901140684],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata)standardCallback(this,hObject,eventdata),... + 'Tag','editGantryAngle',... + 'FontWeight','bold'); + + h17 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','Couch Angle in °',... + 'Style','text',... + 'Position',[0.0347043701799486 0.64638783269962 0.173521850899743 0.0950570342205324],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','txtCouchAngle'); + + h18 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','0',... + 'Style','edit',... + 'Position',[0.219794344473008 0.669201520912547 0.161953727506427 0.0836501901140685],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata) standardCallback(this,hObject,eventdata),... + 'Tag','editCouchAngle',... + 'FontWeight','bold'); + + h19 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String',this.Modalities,...,... + 'Style','popupmenu',... + 'Value',1,... + 'Position',[0.219794344473008 0.52851711026616 0.161953727506427 0.114068441064639],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata)popupRadMode_Callback(this,hObject,eventdata),... + 'Tag','popupRadMode',... + 'FontWeight','bold'); + + h20 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','Radiation Mode',... + 'Style','text',... + 'Position',[0.051413881748072 0.539923954372624 0.146529562982005 0.0950570342205324],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','txtRadMode'); + + h21 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','# Fractions',... + 'Style','text',... + 'Position',[0.051413881748072 0.209125475285171 0.143958868894602 0.106463878326996],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','txtNumOfFractions'); + + h22 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','30',... + 'Style','edit',... + 'Position',[0.219794344473008 0.228136882129278 0.161953727506427 0.0836501901140684],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata) standardCallback(this,hObject,eventdata),... + 'Tag','editFraction',... + 'FontWeight','bold'); + + h23 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','IsoCenter in [mm]',... + 'Style','text',... + 'Position',[0.0282776349614396 0.330798479087452 0.201799485861183 0.091254752851711],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','txtIsoCenter',... + 'UserData',[],... + 'FontName','Helvetica'); + + h24 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','0 0 0',... + 'Style','edit',... + 'Position',[0.219794344473008 0.338403041825095 0.161953727506427 0.0836501901140684],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata) editIsoCenter_Callback(this,hObject,eventdata),... + 'Children',[],... + 'Enable','off',... + 'Tag','editIsoCenter',... + 'FontWeight','bold'); + + h25 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','Auto.',... + 'Style','checkbox',... + 'Value',1,... + 'Position',[0.38560411311054 0.338403041825095 0.0809768637532133 0.091254752851711],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Callback',@(hObject,eventdata) checkIsoCenter_Callback(this,hObject,eventdata),... + 'Tag','checkIsoCenter'); + + h26 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','Run Sequencing',... + 'Style','radiobutton',... + 'Position',[0.553984575835475 0.628020880324805 0.173521850899743 0.140684410646388],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Callback',@(hObject,eventdata) standardCallback(this,hObject,eventdata),... + 'Enable','on',... + 'Tag','btnRunSequencing'); + + h27 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','Run Direct Aperture Optimization',... + 'Style','radiobutton',... + 'Position',[0.553984575835475 0.32003608945028 0.294344473007712 0.140684410646388],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Callback',@(hObject,eventdata)standardCallback(this,hObject,eventdata),... + 'Enable','on',... + 'Tag','btnRunDAO' ); + + h28 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','Stratification Levels',... + 'Style','text',... + 'Position',[0.553984575835475 0.502545595153702 0.179948586118252 0.102661596958175],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','txtSequencing' ); + + h29 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','7',... + 'Style','edit',... + 'Position',[0.58611825192802 0.449313655990204 0.0668380462724936 0.0836501901140685],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata)editSequencingLevel_Callback(this,hObject,eventdata),... + 'Enable','on',... + 'Tag','editSequencingLevel',... + 'FontWeight','bold'); + + h30 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String',{'Generic','generic_MCsquare'},... + 'Style','popupmenu',... + 'Value',1,... + 'Position',[0.219794344473008 0.418250950570342 0.161953727506427 0.114068441064639],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata) popUpMachine_Callback(this,hObject,eventdata),... + 'Tag','popUpMachine',... + 'FontWeight','bold'); + + h31 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','Machine',... + 'Style','text',... + 'Position',[0.0732647814910026 0.433460076045627 0.106683804627249 0.0950570342205323],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','txtMachine' ); + + h32 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','Set Tissue',... + 'Position',[0.401028277634961 0.110266159695817 0.109254498714653 0.0874524714828897],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) btnSetTissue_Callback(this,hObject,eventdata),... + 'Enable','off',... + 'Tag','btnSetTissue'); + + h33 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String',{ 'none'; 'const_RBExD'; 'LEMIV_effect'; 'LEMIV_RBExD' },... + 'Style','popupmenu',... + 'Value',1,... + 'Position',[0.219794344473008 0.0760456273764259 0.165809768637532 0.11787072243346],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata) popMenuBioOpt_Callback(this,hObject,eventdata),... + 'Tag','popMenuBioOpt',... + 'Enable', 'off',... + 'FontWeight','bold'); + + h34 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','Type of optimization',... + 'Style','text',... + 'Position',[0.0102827763496144 0.0988593155893536 0.201799485861183 0.091254752851711],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Interruptible','off',... + 'Tag','text38',... + 'FontName','Helvetica' ); + + h35 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','Dose Calculation: ',... + 'Style','text',... + 'Position',[0.5332245532245534 0.209125475285171 0.201799485861183 0.091254752851711],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Interruptible','off',... + 'Tag','text39',... + 'FontName','Helvetica' ); + + h36 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','3D conformal',... + 'Style','radiobutton',... + 'Position',[0.553224553224553 0.757869249394673 0.212121212121212 0.0847457627118644],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Callback',@(hObject,eventdata) radiobutton3Dconf_Callback(this,hObject,eventdata),... + 'Enable','on',... + 'Tag','radiobutton3Dconf' ); + + h37 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','x',... + 'Style','edit',... + 'Position',[0.553224553224553 0.0760456273764259 0.09 0.11787072243346],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata) standardCallback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','editDoseX',... + 'FontWeight','bold'); + + h38 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','y',... + 'Style','edit',... + 'Position',[0.653224553224553 0.0760456273764259 0.09 0.11787072243346],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata) standardCallback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','editDoseY',... + 'FontWeight','bold'); + + h39 = uicontrol(... + 'Parent',h12,... + 'Units','normalized',... + 'String','z',... + 'Style','edit',... + 'Position',[0.753224553224553 0.0760456273764259 0.09 0.11787072243346],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata) standardCallback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','editDoseZ',... + 'FontWeight','bold'); + + this.createHandles(); + + end + + function this = setPlnDefaultValues(this) + end + + function this = getPlnFromWorkspace(this) + pln = evalin('base', 'pln'); + handles = this.handles; + + % sanity check of isoCenter + if size(pln.propStf.isoCenter,1) ~= pln.propStf.numOfBeams && size(pln.propStf.isoCenter,1) == 1 + pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1) * pln.propStf.isoCenter(1,:); + elseif size(pln.propStf.isoCenter,1) ~= pln.propStf.numOfBeams && size(pln.propStf.isoCenter,1) ~= 1 + error('Isocenter in plan file are incosistent.'); + end + + set(handles.editBixelWidth,'String',num2str(pln.propStf.bixelWidth)); + set(handles.editGantryAngle,'String',num2str(pln.propStf.gantryAngles)); + set(handles.editCouchAngle,'String',num2str(pln.propStf.couchAngles)); + + modIx = find(strcmp(pln.radiationMode,this.Modalities)); + set(handles.popupRadMode,'Value',modIx); + + getMachines(this); + modIy = find(strcmp(pln.machine,this.Machines{modIx})); + set(handles.popUpMachine,'Value',modIy); + + if isfield(pln.propStf,'isoCenter') + if size(unique(pln.propStf.isoCenter,'rows'),1) == 1 + set(handles.editIsoCenter,'String',regexprep(num2str((round(pln.propStf.isoCenter(1,:)*10))./10), '\s+', ' ')); + set(handles.editIsoCenter,'Enable','on'); + set(handles.checkIsoCenter,'Enable','on'); + else + set(handles.editIsoCenter,'String','multiple isoCenter'); + set(handles.editIsoCenter,'Enable','off'); + set(handles.checkIsoCenter,'Value',0); + set(handles.checkIsoCenter,'Enable','off'); + end + end + + set(handles.editFraction,'String',num2str(pln.numOfFractions)); + + this.switchEnables(); + + contentPopUp = get(handles.popMenuBioOpt,'String'); + ix = find(strcmp(pln.propOpt.bioOptimization,contentPopUp)); + set(handles.popMenuBioOpt,'Value',ix); + + + %set(handles.popMenuBioOpt,'String',num2str(pln.propOpt.bioOptimization)); + + set(handles.btnRunSequencing,'Value',pln.propOpt.runSequencing); + set(handles.btnRunDAO,'Value',pln.propOpt.runDAO); + + set(handles.editDoseX,'String',num2str(pln.propDoseCalc.doseGrid.resolution.x)); + set(handles.editDoseY,'String',num2str(pln.propDoseCalc.doseGrid.resolution.y)); + set(handles.editDoseZ,'String',num2str(pln.propDoseCalc.doseGrid.resolution.z)); + + + end + + %Update the workspace pln from the Widget + function updatePlnInWorkspace(this,handles) + this.getMachines(); + handles = this.handles; + + % evalin pln (if existant) in order to decide whether isoCenter should be calculated + % automatically + if evalin('base','exist(''pln'',''var'')') + pln = evalin('base','pln'); + end + + pln.propStf.bixelWidth = this.parseStringAsNum(get(handles.editBixelWidth,'String'),false); % [mm] / also corresponds to lateral spot spacing for particles + pln.propStf.gantryAngles = this.parseStringAsNum(get(handles.editGantryAngle,'String'),true); % [???] + pln.propStf.couchAngles = this.parseStringAsNum(get(handles.editCouchAngle,'String'),true); % [???] + pln.propStf.numOfBeams = numel(pln.propStf.gantryAngles); + pln.propStf.isoCenter = this.parseStringAsNum(get(handles.editIsoCenter,'String'),true); + + % switch machines depending on radmode selection + selectedMachine = get(handles.popUpMachine,'Value'); + popupMachines = get(handles.popUpMachine,'String'); + pln.machine = popupMachines{selectedMachine}; + + % switch optimization depending on radmode selection +% if get(handles.popupRadMode,'Value') == 1 | get(handles.popupRadMode,'Value') == 3 +% set(handles.popMenuBioOpt,'Value',1); +% selectedOpt = get(handles.popMenuBioOpt,'Value'); +% bioOptis = get(handles.popMenuBioOpt,'String'); +% pln.propOpt.bioOptimization = bioOptis{selectedOpt}; +% +% elseif get(handles.popupRadMode,'Value') == 2 +% +% selectedOpt = get(handles.popMenuBioOpt,'Value'); +% bioOptis = get(handles.popMenuBioOpt,'String'); +% pln.propOpt.bioOptimization = bioOptis{selectedOpt}; +% end +% + pln.numOfFractions = this.parseStringAsNum(get(handles.editFraction,'String'),false); + pln.propOpt.runSequencing = this.parseStringAsNum(get(handles.btnRunSequencing,'Value'),false); + pln.propOpt.runDAO = this.parseStringAsNum(get(handles.btnRunDAO,'Value'),false); + + %Dose Grid resolution + pln.propDoseCalc.doseGrid.resolution.x = this.parseStringAsNum(get(handles.editDoseX,'String'),false); + pln.propDoseCalc.doseGrid.resolution.y = this.parseStringAsNum(get(handles.editDoseY,'String'),false); + pln.propDoseCalc.doseGrid.resolution.z = this.parseStringAsNum(get(handles.editDoseZ,'String'),false); + + + try + ct = evalin('base','ct'); + pln.numOfVoxels = prod(ct.cubeDim); + pln.voxelDimensions = ct.cubeDim; + catch + end + pln.numOfFractions = this.parseStringAsNum(get(handles.editFraction,'String'),false); + contents = get(handles.popupRadMode,'String'); + pln.radiationMode = contents{get(handles.popupRadMode,'Value')}; % either photons / protons / carbon + contents = get(handles.popUpMachine,'String'); + + if (~strcmp(pln.radiationMode,'photons')) + contentBioOpt = get(handles.popMenuBioOpt,'String'); + pln.propOpt.bioOptimization = contentBioOpt{get(handles.popMenuBioOpt,'Value'),:}; + else + pln.propOpt.bioOptimization = 'none'; + end + + pln.propOpt.runSequencing = logical(get(handles.btnRunSequencing,'Value')); + pln.propOpt.runDAO = logical(get(handles.btnRunDAO,'Value')); + + try + cst = evalin('base','cst'); + if (sum(strcmp('TARGET',cst(:,3))) > 0 && get(handles.checkIsoCenter,'Value')) || ... + (sum(strcmp('TARGET',cst(:,3))) > 0 && ~isfield(pln.propStf,'isoCenter')) + pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1) * matRad_getIsoCenter(cst,ct); + set(handles.checkIsoCenter,'Value',1); + else + if ~strcmp(get(handles.editIsoCenter,'String'),'multiple isoCenter') + pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1) * str2num(get(handles.editIsoCenter,'String')); + end + end + catch + warning('couldnt set isocenter in getPln function') + end + + this.switchEnables(); + + handles.pln = pln; + assignin('base','pln',pln); + this.handles = handles; + notify(this,'workspaceChanged'); + end + end + + methods(Access = private) + function standardCallback(this, hObject, eventdata) + handles = this.handles; + updatePlnInWorkspace(this); + + this.handles = handles; + end + + function switchEnables(this) + handles = this.handles; + hObject = handles.popupRadMode; + + contents = cellstr(get(hObject,'String')); + RadIdentifier = contents{get(hObject,'Value')}; + contentPopUp = get(handles.popMenuBioOpt,'String'); + + switch RadIdentifier + case 'photons' + + set(handles.popMenuBioOpt,'Enable','off'); + ix = find(strcmp(contentPopUp,'none')); + set(handles.popMenuBioOpt,'Value',ix); + set(handles.btnSetTissue,'Enable','off'); + + set(handles.btnRunSequencing,'Enable','on'); + set(handles.btnRunDAO,'Enable','on'); + set(handles.radiobutton3Dconf,'Enable','on'); + set(handles.txtSequencing,'Enable','on'); + set(handles.editSequencingLevel,'Enable','on'); + + case 'protons' + set(handles.popMenuBioOpt,'Enable','on'); + %ix = find(strcmp(contentPopUp,'const_RBExD')); + %set(handles.popMenuBioOpt,'Value',ix); + set(handles.btnSetTissue,'Enable','on'); + + set(handles.btnRunSequencing,'Enable','off'); + set(handles.btnRunDAO,'Enable','off'); + set(handles.radiobutton3Dconf,'Enable','off'); + set(handles.txtSequencing,'Enable','off'); + set(handles.editSequencingLevel,'Enable','off'); + + case 'carbon' + + set(handles.popMenuBioOpt,'Enable','on'); + %ix = find(strcmp(contentPopUp,'LEMIV_RBExD')); + %set(handles.popMenuBioOpt,'Value',ix); + set(handles.btnSetTissue,'Enable','on'); + + set(handles.btnRunSequencing,'Enable','off'); + set(handles.btnRunDAO,'Enable','off'); + set(handles.radiobutton3Dconf,'Enable','off'); + set(handles.txtSequencing,'Enable','off'); + set(handles.editSequencingLevel,'Enable','off'); + end + + selectedBioOpt = get(handles.popMenuBioOpt,'Value'); + contentPopUp = get(handles.popMenuBioOpt,'String'); + if strcmp(contentPopUp{selectedBioOpt},'none') + set(handles.btnSetTissue,'Enable','off'); + else + set(handles.btnSetTissue,'Enable','on'); + end + end + + function manageRadModeSpecificDisplay(this) + handles = this.handles; + hObject = this.popupRadMode('hObject'); + + end + + function popupRadMode_Callback(this, hObject, eventdata) + % hObject handle to popupRadMode (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + handles = this.handles; + +% checkRadiationComposition(this); ...checkRadiationComposition(handles); + contents = cellstr(get(hObject,'String')); + RadIdentifier = contents{get(hObject,'Value')}; + contentPopUp = get(handles.popMenuBioOpt,'String'); + + % switchcase depending on RadMode + %switchEnables(this); + + pln = evalin('base','pln'); + + % new radiation modality is photons -> just keep physicalDose + if strcmp(contents(get(hObject,'Value')),'photons') + try + AllVarNames = evalin('base','who'); + if ismember('resultGUI',AllVarNames) + resultGUI = evalin('base','resultGUI'); + if isfield(resultGUI,'alpha'); resultGUI = rmfield(resultGUI,'alpha'); end + if isfield(resultGUI,'beta'); resultGUI = rmfield(resultGUI,'beta'); end + if isfield(resultGUI,'RBExDose'); resultGUI = rmfield(resultGUI,'RBExDose');end + if isfield(resultGUI,'RBE'); resultGUI = rmfield(resultGUI,'RBE'); end + assignin('base','resultGUI',resultGUI); + handles = updateIsoDoseLineCache(handles); + end + catch + end + elseif strcmp(contents(get(hObject,'Value')),'protons') + try + AllVarNames = evalin('base','who'); + if ismember('resultGUI',AllVarNames) + resultGUI = evalin('base','resultGUI'); + if isfield(resultGUI,'alpha'); resultGUI = rmfield(resultGUI,'alpha');end + if isfield(resultGUI,'beta'); resultGUI = rmfield(resultGUI,'beta'); end + if isfield(resultGUI,'RBE'); resultGUI = rmfield(resultGUI,'RBE'); end + assignin('base','resultGUI',resultGUI); + handles = updateIsoDoseLineCache(handles); + end + catch + end + end + updatePlnInWorkspace(this); + this.handles = handles; + end + + function editIsoCenter_Callback(this, hObject, eventdata) + + handles = this.handles; + + pln = evalin('base','pln'); + tmpIsoCenter = str2num(get(hObject,'String')); + + if length(tmpIsoCenter) == 3 + if sum(any(unique(pln.propStf.isoCenter,'rows')~=tmpIsoCenter)) + pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1)*tmpIsoCenter; + handles.State = 1; + %UpdateState(handles); + end + else + handles = showError(handles,'EditIsoCenterCallback: Could not set iso center'); + end + + assignin('base','pln',pln); + + % guidata(hObject,handles); + this.handles = handles; + + end + + function checkIsoCenter_Callback(this, hObject, eventdata) + handles = this.handles; + + W = evalin('base','whos'); + doesPlnExist = ismember('pln',{W(:).name}); + + if get(hObject,'Value') && doesPlnExist + pln = evalin('base','pln'); + if ~isfield(pln.propStf,'isoCenter') + pln.propStf.isoCenter = NaN; + end + tmpIsoCenter = matRad_getIsoCenter(evalin('base','cst'),evalin('base','ct')); + if ~isequal(tmpIsoCenter,pln.propStf.isoCenter) + pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1)*tmpIsoCenter; + handles.State = 1; + %UpdateState(handles); + end + set(handles.editIsoCenter,'String',regexprep(num2str((round(tmpIsoCenter*10))./10), '\s+', ' ')); + set(handles.editIsoCenter,'Enable','off') + assignin('base','pln',pln); + else + set(handles.editIsoCenter,'Enable','on') + end + this.handles = handles; + end + + function popUpMachine_Callback(this, hObject, eventdata) + % MÖGLICHER FEHLER WEGEN VALUE WERT! + handles = this.handles; + contents = cellstr(get(hObject,'String')); +% MachineIdentifier = contents{get(hObject,'Value')}; + % contentPopUp = get(handles.) + % checkRadiationComposition(this); + getMachines(this); + pln = evalin('base','pln'); + + % MÖGLICHEE FEHLER HIER VALUE UND GENERIC WERDEN VERGLICHEN + if strcmp(contents(get(hObject,'Value')),'Generic') + try + AllVarNames = evalin('base','who'); + if ismember('resultGUI',AllVarNames) + resultGUI = evalin('base','resultGUI'); + if isfield(resultGUI,'alpha'); resultGUI = rmfield(resultGUI,'alpha'); end + if isfield(resultGUI,'beta'); resultGUI = rmfield(resultGUI,'beta'); end + if isfield(resultGUI,'RBExDose'); resultGUI = rmfield(resultGUI,'RBExDose');end + if isfield(resultGUI,'RBE'); resultGUI = rmfield(resultGUI,'RBE'); end + assignin('base','resultGUI',resultGUI); + handles = updateIsoDoseLineCache(handles); + end + catch + end + % MÖGLICHEE FEHLER HIER VALUE UND GENERIC WERDEN VERGLICHEN + elseif strcmp(contents(get(hObject,'Value')),'generic_MCsquare') + try + AllVarNames = evalin('base','who'); + if ismember('resultGUI',AllVarNames) + resultGUI = evalin('base','resultGUI'); + if isfield(resultGUI,'alpha'); resultGUI = rmfield(resultGUI,'alpha');end + if isfield(resultGUI,'beta'); resultGUI = rmfield(resultGUI,'beta'); end + if isfield(resultGUI,'RBE'); resultGUI = rmfield(resultGUI,'RBE'); end + assignin('base','resultGUI',resultGUI); + handles = updateIsoDoseLineCache(handles); + end + catch + end + end + + updatePlnInWorkspace(this); + this.handles = handles; + end + + function btnSetTissue_Callback(this, hObject, eventdata) + handles = this.handles, + + %check if patient is loaded + % if handles.State == 0 + % return + % end + + %parse variables from base-workspace + cst = evalin('base','cst'); + pln = evalin('base','pln'); + + fileName = [pln.radiationMode '_' pln.machine]; + load(fileName); + + % check for available cell types characterized by alphaX and betaX + for i = 1:size(machine.data(1).alphaX,2) + CellType{i} = [num2str(machine.data(1).alphaX(i)) ' ' num2str(machine.data(1).betaX(i))]; + end + + %fill table data array + for i = 1:size(cst,1) + data{i,1} = cst{i,2}; + data{i,2} = [num2str(cst{i,5}.alphaX) ' ' num2str(cst{i,5}.betaX)]; + data{i,3} = (cst{i,5}.alphaX / cst{i,5}.betaX ); + end + + Width = 400; + Height = 200 + 20*size(data,1); + ScreenSize = get(0,'ScreenSize'); + % show "set tissue parameter" window + figHandles = get(0,'Children'); + if ~isempty(figHandles) + IdxHandle = strcmp(get(figHandles,'Name'),'Set Tissue Parameters'); + else + IdxHandle = []; + end + + %check if window is already exists + if any(IdxHandle) + IdxTable = find(strcmp({figHandles(IdxHandle).Children.Type},'uitable')); + set(figHandles(IdxHandle).Children(IdxTable), 'Data', []); + figTissue = figHandles(IdxHandle); + %set focus + figure(figTissue); + else + figTissue = figure('Name','Set Tissue Parameters','Color',[.5 .5 .5],'NumberTitle','off','Position',... + [ceil(ScreenSize(3)/2) ceil(ScreenSize(4)/2) Width Height]); + end + + % define the tissue parameter table + cNames = {'VOI','alphaX betaX','alpha beta ratio'}; + columnformat = {'char',CellType,'numeric'}; + + tissueTable = uitable('Parent', figTissue,'Data', data,'ColumnEditable',[false true false],... + 'ColumnName',cNames, 'ColumnFormat',columnformat,'Position',[50 150 10 10]); + set(tissueTable,'CellEditCallback',@tissueTable_CellEditCallback); + % set width and height + currTablePos = get(tissueTable,'Position'); + currTableExt = get(tissueTable,'Extent'); + currTablePos(3) = currTableExt(3); + currTablePos(4) = currTableExt(4); + set(tissueTable,'Position',currTablePos); + + % define two buttons with callbacks + uicontrol('Parent', figTissue,'Style', 'pushbutton', 'String', 'Save&Close',... + 'Position', [Width-(0.25*Width) 0.1 * Height 70 30],... + 'Callback', @(hpb,eventdata)SaveTissueParameters(hpb,eventdata,handles)); + + uicontrol('Parent', figTissue,'Style', 'pushbutton', 'String', 'Cancel&Close',... + 'Position', [Width-(0.5*Width) 0.1 * Height 80 30],... + 'Callback', 'close'); + + % guidata(hObject,handles); + %UpdateState(handles); + this.handles = handles; + end + + function popMenuBioOpt_Callback(this, hObject, eventdata) + handles = this.handles; + + pln = evalin('base','pln'); + contentBioOpt = get(handles.popMenuBioOpt,'String'); + NewBioOptimization = contentBioOpt(get(handles.popMenuBioOpt,'Value'),:); + + %if handles.State > 0 + if (strcmp(pln.propOpt.bioOptimization,'LEMIV_effect') && strcmp(NewBioOptimization,'LEMIV_RBExD')) ||... + (strcmp(pln.propOpt.bioOptimization,'LEMIV_RBExD') && strcmp(NewBioOptimization,'LEMIV_effect')) + % do nothing - re-optimization is still possible + elseif ((strcmp(pln.propOpt.bioOptimization,'const_RBE') && strcmp(NewBioOptimization,'none')) ||... + (strcmp(pln.propOpt.bioOptimization,'none') && strcmp(NewBioOptimization,'const_RBE'))) && isequal(pln.radiationMode,'protons') + % do nothing - re-optimization is still possible + else + %handles.State = 1; + end + %end + updatePlnInWorkspace(this); + + %UpdateState(handles); + %guidata(hObject,handles); + this.handles = handles; + end + + function radiobutton3Dconf_Callback(hObject, eventdata, handles) + % hObject handle to radiobutton3Dconf (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hint: get(hObject,'Value') returns toggle state of radiobutton3Dconf + end + + function getMachines(this) + %seach for availabes machines + handles = this.handles; + + %Loop over all modalities to find machine per modalitiy + for i = 1:length(this.Modalities) + pattern = [this.Modalities{1,i} '_*']; %Name pattern, e.g. photons_generic + if isdeployed + Files = dir([ctfroot filesep 'matRad' filesep pattern]); + else + Files = dir([fileparts(mfilename('fullpath')) filesep '..' filesep pattern]); + end + for j = 1:length(Files) + if ~isempty(Files) + % Fehlermeldung wegen empty this.Machines + MachineName = Files(j).name(numel(this.Modalities{1,i})+2:end-4); + this.Machines{i}{j} = MachineName; + end + end + end + + %set handles + selectedRadMod = get(handles.popupRadMode,'Value'); + + nMachines = numel(this.Machines{selectedRadMod}); + + selectedMachine = get(handles.popUpMachine,'Value'); + + if get(handles.popUpMachine,'Value') > nMachines + selectedMachine = 1; + end + + set(handles.popUpMachine,'Value',selectedMachine,'String',this.Machines{selectedRadMod}); + + this.handles = handles; + end + + function editSequencingLevel_Callback(this, hObject, eventdata) + end + + function number = parseStringAsNum(this,stringIn,isVector) + if isnumeric(stringIn) + number = stringIn; + else + number = str2num(stringIn); + if isempty(number) || length(number) > 1 && ~isVector + warndlg(['could not parse all parameters (pln, optimization parameter)']); + number = NaN; + elseif isVector && iscolumn(number) + number = number'; + end + end + end + + function flag = checkRadiationComposition(this) + handles = this.handles; + + flag = true; + contents = cellstr(get(handles.popUpMachine,'String')); + Machine = contents{get(handles.popUpMachine,'Value')}; + contentsPopUp = cellstr(get(handles.popupRadMode,'String')); + radMod = contents{get(handles.popupRadMode,'Value')}; + + if isdeployed + FoundFile = dir([ctfroot filesep 'matRad' filesep radMod '_' Machine '.mat']); + else + FoundFile = dir([fileparts(mfilename('fullpath')) filesep radMod '_' Machine '.mat']); + end + if isempty(FoundFile) + this.showWarning(['No base data available for machine: ' Machine]); + flag = false; + end + this.handles = handles; + end + + end +end diff --git a/gui/matRad_StructureVisibilityWidget.m b/gui/matRad_StructureVisibilityWidget.m new file mode 100644 index 000000000..6ee1c5939 --- /dev/null +++ b/gui/matRad_StructureVisibilityWidget.m @@ -0,0 +1,85 @@ +classdef matRad_StructureVisibilityWidget < matRad_Widget + + properties + + end + + methods + function this = matRad_StructureVisibilityWidget(handleParent) + if nargin < 1 + handleParent = figure(... + 'Units','characters',... + 'Position',[138.4 -7.38461538461539 273.4 59.5384615384615],... + 'Visible','on',... + 'Color',[0.501960784313725 0.501960784313725 0.501960784313725],... 'CloseRequestFcn',@(hObject,eventdata) figure1_CloseRequestFcn(this,hObject,eventdata),... + 'IntegerHandle','off',... + 'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... + 'MenuBar','none',... + 'Name','matRadGUI',... + 'NumberTitle','off',... + 'HandleVisibility','callback',... + 'Tag','figure1',... + 'PaperSize',[20.99999864 29.69999902]); + + end + this = this@matRad_Widget(handleParent); + end + + end + + methods (Access = protected) + function this = createLayout(this) + h86 = this.widgetHandle; + + h87 = uicontrol(... + 'Parent',h86,... + 'Units','normalized',... + 'Style','listbox',... + 'Value',1,... + 'Position',[0.02 0.01 0.97 0.98],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Callback',@(hObject,eventdata) legendTable_Callback(this,hObject,eventdata),... + 'Tag','legendTable'); + end + end + + methods (Access = protected) + function legendTable_Callback(this, hObject, event) + % hObject handle to legendTable (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hints: contents = cellstr(get(hObject,'String')) returns legendTable contents as cell array + % contents{get(hObject,'Value')} returns selected item from legendTable + + handles = this.handles; + cst = evalin('base','cst'); + + idx = get(hObject,'Value'); + clr = dec2hex(round(cst{idx,5}.visibleColor(:)*255),2)'; + clr = ['#';clr(:)]'; + + %Get the string entries + tmpString = get(handles.legendTable,'String'); + + if handles.VOIPlotFlag(idx) + handles.VOIPlotFlag(idx) = false; + cst{idx,5}.Visible = false; + tmpString{idx} = ['
',cst{idx,2},'
']; + elseif ~handles.VOIPlotFlag(idx) + handles.VOIPlotFlag(idx) = true; + cst{idx,5}.Visible = true; + tmpString{idx} = ['
',cst{idx,2},'
']; + end + set(handles.legendTable,'String',tmpString); + + % update cst in workspace accordingly + assignin('base','cst',cst) + + % guidata(hObject, handles); + this.handles = handles; + UpdatePlot(handles) + end + end +end + diff --git a/gui/matRad_ViewerOptionsWidget.m b/gui/matRad_ViewerOptionsWidget.m new file mode 100644 index 000000000..e4bd3b817 --- /dev/null +++ b/gui/matRad_ViewerOptionsWidget.m @@ -0,0 +1,588 @@ +classdef matRad_ViewerOptionsWidget < matRad_Widget + + properties + + end + + methods + function this = matRad_ViewerOptionsWidget(handleParent) + if nargin < 1 + handleParent = figure(... + 'Units','characters',... + 'Position',[138.4 -7.38461538461539 273.4 59.5384615384615],... + 'Visible','on',... + 'Color',[0.501960784313725 0.501960784313725 0.501960784313725],... 'CloseRequestFcn',@(hObject,eventdata) figure1_CloseRequestFcn(this,hObject,eventdata),... + 'IntegerHandle','off',... + 'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... + 'MenuBar','none',... + 'Name','matRadGUI',... + 'NumberTitle','off',... + 'HandleVisibility','callback',... + 'Tag','figure1',... + 'PaperSize',[20.99999864 29.69999902]); + + end + this = this@matRad_Widget(handleParent); + end + + end + + methods (Access = protected) + function this = createLayout(this) + h98 = this.widgetHandle; + + h84 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'String','min value:',... + 'Style','text',... + 'Position',[0.001 0.9 0.6 0.05],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Children',[],... + 'Tag','text24',... + 'FontSize',10,... + 'FontWeight','bold' ); + + h116 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'String','max value:',... + 'Style','text',... + 'Position',[0.001 0.82 0.6 0.05],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Children',[],... + 'Tag','text39',... + 'FontSize',10,... + 'FontWeight','bold' ); + + h85 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'String','Set IsoDose Levels',... + 'Position',[0.05 0.73 0.85 0.06],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata)matRadGUI('btnSetIsoDoseLevels_Callback',hObject,eventdata,guidata(hObject)),... + 'Children',[],... + 'Tag','btnSetIsoDoseLevels'); + + % + % h117 = uicontrol(... + % 'Parent',h1,... + % 'Units','normalized',... + % 'FontUnits',get(0,'defaultuicontrolFontUnits'),... + % 'String','-',... + % 'Style','text',... + % 'Position',[0.955789804908748 0.879908972691808 0.0271397105097546 0.0160598179453836],... + % 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + % 'Children',[],... + % 'Tag','txtMinVal',... + % 'FontSize',10,... + % 'FontWeight','bold',... + % 'CreateFcn', {@local_CreateFcn, blanks(0), appdata} ); + + + % h118 = uicontrol(... + % 'Parent',h1,... + % 'Units','normalized',... + % 'FontUnits',get(0,'defaultuicontrolFontUnits'),... + % 'String','-',... + % 'Style','text',... + % 'Position',[0.955789804908748 0.863003901170351 0.0271397105097546 0.0177503250975293],... + % 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + % 'Children',[],... + % 'Tag','txtMaxVal',... + % 'FontSize',10,... + % 'FontWeight','bold',... + % 'CreateFcn', {@local_CreateFcn, blanks(0), appdata} ); + + h99 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','Window Center:',... + 'Style','text',... + 'Position',[0.0466666666666666 0.442461750109027 0.673333333333333 0.0559999999999998],... + 'Children',[],... + 'Tag','text_windowCenter' ); + + h100 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','Dose opacity:',... + 'Style','text',... + 'Position',[0.0466666666666667 0.0506370831711431 0.847328244274809 0.0514285714285714],... + 'Children',[],... + 'Tag','textDoseOpacity' ); + + + h101 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'String',{ 'None'; 'CT (ED)'; 'Dose' },... + 'Style','popupmenu',... + 'Value',1,... + 'Position',[0.0486486486486487 0.593328859060403 0.940540540540541 0.10744966442953],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,eventdata)popupmenu_chooseColorData_Callback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','popupmenu_chooseColorData'); + + + h102 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'SliderStep',[0.01 0.05],... + 'String','slider',... + 'Style','slider',... + 'Value',0.5,... + 'Position',[0.0432432432432432 0.39758389261745 0.697297297297297 0.0436912751677853],... + 'BackgroundColor',[0.9 0.9 0.9],... + 'Callback',@(hObject,eventdata)slider_windowCenter_Callback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','slider_windowCenter'); + + + h103 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','Window Width:',... + 'Style','text',... + 'Position',[0.0466666666666667 0.345761302394105 0.673333333333333 0.050000000000001],... + 'Children',[],... + 'Tag','text_windowWidth'); + + + h104 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'String','Choose Colormap...',... + 'Style','popupmenu',... + 'Value',1,... + 'Position',[0.0362903225806452 0.158843516266481 0.939516129032258 0.0644686648501362],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,eventdata)popupmenu_chooseColormap_Callback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','popupmenu_chooseColormap'); + + + h105 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','Range:',... + 'Style','text',... + 'Position',[0.0403225806451613 0.237807911050966 0.274193548387097 0.0508446866485015],... + 'Children',[],... + 'Tag','text_windowRange' ); + + + + h106 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'String','0 1',... + 'Style','edit',... + 'Position',[0.323863636363636 0.237807911050966 0.653409090909091 0.0557395498392283],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,eventdata)edit_windowRange_Callback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','edit_windowRange'); + + + + h107 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'String','0.5',... + 'Style','edit',... + 'Value',1,... + 'Position',[0.767567567567568 0.39758389261745 0.205405405405405 0.0604697986577181],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,eventdata)edit_windowCenter_Callback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','edit_windowCenter'); + + h108 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'String','1.0',... + 'Style','edit',... + 'Position',[0.772727272727273 0.298256759964609 0.204545454545455 0.0507395498392284],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,eventdata)edit_windowWidth_Callback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','edit_windowWidth'); + + + h109 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'SliderStep',[0.01 0.05],... + 'String','slider',... + 'Style','slider',... + 'Value',0.6,... + 'Position',[0.147727272727273 0.0057234726688103 0.75 0.0446623794212219],... + 'BackgroundColor',[0.9 0.9 0.9],... + 'Callback',@(hObject,eventdata)sliderOpacity_Callback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','sliderOpacity'); + + + h110 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','0',... + 'Style','text',... + 'Position',[0.0466666666666666 0.00599285798906697 0.0810810810810811 0.042463768115942],... + 'Children',[],... + 'Tag','txtDoseOpacity0Indicator',... + 'UserData',[],... + 'FontName','Helvetica'); + + + h111 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'HorizontalAlignment','right',... + 'String','1',... + 'Style','text',... + 'Position',[0.8963482566536 0.0064864051690258 0.0810810810810811 0.042463768115942],... + 'Children',[],... + 'Tag','txtDoseOpacity1Indicator' ); + + + + h112 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','Window Presets N/A',... + 'Style','text',... + 'Position',[0.0540540540540541 0.570281879194631 0.797297297297297 0.0594697986577181],... + 'Children',[],... + 'Tag','text_windowPreset' ); + + % IS NOT SHOWN IN THE WIDGET?????? + h113 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'String',{ 'Custom'; 'Full'; 'Abd/Med'; 'Head'; 'Liver'; 'Lung'; 'Spine'; 'Vrt/Bone' },... + 'Style','popupmenu',... + 'Value',1,... + 'Position',[0.0486486486486487 0.38889932885906 0.940540540541 0.17744966442953],... + 'BackgroundColor',[1 1 1],... + 'Callback',@(hObject,eventdata)popupmenu_windowPreset_Callback(this,hObject,eventdata),... + 'Children',[],... + 'Visible','on',... % Default should be off! + 'Tag','popupmenu_windowPreset'); + + + h114 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'SliderStep',[0.01 0.05],... + 'String','slider',... + 'Style','slider',... + 'Value',1,... + 'Position',[0.0454545454545455 0.29740507995425 0.698863636363636 0.0446623794212219],... + 'BackgroundColor',[0.9 0.9 0.9],... + 'Callback',@(hObject,eventdata)slider_windowWidth_Callback(this, hObject, eventdata),... + 'Children',[],... + 'Tag','slider_windowWidth'); + + + h115 = uicontrol(... + 'Parent',h98,... + 'Units','normalized',... + 'String','Lock Settings',... + 'Style','checkbox',... + 'Position',[0.0486486486486487 0.111006711409396 0.940540540540541 0.0338926174496644],... + 'BackgroundColor',[0.502 0.502 0.502],... + 'Callback',@(hObject,eventdata)checkbox_lockColormap_Callback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','checkbox_lockColormap' ); + + end + + end + + methods + + % H101 + function popupmenu_chooseColorData_Callback(hObject, eventdata, handles) + % hObject handle to popupmenu_chooseColorData (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hints: contents = cellstr(get(hObject,'String')) returns popupmenu_chooseColorData contents as cell array + % contents{get(hObject,'Value')} returns selected item from popupmenu_chooseColorData + + %index = get(hObject,'Value') - 1; + handles = this.handles; + + handles.cBarChanged = true; + + %guidata(hObject,handles); + this.handles = handles; + UpdatePlot(handles); + end + + % H102 + function slider_windowCenter_Callback(this, hObject, event) + % hObject handle to slider_windowCenter (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hints: get(hObject,'Value') returns position of slider + % get(hObject,'Min') and get(hObject,'Max') to determine range of slider + handles = this.handles + + newCenter = get(hObject,'Value'); + range = get(handles.slider_windowWidth,'Value'); + selectionIndex = get(handles.popupmenu_chooseColorData,'Value'); + + handles.dispWindow{selectionIndex,1} = [newCenter-range/2 newCenter+range/2]; + handles.cBarChanged = true; + + % guidata(hObject,handles); + this.handles = handles; + UpdatePlot(handles); + end + + % H 104 + function popupmenu_chooseColormap_Callback(hObject, eventdata, handles) + % hObject handle to popupmenu_chooseColormap (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hints: contents = cellstr(get(hObject,'String')) returns popupmenu_chooseColormap contents as cell array + % contents{get(hObject,'Value')} returns selected item from popupmenu_chooseColormap + + handles = this.handles; + + index = get(hObject,'Value'); + strings = get(hObject,'String'); + + selectionIndex = get(handles.popupmenu_chooseColorData,'Value'); + + switch selectionIndex + case 2 + handles.ctColorMap = strings{index}; + case 3 + handles.doseColorMap = strings{index}; + otherwise + end + + handles.cBarChanged = true; + + this.handles = handles; + %guidata(hObject,handles); + UpdatePlot(handles); + end + + % H106 + function edit_windowRange_Callback(hObject, eventdata, handles) + % hObject handle to edit_windowRange (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hints: get(hObject,'String') returns contents of edit_windowRange as text + % str2double(get(hObject,'String')) returns contents of edit_windowRange as a double + + handles = this.handles; + + selectionIndex = get(handles.popupmenu_chooseColorData,'Value'); + vRange = str2num(get(hObject,'String')); + % matlab adds a zero in the beginning when text field is changed + if numel(vRange) == 3 + vRange = vRange(vRange~=0); + end + + handles.dispWindow{selectionIndex,1} = sort(vRange); + + handles.cBarChanged = true; + + % compute new iso dose lines + if selectionIndex > 2 + guidata(hObject,handles); + handles = updateIsoDoseLineCache(handles); + end + + this.handles = handles; + %guidata(hObject,handles); + UpdatePlot(handles); + end + + % H107 + function edit_windowCenter_Callback(hObject, eventdata, handles) + % hObject handle to edit_windowCenter (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hints: get(hObject,'String') returns contents of edit_windowCenter as text + % str2double(get(hObject,'String')) returns contents of edit_windowCenter as a double + + handles = this.handles; + + newCenter = str2double(get(hObject,'String')); + width = get(handles.slider_windowWidth,'Value'); + selectionIndex = get(handles.popupmenu_chooseColorData,'Value'); + handles.dispWindow{selectionIndex,1} = [newCenter-width/2 newCenter+width/2]; + handles.cBarChanged = true; + + this.handles = handles; + % guidata(hObject,handles); + UpdatePlot(handles); + end + + % H108 + function edit_windowWidth_Callback(hObject, eventdata, handles) + % hObject handle to edit_windowWidth (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hints: get(hObject,'String') returns contents of edit_windowWidth as text + % str2double(get(hObject,'String')) returns contents of edit_windowWidth as a double + handles = this.handles; + + newWidth = str2double(get(hObject,'String')); + center = get(handles.slider_windowCenter,'Value'); + selectionIndex = get(handles.popupmenu_chooseColorData,'Value'); + handles.dispWindow{selectionIndex,1} = [center-newWidth/2 center+newWidth/2]; + handles.cBarChanged = true; + + this.handles = handles; + % guidata(hObject,handles); + UpdatePlot(handles); + end + + % H109 + function sliderOpacity_Callback(hObject, eventdata, handles) + % hObject handle to sliderOpacity (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + handles = this.handles; + + handles.doseOpacity = get(hObject,'Value'); + + this.handles = handles; + % guidata(hObject,handles); + UpdatePlot(handles); + + + end + + % H113 + function popupmenu_windowPreset_Callback(this, hObject, event) + % hObject handle to popupmenu_windowPreset (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hints: contents = cellstr(get(hObject,'String')) returns popupmenu_windowPreset contents as cell array + % contents{get(hObject,'Value')} returns selected item from popupmenu_windowPreset + handles = this.handles; + + selectionIndexCube = 2; % working on ct only + selectionIndexWindow = get(handles.popupmenu_windowPreset,'Value'); + newCenter = handles.windowPresets(selectionIndexWindow).center; + newWidth = handles.windowPresets(selectionIndexWindow).width; + + handles.dispWindow{selectionIndexCube,1} = [newCenter - newWidth/2 newCenter + newWidth/2]; + handles.cBarChanged = true; + % guidata(hObject,handles); + this.handles = handles; + UpdatePlot(handles); + UpdateColormapOptions(handles); + end + + % H114 + function slider_windowWidth_Callback(hObject, eventdata, handles) + % hObject handle to slider_windowWidth (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hints: get(hObject,'Value') returns position of slider + % get(hObject,'Min') and get(hObject,'Max') to determine range of slider + + handles = this.handles; + newWidth = get(hObject,'Value'); + center = get(handles.slider_windowCenter,'Value'); + selectionIndex = get(handles.popupmenu_chooseColorData,'Value'); + handles.dispWindow{selectionIndex,1} = [center-newWidth/2 center+newWidth/2]; + handles.cBarChanged = true; + + % guidata(hObject,handles); + this.handles = handles; + UpdatePlot(handles); + end + + % H115 Callback + function checkbox_lockColormap_Callback(this, hObject, event) + % hObject handle to checkbox_lockColormap (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hint: get(hObject,'Value') returns toggle state of checkbox_lockColormap + + handles = this.handles; + handles.colormapLocked = get(hObject,'Value'); + + if handles.colormapLocked + state = 'Off'; %'Inactive'; + else + state = 'On'; + end + + set(handles.popupmenu_chooseColorData,'Enable',state); + set(handles.popupmenu_windowPreset,'Enable',state); + set(handles.slider_windowWidth,'Enable',state); + set(handles.slider_windowCenter,'Enable',state); + set(handles.edit_windowWidth,'Enable',state); + set(handles.edit_windowCenter,'Enable',state); + set(handles.edit_windowRange,'Enable',state); + set(handles.popupmenu_chooseColormap,'Enable',state); + + this.handles = handles; + % guidata(hObject,handles); + end + + % button: set iso dose levels + function btnSetIsoDoseLevels_Callback(hObject, eventdata, handles) + handles = this.handles; + prompt = {['Enter iso dose levels in [Gy]. Enter space-separated numbers, e.g. 1.5 2 3 4.98. Enter 0 to use default values']}; + if isequal(handles.IsoDose.Levels,0) || ~isvector(handles.IsoDose.Levels) || any(~isnumeric(handles.IsoDose.Levels)) || any(isnan(handles.IsoDose.Levels)) + defaultLine = {'1 2 3 '}; + else + if isrow(handles.IsoDose.Levels) + defaultLine = cellstr(num2str(handles.IsoDose.Levels,'%.2g ')); + else + defaultLine = cellstr(num2str(handles.IsoDose.Levels','%.2g ')); + end + end + + try + Input = inputdlg(prompt,'Set iso dose levels ', [1 70],defaultLine); + if ~isempty(Input) + handles.IsoDose.Levels = (sort(str2num(Input{1}))); + if length(handles.IsoDose.Levels) == 1 && (handles.IsoDose.Levels(1) ~= 0) + handles.IsoDose.Levels = [handles.IsoDose.Levels handles.IsoDose.Levels]; + end + handles.IsoDose.NewIsoDoseFlag = true; + end + catch + warning('Couldnt parse iso dose levels - using default values'); + handles.IsoDose.Levels = 0; + end + handles = updateIsoDoseLineCache(handles); + handles.IsoDose.NewIsoDoseFlag = false; + %UpdatePlot(handles); + %guidata(hObject,handles); + this.handles = handles; + end + end + +end + diff --git a/gui/matRad_ViewingWidget.m b/gui/matRad_ViewingWidget.m new file mode 100644 index 000000000..a67d8210b --- /dev/null +++ b/gui/matRad_ViewingWidget.m @@ -0,0 +1,747 @@ +classdef matRad_ViewingWidget < matRad_Widget + + properties + + end + + methods + function this = matRad_ViewingWidget(handleParent) + if nargin < 1 + handleParent = figure(... + 'Units','characters',... + 'Position',[138.4 -7.38461538461539 273.4 59.5384615384615],... + 'Visible','on',... + 'Color',[0.501960784313725 0.501960784313725 0.501960784313725],... 'CloseRequestFcn',@(hObject,eventdata) figure1_CloseRequestFcn(this,hObject,eventdata),... + 'IntegerHandle','off',... + 'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... + 'MenuBar','none',... + 'Name','matRadGUI',... + 'NumberTitle','off',... + 'HandleVisibility','callback',... + 'Tag','figure1',... + 'PaperSize',[20.99999864 29.69999902]); + + end + this = this@matRad_Widget(handleParent); + end + + end + + methods(Access = protected) + function this = createLayout(this) + h88 = this.widgetHandle; + + h89 = axes(... + 'Parent',h88,... + 'CameraPosition',[0.5 0.5 9.16025403784439],... + 'CameraTarget',[0.5 0.5 0.5],... + 'CameraViewAngle',6.60861036031192,... + 'PlotBoxAspectRatio',[0.946917808219178 1 0.946917808219178],... + 'FontName','CMU Serif',... + 'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... + 'XTick',[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1],... + 'XTickLabel',{ '0'; '0.1'; '0.2'; '0.3'; '0.4'; '0.5'; '0.6'; '0.7'; '0.8'; '0.9'; '1' },... + 'YTick',[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1],... + 'YTickLabel',{ '0'; '0.1'; '0.2'; '0.3'; '0.4'; '0.5'; '0.6'; '0.7'; '0.8'; '0.9'; '1' },... + 'Position',[0.0718390804597701 0.0354391371340524 0.902298850574712 0.929121725731895],... + 'ActivePositionProperty','position',... + 'LooseInset',[0.199881557553276 0.118695547917832 0.146067292058163 0.0809287826712493],... + 'FontSize',9.63,... + 'SortMethod','childorder',... + 'ButtonDownFcn',@(hObject,eventdata)axesFig_ButtonDownFcn(this,hObject,eventdata),... + 'Tag','axesFig'); + + h90 = get(h89,'title'); + + set(h90,... + 'Parent',h89,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0 0 0],... + 'Position',[0.500000554441759 1.00453467465753 0.5],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','Helvetica',... + 'FontSize',10.593,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','bottom',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',2,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + + h91 = get(h89,'xlabel'); + + set(h91,... + 'Parent',h89,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[0.500000476837158 -0.0373767115122652 0],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','CMU Serif',... + 'FontSize',10.593,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','top',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + + h92 = get(h89,'ylabel'); + + set(h92,... + 'Parent',h89,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[-0.0474647368237942 0.500000476837158 0],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',90,... + 'RotationMode','auto',... + 'FontName','CMU Serif',... + 'FontSize',10.593,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','center',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','bottom',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','on',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + + h93 = get(h89,'zlabel'); + + set(h93,... + 'Parent',h89,... + 'Units','data',... + 'FontUnits','points',... + 'Color',[0.15 0.15 0.15],... + 'Position',[0 0 0],... + 'PositionMode','auto',... + 'Interpreter','tex',... + 'Rotation',0,... + 'RotationMode','auto',... + 'FontName','CMU Serif',... + 'FontSize',10,... + 'FontAngle','normal',... + 'FontWeight','normal',... + 'HorizontalAlignment','left',... + 'HorizontalAlignmentMode','auto',... + 'VerticalAlignment','middle',... + 'VerticalAlignmentMode','auto',... + 'EdgeColor','none',... + 'LineStyle','-',... + 'LineWidth',0.5,... + 'BackgroundColor','none',... + 'Margin',3,... + 'Clipping','off',... + 'XLimInclude','on',... + 'YLimInclude','on',... + 'ZLimInclude','on',... + 'Visible','off',... + 'HandleVisibility','off',... + 'BusyAction','queue',... + 'Interruptible','on',... + 'HitTest','on',... + 'PickableParts','visible'); + + end + end + + methods + function UpdatePlot(handles) + + handles = this.handles; + + %profile on; + + axes(handles.axesFig); + + % this is necessary to prevent multiple callbacks of update plot drawing on + % top of each other in matlab <2014 + drawnow; + + defaultFontSize = 8; + currAxes = axis(handles.axesFig); + AxesHandlesVOI = cell(0); + + AxesHandlesCT_Dose = cell(0); + AxesHandlesIsoDose = cell(0); + + if handles.State == 0 + cla reset + return + elseif handles.State > 0 + ct = evalin('base','ct'); + cst = evalin('base','cst'); + pln = evalin('base','pln'); + end + + %% state 3 indicates that a optimization has been performed + AllVarNames = evalin('base','who'); + if ismember('resultGUI',AllVarNames) + Result = evalin('base','resultGUI'); + end + + if exist('Result','var') + if ~isempty(Result) && ~isempty(ct.cubeHU) && ~isfield(handles,'DispInfo') + + DispInfo = fieldnames(Result); + + for i = 1:size(DispInfo,1) + + % delete weight vectors in Result struct for plotting + if isstruct(Result.(DispInfo{i,1})) || isvector(Result.(DispInfo{i,1})) + Result = rmfield(Result,DispInfo{i,1}); + DispInfo{i,2}=false; + else + %second dimension indicates if it should be plotted + DispInfo{i,2} = true; + % determine units + if strfind(DispInfo{i,1},'physicalDose') + DispInfo{i,3} = '[Gy]'; + elseif strfind(DispInfo{i,1},'alpha') + DispInfo{i,3} = '[Gy^{-1}]'; + elseif strfind(DispInfo{i,1},'beta') + DispInfo{i,3} = '[Gy^{-2}]'; + elseif strfind(DispInfo{i,1},'RBExD') + DispInfo{i,3} = '[Gy(RBE)]'; + elseif strfind(DispInfo{i,1},'LET') + DispInfo{i,3} = '[keV/um]'; + else + DispInfo{i,3} = '[a.u.]'; + end + DispInfo{i,4} = []; % optional for the future: color range for plotting + DispInfo{i,5} = []; % optional for the future: min max values + end + end + + set(handles.popupDisplayOption,'String',fieldnames(Result)); + if sum(strcmp(handles.SelectedDisplayOption,fieldnames(Result))) == 0 + handles.SelectedDisplayOption = DispInfo{find([DispInfo{:,2}],1,'first'),1}; + end + set(handles.popupDisplayOption,'Value',find(strcmp(handles.SelectedDisplayOption,fieldnames(Result)))); + + end + end + + %% set and get required variables + plane = get(handles.popupPlane,'Value'); + slice = round(get(handles.sliderSlice,'Value')); + hold(handles.axesFig,'on'); + if get(handles.popupTypeOfPlot,'Value')==1 + set(handles.axesFig,'YDir','Reverse'); + end + + %% Remove colorbar? + plotColorbarSelection = get(handles.popupmenu_chooseColorData,'Value'); + + if get(handles.popupTypeOfPlot,'Value')==2 || plotColorbarSelection == 1 + if isfield(handles,'cBarHandel') + delete(handles.cBarHandel); + end + %The following seems to be necessary as MATLAB messes up some stuff + %with the handle storage + ch = findall(gcf,'tag','Colorbar'); + if ~isempty(ch) + delete(ch); + end + end + + selectIx = get(handles.popupmenu_chooseColorData,'Value'); + + cla(handles.axesFig); + %% plot ct - if a ct cube is available and type of plot is set to 1 and not 2; 1 indicate cube plotting and 2 profile plotting + if ~isempty(ct) && get(handles.popupTypeOfPlot,'Value')==1 + + if selectIx == 3 + ctIx = 2; + else + ctIx = selectIx; + end + + if isfield(ct, 'cube') + plotCtCube = ct.cube; + else + plotCtCube = ct.cubeHU; + end + + ctMap = matRad_getColormap(handles.ctColorMap,handles.cMapSize); + + if isempty(handles.dispWindow{ctIx,2}) + handles.dispWindow{ctIx,2} = [min(reshape([ct.cubeHU{:}],[],1)) max(reshape([ct.cubeHU{:}],[],1))]; + end + + if get(handles.radiobtnCT,'Value') + [AxesHandlesCT_Dose{end+1},~,handles.dispWindow{ctIx,1}] = matRad_plotCtSlice(handles.axesFig,plotCtCube,1,plane,slice,ctMap,handles.dispWindow{ctIx,1}); + + % plot colorbar? If 1 the user asked for the CT + if plotColorbarSelection == 2 && handles.cBarChanged + %Plot the colorbar + handles.cBarHandel = matRad_plotColorbar(handles.axesFig,ctMap,handles.dispWindow{ctIx,1},'fontsize',defaultFontSize); + %adjust lables + if isfield(ct,'cubeHU') + set(get(handles.cBarHandel,'ylabel'),'String', 'Hounsfield Units','fontsize',defaultFontSize); + else + set(get(handles.cBarHandel,'ylabel'),'String', 'Electron Density','fontsize',defaultFontSize); + end + % do not interprete as tex syntax + set(get(handles.cBarHandel,'ylabel'),'interpreter','none'); + end + end + end + + %% plot dose cube + if handles.State >= 1 && get(handles.popupTypeOfPlot,'Value')== 1 && exist('Result','var') + doseMap = matRad_getColormap(handles.doseColorMap,handles.cMapSize); + doseIx = 3; + % if the selected display option doesn't exist then simply display + % the first cube of the Result struct + if ~isfield(Result,handles.SelectedDisplayOption) + CubeNames = fieldnames(Result); + handles.SelectedDisplayOption = CubeNames{1,1}; + end + + dose = Result.(handles.SelectedDisplayOption); + + % dose colorwash + if ~isempty(dose) && ~isvector(dose) + + if isempty(handles.dispWindow{doseIx,2}) + handles.dispWindow{doseIx,2} = [min(dose(:)) max(dose(:))]; % set min and max dose values + end + + if get(handles.radiobtnDose,'Value') + [doseHandle,~,handles.dispWindow{doseIx,1}] = matRad_plotDoseSlice(handles.axesFig,dose,plane,slice,handles.CutOffLevel,handles.doseOpacity,doseMap,handles.dispWindow{doseIx,1}); + AxesHandlesCT_Dose{end+1} = doseHandle; + end + + % plot colorbar? + if plotColorbarSelection > 2 && handles.cBarChanged + %Plot the colorbar + handles.cBarHandel = matRad_plotColorbar(handles.axesFig,doseMap,handles.dispWindow{selectIx,1},'fontsize',defaultFontSize); + %adjust lables + Idx = find(strcmp(handles.SelectedDisplayOption,DispInfo(:,1))); + set(get(handles.cBarHandel,'ylabel'),'String', [DispInfo{Idx,1} ' ' DispInfo{Idx,3} ],'fontsize',defaultFontSize); + % do not interprete as tex syntax + set(get(handles.cBarHandel,'ylabel'),'interpreter','none'); + end + end + + + %% plot iso dose lines + if get(handles.radiobtnIsoDoseLines,'Value') + plotLabels = get(handles.radiobtnIsoDoseLinesLabels,'Value') == 1; + + %Sanity Check for Contours, which actually should have been + %computed before calling UpdatePlot + if ~isfield(handles.IsoDose,'Contours') + try + handles.IsoDose.Contours = matRad_computeIsoDoseContours(dose,handles.IsoDose.Levels); + catch + %If the computation didn't work, we set the field to + %empty, which will force matRad_plotIsoDoseLines to use + %matlabs contour function instead of repeating the + %failing computation every time + handles.IsoDose.Contours = []; + warning('Could not compute isodose lines! Will try slower contour function!'); + end + end + AxesHandlesIsoDose = matRad_plotIsoDoseLines(handles.axesFig,dose,handles.IsoDose.Contours,handles.IsoDose.Levels,plotLabels,plane,slice,doseMap,handles.dispWindow{doseIx,1},'LineWidth',1.5); + end + end + + selectIx = get(handles.popupmenu_chooseColorData,'Value'); + set(handles.txtMinVal,'String',num2str(handles.dispWindow{selectIx,2}(1,1))); + set(handles.txtMaxVal,'String',num2str(handles.dispWindow{selectIx,2}(1,2))); + + %% plot VOIs + if get(handles.radiobtnContour,'Value') && get(handles.popupTypeOfPlot,'Value')==1 && handles.State>0 + AxesHandlesVOI = [AxesHandlesVOI matRad_plotVoiContourSlice(handles.axesFig,cst,ct,1,handles.VOIPlotFlag,plane,slice,[],'LineWidth',2)]; + end + + %% Set axis labels and plot iso center + matRad_plotAxisLabels(handles.axesFig,ct,plane,slice,defaultFontSize); + + if get(handles.radioBtnIsoCenter,'Value') == 1 && get(handles.popupTypeOfPlot,'Value') == 1 && ~isempty(pln) + hIsoCenterCross = matRad_plotIsoCenterMarker(handles.axesFig,pln,ct,plane,slice); + end + + if get(handles.radiobtnPlan,'value') == 1 && ~isempty(pln) + matRad_plotProjectedGantryAngles(handles.axesFig,pln,ct,plane); + end + + % the following line ensures the plotting order (optional) + % set(gca,'Children',[AxesHandlesCT_Dose hIsoCenterCross AxesHandlesIsoDose AxesHandlesVOI ]); + + %set axis ratio + ratios = [1/ct.resolution.x 1/ct.resolution.y 1/ct.resolution.z]; + set(handles.axesFig,'DataAspectRatioMode','manual'); + if plane == 1 + res = [ratios(3) ratios(2)]./max([ratios(3) ratios(2)]); + set(handles.axesFig,'DataAspectRatio',[res 1]) + elseif plane == 2 % sagittal plane + res = [ratios(3) ratios(1)]./max([ratios(3) ratios(1)]); + set(handles.axesFig,'DataAspectRatio',[res 1]) + elseif plane == 3 % Axial plane + res = [ratios(2) ratios(1)]./max([ratios(2) ratios(1)]); + set(handles.axesFig,'DataAspectRatio',[res 1]) + end + + + %% profile plot + if get(handles.popupTypeOfPlot,'Value') == 2 && exist('Result','var') + % set SAD + fileName = [pln.radiationMode '_' pln.machine]; + try + load(fileName); + SAD = machine.meta.SAD; + catch + error(['Could not find the following machine file: ' fileName ]); + end + + % clear view and initialize some values + cla(handles.axesFig,'reset') + set(gca,'YDir','normal'); + ylabel('{\color{black}dose [Gy]}') + cColor={'black','green','magenta','cyan','yellow','red','blue'}; + + % Rotate the system into the beam. + % passive rotation & row vector multiplication & inverted rotation requires triple matrix transpose + rotMat_system_T = transpose(matRad_getRotationMatrix(pln.propStf.gantryAngles(handles.selectedBeam),pln.propStf.couchAngles(handles.selectedBeam))); + + if strcmp(handles.ProfileType,'longitudinal') + sourcePointBEV = [handles.profileOffset -SAD 0]; + targetPointBEV = [handles.profileOffset SAD 0]; + elseif strcmp(handles.ProfileType,'lateral') + sourcePointBEV = [-SAD handles.profileOffset 0]; + targetPointBEV = [ SAD handles.profileOffset 0]; + end + + rotSourcePointBEV = sourcePointBEV * rotMat_system_T; + rotTargetPointBEV = targetPointBEV * rotMat_system_T; + + % perform raytracing on the central axis of the selected beam, use unit + % electron density for plotting against the geometrical depth + [~,l,rho,~,ix] = matRad_siddonRayTracer(pln.propStf.isoCenter(handles.selectedBeam,:),ct.resolution,rotSourcePointBEV,rotTargetPointBEV,{0*ct.cubeHU{1}+1}); + d = [0 l .* rho{1}]; + % Calculate accumulated d sum. + vX = cumsum(d(1:end-1)); + + % this step is necessary if visualization is set to profile plot + % and another optimization is carried out - set focus on GUI + figHandles = get(0,'Children'); + idxHandle = []; + if ~isempty(figHandles) + v=version; + if str2double(v(1:3))>= 8.5 + idxHandle = strcmp({figHandles(:).Name},'matRadGUI'); + else + idxHandle = strcmp(get(figHandles,'Name'),'matRadGUI'); + end + end + figure(figHandles(idxHandle)); + + % plot physical dose + Content = get(handles.popupDisplayOption,'String'); + SelectedCube = Content{get(handles.popupDisplayOption,'Value')}; + if sum(strcmp(SelectedCube,{'physicalDose','effect','RBExDose','alpha','beta','RBE'})) > 0 + Suffix = ''; + else + Idx = find(SelectedCube == '_'); + Suffix = SelectedCube(Idx:end); + end + + mPhysDose = Result.(['physicalDose' Suffix]); + PlotHandles{1} = plot(handles.axesFig,vX,mPhysDose(ix),'color',cColor{1,1},'LineWidth',3); hold on; + PlotHandles{1,2} ='physicalDose'; + ylabel(handles.axesFig,'dose in [Gy]'); + set(handles.axesFig,'FontSize',defaultFontSize); + + % plot counter + Cnt=2; + + if isfield(Result,['RBE' Suffix]) + + %disbale specific plots + %DispInfo{6,2}=0; + %DispInfo{5,2}=0; + %DispInfo{2,2}=0; + + % generate two lines for ylabel + StringYLabel1 = '\fontsize{8}{\color{red}RBE x dose [Gy(RBE)] \color{black}dose [Gy] '; + StringYLabel2 = ''; + for i=1:1:size(DispInfo,1) + if DispInfo{i,2} && sum(strcmp(DispInfo{i,1},{['effect' Suffix],['alpha' Suffix],['beta' Suffix]})) > 0 + %physicalDose is already plotted and RBExD vs RBE is plotted later with plotyy + if ~strcmp(DispInfo{i,1},['RBExDose' Suffix]) &&... + ~strcmp(DispInfo{i,1},['RBE' Suffix]) && ... + ~strcmp(DispInfo{i,1},['physicalDose' Suffix]) + + mCube = Result.([DispInfo{i,1}]); + PlotHandles{Cnt,1} = plot(handles.axesFig,vX,mCube(ix),'color',cColor{1,Cnt},'LineWidth',3);hold on; + PlotHandles{Cnt,2} = DispInfo{i,1}; + StringYLabel2 = [StringYLabel2 ' \color{' cColor{1,Cnt} '}' DispInfo{i,1} ' [' DispInfo{i,3} ']']; + Cnt = Cnt+1; + end + end + end + StringYLabel2 = [StringYLabel2 '}']; + % always plot RBExD against RBE + mRBExDose = Result.(['RBExDose' Suffix]); + vBED = mRBExDose(ix); + mRBE = Result.(['RBE' Suffix]); + vRBE = mRBE(ix); + + % plot biological dose against RBE + [ax, PlotHandles{Cnt,1}, PlotHandles{Cnt+1,1}]=plotyy(handles.axesFig,vX,vBED,vX,vRBE,'plot');hold on; + PlotHandles{Cnt,2}='RBExDose'; + PlotHandles{Cnt+1,2}='RBE'; + + % set plotyy properties + set(get(ax(2),'Ylabel'),'String','RBE [a.u.]','FontSize',8); + ylabel({StringYLabel1;StringYLabel2}) + set(PlotHandles{Cnt,1},'Linewidth',4,'color','r'); + set(PlotHandles{Cnt+1,1},'Linewidth',3,'color','b'); + set(ax(1),'ycolor','r') + set(ax(2),'ycolor','b') + set(ax,'FontSize',8); + Cnt=Cnt+2; + end + + % asses target coordinates + tmpPrior = intmax; + tmpSize = 0; + for i=1:size(cst,1) + if strcmp(cst{i,3},'TARGET') && tmpPrior >= cst{i,5}.Priority && tmpSize 0 + AllVarNames = evalin('base','who'); + if ismember('resultGUI',AllVarNames) + Result = evalin('base','resultGUI'); + end + + if ismember('stf',AllVarNames) + stf = evalin('base','stf'); + else + stf = []; + end + + ct = evalin('base','ct'); + cst = evalin('base','cst'); + pln = evalin('base','pln'); + end + + oldView = get(axesFig3D,'View'); + + cla(axesFig3D); + %delete(allchild(axesFig3D)); + + %test = allchild(axesFig3D); + + plane = get(handles.popupPlane,'Value'); + slice = round(get(handles.sliderSlice,'Value')); + defaultFontSize = 8; + + %Check if we need to precompute the surface data + if size(cst,2) < 8 + cst = matRad_computeAllVoiSurfaces(ct,cst); + assignin('base','cst',cst); + end + + set(fig3D,'Color',0.5*[1 1 1]); + set(axesFig3D,'Color',1*[0 0 0]); + + %% Plot 3D structures + hold(axesFig3D,'on'); + if get(handles.radiobtnContour,'Value') && handles.State>0 + voiPatches = matRad_plotVois3D(axesFig3D,ct,cst,handles.VOIPlotFlag,colorcube); + end + + %% plot the CT slice + if get(handles.radiobtnCT,'Value') + window = handles.dispWindow{2,1}; %(2 for ct) + ctMap = matRad_getColormap(handles.ctColorMap,handles.cMapSize); + ctHandle = matRad_plotCtSlice3D(axesFig3D,ct,1,plane,slice,ctMap,window); + end + + %% plot the dose slice + if handles.State >= 1 && exist('Result','var') + doseMap = matRad_getColormap(handles.doseColorMap,handles.cMapSize); + doseIx = 3; + % if the selected display option doesn't exist then simply display + % the first cube of the Result struct + if ~isfield(Result,handles.SelectedDisplayOption) + CubeNames = fieldnames(Result); + handles.SelectedDisplayOption = CubeNames{1,1}; + end + + dose = Result.(handles.SelectedDisplayOption); + + % dose colorwash + if ~isempty(dose) && ~isvector(dose) + + if isempty(handles.dispWindow{doseIx,2}) + handles.dispWindow{doseIx,2} = [min(dose(:)) max(dose(:))]; % set min and max dose values + end + + if get(handles.radiobtnDose,'Value') + [doseHandle,~,handles.dispWindow{doseIx,1}] = matRad_plotDoseSlice3D(axesFig3D,ct,dose,plane,slice,handles.CutOffLevel,handles.doseOpacity,doseMap,handles.dispWindow{doseIx,1}); + end + if get(handles.radiobtnIsoDoseLines,'Value') + matRad_plotIsoDoseLines3D(axesFig3D,ct,dose,handles.IsoDose.Contours,handles.IsoDose.Levels,plane,slice,doseMap,handles.dispWindow{doseIx,1},'LineWidth',1.5); + end + end + end + + if get(handles.radiobtnPlan,'Value') + matRad_plotPlan3D(axesFig3D,pln,stf); + end + + %hLight = light('Parent',axesFig3D); + %camlight(hLight,'left'); + %lighting('gouraud'); + + xlabel(axesFig3D,'x [voxels]','FontSize',defaultFontSize) + ylabel(axesFig3D,'y [voxels]','FontSize',defaultFontSize) + zlabel(axesFig3D,'z [voxels]','FontSize',defaultFontSize) + title(axesFig3D,'matRad 3D view'); + + % set axis ratio + ratios = [1 1 1]; %[1/ct.resolution.x 1/ct.resolution.y 1/ct.resolution.z]; + ratios = ratios([2 1 3]); + set(axesFig3D,'DataAspectRatioMode','manual'); + set(axesFig3D,'DataAspectRatio',ratios./max(ratios)); + + set(axesFig3D,'Ydir','reverse'); + + set(axesFig3D,'view',oldView); + + this.handles = handles; + end + end +end \ No newline at end of file diff --git a/gui/matRad_VisualizationWidget.m b/gui/matRad_VisualizationWidget.m new file mode 100644 index 000000000..b148cef5b --- /dev/null +++ b/gui/matRad_VisualizationWidget.m @@ -0,0 +1,558 @@ +classdef matRad_VisualizationWidget < matRad_Widget + + properties + end + + methods + function this = matRad_VisualizationWidget(handleParent) + if nargin < 1 + handleParent = figure(... + 'Units','characters',... + 'Position',[138.4 -7.38461538461539 273.4 59.5384615384615],... + 'Visible','on',... + 'Color',[0.501960784313725 0.501960784313725 0.501960784313725],... 'CloseRequestFcn',@(hObject,eventdata) figure1_CloseRequestFcn(this,hObject,eventdata),... + 'IntegerHandle','off',... + 'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... + 'MenuBar','none',... + 'Name','matRadGUI',... + 'NumberTitle','off',... + 'HandleVisibility','callback',... + 'Tag','figure1',... + 'PaperSize',[20.99999864 29.69999902]); + + end + this = this@matRad_Widget(handleParent); + end + end + + methods (Access = protected) + function this = createLayout(this) + h36 = this.widgetHandle; + h37 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String',{ 'coronal'; 'sagital'; 'axial' },... + 'Style','popupmenu',... + 'Value',3,... + 'Position',[0.465315808689303 0.582191780821918 0.113636363636364 0.143835616438356],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata) popupPlane_Callback(hObject,eventdata),... + 'Tag','popupPlane',... + 'FontWeight','bold'); + + h38 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String',{ 'Slider' },... + 'Style','slider',... + 'Position',[0.134961439588689 0.796610169491525 0.167095115681234 0.096045197740113],... + 'BackgroundColor',[0.9 0.9 0.9],... + 'Callback',@(hObject,eventdata) sliderSlice_Callback(this,hObject,eventdata),... + 'BusyAction','cancel',... + 'Interruptible','off',... + 'Tag','sliderSlice'); + + h39 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','Plane Selection',... + 'Style','text',... + 'Position',[0.34258853596203 0.589041095890411 0.11969696969697 0.116438356164384],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','txtPlanSelection'); + + h40 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','Slice Selection',... + 'Style','text',... + 'Position',[0.00909090909090909 0.808219178082192 0.113636363636364 0.116438356164384],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','text9' ); + + h41 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','plot contour',... + 'Style','radiobutton',... + 'Value',1,... + 'Position',[0.780445969125214 0.733212341197822 0.169811320754717 0.117241379310345],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Callback',@(hObject,eventdata) radiobtnContour_Callback(this,hObject,eventdata),... + 'Tag','radiobtnContour' ); + + h42 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','plot dose',... + 'Style','radiobutton',... + 'Value',1,... + 'Position',[0.780445969125214 0.466969147005444 0.169811320754717 0.117241379310345],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Callback',@(hObject,eventdata) radiobtnDose_Callback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','radiobtnDose' ); + + + h43 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','plot isolines',... + 'Style','radiobutton',... + 'Value',1,... + 'Position',[0.780445969125214 0.600907441016334 0.150943396226415 0.117241379310345],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Callback',@(hObject,eventdata) radiobtnIsoDoseLines_Callback(this,hObject,eventdata),... + 'Tag','radiobtnIsoDoseLines'); + + h44 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','Type of plot',... + 'Style','text',... + 'Position',[0.343053173241852 0.793103448275862 0.108061749571183 0.124137931034483],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','txtTypeOfPlot' ); + + h45 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String',{ 'intensity'; 'profile' },... + 'Style','popupmenu',... + 'Value',1,... + 'Position',[0.465315808689303 0.801369863013699 0.113636363636364 0.143835616438356],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata) popupTypeOfPlot_Callback(this,hObject,eventdata),... + 'Tag','popupTypeOfPlot',... + 'FontWeight','bold'); + + h46 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','Display option',... + 'Style','text',... + 'Position',[0.34258853596203 0.39041095890411 0.128787878787879 0.102739726027397],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','txtDisplayOption' ); + + h47 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','Please select ... ',... + 'Style','popupmenu',... + 'Value',1,... + 'Position',[0.465315808689303 0.36986301369863 0.196969696969697 0.136986301369863],... + 'BackgroundColor',[0.831372549019608 0.815686274509804 0.784313725490196],... + 'Callback',@(hObject,eventdata)popupDisplayOption_Callback(this,hObject,eventdata),... + 'Tag','popupDisplayOption',... + 'FontWeight','bold'); + + h48 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','Beam Selection',... + 'Style','text',... + 'Position',[0.00857632933104631 0.503448275862069 0.118353344768439 0.186206896551724],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','txtBeamSelection' ); + + h49 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','SliderBeamSelection',... + 'Style','slider',... + 'Position',[0.134961439588689 0.542372881355932 0.167095115681234 0.096045197740113],... + 'BackgroundColor',[0.9 0.9 0.9],... + 'Callback',@(hObject,eventdata) sliderBeamSelection_Callback(this,hObject,eventdata),... + 'Enable','off',... + 'Tag','sliderBeamSelection'); + + h50 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','lateral',... + 'Position',[0.658025928757913 0.794520547945205 0.0863636363636364 0.157534246575343],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) btnProfileType_Callback(this,hObject,eventdata),... + 'Enable','off',... + 'Tag','btnProfileType',... + 'FontWeight','bold' ); + + h51 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','GoTo',... + 'Style','text',... + 'Position',[0.604795511376553 0.801369863013698 0.0454545454545454 0.123287671232877],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Children',[],... + 'Tag','text16' ); + + h52 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','Show DVH/QI',... + 'Position',[0.51413881748072 0.0677966101694915 0.123393316195373 0.129943502824859],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) btnDVH_Callback(this,hObject,eventdata),... + 'Enable','off',... + 'Tag','btnDVH',... + 'FontWeight','bold'); + + h53 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','plot isolines labels',... + 'Style','radiobutton',... + 'Position',[0.780445969125214 0.343557168784029 0.202401372212693 0.117241379310345],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Callback',@(hObject,eventdata) radiobtnIsoDoseLinesLabels_Callback(this,hObject,eventdata),... + 'Tag','radiobtnIsoDoseLinesLabels'); + + h54 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'HorizontalAlignment','left',... + 'String','Offset',... + 'Style','text',... + 'Position',[0.00909090909090909 0.287104393008975 0.118181818181818 0.123287671232877],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','textOffset'); + + h55 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','SliderOffset',... + 'Style','slider',... + 'Position',[0.134961439588689 0.271186440677966 0.167095115681234 0.096045197740113],... + 'BackgroundColor',[0.9 0.9 0.9],... + 'Callback',@(hObject,eventdata) sliderOffset_Callback(this,hObject,eventdata),... + 'Enable','off',... + 'Tag','sliderOffset'); + + + h56 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','plot iso center',... + 'Style','radiobutton',... + 'Value',1,... + 'Position',[0.780445969125214 0.205989110707804 0.169811320754717 0.117241379310345],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Callback',@(hObject,eventdata) radioBtnIsoCenter_Callback(this,hObject,eventdata),... + 'Tag','radioBtnIsoCenter'); + + + h57 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','Open 3D-View',... + 'Position',[0.595848595848596 0.578947368421053 0.148962148962149 0.157894736842105],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) btn3Dview_Callback(this,hObject,eventdata),... + 'Enable','off',... + 'Tag','btn3Dview',... + 'FontWeight','bold'); + + h58 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','plot CT',... + 'Style','radiobutton',... + 'Value',1,... + 'Position',[0.780445969125214 0.864791288566243 0.169811320754717 0.117241379310345],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Callback',@(hObject,eventdata) radiobtnCT_Callback(this,hObject,eventdata),... + 'Tag','radiobtnCT'); + + + h59 = uicontrol(... + 'Parent',h36,... + 'Units','normalized',... + 'String','visualize plan / beams',... + 'Style','radiobutton',... + 'Value',1,... + 'Position',[0.78021978021978 0.0736842105263158 0.2002442002442 0.115789473684211],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Callback',@(hObject,eventdata) radiobtnPlan_Callback(this,hObject,eventdata),... + 'Tag','radiobtnPlan'); + + + end + + end + + methods (Access = protected) + + % H37 Calback + function popupPlane_Callback(this, hObject, event) + % hObject handle to popupPlane (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hints: contents = cellstr(get(hObject,'String')) returns popupPlane contents as cell array + % contents{get(hObject,'Value')} returns selected item from popupPlane + + % set slice slider + + handles = this.handles; + + handles.plane = get(handles.popupPlane,'value'); + try + if handles.State > 0 + ct = evalin('base', 'ct'); + set(handles.sliderSlice,'Min',1,'Max',ct.cubeDim(handles.plane),... + 'SliderStep',[1/(ct.cubeDim(handles.plane)-1) 1/(ct.cubeDim(handles.plane)-1)]); + if handles.State < 3 + set(handles.sliderSlice,'Value',round(ct.cubeDim(handles.plane)/2)); + else + pln = evalin('base','pln'); + + if handles.plane == 1 + set(handles.sliderSlice,'Value',ceil(pln.propStf.isoCenter(1,2)/ct.resolution.x)); + elseif handles.plane == 2 + set(handles.sliderSlice,'Value',ceil(pln.propStf.isoCenter(1,1)/ct.resolution.y)); + elseif handles.plane == 3 + set(handles.sliderSlice,'Value',ceil(pln.propStf.isoCenter(1,3)/ct.resolution.z)); + end + + end + end + catch + end + + handles.rememberCurrAxes = false; + UpdatePlot(handles); + handles.rememberCurrAxes = true; + %guidata(hObject,handles); + this.handles = handles; + end + + %45 Callback + function popupTypeOfPlot_Callback(this, hObject, event) + + handles = this.handles; + + % intensity plot + if get(hObject,'Value') == 1 + + set(handles.sliderBeamSelection,'Enable','off') + set(handles.sliderOffset,'Enable','off') + set(handles.popupDisplayOption,'Enable','on') + set(handles.btnProfileType,'Enable','off'); + set(handles.popupPlane,'Enable','on'); + set(handles.radiobtnCT,'Enable','on'); + set(handles.radiobtnContour,'Enable','on'); + set(handles.radiobtnDose,'Enable','on'); + set(handles.radiobtnIsoDoseLines,'Enable','on'); + set(handles.radiobtnIsoDoseLinesLabels,'Enable','on'); + set(handles.sliderSlice,'Enable','on'); + + % profile plot + elseif get(hObject,'Value') == 2 + + if handles.State > 0 + if length(parseStringAsNum(get(handles.editGantryAngle,'String'),true)) > 1 + + set(handles.sliderBeamSelection,'Enable','on'); + handles.selectedBeam = 1; + pln = evalin('base','pln'); + set(handles.sliderBeamSelection,'Min',handles.selectedBeam,'Max',pln.propStf.numOfBeams,... + 'Value',handles.selectedBeam,... + 'SliderStep',[1/(pln.propStf.numOfBeams-1) 1/(pln.propStf.numOfBeams-1)],... + 'Enable','on'); + + else + handles.selectedBeam = 1; + end + + handles.profileOffset = get(handles.sliderOffset,'Value'); + + vMinMax = [-100 100]; + vRange = sum(abs(vMinMax)); + + ct = evalin('base','ct'); + if strcmp(get(handles.btnProfileType,'String'),'lateral') + SliderStep = vRange/ct.resolution.x; + else + SliderStep = vRange/ct.resolution.y; + end + + set(handles.sliderOffset,'Min',vMinMax(1),'Max',vMinMax(2),... + 'Value',handles.profileOffset,... + 'SliderStep',[1/SliderStep 1/SliderStep],... + 'Enable','on'); + end + + + set(handles.popupDisplayOption,'Enable','on'); + set(handles.btnProfileType,'Enable','on'); + set(handles.popupPlane,'Enable','off'); + set(handles.radiobtnCT,'Enable','off'); + set(handles.radiobtnContour,'Enable','off'); + set(handles.radiobtnDose,'Enable','off'); + set(handles.radiobtnIsoDoseLines,'Enable','off'); + set(handles.sliderSlice,'Enable','off'); + set(handles.radiobtnIsoDoseLinesLabels,'Enable','off'); + + + set(handles.btnProfileType,'Enable','on') + + if strcmp(get(handles.btnProfileType,'String'),'lateral') + handles.ProfileType = 'longitudinal'; + else + handles.ProfileType = 'lateral'; + end + + end + + handles.cBarChanged = true; + + handles.rememberCurrAxes = false; + cla(handles.axesFig,'reset'); + UpdatePlot(handles); + handles.rememberCurrAxes = true; + + %guidata(hObject, handles); + this.handles = handles; + end + + % 47 Callback + function popupDisplayOption_Callback(this, hObject, event) + handles = this.handles; + content = get(hObject,'String'); + handles.SelectedDisplayOption = content{get(hObject,'Value'),1}; + handles.SelectedDisplayOptionIdx = get(hObject,'Value'); + %handles.dispWindow{3,1} = []; handles.dispWindow{3,2} = []; + + if ~isfield(handles,'colormapLocked') || ~handles.colormapLocked + handles.dispWindow{3,1} = []; handles.dispWindow{3,2} = []; + end + + handles = updateIsoDoseLineCache(handles); + handles.cBarChanged = true; + % guidata(hObject, handles); + this.handles = handles; + + UpdatePlot(handles); + % guidata(hObject, handles); + this.handles = handles; + end + + % H49 Callback + function sliderBeamSelection_Callback(this, hObject, event) + % hObject handle to sliderBeamSelection (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % Hints: get(hObject,'Value') returns position of slider + % get(hObject,'Min') and get(hObject,'Max') to determine range of slider + + handles = this.handles; + handles.selectedBeam = round(get(hObject,'Value')); + set(hObject, 'Value', handles.selectedBeam); + handles.rememberCurrAxes = false; + UpdatePlot(handles); + handles.rememberCurrAxes = true; + + this.handles = handles; + % guidata(hObject,handles); + end + + % 50 Callback + function btnProfileType_Callback(this, hObject, event) + % hObject handle to btnProfileType (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + handles = this.handles; + + if strcmp(get(hObject,'Enable') ,'on') + if strcmp(handles.ProfileType,'lateral') + handles.ProfileType = 'longitudinal'; + set(hObject,'String','lateral'); + else + handles.ProfileType = 'lateral'; + set(hObject,'String','longitudinal'); + end + + handles.rememberCurrAxes = false; + UpdatePlot(handles); + handles.rememberCurrAxes = true; + + %guidata(hObject, handles); + this.handles = handles; + end + end + + % 52 Callback + function btnDVH_Callback(this, hObject, event) + + handles = this.handles; + resultGUI = evalin('base','resultGUI'); + Content = get(handles.popupDisplayOption,'String'); + SelectedCube = Content{get(handles.popupDisplayOption,'Value')}; + + pln = evalin('base','pln'); + resultGUI_SelectedCube.physicalDose = resultGUI.(SelectedCube); + + if ~strcmp(pln.propOpt.bioOptimization,'none') + + %check if one of the default fields is selected + if sum(strcmp(SelectedCube,{'physicalDose','effect','RBE,','RBExDose','alpha','beta'})) > 0 + resultGUI_SelectedCube.physicalDose = resultGUI.physicalDose; + resultGUI_SelectedCube.RBExDose = resultGUI.RBExDose; + else + Idx = find(SelectedCube == '_'); + SelectedSuffix = SelectedCube(Idx(1):end); + resultGUI_SelectedCube.physicalDose = resultGUI.(['physicalDose' SelectedSuffix]); + resultGUI_SelectedCube.RBExDose = resultGUI.(['RBExDose' SelectedSuffix]); + end + end + + %adapt visibilty + cst = evalin('base','cst'); + for i = 1:size(cst,1) + cst{i,5}.Visible = handles.VOIPlotFlag(i); + end + + matRad_indicatorWrapper(cst,pln,resultGUI_SelectedCube); + + assignin('base','cst',cst); + this.handles = handles; + end + + %H55 Callback + function sliderOffset_Callback(this, hObject, event) + handles = this.handles; + handles.profileOffset = get(hObject,'Value'); + UpdatePlot(handles); + this.handles = handles; + end + + % 57 Callback + function btn3Dview_Callback(this,hObject, event) + % hObject handle to btn3Dview (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + handles = this.handles; + + if ~isfield(handles,'axesFig3D') || ~isfield(handles,'axesFig3D') || ~isgraphics(handles.axesFig3D) + handles.fig3D = figure('Name','matRad 3D View'); + handles.axesFig3D = axes('Parent',handles.fig3D); + view(handles.axesFig3D,3); + end + %end + + UpdatePlot(handles); + + % guidata(hObject,handles); + this.handles = handles; + end + + end +end diff --git a/gui/matRad_WorkflowWidget.m b/gui/matRad_WorkflowWidget.m new file mode 100644 index 000000000..e935d820d --- /dev/null +++ b/gui/matRad_WorkflowWidget.m @@ -0,0 +1,1033 @@ +classdef matRad_WorkflowWidget < matRad_Widget + + properties + end + + methods + function this = matRad_WorkflowWidget(handleParent) + if nargin < 1 + handleParent = figure(... + 'Units','characters',... + 'Position',[138.4 -7.38461538461539 273.4 59.5384615384615],... + 'Visible','on',... + 'Color',[0.501960784313725 0.501960784313725 0.501960784313725],... 'CloseRequestFcn',@(hObject,eventdata) figure1_CloseRequestFcn(this,hObject,eventdata),... + 'IntegerHandle','off',... + 'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],... + 'MenuBar','none',... + 'Name','matRadGUI',... + 'NumberTitle','off',... + 'HandleVisibility','callback',... + 'Tag','figure1',... + 'PaperSize',[20.99999864 29.69999902]); + + end + this = this@matRad_Widget(handleParent); + end + + function changeWorkspace(obj) + notify(obj, 'workspaceChanged'); + end + end + + methods (Access = protected) + function this = createLayout(this) + h71 = this.widgetHandle; + + h72 = uicontrol(... + 'Parent',h71,... + 'Units','normalized',... + 'String','Status:',... + 'Style','text',... + 'Position',[0.318250377073907 0.107438016528926 0.120663650075415 0.12396694214876],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','text13',... + 'FontWeight','bold' ); + + h73 = uicontrol(... + 'Parent',h71,... + 'Units','normalized',... + 'String','no data loaded',... + 'Style','text',... + 'Position',[0.414781297134238 0.0247933884297521 0.371040723981901 0.214876033057851],... + 'BackgroundColor',[0.501960784313725 0.501960784313725 0.501960784313725],... + 'Tag','txtInfo',... + 'FontWeight','bold' ); + + h74 = uicontrol(... + 'Parent',h71,... + 'Units','normalized',... + 'String','Load *.mat data',... + 'Position',[0.151866151866152 0.810126582278481 0.178893178893179 0.145569620253165],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) btnLoadMat_Callback(this,hObject,eventdata),... + 'Tag','btnLoadMat',... + 'FontWeight','bold'); + + h75 = uicontrol(... + 'Parent',h71,... + 'Units','normalized',... + 'String','Calc. influence Mx',... + 'Position',[0.35006435006435 0.810126582278481 0.178893178893179 0.145569620253165],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) btnCalcDose_Callback(this,hObject,eventdata),... + 'Tag','btnCalcDose',... + 'FontWeight','bold'); + + h76 = uicontrol(... + 'Parent',h71,... + 'Units','normalized',... + 'String','Optimize',... + 'Position',[0.544401544401541 0.810126582278481 0.178893178893179 0.145569620253165],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) btnOptimize_Callback(this,hObject,eventdata),... + 'Tag','btnOptimize',... + 'FontWeight','bold'); + + h77 = uicontrol(... + 'Parent',h71,... + 'Units','normalized',... + 'String','Load DICOM',... + 'Position',[0.151866151866152 0.60126582278481 0.177606177606178 0.145569620253165],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) btnLoadDicom_Callback(this,hObject,eventdata),... + 'Tag','btnLoadDicom',... + 'FontWeight','bold' ); + + h78 = uicontrol(... + 'Parent',h71,... + 'Units','normalized',... + 'String','Refresh',... + 'Position',[0.0154440154440154 0.810126582278481 0.0849420849420849 0.145569620253165],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) btnRefresh_Callback(this,hObject,eventdata),... + 'Tag','btnRefresh',... + 'FontWeight','bold' ); + + h79 = uicontrol(... + 'Parent',h71,... + 'Units','normalized',... + 'String','Recalc',... + 'Position',[0.543114543114543 0.60126582278481 0.178893178893179 0.145569620253165],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) pushbutton_recalc_Callback(this,hObject,eventdata),... + 'Tag','pushbutton_recalc',... + 'FontWeight','bold' ); + + h80 = uicontrol(... + 'Parent',h71,... + 'Units','normalized',... + 'String','Save to GUI',... + 'Position',[0.738738738738737 0.810126582278481 0.178893178893179 0.145569620253165],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) btnSaveToGUI_Callback(this,hObject,eventdata),... + 'Tag','btnSaveToGUI',... + 'FontWeight','bold'); + + h81 = uicontrol(... + 'Parent',h71,... + 'Units','normalized',... + 'String','Export',... + 'Position',[0.74002574002574 0.60126582278481 0.178893178893179 0.145569620253165],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) btn_export_Callback(this,hObject,eventdata),... + 'Children',[],... + 'Tag','btn_export',... + 'FontWeight','bold'); + + h82 = uicontrol(... + 'Parent',h71,... + 'Units','normalized',... + 'String','Import Dose',... + 'Position',[0.738738738738738 0.392405063291139 0.178893178893179 0.145569620253165],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) importDoseButton_Callback(this, hObject,eventdata),... + 'Tag','importDoseButton',... + 'FontWeight','bold' ); + + h83 = uicontrol(... + 'Parent',h71,... + 'Units','normalized',... + 'String','Import from Binary',... + 'Position',[0.151866151866152 0.392405063291139 0.177606177606178 0.145569620253165],... + 'BackgroundColor',[0.8 0.8 0.8],... + 'Callback',@(hObject,eventdata) pushbutton_importFromBinary_Callback(this,hObject,eventdata),... + 'TooltipString','Imports a patient data set from binary datafiles describing CT and segmentations',... + 'Tag','pushbutton_importFromBinary',... + 'FontWeight','bold'); + + end + end + + methods + + % H74 Callback + function btnLoadMat_Callback(this, hObject, event) + % hObject handle to btnLoadMat (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + handles = this.handles; + + [FileName, FilePath] = uigetfile('*.mat'); + if FileName == 0 % user pressed cancel --> do nothing. + return; + end + + handles = resetGUI(hObject, handles, varargin); ...resetGUI(hObject, handles, varargin) + + try + + % delete existing workspace - parse variables from base workspace + AllVarNames = evalin('base','who'); + RefVarNames = {'ct','cst','pln','stf','dij','resultGUI'}; + + for i = 1:length(RefVarNames) + if sum(ismember(AllVarNames,RefVarNames{i}))>0 + evalin('base',['clear ', RefVarNames{i}]); + end + end + + % read new data + load([FilePath FileName]); + set(handles.legendTable,'String',{'no data loaded'}); + set(handles.popupDisplayOption,'String','no option available'); + + catch ME + handles = showError(handles,'LoadMatFileFnc: Could not load *.mat file',ME); + + % guidata(hObject,handles); + + %UpdateState(handles); + UpdatePlot(handles); + + this. handles = handles; + return + end + + try + generateCstTable(handles,cst); + handles.TableChanged = false; + set(handles.popupTypeOfPlot,'Value',1); + cst = matRad_computeVoiContoursWrapper(cst,ct); + + assignin('base','ct',ct); + assignin('base','cst',cst); + handles.State = 1; + catch ME + handles = showError(handles,'LoadMatFileFnc: Could not load *.mat file',ME); + end + + % check if a optimized plan was loaded + if exist('stf','var') + assignin('base','stf',stf); + end + if exist('pln','var') + assignin('base','pln',pln); + end + if exist('dij','var') + assignin('base','dij',dij); + end + % if exist('stf','var') && exist('dij','var') + % handles.State = 2; + % end + + if exist('resultGUI','var') + assignin('base','resultGUI',resultGUI); + % handles.State = 3; + % handles.SelectedDisplayOption ='physicalDose'; + end + + % recheck current workspace variables + AllVarNames = evalin('base','who'); + handles.AllVarNames = AllVarNames; + + if ismember('ct',AllVarNames) && ismember('cst',AllVarNames) + handles = reloadGUI(hObject, handles, ct, cst); + else + handles = reloadGUI(hObject, handles); + end + + % guidata(hObject,handles); + this.handles = handles; + + + end + + % H75 Callback + function btnCalcDose_Callback(this, hObject, eventdata) + % hObject handle to btnCalcDose (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + % http://stackoverflow.com/questions/24703962/trigger-celleditcallback-before-button-callback + % http://www.mathworks.com/matlabcentral/newsreader/view_thread/332613 + % wait some time until the CallEditCallback is finished + % Callback triggers the cst saving mechanism from GUI + + handles = this.handles; + try + % indicate that matRad is busy + % change mouse pointer to hour glass + Figures = gcf;%findobj('type','figure'); + set(Figures, 'pointer', 'watch'); + drawnow; + % disable all active objects + InterfaceObj = findobj(Figures,'Enable','on'); + set(InterfaceObj,'Enable','off'); + + %pause(0.1); + %uiTable_CellEditCallback(hObject,[],handles); + %pause(0.3); + + %% get cst from table + %if ~getCstTable(handles) + % return + %end + % read plan from gui and save it to workspace + % gets also IsoCenter from GUI if checkbox is not checked + getPlnFromGUI(handles); + + % get default iso center as center of gravity of all targets if not + % already defined + pln = evalin('base','pln'); + + if length(pln.propStf.gantryAngles) ~= length(pln.propStf.couchAngles) + handles = showWarning(handles,'number of gantryAngles != number of couchAngles'); + end + %% + if ~checkRadiationComposition(handles); + fileName = [pln.radiationMode '_' pln.machine]; + handles = showError(handles,errordlg(['Could not find the following machine file: ' fileName ])); + %guidata(hObject,handles); + this.handles = handles; + return; + end + + %% check if isocenter is already set + if ~isfield(pln.propStf,'isoCenter') + handles = showWarning(handles,'no iso center set - using center of gravity based on structures defined as TARGET'); + pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1) * matRad_getIsoCenter(evalin('base','cst'),evalin('base','ct')); + assignin('base','pln',pln); + elseif ~get(handles.checkIsoCenter,'Value') + if ~strcmp(get(handles.editIsoCenter,'String'),'multiple isoCenter') + pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1)*str2num(get(handles.editIsoCenter,'String')); + end + end + + catch ME + handles = showError(handles,'CalcDoseCallback: Error in preprocessing!',ME); + % change state from busy to normal + set(Figures, 'pointer', 'arrow'); + set(InterfaceObj,'Enable','on'); + % guidata(hObject,handles); + this.handles = handles; + return; + end + + % generate steering file + try + currPln = evalin('base','pln'); + % if we run 3d conf opt -> hijack runDao to trigger computation of + % connected bixels + if strcmp(pln.radiationMode,'photons') && get(handles.radiobutton3Dconf,'Value') + currpln.propOpt.runDAO = true; + end + stf = matRad_generateStf(evalin('base','ct'),... + evalin('base','cst'),... + currPln); + assignin('base','stf',stf); + catch ME + handles = showError(handles,'CalcDoseCallback: Error in steering file generation!',ME); + % change state from busy to normal + set(Figures, 'pointer', 'arrow'); + set(InterfaceObj,'Enable','on'); + % guidata(hObject,handles); + this.handles = handles; + return; + end + + % carry out dose calculation + try + if strcmp(pln.radiationMode,'photons') + dij = matRad_calcPhotonDose(evalin('base','ct'),stf,pln,evalin('base','cst')); + elseif strcmp(pln.radiationMode,'protons') || strcmp(pln.radiationMode,'carbon') + dij = matRad_calcParticleDose(evalin('base','ct'),stf,pln,evalin('base','cst')); + end + + % assign results to base worksapce + assignin('base','dij',dij); + handles.State = 2; + handles.TableChanged = false; + UpdateState(handles); + UpdatePlot(handles); + % guidata(hObject,handles); + this.handles = handles; + + catch ME + handles = showError(handles,'CalcDoseCallback: Error in dose calculation!',ME); + % change state from busy to normal + set(Figures, 'pointer', 'arrow'); + set(InterfaceObj,'Enable','on'); + % guidata(hObject,handles); + this.handles = handles; + return; + end + + % change state from busy to normal + set(Figures, 'pointer', 'arrow'); + set(InterfaceObj,'Enable','on'); + + % guidata(hObject,handles); + this.handles = handles; + end + + % H76 Callback + function btnOptimize_Callback(this, hObject, eventdata) + % hObject handle to btnOptimize (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + handles = this.handles; + try + % indicate that matRad is busy + % change mouse pointer to hour glass + Figures = gcf;%findobj('type','figure'); + set(Figures, 'pointer', 'watch'); + drawnow; + % disable all active objects + InterfaceObj = findobj(Figures,'Enable','on'); + set(InterfaceObj,'Enable','off'); + % wait until the table is updated + btnTableSave_Callback([],[],handles); %We don't need it? + + + % if a critical change to the cst has been made which affects the dij matrix + if handles.DijCalcWarning == true + + choice = questdlg('Overlap priorites of OAR constraints have been edited, a new OAR VOI was added or a critical row constraint was deleted. A new Dij calculation might be necessary.', ... + 'Title','Cancel','Calculate Dij then Optimize','Optimze directly','Optimze directly'); + + switch choice + case 'Cancel' + set(Figures, 'pointer', 'arrow'); + set(InterfaceObj,'Enable','on'); + % guidata(hObject,handles); + this.handles = handles; + + return; + case 'Calculate dij again and optimize' + handles.DijCalcWarning = false; + btnCalcDose_Callback(hObject, eventdata, handles) + case 'Optimze directly' + handles.DijCalcWarning = false; + end + end + + pln = evalin('base','pln'); + ct = evalin('base','ct'); + + % optimize + if get(handles.radiobutton3Dconf,'Value') && strcmp(handles.Modalities{get(handles.popupRadMode,'Value')},'photons') + % conformal plan if photons and 3d conformal + if ~matRad_checkForConnectedBixelRows(evalin('base','stf')) + error('disconnetced dose influence data in BEV - run dose calculation again with consistent settings'); + end + [resultGUIcurrentRun,usedOptimizer] = matRad_fluenceOptimization(matRad_collapseDij(evalin('base','dij')),evalin('base','cst'),pln); + resultGUIcurrentRun.w = resultGUIcurrentRun.w * ones(evalin('base','dij.totalNumOfBixels'),1); + resultGUIcurrentRun.wUnsequenced = resultGUIcurrentRun.w; + else + if pln.propOpt.runDAO + if ~matRad_checkForConnectedBixelRows(evalin('base','stf')) + error('disconnetced dose influence data in BEV - run dose calculation again with consistent settings'); + end + end + + [resultGUIcurrentRun,usedOptimizer] = matRad_fluenceOptimization(evalin('base','dij'),evalin('base','cst'),pln); + end + + %if resultGUI already exists then overwrite the "standard" fields + AllVarNames = evalin('base','who'); + if ismember('resultGUI',AllVarNames) + resultGUI = evalin('base','resultGUI'); + sNames = fieldnames(resultGUIcurrentRun); + oldNames = fieldnames(resultGUI); + if(length(oldNames) > length(sNames)) + for j = 1:length(oldNames) + if strfind(oldNames{j}, 'beam') + resultGUI = rmfield(resultGUI, oldNames{j}); + end + end + end + for j = 1:length(sNames) + resultGUI.(sNames{j}) = resultGUIcurrentRun.(sNames{j}); + end + else + resultGUI = resultGUIcurrentRun; + end + assignin('base','resultGUI',resultGUI); + + % set some values + if handles.plane == 1 + set(handles.sliderSlice,'Value',ceil(pln.propStf.isoCenter(1,2)/ct.resolution.x)); + elseif handles.plane == 2 + set(handles.sliderSlice,'Value',ceil(pln.propStf.isoCenter(1,1)/ct.resolution.y)); + elseif handles.plane == 3 + set(handles.sliderSlice,'Value',ceil(pln.propStf.isoCenter(1,3)/ct.resolution.z)); + end + + handles.State = 3; + handles.SelectedDisplayOptionIdx = 1; + if strcmp(pln.radiationMode,'carbon') || (strcmp(pln.radiationMode,'protons') && strcmp(pln.propOpt.bioOptimization,'const_RBExD')) + handles.SelectedDisplayOption = 'RBExDose'; + else + handles.SelectedDisplayOption = 'physicalDose'; + end + handles.selectedBeam = 1; + % check IPOPT status and return message for GUI user if no DAO or + % particles + if ~pln.propOpt.runDAO || ~strcmp(pln.radiationMode,'photons') + CheckOptimizerStatus(usedOptimizer,'Fluence') + end + + catch ME + handles = showError(handles,'OptimizeCallback: Could not optimize!',ME); + % change state from busy to normal + set(Figures, 'pointer', 'arrow'); + set(InterfaceObj,'Enable','on'); + % guidata(hObject,handles); + this.handles = handles; + return; + end + + % perform sequencing and DAO + try + + %% sequencing + if strcmp(pln.radiationMode,'photons') && (pln.propOpt.runSequencing || pln.propOpt.runDAO) + % resultGUI = matRad_xiaLeafSequencing(resultGUI,evalin('base','stf'),evalin('base','dij')... + % ,get(handles.editSequencingLevel,'Value')); + % resultGUI = matRad_engelLeafSequencing(resultGUI,evalin('base','stf'),evalin('base','dij')... + % ,str2double(get(handles.editSequencingLevel,'String'))); + resultGUI = matRad_siochiLeafSequencing(resultGUI,evalin('base','stf'),evalin('base','dij')... + ,str2double(get(handles.editSequencingLevel,'String'))); + + assignin('base','resultGUI',resultGUI); + end + + catch ME + handles = showError(handles,'OptimizeCallback: Could not perform sequencing',ME); + % change state from busy to normal + set(Figures, 'pointer', 'arrow'); + set(InterfaceObj,'Enable','on'); + %guidata(hObject,handles); + this.handles = handles; + return; + end + + try + %% DAO + if strcmp(pln.radiationMode,'photons') && pln.propOpt.runDAO + handles = showWarning(handles,['Observe: You are running direct aperture optimization' filesep 'This is experimental code that has not been thoroughly debugged - especially in combination with constrained optimization.']); + [resultGUI,usedOptimizer] = matRad_directApertureOptimization(evalin('base','dij'),evalin('base','cst'),... + resultGUI.apertureInfo,resultGUI,pln); + assignin('base','resultGUI',resultGUI); + % check IPOPT status and return message for GUI user + CheckOptimizerStatus(usedOptimizer,'DAO'); + end + + if strcmp(pln.radiationMode,'photons') && (pln.propOpt.runSequencing || pln.propOpt.runDAO) + matRad_visApertureInfo(resultGUI.apertureInfo); + end + + catch ME + handles = showError(handles,'OptimizeCallback: Could not perform direct aperture optimization',ME); + % change state from busy to normal + set(Figures, 'pointer', 'arrow'); + set(InterfaceObj,'Enable','on'); + % guidata(hObject,handles); + this.handles = handles; + return; + end + + % change state from busy to normal + set(Figures, 'pointer', 'arrow'); + set(InterfaceObj,'Enable','on'); + handles.dispWindow{3,1} = []; % reset dose ranges + handles.dispWindow{3,2} = []; % reset min max dose values + handles.rememberCurrAxes = false; + handles.IsoDose.Levels = 0; % ensure to use default iso dose line spacing + handles.cBarChanged = true; + + % guidata(hObject,handles); + this.handles = handles; + handles = updateIsoDoseLineCache(handles); + UpdateState(handles); + UpdatePlot(handles); + handles.rememberCurrAxes = true; + % guidata(hObject,handles); + this.handles = handles; + end + + % H77 Callback + function btnLoadDicom_Callback(this, hObject, event) + % hObject handle to btnLoadDicom (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + handles = this.handles; + try + % delete existing workspace - parse variables from base workspace + set(handles.popupDisplayOption,'String','no option available'); + AllVarNames = evalin('base','who'); + RefVarNames = {'ct','cst','pln','stf','dij','resultGUI'}; + for i = 1:length(RefVarNames) + if sum(ismember(AllVarNames,RefVarNames{i}))>0 + evalin('base',['clear ', RefVarNames{i}]); + end + end + % handles.State = 0; + matRad_importDicomWidget; % matRad_importDicomGUI; + + catch + handles = showError(handles,'DicomImport: Could not import data'); + end + % UpdateState(handles); + %guidata(hObject,handles); + this.handles = handles; + end + + % H78 Callback - button: refresh + function btnRefresh_Callback(this, hObject, event) + handles = this.handles; + handles = resetGUI(hObject, handles, varargin); ...resetGUI(hObject, handles, varargin) + %% parse variables from base workspace + AllVarNames = evalin('base','who'); + handles.AllVarNames = AllVarNames; + try + if ismember('ct',AllVarNames) && ismember('cst',AllVarNames) + ct = evalin('base','ct'); + cst = evalin('base','cst'); + %cst = setCstTable(handles,cst); + generateCstTable(handles,cst); + % handles.State = 1; + cst = matRad_computeVoiContoursWrapper(cst,ct); + assignin('base','cst',cst); + elseif ismember('ct',AllVarNames) && ~ismember('cst',AllVarNames) + % handles = showError(handles,'GUI OpeningFunc: could not find cst file'); + elseif ~ismember('ct',AllVarNames) && ismember('cst',AllVarNames) + % handles = showError(handles,'GUI OpeningFunc: could not find ct file'); + end + catch + % handles = showError(handles,'GUI OpeningFunc: Could not load ct and cst file'); + end + + if ismember('ct',AllVarNames) && ismember('cst',AllVarNames) + handles = initialize(this);... handles = reloadGUI(hObject, handles, ct, cst); + else + handles = initialize(this); ... handles = reloadGUI(hObject, handles); + end + this.handles = handles; + end + +% function btnRefresh_Callback(this, hObject, event) +% handles = this.handles; +% % handles = resetGUI(hObject, handles); +% +% %% parse variables from base workspace +% AllVarNames = evalin('base','who'); +% handles.AllVarNames = AllVarNames; +% try +% if ismember('ct',AllVarNames) && ismember('cst',AllVarNames) +% ct = evalin('base','ct'); +% cst = evalin('base','cst'); +% %cst = setCstTable(handles,cst); +% generateCstTable(handles,cst); +% % handles.State = 1; +% cst = matRad_computeVoiContoursWrapper(cst,ct); +% assignin('base','cst',cst); +% elseif ismember('ct',AllVarNames) && ~ismember('cst',AllVarNames) +% handles = showError(handles,'GUI OpeningFunc: could not find cst file'); +% elseif ~ismember('ct',AllVarNames) && ismember('cst',AllVarNames) +% % handles = showError(handles,'GUI OpeningFunc: could not find ct file'); +% end +% catch +% % handles = showError(handles,'GUI OpeningFunc: Could not load ct and cst file'); +% end +% +% if ismember('ct',AllVarNames) && ismember('cst',AllVarNames) +% handles = initialize(this);... handles = reloadGUI(hObject, handles, ct, cst); +% else +% handles = initialize(this); ... handles = reloadGUI(hObject, handles); +% end +% %guidata(hObject, handles); +% this.handles = handles; +% end + + % H79 Callback + function pushbutton_recalc_Callback(this, hObject, eventdata) + + handles = this.handles; + % recalculation only makes sense if ... + if evalin('base','exist(''pln'',''var'')') && ... + evalin('base','exist(''stf'',''var'')') && ... + evalin('base','exist(''ct'',''var'')') && ... + evalin('base','exist(''cst'',''var'')') && ... + evalin('base','exist(''resultGUI'',''var'')') + + try + + % indicate that matRad is busy + % change mouse pointer to hour glass + Figures = gcf;%findobj('type','figure'); + set(Figures, 'pointer', 'watch'); + drawnow; + % disable all active objects + InterfaceObj = findobj(Figures,'Enable','on'); + set(InterfaceObj,'Enable','off'); + + % get all data from workspace + pln = evalin('base','pln'); + stf = evalin('base','stf'); + ct = evalin('base','ct'); + cst = evalin('base','cst'); + resultGUI = evalin('base','resultGUI'); + + % get weights of the selected cube + Content = get(handles.popupDisplayOption,'String'); + SelectedCube = Content{get(handles.popupDisplayOption,'Value')}; + Suffix = strsplit(SelectedCube,'_'); + if length(Suffix)>1 + Suffix = ['_' Suffix{2}]; + else + Suffix = ''; + end + + if sum([stf.totalNumOfBixels]) ~= length(resultGUI.(['w' Suffix])) + warndlg('weight vector does not corresponding to current steering file'); + return + end + + % change isocenter if that was changed and do _not_ recreate steering + % information + for i = 1:numel(pln.propStf.gantryAngles) + stf(i).isoCenter = pln.propStf.isoCenter(i,:); + end + + % recalculate influence matrix + if strcmp(pln.radiationMode,'photons') + dij = matRad_calcPhotonDose(ct,stf,pln,cst); + elseif strcmp(pln.radiationMode,'protons') || strcmp(pln.radiationMode,'carbon') + dij = matRad_calcParticleDose(ct,stf,pln,cst); + end + + % recalculate cubes in resultGUI + resultGUIreCalc = matRad_calcCubes(resultGUI.(['w' Suffix]),dij,cst); + + % delete old variables to avoid confusion + if isfield(resultGUI,'effect') + resultGUI = rmfield(resultGUI,'effect'); + resultGUI = rmfield(resultGUI,'RBExDose'); + resultGUI = rmfield(resultGUI,'RBE'); + resultGUI = rmfield(resultGUI,'alpha'); + resultGUI = rmfield(resultGUI,'beta'); + end + + % overwrite the "standard" fields + sNames = fieldnames(resultGUIreCalc); + for j = 1:length(sNames) + resultGUI.(sNames{j}) = resultGUIreCalc.(sNames{j}); + end + + % assign results to base worksapce + assignin('base','dij',dij); + assignin('base','resultGUI',resultGUI); + + handles.State = 3; + + % show physicalDose of newly computed state + handles.SelectedDisplayOption = 'physicalDose'; + set(handles.popupDisplayOption,'Value',find(strcmp('physicalDose',Content))); + + % change state from busy to normal + set(Figures, 'pointer', 'arrow'); + set(InterfaceObj,'Enable','on'); + + handles.cBarChanged = true; + + handles = updateIsoDoseLineCache(handles); + + UpdateState(handles); + + handles.rememberCurrAxes = false; + UpdatePlot(handles); + handles.rememberCurrAxes = true; + + % guidata(hObject,handles); + this.handles = handles; + + catch ME + handles = showError(handles,'CalcDoseCallback: Error in dose recalculation!',ME); + + % change state from busy to normal + set(Figures, 'pointer', 'arrow'); + set(InterfaceObj,'Enable','on'); + + % guidata(hObject,handles); + this.handles = handles; + return; + + end + + end + end + + % H80 Callback + function btnSaveToGUI_Callback(this, hObject, eventdata) + handles = this.handles; + + Width = 400; + Height = 200; + ScreenSize = get(0,'ScreenSize'); + + % show "Provide result name" window + figHandles = get(0,'Children'); + if ~isempty(figHandles) + IdxHandle = strcmp(get(figHandles,'Name'),'Provide result name'); + else + IdxHandle = []; + end + + %check if window is already exists + if any(IdxHandle) + figDialog = figHandles(IdxHandle); + %set focus + figure(figDialog); + else + figDialog = dialog('Position',[ceil(ScreenSize(3)/2) ceil(ScreenSize(4)/2) Width Height],'Name','Provide result name','Color',[0.5 0.5 0.5]); + + uicontrol('Parent',figDialog,... + 'Style','text',... + 'Position',[20 Height - (0.35*Height) 350 60],... + 'String','Please provide a decriptive name for your optimization result:','FontSize',10,'BackgroundColor',[0.5 0.5 0.5]); + + uicontrol('Parent',figDialog,... + 'Style','edit',... + 'Position',[30 60 350 60],... + 'String','Please enter name here...','FontSize',10,'BackgroundColor',[0.55 0.55 0.55]); + + uicontrol('Parent', figDialog,'Style', 'pushbutton', 'String', 'Save','FontSize',10,... + 'Position', [0.42*Width 0.1 * Height 70 30],... + 'Callback', @(hpb,eventdata)SaveResultToGUI(hpb,eventdata,guidata(hpb))); + end + + uiwait(figDialog); + % guidata(hObject, handles); + this.handles = handles; + % UpdateState(handles) + UpdatePlot(handles) + end + + % H81 Callback + function btn_export_Callback(this, hObject, eventdata) + handles = this.handles; + % hObject handle to btn_export (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + + try + % matRad_exportGUI; + matRad_exportWidget; + catch + handles = showError(handles,'Could not export data'); + end + % UpdateState(handles); + % guidata(hObject,handles); + this.handles = handles; + end + + % H82 Callback + function importDoseButton_Callback(this, hObject, eventdata) + % hObject handle to importDoseButton (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + handles = this.handles; + + extensions{1} = '*.nrrd'; + [filenames,filepath,~] = uigetfile(extensions,'MultiSelect','on'); + + if ~iscell(filenames) + tmp = filenames; + filenames = cell(1); + filenames{1} = tmp; + end + + ct = evalin('base','ct'); + resultGUI = evalin('base','resultGUI'); + + for filename = filenames + [~,name,~] = fileparts(filename{1}); + [cube,~] = matRad_readCube(fullfile(filepath,filename{1})); + if ~isequal(ct.cubeDim, size(cube)) + errordlg('Dimensions of the imported cube do not match with ct','Import failed!','modal'); + continue; + end + + fieldname = ['import_' matlab.lang.makeValidName(name, 'ReplacementStyle','delete')]; + resultGUI.(fieldname) = cube; + end + + assignin('base','resultGUI',resultGUI); + btnRefresh_Callback(this, hObject, eventdata) + this. handles = handles, + end + + % H83 Callback + function pushbutton_importFromBinary_Callback(this, hObject, eventdata) + % hObject handle to pushbutton_importFromBinary (see GCBO) + % eventdata reserved - to be defined in a future version of MATLAB + % handles structure with handles and user data (see GUIDATA) + handles = this.handles; + + try + % delete existing workspace - parse variables from base workspace + set(handles.popupDisplayOption,'String','no option available'); + AllVarNames = evalin('base','who'); + RefVarNames = {'ct','cst','pln','stf','dij','resultGUI'}; + for i = 1:length(RefVarNames) + if sum(ismember(AllVarNames,RefVarNames{i}))>0 + evalin('base',['clear ', RefVarNames{i}]); + end + end + handles.State = 0; + + %call the gui + uiwait(matRad_importGUI); + + %Check if we have the variables in the workspace + if evalin('base','exist(''cst'',''var'')') == 1 && evalin('base','exist(''ct'',''var'')') == 1 + cst = evalin('base','cst'); + ct = evalin('base','ct'); + %setCstTable(handles,cst); + generateCstTable(hanles,cst); + handles.TableChanged = false; + set(handles.popupTypeOfPlot,'Value',1); + + % compute HU values + if ~isfield(ct, 'cubeHU') + ct = matRad_electronDensitiesToHU(ct); + assignin('base','ct',ct); + end + if ~isfield(ct, 'cubeHU') + handles.cubeHUavailable = false; + else + handles.cubeHUavailable = true; + end + + % precompute contours + cst = precomputeContours(ct,cst); + + assignin('base','ct',ct); + assignin('base','cst',cst); + + if evalin('base','exist(''pln'',''var'')') + assignin('base','pln',pln); + setPln(handles); + else + getPlnFromGUI(handles); + setPln(handles); + end + % handles.State = 1; + end + + % set slice slider + handles.plane = get(handles.popupPlane,'value'); + %if handles.State >0 + set(handles.sliderSlice,'Min',1,'Max',ct.cubeDim(handles.plane),... + 'Value',round(ct.cubeDim(handles.plane)/2),... + 'SliderStep',[1/(ct.cubeDim(handles.plane)-1) 1/(ct.cubeDim(handles.plane)-1)]); + % end + + % if handles.State > 0 + % define context menu for structures + for i = 1:size(cst,1) + if cst{i,5}.Visible + handles.VOIPlotFlag(i) = true; + else + handles.VOIPlotFlag(i) = false; + end + end + % end + + handles.dispWindow = cell(3,2); + handles.cBarChanged = true; + + % UpdateState(handles); + handles.rememberCurrAxes = false; + UpdatePlot(handles); + handles.rememberCurrAxes = true; + catch + handles = showError(handles,'Binary Patient Import: Could not import data'); + % UpdateState(handles); + end + + % guidata(hObject,handles); + this.handles = handles; + + end + + function handles = resetGUI(hObject, handles, varargin) + + [env, versionString] = matRad_getEnvironment(); + + if strcmp(env,'MATLAB') + %OpenGL only works for pc (maybe also for linux?) + if ispc + opengl software + end + end + end + + % show error + function handles = showError(handles,Message,ME) + + handles = this.handles; + if nargin == 3 + %Add exception message + if isfield(handles,'devMode') && handles.devMode + meType = 'extended'; + else + meType = 'basic'; + end + Message = {Message,ME.message};%{Message,ME.getReport(meType,'hyperlinks','off')}; + end + + if isfield(handles,'ErrorDlg') + if ishandle(handles.ErrorDlg) + close(handles.ErrorDlg); + end + end + handles.ErrorDlg = errordlg(Message); + end + + function handles = reloadGUI(hObject, handles, ct, cst) + + handles = this.handles; + AllVarNames = handles.AllVarNames; + + if ismember('ct',AllVarNames) + % compute HU values + if ~isfield(ct, 'cubeHU') + ct = matRad_electronDensitiesToHU(ct); + assignin('base','ct',ct); + end + if ~isfield(ct, 'cubeHU') + handles.cubeHUavailable = false; + else + handles.cubeHUavailable = true; + end + end + + this.handles = handles; + end + end + end + +