Skip to content

axes_widget

Widget for specifying axes order.

AxesWidget #

Bases: QWidget

A widget allowing users to specify axes.

Source code in src/careamics_napari/widgets/axes_widget.py
class AxesWidget(QWidget):
    """A widget allowing users to specify axes.

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

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

        Parameters
        ----------
            training_signal : BaseConfig
                A careamics configuration object.
        """
        super().__init__()
        self.configuration = careamics_config
        self.is_text_valid = True

        # layout
        layout = QHBoxLayout()
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)

        # text field
        self.label = QLabel("Axes")
        self.text_field = QLineEdit(self.configuration.data_config.axes)  # type: ignore
        self.text_field.setMaxLength(6)
        self.text_field.setValidator(LettersValidator(REF_AXES))
        self.text_field.textChanged.connect(self._validate_axes)  # type: ignore
        self.text_field.setToolTip(
            "Enter the axes order as they are in your images, e.g. SZYX.\n"
            "Accepted axes are S(ample), T(ime), C(hannel), Z, Y, and X. Red\n"
            "color highlighting means that a character is not recognized,\n"
            "orange means that the axes order is not allowed. YX axes are\n"
            "mandatory."
        )
        # layout
        layout.addWidget(self.label)
        layout.addWidget(self.text_field)
        self.setLayout(layout)
        # validate text
        self._validate_axes(self.text_field.text())

        # create and bind properties to ui
        type(self).axes = bind(
            self.text_field,
            "text",
            default_value=self.configuration.data_config.axes,  # type: ignore
            validation_fn=self._validate_axes,
        )

    def update_config(self: Self) -> None:
        """Update the axes in the configuration if it's valid."""
        if self.is_text_valid and isinstance(self.configuration.data_config, DataConfig):
            self.configuration.data_config.axes = self.axes

    def _validate_axes(self: Self, axes: str | None = None) -> bool:
        """Validate the input text in the text field."""
        if axes is None:
            axes = self.text_field.text()
        # change text color according to axes validation
        if are_axes_valid(axes):
            self._set_text_color(Highlight.VALID)
            self.is_text_valid = True
            # if axes.upper() in filter_dimensions(self.n_axes, self.is_3D):
            #     self._set_text_color(Highlight.VALID)
            # else:
            #     self._set_text_color(Highlight.NOT_ACCEPTED)
        else:
            self._set_text_color(Highlight.UNRECOGNIZED)
            self.is_text_valid = False

        return self.is_text_valid

    def _set_text_color(self: Self, highlight: Highlight) -> None:
        """Set the text color according to the highlight type.

        Parameters
        ----------
        highlight : Highlight
            Highlight type.
        """
        if highlight == Highlight.UNRECOGNIZED:
            self.text_field.setStyleSheet("color: red;")
        elif highlight == Highlight.NOT_ACCEPTED:
            self.text_field.setStyleSheet("color: orange;")
        else:  # VALID
            self.text_field.setStyleSheet("color: white;")

__init__(careamics_config) #

Initialize the widget.

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

    Parameters
    ----------
        training_signal : BaseConfig
            A careamics configuration object.
    """
    super().__init__()
    self.configuration = careamics_config
    self.is_text_valid = True

    # layout
    layout = QHBoxLayout()
    layout.setSpacing(0)
    layout.setContentsMargins(0, 0, 0, 0)

    # text field
    self.label = QLabel("Axes")
    self.text_field = QLineEdit(self.configuration.data_config.axes)  # type: ignore
    self.text_field.setMaxLength(6)
    self.text_field.setValidator(LettersValidator(REF_AXES))
    self.text_field.textChanged.connect(self._validate_axes)  # type: ignore
    self.text_field.setToolTip(
        "Enter the axes order as they are in your images, e.g. SZYX.\n"
        "Accepted axes are S(ample), T(ime), C(hannel), Z, Y, and X. Red\n"
        "color highlighting means that a character is not recognized,\n"
        "orange means that the axes order is not allowed. YX axes are\n"
        "mandatory."
    )
    # layout
    layout.addWidget(self.label)
    layout.addWidget(self.text_field)
    self.setLayout(layout)
    # validate text
    self._validate_axes(self.text_field.text())

    # create and bind properties to ui
    type(self).axes = bind(
        self.text_field,
        "text",
        default_value=self.configuration.data_config.axes,  # type: ignore
        validation_fn=self._validate_axes,
    )

update_config() #

Update the axes in the configuration if it's valid.

Source code in src/careamics_napari/widgets/axes_widget.py
def update_config(self: Self) -> None:
    """Update the axes in the configuration if it's valid."""
    if self.is_text_valid and isinstance(self.configuration.data_config, DataConfig):
        self.configuration.data_config.axes = self.axes

