diff --git a/listSCase.m b/listSCase.m index bbcf5f6..feda8b6 100755 --- a/listSCase.m +++ b/listSCase.m @@ -1,106 +1,264 @@ function SCaseList = listSCase(varargin) -%LISTSCASE output list of sCases (id and path), accordind to inputList and filter -%arguments. Each sCase directory should at least contain at directory with a -%name staring with 'CT' and ending with '1', containing a 'dicom' -%subdirectory. +%LISTSCASE output list of sCases (id and path), accordind to inputList and +%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 sCases. If empty, sCaseList -% will search for all sCases. The optional input argument filter can restrict le list. +% The optional input argument inputList if an array of SCaseID. 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 + + -% Syntax: sCaseList = listsCase(varargin) -% % Input: -% inputArg: can be nothing (=all), 'N', 'P', or a sCaseId +% inputArg: can be nothing (=all), 'N', 'P', or SCase(s) % % Output: % outputArg: 1 if ok and 0 otherwise % -% Example: listSCase, listSCase('P315') +% Example: listSCase, listSCase('P'), listSCase('P001','P002') % Other M-files required: % Subfunctions: % See also: % % Author: Alexandre Terrier % EPFL-LBO % Creation date: 2018-07-01 % Revision date: 2018-08-09 % % TO DO: -% When varargin = a sCaseId - - +% If no dir CT*-1, check for other, wit the priority with one having amira +% directory + %% Initialisation of paths % Should be replaced by a function -dataDir = '../../../data'; % location of data +currentDir = pwd; +rootDir = strfind(currentDir, 'methods/matlab'); % Check it for windows +rootDir = currentDir(1:rootDir-2); +% We should check here that currentDir contains 'Dev' to associate dataDev +dataDir = [rootDir '/data']; % location of data +%dataDir = '../../../data'; % location of data --> remove if above ok logDir = 'log'; % log file in xls folder %% Open log file - logFile = [logDir '/listSCase.log']; logFileId = fopen(logFile, 'w'); fprintf(logFileId, 'listSCase log file'); fprintf(logFileId, '\nDate: '); fprintf(logFileId, datestr(datetime)); -fprintf(logFileId, '\nGet list of all SCase with a valid dicom folder'); -%% -% Struct contains id and associated directory +%% Struct contains id and associated directory SCaseList = struct(... 'id' ,[],... 'dir' ,[],... 'comment' ,[]... % Might be used later ); -sCaseListIdx = 0; -%% Loop over all cases +%% Check varargin + +dirL0Array = ''; +SCaseListIn = {}; -% At the root of dataDir, two directories should be considered: -% N (normal) and P (pathological). -dirL0Array = ['N';'P']; -if strcmp(varargin,'N') - dirL0Array = 'N'; -elseif strcmp(varargin,'P') - dirL0Array = 'P'; +if nargin == 0 + dirL0Array = ['N';'P']; % All SCase, default when no argument + fprintf(logFileId, '\nGet list of all SCase with a valid dicom folder'); +elseif nargin == 1 + if strcmp(varargin,'N') % All normal SCase + dirL0Array = 'N'; + fprintf(logFileId, '\nGet list of all normal SCase with a valid dicom folder'); + elseif strcmp(varargin,'P') % All pathological SCase + dirL0Array = 'P'; + fprintf(logFileId, '\nGet list of all pathological SCase with a valid dicom folder'); + else % A specific SCase + fprintf(logFileId, '\nGet list of a SCase with a valid dicom folder'); + SCaseListIn = varargin; + end +else % list of multiple SCase given in varargin + fprintf(logFileId, '\nGet list of a SCase with a valid dicom folder'); + SCaseListIn = varargin; 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 for dirL2idx = 0:9 % Tens dirL0Str = dirL0Array(dirL0idx); dirL1Str = num2str(dirL1idx); dirL2Str = num2str(dirL2idx); dirTens = [dataDir '/' dirL0Str '/' dirL1Str '/' dirL2Str]; dirTensList = dir(dirTens); % List all directories in tens directory 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 that this sCase directory contains a directory with the % name [CT?*-1] and with a dicom directory in it. - sCaseID = strtok(sCaseDirName, '-'); % Get chars before '-' - % Listing of (CT) folders in sCaseDirPath staring with CT - % and ending with '-1' - CTdir = dir([sCaseDirPath '/' sCaseDirName '/CT*-1']); - if ~isempty(CTdir) - CTdirPath = [CTdir.folder '/' CTdir.name]; - dicomDirName = [CTdirPath '/dicom']; - if exist(dicomDirName, 'dir') - sCaseListIdx = sCaseListIdx + 1; - SCaseList(sCaseListIdx).id = sCaseID; - SCaseList(sCaseListIdx).dir = CTdirPath; - % We might get here the readme.txt if present - else - fprintf(logFileId, ['\n', sCaseID, ' has no valid dicom directory']); + SCaseID = strtok(sCaseDirName, '-'); % Get chars before '-' + + % Check if this SCaseID has a CT directory with a valid preoprative CT + 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 - fprintf(logFileId, ['\n', sCaseID, ' has no CT*-1 directory']); + 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 + + + + +% % Listing of (CT) folders in sCaseDirPath staring with CT +% % and ending with '-1' +% CTdir = dir([sCaseDirPath '/' sCaseDirName '/CT*-1']); +% if ~isempty(CTdir) +% CTdirPath = [CTdir.folder '/' CTdir.name]; +% dicomDirName = [CTdirPath '/dicom']; +% if exist(dicomDirName, 'dir') +% SCaseListIdx = SCaseListIdx + 1; +% SCaseList(SCaseListIdx).id = SCaseID; +% SCaseList(SCaseListIdx).dir = CTdirPath; +% % We might get here the readme.txt if present +% else +% fprintf(logFileId, ['\n', SCaseID, ' has no valid dicom directory']); +% end +% else +% fprintf(logFileId, ['\n', SCaseID, ' has no CT*-1 directory']); +% 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; + end +end + fprintf(logFileId, ['\nNumber of SCase: ' num2str(length(SCaseList))]); end