def _stepsAddFitClicked(self):
     """
     Add a new fit step.
     """
     self._currentFitterStep = FitterStepFit()
     self._fitter.addFitterStep(self._currentFitterStep)  # Future: , lastFitterStep
     self._buildStepsList()
 def _stepsAddConfigClicked(self):
     """
     Add a new config step.
     """
     self._currentFitterStep = FitterStepConfig()
     self._fitter.addFitterStep(self._currentFitterStep)  # Future: , lastFitterStep
     self._buildStepsList()
 def _stepsAddAlignClicked(self):
     """
     Add a new align step.
     """
     self._currentFitterStep = FitterStepAlign()
     self._fitter.addFitterStep(self._currentFitterStep)  # Future: , lastFitterStep
     self._buildStepsList()
Пример #4
0
    def test_fit_breast2d(self):
        """
        Test 2D fit with curvature penalty requiring fibre field to be set.
        """
        zinc_model_file = os.path.join(here, "resources", "breast_plate.exf")
        zinc_data_file = os.path.join(here, "resources", "breast_data.exf")
        fitter = Fitter(zinc_model_file, zinc_data_file)
        fitter.setDiagnosticLevel(1)
        fitter.load()

        fit1 = FitterStepFit()
        fitter.addFitterStep(fit1)
        self.assertEqual(2, len(fitter.getFitterSteps()))
        fit1.setGroupCurvaturePenalty(None, [100.0])
        # can't use a curvature penalty without a fibre field
        with self.assertRaises(AssertionError) as cm:
            fit1.run()
        self.assertEqual(
            str(cm.exception),
            "Must supply a fibre field to use strain/curvature penalties "
            "with mesh dimension < coordinate components.")

        # set the in-built zero fibres field
        fieldmodule = fitter.getFieldmodule()
        zeroFibreField = fieldmodule.findFieldByName("zero fibres")
        self.assertTrue(zeroFibreField.isValid())
        fitter.setFibreField(zeroFibreField)
        fitter.load()

        # check these now as different after re-load
        fieldmodule = fitter.getFieldmodule()
        coordinates = fitter.getModelCoordinatesField()
        self.assertEqual(coordinates.getName(), "coordinates")
        self.assertEqual(fitter.getDataCoordinatesField().getName(),
                         "data_coordinates")

        fit1.run()

        # check surface area of fitted coordinates
        # Note name is only prefixes with "fitted " when written with Fitter.writeModel
        surfaceAreaField = createFieldMeshIntegral(coordinates,
                                                   fitter.getMesh(2),
                                                   number_of_points=4)
        valid = surfaceAreaField.isValid()
        self.assertTrue(surfaceAreaField.isValid())
        fieldcache = fieldmodule.createFieldcache()
        result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1)
        self.assertEqual(result, RESULT_OK)
        self.assertAlmostEqual(surfaceArea, 104501.36293993103, delta=1.0E-1)
Пример #5
0
class GeometricFitWidget(QtGui.QWidget):
    """
    User interface for github.com/ABI-Software/scaffoldfitter
    """
    def __init__(self, model, parent=None):
        """
        """
        super(GeometricFitWidget, self).__init__(parent)
        self._ui = Ui_GeometricFitWidget()
        self._ui.setupUi(self)
        self._ui.alignmentsceneviewerwidget.setContext(model.getContext())
        self._ui.alignmentsceneviewerwidget.setModel(model)
        self._model = model
        self._fitter = self._model.getFitter()
        self._region = self._fitter.getRegion()
        self._scene = self._region.getScene()
        self._currentFitterStep = None  # Current FitterStep being edited; None = Fitter config
        self._ui.alignmentsceneviewerwidget.graphicsInitialized.connect(
            self._graphicsInitialized)
        self._callback = None
        self._setupConfigWidgets()
        self._updateGeneralWidgets()
        self._updateConfigWidgets()
        self._updateDisplayWidgets()
        self._makeConnections()

    def _graphicsInitialized(self):
        """
        Callback for when SceneviewerWidget is initialised
        """
        self._sceneChanged()
        sceneviewer = self._ui.alignmentsceneviewerwidget.getSceneviewer()
        if sceneviewer is not None:
            sceneviewer.setTransparencyMode(sceneviewer.TRANSPARENCY_MODE_SLOW)
            self._autoPerturbLines()
            sceneviewer.viewAll()

    def _sceneChanged(self):
        """
        Set custom scene from model.
        """
        sceneviewer = self._ui.alignmentsceneviewerwidget.getSceneviewer()
        if sceneviewer is not None:
            self._model.createGraphics()
            sceneviewer.setScene(self._model.getScene())
            self._refreshGraphics()

    def _refreshGraphics(self):
        """
        Autorange spectrum and force redraw of graphics.
        """
        self._model.autorangeSpectrum()
        self._ui.alignmentsceneviewerwidget.paintGL()

    def _makeConnections(self):
        self._makeConnectionsGeneral()
        self._makeConnectionsDisplay()
        self._makeConnectionsConfig()
        self._makeConnectionsAlign()
        self._makeConnectionsFit()

    def registerDoneExecution(self, callback):
        self._callback = callback

    def _autoPerturbLines(self):
        """
        Enable scene viewer perturb lines iff solid surfaces are drawn with lines.
        Call whenever lines, surfaces or translucency changes
        """
        sceneviewer = self._ui.alignmentsceneviewerwidget.getSceneviewer()
        if sceneviewer is not None:
            sceneviewer.setPerturbLinesFlag(self._model.needPerturbLines())

