{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "7c1065dd",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "import pyerrors as pe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "20f67709",
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.style.use('./base_style.mplstyle')\n",
    "import shutil\n",
    "usetex = shutil.which('latex') != ''\n",
    "plt.rc('text', usetex=usetex)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e5764fd0",
   "metadata": {},
   "source": [
    "We can load data from a preprocessed file which contains a list of `pyerror` `Obs`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "fbfa65f5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Data has been written using pyerrors 2.0.0.\n",
      "Format version 0.1\n",
      "Written by fjosw on 2022-01-06 11:11:19 +0100 on host XPS139305, Linux-5.11.0-44-generic-x86_64-with-glibc2.29\n",
      "\n",
      "Description:  Test data for the correlator example\n"
     ]
    }
   ],
   "source": [
    "correlator_data = pe.input.json.load_json(\"./data/correlator_test\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae93c7c2",
   "metadata": {},
   "source": [
    "With this list a `Corr` object can be initialised"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "33a8fdec",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_correlator = pe.Corr(correlator_data)\n",
    "my_correlator.gamma_method()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "5f954607",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Corr T=96 N=1\n",
      "x0/a\tCorr(x0/a)\n",
      "------------------\n",
      "8\t 548(13)\n",
      "9\t 433(11)\n",
      "10\t 343.1(8.6)\n",
      "11\t 273.2(6.6)\n",
      "12\t 217.5(5.6)\n",
      "13\t 172.9(4.9)\n",
      "14\t 137.6(4.6)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "my_correlator.print([8, 14])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b00d670b",
   "metadata": {},
   "source": [
    "The `show` method can display the correlator."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "b71529d0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 6340 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "my_correlator.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c659557e",
   "metadata": {},
   "source": [
    "## Manipulating correlators"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c7f37e9f",
   "metadata": {},
   "source": [
    "Arithmetic operations are overloaded for `Corr` objects as is the case for `Obs` objects."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "bcc9b40e",
   "metadata": {},
   "outputs": [],
   "source": [
    "new_correlator = 1 + 1 / my_correlator ** 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "416cf39a",
   "metadata": {},
   "source": [
    "In addition to that various useful methods for the manipulation of `Corr` objects are implemented. A correlator can for example be periodically shifted"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "e8d65dd5",
   "metadata": {},
   "outputs": [],
   "source": [
    "shifted_correlator = my_correlator.roll(20)\n",
    "shifted_correlator.tag = r'Correlator shifted by $x_0/a=20$'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "634dd613",
   "metadata": {},
   "source": [
    "or symmetrised"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "127a661d",
   "metadata": {},
   "outputs": [],
   "source": [
    "symmetrised_correlator = my_correlator.symmetric()\n",
    "symmetrised_correlator.tag = 'Symmetrised correlator'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d733872",
   "metadata": {},
   "source": [
    "The full list of `Corr` methods can be found in the documentation.\n",
    "\n",
    "We can visually compare different `Corr` objects by passing `comp` to the `show` method. The argument <code>auto_gamma</code> tells `show` to calculate the y-errors using the gamma method with the default parameters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "8e264aed",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 17752 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "shifted_correlator.show(comp=symmetrised_correlator, logscale=True, auto_gamma=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "232e88af",
   "metadata": {},
   "source": [
    "## Effective mass"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "83dc751c",
   "metadata": {},
   "source": [
    "The effective mass of the correlator can be obtained by calling the `m_eff` method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "c686f7e0",
   "metadata": {},
   "outputs": [],
   "source": [
    "m_eff = symmetrised_correlator.m_eff()\n",
    "m_eff.tag = 'Effective mass'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4a9d13b2",
   "metadata": {},
   "source": [
    "We can also use the periodicity of the lattice in order to obtain the cosh effective mass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "5acde8cf",
   "metadata": {},
   "outputs": [],
   "source": [
    "periodic_m_eff = symmetrised_correlator.m_eff('periodic')\n",
    "periodic_m_eff.tag = 'Cosh effective mass'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c658b000",
   "metadata": {},
   "source": [
    "We can compare the two and see how the standard effective mass deviates from the plateau at the center of the lattice"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "1d6ea22a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 14788 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "periodic_m_eff.show([4,47], comp=m_eff, ylabel=r'$am_\\mathrm{eff}$', auto_gamma=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "472ab97b",
   "metadata": {},
   "source": [
    "## Derivatives"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d99414fe",
   "metadata": {},
   "source": [
    "We can obtain derivatives of correlators in the following way"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "03007f8a",
   "metadata": {},
   "outputs": [],
   "source": [
    "first_derivative = symmetrised_correlator.deriv()\n",
    "first_derivative.tag = 'First derivative'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "c0311739",
   "metadata": {},
   "outputs": [],
   "source": [
    "second_derivative = symmetrised_correlator.second_deriv()\n",
    "second_derivative.tag = 'Second derivative'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "165550d9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 12952 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "symmetrised_correlator.show([5, 20], comp=[first_derivative, second_derivative], y_range=[-500, 1300], auto_gamma=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18c75d20",
   "metadata": {},
   "source": [
    "## Missing Values \n",
    "\n",
    "Apart from the build-in functions, another benefit of using ``Corr`` objects is that they can handle missing values. \n",
    "We will create a second correlator with missing values. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "1db86a4c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Corr T=96 N=1\n",
      "x0/a\tCorr(x0/a)\n",
      "------------------\n",
      "0\t 62865(41)\n",
      "1\t 23756(32)\n",
      "2\t 6434(25)\n",
      "3\t 2886(20)\n",
      "4\t 1735(21)\n",
      "5\t 1213(21)\n",
      "6\n",
      "7\t 699(17)\n",
      "8\n",
      "9\n",
      "10\t 343.1(8.6)\n",
      "11\t 273.2(6.6)\n",
      "12\n",
      "13\t 172.9(4.9)\n",
      "14\n",
      "15\n",
      "16\t 88.0(3.9)\n",
      "17\t 70.6(3.2)\n",
      "18\t 56.6(2.6)\n",
      "19\t 45.3(2.1)\n",
      "20\n",
      "21\t 29.2(1.4)\n",
      "22\t 23.4(1.2)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "new_content=[(my_correlator.content[i] if i not in [6,8,9,12,14,15,20] else None ) for i in range(my_correlator.T) ] # We reuse the old example and replace a few values with None\n",
    "correlator_incomplete=pe.Corr(new_content)\n",
    "\n",
    "correlator_incomplete.print([0, 22]) # Print the correlator in the range 0 - 22"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "602d81fa",
   "metadata": {},
   "source": [
    "We see that this is still a valid correlator. It is just missing some values. \n",
    "When we perform operations, which generate new correlators, the missing values are handled automatically.\n",
    "\n",
    "Some functions might also return correlators with missing values. We already looked at the derivative. \n",
    "The symmertic derivative is not defined for the first and last timeslice. Whatever operation is performed on a `Corr` object, the correlators keeps its length **T**. So there will never be confusion about how to count timeslices. One can also take a plateau or perform a fit, even though some values might be missing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e2a52d30",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
