function [overviewData,errorMessages]=DicomOverview_OUH(dirPath,varargin)
%
% Description:
%     This function orders Dicom-RT data in a table such that data linked
%     to each other are provided within the same row of the data table. The
%     function aims to get an overview of unsorted dicom data so that it is
%     possible to select the relevant data for a given study. The user
%     specifies which items from the different dicom headers are selected
%     for the output. All data is sorted in a "tree structure" where the
%     order is dose -> plan -> struct- > images (one row in the returned
%     data per tree branch, but the same, e.g. structure file can be in
%     several branches of the tree, see below). A tree can start with a
%     dose, but if, e.g. a plan has no related dose within the directory,
%     the tree starts with the plan, and the returned dose information will
%     be empty. Similarly, a tree can also start with structures or images.
%     A tree stops when there is no linked data at the next level. The
%     trees are created so that all dose files are analysed first. Having
%     done that, all plan files not part of a previous dose tree are
%     analysed and similar for structures and images. All returned data
%     rows are unique, but a given rt-structure can occur in several rows
%     if two different dose files point to the given structure. It can also
%     happen that a structure is pointing to more than one image group if
%     the data contain both an overview image and "standard" images (these
%     are in the OUH software separated into different image groups).
%
% Input Arguments:
%   - dirPath (char or cell): Path or list of paths to directories
%   containing DICOM files. This can be a single directory (as a
%   string/char) or a cell array of several directories. Each directory
%   will be processed individually; thus, links across directories within
%   the dirPath cell array will not be analysed. The cell array can, for
%   example, be used if the data are ordered within the individual patient
%   so that no linking exists between the individual directories (or
%   related subdirectories). When using the cell array input, the analysis
%   will be performed in parallel, thus making it faster to analyse many
%   patients, especially if the code is executed on a computer with several
%   cores. The number of cores that is used is controlled by the parallel
%   preferences, which can be set within Matlab before the use of the
%   function (Parrallell preferences can usually be accessed from an icon
%   in the lower left corner of Matlab)
%
%   - varargin (optional): Additional options for parsing.
%     - 'dicomImageItems' (cell): List of DICOM image metadata fields to extract.
%       Defaults to {'SeriesInstanceUID'}.
%     - 'dicomStructItems' (cell): List of DICOM structure metadata fields to extract.
%       Defaults to {'SeriesInstanceUID'}.
%     - 'dicomPlanItems' (cell): List of DICOM plan metadata fields to extract.
%       Defaults to {'SeriesInstanceUID'}.
%     - 'dicomDoseItems' (cell): List of DICOM dose metadata fields to extract.
%       Defaults to {'SeriesInstanceUID'}.
%     Any header item at the root level of the related image header can be
%     extracted, e.g. Patient Name, pixel size etc. The naming of the
%     individual item is as used by dicominfo in Matlab (thus the variable
%     names used by Matlab when loading Dicom images –see example)
%     -'addCoM' if set to true volume and COM of ROIs are added, as well as
%     the centre of mass of the image. Defaults to false since the addition
%     of these features is slower than if left out.
%
% Output:
%   - overviewData (struct or cell array): A table representation of the parsed
%     DICOM files. Contains information about dose, plan, structure, and image DICOM 
%     objects and their associated metadata.
%
%   - errorMessages (cell array): A cell array containing error messages, if any, for
%     each directory. Each element of the cell array contains a struct with the fields:
%       - dirPath: Path of the directory that caused the error.
%       - errorMessage: MATLAB error message encountered while parsing the directory.
%     If no errors occur, this will be an empty cell array.
%     Due to parallel execution, all data anlysis is performed such that
%     errors within one directory do not stop the analysis of the remaining
%     directories (try-catch structure per directory). Thus, checking that
%     the error messages are empty after a call to the function is good
%     practice.
%
% Additional info:
%     For all levels of data, the SeriesUID will be present in all outputs
%     by default (used to check, e.g. whether a plan is already part of a
%     dose dicom tree).
%     For structures, the names of the rois are provided
%     as default since they can be relevant but are not accessible as a
%     root item of the dicom header.
%     Some data levels are often the same for several files, e.g., patient
%     IDs on all the slices of an image set. When providing that type of
%     information in the output, it is checked that the information is
%     constant across all the files; if not, the returned value will be
%     empty.
%
% Examples:
%   % Parse DICOM files from a single directory
%   dirPath = 'C:\DICOM\Patient01';
%   [overviewData, errorMessages] = DicomOverview_OUH(dirPath);
%
%   % Parse DICOM files from multiple directories
%   dirPath = {'C:\DICOM\Patient01', 'C:\DICOM\Patient02'};
%   [overviewData, errorMessages] = DicomOverview_OUH(dirPath);
%
%   % Parse DICOM files with custom metadata fields from directory
%   consisting of patient folders
%   masterPath='C:\folder_with_pts';
%   dirPath=dir(masterPath);
%   dirPath = dirPath(~ismember({dirPath.name}, {'.', '..'}));
%   dirPath=cellfun(@(x,y) fullfile(x,y),{dirPath.folder},{dirPath.name},'UniformOutput',false);
%   dicomDoseItems = {'Manufacturer','SoftwareVersions','ImageOrientationPatient'};
%   dicomPlanItems = {'RTPlanLabel', 'RTPlanName'};
%   dicomStructItems = {'StudyDate'};
%   dicomImageItems = {'Modality', 'PatientID'};
%   [overviewData, errorMessages] = DicomOverview_OUH(dirPath, 'dicomDoseItems', ...
%       dicomDoseItems,'dicomPlanItems',dicomPlanItems, ...
%       'dicomStructItems',dicomStructItems, 'dicomImageItems', dicomImageItems,'addCoM',true);
%
% See Also:
%   SortDicomFiles_OUH, DicomLinks_OUH, LoadDicomData_OUH
%
% Author: CaB
% Date: 2024-10-07
inputParam = inputParser;
isCellOrString = @(x) iscell(x) || ischar(x);
addRequired(inputParam,'dirPath',isCellOrString);
addParameter(inputParam,'dicomStructItems',{},@iscell);
addParameter(inputParam,'dicomImageItems',{},@iscell);
addParameter(inputParam,'dicomPlanItems',{},@iscell);
addParameter(inputParam,'dicomDoseItems',{},@iscell);
addParameter(inputParam,'addCoM',false,@logical);
parse(inputParam,dirPath,varargin{:});
%parse(inputParam,varargin{:});
inputValues=inputParam.Results;

