:py:mod:`mipcandy.data.inspection`
==================================

.. py:module:: mipcandy.data.inspection

.. autodoc2-docstring:: mipcandy.data.inspection
   :allowtitles:

Module Contents
---------------

Classes
~~~~~~~

.. list-table::
   :class: autosummary longtable
   :align: left

   * - :py:obj:`InspectionAnnotation <mipcandy.data.inspection.InspectionAnnotation>`
     - .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotation
          :summary:
   * - :py:obj:`InspectionAnnotations <mipcandy.data.inspection.InspectionAnnotations>`
     -
   * - :py:obj:`ROIDataset <mipcandy.data.inspection.ROIDataset>`
     -
   * - :py:obj:`RandomROIDataset <mipcandy.data.inspection.RandomROIDataset>`
     -

Functions
~~~~~~~~~

.. list-table::
   :class: autosummary longtable
   :align: left

   * - :py:obj:`format_bbox <mipcandy.data.inspection.format_bbox>`
     - .. autodoc2-docstring:: mipcandy.data.inspection.format_bbox
          :summary:
   * - :py:obj:`_lists_to_tuples <mipcandy.data.inspection._lists_to_tuples>`
     - .. autodoc2-docstring:: mipcandy.data.inspection._lists_to_tuples
          :summary:
   * - :py:obj:`_str_indices_to_int_indices <mipcandy.data.inspection._str_indices_to_int_indices>`
     - .. autodoc2-docstring:: mipcandy.data.inspection._str_indices_to_int_indices
          :summary:
   * - :py:obj:`parse_inspection_annotation <mipcandy.data.inspection.parse_inspection_annotation>`
     - .. autodoc2-docstring:: mipcandy.data.inspection.parse_inspection_annotation
          :summary:
   * - :py:obj:`load_inspection_annotations <mipcandy.data.inspection.load_inspection_annotations>`
     - .. autodoc2-docstring:: mipcandy.data.inspection.load_inspection_annotations
          :summary:
   * - :py:obj:`bbox_from_indices <mipcandy.data.inspection.bbox_from_indices>`
     - .. autodoc2-docstring:: mipcandy.data.inspection.bbox_from_indices
          :summary:
   * - :py:obj:`inspect <mipcandy.data.inspection.inspect>`
     - .. autodoc2-docstring:: mipcandy.data.inspection.inspect
          :summary:
   * - :py:obj:`crop_and_pad <mipcandy.data.inspection.crop_and_pad>`
     - .. autodoc2-docstring:: mipcandy.data.inspection.crop_and_pad
          :summary:

API
~~~

.. py:function:: format_bbox(bbox: typing.Sequence[int]) -> tuple[int, int, int, int] | tuple[int, int, int, int, int, int]
   :canonical: mipcandy.data.inspection.format_bbox

   .. autodoc2-docstring:: mipcandy.data.inspection.format_bbox

