




"""simple docstring"""







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


__A   :  List[Any]		=      Mapping[str, np.ndarray]
__A   :  int		=      Mapping[str, Any]  # Is a nested dict.
__A   :  List[Any]		=      0.01




@dataclasses.dataclass(frozen=lowerCAmelCase_    )
class       lowerCAmelCase__       :


				"""simple docstring"""





				__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 						snake_case__       (					_lowerCamelCase				)			->Protein:






		"""simple docstring"""


		__lowercase				:		str												=				R"(\[[A-Z]+\]\n)"
		__lowercase				:		List[str]												=				[tag.strip() for tag in re.split(_lowerCamelCase,  _lowerCamelCase				) if len(_lowerCamelCase				) > 0]
		__lowercase				:		Iterator[Tuple[str, List[str]]]												=				zip(tags[0::2],  [l.split("\n"				) for l in tags[1::2]]				)

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






		"""simple docstring"""


		__lowercase				:		List[str]												=				[]

		__lowercase				:		Tuple												=				prot.remark
		if remark is not None:
				pdb_headers.append(F'REMARK {remark}'				)

		__lowercase				:		str												=				prot.parents
		__lowercase				:		List[str]												=				prot.parents_chain_index
		if parents is not None and parents_chain_index is not None:
				__lowercase				:		Any												=				[p for i, p in zip(_lowerCamelCase,  _lowerCamelCase				) if i == chain_id]

		if parents is None or len(_lowerCamelCase				) == 0:
				__lowercase				:		Dict												=				["N/A"]

		pdb_headers.append(F'PARENT {" ".join(_lowerCamelCase				)}'				)

		return pdb_headers

def 						snake_case__       (					_lowerCamelCase,  _lowerCamelCase				)			->str:






		"""simple docstring"""


		__lowercase				:		List[str]												=				[]
		__lowercase				:		List[str]												=				pdb_str.split("\n"				)

		__lowercase				:		Optional[int]												=				prot.remark
		if remark is not None:
				out_pdb_lines.append(F'REMARK {remark}'				)

		__lowercase				:		List[List[str]]
		if prot.parents is not None and len(prot.parents				) > 0:
				__lowercase				:		Union[str, Any]												=				[]
				if prot.parents_chain_index is not None:
						__lowercase				:		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				)

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

		def make_parent_line(_lowerCamelCase				) -> str:
				return F'PARENT {" ".join(_lowerCamelCase				)}'

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

		__lowercase				:		Union[str, Any]												=				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				):
								__lowercase				:		Tuple												=				parents_per_chain[chain_counter]
						else:
								__lowercase				:		Tuple												=				["N/A"]

						out_pdb_lines.append(make_parent_line(_lowerCamelCase				)				)

		return "\n".join(_lowerCamelCase				)