Highlight #

Bases: Enum

Axes highlight types.

Source code in src/careamics_napari/widgets/axes_widget.py
class Highlight(Enum):
    """Axes highlight types."""

    VALID = 0
    """Valid axes."""

    UNRECOGNIZED = 1
    """Unrecognized axes."""

    NOT_ACCEPTED = 2
    """Axes not accepted."""

NOT_ACCEPTED = 2 class-attribute instance-attribute #

Axes not accepted.

UNRECOGNIZED = 1 class-attribute instance-attribute #

Unrecognized axes.

VALID = 0 class-attribute instance-attribute #

Valid axes.

LettersValidator #

Bases: QValidator

Custom validator.

Parameters:

Name Type Description Default
options str

Allowed characters.

required
*args Any

Variable length argument list.

()
**kwargs Any

Arbitrary keyword arguments.

{}
Source code in src/careamics_napari/widgets/axes_widget.py
class LettersValidator(QtGui.QValidator):
    """Custom validator.

    Parameters
    ----------
    options : str
        Allowed characters.
    *args : Any
        Variable length argument list.
    **kwargs : Any
        Arbitrary keyword arguments.
    """

    def __init__(self: Self, options: str, *args: Any, **kwargs: Any) -> None:
        """Initialize the validator.

        Parameters
        ----------
        options : str
            Allowed characters.
        *args : Any
            Variable length argument list.
        **kwargs : Any
            Arbitrary keyword arguments.
        """
        QtGui.QValidator.__init__(self, *args, **kwargs)
        self._options = options

    def validate(
        self: Self, value: str, pos: int
    ) -> tuple[QtGui.QValidator.State, str, int]:
        """Validate the input.

        Parameters
        ----------
        value : str
            Input value.
        pos : int
            Position of the cursor.

        Returns
        -------
        (QtGui.QValidator.State, str, int)
            Validation state, value, and position.
        """
        if len(value) > 0:
            if value[-1] in self._options:
                return QtGui.QValidator.Acceptable, value, pos  # type: ignore
        else:
            if value == "":
                return QtGui.QValidator.Intermediate, value, pos  # type: ignore
        return QtGui.QValidator.Invalid, value, pos  # type: ignore

__init__(options, *args, **kwargs) #

Initialize the validator.

Parameters:

Name Type Description Default
options str

Allowed characters.

required
*args Any

Variable length argument list.

()
**kwargs Any

Arbitrary keyword arguments.

{}
Source code in src/careamics_napari/widgets/axes_widget.py
def __init__(self: Self, options: str, *args: Any, **kwargs: Any) -> None:
    """Initialize the validator.

    Parameters
    ----------
    options : str
        Allowed characters.
    *args : Any
        Variable length argument list.
    **kwargs : Any
        Arbitrary keyword arguments.
    """
    QtGui.QValidator.__init__(self, *args, **kwargs)
    self._options = options

validate(value, pos) #

Validate the input.

Parameters:

Name Type Description Default
value str

Input value.

required
pos int

Position of the cursor.

required

Returns:

Type Description
(State, str, int)

Validation state, value, and position.

Source code in src/careamics_napari/widgets/axes_widget.py
def validate(
    self: Self, value: str, pos: int
) -> tuple[QtGui.QValidator.State, str, int]:
    """Validate the input.

    Parameters
    ----------
    value : str
        Input value.
    pos : int
        Position of the cursor.

    Returns
    -------
    (QtGui.QValidator.State, str, int)
        Validation state, value, and position.
    """
    if len(value) > 0:
        if value[-1] in self._options:
            return QtGui.QValidator.Acceptable, value, pos  # type: ignore
    else:
        if value == "":
            return QtGui.QValidator.Intermediate, value, pos  # type: ignore
    return QtGui.QValidator.Invalid, value, pos  # type: ignore