




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






@dataclasses.dataclass(frozen=_a					)
class       SCREAMING_SNAKE_CASE__					:
						_a    						=						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'.
						_a    						=						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.
						_a    						=						42  # [num_res, num_atom_type]

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

						# Chain indices for multi-chain predictions
						_a    						=						None

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

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

						# Chain corresponding to each parent
						_a    						=						None





def 							lowercase					(snake_case__   : str )     ->  Protein:


				'''simple docstring'''






				lowerCAmelCase  =				R"""(\[[A-Z]+\]\n)"""
				lowerCAmelCase  =				[tag.strip() for tag in re.split(snake_case__      ,       snake_case__ ) if len(snake_case__ ) > 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(snake_case__ ) ):
																if seq[i] not in residue_constants.restypes:
																				lowerCAmelCase  =				"""X"""  # FIXME: strings are immutable
												lowerCAmelCase  =				np.array(
												    [residue_constants.restype_order.get(snake_case__      ,       residue_constants.restype_num ) for res_symbol in seq] )
								elif "[TERTIARY]" == g[0]:
												lowerCAmelCase  =				[]
												for axis in range(3 ):
																tertiary.append(list(map(snake_case__      ,       g[1][axis].split() ) ) )
												lowerCAmelCase  =				np.array(snake_case__ )
												lowerCAmelCase  =				np.zeros((len(tertiary[0] ) // 3, residue_constants.atom_type_num, 3) ).astype(np.floataa )
												for i, atom in enumerate(snake_case__ ):
																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(snake_case__ ),
												        residue_constants.atom_type_num,
												    ) ).astype(np.floataa )
												for i, atom in enumerate(snake_case__ ):
																lowerCAmelCase  =				1
												atom_mask *= mask[..., None]

				assert aatype is not None

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





def 							lowercase					(snake_case__   : Protein      ,       snake_case__   : int = 0 )     ->  List[str]:


				'''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(snake_case__      ,       snake_case__ ) if i == chain_id]

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

				pdb_headers.append(f'''PARENT {' '.join(snake_case__ )}''' )

				return pdb_headers





def 							lowercase					(snake_case__   : Protein      ,       snake_case__   : str )     ->  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(snake_case__ )      ,       [] )
																parent_dict[str(snake_case__ )].append(snake_case__ )

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

				def make_parent_line(snake_case__   : Sequence[str] ) -> str:
								return f'''PARENT {' '.join(snake_case__ )}'''

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

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

												out_pdb_lines.append(make_parent_line(snake_case__ ) )

				return "\n".join(snake_case__ )





def 							lowercase					(snake_case__   : Protein )     ->  str:


				'''simple docstring'''






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

				def res_atoa(snake_case__   : int ) -> 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(snake_case__ )
				if len(snake_case__ ) > 0:
								pdb_lines.extend(snake_case__ )

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

												lowerCAmelCase  =				"""ATOM"""
												lowerCAmelCase  =				atom_name if len(snake_case__ ) == 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(snake_case__ )
												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(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(snake_case__      ,       snake_case__ ) )

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





def 							lowercase					(snake_case__   : Protein )     ->  np.ndarray:


				'''simple docstring'''






				return residue_constants.STANDARD_ATOM_MASK[prot.aatype]






def 							lowercase					(snake_case__   : FeatureDict      ,       snake_case__   : ModelOutput      ,       snake_case__   : Optional[np.ndarray] = None      ,       snake_case__   : Optional[np.ndarray] = None      ,       snake_case__   : Optional[str] = None      ,       snake_case__   : Optional[Sequence[str]] = None      ,       snake_case__   : Optional[Sequence[int]] = 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=snake_case__      ,       remark=snake_case__      ,       parents=snake_case__      ,       parents_chain_index=snake_case__      ,       )











"""simple docstring"""







import argparse
import json

import numpy
import torch

from transformers.models.xlm.tokenization_xlm import VOCAB_FILES_NAMES
from transformers.utils import CONFIG_NAME, WEIGHTS_NAME, logging


logging.set_verbosity_info()





def 							lowercase					(snake_case__   : int      ,       snake_case__   : Union[str, Any] )     ->  List[Any]:


				'''simple docstring'''






				lowerCAmelCase  =				torch.load(snake_case__      ,       map_location="""cpu""" )

				lowerCAmelCase  =				chkpt["""model"""]

				# We have the base model one level deeper than the original XLM repository
				lowerCAmelCase  =				{}
				for k, v in state_dict.items():
								if "pred_layer" in k:
												lowerCAmelCase  =				v
								else:
												lowerCAmelCase  =				v

				lowerCAmelCase  =				chkpt["""params"""]
				lowerCAmelCase  =				{n: v for n, v in config.items() if not isinstance(snake_case__      ,       (torch.FloatTensor, numpy.ndarray) )}

				lowerCAmelCase  =				chkpt["""dico_word2id"""]
				lowerCAmelCase  =				{s + """</w>""" if s.find("""@@""" ) == -1 and i > 13 else s.replace("""@@"""      ,       """""" ): i for s, i in vocab.items()}

				# Save pytorch-model
				lowerCAmelCase  =				pytorch_dump_folder_path + """/""" + WEIGHTS_NAME
				lowerCAmelCase  =				pytorch_dump_folder_path + """/""" + CONFIG_NAME
				lowerCAmelCase  =				pytorch_dump_folder_path + """/""" + VOCAB_FILES_NAMES["""vocab_file"""]

				print(f'''Save PyTorch model to {pytorch_weights_dump_path}''' )
				torch.save(snake_case__      ,       snake_case__ )

				print(f'''Save configuration file to {pytorch_config_dump_path}''' )
				with open(snake_case__      ,       """w"""      ,       encoding="""utf-8""" ) as f:
								f.write(json.dumps(snake_case__      ,       indent=2 ) + """\n""" )

				print(f'''Save vocab file to {pytorch_config_dump_path}''' )
				with open(snake_case__      ,       """w"""      ,       encoding="""utf-8""" ) as f:
								f.write(json.dumps(snake_case__      ,       indent=2 ) + """\n""" )


if __name__ == "__main__":
		a      =							argparse.ArgumentParser()
		# Required parameters
		parser.add_argument(
		    '--xlm_checkpoint_path', default=None, type=str, required=True, help='Path the official PyTorch dump.'
		)
		parser.add_argument(
		    '--pytorch_dump_folder_path', default=None, type=str, required=True, help='Path to the output PyTorch model.'
		)
		a      =							parser.parse_args()
		convert_xlm_checkpoint_to_pytorch(args.xlm_checkpoint_path, args.pytorch_dump_folder_path)





