From c1752bdda919c28b6f6e3a49a1a6bd7b37580b41 Mon Sep 17 00:00:00 2001
From: ac <andrew.r.cohen@drexel.edu>
Date: Tue, 1 Oct 2024 22:53:40 -0400
Subject: [PATCH] rsf.darktubes rnfl et al forte

---
 src/MATLAB/+RSF/darkTubes.m         | 25 +++++++++++++++
 src/MATLAB/+RSF/getImf.m            | 10 ++++--
 src/MATLAB/+RSF/quantizePair.m      |  6 ++--
 src/MATLAB/clusterExamples/goLR.m   | 33 ++++++-------------
 src/MATLAB/ncdVSvfmd/getRNFL.m      |  8 +++++
 src/MATLAB/ncdVSvfmd/getStats.m     | 29 ++++++++++++-----
 src/MATLAB/ncdVSvfmd/getVFMD.m      |  2 +-
 src/MATLAB/ncdVSvfmd/goKernelCorr.m | 50 +++++++++--------------------
 src/MATLAB/ncdVSvfmd/kernelCorr.m   |  8 ++---
 src/MATLAB/ncdVSvfmd/regnetCorr.m   | 14 ++++----
 src/MATLAB/qualify/getRNFL.m        |  3 ++
 src/MATLAB/qualify/goQualify.m      | 33 +++++++++++++++++++
 12 files changed, 138 insertions(+), 83 deletions(-)
 create mode 100644 src/MATLAB/+RSF/darkTubes.m
 create mode 100644 src/MATLAB/ncdVSvfmd/getRNFL.m
 create mode 100644 src/MATLAB/qualify/getRNFL.m
 create mode 100644 src/MATLAB/qualify/goQualify.m

diff --git a/src/MATLAB/+RSF/darkTubes.m b/src/MATLAB/+RSF/darkTubes.m
new file mode 100644
index 0000000..f65e157
--- /dev/null
+++ b/src/MATLAB/+RSF/darkTubes.m
@@ -0,0 +1,25 @@
+function imfm = darkTubes(im,CONSTANTS,thickness)
+
+voxelSize = CONSTANTS.imageData.PixelPhysicalSize;
+voxelSize([1,2]) = voxelSize([2,1]); % swap (x,y,z) to matlab column major (y,x,z)
+vx = max(voxelSize)./voxelSize;
+% vx = [1,1,1];
+sigma = 1/sqrt(3) * thickness * vx;
+
+cudaTarget = getCudaTarget;
+imf = HIP.LoG(im,sigma,cudaTarget);
+imn = imf;
+imn(imn>0) = 0;
+imn = abs(imn);
+
+bw = imbinarize(im);
+bw = bwareaopen(bw,1e3);
+bw = imdilate(bw,ones(4*thickness));
+
+imn(~bw) = 0;
+
+imfm = fibermetric(imn);
+% imfm = imfm .* imregionalmax(imfm);
+4;
+
+
diff --git a/src/MATLAB/+RSF/getImf.m b/src/MATLAB/+RSF/getImf.m
index e0cb7b7..635d6f3 100644
--- a/src/MATLAB/+RSF/getImf.m
+++ b/src/MATLAB/+RSF/getImf.m
@@ -19,13 +19,19 @@ while startTarget <= size(pData,1)
         pp = spmdIndex - 1 + startTarget;
         if spmdIndex <= N_CUDA_PROCS && pp <= size(pData,1)            
             strDB = fullfile(pData.folder{pp},pData.filename{pp});
-            [im] = SSF.loadImage(strDB,1);
+            % RSF images and metadata via lever file
+            [im,CONSTANTS] = leversc.loadImage(strDB,1,1); 
             % 3-channel e.g. plate,blob,0
             for c = 1:length(radii)
                 if all(0==radii{c})
                     im1(:,:,:,c) = zeros(size(im));
                 else
-                    im1(:,:,:,c) = RSF.imPreProcess(im,radii{c});
+                    if length(radii{c}) == 1
+                        % hardcode for darktubes...careful...ACK
+                        im1(:,:,:,c) = RSF.darkTubes(im,CONSTANTS,radii{c});
+                    else
+                        im1(:,:,:,c) = RSF.imPreProcess(im,radii{c});
+                    end
                 end  
             end
         end
