




"""simple docstring"""

import random
import unittest

import torch

from diffusers import IFImgaImgPipeline
from diffusers.utils import floats_tensor
from diffusers.utils.import_utils import is_xformers_available
from diffusers.utils.testing_utils import skip_mps, torch_device

from ..pipeline_params import (
    TEXT_GUIDED_IMAGE_VARIATION_BATCH_PARAMS,
    TEXT_GUIDED_IMAGE_VARIATION_PARAMS,
)
from ..test_pipelines_common import PipelineTesterMixin
from . import IFPipelineTesterMixin



@skip_mps
class  _snake_case				(							snake_case__							,						snake_case__							,						unittest.TestCase       ):

    '''simple docstring'''




    UpperCamelCase__		     =IFImgaImgPipeline
    UpperCamelCase__		     =TEXT_GUIDED_IMAGE_VARIATION_PARAMS - {"""width""", """height"""}
    UpperCamelCase__		     =TEXT_GUIDED_IMAGE_VARIATION_BATCH_PARAMS
    UpperCamelCase__		     =PipelineTesterMixin.required_optional_params - {"""latents"""}





    def 				snake_case_ (							self      :  Optional[int]     ):
        return self._get_dummy_components()





    def 				snake_case_ (							self      :  List[Any]					,							snake_case      :  Tuple					,							snake_case      :  Any=0     ):
        if str(__snake_case     ).startswith('''mps'''     ):
            UpperCAmelCase_					:int      			=      torch.manual_seed(__snake_case     )
        else:
            UpperCAmelCase_					:List[Any]      			=      torch.Generator(device=__snake_case     ).manual_seed(__snake_case     )

        UpperCAmelCase_					:int      			=      floats_tensor((1, 3, 32, 32)					,							rng=random.Random(__snake_case     )     ).to(__snake_case     )

        UpperCAmelCase_					:List[Any]      			=      {
            '''prompt''': '''A painting of a squirrel eating a burger''',
            '''image''': image,
            '''generator''': generator,
            '''num_inference_steps''': 2,
            '''output_type''': '''numpy''',
        }

        return inputs





    def 				snake_case_ (							self      :  Any     ):
        self._test_save_load_optional_components()





    @unittest.skipIf(
        torch_device != '''cuda''' or not is_xformers_available()					,							reason='''XFormers attention is only available with CUDA and `xformers` installed'''					,							)
    def 				snake_case_ (							self      :  Dict     ):
        self._test_xformers_attention_forwardGenerator_pass(expected_max_diff=1e-3     )





    @unittest.skipIf(torch_device != '''cuda'''					,							reason='''float16 requires CUDA'''     )
    def 				snake_case_ (							self      :  Dict     ):
        # Due to non-determinism in save load of the hf-internal-testing/tiny-random-t5 text encoder
        super().test_save_load_floataa(expected_max_diff=1e-1     )





    @unittest.skipIf(torch_device != '''cuda'''					,							reason='''float16 requires CUDA'''     )
    def 				snake_case_ (							self      :  Tuple     ):
        super().test_floataa_inference(expected_max_diff=1e-1     )





    def 				snake_case_ (							self      :  Optional[Any]     ):
        self._test_attention_slicing_forward_pass(expected_max_diff=1e-2     )





    def 				snake_case_ (							self      :  List[Any]     ):
        self._test_save_load_local()





    def 				snake_case_ (							self      :  Optional[int]     ):
        self._test_inference_batch_single_identical(
            expected_max_diff=1e-2					,							)








"""simple docstring"""

from typing import Dict, Tuple, overload

import torch
import torch.types
from torch import nn

from . import residue_constants as rc
from .rigid_utils import Rigid, Rotation
from .tensor_utils import batched_gather



@overload
def 				a (						__snake_case     :				torch.Tensor,    __snake_case     :				torch.Tensor,    __snake_case     :				None  ):



				'''simple docstring'''





				...