if ~all(cellfun(@isfolder, dirPath))
  error('Not all the paths in dirPath are actual existing paths')
end

%Add some default values to the dicom list
doseDicomDefault={'SeriesInstanceUID'} ;
planDicomDefault={'SeriesInstanceUID'};
structDicomDefault={'SeriesInstanceUID'};
imageDicomDefault={'SeriesInstanceUID'};
inputValues.dicomDoseItems=[doseDicomDefault;inputValues.dicomDoseItems(:)];
inputValues.dicomPlanItems=[planDicomDefault;inputValues.dicomPlanItems(:)];
inputValues.dicomStructItems=[structDicomDefault;inputValues.dicomStructItems(:)];
inputValues.dicomImageItems=[imageDicomDefault;inputValues.dicomImageItems(:)];
inputValues.dicomDoseItems=unique(inputValues.dicomDoseItems);
inputValues.dicomPlanItems=unique(inputValues.dicomPlanItems);
inputValues.dicomStructItems=unique(inputValues.dicomStructItems);
inputValues.dicomImageItems=unique(inputValues.dicomImageItems);

errorMessages={};
if ischar(dirPath)
  try
    overviewData=ScanOneDirectory(dirPath,inputValues);
  catch mse
    temp=[];
    temp.dirPath=dirPath;
    temp.errorMessage=mse;
    errorMessages{1}=temp;
  end
end
if iscell(dirPath)
  errorMessages=cell(length(dirPath),1);
  overviewData=cell(length(dirPath),1);
  parfor iPath=1:length(dirPath)
  %for iPath=1:length(dirPath)
    try
      overviewData{iPath}=ScanOneDirectory(dirPath{iPath},inputValues);

    catch mse
      temp=[];
      temp.dirPath=dirPath{iPath};
      temp.errorMessage=mse;
      errorMessages{iPath}=temp;
    end
  end
  temp=[];
  for iPath=1:length(dirPath)
    temp=[temp,overviewData{iPath}]; %#ok<AGROW>
  end
  overviewData=temp;
end
indexEmpty=cellfun(@(x) isempty(x),errorMessages);
errorMessages=errorMessages(~indexEmpty);
overviewData=struct2table(overviewData,"AsArray",true);