diff --git a/src/MATLAB/+RSF/quantizePair.m b/src/MATLAB/+RSF/quantizePair.m
index 7bda641..03dc8e5 100644
--- a/src/MATLAB/+RSF/quantizePair.m
+++ b/src/MATLAB/+RSF/quantizePair.m
@@ -1,9 +1,9 @@
 % clipLimits = [minVal,maxVal];
 function [i1q,i2q] = quantizePair(i1,i2)
 
-if isa(i1,'uint8') && isa(i2,'uint8')
-    return
-end
+% if isa(i1,'uint8') && isa(i2,'uint8')
+%     return
+% end
 
 pix = [i1(find(i1));i2(find(i2))];
 
diff --git a/src/MATLAB/clusterExamples/goLR.m b/src/MATLAB/clusterExamples/goLR.m
index 4c47c8b..8fa05c2 100644
--- a/src/MATLAB/clusterExamples/goLR.m
+++ b/src/MATLAB/clusterExamples/goLR.m
@@ -1,5 +1,5 @@
 tic
-ROOT = '/g/leverjs/Schuman_OCT/OCT/combined';
+ROOT = '/g/leverjs/Schuman_OCT/OCT/qualified';
 
 PID = 'P10010';
 flist = dir(fullfile(ROOT,['/' PID '*.LEVER']));
@@ -13,25 +13,12 @@ tblMeta = tblMeta(contains(tblMeta.scanType,'Optic'),:);
 % tblMeta = tblMeta(contains(tblMeta.scanType,'Macula'),:);
 % tblMeta = tblMeta(contains(tblMeta.eye,'OD'),:);
 
-tblQualify = readtable('../ncdVSvfmd/nyu onh matched.xlsx');
-mx = regexp(tblQualify.file_name,'P(\d+)_(.+?)_(\d+-\d+-\d+)_(\d+-\d+-\d+)_(\w\w)_(.+?)_.*.img','tokens');
-tblQualify.scanID = cellfun(@(x) x{1}{6},mx,'UniformOutput',false);
-tblQualify.PID = cellfun(@(x) str2double(x{1}{1}),mx,'UniformOutput',false);
-PID = str2double(PID(2:end));
-idx = find(cell2mat(tblQualify.PID) == PID);
-
-for i = 1:height(tblMeta)
-    idx = find(strcmp(tblQualify.scanID,tblMeta.scanID{i}));
-    if any(strcmp(tblQualify.qualification_status(idx),'No'))
-        tblMeta.bDisqualified(i) = true;
-    end
-end
-tblMeta(tblMeta.bDisqualified,:) = [];    
 p = ljsStartParallel(96);
 
-radii = {[0.5,8,8],[5,5,5],[0,0,0]}; % plate,blob
+% radii = {[0.5,8,8],[5,5,5],[0,0,0]}; % plate,blob
 % radii = {[0.5,8,8]}; % plate
 
+radii = {[3]} % dark tubes
 imf = RSF.getImf(tblMeta,radii);
 d = [];
 parfor i = 1:length(imf)
@@ -57,13 +44,13 @@ tM = tblMeta(contains(tblMeta.scanType,'Macular'),:);
 t3 = tO;
 t4 = tM;
 
-clf;hold on
-plot3(t1.Y(:,1),t1.Y(:,2),t1.Y(:,3),'r*')
-plot3(t2.Y(:,1),t2.Y(:,2),t2.Y(:,3),'og')
-legend({'OS','OD'})
-xlabel('NCD1')
-ylabel('NCD2')
-zlabel('NCD3')
+    clf;hold on
+    plot3(t1.Y(:,1),t1.Y(:,2),t1.Y(:,3),'r*')
+    plot3(t2.Y(:,1),t2.Y(:,2),t2.Y(:,3),'og')
+    legend({'OS','OD'})
+    xlabel('NCD1')
+    ylabel('NCD2')
+    zlabel('NCD3')
 
 plot3(t3.Y(:,1),t3.Y(:,2),t3.Y(:,3),'mx')
 plot3(t4.Y(:,1),t4.Y(:,2),t4.Y(:,3),'cs')
