matRadGUI

Purpose ^

matRad GUI

Synopsis ^

function varargout = matRadGUI(varargin)

Description ^

 matRad GUI

 call
      MATRADGUI, by itself, creates a new MATRADGUI or raises the existing
      singleton*.

      H = MATRADGUI returns the handle to a new MATRADGUI or the handle to
      the existing singleton*.

      MATRADGUI('CALLBACK',hObject,eventData,handles,...) calls the local
      function named CALLBACK in MATRADGUI.M with the given input arguments.

      MATRADGUI('Property','Value',...) creates a new MATRADGUI or raises the
      existing singleton*.  Starting from the left, property value pairs are
      applied to the GUI before matRadGUI_OpeningFcn gets called.  An
      unrecognized property name or invalid value makes property application
      stop.  All inputs are passed to matRadGUI_OpeningFcn via varargin.

      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
      instance to run (singleton)".

 See also: GUIDE, GUIDATA, GUIHANDLES

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 Copyright 2015 the matRad development team.

 This file is part of the matRad project. It is subject to the license
 terms in the LICENSE file found in the top-level directory of this
 distribution and at https://github.com/e0404/matRad/LICENSES.txt. No part
 of the matRad project, including this file, may be copied, modified,
 propagated, or distributed except according to the terms contained in the
 LICENSE file.

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Cross-reference information ^

This function calls: This function is called by:

Subfunctions ^

Source code ^

