Integrated Analysis of Cell Shape and Movement in Moving Frame

Environment Setting

# Add necessary packages
pkg"add  GaussianProcesses Conda"
13.4s
Julia
# Add python package igl from conda-forge as one of MovingFrame dependency
using Conda
Conda.add("igl";channel="conda-forge")
48.6s
Julia
# Add MovingFrame package from github repository
pkg"add https://github.com/yusri-dh/MovingFrame.jl"
pkg"precompile"
208.3s
Julia

Data extraction

cell_shape_final.tar.gz
38.73 MB
tar -xzvf 
cell_shape_final.tar.gz
2.2s
Bash in Julia

Experiment

using MovingFrame;
using GeometryBasics
using FileIO
using LinearAlgebra;
using GaussianProcesses;
import Plots;
const mva = MovingFrame
const plt = Plots
61.9s
Julia
# Create MovingCells Type
struct MovingCells
    coordinates::Matrix{Float64}
    time::Vector{Float64}
    smooth_n_points::Int64
    smooth_coordinates::Matrix{Float64}
    smooth_time::Vector{Float64}
    T::Matrix{Float64}
    N::Matrix{Float64}
    B::Matrix{Float64}
    curvature::Vector{Float64}
    torsion::Vector{Float64}
    speed::Vector{Float64}
    original_shapes::Vector{GeometryBasics.Mesh}
    reoriented_shapes::Vector{GeometryBasics.Mesh}
    Spharm_Cx::Matrix{Float64}
    Spharm_Cy::Matrix{Float64}
    Spharm_Cz::Matrix{Float64}
end
0.2s
Julia
const base_dir = pwd();
# You need to extract the cell_shape_final.zip first
const input_data_dir = joinpath(base_dir, "cell_shape_final/")
const input_files = readdir(input_data_dir);
const n_points = length(input_files)
0.2s
Julia
# Calculating the cell trajectory
coordinate = Matrix{Float64}(undef, n_points, 3)
time = collect(1.0:n_points)
shapes = Vector{GeometryBasics.Mesh}(undef, n_points)
for i = 1:length(input_files)
    shape = load(joinpath(input_data_dir, input_files[i]))
    shapes[i] = shape
    verts = decompose(Point3f0, shape)
    # The trajectory is the mass centre of the cell
    coordinate[i, :] .= reduce(+, verts) / length(verts)
end
# Normalizing volume and translation
shapes = (volume_normalizing  mesh_centering).(shapes)
new_coordinate = coordinate .- coordinate[1, :]';
36.0s
Julia
exp_lengthscale = 3.4 # lengthscale = e^3.4
exp_variance= 0.0 #variance = e^0.0
# Gaussian Processs using Zero mean function and 
# Squared exponential kernel (note that hyperparameters are on the log scale)
smoother =  GaussianProcessSmoother(MeanZero(), SE(exp_lengthscale, exp_variance))
smooth_coordinates = smoothing(new_coordinate, smoother, step=1.)
smooth_time = range(1.0, stop=time[end], length=size(smooth_coordinates, 1)) |> collect
T, N, B, curvature, torsion, speed = parallel_transport(smooth_coordinates);
15.9s
Julia
# Reoriented the cell shape to the Moving Frame basis
reoriented_shape = [
    mesh_reorientation(shapes[i], T[i, :], N[i, :], B[i, :])
    for i in eachindex(shapes)
];
2.8s
Julia
# Spherical parameterization
spheres = MovingFrame.spherization.(reoriented_shape, n_step=100);
468.7s
Julia
# Calculating spherical harmonics coefficients
spharm_coefs = [
    MovingFrame.spharm_descriptor(
        reoriented_shape[i],
        GeometryBasics.coordinates(spheres[i]),
    ) for i in eachindex(reoriented_shape)
]
Cx = MovingFrame.array_of_array_to_matrix([coef[:Cx] for coef in spharm_coefs])
Cy = MovingFrame.array_of_array_to_matrix([coef[:Cy] for coef in spharm_coefs])
Cz = MovingFrame.array_of_array_to_matrix([coef[:Cz] for coef in spharm_coefs])
22.9s
Julia
xy_ecc = Cx[:, 4] ./ Cy[:, 2]
xz_ecc = Cx[:, 4] ./ Cz[:, 3]
yz_ecc = Cy[:, 2] ./ Cz[:, 3]
1.0s
Julia
plt.plot(smooth_coordinates[:,1],smooth_coordinates[:,2],smooth_coordinates[:,3],label ="SMOOTH_TRAJECTORY")
plt.scatter!(new_coordinate[:,1],new_coordinate[:,2],new_coordinate[:,3],label ="OBSERVATION",markersize=1.0)
27.4s
Julia
plt.plot(smooth_time,[xy_ecc xz_ecc],label=["XY Eccentricity" "XZ Eccentricity"])
1.9s
Julia
begin
	p1 = plt.plot(smooth_time,speed,ylabel = "Speed")
	p2 = plt.plot(smooth_time,curvature,ylabel = "Curvature",)
	p3 = plt.plot(smooth_time,torsion,ylabel="Torsion",)
	plt.plot(p1,p2,p3,legend=false)
end
1.5s
Julia
Runtimes (1)