Skip to content
Merged
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
87 changes: 84 additions & 3 deletions Tests/test_vertexModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
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, 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.algorithm.vertexModelVoronoiFromTimeImage import build_triplets_of_neighs, \
VertexModelVoronoiFromTimeImage, add_tetrahedral_intercalations, \
get_four_fold_vertices, divide_quartets_neighbours, process_image
Comment on lines +15 to +17
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import list was trimmed, but this test module still calls calculate_neighbours, build_2d_voronoi_from_image, populate_vertices_info, and calculate_vertices later in the file. Those names are now undefined, so the test suite will fail with NameError. Either restore the needed imports or update the tests to call these via a VertexModelVoronoiFromTimeImage instance (if they are instance methods).

Suggested change
from src.pyVertexModel.algorithm.vertexModelVoronoiFromTimeImage import build_triplets_of_neighs, \
VertexModelVoronoiFromTimeImage, add_tetrahedral_intercalations, \
get_four_fold_vertices, divide_quartets_neighbours, process_image
from src.pyVertexModel.algorithm.vertexModelVoronoiFromTimeImage import build_triplets_of_neighs, calculate_neighbours, \
build_2d_voronoi_from_image, populate_vertices_info, calculate_vertices, VertexModelVoronoiFromTimeImage, \
add_tetrahedral_intercalations, get_four_fold_vertices, divide_quartets_neighbours, process_image

Copilot uses AI. Check for mistakes.
from src.pyVertexModel.geometry.degreesOfFreedom import DegreesOfFreedom
from src.pyVertexModel.util.utils import save_backup_vars

Expand Down Expand Up @@ -496,3 +496,84 @@ def test_initialize_voronoi_from_time_image(self):
assert_array1D(g_test, mat_info['g'])
assert_matrix(K_test, mat_info['K'])

def test_initialize_cells_with_numpy_array(self):
"""
Test that initialize_cells can accept a numpy array directly.
:return:
"""
import scipy.io
from src.pyVertexModel.parameters.set import Set

# Load an existing image as a numpy array
mat_data = scipy.io.loadmat('resources/LblImg_imageSequence.mat')
img_array = mat_data['imgStackLabelled']

# Create a simple 2D labeled image for testing
# Using a subset to make it faster
img_2d = img_array[:, :, 0]

# Create settings
set_test = Set(set_option='voronoi_from_image')
set_test.TotalCells = 50 # Use fewer cells for faster testing
set_test.CellHeight = 10

# Test with numpy array input
Comment on lines +516 to +520
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set does not accept a set_option keyword argument (its constructor takes only mat_file=None). This will raise TypeError and fail the test. Create Set() and then set the needed attributes (and call set_test.update_derived_parameters() if required), or construct the model using VertexModelVoronoiFromTimeImage(set_option=..., set_test=None) with a valid Set preset method name.

Copilot uses AI. Check for mistakes.
vModel_test = VertexModelVoronoiFromTimeImage(set_option='voronoi_from_image', set_test=set_test,
create_output_folder=False)
vModel_test.initialize_cells(img_2d)

# Verify that the geometry was created
assert vModel_test.geo is not None, "Geometry should be initialized"
assert vModel_test.geo.nCells > 0, "Should have cells"
assert len(vModel_test.geo.Cells) > 0, "Should have Cell objects"

def test_process_image_with_numpy_array(self):
"""
Test that process_image can handle numpy array input.
:return:
"""
# Create a simple labeled image
test_img = np.zeros((100, 100), dtype=np.uint16)
# Create some labeled regions
test_img[10:30, 10:30] = 1
test_img[40:60, 40:60] = 2
test_img[70:90, 70:90] = 3

# Test process_image with numpy array
img2d, img_stack = process_image(test_img)

# Verify the output
assert img2d is not None, "2D image should be returned"
assert img_stack is not None, "Image stack should be returned"
assert img2d.shape == test_img.shape, "2D image should have same shape as input"
Comment on lines +535 to +548
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new test only asserts that shapes are returned, so it won’t catch incorrect relabeling (e.g., returning labels for background regions instead of the input labeled regions). Add assertions that the labeled regions remain labeled after process_image (e.g., pixels in the three squares stay non-zero and distinct, and background stays 0).

Copilot uses AI. Check for mistakes.

def test_initialize_with_numpy_array(self):
"""
Test that initialize method can accept a numpy array.
:return:
"""
import scipy.io
from src.pyVertexModel.parameters.set import Set

# Load an existing image as a numpy array
mat_data = scipy.io.loadmat('resources/LblImg_imageSequence.mat')
img_array = mat_data['imgStackLabelled']

# Use a 2D slice for faster testing
img_2d = img_array[:, :, 0]

# Create settings
set_test = Set(set_option='voronoi_from_image')
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue here: Set(set_option='voronoi_from_image') is not a valid constructor call for Set and will raise TypeError. Use Set() + attribute overrides (and update derived parameters) instead.

Suggested change
set_test = Set(set_option='voronoi_from_image')
set_test = Set()
set_test.set_option = 'voronoi_from_image'

Copilot uses AI. Check for mistakes.
set_test.TotalCells = 50
set_test.CellHeight = 10

# Test initialize with numpy array input
vModel_test = VertexModelVoronoiFromTimeImage(set_option='voronoi_from_image', set_test=set_test,
create_output_folder=False)
vModel_test.initialize(img_2d)

# Verify that the geometry was created
assert vModel_test.geo is not None, "Geometry should be initialized"
assert vModel_test.geo.nCells > 0, "Should have cells"


9 changes: 7 additions & 2 deletions src/pyVertexModel/algorithm/vertexModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,11 @@ def __init__(self, set_option='wing_disc', c_set=None, create_output_folder=True
self.tr = 0
self.numStep = 1

def initialize(self):
def initialize(self, img_input=None):
"""
Initialize the geometry and the topology of the model.
:param img_input: Optional. Either a filename (str) or a numpy array containing the image.
If None, uses the filename from settings.
"""
filename = os.path.join(PROJECT_DIRECTORY, self.set.initial_filename_state)

Expand Down Expand Up @@ -285,7 +287,10 @@ def initialize(self):
self.geo = Geo(mat_info['Geo'])
self.geo.update_measures()
else:
self.initialize_cells(filename)
if img_input is None:
self.initialize_cells(filename)
else:
self.initialize_cells(img_input)
Comment on lines +290 to +293
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When img_input is provided, initialization correctly calls initialize_cells(img_input), but the earlier cache check (exists(output_filename)) is still based on self.set.initial_filename_state rather than the provided image. This means passing an array can be ignored if a cached state exists for the settings file. Consider bypassing the cache or incorporating img_input into the cache key when img_input is not None.

Copilot uses AI. Check for mistakes.

# Resize the geometry to a given cell volume average
self.geo.resize_tissue()
Expand Down
Loading
Loading