@overload
def 				a (						__snake_case     :				torch.Tensor,    __snake_case     :				torch.Tensor,    __snake_case     :				torch.Tensor  ):



				'''simple docstring'''





				...



def 				a (						__snake_case     :				List[str],    __snake_case     :				Optional[int],    __snake_case     :				str  ):



				'''simple docstring'''





				UpperCAmelCase_					:int      			=      aatype == rc.restype_order['''G''']
				UpperCAmelCase_					:Optional[Any]      			=      rc.atom_order['''CA''']
				UpperCAmelCase_					:Optional[Any]      			=      rc.atom_order['''CB''']
				UpperCAmelCase_					:Optional[Any]      			=      torch.where(
				    is_gly[..., None].expand(*((-1,) * len(is_gly.shape  )),    3  ),    all_atom_positions[..., ca_idx, :],    all_atom_positions[..., cb_idx, :],    )

				if all_atom_masks is not None:
								UpperCAmelCase_					:Any      			=      torch.where(
								    __snake_case,    all_atom_masks[..., ca_idx],    all_atom_masks[..., cb_idx],    )
								return pseudo_beta, pseudo_beta_mask
				else:
								return pseudo_beta



def 				a (						__snake_case     :				torch.Tensor,    __snake_case     :				Dict[str, torch.Tensor]  ):



				'''simple docstring'''





				UpperCAmelCase_					:List[Any]      			=      batched_gather(
				    __snake_case,    batch['''residx_atom37_to_atom14'''],    dim=-2,    no_batch_dims=len(atomaa.shape[:-2]  ),    )

				UpperCAmelCase_					:Optional[Any]      			=      atomaa_data * batch['''atom37_atom_exists'''][..., None]

				return atomaa_data



def 				a (						__snake_case     :				Dict[str, torch.Tensor]  ):



				'''simple docstring'''





				UpperCAmelCase_					:str      			=      template_feats['''template_aatype''']
				UpperCAmelCase_					:Union[str, Any]      			=      template_feats['''template_torsion_angles_sin_cos''']
				UpperCAmelCase_					:Tuple      			=      template_feats['''template_alt_torsion_angles_sin_cos''']
				UpperCAmelCase_					:Tuple      			=      template_feats['''template_torsion_angles_mask''']
				UpperCAmelCase_					:int      			=      torch.cat(
				    [
				        nn.functional.one_hot(__snake_case,    22  ),
				        torsion_angles_sin_cos.reshape(*torsion_angles_sin_cos.shape[:-2],    14  ),
				        alt_torsion_angles_sin_cos.reshape(*alt_torsion_angles_sin_cos.shape[:-2],    14  ),
				        torsion_angles_mask,
				    ],    dim=-1,    )

				return template_angle_feat



