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()
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)
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)
def _stepsAddFitClicked(self): """ Add a new fit step. """ self._currentFitterStep = FitterStepFit(self._fitter) self._buildStepsList()
def _stepsAddAlignClicked(self): """ Add a new align step. """ self._currentFitterStep = FitterStepAlign(self._fitter) self._buildStepsList()
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)
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)
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)
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)
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)