



'''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


snake_case__					:     List[Any]    		=   Mapping[str, np.ndarray]
snake_case__					:     Any    		=   Mapping[str, Any]  # Is a nested dict.
snake_case__					:     Any    		=   0.0_1

@dataclasses.dataclass(frozen=_lowercase	)
class   _A   :


						'''simple docstring'''





						_snake_case			:     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'.
						_snake_case			:     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.
						_snake_case			:     np.ndarray  # [num_res, num_atom_type]

						# Residue index as used in PDB. It is not necessarily continuous or 0-indexed.
						_snake_case			:     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.
						_snake_case			:     np.ndarray  # [num_res, num_atom_type]

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

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

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

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



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

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

	assert aatype is not None

	return Protein(
	    atom_positions=_SCREAMING_SNAKE_CASE  ,	atom_mask=_SCREAMING_SNAKE_CASE  ,	aatype=_SCREAMING_SNAKE_CASE  ,	residue_index=np.arange(len(_SCREAMING_SNAKE_CASE   )   )  ,	b_factors=_SCREAMING_SNAKE_CASE  ,	)



def    snake_case_				(    _SCREAMING_SNAKE_CASE  ,	_SCREAMING_SNAKE_CASE = 0   ):
	__lowercase		       =			[]

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

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

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

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

	return pdb_headers



def    snake_case_				(    _SCREAMING_SNAKE_CASE  ,	_SCREAMING_SNAKE_CASE   ):
	__lowercase		       =			[]
	__lowercase		       =			pdb_str.split("\n"   )

	__lowercase		       =			prot.remark
	if remark is not None:
		out_pdb_lines.append(F"""REMARK {remark}"""   )

	__lowercase		       =			4_2
	if prot.parents is not None and len(prot.parents   ) > 0:
		__lowercase		       =			[]
		if prot.parents_chain_index is not None:
			__lowercase		       =			{}
			for p, i in zip(prot.parents  ,	prot.parents_chain_index   ):
				parent_dict.setdefault(str(_SCREAMING_SNAKE_CASE   )  ,	[]   )
				parent_dict[str(_SCREAMING_SNAKE_CASE   )].append(_SCREAMING_SNAKE_CASE   )

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

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

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

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

			out_pdb_lines.append(make_parent_line(_SCREAMING_SNAKE_CASE   )   )

	return "\n".join(_SCREAMING_SNAKE_CASE   )



def    snake_case_				(    _SCREAMING_SNAKE_CASE   ):
	__lowercase		       =			residue_constants.restypes + ["X"]

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

	__lowercase		       =			residue_constants.atom_types

	__lowercase		       =			[]

	__lowercase		       =			prot.atom_mask
	__lowercase		       =			prot.aatype
	__lowercase		       =			prot.atom_positions
	__lowercase		       =			prot.residue_index.astype(np.intaa   )
	__lowercase		       =			prot.b_factors
	__lowercase		       =			prot.chain_index

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

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

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

			__lowercase		       =			"ATOM"
			__lowercase		       =			atom_name if len(_SCREAMING_SNAKE_CASE   ) == 4 else F""" {atom_name}"""
			__lowercase		       =			""
			__lowercase		       =			""
			__lowercase		       =			1.0_0
			__lowercase		       =			atom_name[0]  # Protein supports only C, N, O, S, this works.
			__lowercase		       =			""

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

			# PDB is a columnar format, every space matters here!
			__lowercase		       =			(
			    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(_SCREAMING_SNAKE_CASE   )
			atom_index += 1

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

		if should_terminate:
			# Close the chain.
			__lowercase		       =			"TER"
			__lowercase		       =			(
			    F"""{chain_end:<6}{atom_index:>5}      {res_atoa(aatype[i]   ):>3} {chain_tag:>1}{residue_index[i]:>4}"""
			)
			pdb_lines.append(_SCREAMING_SNAKE_CASE   )
			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(_SCREAMING_SNAKE_CASE  ,	_SCREAMING_SNAKE_CASE   )   )

	pdb_lines.append("END"   )
	pdb_lines.append(""   )
	return "\n".join(_SCREAMING_SNAKE_CASE   )



def    snake_case_				(    _SCREAMING_SNAKE_CASE   ):
	return residue_constants.STANDARD_ATOM_MASK[prot.aatype]



def    snake_case_				(    _SCREAMING_SNAKE_CASE  ,	_SCREAMING_SNAKE_CASE  ,	_SCREAMING_SNAKE_CASE = None  ,	_SCREAMING_SNAKE_CASE = None  ,	_SCREAMING_SNAKE_CASE = None  ,	_SCREAMING_SNAKE_CASE = None  ,	_SCREAMING_SNAKE_CASE = None  ,	):
	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=_SCREAMING_SNAKE_CASE  ,	remark=_SCREAMING_SNAKE_CASE  ,	parents=_SCREAMING_SNAKE_CASE  ,	parents_chain_index=_SCREAMING_SNAKE_CASE  ,	)








# Copyright 2023 The HuggingFace Team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import TYPE_CHECKING

from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available


snake_case__					:     List[str]    		=   {
    """configuration_mgp_str""": ["""MGP_STR_PRETRAINED_CONFIG_ARCHIVE_MAP""", """MgpstrConfig"""],
    """processing_mgp_str""": ["""MgpstrProcessor"""],
    """tokenization_mgp_str""": ["""MgpstrTokenizer"""],
}

try:
	if not is_torch_available():
		raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
	pass
else:
	snake_case__					:     Dict    		=   [
	    """MGP_STR_PRETRAINED_MODEL_ARCHIVE_LIST""",
	    """MgpstrModel""",
	    """MgpstrPreTrainedModel""",
	    """MgpstrForSceneTextRecognition""",
	]

if TYPE_CHECKING:
	from .configuration_mgp_str import MGP_STR_PRETRAINED_CONFIG_ARCHIVE_MAP, MgpstrConfig
	from .processing_mgp_str import MgpstrProcessor
	from .tokenization_mgp_str import MgpstrTokenizer

	try:
		if not is_torch_available():
			raise OptionalDependencyNotAvailable()
	except OptionalDependencyNotAvailable:
		pass
	else:
		from .modeling_mgp_str import (
		    MGP_STR_PRETRAINED_MODEL_ARCHIVE_LIST,
		    MgpstrForSceneTextRecognition,
		    MgpstrModel,
		    MgpstrPreTrainedModel,
		)
else:
	import sys

	snake_case__					:     Union[str, Any]    		=   _LazyModule(__name__, globals()["""__file__"""], _import_structure, module_spec=__spec__)