def 				a (						__snake_case     :				Dict[str, torch.Tensor],    __snake_case     :				torch.types.Number,    __snake_case     :				torch.types.Number,    __snake_case     :				int,    __snake_case     :				bool = False,    __snake_case     :				float = 1E-20,    __snake_case     :				float = 1E8,    ):



				'''simple docstring'''





				UpperCAmelCase_					:List[str]      			=      batch['''template_pseudo_beta_mask''']
				UpperCAmelCase_					:Any      			=      template_mask[..., None] * template_mask[..., None, :]

				# Compute distogram (this seems to differ slightly from Alg. 5)
				UpperCAmelCase_					:List[str]      			=      batch['''template_pseudo_beta''']
				UpperCAmelCase_					:Any      			=      torch.sum((tpb[..., None, :] - tpb[..., None, :, :]) ** 2,    dim=-1,    keepdim=__snake_case  )
				UpperCAmelCase_					:Any      			=      torch.linspace(__snake_case,    __snake_case,    __snake_case,    device=tpb.device  ) ** 2
				UpperCAmelCase_					:Union[str, Any]      			=      torch.cat([lower[1:], lower.new_tensor([inf]  )],    dim=-1  )
				UpperCAmelCase_					:Tuple      			=      ((dgram > lower) * (dgram < upper)).type(dgram.dtype  )

				UpperCAmelCase_					:List[str]      			=      [dgram, template_mask_ad[..., None]]

				UpperCAmelCase_					:torch.LongTensor      			=      nn.functional.one_hot(
				    batch['''template_aatype'''],    rc.restype_num + 2,    )

				UpperCAmelCase_					:Optional[Any]      			=      batch['''template_aatype'''].shape[-1]
				to_concat.append(aatype_one_hot[..., None, :, :].expand(*aatype_one_hot.shape[:-2],    __snake_case,    -1,    -1  )  )
				to_concat.append(aatype_one_hot[..., None, :].expand(*aatype_one_hot.shape[:-2],    -1,    __snake_case,    -1  )  )

				UpperCAmelCase_			,UpperCAmelCase_			,UpperCAmelCase_					:Optional[int]      			=      [rc.atom_order[a] for a in ['''N''', '''CA''', '''C''']]
				UpperCAmelCase_					:str      			=      Rigid.make_transform_from_reference(
				    n_xyz=batch['''template_all_atom_positions'''][..., n, :],    ca_xyz=batch['''template_all_atom_positions'''][..., ca, :],    c_xyz=batch['''template_all_atom_positions'''][..., c, :],    eps=__snake_case,    )
				UpperCAmelCase_					:Dict      			=      rigids.get_trans()[..., None, :, :]
				UpperCAmelCase_					:Dict      			=      rigids[..., None].invert_apply(__snake_case  )

				UpperCAmelCase_					:Optional[int]      			=      torch.rsqrt(eps + torch.sum(rigid_vec**2,    dim=-1  )  )

				UpperCAmelCase_					:Optional[int]      			=      batch['''template_all_atom_mask''']
				UpperCAmelCase_					:Tuple      			=      t_aa_masks[..., n] * t_aa_masks[..., ca] * t_aa_masks[..., c]
				UpperCAmelCase_					:int      			=      template_mask[..., None] * template_mask[..., None, :]

				UpperCAmelCase_					:str      			=      inv_distance_scalar * template_mask_ad
				UpperCAmelCase_					:List[Any]      			=      rigid_vec * inv_distance_scalar[..., None]

				if not use_unit_vector:
								UpperCAmelCase_					:List[Any]      			=      unit_vector * 0.0

				to_concat.extend(torch.unbind(unit_vector[..., None, :],    dim=-1  )  )
				to_concat.append(template_mask_ad[..., None]  )

				UpperCAmelCase_					:Optional[int]      			=      torch.cat(__snake_case,    dim=-1  )
				UpperCAmelCase_					:Optional[Any]      			=      act * template_mask_ad[..., None]

				return act



def 				a (						__snake_case     :				Dict[str, torch.Tensor]  ):



				'''simple docstring'''





				UpperCAmelCase_					:torch.LongTensor      			=      nn.functional.one_hot(batch['''extra_msa'''],    23  )
				UpperCAmelCase_					:Union[str, Any]      			=      [
				    msa_ahot,
				    batch['''extra_has_deletion'''].unsqueeze(-1  ),
				    batch['''extra_deletion_value'''].unsqueeze(-1  ),
				]
				return torch.cat(__snake_case,    dim=-1  )



