{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "7c1065dd",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\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",
    "plt.rc('text', usetex=True)"
   ]
  },
  {
   "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, 10300 characters]\n",
      "text/plain": [
       "<Figure size 640x395.55 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": "416cf39a",
   "metadata": {},
   "source": [
    "`Corr` objects can be shifted"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "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": 8,
   "id": "127a661d",
   "metadata": {},
   "outputs": [],
   "source": [
    "symmetrised_correlator = my_correlator.symmetric()\n",
    "symmetrised_correlator.tag = 'Symmetrised correlator'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d733872",
   "metadata": {},
   "source": [
    "We can compare different `Corr` objects by passing `comp` to the `show` method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "8e264aed",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 33316 characters]\n",
      "text/plain": [
       "<Figure size 640x395.55 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "shifted_correlator.show(comp=symmetrised_correlator, logscale=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": 10,
   "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 priodicity of the lattice in order to obtain the cosh effective mass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "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 form the plateau at the center of the lattice"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "1d6ea22a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 28136 characters]\n",
      "text/plain": [
       "<Figure size 640x395.55 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}$')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e3762e68",
   "metadata": {},
   "source": [
    "Arithmetic operations and mathematical functions are also overloaded for the `Corr` class. We can compute the difference between the two variants of the effective mass as follows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "e56d164c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 14664 characters]\n",
      "text/plain": [
       "<Figure size 640x395.55 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "difference_m_eff = np.abs(periodic_m_eff - m_eff)\n",
    "difference_m_eff.show([0, 47], logscale=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, 24556 characters]\n",
      "text/plain": [
       "<Figure size 640x395.55 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])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18c75d20",
   "metadata": {},
   "source": [
    "## Missing Values \n",
    "\n",
    "Apart from the build-in functions, there is another reason, why one should use a **Corr** instead of a list of **Obs**. \n",
    "Missing values are handled for you. \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."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6479a999",
   "metadata": {},
   "source": [
    "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. \n",
    "\n",
    "The important thing is that, whatever you do, correlators keep their length **T**. So there will never be confusion about how you count timeslices. You can also take a plateau or perform a fit, even though some values might be missing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "f3c4609c",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert first_derivative.T == my_correlator.T == len(first_derivative.content) == len(my_correlator.content)\n",
    "assert first_derivative.content[0] is None\n",
    "assert first_derivative.content[-1] is None"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fcbcac4",
   "metadata": {},
   "source": [
    "There is a range of addtional methods of the `Corr` class which can be found in the documentation."
   ]
  }
 ],
 "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
}
