def _stepsAddAlignClicked(self):
     """
     Add a new align step.
     """
     self._currentFitterStep = FitterStepAlign()
     self._fitter.addFitterStep(self._currentFitterStep)  # Future: , lastFitterStep
     self._buildStepsList()
Esempio n. 2
0
 def _stepsAddAlignClicked(self):
     """
     Add a new align step.
     """
     self._currentFitterStep = FitterStepAlign(self._fitter)
     self._buildStepsList()
Esempio n. 3
0
    def test_alignFixedRandomData(self):
        """
        Test alignment of model and data to known transformations.
        """
        zinc_model_file = os.path.join(here, "resources", "cube_to_sphere.exf")
        zinc_data_file = os.path.join(here, "resources", "cube_to_sphere_data_random.exf")
        fitter = Fitter(zinc_model_file, zinc_data_file)
        fitter.setDiagnosticLevel(1)
        fitter.load()

        self.assertEqual(fitter.getModelCoordinatesField().getName(), "coordinates")
        self.assertEqual(fitter.getDataCoordinatesField().getName(), "data_coordinates")
        self.assertEqual(fitter.getMarkerGroup().getName(), "marker")
        bottomCentre1 = fitter.evaluateNodeGroupMeanCoordinates("bottom", "coordinates", isData = False)
        sidesCentre1 = fitter.evaluateNodeGroupMeanCoordinates("sides", "coordinates", isData = False)
        topCentre1 = fitter.evaluateNodeGroupMeanCoordinates("top", "coordinates", isData = False)
        assertAlmostEqualList(self, bottomCentre1, [ 0.5, 0.5, 0.0 ], delta=1.0E-7)
        assertAlmostEqualList(self, sidesCentre1, [ 0.5, 0.5, 0.5 ], delta=1.0E-7)
        assertAlmostEqualList(self, topCentre1, [ 0.5, 0.5, 1.0 ], delta=1.0E-7)
        align = FitterStepAlign(fitter)
        align.setScale(1.1)
        align.setTranslation([ 0.1, -0.2, 0.3 ])
        align.setRotation([ math.pi/4.0, math.pi/8.0, math.pi/2.0 ])
        self.assertTrue(align.isAlignMarkers())
        align.setAlignMarkers(False)
        align.run()
        rotation = align.getRotation()
        scale = align.getScale()
        translation = align.getTranslation()
        rotationMatrix = getRotationMatrix(rotation)
        transformationMatrix = [ v*scale for v in rotationMatrix ]
        bottomCentre2Expected, sidesCentre2Expected, topCentre2Expected = transformCoordinatesList(
            [ bottomCentre1, sidesCentre1, topCentre1 ], transformationMatrix, translation)
        bottomCentre2 = fitter.evaluateNodeGroupMeanCoordinates("bottom", "coordinates", isData = False)
        sidesCentre2 = fitter.evaluateNodeGroupMeanCoordinates("sides", "coordinates", isData = False)
        topCentre2 = fitter.evaluateNodeGroupMeanCoordinates("top", "coordinates", isData = False)
        assertAlmostEqualList(self, bottomCentre2, bottomCentre2Expected, delta=1.0E-7)
        assertAlmostEqualList(self, sidesCentre2, sidesCentre2Expected, delta=1.0E-7)
        assertAlmostEqualList(self, topCentre2, topCentre2Expected, delta=1.0E-7)
