diff --git a/ShoulderCase/@ShoulderCase/ShoulderCase.m b/ShoulderCase/@ShoulderCase/ShoulderCase.m index a17e172..23999fc 100755 --- a/ShoulderCase/@ShoulderCase/ShoulderCase.m +++ b/ShoulderCase/@ShoulderCase/ShoulderCase.m @@ -1,499 +1,499 @@ classdef ShoulderCase < handle % Properties and methods associated to the SoulderCase object. % Author: Alexandre Terrier, EPFL-LBO % Creation date: 2018-07-01 % Revision date: 2018-12-31 % TODO: % Need method to load properties (from amira, matlab, excel, SQL) % Need method to save properties (in matlab, excel, SQL) % Remove datapath from constants % properties id % id of the shoulder case, as it appears in the database (Pnnn) diagnosis treatment outcome patient shoulder study comment end % properties (Constant, Hidden = true) % dataPath = '/Volumes/shoulder/dataDev'; % path to data folder from package folder % % This should be done differently. Check where we are, and where we % % should go. % end properties (Hidden = true) dataPath dataCTPath dataAmiraPath dataMatlabPath id4C % SCaseId with P/N followed by 3 digits --> 4 char end methods function obj = ShoulderCase(SCaseId) %SHOULDERCASE Construct an instance of this class % If called with argument SCaseId, set id and path of CT if nargin > 0 obj.id = SCaseId; %{ % SCaseId must be P or N followed by 1-3 digit. if ischar(SCaseId) if strlength(SCaseId) == 4 obj.id = SCaseId; else error('id must have 4 char'); end else % error('id must be a string'); end %} else % error('id is required'); end % Initialsation obj.diagnosis = ''; obj.treatment = ''; obj.outcome = ''; obj.patient = Patient(obj); obj.shoulder = Shoulder(obj); obj.study = ''; obj.comment = ''; obj.dataCTPath = ''; obj.dataAmiraPath = ''; obj.dataMatlabPath = ''; obj.id4C = ''; % Set path of the SCase % obj.path; To be set only if varargin ~isempty end function outputArg = path(obj) % Should be private % PATH Summary of this method goes here % Detailed explanation goes here SCase = obj; SCaseId = SCase.id; % The validity of the format should be checked Pnnn or Nnnn. if (numel(regexp(SCaseId,'^[PN]\d{1,3}$')) == 0) error(['Invalid format of SCaseId: ' SCaseId{1i} '. 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)]; obj.id4C = SCaseId4C; % Check if a (!unique! to be done) directory exists for this SCaseId dataDir = obj.dataPath; 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]; %{ %8 lines below to remove when -1 consrain avoided % Check if this SCaseId has a CT directory with '-1' postfix (preoperative % sharp CT FindCTFolder = dir([SCaseDir '/' 'CT*-1']); if (isempty(FindCTFolder)) % No CT directory for this SCaseId error(['Missing directory for SCaseId: ' SCaseId]); % ! should exist script here ! end CTDir = [SCaseDir '/' FindCTFolder.name]; %} 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 error(['\n', SCaseID, ' has no valid dicom directory']); else if iCTdirAmira % If amira dir exist, use it iCTdir2use = iCTdirAmira; end CTdir = CTdirList(iCTdir2use); CTdirPath = [CTdir.folder '/' CTdir.name]; end CTDir = CTdirPath; amiraDir = [CTDir '/amira']; % we should check for existance matlabDir = [CTDir '/matlab']; % we should check for existance obj.dataCTPath = CTDir; obj.dataAmiraPath = amiraDir; obj.dataMatlabPath = matlabDir; outputArg = 1; % Should report on directories existence if exist(amiraDir, 'dir') ~= 7 outputArg = 0; end end function outputArg = output(obj, varargin) % Below is copy/past from previous version % This function is used to output the variable Results, used % by scapula_measurePKG the modified funcion scapula_measure. % inputArg could be as in scapula_calculation % 'density', 'References', 'obliqueSlice', 'display' Result.SCase_id = obj.id; % 1 Result.glenoid_Radius = obj.shoulder.scapula.glenoid.radius; % 2 Result.glenoid_radiusRMSE = obj.shoulder.scapula.glenoid.sphereRMSE; % 3 % 3 %Result.glenoidSphericity = ' '; %Result.glenoid_biconcave = ' '; Result.glenoid_depth = obj.shoulder.scapula.glenoid.depth; % 4 Result.glenoid_width = obj.shoulder.scapula.glenoid.width; % 5 Result.glenoid_height = obj.shoulder.scapula.glenoid.height; % 6 Result.glenoid_center_PA = obj.shoulder.scapula.glenoid.centerLocal(1); % 7 Result.glenoid_center_IS = obj.shoulder.scapula.glenoid.centerLocal(2); % 8 Result.glenoid_center_ML = obj.shoulder.scapula.glenoid.centerLocal(3); % 9 Result.glenoid_version_ampl = obj.shoulder.scapula.glenoid.versionAmpl; % 10 Result.glenoid_version_orient = obj.shoulder.scapula.glenoid.versionOrient; % 11 Result.glenoid_Version = obj.shoulder.scapula.glenoid.version; % 12 Result.glenoid_Inclination = obj.shoulder.scapula.glenoid.inclination; % 13 Result.humerus_joint_radius = ' '; % 14 Result.humeral_head_radius = obj.shoulder.humerus.radius; % 15 % Result.humerus_GHsublux_2D = ' '; % Result.humerus_SHsublux_2D = ' '; Result.humerus_GHsubluxation_ampl = obj.shoulder.humerus.GHSAmpl; % 16 Result.humerus_GHsubluxation_orient = obj.shoulder.humerus.GHSOrient; % 17 Result.humerus_SHsubluxation_ampl = obj.shoulder.humerus.SHSAmpl; % 18 Result.humerus_SHsubluxation_orient = obj.shoulder.humerus.SHSOrient; % 19 Result.scapula_CSA = obj.shoulder.scapula.acromion.criticalShoulderAngle; % radCSA; % 5 Lines below should be updated Result.scapula_CTangle = 0; %CTorientation; %20 Result.scapula_CTangleVersion = 0; % WearPlaneAngle; %21 Result.scapula_CTangleSHS = 0; % SHSPlaneAngle; % 22 Result.scapula_CTangleGHS = 0; % GHSPlaneAngle; % 23 Result.scapula_PlaneRMSE = 0; %PlaneRMSE;%24 Result.scapula_AI = obj.shoulder.scapula.acromion.acromionIndex; outputArg = Result; end function outputArg = saveMatlab(obj) % Save SCase to matlab file dir = obj.dataMatlabPath; % Create dir if not exist try if ~exist(dir, 'dir') % create directory if it does not exist mkdir(dir); end catch fprintf('Error creating the matlab directory \n'); % Should be in log end % Save SCase in matlab directoty, in a file named SCaseCNNN.m filename = 'SCase'; filename = [dir '/' filename '.mat']; try SCase = obj; save(filename, 'SCase'); outputArg = 1; catch fprintf('Error creating SCase matlab file \n'); % Should be in log outputArg = -1; end end function outputArg = appendToCSV(obj,filename) % Save SCase to csv file logFid = fopen('log/measureSCase.log', 'a'); dataDir = openConfigFile('config.txt', logFid); xlsDir = [dataDir '/Excel/xlsFromMatlab']; fid = fopen([xlsDir '/' filename],'a'); fprintf(fid,[... - obj.id ';'... % SCase_id - obj.shoulder.side ';'... % shoulder_side - num2str(obj.shoulder.scapula.glenoid.radius) ';'... % glenoid_radius - num2str(obj.shoulder.scapula.glenoid.sphereRMSE) ';'... % glenoid_sphereRMSE - num2str(obj.shoulder.scapula.glenoid.depth) ';'... % glenoid_depth - num2str(obj.shoulder.scapula.glenoid.width) ';'... % glenoid_width - num2str(obj.shoulder.scapula.glenoid.height) ';'... % glenoid_height - num2str(obj.shoulder.scapula.glenoid.centerLocal.x) ';'... % glenoid_centerPA - num2str(obj.shoulder.scapula.glenoid.centerLocal.y) ';'... % glenoid_centerIS - num2str(obj.shoulder.scapula.glenoid.centerLocal.z) ';'... % glenoid_centerML - num2str(obj.shoulder.scapula.glenoid.versionAmpl) ';'... % glenoid_versionAmpl - num2str(obj.shoulder.scapula.glenoid.versionOrient) ';'... % glenoid_versionOrient - num2str(obj.shoulder.scapula.glenoid.version) ';'... % glenoid_version - num2str(obj.shoulder.scapula.glenoid.inclination) ';'... % glenoid_inclination - num2str(obj.shoulder.humerus.jointRadius) ';'... % humerus_jointRadius - num2str(obj.shoulder.humerus.radius) ';'... % humerus_headRadius - num2str(obj.shoulder.humerus.GHSAmpl) ';'... % humerus_GHSAmpl - num2str(obj.shoulder.humerus.GHSOrient) ';'... % humerus_GHSOrient - num2str(obj.shoulder.humerus.SHSAmpl) ';'... % humerus_SHSAmpl - num2str(obj.shoulder.humerus.SHSOrient) ';'... % humerus_SHSOrient - num2str(obj.shoulder.humerus.SHSAngle) ';'... % humerus_SHSAgle - num2str(obj.shoulder.humerus.SHSPA) ';'... % humerus_SHSPA - num2str(obj.shoulder.humerus.SHSIS) ';'... % humerus_SHSIS - num2str(obj.shoulder.scapula.acromion.AI) ';'... % acromion_AI - num2str(obj.shoulder.scapula.acromion.CSA) ';'... % acromion_CSA - num2str(obj.shoulder.scapula.acromion.PSA) ';'... % acromion_PSA + obj.id ','... % SCase_id + obj.shoulder.side ','... % shoulder_side + num2str(obj.shoulder.scapula.glenoid.radius) ','... % glenoid_radius + num2str(obj.shoulder.scapula.glenoid.sphereRMSE) ','... % glenoid_sphereRMSE + num2str(obj.shoulder.scapula.glenoid.depth) ','... % glenoid_depth + num2str(obj.shoulder.scapula.glenoid.width) ','... % glenoid_width + num2str(obj.shoulder.scapula.glenoid.height) ','... % glenoid_height + num2str(obj.shoulder.scapula.glenoid.centerLocal.x) ','... % glenoid_centerPA + num2str(obj.shoulder.scapula.glenoid.centerLocal.y) ','... % glenoid_centerIS + num2str(obj.shoulder.scapula.glenoid.centerLocal.z) ','... % glenoid_centerML + num2str(obj.shoulder.scapula.glenoid.versionAmpl) ','... % glenoid_versionAmpl + num2str(obj.shoulder.scapula.glenoid.versionOrient) ','... % glenoid_versionOrient + num2str(obj.shoulder.scapula.glenoid.version) ','... % glenoid_version + num2str(obj.shoulder.scapula.glenoid.inclination) ','... % glenoid_inclination + num2str(obj.shoulder.humerus.jointRadius) ','... % humerus_jointRadius + num2str(obj.shoulder.humerus.radius) ','... % humerus_headRadius + num2str(obj.shoulder.humerus.GHSAmpl) ','... % humerus_GHSAmpl + num2str(obj.shoulder.humerus.GHSOrient) ','... % humerus_GHSOrient + num2str(obj.shoulder.humerus.SHSAmpl) ','... % humerus_SHSAmpl + num2str(obj.shoulder.humerus.SHSOrient) ','... % humerus_SHSOrient + num2str(obj.shoulder.humerus.SHSAngle) ','... % humerus_SHSAgle + num2str(obj.shoulder.humerus.SHSPA) ','... % humerus_SHSPA + num2str(obj.shoulder.humerus.SHSIS) ','... % humerus_SHSIS + num2str(obj.shoulder.scapula.acromion.AI) ','... % acromion_AI + num2str(obj.shoulder.scapula.acromion.CSA) ','... % acromion_CSA + num2str(obj.shoulder.scapula.acromion.PSA) ','... % acromion_PSA num2str(obj.shoulder.scapula.acromion.AAA) '\n'... % acromion_AAA ]); fclose(fid); fclose(logFid); outputArg = 1; end function outputArg = saveExcel(~) % Save SCase to Excel file outputArg = 1; end function outputArg = saveSQL(~) % Save SCase to MySQL database outputArg = 1; end %{ function outputArg = plot(obj) % code moved to file plot.m % Plot SCase figure; % Create figure hold on; % Superpose objects on the same figure %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Scapula % Plot the scapula surface as points % If exists, plot the segemented surface (manual) if strcmp(obj.shoulder.scapula.segmentation, 'M') points = obj.shoulder.scapula.surface.points; faces = obj.shoulder.scapula.surface.faces; x = points(:,1); y = points(:,2); z = points(:,3); trisurf(faces,x,y,z,'Facecolor','yellow','FaceAlpha',1,'EdgeColor','none','FaceLighting','gouraud'); %scatter3(x,y,z,1,'black'); % Point points end % If exists, plot the segemented surface (auto) if strcmp(obj.shoulder.scapulaAuto.segmentation, 'A') points = obj.shoulder.scapulaAuto.surface.points; faces = obj.shoulder.scapulaAuto.surface.faces; x = points(:,1); y = points(:,2); z = points(:,3); trisurf(faces,x,y,z,'Facecolor','red','FaceAlpha',0.25,'EdgeColor','none','FaceLighting','gouraud'); end % Plot scapula groove (manual) points = obj.shoulder.scapula.groove; x = points(:,1); y = points(:,2); z = points(:,3); scatter3(x,y,z,100,'blue'); % If exists, plot segments between manual and auto % Plot scapula markers points = [... obj.shoulder.scapula.angulusInferior; obj.shoulder.scapula.trigonumSpinae; obj.shoulder.scapula.processusCoracoideus; obj.shoulder.scapula.acromioClavicular; obj.shoulder.scapula.angulusAcromialis; obj.shoulder.scapula.spinoGlenoidNotch... ]; x = points(:,1); y = points(:,2); z = points(:,3); scatter3(x,y,z,100,'blue','LineWidth',2); % Plot scapular plane axisLength = 50; pt0 = obj.shoulder.scapula.coordSys.origin; pt1 = pt0 + (obj.shoulder.scapula.coordSys.ML + obj.shoulder.scapula.coordSys.IS) * axisLength ; pt2 = pt1 - obj.shoulder.scapula.coordSys.IS * pdist([pt1 ; obj.shoulder.scapula.angulusInferior]); pt3 = pt2 - obj.shoulder.scapula.coordSys.ML * pdist([pt1 ; obj.shoulder.scapula.trigonumSpinae] ); pt4 = pt3 + obj.shoulder.scapula.coordSys.IS * pdist([pt1 ; obj.shoulder.scapula.angulusInferior]); X = [pt1(1) pt2(1) pt3(1) pt4(1)]; Y = [pt1(2) pt2(2) pt3(2) pt4(2)]; Z = [pt1(3) pt2(3) pt3(3) pt4(3)]; patch(X,Y,Z,'black','FaceAlpha',0.3); % Transparent plane % Plot scapular axis pt1 = obj.shoulder.scapula.coordSys.origin; axisLength = 10 + pdist([pt1 ; obj.shoulder.scapula.trigonumSpinae]); pt2 = pt1 - obj.shoulder.scapula.coordSys.ML * axisLength; x = [pt1(1), pt2(1)]; y = [pt1(2), pt2(2)]; z = [pt1(3), pt2(3)]; plot3(x,y,z,'Color','blue','LineWidth', 5); % Plot scapular coordinate system axisLength = 50; % Length of the cood. sys. axes pt0 = obj.shoulder.scapula.coordSys.origin; pt1 = pt0 + obj.shoulder.scapula.coordSys.PA*axisLength; % X pt2 = pt0 + obj.shoulder.scapula.coordSys.IS*axisLength; % Y pt3 = pt0 + obj.shoulder.scapula.coordSys.ML*axisLength; % Z x = [pt0(1), pt1(1)]; y = [pt0(2), pt1(2)]; z = [pt0(3), pt1(3)]; plot3(x,y,z,'Color','red','LineWidth', 5); x = [pt0(1), pt2(1)]; y = [pt0(2), pt2(2)]; z = [pt0(3), pt2(3)]; plot3(x,y,z,'Color','green','LineWidth', 5); % Not plotting ML axis to avoid its superposition with scapular axis on glenoid center % x = [pt0(1), pt3(1)]; % y = [pt0(2), pt3(2)]; % z = [pt0(3), pt3(3)]; % plot3(x,y,z,'Color','blue','LineWidth', 5); % plot scapular axis on glenoid center axisLength = 50; pt1 = obj.shoulder.scapula.glenoid.center; pt2 = pt1 + obj.shoulder.scapula.coordSys.ML*axisLength; x = [pt1(1), pt2(1)]; y = [pt1(2), pt2(2)]; z = [pt1(3), pt2(3)]; plot3(x,y,z,'Color','blue','LineWidth', 5); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Glenoid % Plot the glenoid surface % We might move them in the direction of th glenoid center % instead of the ML axis points = obj.shoulder.scapula.glenoid.surface.points +... obj.shoulder.scapula.coordSys.ML * 0.2; faces = obj.shoulder.scapula.glenoid.surface.faces; x = points(:,1); y = points(:,2); z = points(:,3); %scatter3(x,y,z,1,'blach'); trisurf(faces,x,y,z,'Facecolor','none','FaceAlpha',1,'EdgeColor','yellow','FaceLighting','none'); % plot glenoid centerline pt1 = obj.shoulder.scapula.glenoid.center; pt2 = pt1 + obj.shoulder.scapula.glenoid.centerLine; x = [pt1(1), pt2(1)]; y = [pt1(2), pt2(2)]; z = [pt1(3), pt2(3)]; plot3(x,y,z,'Color','yellow','LineWidth', 5); % We might add spherical cap %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Humerus % plot humeral head sphere n = 20; % number of lines [X,Y,Z] = sphere(n); X = X*obj.shoulder.humerus.radius; Y = Y*obj.shoulder.humerus.radius; Z = Z*obj.shoulder.humerus.radius; Xc = obj.shoulder.humerus.center(1); Yc = obj.shoulder.humerus.center(2); Zc = obj.shoulder.humerus.center(3); mesh(X+Xc,Y+Yc,Z+Zc,'LineStyle','none','FaceColor','magenta','FaceAlpha',0.3,'FaceLighting','gouraud'); % hidden off; % Transparent sphere % check 'FaceLighting','gouraud', % plot humeral head centerline pt1 = obj.shoulder.scapula.glenoid.center; pt2 = obj.shoulder.humerus.center; x = [pt1(1), pt2(1)]; y = [pt1(2), pt2(2)]; z = [pt1(3), pt2(3)]; plot3(x,y,z,'Color','magenta','LineWidth', 5); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Graph properties % axis off; % remove axis lightPosition = obj.shoulder.scapula.glenoid.center + ... (... obj.shoulder.scapula.coordSys.ML + ... obj.shoulder.scapula.coordSys.IS + ... obj.shoulder.scapula.coordSys.PA ... ) * 100; light('Position',lightPosition,'Style','local'); grid on; xlabel('X (CT)'); ylabel('Y (CT)'); zlabel('Z (CT)'); axis square; axis vis3d; % fixed limits and scaling view(obj.shoulder.scapula.coordSys.IS); % view from top % Align ML axis with window horizontal axis !to do % obj.shoulder.scapula.coordSys.ML %angleDegrees = rad2deg(obj.shoulder.scapula.coordSys.ML % camroll(angleDegrees); figureHandle = gca; figureHandle.DataAspectRatio = [1 1 1]; % Same relative length of data units along each axis figureHandle.Box = 'On'; outputArg = 1; end %} end end diff --git a/config.txt b/config.txt deleted file mode 100755 index 1aec18b..0000000 --- a/config.txt +++ /dev/null @@ -1,9 +0,0 @@ -% configuration file contains the definition of variable dataDir for database access. -% It is used by functions: listSCase.m, measureSCase.m, plotScase.m -% /home/shoulder/data <-- acces data dir from lbovenus or lbomars (default) -% /home/shoulder/dataDev <-- acces dataDev dir from lbovenus or lbomars -% /Volumes/shoulder/data <-- acces data dir from lbovenus/lbomars mounted on macos -% /Volumes/shoulder/dataDev <-- acces dataDev dir from lbovenus mounted on macos -% Z:\data <-- acces data dir from lbovenus/lbomars mounted on windows -% Z:\dataDev <-- acces dataDev dir from lbovenus mounted on windows -dataDir = /home/shoulder/dataDev diff --git a/measureSCase.m b/measureSCase.m index 6f878a3..d2591e7 100755 --- a/measureSCase.m +++ b/measureSCase.m @@ -1,484 +1,486 @@ function [status,message] = measureSCase(varargin) % MEASURESCASE Update the entire SCase DB with anatomical measurements. % The function can be run from (lbovenus) server with the following shell command % cd /home/shoulder/methods/matlab/database; matlab -nodisplay -nosplash -r "measureSCase;quit" % Progress can be checked through log file with following shell command % cd /home/shoulder/methods/matlab/database;tail -f log/measureSCase.log % It take ~30 min for 700 cases when run from server. % After run from server, the output file % /shoulder/data/Excel/xlsFromMatlab/anatomy.csv % must be open from Excel and saved % as xls at the same location. Excel file % /shoulder/data/Excel/ShoulderDataBase.xlsx should also be open, updated, and saved. % The script measureSCase was replacing 3 previous functions % 1) rebuildDatabaseScapulaMeasurements.m --> list of all SCases --> execute scapula_measure.m % 2) scapula_measure.m --> execute scapula_calculation and save results in Excel and SQL % 3) scapula_calculation.m --> perform anatomical analysis --> results varaiable % Input arguments can be one or several among: % {Empty,'GlenoidDensity', 'Update', '[NP][1-999]', '[NP]'} % % If there is no argument the function will measure every new case. % The first 'N' or 'P' given as an argument will force the function to be % executed on all the corresponding 'N' or 'P' cases. This will overwrite % every other ShoulderCase argument '[NP][1-999]' given before and will % not take the next arguments into account. % % Examples: % measureSCase('GlenoidDensity') % is a valid instruction where every new case is measured % including its glenoid density. % measureSCase('P400','N520') % is a valid instruction where the cases 'P400' and 'N520' are % measured only if they have not already been measured yet (new % cases). % measureSCase('P400','N520','Update') % is a valid instruction where the cases 'P400' and 'N520' are % measured whether they have already been measured or not. % measureSCase('GlenoidDensity','P400','N520','P','Update') % is a valid instruction where all the 'P' cases are measured % including their glenoid density only if they have not been % measured yet (new P cases). % measureSCase('GlenoidDensity','P400','N520','Update','P') % is a valid instruction where all the 'P' cases are measured % including their glenoid density whether they have been % measured or not. % measureSCase('Z1590','trollingArgumentLol') % is a valid instruction which raises a warning about the % arguments and will result in the same as executing % measureSCase() i.e. every new case is calculated. % Output % File /shoulder/data/Excel/xlsFromMatlab/anatomy.csv % File /shoulder/data/Excel/xlsFromMatlab/anatomy.xls (only windows) % File /home/shoulder/data/matlab/SCaseDB.mat % File {SCaseId}.mat in each {SCaseId}/{CT}/matlab directory % logs in /log/measureSCase.log % Example: measureSCase % Author: Alexandre Terrier, EPFL-LBO % Creation date: 2018-07-01 % Revision date: 2019-06-29 % TO DO: % Read first last anatomy.csv and/or SCaseDB.mat % Fill with patient and clinical data, from excel or MySQL % use argument to redo or update % Save csv within the main loop (not sure it's a good idea) % Add more message in log % Add more test to assess validity of data % Update MySQL % Rename all objects with a capital % Make it faster by not loading scapula surface if already in SCaseDB.mat % Add argument 'load' to force reload files even if they are alerady in DB % Add argument 'measure' to force re-measuring event if measurement is already in DB % Add "scapula_addmeasure.m" --> should be coded in ShoulderCase class tic; % Start stopwatch timer %% Open log file logFileID = openLogFile('measureSCase.log'); %% Set the data directory from the configuration file config.txt dataDir = openConfigFile('config.txt', logFileID); %% Location of the XLS ShoulderDatabase xlsDir = [dataDir '/Excel/xlsFromMatlab']; matlabDir = [dataDir '/matlab']; %% Get list of all SCase % Get list of SCases from varargin % Delault value for inputArg calcGlenoidDensity = false; updateCalculations = false; fprintf(logFileID, '\n\nList of SCase'); cases = {}; for argument = 1:nargin switch varargin{argument} % Test every argument in varargin. case 'GlenoidDensity' calcGlenoidDensity = true; case 'Update' updateCalculations = true; case regexp(varargin{argument},'[NP]','match') % Detect if argument is 'N' or 'P'. cases = {}; % If it's the case the for loop cases{end+1} = varargin{argument}; % ends here. break % case regexp(varargin{argument},'[NP][1-9][0-9]{0,2}','match') % Test for a correct argument [NP][1-999] cases{end+1} = varargin{argument}; % for element = 1:length(cases)-1 % Check if the case has already been added to the case list before if varargin{argument} == cases{element} % cases = cases(1:end-1); % Delete the last element added to cases if it is already in the list end end otherwise warning(['\n "%s" is not a valid argument and has not been added to the'... ' list of cases.\n measureSCase arguments format must be "[NP]",'... ' "[NP][1-999]", "GlenoidDensity", or "Update"'],varargin{argument}) end end SCaseList = listSCase(cases); %% Load current xls database (for clinical data) fprintf(logFileID, '\nLoad xls database'); addpath('XLS_MySQL_DB'); filename = [dataDir '/Excel/ShoulderDataBase.xlsx']; excelRaw = rawFromExcel(filename); % cell array excelSCaseID = excelRaw(2:end, 1); excelDiagnosis = excelRaw(2:end, 4); excelPatientHeight = excelRaw(2:end, 23); excelGlenoidWalch = excelRaw(2:end, 55); % Lines below adapted from XLS_MySQL_DB/MainExcel2XLS % Excel.diagnosisList = diagnosisListFromExcel(Excel.Raw); % Excel.treatmentList = treatmentListFromExcel(Excel.Raw); % ExcelData.Patient = patientFromExcel(excelRaw); % Structure with patient data % Excel.shoulder = shoulderFromExcel(Excel.patient, Excel.Raw); % [Excel.SCase, Excel.diagnosis, Excel.treatment, Excel.outcome, Excel.study] = SCaseFromExcel(... % Excel.shoulder, Excel.patient, Excel.diagnosisList, Excel.treatmentList, Excel.Raw); % fprintf(logFileID, ': OK'); %% Add path to ShoulderCase class addpath('ShoulderCase'); %% Instance of a ShoulderCase object if (exist('SCase','var') > 0) clear SCase; % Check for delete method end SCase = ShoulderCase; % Instanciate a ShoulderCase object SCaseDB = ShoulderCase; SCase.dataPath = dataDir; % Set dataDir for SCase %% Start loop over SCases in SCaseList nSCase = length(SCaseList); % Number of SCases for iSCaseID = 1:nSCase - SCaseID = SCaseList(iSCaseID).id; - SCase(iSCaseID).id = SCaseID; - SCase(iSCaseID).dataPath = dataDir; % Set dataDir for SCase - percentProgress = num2str(iSCaseID/nSCase*100, '%3.1f'); - fprintf(logFileID, ['\n\nSCaseID: ' SCaseID ' (' percentProgress '%%)']); - - % There are 3 parts within this SCase loop: - % 1) Load & analyses manual data from amira - % 2) Load & analyses auto data from matlab (Statistical Shape Model) - % 3) Load clinical data from Excel database, and set them to SCase - % 4) Save SCase in file SCaseID/matlab/SCase.mat - - % 1) Load & analyses manual data from amira - - if (~exist([SCase(iSCaseID).dataMatlabPath '\SCase.mat'],'file') || updateCalculations) % New calculation of SCase.mat or update the current calculation - fprintf(logFileID, '\n Segmentation manual '); - output = SCase(iSCaseID).path; % Set data path of this SCase - if output % Continue if amira dir exists in SCase - fprintf(logFileID, '\n Load scapula surface and landmarks'); - output = SCase(iSCaseID).shoulder.scapula.load; - if output - fprintf(logFileID, ': OK'); - fprintf(logFileID, '\n Set coord. syst.'); - output = SCase(iSCaseID).shoulder.scapula.coordSysSet; - if output - fprintf(logFileID, ': OK'); - fprintf(logFileID, '\n Load glenoid surface'); - output = SCase(iSCaseID).shoulder.scapula.glenoid.load; - if output - fprintf(logFileID, ': OK'); - fprintf(logFileID, '\n Measure glenoid anatomy'); - output = SCase(iSCaseID).shoulder.scapula.glenoid.morphology; - if output - fprintf(logFileID, ': OK'); - if calcGlenoidDensity - fprintf(logFileID, '\n Measure glenoid density'); - output = SCase(iSCaseID).shoulder.scapula.glenoid.calcDensity; - if output - fprintf(logFileID, ': OK'); - else - fprintf(logFileID, ': Could no read dicom'); - end - end - fprintf(logFileID, '\n Load humerus data'); - output = SCase(iSCaseID).shoulder.humerus.load; - if output - fprintf(logFileID, ': OK'); - fprintf(logFileID, '\n Measure humerus subluxation'); - output = SCase(iSCaseID).shoulder.humerus.subluxation; - if output - fprintf(logFileID, ': OK'); - fprintf(logFileID, '\n Measure acromion anatomy'); - % Should be run after SCase.shoulder.humerus (for AI) - output = SCase(iSCaseID).shoulder.scapula.acromion.morphology; - if output - fprintf(logFileID, ': OK'); - else - fprintf(logFileID, '\n: Measure acromion anatomy error'); - end % Acromion anatomy - else - fprintf(logFileID, '\n: Measure humerus subluxation error'); - end % Subluxation humerus - else - fprintf(logFileID, '\n: Load humerus data error'); - end % Load humerus - else - fprintf(logFileID, '\n: Measure glenoid anatomy error'); - end % Anatomy glenoid - else - fprintf(logFileID, '\n: Density calculus error'); - end % Load glenoid - else - fprintf(logFileID, '\n Scapula coord syst error '); - end % Set coord. syst. + SCaseID = SCaseList(iSCaseID).id; + SCase(iSCaseID).id = SCaseID; + SCase(iSCaseID).dataPath = dataDir; % Set dataDir for SCase + output = SCase(iSCaseID).path; % Set data path of this SCase + percentProgress = num2str(iSCaseID/nSCase*100, '%3.1f'); + fprintf(logFileID, ['\n\nSCaseID: ' SCaseID ' (' percentProgress '%%)']); + + % There are 3 parts within this SCase loop: + % 1) Load & analyses manual data from amira + % 2) Load & analyses auto data from matlab (Statistical Shape Model) + % 3) Load clinical data from Excel database, and set them to SCase + % 4) Save SCase in file SCaseID/matlab/SCase.mat + + % 1) Load & analyses manual data from amira + if (~exist([SCase(iSCaseID).dataMatlabPath '/SCase.mat'],'file') || updateCalculations) % New calculation of SCase.mat or update the current calculation + fprintf(logFileID, '\n Segmentation manual '); + if output % Continue if amira dir exists in SCase + fprintf(logFileID, '\n Load scapula surface and landmarks'); + output = SCase(iSCaseID).shoulder.scapula.load; + if output + fprintf(logFileID, ': OK'); + fprintf(logFileID, '\n Set coord. syst.'); + output = SCase(iSCaseID).shoulder.scapula.coordSysSet; + if output + fprintf(logFileID, ': OK'); + fprintf(logFileID, '\n Load glenoid surface'); + output = SCase(iSCaseID).shoulder.scapula.glenoid.load; + if output + fprintf(logFileID, ': OK'); + fprintf(logFileID, '\n Measure glenoid anatomy'); + output = SCase(iSCaseID).shoulder.scapula.glenoid.morphology; + if output + fprintf(logFileID, ': OK'); + if calcGlenoidDensity + fprintf(logFileID, '\n Measure glenoid density'); + output = SCase(iSCaseID).shoulder.scapula.glenoid.calcDensity; + if output + fprintf(logFileID, ': OK'); + else + fprintf(logFileID, ': Could no read dicom'); + end + end + fprintf(logFileID, '\n Load humerus data'); + output = SCase(iSCaseID).shoulder.humerus.load; + if output + fprintf(logFileID, ': OK'); + fprintf(logFileID, '\n Measure humerus subluxation'); + output = SCase(iSCaseID).shoulder.humerus.subluxation; + if output + fprintf(logFileID, ': OK'); + fprintf(logFileID, '\n Measure acromion anatomy'); + % Should be run after SCase.shoulder.humerus (for AI) + output = SCase(iSCaseID).shoulder.scapula.acromion.morphology; + if output + fprintf(logFileID, ': OK'); + else + fprintf(logFileID, '\n: Measure acromion anatomy error'); + end % Acromion anatomy + else + fprintf(logFileID, '\n: Measure humerus subluxation error'); + end % Subluxation humerus + else + fprintf(logFileID, '\n: Load humerus data error'); + end % Load humerus + else + fprintf(logFileID, '\n: Measure glenoid anatomy error'); + end % Anatomy glenoid + else + fprintf(logFileID, '\n: Density calculus error'); + end % Load glenoid + else + fprintf(logFileID, '\n Scapula coord syst error '); + end % Set coord. syst. + + else + fprintf(logFileID, '\n Scapula loading error'); + end % Load scapula + + else + fprintf(logFileID, '\n No amira folder'); + end % Amira path exist + % 2) Set clinical data from Excel database to SCase + fprintf(logFileID, '\n Set clinical data from Excel'); - else - fprintf(logFileID, '\n Scapula loading error'); - end % Load scapula + % Get idx of excelRaw for SCaseID + % Use cell2struct when dots are removed from excel headers + idx = find(strcmp(excelRaw, SCaseID)); % Index of SCaseID in excelRaw + SCase(iSCaseID).diagnosis = excelRaw{idx,4}; + SCase(iSCaseID).treatment = excelRaw{idx,9}; + SCase(iSCaseID).patient.gender = excelRaw{idx,19}; + SCase(iSCaseID).patient.age = excelRaw{idx,21}; + SCase(iSCaseID).patient.height = excelRaw{idx,23}; + SCase(iSCaseID).patient.weight = excelRaw{idx,24}; + SCase(iSCaseID).patient.BMI = excelRaw{idx,25}; + SCase(iSCaseID).shoulder.scapula.glenoid.walch = excelRaw{idx,55}; - else - fprintf(logFileID, '\n No amira folder'); - end % Amira path exist + + % Patient data --> TO DO + % find patient id (in SQL) corresponding to iSCaseID + % + % + % idxSCase = find(contains(ExcelData, SCaseID)); + % SCase(iSCaseID).patient.id = ExcelData(idxSCase).patient.patient_id; % SQL patient id + % SCase(iSCaseID).patient.idMed = ExcelData(idxSCase).patient.IPP; % IPP to be replace by coded (anonymized) IPP from SecuTrial + % SCase(iSCaseID).patient.gender = ExcelData(idxSCase).patient.gender; + % SCase(iSCaseID).patient.age = []; % Age (years) at treatment, or preop CT (we might also add birthdate wi day et at 15 of the month) + % SCase(iSCaseID).patient.ethnicity = ExcelData(idxSCase).patient.IPP; + % SCase(iSCaseID).patient.weight = ExcelData(idxSCase).patient.weight; + % SCase(iSCaseID).patient.height = ExcelData(idxSCase).patient.height; + % SCase(iSCaseID).patient.BMI = ExcelData(idxSCase).pateint.BMI; + % SCase(iSCaseID).patient.comment = ExcelData(idxSCase).patient.comment; + + % 3) Save SCase in file SCaseID/matlab/SCase.mat + fprintf(logFileID, '\n Save SCase.mat'); + output = SCase(iSCaseID).saveMatlab; + if output + fprintf(logFileID, ': OK'); + else + fprintf(logFileID, ': Error'); end - % 2) Load & analyses auto data from matlab (Statistical Shape Model) + end + + % 4) Load & analyses auto data from matlab (Statistical Shape Model) + % Load scapula surface and landmarks + if (~exist([SCase(iSCaseID).dataMatlabPath '/scapulaLandmarksAutoR.mat'],'file') || updateCalculations) % New calculation of SCase.mat or update the current calculation fprintf(logFileID, '\n Segmentation auto '); - % Load scapula surface and landmarks fprintf(logFileID, '\n Load scapula surface and landmarks'); output = SCase(iSCaseID).shoulder.scapulaAuto.loadAuto; % Load auto data from matlab directory if output fprintf(logFileID, ': OK'); fprintf(logFileID, '\n Set coord. syst.'); output = SCase(iSCaseID).shoulder.scapulaAuto.coordSysSet; if output fprintf(logFileID, ': OK'); fprintf(logFileID, '\n Load glenoid surface'); output = SCase(iSCaseID).shoulder.scapulaAuto.glenoid.loadAuto; if output fprintf(logFileID, ': OK'); fprintf(logFileID, '\n Measure glenoid anatomy'); output = SCase(iSCaseID).shoulder.scapulaAuto.glenoid.morphology; if output fprintf(logFileID, ': OK'); else fprintf(logFileID, '\n: Error in measuring glenoid anatomy'); end else fprintf(logFileID, '\n: Error in loading glenoid surface'); end else fprintf(logFileID, '\n: Error in setting the coordonnate System'); end else fprintf(logFileID, '\n: Error in loading scapula surface and landmarks'); end + end - % 3) Set clinical data from Excel database to SCase - fprintf(logFileID, '\n Set clinical data from Excel'); - - % Get idx of excelRaw for SCaseID - % Use cell2struct when dots are removed from excel headers - idx = find(strcmp(excelRaw, SCaseID)); % Index of SCaseID in excelRaw - SCase(iSCaseID).diagnosis = excelRaw{idx,4}; - SCase(iSCaseID).treatment = excelRaw{idx,9}; - SCase(iSCaseID).patient.gender = excelRaw{idx,19}; - SCase(iSCaseID).patient.age = excelRaw{idx,21}; - SCase(iSCaseID).patient.height = excelRaw{idx,23}; - SCase(iSCaseID).patient.weight = excelRaw{idx,24}; - SCase(iSCaseID).patient.BMI = excelRaw{idx,25}; - SCase(iSCaseID).shoulder.scapula.glenoid.walch = excelRaw{idx,55}; - - - % Patient data --> TO DO - % find patient id (in SQL) corresponding to iSCaseID -% -% -% idxSCase = find(contains(ExcelData, SCaseID)); -% SCase(iSCaseID).patient.id = ExcelData(idxSCase).patient.patient_id; % SQL patient id -% SCase(iSCaseID).patient.idMed = ExcelData(idxSCase).patient.IPP; % IPP to be replace by coded (anonymized) IPP from SecuTrial -% SCase(iSCaseID).patient.gender = ExcelData(idxSCase).patient.gender; -% SCase(iSCaseID).patient.age = []; % Age (years) at treatment, or preop CT (we might also add birthdate wi day et at 15 of the month) -% SCase(iSCaseID).patient.ethnicity = ExcelData(idxSCase).patient.IPP; -% SCase(iSCaseID).patient.weight = ExcelData(idxSCase).patient.weight; -% SCase(iSCaseID).patient.height = ExcelData(idxSCase).patient.height; -% SCase(iSCaseID).patient.BMI = ExcelData(idxSCase).pateint.BMI; -% SCase(iSCaseID).patient.comment = ExcelData(idxSCase).patient.comment; - - % 4) Save SCase in file SCaseID/matlab/SCase.mat - fprintf(logFileID, '\n Save SCase'); - output = SCase(iSCaseID).saveMatlab; - if output - fprintf(logFileID, ': OK'); - else - fprintf(logFileID, ': Error'); - end end % End of loop on SCaseList %% Write csv file % This might be a function (SCase.csvSave()). The input would be a filename and a structure % data % Replace header and data by structure. Currently not working %{ txtFilename = [xlsDir, '/anatomy.txt']; % Name of the txt file DataStruc = struc(... 'SCase_id', SCase.id, ... 'shoulder_side', SCase.shoulder.side,... 'glenoid_radius', SCase.shoulder.scapula.glenoid.radius,... 'glenoid_sphereRMSE', SCase.shoulder.scapula.glenoid.sphereRMSE,... 'glenoid_depth', SCase.shoulder.scapula.glenoid.depth,... 'glenoid_width', SCase.shoulder.scapula.glenoid.width,... 'glenoid_height', SCase.shoulder.scapula.glenoid.height,... 'glenoid_centerPA', SCase.shoulder.scapula.glenoid.centerLocal(1),... 'glenoid_centerIS', SCase.shoulder.scapula.glenoid.centerLocal(2),... 'glenoid_centerML', SCase.shoulder.scapula.glenoid.centerLocal(3),... 'glenoid_versionAmpl', SCase.shoulder.scapula.glenoid.versionAmpl,... 'glenoid_versionOrient', SCase.shoulder.scapula.glenoid.versionOrient,... 'glenoid_version', SCase.shoulder.scapula.glenoid.version,... 'glenoid_inclination', SCase.shoulder.scapula.glenoid.inclination,... 'humerus_jointRadius', SCase.shoulder.humerus.jointRadius,... 'humerus_headRadius', SCase.shoulder.humerus.radius,... 'humerus_GHSAmpl', SCase.shoulder.humerus.GHSAmpl,... 'humerus_GHSOrient', SCase.shoulder.humerus.GHSOrient,... 'humerus_SHSAmpl', SCase.shoulder.humerus.SHSAmpl,... 'humerus_SHSOrient', SCase.shoulder.humerus.SHSOrient,... 'humerus_SHSAngle', SCase.shoulder.humerus.SHSAngle,... 'humerus_SHSPA', SCase.shoulder.humerus.SHSPA,... 'humerus_SHSIS', SCase.shoulder.humerus.SHSIS,... 'acromion_AI', SCase.shoulder.scapula.acromion.AI,... 'acromion_CSA', SCase.shoulder.scapula.acromion.CSA,... 'acromion_PS', SCase.shoulder.scapula.acromion.PS... ); DataTable = strct2table(Data); writetable(DataTable,filename); %} % Header of the csv file dataHeader = [... - 'SCase_id;' ... - 'shoulder_side;' ... - 'glenoid_radius;' ... - 'glenoid_sphereRMSE;' ... - 'glenoid_depth;' ... - 'glenoid_width;' ... - 'glenoid_height;' ... - 'glenoid_centerPA;' ... - 'glenoid_centerIS;' ... - 'glenoid_centerML;' ... - 'glenoid_versionAmpl;' ... - 'glenoid_versionOrient;' ... - 'glenoid_version;' ... - 'glenoid_inclination;' ... - 'humerus_jointRadius;' ... - 'humerus_headRadius;' ... - 'humerus_GHSAmpl;' ... - 'humerus_GHSOrient;' ... - 'humerus_SHSAmpl;' ... - 'humerus_SHSOrient;' ... - 'humerus_SHSAngle;' ... - 'humerus_SHSPA;' ... - 'humerus_SHSIS;' ... - 'acromion_AI;' ... - 'acromion_CSA;' ... - 'acromion_PSA;'... + 'SCase_id,' ... + 'shoulder_side,' ... + 'glenoid_radius,' ... + 'glenoid_sphereRMSE,' ... + 'glenoid_depth,' ... + 'glenoid_width,' ... + 'glenoid_height,' ... + 'glenoid_centerPA,' ... + 'glenoid_centerIS,' ... + 'glenoid_centerML,' ... + 'glenoid_versionAmpl,' ... + 'glenoid_versionOrient,' ... + 'glenoid_version,' ... + 'glenoid_inclination,' ... + 'humerus_jointRadius,' ... + 'humerus_headRadius,' ... + 'humerus_GHSAmpl,' ... + 'humerus_GHSOrient,' ... + 'humerus_SHSAmpl,' ... + 'humerus_SHSOrient,' ... + 'humerus_SHSAngle,' ... + 'humerus_SHSPA,' ... + 'humerus_SHSIS,' ... + 'acromion_AI,' ... + 'acromion_CSA,' ... + 'acromion_PSA,'... 'acromion_AAA\n'... ]; updateList = listSCase; % The list of SCase to use to construct anatomy.csv and SCaseDB.mat fprintf(logFileID, '\n\nSave anatomy.csv file'); fid = fopen([xlsDir, '/anatomy.csv'],'w'); %Last csv is deleted and a new one, updated is being created fprintf(fid,dataHeader); fclose(fid); % The following lines re-create the SCaseDB.mat and contruct the anatomy.csv file S = ShoulderCase; for Case=1:length(updateList) S(Case).id = updateList(Case).id; % S(Case).dataPath = dataDir; % S(Case).path; % Compute the SCase.dataMatlabPath loaded = load([S(Case).dataMatlabPath '/SCase.mat']); % Load SCase.mat SCaseDB(Case) = loaded.SCase; SCaseDB(Case).appendToCSV('anatomy.csv'); end fprintf(logFileID, ': OK'); %% Save the entire SCaseDB array as a matlab file fprintf(logFileID, '\n\nSave SCase database'); filename = 'SCaseDB'; filename = [matlabDir '/' filename '.mat']; try save(filename, 'SCaseDB'); fprintf(logFileID, ': OK'); catch fprintf(logFileID, ': Error'); end %fprintf(logFileID, [': ' csvFilename]); %% Write xls file (Windows only) % [~,message] = csv2xlsSCase(csvFilename); % fprintf(logFileID, message); % If run from non-windows system, only csv will be produced. The xls can be % produced by opening the csv from Excel and save as xls. % Could be a function with 1 input (cvsFilenames %{ xlsFilename = strrep(csvFilename, '.csv', '.xls'); % Replace .csv by .xls if ispc % Check if run from windows! % Read cvs file as table and write the table as xls cvsTable = readtable(csvFilename); % Get table from csv (only way to read non-numeric data) cvsCell = table2cell(cvsTable); % Tranform table cell array dataHeader = cvsTable.Properties.VariableNames; % Get header cvsCell = [dataHeader; cvsCell]; % Add header sheet = 'anatomy'; % Sheet name of the xls file [status,message] = xlswrite(xlsFilename, cvsCell, sheet); % Save xls if status fprintf(logFileId, ['\nSaved ' xlsFilename]); else fprintf(logFileId, ['\nCould not save ' xlsFilename]); fprintf(logFileId, ['\n' message.identifier]); fprintf(logFileId, ['\n' message.message]); end else fprintf(logFileId, ['\n' xlsFilename ' not saved. Open and save as xls from Excel']); end %} %% Close log file fprintf(logFileID, '\n\nSCase measured: %s', num2str(length(SCaseList))); % Number of SCases measured fprintf(logFileID, '\nElapsed time (s): %s', num2str(toc)); % stopwatch timer fprintf(logFileID, '\n'); fclose(logFileID); % Close log file %% Output of the SCase if required by argument % SCase.output % inputArg = abaqus/density/references/ % update mySQL % SCase.sqlSave status = 1; message = 'OK'; end diff --git a/test_measureSCase.m b/test_measureSCase.m deleted file mode 100755 index 9d60d1f..0000000 --- a/test_measureSCase.m +++ /dev/null @@ -1,28 +0,0 @@ -function output = test_measureSCase(varargin) - -disp('Test: measureSCase("Z100","P1500","P001","trollingArgumentLol","N29");') -measureSCase('Z100','P1500','P001','trollingArgumentLol','N29'); - -%disp('Test: measureSCase("GlenoidDensity");') -%measureSCase('GlenoidDensity'); - -disp('Test: measureSCase("N29","N32");') -measureSCase('N29','N32'); - -disp('Test: measureSCase("N29","N29");') -measureSCase('N29','N29'); - -disp('Test: measureSCase("N29","N32","N34","N37");') -measureSCase('N29','N32','N34','N37'); - -disp('Test: measureSCase("N29","N32","Update");') -measureSCase('N29','N32','Update'); - -disp('Test: measureSCase("GlenoidDensity","N29","Update");') -measureSCase('GlenoidDensity','N29','Update'); - -% disp('Test: measureSCase("GlenoidDensity","N29","N32","Update","P");') -% measureSCase('GlenoidDensity','N29','N32','Update','P'); - -disp('Test: measureSCase("N29","N32","P");') -measureSCase('N29','N32','P');