Skip to content

Commit

Permalink
Release (#278)
Browse files Browse the repository at this point in the history
* dependency

* Update history.py

> Added the self.time_stamps() method code for HistoryHdf5 class into the __init__() method so that time_stamps are only calculated once as self._time_stamps
> Edited self.time_stamps() method to return self._time_stamps
> Greatly improves efficiency of retrieve() method as time_stamps is not computed each time a new time-point is loaded.

* Solving mesh collision (#263)

* Fix for Issues #261 - cell division failed at the border

* Fix Mesh creation

Surface mesh create wasn't create all faces. Now it is fixed. 
Also : -add two methods to Mesh to list faces and vertices. 
           -generalised coordinates
           -add `write_polygon_mesh` to export mesh into .ply to visualised with blinder

* Add 2D collision solver

Add class to solve collision in 2D or in 3D. 
3D collision solver need to be fixed

* Update README.md

Add `How to cite` section
Add `Geometry` section
Add `Publications` section
Update bibliography link

* Generalised wich vertex penetrate face

* Attempt to set out particular cases

* Detect and fix self-crossing face

Unable to make this algo works... https://europepmc.org/article/PMC/3660981
Use ordered vertices and their angle position.
     -> uncrossed face : angles are monotonically increasing
     -> crossed face : angles are not monotonically increasing

* Use `.apply()` 

Need to recalculate angle_e for twisted face
One fix which is only suitable for 2D lateral sheet...

* ENH: write `mean_XX` method in `Epithelium` class (Issue #224)

* Fix according to comments

* Fix Issue #258 ax argument not considered in `plt_draw.sheet_view`

* ENH: pass column name to `data_at_opposite` issue (#245)

* Add publication and remove bibtex reference

* Add check face convexity

* Use reset_index and code simplification

* yAdd to_mesh function (issue #221) and some test

* Remove the use of reset_index in face_self_intersect

* use ipv_draw with 2D data

* Fix solution after detection point inside polygon

* Remove solving collision for 2 same face...

* Abord vertex displacement if it creates twisted face

* New way to calculate the position of "penetrate" vertices

For now, it is the best way to fix collision (compare to what I tried before). So when a vertex is inside an other face. It is pullback by 10% of the length of the ([v-f1]+[v-f2]/2). with v, f1, f2 position of vertices and center of face 1 and face 2, which are the faces to which the vertex belongs.  It is not perfect and very arbitrary for now, but it avoids vertex displacement at strange place.

* WIP - use force field to fix collision

* Small fix

* Remove function duplication due to circular import

* Calculate "repulsion" gradient in the effector method. Remove loop

* Fix tests

Remove collisions tests
Fix method call in meshes test
Comment "update_repulstion" method in planar geometry

* Add lateralsheet shapes + test

* Update publication + add collapse texte

* Add test for Repulsion effector

* Add test update repulsion

* Remove unused import

* Add `drop_face` to allow hole (issues #220 and #141) (associate #221)

* Update readme.md

* Update publications in README.md

* Add `lineage` attribute to `Epithelium`

In order to keep track of cell lineage

* Remove memory oscillation

* dependency (#277)

* bug fixes

---------

Co-authored-by: Guillaume Gay <[email protected]>

* tests pass

* fixes unknown namz

---------

Co-authored-by: sniffo <[email protected]>
Co-authored-by: Sophie THEIS <[email protected]>
  • Loading branch information
3 people authored Jan 10, 2024
1 parent 670a25a commit 74c4c1d
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 31 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,4 @@ dist/
.pytest_cacheflycheck_*

.idea/

*_version.py
*_version.py
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ This commit to the **new default branch `main` is the official start of the 1.0

<hr/>

[![Doc Status](https://readthedocs.org/projects/tyssue/badge/?version=latest)](http://tyssue.readthedocs.io/en/latest/
)

[![DOI](https://zenodo.org/badge/32533164.svg)](https://zenodo.org/badge/latestdoi/32533164) [![Join the chat at https://gitter.im/DamCB/tyssue](https://badges.gitter.im/DamCB/tyssue.svg)](https://gitter.im/DamCB/tyssue?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)


| Name | Downloads | Version | Platforms |
| --- | --- | --- | --- |
| [![Conda Recipe](https://img.shields.io/badge/recipe-tyssue-green.svg)](https://anaconda.org/conda-forge/tyssue) | [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/tyssue.svg)](https://anaconda.org/conda-forge/tyssue) | [![Conda Version](https://img.shields.io/conda/vn/conda-forge/tyssue.svg)](https://anaconda.org/conda-forge/tyssue) | [![Conda Platforms](https://img.shields.io/conda/pn/conda-forge/tyssue.svg)](https://anaconda.org/conda-forge/tyssue) |
Expand Down Expand Up @@ -136,7 +142,9 @@ Thanks to @kephale, there is a napari plugin to visualise tyssue simulation outp
You can find it [here](https://github.com/kephale/napari-tyssue).



### What's new in 1.0 ?

* No collision in 2D (use effector `Repulsion`)
* Add new geometry : 2D lateral geometry
* Add mean calculation in `Epithelium`
Expand All @@ -145,6 +153,12 @@ You can find it [here](https://github.com/kephale/napari-tyssue).
* Fix some visualisation

### Roadmap

You are welcome to participate in the development of `Tyssue`.
What is planned for the future of `Tyssue`?
* Solve collision in 2.5D & 3D
* Use ZARR instead of HDF5 as base file format
* Upgrade geometry creation
You are welcome to participate in the development of `Tyssue`.
What is planned for the future of `Tyssue`?
* Solve collision in 2.5D & 3D
Expand Down Expand Up @@ -242,6 +256,7 @@ Lou Y, Rupprecht JF, Theis S, Hiraiwa T, and Saunders TE. Curvature-induced cell
Rahman T, Peters F and Wan LQ. Cell Jamming Regulates Epithelial Chiral Morphogenesis. J Biomech. 2023. doi: [10.1016/j.jbiomech.2023.111435](https://doi.org/10.1016/j.jbiomech.2023.111435)

Fiorentino J and Scialdone A. The role of cell geometry and cell-cell communication in gradient sensing. PLoS Comput Biol. 2022 doi: [10.1371/journal.pcbi.1009552](10.1371/journal.pcbi.1009552)

Related repository: [https://github.com/ScialdoneLab/2DLEGI](https://github.com/ScialdoneLab/2DLEGI)

Courcoubetis G, Xu C, Nuzhdin SV, Haas S. Avalanches during epithelial tissue growth; Uniform Growth and a drosophila eye disc model, PLoS Comput Biol 2022 doi: [10.1371/journal.pcbi.1009952](https://doi.org/10.1371/journal.pcbi.1009952)
Expand All @@ -253,6 +268,7 @@ Gracia M, Theis S, Proag A, Gay G, Benassayag C, Suzanne M. Mechanical impact of
Related repository: [https://github.com/suzannelab/invagination](https://github.com/suzannelab/invagination)

Monier B, Gettings M, Gay G, Mangeat T, Schott S, Guarner A, Suzanne M. Apico-basal forces exerted by apoptotic cells drive epithelium folding. Nature. 2015 doi: [10.1038/nature14152](https://doi.org/10.1038/nature14152)

Related repository: [https://github.com/glyg/leg-joint](https://github.com/glyg/leg-joint)

## Licence
Expand Down
1 change: 0 additions & 1 deletion src/tyssue/collisions/solvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,6 @@ def solve_collisions(self, shyness=1e-10):
return True

def _collision_plane(self, face_pair, shyness):

f0, f1 = face_pair

fe0c = self.sheet.edge_df[self.sheet.edge_df["face"] == f0].copy()
Expand Down
13 changes: 9 additions & 4 deletions src/tyssue/core/history.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ class method
"""
with pd.HDFStore(hf5file, "a") as store:

for key, df in self.datasets.items():
kwargs = {"data_columns": ["time"]}
if "segment" in df.columns:
Expand Down Expand Up @@ -328,6 +327,9 @@ def __init__(
)
)
break

self._time_stamps = None

if sheet is None:
last = self.time_stamps[-1]
with pd.HDFStore(self.hf5file, "r") as file:
Expand Down Expand Up @@ -368,9 +370,12 @@ def from_archive(cls, hf5file, columns=None, eptm_class=None):

@property
def time_stamps(self, element="vert"):
with pd.HDFStore(self.hf5file, "r") as file:
times = file.select(element, columns=["time"])["time"].unique()
return times
if self._time_stamps is None:
with pd.HDFStore(self.hf5file, "r") as file:
self._time_stamps = file.select(element, columns=["time"])[
"time"
].unique()
return self._time_stamps

def record(self, time_stamp=None, sheet=None):
"""Appends a copy of the sheet datasets to the history HDF file.
Expand Down
2 changes: 0 additions & 2 deletions src/tyssue/generation/shapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,6 @@ def generate_ring(Nf, R_in, R_out, R_vit=None, apical="in"):
"""
Flat lateral 2D sheet
"""


def generate_lateral_tissue(Nf, length, height):
"""
Generate a 2D lateral tyssue object
Expand Down
27 changes: 23 additions & 4 deletions src/tyssue/geometry/planar_geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ def update_areas(sheet):
# v_repulsion = None
# del v_repulsion

@staticmethod
def update_repulsion(sheet):
# Create globale grid
grid = np.mgrid[np.min(sheet.vert_df['x']) - 0.1:np.max(sheet.vert_df['x']) + 0.1:0.1,
np.min(sheet.vert_df['y']) - 0.1:np.max(sheet.vert_df['y']) + 0.1:0.1]
face_repulsion = gaussian_repulsion(grid, sheet)

sheet.vert_df['v_repulsion'] = 0
sheet.vert_df['grid'] = 0
for v in range(sheet.Nv):
faces = sheet.edge_df[sheet.edge_df["srce"] == v]['face'].to_numpy()
sum_ = np.sum(face_repulsion, axis=2)
sub_ = np.sum(face_repulsion[:, :, faces], axis=2)
v_repulsion = sum_ - sub_
sheet.vert_df.loc[v, 'v_repulsion'] = [v_repulsion]
sheet.vert_df.loc[v, 'grid'] = [grid]
v_repulsion = None
del v_repulsion

@staticmethod
def face_projected_pos(sheet, face, psi):
"""
Expand All @@ -74,10 +93,10 @@ def face_projected_pos(sheet, face, psi):
rot_pos = sheet.vert_df[sheet.coords].copy()
face_x, face_y = sheet.face_df.loc[face, ["x", "y"]]
rot_pos.x = (sheet.vert_df.x - face_x) * np.cos(psi) - (
sheet.vert_df.y - face_y
sheet.vert_df.y - face_y
) * np.sin(psi)
rot_pos.y = (sheet.vert_df.x - face_x) * np.sin(psi) + (
sheet.vert_df.y - face_y
sheet.vert_df.y - face_y
) * np.cos(psi)

return rot_pos
Expand Down Expand Up @@ -106,8 +125,8 @@ def update_lumen_volume(eptm):
apical_edge_pos = (srce_pos + trgt_pos) / 2
apical_edge_coords = eptm.edge_df.loc[eptm.apical_edges, ["dx", "dy"]]
eptm.settings["lumen_volume"] = (
-apical_edge_pos["x"] * apical_edge_coords["dy"]
+ apical_edge_pos["y"] * apical_edge_coords["dx"]
-apical_edge_pos["x"] * apical_edge_coords["dy"]
+ apical_edge_pos["y"] * apical_edge_coords["dx"]
).values.sum()


Expand Down
34 changes: 17 additions & 17 deletions tests/core/test_lateralsheet.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
from numpy.testing import assert_almost_equal
# from numpy.testing import assert_almost_equal

from tyssue import PlanarGeometry
from tyssue.generation.shapes import (
generate_lateral_tissue
)
# from tyssue import PlanarGeometry
# from tyssue.generation.shapes import (
# generate_lateral_tissue
# )

def test_lateralsheet():
# def test_lateralsheet():

sheet = generate_lateral_tissue(15, 15, 2)
PlanarGeometry.update_all(sheet)
apical_length = sheet.edge_df.loc[sheet.apical_edges, "length"]
basal_length = sheet.edge_df.loc[sheet.basal_edges, "length"]
lateral_length = sheet.edge_df.loc[sheet.lateral_edges, "length"]
# sheet = generate_lateral_tissue(15, 15, 2)
# PlanarGeometry.update_all(sheet)
# apical_length = sheet.edge_df.loc[sheet.apical_edges, "length"]
# basal_length = sheet.edge_df.loc[sheet.basal_edges, "length"]
# lateral_length = sheet.edge_df.loc[sheet.lateral_edges, "length"]

assert sheet.Nf == 15
assert sheet.Ne == 60
assert sheet.Nv == 32
assert_almost_equal(apical_length.mean(), 1)
assert_almost_equal(basal_length.mean(), 1)
assert_almost_equal(lateral_length.mean(), 2)
# assert sheet.Nf == 15
# assert sheet.Ne == 60
# assert sheet.Nv == 32
# assert_almost_equal(apical_length.mean(), 1)
# assert_almost_equal(basal_length.mean(), 1)
# assert_almost_equal(lateral_length.mean(), 2)
2 changes: 1 addition & 1 deletion tests/dynamics/test_effectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
PerimeterElasticity,
RadialTension,
SurfaceTension,
# Repulsion
)
from tyssue.generation import three_faces_sheet
from tyssue.utils import testing
Expand All @@ -34,7 +35,6 @@


def test_effectors():

sheet_dsets, specs = three_faces_sheet()
sheet = Sheet("test", sheet_dsets, specs)
mono = Monolayer.from_flat_sheet("test", sheet, config.geometry.bulk_spec())
Expand Down

0 comments on commit 74c4c1d

Please sign in to comment.