{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Live Nonlinear Fitting\n", "\n", "## Configuration\n", "\n", "This code would normally go in a script automatically run at startup. The user would not have to worry about this." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib widget\n", "import matplotlib.pyplot as plt\n", "\n", "import numpy as np\n", "import lmfit\n", "from bluesky import RunEngine\n", "from bluesky.plans import scan\n", "from ophyd.sim import motor, noisy_det\n", "from bluesky.callbacks import LiveFit, LivePlot, LiveFitPlot\n", "import matplotlib.pyplot as plt\n", "\n", "RE = RunEngine({})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Data Acquisition" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots() # As before, create plot to be able to follow the progress of the fit during the scan" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# define Gaussian function and save it as a model using lmfit\n", "def gaussian(x, A, sigma, x0):\n", " return A*np.exp(-(x - x0)**2/(2 * sigma**2))\n", "\n", "model = lmfit.Model(gaussian)\n", "\n", "# The initial guess (gray on the plot) is just a starting point from which the fitting algorithm works.\n", "init_guess = {'A': 2,\n", " 'sigma': lmfit.Parameter('sigma', 3, min=0),\n", " 'x0': -0.2}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# LiveFit example\n", "lf = LiveFit(model, 'noisy_det', {'x': 'motor'}, init_guess)\n", "\n", "# now add the plot...\n", "lfp = LiveFitPlot(lf, color='r', ax=ax)\n", "\n", "RE(scan([noisy_det], motor, -1, 1, 100), lfp)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plt.gcf() # Unfortunately, since we do not see the motor positions relative to the fit,\n", " # we cannot evaluate how well the fit worked." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Show motor position vs. fit during the scan\n", "\n", "fig, ax = plt.subplots() # explitly create figure to follow fitting" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lfp = LiveFitPlot(lf, ax=ax, color='r')\n", "lp = LivePlot('noisy_det', 'motor', ax=ax, marker='o', linestyle='none') # plotting the noisy_det scalar object\n", "\n", "RE(scan([noisy_det], motor, -1, 1, 100), [lfp, lp])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# We can see that from imperfect initial conditions, the fit now matches the data well\n", "plt.gcf() # Display a snapshot of the current state of the figure." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Get the final fit parameters\n", "lf.result.best_values" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercises\n", "\n", "1. Try a different user-defined peak-like function to use as a model." ] } ], "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.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }