Skip to content

Commit

Permalink
Merge branch 'dev_FREDengine_release' of https://github.com/remocrist…
Browse files Browse the repository at this point in the history
…oforetti/matRad into pr/800
  • Loading branch information
wahln committed Dec 3, 2024
2 parents e46442f + bc48e76 commit 5986254
Show file tree
Hide file tree
Showing 16 changed files with 348 additions and 76 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/test-results.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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

51 changes: 51 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
50 changes: 23 additions & 27 deletions matRad/dicom/@matRad_DicomExporter/matRad_exportDicomRTDoses.m
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion matRad/dicom/@matRad_DicomImporter/matRad_DicomImporter.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 16 additions & 3 deletions matRad/dicom/@matRad_DicomImporter/matRad_importDicomRTDose.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 11 additions & 2 deletions matRad/gui/widgets/matRad_DVHWidget.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 12 additions & 10 deletions matRad/gui/widgets/matRad_importDicomWidget.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion matRad/planAnalysis/matRad_showDVH.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 5986254

Please sign in to comment.