Skip to content

nabu.io.models.crop_volume

[docs] module nabu.io.models.crop_volume

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from __future__ import annotations

from pydantic import BaseModel, ConfigDict, Field, field_validator, field_serializer


class CropModel(BaseModel):
    model_config = ConfigDict(validate_assignment=True, arbitrary_types_allowed=True)

    axis_0_slice: slice | None = Field(default=None, examples=["0:60", None])
    """ROI to apply along the axis 0"""
    axis_1_slice: slice | None = Field(default=None, examples=["0:60", None])
    """ROI to apply along the axis 1"""
    axis_2_slice: slice | None = Field(default=None, examples=["0:60", None])
    """ROI to apply along the axis 2"""

    @field_validator(
        "axis_0_slice",
        "axis_1_slice",
        "axis_2_slice",
        mode="before",
    )
    @classmethod
    def cast_axis_slice(cls, v: slice | str | None) -> slice | None:
        if isinstance(v, str):
            if v.replace(" ", "") == ":":
                return None
            slice_ = slice(*[int(x) if x else None for x in v.split(":")])
            if slice_.step not in (None, 1):
                raise ValueError(f"only slices with step 1 are supported. Got {v}")
            if slice_.start is None:
                slice_ = slice(0, slice_.stop, slice_.step)

            if (slice_.stop is not None) and (slice_.start > slice_.stop):
                raise ValueError(f"slice start should be inferior to slice stop. Got {v}")
            if (slice_.stop is not None) and (slice_.start < 0 or slice_.stop < 0):
                raise ValueError(f"slice start and stop should be positive. Got {v}")
            return slice_
        return v

    @field_serializer(
        "axis_0_slice",
        "axis_1_slice",
        "axis_2_slice",
        when_used="always",
    )
    @classmethod
    def serialize_axis_slice(cls, v: slice | None) -> str:
        if isinstance(v, slice):
            return f"{v.start}:{v.stop}"
        if v is None:
            return ":"
        return v