Skip to content

training_configuration_widget

A widget allowing the creation of a CAREamics configuration.

ConfigurationWidget #

Bases: QGroupBox

A widget allowing the creation of a CAREamics configuration.

Parameters:

Name Type Description Default
careamics_config Configuration

careamics configuration object.

required
Source code in src/careamics_napari/widgets/training_configuration_widget.py
class ConfigurationWidget(QGroupBox):
    """A widget allowing the creation of a CAREamics configuration.

    Parameters
    ----------
    careamics_config : Configuration
        careamics configuration object.
    """

    # signal to show algorithm advanced configuration window.
    show_advanced_config = Signal()

    def __init__(self, careamics_config: BaseConfig) -> None:
        """Initialize the widget.

        Parameters
        ----------
        careamics_config : Configuration
            careamics configuration object.
        """
        super().__init__()

        self.configuration = careamics_config

        self.setTitle("Training Parameters")
        self.setMinimumWidth(200)

        # advanced settings
        icon = QtGui.QIcon(ICON_GEAR)
        self.training_expert_btn = QPushButton(icon, "")
        self.training_expert_btn.setFixedSize(35, 35)
        self.training_expert_btn.setToolTip("Open the advanced settings window.")
        self.training_expert_btn.clicked.connect(lambda: self.show_advanced_config.emit())

        # 3D checkbox
        self.enable_3d_chkbox = QCheckBox()
        self.enable_3d_chkbox.setToolTip("Use a 3D network")
        self.enable_3d_chkbox.clicked.connect(self._enable_3d_changed)

        # axes
        self.axes_widget = AxesWidget(careamics_config=self.configuration)

        # number of epochs
        _n_epochs = 30
        if self.configuration.training_config.lightning_trainer_config is not None:
            _n_epochs = self.configuration.training_config.lightning_trainer_config[
                "max_epochs"
            ]
        self.n_epochs_spin = create_int_spinbox(
            1, 1000, _n_epochs, tooltip="Number of epochs"
        )

        # batch size
        self.batch_size_spin = create_int_spinbox(1, 512, 16, 1)
        self.batch_size_spin.setToolTip(
            "Number of patches per batch (decrease if GPU memory is insufficient)"
        )

        # patch size XY
        self.patch_xy_spin = PowerOfTwoSpinBox(16, 512, 64)
        self.patch_xy_spin.setToolTip("Dimension of the patches in XY.")
        # patch size Z
        self.patch_z_spin = PowerOfTwoSpinBox(8, 512, 8)
        self.patch_z_spin.setToolTip("Dimension of the patches in Z.")
        self.patch_z_spin.setEnabled(self.configuration.is_3D)

        # layout
        formLayout = QFormLayout()
        formLayout.setContentsMargins(0, 0, 0, 0)
        formLayout.setFormAlignment(Qt.AlignLeft | Qt.AlignTop)  # type: ignore
        formLayout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)  # type: ignore
        formLayout.addRow("Enable 3D", self.enable_3d_chkbox)
        formLayout.addRow(self.axes_widget.label.text(), self.axes_widget.text_field)
        formLayout.addRow("# Epochs", self.n_epochs_spin)
        formLayout.addRow("Batch size", self.batch_size_spin)
        formLayout.addRow("Patch XY", self.patch_xy_spin)
        formLayout.addRow("Patch Z", self.patch_z_spin)
        formLayout.minimumSize()

        vbox = QVBoxLayout()
        vbox.setContentsMargins(5, 20, 5, 10)
        vbox.addWidget(
            self.training_expert_btn,
            alignment=Qt.AlignRight | Qt.AlignVCenter,  # type: ignore
        )
        vbox.addLayout(formLayout)
        self.setLayout(vbox)

        # create and bind properties to ui
        self._bind_properties()

    def update_config(self) -> None:
        """Update the configuration from the UI element."""
        # update config axes (from axes widget)
        self.axes_widget.update_config()
        # is 3D
        self.configuration.is_3D = self.is_3D

        # num epochs
        if self.configuration.training_config.lightning_trainer_config is not None:
            self.configuration.training_config.lightning_trainer_config["max_epochs"] = (
                self.num_epochs
            )

        if isinstance(self.configuration.data_config, DataConfig):
            # batch size
            self.configuration.data_config.batch_size = self.batch_size
            # patch size
            _patch_size = [self.patch_xy_size, self.patch_xy_size]
            if self.is_3D:
                _patch_size.insert(0, self.patch_z_size)
            self.configuration.data_config.patch_size = _patch_size
            self.configuration.set_3D(
                self.is_3D, self.configuration.data_config.axes, _patch_size
            )  # maybe not necessary, but let's have it to be sure.

    def _enable_3d_changed(self, state: bool) -> None:
        """Update the signal 3D state.

        Parameters
        ----------
        state : bool
            3D state.
        """
        self.patch_z_spin.setEnabled(state)

    def _bind_properties(self) -> None:
        """Create and bind the properties to the UI elements."""
        # type(self) returns the class of the instance, so we are adding
        # properties to the class itself, not the instance.
        # is 3D
        type(self).is_3D = bind(self.enable_3d_chkbox, "checked")
        # number of epochs
        if self.configuration.training_config.lightning_trainer_config is not None:
            type(self).num_epochs = bind(self.n_epochs_spin, "value")

        if isinstance(self.configuration.data_config, DataConfig):
            # batch size
            type(self).batch_size = bind(self.batch_size_spin, "value")
            # XY patch size
            type(self).patch_xy_size = bind(self.patch_xy_spin, "value")
            # Z patch size
            type(self).patch_z_size = bind(self.patch_z_spin, "value")

