diff --git a/Ai9DetermineCutoff.m b/Ai9DetermineCutoff.m new file mode 100644 index 0000000..10cb092 --- /dev/null +++ b/Ai9DetermineCutoff.m @@ -0,0 +1,16 @@ +Area=squeeze(Data(:,:,1,:)); +Tomato=squeeze(Data(:,:,2,:)); +TooLow=~(Tomato>0.1); +Area2=Area; +Tomato2=Tomato; +Area2(TooLow) =[NaN]; +Tomato2(TooLow)=[NaN]; +% +TotArea=sum(Area2,'omitnan'); +AvTomato=(Tomato2); +figure, plot3(1:384,Area2,Tomato2,'o') +grid on +% % Area=sum(squeeze(Data(:,:,1,:)),'omitnan'); +% % AvTomato=mean(squeeze(Data(:,:,2,:)),'omitnan'); +% figure, plot3(1:384,Area,AvTomato,'o') +% grid on \ No newline at end of file diff --git a/Analysis/CellAnalysis/Plot_Fluorescence.m b/Analysis/CellAnalysis/Plot_Fluorescence.m index 52cdc70..5e4a1c0 100644 --- a/Analysis/CellAnalysis/Plot_Fluorescence.m +++ b/Analysis/CellAnalysis/Plot_Fluorescence.m @@ -66,6 +66,8 @@ function Plot_Fluorescence(aCells, aAxes, aChannel, varargin) fluor = c.regionProps.(['FluorMax' aChannel]); case 'avg' fluor = c.regionProps.(['FluorAvg' aChannel]); + case 'test' + fluor = c.regionProps.(['FluorAvg' aChannel]); case 'tot' fluor = c.regionProps.(['FluorTot' aChannel]); if strcmpi(aYUnit, 'microns') diff --git a/Analysis/CellAnalysis/Plot_Fluorescence3D.m b/Analysis/CellAnalysis/Plot_Fluorescence3D.m new file mode 100644 index 0000000..fa960fd --- /dev/null +++ b/Analysis/CellAnalysis/Plot_Fluorescence3D.m @@ -0,0 +1,155 @@ +function Plot_Fluorescence(aCells, aAxes, aChannel,aChannel2,Color, varargin) +% Plots the fluorescence intensity of cells over time. +% +% The function can be used to plot the maximum intensity, the average +% intensity or the integrated intensity. The function only works for cells +% that come from the same image sequence. The function can only be used on +% tracking results where there is a fluorescent channel. The function is +% meant to be called by CellAnalysisPlayer. The function will only show up +% in the CellAnalysisPlayer GUI if the dataset has one or more +% fluorescence channels. The function PrintStyle is called to make the +% plotting style consistent with other plots. +% +% Inputs: +% aCells - Cells for which the fluorescence will be plotted. +% aAxes - Axes object to plot the data in. +% aChannel - The name of the fluorescence channel to be plotted. +% +% Property/Value inputs: +% XUnit - The time unit used on the x-axis. The options are 'frames' and +% 'hours', and the default is 'hours'. +% YUnit - The length unit used to compute the integrated intensity. The +% options are 'pixels' and 'microns'. For 2D datasets, the +% resulting units on the y-axis are intensity * pixels and +% intensity * square microns respectively. For 3D datasets, the +% units are intensity * voxels or intensity * cubic microns. The +% default is 'microns'. Note that this input has an effect only if +% Metric is 'tot'. +% Metric - What parameter of the fluorescence to plot. The options are +% 'max', 'avg', and 'tot', and they correspond to the maximum, +% average, and the integrated fluorescence over the cell area. The +% default is 'max'. +% +% See also: +% CellAnalysisPlayer, Plot_AxisRatio, Plot_CellSize, Plot_LinageTree, +% Plot_TotalDistance, PrintStyle + +% Get property/value inputs. +[aXUnit, aYUnit, aMetric1] = GetArgs(... + {'XUnit', 'YUnit', 'Metric'},... + {'hours', 'microns', 'max'},... + true, varargin); + +% Clear the previous plot. +% cla(aAxes) +% hold(aAxes, 'off') + +if isempty(aCells) + return +end +imData = aCells(1).imageData; +% BronkBox=cell(length(cells2),max([cells2.stopT])); +for i = 1:length(aCells) + c = aCells(i); + % Time (x-coordinates of plot). +% switch aXUnit +% case 'hours' +% t = imData.FrameToT(c.firstFrame : c.lastFrame); +% case 'frames' +% t = c.firstFrame : c.lastFrame; +% end + t=1; + % Fluorescence (y-coordinates of plot). + aMetric1= 'avg'; + switch lower(aMetric1) + case 'max' + fluor = c.regionProps.(['FluorMax' aChannel]); + case 'avg' + fluor = c.regionProps.(['FluorAvg' aChannel]); + case 'test' + fluor = c.regionProps.(['FluorAvg' aChannel]); + case 'tot' + fluor = c.regionProps.(['FluorTot' aChannel]); + if strcmpi(aYUnit, 'microns') + if imData.GetDim() == 2 + fluor = imData.Pixel2ToMicroM2(fluor); + else + fluor = imData.VoxelToMicroM3(fluor); + end + end + end + aMetric2= 'tot'; + % Fluorescence (z-coordinates of plot). + switch lower(aMetric2) + case 'max' + fluor2 = c.regionProps.(['FluorMax' aChannel2]); + case 'avg' + fluor2 = c.regionProps.(['FluorAvg' aChannel2]); + case 'test' + fluor2 = c.regionProps.(['FluorAvg' aChannel2]); + case 'tot' + fluor2 = c.regionProps.(['FluorTot' aChannel2]); + if strcmpi(aYUnit, 'microns') + if imData.GetDim() == 2 + fluor2 = imData.Pixel2ToMicroM2(fluor2); + else + fluor2 = imData.VoxelToMicroM3(fluor2); + end + end + end + % Plot the fluorescence over time for one cell. + Color=Color; + Color2=Color+0.4*((i-1)/length(aCells)); + Color2(Color2>1)=1; + Color2(Color2<0)=1; + PlotWithNan3D(aAxes, t, fluor,fluor2,'color',Color2,... + 'LineWidth', 2); +% alpha(.5); + hold(aAxes, 'on') +% testing=Color; +end + +% Set the limits of the plot. +SetYLimits(aAxes) +xlim(aAxes, imData.GetTLim(aXUnit, 'Margins', [0.01 0.01])) + +% x-label. +switch lower(aXUnit) + case 'frames' + xlabel(aAxes, 'Time (frames)') + case 'hours' + xlabel(aAxes, 'Time (hours)') +end + +% y-label and title. +switch lower(aMetric1) + case 'max' + title(aAxes, sprintf('Maximum fluorescence (%s)',... + SpecChar(imData.GetSeqDir(), 'matlab'))) + ylabel(aAxes, 'Fluorescence (relative to max)') + case 'avg' + title(aAxes, sprintf('Average fluorescence (%s)',... + SpecChar(imData.GetSeqDir(), 'matlab'))) + ylabel(aAxes, 'Fluorescence (relative to max)') + case 'tot' + title(aAxes, sprintf('Integrated fluorescence (%s)',... + SpecChar(imData.GetSeqDir(), 'matlab'))) + if imData.GetDim() == 2 + switch aYUnit + case 'pixels' + ylabel(aAxes, 'Fluorescence (relative to max) * Area in pixels') + case 'microns' + ylabel(aAxes, 'Fluorescence (relative to max) * Area in \mum^2') + end + else + switch aYUnit + case 'pixels' + ylabel(aAxes, 'Fluorescence (relative to max) * Volume in voxels') + case 'microns' + ylabel(aAxes, 'Fluorescence (relative to max) * Volume in \mum^3') + end + end +end + +PrintStyle(aAxes) +end \ No newline at end of file diff --git a/Analysis/CellAnalysis/Plot_Fluorescence3D_2.m b/Analysis/CellAnalysis/Plot_Fluorescence3D_2.m new file mode 100644 index 0000000..255d8a8 --- /dev/null +++ b/Analysis/CellAnalysis/Plot_Fluorescence3D_2.m @@ -0,0 +1,157 @@ +function Plot_Fluorescence3D_2(aCells, aAxes, aChannel,aChannel2,Color,x_in, varargin) +% Plots the fluorescence intensity of cells over time. +% +% The function can be used to plot the maximum intensity, the average +% intensity or the integrated intensity. The function only works for cells +% that come from the same image sequence. The function can only be used on +% tracking results where there is a fluorescent channel. The function is +% meant to be called by CellAnalysisPlayer. The function will only show up +% in the CellAnalysisPlayer GUI if the dataset has one or more +% fluorescence channels. The function PrintStyle is called to make the +% plotting style consistent with other plots. +% +% Inputs: +% aCells - Cells for which the fluorescence will be plotted. +% aAxes - Axes object to plot the data in. +% aChannel - The name of the fluorescence channel to be plotted. +% +% Property/Value inputs: +% XUnit - The time unit used on the x-axis. The options are 'frames' and +% 'hours', and the default is 'hours'. +% YUnit - The length unit used to compute the integrated intensity. The +% options are 'pixels' and 'microns'. For 2D datasets, the +% resulting units on the y-axis are intensity * pixels and +% intensity * square microns respectively. For 3D datasets, the +% units are intensity * voxels or intensity * cubic microns. The +% default is 'microns'. Note that this input has an effect only if +% Metric is 'tot'. +% Metric - What parameter of the fluorescence to plot. The options are +% 'max', 'avg', and 'tot', and they correspond to the maximum, +% average, and the integrated fluorescence over the cell area. The +% default is 'max'. +% +% See also: +% CellAnalysisPlayer, Plot_AxisRatio, Plot_CellSize, Plot_LinageTree, +% Plot_TotalDistance, PrintStyle + +% Get property/value inputs. +[aXUnit, aYUnit, aMetric] = GetArgs(... + {'XUnit', 'YUnit', 'Metric'},... + {'hours', 'microns', 'max'},... + true, varargin); + +% Clear the previous plot. +% cla(aAxes) +% hold(aAxes, 'off') + +if isempty(aCells) + return +end +imData = aCells(1).imageData; +% BronkBox=cell(length(cells2),max([cells2.stopT])); +for i = 1:length(aCells) + c = aCells(i); + % Time (x-coordinates of plot). + switch aXUnit + case 'hours' + t = imData.FrameToT(c.firstFrame : c.lastFrame); + case 'frames' + t = c.firstFrame : c.lastFrame; + end + t=x_in; + % Fluorescence (y-coordinates of plot). + aMetric= 'avg'; + switch lower(aMetric) + case 'max' + fluor = c.regionProps.(['FluorMax' aChannel]); + case 'avg' + fluor = c.regionProps.(['FluorAvg' aChannel]); + case 'test' + fluor = c.regionProps.(['FluorAvg' aChannel]); + case 'tot' + fluor = c.regionProps.(['FluorTot' aChannel]); + if strcmpi(aYUnit, 'microns') + if imData.GetDim() == 2 + fluor = imData.Pixel2ToMicroM2(fluor); + else + fluor = imData.VoxelToMicroM3(fluor); + end + end + end + aMetric2= 'tot'; + % Fluorescence (z-coordinates of plot). + switch lower(aMetric2) + case 'max' + fluor2 = c.regionProps.(['FluorMax' aChannel2]); + case 'avg' + fluor2 = c.regionProps.(['FluorAvg' aChannel2]); + case 'test' + fluor2 = c.regionProps.(['FluorAvg' aChannel2]); + case 'tot' + fluor2 = c.regionProps.(['FluorTot' aChannel2]); + if strcmpi(aYUnit, 'microns') + if imData.GetDim() == 2 + fluor2 = imData.Pixel2ToMicroM2(fluor2); + else + fluor2 = imData.VoxelToMicroM3(fluor2); + end + end + end + % Plot the fluorescence over time for one cell. + Color=Color; + Color2=Color+0.4*((i-1)/length(aCells)); + Color2(Color2>1)=1; + Color2(Color2<0)=1; +% PlotWithNan3D(aAxes, t, fluor,fluor2,'color',Color2,... +% 'LineWidth', 2); + PlotWithNan3D(aAxes, t, fluor,fluor2,'color',Color2,... + 'LineWidth', 2); +% alpha(.5); +% hold(aAxes, 'on') +% testing=Color; +end + +% % Set the limits of the plot. +% % SetYLimits(aAxes) +% xlim(aAxes, imData.GetTLim(aXUnit, 'Margins', [0.01 0.01])) +% +% % x-label. +% switch lower(aXUnit) +% case 'frames' +% xlabel(aAxes, 'Time (frames)') +% case 'hours' +% xlabel(aAxes, 'Time (hours)') +% end +% +% % y-label and title. +% switch lower(aMetric1) +% case 'max' +% title(aAxes, sprintf('Maximum fluorescence (%s)',... +% SpecChar(imData.GetSeqDir(), 'matlab'))) +% ylabel(aAxes, 'Fluorescence (relative to max)') +% case 'avg' +% title(aAxes, sprintf('Average fluorescence (%s)',... +% SpecChar(imData.GetSeqDir(), 'matlab'))) +% ylabel(aAxes, 'Fluorescence (relative to max)') +% case 'tot' +% title(aAxes, sprintf('Integrated fluorescence (%s)',... +% SpecChar(imData.GetSeqDir(), 'matlab'))) +% if imData.GetDim() == 2 +% switch aYUnit +% case 'pixels' +% ylabel(aAxes, 'Fluorescence (relative to max) * Area in pixels') +% case 'microns' +% ylabel(aAxes, 'Fluorescence (relative to max) * Area in \mum^2') +% end +% else +% switch aYUnit +% case 'pixels' +% ylabel(aAxes, 'Fluorescence (relative to max) * Volume in voxels') +% case 'microns' +% ylabel(aAxes, 'Fluorescence (relative to max) * Volume in \mum^3') +% end +% end +% end + +% PrintStyle(aAxes) +end \ No newline at end of file diff --git a/Analysis/Plotting/PlotWithNan3D.m b/Analysis/Plotting/PlotWithNan3D.m new file mode 100644 index 0000000..f85b494 --- /dev/null +++ b/Analysis/Plotting/PlotWithNan3D.m @@ -0,0 +1,58 @@ +function PlotWithNan3D(aAxes,aX, aY,aZ, varargin) +% Plots a curve and fills in gaps of NaNs with dotted lines. +% +% The built in plot function in MATLAB will create gaps in the lines in +% places where there are NaN-values. This function will instead connect the +% end-points around the gaps with dotted lines. NaNs in the beginning and +% at the end of an array are not plotted. +% +% Inputs: +% aAxes - Axes object to plot in. +% aX - Array of x-values. +% aY - Array of y-values, that may contain NaN-values. +% varargin - Extra input arguments passed to the built in function plot. + +% Make the function work for both row- and column vectors. +aX = aX(:); +aY = aY(:); +aZ = aZ(:); +if isempty(aX) + return +end + +% Get the original hold-setting. +% hSet = ishold(aAxes); + +% Find breakpoints between NaN-values and other values. There will be 1s at +% each start of a new interval and at the first and the last element. +bp = [1; find(abs(diff(isnan(aY))))+1; length(aY)+1]; + +for i = 1:length(bp) - 1 + if isnan(aY(bp(i))) + if i ~= 1 && i ~= length(bp) - 1 + % Plot a dotted line over a NaN-gap. + start = bp(i)-1; + stop = bp(i + 1); + plot3([aX(start); aX(stop)],... + [aY(start); aY(stop)],... + [aZ(start); aZ(stop)],... + varargin{:},... + 'LineStyle', ':') + alpha(.1); + hold(aAxes, 'on') + end + else + % Plot a normal line. + start = bp(i); + stop = bp(i + 1) - 1; + plot3(aX(start : stop), aY(start : stop),aZ(start : stop),'o',varargin{:}) + alpha(.1); + grid on +% hold(aAxes, 'on') + end +end + +% Restore the original hold-setting. +% if ~hSet +% hold(aAxes, 'off') +end diff --git a/Analysis/PopulationAnalysis/OverTime3D.m b/Analysis/PopulationAnalysis/OverTime3D.m new file mode 100644 index 0000000..0e27a27 --- /dev/null +++ b/Analysis/PopulationAnalysis/OverTime3D.m @@ -0,0 +1,136 @@ +function OverTime(aAxes, aCellVec, aLabels, aProperty, aTitle, aPropertyLabel, ~, ~) +% Plots time averaged cell properties against appearance times of cells. +% +% The appearance times are binned into intervals of 1 hour, and average +% parameter values for the bins are computed and plotted against time. When +% there are no cells in a bin, the value of that bin is interpolated from +% surrounding values using linear interpolation. Lines that end in +% interpolated points are plotted using a dashed line style. +% +% Inputs: +% aAxes - Axes object to plot in. +% aCellVec - Cell array where each cell contains a group of Cell objects +% that will be plotted in a separate color. +% aLabels - Labels associated with the different cell groups. The groups +% are usually experimental conditions. +% aProperty - The name of the cell property to be plotted. The property +% must be a property of the Cell class. +% aTitle - Title describing the plotted property. The title will be placed +% at the top of the plot. +% aPropertyLabel - The axis label associated with the plotted property. +% +% The function also takes two dummy inputs which make it possible to call +% the function from PlotConditionProperty with the same input arguments as +% Scatter. +% +% See also: +% PlotConditionProperty + +% Colors used for plotting the different groups of cells. If there are more +% groups than colors, the colors are recycled. +colors = {'b', 'r', 'c', 'm', 'k', 'y', 'g'}; + +% Get the maximum property value. +cells = [aCellVec{:}]; +props = ExtractProperty(cells, aProperty); +if all(isnan(props)) + return +end +maxVal = max(props(~isnan(props))); + +numFrames = TimeSpan(cells); +df = 3600/cells(1).dT; % Number of frames in each bin. +% Time points corresponding to the bins. +t = cells(1).imageData.FrameToT(1:df:numFrames); + +propHist = cell(size(aCellVec)); +counts = cell(size(aCellVec)); + +% Put the cells and their properties into the bins. +for i = 1:length(aCellVec) + propHist{i} = zeros(ceil(numFrames / df), 1); + counts{i} = zeros(ceil(numFrames / df), 1); + for cIndex = 1:length(aCellVec{i}) + c = aCellVec{i}(cIndex); + if ~isnan(ExtractProperty(c, aProperty)) + % Bin that the cell belongs to. + bin = floor(c.firstFrame / df) + 1; + if strcmpi(aProperty, 'deltaT') + % For the property deltaT, each sister cell pair has a + % positive and a negative value (or two zeros). To deal + % with this, we take the absolute value of the property. + propHist{i}(bin) = propHist{i}(bin) +... + abs(ExtractProperty(c, aProperty)); + else + propHist{i}(bin) = propHist{i}(bin) +... + ExtractProperty(c, aProperty); + end + counts{i}(bin) = counts{i}(bin) + 1; + end + end +end + +% Compute the average property value in each bin, by dividing the summed +% property values by the number of cells. +propHistNorm = cell(size(propHist)); +for i = 1:length(aCellVec) + propHistNorm{i} = propHist{i} ./ counts{i}; +end + +% Create label strings, and make fake lines at the origin with the +% corresponding line styles, so that the correct lines are drawn in the +% legend. +labelStrings = {}; +for i = 1:length(aCellVec) + if all(isnan(propHistNorm{i})) + continue + end + + colorIndex = mod(i-1,length(colors)) + 1; + + % Solid line. + plot(aAxes, 0, 0, 'LineWidth', 4, 'Color', colors{colorIndex}) + hold(aAxes, 'on') + labelStrings = [labelStrings {num2str(aLabels{i})}]; %#ok + + % Dashed line. + if any(isnan(propHistNorm{i})) + plot(aAxes, 0, 0,... + 'LineWidth', 4,... + 'Color', colors{colorIndex},... + 'LineStyle', '--') + labelStrings = [labelStrings... + {[num2str(aLabels{i}) ' (interpolated)']}]; %#ok + end +end + +% Plot observed values with solid lines and interpolated values with dotted +% lines. The bins that need to be interpolated have NaN-values. +for i = 1:length(aCellVec) + colorIndex = mod(i-1,length(colors)) + 1; + bronkx=t' + bronky=propHistNorm{i}' + PlotWithNan(aAxes, t', propHistNorm{i}',... + 'LineWidth', 4,... + 'Color', colors{colorIndex}) +end + +% Set axis limits for the time axes. +if length(t) == 1 + % Avoids a crash when the plot is empty. + xlim(aAxes, [t t+1]) +else + xlim(aAxes, [t(1) t(end)]) +end + +% Set y-axis limits so that there is a 10 % Margin at the top. +if maxVal > 0 + set(aAxes, 'ylim', [0, maxVal*1.1]) +end + +grid(aAxes, 'on') +xlabel(aAxes, 'Time (hours)') +ylabel(aAxes, aPropertyLabel) +legend(aAxes, labelStrings, 'Location', 'Best') +title(aAxes, aTitle) +end \ No newline at end of file diff --git a/BF_Functions/BronkOpeningWindow.mlapp b/BF_Functions/BronkOpeningWindow.mlapp new file mode 100644 index 0000000..910f5e6 Binary files /dev/null and b/BF_Functions/BronkOpeningWindow.mlapp differ diff --git a/BF_Functions/CytDrug.m b/BF_Functions/CytDrug.m new file mode 100644 index 0000000..e97bc53 --- /dev/null +++ b/BF_Functions/CytDrug.m @@ -0,0 +1,25 @@ + %%Drugmine Code + +function [DrugBright,areaDrug, Drugsum, DrugAvgInCell, DrugAvgOutCell,Drug_eq,DrugMask] = Drug(Img, Drug_threshold, cyt_bw4) + + Drug_eq =imadjust(Img,[0 0.4],[]); + + Drug_threshold = Drug_threshold *intmax(class(drug)); + + Drugweiner=wiener2(Img); + RhodMask=Drugweiner>Drug_threshold; + areaDrug = sum(RhodMask,'all'); + if + Drug_in_cell = drug(cyt_bw4); + Drug_out_cell = drug(cyt_bw4 == 0); + + cell_area = sum(sum(cyt_bw4)); + not_cell_area = size(cyt_bw4,1) * size(cyt_bw4, 2) - cell_area; + + Rhodsum = sum(rhod_eq(RhodMask)); + RhodBright=drug; + RhodBright(~RhodMask)=0; + DrugvgInCell = sum(Drug_in_cell) / cell_area; + DrugvgOutCell = sum(Drug_out_cell) / not_cell_area; + + \ No newline at end of file diff --git a/BF_Functions/CytNucWaterShed.m b/BF_Functions/CytNucWaterShed.m new file mode 100644 index 0000000..ff0c048 --- /dev/null +++ b/BF_Functions/CytNucWaterShed.m @@ -0,0 +1,21 @@ +function [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4) +%UNTITLED4 Summary of this function goes here +% Detailed explanation goes here +cytsize=size(cyt); + border = ones(cytsize); + border(2:end-1,2:end-1) = 0; + n_maxs=imerode(Nuc_bw4,strel('disk',1)); + n_maxs=bwareaopen(n_maxs,100); + h=imhmin(CytTopHat,1); + h_c=imcomplement(h); + h_c_min=imimposemin(h_c, n_maxs); + L_n = watershed(h_c_min); + L_n(~cyt_bw4) = 0; + borderInverse=~border; + L_n(~borderInverse) = 0; + howdy=L_n; + Cyt_WS=imfill((howdy),4,'holes'); + Cyt_WS_perim = imdilate(bwperim(Cyt_WS),strel('disk',1)); + +end + diff --git a/BF_Functions/Cytosol.m b/BF_Functions/Cytosol.m new file mode 100644 index 0000000..4fe5036 --- /dev/null +++ b/BF_Functions/Cytosol.m @@ -0,0 +1,27 @@ +function [CytBright,CytArea,CytCytOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(cyt,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk) +%UNTITLED2 Summary of this function goes here +% Detailed explanation goes here + CytTopHat=imtophat(cyt,CytTophatDisk); % Clean image with tophat filter for thresholding + CytOpen=imerode(CytTopHat,CytOpenDisk); + CytOpen=imreconstruct(CytOpen,CytTopHat); + cyt_eq =imadjust(CytTopHat,[0 0.25],[]); %Make it easy to see + + CytMaxValue= CytMax*intmax(class(cyt)); + CytOverbright=CytOpen>CytMaxValue; + CytBright=CytOpen; + CytBright(CytOverbright)=0; + CytMT1=multithresh(CytBright,20); %Calculate 20 brightness thresholds for image + CytQuant1=imquantize(CytBright,CytMT1); %Divide Image into the 20 brightness baskets + CytBrightEnough=CytQuant1>CytLow; + + CytPos=CytBright; + CytPos(~CytBrightEnough)=0; + cyt_bw2=imerode(CytPos,CytErodeDisk); + cyt_bw3 = bwareaopen(cyt_bw2, 2000); %%Be sure to check this threshold + cyt_bw4 = imclose(cyt_bw3, CytCloseDisk); + CytPos(~cyt_bw4)=0; + cyt_bw4_perim = imdilate(bwperim(cyt_bw4),strel('disk',2)); + CytArea = imoverlay(cyt_eq, cyt_bw4_perim, [.3 1 .3]); + CytCytOverlay = imoverlay(cyt_eq, cyt_bw4_perim, [.3 1 .3]); +end + diff --git a/BF_Functions/Drug.m b/BF_Functions/Drug.m new file mode 100644 index 0000000..ff3cf5d --- /dev/null +++ b/BF_Functions/Drug.m @@ -0,0 +1,12 @@ + %%BasicThresh Code + +function [DrugBright,areaDrug, Drugsum, DrugMask] = Drug(Img, Drug_threshold) + + Drug_threshold = Drug_threshold *intmax(class(drug)); + DrugMask=Img>Drug_threshold; + areaDrug = sum(DrugMask,'all'); + Drugsum = sum(Img(DrugMask)); + DrugBright(~DrugMask)=0; + + + \ No newline at end of file diff --git a/BF_Functions/Gal8.m b/BF_Functions/Gal8.m new file mode 100644 index 0000000..3584c1d --- /dev/null +++ b/BF_Functions/Gal8.m @@ -0,0 +1,31 @@ +function [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix) +%UNTITLED2 Summary of this function goes here +% Detailed explanation goes here +Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + +Gal8=wiener2(Img); +Gal8TH=imtophat(Gal8,Gal8TophatDisk); +Gal8Open=imopen(Gal8TH,Gal8OpenDisk); + +Gal8MinValue= Gal8MinThreshold*intmax(class(Img)); +Gal8Quant2=Gal8Open-Gal8MinValue; +Gal8Quant2(Gal8Quant2<=0)=0; +Gal8Quant3=bwareaopen(Gal8Quant2,4); +% Gal8Quant3(~Cyt_WS)=0; +Gal8Quant3(~CytPos)=0; +Gal8Quant3=imdilate(Gal8Quant3,Gal8DilateDisk); +Gal8Quant4=imdilate(Gal8Quant3,Gal8OutlineDisk); +Gal8Quant5=imbinarize(Gal8Quant4-Gal8Quant3); +GalPals=Img; +GalPals(~Gal8Quant3)=0; + +Puncta=regionprops(Gal8Quant3,Img,'Area','Centroid','MeanIntensity'); +Ring=regionprops(Gal8Quant5,Img,'Area','Centroid','MeanIntensity'); %need to figure out way to subtract out surrounding brightness for each individual Point +RingMeanInt=2; %need to figure out way to subtract out surrounding brightness for each individual Point +Gal8Signal=sum((vertcat(Puncta.MeanIntensity).*vertcat(Puncta.Area))); +% Gal8Signal=Gal8Signal'; +end + diff --git a/BF_Functions/NuclearStain.m b/BF_Functions/NuclearStain.m new file mode 100644 index 0000000..ae8496c --- /dev/null +++ b/BF_Functions/NuclearStain.m @@ -0,0 +1,34 @@ +function [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Nuc,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk) +%UNTITLED2 Summary of this function goes here +% Detailed explanation goes here + NucWeiner=wiener2(Nuc); + NucTopHat=imtophat(NucWeiner,NucTophatDisk); % Clean image with tophat filter for thresholding +% NucOpen=imerode(NucTopHat,NucOpenDisk); +% NucOpen=imreconstruct(NucOpen,NucTopHat); + Nuc_eq =imadjust(NucTopHat); %Make it easy to see + NucOpen=imopen(NucTopHat,NucOpenDisk); + NucMaxValue= NucMax*intmax(class(Nuc)); + NucOverbright=NucTopHat>NucMaxValue; + + NucOpen(NucOverbright)=0; +% NucMT1=multithresh(NucOpen,20); %Calculate 20 brightness thresholds for image +% NucQuant1=imquantize(NucOpen,NucMT1); %Divide Image into the 20 brightness baskets + NucMT1=1; + NucQuant1=1; +% NucBrightEnough=NucQuant1>NucLow; + NucBrightEnough=NucOpen>NucLow; + NucPos=NucOpen; + NucPos(~NucBrightEnough)=0; +% NucPos=imadjust(NucPos); + Nuc_bw2=imerode(NucPos,NucErodeDisk); + Nuc_bw3 = bwareaopen(Nuc_bw2, 250); %%Be sure to check this threshold + Nuc_bw4 = imclose(Nuc_bw3, NucCloseDisk); + Nuc_bw4 = imfill(Nuc_bw4,'holes'); + Nuc_bw4_perim = imdilate(bwperim(Nuc_bw4),strel('disk',3)); + + NucConn=bwconncomp(Nuc_bw4); + NucLabel = labelmatrix(NucConn); + NucArea = imoverlay(Nuc_eq, Nuc_bw4_perim, [.3 1 .3]); + +end + diff --git a/BF_Functions/Old Files/RunLogbackup_2022-02-09-02-21-07.m b/BF_Functions/Old Files/RunLogbackup_2022-02-09-02-21-07.m new file mode 100644 index 0000000..086eada --- /dev/null +++ b/BF_Functions/Old Files/RunLogbackup_2022-02-09-02-21-07.m @@ -0,0 +1,283 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')]; +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +Gitdir=fullfile(pwd,'RunLog'); +GitLog=sprintf('%sbackup_%s.m',Gitdir,Version); +% GitLog=sprintf('%sbackup_%s.m',LogFolder,Version); +% mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,GitLog) +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/Old Files/RunLogbackup_2022-02-09-02-21-10.m b/BF_Functions/Old Files/RunLogbackup_2022-02-09-02-21-10.m new file mode 100644 index 0000000..086eada --- /dev/null +++ b/BF_Functions/Old Files/RunLogbackup_2022-02-09-02-21-10.m @@ -0,0 +1,283 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')]; +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +Gitdir=fullfile(pwd,'RunLog'); +GitLog=sprintf('%sbackup_%s.m',Gitdir,Version); +% GitLog=sprintf('%sbackup_%s.m',LogFolder,Version); +% mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,GitLog) +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/Old Files/m_2021_12_30.m b/BF_Functions/Old Files/m_2021_12_30.m new file mode 100644 index 0000000..211e2ba --- /dev/null +++ b/BF_Functions/Old Files/m_2021_12_30.m @@ -0,0 +1,257 @@ +%% Gal8 Recruitment MATLAB Program + +% Written by Brock Fletcher in the Biomedical Engineering Department at +% Vanderbilt University 2017 - 2022 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/). +%Adapted from work by Kameron V Kilchrist, 2015 - 2018 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/), published in +% Kilchrist, Dimobi, ..., Duvall; "Gal8 +% Visualization of Endosome Disruption Predicts Carrier-mediated Biologic +% Drug Intracellular Bioavailability". + +% University Email: brock.fletcher@vanderbilt.edu +% Permanent Email: brockfletch@gmail.com + +% This code may be reused at will for non-commercial purposes. +% Licensed under a Creative Commons Attribution 4.0 International License. + +% Derivative code should be published at GitHub or FigShare. Derivative +% scientific works should cite _______________ +%% Usage Guide (TL/DR): + %Steps + %Export your fluorescent microscopy as multipage TIFs + %Grab a few example TIFs to test your parameters and put them + %into a folder. (..\Test) + %Create a Second Folder to output to (..\TestExports) + + %Copy the file paths from file explorer and paste them into the + %"workingdir" and "exportdir" + + %Enter your "Calibration" value + %Enter what programs to run on each Channel ("C1=[]") + %Set your thresholds to a starting value + %Run Program + %Check output Images and Excel File + %Change Threshold Values and Re-Run until results are good enough + %If good analysis cannot be reached, edit advanced Values + %If still not good enough, edit actual bulk of code + %Once ready, change "workingdir" to a folder containing all images + %to be analyzed, and "exportdir" to a new, empty folder + + %Run Program and wait. If too hard on your CPU, change "parfor" to + %"for" + + %Review output images and analyze Data. + %Reccomended Analysis Steps: + %Label Each row of Data using VLOOKUP in Excel. + %Explore Data using JMP's Graphbuilder. + %Graph Data in Prism. +%% Image Folder Location +clc, clear; +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-02-BigPRoteinScreen\20211002BigProteinScreen001.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-02-BigPRoteinScreen\2022-01-04_Demo'; +% filetype='tif'; +% listing=dir(strcat(workingdir,'*.TIF')); +% ds=imageDatastore(workingdir); +%% Directory Code +readeromeMeta=reader.getMetadataStore(); +destdirectory1 = fullfile(exportdir,'Overlaid'); +BaxtDirectory= fullfile(exportdir,'Baxter'); +exportbaseBAXTSegNuc=fullfile(BaxtDirectory,'Analysis','Segmentation_Nuc'); +exportbaseBAXTSegCell=fullfile(BaxtDirectory,'Analysis','Segmentation_Cell'); +mkdir(destdirectory1); %create the directory +mkdir(BaxtDirectory); +mkdir(exportbaseBAXTSegNuc); +mkdir(exportbaseBAXTSegCell); +%% +% This will measure the total Gal8 recruited to puncta and count cell +% nuclei or cytosol in each frame. + +% This code assumes you have exported images as multipage TIF files, with +% any of the following stains in each channel: + % nuclear Stain + % Difuse Cytosolic Stain + % Punctate Cytosolic Stain + % Labeled Drug or other exogenous molecule (Cas9, siRNA) + +% Images were exported to 2 page TIF images using Nikon NIS Elements. If +% you use alternate file formats or use separate export files for each +% channel, please edit the code as appropriate. + +% You *must* edit the workingdir and exportdir variables for this code to +% work. +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); +%% Image Thresholding EDIT HERE BASIC +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + +%Input Planes + InputPlanes={'Nuc','cyt','drug'}; + +%Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=1; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.08;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.4; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables +bitConvert=(2^16/2^bitdepthin); +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + % export file names and in the DataCells array. Note: it is a character + % array / string! +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +NumSeries=reader.getSeriesCount(); +NumColors=reader.getEffectiveSizeC(); +NumTimepoint=(reader.getImageCount())/NumColors; +NumImg=NumSeries*NumTimepoint*NumColors; + +C = cell(NumImg,length(Categories)); +%% Analysis Program +for j=0:NumSeries% Number of images in ND2 File + %% Import TIFs + % %The next few lines are specific to 2 page TIF images. Edit from here + % if you have alternate arrangements. +% currfile=strcat(workingdir,listing(j,1).name); + CurrSeries=j; + reader.setSeries(CurrSeries); + fname = reader.getSeries; + Well=num2str(fname,'%05.f'); + + BaxWellFolder=fullfile(BaxtDirectory,Well); + mkdir(BaxWellFolder); + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); + T_Value = reader.getSizeT()-1; + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); + mkdir(BaxSegFolderNuc); + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); + mkdir(BaxSegFolderCell); + + for i=1:T_Value + +% T_Value = reader.getSizeT(); + Timepoint = num2str(i,'%03.f'); + iplane=reader.getIndex(0,0,i); + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())) + for n= + ImagePlane(n)= bitConvert*bfGetPlane(reader,iplane+n); + end + + + %% Analyze Images + %%Nuclear Stain Code + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Nuc,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + % NucStats=regionprops(Nuc_bw4,'Centroid','Area'); + + %%Cytosol Code + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(cyt,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + + %WaterShed Segmentation of Individual Cells + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + % figure; imshow(imoverlay(cyt_eq,Cyt_WS, [.3 .3 1])); + %Gal8 Puncta Segmentation + [GalPals,Gal8Signal,RingMeanInt,Gal8Quant5,Gal8Quant4,Gal8Quant3,Gal8Open,Gal8TH,Gal8Quant2,Puncta,Ring] = Gal8(cyt,Gal8TophatDisk,Gal8OpenDisk,Gal8DilateDisk,Gal8MinThreshold,Cyt_WS,CytPos,Gal8OutlineDisk); + % figure; imshow(imoverlay(cyt_eq,Gal8Quant5, [.3 .3 1])); + + %Rhodamine Code + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(drug, Rhoda_threshold, cyt_bw4); + rhodPerim=bwperim(RhodMask); + + %All Data Images + RGBExportImage=cat(3,rhod_eq,cyt_eq,Nuc_eq); + WSArea = imoverlay(RGBExportImage, Cyt_WS_perim,[0.8500 0.3250 0.0980]); + ExportImage=imoverlay(WSArea,Gal8Quant5,'m'); + ExportImage=imoverlay(ExportImage,Nuc_bw4_perim, [0.3010 0.7450 0.9330]); + ExportImage=imoverlay(ExportImage,rhodPerim, 'y'); + % figure; imshow(ExportImage); + % + + %% Measure Image Data + + % measurement + areacell=bwarea(Nuc_bw4(:)); + CellSum=sum(Nuc(Nuc_bw4)); + areaGal8=sum((vertcat(Puncta.Area))); + % + % C(j,:)=[{run},{WellTime},{areacell},{CellSum},{areaGal8},{Gal8Signal},{areaRhod},{Rhodsum},{RhodAvgInCell},{RhodAvgOutCell}]; + %% Write Images to File + %overlaid Image + BaxterName=strcat('w',Well,'t',Timepoint) + + exportbase=strcat(destdirectory1,'\',run,'_',BaxterName); + + + fulldestination = strcat(exportbase,'.png'); %name file relative to that directory + imwrite(ExportImage, fulldestination); %save the file there directory + + %BaxterImages + ImageName=fullfile(BaxWellFolder,BaxterName); + imwrite(Nuc, strcat(ImageName,'c01','.tif'),'tif'); + imwrite(cyt, strcat(ImageName,'c02','.tif'),'tif'); + imwrite(GalPals, strcat(ImageName,'c03','.tif'),'tif'); + imwrite(drug, strcat(ImageName,'c04','.tif'),'tif'); + imwrite(RhodBright, strcat(ImageName,'c05','.tif'),'tif'); + + + SegNameNuc=fullfile(BaxSegFolderNuc,BaxterName); + imwrite(NucLabel, strcat(SegNameNuc,'c01','.tif'),'tif'); + + + SegNameCell=fullfile(BaxSegFolderCell,BaxterName); + imwrite(Cyt_WS, strcat(SegNameCell,'c01','.tif'),'tif'); + + + end +end +%% Write Analysis Data to File + +D=[Categories;C]; +WritingHere=strcat(exportdir,'\','Gal8','_',run); + writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data \ No newline at end of file diff --git a/BF_Functions/Old Files/m_Bronk_2022_01_05.m b/BF_Functions/Old Files/m_Bronk_2022_01_05.m new file mode 100644 index 0000000..c0fa4f0 --- /dev/null +++ b/BF_Functions/Old Files/m_Bronk_2022_01_05.m @@ -0,0 +1,255 @@ +%% Gal8 Recruitment MATLAB Program + +% Written by Brock Fletcher in the Biomedical Engineering Department at +% Vanderbilt University 2017 - 2022 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/). +%Adapted from work by Kameron V Kilchrist, 2015 - 2018 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/), published in +% Kilchrist, Dimobi, ..., Duvall; "Gal8 +% Visualization of Endosome Disruption Predicts Carrier-mediated Biologic +% Drug Intracellular Bioavailability". + +% University Email: brock.fletcher@vanderbilt.edu +% Permanent Email: brockfletch@gmail.com + +% This code may be reused at will for non-commercial purposes. +% Licensed under a Creative Commons Attribution 4.0 International License. + +% Derivative code should be published at GitHub or FigShare. Derivative +% scientific works should cite _______________ +%% Usage Guide (TL/DR): + %Steps + %Export your fluorescent microscopy as multipage TIFs + %Grab a few example TIFs to test your parameters and put them + %into a folder. (..\Test) + %Create a Second Folder to output to (..\TestExports) + + %Copy the file paths from file explorer and paste them into the + %"workingdir" and "exportdir" + + %Enter your "Calibration" value + %Enter what programs to run on each Channel ("C1=[]") + %Set your thresholds to a starting value + %Run Program + %Check output Images and Excel File + %Change Threshold Values and Re-Run until results are good enough + %If good analysis cannot be reached, edit advanced Values + %If still not good enough, edit actual bulk of code + %Once ready, change "workingdir" to a folder containing all images + %to be analyzed, and "exportdir" to a new, empty folder + + %Run Program and wait. If too hard on your CPU, change "parfor" to + %"for" + + %Review output images and analyze Data. + %Reccomended Analysis Steps: + %Label Each row of Data using VLOOKUP in Excel. + %Explore Data using JMP's Graphbuilder. + %Graph Data in Prism. +%% Image Folder Location +clc, clear; +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-11-BigProteinFollowUp\Ai9Lipo48hrs002.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-11-BigProteinFollowUp\Analysis'; +% filetype='tif'; +% listing=dir(strcat(workingdir,'*.TIF')); +% ds=imageDatastore(workingdir); +%% Directory Code +readeromeMeta=reader.getMetadataStore(); +destdirectory1 = fullfile(exportdir,'Overlaid'); +BaxtDirectory= fullfile(exportdir,'Baxter'); +exportbaseBAXTSegNuc=fullfile(BaxtDirectory,'Analysis','Segmentation_Nuc'); +exportbaseBAXTSegCell=fullfile(BaxtDirectory,'Analysis','Segmentation_Cell'); +mkdir(destdirectory1); %create the directory +mkdir(BaxtDirectory); +mkdir(exportbaseBAXTSegNuc); +mkdir(exportbaseBAXTSegCell); +%% +% This will measure the total Gal8 recruited to puncta and count cell +% nuclei or cytosol in each frame. + +% This code assumes you have exported images as multipage TIF files, with +% any of the following stains in each channel: + % nuclear Stain + % Difuse Cytosolic Stain + % Punctate Cytosolic Stain + % Labeled Drug or other exogenous molecule (Cas9, siRNA) + +% Images were exported to 2 page TIF images using Nikon NIS Elements. If +% you use alternate file formats or use separate export files for each +% channel, please edit the code as appropriate. + +% You *must* edit the workingdir and exportdir variables for this code to +% work. +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=1.36; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); +%% Image Thresholding EDIT HERE BASIC +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 +%Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=1000;% + %Cytosol + CytMax= 1.1; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=1; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=1;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 1; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables +bitConvert=(2^16/2^bitdepthin); +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + % export file names and in the DataCells array. Note: it is a character + % array / string! +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +NumSeries=reader.getSeriesCount(); +NumColors=reader.getEffectiveSizeC(); +NumTimepoint=(reader.getImageCount())/NumColors; +NumImg=NumSeries*NumTimepoint*NumColors; + +C = cell(NumImg,length(Categories)); +%% Analysis Program +for j=0:NumSeries% Number of images in ND2 File + %% Import TIFs + % %The next few lines are specific to 2 page TIF images. Edit from here + % if you have alternate arrangements. +% currfile=strcat(workingdir,listing(j,1).name); + CurrSeries=j; + reader.setSeries(CurrSeries); + fname = reader.getSeries; + Well=num2str(fname,'%05.f'); + + BaxWellFolder=fullfile(BaxtDirectory,Well); + mkdir(BaxWellFolder); + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); + T_Value = reader.getSizeT()-1; + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); + mkdir(BaxSegFolderNuc); + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); + mkdir(BaxSegFolderCell); + + for i=0:T_Value + +% T_Value = reader.getSizeT(); + Timepoint = num2str(i,'%03.f'); + iplane=reader.getIndex(0,0,i); + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())) + + Nuc = bitConvert*bfGetPlane(reader,iplane+2); + + cyt = bitConvert*bfGetPlane(reader,iplane+2); + + drug = bitConvert*bfGetPlane(reader,iplane+1); + + %% Analyze Images + %%Nuclear Stain Code + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Nuc,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + % NucStats=regionprops(Nuc_bw4,'Centroid','Area'); + + %%Cytosol Code + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(cyt,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + + %WaterShed Segmentation of Individual Cells + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + % figure; imshow(imoverlay(cyt_eq,Cyt_WS, [.3 .3 1])); + %Gal8 Puncta Segmentation + [GalPals,Gal8Signal,RingMeanInt,Gal8Quant5,Gal8Quant4,Gal8Quant3,Gal8Open,Gal8TH,Gal8Quant2,Puncta,Ring] = Gal8(cyt,Gal8TophatDisk,Gal8OpenDisk,Gal8DilateDisk,Gal8MinThreshold,Cyt_WS,CytPos,Gal8OutlineDisk); + % figure; imshow(imoverlay(cyt_eq,Gal8Quant5, [.3 .3 1])); + + %Rhodamine Code + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(drug, Rhoda_threshold, cyt_bw4); + rhodPerim=bwperim(RhodMask); + + %All Data Images + RGBExportImage=cat(3,rhod_eq,cyt_eq,Nuc_eq); + WSArea = imoverlay(RGBExportImage, Cyt_WS_perim,[0.8500 0.3250 0.0980]); + ExportImage=imoverlay(WSArea,Gal8Quant5,'m'); + ExportImage=imoverlay(ExportImage,Nuc_bw4_perim, [0.3010 0.7450 0.9330]); + ExportImage=imoverlay(ExportImage,rhodPerim, 'y'); + % figure; imshow(ExportImage); + % + + %% Measure Image Data + + % measurement + areacell=bwarea(Nuc_bw4(:)); + CellSum=sum(Nuc(Nuc_bw4)); + areaGal8=sum((vertcat(Puncta.Area))); + % + % C(j,:)=[{run},{WellTime},{areacell},{CellSum},{areaGal8},{Gal8Signal},{areaRhod},{Rhodsum},{RhodAvgInCell},{RhodAvgOutCell}]; + %% Write Images to File + %overlaid Image + BaxterName=strcat('w',Well,'t',Timepoint) + + exportbase=strcat(destdirectory1,'\',run,'_',BaxterName); + + + fulldestination = strcat(exportbase,'.png'); %name file relative to that directory + imwrite(ExportImage, fulldestination); %save the file there directory + + %BaxterImages + ImageName=fullfile(BaxWellFolder,BaxterName); + imwrite(Nuc, strcat(ImageName,'c01','.tif'),'tif'); + imwrite(cyt, strcat(ImageName,'c02','.tif'),'tif'); + imwrite(GalPals, strcat(ImageName,'c03','.tif'),'tif'); + imwrite(drug, strcat(ImageName,'c04','.tif'),'tif'); + imwrite(RhodBright, strcat(ImageName,'c05','.tif'),'tif'); + + + SegNameNuc=fullfile(BaxSegFolderNuc,BaxterName); + imwrite(NucLabel, strcat(SegNameNuc,'c01','.tif'),'tif'); + + + SegNameCell=fullfile(BaxSegFolderCell,BaxterName); + imwrite(Cyt_WS, strcat(SegNameCell,'c01','.tif'),'tif'); + + + end +end +%% Write Analysis Data to File + +D=[Categories;C]; +WritingHere=strcat(exportdir,'\','Gal8','_',run); + writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data \ No newline at end of file diff --git a/BF_Functions/Old Files/m_Bronk_2022_01_05_bigChanges.m b/BF_Functions/Old Files/m_Bronk_2022_01_05_bigChanges.m new file mode 100644 index 0000000..8484300 --- /dev/null +++ b/BF_Functions/Old Files/m_Bronk_2022_01_05_bigChanges.m @@ -0,0 +1,273 @@ +%% Gal8 Recruitment MATLAB Program + +% Written by Brock Fletcher in the Biomedical Engineering Department at +% Vanderbilt University 2017 - 2022 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/). +%Adapted from work by Kameron V Kilchrist, 2015 - 2018 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/), published in +% Kilchrist, Dimobi, ..., Duvall; "Gal8 +% Visualization of Endosome Disruption Predicts Carrier-mediated Biologic +% Drug Intracellular Bioavailability". + +% University Email: brock.fletcher@vanderbilt.edu +% Permanent Email: brockfletch@gmail.com + +% This code may be reused at will for non-commercial purposes. +% Licensed under a Creative Commons Attribution 4.0 International License. + +% Derivative code should be published at GitHub or FigShare. Derivative +% scientific works should cite _______________ +%% Usage Guide (TL/DR): + %Steps + %Export your fluorescent microscopy as multipage TIFs + %Grab a few example TIFs to test your parameters and put them + %into a folder. (..\Test) + %Create a Second Folder to output to (..\TestExports) + + %Copy the file paths from file explorer and paste them into the + %"workingdir" and "exportdir" + + %Enter your "Calibration" value + %Enter what programs to run on each Channel ("C1=[]") + %Set your thresholds to a starting value + %Run Program + %Check output Images and Excel File + %Change Threshold Values and Re-Run until results are good enough + %If good analysis cannot be reached, edit advanced Values + %If still not good enough, edit actual bulk of code + %Once ready, change "workingdir" to a folder containing all images + %to be analyzed, and "exportdir" to a new, empty folder + + %Run Program and wait. If too hard on your CPU, change "parfor" to + %"for" + + %Review output images and analyze Data. + %Reccomended Analysis Steps: + %Label Each row of Data using VLOOKUP in Excel. + %Explore Data using JMP's Graphbuilder. + %Graph Data in Prism. +%% Image Folder Location +clc, clear; +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-02-BigPRoteinScreen\20211002BigProteinScreen001.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-02-BigPRoteinScreen\2022-01-04_Demo'; +% filetype='tif'; +% listing=dir(strcat(workingdir,'*.TIF')); +% ds=imageDatastore(workingdir); +%% Directory Code +readeromeMeta=reader.getMetadataStore(); +destdirectory1 = fullfile(exportdir,'Overlaid'); +BaxtDirectory= fullfile(exportdir,'Baxter'); +exportbaseBAXTSegNuc=fullfile(BaxtDirectory,'Analysis','Segmentation_Nuc'); +exportbaseBAXTSegCell=fullfile(BaxtDirectory,'Analysis','Segmentation_Cell'); +mkdir(destdirectory1); %create the directory +mkdir(BaxtDirectory); +mkdir(exportbaseBAXTSegNuc); +mkdir(exportbaseBAXTSegCell); +%% +% This will measure the total Gal8 recruited to puncta and count cell +% nuclei or cytosol in each frame. + +% This code assumes you have exported images as multipage TIF files, with +% any of the following stains in each channel: + % nuclear Stain + % Difuse Cytosolic Stain + % Punctate Cytosolic Stain + % Labeled Drug or other exogenous molecule (Cas9, siRNA) + +% Images were exported to 2 page TIF images using Nikon NIS Elements. If +% you use alternate file formats or use separate export files for each +% channel, please edit the code as appropriate. + +% You *must* edit the workingdir and exportdir variables for this code to +% work. +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); +%% Image Thresholding EDIT HERE BASIC +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + +%Input Planes + ImagePlanes=[1,2,3]; + ImageAnalyses={{'nuc'},{'cyt' 'gal'},{'drug'}}; +%Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=1; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.08;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.4; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables +bitConvert=(2^16/2^bitdepthin); +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + % export file names and in the DataCells array. Note: it is a character + % array / string! +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +NumSeries=reader.getSeriesCount(); +NumColors=reader.getEffectiveSizeC(); +NumTimepoint=(reader.getImageCount())/NumColors; +NumImg=NumSeries*NumTimepoint*NumColors; + +C = cell(NumImg,length(Categories)); +%% Analysis Program +for j=0:NumSeries% Number of images in ND2 File + %% Import TIFs + % %The next few lines are specific to 2 page TIF images. Edit from here + % if you have alternate arrangements. +% currfile=strcat(workingdir,listing(j,1).name); + CurrSeries=j; + reader.setSeries(CurrSeries); + fname = reader.getSeries; + Well=num2str(fname,'%05.f'); + + BaxWellFolder=fullfile(BaxtDirectory,Well); + mkdir(BaxWellFolder); + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); + T_Value = reader.getSizeT()-1; + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); + mkdir(BaxSegFolderNuc); + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); + mkdir(BaxSegFolderCell); + + for i=1:T_Value + +% T_Value = reader.getSizeT(); + Timepoint = num2str(i,'%03.f'); + iplane=reader.getIndex(0,0,i); + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())) + Img=[]; + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + n + if contains(CurrPlane,'nuc') + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + x='hell0' + end + if contains(CurrPlane,'cyt') + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + if contains(CurrPlane,'gal') + [GalPals,Gal8Signal,RingMeanInt,Gal8Quant5,Gal8Quant4,Gal8Quant3,Gal8Open,Gal8TH,Gal8Quant2,Puncta,Ring] = Gal8(Img,Gal8TophatDisk,Gal8OpenDisk,Gal8DilateDisk,Gal8MinThreshold,Cyt_WS,CytPos,Gal8OutlineDisk); + end + if contains(CurrPlane,'drug') + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + + +% %% Analyze Images +% %%Nuclear Stain Code +% [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); +% % NucStats=regionprops(Nuc_bw4,'Centroid','Area'); + end +% %%Cytosol Code +% +% +% %WaterShed Segmentation of Individual Cells +% [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); +% % figure; imshow(imoverlay(cyt_eq,Cyt_WS, [.3 .3 1])); +% %Gal8 Puncta Segmentation +% [GalPals,Gal8Signal,RingMeanInt,Gal8Quant5,Gal8Quant4,Gal8Quant3,Gal8Open,Gal8TH,Gal8Quant2,Puncta,Ring] = Gal8(cyt,Gal8TophatDisk,Gal8OpenDisk,Gal8DilateDisk,Gal8MinThreshold,Cyt_WS,CytPos,Gal8OutlineDisk); +% % figure; imshow(imoverlay(cyt_eq,Gal8Quant5, [.3 .3 1])); +% +% %Rhodamine Code +% [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(drug, Rhoda_threshold, cyt_bw4); +% rhodPerim=bwperim(RhodMask); +% +% %All Data Images +% RGBExportImage=cat(3,rhod_eq,cyt_eq,Nuc_eq); +% WSArea = imoverlay(RGBExportImage, Cyt_WS_perim,[0.8500 0.3250 0.0980]); +% ExportImage=imoverlay(WSArea,Gal8Quant5,'m'); +% ExportImage=imoverlay(ExportImage,Nuc_bw4_perim, [0.3010 0.7450 0.9330]); +% ExportImage=imoverlay(ExportImage,rhodPerim, 'y'); +% % figure; imshow(ExportImage); +% % +% +% %% Measure Image Data +% +% % measurement +% areacell=bwarea(Nuc_bw4(:)); +% CellSum=sum(Nuc(Nuc_bw4)); +% areaGal8=sum((vertcat(Puncta.Area))); +% % +% % C(j,:)=[{run},{WellTime},{areacell},{CellSum},{areaGal8},{Gal8Signal},{areaRhod},{Rhodsum},{RhodAvgInCell},{RhodAvgOutCell}]; +% %% Write Images to File +% %overlaid Image +% BaxterName=strcat('w',Well,'t',Timepoint) +% +% exportbase=strcat(destdirectory1,'\',run,'_',BaxterName); +% +% +% fulldestination = strcat(exportbase,'.png'); %name file relative to that directory +% imwrite(ExportImage, fulldestination); %save the file there directory +% +% %BaxterImages +% ImageName=fullfile(BaxWellFolder,BaxterName); +% imwrite(Nuc, strcat(ImageName,'c01','.tif'),'tif'); +% imwrite(cyt, strcat(ImageName,'c02','.tif'),'tif'); +% imwrite(GalPals, strcat(ImageName,'c03','.tif'),'tif'); +% imwrite(drug, strcat(ImageName,'c04','.tif'),'tif'); +% imwrite(RhodBright, strcat(ImageName,'c05','.tif'),'tif'); +% +% +% SegNameNuc=fullfile(BaxSegFolderNuc,BaxterName); +% imwrite(NucLabel, strcat(SegNameNuc,'c01','.tif'),'tif'); +% +% +% SegNameCell=fullfile(BaxSegFolderCell,BaxterName); +% imwrite(Cyt_WS, strcat(SegNameCell,'c01','.tif'),'tif'); +% + + end +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data \ No newline at end of file diff --git a/BF_Functions/Old Files/m_Bronk_2022_01_06_for11_15_assay.m b/BF_Functions/Old Files/m_Bronk_2022_01_06_for11_15_assay.m new file mode 100644 index 0000000..f2c7b99 --- /dev/null +++ b/BF_Functions/Old Files/m_Bronk_2022_01_06_for11_15_assay.m @@ -0,0 +1,278 @@ +%% Gal8 Recruitment MATLAB Program + +% Written by Brock Fletcher in the Biomedical Engineering Department at +% Vanderbilt University 2017 - 2022 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/). +%Adapted from work by Kameron V Kilchrist, 2015 - 2018 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/), published in +% Kilchrist, Dimobi, ..., Duvall; "Gal8 +% Visualization of Endosome Disruption Predicts Carrier-mediated Biologic +% Drug Intracellular Bioavailability". +%hello world + +% University Email: brock.fletcher@vanderbilt.edu +% Permanent Email: brockfletch@gmail.com + +% This code may be reused at will for non-commercial purposes. +% Licensed under a Creative Commons Attribution 4.0 International License. + +% Derivative code should be published at GitHub or FigShare. Derivative +% scientific works should cite _______________ +%% Usage Guide (TL/DR): + %Steps + %Export your fluorescent microscopy as multipage TIFs + %Grab a few example TIFs to test your parameters and put them + %into a folder. (..\Test) + %Create a Second Folder to output to (..\TestExports) + + %Copy the file paths from file explorer and paste them into the + %"workingdir" and "exportdir" + + %Enter your "Calibration" value + %Enter what programs to run on each Channel ("C1=[]") + %Set your thresholds to a starting value + %Run Program + %Check output Images and Excel File + %Change Threshold Values and Re-Run until results are good enough + %If good analysis cannot be reached, edit advanced Values + %If still not good enough, edit actual bulk of code + %Once ready, change "workingdir" to a folder containing all images + %to be analyzed, and "exportdir" to a new, empty folder + + %Run Program and wait. If too hard on your CPU, change "parfor" to + %"for" + + %Review output images and analyze Data. + %Reccomended Analysis Steps: + %Label Each row of Data using VLOOKUP in Excel. + %Explore Data using JMP's Graphbuilder. + %Graph Data in Prism. +%% Image Folder Location +clc, clear; +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-11-15-Ai9CMAX PRotein Screen\ProteinScreen.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-11-15-Ai9CMAX PRotein Screen\Analysis'; +% filetype='tif'; +% listing=dir(strcat(workingdir,'*.TIF')); +% ds=imageDatastore(workingdir); +%% Directory Code +readeromeMeta=reader.getMetadataStore(); +destdirectory1 = fullfile(exportdir,'Overlaid'); +BaxtDirectory= fullfile(exportdir,'Baxter'); +exportbaseBAXTSegNuc=fullfile(BaxtDirectory,'Analysis','Segmentation_Nuc'); +exportbaseBAXTSegCell=fullfile(BaxtDirectory,'Analysis','Segmentation_Cell'); +mkdir(destdirectory1); %create the directory +mkdir(BaxtDirectory); +mkdir(exportbaseBAXTSegNuc); +mkdir(exportbaseBAXTSegCell); +%% +% This will measure the total Gal8 recruited to puncta and count cell +% nuclei or cytosol in each frame. + +% This code assumes you have exported images as multipage TIF files, with +% any of the following stains in each channel: + % nuclear Stain + % Difuse Cytosolic Stain + % Punctate Cytosolic Stain + % Labeled Drug or other exogenous molecule (Cas9, siRNA) + +% Images were exported to 2 page TIF images using Nikon NIS Elements. If +% you use alternate file formats or use separate export files for each +% channel, please edit the code as appropriate. + +% You *must* edit the workingdir and exportdir variables for this code to +% work. +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); +%% Image Thresholding EDIT HERE BASIC +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + +%Input Planes + ImagePlanes=[1,2]; + ImageAnalyses={{'Bax'},{'Bax'}}; +%Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=1; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.08;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.4; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables +bitConvert=(2^16/2^bitdepthin); +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + % export file names and in the DataCells array. Note: it is a character + % array / string! +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +NumSeries=reader.getSeriesCount(); +NumColors=reader.getEffectiveSizeC(); +NumTimepoint=(reader.getImageCount())/NumColors; +NumImg=NumSeries*NumTimepoint*NumColors; + +C = cell(NumImg,length(Categories)); +%% Analysis Program +for j=0:NumSeries-1% Number of images in ND2 File + %% Import TIFs + % %The next few lines are specific to 2 page TIF images. Edit from here + % if you have alternate arrangements. +% currfile=strcat(workingdir,listing(j,1).name); + CurrSeries=j; + reader.setSeries(CurrSeries); + fname = reader.getSeries; + Well=num2str(fname,'%05.f'); + + BaxWellFolder=fullfile(BaxtDirectory,Well); + mkdir(BaxWellFolder); + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); + T_Value = reader.getSizeT()-1; + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); + mkdir(BaxSegFolderNuc); + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); + mkdir(BaxSegFolderCell); + + for i=1:T_Value + +% T_Value = reader.getSizeT(); + Timepoint = num2str(i,'%03.f'); + iplane=reader.getIndex(0,0,i); + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); + Img=[]; + %overlaid Image + BaxterName=strcat('w',Well,'t',Timepoint) ; + exportbase=strcat(destdirectory1,'\',run,'_',BaxterName); + fulldestination = strcat(exportbase,'.png'); + ImageName=fullfile(BaxWellFolder,BaxterName); + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + + if contains(CurrPlane,'Bax') + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + end + if contains(CurrPlane,'nuc') + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + x='hell0' + end + if contains(CurrPlane,'cyt') + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + if contains(CurrPlane,'gal') + [GalPals,Gal8Signal,RingMeanInt,Gal8Quant5,Gal8Quant4,Gal8Quant3,Gal8Open,Gal8TH,Gal8Quant2,Puncta,Ring] = Gal8(Img,Gal8TophatDisk,Gal8OpenDisk,Gal8DilateDisk,Gal8MinThreshold,Cyt_WS,CytPos,Gal8OutlineDisk); + end + if contains(CurrPlane,'drug') + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + end + %% Test +% %% Analyze Images +% %%Nuclear Stain Code +% [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); +% % NucStats=regionprops(Nuc_bw4,'Centroid','Area'); + +% %%Cytosol Code +% +% +% %WaterShed Segmentation of Individual Cells +% [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); +% % figure; imshow(imoverlay(cyt_eq,Cyt_WS, [.3 .3 1])); +% %Gal8 Puncta Segmentation +% [GalPals,Gal8Signal,RingMeanInt,Gal8Quant5,Gal8Quant4,Gal8Quant3,Gal8Open,Gal8TH,Gal8Quant2,Puncta,Ring] = Gal8(cyt,Gal8TophatDisk,Gal8OpenDisk,Gal8DilateDisk,Gal8MinThreshold,Cyt_WS,CytPos,Gal8OutlineDisk); +% % figure; imshow(imoverlay(cyt_eq,Gal8Quant5, [.3 .3 1])); +% +% %Rhodamine Code +% [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(drug, Rhoda_threshold, cyt_bw4); +% rhodPerim=bwperim(RhodMask); +% +% %All Data Images +% RGBExportImage=cat(3,rhod_eq,cyt_eq,Nuc_eq); +% WSArea = imoverlay(RGBExportImage, Cyt_WS_perim,[0.8500 0.3250 0.0980]); +% ExportImage=imoverlay(WSArea,Gal8Quant5,'m'); +% ExportImage=imoverlay(ExportImage,Nuc_bw4_perim, [0.3010 0.7450 0.9330]); +% ExportImage=imoverlay(ExportImage,rhodPerim, 'y'); +% % figure; imshow(ExportImage); +% % +% +% %% Measure Image Data +% +% % measurement +% areacell=bwarea(Nuc_bw4(:)); +% CellSum=sum(Nuc(Nuc_bw4)); +% areaGal8=sum((vertcat(Puncta.Area))); +% % +% % C(j,:)=[{run},{WellTime},{areacell},{CellSum},{areaGal8},{Gal8Signal},{areaRhod},{Rhodsum},{RhodAvgInCell},{RhodAvgOutCell}]; + %% Write Images to File + %name file relative to that directory +% imwrite(ExportImage, fulldestination); %save the file there directory + + %BaxterImages + + +% imwrite(GalPals, strcat(ImageName,'c03','.tif'),'tif'); +% imwrite(drug, strcat(ImageName,'c04','.tif'),'tif'); +% imwrite(RhodBright, strcat(ImageName,'c05','.tif'),'tif'); +% +% +% SegNameNuc=fullfile(BaxSegFolderNuc,BaxterName); +% imwrite(NucLabel, strcat(SegNameNuc,'c01','.tif'),'tif'); +% +% +% SegNameCell=fullfile(BaxSegFolderCell,BaxterName); +% imwrite(Cyt_WS, strcat(SegNameCell,'c01','.tif'),'tif'); +% + + end +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data \ No newline at end of file diff --git a/BF_Functions/Old Files/m_Bronk_2022_02_04_for2021_06_29_assay.m b/BF_Functions/Old Files/m_Bronk_2022_02_04_for2021_06_29_assay.m new file mode 100644 index 0000000..2dc0757 --- /dev/null +++ b/BF_Functions/Old Files/m_Bronk_2022_02_04_for2021_06_29_assay.m @@ -0,0 +1,325 @@ +%% Gal8 Recruitment MATLAB Program + +% Written by Brock Fletcher in the Biomedical Engineering Department at +% Vanderbilt University 2017 - 2022 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/). +%Adapted from work by Kameron V Kilchrist, 2015 - 2018 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/), published in +% Kilchrist, Dimobi, ..., Duvall; "Gal8 +% Visualization of Endosome Disruption Predicts Carrier-mediated Biologic +% Drug Intracellular Bioavailability". +%hello world + +% University Email: brock.fletcher@vanderbilt.edu +% Permanent Email: brockfletch@gmail.com + +% This code may be reused at will for non-commercial purposes. +% Licensed under a Creative Commons Attribution 4.0 International License. + +% Derivative code should be published at GitHub or FigShare. Derivative +% scientific works should cite _______________ +%% Usage Guide (TL/DR): + %Steps + %Export your fluorescent microscopy as multipage TIFs + %Grab a few example TIFs to test your parameters and put them + %into a folder. (..\Test) + %Create a Second Folder to output to (..\TestExports) + + %Copy the file paths from file explorer and paste them into the + %"workingdir" and "exportdir" + + %Enter your "Calibration" value + %Enter what programs to run on each Channel ("C1=[]") + %Set your thresholds to a starting value + %Run Program + %Check output Images and Excel File + %Change Threshold Values and Re-Run until results are good enough + %If good analysis cannot be reached, edit advanced Values + %If still not good enough, edit actual bulk of code + %Once ready, change "workingdir" to a folder containing all images + %to be analyzed, and "exportdir" to a new, empty folder + + %Run Program and wait. If too hard on your CPU, change "parfor" to + %"for" + + %Review output images and analyze Data. + %Reccomended Analysis Steps: + %Label Each row of Data using VLOOKUP in Excel. + %Explore Data using JMP's Graphbuilder. + %Graph Data in Prism. +%% Image Folder Location +clc, clear all, close all +string() +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; +% filetype='tif'; +% listing=dir(strcat(workingdir,'*.TIF')); +% ds=imageDatastore(workingdir); +%% Directory Code +readeromeMeta=reader.getMetadataStore(); +destdirectory1 = fullfile(exportdir,'Overlaid'); +BaxtDirectory= fullfile(exportdir,'Baxter'); +exportbaseBAXTSegNuc=fullfile(BaxtDirectory,'Analysis','Segmentation_Nuc'); +exportbaseBAXTSegCell=fullfile(BaxtDirectory,'Analysis','Segmentation_Cell'); +mkdir(destdirectory1); %create the directory +mkdir(BaxtDirectory); +mkdir(exportbaseBAXTSegNuc); +mkdir(exportbaseBAXTSegCell); +%% +% This will measure the total Gal8 recruited to puncta and count cell +% nuclei or cytosol in each frame. + +% This code assumes you have exported images as multipage TIF files, with +% any of the following stains in each channel: + % nuclear Stain + % Difuse Cytosolic Stain + % Punctate Cytosolic Stain + % Labeled Drug or other exogenous molecule (Cas9, siRNA) + +% Images were exported to 2 page TIF images using Nikon NIS Elements. If +% you use alternate file formats or use separate export files for each +% channel, please edit the code as appropriate. + +% You *must* edit the workingdir and exportdir variables for this code to +% work. +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); +%% Image Thresholding EDIT HERE BASIC +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze #Integrate with + ImageAnalyses={{'Bax'},{},{'Bax'}}; %Which Image analysis/functions to call. NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=1;%Logical Yes or no to make overlay image + % Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % Add selection for data of interest from each analysis + % +%Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables +bitConvert=(2^16/2^bitdepthin); +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + % export file names and in the DataCells array. Note: it is a character + % array / string! + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +NumSeries=reader.getSeriesCount(); +NumColors=reader.getEffectiveSizeC(); +NumTimepoint=(reader.getImageCount())/NumColors; +NumImg=NumSeries*NumTimepoint*NumColors; + +C = cell(NumImg,length(Categories)); +%% Analysis Program +%j=0:NumSeries-1% + +for j=0:NumSeries-1% Number of images in ND2 File + %% Import TIFs + % %The next few lines are specific to 2 page TIF images. Edit from here + % if you have alternate arrangements. +% currfile=strcat(workingdir,listing(j,1).name); + CurrSeries=j; + reader.setSeries(CurrSeries); + fname = reader.getSeries; + Well=num2str(fname,'%05.f'); + + BaxWellFolder=fullfile(BaxtDirectory,Well); + mkdir(BaxWellFolder); + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); + T_Value = reader.getSizeT()-1; + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); + mkdir(BaxSegFolderNuc); + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); + mkdir(BaxSegFolderCell); + + for i=0:T_Value + +% T_Value = reader.getSizeT(); + Timepoint = num2str(i,'%03.f'); + iplane=reader.getIndex(0,0,i); + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); + Img=[]; + %overlaid Image + BaxterName=strcat('w',Well,'t',Timepoint) ; + exportbase=strcat(destdirectory1,'\',run,'_',BaxterName); + fulldestination = strcat(exportbase,'.png'); + ImageName=fullfile(BaxWellFolder,BaxterName); + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,RingMeanInt,Gal8Quant5,Gal8Quant4,Gal8Quant3,Gal8Open,Gal8TH,Gal8Quant2,Puncta,Ring] = Gal8(Img,Gal8TophatDisk,Gal8OpenDisk,Gal8DilateDisk,Gal8MinThreshold,CytPos,Gal8OutlineDisk); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end +% UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH COLOR +% RGBExportImage=imoverlay(RGBExportImage,Gal8Quant5,'m'); +% ExportImage=imoverlay(ExportImage,Nuc_bw4_perim, [0.3010 0.7450 0.9330]); +% ExportImage=imoverlay(ExportImage,rhodPerim, 'y'); +% +% + imshow(RGBExportImage) + end + %% Test + + %All Data Images + +% WSArea = imoverlay(RGBExportImage, Cyt_WS_perim,[0.8500 0.3250 0.0980]); +% ExportImage=imoverlay(WSArea,Gal8Quant5,'m'); +% ExportImage=imoverlay(ExportImage,Nuc_bw4_perim, [0.3010 0.7450 0.9330]); +% ExportImage=imoverlay(ExportImage,rhodPerim, 'y'); + % figure; imshow(ExportImage); + % + + %% Measure Image Data + + % measurement +% areacell=bwarea(Nuc_bw4(:)); +% CellSum=sum(Nuc(Nuc_bw4)); +% areaGal8=sum((vertcat(Puncta.Area))); + % + % C(j,:)=[{run},{WellTime},{areacell},{CellSum},{areaGal8},{Gal8Signal},{areaRhod},{Rhodsum},{RhodAvgInCell},{RhodAvgOutCell}]; + % Write Images to File +% name file relative to that directory +% imwrite(ExportImage, fulldestination); %save the file there directory +% +% BaxterImages + + + +% imwrite(drug, strcat(ImageName,'c04','.tif'),'tif'); +% imwrite(RhodBright, strcat(ImageName,'c05','.tif'),'tif'); +% +% +% SegNameNuc=fullfile(BaxSegFolderNuc,BaxterName); +% imwrite(NucLabel, strcat(SegNameNuc,'c01','.tif'),'tif'); +% +% +% SegNameCell=fullfile(BaxSegFolderCell,BaxterName); +% imwrite(Cyt_WS, strcat(SegNameCell,'c01','.tif'),'tif'); +% % + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/Old Files/m_Bronk_2022_02_07_for2021_06_29_assay.m b/BF_Functions/Old Files/m_Bronk_2022_02_07_for2021_06_29_assay.m new file mode 100644 index 0000000..bf025f0 --- /dev/null +++ b/BF_Functions/Old Files/m_Bronk_2022_02_07_for2021_06_29_assay.m @@ -0,0 +1,309 @@ +%% Gal8 Recruitment MATLAB Program + +% Written by Brock Fletcher in the Biomedical Engineering Department at +% Vanderbilt University 2017 - 2022 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/). +%Adapted from work by Kameron V Kilchrist, 2015 - 2018 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/), published in +% Kilchrist, Dimobi, ..., Duvall; "Gal8 +% Visualization of Endosome Disruption Predicts Carrier-mediated Biologic +% Drug Intracellular Bioavailability". +%hello world + +% University Email: brock.fletcher@vanderbilt.edu +% Permanent Email: brockfletch@gmail.com + +% This code may be reused at will for non-commercial purposes. +% Licensed under a Creative Commons Attribution 4.0 International License. + +% Derivative code should be published at GitHub or FigShare. Derivative +% scientific works should cite _______________ +%% Usage Guide (TL/DR): + %Steps + %Export your fluorescent microscopy as multipage TIFs + %Grab a few example TIFs to test your parameters and put them + %into a folder. (..\Test) + %Create a Second Folder to output to (..\TestExports) + + %Copy the file paths from file explorer and paste them into the + %"workingdir" and "exportdir" + + %Enter your "Calibration" value + %Enter what programs to run on each Channel ("C1=[]") + %Set your thresholds to a starting value + %Run Program + %Check output Images and Excel File + %Change Threshold Values and Re-Run until results are good enough + %If good analysis cannot be reached, edit advanced Values + %If still not good enough, edit actual bulk of code + %Once ready, change "workingdir" to a folder containing all images + %to be analyzed, and "exportdir" to a new, empty folder + + %Run Program and wait. If too hard on your CPU, change "parfor" to + %"for" + + %Review output images and analyze Data. + %Reccomended Analysis Steps: + %Label Each row of Data using VLOOKUP in Excel. + %Explore Data using JMP's Graphbuilder. + %Graph Data in Prism. +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('/Users/sarahreilly/Desktop/PolyScreen004.nd2'); +exportdir='/Users/sarahreilly/Desktop/TestExport'; +% filetype='tif'; +% listing=dir(strcat(workingdir,'*.TIF')); +% ds=imageDatastore(workingdir); +%% Directory Code +readeromeMeta=reader.getMetadataStore(); +destdirectory1 = fullfile(exportdir,'Overlaid'); +BaxtDirectory= fullfile(exportdir,'Baxter'); +exportbaseBAXTSegNuc=fullfile(BaxtDirectory,'Analysis','Segmentation_Nuc'); +exportbaseBAXTSegCell=fullfile(BaxtDirectory,'Analysis','Segmentation_Cell'); +mkdir(destdirectory1); %create the directory +mkdir(BaxtDirectory); +mkdir(exportbaseBAXTSegNuc); +mkdir(exportbaseBAXTSegCell); +%% +% This will measure the total Gal8 recruited to puncta and count cell +% nuclei or cytosol in each frame. + +% This code assumes you have exported images as multipage TIF files, with +% any of the following stains in each channel: + % nuclear Stain + % Difuse Cytosolic Stain + % Punctate Cytosolic Stain + % Labeled Drug or other exogenous molecule (Cas9, siRNA) + +% Images were exported to 2 page TIF images using Nikon NIS Elements. If +% you use alternate file formats or use separate export files for each +% channel, please edit the code as appropriate. + +% You *must* edit the workingdir and exportdir variables for this code to +% work. +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); +%% Image Thresholding EDIT HERE BASIC +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + +%Input Planes + ImagePlanes=[1,3]; + ImageAnalyses={{'Bax'},{},{'Bax'}}; + MakeOverlayImage=1; +%Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables +bitConvert=(2^16/2^bitdepthin); +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + % export file names and in the DataCells array. Note: it is a character + % array / string! +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +NumSeries=reader.getSeriesCount(); +NumColors=reader.getEffectiveSizeC(); +NumTimepoint=(reader.getImageCount())/NumColors; +NumImg=NumSeries*NumTimepoint*NumColors; + +C = cell(NumImg,length(Categories)); +%% Analysis Program +%j=0:NumSeries-1% +for j=0:NumSeries - 1% Number of images in ND2 File + place='series for loop' + + %% Import TIFs + % %The next few lines are specific to 2 page TIF images. Edit from here + % if you have alternate arrangements. +% currfile=strcat(workingdir,listing(j,1).name); + CurrSeries=j; + reader.setSeries(CurrSeries); + fname = reader.getSeries; + Well=num2str(fname,'%05.f'); + + BaxWellFolder=fullfile(BaxtDirectory,Well); + mkdir(BaxWellFolder); + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); + T_Value = reader.getSizeT()-1; + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); + mkdir(BaxSegFolderNuc); + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); + mkdir(BaxSegFolderCell); + + for i=0:T_Value + place = 'inside time for loop' + +% T_Value = reader.getSizeT(); + Timepoint = num2str(i,'%03.f'); + iplane=reader.getIndex(0,0,i); + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); + Img=[]; + %overlaid Image + BaxterName=strcat('w',Well,'t',Timepoint) ; + exportbase=strcat(destdirectory1,'\',run,'_',BaxterName); + fulldestination = strcat(exportbase,'.png'); + ImageName=fullfile(BaxWellFolder,BaxterName); + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + test='Hello' + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,RingMeanInt,Gal8Quant5,Gal8Quant4,Gal8Quant3,Gal8Open,Gal8TH,Gal8Quant2,Puncta,Ring] = Gal8(Img,Gal8TophatDisk,Gal8OpenDisk,Gal8DilateDisk,Gal8MinThreshold,CytPos,Gal8OutlineDisk); + + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end +% RGBExportImage=imoverlay(RGBExportImage,Gal8Quant5,'m'); +% ExportImage=imoverlay(ExportImage,Nuc_bw4_perim, [0.3010 0.7450 0.9330]); +% ExportImage=imoverlay(ExportImage,rhodPerim, 'y'); +% +% + imshow(RGBExportImage) + end + %% Test + + %All Data Images + +% WSArea = imoverlay(RGBExportImage, Cyt_WS_perim,[0.8500 0.3250 0.0980]); +% ExportImage=imoverlay(WSArea,Gal8Quant5,'m'); +% ExportImage=imoverlay(ExportImage,Nuc_bw4_perim, [0.3010 0.7450 0.9330]); +% ExportImage=imoverlay(ExportImage,rhodPerim, 'y'); + % figure; imshow(ExportImage); + % + + %% Measure Image Data + + % measurement +% areacell=bwarea(Nuc_bw4(:)); +% CellSum=sum(Nuc(Nuc_bw4)); +% areaGal8=sum((vertcat(Puncta.Area))); + % + % C(j,:)=[{run},{WellTime},{areacell},{CellSum},{areaGal8},{Gal8Signal},{areaRhod},{Rhodsum},{RhodAvgInCell},{RhodAvgOutCell}]; + % Write Images to File +% name file relative to that directory +% imwrite(ExportImage, fulldestination); %save the file there directory +% +% BaxterImages + + + +% imwrite(drug, strcat(ImageName,'c04','.tif'),'tif'); +% imwrite(RhodBright, strcat(ImageName,'c05','.tif'),'tif'); +% +% +% SegNameNuc=fullfile(BaxSegFolderNuc,BaxterName); +% imwrite(NucLabel, strcat(SegNameNuc,'c01','.tif'),'tif'); +% +% +% SegNameCell=fullfile(BaxSegFolderCell,BaxterName); +% imwrite(Cyt_WS, strcat(SegNameCell,'c01','.tif'),'tif'); +% % + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data \ No newline at end of file diff --git a/BF_Functions/Rhoda.m b/BF_Functions/Rhoda.m new file mode 100644 index 0000000..fde251b --- /dev/null +++ b/BF_Functions/Rhoda.m @@ -0,0 +1,25 @@ + %%Rhodamine Code + +function [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(drug, Rhoda_threshold, cyt_bw4) + + rhod_eq =imadjust(drug,[0 0.4],[]); + + Rhoda_threshold = Rhoda_threshold *intmax(class(drug)); + + rhodaweiner=wiener2(drug); + RhodMask=rhodaweiner>Rhoda_threshold; + areaRhod = sum(RhodMask,'all'); + + rhoda_in_cell = drug(cyt_bw4); + rhoda_out_cell = drug(cyt_bw4 == 0); + + cell_area = sum(sum(cyt_bw4)); + not_cell_area = size(cyt_bw4,1) * size(cyt_bw4, 2) - cell_area; + + Rhodsum = sum(rhod_eq(RhodMask)); + RhodBright=drug; + RhodBright(~RhodMask)=0; + RhodAvgInCell = sum(rhoda_in_cell) / cell_area; + RhodAvgOutCell = sum(rhoda_out_cell) / not_cell_area; + + \ No newline at end of file diff --git a/BF_Functions/RunLog/backup_2022-02-09-02-23-12.m b/BF_Functions/RunLog/backup_2022-02-09-02-23-12.m new file mode 100644 index 0000000..61fb464 --- /dev/null +++ b/BF_Functions/RunLog/backup_2022-02-09-02-23-12.m @@ -0,0 +1,283 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')]; +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +Gitdir=fullfile(pwd,'RunLog\'); +GitLog=sprintf('%sbackup_%s.m',Gitdir,Version); +% GitLog=sprintf('%sbackup_%s.m',LogFolder,Version); +% mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,GitLog) +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/RunLog/backup_2022-02-09-02-23-14.m b/BF_Functions/RunLog/backup_2022-02-09-02-23-14.m new file mode 100644 index 0000000..61fb464 --- /dev/null +++ b/BF_Functions/RunLog/backup_2022-02-09-02-23-14.m @@ -0,0 +1,283 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')]; +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +Gitdir=fullfile(pwd,'RunLog\'); +GitLog=sprintf('%sbackup_%s.m',Gitdir,Version); +% GitLog=sprintf('%sbackup_%s.m',LogFolder,Version); +% mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,GitLog) +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/RunLog/backup_2022-02-09-02-23-19.m b/BF_Functions/RunLog/backup_2022-02-09-02-23-19.m new file mode 100644 index 0000000..61fb464 --- /dev/null +++ b/BF_Functions/RunLog/backup_2022-02-09-02-23-19.m @@ -0,0 +1,283 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')]; +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +Gitdir=fullfile(pwd,'RunLog\'); +GitLog=sprintf('%sbackup_%s.m',Gitdir,Version); +% GitLog=sprintf('%sbackup_%s.m',LogFolder,Version); +% mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,GitLog) +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/RunLog/backup_2022-02-09-02-25-04.m b/BF_Functions/RunLog/backup_2022-02-09-02-25-04.m new file mode 100644 index 0000000..52e549a --- /dev/null +++ b/BF_Functions/RunLog/backup_2022-02-09-02-25-04.m @@ -0,0 +1,283 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')] +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +Gitdir=fullfile(pwd,'RunLog\'); +GitLog=sprintf('%sbackup_%s.m',Gitdir,Version); +% GitLog=sprintf('%sbackup_%s.m',LogFolder,Version); +% mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,GitLog) +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/RunLog/backup_2022-02-09-02-25-31.m b/BF_Functions/RunLog/backup_2022-02-09-02-25-31.m new file mode 100644 index 0000000..52e549a --- /dev/null +++ b/BF_Functions/RunLog/backup_2022-02-09-02-25-31.m @@ -0,0 +1,283 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')] +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +Gitdir=fullfile(pwd,'RunLog\'); +GitLog=sprintf('%sbackup_%s.m',Gitdir,Version); +% GitLog=sprintf('%sbackup_%s.m',LogFolder,Version); +% mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,GitLog) +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/RunLog/backup_2022-02-09-02-26-32.m b/BF_Functions/RunLog/backup_2022-02-09-02-26-32.m new file mode 100644 index 0000000..52e549a --- /dev/null +++ b/BF_Functions/RunLog/backup_2022-02-09-02-26-32.m @@ -0,0 +1,283 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')] +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +Gitdir=fullfile(pwd,'RunLog\'); +GitLog=sprintf('%sbackup_%s.m',Gitdir,Version); +% GitLog=sprintf('%sbackup_%s.m',LogFolder,Version); +% mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,GitLog) +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/RunLog/backup_2022-02-09-02-26-43.m b/BF_Functions/RunLog/backup_2022-02-09-02-26-43.m new file mode 100644 index 0000000..52e549a --- /dev/null +++ b/BF_Functions/RunLog/backup_2022-02-09-02-26-43.m @@ -0,0 +1,283 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')] +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +Gitdir=fullfile(pwd,'RunLog\'); +GitLog=sprintf('%sbackup_%s.m',Gitdir,Version); +% GitLog=sprintf('%sbackup_%s.m',LogFolder,Version); +% mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,GitLog) +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/RunLog/backup_2022-02-09-02-27-51.m b/BF_Functions/RunLog/backup_2022-02-09-02-27-51.m new file mode 100644 index 0000000..52e549a --- /dev/null +++ b/BF_Functions/RunLog/backup_2022-02-09-02-27-51.m @@ -0,0 +1,283 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')] +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +Gitdir=fullfile(pwd,'RunLog\'); +GitLog=sprintf('%sbackup_%s.m',Gitdir,Version); +% GitLog=sprintf('%sbackup_%s.m',LogFolder,Version); +% mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,GitLog) +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/RunLog/backup_LiveEditorEvaluationHelperESectionEval2ef0f50d.m2022-02-09-02-24-29backup_ b/BF_Functions/RunLog/backup_LiveEditorEvaluationHelperESectionEval2ef0f50d.m2022-02-09-02-24-29backup_ new file mode 100644 index 0000000..93dc60f --- /dev/null +++ b/BF_Functions/RunLog/backup_LiveEditorEvaluationHelperESectionEval2ef0f50d.m2022-02-09-02-24-29backup_ @@ -0,0 +1,283 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')]; +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +Gitdir=fullfile(pwd,'RunLog\'); +GitLog=sprintf('%sbackup_%s.m',Gitdir,mfilename,Version); +% GitLog=sprintf('%sbackup_%s.m',LogFolder,Version); +% mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,GitLog) +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/RunLog/m_2022_02_08_Commented_byBF_forMichaelSarah.m b/BF_Functions/RunLog/m_2022_02_08_Commented_byBF_forMichaelSarah.m new file mode 100644 index 0000000..045a8c9 --- /dev/null +++ b/BF_Functions/RunLog/m_2022_02_08_Commented_byBF_forMichaelSarah.m @@ -0,0 +1,281 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')]; +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +RunLog=fullfile(pwd,'RunLog'); +mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,RunLog); +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/m_2022_02_08_Commented_byBF_forMichaelSarah.m b/BF_Functions/m_2022_02_08_Commented_byBF_forMichaelSarah.m new file mode 100644 index 0000000..b574c8a --- /dev/null +++ b/BF_Functions/m_2022_02_08_Commented_byBF_forMichaelSarah.m @@ -0,0 +1,283 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')]; +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +Gitdir=fullfile(pwd,'RunLog\'); +GitLog=sprintf('%sbackup_%s.m',Gitdir,Version); +% GitLog=sprintf('%sbackup_%s.m',LogFolder,Version); +% mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,GitLog) +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +% sr1=strel('square',1); +% se1=strel('disk',1); +% sr2=strel('square',2); +% se2=strel('disk',2); +% se3=strel('disk',3); +% sr3=strel('square',3); +% se4=strel('disk',4); +% se5=strel('disk',5); +% se6=strel('disk',6); +% se7=strel('disk',7); +% se8=strel('disk',8); +% se9=strel('disk',9); +% se10=strel('disk',10); +% se12=strel('disk',12); +% se20=strel('disk',20); +% se25=strel('disk',25); +% se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Drugamine + Drug_threshold = 0.01; %Number 0-1, removes Drugmine signal dimmer than threshold +% Drug_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaDrug'},{'Drugsum'},{'DrugAvgInCell'},{'DrugAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [DrugBright,areaDrug, Drugsum, DrugAvgInCell, DrugAvgOutCell,Drug_eq,DrugMask] = Drug(Img, Drug_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Functions/m_2022_02_08_Commented_byBF_forMichaelSarah/RunLog/m_2022_02_08_Commented_byBF_forMichaelSarah.m b/BF_Functions/m_2022_02_08_Commented_byBF_forMichaelSarah/RunLog/m_2022_02_08_Commented_byBF_forMichaelSarah.m new file mode 100644 index 0000000..ea10e3a --- /dev/null +++ b/BF_Functions/m_2022_02_08_Commented_byBF_forMichaelSarah/RunLog/m_2022_02_08_Commented_byBF_forMichaelSarah.m @@ -0,0 +1,281 @@ +%% Gal8 Recruitment MATLAB Program +%% Image Folder Location +clc, clear all, close all +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\PolyScreen004.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-06-29-PolymerScreen\2022_02_04_SarahHelp'; + +%% Directory Code + +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + +readeromeMeta=reader.getMetadataStore(); +RunDirectory= fullfile(exportdir,run); +mkdir(RunDirectory); + +destdirectory1 = fullfile(RunDirectory,'Overlaid'); +mkdir(destdirectory1); + +BaxtDirectory = fullfile(RunDirectory,'Baxter'); +mkdir(BaxtDirectory); + +LogDirectory = fullfile(RunDirectory,'Log'); +mkdir(LogDirectory); + +SegDirectory = fullfile(RunDirectory,'Segmentation'); +mkdir(SegDirectory); + +exportbaseBAXTSegNuc=fullfile(SegDirectory,'Segmentation_Nuc'); +mkdir(exportbaseBAXTSegNuc); + +exportbaseBAXTSegCell=fullfile(SegDirectory,'Segmentation_Cell'); +mkdir(exportbaseBAXTSegCell); + %##Need to universalize the Segmentation stuff for whatever the + %GUI needs, so that it can be arbitrarily named and assigned. + %Might be a good idea to write this all into a function + +%%Log Data +Version=run; +LogFile=strcat(LogDirectory,'\'); +FileNameAndLocation=[mfilename('fullpath')]; +newbackup=sprintf('%sbackup_%s.m',LogFile,Version); +RunLog=fullfile(FileNameAndLocation,'RunLog'); +mkdir(RunLog); +currentfile=strcat(FileNameAndLocation, '.m'); +copyfile(currentfile,newbackup); +copyfile(currentfile,RunLog); +% A = exist(newbackup,'file'); +% if (A~=0) +% warning('Backup already exists for the current version') +% end +%##This may not be the best way to be logging the data and directory, since +%it's in a new folder every time, but we can figure htis otu later. Also +%might be possible to write this all into a function + + +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +%## Can probably delete this section after checking on all of the functions +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); + + %##Probabloy possible and better to integrate all of this into + %a single function for the "round" section and then have ll of + %the indivual disks just created in each function based on the + %relative pixel size with a cell size correction +%% Analysis Functions +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + bitConvert=(2^16/2^bitdepthin); %This assures that whatever the bit depth of the input image, the analyzed images are all 16 bit. +%Input Planes + ImagePlanes=[1,2,3]; %Which image Planes to analyze ##Integrate with GUI + ImageAnalyses={{'cytgal'},{},{}}; %Which Image analysis/functions to call. ##NEed to solve problem of secondary analyses like watershed of Nuc and Cytosol or gal8 and cytosol + MakeOverlayImage=0;%Logical Yes or no to make overlay image #Integrate with GUI + % ##Add selection for what to overlay on the overlay image, for example, + % showing the cytosol perimeter analysis or Not + + % ##Add selection for data of interest from each analysis, i.e. what to + % export from each function + % + +%% Image Thresholding EDIT HERE BASIC + %##Need to make these into GUI, and make universal so that as we call + %each function we can set the function parameters in the GUI. I believe + %Baxter has a very good solution for doing this + %Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=0; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.2;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.01; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables + +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +%##Categories are manually typed out here, but it should integrate so that +%these are auto-populated or selectable within the GUI, might have to get +%clever for this to work + +NumSeries=reader.getSeriesCount(); %The number of different wells you imaged +NumColors=reader.getEffectiveSizeC(); %The number of colors of each well you imaged +NumTimepoint=(reader.getImageCount())/NumColors; %The number of timepoints you imaged +NumImg=NumSeries*NumTimepoint*NumColors; %The total number of images, combining everything + +C = cell(NumImg,length(Categories)); +%##C is something that will probably have be edited to allow data output +%from this scale of the analysis. Don't even know if it's correct right now +%or even neccessary at all +%% Analysis Program +for j=0:NumSeries-1% Number of wells in ND2 File + % Set Current Well and other important values + %##Would be very useful to figure out how to make this work as a parfor + %loop, but might be quite difficult + CurrSeries=j; %The current well that we're looking at + reader.setSeries(CurrSeries); %##uses BioFormats function, can be swapped with something else (i forget what) if it's buggy with the GUI + fname = reader.getSeries; %gets the name of the series using BioFormats + Well=num2str(fname,'%05.f'); %Formats the well name for up to 5 decimal places of different wells, could increase but 5 already feels like overkill + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); %May be useful someday, but not needed here + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); %May be useful someday, but not needed yet. Get's the position of the actual image. Useful for checking stuff + T_Value = reader.getSizeT()-1; %Very important, the timepoints of the images. Returns the total number of timepoints, the -1 is important. + + %CreateFolders for Baxter to read data + %##Important work: generalize this folder creation and put into GUI, so + %that whatever segmentations the user creates can be saved for baxter + %analysis. The "BaxSegFolderCell" is probably the most important and + %default, but this should be customizable + + BaxWellFolder=fullfile(BaxtDirectory,Well); %Creates a filename that's compatible with both PC and Mac (##Check and see if any of the strcat functions need to be replaced with fullfile functions) + mkdir(BaxWellFolder); %makes a new folder on your hard drive for the baxter stuff + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderNuc); %makes a new folder on your hard drive for the nuclear segmentaiton for Baxter + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); %Creates a filename that's compatible with both PC and Mac + mkdir(BaxSegFolderCell); + + for i=0:T_Value %For all of the time points in the series, should start at zero if T_Value has -1 built in, which it should + %Set up the particular timepoint image + Timepoint = num2str(i,'%03.f'); %Creates a string so taht the BioFormats can read it + iplane=reader.getIndex(0,0,i); %Gets the particular timepoint image, so now we're in a particular well at a particular timepoint + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())); %The time that the well image was taken. Very useful for sanity checks + Img=[];%Creates an empty array for the image ##Check and see if this is necessary or if there's a more efficient way of doing this. + + BaxterName=strcat('w',Well,'t',Timepoint) ; %Very important, creates a name in the format that Baxter Algorithms prefers + + ImageName=fullfile(BaxWellFolder,BaxterName); %Creates a name for each particular image + + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + CurrPlane=ImageAnalyses{n}; + + %Primary Analyses + if any(contains(CurrPlane,'Bax')) + my_field = strcat('c',num2str(n,'%02.f')); + imwrite(Img, strcat(ImageName,my_field,'.tif'),'tif'); + + end + if any(contains(CurrPlane,'nuc')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + + end + + if any(contains(CurrPlane,'cyt')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + end + + if any(contains(CurrPlane,'drug')) + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(Img, Rhoda_threshold, cyt_bw4); + end + + %Secondary Analyses + if any(contains(CurrPlane,'cytgal')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [GalPals,Gal8Signal,Gal8Quant5] = Gal8(Img,Gal8MinThreshold,CytPos,MiPerPix); + end + + if any(contains(CurrPlane,'nucWS')) + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + end + if any(contains(CurrPlane,'cytWS')) + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + end + + %Make RGB Image + + if any(contains(CurrPlane,'blue')) + blue=imadjust(Img); +% else +% blue=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'green')) + green=imadjust(Img); +% else +% green=zeros(size(Img),'like',Img); + end + if any(contains(CurrPlane,'red')) + red=imadjust(Img); +% else +% red=zeros(size(Img),'like',Img); + end + + end + + %Make Overlay Image + %#UNIVERSALIZE THIS CODE AND MAKE IT SO THAT WE FROM THE GUI + %CALL WHICH PERIMETER OF WHICH MASK WE WANT TO OVERLAY IN WHICH + %COLOR + + if logical(MakeOverlayImage) + if ~exist('blue','var') + blue=zeros(size(Img),'like',Img); + end + if ~exist('green','var') + green=zeros(size(Img),'like',Img); + end + if ~exist('red','var') + red=zeros(size(Img),'like',Img); + end + RGBExportImage=cat(3,red,green,blue); + if exist('cyt_bw4_perim','var') + RGBExportImage=imoverlay(RGBExportImage,cyt_bw4_perim,[0.8500 0.3250 0.0980]); + end + imshow(RGBExportImage) + end + %% Measure Image Data + %##Write Code here that uses parameters set in the GUI to take + %all of the data we'd be interested in analyzing. Will probably + %need to get clever with the analysis function output names in + %order to make it all work with an arbitrary number of analyses + %and image planes + + end + +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data +% +%% add code that writes the text of this code with the timestamp to a record every time it is run \ No newline at end of file diff --git a/BF_Gal8_Settings.csv b/BF_Gal8_Settings.csv new file mode 100644 index 0000000..c20bdcc --- /dev/null +++ b/BF_Gal8_Settings.csv @@ -0,0 +1,84 @@ +setting,A20,F08 +numZ,1,1 +bits,16,16 +minWellR,NaN,NaN +maxWellR,NaN,NaN +channelNames,Dapi:Gal8:RNA:TD,Dapi:Gal8:RNA +channelTags,c1:c2:c3:c4,c1:c2:c3 +channelColors,0 0 1:0 1 0:1 0.5 0:1 1 1,0 0 1:0 1 0:1 0.5 0:1 1 1 +channelMin,0:0:0:0,0:0:0:0 +channelMax,0.32022:0.58192:0.69413:1,0.32022:0.58192:0.69413:1 +use,1,1 +sequenceLength,, +SegOldVersion,none,none +SegSave,1,1 +SegAlgorithm,Segment_bandpass,Segment_bandpass +SegChannel,Gal8,Gal8 +SegLightCorrect,none,none +SegBgSubAlgorithm,none,none +SegTopHatRadius,Inf,Inf +SegFillHoles,1,1 +SegMinHoleArea,Inf,Inf +SegMinArea,1000,1000 +SegMaxArea,Inf,Inf +SegMinSumIntensity,0,0 +SegClipping,1,1 +SegClippingBelow,0,0 +SegSmooth,2,2 +SegMedFilt,1,1 +SegWatershed,intermediate,intermediate +SegWSmooth,5,5 +SegWHMax,6,6 +SegWThresh,-Inf,-Inf +SegWatershed2,darkness,darkness +SegWLocMaxCentroids,0,0 +SegCellMorphOp,none,none +BPSegHighStd,5,5 +BPSegLowStd,2,2 +BPSegBgFactor,1,1 +BPSegThreshold,1e-06,1e-06 +BPSegDarkOrBright,bright,bright +TrackXSpeedStd,12,12 +countClassifier,none,none +splitClassifier,none,none +deathClassifier,none,none +migClassifier,none,none +pCnt0,0.2,0.2 +pCnt1,0.7,0.7 +pCnt2,0.1,0.1 +pCntExtrap,0.25,0.25 +pSplit,0.01,0.01 +pDeath,0.01,0.01 +TrackPAppear,0,0 +TrackPDisappear,0,0 +TrackMotionModel,none,none +TrackMigLogLikeList,MigLogLikeList_uniformClutter,MigLogLikeList_uniformClutter +TrackDeathShift,2e-05,2e-05 +TrackMaxDeathProb,1,1 +TrackMaxMigScore,0,0 +TrackMigInOut,1,1 +TrackNumNeighbours,3,3 +TrackSingleIdleState,0,0 +TrackBipartiteMatch,1,1 +TrackFalsePos,1,1 +TrackSaveFPAsCells,0,0 +TrackCentroidOffset,0,0 +TrackMergeWatersheds,1,1 +TrackMergeOverlapMaxIter,0,0 +TrackMergeBrokenMaxArea,0,0 +TrackMergeBrokenRatio,0.75,0.75 +foiErosion,0,0 +TrackSaveIterations,0,0 +TrackSavePTC,0,0 +TrackSaveCTC,0,0 +TrackEvaluateCTC,0,0 +TrackSelectFromGT,0,0 +condition,Unspecified,Unspecified +pixelSize,1,1 +magnification,1,1 +dT,1,1 +startT,0,0 +authorStr,, +SegWSmooth2,7,7 +SegWHMax2,0.1,0.1 +SegWThresh2,-Inf,-Inf diff --git a/Copy_of_BF_Functions/CytNucWaterShed.m b/Copy_of_BF_Functions/CytNucWaterShed.m new file mode 100644 index 0000000..ff0c048 --- /dev/null +++ b/Copy_of_BF_Functions/CytNucWaterShed.m @@ -0,0 +1,21 @@ +function [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4) +%UNTITLED4 Summary of this function goes here +% Detailed explanation goes here +cytsize=size(cyt); + border = ones(cytsize); + border(2:end-1,2:end-1) = 0; + n_maxs=imerode(Nuc_bw4,strel('disk',1)); + n_maxs=bwareaopen(n_maxs,100); + h=imhmin(CytTopHat,1); + h_c=imcomplement(h); + h_c_min=imimposemin(h_c, n_maxs); + L_n = watershed(h_c_min); + L_n(~cyt_bw4) = 0; + borderInverse=~border; + L_n(~borderInverse) = 0; + howdy=L_n; + Cyt_WS=imfill((howdy),4,'holes'); + Cyt_WS_perim = imdilate(bwperim(Cyt_WS),strel('disk',1)); + +end + diff --git a/Copy_of_BF_Functions/Cytosol.m b/Copy_of_BF_Functions/Cytosol.m new file mode 100644 index 0000000..029f0ea --- /dev/null +++ b/Copy_of_BF_Functions/Cytosol.m @@ -0,0 +1,27 @@ +function [CytBright,CytArea,CytCytOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(cyt,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk) +%UNTITLED2 Summary of this function goes here +% Detailed explanation goes here + CytTopHat=imtophat(cyt,CytTophatDisk); % Clean image with tophat filter for thresholding + CytOpen=imerode(CytTopHat,CytOpenDisk); + CytOpen=imreconstruct(CytOpen,CytTopHat); + cyt_eq =imadjust(CytTopHat,[0 0.25],[]); %Make it easy to see + + CytMaxValue= CytMax*intmax(class(cyt)); + CytOverbright=CytOpen>CytMaxValue; + CytBright=CytOpen; + CytBright(CytOverbright)=0; + CytMT1=multithresh(CytBright,20); %Calculate 20 brightness thresholds for image + CytQuant1=imquantize(CytBright,CytMT1); %Divide Image into the 20 brightness baskets + CytBrightEnough=CytQuant1>CytLow; + + CytPos=CytBright; + CytPos(~CytBrightEnough)=0; + cyt_bw2=imerode(CytPos,CytErodeDisk); + cyt_bw3 = bwareaopen(cyt_bw2, 2000); %%Be sure to check this threshold + cyt_bw4 = imclose(cyt_bw3, CytCloseDisk); + CytPos(~cyt_bw4)=0; + cyt_bw4_perim = imdilate(bwperim(cyt_bw4),strel('disk',3)); + CytArea = imoverlay(cyt_eq, cyt_bw4_perim, [.3 1 .3]); + CytCytOverlay = imoverlay(cyt_eq, cyt_bw4_perim, [.3 1 .3]); +end + diff --git a/Copy_of_BF_Functions/Gal8.m b/Copy_of_BF_Functions/Gal8.m new file mode 100644 index 0000000..7a57b30 --- /dev/null +++ b/Copy_of_BF_Functions/Gal8.m @@ -0,0 +1,25 @@ +function [GalPals,Gal8Signal,RingMeanInt,Gal8Quant5,Gal8Quant4,Gal8Quant3,Gal8Open,Gal8TH,Gal8Quant2,Puncta,Ring] = Gal8(cyt,Gal8TophatDisk,Gal8OpenDisk,Gal8DilateDisk,Gal8MinThreshold,CytPos,Gal8OutlineDisk) +%UNTITLED2 Summary of this function goes here +% Detailed explanation goes here +Gal8=wiener2(cyt); +Gal8TH=imtophat(Gal8,Gal8TophatDisk); +Gal8Open=imopen(Gal8TH,Gal8OpenDisk); + +Gal8MinValue= Gal8MinThreshold*intmax(class(cyt)); +Gal8Quant2=Gal8Open-Gal8MinValue; +Gal8Quant2(Gal8Quant2<=0)=0; +Gal8Quant3=bwareaopen(Gal8Quant2,4); +Gal8Quant3(~CytPos)=0; +Gal8Quant3=imdilate(Gal8Quant3,Gal8DilateDisk); +Gal8Quant4=imdilate(Gal8Quant3,Gal8OutlineDisk); +Gal8Quant5=imbinarize(Gal8Quant4-Gal8Quant3); +GalPals=cyt; +GalPals(~Gal8Quant3)=0; + +Puncta=regionprops(Gal8Quant3,cyt,'Area','Centroid','MeanIntensity'); +Ring=regionprops(Gal8Quant5,cyt,'Area','Centroid','MeanIntensity'); %need to figure out way to subtract out surrounding brightness for each individual Point +RingMeanInt=2; %need to figure out way to subtract out surrounding brightness for each individual Point +Gal8Signal=sum((vertcat(Puncta.MeanIntensity).*vertcat(Puncta.Area))); +% Gal8Signal=Gal8Signal'; +end + diff --git a/Copy_of_BF_Functions/NuclearStain.m b/Copy_of_BF_Functions/NuclearStain.m new file mode 100644 index 0000000..ae8496c --- /dev/null +++ b/Copy_of_BF_Functions/NuclearStain.m @@ -0,0 +1,34 @@ +function [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Nuc,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk) +%UNTITLED2 Summary of this function goes here +% Detailed explanation goes here + NucWeiner=wiener2(Nuc); + NucTopHat=imtophat(NucWeiner,NucTophatDisk); % Clean image with tophat filter for thresholding +% NucOpen=imerode(NucTopHat,NucOpenDisk); +% NucOpen=imreconstruct(NucOpen,NucTopHat); + Nuc_eq =imadjust(NucTopHat); %Make it easy to see + NucOpen=imopen(NucTopHat,NucOpenDisk); + NucMaxValue= NucMax*intmax(class(Nuc)); + NucOverbright=NucTopHat>NucMaxValue; + + NucOpen(NucOverbright)=0; +% NucMT1=multithresh(NucOpen,20); %Calculate 20 brightness thresholds for image +% NucQuant1=imquantize(NucOpen,NucMT1); %Divide Image into the 20 brightness baskets + NucMT1=1; + NucQuant1=1; +% NucBrightEnough=NucQuant1>NucLow; + NucBrightEnough=NucOpen>NucLow; + NucPos=NucOpen; + NucPos(~NucBrightEnough)=0; +% NucPos=imadjust(NucPos); + Nuc_bw2=imerode(NucPos,NucErodeDisk); + Nuc_bw3 = bwareaopen(Nuc_bw2, 250); %%Be sure to check this threshold + Nuc_bw4 = imclose(Nuc_bw3, NucCloseDisk); + Nuc_bw4 = imfill(Nuc_bw4,'holes'); + Nuc_bw4_perim = imdilate(bwperim(Nuc_bw4),strel('disk',3)); + + NucConn=bwconncomp(Nuc_bw4); + NucLabel = labelmatrix(NucConn); + NucArea = imoverlay(Nuc_eq, Nuc_bw4_perim, [.3 1 .3]); + +end + diff --git a/Copy_of_BF_Functions/Rhoda.m b/Copy_of_BF_Functions/Rhoda.m new file mode 100644 index 0000000..606771e --- /dev/null +++ b/Copy_of_BF_Functions/Rhoda.m @@ -0,0 +1,14 @@ + %%Rhodamine Code + +function [area,Thresh_eq,DrugMask,ThreshHigh] = ThreshSeg(Img, threshold) + + Thresh_eq =imadjust(Img,[0 0.4],[]); + + threshold = threshold *intmax(class(Img)); + + rhodaweiner=wiener2(Img); + DrugMask=rhodaweiner>threshold; + + area = sum(DrugMask,'all'); + + \ No newline at end of file diff --git a/Copy_of_BF_Functions/ThreshSeg.m b/Copy_of_BF_Functions/ThreshSeg.m new file mode 100644 index 0000000..d8aa2d6 --- /dev/null +++ b/Copy_of_BF_Functions/ThreshSeg.m @@ -0,0 +1,15 @@ + %%Rhodamine Code + +function [area,Thresh_eq,DrugMask,ThreshHigh] = ThreshSeg(Img, threshold) + + Thresh_eq =imadjust(Img,[0 0.4],[]); + + threshold = threshold *intmax(class(Img)); + + rhodaweiner=wiener2(Img); + DrugMask=rhodaweiner>threshold; + ThreshHigh=Img; + ThreshHigh(~DrugMask)=0; + area = sum(DrugMask,'all'); + + \ No newline at end of file diff --git a/Copy_of_BF_Functions/m_2021_12_30.m b/Copy_of_BF_Functions/m_2021_12_30.m new file mode 100644 index 0000000..211e2ba --- /dev/null +++ b/Copy_of_BF_Functions/m_2021_12_30.m @@ -0,0 +1,257 @@ +%% Gal8 Recruitment MATLAB Program + +% Written by Brock Fletcher in the Biomedical Engineering Department at +% Vanderbilt University 2017 - 2022 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/). +%Adapted from work by Kameron V Kilchrist, 2015 - 2018 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/), published in +% Kilchrist, Dimobi, ..., Duvall; "Gal8 +% Visualization of Endosome Disruption Predicts Carrier-mediated Biologic +% Drug Intracellular Bioavailability". + +% University Email: brock.fletcher@vanderbilt.edu +% Permanent Email: brockfletch@gmail.com + +% This code may be reused at will for non-commercial purposes. +% Licensed under a Creative Commons Attribution 4.0 International License. + +% Derivative code should be published at GitHub or FigShare. Derivative +% scientific works should cite _______________ +%% Usage Guide (TL/DR): + %Steps + %Export your fluorescent microscopy as multipage TIFs + %Grab a few example TIFs to test your parameters and put them + %into a folder. (..\Test) + %Create a Second Folder to output to (..\TestExports) + + %Copy the file paths from file explorer and paste them into the + %"workingdir" and "exportdir" + + %Enter your "Calibration" value + %Enter what programs to run on each Channel ("C1=[]") + %Set your thresholds to a starting value + %Run Program + %Check output Images and Excel File + %Change Threshold Values and Re-Run until results are good enough + %If good analysis cannot be reached, edit advanced Values + %If still not good enough, edit actual bulk of code + %Once ready, change "workingdir" to a folder containing all images + %to be analyzed, and "exportdir" to a new, empty folder + + %Run Program and wait. If too hard on your CPU, change "parfor" to + %"for" + + %Review output images and analyze Data. + %Reccomended Analysis Steps: + %Label Each row of Data using VLOOKUP in Excel. + %Explore Data using JMP's Graphbuilder. + %Graph Data in Prism. +%% Image Folder Location +clc, clear; +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-02-BigPRoteinScreen\20211002BigProteinScreen001.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-02-BigPRoteinScreen\2022-01-04_Demo'; +% filetype='tif'; +% listing=dir(strcat(workingdir,'*.TIF')); +% ds=imageDatastore(workingdir); +%% Directory Code +readeromeMeta=reader.getMetadataStore(); +destdirectory1 = fullfile(exportdir,'Overlaid'); +BaxtDirectory= fullfile(exportdir,'Baxter'); +exportbaseBAXTSegNuc=fullfile(BaxtDirectory,'Analysis','Segmentation_Nuc'); +exportbaseBAXTSegCell=fullfile(BaxtDirectory,'Analysis','Segmentation_Cell'); +mkdir(destdirectory1); %create the directory +mkdir(BaxtDirectory); +mkdir(exportbaseBAXTSegNuc); +mkdir(exportbaseBAXTSegCell); +%% +% This will measure the total Gal8 recruited to puncta and count cell +% nuclei or cytosol in each frame. + +% This code assumes you have exported images as multipage TIF files, with +% any of the following stains in each channel: + % nuclear Stain + % Difuse Cytosolic Stain + % Punctate Cytosolic Stain + % Labeled Drug or other exogenous molecule (Cas9, siRNA) + +% Images were exported to 2 page TIF images using Nikon NIS Elements. If +% you use alternate file formats or use separate export files for each +% channel, please edit the code as appropriate. + +% You *must* edit the workingdir and exportdir variables for this code to +% work. +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); +%% Image Thresholding EDIT HERE BASIC +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + +%Input Planes + InputPlanes={'Nuc','cyt','drug'}; + +%Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=1; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.08;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 0.4; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables +bitConvert=(2^16/2^bitdepthin); +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + % export file names and in the DataCells array. Note: it is a character + % array / string! +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +NumSeries=reader.getSeriesCount(); +NumColors=reader.getEffectiveSizeC(); +NumTimepoint=(reader.getImageCount())/NumColors; +NumImg=NumSeries*NumTimepoint*NumColors; + +C = cell(NumImg,length(Categories)); +%% Analysis Program +for j=0:NumSeries% Number of images in ND2 File + %% Import TIFs + % %The next few lines are specific to 2 page TIF images. Edit from here + % if you have alternate arrangements. +% currfile=strcat(workingdir,listing(j,1).name); + CurrSeries=j; + reader.setSeries(CurrSeries); + fname = reader.getSeries; + Well=num2str(fname,'%05.f'); + + BaxWellFolder=fullfile(BaxtDirectory,Well); + mkdir(BaxWellFolder); + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); + T_Value = reader.getSizeT()-1; + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); + mkdir(BaxSegFolderNuc); + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); + mkdir(BaxSegFolderCell); + + for i=1:T_Value + +% T_Value = reader.getSizeT(); + Timepoint = num2str(i,'%03.f'); + iplane=reader.getIndex(0,0,i); + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())) + for n= + ImagePlane(n)= bitConvert*bfGetPlane(reader,iplane+n); + end + + + %% Analyze Images + %%Nuclear Stain Code + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Nuc,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + % NucStats=regionprops(Nuc_bw4,'Centroid','Area'); + + %%Cytosol Code + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(cyt,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + + %WaterShed Segmentation of Individual Cells + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + % figure; imshow(imoverlay(cyt_eq,Cyt_WS, [.3 .3 1])); + %Gal8 Puncta Segmentation + [GalPals,Gal8Signal,RingMeanInt,Gal8Quant5,Gal8Quant4,Gal8Quant3,Gal8Open,Gal8TH,Gal8Quant2,Puncta,Ring] = Gal8(cyt,Gal8TophatDisk,Gal8OpenDisk,Gal8DilateDisk,Gal8MinThreshold,Cyt_WS,CytPos,Gal8OutlineDisk); + % figure; imshow(imoverlay(cyt_eq,Gal8Quant5, [.3 .3 1])); + + %Rhodamine Code + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(drug, Rhoda_threshold, cyt_bw4); + rhodPerim=bwperim(RhodMask); + + %All Data Images + RGBExportImage=cat(3,rhod_eq,cyt_eq,Nuc_eq); + WSArea = imoverlay(RGBExportImage, Cyt_WS_perim,[0.8500 0.3250 0.0980]); + ExportImage=imoverlay(WSArea,Gal8Quant5,'m'); + ExportImage=imoverlay(ExportImage,Nuc_bw4_perim, [0.3010 0.7450 0.9330]); + ExportImage=imoverlay(ExportImage,rhodPerim, 'y'); + % figure; imshow(ExportImage); + % + + %% Measure Image Data + + % measurement + areacell=bwarea(Nuc_bw4(:)); + CellSum=sum(Nuc(Nuc_bw4)); + areaGal8=sum((vertcat(Puncta.Area))); + % + % C(j,:)=[{run},{WellTime},{areacell},{CellSum},{areaGal8},{Gal8Signal},{areaRhod},{Rhodsum},{RhodAvgInCell},{RhodAvgOutCell}]; + %% Write Images to File + %overlaid Image + BaxterName=strcat('w',Well,'t',Timepoint) + + exportbase=strcat(destdirectory1,'\',run,'_',BaxterName); + + + fulldestination = strcat(exportbase,'.png'); %name file relative to that directory + imwrite(ExportImage, fulldestination); %save the file there directory + + %BaxterImages + ImageName=fullfile(BaxWellFolder,BaxterName); + imwrite(Nuc, strcat(ImageName,'c01','.tif'),'tif'); + imwrite(cyt, strcat(ImageName,'c02','.tif'),'tif'); + imwrite(GalPals, strcat(ImageName,'c03','.tif'),'tif'); + imwrite(drug, strcat(ImageName,'c04','.tif'),'tif'); + imwrite(RhodBright, strcat(ImageName,'c05','.tif'),'tif'); + + + SegNameNuc=fullfile(BaxSegFolderNuc,BaxterName); + imwrite(NucLabel, strcat(SegNameNuc,'c01','.tif'),'tif'); + + + SegNameCell=fullfile(BaxSegFolderCell,BaxterName); + imwrite(Cyt_WS, strcat(SegNameCell,'c01','.tif'),'tif'); + + + end +end +%% Write Analysis Data to File + +D=[Categories;C]; +WritingHere=strcat(exportdir,'\','Gal8','_',run); + writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data \ No newline at end of file diff --git a/Copy_of_BF_Functions/m_Bronk_2022_01_05.m b/Copy_of_BF_Functions/m_Bronk_2022_01_05.m new file mode 100644 index 0000000..c0fa4f0 --- /dev/null +++ b/Copy_of_BF_Functions/m_Bronk_2022_01_05.m @@ -0,0 +1,255 @@ +%% Gal8 Recruitment MATLAB Program + +% Written by Brock Fletcher in the Biomedical Engineering Department at +% Vanderbilt University 2017 - 2022 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/). +%Adapted from work by Kameron V Kilchrist, 2015 - 2018 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/), published in +% Kilchrist, Dimobi, ..., Duvall; "Gal8 +% Visualization of Endosome Disruption Predicts Carrier-mediated Biologic +% Drug Intracellular Bioavailability". + +% University Email: brock.fletcher@vanderbilt.edu +% Permanent Email: brockfletch@gmail.com + +% This code may be reused at will for non-commercial purposes. +% Licensed under a Creative Commons Attribution 4.0 International License. + +% Derivative code should be published at GitHub or FigShare. Derivative +% scientific works should cite _______________ +%% Usage Guide (TL/DR): + %Steps + %Export your fluorescent microscopy as multipage TIFs + %Grab a few example TIFs to test your parameters and put them + %into a folder. (..\Test) + %Create a Second Folder to output to (..\TestExports) + + %Copy the file paths from file explorer and paste them into the + %"workingdir" and "exportdir" + + %Enter your "Calibration" value + %Enter what programs to run on each Channel ("C1=[]") + %Set your thresholds to a starting value + %Run Program + %Check output Images and Excel File + %Change Threshold Values and Re-Run until results are good enough + %If good analysis cannot be reached, edit advanced Values + %If still not good enough, edit actual bulk of code + %Once ready, change "workingdir" to a folder containing all images + %to be analyzed, and "exportdir" to a new, empty folder + + %Run Program and wait. If too hard on your CPU, change "parfor" to + %"for" + + %Review output images and analyze Data. + %Reccomended Analysis Steps: + %Label Each row of Data using VLOOKUP in Excel. + %Explore Data using JMP's Graphbuilder. + %Graph Data in Prism. +%% Image Folder Location +clc, clear; +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-11-BigProteinFollowUp\Ai9Lipo48hrs002.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-11-BigProteinFollowUp\Analysis'; +% filetype='tif'; +% listing=dir(strcat(workingdir,'*.TIF')); +% ds=imageDatastore(workingdir); +%% Directory Code +readeromeMeta=reader.getMetadataStore(); +destdirectory1 = fullfile(exportdir,'Overlaid'); +BaxtDirectory= fullfile(exportdir,'Baxter'); +exportbaseBAXTSegNuc=fullfile(BaxtDirectory,'Analysis','Segmentation_Nuc'); +exportbaseBAXTSegCell=fullfile(BaxtDirectory,'Analysis','Segmentation_Cell'); +mkdir(destdirectory1); %create the directory +mkdir(BaxtDirectory); +mkdir(exportbaseBAXTSegNuc); +mkdir(exportbaseBAXTSegCell); +%% +% This will measure the total Gal8 recruited to puncta and count cell +% nuclei or cytosol in each frame. + +% This code assumes you have exported images as multipage TIF files, with +% any of the following stains in each channel: + % nuclear Stain + % Difuse Cytosolic Stain + % Punctate Cytosolic Stain + % Labeled Drug or other exogenous molecule (Cas9, siRNA) + +% Images were exported to 2 page TIF images using Nikon NIS Elements. If +% you use alternate file formats or use separate export files for each +% channel, please edit the code as appropriate. + +% You *must* edit the workingdir and exportdir variables for this code to +% work. +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=1.36; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); +%% Image Thresholding EDIT HERE BASIC +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 +%Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=1000;% + %Cytosol + CytMax= 1.1; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=1; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=1;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + Rhoda_threshold = 1; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables +bitConvert=(2^16/2^bitdepthin); +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + % export file names and in the DataCells array. Note: it is a character + % array / string! +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +NumSeries=reader.getSeriesCount(); +NumColors=reader.getEffectiveSizeC(); +NumTimepoint=(reader.getImageCount())/NumColors; +NumImg=NumSeries*NumTimepoint*NumColors; + +C = cell(NumImg,length(Categories)); +%% Analysis Program +for j=0:NumSeries% Number of images in ND2 File + %% Import TIFs + % %The next few lines are specific to 2 page TIF images. Edit from here + % if you have alternate arrangements. +% currfile=strcat(workingdir,listing(j,1).name); + CurrSeries=j; + reader.setSeries(CurrSeries); + fname = reader.getSeries; + Well=num2str(fname,'%05.f'); + + BaxWellFolder=fullfile(BaxtDirectory,Well); + mkdir(BaxWellFolder); + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); + T_Value = reader.getSizeT()-1; + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); + mkdir(BaxSegFolderNuc); + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); + mkdir(BaxSegFolderCell); + + for i=0:T_Value + +% T_Value = reader.getSizeT(); + Timepoint = num2str(i,'%03.f'); + iplane=reader.getIndex(0,0,i); + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())) + + Nuc = bitConvert*bfGetPlane(reader,iplane+2); + + cyt = bitConvert*bfGetPlane(reader,iplane+2); + + drug = bitConvert*bfGetPlane(reader,iplane+1); + + %% Analyze Images + %%Nuclear Stain Code + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Nuc,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + % NucStats=regionprops(Nuc_bw4,'Centroid','Area'); + + %%Cytosol Code + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(cyt,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + + %WaterShed Segmentation of Individual Cells + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + % figure; imshow(imoverlay(cyt_eq,Cyt_WS, [.3 .3 1])); + %Gal8 Puncta Segmentation + [GalPals,Gal8Signal,RingMeanInt,Gal8Quant5,Gal8Quant4,Gal8Quant3,Gal8Open,Gal8TH,Gal8Quant2,Puncta,Ring] = Gal8(cyt,Gal8TophatDisk,Gal8OpenDisk,Gal8DilateDisk,Gal8MinThreshold,Cyt_WS,CytPos,Gal8OutlineDisk); + % figure; imshow(imoverlay(cyt_eq,Gal8Quant5, [.3 .3 1])); + + %Rhodamine Code + [RhodBright,areaRhod, Rhodsum, RhodAvgInCell, RhodAvgOutCell,rhod_eq,RhodMask] = Rhoda(drug, Rhoda_threshold, cyt_bw4); + rhodPerim=bwperim(RhodMask); + + %All Data Images + RGBExportImage=cat(3,rhod_eq,cyt_eq,Nuc_eq); + WSArea = imoverlay(RGBExportImage, Cyt_WS_perim,[0.8500 0.3250 0.0980]); + ExportImage=imoverlay(WSArea,Gal8Quant5,'m'); + ExportImage=imoverlay(ExportImage,Nuc_bw4_perim, [0.3010 0.7450 0.9330]); + ExportImage=imoverlay(ExportImage,rhodPerim, 'y'); + % figure; imshow(ExportImage); + % + + %% Measure Image Data + + % measurement + areacell=bwarea(Nuc_bw4(:)); + CellSum=sum(Nuc(Nuc_bw4)); + areaGal8=sum((vertcat(Puncta.Area))); + % + % C(j,:)=[{run},{WellTime},{areacell},{CellSum},{areaGal8},{Gal8Signal},{areaRhod},{Rhodsum},{RhodAvgInCell},{RhodAvgOutCell}]; + %% Write Images to File + %overlaid Image + BaxterName=strcat('w',Well,'t',Timepoint) + + exportbase=strcat(destdirectory1,'\',run,'_',BaxterName); + + + fulldestination = strcat(exportbase,'.png'); %name file relative to that directory + imwrite(ExportImage, fulldestination); %save the file there directory + + %BaxterImages + ImageName=fullfile(BaxWellFolder,BaxterName); + imwrite(Nuc, strcat(ImageName,'c01','.tif'),'tif'); + imwrite(cyt, strcat(ImageName,'c02','.tif'),'tif'); + imwrite(GalPals, strcat(ImageName,'c03','.tif'),'tif'); + imwrite(drug, strcat(ImageName,'c04','.tif'),'tif'); + imwrite(RhodBright, strcat(ImageName,'c05','.tif'),'tif'); + + + SegNameNuc=fullfile(BaxSegFolderNuc,BaxterName); + imwrite(NucLabel, strcat(SegNameNuc,'c01','.tif'),'tif'); + + + SegNameCell=fullfile(BaxSegFolderCell,BaxterName); + imwrite(Cyt_WS, strcat(SegNameCell,'c01','.tif'),'tif'); + + + end +end +%% Write Analysis Data to File + +D=[Categories;C]; +WritingHere=strcat(exportdir,'\','Gal8','_',run); + writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data \ No newline at end of file diff --git a/Copy_of_BF_Functions/m_Bronk_2022_01_05_bigChanges.m b/Copy_of_BF_Functions/m_Bronk_2022_01_05_bigChanges.m new file mode 100644 index 0000000..65aff67 --- /dev/null +++ b/Copy_of_BF_Functions/m_Bronk_2022_01_05_bigChanges.m @@ -0,0 +1,279 @@ +%% Gal8 Recruitment MATLAB Program + +% Written by Brock Fletcher in the Biomedical Engineering Department at +% Vanderbilt University 2017 - 2022 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/). +%Adapted from work by Kameron V Kilchrist, 2015 - 2018 in the course of his PhD studies +% advised by Craig Duvall (https://my.vanderbilt.edu/duvall/), published in +% Kilchrist, Dimobi, ..., Duvall; "Gal8 +% Visualization of Endosome Disruption Predicts Carrier-mediated Biologic +% Drug Intracellular Bioavailability". + +% University Email: brock.fletcher@vanderbilt.edu +% Permanent Email: brockfletch@gmail.com + +% This code may be reused at will for non-commercial purposes. +% Licensed under a Creative Commons Attribution 4.0 International License. + +% Derivative code should be published at GitHub or FigShare. Derivative +% scientific works should cite _______________ +%% Usage Guide (TL/DR): + %Steps + %Export your fluorescent microscopy as multipage TIFs + %Grab a few example TIFs to test your parameters and put them + %into a folder. (..\Test) + %Create a Second Folder to output to (..\TestExports) + + %Copy the file paths from file explorer and paste them into the + %"workingdir" and "exportdir" + + %Enter your "Calibration" value + %Enter what programs to run on each Channel ("C1=[]") + %Set your thresholds to a starting value + %Run Program + %Check output Images and Excel File + %Change Threshold Values and Re-Run until results are good enough + %If good analysis cannot be reached, edit advanced Values + %If still not good enough, edit actual bulk of code + %Once ready, change "workingdir" to a folder containing all images + %to be analyzed, and "exportdir" to a new, empty folder + + %Run Program and wait. If too hard on your CPU, change "parfor" to + %"for" + + %Review output images and analyze Data. + %Reccomended Analysis Steps: + %Label Each row of Data using VLOOKUP in Excel. + %Explore Data using JMP's Graphbuilder. + %Graph Data in Prism. +%% Image Folder Location +clc, clear; +reader = bfGetReader('D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-02-BigPRoteinScreen\20211002BigProteinScreen001.nd2'); +exportdir='D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-02-BigPRoteinScreen\2022-01-04_Demo'; +% filetype='tif'; +% listing=dir(strcat(workingdir,'*.TIF')); +% ds=imageDatastore(workingdir); +%% Directory Code +readeromeMeta=reader.getMetadataStore(); +destdirectory1 = fullfile(exportdir,'Overlaid'); +BaxtDirectory= fullfile(exportdir,'Baxter'); +exportbaseBAXTSegNuc=fullfile(BaxtDirectory,'Analysis','Segmentation_Nuc'); +exportbaseBAXTSegCell=fullfile(BaxtDirectory,'Analysis','Segmentation_Cell'); +mkdir(destdirectory1); %create the directory +mkdir(BaxtDirectory); +mkdir(exportbaseBAXTSegNuc); +mkdir(exportbaseBAXTSegCell); +%% +% This will measure the total Gal8 recruited to puncta and count cell +% nuclei or cytosol in each frame. + +% This code assumes you have exported images as multipage TIF files, with +% any of the following stains in each channel: + % nuclear Stain + % Difuse Cytosolic Stain + % Punctate Cytosolic Stain + % Labeled Drug or other exogenous molecule (Cas9, siRNA) + +% Images were exported to 2 page TIF images using Nikon NIS Elements. If +% you use alternate file formats or use separate export files for each +% channel, please edit the code as appropriate. + +% You *must* edit the workingdir and exportdir variables for this code to +% work. +%% Structuring Elements +% For conveience, a number of sizes of disk shaped structural elements are +% generated for data exploration. +sr1=strel('square',1); +se1=strel('disk',1); +sr2=strel('square',2); +se2=strel('disk',2); +se3=strel('disk',3); +sr3=strel('square',3); +se4=strel('disk',4); +se5=strel('disk',5); +se6=strel('disk',6); +se7=strel('disk',7); +se8=strel('disk',8); +se9=strel('disk',9); +se10=strel('disk',10); +se12=strel('disk',12); +se20=strel('disk',20); +se25=strel('disk',25); +se100=strel('disk',100); +%% Sizing/Resolution Parameters EDIT HERE ADVANCED + + %NEED TO ADD microns per Pixel %NEED TO ADD Cell size (Small, Medium, Large)%Go through this and make all disks calculated on the microns per pixel and %the Cell Size + +MiPerPix=0.34; +CellSize=1; %Scale as needed for different Cells + %Disks + NucTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); + NucOpenDisk= strel('disk',round(5*(0.34/MiPerPix))); + NucErodeDisk=strel('disk',round(6*(0.34/MiPerPix))); + NucCloseDisk=strel('disk',round(4*(0.34/MiPerPix))); + + CytTophatDisk=strel('disk',round(250*(0.34/MiPerPix))); % EditHere + CytOpenDisk =strel('disk',round(5*(0.34/MiPerPix))); + CytErodeDisk=strel('disk',round(5*(0.34/MiPerPix))); + CytCloseDisk=strel('disk',round(5*(0.34/MiPerPix))); + + Gal8TophatDisk=strel('disk',round(6*(0.34/MiPerPix)));% EditHere + Gal8OpenDisk =strel('square',round(2*(0.34/MiPerPix))); + Gal8DilateDisk=strel('disk',round(1*(0.34/MiPerPix))); + Gal8OutlineDisk=strel('disk',round(2*(0.34/MiPerPix))); +%% Image Thresholding EDIT HERE BASIC +%Bit Depth + bitdepthin= 12; %Bit depth of original image, usually 8, 12, or 16 + +%Input Planes + ImagePlanes=[1,2,3]; + FirstAnalyses={{'nuc'},{'cyt'},{'thresh'}}; + SecondAnalyses={{},{'SeededWS' 'gal' },{}}; +%Nuclear Stain + NucMax=0.8;%Number 0-1, removes Cell Debris brighter than this value in order to allow low end to remain visible. 0.2 is usually a good start + NucLow=100;% + %Cytosol + CytMax= 0.5; %Number 0-1, removes Cell Debris brighter than this value. 0.2 is usually a good start + CytLow=1; %Choose number 0-20, start at 0. Higher numbers remove more dim cells and background. + %Gal8 + Gal8MinThreshold=0.08;%Number 0-1, removes Puncta Dimmer than this value. 0.05 is usually a good start + %Rhodamine + thresh = 0.4; %Number 0-1, removes rhodamine signal dimmer than threshold +% Rhoda_threshold_Big = 100; +%% Analysis Variables +bitConvert=(2^16/2^bitdepthin); +run=char(datetime(clock),"yyyy-MM-dd-hh-mm-ss"); % The Run number is used to track multiple runs of the software, and is used in + % export file names and in the DataCells array. Note: it is a character + % array / string! +Categories=[{'run'},{'well'},{'areacell'},{'CellSum'},{'areaGal8'},{'galsum'},{'areaRhod'},{'Rhodsum'},{'RhodAvgInCell'},{'RhodAvgOutCell'}]; +NumSeries=reader.getSeriesCount(); +NumColors=reader.getEffectiveSizeC(); +NumTimepoint=(reader.getImageCount())/NumColors; +NumImg=NumSeries*NumTimepoint*NumColors; + +C = cell(NumImg,length(Categories)); +%% Analysis Program +for j=0:NumSeries% Number of images in ND2 File + %% Import TIFs + % %The next few lines are specific to 2 page TIF images. Edit from here + % if you have alternate arrangements. +% currfile=strcat(workingdir,listing(j,1).name); + CurrSeries=j; + reader.setSeries(CurrSeries); + fname = reader.getSeries; + Well=num2str(fname,'%05.f'); + + BaxWellFolder=fullfile(BaxtDirectory,Well); + mkdir(BaxWellFolder); + PositionX = readeromeMeta.getPlanePositionX(CurrSeries,1).value(); + PositionY = readeromeMeta.getPlanePositionY(CurrSeries,1).value(); + T_Value = reader.getSizeT()-1; + + BaxSegFolderNuc=fullfile(exportbaseBAXTSegNuc,Well); + mkdir(BaxSegFolderNuc); + + BaxSegFolderCell=fullfile(exportbaseBAXTSegCell,Well); + mkdir(BaxSegFolderCell); + + for i=1:T_Value + +% T_Value = reader.getSizeT(); + Timepoint = num2str(i,'%03.f'); + iplane=reader.getIndex(0,0,i); + WellTime = round(str2double(readeromeMeta.getPlaneDeltaT(CurrSeries,iplane).value())) + Img=[]; +% Red=zeros(imsize); +% Green=zeros(imsize); +% Blue=zeros(imsize); + for n=ImagePlanes + Img= bitConvert*bfGetPlane(reader,iplane+n); + imsize=size(Img); + CurrPlane=FirstAnalyses{n}; + for c=1:length(CurrPlane) + Analysis=CurrPlane{c} + + if contains(Analysis,'nuc') + [NucLabel,Nuc_bw4,NucPos,NucBrightEnough,NucMT1,NucOpen,Nuc_eq,NucTopHat,Nuc_bw4_perim,NucOverbright,NucQuant1,NucWeiner,NucArea] = NuclearStain(Img,NucTophatDisk,NucMax,NucOpenDisk,NucErodeDisk,NucLow,NucCloseDisk); + % x='hell0' + nuc=Img; + Blue=Nuc_eq; + NucStats=regionprops(Nuc_bw4,'Centroid','Area'); + end + if contains(Analysis,'cyt') + [CytBright,CytArea,CytNucOverlay,cyt_bw4,CytPos,CytBrightEnough,CytMT1,CytOpen,cyt_eq,CytTopHat,cyt_bw4_perim] = Cytosol(Img,CytTophatDisk,CytMax,CytOpenDisk,CytErodeDisk,CytLow,CytCloseDisk); + x='hell0'; + cyt=Img; + Green=cyt_eq; + end + if contains(Analysis,'thresh') + [areaThresh,Thresh_eq,ThreshMask,ThreshHigh] = ThreshSeg(Img, thresh); + drug=Img; + Red=Thresh_eq; + ThreshPerim=bwperim(ThreshMask); + end + + end + + +% ExportImage=cat(3,Red,Green,Blue); +% ExportImage=imoverlay(ExportImage,ThreshPerim, 'y'); + CurrPlane2=SecondAnalyses{n}; + for d=1:length(CurrPlane2) + Analysis2=CurrPlane2{d} + if contains(Analysis2,'SeededWS') + [Cyt_WS,Cyt_WS_perim,L_n] = CytNucWaterShed(cyt,Nuc_bw4,CytTopHat,cyt_bw4); + + end + if contains(Analysis2,'gal') + [GalPals,Gal8Signal,RingMeanInt,Gal8Quant5,Gal8Quant4,Gal8Quant3,Gal8Open,Gal8TH,Gal8Quant2,Puncta,Ring] = Gal8(Img,Gal8TophatDisk,Gal8OpenDisk,Gal8DilateDisk,Gal8MinThreshold,CytPos,Gal8OutlineDisk); + + end + + + end + end + ExportImage=cat(3,Red,Green,Blue); + ExportImage = imoverlay(ExportImage, Cyt_WS_perim,[0.8500 0.3250 0.0980]); + ExportImage=imoverlay(ExportImage,Gal8Quant5,'m'); + %% Measure Image Data + + % measurement +% areacell=bwarea(Nuc_bw4(:)); +% CellSum=sum(Nuc(Nuc_bw4)); +% areaGal8=sum((vertcat(Puncta.Area))); +% % % +% % C(j,:)=[{run},{WellTime},{areacell},{CellSum},{areaGal8},{Gal8Signal},{areaRhod},{Rhodsum},{RhodAvgInCell},{RhodAvgOutCell}]; +% %% Write Images to File +% %overlaid Image + BaxterName=strcat('w',Well,'t',Timepoint); +% + exportbase=strcat(destdirectory1,'\',run,'_',BaxterName); +% +% + fulldestination = strcat(exportbase,'.png'); %name file relative to that directory + imwrite(ExportImage, fulldestination); %save the file there directory + + %BaxterImages + ImageName=fullfile(BaxWellFolder,BaxterName); + imwrite(nuc, strcat(ImageName,'c01','.tif'),'tif'); + imwrite(cyt, strcat(ImageName,'c02','.tif'),'tif'); + imwrite(GalPals, strcat(ImageName,'c03','.tif'),'tif'); + imwrite(drug, strcat(ImageName,'c04','.tif'),'tif'); + imwrite(ThreshHigh, strcat(ImageName,'c05','.tif'),'tif'); + + + SegNameNuc=fullfile(BaxSegFolderNuc,BaxterName); + imwrite(NucLabel, strcat(SegNameNuc,'c01','.tif'),'tif'); + + + SegNameCell=fullfile(BaxSegFolderCell,BaxterName); + imwrite(Cyt_WS, strcat(SegNameCell,'c01','.tif'),'tif'); +% + + end +end +%% Write Analysis Data to File +% +% D=[Categories;C]; +% WritingHere=strcat(exportdir,'\','Gal8','_',run); +% writecell(D,strcat(WritingHere,'.xlsx')); % Exports an XLSX sheet of your data \ No newline at end of file diff --git a/DataWriteTest.m b/DataWriteTest.m new file mode 100644 index 0000000..382421c --- /dev/null +++ b/DataWriteTest.m @@ -0,0 +1,17 @@ +for i=0:2 + seqPath = 'D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-02-BigPRoteinScreen\2021-12-31-TestMultiTimepoint\Baxter\'; + Run=num2str(i) + seqPath=strcat(seqPath,'0000',num2str(i)); + cells = LoadCells (seqPath , '_211231_152842','AreCells', true, 'Compact', true); +% cells2=AreCells(cells); +properties=cells(1).regionProps.Area(2) +% % [cellVec2, labels2] = PartitionCells(cells, 'firstFrame'); +% Test=a; +fluorProps = {cells.regionProps}; +fluorProps = cellfun(@fieldnames, fluorProps,'UniformOutput', false); +fluorProps = unique(cat(1,fluorProps{:}))'; +% fluorProps = regexp(fluorProps, '^Fluor.*', 'match', 'once'); +% fluorProps(cellfun(@isempty, fluorProps)) = []; + + Plot_Fluorescence3D(cells,ax1,'Drug','Gal',rand(1,3)); +end diff --git a/DetermineCutoff.m b/DetermineCutoff.m new file mode 100644 index 0000000..e69de29 diff --git a/Files/Settings/Brock/Settings.csv b/Files/Settings/Brock/Settings.csv new file mode 100644 index 0000000..c20bdcc --- /dev/null +++ b/Files/Settings/Brock/Settings.csv @@ -0,0 +1,84 @@ +setting,A20,F08 +numZ,1,1 +bits,16,16 +minWellR,NaN,NaN +maxWellR,NaN,NaN +channelNames,Dapi:Gal8:RNA:TD,Dapi:Gal8:RNA +channelTags,c1:c2:c3:c4,c1:c2:c3 +channelColors,0 0 1:0 1 0:1 0.5 0:1 1 1,0 0 1:0 1 0:1 0.5 0:1 1 1 +channelMin,0:0:0:0,0:0:0:0 +channelMax,0.32022:0.58192:0.69413:1,0.32022:0.58192:0.69413:1 +use,1,1 +sequenceLength,, +SegOldVersion,none,none +SegSave,1,1 +SegAlgorithm,Segment_bandpass,Segment_bandpass +SegChannel,Gal8,Gal8 +SegLightCorrect,none,none +SegBgSubAlgorithm,none,none +SegTopHatRadius,Inf,Inf +SegFillHoles,1,1 +SegMinHoleArea,Inf,Inf +SegMinArea,1000,1000 +SegMaxArea,Inf,Inf +SegMinSumIntensity,0,0 +SegClipping,1,1 +SegClippingBelow,0,0 +SegSmooth,2,2 +SegMedFilt,1,1 +SegWatershed,intermediate,intermediate +SegWSmooth,5,5 +SegWHMax,6,6 +SegWThresh,-Inf,-Inf +SegWatershed2,darkness,darkness +SegWLocMaxCentroids,0,0 +SegCellMorphOp,none,none +BPSegHighStd,5,5 +BPSegLowStd,2,2 +BPSegBgFactor,1,1 +BPSegThreshold,1e-06,1e-06 +BPSegDarkOrBright,bright,bright +TrackXSpeedStd,12,12 +countClassifier,none,none +splitClassifier,none,none +deathClassifier,none,none +migClassifier,none,none +pCnt0,0.2,0.2 +pCnt1,0.7,0.7 +pCnt2,0.1,0.1 +pCntExtrap,0.25,0.25 +pSplit,0.01,0.01 +pDeath,0.01,0.01 +TrackPAppear,0,0 +TrackPDisappear,0,0 +TrackMotionModel,none,none +TrackMigLogLikeList,MigLogLikeList_uniformClutter,MigLogLikeList_uniformClutter +TrackDeathShift,2e-05,2e-05 +TrackMaxDeathProb,1,1 +TrackMaxMigScore,0,0 +TrackMigInOut,1,1 +TrackNumNeighbours,3,3 +TrackSingleIdleState,0,0 +TrackBipartiteMatch,1,1 +TrackFalsePos,1,1 +TrackSaveFPAsCells,0,0 +TrackCentroidOffset,0,0 +TrackMergeWatersheds,1,1 +TrackMergeOverlapMaxIter,0,0 +TrackMergeBrokenMaxArea,0,0 +TrackMergeBrokenRatio,0.75,0.75 +foiErosion,0,0 +TrackSaveIterations,0,0 +TrackSavePTC,0,0 +TrackSaveCTC,0,0 +TrackEvaluateCTC,0,0 +TrackSelectFromGT,0,0 +condition,Unspecified,Unspecified +pixelSize,1,1 +magnification,1,1 +dT,1,1 +startT,0,0 +authorStr,, +SegWSmooth2,7,7 +SegWHMax2,0.1,0.1 +SegWThresh2,-Inf,-Inf diff --git a/Make4DMatrix.m b/Make4DMatrix.m new file mode 100644 index 0000000..520c4ff --- /dev/null +++ b/Make4DMatrix.m @@ -0,0 +1,46 @@ +seqPath = 'D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-11-15-Ai9CMAX PRotein Screen\Analysis\Baxter'; +TrackVersion='_220106_115446'; +FilePath=fullfile(seqPath,'Analysis',strcat('CellData',TrackVersion),'Compact'); +a=dir(fullfile(FilePath,'*.mat')); +b={a.name}; +HasCells=[a.bytes]; +blank=~(HasCells>185); +d=b; +d(blank) =[]; + +for m=1:length(b) + Run=b{1,m}; + Run=Run(1:end-4) + if blank(m) + BronkBox{1,1,1,m}={}; + else + cellPath=strcat(seqPath,'\',Run); + cells = LoadCells(cellPath, TrackVersion, 'Compact', true); + fluorProps = {cells.regionProps}; + fluorProps = cellfun(@fieldnames, fluorProps,'UniformOutput', false); + fluorProps = unique(cat(1,fluorProps{:}))'; + BronkBox=cell(length(cells),max([cells.stopT]),length(fluorProps),NumWells); +for k=1:length(fluorProps) + currProp=fluorProps{k}; + Test='MinorAxisLength'; +for j=1:length(cells) + c = cells(j); + t = c.firstFrame : c.lastFrame; + tp=1; + for i=t + BronkBox{j,i,k,m}=cells(1,j).regionProps.(currProp)(tp); + tp=tp+1; + end +end +end + end +end +empties=cellfun('isempty',BronkBox); +BronkBox(empties) = {NaN}; +Data=cell2mat(BronkBox); +means=mean(Data(:,:,:,:),'omitnan'); +medians=median(Data(:,:,:,:),'omitnan'); +stds=std(Data(:,:,:,:),'omitnan'); +vars=var(Data(:,:,:,:),'omitnan'); +sums=sum(Data(:,:,:,:),'omitnan'); +CVs=stds./means; \ No newline at end of file diff --git a/PlotTest.m b/PlotTest.m new file mode 100644 index 0000000..d38bb81 --- /dev/null +++ b/PlotTest.m @@ -0,0 +1,13 @@ +figure, ax1 = axes('Position',[0.1 0.1 0.7 0.7]); +for i=0:2 + seqPath = 'D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-02-BigPRoteinScreen\2021-12-31-TestMultiTimepoint\Baxter\'; + Run=num2str(i) + seqPath=strcat(seqPath,'0000',num2str(i)); + cells2 = LoadCells (seqPath , '_211231_152842','AreCells', true, 'Compact', true); +% cells2=AreCells(cells); + Plot_Fluorescence3D(cells2,ax1,'Drug','Gal',rand(1,3)); +end +% for i = 1:length(cells2) +% c = cells2(i) +% +% end \ No newline at end of file diff --git a/TestApp.mlapp b/TestApp.mlapp new file mode 100644 index 0000000..3c508ad Binary files /dev/null and b/TestApp.mlapp differ diff --git a/WriteTest.m b/WriteTest.m new file mode 100644 index 0000000..a8fbbd0 --- /dev/null +++ b/WriteTest.m @@ -0,0 +1,53 @@ +seqPath = 'D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-02-BigPRoteinScreen\2021-12-31-TestMultiTimepoint\Baxter\'; +TrackVersion='_211231_152842'; +FilePath=fullfile(seqPath,'Analysis',strcat('CellData',TrackVersion),'Compact'); +a=dir(fullfile(FilePath,'*.mat')); +b={a.name}; +HasCells=[a.bytes]; +c=~(HasCells>185); +d=b; +d(c) =[]; + + +figure, ax2 = axes('Position',[0.1 0.1 0.7 0.7]); +for m=1:length(d) + Run=d{1,m}; + Run=Run(1:end-4) + cellPath=strcat(seqPath,Run); + cells = LoadCells(cellPath , TrackVersion,'AreCells', true, 'Compact', true); + fluorProps = {cells.regionProps}; + fluorProps = cellfun(@fieldnames, fluorProps,'UniformOutput', false); + fluorProps = unique(cat(1,fluorProps{:}))'; + + Plot_Fluorescence3D(cells,ax2,'Cyt','Debris',rand(1,3)); +% BronkBox=cell(length(cells),max([cells.stopT]),length(fluorProps),NumWells); +for k=1:length(fluorProps); + currProp=fluorProps{k}; + Test='MinorAxisLength'; +for j=1:length(cells) + c = cells(j); + t = c.firstFrame : c.lastFrame; + tp=1; + for i=t + BronkBox{j,i,k,m}=cells(1,j).regionProps.(currProp)(tp); + tp=tp+1; + end +end +end +end +empties=cellfun('isempty',BronkBox); +BronkBox(empties) = {NaN}; +Data=cell2mat(BronkBox); +means=mean(Data(:,:,:,:),'omitnan'); +medians=median(Data(:,:,:,:),'omitnan'); +stds=std(Data(:,:,:,:),'omitnan'); +vars=var(Data(:,:,:,:),'omitnan'); +sums=sum(Data(:,:,:,:),'omitnan'); +CVs=stds./means; +figure, ax1 = axes('Position',[0.1 0.1 0.7 0.7]); +% figure, +for n=1:length(d) +PlotWithNan3D(ax1,1:length(d),means(:,:,1,n),means(:,:,6,n)); +% scatter(means(:,:,1,n),means(:,:,6,n)); +hold on +end \ No newline at end of file diff --git a/WriteTest2.m b/WriteTest2.m new file mode 100644 index 0000000..b8a1108 --- /dev/null +++ b/WriteTest2.m @@ -0,0 +1,34 @@ +Bigbox=cell(1,3); +NumWells=3; +for m=0:NumWells-1 + seqPath = 'D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Isa\2021-10-02-BigPRoteinScreen\2021-12-31-TestMultiTimepoint\Baxter\'; + Run=num2str(m,'%05.f'); + seqPath=strcat(seqPath,Run); + cells = LoadCells (seqPath , '_211231_152842','AreCells', true, 'Compact', true); + fluorProps = {cells.regionProps}; + fluorProps = cellfun(@fieldnames, fluorProps,'UniformOutput', false); + fluorProps = unique(cat(1,fluorProps{:}))'; + BronkBox=cell(length(cells),max([cells.stopT])); +for k=1:length(fluorProps) +% k=1:length(fluorProps); + currProp=fluorProps{k}; + Test='MinorAxisLength'; +for j=1:length(cells) + c = cells(j); + t = c.firstFrame : c.lastFrame; + tp=1; + for i=t +% BronkBox{j,i}=cells(1,j).regionProps; + BronkBox{j,i}=cells(1,j).regionProps.(currProp)(tp); + tp=tp+1; + LilBox{k,1}=[BronkBox]; + + Bigbox{1,m+1}=[LilBox]; + end +end +end +LilStruct=cell2struct(LilBox,fluorProps,1); +Bigbox{1,m+1}=[LilStruct]; + Count{1,m+1}=char(Run); +end +% BigStruct=cell2struct(Bigbox,{'zero','One','Tree'},2); \ No newline at end of file diff --git a/WriteTest3.m b/WriteTest3.m new file mode 100644 index 0000000..998642c --- /dev/null +++ b/WriteTest3.m @@ -0,0 +1,75 @@ +% Update seqpath with image location +% Leave trailing slash +seqPath = 'C:\Users\Owner\Dropbox (VU Basic Sciences)\LabConfocalOld\Duvall Lab\Isa\2021-10-11-BigProteinFollowUp\Analysis\Baxter\'; +% Update track number here from BaxterAlgorithms.m GUI +TrackVersion='_220105_121225'; +FilePath=fullfile(seqPath,'Analysis',strcat('CellData',TrackVersion),'Compact'); +a=dir(fullfile(FilePath,'*.mat')); +b={a.name}; +% Rough way of gating / filtering cells by file size (bytes) +HasCells=[a.bytes]; +c=~(HasCells>185); +d=b; +d(c) =[]; + + +figure, ax2 = axes('Position',[0.1 0.1 0.7 0.7]); +for m=1:length(d) + Run=d{1,m}; + Run=Run(1:end-4) + cellPath=strcat(seqPath,Run); % Appends Cell Path + cells = LoadCells (cellPath , TrackVersion,'AreCells', true, 'Compact', true); + fluorProps = {cells.regionProps}; + fluorProps = cellfun(@fieldnames, fluorProps,'UniformOutput', false); + fluorProps = unique(cat(1,fluorProps{:}))'; + + Plot_Fluorescence3D(cells,ax2,'Cyt','Debris',rand(1,3)); + % BronkBox=cell(length(cells),max([cells.stopT]),length(fluorProps),NumWells); +for k=1:length(fluorProps); + currProp=fluorProps{k}; + Test='MinorAxisLength'; +for j=1:length(cells) + c = cells(j); + t = c.firstFrame : c.lastFrame; + tp=1; + for i=t + BronkBox{j,i,k,m}=cells(1,j).regionProps.(currProp)(tp); + tp=tp+1; + end +end +end +end + +% Replaces all BronkBox 'empty' data with NaN +empties=cellfun('isempty',BronkBox); +BronkBox(empties) = {NaN}; + +% Data holds BronkBox in a matrix +% cell2mat converts cell array to one standard array +Data=cell2mat(BronkBox); + +means=mean(Data(:,:,:,:),'omitnan'); +medians=median(Data(:,:,:,:),'omitnan'); +stds=std(Data(:,:,:,:),'omitnan'); +vars=var(Data(:,:,:,:),'omitnan'); +sums=sum(Data(:,:,:,:),'omitnan'); +CVs=stds./means; + +figure, ax1 = axes('Position',[0.1 0.1 0.7 0.7]); +xbar=categorical(d); +ybar=[]; +for n=1:length(d) +<<<<<<< HEAD +% PlotWithNan3D(ax1,n*ones(size(Data(:,:,6,n))),Data(:,:,1,n),Data(:,:,6,n)); +swarmchart(n*ones(size(sums(:,:,6,n))),sums(:,:,1,n)); +ybar=cat(2,ybar,[sums(:,:,1,n)]); +======= +PlotWithNan3D(ax1,n*ones(size(Data(:,:,5,n))),Data(:,:,1,n),Data(:,:,5,n)); +% swarmchart(n*ones(size(sums(:,:,6,n))),sums(:,:,1,n)); + % ybar=cat(2,ybar,[sums(:,:,1,n)]); +% Plot_Fluorescence3D(cells2,ax1,'Drug','Gal',rand(1,3)); +>>>>>>> c1e554047a8962cae6cafd1ca8a96a7c2015188b + + % scatter(means(:,:,1,n),means(:,:,6,n)); +hold on +end \ No newline at end of file diff --git a/WriteTest4.m b/WriteTest4.m new file mode 100644 index 0000000..c5e3539 --- /dev/null +++ b/WriteTest4.m @@ -0,0 +1,64 @@ +seqPath = 'D:\Dropbox (VU Basic Sciences)\Duvall Confocal\Duvall Lab\Brock Fletcher\2021-11-15-Ai9CMAX PRotein Screen\Analysis\Baxter'; +TrackVersion='_220106_115446'; +FilePath=fullfile(seqPath,'Analysis',strcat('CellData',TrackVersion),'Compact'); +a=dir(fullfile(FilePath,'*.mat')); +b={a.name}; +HasCells=[a.bytes]; +blank=~(HasCells>185); +d=b; +d(blank) =[]; + + +ax2 = axes; +for m=1:length(b) + Run=b{1,m}; + Run=Run(1:end-4) + if blank(m) + BronkBox{1,1,1,m}={}; + else + + cellPath=strcat(seqPath,'\',Run); + cells = LoadCells(cellPath, TrackVersion, 'Compact', true); + fluorProps = {cells.regionProps}; + fluorProps = cellfun(@fieldnames, fluorProps,'UniformOutput', false); + fluorProps = unique(cat(1,fluorProps{:}))'; + x_in=m; +% Plot_Fluorescence3D_2(cells,ax2,'c01','c01',rand(1,3),x_in); + hold on +% BronkBox=cell(length(cells),max([cells.stopT]),length(fluorProps),NumWells); +for k=1:length(fluorProps) + currProp=fluorProps{k}; + Test='MinorAxisLength'; +for j=1:length(cells) + c = cells(j); + t = c.firstFrame : c.lastFrame; + tp=1; + for i=t + BronkBox{j,i,k,m}=cells(1,j).regionProps.(currProp)(tp); + tp=tp+1; + end +end +end + end +end +empties=cellfun('isempty',BronkBox); +BronkBox(empties) = {NaN}; +Data=cell2mat(BronkBox); +means=mean(Data(:,:,:,:),'omitnan'); +medians=median(Data(:,:,:,:),'omitnan'); +stds=std(Data(:,:,:,:),'omitnan'); +vars=var(Data(:,:,:,:),'omitnan'); +sums=sum(Data(:,:,:,:),'omitnan'); +CVs=stds./means; +% figure, ax1 = axes('Position',[0.1 0.1 0.7 0.7]); +% % figure, +% xbar=categorical(d); +% ybar=[]; +% for n=1:length(d) +% % PlotWithNan3D(ax1,n*ones(size(Data(:,:,6,n))),Data(:,:,1,n),Data(:,:,6,n)); +% % swarmchart(n*ones(size(sums(:,:,6,n))),sums(:,:,1,n)); +% % ybar=cat(2,ybar,[sums(:,:,1,n)]); +% +% % scatter(means(:,:,1,n),means(:,:,6,n)); +% hold on +% end \ No newline at end of file