



import dataclasses
import re
import string
from typing import Any, Dict, Iterator, List, Mapping, Optional, Sequence, Tuple

import numpy as np

from . import residue_constants


__UpperCAmelCase	       =	Mapping[str, np.ndarray]
__UpperCAmelCase	       =	Mapping[str, Any]  # Is a nested dict.
__UpperCAmelCase	       =	0.01



@dataclasses.dataclass(frozen=UpperCamelCase_							)
class     lowerCAmelCase_		:
       UpperCAmelCase__    : np.ndarray  # [num_res, num_atom_type, 3]

       # Amino-acid type for each residue represented as an integer between 0 and
       # 20, where 20 is 'X'.
       UpperCAmelCase__    : np.ndarray  # [num_res]

       # Binary float mask to indicate presence of a particular atom. 1.0 if an atom
       # is present and 0.0 if not. This should be used for loss masking.
       UpperCAmelCase__    : np.ndarray  # [num_res, num_atom_type]

       # Residue index as used in PDB. It is not necessarily continuous or 0-indexed.
       UpperCAmelCase__    : np.ndarray  # [num_res]

       # B-factors, or temperature factors, of each residue (in sq. angstroms units),
       # representing the displacement of the residue from its ground truth mean
       # value.
       UpperCAmelCase__    : np.ndarray  # [num_res, num_atom_type]

       # Chain indices for multi-chain predictions
       UpperCAmelCase__    : Optional[np.ndarray]       					=  None

       # Optional remark about the protein. Included as a comment in output PDB
       # files
       UpperCAmelCase__    : Optional[str]       					=  None

       # Templates used to generate this protein (prediction-only)
       UpperCAmelCase__    : Optional[Sequence[str]]       					=  None

       # Chain corresponding to each parent
       UpperCAmelCase__    : Optional[Sequence[int]]       					=  None