Esempio n. 4
0
    def test_alignMarkersFitRegularData(self):
        """
        Test automatic alignment of model and data using fiducial markers.
        """
        zinc_model_file = os.path.join(here, "resources", "cube_to_sphere.exf")
        zinc_data_file = os.path.join(here, "resources", "cube_to_sphere_data_regular.exf")
        fitter = Fitter(zinc_model_file, zinc_data_file)
        fitter.setDiagnosticLevel(1)
        fitter.load()
        coordinates = fitter.getModelCoordinatesField()
        self.assertEqual(coordinates.getName(), "coordinates")
        self.assertEqual(fitter.getDataCoordinatesField().getName(), "data_coordinates")
        self.assertEqual(fitter.getMarkerGroup().getName(), "marker")
        #fitter.getRegion().writeFile(os.path.join(here, "resources", "km_fitgeometry1.exf"))
        fieldmodule = fitter.getFieldmodule()
        surfaceAreaField = createFieldMeshIntegral(coordinates, fitter.getMesh(2), number_of_points=4)
        volumeField = createFieldMeshIntegral(coordinates, fitter.getMesh(3), number_of_points=3)
        fieldcache = fieldmodule.createFieldcache()
        result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(surfaceArea, 6.0, delta=1.0E-6)
        result, volume = volumeField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(volume, 1.0, delta=1.0E-7)

        align = FitterStepAlign(fitter)
        self.assertTrue(align.isAlignMarkers())
        align.setAlignMarkers(True)
        align.run()
        #fitter.getRegion().writeFile(os.path.join(here, "resources", "km_fitgeometry2.exf"))
        rotation = align.getRotation()
        scale = align.getScale()
        translation = align.getTranslation()
        assertAlmostEqualList(self, rotation, [ -0.25*math.pi, 0.0, 0.0 ], delta=1.0E-4)
        self.assertAlmostEqual(scale, 0.8047378476539072, places=5)
        assertAlmostEqualList(self, translation, [ -0.5690355950594247, 1.1068454682130484e-05, -0.4023689233125251 ], delta=1.0E-6)
        result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(surfaceArea, 3.885618020657802, delta=1.0E-6)
        result, volume = volumeField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(volume, 0.5211506471189844, delta=1.0E-6)

        fit1 = FitterStepFit(fitter)
        fit1.setMarkerWeight(1.0)
        fit1.setCurvaturePenaltyWeight(0.1)
        fit1.setNumberOfIterations(3)
        fit1.setUpdateReferenceState(True)
        fit1.run()
        #fitter.getRegion().writeFile(os.path.join(here, "resources", "km_fitgeometry3.exf"))

        result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(surfaceArea, 3.1892231780263853, delta=1.0E-4)
        result, volume = volumeField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(volume, 0.5276229458448985, delta=1.0E-4)

        # test json serialisation
        s = fitter.encodeSettingsJSON()
        fitter2 = Fitter(zinc_model_file, zinc_data_file)
        fitter2.decodeSettingsJSON(s, decodeJSONFitterSteps)
        fitterSteps = fitter2.getFitterSteps()
        self.assertEqual(2, len(fitterSteps))
        self.assertTrue(isinstance(fitterSteps[0], FitterStepAlign))
        self.assertTrue(isinstance(fitterSteps[1], FitterStepFit))
        #fitter2.load()
        #for fitterStep in fitterSteps:
        #    fitterStep.run()
        s2 = fitter.encodeSettingsJSON()
        self.assertEqual(s, s2)
