



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


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

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


						'''simple docstring'''



						UpperCAmelCase				:       int 	=						42  # [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				:       Optional[Any] 	=						42  # [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				:       int 	=						42  # [num_res, num_atom_type]

						# Residue index as used in PDB. It is not necessarily continuous or 0-indexed.
						UpperCAmelCase				:       List[str] 	=						42  # [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				:       Union[str, Any] 	=						42  # [num_res, num_atom_type]

						# Chain indices for multi-chain predictions
						UpperCAmelCase				:       List[Any] 	=						None

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

						# Templates used to generate this protein (prediction-only)
						UpperCAmelCase				:       List[str] 	=						None

						# Chain corresponding to each parent
						UpperCAmelCase				:       Any 	=						None







def 						_snake_case						(   _SCREAMING_SNAKE_CASE	:		Tuple				)     ->		Tuple:







	"""simple docstring"""
	lowerCAmelCase       =      R"""(\[[A-Z]+\]\n)"""
	lowerCAmelCase       =      [tag.strip() for tag in re.split(A_				,						A_				) if len(A_				) > 0]
	lowerCAmelCase       =      zip(tags[0::2]				,						[l.split("""\n"""				) for l in tags[1::2]]				)

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

	assert aatype is not None

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






def 						_snake_case						(   _SCREAMING_SNAKE_CASE	:		int				,						_SCREAMING_SNAKE_CASE	:		Optional[Any] = 0				)     ->		Dict:







	"""simple docstring"""
	lowerCAmelCase       =      []

	lowerCAmelCase       =      prot.remark
	if remark is not None:
		pdb_headers.append(f'REMARK {remark}'				)

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

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

	pdb_headers.append(f'PARENT {" ".join(A_				)}'				)

	return pdb_headers






def 						_snake_case						(   _SCREAMING_SNAKE_CASE	:		List[Any]				,						_SCREAMING_SNAKE_CASE	:		Union[str, Any]				)     ->		str:







	"""simple docstring"""
	lowerCAmelCase       =      []
	lowerCAmelCase       =      pdb_str.split("""\n"""				)

	lowerCAmelCase       =      prot.remark
	if remark is not None:
		out_pdb_lines.append(f'REMARK {remark}'				)

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

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

	def make_parent_line(_SCREAMING_SNAKE_CASE	:		List[str]				) -> str:
		return f'PARENT {" ".join(A_				)}'

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

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

			out_pdb_lines.append(make_parent_line(A_				)				)

	return "\n".join(A_				)






def 						_snake_case						(   _SCREAMING_SNAKE_CASE	:		Optional[int]				)     ->		Optional[Any]:







	"""simple docstring"""
	lowerCAmelCase       =      residue_constants.restypes + ["""X"""]

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

	lowerCAmelCase       =      residue_constants.atom_types

	lowerCAmelCase       =      []

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

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

	lowerCAmelCase       =      get_pdb_headers(A_				)
	if len(A_				) > 0:
		pdb_lines.extend(A_				)

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

			lowerCAmelCase       =      """ATOM"""
			lowerCAmelCase       =      atom_name if len(A_				) == 4 else f' {atom_name}'
			lowerCAmelCase       =      """"""
			lowerCAmelCase       =      """"""
			lowerCAmelCase       =      1.00
			lowerCAmelCase       =      atom_name[0]  # Protein supports only C, N, O, S, this works.
			lowerCAmelCase       =      """"""

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

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

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

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

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






def 						_snake_case						(   _SCREAMING_SNAKE_CASE	:		Optional[Any]				)     ->		List[Any]:







	"""simple docstring"""
	return residue_constants.STANDARD_ATOM_MASK[prot.aatype]