.. py:class:: InspectionAnnotation
   :canonical: mipcandy.data.inspection.InspectionAnnotation

   Bases: :py:obj:`object`

   .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotation

   .. py:attribute:: shape
      :canonical: mipcandy.data.inspection.InspectionAnnotation.shape
      :type: mipcandy.types.AmbiguousShape
      :value: None

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotation.shape

   .. py:attribute:: foreground_bbox
      :canonical: mipcandy.data.inspection.InspectionAnnotation.foreground_bbox
      :type: tuple[int, int, int, int] | tuple[int, int, int, int, int, int]
      :value: None

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotation.foreground_bbox

   .. py:attribute:: class_ids
      :canonical: mipcandy.data.inspection.InspectionAnnotation.class_ids
      :type: tuple[int, ...]
      :value: None

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotation.class_ids

   .. py:attribute:: class_counts
      :canonical: mipcandy.data.inspection.InspectionAnnotation.class_counts
      :type: dict[int, int]
      :value: None

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotation.class_counts

   .. py:attribute:: class_bboxes
      :canonical: mipcandy.data.inspection.InspectionAnnotation.class_bboxes
      :type: dict[int, tuple[int, int, int, int] | tuple[int, int, int, int, int, int]]
      :value: None

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotation.class_bboxes

   .. py:attribute:: class_locations
      :canonical: mipcandy.data.inspection.InspectionAnnotation.class_locations
      :type: dict[int, tuple[tuple[int, int] | tuple[int, int, int], ...]]
      :value: None

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotation.class_locations

   .. py:attribute:: spacing
      :canonical: mipcandy.data.inspection.InspectionAnnotation.spacing
      :type: mipcandy.types.Shape | None
      :value: None

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotation.spacing

   .. py:method:: foreground_shape() -> mipcandy.types.Shape
      :canonical: mipcandy.data.inspection.InspectionAnnotation.foreground_shape

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotation.foreground_shape

   .. py:method:: center_of_foreground() -> tuple[int, int] | tuple[int, int, int]
      :canonical: mipcandy.data.inspection.InspectionAnnotation.center_of_foreground

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotation.center_of_foreground

.. py:class:: InspectionAnnotations(dataset: mipcandy.data.dataset.SupervisedDataset, background: int, intensity_stats: tuple[float, float, float, float], *annotations: mipcandy.data.inspection.InspectionAnnotation)
   :canonical: mipcandy.data.inspection.InspectionAnnotations

   Bases: :py:obj:`typing.Sequence`\ [\ :py:obj:`mipcandy.data.inspection.InspectionAnnotation`\ ]

   .. py:method:: dataset() -> mipcandy.data.dataset.SupervisedDataset
      :canonical: mipcandy.data.inspection.InspectionAnnotations.dataset

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.dataset

   .. py:method:: background() -> int
      :canonical: mipcandy.data.inspection.InspectionAnnotations.background

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.background

   .. py:method:: intensity_stats() -> tuple[float, float, float, float]
      :canonical: mipcandy.data.inspection.InspectionAnnotations.intensity_stats

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.intensity_stats

   .. py:method:: annotations() -> tuple[mipcandy.data.inspection.InspectionAnnotation, ...]
      :canonical: mipcandy.data.inspection.InspectionAnnotations.annotations

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.annotations

   .. py:method:: __getitem__(item: int) -> mipcandy.data.inspection.InspectionAnnotation
      :canonical: mipcandy.data.inspection.InspectionAnnotations.__getitem__

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.__getitem__

   .. py:method:: __len__() -> int
      :canonical: mipcandy.data.inspection.InspectionAnnotations.__len__

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.__len__

   .. py:method:: save(path: str | os.PathLike[str]) -> None
      :canonical: mipcandy.data.inspection.InspectionAnnotations.save

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.save

   .. py:method:: _get_shapes(get_shape: typing.Callable[[mipcandy.data.inspection.InspectionAnnotation], mipcandy.types.AmbiguousShape]) -> tuple[tuple[int, ...] | None, tuple[int, ...], tuple[int, ...]]
      :canonical: mipcandy.data.inspection.InspectionAnnotations._get_shapes

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations._get_shapes

   .. py:method:: shapes() -> tuple[tuple[int, ...] | None, tuple[int, ...], tuple[int, ...]]
      :canonical: mipcandy.data.inspection.InspectionAnnotations.shapes

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.shapes

   .. py:method:: statistical_shape(*, percentile: float = 0.95) -> mipcandy.types.Shape
      :canonical: mipcandy.data.inspection.InspectionAnnotations.statistical_shape

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.statistical_shape

   .. py:method:: foreground_shapes() -> tuple[tuple[int, ...] | None, tuple[int, ...], tuple[int, ...]]
      :canonical: mipcandy.data.inspection.InspectionAnnotations.foreground_shapes

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.foreground_shapes

   .. py:method:: statistical_foreground_shape(*, percentile: float = 0.95) -> mipcandy.types.Shape
      :canonical: mipcandy.data.inspection.InspectionAnnotations.statistical_foreground_shape

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.statistical_foreground_shape

   .. py:method:: crop_foreground(i: int, *, expand_ratio: float = 1) -> tuple[torch.Tensor, torch.Tensor]
      :canonical: mipcandy.data.inspection.InspectionAnnotations.crop_foreground

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.crop_foreground

   .. py:method:: foreground_heatmap() -> torch.Tensor
      :canonical: mipcandy.data.inspection.InspectionAnnotations.foreground_heatmap

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.foreground_heatmap

   .. py:method:: center_of_foregrounds() -> tuple[int, int] | tuple[int, int, int]
      :canonical: mipcandy.data.inspection.InspectionAnnotations.center_of_foregrounds

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.center_of_foregrounds

   .. py:method:: center_of_foregrounds_offsets() -> tuple[int, int] | tuple[int, int, int]
      :canonical: mipcandy.data.inspection.InspectionAnnotations.center_of_foregrounds_offsets

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.center_of_foregrounds_offsets

   .. py:method:: set_roi_shape(roi_shape: mipcandy.types.Shape | None) -> None
      :canonical: mipcandy.data.inspection.InspectionAnnotations.set_roi_shape

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.set_roi_shape

   .. py:method:: roi_shape(*, clamp: bool = True, percentile: float = 0.95) -> mipcandy.types.Shape
      :canonical: mipcandy.data.inspection.InspectionAnnotations.roi_shape

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.roi_shape

   .. py:method:: roi(i: int, *, clamp: bool = True, percentile: float = 0.95) -> tuple[int, int, int, int] | tuple[int, int, int, int, int, int]
      :canonical: mipcandy.data.inspection.InspectionAnnotations.roi

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.roi

   .. py:method:: crop_roi(i: int, *, clamp: bool = True, percentile: float = 0.95) -> tuple[torch.Tensor, torch.Tensor]
      :canonical: mipcandy.data.inspection.InspectionAnnotations.crop_roi

      .. autodoc2-docstring:: mipcandy.data.inspection.InspectionAnnotations.crop_roi