diff --git a/src/MATLAB/ncdVSvfmd/getRNFL.m b/src/MATLAB/ncdVSvfmd/getRNFL.m
new file mode 100644
index 0000000..fb7bb82
--- /dev/null
+++ b/src/MATLAB/ncdVSvfmd/getRNFL.m
@@ -0,0 +1,8 @@
+function iRNFL = getRNFL(p1,tblRNFL)
+
+% find p1 in tblRNFL and return avg thickness
+[~,f1,~] = fileparts(p1.filename);
+[~,tblFname,~] = fileparts(tblRNFL.file_name);
+idx1 = find(strcmp(f1,tblFname),1,'first');
+iRNFL = tblRNFL{idx1,"AVERAGETHICKNESS"};
+4;
diff --git a/src/MATLAB/ncdVSvfmd/getStats.m b/src/MATLAB/ncdVSvfmd/getStats.m
index 8197425..9a15882 100644
--- a/src/MATLAB/ncdVSvfmd/getStats.m
+++ b/src/MATLAB/ncdVSvfmd/getStats.m
@@ -1,19 +1,21 @@
 
-function tblVelo = getStats(dxx, pData, tblMD)
-if ~exist('idxDel','var')
-    idxDel = [];
+function tblVelo = getStats(dxx, pData, tblMD, tblRNFL)
+
+if ~exist('tblRNFL','var')
+    tblRNFL = [];
 end
+
 tblVelo = table();
 idxUnused = 1:height(pData);
 for i = 1:length(dxx)
+    
     for j = 1:size(dxx{i},1)
+        jRNFL = getRNFL(pData(j,:),tblRNFL);
         m = dxx{i}(j,2);
         n = dxx{i}(j,3);
         % m and n are indices into pData
         % check first if either is disqualified
-        if pData.disqualified(m) || pData.disqualified(n)
-            continue
-        end
+        
        
         if pData.dx(m) > pData.dx(n)
             4;
@@ -30,26 +32,37 @@ for i = 1:length(dxx)
         if dmd>0
             continue
         end
+
+        mRNFL = getRNFL(pData(m,:),tblRNFL);
+        nRNFL = getRNFL(pData(n,:),tblRNFL);
+        deltaRNFL = nRNFL - mRNFL;
+
         nt = table();
         nt.subjectID = pData.subjectID(m);
         idxm = find(dxx{i}(:,2)==m & dxx{i}(:,3) == m);
         idxn = find(dxx{i}(:,2)==n & dxx{i}(:,3) == n);
         nt.X = [dxx{i}(idxm,1),dxx{i}(idxn,1),dxx{i}(j,1)];
-        nt.velocity = (dxx{i}(j,1));        
+        nt.ncd = (dxx{i}(j,1));        
         nt.md = min(pData.md(n),pData.md(m));
         nt.dmd = dmd;
         nt.mn = [m,n];                
         nt.ddx = pData.dx(n) - pData.dx(m);
+        
+        nt.mRNFL = mRNFL;
+        nt.nRNFL = nRNFL;
+        nt.deltaRNFL = deltaRNFL;
         % find sex
         idx = find(tblMD.subjectID == pData.subjectID(m),1,'first');
         nt.sex = tblMD.gender_full(idx);
         if abs(nt.dmd)>4
             continue
         end
+
+% on the unqualified data vs. qualified data 
 %         if years(nt.ddx)>1
 %             continue
 %         end
-%         if nt.velocity > 0.9 && nt.velocity < 0.975
+%         if nt.ncd > 0.9 && nt.ncd< 0.975
 %             continue
 %         end
         if m ~= n