Esempio n. 5
0
    def test_preAlignment(self):
        """
        Test prealignment step to ensure models at different translation, scale and rotation all return close
        to same aligned model.
        """
        zinc_model_file = os.path.join(here, "resources", "cube_to_sphere.exf")
        zinc_data_file = os.path.join(here, "resources",
                                      "cube_to_sphere_data_random.exf")
        fitter = Fitter(zinc_model_file, zinc_data_file)
        self.assertEqual(1, len(fitter.getFitterSteps()))
        fitter.setDiagnosticLevel(1)

        # Rotation, scale, translation
        transformationList = [
            [[0.0, 0.0, 0.0], 1.0, [0.0, 0.0, 0.0]],
            [[math.pi * 20 / 180, 0.0, 0.0], 1.0, [0.0, 0.0, 0.0]],
            [[math.pi * 135 / 180, 0.0, 0.0], 1.0, [0.0, 0.0, 0.0]],
            [[math.pi * 250 / 180, math.pi * -45 / 180, 0.0], 1.0,
             [0.0, 0.0, 0.0]],
            [[math.pi * 45 / 180, math.pi * 45 / 180, math.pi * 45 / 180], 1.0,
             [0.0, 0.0, 0.0]], [[0.0, 0.0, 0.0], 0.05, [0.0, 0.0, 0.0]],
            [[math.pi * 70 / 180, math.pi * 10 / 180, math.pi * -300 / 180],
             0.2, [0.0, 0.0, 0.0]], [[0.0, 0.0, 0.0], 1.0, [15.0, 15.0, 15.0]],
            [[0.0, 0.0, 0.0], 20.0, [50.0, 0.0, 10.0]],
            [[math.pi * 90 / 180, math.pi * 200 / 180, math.pi * 5 / 180], 1.0,
             [-10.0, -20.0, 100.0]],
            [[math.pi * -45 / 180, math.pi * 120 / 180, math.pi * 10 / 180],
             500.0, [100.0, 100.0, 100.0]]
        ]

        expectedAlignedNodes = [
            [
                -0.5690355951820659, 1.1070979208244695e-05,
                -0.40236892417087866
            ],
            [
                -1.1077595833408616e-05, -0.5690355904946871,
                -0.4023689227447479
            ],
            [1.1066291829453512e-05, 0.5690355885654408, -0.4023689255966489],
            [0.569035583878062, -1.1072908454692232e-05, -0.4023689241705181],
            [-0.5690355951822816, 1.1072995806778281e-05, 0.4023689241678401],
            [-1.107759604912495e-05, -0.5690355884780887, 0.40236892559397086],
            [1.10662916138482e-05, 0.5690355905820392, 0.4023689227420698],
            [0.5690355838778464, -1.1070891856158648e-05, 0.4023689241682007]
        ]

        align = FitterStepAlign()
        fitter.addFitterStep(align)
        self.assertTrue(align.setAlignMarkers(True))
        self.assertTrue(align.isAlignMarkers())

        for i in range(len(transformationList)):
            fitter.load()

            fieldmodule = fitter.getFieldmodule()
            fieldcache = fieldmodule.createFieldcache()
            modelCoordinates = fitter.getModelCoordinatesField()

            rotation = transformationList[i][0]
            scale = transformationList[i][1]
            translation = transformationList[i][2]
            modelCoordinatesTransformed = createFieldsTransformations(
                modelCoordinates, rotation, scale, translation)[0]
            fieldassignment = modelCoordinates.createFieldassignment(
                modelCoordinatesTransformed)
            fieldassignment.assign()

            align.run()
            nodeset = fieldmodule.findNodesetByFieldDomainType(
                Field.DOMAIN_TYPE_NODES)

            for nodeIdentifier in range(1, 9):
                node = nodeset.findNodeByIdentifier(nodeIdentifier)
                fieldcache.setNode(node)
                result, x = modelCoordinates.getNodeParameters(
                    fieldcache, -1, Node.VALUE_LABEL_VALUE, 1, 3)
                assertAlmostEqualList(self,
                                      x,
                                      expectedAlignedNodes[nodeIdentifier - 1],
                                      delta=1.0E-3)