# === general widgets ===

    def _makeConnectionsGeneral(self):
        self._ui.stepsAddAlign_pushButton.clicked.connect(
            self._stepsAddAlignClicked)
        self._ui.stepsAddFit_pushButton.clicked.connect(
            self._stepsAddFitClicked)
        self._ui.stepsDelete_pushButton.clicked.connect(
            self._stepsDeleteClicked)
        self._ui.steps_listView.clicked[QtCore.QModelIndex].connect(
            self._stepsListItemClicked)
        self._ui.done_pushButton.clicked.connect(self._doneClicked)
        self._ui.viewAll_pushButton.clicked.connect(self._viewAllClicked)

    def _updateGeneralWidgets(self):
        self._ui.identifier_label.setText("Identifier:  " +
                                          self._model.getIdentifier())
        self._buildStepsList()

    def _stepsAddAlignClicked(self):
        """
        Add a new align step.
        """
        self._currentFitterStep = FitterStepAlign(self._fitter)
        self._buildStepsList()

    def _stepsAddFitClicked(self):
        """
        Add a new fit step.
        """
        self._currentFitterStep = FitterStepFit(self._fitter)
        self._buildStepsList()

    def _stepsDeleteClicked(self):
        """
        Delete the currently selected step, except for config.
        Select next step after, or before if none.
        """
        destroyFitterStep = self._currentFitterStep
        if destroyFitterStep:
            if destroyFitterStep.hasRun():
                # Undo to before step being destroyed
                fitterSteps = self._fitter.getFitterSteps()
                currentIndex = fitterSteps.index(self._currentFitterStep)
                self._fitter.load()
                self._sceneChanged()
                for index in range(currentIndex):
                    fitterSteps[index].run()
                    self._refreshGraphics()
                for index in range(currentIndex, len(fitterSteps)):
                    fitterSteps[index].setHasRun(False)
            self._currentFitterStep = self._fitter.getNextFitterStep(
                self._currentFitterStep)
            destroyFitterStep.destroy()
            self._buildStepsList()

    def _stepsListItemClicked(self, modelIndex):
        """
        Changes current step and possibly changes checked/run status.
        """
        model = modelIndex.model()
        item = model.itemFromIndex(modelIndex)
        isChecked = item.checkState() == QtCore.Qt.Checked
        self._currentFitterStep = item.data()
        if self._currentFitterStep:
            fitterSteps = self._fitter.getFitterSteps()
            currentIndex = fitterSteps.index(self._currentFitterStep)
            #print("currentIndex", currentIndex, isChecked)
            if (not self._currentFitterStep.hasRun()) and isChecked:
                for index in range(currentIndex + 1):
                    step = fitterSteps[index]
                    if not step.hasRun():
                        step.run()
                        self._refreshStepItem(step)
                        self._refreshGraphics()
            elif self._currentFitterStep.hasRun() and (not isChecked):
                self._fitter.load()
                self._sceneChanged()
                for index in range(currentIndex):
                    fitterSteps[index].run()
                self._refreshGraphics()
                for index in range(currentIndex, len(fitterSteps)):
                    step = fitterSteps[index]
                    if step.hasRun():
                        step.setHasRun(False)
                        self._refreshStepItem(step)
        self._updateFitterStepWidgets()

    def _buildStepsList(self):
        """
        Fill the graphics list view with the list of graphics for current region/scene
        """
        self._stepsItems = QtGui.QStandardItemModel(self._ui.steps_listView)
        selectedIndex = None
        fitter = self._model.getFitter()
        # fitter configuration appears as first step called "Config"
        item = QtGui.QStandardItem("Config")
        item.setData(None)
        item.setCheckable(False)
        item.setEditable(False)
        self._stepsItems.appendRow(item)
        selectedIndex = self._stepsItems.indexFromItem(item)
        for step in fitter.getFitterSteps():
            name = None
            isAlign = isinstance(step, FitterStepAlign)
            isFit = isinstance(step, FitterStepFit)
            assert isAlign or isFit, "GeometricFitWidget.  Unknown FitterStep type"
            name = "Align" if isAlign else "Fit"
            item = QtGui.QStandardItem(name)
            item.setData(step)
            item.setCheckable(True)
            item.setEditable(False)
            item.setCheckState(
                QtCore.Qt.Checked if step.hasRun() else QtCore.Qt.Unchecked)
            self._stepsItems.appendRow(item)
            if step == self._currentFitterStep:
                selectedIndex = self._stepsItems.indexFromItem(item)
        self._ui.steps_listView.setModel(self._stepsItems)
        self._ui.steps_listView.setCurrentIndex(selectedIndex)
        self._ui.steps_listView.show()
        self._updateFitterStepWidgets()

    def _refreshStepItem(self, step):
        """
        Update check state and selection of step in steps list view.
        :param stepIndex: Row index of item in step items.
        """
        item = self._stepsItems.item(
            self._fitter.getFitterSteps().index(step) + 1)
        item.setCheckState(
            QtCore.Qt.Checked if step.hasRun() else QtCore.Qt.Unchecked)
        step = item.data()
        if step == self._currentFitterStep:
            self._ui.steps_listView.setCurrentIndex(
                self._stepsItems.indexFromItem(item))

    def _updateFitterStepWidgets(self):
        """
        Update and display widgets for currentFitterStep
        """
        if self._currentFitterStep is None:
            self._ui.config_groupBox.show()
            self._ui.align_groupBox.hide()
            self._ui.fit_groupBox.hide()
        elif isinstance(self._currentFitterStep, FitterStepAlign):
            self._updateAlignWidgets()
            self._ui.config_groupBox.hide()
            self._ui.align_groupBox.show()
            self._ui.fit_groupBox.hide()
        else:  # elif isinstance(self._currentFitterStep, FitterStepFit):
            self._updateFitWidgets()
            self._ui.config_groupBox.hide()
            self._ui.align_groupBox.hide()
            self._ui.fit_groupBox.show()
        self._ui.stepsDelete_pushButton.setEnabled(
            self._currentFitterStep is not None)

    def _doneClicked(self):
        self._model.done()
        self._ui.dockWidget.setFloating(False)
        self._callback()

    def _viewAllClicked(self):
        self._ui.alignmentsceneviewerwidget.viewAll()