.. py:function:: _lists_to_tuples(pairs: typing.Sequence[tuple[str, typing.Any]]) -> dict[str, typing.Any]
   :canonical: mipcandy.data.inspection._lists_to_tuples

   .. autodoc2-docstring:: mipcandy.data.inspection._lists_to_tuples

.. py:function:: _str_indices_to_int_indices(obj: dict[str, typing.Any]) -> dict[int, typing.Any]
   :canonical: mipcandy.data.inspection._str_indices_to_int_indices

   .. autodoc2-docstring:: mipcandy.data.inspection._str_indices_to_int_indices

.. py:function:: parse_inspection_annotation(obj: dict[str, typing.Any]) -> mipcandy.data.inspection.InspectionAnnotation
   :canonical: mipcandy.data.inspection.parse_inspection_annotation

   .. autodoc2-docstring:: mipcandy.data.inspection.parse_inspection_annotation

.. py:function:: load_inspection_annotations(path: str | os.PathLike[str], dataset: mipcandy.data.dataset.SupervisedDataset) -> mipcandy.data.inspection.InspectionAnnotations
   :canonical: mipcandy.data.inspection.load_inspection_annotations

   .. autodoc2-docstring:: mipcandy.data.inspection.load_inspection_annotations

.. py:function:: bbox_from_indices(indices: torch.Tensor, num_dim: typing.Literal[2, 3]) -> tuple[int, int, int, int]
   :canonical: mipcandy.data.inspection.bbox_from_indices

   .. autodoc2-docstring:: mipcandy.data.inspection.bbox_from_indices