Esempio n. 6
0
    def test_fitRegularDataGroupWeight(self):
        """
        Test automatic alignment of model and data using fiducial markers.
        """
        zinc_model_file = os.path.join(here, "resources", "cube_to_sphere.exf")
        zinc_data_file = os.path.join(here, "resources",
                                      "cube_to_sphere_data_regular.exf")
        fitter = Fitter(zinc_model_file, zinc_data_file)
        self.assertEqual(1, len(fitter.getFitterSteps())
                         )  # there is always an initial FitterStepConfig
        fitter.setDiagnosticLevel(1)
        fitter.load()

        coordinates = fitter.getModelCoordinatesField()
        self.assertEqual(coordinates.getName(), "coordinates")
        fieldmodule = fitter.getFieldmodule()
        surfaceAreaField = createFieldMeshIntegral(coordinates,
                                                   fitter.getMesh(2),
                                                   number_of_points=4)
        volumeField = createFieldMeshIntegral(coordinates,
                                              fitter.getMesh(3),
                                              number_of_points=3)
        fieldcache = fieldmodule.createFieldcache()

        align = FitterStepAlign()
        fitter.addFitterStep(align)
        self.assertEqual(2, len(fitter.getFitterSteps()))
        self.assertTrue(align.setAlignMarkers(True))
        align.run()

        fit1 = FitterStepFit()
        fitter.addFitterStep(fit1)
        self.assertEqual(3, len(fitter.getFitterSteps()))
        fit1.setGroupDataWeight("bottom", 0.5)
        fit1.setGroupDataWeight("sides", 0.1)
        groupNames = fit1.getGroupSettingsNames()
        self.assertEqual(2, len(groupNames))
        self.assertEqual((0.5, True, False), fit1.getGroupDataWeight("bottom"))
        self.assertEqual((0.1, True, False), fit1.getGroupDataWeight("sides"))
        fit1.setCurvaturePenaltyWeight(0.01)
        fit1.setNumberOfIterations(3)
        fit1.setUpdateReferenceState(True)
        fit1.run()
        dataWeightField = fieldmodule.findFieldByName(
            "data_weight").castFiniteElement()
        self.assertTrue(dataWeightField.isValid())
        groupData = {
            "bottom": (72, 0.5),
            "sides": (144, 0.1),
            "top": (72, 1.0)
        }
        mesh2d = fitter.getMesh(2)
        for groupName in groupData.keys():
            expectedSize, expectedWeight = groupData[groupName]
            group = fieldmodule.findFieldByName(groupName).castGroup()
            dataGroup = fitter.getGroupDataProjectionNodesetGroup(group)
            size = dataGroup.getSize()
            self.assertEqual(size, expectedSize)
            dataIterator = dataGroup.createNodeiterator()
            node = dataIterator.next()
            while node.isValid():
                fieldcache.setNode(node)
                result, weight = dataWeightField.evaluateReal(fieldcache, 1)
                self.assertEqual(result, RESULT_OK)
                self.assertAlmostEqual(weight, expectedWeight, delta=1.0E-10)
                node = dataIterator.next()

        result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(surfaceArea, 3.2298953613027956, delta=1.0E-4)
        result, volume = volumeField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(volume, 0.5156233237703589, delta=1.0E-4)