# === display widgets ===

    def _makeConnectionsDisplay(self):
        self._ui.displayAxes_checkBox.clicked.connect(self._displayAxesClicked)
        self._ui.displayMarkerDataPoints_checkBox.clicked.connect(
            self._displayMarkerDataPointsClicked)
        self._ui.displayMarkerDataNames_checkBox.clicked.connect(
            self._displayMarkerDataNamesClicked)
        self._ui.displayMarkerDataProjections_checkBox.clicked.connect(
            self._displayMarkerDataProjectionsClicked)
        self._ui.displayMarkerPoints_checkBox.clicked.connect(
            self._displayMarkerPointsClicked)
        self._ui.displayMarkerNames_checkBox.clicked.connect(
            self._displayMarkerNamesClicked)
        self._ui.displayDataPoints_checkBox.clicked.connect(
            self._displayDataPointsClicked)
        self._ui.displayDataProjections_checkBox.clicked.connect(
            self._displayDataProjectionsClicked)
        self._ui.displayDataProjectionPoints_checkBox.clicked.connect(
            self._displayDataProjectionPointsClicked)
        self._ui.displayNodePoints_checkBox.clicked.connect(
            self._displayNodePointsClicked)
        self._ui.displayNodeNumbers_checkBox.clicked.connect(
            self._displayNodeNumbersClicked)
        self._ui.displayNodeDerivativeLabelsD1_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD1Clicked)
        self._ui.displayNodeDerivativeLabelsD2_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD2Clicked)
        self._ui.displayNodeDerivativeLabelsD3_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD3Clicked)
        self._ui.displayNodeDerivativeLabelsD12_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD12Clicked)
        self._ui.displayNodeDerivativeLabelsD13_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD13Clicked)
        self._ui.displayNodeDerivativeLabelsD23_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD23Clicked)
        self._ui.displayNodeDerivativeLabelsD123_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD123Clicked)
        self._ui.displayNodeDerivatives_checkBox.clicked.connect(
            self._displayNodeDerivativesClicked)
        self._ui.displayElementAxes_checkBox.clicked.connect(
            self._displayElementAxesClicked)
        self._ui.displayElementNumbers_checkBox.clicked.connect(
            self._displayElementNumbersClicked)
        self._ui.displayLines_checkBox.clicked.connect(
            self._displayLinesClicked)
        self._ui.displayLinesExterior_checkBox.clicked.connect(
            self._displayLinesExteriorClicked)
        self._ui.displaySurfaces_checkBox.clicked.connect(
            self._displaySurfacesClicked)
        self._ui.displaySurfacesExterior_checkBox.clicked.connect(
            self._displaySurfacesExteriorClicked)
        self._ui.displaySurfacesTranslucent_checkBox.clicked.connect(
            self._displaySurfacesTranslucentClicked)
        self._ui.displaySurfacesWireframe_checkBox.clicked.connect(
            self._displaySurfacesWireframeClicked)

    def _updateDisplayWidgets(self):
        """
        Update display widgets to display settings for model graphics display.
        """
        self._ui.displayAxes_checkBox.setChecked(self._model.isDisplayAxes())
        self._ui.displayMarkerDataPoints_checkBox.setChecked(
            self._model.isDisplayMarkerDataPoints())
        self._ui.displayMarkerDataNames_checkBox.setChecked(
            self._model.isDisplayMarkerDataNames())
        self._ui.displayMarkerDataProjections_checkBox.setChecked(
            self._model.isDisplayMarkerDataProjections())
        self._ui.displayMarkerPoints_checkBox.setChecked(
            self._model.isDisplayMarkerPoints())
        self._ui.displayMarkerNames_checkBox.setChecked(
            self._model.isDisplayMarkerNames())
        self._ui.displayDataPoints_checkBox.setChecked(
            self._model.isDisplayDataPoints())
        self._ui.displayDataProjections_checkBox.setChecked(
            self._model.isDisplayDataProjections())
        self._ui.displayDataProjectionPoints_checkBox.setChecked(
            self._model.isDisplayDataProjectionPoints())
        self._ui.displayNodePoints_checkBox.setChecked(
            self._model.isDisplayNodePoints())
        self._ui.displayNodeNumbers_checkBox.setChecked(
            self._model.isDisplayNodeNumbers())
        self._ui.displayNodeDerivativeLabelsD1_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D1"))
        self._ui.displayNodeDerivativeLabelsD2_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D2"))
        self._ui.displayNodeDerivativeLabelsD3_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D3"))
        self._ui.displayNodeDerivativeLabelsD12_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D12"))
        self._ui.displayNodeDerivativeLabelsD13_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D13"))
        self._ui.displayNodeDerivativeLabelsD23_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D23"))
        self._ui.displayNodeDerivativeLabelsD123_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D123"))
        self._ui.displayNodeDerivatives_checkBox.setChecked(
            self._model.isDisplayNodeDerivatives())
        self._ui.displayElementNumbers_checkBox.setChecked(
            self._model.isDisplayElementNumbers())
        self._ui.displayElementAxes_checkBox.setChecked(
            self._model.isDisplayElementAxes())
        self._ui.displayLines_checkBox.setChecked(self._model.isDisplayLines())
        self._ui.displayLinesExterior_checkBox.setChecked(
            self._model.isDisplayLinesExterior())
        self._ui.displaySurfaces_checkBox.setChecked(
            self._model.isDisplaySurfaces())
        self._ui.displaySurfacesExterior_checkBox.setChecked(
            self._model.isDisplaySurfacesExterior())
        self._ui.displaySurfacesTranslucent_checkBox.setChecked(
            self._model.isDisplaySurfacesTranslucent())
        self._ui.displaySurfacesWireframe_checkBox.setChecked(
            self._model.isDisplaySurfacesWireframe())

    def _displayAxesClicked(self):
        self._model.setDisplayAxes(self._ui.displayAxes_checkBox.isChecked())

    def _displayMarkerDataPointsClicked(self):
        self._model.setDisplayMarkerDataPoints(
            self._ui.displayMarkerDataPoints_checkBox.isChecked())

    def _displayMarkerDataNamesClicked(self):
        self._model.setDisplayMarkerDataNames(
            self._ui.displayMarkerDataNames_checkBox.isChecked())

    def _displayMarkerDataProjectionsClicked(self):
        self._model.setDisplayMarkerDataProjections(
            self._ui.displayMarkerDataProjections_checkBox.isChecked())

    def _displayMarkerPointsClicked(self):
        self._model.setDisplayMarkerPoints(
            self._ui.displayMarkerPoints_checkBox.isChecked())

    def _displayMarkerNamesClicked(self):
        self._model.setDisplayMarkerNames(
            self._ui.displayMarkerNames_checkBox.isChecked())

    def _displayDataPointsClicked(self):
        self._model.setDisplayDataPoints(
            self._ui.displayDataPoints_checkBox.isChecked())

    def _displayDataProjectionsClicked(self):
        self._model.setDisplayDataProjections(
            self._ui.displayDataProjections_checkBox.isChecked())

    def _displayDataProjectionPointsClicked(self):
        self._model.setDisplayDataProjectionPoints(
            self._ui.displayDataProjectionPoints_checkBox.isChecked())

    def _displayNodePointsClicked(self):
        self._model.setDisplayNodePoints(
            self._ui.displayNodePoints_checkBox.isChecked())

    def _displayNodeNumbersClicked(self):
        self._model.setDisplayNodeNumbers(
            self._ui.displayNodeNumbers_checkBox.isChecked())

    def _displayNodeDerivativesClicked(self):
        self._model.setDisplayNodeDerivatives(
            self._ui.displayNodeDerivatives_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD1Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D1", self._ui.displayNodeDerivativeLabelsD1_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD2Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D2", self._ui.displayNodeDerivativeLabelsD2_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD3Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D3", self._ui.displayNodeDerivativeLabelsD3_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD12Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D12",
            self._ui.displayNodeDerivativeLabelsD12_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD13Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D13",
            self._ui.displayNodeDerivativeLabelsD13_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD23Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D23",
            self._ui.displayNodeDerivativeLabelsD23_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD123Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D123",
            self._ui.displayNodeDerivativeLabelsD123_checkBox.isChecked())

    def _displayElementAxesClicked(self):
        self._model.setDisplayElementAxes(
            self._ui.displayElementAxes_checkBox.isChecked())

    def _displayElementNumbersClicked(self):
        self._model.setDisplayElementNumbers(
            self._ui.displayElementNumbers_checkBox.isChecked())

    def _displayLinesClicked(self):
        self._model.setDisplayLines(self._ui.displayLines_checkBox.isChecked())
        self._autoPerturbLines()

    def _displayLinesExteriorClicked(self):
        self._model.setDisplayLinesExterior(
            self._ui.displayLinesExterior_checkBox.isChecked())

    def _displaySurfacesClicked(self):
        self._model.setDisplaySurfaces(
            self._ui.displaySurfaces_checkBox.isChecked())
        self._autoPerturbLines()

    def _displaySurfacesExteriorClicked(self):
        self._model.setDisplaySurfacesExterior(
            self._ui.displaySurfacesExterior_checkBox.isChecked())

    def _displaySurfacesTranslucentClicked(self):
        self._model.setDisplaySurfacesTranslucent(
            self._ui.displaySurfacesTranslucent_checkBox.isChecked())
        self._autoPerturbLines()

    def _displaySurfacesWireframeClicked(self):
        self._model.setDisplaySurfacesWireframe(
            self._ui.displaySurfacesWireframe_checkBox.isChecked())

# === config widgets ===

    def _setupConfigWidgets(self):
        """
        Set up config widgets and display values from fitter object.
        """
        self._ui.configModelCoordinates_fieldChooser.setRegion(self._region)
        self._ui.configModelCoordinates_fieldChooser.setNullObjectName("-")
        self._ui.configModelCoordinates_fieldChooser.setConditional(
            fieldIsManagedCoordinates)
        self._ui.configDataCoordinates_fieldChooser.setRegion(self._region)
        self._ui.configDataCoordinates_fieldChooser.setNullObjectName("-")
        self._ui.configDataCoordinates_fieldChooser.setConditional(
            fieldIsManagedCoordinates)
        self._ui.configMarkerGroup_fieldChooser.setRegion(self._region)
        self._ui.configMarkerGroup_fieldChooser.setNullObjectName("-")
        self._ui.configMarkerGroup_fieldChooser.setConditional(
            fieldIsManagedGroup)

    def _updateConfigWidgets(self):
        """
        Update config widgets to display settings for Fitter.
        """
        self._ui.configModelCoordinates_fieldChooser.setField(
            self._fitter.getModelCoordinatesField())
        self._ui.configDataCoordinates_fieldChooser.setField(
            self._fitter.getDataCoordinatesField())
        self._ui.configMarkerGroup_fieldChooser.setField(
            self._fitter.getMarkerGroup())

    def _makeConnectionsConfig(self):
        self._ui.configModelCoordinates_fieldChooser.currentIndexChanged.connect(
            self._configModelCoordinatesFieldChanged)
        self._ui.configDataCoordinates_fieldChooser.currentIndexChanged.connect(
            self._configDataCoordinatesFieldChanged)
        self._ui.configMarkerGroup_fieldChooser.currentIndexChanged.connect(
            self._configMarkerGroupChanged)

    def _configModelCoordinatesFieldChanged(self, index):
        """
        Callback for change in model coordinates field chooser widget.
        """
        field = self._ui.configModelCoordinates_fieldChooser.getField()
        if field:
            self._fitter.setModelCoordinatesField(field)

    def _configDataCoordinatesFieldChanged(self, index):
        """
        Callback for change in data coordinates field chooser widget.
        """
        field = self._ui.configDataCoordinates_fieldChooser.getField()
        if field:
            self._fitter.setDataCoordinatesField(field)

    def _configMarkerGroupChanged(self, index):
        """
        Callback for change in marker group field chooser widget.
        """
        group = self._ui.configMarkerGroup_fieldChooser.getField()
        if group:
            self._fitter.setMarkerGroup(group)