%If struct_volumeArray is present, it will generally be of type cell since,
%typically, the individual patient contains a different number of ROI;
%thus, the information can only be stored in a cellist of a double array.
%However, if all the patients have the same number of ROIs, the data can be
%represented in an array. Matlab will, in that case, return an array. To
%prevent the change of returned data type, make the array into a cell list
%of volume arrays for that untypical case.
if ismember('struct_volumeArray', overviewData.Properties.VariableNames)
  if isnumeric(overviewData.struct_volumeArray)
    overviewData.struct_volumeArray=mat2cell(overviewData.struct_volumeArray,ones(1,size(overviewData,1)));
  end
end
%Delete the internal items from table
overviewData.dose_internalSortDicomNumber = [];
overviewData.plan_internalSortDicomNumber = [];
overviewData.struct_internalSortDicomNumber = [];
overviewData.image_internalSortDicomNumber = [];
overviewData.image_internalSortDicomEntry = [];

end
function mainTree=ScanOneDirectory(dirPath,inputValues)
dicomData=SortDicomFiles_OUH(dirPath);
indexDose=cellfun(@(x) strcmpi(x,'RTDOSE'),dicomData(:,1));
indexPlan=cellfun(@(x) strcmpi(x,'RTPLAN'),dicomData(:,1));
indexStruct=cellfun(@(x) strcmpi(x,'RTSTRUCT'),dicomData(:,1));
indexCT=cellfun(@(x) strcmpi(x,'CT'),dicomData(:,1));
indexMR=cellfun(@(x) strcmpi(x,'MR'),dicomData(:,1));
indexPT=cellfun(@(x) strcmpi(x,'PT'),dicomData(:,1));

mainTree = [];

nrDose=length(dicomData{indexDose,2});
nrPlan=length(dicomData{indexPlan,2});
nrStruct=length(dicomData{indexStruct,2});
nrCT=length(dicomData{indexCT,2});
nrMR=length(dicomData{indexMR,2});
nrPT=length(dicomData{indexPT,2});
for iDose=1:nrDose
  currentTree=[];
  mainTree=addDoseInfo(dicomData,mainTree,currentTree,iDose,inputValues);
end
for iPlan=1:nrPlan
  if isempty(mainTree) || ~ismember(iPlan,[mainTree.plan_internalSortDicomNumber])
    currentTree=[];
    mainTree=addPlanInfo(dicomData,mainTree,currentTree,iPlan,inputValues);
  end
end
for iStruct=1:nrStruct
  if isempty(mainTree) || ~ismember(iStruct,[mainTree.struct_internalSortDicomNumber])
    currentTree=[];
    mainTree=addStructInfo(dicomData,mainTree,currentTree,iStruct,inputValues);
  end
end
for iCT=1:nrCT
  indexHanledCT=cellfun(@(x) ~isempty(x) && x==find(indexCT),{mainTree.image_internalSortDicomEntry});
  if isempty(mainTree) || ~ismember(iCT,[mainTree(indexHanledCT).image_internalSortDicomNumber])
    currentTree=[];
    mainTree=addImageInfo(dicomData,mainTree,currentTree,indexCT,iCT,inputValues);
  end
end

for iMR=1:nrMR
  indexHanledMR=cellfun(@(x) ~isempty(x) && x==find(indexMR),{mainTree.image_internalSortDicomEntry});
  if isempty(mainTree) || ~ismember(iMR,[mainTree(indexHanledMR).image_internalSortDicomNumber])
    currentTree=[];
    mainTree=addImageInfo(dicomData,mainTree,currentTree,indexMR,iMR,inputValues);
  end
end

for iPT=1:nrPT
  indexHanledPT=cellfun(@(x) ~isempty(x) && x==find(indexPT),{mainTree.image_internalSortDicomEntry});
  if isempty(mainTree) || ~ismember(iPT,[mainTree(indexHanledPT).image_internalSortDicomNumber])
    currentTree=[];
    mainTree=addImageInfo(dicomData,mainTree,currentTree,indexPT,iPT,inputValues);
  end
end


end