Esempio n. 7
0
    def test_alignGroupsFitEllipsoidRegularData(self):
        """
        Test automatic alignment of model and data using groups & fit two cubes model to ellipsoid data.
        """
        zinc_model_file = os.path.join(here, "resources",
                                       "two_cubes_hermite_nocross_groups.exf")
        zinc_data_file = os.path.join(here, "resources",
                                      "two_cubes_ellipsoid_data_regular.exf")
        fitter = Fitter(zinc_model_file, zinc_data_file)
        fitter.setDiagnosticLevel(1)
        fitter.load()

        coordinates = fitter.getModelCoordinatesField()
        self.assertEqual(coordinates.getName(), "coordinates")
        self.assertEqual(fitter.getDataCoordinatesField().getName(),
                         "data_coordinates")
        fieldmodule = fitter.getFieldmodule()
        # surface area includes interior surface in this case
        surfaceAreaField = createFieldMeshIntegral(coordinates,
                                                   fitter.getMesh(2),
                                                   number_of_points=4)
        volumeField = createFieldMeshIntegral(coordinates,
                                              fitter.getMesh(3),
                                              number_of_points=3)
        fieldcache = fieldmodule.createFieldcache()
        result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(surfaceArea, 11.0, delta=1.0E-6)
        result, volume = volumeField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(volume, 2.0, delta=1.0E-6)
        activeNodeset = fitter.getActiveDataNodesetGroup()

        align = FitterStepAlign()
        fitter.addFitterStep(align)
        self.assertEqual(2, len(fitter.getFitterSteps()))
        self.assertTrue(align.setAlignGroups(True))
        self.assertTrue(align.isAlignGroups())
        align.run()
        rotation = align.getRotation()
        scale = align.getScale()
        translation = align.getTranslation()
        assertAlmostEqualList(self, rotation, [0.0, 0.0, 0.0], delta=1.0E-5)
        self.assertAlmostEqual(scale, 1.040599599095245, places=5)
        assertAlmostEqualList(
            self,
            translation,
            [-1.0405995643008867, -0.5202997843515198, -0.5202997827678563],
            delta=1.0E-6)
        result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(surfaceArea, 11.0 * scale * scale, delta=1.0E-6)
        result, volume = volumeField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(volume,
                               2.0 * scale * scale * scale,
                               delta=1.0E-6)

        fit1 = FitterStepFit()
        fitter.addFitterStep(fit1)
        self.assertEqual(3, len(fitter.getFitterSteps()))
        strainPenalty, locallySet, inheritable = fit1.getGroupStrainPenalty(
            None)
        assertAlmostEqualList(self, strainPenalty, [0.0], delta=1.0E-7)
        self.assertFalse(locallySet)
        self.assertFalse(inheritable)
        curvaturePenalty, locallySet, inheritable = fit1.getGroupCurvaturePenalty(
            None)
        assertAlmostEqualList(self, curvaturePenalty, [0.0], delta=1.0E-7)
        self.assertFalse(locallySet)
        self.assertFalse(inheritable)
        fit1.setGroupStrainPenalty(None, [0.1])
        strainPenalty, locallySet, inheritable = fit1.getGroupStrainPenalty(
            None)
        assertAlmostEqualList(self, strainPenalty, [0.1], delta=1.0E-7)
        self.assertTrue(locallySet)
        self.assertFalse(inheritable)
        fit1.setGroupCurvaturePenalty(None, [0.01])
        curvaturePenalty, locallySet, inheritable = fit1.getGroupCurvaturePenalty(
            None)
        assertAlmostEqualList(self, curvaturePenalty, [0.01], delta=1.0E-7)
        self.assertTrue(locallySet)
        self.assertFalse(inheritable)
        # test specifying number of components:
        curvaturePenalty, locallySet, inheritable = fit1.getGroupCurvaturePenalty(
            None, count=5)
        assertAlmostEqualList(self,
                              curvaturePenalty, [0.01, 0.01, 0.01, 0.01, 0.01],
                              delta=1.0E-7)
        # group "two" strain penalty will initially fall back to default value
        strainPenalty, locallySet, inheritable = fit1.getGroupStrainPenalty(
            "two")
        assertAlmostEqualList(self, strainPenalty, [0.1], delta=1.0E-7)
        self.assertFalse(locallySet)
        self.assertFalse(inheritable)
        fit1.setGroupStrainPenalty(
            "two", [0.1, 0.1, 0.1, 0.1, 20.0, 0.1, 0.1, 20.0, 2.0])
        strainPenalty, locallySet, inheritable = fit1.getGroupStrainPenalty(
            "two")
        assertAlmostEqualList(self,
                              strainPenalty,
                              [0.1, 0.1, 0.1, 0.1, 20.0, 0.1, 0.1, 20.0, 2.0],
                              delta=1.0E-7)
        self.assertTrue(locallySet)
        self.assertFalse(inheritable)
        fit1.setNumberOfIterations(1)
        fit1.run()
        result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(surfaceArea, 11.097773862300704, delta=1.0E-4)
        result, volume = volumeField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(volume, 2.323461787566051, delta=1.0E-4)

        # test fibre orientation field
        fitter.load()
        fieldmodule = fitter.getFieldmodule()
        self.assertEqual(None, fitter.getFibreField())
        fibreField = fieldmodule.createFieldConstant(
            [0.0, 0.0, 0.25 * math.pi])
        fibreField.setName("custom fibres")
        fibreField.setManaged(True)
        fitter.setFibreField(fibreField)
        self.assertEqual(fibreField, fitter.getFibreField())
        coordinates = fitter.getModelCoordinatesField()
        align.run()
        fit1.run()
        # get end node coordinate to prove twist
        nodeExpectedCoordinates = {
            3: [0.8487623099139301, -0.5012613734076182, -0.5306482017126274],
            6: [0.8487623092159226, 0.2617063557585618, -0.5464896371028911],
            9: [0.8487623062422882, -0.2617063537282271, 0.5464896401724635],
            12: [0.8487623124370356, 0.5012613792923117, 0.5306482045212996]
        }
        fieldcache = fieldmodule.createFieldcache()
        nodes = fieldmodule.findNodesetByFieldDomainType(
            Field.DOMAIN_TYPE_NODES)
        for nodeIdentifier, expectedCoordinates in nodeExpectedCoordinates.items(
        ):
            node = nodes.findNodeByIdentifier(nodeIdentifier)
            self.assertEqual(RESULT_OK, fieldcache.setNode(node))
            result, x = coordinates.getNodeParameters(fieldcache, -1,
                                                      Node.VALUE_LABEL_VALUE,
                                                      1, 3)
            self.assertEqual(RESULT_OK, result)
            assertAlmostEqualList(self, x, expectedCoordinates, delta=1.0E-6)

        # test inheritance and override of penalties
        fit2 = FitterStepFit()
        fitter.addFitterStep(fit2)
        self.assertEqual(4, len(fitter.getFitterSteps()))
        strainPenalty, locallySet, inheritable = fit2.getGroupStrainPenalty(
            None)
        assertAlmostEqualList(self, strainPenalty, [0.1], delta=1.0E-7)
        self.assertFalse(locallySet)
        self.assertTrue(inheritable)
        curvaturePenalty, locallySet, inheritable = fit2.getGroupCurvaturePenalty(
            None)
        assertAlmostEqualList(self, curvaturePenalty, [0.01], delta=1.0E-7)
        self.assertFalse(locallySet)
        self.assertTrue(inheritable)
        fit2.setGroupCurvaturePenalty(None, None)
        curvaturePenalty, locallySet, inheritable = fit2.getGroupCurvaturePenalty(
            None)
        assertAlmostEqualList(self, curvaturePenalty, [0.0], delta=1.0E-7)
        self.assertTrue(locallySet is None)
        self.assertTrue(inheritable)
        strainPenalty, locallySet, inheritable = fit2.getGroupStrainPenalty(
            "two")
        assertAlmostEqualList(self,
                              strainPenalty,
                              [0.1, 0.1, 0.1, 0.1, 20.0, 0.1, 0.1, 20.0, 2.0],
                              delta=1.0E-7)
        self.assertFalse(locallySet)
        self.assertTrue(inheritable)
        fit2.setGroupStrainPenalty("two", [0.5, 0.9, 0.2])
        strainPenalty, locallySet, inheritable = fit2.getGroupStrainPenalty(
            "two", count=9)
        assertAlmostEqualList(self,
                              strainPenalty,
                              [0.5, 0.9, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2],
                              delta=1.0E-7)
        self.assertTrue(locallySet)
        self.assertTrue(inheritable)

        # test json serialisation
        s = fitter.encodeSettingsJSON()
        fitter2 = Fitter(zinc_model_file, zinc_data_file)
        fitter2.decodeSettingsJSON(s, decodeJSONFitterSteps)
        fitterSteps = fitter2.getFitterSteps()
        self.assertEqual(4, len(fitterSteps))
        self.assertTrue(isinstance(fitterSteps[0], FitterStepConfig))
        self.assertTrue(isinstance(fitterSteps[1], FitterStepAlign))
        self.assertTrue(isinstance(fitterSteps[2], FitterStepFit))
        self.assertTrue(isinstance(fitterSteps[3], FitterStepFit))
        fit1 = fitterSteps[2]
        strainPenalty, locallySet, inheritable = fit1.getGroupStrainPenalty(
            "two")
        assertAlmostEqualList(self,
                              strainPenalty,
                              [0.1, 0.1, 0.1, 0.1, 20.0, 0.1, 0.1, 20.0, 2.0],
                              delta=1.0E-7)
        self.assertTrue(locallySet)
        self.assertFalse(inheritable)
        fit2 = fitterSteps[3]
        curvaturePenalty, locallySet, inheritable = fit2.getGroupCurvaturePenalty(
            None)
        assertAlmostEqualList(self, curvaturePenalty, [0.0], delta=1.0E-7)
        self.assertTrue(locallySet is None)
        self.assertTrue(inheritable)
        strainPenalty, locallySet, inheritable = fit2.getGroupStrainPenalty(
            "two")
        assertAlmostEqualList(self,
                              strainPenalty, [0.5, 0.9, 0.2],
                              delta=1.0E-7)
        self.assertTrue(locallySet)
        self.assertTrue(inheritable)
        s2 = fitter.encodeSettingsJSON()
        self.assertEqual(s, s2)
    def test_alignMarkersFitRegularData(self):
        """
        Test automatic alignment of model and data using fiducial markers.
        """
        zinc_model_file = os.path.join(here, "resources", "cube_to_sphere.exf")
        zinc_data_file = os.path.join(here, "resources",
                                      "cube_to_sphere_data_regular.exf")
        fitter = Fitter(zinc_model_file, zinc_data_file)
        self.assertEqual(1, len(fitter.getFitterSteps())
                         )  # there is always an initial FitterStepConfig
        fitter.setDiagnosticLevel(1)
        fitter.load()
        dataScale = fitter.getDataScale()
        self.assertAlmostEqual(dataScale, 1.0, delta=1.0E-7)

        coordinates = fitter.getModelCoordinatesField()
        self.assertEqual(coordinates.getName(), "coordinates")
        self.assertEqual(fitter.getDataCoordinatesField().getName(),
                         "data_coordinates")
        self.assertEqual(fitter.getMarkerGroup().getName(), "marker")
        # fitter.getRegion().writeFile(os.path.join(here, "resources", "km_fitgeometry1.exf"))
        fieldmodule = fitter.getFieldmodule()
        surfaceAreaField = createFieldMeshIntegral(coordinates,
                                                   fitter.getMesh(2),
                                                   number_of_points=4)
        volumeField = createFieldMeshIntegral(coordinates,
                                              fitter.getMesh(3),
                                              number_of_points=3)
        fieldcache = fieldmodule.createFieldcache()
        result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(surfaceArea, 6.0, delta=1.0E-6)
        result, volume = volumeField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(volume, 1.0, delta=1.0E-7)
        activeNodeset = fitter.getActiveDataNodesetGroup()
        self.assertEqual(292, activeNodeset.getSize())
        groupSizes = {"bottom": 72, "sides": 144, "top": 72, "marker": 4}
        for groupName, count in groupSizes.items():
            self.assertEqual(
                count,
                getNodesetConditionalSize(
                    activeNodeset,
                    fitter.getFieldmodule().findFieldByName(groupName)))

        align = FitterStepAlign()
        fitter.addFitterStep(align)
        self.assertEqual(2, len(fitter.getFitterSteps()))
        self.assertTrue(align.setAlignMarkers(True))
        self.assertTrue(align.isAlignMarkers())
        align.run()
        # fitter.getRegion().writeFile(os.path.join(here, "resources", "km_fitgeometry2.exf"))
        rotation = align.getRotation()
        scale = align.getScale()
        translation = align.getTranslation()
        assertAlmostEqualList(self,
                              rotation, [-0.25 * math.pi, 0.0, 0.0],
                              delta=1.0E-4)
        self.assertAlmostEqual(scale, 0.8047378476539072, places=5)
        assertAlmostEqualList(
            self,
            translation,
            [-0.5690355950594247, 1.1068454682130484e-05, -0.4023689233125251],
            delta=1.0E-6)
        result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(surfaceArea, 3.885618020657802, delta=1.0E-6)
        result, volume = volumeField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(volume, 0.5211506471189844, delta=1.0E-6)

        fit1 = FitterStepFit()
        fitter.addFitterStep(fit1)
        self.assertEqual(3, len(fitter.getFitterSteps()))
        fit1.setGroupDataWeight("marker", 1.0)
        fit1.setGroupCurvaturePenalty(None, [0.01])
        fit1.setNumberOfIterations(3)
        fit1.setUpdateReferenceState(True)
        fit1.run()
        # fitter.getRegion().writeFile(os.path.join(here, "resources", "km_fitgeometry3.exf"))

        result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(surfaceArea, 3.18921662820759, delta=1.0E-4)
        result, volume = volumeField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(volume, 0.5276212500499845, delta=1.0E-4)

        # test json serialisation
        s = fitter.encodeSettingsJSON()
        fitter2 = Fitter(zinc_model_file, zinc_data_file)
        fitter2.decodeSettingsJSON(s, decodeJSONFitterSteps)
        fitterSteps = fitter2.getFitterSteps()
        self.assertEqual(3, len(fitterSteps))
        self.assertTrue(isinstance(fitterSteps[0], FitterStepConfig))
        self.assertTrue(isinstance(fitterSteps[1], FitterStepAlign))
        self.assertTrue(isinstance(fitterSteps[2], FitterStepFit))
        # fitter2.load()
        # for fitterStep in fitterSteps:
        #    fitterStep.run()
        s2 = fitter.encodeSettingsJSON()
        self.assertEqual(s, s2)