diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index e29fb69e..3f8b5059 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -1,6 +1,7 @@
name: Run Python Tests
on:
+ workflow_dispatch:
push:
branches: [ main megha]
pull_request:
diff --git a/.gitignore b/.gitignore
index f9064758..ea40df8d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,7 @@ __pycache__/
# Distribution / packaging
.Python
-build/
+src/pyVertexModel/Kg/build/
develop-eggs/
dist/
downloads/
@@ -186,3 +186,5 @@ data/
.idea/misc.xml
*.db
+
+*.o
diff --git a/.idea/pyVertexModel.iml b/.idea/pyVertexModel.iml
index 8fd60d93..6625830e 100644
--- a/.idea/pyVertexModel.iml
+++ b/.idea/pyVertexModel.iml
@@ -4,7 +4,7 @@
-
+
diff --git a/Tests/test_cell.py b/Tests/test_cell.py
index a0bbaf14..0df14c3b 100644
--- a/Tests/test_cell.py
+++ b/Tests/test_cell.py
@@ -4,7 +4,6 @@
from Tests.tests import Tests, load_data
from src.pyVertexModel.geometry.cell import Cell
-
class TestCell(Tests):
def test_compute_cell_area(self):
geo_test, _, _ = load_data('Geo_var_3x3_stretch.mat')
@@ -78,3 +77,17 @@ def test_copy(self):
self.assertEqual(original_cell.ID, copied_cell.ID)
self.assertTrue(np.array_equal(original_cell.X, copied_cell.X))
self.assertTrue(np.array_equal(original_cell.T, copied_cell.T))
+
+ def test_compute_cell_area_edge_cases(self):
+ geo_test, _, _ = load_data('Geo_var_3x3_stretch.mat')
+
+ # Test with zero-area cells
+ geo_test.Cells[0].X = np.array([[0, 0], [0, 0], [0, 0]]) # Degenerate cell
+ geo_test.Cells[0].compute_area()
+ self.assertEqual(geo_test.Cells[0].Area, 0)
+
+ # Test with very large area
+ geo_test.Cells[1].X = np.array([[1e6, 1e6], [1e7, 1e7], [1e8, 1e8]]) # Extreme values
+ geo_test.Cells[1].compute_area()
+ self.assertTrue(geo_test.Cells[1].Area > 0) # a non-zero area
+
diff --git a/Tests/test_geo.py b/Tests/test_geo.py
index 4fa869a7..5617166c 100644
--- a/Tests/test_geo.py
+++ b/Tests/test_geo.py
@@ -5,6 +5,7 @@
from src.pyVertexModel.algorithm.vertexModelVoronoiFromTimeImage import VertexModelVoronoiFromTimeImage
from src.pyVertexModel.geometry.geo import Geo, get_node_neighbours_per_domain
from src.pyVertexModel.util.utils import load_state, ismember_rows
+from Tests.tests import Tests, load_data, assert_matrix
def check_if_cells_are_the_same(geo_expected, geo_test):
diff --git a/Tests/test_vertexModel.py b/Tests/test_vertexModel.py
index 3229b0c7..9cafd46c 100644
--- a/Tests/test_vertexModel.py
+++ b/Tests/test_vertexModel.py
@@ -8,10 +8,11 @@
from Tests.tests import Tests, assert_matrix, load_data, assert_array1D
from src.pyVertexModel.algorithm import newtonRaphson
from src.pyVertexModel.algorithm.newtonRaphson import newton_raphson
+from src.pyVertexModel.algorithm.vertexModel import create_tetrahedra
from src.pyVertexModel.algorithm.vertexModelBubbles import build_topo, SeedWithBoundingBox, generate_first_ghost_nodes, \
delaunay_compute_entities, VertexModelBubbles
from src.pyVertexModel.algorithm.vertexModelVoronoiFromTimeImage import build_triplets_of_neighs, calculate_neighbours, \
- VertexModelVoronoiFromTimeImage, create_tetrahedra, add_tetrahedral_intercalations, build_2d_voronoi_from_image, \
+ VertexModelVoronoiFromTimeImage, add_tetrahedral_intercalations, build_2d_voronoi_from_image, \
populate_vertices_info, calculate_vertices, get_four_fold_vertices, divide_quartets_neighbours, process_image
from src.pyVertexModel.geometry.degreesOfFreedom import DegreesOfFreedom
from src.pyVertexModel.util.utils import save_backup_vars
@@ -296,7 +297,7 @@ def test_create_tetrahedra(self):
# Test if initialize geometry function does not change anything
Twg_test = create_tetrahedra(traingles_connectivity, neighbours_network, edges_of_vertices, x_internal,
- x_face_ids, x_vertices_ids, x)
+ x_face_ids, x_vertices_ids)
# Check if the test and expected are the same
assert_matrix(Twg_test, mat_info['Twg'])
diff --git a/Tests/tests.py b/Tests/tests.py
index fb1be981..7cfe13e7 100644
--- a/Tests/tests.py
+++ b/Tests/tests.py
@@ -1,15 +1,14 @@
import unittest
-from os.path import exists
-
+import scipy.io
import numpy as np
-import scipy
+from os.path import exists, abspath
from src.pyVertexModel.geometry.geo import Geo
from src.pyVertexModel.parameters.set import Set
-
+from src.pyVertexModel.Kg import kg_functions
def load_data(file_name, return_geo=True):
- test_dir = 'Tests/data/%s' % file_name
+ test_dir = abspath('Tests/data/%s' % file_name)
if exists(test_dir):
mat_info = scipy.io.loadmat(test_dir)
else:
@@ -23,10 +22,8 @@ def load_data(file_name, return_geo=True):
if 'Set' in mat_info.keys():
set_test = Set(mat_info['Set'])
- # Set the output folder to the test directory if it is not set
if set_test.OutputFolder.__eq__(b'') or set_test.OutputFolder is None:
set_test.OutputFolder = '../Result/Test'
-
else:
set_test = None
else:
@@ -40,9 +37,27 @@ def assert_matrix(k_expected, k):
np.testing.assert_allclose(k_expected, k, rtol=1e-3, atol=1e-1)
-def assert_array1D(g_expected, g):
+def assert_array1D(array1, array2):
np.testing.assert_allclose(g_expected, g, rtol=1e-3, atol=1e-1)
class Tests(unittest.TestCase):
- pass
+
+ def test_load_data_geo(self):
+ geo_test, set_test, mat_info = load_data('Geo_3x3_dofs_expected.mat')
+ self.assertIsNotNone(geo_test)
+ self.assertTrue('Geo' in mat_info)
+
+ def test_load_data_set(self):
+ geo_test, set_test, mat_info = load_data('Geo_var_3x3_stretch.mat')
+ self.assertIsNotNone(set_test)
+ self.assertTrue('Set' in mat_info)
+
+ def test_assert_matrix(self):
+ k_expected = np.array([[1, 2], [3, 4]])
+ k = np.array([[1, 2], [3, 4]])
+ assert_matrix(k_expected, k)
+
+ def test_load_data_invalid_file(self):
+ with self.assertRaises(FileNotFoundError):
+ load_data('invalid_file.mat')
diff --git a/pyproject.toml b/pyproject.toml
index d8d0e2a9..7d1f77f8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -15,14 +15,17 @@ dynamic = [
]
dependencies = [
"cython",
- "numpy",
+ "numpy==1.26.4",
"scipy",
"pillow",
"scikit-image",
"cython",
"vtk",
"pandas",
- "networkx"
+ "networkx",
+ "pyvista",
+ "scikit-learn",
+ "matplotlib",
]
[tool.coverage]
diff --git a/src/pyVertexModel/Kg/kg_functions.pyx b/src/pyVertexModel/Kg/kg_functions.pyx
index 3ead78aa..f9ce87a4 100644
--- a/src/pyVertexModel/Kg/kg_functions.pyx
+++ b/src/pyVertexModel/Kg/kg_functions.pyx
@@ -4,6 +4,8 @@ import cython
import numpy as np
cimport numpy as np
+np.import_array()
+
# RUN IT LIKE: python setup.py build_ext --inplace
@cython.wraparound(False)
diff --git a/src/pyVertexModel/analysis/analyse_in_vivo_ablation_data.py b/src/pyVertexModel/analysis/analyse_in_vivo_ablation_data.py
index d1f5a367..18c80609 100644
--- a/src/pyVertexModel/analysis/analyse_in_vivo_ablation_data.py
+++ b/src/pyVertexModel/analysis/analyse_in_vivo_ablation_data.py
@@ -1,4 +1,3 @@
-from datetime import datetime
import os
import numpy as np
diff --git a/src/pyVertexModel/analysis/analyse_results_excel.py b/src/pyVertexModel/analysis/analyse_results_excel.py
index 4e01d8d3..cd4dea06 100644
--- a/src/pyVertexModel/analysis/analyse_results_excel.py
+++ b/src/pyVertexModel/analysis/analyse_results_excel.py
@@ -1,8 +1,6 @@
-import numpy as np
+import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
-import matplotlib.pyplot as plt
-from scipy.interpolate import griddata
# Read excel into a pandas dataframe
results_excel = pd.read_excel('data/simulations_results/all_files_features.xlsx')
diff --git a/src/pyVertexModel/analysis/analyse_simulation.py b/src/pyVertexModel/analysis/analyse_simulation.py
index 1c38ea1f..64f44370 100644
--- a/src/pyVertexModel/analysis/analyse_simulation.py
+++ b/src/pyVertexModel/analysis/analyse_simulation.py
@@ -1,7 +1,7 @@
import os
import pickle
-import cv2
+import cv2
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
diff --git a/src/pyVertexModel/analysis/analyse_simulations.py b/src/pyVertexModel/analysis/analyse_simulations.py
index 85e810fc..1fb60e01 100644
--- a/src/pyVertexModel/analysis/analyse_simulations.py
+++ b/src/pyVertexModel/analysis/analyse_simulations.py
@@ -3,8 +3,7 @@
import numpy as np
import pandas as pd
-from src.pyVertexModel.analysis.analyse_simulation import analyse_simulation, analyse_edge_recoil, create_video
-from src.pyVertexModel.util.utils import save_variables, load_variables
+from src.pyVertexModel.analysis.analyse_simulation import analyse_simulation, create_video
folder = '/media/pablo/d7c61090-024c-469a-930c-f5ada47fb049/PabloVicenteMunuera/VertexModel/pyVertexModel/Result/final_results'
all_files_features = []
diff --git a/src/pyVertexModel/geometry/geo.py b/src/pyVertexModel/geometry/geo.py
index ae6191e3..a231ec42 100644
--- a/src/pyVertexModel/geometry/geo.py
+++ b/src/pyVertexModel/geometry/geo.py
@@ -3,9 +3,7 @@
import numpy as np
import vtk
-from numpy.ma.extras import setxor1d
from scipy.spatial import ConvexHull
-from torch.fx.experimental.unification.unification_tools import get_in
from src.pyVertexModel.Kg.kg import add_noise_to_parameter
from src.pyVertexModel.geometry import face, cell
@@ -797,6 +795,8 @@ def check_ys_and_faces_have_not_changed(self, new_tets, old_tets, old_geo):
assert np.all(self.Cells[cell_id].Faces[id_with_new_index].Centre == c_face.Centre)
+
+
def add_and_rebuild_cells(self, old_geo, old_tets, new_tets, y_new, c_set, update_measurements):
"""
Add and rebuild the cells
diff --git a/src/pyVertexModel/mesh_remodelling/remodelling.py b/src/pyVertexModel/mesh_remodelling/remodelling.py
index 641e5711..3dd5aa0f 100644
--- a/src/pyVertexModel/mesh_remodelling/remodelling.py
+++ b/src/pyVertexModel/mesh_remodelling/remodelling.py
@@ -5,8 +5,7 @@
import pandas as pd
from numpy.ma.extras import setdiff1d
-from src.pyVertexModel.algorithm.newtonRaphson import gGlobal, newton_raphson_iteration_explicit
-from src.pyVertexModel.geometry.cell import face_centres_to_middle_of_neighbours_vertices
+from src.pyVertexModel.algorithm.newtonRaphson import gGlobal
from src.pyVertexModel.geometry.face import get_interface
from src.pyVertexModel.geometry.geo import edge_valence, get_node_neighbours_per_domain, get_node_neighbours
from src.pyVertexModel.mesh_remodelling.flip import y_flip_nm, post_flip
diff --git a/src/pyVertexModel/parameters/set.py b/src/pyVertexModel/parameters/set.py
index 2046dcaa..f8a21296 100644
--- a/src/pyVertexModel/parameters/set.py
+++ b/src/pyVertexModel/parameters/set.py
@@ -220,15 +220,15 @@ def update_derived_parameters(self):
current_datetime = datetime.now()
new_outputFolder = ''.join([PROJECT_DIRECTORY, '/Result/', str(current_datetime.strftime("%m-%d_%H%M%S_")),
- 'noise_', '{:0.2e}'.format(self.noise_random), '_bNoise_', '{:0.2e}'.format(self.brownian_motion_scale),
- '_lVol_', '{:0.2e}'.format(self.lambdaV), '_refV0_', '{:0.2e}'.format(self.ref_V0),
- '_kSubs_', '{:0.2e}'.format(self.kSubstrate),
- '_lt_', '{:0.2e}'.format(self.cLineTension),
- '_refA0_', '{:0.2e}'.format(self.ref_A0),
- '_eARBarrier_', '{:0.2e}'.format(self.lambdaR),
- '_RemStiff_', str(self.RemodelStiffness), '_lS1_', '{:0.2e}'.format(self.lambdaS1),
- '_lS2_', '{:0.2e}'.format(self.lambdaS2), '_lS3_', '{:0.2e}'.format(self.lambdaS3),
- '_ps_', '{:0.2e}'.format(self.purseStringStrength), '_lc_', '{:0.2e}'.format(self.lateralCablesStrength)])
+ 'noise_', '{:0.2e}'.format(self.noise_random), '_bNoise_', '{:0.2e}'.format(self.brownian_motion_scale),
+ '_lVol_', '{:0.2e}'.format(self.lambdaV), '_refV0_', '{:0.2e}'.format(self.ref_V0),
+ '_kSubs_', '{:0.2e}'.format(self.kSubstrate),
+ '_lt_', '{:0.2e}'.format(self.cLineTension),
+ '_refA0_', '{:0.2e}'.format(self.ref_A0),
+ '_eARBarrier_', '{:0.2e}'.format(self.lambdaR),
+ '_RemStiff_', str(self.RemodelStiffness), '_lS1_', '{:0.2e}'.format(self.lambdaS1),
+ '_lS2_', '{:0.2e}'.format(self.lambdaS2), '_lS3_', '{:0.2e}'.format(self.lambdaS3),
+ '_ps_', '{:0.2e}'.format(self.purseStringStrength), '_lc_', '{:0.2e}'.format(self.lateralCablesStrength)])
self.define_if_not_defined("OutputFolder", new_outputFolder)
def stretch(self):
@@ -320,7 +320,7 @@ def wing_disc(self):
self.lambdaS4 = self.lambdaS2
# VTK
- self.VTK = False
+ self.VTK = True
# Implicit vs Explicit
self.implicit_method = False
@@ -337,7 +337,7 @@ def wound_default(self):
self.debris_contribution = np.finfo(float).eps
# =========================== Contractility ==========================
self.Contractility = True
- self.TypeOfPurseString = 0
+ self.TypeOfPurseString = 2
# 0: Intensity-based purse string
# 1: Strain-based purse string (delayed)
# 2: Fixed with linear increase purse string
diff --git a/src/pyVertexModel/util/space_exploration.py b/src/pyVertexModel/util/space_exploration.py
index 2ee730b7..c1e8eb51 100644
--- a/src/pyVertexModel/util/space_exploration.py
+++ b/src/pyVertexModel/util/space_exploration.py
@@ -12,6 +12,7 @@
from src.pyVertexModel.parameters.set import Set
from src.pyVertexModel.util.utils import load_state, load_variables, save_variables
+
def objective(trial):
"""
Objective function to minimize
diff --git a/src/pyVertexModel/util/utils.py b/src/pyVertexModel/util/utils.py
index b428c6bd..e1ed7f00 100644
--- a/src/pyVertexModel/util/utils.py
+++ b/src/pyVertexModel/util/utils.py
@@ -6,8 +6,8 @@
import pickle
import imageio
-import pyvista as pv
import numpy as np
+import pyvista as pv
from scipy.optimize import fsolve