# === align widgets ===

    def _makeConnectionsAlign(self):
        self._ui.alignMarkers_checkBox.clicked.connect(
            self._alignMarkersClicked)
        self._ui.alignRotation_lineEdit.editingFinished.connect(
            self._alignRotationEntered)
        self._ui.alignScale_lineEdit.editingFinished.connect(
            self._alignScaleEntered)
        self._ui.alignTranslation_lineEdit.editingFinished.connect(
            self._alignTranslationEntered)

    def _getAlign(self):
        align = self._currentFitterStep
        assert isinstance(align, FitterStepAlign)
        return align

    def _updateAlignWidgets(self):
        """
        Update align widgets to display parameters from current align step.
        """
        align = self._getAlign()
        realFormat = "{:.4g}"
        self._ui.alignMarkers_checkBox.setCheckState(
            QtCore.Qt.Checked if align.isAlignMarkers(
            ) else QtCore.Qt.Unchecked)
        self._ui.alignRotation_lineEdit.setText(", ".join(
            realFormat.format(value) for value in align.getRotation()))
        self._ui.alignScale_lineEdit.setText(
            realFormat.format(align.getScale()))
        self._ui.alignTranslation_lineEdit.setText(", ".join(
            realFormat.format(value) for value in align.getTranslation()))

    def _alignMarkersClicked(self):
        state = self._ui.alignMarkers_checkBox.checkState()
        self._getAlign().setAlignMarkers(state == QtCore.Qt.Checked)

    def _alignRotationEntered(self):
        values = QLineEdit_parseVector3(self._ui.alignRotation_lineEdit)
        if values:
            self._getAlign().setRotation(values)
        else:
            print("Invalid model rotation Euler angles entered")
        self._updateAlignWidgets()

    def _alignScaleEntered(self):
        value = QLineEdit_parseRealNonNegative(self._ui.alignScale_lineEdit)
        if value > 0.0:
            self._getAlign().setScale(value)
        else:
            print("Invalid model scale entered")
        self._updateAlignWidgets()

    def _alignTranslationEntered(self):
        values = QLineEdit_parseVector3(self._ui.alignTranslation_lineEdit)
        if values:
            self._getAlign().setTranslation(values)
        else:
            print("Invalid model translation entered")
        self._updateAlignWidgets()

# === fit widgets ===

    def _makeConnectionsFit(self):
        self._ui.fitMarkerWeight_lineEdit.editingFinished.connect(
            self._fitMarkerWeightEntered)
        self._ui.fitStrainPenalty_lineEdit.editingFinished.connect(
            self._fitStrainPenaltyEntered)
        self._ui.fitCurvaturePenalty_lineEdit.editingFinished.connect(
            self._fitCurvaturePenaltyEntered)
        self._ui.fitEdgeDiscontinuityPenalty_lineEdit.editingFinished.connect(
            self._fitEdgeDiscontinuityPenaltyEntered)
        self._ui.fitIterations_spinBox.valueChanged.connect(
            self._fitIterationsValueChanged)
        self._ui.fitUpdateReferenceState_checkBox.clicked.connect(
            self._fitUpdateReferenceStateClicked)

    def _getFit(self):
        assert isinstance(self._currentFitterStep, FitterStepFit)
        return self._currentFitterStep

    def _updateFitWidgets(self):
        """
        Update fit widgets to display parameters from fit step.
        """
        fit = self._getFit()
        realFormat = "{:.16}"
        self._ui.fitMarkerWeight_lineEdit.setText(
            realFormat.format(fit.getMarkerWeight()))
        self._ui.fitStrainPenalty_lineEdit.setText(
            realFormat.format(fit.getStrainPenaltyWeight()))
        self._ui.fitCurvaturePenalty_lineEdit.setText(
            realFormat.format(fit.getCurvaturePenaltyWeight()))
        self._ui.fitEdgeDiscontinuityPenalty_lineEdit.setText(
            realFormat.format(fit.getEdgeDiscontinuityPenaltyWeight()))
        self._ui.fitIterations_spinBox.setValue(fit.getNumberOfIterations())
        self._ui.fitUpdateReferenceState_checkBox.setCheckState(
            QtCore.Qt.Checked if fit.isUpdateReferenceState(
            ) else QtCore.Qt.Unchecked)

    def _fitMarkerWeightEntered(self):
        value = QLineEdit_parseRealNonNegative(
            self._ui.fitMarkerWeight_lineEdit)
        if value >= 0.0:
            self._getFit().setMarkerWeight(value)
        else:
            print("Invalid marker weight; must be non-negative")
        self._updateFitWidgets()

    def _fitStrainPenaltyEntered(self):
        value = QLineEdit_parseRealNonNegative(
            self._ui.fitStrainPenalty_lineEdit)
        if value >= 0.0:
            self._getFit().setStrainPenaltyWeight(value)
        else:
            print("Invalid penalty weight; must be non-negative")
        self._updateFitWidgets()

    def _fitCurvaturePenaltyEntered(self):
        value = QLineEdit_parseRealNonNegative(
            self._ui.fitCurvaturePenalty_lineEdit)
        if value >= 0.0:
            self._getFit().setCurvaturePenaltyWeight(value)
        else:
            print("Invalid penalty weight; must be non-negative")
        self._updateFitWidgets()

    def _fitEdgeDiscontinuityPenaltyEntered(self):
        value = QLineEdit_parseRealNonNegative(
            self._ui.fitEdgeDiscontinuityPenalty_lineEdit)
        if value >= 0.0:
            self._getFit().setEdgeDiscontinuityPenaltyWeight(value)
        else:
            print("Invalid penalty weight; must be non-negative")
        self._updateFitWidgets()

    def _fitIterationsValueChanged(self, value):
        self._getFit().setNumberOfIterations(value)

    def _fitUpdateReferenceStateClicked(self):
        state = self._ui.fitUpdateReferenceState_checkBox.checkState()
        self._getFit().setUpdateReferenceState(state == QtCore.Qt.Checked)
Пример #6
0
 def _stepsAddFitClicked(self):
     """
     Add a new fit step.
     """
     self._currentFitterStep = FitterStepFit(self._fitter)
     self._buildStepsList()
Пример #7
0
 def _stepsAddAlignClicked(self):
     """
     Add a new align step.
     """
     self._currentFitterStep = FitterStepAlign(self._fitter)
     self._buildStepsList()