def 				a (						__snake_case     :				Rigid,    __snake_case     :				torch.Tensor,    __snake_case     :				torch.Tensor,    __snake_case     :				torch.Tensor,    ):



				'''simple docstring'''





				UpperCAmelCase_					:Optional[int]      			=      rrgdf[aatype, ...]

				# [*, N, 8] transformations, i.e.
				#   One [*, N, 8, 3, 3] rotation matrix and
				#   One [*, N, 8, 3]    translation matrix
				UpperCAmelCase_					:Optional[int]      			=      r.from_tensor_axa(__snake_case  )

				UpperCAmelCase_					:List[Any]      			=      alpha.new_zeros((*((1,) * len(alpha.shape[:-1]  )), 2)  )
				UpperCAmelCase_					:List[Any]      			=      1

				# [*, N, 8, 2]
				UpperCAmelCase_					:Tuple      			=      torch.cat([bb_rot.expand(*alpha.shape[:-2],    -1,    -1  ), alpha],    dim=-2  )

				# [*, N, 8, 3, 3]
				# Produces rotation matrices of the form:
				# [
				#   [1, 0  , 0  ],
				#   [0, a_2,-a_1],
				#   [0, a_1, a_2]
				# ]
				# This follows the original code rather than the supplement, which uses
				# different indices.

				UpperCAmelCase_					:Any      			=      alpha.new_zeros(default_r.get_rots().get_rot_mats().shape  )
				UpperCAmelCase_					:Optional[Any]      			=      1
				UpperCAmelCase_					:int      			=      alpha[..., 1]
				UpperCAmelCase_					:Optional[int]      			=      -alpha[..., 0]
				UpperCAmelCase_					:int      			=      alpha

				UpperCAmelCase_					:List[str]      			=      default_r.compose(Rigid(Rotation(rot_mats=__snake_case  ),    __snake_case  )  )

				UpperCAmelCase_					:List[str]      			=      all_frames[..., 5]
				UpperCAmelCase_					:str      			=      all_frames[..., 6]
				UpperCAmelCase_					:List[Any]      			=      all_frames[..., 7]

				UpperCAmelCase_					:Tuple      			=      all_frames[..., 4]
				UpperCAmelCase_					:Optional[Any]      			=      chia_frame_to_bb.compose(__snake_case  )
				UpperCAmelCase_					:Optional[Any]      			=      chia_frame_to_bb.compose(__snake_case  )
				UpperCAmelCase_					:Union[str, Any]      			=      chia_frame_to_bb.compose(__snake_case  )

				UpperCAmelCase_					:List[str]      			=      Rigid.cat(
				    [
				        all_frames[..., :5],
				        chia_frame_to_bb.unsqueeze(-1  ),
				        chia_frame_to_bb.unsqueeze(-1  ),
				        chia_frame_to_bb.unsqueeze(-1  ),
				    ],    dim=-1,    )

				UpperCAmelCase_					:Any      			=      r[..., None].compose(__snake_case  )

				return all_frames_to_global





def 				a (						__snake_case     :				Rigid,    __snake_case     :				torch.Tensor,    __snake_case     :				torch.Tensor,    __snake_case     :				torch.Tensor,    __snake_case     :				torch.Tensor,    __snake_case     :				torch.Tensor,    ):



				'''simple docstring'''





				UpperCAmelCase_					:Optional[Any]      			=      group_idx[aatype, ...]

				# [*, N, 14, 8]
				UpperCAmelCase_					:torch.LongTensor      			=      nn.functional.one_hot(
				    __snake_case,    num_classes=default_frames.shape[-3],    )

				# [*, N, 14, 8]
				UpperCAmelCase_					:Dict      			=      r[..., None, :] * group_mask_one_hot

				# [*, N, 14]
				UpperCAmelCase_					:List[Any]      			=      t_atoms_to_global.map_tensor_fn(lambda __snake_case  : torch.sum(__snake_case,    dim=-1  )  )

				# [*, N, 14, 1]
				UpperCAmelCase_					:List[Any]      			=      atom_mask[aatype, ...].unsqueeze(-1  )

				# [*, N, 14, 3]
				UpperCAmelCase_					:List[Any]      			=      lit_positions[aatype, ...]
				UpperCAmelCase_					:Optional[int]      			=      t_atoms_to_global.apply(__snake_case  )
				UpperCAmelCase_					:int      			=      pred_positions * atom_mask

				return pred_positions


