%% Figure 8 -- figure supplement 2 % Generates data for panels A, B and C. % figure8supp2.XLSX data file must be in the same directory (experimental data % are read for angle and tension PDFS % Function can be switched to behave like a script ('true'), assigning but % not returning values, or in a standard way ('false'). No input is % implicit 'true'. % =================================================================== %% The calling the 'script' function % ===================================================================== function [varargout] = figure8supp2_source_code(scriptlike) % if called with scriptlike==true, function behaves like a script, returns % nothing and copies results directly into the base workspace if nargin == 0; % without input, function behaves like a script scriptlike = true; end % ======================================================================= % Panel A % read angle and tension measured distributions disp('Reading data from XLSX file'); if ~exist('figure8supp2.xlsx','file') error(strjoin({'File ''figure8supp2.xlsx'' cannot be found.'... 'This file contains source data for this code. Please make sure'... 'the file is accessible and try again'})); end tensionPDF = xlsread('figure8supp2.xlsx',2,'C2:D2001','basic'); anglePDF = xlsread('figure8supp2.xlsx',2,'A2:B2001','basic'); % estimate adhesion parameter S by seeking maximal correlation between data % angle PDF and angle PDF transformed from tension PDF disp(strcat('Estimating adhesion parameter S by maximal correlation between data',... ' angle PDF and angle PDF transformed from tension PDF (corresponds to panel A)')); [ transAnglePDF,~,S] = tensionAngleTransform( tensionPDF, anglePDF ); transAnglePDF(:,1) = transAnglePDF(:,1)*180/pi; % consistently in degrees transAnglePDF(:,2) = transAnglePDF(:,2)*pi/180; if scriptlike disp('Angle PDF obtained by transforming tension PDF was saved as ''transAnglePDF''.'); disp('Estimated adhesion parameter S [pN] was saved in variable ''S'''); end; S=1000*S; % to piconewtons % calculate joint distribution and use it to obtain adhesion distribution % of S; disp(strcat('Estimating adhesion parameter S based on joint PDF of angle and tension (corresponds to panel B and C)')); [AFM, ASM, ADM, ~, ~, adhesionPDF, quantile, jointPDF] = getAdhesionDistribution(anglePDF, tensionPDF, 20); disp(strcat('Mean adhesion is:', num2str(AFM),' pN')); disp(strcat('Adhesion median is:', num2str(quantile(10)), ' pN')); disp(strcat('Adhesion mode is:', num2str(ADM), ' pN')); disp(strcat('Adhesion inetrquartile range is:', '[', num2str(quantile(5)),',',num2str(quantile(15)),'] pN')); if scriptlike disp('Joint PDF was saved (in reduced form) in variable ''jointPDF'''); disp('A contourplot can be generated typing ''contour(jointPDF)'''); disp('Adhesion PDF was saved in variable ''adhesionPDF'''); end % to mimic behaviour of a script; force variables into base workspace if scriptlike assignin('base','tensionPDF',tensionPDF); assignin('base','anglePDF',anglePDF); assignin('base','transAnglePDF',transAnglePDF); assignin('base','adhesionPDF',adhesionPDF); assignin('base','jointPDF',jointPDF); assignin('base','S',S); assignin('base','AFM',AFM); assignin('base','ASM',ASM); assignin('base','ADM',ADM); assignin('base','quantile',quantile); else varargout{1} = tensionPDF; varargout{2} = anglePDF; varargout{3} = transAnglePDF; varargout{4} = adhesionPDF; varargout{5} = jointPDF; varargout{6} = S; varargout{7} = AFM; varargout{8} = ASM; varargout{9} = ADM; varargout{10}= quantile; end end %% The methods section, called by the first 'script' function % ==================================================================== function [ angDst, angDataDst, adh ] = tensionAngleTransform( tenDst, angDataDst ) %TENSIONANGLETRANSFORM Transformation from distribution of tension to % distribution of angles according to a prescribed function % T = ADH/(2(1-cos(ang/2))); The transformation from tensions to angles is % first calculated (transforming coordinates, transforming density using % Jacobian). Then, it is re-binned to conform with experimental angles % distribution (angDataDst), error is calculated, and minimum search run % to find the optimal adhesion parameter. % % tenDst = tension PDF % angDataDst = measured angle PDF % angDst = angle PDF as a transform of tension PDF % adh = adhesion parameter estimated by max. correl. of angDataDst and % angDst % ==================================================================== adh = 0.1; % initial adhesion guess % normalize inputs, if not normalized tenDst(:,1) = tenDst(:,1)/1000; % in nanonewtons tenDstSum = sum(tenDst(:,2)) * (max(tenDst(:,1)-min(tenDst(:,1))))/numel(tenDst(:,1)); tenDst(:,2) = tenDst(:,2)/tenDstSum; angDataDst(:,1) = angDataDst(:,1)*pi/180; % in radians angDataDstSum = sum(angDataDst(:,2)) * (max(angDataDst(:,1))-min(angDataDst(:,1)))/numel(angDataDst(:,1)); angDataDst(:,2) = angDataDst(:,2)/angDataDstSum; % experimental angles distribution; normalized s=size(tenDst,1); % tension data vector length -> calculated angles dist length ds = size(angDataDst,1);% angle data vector length % relAT = @(a) (0.5*adh/(1-cos(a/2))); % angle to tension relation; model = @distDiff; % model for min-search est = fminsearch(model,adh,optimset('MaxIter',100)); % min seach, max 100 iterations % transforms tension distribution into angle distribution using % equation with single parameter (adhesion), which is optimized by % compating the resulting angle distribution with a real distribution % of angles in culture -- order of magnitude estimate function [err,angDst] = distDiff(par) persistent itr; % number of iterations if isempty(itr);itr=0;end; angVar = zeros(s,1); angJac = zeros(s,1); angDst = zeros(s,2); angDstSum = 0; relTA = @(t) (2*acos(max(0,1-0.5*par/t))); % tension to angle relation angJ = @(a) (0.25*par * sqrt(2*(1-cos(a/2))-(1-cos(a/2))^2) / (1-(cos(a/2))^2) ); % jacobian for i=1:s angVar(i) = relTA( tenDst(i,1) ); % get angle corresponding to the given tension angJac(i) = angJ( angVar(i) ); % get jacobian at the given point angDst(i,:) = [angVar(i), tenDst(i,2) * angJac(i)]; if i>1; angDstSum = angDstSum + angDst(i-1,2) * abs(angDst(i-1,1)-angDst(i,1)); end; end angDst(:,2) = angDst(:,2)/angDstSum; % normalize; ang distribution calculated from tension with given adh angDstCopy = angDst(:,1); % copy the angles corresponding to the tensions angDataDst(:,3) = zeros(ds,1); % create one more collumn for the calculated ang data for d=2:size(angDataDst,1) % angle increases; equidistant angle values bin = [angDataDst(d-1,1),angDataDst(d,1)]; for b=numel(angDstCopy):-1:1 % angle increases (inverse ordering) -- from the end so it can be cropped each iteration dot=angDstCopy(b); % angle value at particular coordinate if in(bin,dot) % if the value belongs to the designated bit angDstCopy(b:numel(angDstCopy)) = []; % delete all smaller angles (out of scope) angDataDst(d,3) = angDataDst(d,3) + angDst(b,2); break; end; end end itr = itr+1; CC = corrcoef(angDataDst(:,2), angDataDst(:,3)); err = (1 - CC(1,2))^2; %err = sum(( angDataDst(:,2) - angDataDst(:,3) ).^2); % get error %disp(strcat('Iteration:',num2str(itr),... % ',adhesion estimate is:',num2str(par),' nN,with correlation:',num2str(CC(1,2)))); end % checks if 'dot' belongs into a 'bin'; bin(1) < bin(2) function [is] = in(bin,dot) if dot>=bin(1)&& dot <=bin(2); is=true; else is=false; end end [err,angDst] = model(est); % generate the output disp(strcat('The adhesion estimate is:',num2str(est),' nN, with correlation:',num2str(1-sqrt(err)))); % display what was converget to adh=est; % plot the results plot(angDst(:,1)*180/pi,angDst(:,2)*pi/180,'r-', 'LineWidth',2); xlim([0,180]); hold on; plot(angDataDst(:,1)*180/pi,angDataDst(:,2)*pi/180,'b-','LineWidth',2 ); lh = legend('Transformed distribution','Experimental data'); lh.Box = 'off'; lh.Location = 'northeast'; title('Angle $$\beta$$ distribution','Interpreter','latex'); xlabel('angle $$\beta$$ [$$^{\circ}$$]','Interpreter','latex'); ylabel('PDF($$\beta$$)','Interpreter','latex'); ha = gca; set(ha,'LineWidth',2,'FontSize',18); text(80,0.04,strjoin({'Adhesion estimate: $$S=$$',num2str(round(est*1000)),'pN',... char(10),'distribution correlation:',num2str(round(1-sqrt(err),3))}),'Interpreter','latex','FontSize',18); angDataDst(:,3) = []; end function [AFM, ASM, ADM, ADMindex, DFM, adhHist, quantile, adhDistReduced] = getAdhesionDistribution(angleDist, tensionDist, quantiles) % Calculates the adhesion parameter and it's distribution % Cosiders angle distribution and tension distribution independent, which % they aren't, but since we have no information on their correlation, it is % the best we can do. % angleDist = distribution of angles, first column are angle values in degrees, second % the probabilities. % tensionDist = distribution of tensions, the first column are tension % values, the second their probabilities. % quantiles = number of qunatiles to calculate % returns adhesive parameter: AFM - 1st moment, ASM - standard deviation, % ADM - mode, adhDistReduced - distribution % DFM - angle and tension first moments % adhHist - adhesion PDF % quantile - values for 20 quantiles % ======================================================================== adhDist = zeros(numel(angleDist(:,1)), numel(tensionDist(:,1))); AFM = 0; ASM = 0; dt = 1; dA = 0.1; % distribution is normalized by a sum, not integral. Otherwise, dA = 0.1 DFM = [0,0]; % approximate the joint probability distribution for a=1:numel(angleDist(:,1)) for t=1:numel(tensionDist(:,1)) adhDist(a,t) = angleDist(a,2) * tensionDist(t,2); end end % average - distribution first moment for a=1:numel(angleDist(:,1)) for t=1:numel(tensionDist(:,1)) DFM(2) = DFM(2) + tensionDist(t,1) * adhDist(a,t) * dA * dt; DFM(1) = DFM(1) + angleDist(a,1) * adhDist(a,t) * dA * dt; end end % calculate the adhesion coefficient for a=1:numel(angleDist(:,1)) for t=1:numel(tensionDist(:,1)) AFM = AFM + 2*tensionDist(t,1)*(1-cos(angleDist(a,1) * pi/360)) * adhDist(a,t) * dt * dA; end end % calculate the variance for a=1:numel(angleDist(:,1)) for t=1:numel(tensionDist(:,1)) ASM = ASM + (2*tensionDist(t,1)*(1-cos(angleDist(a,1) * pi/360))-AFM)^2 * adhDist(a,t) * dt * dA; end end ASM = sqrt(ASM); [maxVal,maxInd] = max(adhDist,[],1); [~,ind] = max(maxVal); ADMindex = [maxInd(ind),ind]; % calculate the mode of adhesion ADM = (2*tensionDist(ADMindex(2),1)*(1-cos(angleDist(ADMindex(1),1) * pi/360))); adhHist = zeros(4001,2); adhHist(:,1) = (1:1:4001)'; % calculate adhesion histohram for a=1:numel(angleDist(:,1)) for t=1:numel(tensionDist(:,1)) Si = 2*tensionDist(t,1)*(1-cos(angleDist(a,1) * pi/360)); adhHist( round(Si)+1,2 ) = adhHist( round(Si)+1,2 ) + adhDist(a,t) * dA * dt; end end P = 0; n = quantiles; quantile = zeros(1,n); a = 1; for i=1:4000 P = P + adhHist(i,2); if P > a/n && quantile(a)==0 quantile(a) = i-1; a = a+1; end end quantile(n) = 4000; adhDistReduced = zeros( round(size(adhDist,1)/10), round(size(adhDist,2)/10)); %downsample the distribution so it can be visualized for a=1:size(adhDistReduced,1) for t=1:size(adhDistReduced,2) adhDistReduced(a,t) = sum(sum(adhDist(1+(a-1)*10:a*10, 1+(t-1)*10:t*10))); end end end