{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"# Imports\n\n# Basic imports\nimport numpy as np\nimport pandas as pd\n\n# Graphs\n# %matplotlib widget\n%matplotlib notebook\nimport matplotlib\nimport matplotlib.pyplot as plt\nfrom matplotlib.lines import Line2D\nimport seaborn as sns\n\nfrom tqdm.auto import tqdm","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"# Seaborn advanced settings\n\nsns.set(style='ticks',          # 'ticks', 'darkgrid'\n        palette='colorblind',   # 'colorblind', 'pastel', 'muted', 'bright'\n        #palette=sns.color_palette('Accent'),   # 'Set1', 'Set2', 'Dark2', 'Accent'\n        rc = {\n           'figure.autolayout': True,\n           'figure.figsize': (14, 8),\n           'legend.frameon': True,\n           'patch.linewidth': 2.0,\n           'lines.markersize': 6,\n           'lines.linewidth': 2.0,\n           'font.size': 20,\n           'legend.fontsize': 20,\n           'axes.labelsize': 16,\n           'axes.titlesize': 22,\n           'axes.grid': True,\n           'grid.color': '0.9',\n           'grid.linestyle': '-',\n           'grid.linewidth': 1.0,\n           'xtick.labelsize': 20,\n           'ytick.labelsize': 20,\n           'xtick.major.size': 8,\n           'ytick.major.size': 8,\n           'xtick.major.pad': 10.0,\n           'ytick.major.pad': 10.0,\n           }\n       )\n\nplt.rcParams['image.cmap'] = 'viridis'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"import sys\n!conda install --yes --prefix {sys.prefix} -c rdkit rdkit","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"%%bash -e\nif ! [[ -f ./xyz2mol.py ]]; then\n  wget https://raw.githubusercontent.com/jensengroup/xyz2mol/master/xyz2mol.py\nfi","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"from rdkit import Chem\nfrom rdkit.Chem import rdMolTransforms\nfrom rdkit.Chem.rdmolops import SanitizeFlags\n\nfrom xyz2mol import xyz2mol, xyz2AC, AC2mol, read_xyz_file\nfrom pathlib import Path","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"CACHEDIR = Path('./')\n\ndef chiral_stereo_check(mol):\n    Chem.SanitizeMol(mol, SanitizeFlags.SANITIZE_ALL - SanitizeFlags.SANITIZE_PROPERTIES)\n    Chem.DetectBondStereochemistry(mol,-1)\n    return mol\n\ndef xyz2mol(atomicNumList,charge,xyz_coordinates,charged_fragments,quick):\n    AC,mol = xyz2AC(atomicNumList,xyz_coordinates)\n    new_mol = AC2mol(mol,AC,atomicNumList,charge,charged_fragments,quick)\n    new_mol = chiral_stereo_check(new_mol)\n    return new_mol\n\ndef MolFromXYZ(filename):\n    charged_fragments = True\n    quick = True\n    try:\n        atomicNumList, charge, xyz_coordinates = read_xyz_file(filename)\n        mol = xyz2mol(atomicNumList, charge, xyz_coordinates, charged_fragments, quick)\n    except:\n        print(filename)\n    return atomicNumList, mol\n\ndef MolFromXYZ_(filename):\n    return filename.stem, MolFromXYZ(filename)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"train_df = pd.read_csv(\"../input/champs-scalar-coupling/train.csv\")\ntest_df = pd.read_csv(\"../input/champs-scalar-coupling/test.csv\")\nstructures = pd.read_csv(\"../input/champs-scalar-coupling/structures.csv\")\ndftr = structures[[\"molecule_name\"]]\ndftr = dftr.drop_duplicates()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"ring_sizes = {3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0}\nring_types = dict()\nring_repetitions = dict()\nmolecules_with_rings = {0:0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0}\nangle_minima = dict()\nangle_maxima = dict()\nangle_means = dict()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"for i, row in tqdm(dftr.iterrows()):\n    path = Path(f'../input/champs-scalar-coupling/structures/{row[\"molecule_name\"]}.xyz')\n    ats, molecule = MolFromXYZ(path)\n    rings = molecule.GetRingInfo().AtomRings()\n    molecules_with_rings[len(rings)] += 1\n    for ring in rings:\n        ring_sizes[len(ring)] += 1\n    ring_list = [\"\" for ring in rings]\n    ring_atom_indices = [[] for ring in rings]\n    ring_atom_indices2 = [[] for ring in rings]\n    for i, ring in enumerate(rings):\n        for atom in ring:\n            ring_list[i] += molecule.GetAtomWithIdx(atom).GetSymbol()\n            ring_atom_indices[i].append(atom)\n            ring_atom_indices2[i].append(molecule.GetAtomWithIdx(atom).GetSymbol())\n    tmp_dict = dict()\n    sorted_ring_list = list()\n    for ring in ring_list:\n        sorted_type = \"\".join(sorted(ring))\n        ring_types.setdefault(sorted_type, 0)\n        ring_types[sorted_type] += 1\n        tmp_dict.setdefault(sorted_type, 0)\n        tmp_dict[sorted_type] += 1\n        sorted_ring_list.append(sorted_type)\n    for key, value in tmp_dict.items():\n        if key in ring_repetitions.keys():\n            if value > ring_repetitions[key]:\n                ring_repetitions[key] = value\n        else:\n            ring_repetitions[key] = value\n    conf = molecule.GetConformer(0)\n    for ring_number, ring in enumerate(rings):\n        current_ring_angles = list()\n        for i in range(-2, len(ring)-2):\n            angle = rdMolTransforms.GetAngleDeg(conf,ring[i],ring[i+1],ring[i+2])\n            current_ring_angles.append(angle)\n        angle_minima.setdefault(sorted_ring_list[ring_number], [])\n        angle_maxima.setdefault(sorted_ring_list[ring_number], [])\n        angle_means.setdefault(sorted_ring_list[ring_number], [])      \n        angle_minima[sorted_ring_list[ring_number]].append(min(current_ring_angles))\n        angle_maxima[sorted_ring_list[ring_number]].append(max(current_ring_angles))\n        angle_means[sorted_ring_list[ring_number]].append(np.mean(current_ring_angles))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Rings in molecules\n\nRings (or cycles) significantly change properties of molecules. Molecules with rings are called aromatic. In cycles, electrons are distributed in a different way then in non-aromatic molecules (without cycles), it is said that they are delocalized, as usually in non-aromatic molecules they are localized around their atom. Also, from my physical perspective, rings are similar to coils which has different surrounding electromagnetic field than e.g. wires. It is very important to add information about rings to ML models if they are to achieve good accuracy, because scalar coupling constant is electronic property of a molecule, which depends on how electrons are distributed in a molecule. As there is no way for us to exactly compute electronic wavefunction (where are electrons with highest probability), then adding information about rings which change electronic wavefunction, is the minimum we can do for ML models."},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"for key, value in molecules_with_rings.items():\n    print(f\"{value} molecules have {key} rings.\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"plt.figure(\"MoleculesWithRings\")\nax = sns.barplot(x=list(molecules_with_rings.keys()), y=list(molecules_with_rings.values()))\nplt.xlabel(\"Number of rings in molecule\")\nplt.ylabel(\"Count of molecules\")\nplt.title(\"Molecules with rings\")\nplt.savefig(\"MoleculesWithRings.png\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"for key, value in ring_sizes.items():\n    print(f\"{value} rings contain {key} atoms.\")","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"plt.figure(\"RingSizes\")\nax = sns.barplot(x=list(ring_sizes.keys()), y=list(ring_sizes.values()))\nplt.xlabel(\"Sizes of rings\")\nplt.ylabel(\"Count of rings\")\nplt.title(\"Ring sizes\")\nplt.savefig(\"RingSizes.png\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Ring types"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"print(f\"There are {len(ring_types.keys())} types of rings.\")","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"print(\"There are:\")\nfor key, value in ring_types.items():\n    print(f\"{value} {key} rings\")","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"ring_types3 = dict()\nring_types4 = dict()\nring_types5 = dict()\nring_types6 = dict()\nring_types7 = dict()\nring_types8 = dict()\nring_types9 = dict()\nfor key, value in tqdm(ring_types.items()):\n    if len(key) == 3:\n        ring_types3[key] = value\n    elif len(key) == 4:\n        ring_types4[key] = value\n    elif len(key) == 5:\n        ring_types5[key] = value\n    elif len(key) == 6:\n        ring_types6[key] = value\n    elif len(key) == 7:\n        ring_types7[key] = value\n    elif len(key) == 8:\n        ring_types8[key] = value\n    elif len(key) == 9:\n        ring_types9[key] = value","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"plt.figure(\"3RingTypes\", figsize=(20,10))\nax = sns.barplot(x=list(ring_types3.keys()), y=list(ring_types3.values()))\nfor i,p in enumerate(ax.patches):\n    x = (p.get_x() + p.get_width()/2) - 0.09\n    y = p.get_y() + p.get_height() + 0.15\n    ax.annotate(list(ring_types3.values())[i], (x, y))\nplt.xlabel(\"Ring types\")\nplt.ylabel(\"Count of rings\")\nplt.title(\"Types of 3-rings\")\nplt.savefig(\"3RingTypes.png\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"plt.figure(\"4RingTypes\", figsize=(20,10))\nax = sns.barplot(x=list(ring_types4.keys()), y=list(ring_types4.values()))\nfor i,p in enumerate(ax.patches):\n    x = (p.get_x() + p.get_width()/2) - 0.09\n    y = p.get_y() + p.get_height() + 0.15\n    ax.annotate(list(ring_types4.values())[i], (x, y))\nplt.xlabel(\"Ring types\")\nplt.ylabel(\"Count of rings\")\nplt.title(\"Types of 4-rings\")\nplt.savefig(\"4RingTypes.png\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"plt.figure(\"5RingTypes\", figsize=(20,10))\nax = sns.barplot(x=list(ring_types5.keys()), y=list(ring_types5.values()))\nfor i,p in enumerate(ax.patches):\n    x = (p.get_x() + p.get_width()/2) - 0.22\n    y = p.get_y() + p.get_height() + 0.15\n    ax.annotate(list(ring_types5.values())[i], (x, y))\nplt.xlabel(\"Ring types\")\nplt.ylabel(\"Count of rings\")\nplt.title(\"Types of 5-rings\")\nplt.savefig(\"5RingTypes.png\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"plt.figure(\"6RingTypes\", figsize=(20,10))\nax = sns.barplot(x=list(ring_types6.keys()), y=list(ring_types6.values()))\nfor i,p in enumerate(ax.patches):\n    x = (p.get_x() + p.get_width()/2) - 0.2\n    y = p.get_y() + p.get_height() + 0.15\n    ax.annotate(list(ring_types6.values())[i], (x, y))\nplt.xlabel(\"Ring types\")\nplt.ylabel(\"Count of rings\")\nplt.title(\"Types of 6-rings\")\nplt.savefig(\"6RingTypes.png\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"plt.figure(\"7RingTypes\", figsize=(20,10))\nx_labels = [label[2:] for label in list(ring_types7.keys())]\nax = sns.barplot(x=x_labels, y=list(ring_types7.values()))\nfor i,p in enumerate(ax.patches):\n    x = (p.get_x() + p.get_width()/2) - 0.15\n    y = p.get_y() + p.get_height() + 0.15\n    ax.annotate(list(ring_types7.values())[i], (x, y))\nplt.xlabel(\"Ring types [CC+]\")\nplt.ylabel(\"Count of rings\")\nplt.title(\"Types of 7-rings\")\nplt.savefig(\"7RingTypes.png\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"plt.figure(\"8RingTypes\", figsize=(20,10))\nax = sns.barplot(x=list(ring_types8.keys()), y=list(ring_types8.values()))\nfor i,p in enumerate(ax.patches):\n    x = (p.get_x() + p.get_width()/2) - 0.09\n    y = p.get_y() + p.get_height() + 0.15\n    ax.annotate(list(ring_types8.values())[i], (x, y))\nplt.xlabel(\"Ring types\")\nplt.ylabel(\"Count of rings\")\nplt.title(\"Types of 8-rings\")\nplt.savefig(\"8RingTypes.png\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"plt.figure(\"9RingTypes\", figsize=(20,10))\nx_labels = [label[3:] for label in list(ring_types9.keys())]\nax = sns.barplot(x=x_labels, y=list(ring_types9.values()))\nfor i,p in enumerate(ax.patches):\n    x = (p.get_x() + p.get_width()/2) - 0.09\n    y = p.get_y() + p.get_height() + 0.15\n    ax.annotate(list(ring_types9.values())[i], (x, y))\nplt.xlabel(\"Ring types [CCC+]\")\nplt.ylabel(\"Count of rings\")\nplt.title(\"Types of 9-rings\")\nplt.savefig(\"9RingTypes.png\")\nplt.show()","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":1}