Пример #8
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)
Пример #9
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)
Пример #10
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)
Пример #11
0
class GeometricFitWidget(QtGui.QWidget):
    """
    User interface for github.com/ABI-Software/scaffoldfitter
    """
    def __init__(self, model, parent=None):
        """
        """
        super(GeometricFitWidget, self).__init__(parent)
        self._ui = Ui_GeometricFitWidget()
        self._ui.setupUi(self)
        self._ui.alignmentsceneviewerwidget.setContext(model.getContext())
        self._ui.alignmentsceneviewerwidget.setModel(model)
        self._model = model
        self._fitter = self._model.getFitter()
        self._region = self._fitter.getRegion()
        self._scene = self._region.getScene()
        self._currentFitterStep = self._fitter.getInitialFitterStepConfig(
        )  # always exists
        self._ui.alignmentsceneviewerwidget.graphicsInitialized.connect(
            self._graphicsInitialized)
        self._callback = None
        self._setupConfigWidgets()
        self._updateGeneralWidgets()
        self._updateDisplayWidgets()
        self._makeConnections()

    def _graphicsInitialized(self):
        """
        Callback for when SceneviewerWidget is initialised
        """
        self._sceneChanged()
        sceneviewer = self._ui.alignmentsceneviewerwidget.getSceneviewer()
        if sceneviewer is not None:
            sceneviewer.setTransparencyMode(sceneviewer.TRANSPARENCY_MODE_SLOW)
            self._autoPerturbLines()
            sceneviewer.viewAll()

    def _sceneChanged(self):
        """
        Set custom scene from model.
        """
        sceneviewer = self._ui.alignmentsceneviewerwidget.getSceneviewer()
        if sceneviewer is not None:
            self._model.createGraphics()
            sceneviewer.setScene(self._model.getScene())
            self._refreshGraphics()

    def _refreshGraphics(self):
        """
        Autorange spectrum and force redraw of graphics.
        """
        self._model.autorangeSpectrum()
        self._ui.alignmentsceneviewerwidget.paintGL()

    def _makeConnections(self):
        self._makeConnectionsGeneral()
        self._makeConnectionsDisplay()
        self._makeConnectionsConfig()
        self._makeConnectionsAlign()
        self._makeConnectionsFit()

    def registerDoneExecution(self, callback):
        self._callback = callback

    def _autoPerturbLines(self):
        """
        Enable scene viewer perturb lines iff solid surfaces are drawn with lines.
        Call whenever lines, surfaces or translucency changes
        """
        sceneviewer = self._ui.alignmentsceneviewerwidget.getSceneviewer()
        if sceneviewer is not None:
            sceneviewer.setPerturbLinesFlag(self._model.needPerturbLines())

# === general widgets ===

    def _makeConnectionsGeneral(self):
        self._ui.stepsAddAlign_pushButton.clicked.connect(
            self._stepsAddAlignClicked)
        self._ui.stepsAddConfig_pushButton.clicked.connect(
            self._stepsAddConfigClicked)
        self._ui.stepsAddFit_pushButton.clicked.connect(
            self._stepsAddFitClicked)
        self._ui.stepsDelete_pushButton.clicked.connect(
            self._stepsDeleteClicked)
        self._ui.steps_listView.clicked[QtCore.QModelIndex].connect(
            self._stepsListItemClicked)
        self._ui.done_pushButton.clicked.connect(self._doneButtonClicked)
        self._ui.stdViews_pushButton.clicked.connect(
            self._stdViewsButtonClicked)
        self._ui.viewAll_pushButton.clicked.connect(self._viewAllButtonClicked)

    def _updateGeneralWidgets(self):
        self._ui.identifier_label.setText("Identifier:  " +
                                          self._model.getIdentifier())
        self._buildStepsList()

    def _stepsAddAlignClicked(self):
        """
        Add a new align step.
        """
        self._currentFitterStep = FitterStepAlign()
        self._fitter.addFitterStep(
            self._currentFitterStep)  # Future: , lastFitterStep
        self._buildStepsList()

    def _stepsAddConfigClicked(self):
        """
        Add a new config step.
        """
        self._currentFitterStep = FitterStepConfig()
        self._fitter.addFitterStep(
            self._currentFitterStep)  # Future: , lastFitterStep
        self._buildStepsList()

    def _stepsAddFitClicked(self):
        """
        Add a new fit step.
        """
        self._currentFitterStep = FitterStepFit()
        self._fitter.addFitterStep(
            self._currentFitterStep)  # Future: , lastFitterStep
        self._buildStepsList()

    def runToStep(self, endStep):
        """
        Run fitter steps up to specified end step.
        """
        fitterSteps = self._fitter.getFitterSteps()
        endIndex = fitterSteps.index(endStep)
        sceneChanged = self._fitter.run(
            endStep, self._model.getOutputModelFileNameStem())
        if sceneChanged:
            for index in range(endIndex + 1, len(fitterSteps)):
                self._refreshStepItem(fitterSteps[index])
            self._sceneChanged()
        else:
            for index in range(1, endIndex + 1):
                self._refreshStepItem(fitterSteps[index])
            self._refreshGraphics()

    def _stepsDeleteClicked(self):
        """
        Delete the currently selected step, except for initial config.
        Select next step after, or before if none.
        """
        assert self._currentFitterStep is not self._fitter.getInitialFitterStepConfig(
        )
        if self._currentFitterStep.hasRun():
            # reload and run to step before current
            fitterSteps = self._fitter.getFitterSteps()
            index = fitterSteps.index(self._currentFitterStep)
            self._fitter.run(fitterSteps[index - 1])
            self._sceneChanged()
        self._currentFitterStep = self._fitter.removeFitterStep(
            self._currentFitterStep)
        self._buildStepsList()

    def _stepsListItemClicked(self, modelIndex):
        """
        Changes current step and possibly changes checked/run status.
        """
        model = modelIndex.model()
        item = model.itemFromIndex(modelIndex)
        step = item.data()
        if step != self._currentFitterStep:
            self._currentFitterStep = step
            self._updateFitterStepWidgets()
        isInitialConfig = step is self._fitter.getInitialFitterStepConfig()
        isChecked = True if isInitialConfig else (item.checkState()
                                                  == QtCore.Qt.Checked)
        if step.hasRun() != isChecked:
            if isChecked:
                endStep = step
            else:
                fitterSteps = self._fitter.getFitterSteps()
                index = fitterSteps.index(step)
                endStep = fitterSteps[index - 1]
            self.runToStep(endStep)

    def _buildStepsList(self):
        """
        Fill the graphics list view with the list of graphics for current region/scene
        """
        self._stepsItems = QtGui.QStandardItemModel(self._ui.steps_listView)
        selectedIndex = None
        firstStep = True
        fitterSteps = self._fitter.getFitterSteps()
        for step in fitterSteps:
            name = None
            if isinstance(step, FitterStepAlign):
                name = "Align"
            elif isinstance(step, FitterStepConfig):
                name = "Config"
            elif isinstance(step, FitterStepFit):
                name = "Fit"
            else:
                assert False, "GeometricFitWidget.  Unknown FitterStep type"
            item = QtGui.QStandardItem(name)
            item.setData(step)
            item.setEditable(False)
            if firstStep:
                item.setCheckable(False)
                firstStep = False
            else:
                item.setCheckable(True)
                item.setCheckState(QtCore.Qt.Checked if step.hasRun(
                ) else QtCore.Qt.Unchecked)
            self._stepsItems.appendRow(item)
            if step == self._currentFitterStep:
                selectedIndex = self._stepsItems.indexFromItem(item)
        self._ui.steps_listView.setModel(self._stepsItems)
        self._ui.steps_listView.setCurrentIndex(selectedIndex)
        self._ui.steps_listView.show()
        self._updateFitterStepWidgets()

    def _refreshStepItem(self, step):
        """
        Update check state and selection of step in steps list view.
        :param stepIndex: Row index of item in step items.
        """
        index = self._fitter.getFitterSteps().index(step)
        item = self._stepsItems.item(index)
        if step is not self._fitter.getInitialFitterStepConfig():
            item.setCheckState(
                QtCore.Qt.Checked if step.hasRun() else QtCore.Qt.Unchecked)
        if step == self._currentFitterStep:
            self._ui.steps_listView.setCurrentIndex(
                self._stepsItems.indexFromItem(item))

    def _updateFitterStepWidgets(self):
        """
        Update and display widgets for currentFitterStep
        """
        isInitialConfig = self._currentFitterStep == self._fitter.getInitialFitterStepConfig(
        )
        isAlign = isinstance(self._currentFitterStep, FitterStepAlign)
        isConfig = isinstance(self._currentFitterStep, FitterStepConfig)
        isFit = isinstance(self._currentFitterStep, FitterStepFit)
        if isAlign:
            self._updateAlignWidgets()
        elif isConfig:
            self._ui.configInitial_groupBox.setVisible(isInitialConfig)
            self._updateConfigWidgets()
        elif isFit:
            self._updateFitWidgets()
        self._ui.align_groupBox.setVisible(isAlign)
        self._ui.config_groupBox.setVisible(isConfig)
        self._ui.fit_groupBox.setVisible(isFit)
        self._ui.stepsDelete_pushButton.setEnabled(not isInitialConfig)

    def _doneButtonClicked(self):
        self._model.done()
        self._ui.dockWidget.setFloating(False)
        self._callback()

    def _stdViewsButtonClicked(self):
        sceneviewer = self._ui.alignmentsceneviewerwidget.getSceneviewer()
        if sceneviewer is not None:
            result, eyePosition, lookatPosition, upVector = sceneviewer.getLookatParameters(
            )
            upVector = normalize(upVector)
            viewVector = sub(lookatPosition, eyePosition)
            viewDistance = magnitude(viewVector)
            viewVector = normalize(viewVector)
            viewX = dot(viewVector, [1.0, 0.0, 0.0])
            viewY = dot(viewVector, [0.0, 1.0, 0.0])
            viewZ = dot(viewVector, [0.0, 0.0, 1.0])
            upX = dot(upVector, [1.0, 0.0, 0.0])
            upY = dot(upVector, [0.0, 1.0, 0.0])
            upZ = dot(upVector, [0.0, 0.0, 1.0])
            if (viewZ < -0.999) and (upY > 0.999):
                # XY -> XZ
                viewVector = [0.0, 1.0, 0.0]
                upVector = [0.0, 0.0, 1.0]
            elif (viewY > 0.999) and (upZ > 0.999):
                # XZ -> YZ
                viewVector = [-1.0, 0.0, 0.0]
                upVector = [0.0, 0.0, 1.0]
            else:
                # XY
                viewVector = [0.0, 0.0, -1.0]
                upVector = [0.0, 1.0, 0.0]
            eyePosition = sub(lookatPosition, mult(viewVector, viewDistance))
            sceneviewer.setLookatParametersNonSkew(eyePosition, lookatPosition,
                                                   upVector)

    def _viewAllButtonClicked(self):
        self._ui.alignmentsceneviewerwidget.viewAll()

