diff --git a/.github/workflows/test-results.yml b/.github/workflows/test-results.yml index 8322c983a..8507868cf 100644 --- a/.github/workflows/test-results.yml +++ b/.github/workflows/test-results.yml @@ -36,5 +36,10 @@ jobs: with: files: | test-results/*/testresults.xml - + + - name: Publish Test Results on Codecov + uses: codecov/test-results-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: test-results/matlab-R2022b/testresults.xml,test-results/matlab-latest/testresults.xml,test-results/octave/testresults.xml \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 000000000..5b7b37775 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,51 @@ +variables: + GIT_SUBMODULE_STRATEGY: recursive + GIT_SUBMODULE_DEPTH: 1 + GIT_SUBMODULE_PATH: submodules/MOxUnit submodules/MOcov + +.matlab_defaults: + image: + name: '${CUSTOM_MATLAB_IMAGE}:r2024b' # Replace the value with the name of the MATLAB container image you want to use + entrypoint: [""] + variables: + MLM_LICENSE_FILE: $E040_MATLAB_LICENSE_SERVER # Replace the value with the port number and DNS address for your network license manager + resource_group: matlab + +test: + stage: test + extends: .matlab_defaults + script: matlab -batch "assert(matRad_runTests('test',true));" + artifacts: + reports: + junit: "./testresults.xml" + coverage_report: + coverage_format: cobertura + path: "./coverage.xml" + paths: + - "./*.xml" + - "./*.json" + coverage: '/TOTAL.*? (100(?:\.0+)?%|[1-9]?\d(?:\.\d+)?%)/' + + +package: + stage: deploy + extends: .matlab_defaults + script: + - | + if [ -n "$CI_COMMIT_TAG" ]; then + matlab -batch "matRad_buildStandalone('isRelease', true);" + PACKAGE_NAME="$CI_COMMIT_TAG" + else + matlab -batch "matRad_buildStandalone();" + PACKAGE_NAME="$CI_COMMIT_BRANCH" + fi + INSTALLER_NAME="matRad_installerLinux64_$PACKAGE_NAME" + - tar -czvf $INSTALLER_NAME.tar.gz build/installer + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file $INSTALLER_NAME.tar.gz "$CI_API_V4_URL/projects/$CI_PROJECT_ID/packages/generic/matRad_linux64/$CI_COMMIT_BRANCH/matRad/$PACKAGE_NAME/$INSTALLER_NAME.tar.gz"' + # - echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin + # - docker image tag matRad:develop $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/matRad:develop + # - docker push $CI_REGISTRY/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/matRad:develop + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - if: $CI_COMMIT_BRANCH == "dev" + - if: $CI_COMMIT_TAG diff --git a/CHANGELOG.md b/CHANGELOG.md index fd1ac42ab..2c221a221 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## Development Changes + +### Bug Fixes +- DICOM Import widget allow selection of multiple RTDose files. +- DICOM Import Widget and importer handle selected patient more consistently and robustly. +- DICOM Exporter writes quantities beyond dose, importer tries to import them correctly. +- DICOM Exporter now always writes ReferencedRTPlanSequence. Importer can now survive without it. +- DVH widget does not throw a warning in updates, handle scenarios correctly / more robustly and missing xlabel axesHandle parameter. + + ## Version 3.1.0 - "Cleve" ### Major Changes and New Features diff --git a/matRad/dicom/@matRad_DicomExporter/matRad_exportDicomRTDoses.m b/matRad/dicom/@matRad_DicomExporter/matRad_exportDicomRTDoses.m index ed420dc0e..c0d6380a1 100644 --- a/matRad/dicom/@matRad_DicomExporter/matRad_exportDicomRTDoses.m +++ b/matRad/dicom/@matRad_DicomExporter/matRad_exportDicomRTDoses.m @@ -44,15 +44,12 @@ meta.Modality = 'RTDOSE'; meta.Manufacturer = ''; -meta.DoseUnits = 'GY'; %Reference %ID of the CT meta.StudyInstanceUID = obj.StudyInstanceUID; meta.StudyID = obj.StudyID; - - %Dates & Times currDate = now; currDateStr = datestr(currDate,'yyyymmdd'); @@ -99,10 +96,11 @@ meta.GridFrameOffsetVector = transpose(ct.z - ct.z(1)); %Referenced Plan -%This does currently not work due to how Matlab creates UIDs by itself, -%we can not know the reference before it is written by the RTPlanExport, -%which itself needs the RTDose UIDs -%{ +%This does currently not work well due to how Matlab creates UIDs by +%itself, we can not know the reference before it is written by the +%RTPlanExport, which itself needs the RTDose UIDs. +%However, we need to set the ReferencedRTPlanSequence, because it is a +%conditionally required field according to the DICOM standard try rtPlanUID = obj.rtPlanMeta.SOPInstanceUID; catch @@ -111,38 +109,34 @@ obj.rtPlanMeta.SOPClassUID = obj.rtPlanClassUID; rtPlanUID = obj.rtPlanMeta.SOPInstanceUID; end -%} - - -%meta.ReferencedRTPlanSequence.Item_1.ReferencedSOPClassUID = obj.rtPlanClassUID; -%meta.ReferencedRTPlanSequence.Item_1.ReferencedSOPInstanceUID = rtPlanUID; - -if nargin < 4 || isempty(doseFieldNames) - doseFieldNames = cell(0); - fn = fieldnames(obj.resultGUI); - for i = 1:numel(fn) - if numel(size(obj.resultGUI.(fn{i}))) == 3 - doseFieldNames{end+1} = fn{i}; - end + +meta.ReferencedRTPlanSequence.Item_1.ReferencedSOPClassUID = obj.rtPlanClassUID; +meta.ReferencedRTPlanSequence.Item_1.ReferencedSOPInstanceUID = rtPlanUID; + +doseFieldNames = cell(0); +fn = fieldnames(obj.resultGUI); +for i = 1:numel(fn) + if numel(size(obj.resultGUI.(fn{i}))) == 3 + doseFieldNames{end+1} = fn{i}; end end - - - - obj.rtDoseMetas = struct([]); obj.rtDoseExportStatus = struct([]); for i = 1:numel(doseFieldNames) - doseName = doseFieldNames{i}; + doseName = doseFieldNames{i}; + doseUnits = 'GY'; %Now check if we export physical or RBE weighted dose, they are known %to dicom - if strncmp(doseName,'physicalDose',12) + if strncmp(doseName,'physicalDose',12) || strncmp(doseName,'LET',3) doseType = 'PHYSICAL'; - elseif strncmp(doseName,'RBExDose',8) + elseif strncmp(doseName,'RBExDose',8) || strncmp(doseName,'BED',3) || strncmp(doseName,'alpha',3) || strncmp(doseName,'beta',3) || strncmp(doseName,'effect',6) || strncmp(doseName,'RBE',3) doseType = 'EFFECTIVE'; + if strncmp(doseName,'RBE',3) + doseUnits = 'RELATIVE'; + end else matRad_cfg.dispInfo('Dose Cube ''%s'' of unknown type for DICOM. Not exported!\n',doseName); continue; @@ -174,6 +168,8 @@ metaCube = meta; metaCube.DoseType = doseType; metaCube.DoseSummationType = deliveryType; + metaCube.DoseComment = doseName; + metaCube.DoseUnits = doseUnits; %ID of the RTDose metaCube.SeriesInstanceUID = dicomuid; diff --git a/matRad/dicom/@matRad_DicomImporter/matRad_DicomImporter.m b/matRad/dicom/@matRad_DicomImporter/matRad_DicomImporter.m index c870cb100..1c3368182 100644 --- a/matRad/dicom/@matRad_DicomImporter/matRad_DicomImporter.m +++ b/matRad/dicom/@matRad_DicomImporter/matRad_DicomImporter.m @@ -26,7 +26,8 @@ % lists of all files allfiles; - patient; + patients; + selectedPatient; importFiles; % all the names (directories) of files, that will be imported % properties with data for import functions diff --git a/matRad/dicom/@matRad_DicomImporter/matRad_importDicomRTDose.m b/matRad/dicom/@matRad_DicomImporter/matRad_importDicomRTDose.m index 52672fab6..93f49a979 100644 --- a/matRad/dicom/@matRad_DicomImporter/matRad_importDicomRTDose.m +++ b/matRad/dicom/@matRad_DicomImporter/matRad_importDicomRTDose.m @@ -62,11 +62,24 @@ else doseInstanceHelper = []; end - + + doseComment = ''; + if isfield(dose.(itemName).dicomInfo,'DoseComment') + doseComment = dose.(itemName).dicomInfo.DoseComment; + end + if strncmpi(doseTypeHelper,'PHYSICAL',6) - doseTypeHelper = 'physicalDose'; + if any(strcmp(doseComment,{'physicalDose','LET'})) + doseTypeHelper = doseComment; + else + doseTypeHelper = 'physicalDose'; + end elseif strncmpi(doseTypeHelper,'EFFECTIVE',6) - doseTypeHelper = 'RBExDose'; + if any(strcmp(doseComment,{'RBExDose','BED','alpha','beta','effect','RBE'})) + doseTypeHelper = doseComment; + else + doseTypeHelper = 'RBExDose'; + end end %If given as plan and not per fraction diff --git a/matRad/dicom/@matRad_DicomImporter/matRad_interpDicomDoseCube.m b/matRad/dicom/@matRad_DicomImporter/matRad_interpDicomDoseCube.m index 516eedc46..0fd4847f5 100644 --- a/matRad/dicom/@matRad_DicomImporter/matRad_interpDicomDoseCube.m +++ b/matRad/dicom/@matRad_DicomImporter/matRad_interpDicomDoseCube.m @@ -102,7 +102,9 @@ %always given obj.importRTDose.dose.dicomInfo.SOPClassUID = doseInfo.SOPClassUID; obj.importRTDose.dose.dicomInfo.SOPInstanceUID = doseInfo.SOPInstanceUID; -obj.importRTDose.dose.dicomInfo.ReferencedRTPlanSequence = doseInfo.ReferencedRTPlanSequence; +if isfield(doseInfo,'ReferencedRTPlanSequence') + obj.importRTDose.dose.dicomInfo.ReferencedRTPlanSequence = doseInfo.ReferencedRTPlanSequence; +end end diff --git a/matRad/dicom/@matRad_DicomImporter/matRad_scanDicomImportFolder.m b/matRad/dicom/@matRad_DicomImporter/matRad_scanDicomImportFolder.m index ab4d3c376..b5874a40b 100644 --- a/matRad/dicom/@matRad_DicomImporter/matRad_scanDicomImportFolder.m +++ b/matRad/dicom/@matRad_DicomImporter/matRad_scanDicomImportFolder.m @@ -246,9 +246,9 @@ close(h) if ~isempty(obj.allfiles) - obj.patient = unique(obj.allfiles(:,3)); + obj.patients = unique(obj.allfiles(:,3)); - if isempty(obj.patient) + if isempty(obj.patients) matRad_cfg.dispError('No patient found with DICOM CT _and_ RT structure set in patient directory!'); end else diff --git a/matRad/gui/widgets/matRad_DVHWidget.m b/matRad/gui/widgets/matRad_DVHWidget.m index 61bb83f81..dc8fe26e5 100644 --- a/matRad/gui/widgets/matRad_DVHWidget.m +++ b/matRad/gui/widgets/matRad_DVHWidget.m @@ -109,15 +109,24 @@ function showDVH(this) resultGUI = evalin('base','resultGUI'); pln = evalin('base','pln'); cst = evalin('base','cst'); + ct = evalin('base','ct'); + % Calculate and show DVH doseCube = resultGUI.(this.selectedCube); dvh = matRad_calcDVH(cst,doseCube,'cum'); matRad_showDVH(dvh,cst,pln,'axesHandle',this.dvhAx); + + if ~isfield(pln,'multScen') + multScen = matRad_NominalScenario(ct); + else + multScen = pln.multScen; + end + multScen = matRad_ScenarioModel.create(multScen,ct); %check scenarios - if pln.multScen.totNumScen > 1 - for i = 1:pln.multScen.totNumScen + if multScen.totNumScen > 1 + for i = 1:multScen.totNumScen scenFieldName = sprintf('%s_scen%d',this.selectedCube,i); if isfield(resultGUI,scenFieldName) tmpDvh = matRad_calcDVH(cst,resultGUI.(scenFieldName),'cum'); % Calculate cumulative scenario DVH diff --git a/matRad/gui/widgets/matRad_importDicomWidget.m b/matRad/gui/widgets/matRad_importDicomWidget.m index 5cb106379..9c4deb25e 100644 --- a/matRad/gui/widgets/matRad_importDicomWidget.m +++ b/matRad/gui/widgets/matRad_importDicomWidget.m @@ -174,8 +174,8 @@ % to pass only selected objects to the matRad_importDicom % selected patient if ~isempty(handles.patient_listbox) - selected_patient = this.importer.patient{get(handles.patient_listbox,'Value')}; - this.importer.patient = selected_patient; + selected_patient = get(handles.patient_listbox,'Value'); + this.importer.selectedPatient = selected_patient; end % selected CT serie @@ -211,7 +211,7 @@ % selected dose serie allRTDoses = this.importer.importFiles.rtdose; if ~isempty(allRTDoses) && ~isempty(handles.doseseries_listbox.Value) - UIDSelected_rtdose = handles.doseseries_listbox.String{get(handles.doseseries_listbox,'Value'), 1}; + UIDSelected_rtdose = handles.doseseries_listbox.String(get(handles.doseseries_listbox,'Value')); selectedRTDose = allRTDoses(strcmp(allRTDoses(:, 4), UIDSelected_rtdose), :); this.importer.importFiles.rtdose = selectedRTDose; else @@ -222,7 +222,7 @@ %% save ct, cst, pln, dose matRad_cfg = MatRad_Config.instance(); - matRadFileName = fullfile(matRad_cfg.userfolders{1},[this.importer.patient '.mat']); % use default from dicom + matRadFileName = fullfile(matRad_cfg.userfolders{1},[this.importer.patients{this.importer.selectedPatient} '.mat']); % use default from dicom [FileName,PathName] = uiputfile('*.mat','Save as...',matRadFileName); ct = this.importer.ct; cst = this.importer.cst; @@ -970,13 +970,15 @@ this.importer = matRad_DicomImporter(get(handles.dir_path_field,'String')); - if iscell(this.importer.patient) - handles.fileList = this.importer.allfiles; - %handles.patient_listbox.String = patient_listbox; - set(handles.patient_listbox,'String',this.importer.patient,'Value',1); - % guidata(hObject, handles); - this.handles = handles; + handles.fileList = this.importer.allfiles; + %handles.patient_listbox.String = patient_listbox; + if isempty(this.importer.selectedPatient) || this.importer.selectedPatient > numel(this.importer.patients) + this.importer.selectedPatient = 1; end + + set(handles.patient_listbox,'String',this.importer.patients,'Value',this.importer.selectedPatient); + % guidata(hObject, handles); + this.handles = handles; end end diff --git a/matRad/planAnalysis/matRad_showDVH.m b/matRad/planAnalysis/matRad_showDVH.m index cbf67a700..b9ebde1cb 100644 --- a/matRad/planAnalysis/matRad_showDVH.m +++ b/matRad/planAnalysis/matRad_showDVH.m @@ -163,7 +163,7 @@ function matRad_showDVH(dvh,cst,varargin) pln.bioModel = matRad_BiologicalModel.validate(pln.bioModel,pln.radiationMode); if strcmp(pln.bioModel.model,'none') - xlabel('Dose [Gy]','FontSize',fontSizeValue); + xlabel(axesHandle,'Dose [Gy]','FontSize',fontSizeValue); else xlabel(axesHandle,'RBE x Dose [Gy(RBE)]','FontSize',fontSizeValue); end diff --git a/matRad_buildStandalone.m b/matRad_buildStandalone.m index 6feebb3e2..55de5a97e 100644 --- a/matRad_buildStandalone.m +++ b/matRad_buildStandalone.m @@ -23,8 +23,8 @@ matRadRoot = matRad_cfg.matRadRoot; standaloneFolder = fullfile(matRadRoot,'standalone'); +%Setup Input Parsing p = inputParser; - p.addParameter('isRelease',false,@islogical); %By default we compile a snapshot of the current branch p.addParameter('compileWithRT',false,@islogical); %By default we don't package installers with runtime p.addParameter('buildDir',fullfile(matRadRoot,'build'),@(x) ischar(x) || isstring(x)); %Build directory @@ -34,8 +34,8 @@ p.addParameter('python',false,@islogical); p.addParameter('json',[],@(x) isempty(x) || ischar(x) || isstring(x)); +%Parse and manage inputs p.parse(varargin{:}); - isRelease = p.Results.isRelease; compileWithRT = p.Results.compileWithRT; buildDir = p.Results.buildDir; @@ -56,12 +56,20 @@ rtOption = 'web'; end -try +%Display OS for debugging and information +arch = computer('arch'); +fprintf('Build Architecture: %s\n',arch); +archcheck = string([ispc,isunix,ismac]).cellstr(); +fprintf('pc\t\tunix\tmac\n%s\t%s\t%s\n',archcheck{:}); + +%Check build directory +try mkdir(buildDir); catch ME error(ME.identifier,'Could not create build directory %s\n Error:',buildDir,ME.message); end +%Docker build? if buildDocker && isunix && ~ismac warning('Can''t build docker container. Only works on linux!'); buildDocker = false; @@ -103,7 +111,7 @@ 'ExecutableVersion',vernumApp,... 'TreatInputsAsNumeric','off',... 'Verbose',verbose); - + if ispc resultsStandalone = compiler.build.standaloneWindowsApplication(buildOpts); else @@ -120,20 +128,12 @@ %% Package if ispc readmeFile = 'readme_standalone_windows.txt'; - installerId = 'Win64'; elseif ismac readmeFile = 'readme_standalone_mac.txt'; - [~,result] = system('uname -m'); - if any(strfind(result,'ARM64')) %is m1mac - installerId = 'MacARM'; - else - installerId = 'Mac64'; - end - else readmeFile = 'readme_standalone_linux.txt'; - installerId = 'Linux64'; end +installerId = arch; try packageOpts = compiler.package.InstallerOptions(resultsStandalone,... @@ -147,7 +147,7 @@ 'InstallerIcon',fullfile(standaloneFolder,'matRad_icon.png'),... 'InstallerLogo',fullfile(standaloneFolder,'matRad_installscreen.png'),... 'InstallerSplash',fullfile(standaloneFolder,'matRad_splashscreen.png'),... - 'InstallerName',sprintf('matRad_installer%s_v%s',installerId,vernumApp),... + 'InstallerName',sprintf('matRad_installer_%s_v%s',installerId,vernumApp),... 'OutputDir',fullfile(buildDir,'installer'),... 'RuntimeDelivery',rtOption,... 'Summary','matRad is an open source treatment planning system for radiation therapy written in Matlab.',... @@ -208,34 +208,33 @@ %% Docker if buildDocker try + if isRelease + imageName = ['matRad:' vernumInstall]; + else + imageName = 'matRad:develop'; + end dockerOpts = compiler.package.DockerOptions(results,... 'AdditionalInstructions','',... 'AdditionalPackages','',... 'ContainerUser','appuser',... 'DockerContext',fullfile(buildDir,'docker'),... 'ExecuteDockerBuild','on',... - 'ImageName','e0404/matrad'); + 'ImageName',imageName); compiler.package.docker(results,'Options',dockerOpts); buildResult.docker.image = dockerOpts.ImageName; catch ME warning(ME.identifier,'Java build failed due to %s!',ME.message); end -end +end if ~isempty(json) try fH = fopen(json,'w'); - jsonStr = jsonencode(buildResult,"PrettyPrint",true); + jsonStr = jsonencode(buildResult,"PrettyPrint",true); fwrite(fH,jsonStr); - fclose(fH); + fclose(fH); catch ME warning(ME.identifier,'Could not open JSON file for writing: %s',ME.message); end end - - - - - - diff --git a/test/gui/test_gui_DVHStatsWidget.m b/test/gui/test_gui_DVHStatsWidget.m index 0d1024de7..2a9cbc111 100644 --- a/test/gui/test_gui_DVHStatsWidget.m +++ b/test/gui/test_gui_DVHStatsWidget.m @@ -40,4 +40,61 @@ delete(h); close(get(p,'Parent')); +function test_DVHStatsWidget_constructWithPhotonPln + evalin('base','load photons_testData.mat'); + h = matRad_DVHStatsWidget(); + h.selectedDisplayOption = 'physicalDose'; + try + assertTrue(isa(h, 'matRad_DVHStatsWidget')); + assertTrue(isa(h, 'matRad_Widget')); + catch ME + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + rethrow(ME); + end + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + +function test_DVHStatsWidget_constructWithProtonPln + evalin('base','load protons_testData.mat'); + h = matRad_DVHStatsWidget(); + try + assertTrue(isa(h, 'matRad_DVHStatsWidget')); + assertTrue(isa(h, 'matRad_Widget')); + catch ME + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + rethrow(ME); + end + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + +function test_DVHStatsWidget_constructWithCarbonPln + evalin('base','load carbon_testData.mat'); + h = matRad_DVHStatsWidget(); + try + assertTrue(isa(h, 'matRad_DVHStatsWidget')); + assertTrue(isa(h, 'matRad_Widget')); + catch ME + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + rethrow(ME); + end + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + +function test_DVHStatsWidget_constructWithHeliumPln + evalin('base','load helium_testData.mat'); + h = matRad_DVHStatsWidget(); + try + assertTrue(isa(h, 'matRad_DVHStatsWidget')); + assertTrue(isa(h, 'matRad_Widget')); + catch ME + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + rethrow(ME); + end + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + %TODO: Test Buttons / visibility depending on data \ No newline at end of file diff --git a/test/gui/test_gui_PlanWidget.m b/test/gui/test_gui_PlanWidget.m index 483aa8b86..d397da83d 100644 --- a/test/gui/test_gui_PlanWidget.m +++ b/test/gui/test_gui_PlanWidget.m @@ -40,7 +40,7 @@ delete(h); close(get(p,'Parent')); -function test_PlanWidget_constructWithData +function test_PlanWidget_constructWithTG119 evalin('base','load TG119.mat'); h = matRad_PlanWidget(); try @@ -52,6 +52,63 @@ rethrow(ME); end evalin('base','clear ct cst pln'); - delete(h); + delete(h); + +function test_PlanWidget_constructWithPhotonPln + evalin('base','load photons_testData.mat'); + h = matRad_PlanWidget(); + try + assertTrue(isa(h, 'matRad_PlanWidget')); + assertTrue(isa(h, 'matRad_Widget')); + catch ME + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + rethrow(ME); + end + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + +function test_PlanWidget_constructWithProtonPln + evalin('base','load protons_testData.mat'); + h = matRad_PlanWidget(); + try + assertTrue(isa(h, 'matRad_PlanWidget')); + assertTrue(isa(h, 'matRad_Widget')); + catch ME + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + rethrow(ME); + end + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + +function test_PlanWidget_constructWithCarbonPln + evalin('base','load carbon_testData.mat'); + h = matRad_PlanWidget(); + try + assertTrue(isa(h, 'matRad_PlanWidget')); + assertTrue(isa(h, 'matRad_Widget')); + catch ME + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + rethrow(ME); + end + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + +function test_PlanWidget_constructWithHeliumPln + evalin('base','load helium_testData.mat'); + h = matRad_PlanWidget(); + try + assertTrue(isa(h, 'matRad_PlanWidget')); + assertTrue(isa(h, 'matRad_Widget')); + catch ME + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + rethrow(ME); + end + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + -%TODO: Test Buttons / visibility depending on data \ No newline at end of file +%TODO: Test Buttons \ No newline at end of file diff --git a/test/gui/test_gui_exportWidget.m b/test/gui/test_gui_exportWidget.m index fb39d2a47..4042973d5 100644 --- a/test/gui/test_gui_exportWidget.m +++ b/test/gui/test_gui_exportWidget.m @@ -55,4 +55,18 @@ evalin('base','clear ct cst pln'); delete(h); +function test_exportWidget_constructWithCarbonPln + evalin('base','load carbon_testData.mat'); + h = matRad_exportWidget(); + try + assertTrue(isa(h, 'matRad_exportWidget')); + assertTrue(isa(h, 'matRad_Widget')); + catch ME + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + rethrow(ME); + end + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + %TODO: Test Buttons / visibility depending on data \ No newline at end of file diff --git a/test/gui/test_gui_viewingWidget.m b/test/gui/test_gui_viewingWidget.m index 91a33bd72..db112f800 100644 --- a/test/gui/test_gui_viewingWidget.m +++ b/test/gui/test_gui_viewingWidget.m @@ -40,7 +40,7 @@ delete(h); close(get(p,'Parent')); -function test_viewingWidget_constructWithData +function test_viewingWidget_constructWithTG119 evalin('base','load TG119.mat'); h = matRad_ViewingWidget(); try @@ -53,4 +53,60 @@ evalin('base','clear ct cst pln'); delete(h); +function test_ViewingWidget_constructWithPhotonPln + evalin('base','load photons_testData.mat'); + h = matRad_ViewingWidget(); + try + assertTrue(isa(h, 'matRad_ViewingWidget')); + assertTrue(isa(h, 'matRad_Widget')); + catch ME + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + rethrow(ME); + end + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + +function test_ViewingWidget_constructWithProtonPln + evalin('base','load protons_testData.mat'); + h = matRad_ViewingWidget(); + try + assertTrue(isa(h, 'matRad_ViewingWidget')); + assertTrue(isa(h, 'matRad_Widget')); + catch ME + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + rethrow(ME); + end + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + +function test_ViewingWidget_constructWithCarbonPln + evalin('base','load carbon_testData.mat'); + h = matRad_ViewingWidget(); + try + assertTrue(isa(h, 'matRad_ViewingWidget')); + assertTrue(isa(h, 'matRad_Widget')); + catch ME + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + rethrow(ME); + end + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + +function test_ViewingWidget_constructWithHeliumPln + evalin('base','load helium_testData.mat'); + h = matRad_ViewingWidget(); + try + assertTrue(isa(h, 'matRad_ViewingWidget')); + assertTrue(isa(h, 'matRad_Widget')); + catch ME + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + rethrow(ME); + end + evalin('base','clear ct cst pln stf dij resultGUI'); + delete(h); + %TODO: Test Buttons / visibility depending on data \ No newline at end of file