{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport os\nprint(os.listdir(\"../input\"))\n\n","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"df_train = pd.read_csv('../input/train.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":" df_structures = pd.read_csv('../input/structures.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-output":true,"_kg_hide-input":true},"cell_type":"code","source":"import plotly.graph_objs as go\nfrom plotly.offline import offline\n\ncpk_colors = dict(Ar='cyan', B='salmon', Ba='darkgreen', Be='darkgreen', Br='darkred', C='black', Ca='darkgreen',\n                  Cl='green', Cs='violet', F='green', Fe='darkorange', Fr='violet', H='white', He='cyan',\n                  I='darkviolet', K='violet', Kr='cyan', Li='violet', Mg='darkgreen', N='blue', Na='violet', Ne='cyan',\n                  O='red', P='orange', Ra='darkgreen', Rb='violet', S='yellow', Sr='darkgreen', Ti='gray', Xe='cyan')\ncpk_color_rest = 'pink'\n\n\ndef plot(adjacency_list: dict, elements: list, x_coordinates: list,\n         y_coordinates: list, z_coordinates: list, plot_name: str = 'plot') -> None:\n    \"\"\"Creates a 3D scatter plot\"\"\"\n    def atom_trace():\n        \"\"\"Creates an atom trace for the plot\"\"\"\n        colors = [cpk_colors.get(element, cpk_color_rest) for element in elements]\n        markers = dict(color=colors, line=dict(color='lightgray', width=2), size=7, symbol='circle', opacity=0.8)\n        trace = go.Scatter3d(x=x_coordinates, y=y_coordinates, z=z_coordinates, mode='markers', marker=markers,\n                             text=elements)\n        return trace\n\n    def bond_trace():\n        \"\"\"\"Creates a bond trace for the plot\"\"\"\n        trace = go.Scatter3d(x=[], y=[], z=[], hoverinfo='none', mode='lines',\n                             marker=dict(color='grey', size=7, opacity=1))\n        adjascent_atoms = ((atom, neighbour) for atom, neighbours in adjacency_list.items()\n                           for neighbour in neighbours)\n        for i, j in adjascent_atoms:\n            trace['x'] += (x_coordinates[i], x_coordinates[j], None)\n            trace['y'] += (y_coordinates[i], y_coordinates[j], None)\n            trace['z'] += (z_coordinates[i], z_coordinates[j], None)\n        return trace\n\n    atoms = zip(elements, x_coordinates, y_coordinates, z_coordinates)\n    annotations = [dict(text=element, x=x, y=y, z=z, showarrow=False, yshift=15) for element, x, y, z in atoms]\n    data = [atom_trace(), bond_trace()]\n    axis_params = dict(showgrid=False, showticklabels=False, zeroline=False, titlefont=dict(color='white'))\n    layout = go.Layout(scene=dict(xaxis=axis_params, yaxis=axis_params, zaxis=axis_params, annotations=annotations),\n                       margin=dict(r=0, l=0, b=0, t=0), showlegend=False)\n    fig = go.Figure(data=data, layout=layout)\n    iplot(fig)\n    #offline.plot(fig, show_link=False, filename=plot_name + '.html')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-output":true,"_kg_hide-input":true},"cell_type":"code","source":"import re\nfrom itertools import combinations\nfrom math import sqrt\n\natomic_radii = dict(Ac=1.88, Ag=1.59, Al=1.35, Am=1.51, As=1.21, Au=1.50, B=0.83, Ba=1.34, Be=0.35, Bi=1.54, Br=1.21,\n                    C=0.68, Ca=0.99, Cd=1.69, Ce=1.83, Cl=0.99, Co=1.33, Cr=1.35, Cs=1.67, Cu=1.52, D=0.23, Dy=1.75,\n                    Er=1.73, Eu=1.99, F=0.64, Fe=1.34, Ga=1.22, Gd=1.79, Ge=1.17, H=0.23, Hf=1.57, Hg=1.70, Ho=1.74,\n                    I=1.40, In=1.63, Ir=1.32, K=1.33, La=1.87, Li=0.68, Lu=1.72, Mg=1.10, Mn=1.35, Mo=1.47, N=0.68,\n                    Na=0.97, Nb=1.48, Nd=1.81, Ni=1.50, Np=1.55, O=0.68, Os=1.37, P=1.05, Pa=1.61, Pb=1.54, Pd=1.50,\n                    Pm=1.80, Po=1.68, Pr=1.82, Pt=1.50, Pu=1.53, Ra=1.90, Rb=1.47, Re=1.35, Rh=1.45, Ru=1.40, S=1.02,\n                    Sb=1.46, Sc=1.44, Se=1.22, Si=1.20, Sm=1.80, Sn=1.46, Sr=1.12, Ta=1.43, Tb=1.76, Tc=1.35, Te=1.47,\n                    Th=1.79, Ti=1.47, Tl=1.55, Tm=1.72, U=1.58, V=1.33, W=1.37, Y=1.78, Yb=1.94, Zn=1.45, Zr=1.56)\n\n\nclass Graph:\n    \"\"\"Represents a molecular graph.\"\"\"\n    __slots__ = ['elements', 'x_coordinates', 'y_coordinates', 'z_coordinates', 'adjacency_list',\n                 'atomic_radii']\n\n    def __init__(self):\n        self.elements = []\n        self.x_coordinates = []\n        self.y_coordinates = []\n        self.z_coordinates = []\n        self.adjacency_list = {}\n        self.atomic_radii = []\n\n    def read_file(self, file_path: str) -> None:\n        \"\"\"Reads an XYZ file, searches for elements and their cartesian coordinates\n        and adds them to corresponding arrays\"\"\"\n        pattern = re.compile(r'([A-Za-z]{1,3})\\s*(-?\\d+(?:\\.\\d+)?)\\s*(-?\\d+(?:\\.\\d+)?)\\s*(-?\\d+(?:\\.\\d+)?)')\n        with open(file_path) as file:\n            for element, x, y, z in pattern.findall(file.read()):\n                self.elements.append(element)\n                self.x_coordinates.append(float(x))\n                self.y_coordinates.append(float(y))\n                self.z_coordinates.append(float(z))\n        self.atomic_radii = [atomic_radii[element] for element in self.elements]\n        self._generate_adjacency_list()\n\n    def _generate_adjacency_list(self):\n        \"\"\"Generates an adjacency list from atomic cartesian coordinates\"\"\"\n        node_ids = range(len(self.elements))\n        for i, j in combinations(node_ids, 2):\n            x_i, y_i, z_i = self.__getitem__(i)[1]\n            x_j, y_j, z_j = self.__getitem__(j)[1]\n            distance = sqrt((x_i - x_j) ** 2 + (y_i - y_j) ** 2 + (z_i - z_j) ** 2)\n            if 0.1 < distance < (self.atomic_radii[i] + self.atomic_radii[j]) * 1.3:\n                self.adjacency_list.setdefault(i, set()).add(j)\n                self.adjacency_list.setdefault(j, set()).add(i)\n\n    def edges(self):\n        \"\"\"Creates an iterator with all graph edges\"\"\"\n        edges = set()\n        for node, neighbours in self.adjacency_list.items():\n            for neighbour in neighbours:\n                edge = frozenset([node, neighbour])\n                if edge in edges:\n                    continue\n                edges.add(edge)\n                yield node, neighbour\n\n    def __len__(self):\n        return len(self.elements)\n\n    def __getitem__(self, position):\n        return self.elements[position], (\n            self.x_coordinates[position], self.y_coordinates[position], self.z_coordinates[position])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-output":true,"_kg_hide-input":true},"cell_type":"code","source":"\"\"\"Molecular graph constructor.\nThis script constructs a molecular graph from atomic coordinates.\nThis tool relies on the most straightforward method for determination of atomic connectivity in molecules,\nwhich is based on interatomic distances and atomic covalent radii. Each interatomic distance is compared to the sum\nof covalent radii r_i and r_j of both atoms.If the distance between two atoms is within the range d = 1.3(r_i + r_j),\nthat is the sum of covalent radii plus thirty per cent, then an edge connecting the two nodes is added to the\nmolecular graph.\nThis script accepts an XYZ ﬁle with chemical elements and their cartesian coordinates as input.\nThe `plotly` package is required for visualisation of the the molecular graph.\n\"\"\"\n\nfrom sys import argv\n\n#from molecular_graph import Graph\n#from plot import plot\n\n#script, file = argv\n\nmolecule = Graph()\n\n#molecule.read_file(file)\n\n#plot(adjacency_list=molecule.adjacency_list, elements=molecule.elements, x_coordinates=molecule.x_coordinates,\n#     y_coordinates=molecule.y_coordinates, z_coordinates=molecule.z_coordinates)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_structures.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"file = '../input/structures/dsgdb9nsd_028960.xyz'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"molecule.read_file(file)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from plotly.offline import init_notebook_mode, iplot\ninit_notebook_mode(connected=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot(adjacency_list=molecule.adjacency_list, elements=molecule.elements, x_coordinates=molecule.x_coordinates,\n     y_coordinates=molecule.y_coordinates, z_coordinates=molecule.z_coordinates)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(molecule)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"molecule.elements","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}