function SCaseList = listSCase(varargin) %LISTSCASE output list of sCases (id and path), accordind to inputList or %filter arguments. % Each sCase directory should at least contain at % directory with a name staring with 'CT' and ending with either % '-1' : preop/shoulder/sharp/noPhantom % '-2' : preop/shoulder/smooth/noPhantom % '-3' : preop/shoulder/sharp/phantom % '-4' : preop/shoulder/smooth/phantom % and containing a 'dicom' subdirectory. The priority is '1', '2', '3', '4', % unless there is a amira folder already present in one of these diretories. % % The optional input argument inputList if an array of SCaseID, or 'N' or % 'P'. If empty, listSCase will search for all SCaseID. The optional % input argument filter can restrict le list. % The fonction can be run from server (lbovenus) with % cd /home/shoulder/methods/matlab/database; matlab -nojvm -nodisplay -nosplash -r "listSCase;quit" % For 700 cases, it takes less than 60 seconds (when executed from server) % Progress can be be checked throuhth log file with following shell command % cd /home/shoulder/methods/matlab/database;tail -f log/listSCase.log % Input: % inputArg: can be nothing (=all), 'N', 'P', or SCase(s) % % Output: % outputArg: 1 if ok and 0 otherwise % % Example: listSCase, listSCase('P'), listSCase('P001','P002') % Other M-files required: None % Subfunctions: None % See also: Used by dicominfoSCase, measureSCase, % % Author: Alexandre Terrier % EPFL-LBO % Creation date: 2018-07-01 % Revision date: 2018-12-30 % % TODO % Two main looops might be merged in one, to avoid duplicagte post % treatment %% Open log file logFileID = openLogFile('listSCase.log'); % %% Set the data directory from the configuration file config.txt % dataDir = openConfigFile('config.txt', logFileID); %% Struct contains id and associated directory SCaseList = struct(... 'id' ,[],... 'dir' ,[],... 'comment' ,[]... % Might be used later ); %% Check varargin dirL0Array = ''; SCaseListIn = {}; switch nargin case 0 % All SCase, default when no argument dirL0Array = ['N';'P']; fprintf(logFileID, '\nGet list of all SCase with a valid dicom folder'); % Set the data directory from the configuration file config.txt dataDir = openConfigFile('config.txt', logFileID); case 1 if exist(varargin{1},'dir')==7 % Assumes the input is the data directory dataDir = varargin{1}; % All SCase as default when no more arguments dirL0Array = ['N';'P']; % All SCase, default when no argument fprintf(logFileID, '\nGet list of all SCase with a valid dicom folder'); else % When the only argument is not a directory % Set the data directory from the configuration file config.txt dataDir = openConfigFile('config.txt', logFileID); % Assumes the argument is 'N', 'P' or a list of SCases switch varargin{1} case 'N' % All normal SCase dirL0Array = 'N'; fprintf(logFileID, '\nGet list of all normal SCase with a valid dicom folder'); case 'P' % All pathological SCase dirL0Array = 'P'; fprintf(logFileID, '\nGet list of all pathological SCase with a valid dicom folder'); otherwise % A specific SCase fprintf(logFileID, '\nGet list of a SCase with a valid dicom folder'); SCaseListIn = varargin; end end otherwise if exist(varargin{1},'dir') % Assumes the input is the data directory dataDir = varargin{1}; switch varargin{2} case 'N' % All normal SCase dirL0Array = 'N'; fprintf(logFileID, '\nGet list of all normal SCase with a valid dicom folder'); case 'P' % All pathological SCase dirL0Array = 'P'; fprintf(logFileID, '\nGet list of all pathological SCase with a valid dicom folder'); otherwise % Some specific SCase (wrong) fprintf(logFileID, '\nGet list of a SCase with a valid dicom folder'); SCaseListIn = varargin; SCaseListIn(1) = []; % removing the dataDir from the argument list end else % When the first argument is not a directory, assumes it is a list of SCases % Set the data directory from the configuration file config.txt dataDir = openConfigFile('config.txt', logFileID); % list of multiple SCase given in varargin fprintf(logFileID, '\nGet list of a SCase with a valid dicom folder'); SCaseListIn = varargin; end end %% Only one of the two loops below are performed SCaseListIdx = 0; % Used in one of two loops below %% Loop over SCase (N, P, or both), if length(dirL0Array) > 1 for dirL0idx = 1:length(dirL0Array) % N or P for dirL1idx = 0:9 % Hunderts dir for dirL2idx = 0:9 % Tens dir dirL0Str = dirL0Array(dirL0idx); dirL1Str = num2str(dirL1idx); dirL2Str = num2str(dirL2idx); dirTens = [dataDir '/' dirL0Str '/' dirL1Str '/' dirL2Str]; dirTensList = dir(dirTens); % List all directories in tens dir dirTensList = dirTensList(~ismember({dirTensList.name},{'.','..'})); % Remove . and .. % We might add here a filter (only diretories, {N/P} followed % by digits for dirL3idx = 1:numel(dirTensList) sCaseDirName = dirTensList(dirL3idx).name; % Root directory of this case sCaseDirPath = dirTensList(dirL3idx).folder; % Check if this SCaseID has a CT dir [CT?*-?] with a valid preoprative CT SCaseID = strtok(sCaseDirName, '-'); % Get chars before '-' CTdirList = dir([sCaseDirPath '/' sCaseDirName '/CT-*']); % List directories with CT iCTdirAmira = 0; iCTdir2use = 0; for iCTdirList = length(CTdirList):-1:1 % Loop from last to first (4 to 1) CTdir = CTdirList(iCTdirList); % Check that dir name ends with -1,-2,-3,-4 dirName = CTdir.name; if strcmp(dirName(end-1),'-') % Exclude postoperative 'p' CT CTnum = str2num(dirName(end)); if CTnum <= 4 % Exlude non shoulder (elbow) CT % Check that the dir contains a dicom dir CTdir = [CTdir.folder '/' CTdir.name]; dicomDir = [CTdir '/dicom']; if exist(dicomDir, 'dir') % Chech if amira dir exist amiraDir = [CTdir '/amira']; if exist(amiraDir, 'dir') % This is the CT folder to use iCTdirAmira = iCTdirList; end iCTdir2use = iCTdirList; end end end end if iCTdir2use == 0 fprintf(logFileID, ['\n', SCaseID, ' has no valid dicom directory']); else if iCTdirAmira % If amira dir exist, use it iCTdir2use = iCTdirAmira; end CTdir = CTdirList(iCTdir2use); SCaseListIdx = SCaseListIdx + 1; SCaseList(SCaseListIdx).id = SCaseID; CTdirPath = [CTdir.folder '/' CTdir.name]; SCaseList(SCaseListIdx).dir = CTdirPath; if CTnum ~= 1 fprintf(logFileID, ['\n', SCaseID, ' dicom directory is CT-' num2str(CTnum)]); end end end end end end %% Loop over input SCase list (given as input argument), if length(SCaseListIn) > 0 for iSCaseListIn = 1:length(SCaseListIn) % Check if there is a valid dicom directory for this SCaseID SCaseID = char(SCaseListIn{iSCaseListIn}); % Build directory from SCaseID (as in function ShoulderCase.path) % The validity of the format should be either Pnnn or Nnnn. if (numel(regexp(SCaseID,'^[PN]\d{1,3}$')) == 0) error(['Invalid format of SCaseID: ' SCaseID{1} '. CaseID must start with "P" or "N" and be followed by 1 to 3 digits.']); end % Set the folder of the SCaseID SCaseDirLevelPN = SCaseID(1); % Either 'P' or 'N' strLengthSCaseID = strlength(SCaseID(2:end)); if (strLengthSCaseID < 2) SCaseDirLevel2 = '0'; % Hunderets SCaseDirLevel1 = '0'; % Dozent elseif (strLengthSCaseID < 3) SCaseDirLevel2 = '0'; % Hunderets SCaseDirLevel1 = SCaseID(2); % Dozent else SCaseDirLevel2 = SCaseID(2); % Hunderets SCaseDirLevel1 = SCaseID(3); % Dozent end % Set SCaseID with fixed 3 digits after P/N (needed when id < % 10 inloading of data in amira directory. SCaseID4C = [SCaseDirLevelPN SCaseDirLevel2 SCaseDirLevel1 SCaseID(end)]; % Check if a (!unique! to be done) directory exists for this SCaseID FindSCaseIDFolder = dir([dataDir '/' SCaseDirLevelPN '/' SCaseDirLevel2 '/' SCaseDirLevel1 '/' SCaseID '*']); if (isempty(FindSCaseIDFolder)) % No directory for this SCaseID error(['Missing directory for SCaseID: ' SCaseID]); end SCaseDirLevel0 = FindSCaseIDFolder.name; SCaseDir = [dataDir '/' SCaseDirLevelPN '/' SCaseDirLevel2 '/' SCaseDirLevel1 '/' SCaseDirLevel0]; % Check if this SCaseID has a CT directory with a valid preoprative CT CTdirList=dir([SCaseDir '/CT-*']); % List directories with CT iCTdirAmira = 0; iCTdir2use = 0; for iCTdirList = length(CTdirList):-1:1 % Loop from last to first (4 to 1) CTdir = CTdirList(iCTdirList); % Check that dir name ends with -1,-2,-3,-4 dirName = CTdir.name; if strcmp(dirName(end-1),'-') % Exclude postoperative 'p' CT CTnum = str2num(dirName(end)); if CTnum <= 4 % Exlude non shoulder (elbow) CT % Check that the dir contains a dicom dir CTdir = [CTdir.folder '/' CTdir.name]; dicomDir = [CTdir '/dicom']; if exist(dicomDir, 'dir') % Chech if amira dir exist amiraDir = [CTdir '/amira']; if exist(amiraDir, 'dir') % This is the CT folder to use iCTdirAmira = iCTdirList; end iCTdir2use = iCTdirList; end end end end if iCTdir2use == 0 fprintf(logFileID, ['\n', SCaseID, ' has no valid dicom directory']); else if iCTdirAmira % If amira dir exist, use it iCTdir2use = iCTdirAmira; end CTdir = CTdirList(iCTdir2use); SCaseListIdx = SCaseListIdx + 1; SCaseList(SCaseListIdx).id = SCaseID; CTdirPath = [CTdir.folder '/' CTdir.name]; SCaseList(SCaseListIdx).dir = CTdirPath; if CTnum ~= 1 fprintf(logFileID, ['\n', SCaseID, ' dicom directory is CT-' num2str(CTnum)]); end end end fprintf(logFileID, ['\nNumber of SCase: ' num2str(length(SCaseList))]); fclose(logFileID); % Close log file end