{ "cells": [ { "cell_type": "markdown", "id": "01850ff6", "metadata": {}, "source": [ "# Figure 1A: CP3 per-site ¹H shift spread vs the DFT and experimental resolution limits\n", "\n", "Histogram of per-site ¹H shift spread across the Goodman CP3 stereoisomers (Goodman, JOC 2009, 74,\n", "4597), against the experimental noise floor (0.02 ppm) and DFT's resolving power (0.10 ppm)." ] }, { "cell_type": "code", "execution_count": null, "id": "a460d80b", "metadata": {}, "outputs": [], "source": [ "import os, sys\n", "\n", "# make the in-repo modules importable (not pip-installed)\n", "REPO = os.path.abspath(\"../..\")\n", "for _p in (\"analysis/code\",):\n", " sys.path.insert(0, os.path.join(REPO, _p))" ] }, { "cell_type": "code", "execution_count": null, "id": "e0adf094", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "from matplotlib.ticker import FixedLocator\n", "\n", "import cp3" ] }, { "cell_type": "code", "execution_count": null, "id": "b68e0918", "metadata": {}, "outputs": [], "source": [ "def figure_path(name):\n", " os.makedirs(\"figures\", exist_ok=True)\n", " return os.path.join(\"figures\", name)" ] }, { "cell_type": "code", "execution_count": null, "id": "f599e59b", "metadata": {}, "outputs": [], "source": [ "variations = cp3.load_variations(nucleus=\"H\")\n", "frac = cp3.fraction_below_dft(variations)\n", "print(f\"{len(variations)} proton sites; {frac:.1%} fall between the experimental floor \"\n", " f\"({cp3.EXPERIMENTAL_LIMIT} ppm) and the DFT limit ({cp3.DFT_LIMIT} ppm)\")" ] }, { "cell_type": "code", "execution_count": null, "id": "c88605cd", "metadata": {}, "outputs": [], "source": [ "# color per zone; keys match cp3._zone's return values\n", "zone_colors = {\n", " \"below_experimental\": \"#2c4553\", # < 0.02 ppm: within experimental noise\n", " \"below_dft\": \"#a72608\", # 0.02 - 0.10 ppm: informative but DFT cannot resolve\n", " \"dft_zone\": \"#dacd82\", # 0.10 - 0.30 ppm: resolvable by DFT\n", " \"large\": \"#68a79a\", # >= 0.30 ppm\n", "}\n", "boundaries = (cp3.EXPERIMENTAL_LIMIT, cp3.DFT_LIMIT, cp3.LARGE_VARIATION)" ] }, { "cell_type": "code", "execution_count": null, "id": "03efe205", "metadata": {}, "outputs": [], "source": [ "sns.set_theme(context=\"paper\", style=\"white\")\n", "fig, ax = plt.subplots(figsize=(8, 4))\n", "\n", "bins = 30\n", "edges = np.linspace(0.0, float(variations.max()), bins + 1)\n", "counts, edge = np.histogram(variations, bins=edges)\n", "\n", "# Draw each bar, splitting any bin that straddles a zone boundary so each segment gets its color.\n", "for height, left, right in zip(counts, edge[:-1], edge[1:]):\n", " splits = sorted({left, right} | {b for b in boundaries if left < b < right})\n", " for a, b in zip(splits[:-1], splits[1:]):\n", " ax.bar(a, height, width=b - a, align=\"edge\",\n", " color=zone_colors[cp3._zone(0.5 * (a + b))],\n", " edgecolor=\"white\", linewidth=0.6, alpha=0.9)\n", "\n", "ax.set_xlim(left=0.0)\n", "ax.set_ylim(0, ax.get_ylim()[1])\n", "ax.margins(x=0)\n", "ax.set_title(\"Chemical shift variation (¹H)\", pad=8, fontsize=16)\n", "ax.set_xlabel(\"Variation at Site (standard deviation, ¹H ppm)\", fontsize=13)\n", "ax.set_ylabel(\"Count\", fontsize=13)\n", "sns.despine(ax=ax, top=True, right=True)\n", "for side in (\"left\", \"bottom\"):\n", " ax.spines[side].set_linewidth(0.6)\n", "ax.xaxis.set_major_locator(FixedLocator([0.0, 0.1, 0.2, 0.3, 0.4, 0.5]))\n", "ax.tick_params(axis=\"both\", which=\"major\", labelsize=10, size=1.5, width=0.6)\n", "ax.minorticks_off()\n", "fig.tight_layout()\n", "\n", "fig.savefig(figure_path(\"fig1a_cp3_1H.png\"), dpi=300, bbox_inches=\"tight\", pad_inches=0.02)\n", "plt.show()" ] } ], "metadata": { "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.12.13" } }, "nbformat": 4, "nbformat_minor": 5 }