Ë
    þÍ:jLL  ã                   óÈ   — d dl mZ d dlmZmZmZmZ d dlZd dlmZ d dl	m
Z
 d dlmZmZmZ d dlmZ d dlmZ d d	lmZ d d
lmZmZ esddgZ G d„ de«      Z G d„ de«      Zy)é    )ÚSequence)ÚAnyÚListÚOptionalÚUnionN)ÚTensor)ÚLiteral)Ú_multiscale_ssim_updateÚ_ssim_check_inputsÚ_ssim_update)ÚMetric)Údim_zero_cat)Ú_MATPLOTLIB_AVAILABLE)Ú_AX_TYPEÚ_PLOT_OUT_TYPEz%StructuralSimilarityIndexMeasure.plotz/MultiScaleStructuralSimilarityIndexMeasure.plotc                   ót  ‡ — e Zd ZU dZdZeed<   dZeed<   dZeed<   dZ	e
ed<   d	Ze
ed
<   ee   ed<   ee   ed<   	 	 	 	 	 	 	 	 	 d dedee
ee
   f   deeee   f   ded   deee
ee
e
f   f      de
de
dedededdfˆ fd„Zdededdfd„Zdeeeeef   f   fd„Z	 d!deeeee   f      dee   defd„Zˆ xZS )"Ú StructuralSimilarityIndexMeasurea4	  Compute Structural Similarity Index Measure (SSIM_).

    As input to ``forward`` and ``update`` the metric accepts the following input

    - ``preds`` (:class:`~torch.Tensor`): Predictions from model
    - ``target`` (:class:`~torch.Tensor`): Ground truth values

    As output of `forward` and `compute` the metric returns the following output

    - ``ssim`` (:class:`~torch.Tensor`): if ``reduction!='none'`` returns float scalar tensor with average SSIM value
      over sample else returns tensor of shape ``(N,)`` with SSIM values per sample

    Args:
        preds: estimated image
        target: ground truth image
        gaussian_kernel: If ``True`` (default), a gaussian kernel is used, if ``False`` a uniform kernel is used
        sigma: Standard deviation of the gaussian kernel, anisotropic kernels are possible.
            Ignored if a uniform kernel is used
        kernel_size: the size of the uniform kernel, anisotropic kernels are possible.
            Ignored if a Gaussian kernel is used
        reduction: a method to reduce metric score over individual batch scores

            - ``'elementwise_mean'``: takes the mean
            - ``'sum'``: takes the sum
            - ``'none'`` or ``None``: no reduction will be applied

        data_range:
            the range of the data. If None, it is determined from the data (max - min). If a tuple is provided then
            the range is calculated as the difference and input is clamped between the values.
        k1: Parameter of SSIM.
        k2: Parameter of SSIM.
        return_full_image: If true, the full ``ssim`` image is returned as a second argument.
            Mutually exclusive with ``return_contrast_sensitivity``
        return_contrast_sensitivity: If true, the constant term is returned as a second argument.
            The luminance term can be obtained with luminance=ssim/contrast
            Mutually exclusive with ``return_full_image``
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Example:
        >>> import torch
        >>> from torchmetrics.image import StructuralSimilarityIndexMeasure
        >>> preds = torch.rand([3, 3, 256, 256])
        >>> target = preds * 0.75
        >>> ssim = StructuralSimilarityIndexMeasure(data_range=1.0)
        >>> ssim(preds, target)
        tensor(0.9219)

    TÚhigher_is_betterÚis_differentiableFÚfull_state_updateç        Úplot_lower_boundç      ð?Úplot_upper_boundÚpredsÚtargetNÚgaussian_kernelÚsigmaÚkernel_sizeÚ	reduction©Úelementwise_meanÚsumÚnoneNÚ
data_rangeÚk1Úk2Úreturn_full_imageÚreturn_contrast_sensitivityÚkwargsÚreturnc
                 óÎ  •— t        ‰| �  di |
¤Ž d}||vrt        d|› d|› �«      ‚|dv r(| j                  dt	        j
                  d«      d¬«       n| j                  dg d ¬«       | j                  d	t	        j
                  d«      d¬«       |	s|r| j                  d
g d¬«       || _        || _        || _        || _	        || _
        || _        || _        || _        |	| _        y )Nr!   ú$Argument `reduction` must be one of ú
