



"""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_    					=	Mapping[str, np.ndarray]
snake_case_    					=	Mapping[str, Any]  # Is a nested dict.
snake_case_    					=	0.01







@dataclasses.dataclass(frozen=SCREAMING_SNAKE_CASE_    )
class 				A_      :



						"""simple docstring"""
						__UpperCamelCase		    =							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		    =							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		    =							42  # [num_res, num_atom_type]

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

						# Chain indices for multi-chain predictions
						__UpperCamelCase		    =							None

						# Optional remark about the protein. Included as a comment in output PDB
						# files
						__UpperCamelCase		    =							None

						# Templates used to generate this protein (prediction-only)
						__UpperCamelCase		    =							None

						# Chain corresponding to each parent
						__UpperCamelCase		    =							None


def 			_lowerCAmelCase				(       lowercase_						):
						UpperCAmelCase					=			R'(\[[A-Z]+\]\n)'
						UpperCAmelCase					=			[tag.strip() for tag in re.split(lowercase_		,     lowercase_						) if len(lowercase_						) > 0]
						UpperCAmelCase					=			zip(tags[0::2]		,     [l.split('\n'						) for l in tags[1::2]]						)

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

						assert aatype is not None

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

def 			_lowerCAmelCase				(       lowercase_		,     lowercase_ = 0						):
						UpperCAmelCase					=			[]

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

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

						if parents is None or len(lowercase_						) == 0:
												UpperCAmelCase					=			['N/A']

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

						return pdb_headers

def 			_lowerCAmelCase				(       lowercase_		,     lowercase_						):
						UpperCAmelCase					=			[]
						UpperCAmelCase					=			pdb_str.split('\n'						)

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

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

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

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

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

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

																		out_pdb_lines.append(make_parent_line(lowercase_						)						)

						return "\n".join(lowercase_						)

def 			_lowerCAmelCase				(       lowercase_						):
						UpperCAmelCase					=			residue_constants.restypes + ['X']

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

						UpperCAmelCase					=			residue_constants.atom_types

						UpperCAmelCase					=			[]

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

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

						UpperCAmelCase					=			get_pdb_headers(lowercase_						)
						if len(lowercase_						) > 0:
												pdb_lines.extend(lowercase_						)

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

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

																		UpperCAmelCase					=			'A'
																		if chain_index is not None:
																								UpperCAmelCase					=			chain_tags[chain_index[i]]

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

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

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

						pdb_lines.append('END'						)
						pdb_lines.append(''						)
						return "\n".join(lowercase_						)

def 			_lowerCAmelCase				(       lowercase_						):
						return residue_constants.STANDARD_ATOM_MASK[prot.aatype]






def 			_lowerCAmelCase				(       lowercase_		,     lowercase_		,     lowercase_ = None		,     lowercase_ = None		,     lowercase_ = None		,     lowercase_ = None		,     lowercase_ = 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=lowercase_		,     remark=lowercase_		,     parents=lowercase_		,     parents_chain_index=lowercase_		,     )










"""simple docstring"""


import math

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

def 			_lowerCAmelCase				(       lowercase_		,     lowercase_		,     lowercase_ = 1		,     lowercase_ = 1		,     lowercase_ = 1.0e4		,     lowercase_ = False		,     lowercase_ = 1.0		,     ):
						assert timesteps.ndim == 1, "Timesteps should be a 1d-array"
						assert embedding_dim % 2 == 0, F"""Embedding dimension {embedding_dim} should be even"""
						UpperCAmelCase					=			float(embedding_dim // 2						)
						UpperCAmelCase					=			math.log(max_timescale / min_timescale						) / (num_timescales - freq_shift)
						UpperCAmelCase					=			min_timescale * jnp.exp(jnp.arange(lowercase_		,     dtype=jnp.floataa						) * -log_timescale_increment						)
						UpperCAmelCase					=			jnp.expand_dims(lowercase_		,     1						) * jnp.expand_dims(lowercase_		,     0						)

						# scale embeddings
						UpperCAmelCase					=			scale * emb

						if flip_sin_to_cos:
												UpperCAmelCase					=			jnp.concatenate([jnp.cos(lowercase_						), jnp.sin(lowercase_						)]		,     axis=1						)
						else:
												UpperCAmelCase					=			jnp.concatenate([jnp.sin(lowercase_						), jnp.cos(lowercase_						)]		,     axis=1						)
						UpperCAmelCase					=			jnp.reshape(lowercase_		,     [jnp.shape(lowercase_						)[0], embedding_dim]						)
						return signal







class 				A_      (					nn.Module    ):



						"""simple docstring"""
						__UpperCamelCase		    =							32
						__UpperCamelCase		    =							jnp.floataa






						@nn.compact
						def __call__( self			:Union[str, Any]       ,  lowercase_			:Tuple )    ->      str:
												UpperCAmelCase					=			nn.Dense(self.time_embed_dim       ,  dtype=self.dtype       ,  name='linear_1' )(lowercase_ )
												UpperCAmelCase					=			nn.silu(lowercase_ )
												UpperCAmelCase					=			nn.Dense(self.time_embed_dim       ,  dtype=self.dtype       ,  name='linear_2' )(lowercase_ )
												return temb







class 				A_      (					nn.Module    ):



						"""simple docstring"""
						__UpperCamelCase		    =							32
						__UpperCamelCase		    =							False
						__UpperCamelCase		    =							1






						@nn.compact
						def __call__( self			:Any       ,  lowercase_			:int )    ->      Union[str, Any]:
												return get_sinusoidal_embeddings(
												    lowercase_       ,  embedding_dim=self.dim       ,  flip_sin_to_cos=self.flip_sin_to_cos       ,  freq_shift=self.freq_shift )