__init__(careamics_config) #

Initialize the widget.

Parameters:

Name Type Description Default
careamics_config Configuration

careamics configuration object.

required
Source code in src/careamics_napari/widgets/training_configuration_widget.py
def __init__(self, careamics_config: BaseConfig) -> None:
    """Initialize the widget.

    Parameters
    ----------
    careamics_config : Configuration
        careamics configuration object.
    """
    super().__init__()

    self.configuration = careamics_config

    self.setTitle("Training Parameters")
    self.setMinimumWidth(200)

    # advanced settings
    icon = QtGui.QIcon(ICON_GEAR)
    self.training_expert_btn = QPushButton(icon, "")
    self.training_expert_btn.setFixedSize(35, 35)
    self.training_expert_btn.setToolTip("Open the advanced settings window.")
    self.training_expert_btn.clicked.connect(lambda: self.show_advanced_config.emit())

    # 3D checkbox
    self.enable_3d_chkbox = QCheckBox()
    self.enable_3d_chkbox.setToolTip("Use a 3D network")
    self.enable_3d_chkbox.clicked.connect(self._enable_3d_changed)

    # axes
    self.axes_widget = AxesWidget(careamics_config=self.configuration)

    # number of epochs
    _n_epochs = 30
    if self.configuration.training_config.lightning_trainer_config is not None:
        _n_epochs = self.configuration.training_config.lightning_trainer_config[
            "max_epochs"
        ]
    self.n_epochs_spin = create_int_spinbox(
        1, 1000, _n_epochs, tooltip="Number of epochs"
    )

    # batch size
    self.batch_size_spin = create_int_spinbox(1, 512, 16, 1)
    self.batch_size_spin.setToolTip(
        "Number of patches per batch (decrease if GPU memory is insufficient)"
    )

    # patch size XY
    self.patch_xy_spin = PowerOfTwoSpinBox(16, 512, 64)
    self.patch_xy_spin.setToolTip("Dimension of the patches in XY.")
    # patch size Z
    self.patch_z_spin = PowerOfTwoSpinBox(8, 512, 8)
    self.patch_z_spin.setToolTip("Dimension of the patches in Z.")
    self.patch_z_spin.setEnabled(self.configuration.is_3D)

    # layout
    formLayout = QFormLayout()
    formLayout.setContentsMargins(0, 0, 0, 0)
    formLayout.setFormAlignment(Qt.AlignLeft | Qt.AlignTop)  # type: ignore
    formLayout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)  # type: ignore
    formLayout.addRow("Enable 3D", self.enable_3d_chkbox)
    formLayout.addRow(self.axes_widget.label.text(), self.axes_widget.text_field)
    formLayout.addRow("# Epochs", self.n_epochs_spin)
    formLayout.addRow("Batch size", self.batch_size_spin)
    formLayout.addRow("Patch XY", self.patch_xy_spin)
    formLayout.addRow("Patch Z", self.patch_z_spin)
    formLayout.minimumSize()

    vbox = QVBoxLayout()
    vbox.setContentsMargins(5, 20, 5, 10)
    vbox.addWidget(
        self.training_expert_btn,
        alignment=Qt.AlignRight | Qt.AlignVCenter,  # type: ignore
    )
    vbox.addLayout(formLayout)
    self.setLayout(vbox)

    # create and bind properties to ui
    self._bind_properties()

update_config() #

Update the configuration from the UI element.

Source code in src/careamics_napari/widgets/training_configuration_widget.py
def update_config(self) -> None:
    """Update the configuration from the UI element."""
    # update config axes (from axes widget)
    self.axes_widget.update_config()
    # is 3D
    self.configuration.is_3D = self.is_3D

    # num epochs
    if self.configuration.training_config.lightning_trainer_config is not None:
        self.configuration.training_config.lightning_trainer_config["max_epochs"] = (
            self.num_epochs
        )

    if isinstance(self.configuration.data_config, DataConfig):
        # batch size
        self.configuration.data_config.batch_size = self.batch_size
        # patch size
        _patch_size = [self.patch_xy_size, self.patch_xy_size]
        if self.is_3D:
            _patch_size.insert(0, self.patch_z_size)
        self.configuration.data_config.patch_size = _patch_size
        self.configuration.set_3D(
            self.is_3D, self.configuration.data_config.axes, _patch_size
        )  # maybe not necessary, but let's have it to be sure.