def 						snake_case__       (					_lowerCamelCase				)			->str:






		"""simple docstring"""


		__lowercase				:		Optional[Any]												=				residue_constants.restypes + ["X"]

		def res_atoa(_lowerCamelCase				) -> str:
				return residue_constants.restype_atoa.get(restypes[r],  "UNK"				)

		__lowercase				:		int												=				residue_constants.atom_types

		__lowercase				:		List[str]												=				[]

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

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

		__lowercase				:		int												=				get_pdb_headers(_lowerCamelCase				)
		if len(_lowerCamelCase				) > 0:
				pdb_lines.extend(_lowerCamelCase				)

		__lowercase				:		Union[str, Any]												=				aatype.shape[0]
		__lowercase				:		Union[str, Any]												=				1
		__lowercase				:		Optional[Any]												=				0
		__lowercase				:		Any												=				string.ascii_uppercase
		__lowercase				:		List[str]												=				None
		# Add all atom sites.
		for i in range(_lowerCamelCase				):
				__lowercase				:		List[Any]												=				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

						__lowercase				:		Tuple												=				"ATOM"
						__lowercase				:		Optional[int]												=				atom_name if len(_lowerCamelCase				) == 4 else F' {atom_name}'
						__lowercase				:		Union[str, Any]												=				""
						__lowercase				:		Union[str, Any]												=				""
						__lowercase				:		Optional[Any]												=				1.0_0
						__lowercase				:		Optional[int]												=				atom_name[0]  # Protein supports only C, N, O, S, this works.
						__lowercase				:		Union[str, Any]												=				""

						__lowercase				:		Dict												=				"A"
						if chain_index is not None:
								__lowercase				:		Optional[int]												=				chain_tags[chain_index[i]]

						# PDB is a columnar format, every space matters here!
						__lowercase				:		Optional[int]												=				(
						    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

				__lowercase				:		int												=				i == n - 1
				if chain_index is not None:
						if i != n - 1 and chain_index[i + 1] != prev_chain_index:
								__lowercase				:		Dict												=				True
								__lowercase				:		List[Any]												=				chain_index[i + 1]

				if should_terminate:
						# Close the chain.
						__lowercase				:		Dict												=				"TER"
						__lowercase				:		List[Any]												=				(
						    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 						snake_case__       (					_lowerCamelCase				)			->np.ndarray:






		"""simple docstring"""


		return residue_constants.STANDARD_ATOM_MASK[prot.aatype]





def 						snake_case__       (					_lowerCamelCase,  _lowerCamelCase,  _lowerCamelCase = None,  _lowerCamelCase = None,  _lowerCamelCase = None,  _lowerCamelCase = None,  _lowerCamelCase = None,  )			->Protein:






		"""simple docstring"""


		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,  )






"""simple docstring"""







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__       :


				"""simple docstring"""





				def __init__(     self					:	Tuple    ,   lowercase__					:	Tuple    ,   lowercase__					:	Tuple=1_3    ,   lowercase__					:	Optional[int]=7    ,   lowercase__					:	List[str]=False    ,   lowercase__					:	Tuple=True    ,   lowercase__					:	int=False    ,   lowercase__					:	List[str]=False    ,   lowercase__					:	Optional[Any]=1_9    ,   lowercase__					:	int=3_2    ,   lowercase__					:	List[Any]=5    ,   lowercase__					:	Optional[int]=4    ,   lowercase__					:	Any=3_7    ,   lowercase__					:	Tuple="gelu"    ,   lowercase__					:	int=0.1    ,   lowercase__					:	Tuple=0.1    ,   lowercase__					:	List[Any]=5_1_2    ,   lowercase__					:	List[Any]=1_6    ,   lowercase__					:	Union[str, Any]=2    ,   lowercase__					:	List[str]=0.0_2    ,   lowercase__					:	List[Any]=3    ,   lowercase__					:	Any=4    ,   lowercase__					:	Optional[Any]=None    ,   ):
						__lowercase				:		int												=				parent
						__lowercase				:		Tuple												=				batch_size
						__lowercase				:		Optional[int]												=				seq_length
						__lowercase				:		str												=				is_training
						__lowercase				:		List[Any]												=				use_input_mask
						__lowercase				:		Any												=				use_token_type_ids
						__lowercase				:		str												=				use_labels
						__lowercase				:		Dict												=				vocab_size
						__lowercase				:		Optional[int]												=				hidden_size
						__lowercase				:		List[Any]												=				num_hidden_layers
						__lowercase				:		int												=				num_attention_heads
						__lowercase				:		Union[str, Any]												=				intermediate_size
						__lowercase				:		Dict												=				hidden_act
						__lowercase				:		Union[str, Any]												=				hidden_dropout_prob
						__lowercase				:		Optional[int]												=				attention_probs_dropout_prob
						__lowercase				:		Optional[Any]												=				max_position_embeddings
						__lowercase				:		List[str]												=				type_vocab_size
						__lowercase				:		str												=				type_sequence_label_size
						__lowercase				:		List[str]												=				initializer_range
						__lowercase				:		Optional[Any]												=				num_labels
						__lowercase				:		Tuple												=				num_choices
						__lowercase				:		Optional[Any]												=				scope



				def       snake_case    (     self					:	Optional[int]						):
						__lowercase				:		Tuple												=				ids_tensor([self.batch_size, self.seq_length]    ,   self.vocab_size						)

						__lowercase				:		Union[str, Any]												=				None
						if self.use_input_mask:
								__lowercase				:		List[str]												=				random_attention_mask([self.batch_size, self.seq_length]						)

						__lowercase				:		Dict												=				None
						__lowercase				:		Any												=				None
						__lowercase				:		Optional[Any]												=				None
						if self.use_labels:
								__lowercase				:		Tuple												=				ids_tensor([self.batch_size]    ,   self.type_sequence_label_size						)
								__lowercase				:		List[str]												=				ids_tensor([self.batch_size, self.seq_length]    ,   self.num_labels						)
								__lowercase				:		Optional[Any]												=				ids_tensor([self.batch_size]    ,   self.num_choices						)

						__lowercase				:		Optional[Any]												=				self.get_config()

						return config, input_ids, input_mask, sequence_labels, token_labels, choice_labels



				def       snake_case    (     self					:	Any						):
						__lowercase				:		Dict												=				EsmConfig(
						    vocab_size=3_3    ,   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=lowercase__    ,   esmfold_config={"trunk": {"num_blocks": 2}, "fp16_esm": False}    ,   )
						return config



				def       snake_case    (     self					:	str    ,   lowercase__					:	List[Any]    ,   lowercase__					:	Optional[int]    ,   lowercase__					:	List[Any]    ,   lowercase__					:	int    ,   lowercase__					:	List[Any]    ,   lowercase__					:	str						):
						__lowercase				:		List[Any]												=				EsmForProteinFolding(config=lowercase__						).float()
						model.to(lowercase__						)
						model.eval()
						__lowercase				:		List[str]												=				model(lowercase__    ,   attention_mask=lowercase__						)
						__lowercase				:		Any												=				model(lowercase__						)
						__lowercase				:		Any												=				model(lowercase__						)

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



				def       snake_case    (     self					:	Tuple						):
						__lowercase				:		List[str]												=				self.prepare_config_and_inputs()
						(
						    (
						    __lowercase
						)						,(
						    __lowercase
						)						,(
						    __lowercase
						)						,(
						    __lowercase
						)						,(
						    __lowercase
						)						,(
						    __lowercase
						)						,
						)				:		Any												=				config_and_inputs
						__lowercase				:		int												=				{"input_ids": input_ids, "attention_mask": input_mask}
						return config, inputs_dict





@require_torch
class       lowerCAmelCase__       (			lowerCAmelCase_  ,			lowerCAmelCase_  ,			unittest.TestCase    ):


				"""simple docstring"""





				__UpperCAmelCase :     Union[str, Any]       =      False

				__UpperCAmelCase :     List[Any]       =      (EsmForProteinFolding,) if is_torch_available() else ()
				__UpperCAmelCase :     int       =      ()
				__UpperCAmelCase :     Tuple       =      {} if is_torch_available() else {}
				__UpperCAmelCase :     Optional[Any]       =      False



				def       snake_case    (     self					:	Tuple						):
						__lowercase				:		Tuple												=				EsmFoldModelTester(self						)
						__lowercase				:		Dict												=				ConfigTester(self    ,   config_class=lowercase__    ,   hidden_size=3_7						)



				def       snake_case    (     self					:	Dict						):
						self.config_tester.run_common_tests()



				def       snake_case    (     self					:	Optional[int]						):
						__lowercase				:		Tuple												=				self.model_tester.prepare_config_and_inputs()
						self.model_tester.create_and_check_model(*lowercase__						)



				@unittest.skip("Does not support attention outputs"						)
				def       snake_case    (     self					:	Union[str, Any]						):
						pass



				@unittest.skip
				def       snake_case    (     self					:	Tuple						):
						pass



				@unittest.skip("Esm does not support embedding resizing"						)
				def       snake_case    (     self					:	Optional[int]						):
						pass



				@unittest.skip("Esm does not support embedding resizing"						)
				def       snake_case    (     self					:	List[str]						):
						pass



				@unittest.skip("ESMFold does not support passing input embeds!"						)
				def       snake_case    (     self					:	int						):
						pass



				@unittest.skip("ESMFold does not support head pruning."						)
				def       snake_case    (     self					:	List[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					:	Optional[Any]						):
						pass



				@unittest.skip("ESMFold does not support head pruning."						)
				def       snake_case    (     self					:	List[str]						):
						pass



				@unittest.skip("ESMFold does not support head pruning."						)
				def       snake_case    (     self					:	List[str]						):
						pass



				@unittest.skip("ESMFold does not output hidden states in the normal way."						)
				def       snake_case    (     self					:	Optional[Any]						):
						pass



				@unittest.skip("ESMfold does not output hidden states in the normal way."						)
				def       snake_case    (     self					:	Optional[Any]						):
						pass



				@unittest.skip("ESMFold only has one output format."						)
				def       snake_case    (     self					:	Tuple						):
						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					:	str						):
						pass



				@unittest.skip("ESMFold doesn't respect you and it certainly doesn't respect your initialization arguments."						)
				def       snake_case    (     self					:	Any						):
						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					:	Tuple						):
						pass



				@unittest.skip("ESMFold doesn't support torchscript compilation."						)
				def       snake_case    (     self					:	List[str]						):
						pass



				@unittest.skip("ESMFold doesn't support data parallel."						)
				def       snake_case    (     self					:	Optional[Any]						):
						pass



				@unittest.skip("Will be fixed soon by reducing the size of the model used for common tests."						)
				def       snake_case    (     self					:	Any						):
						pass





@require_torch
class       lowerCAmelCase__       (			lowerCAmelCase_    ):


				"""simple docstring"""





				@slow
				def       snake_case    (     self					:	Union[str, Any]						):
						__lowercase				:		Tuple												=				EsmForProteinFolding.from_pretrained("facebook/esmfold_v1"						).float()
						model.eval()
						__lowercase				:		Optional[int]												=				torch.tensor([[0, 6, 4, 1_3, 5, 4, 1_6, 1_2, 1_1, 7, 2]]						)
						__lowercase				:		str												=				model(lowercase__						)["positions"]
						__lowercase				:		Union[str, Any]												=				torch.tensor([2.5_8_2_8, 0.7_9_9_3, -1_0.9_3_3_4]    ,   dtype=torch.floataa						)
						self.assertTrue(torch.allclose(position_outputs[0, 0, 0, 0]    ,   lowercase__    ,   atol=1e-4						)						)