def 		UpperCamelCase     (       snake_case__	:   List[str]     )     ->					Protein:
   UpperCamelCase   :  str						     =     r"""(\[[A-Z]+\]\n)"""
   UpperCamelCase   :  List[str]						     =     [tag.strip() for tag in re.split(__lowerCAmelCase	,					__lowerCAmelCase     ) if len(__lowerCAmelCase     ) > 0]
   UpperCamelCase   :  Iterator[Tuple[str, List[str]]]						     =     zip(tags[0::2]	,					[l.split('\n'     ) for l in tags[1::2]]     )

   UpperCamelCase   :  List[str]						     =     ["N", "CA", "C"]
   UpperCamelCase   :  List[str]						     =     None
   UpperCamelCase   :  Dict						     =     None
   UpperCamelCase   :  Union[str, Any]						     =     None
   for g in groups:
      if "[PRIMARY]" == g[0]:
         UpperCamelCase   :  str						     =     g[1][0].strip()
         for i in range(len(__lowerCAmelCase     )     ):
            if seq[i] not in residue_constants.restypes:
               UpperCamelCase   :  Tuple						     =     """X"""  # FIXME: strings are immutable
         UpperCamelCase   :  Any						     =     np.array(
             [residue_constants.restype_order.get(__lowerCAmelCase	,					residue_constants.restype_num     ) for res_symbol in seq]     )
      elif "[TERTIARY]" == g[0]:
         UpperCamelCase   :  List[List[float]]						     =     []
         for axis in range(3     ):
            tertiary.append(list(map(__lowerCAmelCase	,					g[1][axis].split()     )     )     )
         UpperCamelCase   :  Any						     =     np.array(__lowerCAmelCase     )
         UpperCamelCase   :  Dict						     =     np.zeros((len(tertiary[0]     ) // 3, residue_constants.atom_type_num, 3)     ).astype(np.floataa     )
         for i, atom in enumerate(__lowerCAmelCase     ):
            UpperCamelCase   :  int						     =     np.transpose(tertiary_np[:, i::3]     )
         atom_positions *= PICO_TO_ANGSTROM
      elif "[MASK]" == g[0]:
         UpperCamelCase   :  Any						     =     np.array(list(map({'-': 0, '+': 1}.get	,					g[1][0].strip()     )     )     )
         UpperCamelCase   :  Optional[int]						     =     np.zeros(
             (
                 len(__lowerCAmelCase     ),
                 residue_constants.atom_type_num,
             )     ).astype(np.floataa     )
         for i, atom in enumerate(__lowerCAmelCase     ):
            UpperCamelCase   :  int						     =     1
         atom_mask *= mask[..., None]

   assert aatype is not None

   return Protein(
       atom_positions=__lowerCAmelCase	,					atom_mask=__lowerCAmelCase	,					aatype=__lowerCAmelCase	,					residue_index=np.arange(len(__lowerCAmelCase     )     )	,					b_factors=__lowerCAmelCase	,					)
def 		UpperCamelCase     (       snake_case__	:   List[str]	,					snake_case__	:   Tuple = 0     )     ->					List[str]:
   UpperCamelCase   :  List[str]						     =     []

   UpperCamelCase   :  List[str]						     =     prot.remark
   if remark is not None:
      pdb_headers.append(F"""REMARK {remark}"""     )

   UpperCamelCase   :  int						     =     prot.parents
   UpperCamelCase   :  Optional[Any]						     =     prot.parents_chain_index
   if parents is not None and parents_chain_index is not None:
      UpperCamelCase   :  List[Any]						     =     [p for i, p in zip(__lowerCAmelCase	,					__lowerCAmelCase     ) if i == chain_id]

   if parents is None or len(__lowerCAmelCase     ) == 0:
      UpperCamelCase   :  Optional[int]						     =     ["""N/A"""]

   pdb_headers.append(F"""PARENT {" ".join(__lowerCAmelCase     )}"""     )

   return pdb_headers
def 		UpperCamelCase     (       snake_case__	:   List[str]	,					snake_case__	:   List[str]     )     ->					str:
   UpperCamelCase   :  List[str]						     =     []
   UpperCamelCase   :  Union[str, Any]						     =     pdb_str.split('\n'     )

   UpperCamelCase   :  List[Any]						     =     prot.remark
   if remark is not None:
      out_pdb_lines.append(F"""REMARK {remark}"""     )

   UpperCamelCase   :  List[List[str]]
   if prot.parents is not None and len(prot.parents     ) > 0:
      UpperCamelCase   :  int						     =     []
      if prot.parents_chain_index is not None:
         UpperCamelCase   :  Dict[str, List[str]]						     =     {}
         for p, i in zip(prot.parents	,					prot.parents_chain_index     ):
            parent_dict.setdefault(str(__lowerCAmelCase     )	,					[]     )
            parent_dict[str(__lowerCAmelCase     )].append(__lowerCAmelCase     )

         UpperCamelCase   :  Optional[int]						     =     max([int(__lowerCAmelCase     ) for chain_idx in parent_dict]     )
         for i in range(max_idx + 1     ):
            UpperCamelCase   :  str						     =     parent_dict.get(str(__lowerCAmelCase     )	,					['N/A']     )
            parents_per_chain.append(__lowerCAmelCase     )
      else:
         parents_per_chain.append(list(prot.parents     )     )
   else:
      UpperCamelCase   :  List[Any]						     =     [["""N/A"""]]

   def make_parent_line(snake_case__	:   int     ) -> str:
      return F"""PARENT {" ".join(__lowerCAmelCase     )}"""

   out_pdb_lines.append(make_parent_line(parents_per_chain[0]     )     )

   UpperCamelCase   :  Tuple						     =     0
   for i, l in enumerate(__lowerCAmelCase     ):
      if "PARENT" not in l and "REMARK" not in l:
         out_pdb_lines.append(__lowerCAmelCase     )
      if "TER" in l and "END" not in lines[i + 1]:
         chain_counter += 1
         if not chain_counter >= len(__lowerCAmelCase     ):
            UpperCamelCase   :  Optional[Any]						     =     parents_per_chain[chain_counter]
         else:
            UpperCamelCase   :  Any						     =     ["""N/A"""]

         out_pdb_lines.append(make_parent_line(__lowerCAmelCase     )     )

   return "\n".join(__lowerCAmelCase     )
def 		UpperCamelCase     (       snake_case__	:   Tuple     )     ->					str:
   UpperCamelCase   :  int						     =     residue_constants.restypes + ["""X"""]

   def res_atoa(snake_case__	:   List[str]     ) -> str:
      return residue_constants.restype_atoa.get(restypes[r]	,					'UNK'     )

   UpperCamelCase   :  List[str]						     =     residue_constants.atom_types

   UpperCamelCase   :  List[str]						     =     []

   UpperCamelCase   :  List[str]						     =     prot.atom_mask
   UpperCamelCase   :  Optional[int]						     =     prot.aatype
   UpperCamelCase   :  Optional[int]						     =     prot.atom_positions
   UpperCamelCase   :  Optional[int]						     =     prot.residue_index.astype(np.intaa     )
   UpperCamelCase   :  int						     =     prot.b_factors
   UpperCamelCase   :  Union[str, Any]						     =     prot.chain_index

   if np.any(aatype > residue_constants.restype_num     ):
      raise ValueError('Invalid aatypes.'     )

   UpperCamelCase   :  Tuple						     =     get_pdb_headers(__lowerCAmelCase     )
   if len(__lowerCAmelCase     ) > 0:
      pdb_lines.extend(__lowerCAmelCase     )

   UpperCamelCase   :  List[str]						     =     aatype.shape[0]
   UpperCamelCase   :  Dict						     =     1
   UpperCamelCase   :  List[str]						     =     0
   UpperCamelCase   :  str						     =     string.ascii_uppercase
   UpperCamelCase   :  List[str]						     =     None
   # Add all atom sites.
   for i in range(__lowerCAmelCase     ):
      UpperCamelCase   :  Optional[int]						     =     res_atoa(aatype[i]     )
      for atom_name, pos, mask, b_factor in zip(__lowerCAmelCase	,					atom_positions[i]	,					atom_mask[i]	,					b_factors[i]     ):
         if mask < 0.5:
            continue

         UpperCamelCase   :  List[str]						     =     """ATOM"""
         UpperCamelCase   :  Optional[Any]						     =     atom_name if len(__lowerCAmelCase     ) == 4 else F""" {atom_name}"""
         UpperCamelCase   :  List[Any]						     =     """"""
         UpperCamelCase   :  int						     =     """"""
         UpperCamelCase   :  List[Any]						     =     1.00
         UpperCamelCase   :  List[Any]						     =     atom_name[0]  # Protein supports only C, N, O, S, this works.
         UpperCamelCase   :  int						     =     """"""

         UpperCamelCase   :  Union[str, Any]						     =     """A"""
         if chain_index is not None:
            UpperCamelCase   :  Optional[Any]						     =     chain_tags[chain_index[i]]

         # PDB is a columnar format, every space matters here!
         UpperCamelCase   :  Tuple						     =     (
             F"""{record_type:<6}{atom_index:>5} {name:<4}{alt_loc:>1}"""
             F"""{res_name_a:>3} {chain_tag:>1}"""
             F"""{residue_index[i]:>4}{insertion_code:>1}   """
             F"""{pos[0]:>8.3f}{pos[1]:>8.3f}{pos[2]:>8.3f}"""
             F"""{occupancy:>6.2f}{b_factor:>6.2f}          """
             F"""{element:>2}{charge:>2}"""
         )
         pdb_lines.append(__lowerCAmelCase     )
         atom_index += 1

      UpperCamelCase   :  Union[str, Any]						     =     i == n - 1
      if chain_index is not None:
         if i != n - 1 and chain_index[i + 1] != prev_chain_index:
            UpperCamelCase   :  str						     =     True
            UpperCamelCase   :  Optional[int]						     =     chain_index[i + 1]

      if should_terminate:
         # Close the chain.
         UpperCamelCase   :  Dict						     =     """TER"""
         UpperCamelCase   :  int						     =     (
             F"""{chain_end:<6}{atom_index:>5}      {res_atoa(aatype[i]     ):>3} {chain_tag:>1}{residue_index[i]:>4}"""
         )
         pdb_lines.append(__lowerCAmelCase     )
         atom_index += 1

         if i != n - 1:
            # "prev" is a misnomer here. This happens at the beginning of
            # each new chain.
            pdb_lines.extend(get_pdb_headers(__lowerCAmelCase	,					__lowerCAmelCase     )     )

   pdb_lines.append('END'     )
   pdb_lines.append(''     )
   return "\n".join(__lowerCAmelCase     )
def 		UpperCamelCase     (       snake_case__	:   int     )     ->					np.ndarray:
   return residue_constants.STANDARD_ATOM_MASK[prot.aatype]


def 		UpperCamelCase     (       snake_case__	:   List[Any]	,					snake_case__	:   Tuple	,					snake_case__	:   List[Any] = None	,					snake_case__	:   Tuple = None	,					snake_case__	:   int = None	,					snake_case__	:   Union[str, Any] = None	,					snake_case__	:   str = None	,					)     ->					Protein:
   return Protein(
       aatype=features['aatype']	,					atom_positions=result['final_atom_positions']	,					atom_mask=result['final_atom_mask']	,					residue_index=features['residue_index'] + 1	,					b_factors=b_factors if b_factors is not None else np.zeros_like(result['final_atom_mask']     )	,					chain_index=__lowerCAmelCase	,					remark=__lowerCAmelCase	,					parents=__lowerCAmelCase	,					parents_chain_index=__lowerCAmelCase	,					)





import unittest

from transformers import EsmConfig, is_torch_available
from transformers.testing_utils import TestCasePlus, require_torch, slow, torch_device

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
    import torch

    from transformers.models.esm.modeling_esmfold import EsmForProteinFolding



class     lowerCAmelCase_		:
       def __init__(      self,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_=13,      SCREAMING_SNAKE_CASE_=7,      SCREAMING_SNAKE_CASE_=False,      SCREAMING_SNAKE_CASE_=True,      SCREAMING_SNAKE_CASE_=False,      SCREAMING_SNAKE_CASE_=False,      SCREAMING_SNAKE_CASE_=19,      SCREAMING_SNAKE_CASE_=32,      SCREAMING_SNAKE_CASE_=5,      SCREAMING_SNAKE_CASE_=4,      SCREAMING_SNAKE_CASE_=37,      SCREAMING_SNAKE_CASE_="gelu",      SCREAMING_SNAKE_CASE_=0.1,      SCREAMING_SNAKE_CASE_=0.1,      SCREAMING_SNAKE_CASE_=512,      SCREAMING_SNAKE_CASE_=16,      SCREAMING_SNAKE_CASE_=2,      SCREAMING_SNAKE_CASE_=0.02,      SCREAMING_SNAKE_CASE_=3,      SCREAMING_SNAKE_CASE_=4,      SCREAMING_SNAKE_CASE_=None,      )					->		Optional[int]:
          UpperCamelCase   :  Any						     =     parent
          UpperCamelCase   :  Optional[Any]						     =     batch_size
          UpperCamelCase   :  Optional[Any]						     =     seq_length
          UpperCamelCase   :  Tuple						     =     is_training
          UpperCamelCase   :  List[str]						     =     use_input_mask
          UpperCamelCase   :  Optional[int]						     =     use_token_type_ids
          UpperCamelCase   :  Any						     =     use_labels
          UpperCamelCase   :  Union[str, Any]						     =     vocab_size
          UpperCamelCase   :  int						     =     hidden_size
          UpperCamelCase   :  List[Any]						     =     num_hidden_layers
          UpperCamelCase   :  Dict						     =     num_attention_heads
          UpperCamelCase   :  List[Any]						     =     intermediate_size
          UpperCamelCase   :  str						     =     hidden_act
          UpperCamelCase   :  List[Any]						     =     hidden_dropout_prob
          UpperCamelCase   :  List[str]						     =     attention_probs_dropout_prob
          UpperCamelCase   :  List[str]						     =     max_position_embeddings
          UpperCamelCase   :  Union[str, Any]						     =     type_vocab_size
          UpperCamelCase   :  str						     =     type_sequence_label_size
          UpperCamelCase   :  List[str]						     =     initializer_range
          UpperCamelCase   :  List[Any]						     =     num_labels
          UpperCamelCase   :  Any						     =     num_choices
          UpperCamelCase   :  Tuple						     =     scope
       def  snake_case_	(      self	)					->		Optional[int]:
          UpperCamelCase   :  str						     =     ids_tensor([self.batch_size, self.seq_length],      self.vocab_size	)

          UpperCamelCase   :  Optional[Any]						     =     None
          if self.use_input_mask:
             UpperCamelCase   :  Dict						     =     random_attention_mask([self.batch_size, self.seq_length]	)

          UpperCamelCase   :  Union[str, Any]						     =     None
          UpperCamelCase   :  Optional[int]						     =     None
          UpperCamelCase   :  Optional[int]						     =     None
          if self.use_labels:
             UpperCamelCase   :  int						     =     ids_tensor([self.batch_size],      self.type_sequence_label_size	)
             UpperCamelCase   :  Optional[Any]						     =     ids_tensor([self.batch_size, self.seq_length],      self.num_labels	)
             UpperCamelCase   :  Tuple						     =     ids_tensor([self.batch_size],      self.num_choices	)

          UpperCamelCase   :  Union[str, Any]						     =     self.get_config()

          return config, input_ids, input_mask, sequence_labels, token_labels, choice_labels
       def  snake_case_	(      self	)					->		Optional[int]:
          UpperCamelCase   :  List[str]						     =     EsmConfig(
              vocab_size=33,      hidden_size=self.hidden_size,      pad_token_id=1,      num_hidden_layers=self.num_hidden_layers,      num_attention_heads=self.num_attention_heads,      intermediate_size=self.intermediate_size,      hidden_act=self.hidden_act,      hidden_dropout_prob=self.hidden_dropout_prob,      attention_probs_dropout_prob=self.attention_probs_dropout_prob,      max_position_embeddings=self.max_position_embeddings,      type_vocab_size=self.type_vocab_size,      initializer_range=self.initializer_range,      is_folding_model=SCREAMING_SNAKE_CASE_,      esmfold_config={'trunk': {'num_blocks': 2}, 'fp16_esm': False},      )
          return config
       def  snake_case_	(      self,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_	)					->		Tuple:
          UpperCamelCase   :  Union[str, Any]						     =     EsmForProteinFolding(config=SCREAMING_SNAKE_CASE_	).float()
          model.to(SCREAMING_SNAKE_CASE_	)
          model.eval()
          UpperCamelCase   :  int						     =     model(SCREAMING_SNAKE_CASE_,      attention_mask=SCREAMING_SNAKE_CASE_	)
          UpperCamelCase   :  List[Any]						     =     model(SCREAMING_SNAKE_CASE_	)
          UpperCamelCase   :  List[Any]						     =     model(SCREAMING_SNAKE_CASE_	)

          self.parent.assertEqual(result.positions.shape,      (8, self.batch_size, self.seq_length, 14, 3)	)
          self.parent.assertEqual(result.angles.shape,      (8, self.batch_size, self.seq_length, 7, 2)	)






       def  snake_case_	(      self	)					->		Optional[int]:
          UpperCamelCase   :  Union[str, Any]						     =     self.prepare_config_and_inputs()
          (
              (
              UpperCamelCase
          )     ,					(
              UpperCamelCase
          )     ,					(
              UpperCamelCase
          )     ,					(
              UpperCamelCase
          )     ,					(
              UpperCamelCase
          )     ,					(
              UpperCamelCase
          )     ,					
          )   :  Tuple						     =     config_and_inputs
          UpperCamelCase   :  Optional[Any]						     =     {'input_ids': input_ids, 'attention_mask': input_mask}
          return config, inputs_dict






@require_torch
class     lowerCAmelCase_		(  a__	,   a__	,   unittest.TestCase							):
       UpperCAmelCase__    : Dict       					=  False

       UpperCAmelCase__    : Optional[int]       					=  (EsmForProteinFolding,) if is_torch_available() else ()
       UpperCAmelCase__    : int       					=  ()
       UpperCAmelCase__    : List[str]       					=  {} if is_torch_available() else {}
       UpperCAmelCase__    : Optional[int]       					=  False
       def  snake_case_	(      self	)					->		Dict:
          UpperCamelCase   :  Tuple						     =     EsmFoldModelTester(self	)
          UpperCamelCase   :  List[str]						     =     ConfigTester(self,      config_class=SCREAMING_SNAKE_CASE_,      hidden_size=37	)
       def  snake_case_	(      self	)					->		int:
          self.config_tester.run_common_tests()
       def  snake_case_	(      self	)					->		Union[str, Any]:
          UpperCamelCase   :  int						     =     self.model_tester.prepare_config_and_inputs()
          self.model_tester.create_and_check_model(*SCREAMING_SNAKE_CASE_	)
       @unittest.skip('Does not support attention outputs'	)
       def  snake_case_	(      self	)					->		Tuple:
          pass
       @unittest.skip
       def  snake_case_	(      self	)					->		List[Any]:
          pass
       @unittest.skip('Esm does not support embedding resizing'	)
       def  snake_case_	(      self	)					->		Any:
          pass
       @unittest.skip('Esm does not support embedding resizing'	)
       def  snake_case_	(      self	)					->		Optional[Any]:
          pass
       @unittest.skip('ESMFold does not support passing input embeds!'	)
       def  snake_case_	(      self	)					->		Optional[Any]:
          pass
       @unittest.skip('ESMFold does not support head pruning.'	)
       def  snake_case_	(      self	)					->		Any:
          pass
       @unittest.skip('ESMFold does not support head pruning.'	)
       def  snake_case_	(      self	)					->		int:
          pass
       @unittest.skip('ESMFold does not support head pruning.'	)
       def  snake_case_	(      self	)					->		Dict:
          pass
       @unittest.skip('ESMFold does not support head pruning.'	)
       def  snake_case_	(      self	)					->		Union[str, Any]:
          pass
       @unittest.skip('ESMFold does not support head pruning.'	)
       def  snake_case_	(      self	)					->		Any:
          pass
       @unittest.skip('ESMFold does not output hidden states in the normal way.'	)
       def  snake_case_	(      self	)					->		str:
          pass
       @unittest.skip('ESMfold does not output hidden states in the normal way.'	)
       def  snake_case_	(      self	)					->		List[str]:
          pass
       @unittest.skip('ESMFold only has one output format.'	)
       def  snake_case_	(      self	)					->		int:
          pass
       @unittest.skip('This test doesn\'t work for ESMFold and doesn\'t test core functionality'	)
       def  snake_case_	(      self	)					->		Any:
          pass
       @unittest.skip('ESMFold does not support input chunking.'	)
       def  snake_case_	(      self	)					->		Any:
          pass
       @unittest.skip('ESMFold doesn\'t respect you and it certainly doesn\'t respect your initialization arguments.'	)
       def  snake_case_	(      self	)					->		Tuple:
          pass
       @unittest.skip('ESMFold doesn\'t support torchscript compilation.'	)
       def  snake_case_	(      self	)					->		Any:
          pass
       @unittest.skip('ESMFold doesn\'t support torchscript compilation.'	)
       def  snake_case_	(      self	)					->		str:
          pass
       @unittest.skip('ESMFold doesn\'t support torchscript compilation.'	)
       def  snake_case_	(      self	)					->		List[Any]:
          pass
       @unittest.skip('ESMFold doesn\'t support data parallel.'	)
       def  snake_case_	(      self	)					->		List[str]:
          pass






       @unittest.skip('Will be fixed soon by reducing the size of the model used for common tests.'	)
       def  snake_case_	(      self	)					->		Optional[Any]:
          pass






@require_torch
class     lowerCAmelCase_		(  a__							):
       @slow
       def  snake_case_	(      self	)					->		str:
          UpperCamelCase   :  Union[str, Any]						     =     EsmForProteinFolding.from_pretrained('facebook/esmfold_v1'	).float()
          model.eval()
          UpperCamelCase   :  Tuple						     =     torch.tensor([[0, 6, 4, 13, 5, 4, 16, 12, 11, 7, 2]]	)
          UpperCamelCase   :  List[str]						     =     model(SCREAMING_SNAKE_CASE_	)['positions']
          UpperCamelCase   :  int						     =     torch.tensor([2.58_28, 0.79_93, -10.93_34],      dtype=torch.floataa	)
          self.assertTrue(torch.allclose(position_outputs[0, 0, 0, 0],      SCREAMING_SNAKE_CASE_,      atol=1e-4	)	)