def 						_snake_case						(   _SCREAMING_SNAKE_CASE	:		Optional[Any]				,						_SCREAMING_SNAKE_CASE	:		List[str]				,						_SCREAMING_SNAKE_CASE	:		Tuple = None				,						_SCREAMING_SNAKE_CASE	:		List[Any] = None				,						_SCREAMING_SNAKE_CASE	:		List[str] = None				,						_SCREAMING_SNAKE_CASE	:		Optional[Any] = None				,						_SCREAMING_SNAKE_CASE	:		List[Any] = None				,						)     ->		Tuple:







	"""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=A_				,						remark=A_				,						parents=A_				,						parents_chain_index=A_				,						)

import flax.linen as nn
import jax.numpy as jnp

from .attention_flax import FlaxTransformeraDModel
from .resnet_flax import FlaxDownsampleaD, FlaxResnetBlockaD, FlaxUpsampleaD




class 			UpperCAmelCase_     (					nn.Module	):


  '''simple docstring'''







  a__       			=						42
  a__       			=						42
  a__       			=						0.0
  a__       			=						1
  a__       			=						1
  a__       			=						True
  a__       			=						False
  a__       			=						False
  a__       			=						False
  a__       			=						jnp.floataa
  def 				_lowercase				(					self     :					Optional[Any]       )     ->      Tuple:







    """simple docstring"""






    __magic_name__								=			[]
    __magic_name__								=			[]

    for i in range(self.num_layers       ):
      __magic_name__								=			self.in_channels if i == 0 else self.out_channels

      __magic_name__								=			FlaxResnetBlockaD(
          in_channels=UpperCamelCase__     ,				out_channels=self.out_channels     ,				dropout_prob=self.dropout     ,				dtype=self.dtype     ,				)
      resnets.append(UpperCamelCase__       )

      __magic_name__								=			FlaxTransformeraDModel(
          in_channels=self.out_channels     ,				n_heads=self.num_attention_heads     ,				d_head=self.out_channels // self.num_attention_heads     ,				depth=1     ,				use_linear_projection=self.use_linear_projection     ,				only_cross_attention=self.only_cross_attention     ,				use_memory_efficient_attention=self.use_memory_efficient_attention     ,				dtype=self.dtype     ,				)
      attentions.append(UpperCamelCase__       )

    __magic_name__								=			resnets
    __magic_name__								=			attentions

    if self.add_downsample:
      __magic_name__								=			FlaxDownsampleaD(self.out_channels     ,				dtype=self.dtype       )





  def __call__(					self     :					List[Any]     ,				UpperCamelCase__     :					Optional[int]     ,				UpperCamelCase__     :					Tuple     ,				UpperCamelCase__     :					Dict     ,				UpperCamelCase__     :					Optional[int]=True       )     ->      Any:







    """simple docstring"""






    __magic_name__								=			()

    for resnet, attn in zip(self.resnets     ,				self.attentions       ):
      __magic_name__								=			resnet(UpperCamelCase__     ,				UpperCamelCase__     ,				deterministic=UpperCamelCase__       )
      __magic_name__								=			attn(UpperCamelCase__     ,				UpperCamelCase__     ,				deterministic=UpperCamelCase__       )
      output_states += (hidden_states,)

    if self.add_downsample:
      __magic_name__								=			self.downsamplers_a(UpperCamelCase__       )
      output_states += (hidden_states,)

    return hidden_states, output_states







class 			UpperCAmelCase_     (					nn.Module	):


  '''simple docstring'''







  a__       			=						42
  a__       			=						42
  a__       			=						0.0
  a__       			=						1
  a__       			=						True
  a__       			=						jnp.floataa
  def 				_lowercase				(					self     :					str       )     ->      Optional[Any]:







    """simple docstring"""






    __magic_name__								=			[]

    for i in range(self.num_layers       ):
      __magic_name__								=			self.in_channels if i == 0 else self.out_channels

      __magic_name__								=			FlaxResnetBlockaD(
          in_channels=UpperCamelCase__     ,				out_channels=self.out_channels     ,				dropout_prob=self.dropout     ,				dtype=self.dtype     ,				)
      resnets.append(UpperCamelCase__       )
    __magic_name__								=			resnets

    if self.add_downsample:
      __magic_name__								=			FlaxDownsampleaD(self.out_channels     ,				dtype=self.dtype       )





  def __call__(					self     :					str     ,				UpperCamelCase__     :					Tuple     ,				UpperCamelCase__     :					Union[str, Any]     ,				UpperCamelCase__     :					int=True       )     ->      Dict:







    """simple docstring"""






    __magic_name__								=			()

    for resnet in self.resnets:
      __magic_name__								=			resnet(UpperCamelCase__     ,				UpperCamelCase__     ,				deterministic=UpperCamelCase__       )
      output_states += (hidden_states,)

    if self.add_downsample:
      __magic_name__								=			self.downsamplers_a(UpperCamelCase__       )
      output_states += (hidden_states,)

    return hidden_states, output_states







class 			UpperCAmelCase_     (					nn.Module	):


  '''simple docstring'''







  a__       			=						42
  a__       			=						42
  a__       			=						42
  a__       			=						0.0
  a__       			=						1
  a__       			=						1
  a__       			=						True
  a__       			=						False
  a__       			=						False
  a__       			=						False
  a__       			=						jnp.floataa
  def 				_lowercase				(					self     :					Optional[Any]       )     ->      Any:







    """simple docstring"""






    __magic_name__								=			[]
    __magic_name__								=			[]

    for i in range(self.num_layers       ):
      __magic_name__								=			self.in_channels if (i == self.num_layers - 1) else self.out_channels
      __magic_name__								=			self.prev_output_channel if i == 0 else self.out_channels

      __magic_name__								=			FlaxResnetBlockaD(
          in_channels=resnet_in_channels + res_skip_channels     ,				out_channels=self.out_channels     ,				dropout_prob=self.dropout     ,				dtype=self.dtype     ,				)
      resnets.append(UpperCamelCase__       )

      __magic_name__								=			FlaxTransformeraDModel(
          in_channels=self.out_channels     ,				n_heads=self.num_attention_heads     ,				d_head=self.out_channels // self.num_attention_heads     ,				depth=1     ,				use_linear_projection=self.use_linear_projection     ,				only_cross_attention=self.only_cross_attention     ,				use_memory_efficient_attention=self.use_memory_efficient_attention     ,				dtype=self.dtype     ,				)
      attentions.append(UpperCamelCase__       )

    __magic_name__								=			resnets
    __magic_name__								=			attentions

    if self.add_upsample:
      __magic_name__								=			FlaxUpsampleaD(self.out_channels     ,				dtype=self.dtype       )





  def __call__(					self     :					Optional[int]     ,				UpperCamelCase__     :					Any     ,				UpperCamelCase__     :					Dict     ,				UpperCamelCase__     :					Optional[int]     ,				UpperCamelCase__     :					Optional[Any]     ,				UpperCamelCase__     :					Dict=True       )     ->      Union[str, Any]:







    """simple docstring"""






    for resnet, attn in zip(self.resnets     ,				self.attentions       ):
      # pop res hidden states
      __magic_name__								=			res_hidden_states_tuple[-1]
      __magic_name__								=			res_hidden_states_tuple[:-1]
      __magic_name__								=			jnp.concatenate((hidden_states, res_hidden_states)     ,				axis=-1       )

      __magic_name__								=			resnet(UpperCamelCase__     ,				UpperCamelCase__     ,				deterministic=UpperCamelCase__       )
      __magic_name__								=			attn(UpperCamelCase__     ,				UpperCamelCase__     ,				deterministic=UpperCamelCase__       )

    if self.add_upsample:
      __magic_name__								=			self.upsamplers_a(UpperCamelCase__       )

    return hidden_states







class 			UpperCAmelCase_     (					nn.Module	):


  '''simple docstring'''







  a__       			=						42
  a__       			=						42
  a__       			=						42
  a__       			=						0.0
  a__       			=						1
  a__       			=						True
  a__       			=						jnp.floataa
  def 				_lowercase				(					self     :					List[Any]       )     ->      str:







    """simple docstring"""






    __magic_name__								=			[]

    for i in range(self.num_layers       ):
      __magic_name__								=			self.in_channels if (i == self.num_layers - 1) else self.out_channels
      __magic_name__								=			self.prev_output_channel if i == 0 else self.out_channels

      __magic_name__								=			FlaxResnetBlockaD(
          in_channels=resnet_in_channels + res_skip_channels     ,				out_channels=self.out_channels     ,				dropout_prob=self.dropout     ,				dtype=self.dtype     ,				)
      resnets.append(UpperCamelCase__       )

    __magic_name__								=			resnets

    if self.add_upsample:
      __magic_name__								=			FlaxUpsampleaD(self.out_channels     ,				dtype=self.dtype       )





  def __call__(					self     :					List[Any]     ,				UpperCamelCase__     :					str     ,				UpperCamelCase__     :					Union[str, Any]     ,				UpperCamelCase__     :					Optional[Any]     ,				UpperCamelCase__     :					str=True       )     ->      Dict:







    """simple docstring"""






    for resnet in self.resnets:
      # pop res hidden states
      __magic_name__								=			res_hidden_states_tuple[-1]
      __magic_name__								=			res_hidden_states_tuple[:-1]
      __magic_name__								=			jnp.concatenate((hidden_states, res_hidden_states)     ,				axis=-1       )

      __magic_name__								=			resnet(UpperCamelCase__     ,				UpperCamelCase__     ,				deterministic=UpperCamelCase__       )

    if self.add_upsample:
      __magic_name__								=			self.upsamplers_a(UpperCamelCase__       )

    return hidden_states







class 			UpperCAmelCase_     (					nn.Module	):


  '''simple docstring'''







  a__       			=						42
  a__       			=						0.0
  a__       			=						1
  a__       			=						1
  a__       			=						False
  a__       			=						False
  a__       			=						jnp.floataa
  def 				_lowercase				(					self     :					List[Any]       )     ->      Optional[Any]:







    """simple docstring"""






    __magic_name__								=			[
        FlaxResnetBlockaD(
            in_channels=self.in_channels     ,				out_channels=self.in_channels     ,				dropout_prob=self.dropout     ,				dtype=self.dtype     ,				)
    ]

    __magic_name__								=			[]

    for _ in range(self.num_layers       ):
      __magic_name__								=			FlaxTransformeraDModel(
          in_channels=self.in_channels     ,				n_heads=self.num_attention_heads     ,				d_head=self.in_channels // self.num_attention_heads     ,				depth=1     ,				use_linear_projection=self.use_linear_projection     ,				use_memory_efficient_attention=self.use_memory_efficient_attention     ,				dtype=self.dtype     ,				)
      attentions.append(UpperCamelCase__       )

      __magic_name__								=			FlaxResnetBlockaD(
          in_channels=self.in_channels     ,				out_channels=self.in_channels     ,				dropout_prob=self.dropout     ,				dtype=self.dtype     ,				)
      resnets.append(UpperCamelCase__       )

    __magic_name__								=			resnets
    __magic_name__								=			attentions





  def __call__(					self     :					Optional[int]     ,				UpperCamelCase__     :					Any     ,				UpperCamelCase__     :					Any     ,				UpperCamelCase__     :					List[Any]     ,				UpperCamelCase__     :					int=True       )     ->      str:







    """simple docstring"""






    __magic_name__								=			self.resnets[0](UpperCamelCase__     ,				UpperCamelCase__       )
    for attn, resnet in zip(self.attentions     ,				self.resnets[1:]       ):
      __magic_name__								=			attn(UpperCamelCase__     ,				UpperCamelCase__     ,				deterministic=UpperCamelCase__       )
      __magic_name__								=			resnet(UpperCamelCase__     ,				UpperCamelCase__     ,				deterministic=UpperCamelCase__       )

    return hidden_states