0001 function varargout = matRadGUI(varargin)
0002 % matRad GUI
0003 %
0004 % call
0005 %      MATRADGUI, by itself, creates a new MATRADGUI or raises the existing
0006 %      singleton*.
0007 %
0008 %      H = MATRADGUI returns the handle to a new MATRADGUI or the handle to
0009 %      the existing singleton*.
0010 %
0011 %      MATRADGUI('CALLBACK',hObject,eventData,handles,...) calls the local
0012 %      function named CALLBACK in MATRADGUI.M with the given input arguments.
0013 %
0014 %      MATRADGUI('Property','Value',...) creates a new MATRADGUI or raises the
0015 %      existing singleton*.  Starting from the left, property value pairs are
0016 %      applied to the GUI before matRadGUI_OpeningFcn gets called.  An
0017 %      unrecognized property name or invalid value makes property application
0018 %      stop.  All inputs are passed to matRadGUI_OpeningFcn via varargin.
0019 %
0020 %      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
0021 %      instance to run (singleton)".
0022 %
0023 % See also: GUIDE, GUIDATA, GUIHANDLES
0024 %
0025 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0026 %
0027 % Copyright 2015 the matRad development team.
0028 %
0029 % This file is part of the matRad project. It is subject to the license
0030 % terms in the LICENSE file found in the top-level directory of this
0031 % distribution and at https://github.com/e0404/matRad/LICENSES.txt. No part
0032 % of the matRad project, including this file, may be copied, modified,
0033 % propagated, or distributed except according to the terms contained in the
0034 % LICENSE file.
0035 %
0036 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0037 
0038 matRad_cfg = MatRad_Config.instance();
0039 
0040 if matRad_cfg.disableGUI
0041     matRad_cfg.dispInfo('matRad GUI disabled in matRad_cfg!\n');
0042     return;
0043 end
0044 
0045 if ~isdeployed
0046     matRadRootDir = fileparts(mfilename('fullpath'));
0047     addpath(genpath(matRadRootDir));
0048 end
0049 
0050 [env, versionString] = matRad_getEnvironment();
0051 
0052 % abort for octave
0053 switch env
0054      case 'MATLAB'
0055          
0056      case 'OCTAVE'
0057          matRad_cfg.dispInfo(['matRad GUI not available for ' env ' ' versionString ' \n']);
0058          return;
0059      otherwise
0060          matRad_cfg.dispInfo('not yet tested');
0061  end
0062         
0063 % Begin initialization code - DO NOT EDIT
0064 % set platform specific look and feel
0065 if ispc
0066     lf = 'com.sun.java.swing.plaf.windows.WindowsLookAndFeel';
0067 elseif isunix
0068     lf = 'com.jgoodies.looks.plastic.Plastic3DLookAndFeel';
0069 elseif ismac
0070     lf = 'com.apple.laf.AquaLookAndFeel';
0071 end
0072 javax.swing.UIManager.setLookAndFeel(lf);
0073 
0074 gui_Singleton = 1;
0075 gui_State = struct('gui_Name',       mfilename, ...
0076                    'gui_Singleton',  gui_Singleton, ...
0077                    'gui_OpeningFcn', @matRadGUI_OpeningFcn, ...
0078                    'gui_OutputFcn',  @matRadGUI_OutputFcn, ...
0079                    'gui_LayoutFcn',  [] , ...
0080                    'gui_Callback',   []);
0081 if nargin && ischar(varargin{1})
0082     gui_State.gui_Callback = str2func(varargin{1});
0083 end
0084 
0085 if nargout
0086     [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
0087 else
0088     gui_mainfcn(gui_State, varargin{:});
0089 end
0090 
0091 % End initialization code - DO NOT EDIT
0092 
0093 function handles = resetGUI(hObject, handles, varargin)
0094 % enable opengl software rendering to visualize linewidths properly
0095 if ispc
0096   opengl software
0097 elseif ismac
0098   % opengl is not supported
0099 end
0100 
0101 % Choose default command line output for matRadGUI
0102 handles.output = hObject;
0103 %show matrad logo
0104 axes(handles.axesLogo)
0105 [im, ~, alpha] = imread('matrad_logo.png');
0106 f = image(im);
0107 axis equal off
0108 set(f, 'AlphaData', alpha);
0109 % show dkfz logo
0110 axes(handles.axesDKFZ)
0111 [im, ~, alpha] = imread('DKFZ_Logo.png');
0112 f = image(im);
0113 axis equal off;
0114 set(f, 'AlphaData', alpha);
0115 
0116 % turn off the datacursormode (since it does not allow to set scrolling
0117 % callbacks
0118 handles.dcm_obj = datacursormode(handles.figure1);
0119 set(handles.dcm_obj,'DisplayStyle','window');
0120 if strcmpi(get(handles.dcm_obj,'Enable'),'on')
0121   set(handles.dcm_obj,'Enable','off');
0122 end
0123 %Add the callback for the datacursor display
0124 set(handles.dcm_obj,'UpdateFcn',@dataCursorUpdateFunction);
0125 
0126 % set callback for scroll wheel function
0127 set(gcf,'WindowScrollWheelFcn',@matRadScrollWheelFcn);
0128 
0129 % change color of toobar but only the first time GUI is started
0130 if handles.initialGuiStart
0131   hToolbar = findall(hObject,'tag','uitoolbar1');
0132   jToolbar = get(get(hToolbar,'JavaContainer'),'ComponentPeer');
0133   jToolbar.setBorderPainted(false);
0134   color = java.awt.Color.gray;
0135   % Remove the toolbar border, to blend into figure contents
0136   jToolbar.setBackground(color);
0137   % Remove the separator line between toolbar and contents
0138   warning('off','MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame');
0139   jFrame = get(handle(hObject),'JavaFrame');
0140   jFrame.showTopSeparator(false);
0141   jtbc = jToolbar.getComponents;
0142   for idx=1:length(jtbc)
0143       jtbc(idx).setOpaque(false);
0144       jtbc(idx).setBackground(color);
0145       for childIdx = 1 : length(jtbc(idx).getComponents)
0146           jtbc(idx).getComponent(childIdx-1).setBackground(color);
0147       end
0148   end
0149 end
0150 
0151 
0152 set(handles.legendTable,'String',{'no data loaded'});
0153 % clear  VOIPlotFlag
0154 if isfield(handles,'VOIPlotFlag')
0155   handles = rmfield(handles,'VOIPlotFlag');
0156 end
0157 
0158 %seach for availabes machines
0159 handles.Modalities = {'photons','protons','carbon'};
0160 for i = 1:length(handles.Modalities)
0161   pattern = [handles.Modalities{1,i} '_*'];
0162   if isdeployed
0163       baseroot = [ctfroot filesep 'matRad'];
0164   else
0165       baseroot = fileparts(mfilename('fullpath'));
0166   end
0167   Files = dir([baseroot filesep 'basedata' filesep pattern]);
0168   
0169   for j = 1:length(Files)
0170       if ~isempty(Files)
0171           MachineName = Files(j).name(numel(handles.Modalities{1,i})+2:end-4);
0172           if isfield(handles,'Machines')
0173               if sum(strcmp(handles.Machines,MachineName)) == 0
0174                 handles.Machines{size(handles.Machines,2)+1} = MachineName;
0175               end
0176           else
0177               handles.Machines = cell(1);
0178               handles.Machines{1} = MachineName;
0179           end
0180       end
0181   end
0182 end
0183 set(handles.popUpMachine,'String',handles.Machines);
0184 
0185 
0186 vChar = get(handles.editGantryAngle,'String');
0187 if strcmp(vChar(1,1),'0') && length(vChar)==6
0188   set(handles.editGantryAngle,'String','0');
0189 end
0190 vChar = get(handles.editCouchAngle,'String');
0191 if strcmp(vChar(1,1),'0') && length(vChar)==3
0192   set(handles.editCouchAngle,'String','0')
0193 end
0194 %%
0195 % handles.State=0   no data available
0196 % handles.State=1   ct cst and pln available; ready for dose calculation
0197 % handles.State=2   ct cst and pln available and dij matric(s) are calculated;
0198 %                   ready for optimization
0199 % handles.State=3   plan is optimized
0200 
0201 
0202 % if plan is changed go back to state 1
0203 % if table VOI Type or Priorities changed go to state 1
0204 % if objective parameters changed go back to state 2
0205 handles.CutOffLevel            = 0.01; % relative cut off level for dose vis
0206 handles.IsoDose.NewIsoDoseFlag = false;
0207 handles.TableChanged           = false;
0208 handles.State                  = 0;
0209 handles.doseOpacity            = 0.6;
0210 handles.IsoDose.Levels         = 0;
0211 handles.dispWindow             = cell(3,2); % first dimension refers to the selected
0212 
0213 % do not calculate / suggest isoCenter new by default
0214 set(handles.checkIsoCenter, 'Value', 0);
0215 set(handles.editIsoCenter,'Enable','on')
0216 
0217 % suppose no ct cube in HU is available (because no ct could be available)
0218 handles.cubeHUavailable = false;
0219 % initial startup finished
0220 handles.initialGuiStart = false;
0221 guidata(hObject, handles);  
0222 % eof resetGUI
0223 
0224 
0225 % --- Initializes the slice slider for the current ct & isocenter (or sets
0226 % it to default)
0227 function initViewSliceSlider(handles)
0228 % handles    structure with handles and user data (see GUIDATA)
0229 
0230 if handles.State > 0
0231     ct = evalin('base', 'ct');
0232     
0233     %Helpers for managing the resolution and Matlab xy permutation
0234     planePermute = [2 1 3];
0235     ctRes = [ct.resolution.x ct.resolution.y ct.resolution.z];
0236     planePermIx = planePermute(handles.plane);
0237     planeDim = ct.cubeDim(handles.plane);   
0238 
0239     %Try to select the slice from defined isocenter
0240     try
0241         if evalin('base','exist(''pln'',''var'')')
0242             currPln = evalin('base','pln');
0243             
0244             if sum(currPln.propStf.isoCenter(:)) ~= 0
0245                 %currSlice = round((currPln.propStf.isoCenter(1,planePermIx)+ctRes(planePermix)/2)/ctRes(planePermIx))-1;
0246                 currSlice = round(currPln.propStf.isoCenter(1,planePermIx) / ctRes(planePermIx));
0247             end
0248         end
0249     catch
0250         currSlice = 0; %Set to zero for next if
0251     end
0252 
0253     %If no isocenter or wrong value, choose central slice
0254     if currSlice < 1 || currSlice > planeDim
0255         currSlice = ceil(planeDim/2);
0256     end
0257 
0258     set(handles.sliderSlice,'Min',1,'Max',planeDim,...
0259         'Value',currSlice,...
0260         'SliderStep',[1/(planeDim-1) 1/(planeDim-1)]);
0261 else
0262     % reset slider when nothing is loaded
0263     set(handles.sliderSlice,'Min',0,'Max',1,'Value',0,'SliderStep',[1 1]);
0264 end
0265 
0266 
0267 
0268 function handles = reloadGUI(hObject, handles, ct, cst)
0269 AllVarNames = handles.AllVarNames;
0270 
0271 if nargin >=3 && ismember('ct',AllVarNames)
0272     % compute HU values
0273     if ~isfield(ct, 'cubeHU')
0274         ct = matRad_electronDensitiesToHU(ct);
0275         assignin('base','ct',ct);
0276     end
0277     if ~isfield(ct, 'cubeHU')
0278         handles.cubeHUavailable = false;
0279     else
0280         handles.cubeHUavailable = true;
0281     end
0282 end
0283 
0284 %set plan if available - if not create one
0285 try   
0286     if ismember('pln',AllVarNames) && handles.State > 0
0287         % check if you are working with a valid pln
0288         pln = evalin('base','pln');
0289         if ~isfield(pln,'propStf')
0290             handles = showWarning(handles,'GUI OpeningFunc: Overwriting outdated pln format with default GUI pln');
0291             evalin('base','clear pln');
0292             getPlnFromGUI(handles);
0293         end
0294         setPln(handles);
0295     elseif handles.State > 0 
0296          getPlnFromGUI(handles);
0297          setPln(handles);
0298     end
0299         
0300 catch
0301        handles.State = 0;
0302        handles = showError(handles,'GUI OpeningFunc: Could not set or get pln');
0303 end
0304 
0305 % check for dij structure
0306 if ismember('dij',AllVarNames)
0307     handles.State = 2;
0308 end
0309 
0310 % check for optimized results
0311 if ismember('resultGUI',AllVarNames)
0312     handles.State = 3;
0313 end
0314 
0315 % set some default values
0316 if handles.State == 2 || handles.State == 3
0317     set(handles.popupDisplayOption,'String','physicalDose');
0318     handles.SelectedDisplayOption ='physicalDose';
0319     handles.SelectedDisplayOptionIdx=1;
0320 else
0321     handles.resultGUI = [];
0322     set(handles.popupDisplayOption,'String','no option available');
0323     handles.SelectedDisplayOption='';
0324     handles.SelectedDisplayOptionIdx=1;
0325 end
0326 
0327 % precompute iso dose lines
0328 if handles.State == 3
0329     handles = updateIsoDoseLineCache(handles);
0330 end
0331 
0332 %per default the first beam is selected for the profile plot
0333 handles.selectedBeam = 1;
0334 handles.plane = get(handles.popupPlane,'Value');
0335 handles.DijCalcWarning = false;
0336 
0337 % set slice slider
0338 initViewSliceSlider(handles);
0339 
0340 % define context menu for structures
0341 if handles.State > 0
0342     for i = 1:size(cst,1)
0343         if cst{i,5}.Visible
0344             handles.VOIPlotFlag(i) = true;
0345         else
0346             handles.VOIPlotFlag(i) = false;
0347         end
0348     end
0349 end
0350 
0351 %Initialize colormaps and windows
0352 handles.doseColorMap = 'jet';
0353 handles.ctColorMap   = 'bone';
0354 handles.cMapSize     = 64;
0355 handles.cBarChanged  = true;
0356 
0357 %Set up the colormap selection box
0358 availableColormaps = matRad_getColormap();
0359 set(handles.popupmenu_chooseColormap,'String',availableColormaps);
0360 
0361 currentCtMapIndex   = find(strcmp(availableColormaps,handles.ctColorMap));
0362 currentDoseMapIndex = find(strcmp(availableColormaps,handles.doseColorMap));
0363 
0364 if handles.State >= 1    
0365    set(handles.popupmenu_chooseColormap,'Value',currentCtMapIndex);
0366 end
0367 
0368 if handles.State >= 3
0369     set(handles.popupmenu_chooseColormap,'Value',currentDoseMapIndex);
0370 end
0371 
0372 % Update handles structure
0373 handles.profileOffset = 0;
0374 UpdateState(handles)
0375 
0376 axes(handles.axesFig)
0377 
0378 handles.rememberCurrAxes = false;
0379 UpdatePlot(handles)
0380 handles.rememberCurrAxes = true;
0381 guidata(hObject, handles);  
0382 % eof reloadGUI
0383 
0384 % --- Executes just before matRadGUI is made visible.
0385 function matRadGUI_OpeningFcn(hObject, ~, handles, varargin) 
0386 %#ok<*DEFNU>
0387 %#ok<*AGROW>
0388 % This function has no output args, see OutputFcn.
0389 % hObject    handle to figure
0390 % eventdata  reserved - to be defined in a future version of MATLAB
0391 % handles    structure with handles and user data (see GUIDATA)
0392 % varargin   command line arguments to matRadGUI (see VARARGIN)
0393 
0394 % variable to check whether GUI is opened or just refreshed / new data
0395 % loaded, since resetGUI needs to distinguish at one point
0396 
0397 handles.initialGuiStart = true;
0398 
0399 p = inputParser;
0400 addParameter(p,'devMode',false,@validateModeValue);
0401 addParameter(p,'eduMode',false,@validateModeValue);
0402 p.KeepUnmatched = true; %No error with incorrect parameters
0403 
0404 parse(p,varargin{:});
0405 parsedInput = p.Results;
0406 
0407 if ischar(parsedInput.devMode) || isstring(parsedInput.devMode)
0408     parsedInput.devMode = str2double(parsedInput.devMode);
0409 end
0410 
0411 if ischar(parsedInput.eduMode) || isstring(parsedInput.eduMode)
0412     parsedInput.eduMode = str2double(parsedInput.eduMode);
0413 end
0414 
0415 %If devMode is true, error dialogs will include the full stack trace of the error
0416 %If false, only the basic error message is shown (works for errors that
0417 %handle the MException object)
0418 handles.devMode = logical(parsedInput.devMode);
0419 if handles.devMode
0420     disp('matRadGUI starting in developer mode!');
0421 end
0422 
0423 %Enables simple educational mode which removes certain functionality from
0424 %the GUI
0425 handles.eduMode = logical(parsedInput.eduMode);
0426 if handles.eduMode
0427     disp('matRadGUI starting in educational mode!');
0428 end
0429 
0430 
0431 set(handles.radiobtnPlan,'value',0);
0432 
0433 
0434 
0435 if handles.eduMode
0436     %Visisbility in Educational Mode
0437     eduHideHandles =   {handles.radiobutton3Dconf,...
0438         handles.btnRunDAO,...
0439         handles.pushbutton_importFromBinary,...
0440         handles.btnLoadDicom,...
0441         handles.btn_export,...
0442         handles.importDoseButton};
0443     eduDisableHandles = {handles.editCouchAngle,handles.popUpMachine};
0444     cellfun(@(h) set(h,'Visible','Off'),eduHideHandles);
0445     cellfun(@(h) set(h,'Enable','Off'),eduDisableHandles);   
0446 end
0447 
0448 
0449 %Alter matRad Version string positioning
0450 vString = matRad_version();
0451 vPos = get(handles.text15,'Position');
0452 urlPos = get(handles.text31,'Position');
0453 btnPos = get(handles.btnAbout,'Position');
0454 
0455 %vPos([1 3]) = urlPos([1 3]);
0456 vPos([1 3]) = [0 1];
0457 vPos(4) = vPos(4)*1.25;
0458 btnPos(2) = 0.05;
0459 urlPos(2) = btnPos(2)+btnPos(4)+0.05;
0460 vPos(2) = urlPos(2) + urlPos(4) + 0.05;
0461 vPos(4) = 0.98 - vPos(2);
0462 
0463 set(handles.btnAbout,'Position',btnPos);
0464 set(handles.text31,'String','www.matRad.org','Position',urlPos,'Enable','inactive','ButtonDownFcn', @(~,~) web('www.matrad.org','-browser'));
0465 set(handles.text15,'String',vString,'Position',vPos);
0466 
0467 handles = resetGUI(hObject, handles);
0468 
0469 %% parse variables from base workspace
0470 AllVarNames = evalin('base','who');
0471 handles.AllVarNames = AllVarNames;
0472 try
0473     if  ismember('ct',AllVarNames) &&  ismember('cst',AllVarNames)
0474         ct  = evalin('base','ct');
0475         cst = evalin('base','cst');
0476         %cst = setCstTable(handles,cst);
0477         cst = generateCstTable(handles,cst);
0478         handles.State = 1;
0479         cst = matRad_computeVoiContoursWrapper(cst,ct);
0480         assignin('base','cst',cst);
0481 
0482     elseif ismember('ct',AllVarNames) &&  ~ismember('cst',AllVarNames)
0483          handles = showError(handles,'GUI OpeningFunc: could not find cst file');
0484     elseif ~ismember('ct',AllVarNames) &&  ismember('cst',AllVarNames)
0485          handles = showError(handles,'GUI OpeningFunc: could not find ct file');
0486     end
0487 catch
0488    handles = showError(handles,'GUI OpeningFunc: Could not load ct and cst file');
0489 end
0490 
0491 if ismember('ct',AllVarNames) &&  ismember('cst',AllVarNames)
0492     handles = reloadGUI(hObject, handles, ct, cst);
0493 else
0494     handles = reloadGUI(hObject, handles);
0495 end
0496 
0497 guidata(hObject, handles);
0498 
0499 %Validates the attributes for the command line Modes
0500 function validateModeValue(x)
0501 %When passed from OS terminal (or inline in Command Window) everything is a string
0502 if isdeployed || ischar(x) || isstring(x)
0503     x=str2double(x);
0504 end
0505 validateattributes(x,{'logical','numeric'},{'scalar','binary'});
0506 
0507 
0508 
0509 function Callback_StructVisibilty(source,~)
0510 
0511 handles = guidata(findobj('Name','matRadGUI'));
0512 
0513 contextUiChildren = get(get(handles.figure1,'UIContextMenu'),'Children');
0514 
0515 Idx = find(strcmp(get(contextUiChildren,'Label'),get(source,'Label')));
0516 if strcmp(get(source,'Checked'),'on')
0517     set(contextUiChildren(Idx),'Checked','off');
0518 else
0519     set(contextUiChildren(Idx),'Checked','on');
0520 end
0521 %guidata(findobj('Name','matRadGUI'), handles);
0522 UpdatePlot(handles);
0523 
0524 % --- Outputs from this function are returned to the command line.
0525 function varargout = matRadGUI_OutputFcn(~, ~, handles) 
0526 % varargout  cell array for returning output args (see VARARGOUT);
0527 % hObject    handle to figure
0528 % eventdata  reserved - to be defined in a future version of MATLAB
0529 % handles    structure with handles and user data (see GUIDATA)
0530 
0531 % Get default command line output from handles structure
0532 varargout{1} = handles.output;
0533 
0534 % set focus on error dialog
0535 if isfield(handles,'ErrorDlg')
0536     figure(handles.ErrorDlg)
0537 end
0538 
0539 % --- Executes on button press in btnLoadMat.
0540 function btnLoadMat_Callback(hObject, ~, handles)
0541 % hObject    handle to btnLoadMat (see GCBO)
0542 % eventdata  reserved - to be defined in a future version of MATLAB
0543 % handles    structure with handles and user data (see GUIDATA)
0544 
0545 [FileName, FilePath] = uigetfile('*.mat');
0546 if FileName == 0 % user pressed cancel --> do nothing.
0547     return;
0548 end
0549 
0550 handles = resetGUI(hObject, handles);
0551 
0552 try 
0553     
0554     % delete existing workspace - parse variables from base workspace
0555     AllVarNames = evalin('base','who');
0556     RefVarNames = {'ct','cst','pln','stf','dij','resultGUI'};
0557     
0558     for i = 1:length(RefVarNames)  
0559         if sum(ismember(AllVarNames,RefVarNames{i}))>0
0560             evalin('base',['clear ', RefVarNames{i}]);
0561         end
0562     end
0563 
0564     % read new data
0565     load([FilePath FileName]);
0566     set(handles.legendTable,'String',{'no data loaded'});
0567     set(handles.popupDisplayOption,'String','no option available');
0568     
0569 catch ME
0570     handles = showError(handles,'LoadMatFileFnc: Could not load *.mat file',ME); 
0571 
0572     guidata(hObject,handles);
0573     UpdateState(handles);
0574     UpdatePlot(handles);
0575     return
0576 end
0577 
0578 try
0579     generateCstTable(handles,cst);
0580     handles.TableChanged = false;
0581     set(handles.popupTypeOfPlot,'Value',1);
0582     cst = matRad_computeVoiContoursWrapper(cst,ct);
0583 
0584     assignin('base','ct',ct);
0585     assignin('base','cst',cst);
0586     handles.State = 1;
0587 catch ME
0588     handles = showError(handles,'LoadMatFileFnc: Could not load *.mat file',ME); 
0589 end
0590 
0591 % check if a optimized plan was loaded
0592 if exist('stf','var')
0593     assignin('base','stf',stf);
0594 end
0595 if exist('pln','var')
0596     assignin('base','pln',pln);
0597 end
0598 if exist('dij','var')
0599     assignin('base','dij',dij);
0600 end
0601 % if exist('stf','var') && exist('dij','var')
0602 %     handles.State = 2;
0603 % end
0604 
0605 if exist('resultGUI','var')
0606     assignin('base','resultGUI',resultGUI);
0607     % handles.State = 3;
0608     % handles.SelectedDisplayOption ='physicalDose';
0609 end
0610 
0611 % recheck current workspace variables
0612 AllVarNames = evalin('base','who');
0613 handles.AllVarNames = AllVarNames;
0614 
0615 if ismember('ct',AllVarNames) &&  ismember('cst',AllVarNames)
0616     handles = reloadGUI(hObject, handles, ct, cst);
0617 else
0618     handles = reloadGUI(hObject, handles);
0619 end
0620 
0621 guidata(hObject,handles);
0622 
0623 % --- Executes on button press in btnLoadDicom.
0624 function btnLoadDicom_Callback(hObject, ~, handles)
0625 % hObject    handle to btnLoadDicom (see GCBO)
0626 % eventdata  reserved - to be defined in a future version of MATLAB
0627 % handles    structure with handles and user data (see GUIDATA)
0628 try
0629     % delete existing workspace - parse variables from base workspace
0630     set(handles.popupDisplayOption,'String','no option available');
0631     AllVarNames = evalin('base','who');
0632     RefVarNames = {'ct','cst','pln','stf','dij','resultGUI'};
0633     for i = 1:length(RefVarNames)  
0634         if sum(ismember(AllVarNames,RefVarNames{i}))>0
0635             evalin('base',['clear ', RefVarNames{i}]);
0636         end
0637     end
0638     handles.State = 0;
0639     matRad_importDicomGUI;
0640  
0641 catch
0642    handles = showError(handles,'DicomImport: Could not import data'); 
0643 end
0644 UpdateState(handles);
0645 guidata(hObject,handles);
0646 
0647 
0648 % --- Executes on button press in btn_export.
0649 function btn_export_Callback(hObject, eventdata, handles)
0650 % hObject    handle to btn_export (see GCBO)
0651 % eventdata  reserved - to be defined in a future version of MATLAB
0652 % handles    structure with handles and user data (see GUIDATA)
0653 
0654 try
0655     matRad_exportGUI;
0656 catch
0657     handles = showError(handles,'Could not export data'); 
0658 end
0659 UpdateState(handles);
0660 guidata(hObject,handles);
0661 
0662 function editBixelWidth_Callback(hObject, ~, handles)
0663 % hObject    handle to editBixelWidth (see GCBO)
0664 % eventdata  reserved - to be defined in a future version of MATLAB
0665 % handles    structure with handles and user data (see GUIDATA)
0666 
0667 % Hints: get(hObject,'String') returns contents of editBixelWidth as text
0668 %        str2double(get(hObject,'String')) returns contents of editBixelWidth as a double
0669 getPlnFromGUI(handles);
0670 if handles.State > 0
0671     handles.State = 1;
0672     UpdateState(handles);
0673     guidata(hObject,handles);
0674 end
0675 
0676 function editGantryAngle_Callback(hObject, ~, handles)
0677 % hObject    handle to editGantryAngle (see GCBO)
0678 % eventdata  reserved - to be defined in a future version of MATLAB
0679 % handles    structure with handles and user data (see GUIDATA)
0680 
0681 % Hints: get(hObject,'String') returns contents of editGantryAngle as text
0682 %        str2double(get(hObject,'String')) returns contents of editGantryAngle as a double
0683 getPlnFromGUI(handles);
0684 if handles.State > 0
0685     handles.State = 1;
0686     UpdateState(handles);
0687     UpdatePlot(handles);
0688     guidata(hObject,handles);
0689 end
0690 
0691 function editCouchAngle_Callback(hObject, ~, handles)
0692 % hObject    handle to editCouchAngle (see GCBO)
0693 % eventdata  reserved - to be defined in a future version of MATLAB
0694 % handles    structure with handles and user data (see GUIDATA)
0695 
0696 % Hints: get(hObject,'String') returns contents of editCouchAngle as text
0697 %        str2double(get(hObject,'String')) returns contents of editCouchAngle as a double
0698 getPlnFromGUI(handles);
0699 if handles.State > 0
0700     handles.State = 1;
0701     UpdateState(handles);
0702     guidata(hObject,handles);
0703 end
0704 
0705 % --- Executes on selection change in popupRadMode.
0706 function popupRadMode_Callback(hObject, eventdata, handles)
0707 % hObject    handle to popupRadMode (see GCBO)
0708 % eventdata  reserved - to be defined in a future version of MATLAB
0709 % handles    structure with handles and user data (see GUIDATA)
0710 checkRadiationComposition(handles);
0711 contents      = cellstr(get(hObject,'String')); 
0712 RadIdentifier = contents{get(hObject,'Value')};
0713 contentPopUp  = get(handles.popMenuBioOpt,'String');
0714 switch RadIdentifier
0715     case 'photons'
0716 
0717         set(handles.popMenuBioOpt,'Enable','off');
0718         ix = find(strcmp(contentPopUp,'none'));
0719         set(handles.popMenuBioOpt,'Value',ix);
0720         set(handles.btnSetTissue,'Enable','off');
0721         
0722         set(handles.btnRunSequencing,'Enable','on');
0723         set(handles.btnRunDAO,'Enable','on');
0724         set(handles.radiobutton3Dconf,'Enable','on');
0725         set(handles.txtSequencing,'Enable','on');
0726         set(handles.editSequencingLevel,'Enable','on');
0727         
0728     case 'protons'
0729         
0730         set(handles.popMenuBioOpt,'Enable','on');
0731         ix = find(strcmp(contentPopUp,'const_RBExD'));
0732         set(handles.popMenuBioOpt,'Value',ix);
0733         set(handles.btnSetTissue,'Enable','on');
0734         
0735         set(handles.btnSetTissue,'Enable','off');
0736         set(handles.btnRunSequencing,'Enable','off');
0737         set(handles.btnRunDAO,'Enable','off');
0738         set(handles.radiobutton3Dconf,'Enable','off');
0739         set(handles.txtSequencing,'Enable','off');
0740         set(handles.editSequencingLevel,'Enable','off');
0741         
0742     case 'carbon'
0743 
0744         set(handles.popMenuBioOpt,'Enable','on');
0745         ix = find(strcmp(contentPopUp,'LEMIV_RBExD'));
0746         set(handles.popMenuBioOpt,'Value',ix);
0747         set(handles.btnSetTissue,'Enable','on');
0748         
0749         set(handles.btnRunSequencing,'Enable','off');
0750         set(handles.btnRunDAO,'Enable','off');
0751         set(handles.radiobutton3Dconf,'Enable','off');
0752         set(handles.txtSequencing,'Enable','off');
0753         set(handles.editSequencingLevel,'Enable','off');
0754 end
0755 
0756 if handles.State > 0
0757     pln = evalin('base','pln');
0758     if handles.State > 0 && ~strcmp(contents(get(hObject,'Value')),pln.radiationMode)
0759         
0760         % new radiation modality is photons -> just keep physicalDose
0761         if strcmp(contents(get(hObject,'Value')),'photons')
0762             try  
0763             AllVarNames = evalin('base','who');
0764                if  ismember('resultGUI',AllVarNames)
0765                    resultGUI = evalin('base','resultGUI');
0766                    if isfield(resultGUI,'alpha');    resultGUI = rmfield(resultGUI,'alpha');   end
0767                    if isfield(resultGUI,'beta');     resultGUI = rmfield(resultGUI,'beta');    end
0768                    if isfield(resultGUI,'RBExDose'); resultGUI = rmfield(resultGUI,'RBExDose');end
0769                    if isfield(resultGUI,'RBE');      resultGUI = rmfield(resultGUI,'RBE');     end
0770                    assignin('base','resultGUI',resultGUI);
0771                    handles = updateIsoDoseLineCache(handles);
0772                end   
0773             catch
0774             end
0775         elseif strcmp(contents(get(hObject,'Value')),'protons')
0776             try  
0777             AllVarNames = evalin('base','who');
0778                if  ismember('resultGUI',AllVarNames)
0779                    resultGUI = evalin('base','resultGUI');
0780                    if isfield(resultGUI,'alpha'); resultGUI = rmfield(resultGUI,'alpha');end
0781                    if isfield(resultGUI,'beta');  resultGUI = rmfield(resultGUI,'beta'); end
0782                    if isfield(resultGUI,'RBE');   resultGUI = rmfield(resultGUI,'RBE');  end
0783                    assignin('base','resultGUI',resultGUI);
0784                    handles = updateIsoDoseLineCache(handles);
0785                end
0786             catch
0787             end
0788         end
0789       
0790         guidata(hObject,handles);
0791         UpdatePlot(handles);
0792        
0793         getPlnFromGUI(handles);
0794         handles.State = 1;
0795         UpdateState(handles);
0796 
0797     end
0798          
0799 guidata(hObject,handles);
0800            
0801 end
0802 
0803 
0804 % --- Executes on button press in btnCalcDose.
0805 function btnCalcDose_Callback(hObject, ~, handles)
0806 % hObject    handle to btnCalcDose (see GCBO)
0807 % eventdata  reserved - to be defined in a future version of MATLAB
0808 % handles    structure with handles and user data (see GUIDATA)
0809 
0810 % http://stackoverflow.com/questions/24703962/trigger-celleditcallback-before-button-callback
0811 % http://www.mathworks.com/matlabcentral/newsreader/view_thread/332613
0812 % wait some time until the CallEditCallback is finished
0813 % Callback triggers the cst saving mechanism from GUI
0814 try
0815     % indicate that matRad is busy
0816     % change mouse pointer to hour glass
0817     Figures = gcf;%findobj('type','figure');
0818     set(Figures, 'pointer', 'watch'); 
0819     drawnow;
0820     % disable all active objects
0821     InterfaceObj = findobj(Figures,'Enable','on');
0822     set(InterfaceObj,'Enable','off');
0823 
0824     % read plan from gui and save it to workspace
0825     % gets also IsoCenter from GUI if checkbox is not checked
0826     getPlnFromGUI(handles);
0827 
0828     % get default iso center as center of gravity of all targets if not
0829     % already defined
0830     pln = evalin('base','pln');
0831 
0832     if length(pln.propStf.gantryAngles) ~= length(pln.propStf.couchAngles) 
0833         handles = showWarning(handles,'number of gantryAngles != number of couchAngles'); 
0834     end
0835     %%
0836     if ~checkRadiationComposition(handles)
0837         fileName = [pln.radiationMode '_' pln.machine];
0838         handles = showError(handles,errordlg(['Could not find the following machine file: ' fileName ]));
0839         guidata(hObject,handles);
0840         return;
0841     end
0842 
0843     %% check if isocenter is already set
0844     if ~isfield(pln.propStf,'isoCenter')
0845         handles = showWarning(handles,'no iso center set - using center of gravity based on structures defined as TARGET');
0846         pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1) * matRad_getIsoCenter(evalin('base','cst'),evalin('base','ct'));
0847         assignin('base','pln',pln);
0848     elseif ~get(handles.checkIsoCenter,'Value')
0849         if ~strcmp(get(handles.editIsoCenter,'String'),'multiple isoCenter')
0850             pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1)*str2num(get(handles.editIsoCenter,'String'));
0851         end
0852     end
0853 
0854 catch ME
0855     handles = showError(handles,'CalcDoseCallback: Error in preprocessing!',ME); 
0856     % change state from busy to normal
0857     set(Figures, 'pointer', 'arrow');
0858     set(InterfaceObj,'Enable','on');
0859     guidata(hObject,handles);
0860     return;
0861 end
0862 
0863 % generate steering file
0864 try 
0865     currPln = evalin('base','pln');
0866     % if we run 3d conf opt -> hijack runDao to trigger computation of
0867     % connected bixels
0868     if strcmp(pln.radiationMode,'photons') && get(handles.radiobutton3Dconf,'Value')
0869        currpln.propOpt.runDAO = true; 
0870     end
0871     stf = matRad_generateStf(evalin('base','ct'),...
0872                                      evalin('base','cst'),...
0873                                      currPln);
0874     assignin('base','stf',stf);
0875 catch ME
0876     handles = showError(handles,'CalcDoseCallback: Error in steering file generation!',ME); 
0877     % change state from busy to normal
0878     set(Figures, 'pointer', 'arrow');
0879     set(InterfaceObj,'Enable','on');
0880     guidata(hObject,handles);
0881     return;
0882 end
0883 
0884 % carry out dose calculation
0885 try
0886     if strcmp(pln.radiationMode,'photons')
0887         dij = matRad_calcPhotonDose(evalin('base','ct'),stf,pln,evalin('base','cst'));
0888     elseif strcmp(pln.radiationMode,'protons') || strcmp(pln.radiationMode,'carbon')
0889         dij = matRad_calcParticleDose(evalin('base','ct'),stf,pln,evalin('base','cst'));
0890     end
0891 
0892     % assign results to base worksapce
0893     assignin('base','dij',dij);
0894     handles.State = 2;
0895     handles.TableChanged = false;
0896     UpdateState(handles);
0897     UpdatePlot(handles);
0898     guidata(hObject,handles);
0899 catch ME
0900     handles = showError(handles,'CalcDoseCallback: Error in dose calculation!',ME); 
0901     % change state from busy to normal
0902     set(Figures, 'pointer', 'arrow');
0903     set(InterfaceObj,'Enable','on');
0904     guidata(hObject,handles);
0905     return;
0906 end
0907 
0908 % change state from busy to normal
0909 set(Figures, 'pointer', 'arrow');
0910 set(InterfaceObj,'Enable','on');
0911 
0912 guidata(hObject,handles);  
0913 
0914 
0915 
0916 %% plots ct and distributions
0917 function UpdatePlot(handles)
0918 
0919 %profile on;
0920 
0921 axes(handles.axesFig);
0922 
0923 % this is necessary to prevent multiple callbacks of update plot drawing on
0924 % top of each other in matlab <2014
0925 drawnow;
0926 
0927 defaultFontSize = 8;
0928 currAxes            = axis(handles.axesFig);
0929 AxesHandlesCT_Dose  = gobjects(0);
0930 AxesHandlesVOI      = cell(0);
0931 AxesHandlesIsoDose  = gobjects(0);
0932 
0933 if handles.State == 0
0934     cla reset
0935     return
0936 elseif handles.State > 0
0937      ct  = evalin('base','ct');
0938      cst = evalin('base','cst');
0939      pln = evalin('base','pln');
0940 end
0941 
0942 %% state 3 indicates that a optimization has been performed
0943  AllVarNames = evalin('base','who');
0944 if  ismember('resultGUI',AllVarNames)
0945     Result = evalin('base','resultGUI');
0946 end
0947 
0948 if exist('Result','var')
0949     if ~isempty(Result) && ~isempty(ct.cubeHU) && ~isfield(handles,'DispInfo')
0950         
0951         DispInfo = fieldnames(Result);
0952         
0953         for i = 1:size(DispInfo,1)
0954             
0955             % delete weight vectors in Result struct for plotting
0956             if isstruct(Result.(DispInfo{i,1})) || isvector(Result.(DispInfo{i,1}))
0957                  Result = rmfield(Result,DispInfo{i,1});
0958                  DispInfo{i,2}=false;
0959             else
0960                 %second dimension indicates if it should be plotted
0961                 DispInfo{i,2} = true;
0962                 % determine units
0963                 if strfind(DispInfo{i,1},'physicalDose')
0964                     DispInfo{i,3} = '[Gy]';
0965                 elseif strfind(DispInfo{i,1},'alpha')
0966                     DispInfo{i,3} = '[Gy^{-1}]';
0967                 elseif strfind(DispInfo{i,1},'beta')
0968                     DispInfo{i,3} = '[Gy^{-2}]';
0969                 elseif strfind(DispInfo{i,1},'RBExD')
0970                     DispInfo{i,3} = '[Gy(RBE)]';
0971                 elseif strfind(DispInfo{i,1},'LET')
0972                     DispInfo{i,3} = '[keV/um]';
0973                 else
0974                     DispInfo{i,3} = '[a.u.]';
0975                 end
0976                 DispInfo{i,4} = [];    % optional for the future: color range for plotting
0977                 DispInfo{i,5} = [];    % optional for the future: min max values
0978             end
0979         end
0980 
0981         set(handles.popupDisplayOption,'String',fieldnames(Result));
0982         if sum(strcmp(handles.SelectedDisplayOption,fieldnames(Result))) == 0
0983             handles.SelectedDisplayOption = DispInfo{find([DispInfo{:,2}],1,'first'),1};
0984         end
0985         set(handles.popupDisplayOption,'Value',find(strcmp(handles.SelectedDisplayOption,fieldnames(Result))));
0986 
0987     end
0988 end
0989 
0990 %% set and get required variables
0991 plane = get(handles.popupPlane,'Value');
0992 slice = round(get(handles.sliderSlice,'Value'));
0993 hold(handles.axesFig,'on');
0994 if get(handles.popupTypeOfPlot,'Value')==1
0995     set(handles.axesFig,'YDir','Reverse');
0996 end
0997 
0998 %% Remove colorbar?
0999 plotColorbarSelection = get(handles.popupmenu_chooseColorData,'Value');
1000 
1001 if get(handles.popupTypeOfPlot,'Value')==2 || plotColorbarSelection == 1
1002     if isfield(handles,'cBarHandel')
1003         delete(handles.cBarHandel);
1004     end
1005     %The following seems to be necessary as MATLAB messes up some stuff
1006     %with the handle storage
1007     ch = findall(gcf,'tag','Colorbar');
1008     if ~isempty(ch)
1009         delete(ch);
1010     end
1011 end
1012 
1013 selectIx = get(handles.popupmenu_chooseColorData,'Value');  
1014 
1015 cla(handles.axesFig); 
1016 %% 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
1017 if ~isempty(ct) && get(handles.popupTypeOfPlot,'Value')==1
1018     
1019     if selectIx == 3
1020         ctIx = 2;
1021     else
1022         ctIx = selectIx;
1023     end
1024     
1025     if handles.cubeHUavailable
1026         plotCtCube = ct.cubeHU;
1027         ctLabel = 'Hounsfield Units';
1028     else
1029         plotCtCube = ct.cube;
1030         ctLabel = 'Electron Density / WEQ';
1031     end
1032     
1033     ctMap = matRad_getColormap(handles.ctColorMap,handles.cMapSize);
1034     
1035     if isempty(handles.dispWindow{ctIx,2})
1036         handles.dispWindow{ctIx,2} = [min(reshape([ct.cubeHU{:}],[],1)) max(reshape([ct.cubeHU{:}],[],1))];
1037     end
1038 
1039     if get(handles.radiobtnCT,'Value')
1040         [AxesHandlesCT_Dose(end+1),~,handles.dispWindow{ctIx,1}] = matRad_plotCtSlice(handles.axesFig,plotCtCube,1,plane,slice,ctMap,handles.dispWindow{ctIx,1});
1041         
1042         % plot colorbar? If 1 the user asked for the CT
1043         if plotColorbarSelection == 2 && handles.cBarChanged
1044             %Plot the colorbar
1045             handles.cBarHandel = matRad_plotColorbar(handles.axesFig,ctMap,handles.dispWindow{ctIx,1},'fontsize',defaultFontSize);
1046             %adjust lables
1047             set(get(handles.cBarHandel,'ylabel'),'String', ctLabel,'fontsize',defaultFontSize);
1048             % do not interprete as tex syntax
1049             set(get(handles.cBarHandel,'ylabel'),'interpreter','none');
1050         end
1051     end
1052 end
1053 
1054 %% plot dose cube
1055 if handles.State >= 1 &&  get(handles.popupTypeOfPlot,'Value')== 1  && exist('Result','var')
1056         doseMap = matRad_getColormap(handles.doseColorMap,handles.cMapSize);
1057         doseIx  = 3;
1058         % if the selected display option doesn't exist then simply display
1059         % the first cube of the Result struct
1060         if ~isfield(Result,handles.SelectedDisplayOption)
1061             CubeNames = fieldnames(Result);
1062             handles.SelectedDisplayOption = CubeNames{1,1};
1063         end
1064         
1065         dose = Result.(handles.SelectedDisplayOption);
1066         
1067         % dose colorwash
1068         if ~isempty(dose) && ~isvector(dose)
1069            
1070             if isempty(handles.dispWindow{doseIx,2})
1071                 handles.dispWindow{doseIx,2} = [min(dose(:)) max(dose(:))];   % set min and max dose values
1072             end
1073             
1074             if get(handles.radiobtnDose,'Value')
1075                 [doseHandle,~,handles.dispWindow{doseIx,1}] = matRad_plotDoseSlice(handles.axesFig,dose,plane,slice,handles.CutOffLevel,handles.doseOpacity,doseMap,handles.dispWindow{doseIx,1});
1076                 AxesHandlesCT_Dose(end+1)         = doseHandle;
1077             end            
1078                     
1079             % plot colorbar?
1080             if plotColorbarSelection > 2 && handles.cBarChanged
1081                 %Plot the colorbar
1082                 handles.cBarHandel = matRad_plotColorbar(handles.axesFig,doseMap,handles.dispWindow{selectIx,1},'fontsize',defaultFontSize);
1083                 %adjust lables
1084                 Idx = find(strcmp(handles.SelectedDisplayOption,DispInfo(:,1)));
1085                 set(get(handles.cBarHandel,'ylabel'),'String', [DispInfo{Idx,1} ' ' DispInfo{Idx,3} ],'fontsize',defaultFontSize);
1086                 % do not interprete as tex syntax
1087                 set(get(handles.cBarHandel,'ylabel'),'interpreter','none');
1088             end
1089         end
1090         
1091 
1092         %% plot iso dose lines
1093         if get(handles.radiobtnIsoDoseLines,'Value')           
1094             plotLabels = get(handles.radiobtnIsoDoseLinesLabels,'Value') == 1;
1095             
1096             %Sanity Check for Contours, which actually should have been
1097             %computed before calling UpdatePlot
1098             if ~isfield(handles.IsoDose,'Contours')
1099                 try
1100                     handles.IsoDose.Contours = matRad_computeIsoDoseContours(dose,handles.IsoDose.Levels); 
1101                 catch
1102                     %If the computation didn't work, we set the field to
1103                     %empty, which will force matRad_plotIsoDoseLines to use
1104                     %matlabs contour function instead of repeating the
1105                     %failing computation every time
1106                     handles.IsoDose.Contours = [];
1107                     warning('Could not compute isodose lines! Will try slower contour function!');
1108                 end
1109             end
1110             AxesHandlesIsoDose = matRad_plotIsoDoseLines(handles.axesFig,dose,handles.IsoDose.Contours,handles.IsoDose.Levels,plotLabels,plane,slice,doseMap,handles.dispWindow{doseIx,1},'LineWidth',1.5);
1111         end
1112 end
1113 
1114 selectIx = get(handles.popupmenu_chooseColorData,'Value');
1115 set(handles.txtMinVal,'String',num2str(handles.dispWindow{selectIx,2}(1,1)));
1116 set(handles.txtMaxVal,'String',num2str(handles.dispWindow{selectIx,2}(1,2)));
1117 
1118 %% plot VOIs
1119 if get(handles.radiobtnContour,'Value') && get(handles.popupTypeOfPlot,'Value')==1 && handles.State>0
1120     AxesHandlesVOI = [AxesHandlesVOI matRad_plotVoiContourSlice(handles.axesFig,cst,ct,1,handles.VOIPlotFlag,plane,slice,[],'LineWidth',2)];
1121 end
1122 
1123 %% Set axis labels and plot iso center
1124 matRad_plotAxisLabels(handles.axesFig,ct,plane,slice,defaultFontSize);
1125 
1126 if get(handles.radioBtnIsoCenter,'Value') == 1 && get(handles.popupTypeOfPlot,'Value') == 1 && ~isempty(pln)
1127     hIsoCenterCross = matRad_plotIsoCenterMarker(handles.axesFig,pln,ct,plane,slice);
1128 end
1129 
1130 if get(handles.radiobtnPlan,'value') == 1 && ~isempty(pln)
1131     matRad_plotProjectedGantryAngles(handles.axesFig,pln,ct,plane);
1132 end
1133 
1134 % the following line ensures the plotting order (optional)
1135 % set(gca,'Children',[AxesHandlesCT_Dose hIsoCenterCross AxesHandlesIsoDose  AxesHandlesVOI ]);
1136   
1137 %set axis ratio
1138 ratios = [1/ct.resolution.x 1/ct.resolution.y 1/ct.resolution.z];
1139 set(handles.axesFig,'DataAspectRatioMode','manual');
1140 if plane == 1 
1141       res = [ratios(3) ratios(1)]./max([ratios(3) ratios(1)]);  
1142       set(handles.axesFig,'DataAspectRatio',[res 1])
1143 elseif plane == 2 % sagittal plane
1144       res = [ratios(3) ratios(2)]./max([ratios(3) ratios(2)]);  
1145       set(handles.axesFig,'DataAspectRatio',[res 1]) 
1146 elseif  plane == 3 % Axial plane
1147       res = [ratios(1) ratios(2)]./max([ratios(1) ratios(2)]);  
1148       set(handles.axesFig,'DataAspectRatio',[res 1])
1149 end
1150 
1151 
1152 %% profile plot
1153 if get(handles.popupTypeOfPlot,'Value') == 2 && exist('Result','var')
1154     % set SAD
1155     fileName = [pln.radiationMode '_' pln.machine];
1156     try
1157         load(['basedata' filesep fileName]);
1158         SAD = machine.meta.SAD;
1159     catch
1160         error(['Could not find the following machine file: ' fileName ]); 
1161     end
1162      
1163     % clear view and initialize some values
1164     cla(handles.axesFig,'reset')
1165     set(gca,'YDir','normal');
1166     ylabel('{\color{black}dose [Gy]}')
1167     cColor={'black','green','magenta','cyan','yellow','red','blue'};
1168     
1169     % Rotate the system into the beam.
1170     % passive rotation & row vector multiplication & inverted rotation requires triple matrix transpose
1171     rotMat_system_T = transpose(matRad_getRotationMatrix(pln.propStf.gantryAngles(handles.selectedBeam),pln.propStf.couchAngles(handles.selectedBeam)));
1172     
1173     if strcmp(handles.ProfileType,'longitudinal')
1174         sourcePointBEV = [handles.profileOffset -SAD   0];
1175         targetPointBEV = [handles.profileOffset  SAD   0];
1176     elseif strcmp(handles.ProfileType,'lateral')
1177         sourcePointBEV = [-SAD handles.profileOffset   0];
1178         targetPointBEV = [ SAD handles.profileOffset   0];
1179     end
1180     
1181     rotSourcePointBEV = sourcePointBEV * rotMat_system_T;
1182     rotTargetPointBEV = targetPointBEV * rotMat_system_T;
1183     
1184     % perform raytracing on the central axis of the selected beam, use unit
1185     % electron density for plotting against the geometrical depth
1186     [~,l,rho,~,ix] = matRad_siddonRayTracer(pln.propStf.isoCenter(handles.selectedBeam,:),ct.resolution,rotSourcePointBEV,rotTargetPointBEV,{0*ct.cubeHU{1}+1});
1187     d = [0 l .* rho{1}];
1188     % Calculate accumulated d sum.
1189     vX = cumsum(d(1:end-1));
1190     
1191     % this step is necessary if visualization is set to profile plot
1192     % and another optimization is carried out - set focus on GUI
1193     figHandles = get(0,'Children');
1194     idxHandle = [];
1195     if ~isempty(figHandles)
1196         v=version;
1197         if str2double(v(1:3))>= 8.5
1198             idxHandle = strcmp({figHandles(:).Name},'matRadGUI');
1199         else
1200             idxHandle = strcmp(get(figHandles,'Name'),'matRadGUI');
1201         end
1202     end
1203     figure(figHandles(idxHandle));
1204     
1205     % plot physical dose
1206     Content = get(handles.popupDisplayOption,'String');
1207     SelectedCube = Content{get(handles.popupDisplayOption,'Value')};
1208     if sum(strcmp(SelectedCube,{'physicalDose','effect','RBExDose','alpha','beta','RBE'})) > 0
1209          Suffix = '';
1210     else
1211         Idx    = find(SelectedCube == '_');
1212         Suffix = SelectedCube(Idx:end);
1213     end
1214     
1215     mPhysDose = Result.(['physicalDose' Suffix]); 
1216     PlotHandles{1} = plot(handles.axesFig,vX,mPhysDose(ix),'color',cColor{1,1},'LineWidth',3); hold on; 
1217     PlotHandles{1,2} ='physicalDose';
1218     ylabel(handles.axesFig,'dose in [Gy]');
1219     set(handles.axesFig,'FontSize',defaultFontSize);
1220     
1221     % plot counter
1222     Cnt=2;
1223     
1224     if isfield(Result,['RBE' Suffix])
1225         
1226         %disbale specific plots
1227         %DispInfo{6,2}=0;
1228         %DispInfo{5,2}=0;
1229         %DispInfo{2,2}=0;
1230         
1231         % generate two lines for ylabel
1232         StringYLabel1 = '\fontsize{8}{\color{red}RBE x dose [Gy(RBE)] \color{black}dose [Gy] ';
1233         StringYLabel2 = '';
1234         for i=1:1:size(DispInfo,1)
1235             if DispInfo{i,2} && sum(strcmp(DispInfo{i,1},{['effect' Suffix],['alpha' Suffix],['beta' Suffix]})) > 0
1236                 %physicalDose is already plotted and RBExD vs RBE is plotted later with plotyy
1237                 if ~strcmp(DispInfo{i,1},['RBExDose' Suffix]) &&...
1238                    ~strcmp(DispInfo{i,1},['RBE' Suffix]) && ...
1239                    ~strcmp(DispInfo{i,1},['physicalDose' Suffix])
1240                
1241                         mCube = Result.([DispInfo{i,1}]);
1242                         PlotHandles{Cnt,1} = plot(handles.axesFig,vX,mCube(ix),'color',cColor{1,Cnt},'LineWidth',3);hold on; 
1243                         PlotHandles{Cnt,2} = DispInfo{i,1};
1244                         StringYLabel2 = [StringYLabel2  ' \color{'  cColor{1,Cnt} '}' DispInfo{i,1} ' ['  DispInfo{i,3} ']'];
1245                         Cnt = Cnt+1;
1246                 end    
1247             end
1248         end
1249         StringYLabel2 = [StringYLabel2 '}'];
1250         % always plot RBExD against RBE
1251         mRBExDose = Result.(['RBExDose' Suffix]);
1252         vBED = mRBExDose(ix);
1253         mRBE = Result.(['RBE' Suffix]);
1254         vRBE = mRBE(ix);
1255         
1256         % plot biological dose against RBE
1257         [ax, PlotHandles{Cnt,1}, PlotHandles{Cnt+1,1}]=plotyy(handles.axesFig,vX,vBED,vX,vRBE,'plot');hold on;
1258         PlotHandles{Cnt,2}='RBExDose';
1259         PlotHandles{Cnt+1,2}='RBE';
1260          
1261         % set plotyy properties
1262         set(get(ax(2),'Ylabel'),'String','RBE [a.u.]','FontSize',8);       
1263         ylabel({StringYLabel1;StringYLabel2})
1264         set(PlotHandles{Cnt,1},'Linewidth',4,'color','r');
1265         set(PlotHandles{Cnt+1,1},'Linewidth',3,'color','b');
1266         set(ax(1),'ycolor','r')
1267         set(ax(2),'ycolor','b')
1268         set(ax,'FontSize',8);
1269         Cnt=Cnt+2;
1270     end
1271        
1272     % asses target coordinates
1273     tmpPrior = intmax;
1274     tmpSize = 0;
1275     for i=1:size(cst,1)
1276         if strcmp(cst{i,3},'TARGET') && tmpPrior >= cst{i,5}.Priority && tmpSize<numel(cst{i,4}{1})
1277            linIdxTarget = unique(cst{i,4}{1});
1278            tmpPrior=cst{i,5}.Priority;
1279            tmpSize=numel(cst{i,4}{1});
1280            VOI = cst{i,2};
1281         end
1282     end
1283     
1284     str = sprintf('profile plot - central axis of %d beam gantry angle %d? couch angle %d?',...
1285         handles.selectedBeam ,pln.propStf.gantryAngles(handles.selectedBeam),pln.propStf.couchAngles(handles.selectedBeam));
1286     h_title = title(handles.axesFig,str,'FontSize',defaultFontSize);
1287     pos = get(h_title,'Position');
1288     set(h_title,'Position',[pos(1)-40 pos(2) pos(3)])
1289     
1290     % plot target boundaries
1291     mTargetCube = zeros(ct.cubeDim);
1292     mTargetCube(linIdxTarget) = 1;
1293     vProfile = mTargetCube(ix);
1294     WEPL_Target_Entry = vX(find(vProfile,1,'first'));
1295     WEPL_Target_Exit  = vX(find(vProfile,1,'last'));
1296     PlotHandles{Cnt,2} =[VOI ' boundary'];
1297     
1298     if ~isempty(WEPL_Target_Entry) && ~isempty(WEPL_Target_Exit)
1299         hold on
1300         PlotHandles{Cnt,1} = ...
1301         plot([WEPL_Target_Entry WEPL_Target_Entry],get(handles.axesFig,'YLim'),'--','Linewidth',3,'color','k');hold on
1302         plot([WEPL_Target_Exit WEPL_Target_Exit],get(handles.axesFig,'YLim'),'--','Linewidth',3,'color','k');hold on
1303       
1304     else
1305         PlotHandles{Cnt,1} =[];
1306     end
1307     
1308    Lines  = PlotHandles(~cellfun(@isempty,PlotHandles(:,1)),1);
1309    Labels = PlotHandles(~cellfun(@isempty,PlotHandles(:,1)),2);
1310    h=legend(handles.axesFig,[Lines{:}],Labels{:});
1311    set(h,'FontSize',defaultFontSize);
1312    xlabel('radiological depth [mm]','FontSize',8);  
1313    grid on, grid minor
1314    
1315 end
1316 
1317 zoom(handles.figure1,'reset');
1318 axis(handles.axesFig,'tight');
1319 
1320 
1321 if isfield(handles,'rememberCurrAxes') && handles.rememberCurrAxes
1322     axis(currAxes);
1323 end
1324 
1325 hold(handles.axesFig,'off');
1326 
1327 handles.cBarChanged = false;
1328 guidata(handles.axesFig,handles);
1329 %guidata(gcf,handles);
1330 if get(handles.popupTypeOfPlot,'Value')==1 
1331     UpdateColormapOptions(handles);
1332 end
1333 
1334 Update3DView(handles);
1335 
1336 %profile off;
1337 %profile viewer;
1338 
1339 function Update3DView(handles)
1340 
1341 if isfield(handles,'axesFig3D') && isfield(handles,'fig3D') && isgraphics(handles.axesFig3D) && isgraphics(handles.fig3D)
1342     axesFig3D = handles.axesFig3D;
1343     fig3D = handles.fig3D;    
1344 else
1345     return
1346 end
1347 
1348 if handles.State == 0
1349     return
1350 elseif handles.State > 0
1351     AllVarNames = evalin('base','who');
1352     if  ismember('resultGUI',AllVarNames)
1353         Result = evalin('base','resultGUI');
1354     end
1355     
1356     if  ismember('stf',AllVarNames)
1357         stf = evalin('base','stf');
1358     else
1359         stf = [];
1360     end
1361 
1362     ct  = evalin('base','ct');
1363     cst = evalin('base','cst');
1364     pln = evalin('base','pln');
1365 end
1366 
1367 oldView = get(axesFig3D,'View');
1368 
1369 cla(axesFig3D);
1370 %delete(allchild(axesFig3D));
1371 
1372 %test = allchild(axesFig3D);
1373 
1374 plane = get(handles.popupPlane,'Value');
1375 slice = round(get(handles.sliderSlice,'Value'));
1376 defaultFontSize = 8;
1377 
1378 %Check if we need to precompute the surface data
1379 if size(cst,2) < 8
1380     cst = matRad_computeAllVoiSurfaces(ct,cst);
1381     assignin('base','cst',cst);
1382 end
1383 
1384 set(fig3D,'Color',0.5*[1 1 1]);
1385 set(axesFig3D,'Color',1*[0 0 0]);
1386 
1387 %% Plot 3D structures
1388 hold(axesFig3D,'on');
1389 if get(handles.radiobtnContour,'Value') && handles.State>0
1390     voiPatches = matRad_plotVois3D(axesFig3D,ct,cst,handles.VOIPlotFlag,colorcube);
1391 end
1392 
1393 %% plot the CT slice
1394 if get(handles.radiobtnCT,'Value')
1395     window = handles.dispWindow{2,1}; %(2 for ct)
1396     ctMap = matRad_getColormap(handles.ctColorMap,handles.cMapSize);
1397     ctHandle = matRad_plotCtSlice3D(axesFig3D,ct,1,plane,slice,ctMap,window);
1398 end
1399 
1400 %% plot the dose slice
1401 if handles.State >= 1 && exist('Result','var')
1402     doseMap = matRad_getColormap(handles.doseColorMap,handles.cMapSize);
1403     doseIx  = 3;
1404     % if the selected display option doesn't exist then simply display
1405     % the first cube of the Result struct
1406     if ~isfield(Result,handles.SelectedDisplayOption)
1407         CubeNames = fieldnames(Result);
1408         handles.SelectedDisplayOption = CubeNames{1,1};
1409     end
1410     
1411     dose = Result.(handles.SelectedDisplayOption);
1412     
1413     % dose colorwash
1414     if ~isempty(dose) && ~isvector(dose)
1415         
1416         if isempty(handles.dispWindow{doseIx,2})
1417             handles.dispWindow{doseIx,2} = [min(dose(:)) max(dose(:))];   % set min and max dose values
1418         end
1419         
1420         if get(handles.radiobtnDose,'Value')
1421             [doseHandle,~,handles.dispWindow{doseIx,1}] = matRad_plotDoseSlice3D(axesFig3D,ct,dose,plane,slice,handles.CutOffLevel,handles.doseOpacity,doseMap,handles.dispWindow{doseIx,1});
1422         end
1423         if get(handles.radiobtnIsoDoseLines,'Value')
1424             matRad_plotIsoDoseLines3D(axesFig3D,ct,dose,handles.IsoDose.Contours,handles.IsoDose.Levels,plane,slice,doseMap,handles.dispWindow{doseIx,1},'LineWidth',1.5);
1425         end
1426     end
1427 end
1428 
1429 if get(handles.radiobtnPlan,'Value')
1430     matRad_plotPlan3D(axesFig3D,pln,stf);
1431 end
1432 
1433 %hLight = light('Parent',axesFig3D);
1434 %camlight(hLight,'left');
1435 %lighting('gouraud');
1436 
1437 xlabel(axesFig3D,'x [voxels]','FontSize',defaultFontSize)
1438 ylabel(axesFig3D,'y [voxels]','FontSize',defaultFontSize)
1439 zlabel(axesFig3D,'z [voxels]','FontSize',defaultFontSize)
1440 title(axesFig3D,'matRad 3D view');
1441 
1442 % set axis ratio
1443 ratios = [1 1 1]; %[1/ct.resolution.x 1/ct.resolution.y 1/ct.resolution.z];
1444 ratios = ratios([2 1 3]);
1445 set(axesFig3D,'DataAspectRatioMode','manual');
1446 set(axesFig3D,'DataAspectRatio',ratios./max(ratios));
1447 
1448 set(axesFig3D,'Ydir','reverse');
1449 
1450 set(axesFig3D,'view',oldView);
1451 
1452 
1453 % --- Executes on selection change in popupPlane.
1454 function popupPlane_Callback(hObject, ~, handles)
1455 % hObject    handle to popupPlane (see GCBO)
1456 % eventdata  reserved - to be defined in a future version of MATLAB
1457 % handles    structure with handles and user data (see GUIDATA)
1458 
1459 % Hints: contents = cellstr(get(hObject,'String')) returns popupPlane contents as cell array
1460 %        contents{get(hObject,'Value')} returns selected item from popupPlane
1461 
1462 % set slice slider
1463 handles.plane = get(hObject,'value');
1464 initViewSliceSlider(handles);
1465 
1466 handles.rememberCurrAxes = false;
1467 UpdatePlot(handles);
1468 handles.rememberCurrAxes = true;
1469 guidata(hObject,handles);
1470 
1471 % --- Executes on slider movement.
1472 function sliderSlice_Callback(~, ~, handles)
1473 % hObject    handle to sliderSlice (see GCBO)
1474 % eventdata  reserved - to be defined in a future version of MATLAB
1475 % handles    structure with handles and user data (see GUIDATA)
1476 
1477 % Hints: get(hObject,'Value') returns position of slider
1478 %        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
1479 UpdatePlot(handles)
1480 
1481 % --- Executes on button press in radiobtnContour.
1482 function radiobtnContour_Callback(~, ~, handles)
1483 % hObject    handle to radiobtnContour (see GCBO)
1484 % eventdata  reserved - to be defined in a future version of MATLAB
1485 % handles    structure with handles and user data (see GUIDATA)
1486 
1487 % Hint: get(hObject,'Value') returns toggle state of radiobtnContour
1488 UpdatePlot(handles)
1489 
1490 % --- Executes on button press in radiobtnDose.
1491 function radiobtnDose_Callback(~, ~, handles)
1492 % hObject    handle to radiobtnDose (see GCBO)
1493 % eventdata  reserved - to be defined in a future version of MATLAB
1494 % handles    structure with handles and user data (see GUIDATA)
1495 
1496 % Hint: get(hObject,'Value') returns toggle state of radiobtnDose
1497 UpdatePlot(handles)
1498 
1499 % --- Executes on button press in radiobtnIsoDoseLines.
1500 function radiobtnIsoDoseLines_Callback(~, ~, handles)
1501 % hObject    handle to radiobtnIsoDoseLines (see GCBO)
1502 % eventdata  reserved - to be defined in a future version of MATLAB
1503 % handles    structure with handles and user data (see GUIDATA)
1504 
1505 % Hint: get(hObject,'Value') returns toggle state of radiobtnIsoDoseLines
1506 UpdatePlot(handles)
1507 
1508 % --- Executes on button press in btnOptimize.
1509 function btnOptimize_Callback(hObject, eventdata, handles)
1510 % hObject    handle to btnOptimize (see GCBO)
1511 % eventdata  reserved - to be defined in a future version of MATLAB
1512 % handles    structure with handles and user data (see GUIDATA)
1513 
1514 try
1515     % indicate that matRad is busy
1516     % change mouse pointer to hour glass
1517     Figures = gcf;%findobj('type','figure');
1518     set(Figures, 'pointer', 'watch'); 
1519     drawnow;
1520     % disable all active objects
1521     InterfaceObj = findobj(Figures,'Enable','on');
1522     set(InterfaceObj,'Enable','off');
1523     % wait until the table is updated
1524     btnTableSave_Callback([],[],handles); %We don't need it?
1525 
1526 
1527     % if a critical change to the cst has been made which affects the dij matrix
1528     if handles.DijCalcWarning == true
1529 
1530         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.', ...
1531         'Title','Cancel','Calculate Dij then Optimize','Optimze directly','Optimze directly');
1532 
1533         switch choice
1534             case 'Cancel'
1535                 set(Figures, 'pointer', 'arrow');
1536                 set(InterfaceObj,'Enable','on');
1537                 guidata(hObject,handles);
1538                 return;
1539             case 'Calculate dij again and optimize'
1540                 handles.DijCalcWarning = false;
1541                 btnCalcDose_Callback(hObject, eventdata, handles)      
1542             case 'Optimze directly'
1543                 handles.DijCalcWarning = false;       
1544         end
1545     end
1546     
1547     pln = evalin('base','pln');
1548     ct  = evalin('base','ct');
1549     
1550     % optimize
1551     if get(handles.radiobutton3Dconf,'Value') && strcmp(handles.Modalities{get(handles.popupRadMode,'Value')},'photons')
1552         % conformal plan if photons and 3d conformal
1553         if ~matRad_checkForConnectedBixelRows(evalin('base','stf'))
1554             error('disconnetced dose influence data in BEV - run dose calculation again with consistent settings');
1555         end
1556         [resultGUIcurrentRun,usedOptimizer] = matRad_fluenceOptimization(matRad_collapseDij(evalin('base','dij')),evalin('base','cst'),pln);
1557         resultGUIcurrentRun.w = resultGUIcurrentRun.w * ones(evalin('base','dij.totalNumOfBixels'),1);
1558         resultGUIcurrentRun.wUnsequenced = resultGUIcurrentRun.w;
1559     else
1560         if pln.propOpt.runDAO
1561         if ~matRad_checkForConnectedBixelRows(evalin('base','stf'))
1562             error('disconnetced dose influence data in BEV - run dose calculation again with consistent settings');
1563         end
1564         end
1565         
1566         [resultGUIcurrentRun,usedOptimizer] = matRad_fluenceOptimization(evalin('base','dij'),evalin('base','cst'),pln);
1567     end
1568     
1569     %if resultGUI already exists then overwrite the "standard" fields
1570     AllVarNames = evalin('base','who');
1571     if  ismember('resultGUI',AllVarNames)
1572         resultGUI = evalin('base','resultGUI');
1573         sNames = fieldnames(resultGUIcurrentRun);
1574         oldNames = fieldnames(resultGUI);
1575         if(length(oldNames) > length(sNames))
1576             for j = 1:length(oldNames)
1577             if strfind(oldNames{j}, 'beam')
1578                 resultGUI = rmfield(resultGUI, oldNames{j});
1579             end
1580             end
1581         end
1582         for j = 1:length(sNames)
1583             resultGUI.(sNames{j}) = resultGUIcurrentRun.(sNames{j});
1584         end
1585     else
1586         resultGUI = resultGUIcurrentRun;
1587     end
1588     assignin('base','resultGUI',resultGUI);
1589 
1590     % set some values
1591     if handles.plane == 1
1592         set(handles.sliderSlice,'Value',ceil(pln.propStf.isoCenter(1,2)/ct.resolution.x));
1593     elseif handles.plane == 2
1594         set(handles.sliderSlice,'Value',ceil(pln.propStf.isoCenter(1,1)/ct.resolution.y));
1595     elseif handles.plane == 3
1596         set(handles.sliderSlice,'Value',ceil(pln.propStf.isoCenter(1,3)/ct.resolution.z));
1597     end
1598 
1599     handles.State = 3;
1600     handles.SelectedDisplayOptionIdx = 1;
1601     if strcmp(pln.radiationMode,'carbon') || (strcmp(pln.radiationMode,'protons') && strcmp(pln.propOpt.bioOptimization,'const_RBExD'))
1602         handles.SelectedDisplayOption = 'RBExDose';
1603     else
1604         handles.SelectedDisplayOption = 'physicalDose';
1605     end
1606     handles.selectedBeam = 1;
1607     % check IPOPT status and return message for GUI user if no DAO or
1608     % particles
1609     if ~pln.propOpt.runDAO || ~strcmp(pln.radiationMode,'photons')
1610         CheckOptimizerStatus(usedOptimizer,'Fluence')
1611     end
1612     
1613 catch ME
1614     handles = showError(handles,'OptimizeCallback: Could not optimize!',ME); 
1615     % change state from busy to normal
1616     set(Figures, 'pointer', 'arrow');
1617     set(InterfaceObj,'Enable','on');
1618     guidata(hObject,handles);
1619     return;
1620 end
1621 
1622 % perform sequencing and DAO
1623 try
1624     
1625     %% sequencing
1626     if strcmp(pln.radiationMode,'photons') && (pln.propOpt.runSequencing || pln.propOpt.runDAO)
1627     %   resultGUI = matRad_xiaLeafSequencing(resultGUI,evalin('base','stf'),evalin('base','dij')...
1628     %       ,get(handles.editSequencingLevel,'Value'));
1629     %   resultGUI = matRad_engelLeafSequencing(resultGUI,evalin('base','stf'),evalin('base','dij')...
1630     %       ,str2double(get(handles.editSequencingLevel,'String')));
1631         resultGUI = matRad_siochiLeafSequencing(resultGUI,evalin('base','stf'),evalin('base','dij')...
1632             ,str2double(get(handles.editSequencingLevel,'String')));
1633         
1634         assignin('base','resultGUI',resultGUI);
1635     end
1636         
1637 catch ME
1638     handles = showError(handles,'OptimizeCallback: Could not perform sequencing',ME); 
1639     % change state from busy to normal
1640     set(Figures, 'pointer', 'arrow');
1641     set(InterfaceObj,'Enable','on');
1642     guidata(hObject,handles);
1643     return;
1644 end
1645 
1646 try
1647     %% DAO
1648     if strcmp(pln.radiationMode,'photons') && pln.propOpt.runDAO
1649         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.']);
1650        [resultGUI,usedOptimizer] = matRad_directApertureOptimization(evalin('base','dij'),evalin('base','cst'),...
1651            resultGUI.apertureInfo,resultGUI,pln);
1652        assignin('base','resultGUI',resultGUI);
1653        % check IPOPT status and return message for GUI user
1654        CheckOptimizerStatus(usedOptimizer,'DAO');      
1655     end
1656     
1657     if strcmp(pln.radiationMode,'photons') && (pln.propOpt.runSequencing || pln.propOpt.runDAO)
1658         matRad_visApertureInfo(resultGUI.apertureInfo);
1659     end
1660    
1661 catch ME
1662     handles = showError(handles,'OptimizeCallback: Could not perform direct aperture optimization',ME); 
1663     % change state from busy to normal
1664     set(Figures, 'pointer', 'arrow');
1665     set(InterfaceObj,'Enable','on');
1666     guidata(hObject,handles);
1667     return;
1668 end
1669 
1670 % change state from busy to normal
1671 set(Figures, 'pointer', 'arrow');
1672 set(InterfaceObj,'Enable','on');
1673 handles.dispWindow{3,1}  = [];   % reset dose ranges
1674 handles.dispWindow{3,2}  = [];   % reset min max dose values
1675 handles.rememberCurrAxes = false;
1676 handles.IsoDose.Levels   = 0;  % ensure to use default iso dose line spacing
1677 handles.cBarChanged      = true;
1678     
1679 guidata(hObject,handles);
1680 handles = updateIsoDoseLineCache(handles);
1681 UpdateState(handles);
1682 UpdatePlot(handles);
1683 handles.rememberCurrAxes = true;   
1684 guidata(hObject,handles);
1685 
1686 
1687 % the function CheckValidityPln checks if the provided plan is valid so
1688 % that it can be used further on for optimization
1689 function FlagValid = CheckValidityPln(cst)
1690 
1691 FlagValid = true;
1692 %check if mean constraint is always used in combination
1693 for i = 1:size(cst,1)
1694    if ~isempty(cst{i,6})
1695         if ~isempty(strfind([cst{i,6}.type],'mean')) && isempty(strfind([cst{i,6}.type],'square'))
1696              FlagValid = false;
1697              warndlg('mean constraint needs to be defined in addition to a second constraint (e.g. squared deviation)');
1698              break      
1699         end
1700    end
1701 end
1702 
1703 
1704 % --- Executes on selection change in popupTypeOfPlot
1705 function popupTypeOfPlot_Callback(hObject, ~, handles)
1706 
1707  % intensity plot
1708 if get(hObject,'Value') == 1  
1709     
1710     set(handles.sliderBeamSelection,'Enable','off')
1711     set(handles.sliderOffset,'Enable','off')
1712     set(handles.popupDisplayOption,'Enable','on')
1713     set(handles.btnProfileType,'Enable','off');
1714     set(handles.popupPlane,'Enable','on');
1715     set(handles.radiobtnCT,'Enable','on');
1716     set(handles.radiobtnContour,'Enable','on');
1717     set(handles.radiobtnDose,'Enable','on');
1718     set(handles.radiobtnIsoDoseLines,'Enable','on');
1719     set(handles.radiobtnIsoDoseLinesLabels,'Enable','on');
1720     set(handles.sliderSlice,'Enable','on');
1721     
1722 % profile plot
1723 elseif get(hObject,'Value') == 2
1724     
1725     if handles.State > 0
1726         if length(parseStringAsNum(get(handles.editGantryAngle,'String'),true)) > 1
1727             
1728             set(handles.sliderBeamSelection,'Enable','on');
1729             handles.selectedBeam = 1;
1730             pln = evalin('base','pln');
1731             set(handles.sliderBeamSelection,'Min',handles.selectedBeam,'Max',pln.propStf.numOfBeams,...
1732                 'Value',handles.selectedBeam,...
1733                 'SliderStep',[1/(pln.propStf.numOfBeams-1) 1/(pln.propStf.numOfBeams-1)],...
1734                 'Enable','on');
1735 
1736         else
1737             handles.selectedBeam = 1;
1738         end
1739     
1740         handles.profileOffset = get(handles.sliderOffset,'Value');
1741 
1742         vMinMax = [-100 100];
1743         vRange = sum(abs(vMinMax));
1744 
1745         ct = evalin('base','ct');
1746         if strcmp(get(handles.btnProfileType,'String'),'lateral')
1747             SliderStep = vRange/ct.resolution.x;       
1748         else
1749             SliderStep = vRange/ct.resolution.y;  
1750         end
1751         
1752         set(handles.sliderOffset,'Min',vMinMax(1),'Max',vMinMax(2),...
1753                     'Value',handles.profileOffset,...
1754                     'SliderStep',[1/SliderStep 1/SliderStep],...
1755                     'Enable','on');
1756     end
1757     
1758     
1759     set(handles.popupDisplayOption,'Enable','on');
1760     set(handles.btnProfileType,'Enable','on');
1761     set(handles.popupPlane,'Enable','off');
1762     set(handles.radiobtnCT,'Enable','off');
1763     set(handles.radiobtnContour,'Enable','off');
1764     set(handles.radiobtnDose,'Enable','off');
1765     set(handles.radiobtnIsoDoseLines,'Enable','off');
1766     set(handles.sliderSlice,'Enable','off');
1767     set(handles.radiobtnIsoDoseLinesLabels,'Enable','off');
1768     
1769     
1770     set(handles.btnProfileType,'Enable','on')
1771     
1772     if strcmp(get(handles.btnProfileType,'String'),'lateral')
1773         handles.ProfileType = 'longitudinal';
1774     else
1775         handles.ProfileType = 'lateral';
1776     end
1777     
1778 end
1779 
1780 handles.cBarChanged = true;
1781 
1782 handles.rememberCurrAxes = false;
1783 cla(handles.axesFig,'reset');
1784 UpdatePlot(handles);
1785 handles.rememberCurrAxes = true;
1786 guidata(hObject, handles);
1787 
1788 % --- Executes on selection change in popupDisplayOption.
1789 function popupDisplayOption_Callback(hObject, ~, handles)
1790 content = get(hObject,'String');
1791 handles.SelectedDisplayOption = content{get(hObject,'Value'),1};
1792 handles.SelectedDisplayOptionIdx = get(hObject,'Value');
1793 %handles.dispWindow{3,1} = []; handles.dispWindow{3,2} = [];
1794 
1795 if ~isfield(handles,'colormapLocked') || ~handles.colormapLocked
1796     handles.dispWindow{3,1} = []; handles.dispWindow{3,2} = [];
1797 end
1798 
1799 handles = updateIsoDoseLineCache(handles);
1800 handles.cBarChanged = true;
1801 guidata(hObject, handles);
1802 UpdatePlot(handles);
1803 guidata(hObject, handles);
1804 
1805 % --- Executes on slider movement.
1806 function sliderBeamSelection_Callback(hObject, ~, handles)
1807 % hObject    handle to sliderBeamSelection (see GCBO)
1808 % eventdata  reserved - to be defined in a future version of MATLAB
1809 % handles    structure with handles and user data (see GUIDATA)
1810 
1811 % Hints: get(hObject,'Value') returns position of slider
1812 %        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
1813 
1814 
1815 handles.selectedBeam = round(get(hObject,'Value'));
1816 set(hObject, 'Value', handles.selectedBeam);
1817 handles.rememberCurrAxes = false;
1818 UpdatePlot(handles);
1819 handles.rememberCurrAxes = true;
1820 guidata(hObject,handles);
1821 
1822 % --- Executes on button press in btnProfileType.
1823 function btnProfileType_Callback(hObject, ~, handles)
1824 % hObject    handle to btnProfileType (see GCBO)
1825 % eventdata  reserved - to be defined in a future version of MATLAB
1826 % handles    structure with handles and user data (see GUIDATA)
1827 if strcmp(get(hObject,'Enable') ,'on')
1828     if strcmp(handles.ProfileType,'lateral')
1829             handles.ProfileType = 'longitudinal';
1830              set(hObject,'String','lateral');
1831         else
1832             handles.ProfileType = 'lateral';
1833             set(hObject,'String','longitudinal');
1834     end
1835     
1836     handles.rememberCurrAxes = false;
1837     UpdatePlot(handles);
1838     handles.rememberCurrAxes = true;
1839 
1840     guidata(hObject, handles);
1841  
1842 end
1843 
1844 % enables/ disables buttons according to the current state
1845 function UpdateState(handles)
1846 
1847 if handles.State > 0
1848     pln = evalin('base','pln');
1849 
1850     if strcmp(pln.radiationMode,'carbon')
1851         set(handles.popMenuBioOpt,'Enable','on');
1852         set(handles.btnSetTissue,'Enable','on');
1853     elseif strcmp(pln.radiationMode,'protons')
1854         set(handles.popMenuBioOpt,'Enable','on');
1855         set(handles.btnSetTissue,'Enable','off');
1856     else
1857         set(handles.popMenuBioOpt,'Enable','off');
1858         set(handles.btnSetTissue,'Enable','off'); 
1859     end
1860     
1861     cMapControls = allchild(handles.uipanel_colormapOptions);
1862     for runHandles = cMapControls
1863         set(runHandles,'Enable','on');
1864     end
1865 end 
1866 
1867 if handles.cubeHUavailable
1868     cMapOptionsSelectList = {'None','CT (HU)','Result (i.e. dose)'};
1869     set(handles.popupmenu_windowPreset,'Visible','on');
1870     set(handles.text_windowPreset,'String','Window Preset');
1871 else
1872     cMapOptionsSelectList = {'None','CT (ED)','Result (i.e. dose)'};
1873     set(handles.popupmenu_windowPreset,'Visible','off');
1874     set(handles.text_windowPreset,'String','No available Window Presets');
1875 end
1876 handles.cBarChanged = true;
1877 
1878  switch handles.State
1879      
1880      case 0
1881       
1882       set(handles.txtInfo,'String','no data loaded');
1883       set(handles.btnCalcDose,'Enable','off');
1884       set(handles.btnOptimize ,'Enable','off');
1885       set(handles.pushbutton_recalc,'Enable','off');
1886       set(handles.btnSaveToGUI,'Enable','off');
1887       set(handles.btnDVH,'Enable','off'); 
1888       set(handles.importDoseButton,'Enable','off');
1889       set(handles.btn_export,'Enable','off');
1890       set(handles.btn3Dview,'Enable','off');
1891       
1892       cMapControls = allchild(handles.uipanel_colormapOptions);
1893       for runHandles = cMapControls
1894           set(runHandles,'Enable','off');
1895       end
1896       
1897       set(handles.popupmenu_chooseColorData,'String',cMapOptionsSelectList{1})
1898       set(handles.popupmenu_chooseColorData,'Value',1);
1899       
1900      case 1
1901      
1902       set(handles.txtInfo,'String','ready for dose calculation');
1903       set(handles.btnCalcDose,'Enable','on');
1904       set(handles.btnOptimize ,'Enable','off');
1905       set(handles.pushbutton_recalc,'Enable','off');
1906       set(handles.btnSaveToGUI,'Enable','off');
1907       set(handles.btnDVH,'Enable','off');
1908       set(handles.importDoseButton,'Enable','off');
1909       set(handles.btn_export,'Enable','on');
1910       set(handles.btn3Dview,'Enable','on');
1911       
1912       set(handles.popupmenu_chooseColorData,'String',cMapOptionsSelectList(1:2))
1913       set(handles.popupmenu_chooseColorData,'Value',2);
1914       AllVarNames = evalin('base','who');
1915       if ~isempty(AllVarNames)
1916             if  ismember('resultGUI',AllVarNames)
1917               set(handles.pushbutton_recalc,'Enable','on');
1918               set(handles.btnSaveToGUI,'Enable','on');
1919               set(handles.btnDVH,'Enable','on');
1920               set(handles.popupmenu_chooseColorData,'String',cMapOptionsSelectList(1:3))
1921               set(handles.popupmenu_chooseColorData,'Value',3);
1922             end
1923       end
1924 
1925      case 2
1926     
1927       set(handles.txtInfo,'String','ready for optimization');   
1928       set(handles.btnCalcDose,'Enable','on');
1929       set(handles.btnOptimize ,'Enable','on');
1930       set(handles.pushbutton_recalc,'Enable','off');
1931       set(handles.btnSaveToGUI,'Enable','off');
1932       set(handles.btnDVH,'Enable','off');
1933       set(handles.importDoseButton,'Enable','off');
1934       set(handles.btn_export,'Enable','on');
1935       set(handles.btn3Dview,'Enable','on');
1936       set(handles.popupmenu_chooseColorData,'String',cMapOptionsSelectList(1:2))
1937       set(handles.popupmenu_chooseColorData,'Value',2);
1938       AllVarNames = evalin('base','who');
1939       
1940       if ~isempty(AllVarNames)
1941             if  ismember('resultGUI',AllVarNames)
1942               set(handles.pushbutton_recalc,'Enable','on');
1943               set(handles.btnSaveToGUI,'Enable','on');
1944               set(handles.btnDVH,'Enable','on');
1945               set(handles.popupmenu_chooseColorData,'String',cMapOptionsSelectList(1:3))
1946               set(handles.popupmenu_chooseColorData,'Value',3);
1947             end
1948       end
1949       
1950      case 3
1951       set(handles.txtInfo,'String','plan is optimized');   
1952       set(handles.btnCalcDose,'Enable','on');
1953       set(handles.btnOptimize ,'Enable','on');
1954       set(handles.pushbutton_recalc,'Enable','on');
1955       set(handles.btnSaveToGUI,'Enable','on');
1956       set(handles.btnDVH,'Enable','on');
1957       set(handles.btn_export,'Enable','on');
1958       set(handles.btn3Dview,'Enable','on');
1959       % resultGUI struct needs to be available to import dose
1960       % otherwise inconsistent states can be achieved
1961       set(handles.importDoseButton,'Enable','on');
1962       set(handles.popupmenu_chooseColorData,'String',cMapOptionsSelectList(1:3))
1963       set(handles.popupmenu_chooseColorData,'Value',3);
1964  end
1965 
1966 guidata(handles.figure1,handles); 
1967  
1968 % fill GUI elements with plan information
1969 function setPln(handles)
1970 pln = evalin('base','pln');
1971 % sanity check of isoCenter
1972 if size(pln.propStf.isoCenter,1) ~= pln.propStf.numOfBeams && size(pln.propStf.isoCenter,1) == 1
1973   pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1) * pln.propStf.isoCenter(1,:);
1974 elseif size(pln.propStf.isoCenter,1) ~= pln.propStf.numOfBeams && size(pln.propStf.isoCenter,1) ~= 1
1975   error('Isocenter in plan file are incosistent.');
1976 end
1977 set(handles.editBixelWidth,'String',num2str(pln.propStf.bixelWidth));
1978 set(handles.editFraction,'String',num2str(pln.numOfFractions));
1979 
1980 if isfield(pln.propStf,'isoCenter')
1981     if size(unique(pln.propStf.isoCenter,'rows'),1) == 1
1982         set(handles.editIsoCenter,'String',regexprep(num2str((round(pln.propStf.isoCenter(1,:)*10))./10), '\s+', ' '));
1983         set(handles.editIsoCenter,'Enable','on');
1984         set(handles.checkIsoCenter,'Enable','on');
1985     else
1986         set(handles.editIsoCenter,'String','multiple isoCenter');
1987         set(handles.editIsoCenter,'Enable','off');
1988         set(handles.checkIsoCenter,'Value',0);
1989         set(handles.checkIsoCenter,'Enable','off');
1990     end
1991 end
1992 set(handles.editGantryAngle,'String',num2str((pln.propStf.gantryAngles)));
1993 set(handles.editCouchAngle,'String',num2str((pln.propStf.couchAngles)));
1994 set(handles.popupRadMode,'Value',find(strcmp(get(handles.popupRadMode,'String'),pln.radiationMode)));
1995 set(handles.popUpMachine,'Value',find(strcmp(get(handles.popUpMachine,'String'),pln.machine)));
1996 
1997 if ~strcmp(pln.propOpt.bioOptimization,'none')  
1998     set(handles.popMenuBioOpt,'Enable','on');
1999     contentPopUp = get(handles.popMenuBioOpt,'String');
2000     ix = find(strcmp(pln.propOpt.bioOptimization,contentPopUp));
2001     set(handles.popMenuBioOpt,'Value',ix);
2002     set(handles.btnSetTissue,'Enable','on');
2003 else
2004     set(handles.popMenuBioOpt,'Enable','off');
2005     set(handles.btnSetTissue,'Enable','off');
2006 end
2007 %% enable sequencing and DAO button if radiation mode is set to photons
2008 if strcmp(pln.radiationMode,'photons') && pln.propOpt.runSequencing
2009     set(handles.btnRunSequencing,'Enable','on');
2010     set(handles.btnRunSequencing,'Value',1);
2011 elseif strcmp(pln.radiationMode,'photons') && ~pln.propOpt.runSequencing
2012     set(handles.btnRunSequencing,'Enable','on');
2013     set(handles.btnRunSequencing,'Value',0);
2014 else
2015     set(handles.btnRunSequencing,'Enable','off');
2016 end
2017 %% enable DAO button if radiation mode is set to photons
2018 if strcmp(pln.radiationMode,'photons') && pln.propOpt.runDAO
2019     set(handles.btnRunDAO,'Enable','on');
2020     set(handles.btnRunDAO,'Value',1);
2021 elseif strcmp(pln.radiationMode,'photons') && ~pln.propOpt.runDAO
2022     set(handles.btnRunDAO,'Enable','on');
2023     set(handles.btnRunDAO,'Value',0);
2024 else
2025     set(handles.btnRunDAO,'Enable','off');
2026 end
2027 %% enable stratification level input if radiation mode is set to photons
2028 if strcmp(pln.radiationMode,'photons')
2029     set(handles.txtSequencing,'Enable','on');
2030     set(handles.radiobutton3Dconf,'Enable','on');
2031     set(handles.editSequencingLevel,'Enable','on');
2032 else
2033     set(handles.txtSequencing,'Enable','off');
2034     set(handles.radiobutton3Dconf,'Enable','off');
2035     set(handles.editSequencingLevel,'Enable','off');
2036 end
2037 
2038 % --- Executes on button press in btnTableSave.
2039 function btnTableSave_Callback(~, ~, handles)
2040 % hObject    handle to btnTableSave (see GCBO)
2041 % eventdata  reserved - to be defined in a future version of MATLAB
2042 % handles    structure with handles and user data (see GUIDATA)
2043 
2044 if get(handles.checkIsoCenter,'Value')
2045     pln = evalin('base','pln'); 
2046     pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1) * matRad_getIsoCenter(evalin('base','cst'),evalin('base','ct')); 
2047     set(handles.editIsoCenter,'String',regexprep(num2str((round(pln.propStf.isoCenter(1,:) * 10))./10), '\s+', ' '));
2048     assignin('base','pln',pln);
2049 end
2050 getPlnFromGUI(handles);
2051 
2052 % --- Executes on selection change in listBoxCmd.
2053 function listBoxCmd_Callback(hObject, ~, ~)
2054 numLines = size(get(hObject,'String'),1);
2055 set(hObject, 'ListboxTop', numLines);
2056 
2057 % --- Executes on slider movement.
2058 function sliderOffset_Callback(hObject, ~, handles)
2059 handles.profileOffset = get(hObject,'Value');
2060 UpdatePlot(handles);
2061 
2062  
2063 %% HELPER FUNCTIONS
2064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2065 
2066 % check validity of input for cst
2067 function flagValidity = CheckValidity(Val) 
2068       
2069 flagValidity = true;
2070 
2071 if ischar(Val)
2072     Val = str2num(Val);
2073 end 
2074 
2075 if length(Val) > 2
2076     warndlg('invalid input!');
2077 end
2078 
2079 if isempty(Val)
2080    warndlg('Input not a number!');
2081    flagValidity = false;        
2082 end
2083 
2084 if any(Val < 0) 
2085    warndlg('Input not a positive number!');
2086    flagValidity = false;  
2087 end
2088 
2089 % return IPOPT status as message box
2090 function CheckOptimizerStatus(usedOptimizer,OptCase) 
2091       
2092 [statusmsg,statusflag] = usedOptimizer.GetStatus();
2093     
2094 if statusflag == 0 || statusflag == 1
2095     status = 'none';
2096 else
2097     status = 'warn';
2098 end
2099 
2100 msgbox(['Optimizer finished with status ' num2str(statusflag) ' (' statusmsg ')'],'Optimizer',status,'modal');
2101 
2102 % get pln file form GUI
2103 function getPlnFromGUI(handles)
2104 
2105 % evalin pln (if existant) in order to decide whether isoCenter should be calculated
2106 % automatically
2107 if evalin('base','exist(''pln'',''var'')')
2108     pln = evalin('base','pln');
2109 end
2110 
2111 pln.propStf.bixelWidth      = parseStringAsNum(get(handles.editBixelWidth,'String'),false); % [mm] / also corresponds to lateral spot spacing for particles
2112 pln.propStf.gantryAngles    = parseStringAsNum(get(handles.editGantryAngle,'String'),true); % [???]
2113 
2114 if handles.eduMode
2115     set(handles.editCouchAngle,'String',num2str(zeros(size(pln.propStf.gantryAngles))));
2116 end
2117 
2118 pln.propStf.couchAngles     = parseStringAsNum(get(handles.editCouchAngle,'String'),true); % [???]
2119 pln.propStf.numOfBeams      = numel(pln.propStf.gantryAngles);
2120 try
2121     ct = evalin('base','ct');
2122     pln.numOfVoxels     = prod(ct.cubeDim);
2123     pln.voxelDimensions = ct.cubeDim;
2124 catch
2125 end
2126 pln.numOfFractions  = parseStringAsNum(get(handles.editFraction,'String'),false);
2127 contents            = get(handles.popupRadMode,'String'); 
2128 pln.radiationMode   = contents{get(handles.popupRadMode,'Value')}; % either photons / protons / carbon
2129 contents            = get(handles.popUpMachine,'String'); 
2130 pln.machine         = contents{get(handles.popUpMachine,'Value')}; 
2131 
2132 if (~strcmp(pln.radiationMode,'photons'))
2133     contentBioOpt = get(handles.popMenuBioOpt,'String');
2134     pln.propOpt.bioOptimization = contentBioOpt{get(handles.popMenuBioOpt,'Value'),:};
2135 else
2136     pln.propOpt.bioOptimization = 'none';
2137 end
2138 
2139 pln.propOpt.runSequencing = logical(get(handles.btnRunSequencing,'Value'));
2140 pln.propOpt.runDAO = logical(get(handles.btnRunDAO,'Value'));
2141 
2142 try
2143     cst = evalin('base','cst');
2144     if (sum(strcmp('TARGET',cst(:,3))) > 0 && get(handles.checkIsoCenter,'Value')) || ...
2145             (sum(strcmp('TARGET',cst(:,3))) > 0 && ~isfield(pln.propStf,'isoCenter'))
2146        pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1) * matRad_getIsoCenter(cst,ct);
2147        set(handles.checkIsoCenter,'Value',1);
2148     else
2149         if ~strcmp(get(handles.editIsoCenter,'String'),'multiple isoCenter')
2150             pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1) * str2num(get(handles.editIsoCenter,'String'));
2151         end
2152     end
2153 catch
2154     warning('couldnt set isocenter in getPln function')
2155 end
2156 
2157 handles.pln = pln;
2158 assignin('base','pln',pln);
2159 
2160 % parsing a string as number array
2161 function number = parseStringAsNum(stringIn,isVector)
2162 if isnumeric(stringIn)
2163     number = stringIn;
2164 else
2165     number = str2num(stringIn);
2166     if isempty(number) || length(number) > 1 && ~isVector
2167         warndlg(['could not parse all parameters (pln, optimization parameter)']); 
2168         number = NaN;
2169     elseif isVector && iscolumn(number)
2170         number = number';
2171     end
2172 end
2173 
2174 
2175 % show error
2176 function handles = showError(handles,Message,ME)
2177 
2178 if nargin == 3
2179     %Add exception message
2180     if isfield(handles,'devMode') && handles.devMode
2181         meType = 'extended';
2182     else 
2183         meType = 'basic';
2184     end
2185     Message = {Message,ME.getReport(meType,'hyperlinks','off')};    
2186 end
2187 
2188 if isfield(handles,'ErrorDlg')
2189     if ishandle(handles.ErrorDlg)
2190         close(handles.ErrorDlg);
2191     end
2192 end
2193 handles.ErrorDlg = errordlg(Message);
2194 
2195 % show warning
2196 function handles = showWarning(handles,Message,ME)
2197 
2198 if nargin == 3
2199     %Add exception message
2200     if isfield(handles,'devMode') && handles.devMode
2201         meType = 'extended';
2202     else 
2203         meType = 'basic';
2204     end
2205     Message = {Message,ME.getReport(meType,'hyperlinks','off')};    
2206 end
2207 
2208 if isfield(handles,'WarnDlg')
2209     if ishandle(handles.WarnDlg)
2210         close(handles.WarnDlg);
2211     end
2212 end
2213 handles.WarnDlg = warndlg(Message);
2214 
2215 % check for valid machine data input file
2216 function flag = checkRadiationComposition(handles)
2217 flag = true;
2218 contents = cellstr(get(handles.popUpMachine,'String'));
2219 Machine = contents{get(handles.popUpMachine,'Value')};
2220 contents = cellstr(get(handles.popupRadMode,'String'));
2221 radMod = contents{get(handles.popupRadMode,'Value')};
2222 
2223 if isdeployed
2224     baseroot = [ctfroot filesep 'matRad'];
2225 else
2226     baseroot = fileparts(mfilename('fullpath'));
2227 end
2228 FoundFile = dir([baseroot filesep 'basedata' filesep radMod '_' Machine '.mat']);
2229 
2230 
2231 if isempty(FoundFile)
2232     warndlg(['No base data available for machine: ' Machine]);
2233     flag = false;
2234 end
2235 
2236 function matRadScrollWheelFcn(src,event)
2237 
2238 % get handles
2239 handles = guidata(src);
2240 
2241 % compute new slice
2242 currSlice = round(get(handles.sliderSlice,'Value'));
2243 newSlice  = currSlice - event.VerticalScrollCount;
2244 
2245 % project to allowed set
2246 newSlice = min(newSlice,get(handles.sliderSlice,'Max'));
2247 newSlice = max(newSlice,get(handles.sliderSlice,'Min'));
2248 
2249 % update slider
2250 set(handles.sliderSlice,'Value',newSlice);
2251 
2252 % update handles object
2253 guidata(src,handles);
2254 
2255 % update plot
2256 UpdatePlot(handles);
2257 
2258 
2259 
2260 
2261 %% CALLBACKS
2262 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2263 
2264 % button: show DVH
2265 function btnDVH_Callback(~, ~, handles)
2266 
2267 resultGUI = evalin('base','resultGUI');
2268 Content = get(handles.popupDisplayOption,'String');
2269 SelectedCube = Content{get(handles.popupDisplayOption,'Value')};
2270 
2271 pln = evalin('base','pln');
2272 resultGUI_SelectedCube.physicalDose = resultGUI.(SelectedCube);
2273 
2274 if ~strcmp(pln.propOpt.bioOptimization,'none')
2275 
2276     %check if one of the default fields is selected
2277     if sum(strcmp(SelectedCube,{'physicalDose','effect','RBE,','RBExDose','alpha','beta'})) > 0
2278         resultGUI_SelectedCube.physicalDose = resultGUI.physicalDose;
2279         resultGUI_SelectedCube.RBExDose     = resultGUI.RBExDose;
2280     else
2281         Idx    = find(SelectedCube == '_');
2282         SelectedSuffix = SelectedCube(Idx(1):end);
2283         resultGUI_SelectedCube.physicalDose = resultGUI.(['physicalDose' SelectedSuffix]);
2284         resultGUI_SelectedCube.RBExDose     = resultGUI.(['RBExDose' SelectedSuffix]);
2285     end
2286 end
2287 
2288 %adapt visibilty
2289 cst = evalin('base','cst');
2290 for i = 1:size(cst,1)
2291     cst{i,5}.Visible = handles.VOIPlotFlag(i);
2292 end
2293 
2294 matRad_indicatorWrapper(cst,pln,resultGUI_SelectedCube);
2295 
2296 assignin('base','cst',cst);
2297 
2298 % radio button: plot isolines labels
2299 function radiobtnIsoDoseLinesLabels_Callback(~, ~, handles)
2300 UpdatePlot(handles);
2301 
2302 % button: refresh
2303 function btnRefresh_Callback(hObject, ~, handles)
2304 
2305 handles = resetGUI(hObject, handles);
2306 
2307 %% parse variables from base workspace
2308 AllVarNames = evalin('base','who');
2309 handles.AllVarNames = AllVarNames;
2310 try
2311     if  ismember('ct',AllVarNames) &&  ismember('cst',AllVarNames)
2312         ct  = evalin('base','ct');
2313         cst = evalin('base','cst');
2314         %cst = setCstTable(handles,cst);
2315         cst = generateCstTable(handles,cst);
2316         handles.State = 1;
2317         cst = matRad_computeVoiContoursWrapper(cst,ct);
2318         assignin('base','cst',cst);
2319         handles = reloadGUI(hObject, handles, ct, cst);
2320     elseif ismember('ct',AllVarNames) &&  ~ismember('cst',AllVarNames)
2321         handles = showError(handles,'GUI OpeningFunc: could not find cst file');
2322         ct  = evalin('base','ct');
2323         handles = reloadGUI(hObject,handles,ct);
2324     elseif ~ismember('ct',AllVarNames) &&  ismember('cst',AllVarNames)
2325         handles = showError(handles,'GUI OpeningFunc: could not find ct file');
2326         handles = reloadGUI(hObject, handles);
2327     else
2328         handles = reloadGUI(hObject, handles);
2329     end
2330 catch
2331     handles = showError(handles,'GUI OpeningFunc: Could not load ct and cst file');
2332     handles = reloadGUI(hObject, handles);
2333 end
2334 
2335 guidata(hObject, handles);
2336 
2337 
2338 % text box: # fractions
2339 function editFraction_Callback(hObject, ~, handles)
2340 getPlnFromGUI(handles);
2341 guidata(hObject,handles);
2342 
2343 % text box: stratification levels
2344 function editSequencingLevel_Callback(~, ~, ~)
2345 
2346 % text box: isoCenter in [mm]
2347 function editIsoCenter_Callback(hObject, ~, handles)
2348 
2349 pln = evalin('base','pln');
2350 tmpIsoCenter = str2num(get(hObject,'String'));
2351 
2352 if length(tmpIsoCenter) == 3
2353     if sum(any(unique(pln.propStf.isoCenter,'rows')~=tmpIsoCenter))
2354         pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1)*tmpIsoCenter;
2355         handles.State = 1;
2356         UpdateState(handles);
2357     end
2358 else
2359     handles = showError(handles,'EditIsoCenterCallback: Could not set iso center');
2360 end
2361 
2362 assignin('base','pln',pln);
2363 guidata(hObject,handles);
2364 
2365 % check box: iso center auto
2366 function checkIsoCenter_Callback(hObject, ~, handles)
2367 
2368 W = evalin('base','whos');
2369 doesPlnExist = ismember('pln',{W(:).name});
2370 
2371 if get(hObject,'Value') && doesPlnExist
2372     pln = evalin('base','pln');
2373     if ~isfield(pln.propStf,'isoCenter')
2374         pln.propStf.isoCenter = NaN;
2375     end
2376     tmpIsoCenter = matRad_getIsoCenter(evalin('base','cst'),evalin('base','ct'));
2377     if ~isequal(tmpIsoCenter,pln.propStf.isoCenter)
2378         pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1)*tmpIsoCenter;
2379         handles.State = 1;
2380         UpdateState(handles);
2381     end
2382     set(handles.editIsoCenter,'String',regexprep(num2str((round(tmpIsoCenter*10))./10), '\s+', ' '));
2383     set(handles.editIsoCenter,'Enable','off')
2384     assignin('base','pln',pln);
2385 else
2386     set(handles.editIsoCenter,'Enable','on')
2387 end
2388 
2389 % radio button: run sequencing
2390 function btnRunSequencing_Callback(~, ~, handles)
2391 getPlnFromGUI(handles);
2392 
2393 % radio button: run direct aperture optimization
2394 function btnRunDAO_Callback(~, ~, handles)
2395 getPlnFromGUI(handles);
2396 
2397 % button: set iso dose levels
2398 function btnSetIsoDoseLevels_Callback(hObject, ~, handles)
2399 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']};
2400 if isequal(handles.IsoDose.Levels,0) || ~isvector(handles.IsoDose.Levels) || any(~isnumeric(handles.IsoDose.Levels)) || any(isnan(handles.IsoDose.Levels))
2401     defaultLine = {'1 2 3 '};
2402 else
2403     if isrow(handles.IsoDose.Levels)
2404         defaultLine = cellstr(num2str(handles.IsoDose.Levels,'%.2g '));
2405     else 
2406         defaultLine = cellstr(num2str(handles.IsoDose.Levels','%.2g '));
2407     end
2408 end
2409 
2410 try
2411     Input = inputdlg(prompt,'Set iso dose levels ', [1 70],defaultLine);
2412     if ~isempty(Input)
2413         handles.IsoDose.Levels = (sort(str2num(Input{1})));
2414         if length(handles.IsoDose.Levels) == 1 && (handles.IsoDose.Levels(1) ~= 0)
2415             handles.IsoDose.Levels = [handles.IsoDose.Levels handles.IsoDose.Levels];
2416         end
2417         handles.IsoDose.NewIsoDoseFlag = true;
2418     end
2419 catch
2420     warning('Couldnt parse iso dose levels - using default values');
2421     handles.IsoDose.Levels = 0;
2422 end
2423 handles = updateIsoDoseLineCache(handles);
2424 handles.IsoDose.NewIsoDoseFlag = false;
2425 UpdatePlot(handles);
2426 guidata(hObject,handles);
2427 
2428 
2429 % popup menu: machine
2430 function popUpMachine_Callback(hObject, ~, handles)
2431 contents = cellstr(get(hObject,'String'));
2432 checkRadiationComposition(handles);
2433 if handles.State > 0
2434     pln = evalin('base','pln');
2435     if handles.State > 0 && ~strcmp(contents(get(hObject,'Value')),pln.machine)
2436         handles.State = 1;
2437         UpdateState(handles);
2438         guidata(hObject,handles);
2439     end
2440    getPlnFromGUI(handles);
2441 end
2442 
2443 % toolbar load button
2444 function toolbarLoad_ClickedCallback(hObject, eventdata, handles)
2445 btnLoadMat_Callback(hObject, eventdata, handles);
2446 
2447 % toolbar save button
2448 function toolbarSave_ClickedCallback(hObject, eventdata, handles)
2449 
2450 btnTableSave_Callback(hObject, eventdata, handles);
2451 
2452 try
2453 
2454     if handles.State > 0
2455         ct  = evalin('base','ct');
2456         cst = evalin('base','cst');
2457         pln = evalin('base','pln');
2458     end
2459 
2460     if handles.State > 1
2461        stf = evalin('base','stf');
2462        dij = evalin('base','dij');
2463     end
2464 
2465     if handles.State > 2
2466        resultGUI = evalin('base','resultGUI');
2467     end
2468 
2469     switch handles.State
2470         case 1
2471             uisave({'cst','ct','pln'});
2472         case 2
2473             uisave({'cst','ct','pln','stf','dij'});
2474         case 3
2475             uisave({'cst','ct','pln','stf','dij','resultGUI'});
2476     end
2477 
2478 catch
2479      handles = showWarning(handles,'Could not save files'); 
2480 end
2481 guidata(hObject,handles); 
2482 
2483 % button: about
2484 function btnAbout_Callback(hObject, eventdata, handles)
2485 
2486 [~,matRadVer] = matRad_version;
2487 
2488 msg{1} = ['matRad ''' matRadVer.name '''']; %Name
2489 if handles.eduMode
2490     msg{1} = [msg{1} ' Educational'];
2491 end
2492 msg{end+1} = sprintf('v%d.%d.%d',matRadVer.major,matRadVer.minor,matRadVer.patch); %Version Number
2493 if isdeployed
2494    msg{end+1} = 'Standalone Version';
2495 elseif ~isempty(matRadVer.branch) && ~isempty(matRadVer.commitID)
2496     msg{end+1} = sprintf('Git: Branch %s, commit %s',matRadVer.branch,matRadVer.commitID(1:8));
2497 end
2498 
2499 [env,envver]  = matRad_getEnvironment();
2500 msg{end+1} = sprintf('Environment: %s v%s %s',env,envver,version('-release'));
2501 
2502 msg{end+1} = 'Web: www.matrad.org';
2503 msg{end+1} = 'E-Mail: contact@matrad.org';
2504 
2505 msgbox(msg,'About matRad');
2506 
2507 % button: close
2508 function figure1_CloseRequestFcn(hObject, ~, ~)
2509 set(0,'DefaultUicontrolBackgroundColor',[0.5 0.5 0.5]);     
2510 selection = questdlg('Do you really want to close matRad?',...
2511                      'Close matRad',...
2512                      'Yes','No','Yes');
2513 
2514 %BackgroundColor',[0.5 0.5 0.5]
2515  switch selection
2516    case 'Yes'
2517      delete(hObject);
2518    case 'No'
2519      return
2520  end
2521 
2522 % --- Executes on button press in pushbutton_recalc.
2523 function pushbutton_recalc_Callback(hObject, ~, handles)
2524 
2525 % recalculation only makes sense if ...
2526 if evalin('base','exist(''pln'',''var'')') && ...
2527    evalin('base','exist(''stf'',''var'')') && ...
2528    evalin('base','exist(''ct'',''var'')') && ...
2529    evalin('base','exist(''cst'',''var'')') && ...
2530    evalin('base','exist(''resultGUI'',''var'')')
2531 
2532 try
2533 
2534     % indicate that matRad is busy
2535     % change mouse pointer to hour glass
2536     Figures = gcf;%findobj('type','figure');
2537     set(Figures, 'pointer', 'watch'); 
2538     drawnow;
2539     % disable all active objects
2540     InterfaceObj = findobj(Figures,'Enable','on');
2541     set(InterfaceObj,'Enable','off');
2542     
2543     % get all data from workspace
2544     pln       = evalin('base','pln');
2545     stf       = evalin('base','stf');
2546     ct        = evalin('base','ct');
2547     cst       = evalin('base','cst');
2548     resultGUI = evalin('base','resultGUI');
2549     
2550     % get weights of the selected cube
2551     Content = get(handles.popupDisplayOption,'String');
2552     SelectedCube = Content{get(handles.popupDisplayOption,'Value')};
2553     Suffix = strsplit(SelectedCube,'_');
2554     if length(Suffix)>1
2555         Suffix = ['_' Suffix{2}];
2556     else
2557         Suffix = '';
2558     end
2559     
2560     if sum([stf.totalNumOfBixels]) ~= length(resultGUI.(['w' Suffix]))
2561         warndlg('weight vector does not corresponding to current steering file');
2562         return
2563     end
2564     
2565     % change isocenter if that was changed and do _not_ recreate steering
2566     % information
2567     for i = 1:numel(pln.propStf.gantryAngles)
2568         stf(i).isoCenter = pln.propStf.isoCenter(i,:);
2569     end
2570 
2571     % recalculate influence matrix
2572     if strcmp(pln.radiationMode,'photons')
2573         dij = matRad_calcPhotonDose(ct,stf,pln,cst);
2574     elseif strcmp(pln.radiationMode,'protons') || strcmp(pln.radiationMode,'carbon')
2575         dij = matRad_calcParticleDose(ct,stf,pln,cst);
2576     end
2577 
2578     % recalculate cubes in resultGUI
2579     resultGUIreCalc = matRad_calcCubes(resultGUI.(['w' Suffix]),dij,cst);
2580     
2581     % delete old variables to avoid confusion
2582     if isfield(resultGUI,'effect')
2583         resultGUI = rmfield(resultGUI,'effect');
2584         resultGUI = rmfield(resultGUI,'RBExDose'); 
2585         resultGUI = rmfield(resultGUI,'RBE'); 
2586         resultGUI = rmfield(resultGUI,'alpha'); 
2587         resultGUI = rmfield(resultGUI,'beta');
2588     end
2589     
2590     % overwrite the "standard" fields
2591     sNames = fieldnames(resultGUIreCalc);
2592     for j = 1:length(sNames)
2593         resultGUI.(sNames{j}) = resultGUIreCalc.(sNames{j});
2594     end
2595     
2596     % assign results to base worksapce
2597     assignin('base','dij',dij);
2598     assignin('base','resultGUI',resultGUI);
2599     
2600     handles.State = 3;
2601     
2602     % show physicalDose of newly computed state
2603     handles.SelectedDisplayOption = 'physicalDose';
2604     set(handles.popupDisplayOption,'Value',find(strcmp('physicalDose',Content)));
2605     
2606     % change state from busy to normal
2607     set(Figures, 'pointer', 'arrow');
2608     set(InterfaceObj,'Enable','on');
2609     
2610     handles.cBarChanged = true;
2611     
2612     handles = updateIsoDoseLineCache(handles);
2613 
2614     UpdateState(handles);
2615     
2616     handles.rememberCurrAxes = false;
2617     UpdatePlot(handles);
2618     handles.rememberCurrAxes = true;   
2619 
2620     guidata(hObject,handles);
2621 
2622 catch ME
2623     handles = showError(handles,'CalcDoseCallback: Error in dose recalculation!',ME); 
2624 
2625     % change state from busy to normal
2626     set(Figures, 'pointer', 'arrow');
2627     set(InterfaceObj,'Enable','on');
2628 
2629     guidata(hObject,handles);
2630     return;
2631 
2632 end
2633     
2634 end
2635 
2636 
2637 % --- Executes on button press in btnSetTissue.
2638 function btnSetTissue_Callback(hObject, ~, handles)
2639 
2640 %check if patient is loaded
2641 if handles.State == 0
2642     return
2643 end
2644 
2645 %parse variables from base-workspace
2646 cst = evalin('base','cst');
2647 pln = evalin('base','pln');
2648 
2649 fileName = [pln.radiationMode '_' pln.machine];
2650 load(['basedata' filesep fileName]);
2651 
2652 % check for available cell types characterized by alphaX and betaX
2653 for i = 1:size(machine.data(1).alphaX,2)
2654     CellType{i} = [num2str(machine.data(1).alphaX(i)) ' ' num2str(machine.data(1).betaX(i))];
2655 end
2656 
2657 %fill table data array
2658 for i = 1:size(cst,1)
2659     data{i,1} = cst{i,2};
2660     data{i,2} = [num2str(cst{i,5}.alphaX) ' ' num2str(cst{i,5}.betaX)];
2661     data{i,3} = (cst{i,5}.alphaX / cst{i,5}.betaX );
2662 end
2663 
2664 Width  = 400;
2665 Height = 200 + 20*size(data,1);
2666 ScreenSize = get(0,'ScreenSize');
2667 % show "set tissue parameter" window
2668 figHandles = get(0,'Children');
2669 if ~isempty(figHandles)
2670     IdxHandle = strcmp(get(figHandles,'Name'),'Set Tissue Parameters');
2671 else
2672     IdxHandle = [];
2673 end
2674 
2675 %check if window is already exists
2676 if any(IdxHandle)
2677     IdxTable = find(strcmp({figHandles(IdxHandle).Children.Type},'uitable'));
2678     set(figHandles(IdxHandle).Children(IdxTable), 'Data', []);
2679     figTissue = figHandles(IdxHandle);
2680     %set focus
2681     figure(figTissue);
2682 else
2683     figTissue = figure('Name','Set Tissue Parameters','Color',[.5 .5 .5],'NumberTitle','off','Position',...
2684         [ceil(ScreenSize(3)/2) ceil(ScreenSize(4)/2) Width Height]);
2685 end
2686 
2687 % define the tissue parameter table
2688 cNames = {'VOI','alphaX betaX','alpha beta ratio'};
2689 columnformat = {'char',CellType,'numeric'};
2690 
2691 tissueTable = uitable('Parent', figTissue,'Data', data,'ColumnEditable',[false true false],...
2692                       'ColumnName',cNames, 'ColumnFormat',columnformat,'Position',[50 150 10 10]);
2693 set(tissueTable,'CellEditCallback',@tissueTable_CellEditCallback);
2694 % set width and height
2695 currTablePos = get(tissueTable,'Position');
2696 currTableExt = get(tissueTable,'Extent');
2697 currTablePos(3) = currTableExt(3);
2698 currTablePos(4) = currTableExt(4);
2699 set(tissueTable,'Position',currTablePos);
2700 
2701 % define two buttons with callbacks
2702 uicontrol('Parent', figTissue,'Style', 'pushbutton', 'String', 'Save&Close',...
2703         'Position', [Width-(0.25*Width) 0.1 * Height 70 30],...
2704         'Callback', @(hpb,eventdata)SaveTissueParameters(hpb,eventdata,handles,tissueTable));
2705     
2706 uicontrol('Parent', figTissue,'Style', 'pushbutton', 'String', 'Cancel&Close',...
2707         'Position', [Width-(0.5*Width) 0.1 * Height 80 30],...
2708         'Callback', 'close');    
2709     
2710 guidata(hObject,handles); 
2711 UpdateState(handles);
2712     
2713     
2714 function SaveTissueParameters(~, ~, handles,tissueTable) 
2715 cst = evalin('base','cst');    
2716 % get handle to uiTable
2717 
2718 % retrieve data from uitable
2719 data       = get(tissueTable,'data');
2720 
2721 for i = 1:size(cst,1)
2722    for j = 1:size(data,1)
2723        if strcmp(cst{i,2},data{j,1})
2724          alphaXBetaX = str2num(data{j,2});
2725          cst{i,5}.alphaX = alphaXBetaX(1);
2726          cst{i,5}.betaX  = alphaXBetaX(2);
2727        end
2728    end
2729 end
2730 assignin('base','cst',cst);
2731 close(get(tissueTable,'Parent'));
2732 handles.State = 2;
2733 UpdateState(handles);
2734 
2735         
2736 function tissueTable_CellEditCallback(hObject, eventdata, ~) 
2737 if eventdata.Indices(2) == 2
2738    alphaXBetaX = str2num(eventdata.NewData);
2739    data = get(hObject,'Data');
2740    data{eventdata.Indices(1),3} = alphaXBetaX(1)/alphaXBetaX(2);
2741    set(hObject,'Data',data);
2742 end
2743 
2744 % --- Executes on button press in btnSaveToGUI.
2745 function btnSaveToGUI_Callback(hObject, ~, handles)
2746 
2747 Width  = 400;
2748 Height = 200;
2749 ScreenSize = get(0,'ScreenSize');
2750 
2751 % show "Provide result name" window
2752 figHandles = get(0,'Children');
2753 if ~isempty(figHandles)
2754     IdxHandle = strcmp(get(figHandles,'Name'),'Provide result name');
2755 else
2756     IdxHandle = [];
2757 end
2758 
2759 %check if window is already exists
2760 if any(IdxHandle)
2761     figDialog = figHandles(IdxHandle);
2762     %set focus
2763     figure(figDialog);
2764 else
2765     figDialog = dialog('Position',[ceil(ScreenSize(3)/2) ceil(ScreenSize(4)/2) Width Height],'Name','Provide result name','Color',[0.5 0.5 0.5]);
2766     
2767     uicontrol('Parent',figDialog,...
2768               'Style','text',...
2769               'Position',[20 Height - (0.35*Height) 350 60],...
2770               'String','Please provide a decriptive name for your optimization result:','FontSize',10,'BackgroundColor',[0.5 0.5 0.5]);
2771     
2772     uicontrol('Parent',figDialog,...
2773               'Style','edit',...
2774               'Position',[30 60 350 60],... 
2775               'String','Please enter name here...','FontSize',10,'BackgroundColor',[0.55 0.55 0.55]);
2776          
2777     uicontrol('Parent', figDialog,'Style', 'pushbutton', 'String', 'Save','FontSize',10,...
2778               'Position', [0.42*Width 0.1 * Height 70 30],...
2779               'Callback', @(hpb,eventdata)SaveResultToGUI(hpb,eventdata,guidata(hpb)));        
2780 end
2781 
2782 uiwait(figDialog);
2783 guidata(hObject, handles);
2784 UpdateState(handles)
2785 UpdatePlot(handles)
2786 
2787 
2788 function SaveResultToGUI(~, ~, ~)
2789 AllFigHandles = get(0,'Children');    
2790 ixHandle      = strcmp(get(AllFigHandles,'Name'),'Provide result name');
2791 uiEdit        = get(AllFigHandles(ixHandle),'Children');
2792 
2793 if strcmp(get(uiEdit(2),'String'),'Please enter name here...')
2794   
2795     formatOut = 'mmddyyHHMM';
2796     Suffix = ['_' datestr(now,formatOut)];
2797 else
2798     % delete special characters
2799     Suffix = get(uiEdit(2),'String');
2800     logIx = isstrprop(Suffix,'alphanum');
2801     Suffix = ['_' Suffix(logIx)];
2802 end
2803 
2804 pln       = evalin('base','pln');
2805 resultGUI = evalin('base','resultGUI');
2806 
2807 if isfield(resultGUI,'physicalDose')
2808     resultGUI.(['physicalDose' Suffix])  = resultGUI.physicalDose; 
2809 end
2810 if isfield(resultGUI,'w')
2811     resultGUI.(['w' Suffix])             = resultGUI.w;
2812 end
2813 
2814 
2815 if ~strcmp(pln.propOpt.bioOptimization,'none')
2816     
2817     if isfield(resultGUI,'RBExDose')
2818          resultGUI.(['RBExDose' Suffix]) = resultGUI.RBExDose; 
2819     end
2820     
2821     if strcmp(pln.radiationMode,'carbon') == 1 
2822         if isfield(resultGUI,'effect')
2823             resultGUI.(['effect' Suffix])= resultGUI.effect; 
2824         end
2825 
2826         if isfield(resultGUI,'RBE')
2827             resultGUI.(['RBE' Suffix]) = resultGUI.RBE;
2828         end
2829         if isfield(resultGUI,'alpha')
2830             resultGUI.(['alpha' Suffix]) = resultGUI.alpha;
2831         end
2832         if isfield(resultGUI,'beta')
2833             resultGUI.(['beta' Suffix]) = resultGUI.beta;
2834         end
2835     end
2836 end
2837 
2838 close(AllFigHandles(ixHandle));
2839 assignin('base','resultGUI',resultGUI);
2840 
2841 % precompute contours of VOIs
2842 function cst = precomputeContours(ct,cst)
2843 mask = zeros(ct.cubeDim); % create zero cube with same dimeonsions like dose cube
2844 for s = 1:size(cst,1)
2845     cst{s,7} = cell(max(ct.cubeDim(:)),3);
2846     mask(:) = 0;
2847     mask(cst{s,4}{1}) = 1;    
2848     for slice = 1:ct.cubeDim(1)
2849         if sum(sum(mask(slice,:,:))) > 0
2850              cst{s,7}{slice,1} = contourc(squeeze(mask(slice,:,:)),.5*[1 1]);
2851         end
2852     end
2853     for slice = 1:ct.cubeDim(2)
2854         if sum(sum(mask(:,slice,:))) > 0
2855              cst{s,7}{slice,2} = contourc(squeeze(mask(:,slice,:)),.5*[1 1]);
2856         end
2857     end
2858     for slice = 1:ct.cubeDim(3)
2859         if sum(sum(mask(:,:,slice))) > 0
2860              cst{s,7}{slice,3} = contourc(squeeze(mask(:,:,slice)),.5*[1 1]);
2861         end
2862     end
2863 end
2864 
2865 %Update IsodoseLines
2866 function handles = updateIsoDoseLineCache(handles)
2867 resultGUI = evalin('base','resultGUI');
2868 % select first cube if selected option does not exist
2869 if ~isfield(resultGUI,handles.SelectedDisplayOption)
2870     CubeNames = fieldnames(resultGUI);
2871     dose = resultGUI.(CubeNames{1,1});
2872 else
2873     dose = resultGUI.(handles.SelectedDisplayOption);
2874 end
2875 
2876 %if function is called for the first time then set display parameters
2877 if isempty(handles.dispWindow{3,2})
2878     handles.dispWindow{3,1} = [min(dose(:)) max(dose(:))]; % set default dose range
2879     handles.dispWindow{3,2} = [min(dose(:)) max(dose(:))]; % set min max values
2880 end
2881 
2882 minMaxRange = handles.dispWindow{3,1};
2883 % if upper colorrange is defined then use it otherwise 120% iso dose
2884  upperMargin = 1;
2885 if abs((max(dose(:)) - handles.dispWindow{3,1}(1,2))) < 0.01  * max(dose(:))
2886     upperMargin = 1.2;
2887 end
2888 
2889 if (length(handles.IsoDose.Levels) == 1 && handles.IsoDose.Levels(1,1) == 0) || ~handles.IsoDose.NewIsoDoseFlag
2890     vLevels                  = [0.1:0.1:0.9 0.95:0.05:upperMargin];  
2891     referenceDose            = (minMaxRange(1,2))/(upperMargin);
2892     handles.IsoDose.Levels   = minMaxRange(1,1) + (referenceDose-minMaxRange(1,1)) * vLevels;
2893 end
2894 handles.IsoDose.Contours = matRad_computeIsoDoseContours(dose,handles.IsoDose.Levels);
2895 
2896     
2897    
2898 %% CREATE FUNCTIONS
2899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2900 
2901 % popup menu: machine
2902 function popUpMachine_CreateFcn(hObject, ~, ~)
2903 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2904     set(hObject,'BackgroundColor','white');
2905 end
2906 
2907 % text box: max value
2908 function txtMaxVal_CreateFcn(hObject, ~, ~)
2909 
2910 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2911     set(hObject,'BackgroundColor','white');
2912 end
2913 
2914 % text box: edit iso center
2915 function editIsoCenter_CreateFcn(hObject, ~, ~)
2916 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2917     set(hObject,'BackgroundColor','white');
2918 end
2919 
2920 % text box: stratification levels
2921 function editSequencingLevel_CreateFcn(hObject, ~, ~)
2922 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2923     set(hObject,'BackgroundColor','white');
2924 end
2925 
2926 function slicerPrecision_CreateFcn(hObject, ~, ~)
2927 if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2928     set(hObject,'BackgroundColor',[.9 .9 .9]);
2929 end
2930 
2931 function editBixelWidth_CreateFcn(hObject, ~, ~)
2932 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2933     set(hObject,'BackgroundColor','white');
2934 end
2935 
2936 function editGantryAngle_CreateFcn(hObject, ~, ~)
2937 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2938     set(hObject,'BackgroundColor','white');
2939 end
2940 
2941 function editCouchAngle_CreateFcn(hObject, ~, ~)
2942 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2943     set(hObject,'BackgroundColor','white');
2944 end
2945 
2946 function popupRadMode_CreateFcn(hObject, ~, ~)
2947 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2948     set(hObject,'BackgroundColor','white');
2949 end
2950 
2951 function editFraction_CreateFcn(hObject, ~, ~) 
2952 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2953     set(hObject,'BackgroundColor','white');
2954 end
2955 
2956 function popupPlane_CreateFcn(hObject, ~, ~)
2957 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2958     set(hObject,'BackgroundColor','white');
2959 end
2960 
2961 function sliderSlice_CreateFcn(hObject, ~, ~)
2962 if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2963     set(hObject,'BackgroundColor',[.9 .9 .9]);
2964 end
2965 
2966 function popupTypeOfPlot_CreateFcn(hObject, ~, ~)
2967 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2968     set(hObject,'BackgroundColor','white');
2969 end
2970 
2971 function popupDisplayOption_CreateFcn(hObject, ~, ~)
2972 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2973     set(hObject,'BackgroundColor','white');
2974 end
2975 
2976 function sliderBeamSelection_CreateFcn(hObject, ~, ~)
2977 if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2978     set(hObject,'BackgroundColor',[.9 .9 .9]);
2979 end
2980 
2981 function listBoxCmd_CreateFcn(hObject, ~, ~)
2982 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2983     set(hObject,'BackgroundColor','white');
2984 end
2985 
2986 function sliderOffset_CreateFcn(hObject, ~, ~)
2987 if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
2988     set(hObject,'BackgroundColor',[.9 .9 .9]);
2989 end
2990 
2991 % --- Executes on selection change in legendTable.
2992 function legendTable_Callback(hObject, eventdata, handles)
2993 % hObject    handle to legendTable (see GCBO)
2994 % eventdata  reserved - to be defined in a future version of MATLAB
2995 % handles    structure with handles and user data (see GUIDATA)
2996 
2997 % Hints: contents = cellstr(get(hObject,'String')) returns legendTable contents as cell array
2998 %        contents{get(hObject,'Value')} returns selected item from legendTable
2999 cst = evalin('base','cst');
3000 
3001 idx    = get(hObject,'Value');
3002 clr    = dec2hex(round(cst{idx,5}.visibleColor(:)*255),2)';
3003 clr    = ['#';clr(:)]';
3004 
3005 %Get the string entries
3006 tmpString = get(handles.legendTable,'String');
3007 
3008 if handles.VOIPlotFlag(idx)
3009     handles.VOIPlotFlag(idx) = false;
3010     cst{idx,5}.Visible = false;
3011     tmpString{idx} = ['<html><table border=0 ><TR><TD bgcolor=',clr,' width="18"></TD><TD>',cst{idx,2},'</TD></TR> </table></html>'];
3012 elseif ~handles.VOIPlotFlag(idx)
3013     handles.VOIPlotFlag(idx) = true;
3014     cst{idx,5}.Visible = true;
3015     tmpString{idx} = ['<html><table border=0 ><TR><TD bgcolor=',clr,' width="18"><center>&#10004;</center></TD><TD>',cst{idx,2},'</TD></TR> </table></html>'];
3016 end
3017 set(handles.legendTable,'String',tmpString);
3018 
3019 % update cst in workspace accordingly
3020 assignin('base','cst',cst)
3021 
3022 guidata(hObject, handles);
3023 UpdatePlot(handles)
3024 
3025 % --- Executes during object creation, after setting all properties.
3026 function legendTable_CreateFcn(hObject, eventdata, handles)
3027 % hObject    handle to legendTable (see GCBO)
3028 % eventdata  reserved - to be defined in a future version of MATLAB
3029 % handles    empty - handles not created until after all CreateFcns called
3030 
3031 % Hint: listbox controls usually have a white background on Windows.
3032 %       See ISPC and COMPUTER.
3033 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
3034     set(hObject,'BackgroundColor','white');
3035 end
3036 
3037 
3038 % --- Executes on button press in importDoseButton.
3039 function importDoseButton_Callback(hObject,eventdata, handles)
3040 % hObject    handle to importDoseButton (see GCBO)
3041 % eventdata  reserved - to be defined in a future version of MATLAB
3042 % handles    structure with handles and user data (see GUIDATA)
3043 extensions{1} = '*.nrrd';
3044 [filenames,filepath,~] = uigetfile(extensions,'MultiSelect','on');
3045 
3046 if ~iscell(filenames)
3047     tmp = filenames;
3048     filenames = cell(1);
3049     filenames{1} = tmp;
3050 end
3051 
3052 ct = evalin('base','ct');
3053 resultGUI = evalin('base','resultGUI');
3054 
3055 for filename = filenames
3056     [~,name,~] = fileparts(filename{1});
3057     [cube,~] = matRad_readCube(fullfile(filepath,filename{1}));
3058     if ~isequal(ct.cubeDim, size(cube))
3059         errordlg('Dimensions of the imported cube do not match with ct','Import failed!','modal');
3060         continue;
3061     end
3062     
3063     fieldname = ['import_' matlab.lang.makeValidName(name, 'ReplacementStyle','delete')];
3064     resultGUI.(fieldname) = cube;
3065 end
3066 
3067 assignin('base','resultGUI',resultGUI);
3068 btnRefresh_Callback(hObject, eventdata, handles)
3069 
3070 % --- Executes on button press in pushbutton_importFromBinary.
3071 function pushbutton_importFromBinary_Callback(hObject, eventdata, handles)
3072 % hObject    handle to pushbutton_importFromBinary (see GCBO)
3073 % eventdata  reserved - to be defined in a future version of MATLAB
3074 % handles    structure with handles and user data (see GUIDATA)
3075 
3076 try
3077     % delete existing workspace - parse variables from base workspace
3078     set(handles.popupDisplayOption,'String','no option available');
3079     AllVarNames = evalin('base','who');
3080     RefVarNames = {'ct','cst','pln','stf','dij','resultGUI'};
3081     for i = 1:length(RefVarNames)  
3082         if sum(ismember(AllVarNames,RefVarNames{i}))>0
3083             evalin('base',['clear ', RefVarNames{i}]);
3084         end
3085     end
3086     handles.State = 0;
3087 
3088     %call the gui
3089     uiwait(matRad_importGUI);
3090     
3091     %Check if we have the variables in the workspace
3092     if evalin('base','exist(''cst'',''var'')') == 1 && evalin('base','exist(''ct'',''var'')') == 1
3093         cst = evalin('base','cst');
3094         ct = evalin('base','ct');
3095         %setCstTable(handles,cst);
3096         generateCstTable(handles,cst);
3097         handles.TableChanged = false;
3098         set(handles.popupTypeOfPlot,'Value',1);
3099         
3100         % compute HU values
3101         if ~isfield(ct, 'cubeHU')
3102             ct = matRad_electronDensitiesToHU(ct);
3103             assignin('base','ct',ct);
3104         end
3105         if ~isfield(ct, 'cubeHU')
3106             handles.cubeHUavailable = false;
3107         else
3108             handles.cubeHUavailable = true;
3109         end
3110         
3111         % precompute contours
3112         cst = precomputeContours(ct,cst);
3113     
3114         assignin('base','ct',ct);
3115         assignin('base','cst',cst);
3116         
3117         if evalin('base','exist(''pln'',''var'')')
3118             assignin('base','pln',pln);
3119             setPln(handles);
3120         else
3121             getPlnFromGUI(handles);
3122             setPln(handles);
3123         end
3124         handles.State = 1;
3125     end
3126     
3127     % set slice slider
3128     handles.plane = get(handles.popupPlane,'value');
3129     if handles.State >0
3130         set(handles.sliderSlice,'Min',1,'Max',ct.cubeDim(handles.plane),...
3131             'Value',round(ct.cubeDim(handles.plane)/2),...
3132             'SliderStep',[1/(ct.cubeDim(handles.plane)-1) 1/(ct.cubeDim(handles.plane)-1)]);
3133     end
3134 
3135     if handles.State > 0
3136         % define context menu for structures
3137         for i = 1:size(cst,1)
3138             if cst{i,5}.Visible
3139                 handles.VOIPlotFlag(i) = true;
3140             else
3141                 handles.VOIPlotFlag(i) = false;
3142             end
3143         end
3144     end
3145     
3146     handles.dispWindow = cell(3,2);
3147     handles.cBarChanged = true;
3148     
3149     UpdateState(handles);
3150     handles.rememberCurrAxes = false;
3151     UpdatePlot(handles);
3152     handles.rememberCurrAxes = true;
3153 catch
3154    handles = showError(handles,'Binary Patient Import: Could not import data');
3155    UpdateState(handles);
3156 end
3157 
3158 guidata(hObject,handles);
3159 
3160 % --- Executes on button press in radioBtnIsoCenter.
3161 function radioBtnIsoCenter_Callback(hObject, eventdata, handles)
3162 % hObject    handle to radioBtnIsoCenter (see GCBO)
3163 % eventdata  reserved - to be defined in a future version of MATLAB
3164 % handles    structure with handles and user data (see GUIDATA)
3165 UpdatePlot(handles)
3166 % Hint: get(hObject,'Value') returns toggle state of radioBtnIsoCenter
3167 
3168 % --------------------------------------------------------------------
3169 function uipushtool_screenshot_ClickedCallback(hObject, eventdata, handles)
3170 % hObject    handle to uipushtool_screenshot (see GCBO)
3171 % eventdata  reserved - to be defined in a future version of MATLAB
3172 % handles    structure with handles and user data (see GUIDATA)
3173 
3174  
3175 tmpFig = figure('position',[100 100 700 600],'Visible','off','name','Current View'); 
3176 cBarHandle = findobj(handles.figure1,'Type','colorbar');
3177 if ~isempty(cBarHandle)
3178     new_handle = copyobj([handles.axesFig cBarHandle],tmpFig);
3179 else
3180     new_handle = copyobj(handles.axesFig,tmpFig);
3181 end
3182 
3183 oldPos = get(handles.axesFig,'Position');
3184 set(new_handle(1),'units','normalized', 'Position',oldPos);
3185 
3186 if ~isfield(handles,'lastStoragePath') || exist(handles.lastStoragePath,'dir') ~= 7
3187     lastStoragePath = [];   
3188 else
3189     lastStoragePath = handles.lastStoragePath;
3190 end
3191 
3192 [filename, pathname] = uiputfile({'*.jpg;*.tif;*.png;*.gif','All Image Files'; '*.fig','MATLAB figure file'},'Save current view',[lastStoragePath 'screenshot.png']);
3193 
3194 
3195 
3196 if ~isequal(filename,0) && ~isequal(pathname,0)
3197     handles.lastStoragePath = pathname;
3198     set(gcf, 'pointer', 'watch');
3199     saveas(tmpFig,fullfile(pathname,filename));
3200     set(gcf, 'pointer', 'arrow');
3201     close(tmpFig);
3202     uiwait(msgbox('Current view has been succesfully saved!'));
3203 else
3204     uiwait(msgbox('Aborted saving, showing figure instead!'));
3205     set(tmpFig,'Visible','on');
3206 end
3207 
3208 guidata(hObject,handles);
3209 
3210 
3211 %% Callbacks & Functions for color setting
3212 function UpdateColormapOptions(handles)
3213 
3214 if isfield(handles,'colormapLocked') && handles.colormapLocked
3215     return;
3216 end
3217 
3218 selectionIndex = get(handles.popupmenu_chooseColorData,'Value');
3219 
3220 cMapSelectionIndex = get(handles.popupmenu_chooseColormap,'Value');
3221 cMapStrings = get(handles.popupmenu_chooseColormap,'String');
3222 
3223 if selectionIndex > 1 
3224     set(handles.uitoggletool8,'State','on');
3225 else
3226     set(handles.uitoggletool8,'State','off');
3227 end
3228 
3229 try 
3230     if selectionIndex == 2
3231         ct = evalin('base','ct');
3232         currentMap = handles.ctColorMap;
3233         window = handles.dispWindow{selectionIndex,1};
3234         if handles.cubeHUavailable
3235             minMax = [min(ct.cubeHU{1}(:)) max(ct.cubeHU{1}(:))];            
3236         else
3237             minMax = [min(ct.cube{1}(:)) max(ct.cube{1}(:))];
3238         end
3239         % adjust value for custom window to current
3240         handles.windowPresets(1).width = max(window) - min(window);
3241         handles.windowPresets(1).center = mean(window);
3242         % update full window information
3243         handles.windowPresets(2).width = minMax(2) - minMax(1);
3244         handles.windowPresets(2).center = mean(minMax);
3245     elseif selectionIndex == 3
3246         result = evalin('base','resultGUI');        
3247         dose = result.(handles.SelectedDisplayOption);
3248         currentMap = handles.doseColorMap;
3249         minMax = [min(dose(:)) max(dose(:))];
3250         window = handles.dispWindow{selectionIndex,1};
3251     else
3252         window = [0 1];
3253         minMax = window;
3254         currentMap = 'bone';
3255     end
3256 catch
3257     window = [0 1];
3258     minMax = window;
3259     currentMap = 'bone';
3260 end
3261 
3262 valueRange = minMax(2) - minMax(1);
3263 
3264 windowWidth = window(2) - window(1);
3265 windowCenter = mean(window);
3266 
3267 %This are some arbritrary settings to configure the sliders
3268 sliderCenterMinMax = [minMax(1)-valueRange/2 minMax(2)+valueRange/2];
3269 sliderWidthMinMax = [0 valueRange*2];
3270 
3271 %if we have selected a value outside this range, we adapt the slider
3272 %windows
3273 if windowCenter < sliderCenterMinMax(1)
3274     sliderCenterMinMax(1) = windowCenter;
3275 end
3276 if windowCenter > sliderCenterMinMax(2)
3277     sliderCenterMinMax(2) = windowCenter;
3278 end
3279 if windowWidth < sliderWidthMinMax(1)
3280     sliderWidthMinMax(1) = windowWidth;
3281 end
3282 if windowCenter > sliderCenterMinMax(2)
3283     sliderWidthMinMax(2) = windowWidth;
3284 end
3285 
3286 
3287 set(handles.edit_windowCenter,'String',num2str(windowCenter,3));    
3288 set(handles.edit_windowWidth,'String',num2str(windowWidth,3));
3289 set(handles.edit_windowRange,'String',num2str(window,4));
3290 set(handles.slider_windowCenter,'Min',sliderCenterMinMax(1),'Max',sliderCenterMinMax(2),'Value',windowCenter);
3291 set(handles.slider_windowWidth,'Min',sliderWidthMinMax(1),'Max',sliderWidthMinMax(2),'Value',windowWidth);
3292 
3293 cMapPopupIndex = find(strcmp(currentMap,cMapStrings));
3294 set(handles.popupmenu_chooseColormap,'Value',cMapPopupIndex);
3295 
3296 guidata(gcf,handles);
3297 
3298 % --- Executes on selection change in popupmenu_chooseColorData.
3299 function popupmenu_chooseColorData_Callback(hObject, eventdata, handles)
3300 % hObject    handle to popupmenu_chooseColorData (see GCBO)
3301 % eventdata  reserved - to be defined in a future version of MATLAB
3302 % handles    structure with handles and user data (see GUIDATA)
3303 
3304 % Hints: contents = cellstr(get(hObject,'String')) returns popupmenu_chooseColorData contents as cell array
3305 %        contents{get(hObject,'Value')} returns selected item from popupmenu_chooseColorData
3306 
3307 %index = get(hObject,'Value') - 1;
3308 
3309 handles.cBarChanged = true;
3310 
3311 guidata(hObject,handles);
3312 UpdatePlot(handles);
3313 
3314 
3315 % --- Executes during object creation, after setting all properties.
3316 function popupmenu_chooseColorData_CreateFcn(hObject, eventdata, handles)
3317 % hObject    handle to popupmenu_chooseColorData (see GCBO)
3318 % eventdata  reserved - to be defined in a future version of MATLAB
3319 % handles    empty - handles not created until after all CreateFcns called
3320 
3321 % Hint: popupmenu controls usually have a white background on Windows.
3322 %       See ISPC and COMPUTER.
3323 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
3324     set(hObject,'BackgroundColor','white');
3325 end
3326 
3327 
3328 % --- Executes on slider movement.
3329 function slider_windowCenter_Callback(hObject, eventdata, handles)
3330 % hObject    handle to slider_windowCenter (see GCBO)
3331 % eventdata  reserved - to be defined in a future version of MATLAB
3332 % handles    structure with handles and user data (see GUIDATA)
3333 
3334 % Hints: get(hObject,'Value') returns position of slider
3335 %        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
3336 
3337 newCenter      = get(hObject,'Value');
3338 range          = get(handles.slider_windowWidth,'Value');
3339 selectionIndex = get(handles.popupmenu_chooseColorData,'Value');
3340 
3341 handles.dispWindow{selectionIndex,1}  = [newCenter-range/2 newCenter+range/2];
3342 handles.cBarChanged = true;
3343 
3344 guidata(hObject,handles);
3345 UpdatePlot(handles);
3346 
3347 % --- Executes during object creation, after setting all properties.
3348 function slider_windowCenter_CreateFcn(hObject, eventdata, handles)
3349 % hObject    handle to slider_windowCenter (see GCBO)
3350 % eventdata  reserved - to be defined in a future version of MATLAB
3351 % handles    empty - handles not created until after all CreateFcns called
3352 
3353 % Hint: slider controls usually have a light gray background.
3354 if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
3355     set(hObject,'BackgroundColor',[.9 .9 .9]);
3356 end
3357 
3358 set(hObject,'Value',0.5);
3359 
3360 % --- Executes on slider movement.
3361 function slider_windowWidth_Callback(hObject, eventdata, handles)
3362 % hObject    handle to slider_windowWidth (see GCBO)
3363 % eventdata  reserved - to be defined in a future version of MATLAB
3364 % handles    structure with handles and user data (see GUIDATA)
3365 
3366 % Hints: get(hObject,'Value') returns position of slider
3367 %        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
3368 
3369 newWidth = get(hObject,'Value');
3370 center   = get(handles.slider_windowCenter,'Value');
3371 selectionIndex                        = get(handles.popupmenu_chooseColorData,'Value');
3372 handles.dispWindow{selectionIndex,1}  = [center-newWidth/2 center+newWidth/2];
3373 handles.cBarChanged = true;
3374 
3375 guidata(hObject,handles);
3376 UpdatePlot(handles);
3377 
3378 % --- Executes during object creation, after setting all properties.
3379 function slider_windowWidth_CreateFcn(hObject, eventdata, handles)
3380 % hObject    handle to slider_windowWidth (see GCBO)
3381 % eventdata  reserved - to be defined in a future version of MATLAB
3382 % handles    empty - handles not created until after all CreateFcns called
3383 
3384 % Hint: slider controls usually have a light gray background.
3385 if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
3386     set(hObject,'BackgroundColor',[.9 .9 .9]);
3387 end
3388 
3389 set(hObject,'Value',1.0);
3390 
3391 
3392 % --- Executes on selection change in popupmenu_chooseColormap.
3393 function popupmenu_chooseColormap_Callback(hObject, eventdata, handles)
3394 % hObject    handle to popupmenu_chooseColormap (see GCBO)
3395 % eventdata  reserved - to be defined in a future version of MATLAB
3396 % handles    structure with handles and user data (see GUIDATA)
3397 
3398 % Hints: contents = cellstr(get(hObject,'String')) returns popupmenu_chooseColormap contents as cell array
3399 %        contents{get(hObject,'Value')} returns selected item from popupmenu_chooseColormap
3400 
3401 index = get(hObject,'Value');
3402 strings = get(hObject,'String');
3403 
3404 selectionIndex = get(handles.popupmenu_chooseColorData,'Value');
3405 
3406 switch selectionIndex 
3407     case 2
3408         handles.ctColorMap = strings{index};
3409     case 3
3410         handles.doseColorMap = strings{index};
3411     otherwise
3412 end
3413 
3414 handles.cBarChanged = true;
3415 
3416 guidata(hObject,handles);
3417 UpdatePlot(handles);
3418 
3419 % --- Executes during object creation, after setting all properties.
3420 function popupmenu_chooseColormap_CreateFcn(hObject, eventdata, handles)
3421 % hObject    handle to popupmenu_chooseColormap (see GCBO)
3422 % eventdata  reserved - to be defined in a future version of MATLAB
3423 % handles    empty - handles not created until after all CreateFcns called
3424 
3425 % Hint: popupmenu controls usually have a white background on Windows.
3426 %       See ISPC and COMPUTER.
3427 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
3428     set(hObject,'BackgroundColor','white');
3429 end
3430 
3431 
3432 function edit_windowRange_Callback(hObject, eventdata, handles)
3433 % hObject    handle to edit_windowRange (see GCBO)
3434 % eventdata  reserved - to be defined in a future version of MATLAB
3435 % handles    structure with handles and user data (see GUIDATA)
3436 
3437 % Hints: get(hObject,'String') returns contents of edit_windowRange as text
3438 %        str2double(get(hObject,'String')) returns contents of edit_windowRange as a double
3439 
3440 selectionIndex = get(handles.popupmenu_chooseColorData,'Value');
3441 vRange         = str2num(get(hObject,'String'));
3442 % matlab adds a zero in the beginning when text field is changed
3443 if numel(vRange) == 3
3444     vRange = vRange(vRange~=0);
3445 end
3446 
3447 handles.dispWindow{selectionIndex,1} = sort(vRange);
3448 
3449 handles.cBarChanged = true;
3450 
3451     % compute new iso dose lines
3452 if selectionIndex > 2 
3453     guidata(hObject,handles);
3454     handles = updateIsoDoseLineCache(handles);
3455 end
3456 
3457 guidata(hObject,handles);
3458 UpdatePlot(handles);
3459 
3460 % --- Executes during object creation, after setting all properties.
3461 function edit_windowRange_CreateFcn(hObject, eventdata, handles)
3462 % hObject    handle to edit_windowRange (see GCBO)
3463 % eventdata  reserved - to be defined in a future version of MATLAB
3464 % handles    empty - handles not created until after all CreateFcns called
3465 
3466 % Hint: edit controls usually have a white background on Windows.
3467 %       See ISPC and COMPUTER.
3468 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
3469     set(hObject,'BackgroundColor','white');
3470 end
3471 
3472 set(hObject,'String','0 1');
3473 
3474 
3475 function edit_windowCenter_Callback(hObject, eventdata, handles)
3476 % hObject    handle to edit_windowCenter (see GCBO)
3477 % eventdata  reserved - to be defined in a future version of MATLAB
3478 % handles    structure with handles and user data (see GUIDATA)
3479 
3480 % Hints: get(hObject,'String') returns contents of edit_windowCenter as text
3481 %        str2double(get(hObject,'String')) returns contents of edit_windowCenter as a double
3482 
3483 newCenter           = str2double(get(hObject,'String'));
3484 width               = get(handles.slider_windowWidth,'Value');
3485 selectionIndex      = get(handles.popupmenu_chooseColorData,'Value');
3486 handles.dispWindow{selectionIndex,1}  = [newCenter-width/2 newCenter+width/2];
3487 handles.cBarChanged = true;
3488 guidata(hObject,handles);
3489 UpdatePlot(handles);
3490 
3491 % --- Executes during object creation, after setting all properties.
3492 function edit_windowCenter_CreateFcn(hObject, eventdata, handles)
3493 % hObject    handle to edit_windowCenter (see GCBO)
3494 % eventdata  reserved - to be defined in a future version of MATLAB
3495 % handles    empty - handles not created until after all CreateFcns called
3496 
3497 % Hint: edit controls usually have a white background on Windows.
3498 %       See ISPC and COMPUTER.
3499 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
3500     set(hObject,'BackgroundColor','white');
3501 end
3502 
3503 
3504 
3505 function edit_windowWidth_Callback(hObject, eventdata, handles)
3506 % hObject    handle to edit_windowWidth (see GCBO)
3507 % eventdata  reserved - to be defined in a future version of MATLAB
3508 % handles    structure with handles and user data (see GUIDATA)
3509 
3510 % Hints: get(hObject,'String') returns contents of edit_windowWidth as text
3511 %        str2double(get(hObject,'String')) returns contents of edit_windowWidth as a double
3512 
3513 newWidth            = str2double(get(hObject,'String'));
3514 center              = get(handles.slider_windowCenter,'Value');
3515 selectionIndex      = get(handles.popupmenu_chooseColorData,'Value');
3516 handles.dispWindow{selectionIndex,1}  = [center-newWidth/2 center+newWidth/2];
3517 handles.cBarChanged = true;
3518 guidata(hObject,handles);
3519 UpdatePlot(handles);
3520 
3521 
3522 % --- Executes during object creation, after setting all properties.
3523 function edit_windowWidth_CreateFcn(hObject, eventdata, handles)
3524 % hObject    handle to edit_windowWidth (see GCBO)
3525 % eventdata  reserved - to be defined in a future version of MATLAB
3526 % handles    empty - handles not created until after all CreateFcns called
3527 
3528 % Hint: edit controls usually have a white background on Windows.
3529 %       See ISPC and COMPUTER.
3530 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
3531     set(hObject,'BackgroundColor','white');
3532 end
3533 
3534 
3535 % --------------------------------------------------------------------
3536 function uitoggletool8_ClickedCallback(hObject, eventdata, handles)
3537 % hObject    handle to uitoggletool8 (see GCBO)
3538 % eventdata  reserved - to be defined in a future version of MATLAB
3539 % handles    structure with handles and user data (see GUIDATA)
3540 
3541 %Check if on or off
3542 val = strcmp(get(hObject,'State'),'on');
3543 
3544 %Now we have to apply the new selection to our colormap options panel
3545 if ~val
3546     newSelection = 1;
3547 else
3548     %Chooses the selection from the highest state
3549     selections = get(handles.popupmenu_chooseColorData,'String');
3550     newSelection = numel(selections);
3551 end    
3552 set(handles.popupmenu_chooseColorData,'Value',newSelection);
3553 
3554 handles.cBarChanged = true;
3555 guidata(hObject,handles);
3556 UpdatePlot(handles);
3557 
3558 % --- Executes on slider movement.
3559 function sliderOpacity_Callback(hObject, eventdata, handles)
3560 % hObject    handle to sliderOpacity (see GCBO)
3561 % eventdata  reserved - to be defined in a future version of MATLAB
3562 % handles    structure with handles and user data (see GUIDATA)
3563 handles.doseOpacity = get(hObject,'Value');
3564 guidata(hObject,handles);
3565 UpdatePlot(handles);
3566 
3567 % --- Executes during object creation, after setting all properties.
3568 function sliderOpacity_CreateFcn(hObject, eventdata, handles)
3569 % hObject    handle to sliderOpacity (see GCBO)
3570 % eventdata  reserved - to be defined in a future version of MATLAB
3571 % handles    empty - handles not created until after all CreateFcns called
3572 
3573 % Hint: slider controls usually have a light gray background.
3574 if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
3575     set(hObject,'BackgroundColor',[.9 .9 .9]);
3576 end
3577 
3578 %% Data Cursors
3579 function cursorText = dataCursorUpdateFunction(obj,event_obj)
3580 % Display the position of the data cursor
3581 % obj          Currently not used (empty)
3582 % event_obj    Handle to event object
3583 % output_txt   Data cursor text string (string or cell array of strings).
3584 
3585 target = findall(0,'Name','matRadGUI');
3586 
3587 % Get GUI data (maybe there is another way?)
3588 handles = guidata(target);
3589 
3590 % position of the data point to label
3591 pos = get(event_obj,'Position');
3592 
3593 %Different behavior for image and profile plot
3594 if get(handles.popupTypeOfPlot,'Value')==1 %Image view
3595     cursorText = cell(0,1);
3596     try   
3597         if handles.State >= 1
3598             plane = get(handles.popupPlane,'Value');
3599             slice = round(get(handles.sliderSlice,'Value'));
3600             
3601             %Get the CT values
3602             ct  = evalin('base','ct');
3603             
3604             %We differentiate between pos and ix, since the user may put
3605             %the datatip on an isoline which returns a continous position
3606             cubePos = zeros(1,3);
3607             cubePos(plane) = slice;
3608             cubePos(1:end ~= plane) = fliplr(pos);            
3609             cubeIx = round(cubePos);
3610             
3611             %Here comes the index permutation stuff
3612             %Cube Index
3613             cursorText{end+1,1} = ['Cube Index: ' mat2str(cubeIx)];
3614             %Space Coordinates
3615             coords = zeros(1,3);
3616             coords(1) = cubePos(2)*ct.resolution.y;
3617             coords(2) = cubePos(1)*ct.resolution.x;
3618             coords(3) = cubePos(3)*ct.resolution.z;            
3619             cursorText{end+1,1} = ['Space Coordinates: ' mat2str(coords,5) ' mm'];
3620             
3621             ctVal = ct.cubeHU{1}(cubeIx(1),cubeIx(2),cubeIx(3));
3622             cursorText{end+1,1} = ['HU Value: ' num2str(ctVal,3)];
3623         end
3624         
3625         %Add dose information if available
3626         if handles.State == 3
3627             %get result structure
3628             result = evalin('base','resultGUI');
3629             
3630             %Get all result names from popup
3631             resultNames = get(handles.popupDisplayOption,'String');
3632             
3633             %Display all values of fields found in the resultGUI struct
3634             for runResult = 1:numel(resultNames)               
3635                 name = resultNames{runResult};
3636                 if isfield(result,name)
3637                     field = result.(name);
3638                     val = field(cubeIx(1),cubeIx(2),cubeIx(3));
3639                     cursorText{end+1,1} = [name ': ' num2str(val,3)];
3640                 end
3641             end      
3642         end
3643     catch
3644         cursorText{end+1,1} = 'Error while retreiving Data!';
3645     end    
3646 else %Profile view
3647     cursorText = cell(2,1);
3648     cursorText{1} = ['Radiological Depth: ' num2str(pos(1),3) ' mm'];
3649     cursorText{2} = [get(target,'DisplayName') ': ' num2str(pos(2),3)];
3650 end
3651 
3652 
3653 
3654 % --- Executes on selection change in popMenuBioOpt.
3655 function popMenuBioOpt_Callback(hObject, ~, handles)
3656 pln = evalin('base','pln');
3657 contentBioOpt = get(handles.popMenuBioOpt,'String');
3658 NewBioOptimization = contentBioOpt(get(handles.popMenuBioOpt,'Value'),:);
3659 
3660 if handles.State > 0
3661     if (strcmp(pln.propOpt.bioOptimization,'LEMIV_effect') && strcmp(NewBioOptimization,'LEMIV_RBExD')) ||...
3662        (strcmp(pln.propOpt.bioOptimization,'LEMIV_RBExD') && strcmp(NewBioOptimization,'LEMIV_effect')) 
3663        % do nothing - re-optimization is still possible
3664     elseif ((strcmp(pln.propOpt.bioOptimization,'const_RBE') && strcmp(NewBioOptimization,'none')) ||...
3665            (strcmp(pln.propOpt.bioOptimization,'none') && strcmp(NewBioOptimization,'const_RBE'))) && isequal(pln.radiationMode,'protons')
3666        % do nothing - re-optimization is still possible
3667     else
3668         handles.State = 1;
3669     end
3670 end
3671 getPlnFromGUI(handles);
3672 
3673 UpdateState(handles);
3674 guidata(hObject,handles);
3675 
3676 % --- Executes during object creation, after setting all properties.
3677 function popMenuBioOpt_CreateFcn(hObject, eventdata, handles)
3678 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
3679     set(hObject,'BackgroundColor','white');
3680 end
3681 
3682 % --- Executes on button press in btn3Dview.
3683 function btn3Dview_Callback(hObject, eventdata, handles)
3684 % hObject    handle to btn3Dview (see GCBO)
3685 % eventdata  reserved - to be defined in a future version of MATLAB
3686 % handles    structure with handles and user data (see GUIDATA)
3687 
3688 if ~isfield(handles,'axesFig3D') || ~isfield(handles,'axesFig3D') || ~isgraphics(handles.axesFig3D)
3689     handles.fig3D = figure('Name','matRad 3D View');
3690     handles.axesFig3D = axes('Parent',handles.fig3D);
3691     view(handles.axesFig3D,3);
3692     try
3693         ct = evalin('base','ct');
3694     
3695         xlim(handles.axesFig3D,[0 ct.resolution.x*ct.cubeDim(2)]);
3696         ylim(handles.axesFig3D,[0 ct.resolution.y*ct.cubeDim(1)]);
3697         zlim(handles.axesFig3D,[0 ct.resolution.z*ct.cubeDim(3)]);
3698     catch
3699     end
3700 end
3701 %end
3702 
3703 UpdatePlot(handles);
3704 
3705 guidata(hObject,handles);
3706 
3707 % --- Executes on button press in radiobtnCT.
3708 function radiobtnCT_Callback(hObject, eventdata, handles)
3709 % hObject    handle to radiobtnCT (see GCBO)
3710 % eventdata  reserved - to be defined in a future version of MATLAB
3711 % handles    structure with handles and user data (see GUIDATA)
3712 
3713 % Hint: get(hObject,'Value') returns toggle state of radiobtnCT
3714 UpdatePlot(handles)
3715 
3716 % --- Executes on button press in radiobtnPlan.
3717 function radiobtnPlan_Callback(hObject, eventdata, handles)
3718 % hObject    handle to radiobtnPlan (see GCBO)
3719 % eventdata  reserved - to be defined in a future version of MATLAB
3720 % handles    structure with handles and user data (see GUIDATA)
3721 
3722 % Hint: get(hObject,'Value') returns toggle state of radiobtnPlan
3723 UpdatePlot(handles)
3724 
3725 
3726 % --- Executes on selection change in popupmenu_windowPreset.
3727 function popupmenu_windowPreset_Callback(hObject, eventdata, handles)
3728 % hObject    handle to popupmenu_windowPreset (see GCBO)
3729 % eventdata  reserved - to be defined in a future version of MATLAB
3730 % handles    structure with handles and user data (see GUIDATA)
3731 
3732 % Hints: contents = cellstr(get(hObject,'String')) returns popupmenu_windowPreset contents as cell array
3733 %        contents{get(hObject,'Value')} returns selected item from popupmenu_windowPreset
3734 
3735 selectionIndexCube      = 2; % working on ct only
3736 selectionIndexWindow    = get(handles.popupmenu_windowPreset,'Value');
3737 newCenter               = handles.windowPresets(selectionIndexWindow).center;
3738 newWidth                = handles.windowPresets(selectionIndexWindow).width;
3739 
3740 handles.dispWindow{selectionIndexCube,1}  = [newCenter - newWidth/2 newCenter + newWidth/2];
3741 handles.cBarChanged = true;
3742 guidata(hObject,handles);
3743 UpdatePlot(handles);
3744 UpdateColormapOptions(handles);
3745 
3746 
3747 % --- Executes during object creation, after setting all properties.
3748 function popupmenu_windowPreset_CreateFcn(hObject, eventdata, handles)
3749 % hObject    handle to popupmenu_windowPreset (see GCBO)
3750 % eventdata  reserved - to be defined in a future version of MATLAB
3751 % handles    empty - handles not created until after all CreateFcns called
3752 
3753 % Hint: popupmenu controls usually have a white background on Windows.
3754 %       See ISPC and COMPUTER.
3755 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
3756     set(hObject,'BackgroundColor','white');
3757 end
3758 
3759 % setup ct window list
3760 % data and values from CERR https://github.com/adityaapte/CERR
3761 windowNames = {'Custom','Full','Abd/Med', 'Head', 'Liver', 'Lung', 'Spine', 'Vrt/Bone'};
3762 windowCenter = {NaN, NaN, -10, 45, 80, -500, 30, 400};
3763 windowWidth = {NaN, NaN, 330, 125, 305, 1500, 300, 1500};
3764 windowPresets = cell2struct([windowNames', windowCenter', windowWidth'], {'name', 'center', 'width'},2);
3765 
3766 
3767 handles.windowPresets = windowPresets;
3768 
3769 selectionList = {windowPresets(:).name};
3770 set(hObject,'String',selectionList(:));
3771 set(hObject,'Value',1);
3772 
3773 
3774 guidata(hObject,handles);
3775 
3776 % --- Executes on button press in checkbox_lockColormap.
3777 function checkbox_lockColormap_Callback(hObject, eventdata, handles)
3778 % hObject    handle to checkbox_lockColormap (see GCBO)
3779 % eventdata  reserved - to be defined in a future version of MATLAB
3780 % handles    structure with handles and user data (see GUIDATA)
3781 
3782 % Hint: get(hObject,'Value') returns toggle state of checkbox_lockColormap
3783 handles.colormapLocked = get(hObject,'Value');
3784 
3785 if handles.colormapLocked
3786     state = 'Off'; %'Inactive';
3787 else
3788     state = 'On';
3789 end
3790 
3791 set(handles.popupmenu_chooseColorData,'Enable',state);
3792 set(handles.popupmenu_windowPreset,'Enable',state);
3793 set(handles.slider_windowWidth,'Enable',state);
3794 set(handles.slider_windowCenter,'Enable',state);
3795 set(handles.edit_windowWidth,'Enable',state);
3796 set(handles.edit_windowCenter,'Enable',state);
3797 set(handles.edit_windowRange,'Enable',state);
3798 set(handles.popupmenu_chooseColormap,'Enable',state);
3799 
3800 
3801 guidata(hObject,handles);
3802 
3803 
3804 function cst = updateStructureTable(handles,cst)
3805 colorAssigned = true;
3806 
3807 % check whether all structures have an assigned color
3808 for i = 1:size(cst,1)
3809     if ~isfield(cst{i,5},'visibleColor')
3810         colorAssigned = false;
3811         break;
3812     elseif isempty(cst{i,5}.visibleColor)
3813         colorAssigned = false;
3814         break;
3815     end
3816 end
3817 
3818 % assign color if color assignment is not already present or inconsistent
3819 if colorAssigned == false
3820   m         = 64;
3821   colorStep = ceil(m/size(cst,1));
3822   colors    = colorcube(colorStep*size(cst,1));
3823   % spread individual VOI colors in the colorcube color palette
3824   colors    = colors(1:colorStep:end,:);
3825   
3826   for i = 1:size(cst,1)
3827     cst{i,5}.visibleColor = colors(i,:);
3828   end
3829 end
3830 
3831 for s = 1:size(cst,1)
3832     handles.VOIPlotFlag(s) = cst{s,5}.Visible;
3833     clr = dec2hex(round(cst{s,5}.visibleColor(:)*255),2)';
3834     clr = ['#';clr(:)]';
3835     if handles.VOIPlotFlag(s)
3836         tmpString{s} = ['<html><table border=0 ><TR><TD bgcolor=',clr,' width="18"><center>&#10004;</center></TD><TD>',cst{s,2},'</TD></TR> </table></html>'];
3837     else
3838         tmpString{s} = ['<html><table border=0 ><TR><TD bgcolor=',clr,' width="18"></TD><TD>',cst{s,2},'</TD></TR> </table></html>'];
3839     end
3840 end
3841 set(handles.legendTable,'String',tmpString);
3842 
3843 %-- generates the CST table
3844 function cst = generateCstTable(handles,cst)
3845 
3846 cst = updateStructureTable(handles,cst);
3847 
3848 cstPanel = handles.uipanel3;
3849 
3850 %Get units in pixels to to calculate aspect ratio
3851 cstPanelPosUnit = get(cstPanel,'Units');
3852 set(cstPanel,'Units','pixels');
3853 cstPanelPosPix = get(cstPanel,'Position');
3854 set(cstPanel,'Units',cstPanelPosUnit);
3855 
3856 aspectRatio = cstPanelPosPix(3) / cstPanelPosPix(4);
3857 
3858 %Parameters for line height
3859 objHeight = 0.095;% 22;
3860 lineHeight = 0.1; %25; %Height of a table line
3861 yTopSep = 0.12;%40; %Separation of the first line from the top
3862 tableViewHeight = 1 - yTopSep; 
3863 
3864 %Define the widths of the fields relatively
3865 buttonW = objHeight / aspectRatio; % Make button squared
3866 nameW = 3.5*buttonW;
3867 typeW = 3*buttonW;
3868 opW = buttonW;
3869 functionW = 6*buttonW;
3870 penaltyW = 2*buttonW;
3871 paramTitleW = 4*buttonW;
3872 paramW = 2*buttonW;
3873 fieldSep = 0.25*buttonW; %Separation between fields horizontally
3874 
3875 
3876 %Scrollbar
3877 %Check if a scrollbar already exists to get possible position of slider
3878 cstPanelChildren = get(cstPanel,'Children');
3879 cstVertTableScroll = findobj(cstPanelChildren,'Style','slider');
3880 if isempty(cstVertTableScroll)
3881     sliderPos = 0;
3882 else
3883     sliderPos = get(cstVertTableScroll,'Max') - get(cstVertTableScroll,'Value');
3884 end
3885 
3886 ypos = @(c) tableViewHeight - c*lineHeight + sliderPos;
3887 
3888 %Clean the whole panel for new setup
3889 delete(cstPanelChildren);
3890 
3891 %Creates a dummy axis to allow for the use of textboxes instead of uicontrol to be able to use the (la)tex interpreter
3892 tmpAxes = axes('Parent',cstPanel,'units','normalized','position',[0 0 1 1],'visible','off');
3893 
3894 organTypes = {'OAR', 'TARGET'};
3895 
3896 %columnname = {'VOI name','VOI type','priority','obj. / const.'};%,'penalty','dose', 'EUD','volume','robustness'};
3897            
3898 %Get all Classes & classNames
3899 mpkgObjectives = meta.package.fromName('DoseObjectives');
3900 mpkgConstraints = meta.package.fromName('DoseConstraints');
3901 classList = [mpkgObjectives.ClassList; mpkgConstraints.ClassList];
3902 
3903 classList = classList(not([classList.Abstract]));
3904 
3905 %Now get the "internal" name from the properties
3906 classNames = cell(2,numel(classList));
3907 for clIx = 1:numel(classList)
3908     cl = classList(clIx);
3909     pList = cl.PropertyList; %Get List of all properties
3910     pNameIx = arrayfun(@(p) strcmp(p.Name,'name'),pList); %get index of the "name" property
3911     p = pList(pNameIx); %select name property
3912     pName = p.DefaultValue; % get value / name
3913     classNames(:,clIx) = {cl.Name; pName}; %Store class name and display name
3914 end
3915 
3916 numOfObjectives = sum(cellfun(@numel,cst(:,6)));
3917 
3918 cnt = 0;
3919 
3920 newline = '\n';
3921 
3922 %Setup Headlines
3923 xPos = 0.01; %5
3924 
3925 h = uicontrol(cstPanel,'Style','text','String','+/-','Units','normalized','Position',[xPos ypos(cnt) buttonW objHeight],'TooltipString','Remove or add Constraint or Objective');
3926 tmp_pos = get(h,'Position');
3927 xPos = xPos + tmp_pos(3) + fieldSep;
3928 h = uicontrol(cstPanel,'Style','text','String','VOI name','Units','normalized','Position',[xPos ypos(cnt) nameW objHeight],'TooltipString','Name of the structure with objective/constraint');
3929 tmp_pos = get(h,'Position');
3930 xPos = xPos + tmp_pos(3) + fieldSep;
3931 h = uicontrol(cstPanel,'Style','text','String','VOI type','Units','normalized','Position',[xPos ypos(cnt) typeW objHeight],'TooltipString','Segmentation Classification');
3932 tmp_pos = get(h,'Position');
3933 xPos = xPos + tmp_pos(3) + fieldSep;
3934 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)']);
3935 tmp_pos = get(h,'Position');
3936 xPos = xPos + tmp_pos(3) + fieldSep;
3937 h = uicontrol(cstPanel,'Style','text','String','Function','Units','normalized','Position',[xPos ypos(cnt) functionW objHeight],'TooltipString','Objective/Constraint function type');
3938 tmp_pos = get(h,'Position');
3939 xPos = xPos + tmp_pos(3) + fieldSep;
3940 h = uicontrol(cstPanel,'Style','text','String','p','Units','normalized','Position',[xPos ypos(cnt) penaltyW objHeight],'TooltipString','Optimization penalty');
3941 tmp_pos = get(h,'Position');
3942 xPos = xPos + tmp_pos(3) + fieldSep;
3943 h = uicontrol(cstPanel,'Style','text','String','| Parameters','Units','normalized','Position',[xPos ypos(cnt) paramTitleW objHeight],'TooltipString','List of parameters','HorizontalAlignment','left');
3944 tmp_pos = get(h,'Position');
3945 xPos = xPos + tmp_pos(3) + fieldSep;
3946 cnt = cnt + 1;
3947 
3948 %Create Objectives / Constraints controls
3949 for i = 1:size(cst,1)   
3950     if strcmp(cst(i,3),'IGNORED')~=1
3951         %Compatibility Layer for old objective format
3952         if isstruct(cst{i,6})
3953             cst{i,6} = arrayfun(@matRad_DoseOptimizationFunction.convertOldOptimizationStruct,cst{i,6},'UniformOutput',false);
3954         end
3955         for j=1:numel(cst{i,6})
3956       
3957            obj = cst{i,6}{j};
3958            
3959            %Convert to class if not
3960            if ~isa(obj,'matRad_DoseOptimizationFunction')
3961                 try
3962                     obj = matRad_DoseOptimizationFunction.createInstanceFromStruct(obj);
3963                 catch ME
3964                     warning('Objective/Constraint not valid!\n%s',ME.message)
3965                     continue;
3966                 end
3967            end
3968 
3969            %VOI
3970            xPos = 0.01;%5;
3971            
3972            h = uicontrol(cstPanel,'Style','pushbutton','String','-','Units','normalized','Position',[xPos ypos(cnt) buttonW objHeight],'TooltipString','Remove Objective/Constraint','Callback',{@btObjRemove_Callback,handles},...
3973                'UserData',[i,j]);
3974            tmp_pos = get(h,'Position');
3975            xPos = xPos + tmp_pos(3) + fieldSep;
3976            h = uicontrol(cstPanel','Style','edit','String',cst{i,2},'Units','normalized','Position',[xPos ypos(cnt) nameW objHeight],'TooltipString','Name',...
3977                'Enable','inactive',... %Disable editing of name atm
3978                'UserData',[i,2],'Callback',{@editCstParams_Callback,handles}); %Callback added, however, editing is disabled atm
3979            tmp_pos = get(h,'Position');
3980            xPos = xPos + tmp_pos(3) + fieldSep;
3981            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',...
3982                'UserData',[i,3],'Callback',{@editCstParams_Callback,handles});
3983            tmp_pos = get(h,'Position');
3984            xPos = xPos + tmp_pos(3) + fieldSep;
3985            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)'],...
3986                'UserData',[i,5],'Callback',{@editCstParams_Callback,handles});
3987            tmp_pos = get(h,'Position');
3988            xPos = xPos + tmp_pos(3) + fieldSep;
3989            
3990            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',...
3991                'UserData',{[i,j],classNames(1,:)},'Callback',{@changeObjFunction_Callback,handles});
3992            tmp_pos = get(h,'Position');
3993            xPos = xPos + tmp_pos(3) + fieldSep;
3994            
3995            %Check if we have an objective to display penalty
3996            if isa(obj,'DoseObjectives.matRad_DoseObjective')
3997                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});
3998            else
3999                h = uicontrol(cstPanel,'Style','edit','String','----','Units','normalized','Position',[xPos ypos(cnt) penaltyW objHeight],'Enable','off');
4000            end
4001            tmp_pos = get(h,'Position');
4002            xPos = xPos + tmp_pos(3) + fieldSep;
4003            
4004            %Iterate through parameters
4005            for p = 1:numel(obj.parameterNames)
4006               h = text('Parent',tmpAxes,'String',['| ' obj.parameterNames{p} ':'],'VerticalAlignment','middle','Units','normalized','Position',[xPos ypos(cnt)+lineHeight/2],'Interpreter','tex','FontWeight','normal',...
4007                   'FontSize',get(cstPanel,'FontSize'),'FontName',get(cstPanel,'FontName'),'FontUnits',get(cstPanel,'FontUnits'),'FontWeight','normal');
4008               tmp_pos = get(h,'Extent');
4009               xPos = xPos + tmp_pos(3) + fieldSep;
4010               
4011               %Check if we have a cell and therefore a parameter list
4012               if iscell(obj.parameterTypes{p})                  
4013                   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});
4014               else
4015                 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});
4016               end
4017               
4018               tmp_pos = get(h,'Position');
4019               xPos = xPos + tmp_pos(3) + fieldSep;
4020            end
4021 
4022            cnt = cnt +1;
4023        end
4024    end   
4025 end
4026 xPos = 0.01; %5
4027 hAdd = uicontrol(cstPanel,'Style','pushbutton','String','+','Units','normalized','Position',[xPos ypos(cnt) buttonW objHeight],'TooltipString','Add Objective/Constraint','Callback',{@btObjAdd_Callback,handles});
4028 tmp_pos = get(hAdd,'Position');
4029 xPos = xPos + tmp_pos(3) + fieldSep;
4030 h = uicontrol(cstPanel,'Style','popupmenu','String',cst(:,2)','Units','normalized','Position',[xPos ypos(cnt) nameW objHeight]);
4031 set(hAdd,'UserData',h);
4032 
4033 %Calculate Scrollbar / Slider Position
4034 lastPos = ypos(cnt);
4035 firstPos = ypos(0);
4036 tableHeight = abs(firstPos - lastPos);
4037 
4038 exceedFac = tableHeight / tableViewHeight; %How much the current umber of rows exceeds the window height capacity
4039 if exceedFac > 1
4040     sliderFac = exceedFac - 1; 
4041     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});
4042 end
4043  
4044 
4045 % --- Executes when uipanel3 is resized.
4046 function uipanel3_SizeChangedFcn(hObject, eventdata, handles)
4047 % hObject    handle to uipanel3 (see GCBO)
4048 % eventdata  reserved - to be defined in a future version of MATLAB
4049 % handles    structure with handles and user data (see GUIDATA)
4050 
4051 try
4052     generateCstTable(handles,evalin('base','cst'));
4053 catch
4054 end
4055 
4056 function btObjAdd_Callback(hObject, ~, handles)
4057 % hObject    handle to btObjAdd
4058 % eventdata  reserved - to be defined in a future version of MATLAB
4059 % handles    structure with handles and user data (see GUIDATA)
4060 popupHandle = hObject.UserData;
4061 cstIndex = popupHandle.Value;
4062 
4063 cst = evalin('base','cst');
4064 %Add Standard Objective
4065 if strcmp(cst{cstIndex,3},'TARGET')
4066     cst{cstIndex,6}{end+1} = struct(DoseObjectives.matRad_SquaredDeviation);
4067 else
4068     cst{cstIndex,6}{end+1} = struct(DoseObjectives.matRad_SquaredOverdosing);
4069 end
4070 
4071 assignin('base','cst',cst);
4072 
4073 generateCstTable(handles,cst);
4074 
4075 function btObjRemove_Callback(hObject, ~, handles)
4076 % hObject    handle to btObjRemove (see GCBO)
4077 % eventdata  reserved - to be defined in a future version of MATLAB
4078 % handles    structure with handles and user data (see GUIDATA)
4079 ix = hObject.UserData;
4080 
4081 cst = evalin('base','cst');
4082 %Add Standard Objective
4083 
4084 cst{ix(1),6}(ix(2)) = [];
4085 
4086 assignin('base','cst',cst);
4087 
4088 generateCstTable(handles,cst);
4089 
4090 function editObjParam_Callback(hObject, ~, handles)
4091 % hObject    handle to current objective parameter
4092 % eventdata  reserved - to be defined in a future version of MATLAB
4093 % handles    structure with handles and user data (see GUIDATA)
4094 ix = hObject.UserData;
4095 
4096 cst = evalin('base','cst');
4097 %Add Standard Objective
4098 
4099 %if the third index is 0 we changed the penalty
4100 %if we have a popupmenu selection we use value
4101 %otherwise we use the edit string
4102 
4103 if ix(3) == 0
4104     cst{ix(1),6}{ix(2)}.penalty = str2double(hObject.String);
4105 elseif isequal(hObject.Style,'popupmenu')
4106     cst{ix(1),6}{ix(2)}.parameters{ix(3)} = hObject.Value;
4107 else
4108     cst{ix(1),6}{ix(2)}.parameters{ix(3)} = str2double(hObject.String);
4109 end
4110     
4111 assignin('base','cst',cst);
4112 
4113 generateCstTable(handles,cst);
4114 
4115 function changeObjFunction_Callback(hObject, ~, handles)
4116 % hObject    handle to objective popup
4117 % eventdata  reserved - to be defined in a future version of MATLAB
4118 % handles    structure with handles and user data (see GUIDATA)
4119 data = hObject.UserData;
4120 ix = data{1};
4121 classNames = data{2};
4122 classToCreate = classNames{hObject.Value};
4123 
4124 cst = evalin('base','cst');
4125 %Add Standard Objective
4126 
4127 %We just check if the user really wanted to change the objective to be
4128 %user-friendly
4129 currentObj = cst{ix(1),6}{ix(2)};
4130 currentClass = class(currentObj);
4131 if ~strcmp(currentClass,classToCreate)    
4132     newObj = eval(classToCreate);
4133     
4134     % Only if we have a penalty value for optimization, apply the new one
4135     % Maybe this check should be more exact?
4136     if (isfield(currentObj,'penalty') || isprop(currentObj,'penalty')) && isprop(newObj,'penalty')
4137         newObj.penalty = currentObj.penalty;
4138     end
4139     
4140     cst{ix(1),6}{ix(2)} = struct(newObj);
4141     
4142     assignin('base','cst',cst);   
4143     
4144     generateCstTable(handles,cst);
4145 end
4146 
4147 function editCstParams_Callback(hObject,~,handles)
4148 data = hObject.UserData;
4149 ix = data(1);
4150 col = data(2);
4151 
4152 cst = evalin('base','cst');
4153 
4154 switch col
4155     case 2
4156         cst{ix,col} = hObject.String;
4157     case 3
4158         cst{ix,col} = hObject.String{hObject.Value};
4159     case 5
4160         cst{ix,col}.Priority = uint32(str2double(hObject.String));
4161     otherwise
4162         warning('Wrong column assignment in GUI based cst setting');
4163 end
4164 
4165 assignin('base','cst',cst);
4166 
4167 generateCstTable(handles,cst);
4168 
4169     
4170 % --- Executes on button press in radiobutton3Dconf.
4171 function radiobutton3Dconf_Callback(hObject, eventdata, handles)
4172 % hObject    handle to radiobutton3Dconf (see GCBO)
4173 % eventdata  reserved - to be defined in a future version of MATLAB
4174 % handles    structure with handles and user data (see GUIDATA)
4175 
4176 % Hint: get(hObject,'Value') returns toggle state of radiobutton3Dconf
4177 
4178 function x = matRad_checkForConnectedBixelRows(stf)
4179 
4180 x = true;
4181 
4182 for i = 1:size(stf,2)
4183     
4184     bixelPos = reshape([stf(i).ray.rayPos_bev],3,[]);
4185    
4186     rowCoords = unique(bixelPos(3,:));
4187     
4188     for j = 1:numel(rowCoords)
4189         
4190         increments = diff(bixelPos(1,rowCoords(j) == bixelPos(3,:)));
4191         
4192         % if we find one not connected row -> return false
4193         if numel(unique(increments)) > 1
4194             x = false;
4195             return;
4196         end
4197     end
4198     
4199 end
4200 
4201 % --- Executes on slider movement.
4202 function cstTableSlider_Callback(hObject, eventdata, handles)
4203 % hObject    handle to cstTableSlider (see GCBO)
4204 % eventdata  reserved - to be defined in a future version of MATLAB
4205 % handles    structure with handles and user data (see GUIDATA)
4206 
4207 % Hints: get(hObject,'Value') returns position of slider
4208 %        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
4209 generateCstTable(handles,evalin('base','cst'));
4210 
4211 % --- Executes during object creation, after setting all properties.
4212 function cstTableSlider_CreateFcn(hObject, eventdata, handles)
4213 % hObject    handle to cstTableSlider (see GCBO)
4214 % eventdata  reserved - to be defined in a future version of MATLAB
4215 % handles    empty - handles not created until after all CreateFcns called
4216 
4217 % Hint: slider controls usually have a light gray background.
4218 if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
4219     set(hObject,'BackgroundColor',[.9 .9 .9]);
4220 end
4221

| Generated by m2html © 2005