function mainTree=addDoseInfo(dicomData,mainTree,currentTree,doseNumber,inputValues)
indexDose=cellfun(@(x) strcmpi(x,'RTDOSE'),dicomData(:,1));
indexPlan=cellfun(@(x) strcmpi(x,'RTPLAN'),dicomData(:,1));
currentTree.dose_fileNames=cellfun(@(x) x.Filename,dicomData{indexDose,2}{doseNumber},'UniformOutput',false);
currentTree.dose_internalSortDicomNumber=doseNumber;
doseData=dicomData{indexDose, 2}{doseNumber};
for iDoseItem=1:length(inputValues.dicomDoseItems)
  nameEntry=['dose_',inputValues.dicomDoseItems{iDoseItem}];
  valueEntry=[];
  if ~isempty(doseData)
    if iscell(doseData)
      if all(cellfun(@(x) isfield(x,inputValues.dicomDoseItems{iDoseItem}),doseData))
        rawValue=cellfun(@(x) x.(inputValues.dicomDoseItems{iDoseItem}),doseData,'UniformOutput',false);
        if all(cellfun(@(x) isequal(x,rawValue{1}),rawValue))
          valueEntry=doseData{1}.(inputValues.dicomDoseItems{iDoseItem});
        end
        %stringRepresentation=cellfun(@(x) mat2str(x.(inputValues.dicomDoseItems{iDoseItem})),doseData,'UniformOutput',false);
        %[~, uniqueIndices] = unique(stringRepresentation);
        %if isscalar(uniqueIndices)
        %  valueEntry=doseData{uniqueIndices}.(inputValues.dicomDoseItems{iDoseItem});
        %end
      end
    end
  end

  currentTree.(nameEntry)=valueEntry;
end
dicomLink=DicomLinks_OUH(dicomData,indexDose,doseNumber);
noLeaf=true;
if ~isempty(dicomLink{indexPlan,2})
  noLeaf=false;
  for iPlan=1:length(dicomLink{indexPlan,2})
    mainTree=addPlanInfo(dicomData,mainTree,currentTree,dicomLink{indexPlan,2}(iPlan),inputValues);
  end
end
if noLeaf
  mainTree=addMissingInfo(mainTree,currentTree,inputValues);
end
end



function mainTree=addPlanInfo(dicomData,mainTree,currentTree,planNumber,inputValues)
indexPlan=cellfun(@(x) strcmpi(x,'RTPLAN'),dicomData(:,1));
indexStruct=cellfun(@(x) strcmpi(x,'RTSTRUCT'),dicomData(:,1));
currentTree.plan_fileNames=cellfun(@(x) x.Filename,dicomData{indexPlan,2}{planNumber},'UniformOutput',false);
currentTree.plan_internalSortDicomNumber=planNumber;
planData=dicomData{indexPlan, 2}{planNumber};
for iPlanItem=1:length(inputValues.dicomPlanItems)
  nameEntry=['plan_',inputValues.dicomPlanItems{iPlanItem}];
  valueEntry=[];
  if ~isempty(planData)
    if iscell(planData)
      if all(cellfun(@(x) isfield(x,inputValues.dicomPlanItems{iPlanItem}),planData))
        
        rawValue=cellfun(@(x) x.(inputValues.dicomPlanItems{iPlanItem}),planData,'UniformOutput',false);
        if all(cellfun(@(x) isequal(x,rawValue{1}),rawValue))
          valueEntry=planData{1}.(inputValues.dicomPlanItems{iPlanItem});
        end
        %stringRepresentation=cellfun(@(x) mat2str(x.(inputValues.dicomPlanItems{iPlanItem})),planData,'UniformOutput',false);
        %[~, uniqueIndices] = unique(stringRepresentation);
        %if isscalar(uniqueIndices)
        %  valueEntry=planData{uniqueIndices}.(inputValues.dicomPlanItems{iPlanItem});
        %end
      end
    end
  end

  currentTree.(nameEntry)=valueEntry;
end
dicomLink=DicomLinks_OUH(dicomData,indexPlan,planNumber);
noLeaf=true;
if ~isempty(dicomLink{indexStruct,2})
  noLeaf=false;
  for iStruct=1:length(dicomLink{indexStruct,2})
    mainTree=addStructInfo(dicomData,mainTree,currentTree,dicomLink{indexStruct,2}(iStruct),inputValues);
  end
end
if noLeaf
  mainTree=addMissingInfo(mainTree,currentTree,inputValues);
end
end