# === display widgets ===

    def _makeConnectionsDisplay(self):
        self._ui.displayAxes_checkBox.clicked.connect(self._displayAxesClicked)
        self._ui.displayMarkerDataPoints_checkBox.clicked.connect(
            self._displayMarkerDataPointsClicked)
        self._ui.displayMarkerDataNames_checkBox.clicked.connect(
            self._displayMarkerDataNamesClicked)
        self._ui.displayMarkerDataProjections_checkBox.clicked.connect(
            self._displayMarkerDataProjectionsClicked)
        self._ui.displayMarkerPoints_checkBox.clicked.connect(
            self._displayMarkerPointsClicked)
        self._ui.displayMarkerNames_checkBox.clicked.connect(
            self._displayMarkerNamesClicked)
        self._ui.displayDataPoints_checkBox.clicked.connect(
            self._displayDataPointsClicked)
        self._ui.displayDataProjections_checkBox.clicked.connect(
            self._displayDataProjectionsClicked)
        self._ui.displayDataProjectionPoints_checkBox.clicked.connect(
            self._displayDataProjectionPointsClicked)
        self._ui.displayNodePoints_checkBox.clicked.connect(
            self._displayNodePointsClicked)
        self._ui.displayNodeNumbers_checkBox.clicked.connect(
            self._displayNodeNumbersClicked)
        self._ui.displayNodeDerivativeLabelsD1_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD1Clicked)
        self._ui.displayNodeDerivativeLabelsD2_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD2Clicked)
        self._ui.displayNodeDerivativeLabelsD3_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD3Clicked)
        self._ui.displayNodeDerivativeLabelsD12_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD12Clicked)
        self._ui.displayNodeDerivativeLabelsD13_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD13Clicked)
        self._ui.displayNodeDerivativeLabelsD23_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD23Clicked)
        self._ui.displayNodeDerivativeLabelsD123_checkBox.clicked.connect(
            self._displayNodeDerivativeLabelsD123Clicked)
        self._ui.displayNodeDerivatives_checkBox.clicked.connect(
            self._displayNodeDerivativesClicked)
        self._ui.displayElementAxes_checkBox.clicked.connect(
            self._displayElementAxesClicked)
        self._ui.displayElementNumbers_checkBox.clicked.connect(
            self._displayElementNumbersClicked)
        self._ui.displayLines_checkBox.clicked.connect(
            self._displayLinesClicked)
        self._ui.displayLinesExterior_checkBox.clicked.connect(
            self._displayLinesExteriorClicked)
        self._ui.displaySurfaces_checkBox.clicked.connect(
            self._displaySurfacesClicked)
        self._ui.displaySurfacesExterior_checkBox.clicked.connect(
            self._displaySurfacesExteriorClicked)
        self._ui.displaySurfacesTranslucent_checkBox.clicked.connect(
            self._displaySurfacesTranslucentClicked)
        self._ui.displaySurfacesWireframe_checkBox.clicked.connect(
            self._displaySurfacesWireframeClicked)

    def _updateDisplayWidgets(self):
        """
        Update display widgets to display settings for model graphics display.
        """
        self._ui.displayAxes_checkBox.setChecked(self._model.isDisplayAxes())
        self._ui.displayMarkerDataPoints_checkBox.setChecked(
            self._model.isDisplayMarkerDataPoints())
        self._ui.displayMarkerDataNames_checkBox.setChecked(
            self._model.isDisplayMarkerDataNames())
        self._ui.displayMarkerDataProjections_checkBox.setChecked(
            self._model.isDisplayMarkerDataProjections())
        self._ui.displayMarkerPoints_checkBox.setChecked(
            self._model.isDisplayMarkerPoints())
        self._ui.displayMarkerNames_checkBox.setChecked(
            self._model.isDisplayMarkerNames())
        self._ui.displayDataPoints_checkBox.setChecked(
            self._model.isDisplayDataPoints())
        self._ui.displayDataProjections_checkBox.setChecked(
            self._model.isDisplayDataProjections())
        self._ui.displayDataProjectionPoints_checkBox.setChecked(
            self._model.isDisplayDataProjectionPoints())
        self._ui.displayNodePoints_checkBox.setChecked(
            self._model.isDisplayNodePoints())
        self._ui.displayNodeNumbers_checkBox.setChecked(
            self._model.isDisplayNodeNumbers())
        self._ui.displayNodeDerivativeLabelsD1_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D1"))
        self._ui.displayNodeDerivativeLabelsD2_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D2"))
        self._ui.displayNodeDerivativeLabelsD3_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D3"))
        self._ui.displayNodeDerivativeLabelsD12_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D12"))
        self._ui.displayNodeDerivativeLabelsD13_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D13"))
        self._ui.displayNodeDerivativeLabelsD23_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D23"))
        self._ui.displayNodeDerivativeLabelsD123_checkBox.setChecked(
            self._model.isDisplayNodeDerivativeLabels("D123"))
        self._ui.displayNodeDerivatives_checkBox.setChecked(
            self._model.isDisplayNodeDerivatives())
        self._ui.displayElementNumbers_checkBox.setChecked(
            self._model.isDisplayElementNumbers())
        self._ui.displayElementAxes_checkBox.setChecked(
            self._model.isDisplayElementAxes())
        self._ui.displayLines_checkBox.setChecked(self._model.isDisplayLines())
        self._ui.displayLinesExterior_checkBox.setChecked(
            self._model.isDisplayLinesExterior())
        self._ui.displaySurfaces_checkBox.setChecked(
            self._model.isDisplaySurfaces())
        self._ui.displaySurfacesExterior_checkBox.setChecked(
            self._model.isDisplaySurfacesExterior())
        self._ui.displaySurfacesTranslucent_checkBox.setChecked(
            self._model.isDisplaySurfacesTranslucent())
        self._ui.displaySurfacesWireframe_checkBox.setChecked(
            self._model.isDisplaySurfacesWireframe())

    def _displayAxesClicked(self):
        self._model.setDisplayAxes(self._ui.displayAxes_checkBox.isChecked())

    def _displayMarkerDataPointsClicked(self):
        self._model.setDisplayMarkerDataPoints(
            self._ui.displayMarkerDataPoints_checkBox.isChecked())

    def _displayMarkerDataNamesClicked(self):
        self._model.setDisplayMarkerDataNames(
            self._ui.displayMarkerDataNames_checkBox.isChecked())

    def _displayMarkerDataProjectionsClicked(self):
        self._model.setDisplayMarkerDataProjections(
            self._ui.displayMarkerDataProjections_checkBox.isChecked())

    def _displayMarkerPointsClicked(self):
        self._model.setDisplayMarkerPoints(
            self._ui.displayMarkerPoints_checkBox.isChecked())

    def _displayMarkerNamesClicked(self):
        self._model.setDisplayMarkerNames(
            self._ui.displayMarkerNames_checkBox.isChecked())

    def _displayDataPointsClicked(self):
        self._model.setDisplayDataPoints(
            self._ui.displayDataPoints_checkBox.isChecked())

    def _displayDataProjectionsClicked(self):
        self._model.setDisplayDataProjections(
            self._ui.displayDataProjections_checkBox.isChecked())

    def _displayDataProjectionPointsClicked(self):
        self._model.setDisplayDataProjectionPoints(
            self._ui.displayDataProjectionPoints_checkBox.isChecked())

    def _displayNodePointsClicked(self):
        self._model.setDisplayNodePoints(
            self._ui.displayNodePoints_checkBox.isChecked())

    def _displayNodeNumbersClicked(self):
        self._model.setDisplayNodeNumbers(
            self._ui.displayNodeNumbers_checkBox.isChecked())

    def _displayNodeDerivativesClicked(self):
        self._model.setDisplayNodeDerivatives(
            self._ui.displayNodeDerivatives_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD1Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D1", self._ui.displayNodeDerivativeLabelsD1_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD2Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D2", self._ui.displayNodeDerivativeLabelsD2_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD3Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D3", self._ui.displayNodeDerivativeLabelsD3_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD12Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D12",
            self._ui.displayNodeDerivativeLabelsD12_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD13Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D13",
            self._ui.displayNodeDerivativeLabelsD13_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD23Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D23",
            self._ui.displayNodeDerivativeLabelsD23_checkBox.isChecked())

    def _displayNodeDerivativeLabelsD123Clicked(self):
        self._model.setDisplayNodeDerivativeLabels(
            "D123",
            self._ui.displayNodeDerivativeLabelsD123_checkBox.isChecked())

    def _displayElementAxesClicked(self):
        self._model.setDisplayElementAxes(
            self._ui.displayElementAxes_checkBox.isChecked())

    def _displayElementNumbersClicked(self):
        self._model.setDisplayElementNumbers(
            self._ui.displayElementNumbers_checkBox.isChecked())

    def _displayLinesClicked(self):
        self._model.setDisplayLines(self._ui.displayLines_checkBox.isChecked())
        self._autoPerturbLines()

    def _displayLinesExteriorClicked(self):
        self._model.setDisplayLinesExterior(
            self._ui.displayLinesExterior_checkBox.isChecked())

    def _displaySurfacesClicked(self):
        self._model.setDisplaySurfaces(
            self._ui.displaySurfaces_checkBox.isChecked())
        self._autoPerturbLines()

    def _displaySurfacesExteriorClicked(self):
        self._model.setDisplaySurfacesExterior(
            self._ui.displaySurfacesExterior_checkBox.isChecked())

    def _displaySurfacesTranslucentClicked(self):
        self._model.setDisplaySurfacesTranslucent(
            self._ui.displaySurfacesTranslucent_checkBox.isChecked())
        self._autoPerturbLines()

    def _displaySurfacesWireframeClicked(self):
        self._model.setDisplaySurfacesWireframe(
            self._ui.displaySurfacesWireframe_checkBox.isChecked())

