From 73996b78ac373bc297eea4703668a5e7688ce413 Mon Sep 17 00:00:00 2001 From: Hugh Sorby Date: Thu, 13 Feb 2025 16:41:41 +1300 Subject: [PATCH] Add new API to tests for Jacobain determinant. --- src/scaffoldfitter/fitter.py | 6 +++--- tests/test_fitcube.py | 20 ++++++++++++++++---- tests/test_general.py | 3 +++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/scaffoldfitter/fitter.py b/src/scaffoldfitter/fitter.py index 94227ff..93af05b 100644 --- a/src/scaffoldfitter/fitter.py +++ b/src/scaffoldfitter/fitter.py @@ -7,7 +7,7 @@ from cmlibs.maths.vectorops import add, mult, sub from cmlibs.utils.zinc.field import assignFieldParameters, createFieldFiniteElementClone, getGroupList, \ findOrCreateFieldFiniteElement, findOrCreateFieldStoredMeshLocation, getUniqueFieldName, orphanFieldByName, \ - create_xi_reference_jacobian_determinant_field + create_jacobian_determinant_field from cmlibs.utils.zinc.finiteelement import evaluate_field_nodeset_range, findNodeWithName, get_scalar_field_minimum_in_mesh from cmlibs.utils.zinc.general import ChangeManager from cmlibs.utils.zinc.region import write_to_buffer, read_from_buffer @@ -864,7 +864,7 @@ def getLowestElementJacobian(self, mesh_group=None): :return: Element identifier, minimum jacobian value. Values are -1, inf if there is no data or bad fields. """ with ChangeManager(self._fieldmodule): - jacobian = create_xi_reference_jacobian_determinant_field(self._modelCoordinatesField) + jacobian = create_jacobian_determinant_field(self._modelCoordinatesField, self._modelReferenceCoordinatesField) result = get_scalar_field_minimum_in_mesh(jacobian, mesh_group) del jacobian @@ -883,7 +883,7 @@ def getLowestElementJacobianForGroup(self, group_name): """ group = self._fieldmodule.findFieldByName(group_name).castGroup() if group.isValid(): - mesh_group = group.getMeshGroup(self._mesh) + mesh_group = group.getMeshGroup(self.getMesh(3)) return self.getLowestElementJacobian(mesh_group) return None, None diff --git a/tests/test_fitcube.py b/tests/test_fitcube.py index 23f7e48..cd891cf 100644 --- a/tests/test_fitcube.py +++ b/tests/test_fitcube.py @@ -429,6 +429,10 @@ def test_alignGroupsFitEllipsoidRegularData(self): s2 = fitter.encodeSettingsJSON() self.assertEqual(s, s2) + min_jac_el, min_jac_value = fitter.getLowestElementJacobian() + self.assertEqual(1, min_jac_el) + self.assertAlmostEqual(0.1869875394, min_jac_value) + def test_fitRegularDataGroupWeight(self): """ Test fitting with variable data group weights and sliding factors. @@ -518,6 +522,10 @@ def test_fitRegularDataGroupWeight(self): self.assertAlmostEqual(surfaceArea, 3.187490694645035, delta=1.0E-4) self.assertAlmostEqual(volume, 0.5072619397447008, delta=1.0E-4) + min_jac_el, min_jac_value = fitter.getLowestElementJacobian() + self.assertEqual(1, min_jac_el) + self.assertAlmostEqual(1.0, min_jac_value) + def test_groupSettings(self): """ Test per-group settings, and inheritance from previous @@ -572,19 +580,23 @@ def test_groupSettings(self): activeNodeset, fitter.getFieldmodule().findFieldByName(groupName))) groupErrors = { - "bottom": (0.47716552515635985, 0.5001722675609085), - "sides": (0.3721661947669986, 0.5000286856904854), - "top": (0.5699148581001906, 0.6755409758922845), - "marker": (0.9354143466934853, 1.224744871391589) + "bottom": (0.47716552515635985, 0.5001722675609085, math.inf), + "sides": (0.3721661947669986, 0.5000286856904854, math.inf), + "top": (0.5699148581001906, 0.6755409758922845, math.inf), + "marker": (0.9354143466934853, 1.224744871391589, math.inf) } for groupName, errors in groupErrors.items(): rms_error, max_error = fitter.getDataRMSAndMaximumProjectionErrorForGroup(groupName) self.assertAlmostEqual(rms_error, errors[0], 5) self.assertAlmostEqual(max_error, errors[1], 5) + jac_det_el, jac_det_value = fitter.getLowestElementJacobianForGroup(groupName) + self.assertAlmostEqual(jac_det_value, errors[2], 5) rms_error, max_error = fitter.getDataRMSAndMaximumProjectionErrorForGroup('left') self.assertEqual(None, rms_error) self.assertEqual(None, max_error) + jac_det_el, jac_det_value = fitter.getLowestElementJacobianForGroup('left') + self.assertIsNone(jac_det_value) # test override and inherit config2 = FitterStepConfig() diff --git a/tests/test_general.py b/tests/test_general.py index 0cd95e5..2bbca28 100644 --- a/tests/test_general.py +++ b/tests/test_general.py @@ -75,6 +75,9 @@ def test_fit_1d_outliers(self): rmsError, maxError = fitter.getDataRMSAndMaximumProjectionError() self.assertAlmostEqual(rmsError, expectedRmsError, delta=TOL) # sqrt(0.12) self.assertAlmostEqual(maxError, expectedMaxError, delta=TOL) + min_jac_el, min_jac_value = fitter.getLowestElementJacobian() + self.assertEqual(1, min_jac_el) + self.assertAlmostEqual(0.0, min_jac_value, delta=TOL) def test_setting_group_outlier_length(self): zinc_model_file = os.path.join(here, "resources", "nerve_trunk_model.exf")