function scapula_measure(caseID) %%SCAPULA_MEASURE fills the Shoulder database with scapula anatomical data % % This function fills the Shoulder database with the scapula anatomical % data of the case given as input. The anatomical measurements are stored % simultaneously in a XLS file and in the MySQL database. % % USE: scapula_measure(caseID) % % INPUT caseID: Case IDs for which you want to compute scapula anatomical % data. Cell array that stores the case IDs as a char in the form 'P###' or % 'N###' (starts with "P" or "N" followed by 1 to 3 digits). % % REMARKS The anatomical data are saved in the ScapulaAnatomicalData.xls % file. % % created with MATLAB ver.: 8.6.0.267246 (R2015b) on Windows 7 % Author: EPFL-LBO-VMC % Date: 20-Apr-2017 % DBaccess=0; % Variable for database access deactivation due to driver problems CTDatabaseLocation = '../../../data'; % Location of the CT database XLSShoulderDatabaseLocation = '../../../data/Excel/'; % Location of the XLS ShoulderDatabase % Check validity of input argument (cell array) validateattributes(caseID,{'cell'},{'nonempty'}); % Check that imput case IDs are unique [caseIDNames,~,uniqueCaseID] = unique(caseID); countOfCaseID = hist(uniqueCaseID,unique(uniqueCaseID))'; freqCaseIDs = struct('name',caseIDNames,'freq',num2cell(countOfCaseID)); repeatedValues = find([freqCaseIDs.freq] > 1); if(~isempty(repeatedValues)) warning('Input contains repeated Case ID: %s. Repeated occurences of that Case ID will be omitted. \n', freqCaseIDs(repeatedValues).name) caseID = caseIDNames; end % open mySQL connection if DBaccess conn = openSQL(); end % Get the list of exisiting cases in XLS database exist([XLSShoulderDatabaseLocation 'xlsFromMatlab/anatomy.xls']) % add by JSM for debbuging [~,~,currDatabase] = xlsread([XLSShoulderDatabaseLocation 'xlsFromMatlab/anatomy.xls']); currDatabaseCaseIDlist = currDatabase(2:end,1); % --Get CT directory adress from CT database location and case ID-- % Compute scapula anatomical data and fill database for i = 1:length(caseID) % Check validity of input arguments (char and format 'P###' or 'N###') validateattributes(caseID{i},{'char'},{'nonempty'}); if (numel(regexp(caseID{i},'^[PN]\d{1,3}$')) == 0) error(['Invalid format of CaseID: ' caseID{i} '. CaseID must start with "P" or "N" and be followed by 1 to 3 digits.']); end levelDir1 = caseID{i}(1); if (length(caseID{i}(2:end)) < 2) levelDir2 = '0'; levelDir3 = '0'; elseif (length(caseID{i}(2:end)) < 3) levelDir2 = '0'; levelDir3 = caseID{i}(2); else levelDir2 = caseID{i}(2); levelDir3 = caseID{i}(3); end % [CTDatabaseLocation '/' levelDir1 '/' levelDir2 '/' levelDir3 '/' caseID{i} '*'] FindCaseCTFolder = dir([CTDatabaseLocation '/' levelDir1 '/' levelDir2 '/' levelDir3 '/' caseID{i} '*']) if (isempty(FindCaseCTFolder)) error(['Missing CT directory for CaseID: ' caseID{i}]); end CaseID_IPP = FindCaseCTFolder.name; CaseCTFolder = [CTDatabaseLocation '/' levelDir1 '/' levelDir2 '/' levelDir3 '/' CaseID_IPP]; % Compute scapula measurements and store in the XLS database if exist([CaseCTFolder '/CT-' CaseID_IPP '-1/amira'],'dir') == 7 %if a folder "amira" exist, the patient name is added to the "measured" column finalDirectory = [CTDatabaseLocation '/' levelDir1 '/' levelDir2 '/' levelDir3] ; anatomy = scapula_calculation(CaseID_IPP, finalDirectory, levelDir1); % Function that calculates the anatomical data % Write to XLS file % Replace line if already existing or append if(any(strcmp(currDatabaseCaseIDlist, caseID{i}))) xlswrite([XLSShoulderDatabaseLocation 'xlsFromMatlab/anatomy.xls'],struct2cell(anatomy)','Feuil1',['A' int2str(find(strcmp(currDatabaseCaseIDlist, caseID{i}))+1)]); else xlswrite([XLSShoulderDatabaseLocation 'xlsFromMatlab/anatomy.xls'],struct2cell(anatomy)','Feuil1',['A' int2str(length(currDatabaseCaseIDlist)+1+i)]); end struct2cell(anatomy)' % Write to MySQL database % Replace line if already existing or issue warning message if DBaccess sqlquery = ['SELECT CT_id FROM CT WHERE shoulder_id IN (SELECT shoulder_id FROM sCase WHERE folder_name = "' caseID{i} '")']; curs = exec(conn,sqlquery); if ~isempty(curs.Message) fprintf('\nMessage: %s\n', curs.Message); end curs=fetch(curs); sqlresult = curs.Data; if isnumeric(sqlresult{1}) % Update data in table 'glenoid' data = {sqlresult{1} anatomy.glenoid_Radius anatomy.glenoid_Radius/anatomy.glenoid_radiusRMSE '' anatomy.glenoid_depth anatomy.glenoid_width anatomy.glenoid_height anatomy.glenoid_version_ampl anatomy.glenoid_version_orient anatomy.glenoid_center_PA anatomy.glenoid_center_IS anatomy.glenoid_center_ML anatomy.glenoid_Version anatomy.glenoid_Inclination 1 ''}; fieldNames = {'CT_id','radius','sphericity','biconcave','depth','width','height','version_ampl','version_orient','center_PA','center_IS','center_ML','version', 'inclination', 'version_2D', 'walch_class'}; upsert(conn, 'glenoid', fieldNames, [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], data); % Update data in table 'humerus' data = {sqlresult{1} 0.0 anatomy.humeral_head_radius anatomy.humerus_SHsubluxation_ampl anatomy.humerus_SHsubluxation_orient anatomy.humerus_GHsubluxation_ampl anatomy.humerus_GHsubluxation_orient 0.0 0.0}; fieldNames = {'CT_id','joint_radius','head_radius','SHsublux_ampl','SHsublux_orient','GHsublux_ampl','GHsublux_orient','SHsublux_2D','GHsublux_2D'}; upsert(conn, 'humerus', fieldNames, [1 0 0 0 0 0 0 0 0], data); % Update data in table 'scapula' data = {sqlresult{1} anatomy.scapula_CTangle anatomy.scapula_AI}; fieldNames = {'CT_id','CT_angle','AI'}; upsert(conn, 'scapula', fieldNames, [1 0 0], data); else error(['No entry for caseID ' caseID{i} ' was found in the ' conn.Instance ' MySQL database.']); end end else error(['Amira files missing for CaseID: ' caseID{i}]); end end % Close mySQL database if DBaccess closeSQL(conn); end end