# Source code for MDAnalysis.guesser.tables

    # -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*-
    # vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
    #
    # MDAnalysis --- https://www.mdanalysis.org
    # Copyright (c) 2006-2017 The MDAnalysis Development Team and contributors
    # (see the file AUTHORS for the full list of names)
    #
    # Released under the Lesser GNU Public Licence, v2.1 or any higher version
    #
    # Please cite your use of MDAnalysis in published work:
    #
    # R. J. Gowers, M. Linke, J. Barnoud, T. J. E. Reddy, M. N. Melo, S. L. Seyler,
    # D. L. Dotson, J. Domanski, S. Buchoux, I. M. Kenney, and O. Beckstein.
    # MDAnalysis: A Python package for the rapid analysis of molecular dynamics
    # simulations. In S. Benthall and S. Rostrup editors, Proceedings of the 15th
    # Python in Science Conference, pages 102-109, Austin, TX, 2016. SciPy.
    # doi: 10.25080/majora-629e541a-00e
    #
    # N. Michaud-Agrawal, E. J. Denning, T. B. Woolf, and O. Beckstein.
    # MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations.
    # J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787
    #

    """
    MDAnalysis topology tables
    ==========================

    The module contains static lookup tables for atom typing etc. The
    tables are dictionaries that are indexed by the element.

    .. autodata:: atomelements
    .. autodata:: masses
    .. autodata:: vdwradii

    The original raw data are stored as multi-line strings that are
    translated into dictionaries with :func:`kv2dict`. In the future,
    these tables might be moved into external data files; see
    :func:`kv2dict` for explanation of the file format.

    .. autofunction:: kv2dict

    The raw tables are stored in the strings

    .. autodata:: TABLE_ATOMELEMENTS
    .. autodata:: TABLE_MASSES
    .. autodata:: TABLE_VDWRADII
    """

    from typing import Any

    def kv2dict(s, convertor: Any = str):
        """Primitive ad-hoc parser of a key-value record list.

        * The string *s* should contain each key-value pair on a separate
          line (separated by newline). The first white space after the key
          separates key and value.

        * Empty lines are allowed.

        * Comment lines (starting with #) are allowed.

        * Leading whitespace is ignored.

        The *convertor* is a function that converts its single argument to
        a valid Python type. The default is :func:`str` but other
        possibilities are :func:`int` (for integers) or :func:`float` for
        floating point numbers.
        """
        d = {}
        lines = s.splitlines()
        for line in lines:
            line = line.lstrip()
            values = line.split(None, 1)
            if len(values) == 0 or line.startswith("#"):
                continue
            d[values[0]] = convertor(values[1])
        return d

    #: Table with hard-coded special atom names, used for guessing atom types
    #: with :func:`MDAnalysis.topology.core.guess_atom_element`.
    TABLE_ATOMELEMENTS = """
    # translation of atomnames to types/element
    # based on CHARMM and AMBER usage with a little bit of GROMOS (and PROPKA)
    # NOTE: CL might be ambiguous and is interpreted as chloride!

    # --------- ------------------
    # atomname   element
    # --------- ------------------

    # Bromide
    BR           BR

    # Calcium
    CAL          CA
    C0           CA
    CA2+         CA

    # Cesium
    CES          CS

    # Chloride
    CLA          CL
    CLAL         CL
    CL           CL
    CL-          CL

    # Iodide
    IOD          I

    # Iron
    FE           FE
    FE2          FE

    # Lithium
    LIT          LI
    LI           LI
    LI+          LI
    QL           LI

    # Magnesium
    MG           MG
    MG2+         MG

    # Noble gases
    ## XXX collides with NE, HE in Arg  XXX
    ## XXX so we remove the noble gases XXX
    ##HE           HE
    ##NE           NE

    # Potassium
    K            K
    POT          K
    K+           K
    QK           K

    # Sodium
    SOD          NA
    NA           NA
    NA+          NA
    QN           NA

    # Zink
    ZN           ZN

    # Copper
    CU           CU

    # Cesium
    CS           CS
    CS+          CS
    CES          CS

    # Cerium??
    QC           CE

    # Rubidium
    RB           RB
    QR           RB

    # special carbons (Amber?)
    BC           C
    AC           C

    # dummy atom types
    MW           DUMMY

    # other types are guessed from the name; see
    # topology.core.guess_atom_elements()
    """

    #: Dictionary with hard-coded special atom names, used for guessing atom types
    #: with :func:`MDAnalysis.topology.core.guess_atom_type`.
    atomelements = kv2dict(TABLE_ATOMELEMENTS)

    # fmt: off
    elements = ['H',
                'LI', 'BE', 'B', 'C', 'N', 'O', 'F',
                'NA', 'MG', 'AL', 'P', 'SI', 'S', 'CL',
                'K']
    # fmt: on

    #: Plain-text table with atomic masses in u.
    TABLE_MASSES = """
    # masses for elements in atomic units (u)
    # (taken from CHARMM and Gromacs atommass.dat)

    #------------ -----------
    # atomtype    mass
    #------------ -----------
    Ac    227.028
    Al    26.981539
    Am    243
    Sb    121.757
    Ar    39.948
    As    74.92159
    At    210
    Ba    137.327
    Bk    247
    Be    9.012182
    Bi    208.98037
    Bh    264
    B     10.811
    BR    79.90400
    Cd    112.411
    CA    40.08000
    Cf    251
    C     12.01100
    Ce    140.11600
    CS    132.90000
    CL    35.45000
    Cr    51.9961
    Co    58.9332
    CU    63.54600
    Cm    247
    Db    262
    Dy    162.5
    Es    252
    Er    167.26
    Eu    151.965
    Fm    257
    F     18.99800
    Fr    223
    Gd    157.25
    Ga    69.723
    Ge    72.61
    Au    196.96654
    Hf    178.49
    Hs    265
    HE    4.00260
    Ho    164.93032
    H     1.00800
    In    114.82
    I     126.90450
    Ir    192.22
    FE    55.84700
    Kr    83.8
    La    138.9055
    Lr    262
    Pb    207.2
    Li    6.941
    Lu    174.967
    MG    24.30500
    Mn    54.93805
    Mt    266
    Md    258
    Hg    200.59
    Mo    95.94
    N     14.00700
    NA    22.98977
    Nd    144.24
    NE    20.17970
    Np    237.048
    Ni    58.6934
    Nb    92.90638
    No    259
    Os    190.2
    O     15.99900
    Pd    106.42
    P     30.97400
    Pt    195.08
    Pu    244
    Po    209
    K     39.10200
    Pr    140.90765
    Pm    145
    Pa    231.0359
    Ra    226.025
    Rn    222
    Re    186.207
    Rh    102.9055
    RB    85.46780
    Ru    101.07
    Rf    261
    Sm    150.36
    Sc    44.95591
    Sg    263
    Se    78.96
    Si    28.0855
    Ag    107.8682
    Na    22.989768
    Sr    87.62
    S     32.06000
    Ta    180.9479
    Tc    98
    Te    127.6
    Tb    158.92534
    Tl    204.3833
    Th    232.0381
    Tm    168.93421
    Sn    118.71
    Ti    47.88
    W     183.85
    U     238.0289
    V     50.9415
    Xe    131.29
    Yb    173.04
    Y     88.90585
    ZN    65.37000
    Zr    91.224
    DUMMY 0.0
    """

    #: Dictionary table with atomic masses in u, indexed by the element from
    #: :data:`atomelements`.
    masses = kv2dict(TABLE_MASSES, convertor=float)

    #: Plain-text table with vdw radii.
    TABLE_VDWRADII = r"""
    # Van der Waals radii taken from
    # [1] Bondi, A. (1964). "Van der Waals Volumes and Radii".
    #     J. Phys. Chem. 68 (3): 441-451. doi:10.1021/j100785a001.
    # [2] Rowland and Taylor (1996). "Intermolecular Nonbonded Contact Distances in Organic Crystal Structures:
    #                                 Comparison with Distances Expected from van der Waals Radii".
    #     J. Phys. Chem., 1996, 100 (18), 7384.7391. doi:10.1021/jp953141+.
    # [3] Mantina, et al. (2009). "Consistent van der Waals Radii for the Whole Main Group".
    #     J. Phys. Chem. A, 2009, 113 (19), 5806-5812. doi:10.1021/jp8111556.
    #------------ -----------
    # atomtype    r_vdw
    #------------ -----------
    H    1.10
    HE   1.40
    LI   1.82
    BE   1.53
    B    1.92
    C    1.70
    N    1.55
    O    1.52
    F    1.47
    NE   1.54
    NA   2.27
    MG   1.73
    AL   1.84
    SI   2.10
    P    1.80
    S    1.80
    CL   1.75
    AR   1.88
    K    2.75
    CA   2.31
    NI   1.63
    CU   1.40
    ZN   1.39
    GA   1.87
    GE   2.11
    AA   1.85
    SE   1.90
    BR   1.85
    KR   2.02
    RR   3.03
    SR   2.49
    PD   1.63
    AG   1.72
    CD   1.58
    IN   1.93
    SN   2.17
    SB   2.06
    TE   2.06
    I    1.98
    XE   2.16
    CS   3.43
    BA   2.68
    PT   1.75
    AU   1.66
    HH   1.55
    TL   1.96
    PB   2.02
    BI   2.07
    PO   1.97
    AT   2.02
    RN   2.20
    FR   3.48
    RA   2.83
    U    1.86
    """

    #: Dictionary table with vdw radii, indexed by the element from
    #: :data:`atomelements`.
    #: .. SeeAlso:: :func:`MDAnalysis.topology.core.guess_bonds`
    vdwradii = kv2dict(TABLE_VDWRADII, convertor=float)

    # fmt: off
    Z2SYMB = {1: 'H',                                                                2: 'He',
              3: 'Li',   4: 'Be',  5: 'B',   6: 'C',   7: 'N',   8: 'O',   9: 'F',  10: 'Ne',
              11: 'Na', 12: 'Mg', 13: 'Al', 14: 'Si', 15: 'P',  16: 'S',  17: 'Cl', 18: 'Ar',
              19: 'K',  20: 'Ca', 21: 'Sc', 22: 'Ti', 23: 'V',  24: 'Cr', 25: 'Mn', 26: 'Fe',
              27: 'Co', 28: 'Ni', 29: 'Cu', 30: 'Zn', 31: 'Ga', 32: 'Ge', 33: 'As', 34: 'Se',
              35: 'Br', 36: 'Kr', 37: 'Rb', 38: 'Sr', 39: 'Y',  40: 'Zr', 41: 'Nb', 42: 'Mo',
              43: 'Tc', 44: 'Ru', 45: 'Rh', 46: 'Pd', 47: 'Ag', 48: 'Cd', 49: 'In', 50: 'Sn',
              51: 'Sb', 52: 'Te', 53: 'I',  54: 'Xe', 55: 'Cs', 56: 'Ba', 57: 'La', 58: 'Ce',
              59: 'Pr', 60: 'Nd', 61: 'Pm', 62: 'Sm', 63: 'Eu', 64: 'Gd', 65: 'Tb', 66: 'Dy',
              67: 'Ho', 68: 'Er', 69: 'Tm', 70: 'Yb', 71: 'Lu', 72: 'Hf', 73: 'Ta', 74: 'W',
              75: 'Re', 76: 'Os', 77: 'Ir', 78: 'Pt', 79: 'Au', 80: 'Hg', 81: 'Tl', 82: 'Pb',
              83: 'Bi', 84: 'Po', 85: 'At', 86: 'Rn', 87: 'Fr', 88: 'Ra', 89: 'Ac', 90: 'Th',
              91: 'Pa', 92: 'U',  93: 'Np', 94: 'Pu', 95: 'Am', 96: 'Cm', 97: 'Bk', 98: 'Cf',
              99: 'Es', 100: 'Fm', 101: 'Md', 102: 'No', 103: 'Lr', 104: 'Rf', 105: 'Db',
              106: 'Sg', 107: 'Bh', 108: 'Hs', 109: 'Mt', 110: 'Ds', 111: 'Rg', 112: 'Cn',
              113: 'Nh', 114: 'Fl', 115: 'Mc', 116: 'Lv', 117: 'Ts', 118: 'Og'}
    # fmt: on

    SYMB2Z = {v: k for k, v in Z2SYMB.items()}

    # Conversion between SYBYL atom types and corresponding elements
    # Tripos MOL2 file format:
    #   https://web.archive.org/web/*/http://chemyang.ccnu.edu.cn/ccb/server/AIMMS/mol2.pdf
    # fmt: off
    SYBYL2SYMB = {
        "H": "H", "H.spc": "H", "H.t3p": "H",
        "C.3": "C", "C.2": "C", "C.1": "C", "C.ar": "C", "C.cat": "C",
        "N.3": "N", "N.2": "N", "N.1": "N", "N.ar": "N",
        "N.am": "N", "N.pl3": "N", "N.4": "N",
        "O.3": "O", "O.2": "O", "O.co2": "O", "O.spc": "O", "O.t3p": "O",
        "S.3": "S", "S.2": "S", "S.O": "S", "S.O2": "S",
        "S.o": "S", "S.o2": "S",  # Non-standard but often found in the wild...
        "P.3": "P",
        "F": "F",
        "Li": "Li",
        "Na": "Na",
        "Mg": "Mg",
        "Al": "Al",
        "Si": "Si",
        "K": "K",
        "Ca": "Ca",
        "Cr.th": "Cr",
        "Cr.oh": "Cr",
        "Mn": "Mn",
        "Fe": "Fe",
        "Co.oh": "Co",
        "Cu": "Cu",
        "Cl": "Cl",
        "Br": "Br",
        "I": "I",
        "Zn": "Zn",
        "Se": "Se",
        "Mo": "Mo",
        "Sn": "Sn",
    }
    # fmt: on