, but got ©r"   r#   Ú
similarityr   r#   ©ÚdefaultÚdist_reduce_fxÚtotalÚimage_returnÚcat© )ÚsuperÚ__init__Ú
ValueErrorÚ	add_stateÚtorchÚtensorr   r   r   r    r%   r&   r'   r(   r)   )Úselfr   r   r   r    r%   r&   r'   r(   r)   r*   Úvalid_reductionÚ	__class__s               €úl/home/mcse/projects/srt_converter/srt-converter-venv/lib/python3.12/site-packages/torchmetrics/image/ssim.pyr9   z)StructuralSimilarityIndexMeasure.__init__Z   sì   ø€ ô 	‰ÑÑ"˜6Ò"àCˆØ˜OÑ+ÜÐCÀOÐCTÐT^Ð_hÐ^iÐjÓkÐkàÐ3Ñ3Ø�N‰N˜<´·±¸cÓ1BÐSXˆNÕYà�N‰N˜<°ÀDˆNÔIà�‰�w¬¯©°SÓ(9È%ˆÔPá&Ñ*;Ø�N‰N˜>°2ÀeˆNÔLà.ˆÔØˆŒ
Ø&ˆÔØ"ˆŒØ$ˆŒØˆŒØˆŒØ!2ˆÔØ+FˆÕ(ó    c                 ó®  — t        ||«      \  }}t        ||| j                  | j                  | j                  | j
                  | j                  | j                  | j                  | j                  «
      }t        |t        «      r|\  }}n|}| j                  s| j                  r@t        | j                  t        «      st        d«      ‚| j                  j                  «       | j                   dv r¤t        | j"                  t$        j&                  «      st        d«      ‚| xj"                  |j)                  «       z  c_        t        | j*                  t$        j&                  «      st        d«      ‚| xj*                  |j,                  d   z  c_        yt        | j"                  t        «      st        d«      ‚| j"                  j                  |«       y)ú*Update state with predictions and targets.ú@Expected `self.image_return` to be a list when returning images.r/   z9Expected `self.similarity` to be a Tensor for reductions.ú%Expected `self.total` to be a Tensor.r   z>Expected `self.similarity` to be a list when reduction='none'.N)r   r   r   r   r   r%   r&   r'   r(   r)   Ú
