def forward(self, **kwargs) -> torch.Tensor:
        """Generate anomaly map from input features.

        The method expects ``distance`` and ``scale`` as required inputs, with
        optional ``image_size`` for upsampling.

        Args:
            **kwargs: Keyword arguments containing:
                - distance (torch.Tensor): Distance features
                - scale (tuple[int, int]): Feature map scale
                - image_size (tuple[int, int] | torch.Size, optional):
                    Target size for upsampling

        Raises:
            ValueError: If required arguments are missing.

        Returns:
            torch.Tensor: Anomaly heatmap of shape
                ``(batch_size, 1, height, width)``.
        """
        if not ("distance" in kwargs and "scale" in kwargs):
            msg = f"Expected keys `distance` and `scale`. Found {kwargs.keys()}"
            raise ValueError(msg)

        distance: torch.Tensor = kwargs["distance"]
        scale: tuple[int, int] = kwargs["scale"]
        image_size: tuple[int, int] | torch.Size | None = kwargs.get("image_size", None)

        score = self.compute_score(distance=distance, scale=scale)
        return self.compute_anomaly_map(score, image_size=image_size)
Generate anomaly map from input features.

        The method expects ``distance`` and ``scale`` as required inputs, with
        optional ``image_size`` for upsampling.

        Args:
            **kwargs: Keyword arguments containing:
                - distance (torch.Tensor): Distance features
                - scale (tuple[int, int]): Feature map scale
                - image_size (tuple[int, int] | torch.Size, optional):
                    Target size for upsampling

        Raises:
            ValueError: If required arguments are missing.

        Returns:
            torch.Tensor: Anomaly heatmap of shape
                ``(batch_size, 1, height, width)``.
        
src/anomalib/models/image/cfa/anomaly_map.py