iMechanica - grid
https://imechanica.org/taxonomy/term/6286
enSimple Cell Traction Force Script for Elastic Micropatterned Substrata
https://imechanica.org/node/10299
<div class="field field-name-taxonomy-vocabulary-6 field-type-taxonomy-term-reference field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/taxonomy/term/962">software</a></div></div></div><div class="field field-name-taxonomy-vocabulary-8 field-type-taxonomy-term-reference field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/taxonomy/term/1417">Matlab</a></div><div class="field-item odd"><a href="/taxonomy/term/1602">cell mechanics</a></div><div class="field-item even"><a href="/taxonomy/term/1979">traction forces</a></div><div class="field-item odd"><a href="/taxonomy/term/6285">micropattern</a></div><div class="field-item even"><a href="/taxonomy/term/6286">grid</a></div></div></div><div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>
Hi readers,
</p>
<p>
This is MATLAB code that was written by myself and collaborators that we've sought to make available to the wider research community. The program is intended to track the displacements of micropatterned dots on a substrate in a similar manner to that performed by Maloney et al. in "Influence of Finite Thickness on cellular adhesion-induced deformation of an compliant substrata". Physical Review E. 2008.
</p>
<p>
The program is only intended to be for MATLAB and uses programs from other members of the research/MATLAB community to track the displacements of labeled "spots" on a surface of a substrate, sufficiently spaced (approx 5um or greater) so that they do not interfere with eachother. We hope to eventually incorporate a number of other details, such as the application of forces that will influence neighboring points or for points that are more closely spaced than 5um and to increase the level of automation the program has.
</p>
<p>
Thanks for reading and trying it out! Please leave suggestions if you have any. We will post a link to the article, demonstrating the technique and methods on how to apply it once it's published.
</p>
<p>
</p>
<p>
%%Script for Traction Force Calculations Made on an Elastic Gel%%%
</p>
<p>
%%Version 5.0 - Written and Contributions by: Samuel Polio, Katheryn Rothenberg, Dimitrije Stamenovic, and Michael Smith
</p>
<p>
%%Boston University, Deparment of Biomedical Engineering
</p>
<p>
%%
</p>
<p>
</p>
<p>
%uncomment for clearing everything before calculating
</p>
<p>
% close all;
</p>
<p>
% clear;
</p>
<p>
m = [];
</p>
<p>
pk = [];
</p>
<p>
cnt = [];
</p>
<p>
a = [];
</p>
<p>
b = [];
</p>
<p>
pos = [];
</p>
<p>
</p>
<p>
%Note that values need to be entered with YOUR parameters, please adjust accordingly where the XX's are
</p>
<p>
mcircle_dia = XX; %maximum circle diameter in um
</p>
<p>
post_dist = XX; %distance between posts in um
</p>
<p>
pixel_ratio = XX; %number of um per pixel
</p>
<p>
pixel_dia = round(mcircle_dia / pixel_ratio); %max diameter of pixels for circle
</p>
<p>
pix_post_dist = post_dist/pixel_ratio; %distance between posts in pixels
</p>
<p>
</p>
<p>
%Get the dot file!
</p>
<p>
initial_file = uigetfile('*.tif','Pick The Dot File');
</p>
<p>
</p>
<p>
%read in .tif file
</p>
<p>
initial_image = double(imread(initial_file, 'tif'));
</p>
<p>
%display the image
</p>
<p>
colormap(gray);
</p>
<p>
imagesc(initial_image);
</p>
<p>
</p>
<p>
%please freezeColors from:
</p>
<p>
%<a href="http://www.mathworks.com/matlabcentral/fileexchange/7943-freezecolors-unfreezecolors">http://www.mathworks.com/matlabcentral/fileexchange/7943-freezecolors-unfreezecolors</a>
</p>
<p>
freezeColors
</p>
<p>
</p>
<p>
%georgetown macros... please obtain from <a href="http://physics.georgetown.edu/matlab/">http://physics.georgetown.edu/matlab/</a>
</p>
<p>
bp = bpass(initial_image,5,pixel_dia); %bandpass image to remove background
</p>
<p>
m = max(max(bp))*.1; % Percent of the brightest feature estimate
</p>
<p>
pk = pkfnd(bp, m, pixel_dia); %find all peak locations
</p>
<p>
cnt = cntrd(bp,pk,pixel_dia+2); %accurately locate peak centroid
</p>
<p>
</p>
<p>
hold;
</p>
<p>
plot(cnt(:,1),cnt(:,2),'x');
</p>
<p>
</p>
<p>
figure
</p>
<p>
plot(cnt(:,1),cnt(:,2),'x');
</p>
<p>
</p>
<p>
</p>
<p>
%selecting points on plot for the corners
</p>
<p>
datacursormode on;
</p>
<p>
fig_handle = gcf;
</p>
<p>
hold on;
</p>
<p>
pos = zeros(4,2);
</p>
<p>
for i=1:4,
</p>
<p>
choice = menu('Press Enter After Selecting Point','Enter');
</p>
<p>
while choice==0
</p>
<p>
choice = menu('Press Enter After Selecting Point','Enter');
</p>
<p>
end
</p>
<p>
% pause();
</p>
<p>
dcm_obj = datacursormode(fig_handle);
</p>
<p>
info = getCursorInfo(dcm_obj);
</p>
<p>
pos(i,1) = info.Position(1);
</p>
<p>
pos(i,2) = info.Position(2);
</p>
<p>
plot(pos(i,1),pos(i,2),'rx');
</p>
<p>
end
</p>
<p>
</p>
<p>
%putting the 4 corners into the program... Find this program below
</p>
<p>
[x,y]=FourCorners(pos(1,:),pos(2,:),pos(3,:),pos(4,:));
</p>
<p>
</p>
<p>
%setting time to 0 and 1 so that the program knows which dots to connect
</p>
<p>
xy = [x,y];
</p>
<p>
xy(:,3) = 1;
</p>
<p>
</p>
<p>
cnt(:,3)=[];
</p>
<p>
cnt(:,3)=0;
</p>
<p>
</p>
<p>
t_pos = [cnt;xy];
</p>
<p>
tracked = track(t_pos, 30);
</p>
<p>
</p>
<p>
count = 0;
</p>
<p>
for i = 1: (length(tracked)-1)
</p>
<p>
if tracked(i,4) == tracked (i+1,4)
</p>
<p>
count = count+1;
</p>
<p>
p1(count,1) = tracked(i,1);
</p>
<p>
p1(count,2) = tracked(i,2);
</p>
<p>
p2(count,1) = tracked(i+1,1);
</p>
<p>
p2(count,2) = tracked(i+1,2);
</p>
<p>
end
</p>
<p>
end
</p>
<p>
</p>
<p>
%"Error" is if there is no displacement, but one can concieve of it to be the
</p>
<p>
% magnitudes of the displacements
</p>
<p>
error = sqrt((p1(:,1)-p2(:,1)).^2+(p1(:,2)-p2(:,2)).^2);
</p>
<p>
</p>
<p>
cell_image_file = uigetfile('*.tif','Pick The Dot File', 'F:\03_30_11'); %plotting image for the cell with arrows
</p>
<p>
</p>
<p>
%display the figure
</p>
<p>
figure;
</p>
<p>
colormap('gray')
</p>
<p>
%uncomment ONE of the following at a time to show the forces
</p>
<p>
%for displaying the dot displacement, uncomment
</p>
<p>
imagesc(double(imread(initial_file)))
</p>
<p>
%for displaying the displacement on the brightfield image, uncomment
</p>
<p>
%imagesc(double(imread(initial_file)))
</p>
<p>
hold;
</p>
<p>
freezeColors
</p>
<p>
</p>
<p>
A = p1 - p2; %displacements for the image
</p>
<p>
</p>
<p>
thresh2 = 0; %threshold displacement of dots in pixels
</p>
<p>
under = find(error < thresh2); %locating the points under the threshold to set to 0
</p>
<p>
</p>
<p>
for i = 1:length(under),
</p>
<p>
A(under(i),1) = 0;
</p>
<p>
A(under(i),2) = 0;
</p>
<p>
end
</p>
<p>
</p>
<p>
colormap('jet')
</p>
<p>
%forces are shown at the final position and scaled, if you put the dot at
</p>
<p>
%the initial position (p2), then unscale with quiverc(x,y,u1,u2,0), you can show
</p>
<p>
%the actual displacements of the dots
</p>
<p>
%quiverc from Bertrand Dano, <a href="http://www.mathworks.com/matlabcentral/fileexchange/3225-quiverc">http://www.mathworks.com/matlabcentral/fileexchange/3225-quiverc</a>
</p>
<p>
quiverc(p1(:,1), p1(:,2), A(:,1), A(:,2));
</p>
<p>
</p>
<p>
%Get force/displacement vectors magnitudes
</p>
<p>
Disp = error*pixel_ratio;
</p>
<p>
</p>
<p>
%Force magnitudes from gel mechanical data
</p>
<p>
%Calculate the spring constant from Maloney et al. "Influence of Finite Thickness
</p>
<p>
%on cellular adhesion-induced deformation of compliant substrata". Physical Review E. 2008.
</p>
<p>
%For larger dots or dots that interfere with each other even though they
</p>
<p>
%are not being pulled on, different parameters need to be used
</p>
<p>
nu = XX;%Poisson's Ratio
</p>
<p>
dot_radius = XX; %meters
</p>
<p>
Elastic_mod = XX; %pascals
</p>
<p>
k = pi()*(Elastic_mod*dot_radius)/((1+nu)*(2-nu));%spring constant of gel in N/m
</p>
<p>
k_nano = k*10^3; %spring constant in nN/um
</p>
<p>
Force = Disp*k_nano;%nN
</p>
<p>
</p>
<p>
%Vectors for the force and displacement
</p>
<p>
D_Vec = A*pixel_ratio;
</p>
<p>
F_Vec = D_Vec*k_nano;
</p>
<p>
</p>
<p>
%%SETTING UP PLOT AXES%%
</p>
<p>
N = 5;
</p>
<p>
max_F = max(Force); %max total Force and cell number, can change to displacement to show that as well.
</p>
<p>
sep = max_F/N; %separation between ticks - (denominator) - 1
</p>
<p>
</p>
<p>
%Hard-coded axis labels
</p>
<p>
num1 = num2str(0,'%6.2f');
</p>
<p>
num2 = num2str(sep,'%6.2f');
</p>
<p>
num3 = num2str(sep*2,'%6.2f');
</p>
<p>
num4 = num2str(sep*3,'%6.2f');
</p>
<p>
num5 = num2str(sep*4,'%6.2f');
</p>
<p>
num6 = num2str(sep*5,'%6.2f');
</p>
<p>
</p>
<p>
hcb = colorbar('YTickLabel', {num1,num2,num3,num4,num5,num6});
</p>
<p>
</p>
<p>
cax_vals = caxis;
</p>
<p>
</p>
<p>
cax_width = (cax_vals(2)-cax_vals(1))/5;
</p>
<p>
</p>
<p>
set(hcb,'YTick', [cax_vals(1),cax_vals(1)+cax_width,cax_vals(1)+2*cax_width...
</p>
<p>
cax_vals(1)+3*cax_width,cax_vals(1)+4*cax_width,cax_vals(1)+5*cax_width]);
</p>
<p>
%%END PROGRAM %%
</p>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
FourCorners.m
</p>
<p>
</p>
<p>
function [Xf Yf] = FourCorners(pos1, pos2, pos3, pos4, distance)
</p>
<p>
</p>
<p>
%The function FourCorners takes in 4 sets of xy pairs representing the 4
</p>
<p>
%corners of a grid of dots. The idea is to use these 4 corners to calibrate
</p>
<p>
%the distance between the dots in 2 orthogonal axes. Program needs a slight tile to work properly.
</p>
<p>
%distance = distance in pixels between dots
</p>
<p>
</p>
<p>
%Find the corners
</p>
<p>
P = [pos1; pos2; pos3; pos4];
</p>
<p>
</p>
<p>
dist = zeros(length(P)-1,1);
</p>
<p>
i=1;
</p>
<p>
%finding the distance between each point, the longest distance between 2
</p>
<p>
%points will be on a diagonal and used to not knock out the pairing between
</p>
<p>
%the first point and that one when drawing the grid
</p>
<p>
for i = 2:(length(P))
</p>
<p>
j = i-1;
</p>
<p>
dist(j,1) = i;
</p>
<p>
dist(j,2) = sqrt((P(1,1)-P(i,1))^2+(P(1,2)-P(i,2))^2);
</p>
<p>
end
</p>
<p>
</p>
<p>
[~,ma] = max(dist(:,2)); %on diagonal
</p>
<p>
[~,mi] = min(dist(:,2)); %value don't want to use for next one
</p>
<p>
</p>
<p>
%find the longest distance not on the diagonal to get the best average
</p>
<p>
%along the length
</p>
<p>
for i = 1:length(dist),
</p>
<p>
if dist(i,2) ~= max(dist(:,2)) && dist(i,2) ~= min(dist(:,2));
</p>
<p>
conn = dist(i,1);
</p>
<p>
end
</p>
<p>
end
</p>
<p>
</p>
<p>
set1 = [pos1;P(conn,:)]; %arrange data into sets for theoretically parallel lines
</p>
<p>
set2 = [P(dist(mi,1),:); P(dist(ma,1),:)];
</p>
<p>
</p>
<p>
%get equations for both lines
</p>
<p>
s1 = polyfit(set1(:,1),set1(:,2),1);
</p>
<p>
s2 = polyfit(set2(:,1),set2(:,2),1);
</p>
<p>
</p>
<p>
%manual input
</p>
<p>
%ask user number of dots between the points
</p>
<p>
s = sprintf('How many spots are between points %d,%d and %d,%d?\n',...
</p>
<p>
set1(1,1), set1(1,2),set1(2,1), set1(2,2));
</p>
<p>
num_parallel = input(s);
</p>
<p>
</p>
<p>
%automatic input
</p>
<p>
%num_s = sqrt((set1(1,1)-set1(2,1)).^2 +(set1(1,2)-set1(2,2)).^2);
</p>
<p>
%num_p = (num_s)/distance;
</p>
<p>
%num_parallel = round(num_p);
</p>
<p>
</p>
<p>
%calculate the x separation between the points on the parallel lines
</p>
<p>
total_d_parallel_1x = set1(1,1)-set1(2,1);
</p>
<p>
sep_parallel_1x = abs(total_d_parallel_1x / (num_parallel+1));
</p>
<p>
</p>
<p>
total_d_parallel_2x = set2(1,1)-set2(2,1);
</p>
<p>
sep_parallel_2x = abs(total_d_parallel_2x / (num_parallel+1));
</p>
<p>
</p>
<p>
</p>
<p>
</p>
<p>
%Preallocating for speed...
</p>
<p>
x1 = zeros(num_parallel+2,1);
</p>
<p>
y1 = zeros(num_parallel+2,1);
</p>
<p>
x2 = zeros(num_parallel+2,1);
</p>
<p>
y2 = zeros(num_parallel+2,1);
</p>
<p>
</p>
<p>
%"draw" grid points along each parallel line to dot first line
</p>
<p>
for i = 1:num_parallel+2,
</p>
<p>
if set1(1,1)<set1(2,1) %start a point from the left and go to the right
</p>
<p>
x1(i) = set1(1,1)+(i-1)*sep_parallel_1x;
</p>
<p>
y1(i) = s1(1)*x1(i)+s1(2);
</p>
<p>
elseif set1(1,1)>set1(1,2)
</p>
<p>
%go backwards if it's not right
</p>
<p>
x1(i) = set1(1,1)-(i-1)*sep_parallel_1x;
</p>
<p>
y1(i) = s1(1)*x1(i)+s1(2);
</p>
<p>
end
</p>
<p>
end
</p>
<p>
</p>
<p>
%"draw" grid points along each parallel line to dot second line
</p>
<p>
for i = 1:num_parallel+2,
</p>
<p>
if set2(1,1)<set2(2,1) %start a point from the left and go to the right
</p>
<p>
x2(i) = set2(1,1)+(i-1)*sep_parallel_2x;
</p>
<p>
y2(i) = s2(1)*x2(i)+s2(2);
</p>
<p>
elseif set2(1,1)>set2(1,2)
</p>
<p>
%go backwards if it's not right
</p>
<p>
x2(i) = set2(1,1)-(i-1)*sep_parallel_2x;
</p>
<p>
y2(i) = s2(1)*x2(i)+s2(2);
</p>
<p>
end
</p>
<p>
end
</p>
<p>
</p>
<p>
%manual calculate the number of dots to put between
</p>
<p>
s = sprintf('How many spots are between points %d,%d and %d,%d?\n',...
</p>
<p>
set1(1,1), set1(1,2),set2(1,1), set2(1,2));
</p>
<p>
num_perp = input(s);
</p>
<p>
</p>
<p>
%automatic input
</p>
<p>
%num_perp = round((sqrt((set1(1,1)-set2(1,1))^2 +(set1(1,2)-set2(1,2))^2))/distance);
</p>
<p>
</p>
<p>
Xf = [];
</p>
<p>
Yf = [];
</p>
<p>
</p>
<p>
for i = 1:length(x1)
</p>
<p>
s = polyfit([x1(i);x2(i)],[y1(i);y2(i)],1);
</p>
<p>
sep_perp_x = abs((x1(i)-x2(i))/(num_perp+1));
</p>
<p>
</p>
<p>
for k = 1:num_perp+2,
</p>
<p>
if x1(i)<x2(i) %start a point from the left and go to the right
</p>
<p>
X(k) = x1(i)+(k-1)*sep_perp_x;
</p>
<p>
Y(k) = s(1)*X(k)+s(2);
</p>
<p>
elseif x1(i)>x2(i)
</p>
<p>
%go backwards if it's not right
</p>
<p>
X(k) = x1(i)-(k-1)*sep_perp_x;
</p>
<p>
Y(k) = s(1)*X(k)+s(2);
</p>
<p>
end
</p>
<p>
end
</p>
<p>
</p>
<p>
Xf = [Xf;X'];
</p>
<p>
Yf = [Yf;Y'];
</p>
<p>
end
</p>
<p>
</p>
<p>
end
</p>
<p>
</p>
<p>
</p>
</div></div></div>Mon, 16 May 2011 19:40:49 +0000srp21510299 at https://imechanica.orghttps://imechanica.org/node/10299#commentshttps://imechanica.org/crss/node/10299Error | iMechanica