{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n\n# Analyzing Radial Distribution Functions (RDF)\n\nIn this example, we'll explore the radial distribution functions (RDF) of an atomic structure. The RDF provides insights into the probability of finding an atom at a certain distance from another. This can be useful for understanding the local environment of atoms.\n\nWe'll use the `pyprocar` package to:\n\n1. Parse the POSCAR file and obtain atomic positions.\n2. Compute the general KDE curve for all distances.\n3. Compute KDE curves for specific atomic species interactions.\n4. Visualize the results using `matplotlib`.\n\nLet's dive in!\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import itertools\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom matplotlib.gridspec import GridSpec\n\nimport pyprocar.pyposcar as p\nfrom pyprocar.utils import DATA_DIR\n\ncolors = [\"b\", \"r\", \"y\", \"g\", \"m\", \"k\", \"c\"]\n\ndata_dir = os.path.join(DATA_DIR, \"examples\", \"PyPoscar\", \"04-rdf\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Parsing the POSCAR file\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "a = p.poscar.Poscar(os.path.join(data_dir, \"POSCAR-AGNR-defect.vasp\"))\na.parse()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Computing RDF and KDE Curves\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "my_rdf = p.rdf.RDF(poscar=a)\nthresholdSp = my_rdf.neighbor_thresholdSp\n\n# Calculates KDE curves for each species interaction\nspCurves = my_rdf.KDE_CurveSp()\n# All calculations share the same kde space\ndomain = my_rdf.KDE_space\nprint(\"CutOff values for each interaction\")\nfor inter, cutoff in zip(my_rdf.interactions, thresholdSp):\n    print(inter, \" \", cutoff)\n\n\nprint(\n    \"As you can see most interactions have meaaningfull values,\"\n    \" but there is no way to defene nearest neighbors for others (e.g. H-B).\"\n    \" A large cutoff is provided in these cases.\"\n)\n\nprint(\n    \"Note: The class for finding nearest neighbors uses a database to ignore these large distances as `nearest neighbors`\"\n)\n\nNeighborsClass = p.latticeUtils.Neighbors(poscar=a)\nNeighborsClass.estimateMaxBondDist()\nNeighbor_threshold = NeighborsClass.d_Max"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Visualizing the Results\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "gs = GridSpec(2, 2, height_ratios=[1, 2])\n\nax1 = plt.subplot(gs[0, 0])\nax2 = plt.subplot(gs[1, 0])\nax3 = plt.subplot(gs[:, 1])\n\n# fig,axes = plt.subplots(2,2)\n\n\n# This is the kde curve for all the distances in POSCAR\nax1.plot(domain, my_rdf.KDE_Curve())\nax1.set_title(\"General KDE curve\")\n\ncc = itertools.cycle(colors)\nfor i, curve in enumerate(spCurves):\n    label = my_rdf.interactions[i]\n    c = next(cc)\n    ax2.plot(domain, curve, label=label, color=c)\n    ax2.set_title(\"Species KDE curves\")\n    ax2.legend()\n\n\nNeighbor_threshold = np.ndarray.flatten(Neighbor_threshold)\nNeighbor_threshold = set(Neighbor_threshold)\nprint(\"The DataBase Thresholds are:\")\nprint(Neighbor_threshold)\n\n# Distances for Histogram\n\ndistance_matrix = my_rdf.distances\ndistance_matrix = np.array(distance_matrix)\ndistances = np.ndarray.flatten(distance_matrix)\nbins = 100\nn, bins, patches = ax3.hist(distances, bins=bins, edgecolor=\"black\", alpha=0.7)\n\nax3.set_xlabel(\"Distance Between Atoms\")\n\n# Plotting CutOff point vertical lines\n\nlabels = my_rdf.interactions\nlabels = labels.tolist()\n\nPlotlabels = []\nfor interaction in labels:\n    Plotlabels.append(interaction[0] + \"-\" + interaction[1])\n\ncc = itertools.cycle(colors)\nvar_cutoffs = []\nfor i, cutOff in enumerate(thresholdSp):\n    c = next(cc)\n    var_cutoffs.append(\n        ax3.plot([cutOff, cutOff], [0, 1000], color=c, label=my_rdf.interactions[i])\n    )\nleg1 = ax3.legend(\n    title=\"CutOff points\",\n    handles=[x[0] for x in var_cutoffs],\n    labels=Plotlabels,\n    loc=\"upper left\",\n)\n\ncc = itertools.cycle(colors)\ndata_cutoffs = []\n\n\nfor i, cutOff in enumerate(Neighbor_threshold):\n    c = next(cc)\n    data_cutoffs.append(\n        ax3.plot([cutOff, cutOff], [0, 1000], color=\"grey\", linestyle=\"dotted\")\n    )\n\n# leg2 = ax3.legend(title = 'DataBased CutOff', handles = [x[0] for x in data_cutoffs], labels = color_label,loc = 'upper right')\n\nax3.add_artist(leg1)\n# ax3.add_artist(leg2)\n\nax1.grid(True)\nax2.grid(True)\nax3.grid(True)\n\nplt.tight_layout()\nplt.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.9.20"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}