# === config widgets ===

    def _setupConfigWidgets(self):
        """
        Set up config widgets and display values from fitter object.
        """
        self._ui.configModelCoordinates_fieldChooser.setRegion(self._region)
        self._ui.configModelCoordinates_fieldChooser.setNullObjectName("-")
        self._ui.configModelCoordinates_fieldChooser.setConditional(
            fieldIsManagedCoordinates)
        self._ui.configModelCoordinates_fieldChooser.setField(
            self._fitter.getModelCoordinatesField())
        self._ui.configDataCoordinates_fieldChooser.setRegion(self._region)
        self._ui.configDataCoordinates_fieldChooser.setNullObjectName("-")
        self._ui.configDataCoordinates_fieldChooser.setConditional(
            fieldIsManagedCoordinates)
        self._ui.configDataCoordinates_fieldChooser.setField(
            self._fitter.getDataCoordinatesField())
        self._ui.configMarkerGroup_fieldChooser.setRegion(self._region)
        self._ui.configMarkerGroup_fieldChooser.setNullObjectName("-")
        self._ui.configMarkerGroup_fieldChooser.setConditional(
            fieldIsManagedGroup)
        self._ui.configMarkerGroup_fieldChooser.setField(
            self._fitter.getMarkerGroup())

    def _makeConnectionsConfig(self):
        self._ui.configModelCoordinates_fieldChooser.currentIndexChanged.connect(
            self._configModelCoordinatesFieldChanged)
        self._ui.configDataCoordinates_fieldChooser.currentIndexChanged.connect(
            self._configDataCoordinatesFieldChanged)
        self._ui.configMarkerGroup_fieldChooser.currentIndexChanged.connect(
            self._configMarkerGroupChanged)
        self._ui.configProjectionCentreGroups_checkBox.clicked.connect(
            self._configProjectionCentreGroupsClicked)

    def _getConfig(self):
        config = self._currentFitterStep
        assert isinstance(config, FitterStepConfig)
        return config

    def _updateConfigWidgets(self):
        """
        Update config widgets to display settings for Fitter.
        """
        config = self._getConfig()
        self._ui.configProjectionCentreGroups_checkBox.setCheckState(
            QtCore.Qt.Checked if config.isProjectionCentreGroups(
            ) else QtCore.Qt.Unchecked)

    def _configModelCoordinatesFieldChanged(self, index):
        """
        Callback for change in model coordinates field chooser widget.
        """
        field = self._ui.configModelCoordinates_fieldChooser.getField()
        if field:
            self._fitter.setModelCoordinatesField(field)

    def _configDataCoordinatesFieldChanged(self, index):
        """
        Callback for change in data coordinates field chooser widget.
        """
        field = self._ui.configDataCoordinates_fieldChooser.getField()
        if field:
            self._fitter.setDataCoordinatesField(field)

    def _configMarkerGroupChanged(self, index):
        """
        Callback for change in marker group field chooser widget.
        """
        group = self._ui.configMarkerGroup_fieldChooser.getField()
        if group:
            self._fitter.setMarkerGroup(group)

    def _configProjectionCentreGroupsClicked(self):
        state = self._ui.configProjectionCentreGroups_checkBox.checkState()
        config = self._getConfig()
        if config.setProjectionCentreGroups(state == QtCore.Qt.Checked):
            fitterSteps = self._fitter.getFitterSteps()
            index = fitterSteps.index(config)
            if config.hasRun() and (((index + 1) == len(fitterSteps)) or
                                    (not fitterSteps[index + 1].hasRun())):
                config.run()
                self._refreshStepItem(config)
                self._refreshGraphics()