isinstanceÚtupler5   ÚlistÚ	TypeErrorÚappendr    r0   r<   r   r#   r4   Úshape)r>   r   r   Úsimilarity_packr0   Úimages         rA   Úupdatez'StructuralSimilarityIndexMeasure.update�   s^  € ä*¨5°&Ó9‰ˆˆvÜ&ØØØ× Ñ Ø�J‰JØ×ÑØ�O‰OØ�G‰GØ�G‰GØ×"Ñ"Ø×,Ñ,ó
ˆô �o¤uÔ-Ø /ÑˆJ™à(ˆJà×+Ò+¨t×/EÒ/EÜ˜d×/Ñ/´Ô6ÜÐ bÓcÐcØ×Ñ×$Ñ$ UÔ+à�>‰>Ð8Ñ8Ü˜dŸo™o¬u¯|©|Ô<ÜÐ [Ó\Ð\Ø�OŠO˜zŸ~™~Ó/Ñ/�OÜ˜dŸj™j¬%¯,©,Ô7ÜÐ GÓHÐHØ�JŠJ˜%Ÿ+™+ a™.Ñ(ŽJä˜dŸo™o¬tÔ4ÜÐ `ÓaÐaØ�O‰O×"Ñ" :Õ.rB   c                 óz  — | j                   dk(  rYt        | j                  t        «      r4t        | j                  t        «      r| j                  | j                  z  }n‡t        d«      ‚| j                   dk(  r2t        | j                  t        «      st        d«      ‚| j                  }n;t        | j                  t        «      rt        | j                  «      }nt        d«      ‚| j                  s| j                  r>t        | j                  t        «      rt        | j                  «      }||fS t        d«      ‚|S )zCompute SSIM over state.r"   z_Expected `self.similarity`and `self.total` to be of type Tensor for elementwise_mean reduction.r#   ú<Expected `self.similarity` to be a Tensor for sum reduction.ú=Expected `self.similarity` to be a list for reduction='none'.rE   )r    rG   r0   r   r4   rJ   rI   r   r)   r(   r5   )r>   r0   r5   s      rA   Úcomputez(StructuralSimilarityIndexMeasure.compute§   sù   € à�>‰>Ð/Ò/Ü˜$Ÿ/™/¬6Ô2´zÀ$Ç*Á*ÌfÔ7UØ!Ÿ_™_¨t¯z©zÑ9‘
äØuóð ð �^‰^˜uÒ$Ü˜dŸo™o¬vÔ6ÜÐ ^Ó_Ð_ØŸ™‰Jä˜$Ÿ/™/¬4Ô0Ü)¨$¯/©/Ó:‘
äÐ _Ó`Ð`à×+Ò+¨t×/EÒ/EÜ˜$×+Ñ+¬TÔ2Ü+¨D×,=Ñ,=Ó>�ð ˜|Ð+Ð+ô  Ð bÓcÐcð ÐrB   ÚvalÚaxc                 ó&   — | j                  ||«      S )aò  Plot a single or multiple values from the metric.

        Args:
            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.
                If no value is provided, will automatically call `metric.compute` and plot that result.
            ax: An matplotlib axis object. If provided will add plot to that axis

        Returns:
            Figure and Axes object

        Raises:
            ModuleNotFoundError:
                If `matplotlib` is not installed

        .. plot::
            :scale: 75

            >>> # Example plotting a single value
            >>> import torch
            >>> from torchmetrics.image import StructuralSimilarityIndexMeasure
            >>> preds = torch.rand([3, 3, 256, 256])
            >>> target = preds * 0.75
            >>> metric = StructuralSimilarityIndexMeasure(data_range=1.0)
            >>> metric.update(preds, target)
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> import torch
            >>> from torchmetrics.image import StructuralSimilarityIndexMeasure
            >>> preds = torch.rand([3, 3, 256, 256])
            >>> target = preds * 0.75
            >>> metric = StructuralSimilarityIndexMeasure(data_range=1.0)
            >>> values = [ ]
            >>> for _ in range(10):
            ...     values.append(metric(preds, target))
            >>> fig_, ax_ = metric.plot(values)

        ©Ú_plot©r>   rT   rU   s      rA   Úplotz%StructuralSimilarityIndexMeasure.plotÃ   ó   € ðX �z‰z˜#˜rÓ"Ð"rB   )	Tç      ø?é   r"   Nç{®Gáz„?ç¸…ëQ¸ž?FF©NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚboolÚ__annotations__r   r   r   Úfloatr   r   r   r   r   Úintr	   r   rH   r   r9   rO   rS   r   r   rZ   Ú__classcell__©r@   s   @rA   r   r      s£  ø… ñ/ðb "Ð�dÓ!Ø"Ð�tÓ"Ø#Ð�tÓ#Ø!Ð�eÓ!Ø!Ð�eÓ!à�‰<ÓØ�‰LÓð !%Ø/2Ø13ØFXØBFØØØ"'Ø,1ñ%Gàð%Gð �U˜H U™OÐ+Ñ,ð%Gð ˜3 ¨¡Ð-Ñ.ð	%Gð
 ÐBÑCð%Gð ˜U 5¨%°°u°Ñ*=Ð#=Ñ>Ñ?ð%Gð ð%Gð ð%Gð  ð%Gð &*ð%Gð ð%Gð 
õ%GðN$/˜Fð $/¨Fð $/°tó $/ðL˜˜v u¨V°V¨^Ñ'<Ð<Ñ=ó ð: _cñ,#Ø˜E &¨(°6Ñ*:Ð":Ñ;Ñ<ð,#ØIQÐRZÑI[ð,#à	÷,#rB   r   c                   óp  ‡ — e Zd ZU dZdZeed<   dZeed<   dZeed<   dZ	e
ed<   d	Ze
ed
<   ee   ed<   ee   ed<   	 	 	 	 	 	 	 	 	 d"dedeeee   f   dee
ee
   f   ded   deee
ee
e
f   f      de
de
dee
df   ded   deddfˆ fd„Zdededdfd„Zdefd„Z	 d#deeeee   f      d ee   defd!„Zˆ xZS )$Ú*MultiScaleStructuralSimilarityIndexMeasureaF  Compute `MultiScaleSSIM`_, Multi-scale Structural Similarity Index Measure.

    This metric is is a generalization of Structural Similarity Index Measure by incorporating image details at
    different resolution scores.

    As input to ``forward`` and ``update`` the metric accepts the following input

    - ``preds`` (:class:`~torch.Tensor`): Predictions from model
    - ``target`` (:class:`~torch.Tensor`): Ground truth values

    As output of `forward` and `compute` the metric returns the following output

    - ``msssim`` (:class:`~torch.Tensor`): if ``reduction!='none'`` returns float scalar tensor with average MSSSIM
      value over sample else returns tensor of shape ``(N,)`` with SSIM values per sample

    Args:
        gaussian_kernel: If ``True`` (default), a gaussian kernel is used, if false a uniform kernel is used
        kernel_size: size of the gaussian kernel
        sigma: Standard deviation of the gaussian kernel
        reduction: a method to reduce metric score over labels.

            - ``'elementwise_mean'``: takes the mean
            - ``'sum'``: takes the sum
            - ``'none'`` or ``None``: no reduction will be applied

        data_range:
            the range of the data. If None, it is determined from the data (max - min). If a tuple is provided then
            the range is calculated as the difference and input is clamped between the values.
            The ``data_range`` must be given when ``dim`` is not None.
        k1: Parameter of structural similarity index measure.
        k2: Parameter of structural similarity index measure.
        betas: Exponent parameters for individual similarities and contrastive sensitivities returned by different image
            resolutions.
        normalize: When MultiScaleStructuralSimilarityIndexMeasure loss is used for training, it is desirable to use
            normalizes to improve the training stability. This `normalize` argument is out of scope of the original
            implementation [1], and it is adapted from https://github.com/jorge-pessoa/pytorch-msssim instead.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Return:
        Tensor with Multi-Scale SSIM score

    Raises:
        ValueError:
            If ``kernel_size`` is not an int or a Sequence of ints with size 2 or 3.
        ValueError:
            If ``betas`` is not a tuple of floats with length 2.
        ValueError:
            If ``normalize`` is neither `None`, `ReLU` nor `simple`.

    Example:
        >>> from torch import rand
        >>> from torchmetrics.image import MultiScaleStructuralSimilarityIndexMeasure
        >>> preds = torch.rand([3, 3, 256, 256])
        >>> target = preds * 0.75
        >>> ms_ssim = MultiScaleStructuralSimilarityIndexMeasure(data_range=1.0)
        >>> ms_ssim(preds, target)
        tensor(0.9628)

    Tr   r   Fr   r   r   r   r   r   r   Nr   r   r   r    r!   r%   r&   r'   Úbetas.Ú	normalize)ÚreluÚsimpleNr*   r+   c
                 ó  •— t        ‰| �  di |
¤Ž d}||vrt        d|› d|› �«      ‚|dv r(| j                  dt	        j
                  d«      d¬«       n| j                  dg d ¬«       | j                  d	t	        j
                  d«      d¬«       t        |t        t        f«      st        d
|› �«      ‚t        |t        «      r-t        |«      dvst        d„ |D «       «      st        d|› �«      ‚|| _        || _        || _        || _        || _        || _        || _        t        |t$        «      st        d«      ‚t        |t$        «      rt        d„ |D «       «      st        d«      ‚|| _        |	r|	dvrt        d«      ‚|	| _        y )Nr!   r-   r.   r/   r0   r   r#   r1   r4   zRArgument `kernel_size` expected to be an sequence or an int, or a single int. Got )é   é   c              3   ó<   K  — | ]  }t        |t        «      –— Œ y ­w©N)rG   rh   )Ú.0Úkss     rA   ú	<genexpr>zFMultiScaleStructuralSimilarityIndexMeasure.__init__.<locals>.<genexpr>W  s   è ø€ Ò5`Èb´jÀÄS×6IÑ5`ùó   ‚ztArgument `kernel_size` expected to be an sequence of size 2 or 3 where each element is an int, or a single int. Got z3Argument `betas` is expected to be of a type tuple.c              3   ó<   K  — | ]  }t        |t        «      –— Œ y ­wru   )rG   rg   )rv   Úbetas     rA   rx   zFMultiScaleStructuralSimilarityIndexMeasure.__init__.<locals>.<genexpr>g  s   è ø€ Ò/ZÈD´
¸4Ä×0GÑ/Zùry   z5Argument `betas` is expected to be a tuple of floats.)ro   rp   zNArgument `normalize` to be expected either `None` or one of 'relu' or 'simple'r7   )r8   r9   r:   r;   r<   r=   rG   r   rh   ÚlenÚallr   r   r   r    r%   r&   r'   rH   rm   rn   )r>   r   r   r   r    r%   r&   r'   rm   rn   r*   r?   r@   s               €rA   r9   z3MultiScaleStructuralSimilarityIndexMeasure.__init__8  s�  ø€ ô 	‰ÑÑ"˜6Ò"àCˆØ˜OÑ+ÜÐCÀOÐCTÐT^Ð_hÐ^iÐjÓkÐkàÐ3Ñ3Ø�N‰N˜<´·±¸cÓ1BÐSXˆNÕYà�N‰N˜<°ÀDˆNÔIà�‰�w¬¯©°SÓ(9È%ˆÔPä˜;¬´3¨Ô8ÜØdÐepÐdqÐróð ô �k¤8Ô,Ü�Ó FÑ*´#Ñ5`ÐT_Ô5`Ô2`äð(Ø(3 }ð6óð ð
  /ˆÔØˆŒ
Ø&ˆÔØ"ˆŒØ$ˆŒØˆŒØˆŒÜ˜%¤Ô'ÜÐRÓSÐSÜ�eœUÔ#¬CÑ/ZÐTYÔ/ZÔ,ZÜÐTÓUÐUØˆŒ
Ù˜Ð*<Ñ<ÜÐmÓnÐnØ"ˆ�rB   c                 ó"  — t        ||«      \  }}t        ||| j                  | j                  | j                  | j
                  | j                  | j                  | j                  | j                  «
      }| j                  dv rAt        | j                  t        «      st        d«      ‚| j                  j                  |«       nHt        | j                  t         «      st        d«      ‚| xj                  |j#                  «       z  c_        t        | j$                  t         «      st        d«      ‚| xj$                  t'        j(                  |j*                  d   | j$                  j,                  | j$                  j.                  ¬«      z  c_        y)rD   ©r$   NrR   zPExpected `self.similarity` to be a Tensor for elementwise_mean or sum reduction.rF   r   )ÚdtypeÚdeviceN)r   r
   r   r   r   r%   r&   r'   rm   rn   r    rG   r0   rI   rJ   rK   r   r#   r4   r<   r=   rL   r€   r�   )r>   r   r   r0   s       rA   rO   z1MultiScaleStructuralSimilarityIndexMeasure.updaten  s  € ä*¨5°&Ó9‰ˆˆvÜ,ØØØ× Ñ Ø�J‰JØ×ÑØ�O‰OØ�G‰GØ�G‰GØ�J‰JØ�N‰Nó
ˆ
ð �>‰>˜^Ñ+Ü˜dŸo™o¬tÔ4ÜÐ _Ó`Ð`Ø�O‰O×"Ñ" :Õ.ä˜dŸo™o¬vÔ6ÜÐ rÓsÐsØ�OŠO˜zŸ~™~Ó/Ñ/�Oä˜$Ÿ*™*¤fÔ-ÜÐCÓDÐDØ�
Š
”e—l‘l 5§;¡;¨q¡>¸¿¹×9IÑ9IÐRV×R\ÑR\×RcÑRcÔdÑdŽ
rB   c                 óÂ  — | j                   dv r:t        | j                  t        «      rt	        | j                  «      S t        d«      ‚| j                   dk(  r1t        | j                  t        «      r| j                  S t        d«      ‚t        | j                  t        «      r3t        | j                  t        «      r| j                  | j                  z  S t        d«      ‚)zCompute MS-SSIM over state.r   rR   r#   rQ   zYExpected `self.similarity` and `self.total` to be Tensors for elementwise_mean reduction.)r    rG   r0   rI   r   rJ   r   r4   )r>   s    rA   rS   z2MultiScaleStructuralSimilarityIndexMeasure.compute‹  s¡   € à�>‰>˜^Ñ+Ü˜$Ÿ/™/¬4Ô0Ü# D§O¡OÓ4Ð4ÜÐ[Ó\Ð\Ø�>‰>˜UÒ"Ü˜$Ÿ/™/¬6Ô2Ø—‘Ð&ÜÐZÓ[Ð[Ü�d—o‘o¤vÔ.´:¸d¿j¹jÌ&Ô3QØ—?‘? T§Z¡ZÑ/Ð/ÜÐsÓtÐtrB   rT   rU   c                 ó&   — | j                  ||«      S )a"  Plot a single or multiple values from the metric.

        Args:
            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.
                If no value is provided, will automatically call `metric.compute` and plot that result.
            ax: An matplotlib axis object. If provided will add plot to that axis

        Returns:
            Figure and Axes object

        Raises:
            ModuleNotFoundError:
                If `matplotlib` is not installed

        .. plot::
            :scale: 75

            >>> # Example plotting a single value
            >>> from torch import rand
            >>> from torchmetrics.image import MultiScaleStructuralSimilarityIndexMeasure
            >>> preds = rand([3, 3, 256, 256])
            >>> target = preds * 0.75
            >>> metric = MultiScaleStructuralSimilarityIndexMeasure(data_range=1.0)
            >>> metric.update(preds, target)
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> from torch import rand
            >>> from torchmetrics.image import MultiScaleStructuralSimilarityIndexMeasure
            >>> preds = rand([3, 3, 256, 256])
            >>> target = preds * 0.75
            >>> metric = MultiScaleStructuralSimilarityIndexMeasure(data_range=1.0)
            >>> values = [ ]
            >>> for _ in range(10):
            ...     values.append(metric(preds, target))
            >>> fig_, ax_ = metric.plot(values)

        rW   rY   s      rA   rZ   z/MultiScaleStructuralSimilarityIndexMeasure.plot™  r[   rB   )	Tr]   r\   r"   Nr^   r_   )gÇº¸�ð¦?g×4ï8EGÒ?g÷äa¡Ö4Ó?g¼?Î?g9EGrùÁ?ro   r`   )ra   rb   rc   rd   r   re   rf   r   r   r   rg   r   r   r   r   rh   r   r	   r   rH   r   r9   rO   rS   r   r   rZ   ri   rj   s   @rA   rl   rl   ò   s˜  ø… ñ:ðx "Ð�dÓ!Ø"Ð�tÓ"Ø#Ð�tÓ#Ø!Ð�eÓ!Ø!Ð�eÓ!à�‰<ÓØ�‰LÓð !%Ø13Ø/2ØFXØBFØØØ#KØ5;ñ4#àð4#ð ˜3 ¨¡Ð-Ñ.ð4#ð �U˜H U™OÐ+Ñ,ð	4#ð
 ÐBÑCð4#ð ˜U 5¨%°°u°Ñ*=Ð#=Ñ>Ñ?ð4#ð ð4#ð ð4#ð �U˜C�ZÑ ð4#ð Ð1Ñ2ð4#ð ð4#ð 
õ4#ðle˜Fð e¨Fð e°tó eð:u˜ó uð _cñ,#Ø˜E &¨(°6Ñ*:Ð":Ñ;Ñ<ð,#ØIQÐRZÑI[ð,#à	÷,#rB   rl   )Úcollections.abcr   Útypingr   r   r   r   r<   r   Útyping_extensionsr	   Ú"torchmetrics.functional.image.ssimr
   r   r   Útorchmetrics.metricr   Útorchmetrics.utilities.datar   Útorchmetrics.utilities.importsr   Útorchmetrics.utilities.plotr   r   Ú__doctest_skip__r   rl   r7   rB   rA   ú<module>r�      sW   ðõ %ß -Ó -ã Ý Ý %ç hÑ hÝ &Ý 4Ý @ß @áØ?ÐArÐsÐôP# vô P#ôfS#°õ S#rB   