function mainTree=addStructInfo(dicomData,mainTree,currentTree,structNumber,inputValues)
indexStruct=cellfun(@(x) strcmpi(x,'RTSTRUCT'),dicomData(:,1));
indexCT=cellfun(@(x) strcmpi(x,'CT'),dicomData(:,1));
indexMR=cellfun(@(x) strcmpi(x,'MR'),dicomData(:,1));
indexPT=cellfun(@(x) strcmpi(x,'PT'),dicomData(:,1));
RTStruct=LoadDicomData_OUH(dicomData,indexStruct,structNumber);
currentTree.struct_fileNames=cellfun(@(x) x.Filename,dicomData{indexStruct,2}{structNumber},'UniformOutput',false);
currentTree.struct_roiNames=RTStruct{1, 2}(:,1);
currentTree.struct_internalSortDicomNumber=structNumber;
for iStructItem=1:length(inputValues.dicomStructItems)
  nameEntry=['struct_',inputValues.dicomStructItems{iStructItem}];
  valueEntry=[];
  if isfield(RTStruct{1, 1}{1, 1},inputValues.dicomStructItems{iStructItem})
    valueEntry=RTStruct{1, 1}{1, 1}.(inputValues.dicomStructItems{iStructItem});
  end
  currentTree.(nameEntry)=valueEntry;
end
dicomLink=DicomLinks_OUH(dicomData,indexStruct,structNumber);
noLeaf=true;
if ~isempty(dicomLink{indexCT,2})
  noLeaf=false;
  for iImage=1:length(dicomLink{indexCT,2})
    if inputValues.addCoM 
      currentTree=addRoiImageVolumeAndCM(dicomData,structNumber,indexCT,dicomLink{indexCT,2}(iImage),currentTree);
    end
    mainTree=addImageInfo(dicomData,mainTree,currentTree,indexCT,dicomLink{indexCT,2}(iImage),inputValues);
  end
end
if ~isempty(dicomLink{indexMR,2})
  noLeaf=false;
  for iImage=1:length(dicomLink{indexMR,2})
    if inputValues.addCoM 
      currentTree=addRoiImageVolumeAndCM(dicomData,structNumber,indexMR,dicomLink{indexMR,2}(iImage),currentTree);
    end
    mainTree=addImageInfo(dicomData,mainTree,currentTree,indexMR,dicomLink{indexMR,2}(iImage),inputValues);
  end
end
if ~isempty(dicomLink{indexPT,2})
  noLeaf=false;
  for iImage=1:length(dicomLink{indexPT,2})
    if inputValues.addCoM 
      currentTree=addRoiImageVolumeAndCM(dicomData,structNumber,indexPT,dicomLink{indexPT,2}(iImage),currentTree);
    end
    mainTree=addImageInfo(dicomData,mainTree,currentTree,indexPT,dicomLink{indexPT,2}(iImage),inputValues);
  end
end
if noLeaf
  mainTree=addMissingInfo(mainTree,currentTree,inputValues);
end
end

function mainTree=addImageInfo(dicomData,mainTree,currentTree,indexImage,imageNumber,inputValues)
imageData=dicomData{indexImage,2}{imageNumber};
currentTree.image_fileNames=cellfun(@(x) x.Filename,dicomData{indexImage,2}{imageNumber},'UniformOutput',false);
currentTree.image_internalSortDicomEntry=find(indexImage);
currentTree.image_internalSortDicomNumber=imageNumber;
for iImageItem=1:length(inputValues.dicomImageItems)
  nameEntry=['image_',inputValues.dicomImageItems{iImageItem}];
  valueEntry=[];
  if ~isempty(imageData)
    if iscell(imageData)
      if all(cellfun(@(x) isfield(x,inputValues.dicomImageItems{iImageItem}),imageData))
        rawValue=cellfun(@(x) x.(inputValues.dicomImageItems{iImageItem}),imageData,'UniformOutput',false);
        if all(cellfun(@(x) isequal(x,rawValue{1}),rawValue))
          valueEntry=imageData{1}.(inputValues.dicomImageItems{iImageItem});
        end
        %stringRepresentation=cellfun(@(x) mat2str(x.(inputValues.dicomImageItems{iImageItem})),imageData,'UniformOutput',false);
        %[~, uniqueIndices] = unique(stringRepresentation);
        %if isscalar(uniqueIndices)
        %  valueEntry=imageData{uniqueIndices}.(inputValues.dicomImageItems{iImageItem});
        %end
      end
    end
  end
  currentTree.(nameEntry)=valueEntry;