.. py:function:: inspect(dataset: mipcandy.data.dataset.SupervisedDataset, *, background: int = 0, max_samples: int = 10000, console: rich.console.Console = Console()) -> mipcandy.data.inspection.InspectionAnnotations
   :canonical: mipcandy.data.inspection.inspect

   .. autodoc2-docstring:: mipcandy.data.inspection.inspect

.. py:class:: ROIDataset(annotations: mipcandy.data.inspection.InspectionAnnotations, *, clamp: bool = True, percentile: float = 0.95)
   :canonical: mipcandy.data.inspection.ROIDataset

   Bases: :py:obj:`mipcandy.data.dataset.SupervisedDataset`\ [\ :py:obj:`list`\ [\ :py:obj:`int`\ ]\ ]

   .. py:method:: construct_new(images: list[typing.Any], labels: list[typing.Any]) -> typing.Self
      :canonical: mipcandy.data.inspection.ROIDataset.construct_new

      .. autodoc2-docstring:: mipcandy.data.inspection.ROIDataset.construct_new

   .. py:method:: load_image(idx: int) -> torch.Tensor
      :canonical: mipcandy.data.inspection.ROIDataset.load_image
      :abstractmethod:

      .. autodoc2-docstring:: mipcandy.data.inspection.ROIDataset.load_image

   .. py:method:: load_label(idx: int) -> torch.Tensor
      :canonical: mipcandy.data.inspection.ROIDataset.load_label
      :abstractmethod:

      .. autodoc2-docstring:: mipcandy.data.inspection.ROIDataset.load_label

   .. py:method:: load(idx: int) -> tuple[torch.Tensor, torch.Tensor]
      :canonical: mipcandy.data.inspection.ROIDataset.load

.. py:function:: crop_and_pad(x: torch.Tensor, bbox_lbs: list[int], bbox_ubs: list[int], *, pad_value: int | float = 0) -> torch.Tensor
   :canonical: mipcandy.data.inspection.crop_and_pad

   .. autodoc2-docstring:: mipcandy.data.inspection.crop_and_pad

.. py:class:: RandomROIDataset(annotations: mipcandy.data.inspection.InspectionAnnotations, batch_size: int, *, num_patches_per_case: int = 1, oversample_rate: float = 0.33, clamp: bool = False, percentile: float = 0.5, min_factor: int = 16)
   :canonical: mipcandy.data.inspection.RandomROIDataset

   Bases: :py:obj:`mipcandy.data.inspection.ROIDataset`

   .. py:method:: convert_idx(idx: int) -> int
      :canonical: mipcandy.data.inspection.RandomROIDataset.convert_idx

      .. autodoc2-docstring:: mipcandy.data.inspection.RandomROIDataset.convert_idx

   .. py:method:: roi_shape(*, roi_shape: mipcandy.types.Shape | None = None) -> None | mipcandy.types.Shape
      :canonical: mipcandy.data.inspection.RandomROIDataset.roi_shape

      .. autodoc2-docstring:: mipcandy.data.inspection.RandomROIDataset.roi_shape

   .. py:method:: construct_new(images: list[typing.Any], labels: list[typing.Any]) -> typing.Self
      :canonical: mipcandy.data.inspection.RandomROIDataset.construct_new

      .. autodoc2-docstring:: mipcandy.data.inspection.RandomROIDataset.construct_new

   .. py:method:: random_roi(idx: int, force_foreground: bool) -> tuple[list[int], list[int]]
      :canonical: mipcandy.data.inspection.RandomROIDataset.random_roi

      .. autodoc2-docstring:: mipcandy.data.inspection.RandomROIDataset.random_roi

   .. py:method:: oversample_foreground(idx: int) -> bool
      :canonical: mipcandy.data.inspection.RandomROIDataset.oversample_foreground

      .. autodoc2-docstring:: mipcandy.data.inspection.RandomROIDataset.oversample_foreground

   .. py:method:: load(idx: int) -> tuple[torch.Tensor, torch.Tensor]
      :canonical: mipcandy.data.inspection.RandomROIDataset.load