# === align widgets ===

    def _makeConnectionsAlign(self):
        self._ui.alignGroups_checkBox.clicked.connect(self._alignGroupsClicked)
        self._ui.alignMarkers_checkBox.clicked.connect(
            self._alignMarkersClicked)
        self._ui.alignRotation_lineEdit.editingFinished.connect(
            self._alignRotationEntered)
        self._ui.alignScale_lineEdit.editingFinished.connect(
            self._alignScaleEntered)
        self._ui.alignTranslation_lineEdit.editingFinished.connect(
            self._alignTranslationEntered)

    def _getAlign(self):
        align = self._currentFitterStep
        assert isinstance(align, FitterStepAlign)
        return align

    def _updateAlignWidgets(self):
        """
        Update align widgets to display parameters from current align step.
        """
        align = self._getAlign()
        realFormat = "{:.4g}"
        self._ui.alignGroups_checkBox.setCheckState(
            QtCore.Qt.Checked if align.isAlignGroups(
            ) else QtCore.Qt.Unchecked)
        self._ui.alignMarkers_checkBox.setCheckState(
            QtCore.Qt.Checked if align.isAlignMarkers(
            ) else QtCore.Qt.Unchecked)
        self._ui.alignRotation_lineEdit.setText(", ".join(
            realFormat.format(value) for value in align.getRotation()))
        self._ui.alignScale_lineEdit.setText(
            realFormat.format(align.getScale()))
        self._ui.alignTranslation_lineEdit.setText(", ".join(
            realFormat.format(value) for value in align.getTranslation()))

    def _alignGroupsClicked(self):
        state = self._ui.alignGroups_checkBox.checkState()
        self._getAlign().setAlignGroups(state == QtCore.Qt.Checked)

    def _alignMarkersClicked(self):
        state = self._ui.alignMarkers_checkBox.checkState()
        self._getAlign().setAlignMarkers(state == QtCore.Qt.Checked)

    def _alignRotationEntered(self):
        values = QLineEdit_parseVector3(self._ui.alignRotation_lineEdit)
        if values:
            self._getAlign().setRotation(values)
        else:
            print("Invalid model rotation Euler angles entered")
        self._updateAlignWidgets()

    def _alignScaleEntered(self):
        value = QLineEdit_parseRealNonNegative(self._ui.alignScale_lineEdit)
        if value > 0.0:
            self._getAlign().setScale(value)
        else:
            print("Invalid model scale entered")
        self._updateAlignWidgets()

    def _alignTranslationEntered(self):
        values = QLineEdit_parseVector3(self._ui.alignTranslation_lineEdit)
        if values:
            self._getAlign().setTranslation(values)
        else:
            print("Invalid model translation entered")
        self._updateAlignWidgets()

# === fit widgets ===

    def _makeConnectionsFit(self):
        self._ui.fitLineWeight_lineEdit.editingFinished.connect(
            self._fitLineWeightEntered)
        self._ui.fitMarkerWeight_lineEdit.editingFinished.connect(
            self._fitMarkerWeightEntered)
        self._ui.fitStrainPenalty_lineEdit.editingFinished.connect(
            self._fitStrainPenaltyEntered)
        self._ui.fitCurvaturePenalty_lineEdit.editingFinished.connect(
            self._fitCurvaturePenaltyEntered)
        self._ui.fitEdgeDiscontinuityPenalty_lineEdit.editingFinished.connect(
            self._fitEdgeDiscontinuityPenaltyEntered)
        self._ui.fitIterations_spinBox.valueChanged.connect(
            self._fitIterationsValueChanged)
        self._ui.fitMaximumSubIterations_spinBox.valueChanged.connect(
            self._fitMaximumSubIterationsValueChanged)
        self._ui.fitUpdateReferenceState_checkBox.clicked.connect(
            self._fitUpdateReferenceStateClicked)

    def _getFit(self):
        assert isinstance(self._currentFitterStep, FitterStepFit)
        return self._currentFitterStep

    def _updateFitWidgets(self):
        """
        Update fit widgets to display parameters from fit step.
        """
        fit = self._getFit()
        realFormat = "{:.16}"
        self._ui.fitLineWeight_lineEdit.setText(
            realFormat.format(fit.getLineWeight()))
        self._ui.fitMarkerWeight_lineEdit.setText(
            realFormat.format(fit.getMarkerWeight()))
        self._ui.fitStrainPenalty_lineEdit.setText(
            realFormat.format(fit.getStrainPenaltyWeight()))
        self._ui.fitCurvaturePenalty_lineEdit.setText(
            realFormat.format(fit.getCurvaturePenaltyWeight()))
        self._ui.fitEdgeDiscontinuityPenalty_lineEdit.setText(
            realFormat.format(fit.getEdgeDiscontinuityPenaltyWeight()))
        self._ui.fitIterations_spinBox.setValue(fit.getNumberOfIterations())
        self._ui.fitMaximumSubIterations_spinBox.setValue(
            fit.getMaximumSubIterations())
        self._ui.fitUpdateReferenceState_checkBox.setCheckState(
            QtCore.Qt.Checked if fit.isUpdateReferenceState(
            ) else QtCore.Qt.Unchecked)

    def _fitLineWeightEntered(self):
        value = QLineEdit_parseRealNonNegative(self._ui.fitLineWeight_lineEdit)
        if value >= 0.0:
            self._getFit().setLineWeight(value)
        else:
            print("Invalid line weight; must be non-negative")
        self._updateFitWidgets()

    def _fitMarkerWeightEntered(self):
        value = QLineEdit_parseRealNonNegative(
            self._ui.fitMarkerWeight_lineEdit)
        if value >= 0.0:
            self._getFit().setMarkerWeight(value)
        else:
            print("Invalid marker weight; must be non-negative")
        self._updateFitWidgets()

    def _fitStrainPenaltyEntered(self):
        value = QLineEdit_parseRealNonNegative(
            self._ui.fitStrainPenalty_lineEdit)
        if value >= 0.0:
            self._getFit().setStrainPenaltyWeight(value)
        else:
            print("Invalid penalty weight; must be non-negative")
        self._updateFitWidgets()

    def _fitCurvaturePenaltyEntered(self):
        value = QLineEdit_parseRealNonNegative(
            self._ui.fitCurvaturePenalty_lineEdit)
        if value >= 0.0:
            self._getFit().setCurvaturePenaltyWeight(value)
        else:
            print("Invalid penalty weight; must be non-negative")
        self._updateFitWidgets()

    def _fitEdgeDiscontinuityPenaltyEntered(self):
        value = QLineEdit_parseRealNonNegative(
            self._ui.fitEdgeDiscontinuityPenalty_lineEdit)
        if value >= 0.0:
            self._getFit().setEdgeDiscontinuityPenaltyWeight(value)
        else:
            print("Invalid penalty weight; must be non-negative")
        self._updateFitWidgets()

    def _fitIterationsValueChanged(self, value):
        self._getFit().setNumberOfIterations(value)

    def _fitMaximumSubIterationsValueChanged(self, value):
        self._getFit().setMaximumSubIterations(value)

    def _fitUpdateReferenceStateClicked(self):
        state = self._ui.fitUpdateReferenceState_checkBox.checkState()
        self._getFit().setUpdateReferenceState(state == QtCore.Qt.Checked)
Пример #12
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)
        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)