


"""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__				:							Optional[Any]						=     Mapping[str, np.ndarray]
a__				:							Optional[Any]						=     Mapping[str, Any]  # Is a nested dict.
a__				:							Optional[int]						=     0.01




@dataclasses.dataclass(frozen=UpperCamelCase)
class  UpperCamelCase_	:

	"""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    UpperCAmelCase__       (lowerCAmelCase_   ):




					'''simple docstring'''


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

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




					'''simple docstring'''


					__SCREAMING_SNAKE_CASE						   =				[]

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

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

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

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

					return pdb_headers




def    UpperCAmelCase__       (lowerCAmelCase_  ,						lowerCAmelCase_   ):




					'''simple docstring'''


					__SCREAMING_SNAKE_CASE						   =				[]
					__SCREAMING_SNAKE_CASE						   =				pdb_str.split("\n"   )

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

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

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

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

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

					__SCREAMING_SNAKE_CASE						   =				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_   ):
																				__SCREAMING_SNAKE_CASE						   =				parents_per_chain[chain_counter]
															else:
																				__SCREAMING_SNAKE_CASE						   =				["N/A"]

															out_pdb_lines.append(make_parent_line(lowerCAmelCase_   )   )

					return "\n".join(lowerCAmelCase_   )




def    UpperCAmelCase__       (lowerCAmelCase_   ):




					'''simple docstring'''


					__SCREAMING_SNAKE_CASE						   =				residue_constants.restypes + ["X"]

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

					__SCREAMING_SNAKE_CASE						   =				residue_constants.atom_types

					__SCREAMING_SNAKE_CASE						   =				[]

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

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

					__SCREAMING_SNAKE_CASE						   =				get_pdb_headers(lowerCAmelCase_   )
					if len(lowerCAmelCase_   ) > 0:
										pdb_lines.extend(lowerCAmelCase_   )

					__SCREAMING_SNAKE_CASE						   =				aatype.shape[0]
					__SCREAMING_SNAKE_CASE						   =				1
					__SCREAMING_SNAKE_CASE						   =				0
					__SCREAMING_SNAKE_CASE						   =				string.ascii_uppercase
					__SCREAMING_SNAKE_CASE						   =				None
					# Add all atom sites.
					for i in range(lowerCAmelCase_   ):
										__SCREAMING_SNAKE_CASE						   =				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

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

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

															# PDB is a columnar format, every space matters here!
															__SCREAMING_SNAKE_CASE						   =				(
															    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

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

										if should_terminate:
															# Close the chain.
															__SCREAMING_SNAKE_CASE						   =				"TER"
															__SCREAMING_SNAKE_CASE						   =				(
															    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__       (lowerCAmelCase_   ):




					'''simple docstring'''


					return residue_constants.STANDARD_ATOM_MASK[prot.aatype]




def    UpperCAmelCase__       (lowerCAmelCase_  ,						lowerCAmelCase_  ,						lowerCAmelCase_ = None  ,						lowerCAmelCase_ = None  ,						lowerCAmelCase_ = None  ,						lowerCAmelCase_ = None  ,						lowerCAmelCase_ = None  ,						):




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

from ...utils import is_sklearn_available, requires_backends


if is_sklearn_available():
		from scipy.stats import pearsonr, spearmanr
		from sklearn.metrics import fa_score, matthews_corrcoef


a__				:							Any						=     (
    '''This metric will be removed from the library soon, metrics should be handled with the 🤗 Evaluate '''
    '''library. You can have a look at this example script for pointers: '''
    '''https://github.com/huggingface/transformers/blob/main/examples/pytorch/text-classification/run_glue.py'''
)




def    UpperCAmelCase__       (lowerCAmelCase_  ,						lowerCAmelCase_   ):




					'''simple docstring'''


					warnings.warn(lowerCAmelCase_  ,						lowerCAmelCase_   )
					requires_backends(lowerCAmelCase_  ,						"sklearn"   )
					return (preds == labels).mean()




def    UpperCAmelCase__       (lowerCAmelCase_  ,						lowerCAmelCase_   ):




					'''simple docstring'''


					warnings.warn(lowerCAmelCase_  ,						lowerCAmelCase_   )
					requires_backends(lowerCAmelCase_  ,						"sklearn"   )
					__SCREAMING_SNAKE_CASE						   =				simple_accuracy(lowerCAmelCase_  ,						lowerCAmelCase_   )
					__SCREAMING_SNAKE_CASE						   =				fa_score(y_true=lowerCAmelCase_  ,						y_pred=lowerCAmelCase_   )
					return {
					    "acc": acc,
					    "f1": fa,
					    "acc_and_f1": (acc + fa) / 2,
					}




def    UpperCAmelCase__       (lowerCAmelCase_  ,						lowerCAmelCase_   ):




					'''simple docstring'''


					warnings.warn(lowerCAmelCase_  ,						lowerCAmelCase_   )
					requires_backends(lowerCAmelCase_  ,						"sklearn"   )
					__SCREAMING_SNAKE_CASE						   =				pearsonr(lowerCAmelCase_  ,						lowerCAmelCase_   )[0]
					__SCREAMING_SNAKE_CASE						   =				spearmanr(lowerCAmelCase_  ,						lowerCAmelCase_   )[0]
					return {
					    "pearson": pearson_corr,
					    "spearmanr": spearman_corr,
					    "corr": (pearson_corr + spearman_corr) / 2,
					}




def    UpperCAmelCase__       (lowerCAmelCase_  ,						lowerCAmelCase_  ,						lowerCAmelCase_   ):




					'''simple docstring'''


					warnings.warn(lowerCAmelCase_  ,						lowerCAmelCase_   )
					requires_backends(lowerCAmelCase_  ,						"sklearn"   )
					assert len(lowerCAmelCase_   ) == len(lowerCAmelCase_   ), f"""Predictions and labels have mismatched lengths {len(lowerCAmelCase_   )} and {len(lowerCAmelCase_   )}"""
					if task_name == "cola":
										return {"mcc": matthews_corrcoef(lowerCAmelCase_  ,						lowerCAmelCase_   )}
					elif task_name == "sst-2":
										return {"acc": simple_accuracy(lowerCAmelCase_  ,						lowerCAmelCase_   )}
					elif task_name == "mrpc":
										return acc_and_fa(lowerCAmelCase_  ,						lowerCAmelCase_   )
					elif task_name == "sts-b":
										return pearson_and_spearman(lowerCAmelCase_  ,						lowerCAmelCase_   )
					elif task_name == "qqp":
										return acc_and_fa(lowerCAmelCase_  ,						lowerCAmelCase_   )
					elif task_name == "mnli":
										return {"mnli/acc": simple_accuracy(lowerCAmelCase_  ,						lowerCAmelCase_   )}
					elif task_name == "mnli-mm":
										return {"mnli-mm/acc": simple_accuracy(lowerCAmelCase_  ,						lowerCAmelCase_   )}
					elif task_name == "qnli":
										return {"acc": simple_accuracy(lowerCAmelCase_  ,						lowerCAmelCase_   )}
					elif task_name == "rte":
										return {"acc": simple_accuracy(lowerCAmelCase_  ,						lowerCAmelCase_   )}
					elif task_name == "wnli":
										return {"acc": simple_accuracy(lowerCAmelCase_  ,						lowerCAmelCase_   )}
					elif task_name == "hans":
										return {"acc": simple_accuracy(lowerCAmelCase_  ,						lowerCAmelCase_   )}
					else:
										raise KeyError(lowerCAmelCase_   )




def    UpperCAmelCase__       (lowerCAmelCase_  ,						lowerCAmelCase_  ,						lowerCAmelCase_   ):




					'''simple docstring'''


					warnings.warn(lowerCAmelCase_  ,						lowerCAmelCase_   )
					requires_backends(lowerCAmelCase_  ,						"sklearn"   )
					if len(lowerCAmelCase_   ) != len(lowerCAmelCase_   ):
										raise ValueError(f"""Predictions and labels have mismatched lengths {len(lowerCAmelCase_   )} and {len(lowerCAmelCase_   )}"""   )
					if task_name == "xnli":
										return {"acc": simple_accuracy(lowerCAmelCase_  ,						lowerCAmelCase_   )}
					else:
										raise KeyError(lowerCAmelCase_   )