end
mainTree=addMissingInfo(mainTree,currentTree,inputValues);
end
function currentTree=addRoiImageVolumeAndCM(dicomData,structNumber,indexImage,imageNumber,currentTree)
  indexStruct=cellfun(@(x) strcmpi(x,'RTSTRUCT'),dicomData(:,1));
  image=LoadDicomData_OUH(dicomData,find(indexImage),imageNumber);
  [x,y,z]=GetVoxelPositions_OUH(image);
  imageCM=[mean(x),mean(y),mean(z)];
  volumeRoiArray=[];
  cmRoiArray=[];
  voxelVolume=nan;
  if length(x)>1 && length(y)>1 && length(z)>1
    voxelVolume=abs((x(2)-x(1))*(y(2)-y(1))*(z(2)-z(1)));
  end
  rtStruct=LoadDicomData_OUH(dicomData,find(indexStruct),structNumber);
  for iRoi =1:length(rtStruct{1, 2}(:,1))
    maskRoi=SimpleStructMask_OUH(rtStruct,image,iRoi);
    volumeRoi=sum(maskRoi(:))*voxelVolume;
    volumeRoiArray=[volumeRoiArray,sum(maskRoi(:))*voxelVolume]; %#ok<AGROW>
    if volumeRoi>0
      cmVoxels = regionprops3(maskRoi,'Centroid');
      cmInmm=[interp1(1:length(x), x, cmVoxels.Centroid(1)),...
        interp1(1:length(y), y, cmVoxels.Centroid(2))];
      if length(z)>1 %only use this if it is a 3D image
        cmInmm=[cmInmm, interp1(1:length(z), z, cmVoxels.Centroid(3))]; %#ok<AGROW>
      else
        cmInmm=[cmInmm,nan]; %#ok<AGROW>
      end
      cmRoiArray=[cmRoiArray;cmInmm]; %#ok<AGROW>
    else
      if ~isempty(rtStruct{1, 2}{iRoi, 2})
        cmRoiArray=[cmRoiArray;rtStruct{1, 2}{iRoi, 2}{1,:}]; %#ok<AGROW> %Roi is a point
      else
        cmRoiArray=[cmRoiArray;[nan,nan,nan]]; %#ok<AGROW> %Roi is an empty structure
      end
    end
  end
  currentTree.struct_comArray=cmRoiArray;
  currentTree.struct_volumeArray=volumeRoiArray;
  currentTree.image_com=imageCM;
end
function mainTree=addMissingInfo(mainTree,currentTree,inputValues)
if ~isfield(currentTree,'dose_fileNames')
  currentTree.dose_fileNames=[];
end
for iField=1:length(inputValues.dicomDoseItems)
  if ~isfield(currentTree,['dose_',inputValues.dicomDoseItems{iField}])
    currentTree.(['dose_',inputValues.dicomDoseItems{iField}])=[];
  end
end
if ~isfield(currentTree,'plan_fileNames')
  currentTree.plan_fileNames=[];
end
for iField=1:length(inputValues.dicomPlanItems)
  if ~isfield(currentTree,['plan_',inputValues.dicomPlanItems{iField}])
    currentTree.(['plan_',inputValues.dicomPlanItems{iField}])=[];
  end
end
if ~isfield(currentTree,'struct_fileNames')
  currentTree.struct_fileNames=[];
end
if ~isfield(currentTree,'struct_roiNames')
  currentTree.struct_roiNames=[];
end
for iField=1:length(inputValues.dicomStructItems)
  if ~isfield(currentTree,['struct_',inputValues.dicomStructItems{iField}])
    currentTree.(['struct_',inputValues.dicomStructItems{iField}])=[];
  end
end
if ~isfield(currentTree,'image_fileNames')
  currentTree.image_fileNames=[];
end
for iField=1:length(inputValues.dicomImageItems)
  if ~isfield(currentTree,['image_',inputValues.dicomImageItems{iField}])
    currentTree.(['image_',inputValues.dicomImageItems{iField}])=[];
  end
end
if inputValues.addCoM
  if ~isfield(currentTree,'struct_comArray')
    currentTree.struct_comArray=[];
  end
  if ~isfield(currentTree,'struct_volumeArray')
    currentTree.struct_volumeArray=[];
  end
  if ~isfield(currentTree,'image_com')
    currentTree.image_com=[];
  end
end

if ~isfield(currentTree,'dose_internalSortDicomNumber')
  currentTree.dose_internalSortDicomNumber=[];
end
if ~isfield(currentTree,'plan_internalSortDicomNumber')
  currentTree.plan_internalSortDicomNumber=[];
end
if ~isfield(currentTree,'struct_internalSortDicomNumber')
  currentTree.struct_internalSortDicomNumber=[];
end
if ~isfield(currentTree,'image_internalSortDicomEntry')
  currentTree.image_internalSortDicomEntry=[];
end
if ~isfield(currentTree,'image_internalSortDicomNumber')
  currentTree.image_internalSortDicomNumber=[];
end
mainTree=[mainTree,currentTree];
end