diff --git a/src/MATLAB/ncdVSvfmd/getVFMD.m b/src/MATLAB/ncdVSvfmd/getVFMD.m
index 92e08e5..4626b63 100644
--- a/src/MATLAB/ncdVSvfmd/getVFMD.m
+++ b/src/MATLAB/ncdVSvfmd/getVFMD.m
@@ -10,7 +10,7 @@ fx = {'nyu VF qualified data great than -6 data export.xlsx',...
 tblVFMD = table();
 for ff = 1 : length(fx)
     
-    tx = readtable(fullfile("importMetadata/dataExcel/",fx{ff}));
+    tx = readtable(fullfile("../importMetadata/dataExcel/",fx{ff}));
     % filter 1
     idxVFMD = contains(lower(tx.qualification_status),'yes');
     tx = tx(idxVFMD,:);
diff --git a/src/MATLAB/ncdVSvfmd/goKernelCorr.m b/src/MATLAB/ncdVSvfmd/goKernelCorr.m
index 992b050..9451fd9 100644
--- a/src/MATLAB/ncdVSvfmd/goKernelCorr.m
+++ b/src/MATLAB/ncdVSvfmd/goKernelCorr.m
@@ -1,42 +1,22 @@
 datetime
 kernelCorrStart = tic();
 eye = 'OD';
-ROOT = '/g/leverjs/Schuman_OCT/OCT/combined';
+ROOT = '/g/leverjs/Schuman_OCT/OCT/qualified';
 % scanType = 'Macular Cube 200x200';
 scanType = 'Optic Disc Cube 200x200';
 
 load('vfmd_meta.mat');
-[rho2,tblVelo, pData, dxx]  = kernelCorr([0.5,8,8],tblVFMD,tblMeta,scanType,eye);
-[rmse1,rmse2] = regnetCorr(tblVelo)
-% 
-% tblResults = table();
-% for rx = 1:length(radii)
-%     rr = radii{rx};
-%     [rho2,tblVelo, pData, dxx]  = kernelCorr(rr,tblVFMD,tblMeta,scanType,eye);
-%     nt = table();
-%     nt.rr = {rr};
-%     nt.tblVelo = {tblVelo};
-%     nt.pData = {pData};
-%     nt.dxx = {dxx};
-%     nt.r2 = rho2;
-%     if iscell(rr)
-%         rstr = cellfun(@mat2str,rr,'UniformOutput',false);
-%         rstr = horzcat(rstr{:});
-%     else
-%         rstr = mat2str(rr);
-%     end 
-%     nt.rstr = {rstr};
-%     tblResults = [tblResults;nt]
-% end
-% 
-% for i = 1:height(tblResults)
-%     [rmse1,rmse2] = regnetCorr(tblResults.tblVelo{i});
-%     tblResults.rmse(i,:) = [rmse1,rmse2];
-%     tblVelo = tblResults.tblVelo{i};
-%     x = tblVelo.velocity;
-%     y = tblVelo.dmd;
-%     yt = log10(1+y);
-%     [f,gofX]=fit(x,yt,'poly1');
-%     [f,gof]=fit(x,y,'poly1');    
-%     tblResults.r2a(i,1:2) = [gof.adjrsquare,gofX.adjrsquare]
-% end
+% tblVFMD = getVFMD(eye);
+tblMeta = getMetaOCT(ROOT,eye,scanType);
+
+
+load('../qualify/onh_rnfl_thickness.mat');
+
+radii = {[0.5,8,8],[5,5,5],[4]}; % plate,blob
+% radii = {[0.5,8,8]}; % plate
+
+
+[rho2,tblVelo, pData, dxx]  = kernelCorr(radii,tblVFMD,tblMeta,tblRNFL);
+
+
+[rmse1,~] = regnetCorr(tblVelo);median(rmse1)
diff --git a/src/MATLAB/ncdVSvfmd/kernelCorr.m b/src/MATLAB/ncdVSvfmd/kernelCorr.m
index 82dbcc2..1d313ce 100644
--- a/src/MATLAB/ncdVSvfmd/kernelCorr.m
+++ b/src/MATLAB/ncdVSvfmd/kernelCorr.m
@@ -1,4 +1,4 @@
-function [rho2,tblVelo, pData, dxx] = kernelCorr(radii,tblVFMD,tblMeta,scanType,eye)
+function [rho2,tblVelo, pData, dxx] = kernelCorr(radii,tblVFMD,tblMeta,tblRNFL)
 
 kernelCorrStart = tic();
 
@@ -40,7 +40,7 @@ end
 
 p=ljsStartParallel(96);
 
-imf = RSF.getImf(pData,radii,scanType);
+imf = RSF.getImf(pData,radii);
 
 [C,ia,ic] = unique(pData.subjectID);
 
@@ -84,8 +84,8 @@ parfor wx = 1:length(workList)
     end
 end
 
-tblVelo = getStats(dxx,pData,tblVFMD);
-[rho,pCorr] = corr((tblVelo.velocity),(tblVelo.dmd));
+tblVelo = getStats(dxx,pData,tblVFMD,tblRNFL);
+[rho,pCorr] = corr((tblVelo.ncd),(tblVelo.dmd));
 rho2 = rho^2
 toc(kernelCorrStart)
 4;
diff --git a/src/MATLAB/ncdVSvfmd/regnetCorr.m b/src/MATLAB/ncdVSvfmd/regnetCorr.m
index 851f350..6a01931 100644
--- a/src/MATLAB/ncdVSvfmd/regnetCorr.m
+++ b/src/MATLAB/ncdVSvfmd/regnetCorr.m
@@ -1,21 +1,21 @@
 function [err,mdlX] = regnetCorr(tblVelo)
 
-% tblVelo.velocity is NCD 
 % tblVelo.md is vfmd for first of two image pairs
 % tblVelo.dmd is delta VFMD between two image pairs
 
 % tblVelo = getStats(dxx,pData,[],tblVFMD);
-% X = [tblVelo.velocity,tblVelo.md];
+% X = [tblVelo.ncd,tblVelo.md];
 t2 = tblVelo(tblVelo.dmd~=0,:);
 
-X1 = [t2.velocity];
-X2 = [t2.velocity,t2.md];
+X1 = [t2.ncd];
+X2 = [t2.ncd,t2.md];
 T = t2.dmd;
+% T = t2.deltaRNFL;
 
 % leave one out x-validation
 err = [];
 mdlX = {};
-xTarget = X1;
+xTarget = X2;
 for i = 1:length(xTarget)
     trainX = xTarget;
     trainX(i,:) = [];
@@ -27,8 +27,8 @@ for i = 1:length(xTarget)
     mdlX{i} = mdl;
     pred = mdl.predict(xTarget(i,:));
     err(i) = abs(T(i) - pred);
-    [i,mean(err)]
+    [i,median(err)]
 end
-mean(err)
+% mean(err)
 4;
 
diff --git a/src/MATLAB/qualify/getRNFL.m b/src/MATLAB/qualify/getRNFL.m
new file mode 100644
index 0000000..50f0dc4
--- /dev/null
+++ b/src/MATLAB/qualify/getRNFL.m
@@ -0,0 +1,3 @@
+% getRNFL
+tx_onh = readtable('nyu onh matched.xlsx');
+save('onh_rnfl_thickness.mat','tx_onh');
diff --git a/src/MATLAB/qualify/goQualify.m b/src/MATLAB/qualify/goQualify.m
new file mode 100644
index 0000000..1c94df3
--- /dev/null
+++ b/src/MATLAB/qualify/goQualify.m
@@ -0,0 +1,33 @@
+ROOT = '/g/leverjs/Schuman_OCT/OCT/combined';
+target = '/g/leverjs/Schuman_OCT/OCT/qualified';
+if ~exist(target,'dir')
+    mkdir(target);
+end
+% flist = dir(fullfile(ROOT,'**/*.LEVER'));
+% qONH = readtable('nyu onh matched.xlsx');
+% qMacula = readtable('nyu mac matched.xlsx');
+% [~,fONH,~] = fileparts(qONH.file_name);
+% [~,fMacula,~] = fileparts(qMacula.file_name);
+qlist = [];
+for i = 1 : length(flist)
+    
+    [~,fname,~] = fileparts(flist(i).name);
+    idx = find(strcmp(fname,fMacula));
+    if ~isempty(idx)
+        tidx = qMacula(idx,:);
+    else
+        idx = find(strcmp(fname,fONH));
+        tidx = qONH(idx,:);
+    end
+    if isempty(idx)
+        continue
+    end
+    qs = lower(tidx.qualification_status);
+    if any(strcmp(qs,'no'))
+        continue
+    end
+    qlist = [qlist,flist(i)];
+    src = fullfile(flist(i).folder,fname);
+    cmd = ['cp "' src '".* ' target];
+    system(cmd);
+end
-- 
GitLab