Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python

name: Python package

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs:
build:

runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.7"] #["3.7", "3.8", "3.9"]

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
# Display the Python version being used
- name: Display Python version
run: python -c "import sys; print(sys.version)"
# Install the package using the setup.py
- name: Install package
run: pip install git+https://github.com/fabrylab/pyTFM.git
# Install pytest (you can use some other testing utility)
- name: Test with pytest
run: |
pytest test_pyTFM.py
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
[![Python package](https://github.com/martinschatz-cz/pyTFM/actions/workflows/python-package.yml/badge.svg?event=push)](https://github.com/martinschatz-cz/pyTFM/actions/workflows/python-package.yml)

[![Python 3.6](https://img.shields.io/badge/python-3.6-green.svg)]() [![Python 3.7](https://img.shields.io/badge/python-3.7-green.svg)]() [![Python 3.8](https://img.shields.io/badge/python-3.8-red.svg)]() [![Python 3.9](https://img.shields.io/badge/python-3.9-red.svg)]()

## Readme

pyTFM is a python package that allows you to analyze force generation and stresses in cell colonies and confluent cell layers growing on a 2 dimensional surface. This package implements the procedures of [Traction Force Microscopy](https://www.ncbi.nlm.nih.gov/pubmed/11832345) and [Monolayer Stress Microscopy](https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0055172). In addition to the standard measures for stress and force generation, it
also includes the line tension, a measure for the force transfer exclusively across cell-cell boundaries.
pyTFM includes an addon for the image annotation tool [clickpoints](https://clickpoints.readthedocs.io/en/latest/) allowing you to quickly analyze and vizualize large datasets.

Please refer to the [Documentation](https://pytfm.readthedocs.io/en/latest/) of pyTFM for detailed instructions on installation and usage.

## Conda enviroment creation
You need to create python 3.6 enviroment.
```
conda create --name pyTFM python=3.6
conda activate pyTFM
```

Note: python 3.7 works too, but clickpoints need python 3.6.

pyTFM package install
```
pip install git+https://github.com/fabrylab/pyTFM.git
```

If you want to use jupyterlab
```
pip install jupyterlab
jupyter-lab
```
Sometimes it is necessary to reinstall pyTFM again through the JupyterLab because of scikit-image package.
106 changes: 106 additions & 0 deletions test_pyTFM.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import numpy as np
import pytest
import matplotlib.pyplot as plt
import numpy as np
import openpiv.filters
import scipy.fft

from openpiv.pyprocess import extended_search_area_piv
import openpiv.scaling
import openpiv.tools
import openpiv.validation
from matplotlib.colors import LinearSegmentedColormap
from mpl_toolkits.axes_grid1 import make_axes_locatable
from pyTFM.utilities_TFM import suppress_warnings
from scipy.ndimage.filters import median_filter, gaussian_filter
from scipy.ndimage.filters import uniform_filter
from pyTFM.TFM_functions import ffttc_traction
from pyTFM.TFM_functions import get_xy_for_quiver
from pyTFM.TFM_functions import strain_energy_points
from pyTFM.TFM_functions import contractillity

def test_ffttc_traction_output_shape():
# create test inputs
u = np.zeros((10, 10))
v = np.zeros((10, 10))
pixelsize1 = 0.1
pixelsize2 = 0.1
young = 1e6

# call the function
tx_filter, ty_filter = ffttc_traction(u, v, pixelsize1, pixelsize2, young)

# assert that the output shape is as expected
assert tx_filter.shape == (10, 10)
assert ty_filter.shape == (10, 10)

def test_ffttc_traction_output_type():
# create test inputs
u = np.zeros((10, 10))
v = np.zeros((10, 10))
pixelsize1 = 0.1
pixelsize2 = 0.1
young = 1e6

# call the function
tx_filter, ty_filter = ffttc_traction(u, v, pixelsize1, pixelsize2, young)

# assert that the output is of the correct type
assert isinstance(tx_filter, np.ndarray)
assert isinstance(ty_filter, np.ndarray)

def test_ffttc_traction_output_values():
# create test inputs
u = np.zeros((10, 10))
v = np.zeros((10, 10))
pixelsize1 = 0.1
pixelsize2 = 0.1
young = 1e6

# call the function
tx_filter, ty_filter = ffttc_traction(u, v, pixelsize1, pixelsize2, young)

# assert that the output is as expected
assert np.allclose(tx_filter, 0)
assert np.allclose(ty_filter, 0)

def test_ffttc_traction_input_shape():
# create test inputs with incorrect shape
u = np.zeros((10, 10, 10))
v = np.zeros((10, 10))
pixelsize1 = 0.1
pixelsize2 = 0.1
young = 1e6

# assert that a ValueError is raised for incorrect input shape
with pytest.raises(ValueError):
ffttc_traction(u, v, pixelsize1, pixelsize2, young)

def test_ffttc_traction_input_type():
# create test inputs with incorrect type
u = np.zeros((10, 10))
v = "not an array"
pixelsize1 = 0.1
pixelsize2 = 0.1
young = 1e6

# assert that a TypeError is raised for incorrect input type
with pytest.raises(TypeError):
ffttc_traction(u, v, pixelsize1, pixelsize2, young)

########get_xy_for_quiver
def test_get_xy_for_quiver():
u = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
xs, ys = get_xy_for_quiver(u)

# Test the shape of xs and ys
assert np.shape(xs) == np.shape(u)
assert np.shape(ys) == np.shape(u)

# Test the values of xs
for i in range(np.shape(u)[0]):
assert np.array_equal(xs[i, :], np.arange(0, np.shape(u)[1], 1))

# Test the values of ys
for j in range(np.shape(u)[1]):
assert np.array_equal(ys[:, j], np.arange(0, np.shape(u)[0], 1))