Repository: optimagic-dev/optimagic (language: python)

Issue:
Update packaging
### Current situation

outdated package structure and upload to OSE channel

### Desired Situation

- src package structure 
- rename master to main 
- upload to conda forge





Discussion / hints:

Fix patch:
diff --git a/.codecov.yml b/.codecov.yml
deleted file mode 100644
index ddcf26410..000000000
--- a/.codecov.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-coverage:
-  status:
-    patch:
-      default:
-        target: 80%
-    project:
-      default:
-        target: 87%
diff --git a/.conda/bld.bat b/.conda/bld.bat
deleted file mode 100644
index 65ed47c07..000000000
--- a/.conda/bld.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-"%PYTHON%" setup.py install
-if errorlevel 1 exit 1
diff --git a/.conda/build.sh b/.conda/build.sh
deleted file mode 100644
index a40f1097a..000000000
--- a/.conda/build.sh
+++ /dev/null
@@ -1,1 +0,0 @@
-$PYTHON setup.py install     # Python command to install the script.
diff --git a/.conda/meta.yaml b/.conda/meta.yaml
index 42a71c8d5..4044e87c5 100644
--- a/.conda/meta.yaml
+++ b/.conda/meta.yaml
@@ -12,6 +12,7 @@ source:
 build:
   noarch: python
   number: 0
+  script: {{ PYTHON }} setup.py install --single-version-externally-managed --record record.txt
   entry_points:
     - estimagic = estimagic.cli:cli
 
@@ -43,7 +44,7 @@ test:
     - statsmodels
   source_files:
     - tox.ini
-    - estimagic/tests
+    - tests
   commands:
     - pytest -m "not slow"
     - estimagic --version
@@ -52,6 +53,6 @@ test:
 
 about:
   home: https://github.com/OpenSourceEconomics/estimagic
-  license: BSD
+  license: MIT
   license_file: LICENSE
   summary: Tools for the estimation of (structural) econometric models.
diff --git a/.github/workflows/publish-to-pypi.yml b/.github/workflows/publish-to-pypi.yml
new file mode 100644
index 000000000..710ebb1e9
--- /dev/null
+++ b/.github/workflows/publish-to-pypi.yml
@@ -0,0 +1,34 @@
+name: PyPI
+
+on: push
+
+jobs:
+  build-n-publish:
+    name: Build and publish Python 🐍 distributions 📦 to PyPI
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@master
+
+    - name: Set up Python 3.8
+      uses: actions/setup-python@v1
+      with:
+        python-version: 3.8
+
+    - name: Install pypa/build
+      run: >-
+        python -m
+        pip install
+        build
+        --user
+    - name: Build a binary wheel and a source tarball
+      run: >-
+        python -m
+        build
+        --sdist
+        --wheel
+        --outdir dist/
+    - name: Publish distribution 📦 to PyPI
+      if: startsWith(github.ref, 'refs/tags')
+      uses: pypa/gh-action-pypi-publish@master
+      with:
+        password: ${{ secrets.PYPI_API_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 18aba498e..08ba82079 100644
--- a/.gitignore
+++ b/.gitignore
@@ -124,3 +124,6 @@ venv.bak/
 
 
 .pytask.sqlite3
+
+
+src/estimagic/_version.py
diff --git a/LICENSE b/LICENSE
index c36f1e1ad..fbdb461b6 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,29 +1,18 @@
-BSD 3-Clause License
+Copyright 2019-2021 Janos Gabler
 
-Copyright (c) 2019, Janos Gabler
-All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this
+software and associated documentation files (the "Software"), to deal in the Software
+without restriction, including without limitation the rights to use, copy, modify,
+merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to the following
+conditions:
 
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
 
-* Redistributions of source code must retain the above copyright notice, this
-  list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
-  this list of conditions and the following disclaimer in the documentation
-  and/or other materials provided with the distribution.
-
-* Neither the name of the copyright holder nor the names of its
-  contributors may be used to endorse or promote products derived from
-  this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/MANIFEST.in b/MANIFEST.in
index 365303e5f..1341b3d23 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -6,23 +6,25 @@
 # Test what is included in the package by running ``python setup.py sdist`` and inspect
 # the tarball.
 
-include CHANGES.rst
 include CITATION
 include LICENSE
-include README.rst
-include tox.ini
-include *.sh
-include *.yaml
-include *.yml
+include CHANGES.rst
 
-exclude pytask.ini
+recursive-include src *.css
+recursive-include src *.csv
+recursive-include src *.db
+recursive-include src *.html
+recursive-include src *.py
 
-graft docs
-graft estimagic
+exclude *.sh
+exclude *.yaml
+exclude *.yml
+exclude *.pickle
+exclude pytask.ini
+exclude tox.ini
 
-prune docs/_build
-prune docs/build
-prune docs/getting_started/__tutorial__
+prune docs
+prune tests
 prune .conda
 
 global-exclude __pycache__
diff --git a/codecov.yml b/codecov.yml
index 43c1b1e35..9e8ca4421 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -6,6 +6,13 @@ coverage:
   precision: 2
   round: down
   range: "50...100"
+  status:
+    patch:
+      default:
+        target: 80%
+    project:
+      default:
+        target: 87%
 
 ignore:
   - ".tox/**/*"
diff --git a/docs/environment.yml b/docs/environment.yml
index b2dd6d6f3..3d9ce05ac 100644
--- a/docs/environment.yml
+++ b/docs/environment.yml
@@ -3,9 +3,14 @@ channels:
 dependencies:
   - python=3.8
   - ipython
+  - pip
+  - setuptools_scm
+  - toml
+
   - pip:
     - sphinx
     - pydata-sphinx-theme>=0.3.0
     - nbsphinx
     - sphinxcontrib-bibtex
     - sphinx-panels
+    - ../
diff --git a/docs/source/conf.py b/docs/source/conf.py
index fe5e6d062..9c3e36b14 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -16,11 +16,15 @@
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 #
+import datetime as dt
 import os
-import sys
 
+from pkg_resources import get_distribution
 
-sys.path.insert(0, os.path.abspath("../.."))
+
+year = dt.datetime.now().year
+
+author = "Janos Gabler"
 
 # Set variable so that todos are shown in local build
 on_rtd = os.environ.get("READTHEDOCS") == "True"
@@ -98,16 +102,21 @@
 
 # General information about the project.
 project = "estimagic"
-copyright = "2019 - 2021, Janos Gabler"  # noqa: A001
-author = "Janos Gabler"
+copyright = f"2019 - {year}, {author}"  # noqa: A001
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 #
 # The full version, including alpha/beta/rc tags.
-release = "0.1.4"
-version = ".".join(release.split(".")[:2])
+try:
+    release = get_distribution("estimagic").version.split("+")[0]
+except (KeyboardInterrupt, SystemExit):
+    raise
+except Exception:
+    release = "x.x.x"
+
+version = release
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
@@ -175,53 +184,3 @@
         "searchbox.html",
     ]
 }
-
-
-# -- Options for HTMLHelp output ------------------------------------------
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = "estimagicdoc"
-
-
-# -- Options for LaTeX output ---------------------------------------------
-
-latex_elements = {
-    # The paper size ('letterpaper' or 'a4paper').
-    "papersize": "letterpaper",
-    # The font size ('10pt', '11pt' or '12pt').
-    "pointsize": "11pt",
-    # Latex figure (float) alignment
-    "figure_align": "htbp",
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title,
-#  author, documentclass [howto, manual, or own class]).
-latex_documents = [
-    (master_doc, "estimagic.tex", "estimagic Documentation", "Janos Gabler", "manual")
-]
-
-
-# -- Options for manual page output ---------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [(master_doc, "estimagic", "estimagic Documentation", [author], 1)]
-
-
-# -- Options for Texinfo output -------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-#  dir menu entry, description, category)
-texinfo_documents = [
-    (
-        master_doc,
-        "estimagic",
-        "estimagic Documentation",
-        author,
-        "estimagic",
-        "One line description of project.",
-        "Miscellaneous",
-    )
-]
diff --git a/docs/source/explanations/inference/bootstrap_montecarlo_comparison.ipynb b/docs/source/explanations/inference/bootstrap_montecarlo_comparison.ipynb
index 44e8a79ee..b7c7e9995 100644
--- a/docs/source/explanations/inference/bootstrap_montecarlo_comparison.ipynb
+++ b/docs/source/explanations/inference/bootstrap_montecarlo_comparison.ipynb
@@ -3,8 +3,6 @@
   {
    "cell_type": "code",
    "execution_count": 1,
-   "metadata": {},
-   "outputs": [],
    "source": [
     "import random\n",
     "\n",
@@ -17,34 +15,35 @@
     "from joblib import Parallel, delayed\n",
     "\n",
     "from estimagic.inference import get_bootstrap_outcomes"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "# Bootstrap Monte Carlo Comparison"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "In this juypter notebook, I perform a Monte Carlo exercise to illustrate the importance of using the cluster robust variant of the bootstrap when data within clusters is correlated. \n",
     "\n",
     "The main idea is to repeatedly draw clustered samples, get both uniform and clustered bootstrap estimates in these samples, and then compare how often the true null hypothesis is rejected."
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "## Data Generating Process"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "The true data generating process is given by\n",
     "\n",
@@ -53,13 +52,12 @@
     "where the independent variable $x_{i,g} = x_i + x_g$ and the noise term $\\epsilon_{i,g} = \\epsilon_i + \\epsilon_g$ each consist of an individual and a cluster term.\n",
     "\n",
     "In the simulations I perform below, we have $\\beta_0 = \\beta_1 =0$. $x_i$ and $x_g$ are drawn from a standard normal distribution, and $\\epsilon_i$ and $\\epsilon_g$ are drawn from a normal distribution with $\\mu_0$ and $\\sigma=0.5$. The value of $\\sigma$ is chosen to not blow up rejection rates in the independent case too much."
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 2,
-   "metadata": {},
-   "outputs": [],
    "source": [
     "def create_clustered_data(nclusters, nobs_per_cluster, true_beta=0):\n",
     "    \"\"\"Create a bivariate clustered dataset with specified number of\n",
@@ -104,27 +102,27 @@
     "    cluster = np.array(cluster)\n",
     "\n",
     "    return pd.DataFrame({\"y\": y, \"x\": x, \"cluster\": cluster})"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "## Monte Carlo Simulation Code"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
-    "The following function computes bootstrap T-values. As suggested my Cameron and Miller (2015), critical values are the 0.975 quantiles from a T distribution with $n_{clusters} -1$ degrees of freedom."
-   ]
+    "The following function computes bootstrap T-values. As suggested my Cameron and Miller (2015), critical values are the 0.975 quantiles from a T distribution with `n_clusters` -1 degrees of freedom."
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 3,
-   "metadata": {},
-   "outputs": [],
    "source": [
     "def get_t_values(data, hyp_beta=0, cluster=False):\n",
     "    \"\"\"Get bootstrap t-values for testing the hypothesis that beta = hyp_beta.\n",
@@ -161,13 +159,13 @@
     "        )[\"x\"]\n",
     "\n",
     "    return (estimates.mean() - hyp_beta) / estimates.std()"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 4,
-   "metadata": {},
-   "outputs": [],
    "source": [
     "def monte_carlo(nsim, nclusters, nobs_per_cluster, true_beta=0, n_cores=-1):\n",
     "    \"\"\"Run a Monte Carlo simulation for rejection rates and a logit data generating process.\n",
@@ -203,27 +201,27 @@
     "    result = pd.DataFrame(np.abs(t_value_array) > crit, columns=[\"uniform\", \"cluster\"])\n",
     "\n",
     "    return result"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "## Results"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "Here, I perform Monte Carlo simulations with the above functions. In each simulation, the sample size is 1000, but the number of clusters varies across simulations. Be warned that the code below takes a long time to run."
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 5,
-   "metadata": {},
-   "outputs": [],
    "source": [
     "np.random.seed(505)\n",
     "random.seed(505)\n",
@@ -233,16 +231,24 @@
     "for g, k in [[20, 50], [50, 20], [100, 10], [200, 5], [500, 2]]:\n",
     "\n",
     "    results_list.append(monte_carlo(500, g, k))"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 6,
-   "metadata": {},
+   "source": [
+    "mean_rejection_data = pd.DataFrame([x.mean() for x in results_list])\n",
+    "mean_rejection_data[\"nclusters\"] = [20, 50, 100, 200, 500]\n",
+    "mean_rejection_data.set_index(\"nclusters\", inplace=True)\n",
+    "\n",
+    "print(mean_rejection_data)"
+   ],
    "outputs": [
     {
-     "name": "stdout",
      "output_type": "stream",
+     "name": "stdout",
      "text": [
       "           uniform  cluster\n",
       "nclusters                  \n",
@@ -254,61 +260,55 @@
      ]
     }
    ],
-   "source": [
-    "mean_rejection_data = pd.DataFrame([x.mean() for x in results_list])\n",
-    "mean_rejection_data[\"nclusters\"] = [20, 50, 100, 200, 500]\n",
-    "mean_rejection_data.set_index(\"nclusters\", inplace=True)\n",
-    "\n",
-    "print(mean_rejection_data)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 7,
-   "metadata": {},
+   "source": [
+    "y = mean_rejection_data\n",
+    "x = y.index.values\n",
+    "\n",
+    "plt.rcParams[\"figure.figsize\"] = (8, 5)\n",
+    "plt.xlabel(\"Number of clusters\", fontsize=12)\n",
+    "plt.ylabel(\"Rejection rate\", fontsize=12)\n",
+    "plt.plot(x, y[\"uniform\"], label=\"Uniform Bootstrap\", color=\"blue\", marker=\"o\")\n",
+    "plt.plot(x, y[\"cluster\"], label=\"Cluster Bootstrap\", color=\"red\", marker=\"o\")\n",
+    "plt.legend()\n",
+    "plt.suptitle(\"Comparison of Rejection Rates\", fontsize=15)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/plain": [
        "Text(0.5, 0.98, 'Comparison of Rejection Rates')"
       ]
      },
-     "execution_count": 7,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 7
     },
     {
+     "output_type": "display_data",
      "data": {
-      "image/png": "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OZLCwkJGjhzJ4sWLk5b/73//44UXXuCqq67aNQzvXXfdRf/+/SksLOSss85i0aJF3Hfffdx+++0UFxfz+uuvM2bMGH70ox8xYsQIrrnmGqZOncrRRx/NoEGDOProo5k7d+6uY3P66adz8skn069fP2688cZa/U6SSjYcXkN/pWOI20Rz5oRhIR97LO2bFhGptuoMcVsXY9zeeeedfvnll1c6L36I10ceeaTCMK2jRo3ySZMmeUlJiR9//PG7yteuXevuYWjcadOmubv7tm3b/KijjvIVK1a4u/tTTz3l3/72t3ct9/3vf7/S/T/yyCPeoUMHLyoq8v3228+HDh3qZWVl7u5+2mmn+aOPPuru7g899JCffvrpVZaff/75/swzz+zadpcuXXzLli0V6hw/tG9snVGjRu3a5/r163379u3u7j5hwgQ/44wzdtWzc+fOvmrVql1D3cY+e1U0xG0d6tMHWrZUkp6I1EPZGOO2lnr37s2CBQu45JJLGDVqFCeeeOJuy8ydO5eZM2dywgknALBjxw66dOmya37isLfxzjzzTO6++27cnYsuuohbb72Va6+9lilTpvC3v/0NgPPOO4+rr74aIGl5osLCQkaPHs1Xv/pVvvrVrybd/ze/+U3y8vKAMPDN+eefz8cff4yZsX379l3LnXDCCbRv3x4IQwK/8cYbDB5caa+3NaZm/Gpo2lTd5opIA1UHY9wOGDCA6dOn73G5pk2bsnPnzl3TsaFc27Vrx3vvvcfw4cO55557uOCCC3Zb190ZMGAAM2bMYMaMGXzwwQf85z//2TU/cdjbypgZX/7yl3nttdeSzq9O+YsvvshFF13E9OnTOeyww5Lek4+v209/+lNGjBjBzJkz+cc//lFhONvE/aRjSNtECvbVVFioK3sRqYfuuCOMVZvs1bNn5evFxrit7LWHq/rjjjuOrVu38mBcy8C0adN49dVXKyxXUFDAjBkz2LlzJ0uWLGHq1KkArFq1ip07d/L1r3+dX/7yl7zzzjsA7LXXXruGh+3Xrx8rV65kypQpAGzfvp1Zs2aldkzivPHGG7tG4zv66KN56qmnABg/fvyuIWSTlcfXJ/YZRowYwS233MK6devYuHFjhWUqs379erp16waE+/TxJkyYwJo1a9i8eTPPP/88xxxzTLU/355kLNib2clmNtfM5pnZtZXMP8jMppjZ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\n",
+      "image/png": "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OZLCwkJGjhzJ4sWLk5b/73//44UXXuCqq67aNQzvXXfdRf/+/SksLOSss85i0aJF3Hfffdx+++0UFxfz+uuvM2bMGH70ox8xYsQIrrnmGqZOncrRRx/NoEGDOProo5k7d+6uY3P66adz8skn069fP2688cZa/U6SSjYcXkN/pWOI20Rz5oRhIR97LO2bFhGptuoMcVsXY9zeeeedfvnll1c6L36I10ceeaTCMK2jRo3ySZMmeUlJiR9//PG7yteuXevuYWjcadOmubv7tm3b/KijjvIVK1a4u/tTTz3l3/72t3ct9/3vf7/S/T/yyCPeoUMHLyoq8v3228+HDh3qZWVl7u5+2mmn+aOPPuru7g899JCffvrpVZaff/75/swzz+zadpcuXXzLli0V6hw/tG9snVGjRu3a5/r163379u3u7j5hwgQ/44wzdtWzc+fOvmrVql1D3cY+e1U0xG0d6tMHWrZUkp6I1EPZGOO2lnr37s2CBQu45JJLGDVqFCeeeOJuy8ydO5eZM2dywgknALBjxw66dOmya37isLfxzjzzTO6++27cnYsuuohbb72Va6+9lilTpvC3v/0NgPPOO4+rr74aIGl5osLCQkaPHs1Xv/pVvvrVrybd/ze/+U3y8vKAMPDN+eefz8cff4yZsX379l3LnXDCCbRv3x4IQwK/8cYbDB5caa+3NaZm/Gpo2lTd5opIA1UHY9wOGDCA6dOn73G5pk2bsnPnzl3TsaFc27Vrx3vvvcfw4cO55557uOCCC3Zb190ZMGAAM2bMYMaMGXzwwQf85z//2TU/cdjbypgZX/7yl3nttdeSzq9O+YsvvshFF13E9OnTOeyww5Lek4+v209/+lNGjBjBzJkz+cc//lFhONvE/aRjSNtECvbVVFioK3sRqYfuuCOMVZvs1bNn5evFxrit7LWHq/rjjjuOrVu38mBcy8C0adN49dVXKyxXUFDAjBkz2LlzJ0uWLGHq1KkArFq1ip07d/L1r3+dX/7yl7zzzjsA7LXXXruGh+3Xrx8rV65kypQpAGzfvp1Zs2aldkzivPHGG7tG4zv66KN56qmnABg/fvyuIWSTlcfXJ/YZRowYwS233MK6devYuHFjhWUqs379erp16waE+/TxJkyYwJo1a9i8eTPPP/88xxxzTLU/355kLNib2clmNtfM5pnZtZXMP8jMppjZVjO7MmHePmb2rJl9aGZzzOyoTNU7UWEhrFgBtUw2FRHJrHHjwpi28Wo5xq2Z8dxzzzFhwgQOOOAABgwYwA033EDXrl0rLHfMMcfQq1cvBg4cyJVXXsmhhx4KwKeffsrw4cMpLi5mzJgx3HTTTQCMGTOGCy+8kOLiYnbs2MGzzz7LNddcQ1FREcXFxSk/4vb0009TXFxMYWEh7777Lj/96U8BuOuuu3jkkUcoLCzk8ccf35Xcl6z8rLPO4tZbb2XQoEF8/PHHnHvuuQwcOJBBgwbxwx/+kH322Ycvf/nLPPfcc7sS9BJdffXVXHfddRxzzDHs2LGjwryhQ4dy3nnnUVxczNe//vW0N+FDhoa4NbM84CPgBKAUmAac7e6z45bZD+gJfBVY6+63xc17DHjd3f9oZs2BfHdfV9U+0znEbbzJk2HECHj5Zajk9pKISMZUd4hbjXFb/zz66KOUlJRw9913V2u96g5xm6kr+yHAPHdf4O7bgKeA0+MXcPcV7j4N2B5fbmZtgWOBh6Lltu0p0NcldZsrIg3W6NGwaBHs3Bl+KtA3GpkK9t2AJXHTpVFZKnoDK4FHzOxdM/ujmVWakWFmY82sxMxKVq5cWbsaJ9G+PXTrpmAvIiK1N2bMmGpf1ddEpoJ9ZamFqd4/aAocCvzB3QcBXwC73fMHcPcH3H2wuw/u2LFjzWqagqIiZeSLiEjDkalgXwrsHzfdHUi1L8RSoNTd346mnyUE/6wpLIQ5c2DbtmzWQkQkPJomjUtNfueZCvbTgAPNrFeUYHcW8EIqK7r7MmCJmfWLikYCVXdSXMcKC2H7doh6OxQRyYqWLVuyevVqBfxGxN1ZvXo1LVu2rNZ6GelBz93LzOxi4GUgD3jY3WeZ2YXR/PvMrDNQArQFdprZ5UB/d98AXAKMj04UFgDfzkS9kykqCj/fe688YU9EJNO6d+9OaWkpdZWjJPVTy5Yt6d69e7XWyVh3ue7+EvBSQtl9ce+XEZr3K1t3BpD+Bw9rqG9faN5cSXoikl3NmjWjV69e2a6GNADqQa8GmjaFAQMU7EVEpGFQsK8hZeSLiEhDoWBfQ4WFsGxZ6DpXRESkPlOwr6HCwvDzgw+yWw8REZE9UbCvoViwV1O+iIjUdwr2NdSxI3TpoiQ9ERGp/xTsa0Fj24uISEOgYF8LRUUwa1boTU9ERKS+UrCvhcLC0D/+Rx9luyYiIiLJKdjXQixJT035IiJSnynY18JBB0GzZsrIFxGR+k3BvhaaNYP+/XVlLyIi9ZuCfS0pI19EROo7BftaKiqCTz+F1auzXRMREZHKKdjXkpL0RESkvlOwryUFexERqe8U7GupU6fwUka+iIjUVwr2aaAkPRERqc8U7NOgsDB0m1tWlu2aiIiI7E7BPg2KimDLFvj442zXREREZHcK9mmgJD0REanPFOzT4KCDoGlTBXsREamfFOzToEULOPhgZeSLiEj9pGCfJsrIFxGR+krBPk0KC2HJEli7Nts1ERERqUjBPk2KisJPXd2LiEh9o2CfJsrIFxGR+krBPk06d4YOHRTsRUSk/slYsDezk81srpnNM7NrK5l/kJlNMbOtZnZlJfPzzOxdM/tnZmpcPWahKV8Z+SIiUt9kJNibWR5wD3AK0B8428z6Jyy2BrgUuC3JZi4D5tRZJdOgsBBmzoQdO7JdExERkXKZurIfAsxz9wXuvg14Cjg9fgF3X+Hu04DtiSubWXdgFPDHTFS2pgoLYfNmmD8/2zUREREpl6lg3w1YEjddGpWl6g7gamBnVQuZ2VgzKzGzkpUrV1a7krUVy8hXU76IiNQnmQr2VkmZp7Si2WnACnefvqdl3f0Bdx/s7oM7duxY3TrW2sEHQ16ekvRERKR+yVSwLwX2j5vuDixNcd1jgK+Y2SJC8/9xZvZEequXHi1bQr9+CvYiIlK/ZCrYTwMONLNeZtYcOAt4IZUV3f06d+/u7gXReq+4+7l1V9XaUUa+iIjUNxkJ9u5eBlwMvEzIqP+Lu88yswvN7EIAM+tsZqXAj4CfmFmpmbXNRP3SqbAQPvkE1q/Pdk1ERESCppnakbu/BLyUUHZf3PtlhOb9qrYxGZhcB9VLm1hPeh98AEOHZrcuIiIioB700k4Z+SIiUt8o2KdZ166w775K0hMRkfpDwT7NzDS2vYiI1C8K9nWgqCjcs99ZZRdAIiIimaFgXwcKC+GLL2DBgmzXRERERMG+TmhsexERqU8U7OvAgAHQpIky8kVEpH5QsK8DrVpB3766shcRkfpBwb6OKCNfRETqCwX7OlJUFBL0NmzIdk1ERKSxU7CvI7EkvZkzs1sPERERBfs6Egv2StITEZFsU7CvI/vvD/vso/v2IiKSfQr2dUTd5oqISH2hYF+HYsFe3eaKiEg2KdjXoaIi2LgRFi3Kdk1ERKQxU7CvQ+o2V0RE6gMF+zo0YEC4d6+MfBERyaZqBXsz29/MjqyryuSa1q3hwAN1ZS8iItmVUrA3sx5m9ibwIfDfqOwbZvbHuqxcLlBGvoiIZFuqV/b3Ay8CewHbo7IJwAl1UalcUlgI8+eHRD0REZFsSDXYDwF+4+47AQdw9/XA3nVVsVxRVATu6jZXRESyJ9VgvxzoE19gZv2BxWmvUY5RRr6IiGRbqsH+NuCfZvZtoKmZnQ08DdxcZzXLET17Qtu2ysgXEZHsaZrKQu7+sJmtAcYCS4BvAT919+frsG45Qd3miohItqUU7M3siCiwP59QPsTdp9ZBvXJKYSE88US4d2+W7dqIiEhjk2oz/oQk5f9OV0VyWWEhbNgAn3yS7ZqIiEhjVGWwN7MmZpYX3ppF07HXgUBZqjsys5PNbK6ZzTOzayuZf5CZTTGzrWZ2ZVz5/mY2yczmmNksM7usOh+wPlCSnoiIZNOeruzLgG1AfvR+e9xrNnBvKjuJThjuAU4B+gNnR9n88dYAlxKSARPrcIW7HwwcCVxUybr12sCB4aeCvYiIZMOe7tn3Agx4FTg2rtyBle6+OcX9DAHmufsCADN7CjidcMIQNui+AlhhZqPiV3T3z4DPovefm9kcoFv8uvVdmzZwwAHKyBcRkeyoMti7e+wuc89a7qcbIYs/phQ4orobMbMCYBDwdi3rk3HKyBcRkWxJKRsfwMy+AgwDOhCu9gFw92+lsnolZZ7qvqP9twH+Clzu7huSLDOW8HggPXr0qM7m61xRETz/PGzaBPn52a6NiIg0JqkOhPNzQv/4TYBvAquBk4B1Ke6nFNg/bro7sDTVSppZM0KgH+/uf0u2nLs/4O6D3X1wx44dU918RhQWqttcERHJjlQfvfsOcIK7/xDYFv38MlCQ4vrTgAPNrJeZNQfOAl5IZUUzM+AhYI67/y7F/dU7ysgXEZFsSbUZfx93j12TbjOzZu4+1cyGpbKyu5eZ2cXAy0Ae8LC7zzKzC6P595lZZ6AEaAvsNLPLCZn7hcB5wAdmNiPa5PXu/lKKda8XevUKiXoK9iIikmmpBvv5ZjbA3WcBM4Hvm9laYG2qO4qC80sJZffFvV9GaN5P9AaV3/NvUJo0CY/gKSNfREQyLdVg/xOgffT+WuBJoA3wg7qoVK4qLISnn1a3uSIikll7vGdvZk2ALcBbAO4+1d37uHvnqpLlZHdFRbBuHZSWZrsmIiLSmOwx2Lv7TuDv7r4tA/XJabEkPTXli4hIJqWajf+amR1ZpzVpBNRtroiIZEOq9+w/Af5lZn8n9IS3q0Mcd/9ZXVQsF7VtG7LyFexFRCSTUg32rSgfyz4+Y75aveBJaMpXM76IiGRSSsHe3b9d1xVpLAoL4R//gM2boVWrbNdGREQag1Tv2UuaFBXBzp0wu8GM2SciIg2dgn2GKSNfREQyTcE+w3r3DqPeKUlPREQyRcE+w/LywiN4CvYiIpIp1RnPvh9QROgmdxd3fzjdlcp1hYXw17+q21wREcmMlIK9mV0P/Ax4D9gUN8sBBftqKiyEBx+EpUuhW7ds10ZERHJdqlf2lwND3F2Nz2lQVBR+vv++gr2IiNS9VO/ZbwY+rMuKNCaxbnOVkS8iIpmQarD/KfB7M+tiZk3iX3VZuVy1zz7Qo4eS9EREJDNSbcZ/NPp5QVyZEe7Z56WzQo1FUZGCvYiIZEaqwb5XndaiESoshJdegi1boGXLbNdGRERyWap9438CEDXbdwKWR+PcSw0VFsKOHTBnDgwalO3aiIhILkvpnruZtTWzPwFbgE+BzWb2mJntXae1y2HxGfkiIiJ1KdUEu7uA1sAhhOFuBwL5UbnUQJ8+ofleGfkiIlLXUr1nfzLQ291jHep8ZGbfBubXTbVyX14eHHKIruxFRKTupXplvwXomFDWAdia3uo0LkVF4crePds1ERGRXJZqsP8jMMHMLjSzU8zsQuBl4IG6q1ruKyyEVatg2bJs10RERHJZqs3444ClwDlA1+j9Lahf/FqJjW3//vvQpUt26yIiIrkr1UfvYgPeKLinUXywP+mk7NZFRERyV9Jgb2bnufvj0fvvJFtOQ9zW3L77QvfuysgXEZG6VdWV/dnA49H785IsoyFua6mwUBn5IiJSt5Im6Ln7qXHvRyR5HZfqjszsZDOba2bzzOzaSuYfZGZTzGyrmV1ZnXUbsqKi0Ivetm3ZromIiOSqVHvQezdJeUmK6+cB9wCnAP2Bs82sf8Jia4BLgdtqsG6DVVgIZWUh4IuIiNSFVB+965NYYGYG9E5x/SHAPHdf4O7bgKeA0+MXcPcV7j4N2F7ddRuy+CQ9ERGRulBlNn7UHz5A87j3MQXArBT30w1YEjddChyRgXXrvb59oUWLkKR3XrLMCBERkVrY06N385O8d+BN4JkU92OVlKXab1zK65rZWGAsQI8ePVLcfHY1bQoDBujKXkRE6k6Vwd7dbwQws7fc/eVa7KcU2D9uujuhY560ruvuDxD16jd48OAG0wltYSH861/ZroWIiOSqVO/ZDzKzw+MLzGyImV2d4vrTgAPNrJeZNQfOAl7IwLoNQlERLF8eXiIiIumWarC/DJidUDYbuDyVld29DLiY0J/+HOAv7j4r6mv/QgAz62xmpcCPgJ+YWamZtU22bor1bhCUpCciInUp1b7xm7N7lvw2oGWqO3L3l4CXEsrui3u/jNBEn9K6ueSjj8LPE0+Enj1h3DgYPTq7dRIRkdyR6pX9dOAHCWUXAu+ktzqNz/jxcMUV5dOffAJjx4ZyERGRdDBPYTB1MxsATAA+I2Tl9wE6ASe4e2Lzfr0wePBgLylJqc+frCooCAE+Uc+esGhRpmsjIiINlZlNd/fBlc1LddS7WWbWFziNkBn/N+Cf7r4xfdVsnBYvrl65iIhIdaV6zx5332hmbwLd3P2tOqxTo9KjR+VX9g2kmwAREWkAUu0bv0cU6D8E/huVfcPM/liXlWsMxo2D/Pzdy4cPz3hVREQkR6WaoHc/8CKwF+VZ+ROAE+qiUo3J6NHwwAPhHr0Z7L8/DBoEjz0Gv/1ttmsnIiK5INVm/CHAKHffaWYO4O7rzWzvuqta4zF6dMVH7bZvD9NXXgmbNsFPfhJOBERERGoi1WC/nJCB/1GsIBpmVmlkdaBZM3jySWjVCn72M/jiC7jpJgV8ERGpmVSD/W3AP83sJqCpmZ0NXA/8ps5q1sg1bQqPPBLu5998c7jCv+MOaJLqjRcREZFIqo/ePWxmawgjyi0Bzgd+6u7P12HdGr0mTeDee8MV/u23w+bNcN99kJeX7ZqJiEhDUp1H754Hnq+zmkilzEKiXuvW8KtfhSv8xx4LV/4iIiKpSBoyzOw8d388ev+dKraxDVjo7m+mu3ISmMEvfxma9K+/HrZsgT//GZo3z3bNRESkIajq+vBs4PHo/XlVLNcE6G1mk9z9W2mrmezmuutCwL/8cvja1+DZZ0MTv4iISFWSBnt3PzXu/YiqNmJm+YR+86WOXXZZCPAXXginnQZ//zu0aZPtWomISH2Wcm63mbU3s/PM7KpouquZdQdw902ER/MkA8aOhT/9CSZPhpNOgvXrs10jERGpz1LtLncYMBcYDfwsKj4Q+ENsGXdfmfbaSVLnngtPPw1Tp8LIkbB6dbZrJCIi9VWqV/Z3AGe6+8lAWVT2NqFnPcmSb3wDnn8eZs6EESNg+fJs10hEROqjVIN9gbtPjN579HMb1Xh0T+rGqFHw4oswfz4MGwalpdmukYiI1DepBvvZZnZSQtnxwAdpro/UwMiR8PLLsHQpHHssLFyY7RqJiEh9kmqwvwIYb2aPAa3M7H7gUeCquqqYVM/QoTBxIqxbFwL+Rx/tcRUREWkkUgr27v4WUATMAh4GFgJD3H1aHdZNqunww0OG/tatIeDPnJntGomISH2Q8qN37v6pu9/i7he5+2+Afc3smTqsm9RAYSG89lroP3/4cHjnnWzXSEREsq3KYG9m+Wb2SzP7h5n9zszamllvM3sO+B+wIjPVlOo46KAQ8Nu0geOOgylTsl0jERHJpj1d2d8DfBmYTUjI+yvwKqE5v8DdL6rb6klNHXBACPgdO8IJJ8CkSdmukYiIZMuegv1JwInufg1wKjASOMfdf+Luq+q8dlIrPXqEgN+zJ5x6Kvz739mukYiIZMOegn0bd18B4O6lwEZ3f73uqyXp0qULvPpqaNr/yldCJzwiItK47KlTnKZmNgKwWEHitLu/Ukd1kzTp0AFeeQVOOSX0uvf443D22dmulYiIZMqegv0KwqN2MasTph3one5KSfq1awcTJsCXvwyjR8PmzfCd72S7ViIikglVNuO7e4G796rilXKgN7OTzWyumc0zs2srmW9mdlc0/30zOzRu3g/NbJaZzTSzP5tZy+p9TAHYay946aWQsPfd78I992S7RiIikgkpP2dfG2aWR8jsPwXoD5xtZv0TFjuFMJLegcBYohH1zKwbcCkw2N0PAfKAszJR71yUnw8vvACnnw4XXwy33prtGomISF3LSLAnjI43z90XuPs24Cng9IRlTgf+5MFbwD5m1iWa15TQTW9TIB9YmqF656QWLeCZZ+DMM+Hqq+HGG8F9z+uJiEjDlKlR67oBS+KmS4EjUlimm7uXmNltwGJgM/Afd/9PXVa2MWjWDMaPh1at4IYb4Isv4OabwWyPq4qISAOTqSv7ykJI4rVkpcuYWTvCVX8voCvQ2szOrXQnZmPNrMTMSlauXFmrCjcGeXnw0EPwgx+E5vxLLoGdO7NdKxERSbdMXdmXAvvHTXdn96b4ZMscDyx095UAZvY34GjgicSduPsDwAMAgwcPVsN0Cpo0gbvvDlf4v/1tyNJ/4IFwIiAiIrkhU8F+GnCgmfUCPiUk2J2TsMwLwMVm9hShiX+9u39mZouBI80sn9CMPxIoyVC9GwWzcGXfujX84hch4D/2WGjqFxGRhi8jwd7dy8zsYuBlQjb9w+4+y8wujObfB7xE6JJ3HrAJ+HY0720zexZ4BygD3iW6epf0MQuJevn5cO21IeA/9VRI5hMRkYbNPEfTsAcPHuwlJWoAqInf/x4uvRROPhn+9rfQxC8iIvWbmU1398GVzctUgp40IJdcAg8+CC+/DKNGwcaN2a6RiIjUhoK9VOqCC0If+q+9BieeCOvWZbtGIiJSUwr2ktTo0fCXv0BJCYwcCas0qLGISIOkYC9VOuOMMCzurFkwYgTcey8UFIRH9goKQsc8UnPjx+t4ikjdU4KepGTixDBEbllZxa518/PDc/mjR2evbg3V+PEwdixs2lRepuMpIjVVVYKegr2krHNnWL589/JWrcJ9fame//wnPOKYqGdPWLQo49URkQauqmCfqU51JAesWFF5+ebNCk41UVmgB/jkE7jiipAnceyx0KZNZuslIrlHV/aSsoKCEIgS6Uq0ZpIdz1hHRlu3QtOmcMQRIfCPHAlHHgnNm2e0miLSQOg5e0mLcePCPeV4+fmhXKov2fF86CFYuxYmTIArr4Rt2+BXv4Jhw6Bdu9DZ0a23wjvvaOAiEUmNruylWsaPhx//GBYvhh49QsBSMlnNpXo8162DyZNDouTEiTBnTijfd9/wlETsyv/AAzVMsUhjpQS92lB0k3po6VJ45ZXy4L9kSSjv3r088I8cCV27ZreeIpI5CvY1pWejpAFwh3nzygP/pEmwenWYd9BB5YF/+PBwG0BEcpOCfU0pI00aoJ074b33yoP/a6+F89UmTeDQQ8uD/zHH7J4zICINl4J9TTVpUrEHmRgzZUZJg7FtG7z9dnnwf+ut0DlS8+Zw9NHlwf/ww0P2v4g0TAr2NaUre8lBGzfC66+XB/8ZM0L5XnuFjP9Y8D/kECX7iTQk6lSnpsaN2/2efV6enjWTBq1Nm9D18SmnhOlVq8J9/ljw/+c/Q/l++8Fxx5UH/169sldnEakdBfuqxJLwYtn4bdvC+vWwcGF26yWSRh06wDe/GV4QvuqxwD9xIjz1VCjv1as88B93XDgZEJGGQc341eEO558fBnofPx7OOSe92xepZ9zDM/2xwD95cjjfBRg4sDz4H3tsOBcWkezRPft02roVTjoJpkwJ//2GDk3/PkTqqbKy0HNfLPi/+SZs2RLubg0ZUh78jzqqvNtfEckMBft0W7Mm/DdbvToE/QMPrJv9iNRzW7bA//5XHvynTQsPqrRqFc6DY8F/0KBwQiAidUfBvi7Mnx9GJWnXLgT89u3rbl8iDcT69fDqq+XBf9asUN6uXejUJxb8+/VTpr9IuinY15U33wz/uYYMCaOWqN1SpIJlyyp26xt7krVr14rd+nbvnt16iuQCBfu69NRTcPbZIXP/8cd1uSKShDssWFAe+F95JTz2B9C3b3ngHzEiDPAjItWj5+zr0llnhf9gP/4x9OkDN9yQ7RqJ1EtmcMAB4TV2bLi3/8EH5cH/8cfhD38Iyw0aVB78hw6F1q2zXXuRhk1X9ungDt/9LjzyCDz2GHzrW5nZr0gO2b4dpk4tD/5TpoSyZs1CPmws+A8ZEspEpCI142fCtm2hS7LXXw/374cNy9y+RXLQF1/AG2+UB/933w3n1W3ahOf6Y8F/4MAwjIVIY6dgnynr1oWRRZYtC5cl/fpldv8iOWzNmord+n70USjv0KFit769eyt1RhonBftMWrgwPJLXpk0YXqxjx8zXQaQRKC2t2K3v0qWhvGfPit36du6c3XqKZEq9CPZmdjJwJ5AH/NHdf5Mw36L5pwKbgDHu/k40bx/gj8AhgAPfcfcpVe0va8Eewniiw4eHwcMnToSWLbNTD5FGwh3mzi0P/JMmhYY2gAEDyoP/sGGw995ZrapInakq2GfkTpeZ5QH3AKcA/YGzzax/wmKnAAdGr7HAH+Lm3Qn8290PAoqAOXVe6do44gh44onQtdiYMSHtWKQy48eHoZSbNAk/x4/Pdo0aJDM46CC46CL429/CI33TpsFvfhOe6X/wQTj99ND31ZFHhodnXnkl9AAo0hhk5MrezI4CbnD3k6Lp6wDc/aa4Ze4HJrv7n6PpucBw4AvgPaC3V6OyWb2yj7n1Vrj6arj+eg2LK7sbP373IZTz8+GBB8pHXJS02Lq1fDiLiRND1v+OHaHR7Zhjyq/8DztM3fpKw1UfnrPvBiyJmy4FjkhhmW5AGbASeMTMioDpwGXu/kXdVTdNrrwS5s2DX/86PFz8ne9ku0aSbe6wfDnMnAmXXFIx0EOYvuSSMIRc797hal8Pmddaixbhztrw4fDLX8KGDfDaa+XB//rrw3J7712xW9+DD1ayn+SGTAX7yv5cEq/Sky3TFDgUuMTd3zazO4FrgZ/uthOzsYRbAPTo0aNWFU4LM7j7bli0CL73vfLMIWkcPv88dA7/wQfhNXNm+BnrNi6ZtWvhK18pn+7UKQwm37v37j+7d9elaA20bQunnRZeACtWVOzW9+9/D+VdulTM9K8P/1ZEaqIhNOM78Ja7F0TlXwKudfdRVe2zXjTjx6xfH7oBW7Ik3Mfvn5iuIA3atm3hObDEoL5oUfkyrVvDIYeEh8IHDgzvzz8/pJQn6t4dnnkmPNmxYEHFn4sXV8wBado0nEQmOxnYd19dmtbAwoUVu/VdsSKU9+lTsVvfDh2yW0+ReFnPxjezpsBHwEjgU2AacI67z4pbZhRwMSEb/wjgLncfEs17HbjA3eea2Q1Aa3e/qqp91qtgD+Gf9BFHhJuEb70VrtakYdm5M/weE4P63LmhqzcIwbdfv/KAHgvuPXvu3vNLTe7Zb98eThpjwT/xhCCx1WCvvSo/CejVK9wiaNUqbYcnV7mHX3Us+L/6ami0ASguLg/+X/pSeOJWJFuyHuyjSpwK3EF49O5hdx9nZhcCuPt90aN3dwMnEx69+7a7l0TrFhMevWsOLIjmra1qf/Uu2AOUlISuvwYODM8G5ednu0aSzKpVuwf1mTNh48byZXr23D2o9+sHzZunvp/x40Nq+OLFoY143LjaJed9/nnlJwGxn4np5126JD8Z6NpVtwgqUVYWMv1jwf9//wuNO02bhkz/WPA/4ojqfRVEaqteBPtMq5fBHuD55+GMM8LrL39RP5/Z9sUXMHt2xaD+wQchiS6mffuKze8DB4aHt9u2zV69ayKWHBgf/OPfl5aGZWKaNw8nNMlOBtq1y95nqUc2bQqjXceC//Tp4TC2bh2u9mPBv6hIf+5StxTs65vbb4cf/Sg8lnfzzdmuTeNQVgYff7x7UF+woDzAtWoVgnji1XqnTo3jvve2bWHA+WQtA2vWVFx+n32S5wr07BlS4BuhtWth8uTy4P/hh6G8fftwnz8W/Pv0aRxfK8kcBfv6xj08XnXPPXD//eG+raSHe7hCTQzqc+aEYAbh8qpv34oBfeDAEKjUbJ3c+vXJbw8sWhQeZo8xg27dkp8MdO7caC5zP/20YqZ/LCdz//3LA//IkeGOikhtKNjXR2VloUuvl1+Gl16CE0/Mdo0anrVrdw/qM2eGoBTTvfvuV+oHHaQujNNt50747LPkJwOfflpx+RYtQuBPdjLQ0G6RpMg9NDDFd+sbazA5+ODywD98eGg4EakOBfv66vPPw029Dz8Mj0gtW5aeJK1cs3lzuDJPDOrxAWSffXYP6gMG6L5yfbFlS/ktgspOBuJP0CD8PSTLFejRI2cy33buhBkzyoP/66+HHIAmTUJvfrHgf8wxenBC9kzBvj77/e/hsssqJkY11i5Td+yA+fN3D+off1z+bHmLFqGfgsRn1rt10w3Qhmzt2spPAhYuDLcIYo82QoiE3bsnPxlowDkW27aFJ3Njwf/tt0MjYIsWYfTsWPAfPDhk/4vEU7CvzwoKwhVPorZt4YYbwj+u/fYLr06dQpZPQ/8rdw9NvolBffbscBUP4Z91nz67B/U+fRr+55fq2bEjjF+b7GTgs88qLp+fH/6ukp0MNKCH4T//PFztx4L/e++F8rZtwwh+seA/YECDPb+RNFKwr8+aNKl4Vb8nZiHgJ54EJHuf7X7V16+vvMvY+MzuLl12D+r9+6sfAknN5s3h6r+yk4EFCyr2jQDQsWPyXIH996/XJ5MrV4b7/LHgP39+KO/UqWK3vgUFWa2mZImCfX2W7Mq+R49wM2/FivBavnz39/Flifc8Y/Lz93xCEHvfvv2es9GTdQKzdWvoSS4xqC9eXL7uXnvtHtQPOUR9jkrdcYfVq5PnCixeHNrJY/Lywvc62clAhw716hL6k0/KA//EieXdQ/TuXR74jzsunN9I7lOwr8/SNczpli3htD/ZiUHi+x07dt9Gkybhn1myE4LZs+Heeyv2wpaXF+avWFH+T7NZs5DxntgRTY8e9eofpQhlZeFZuGQnA7FO8WNat05+e6BXr6y2RrmHP9FY4J88OYzuB1BYWB78jz02nHdL7lGwr+/S3WXqnuzcGRKiUj0xiHUEnkyrVqGToFhQ79s3BHyRhm7jxnCLoLIeBxcu3H2I4k6dkp8MZHiEwrKy0JtfLPi/+WZogGvaFIYMKQ/+Rx7ZaPs/yjkK9lI7mzaFVoNevSrPLzCrOBKbSGPgHk6Gk/U4mDhCYbNm4WQ+2clAHY9QuHlz6Mc/FvxLSkL1WrWq2K1vcbH6lmqoFOwlPZLlF/TsWXE4VxHZfYTCxJ+JIxS2bZs8V6CgIO0dQa1bF0bwiwX/2bNDebt2Fbv17dtXd98aCgV7SY905ReISPkIhclOBhJHKOzaNfnJQNeute5++LPPKnbrG8ut7d69YqZ/t2612o3UIQV7SZ9M5xeINEY7d4a8mWQnA5WNUFhQkPxkoJp977qHx/pigf+VV8JDDRBGcY4F/hEj1EllfaJgLyKSS7ZuDSfcyU4G1q6tuPw++yTPFUhhhMKdO+H998uD/2uvhdGhzeDQQ8uD/9Ch6h4jmxTsRUQak3XrkicOLlxYPgIklI9QmOxkoJIRCrdtg6lTy4P/W2+FFIXmzeGoo8qD/+GH68GcTFKwFxGRIDZCYbJcgcQRClu2rLr74bZt+eKLit36zpgRbgXstVd4rj8W/A85pNGMbJwVCvYiIpKa2AiFybofjvXUE9O+/W4nARva9+LNz3rzz/d7MGFyMz7+OCzasWPFZL/evTP/8XKZgr2IiNSee8gHSJYr8Mknu49QuP/+bOnai8VNe/P+hl5M+qQ376zrxQJ6k99zP0Yeb7u69e3UKXsfLRco2IuISN3bsSPcBkh2MrBsWYXFt+Tls9B7MW9nCP5bOvdi38N7c+AJvTj0671o27XhjFBYHyjYi4hI9m3aVLH74YUL8fkL2Dx7IXmLF9BiW8URCtc07cgX+/Wmeb9etD+8N00PjLtdUM9HKMyGqoK9jpSIiGRGfn4Yvrp//11FBuTDrhEKt85ZwLwJC/n09QVsmr2QvZYuoGDpVNpPegYoH8DL8/KwqrofrmcjFGabruxFRKTe2rAhdOs7aUIZs14uZftHC+jFQvq3WMDhHRfSt+kCOny+kKarE0YobNMm+YlAQUFOdgigZnwREckJy5dX7NY3NixHn84b+cbgRZxwwAIObbeQfdbsYYTCzp0rDk8cf0LQrVuDHA1IwV5ERHLSggUVu/VduTKU9+0b163vcGffshXJEweXLNl9hMKePZN3P9yuXb28RaBgLyIiOW/nTpg5szz4v/oqbNwY4vKgQeXP+H/pS9C6ddyK27dX3f1wbGCAmLZtKwb/+Pc9e+55hMI6GmNEwV5ERBqd7dth2rTy4D9lSujqt1kzOPLI8iv/I47YQ7e+GzZU3f1w4giF3bolbxWYNAm+9706GT1UwV5ERBq9TZvgjTfKg/8774SHAFq3rtitb2FhNbr1jY1QmKz74cQRCpPp2bM8AaGG6kWwN7OTgTuBPOCP7v6bhPkWzT8V2ASMcfd34ubnASXAp+5+2p72p2AvIiJVWbMGJk8uD/5z54byDh3C8L2x4H/AAbW4RR8boTAW/L///cqXM6uYN1ADWQ/2UaD+CDgBKAWmAWe7++y4ZU4FLiEE+yOAO939iLj5PwIGA20V7EVEJN1KSytm+sfGBOrRozzwjxwZEvlrrKAgdCucqI6v7DM1/tAQYJ67L3D3bcBTwOkJy5wO/MmDt4B9zKwLgJl1B0YBf8xQfUVEpJHp3h2+9S147LGQoP/hh3DPPTB4MDz/PJx7LnTpEkbvu+wyeOEFWL++mjsZN273Z/zz80N5HcpUsO8GLImbLo3KUl3mDuBqoHZtHCIiIikwg3794Ac/gL/+NTzSV1ICN98c8u8efBBOPx323Tck+/34x6FVIDFXbzejR4dkvJ49w0569kxLct6eZCrYV3a3I/H+QaXLmNlpwAp3n77HnZiNNbMSMytZGXvYUkREpJby8uCww+Dqq+Hll8Pgf5MnhyCflxdOAkaODI/gH3883HQTTJ0axgZKNJ7RFLCIJuykgEWMp24DPWTunv1RwA3uflI0fR2Au98Ut8z9wGR3/3M0PRcYDlwKnAeUAS2BtsDf3P3cqvape/YiIpIpn38Or71Wfr///fdD+d57w/Dh5ff7330Xxo6tkyfv6kWCXlNCgt5I4FNCgt457j4rbplRwMWUJ+jd5e5DErYzHLhSCXoiIlKfrVgRHqmPBf8FC0J5kyaVJ92nIT8v+6PeuXuZmV0MvEx49O5hd59lZhdG8+8DXiIE+nmER+++nYm6iYiIpNt++8GZZ4YXhEA+cSJccEHlyy9eXLf1Uac6IiIiGVKHT97Vi0fvREREGr0sPXmnYC8iIpIpWXryLjP37EVERCQYPbrug3siXdmLiIjkOAV7ERGRHKdgLyIikuMU7EVERHKcgr2IiEiOU7AXERHJcQr2IiIiOU7BXkREJMflbN/4ZrYSiPVA3AFYlcXq5CId0/TS8Uw/HdP00vFMv3Qf057u3rGyGTkb7OOZWUmywQGkZnRM00vHM/10TNNLxzP9MnlM1YwvIiKS4xTsRUREclxjCfYPZLsCOUjHNL10PNNPxzS9dDzTL2PHtFHcsxcREWnMGsuVvYiISKOV08HezE42s7lmNs/Mrs12fRoKM3vYzFaY2cy4sn3NbIKZfRz9bBc377roGM81s5OyU+v6y8z2N7NJZjbHzGaZ2WVRuY5pDZlZSzObambvRcf0xqhcx7QWzCzPzN41s39G0zqetWBmi8zsAzObYWYlUVlWjmnOBnszywPuAU4B+gNnm1n/7NaqwXgUODmh7FpgorsfCEyMpomO6VnAgGide6NjL+XKgCvc/WDgSOCi6LjpmNbcVuA4dy8CioGTzexIdExr6zJgTty0jmftjXD34rhH7LJyTHM22ANDgHnuvsDdtwFPAadnuU4Ngru/BqxJKD4deCx6/xjw1bjyp9x9q7svBOYRjr1E3P0zd38nev854Z9pN3RMa8yDjdFks+jl6JjWmJl1B0YBf4wr1vFMv6wc01wO9t2AJXHTpVGZ1Ewnd/8MQvAC9ovKdZyrwcwKgEHA2+iY1krU5DwDWAFMcHcd09q5A7ga2BlXpuNZOw78x8ymm9nYqCwrx7RpujZUD1klZXr0IP10nFNkZm2AvwKXu/sGs8oOXVi0kjId0wTuvgMoNrN9gOfM7JAqFtcxrYKZnQascPfpZjY8lVUqKdPx3N0x7r7UzPYDJpjZh1UsW6fHNJev7EuB/eOmuwNLs1SXXLDczLoARD9XROU6zikws2aEQD/e3f8WFeuYpoG7rwMmE+5z6pjWzDHAV8xsEeGW53Fm9gQ6nrXi7kujnyuA5wjN8lk5prkc7KcBB5pZLzNrTkh8eCHLdWrIXgDOj96fD/w9rvwsM2thZr2AA4GpWahfvWXhEv4hYI67/y5ulo5pDZlZx+iKHjNrBRwPfIiOaY24+3Xu3t3dCwj/K19x93PR8awxM2ttZnvF3gMnAjPJ0jHN2WZ8dy8zs4uBl4E84GF3n5XlajUIZvZnYDjQwcxKgZ8DvwH+YmbfBRYD3wRw91lm9hdgNiHr/KKoeVXKHQOcB3wQ3WMGuB4d09roAjwWZSs3Af7i7v80synomKaTvqM114lwewlCrH3S3f9tZtPIwjFVD3oiIiI5Lpeb8UVERAQFexERkZynYC8iIpLjFOxFRERynIK9iIhIjlOwF8lhZvaomf0qS/s2M3vEzNaaWbWeF45GCzu+ruom0tgo2ItkUBTElkedbMTKLjCzyVmsVl0ZCpwAdHf3jA+SYmY3RL3AiTR6CvYimdeUMJRog1KD4TZ7Aovc/Yu6qE9dM7Oc7XRMGh8Fe5HMuxW4MtbdazwzKzAzjw80ZjbZzC6I3o8xszfN7HYzW2dmC8zs6Kh8iZmtMLPzEzbbwcwmmNnnZvaqmfWM2/ZB0bw1ZjbXzP5f3LxHzewPZvaSmX0BjKikvl3N7IVo/Xlm9n9R+XcJQ6UeZWYbzezGyg6Emf2fmc2J6jbbzA6tZJkKtyLMbHjUs2Ns+hoz+zTaxlwzG2lmJxN6KTwz2v970bJ7m9lDZvZZtM6vYicxCcd2DXCDmfWJjtl6M1tlZk9X9jlE6juduYpkXglh4JYrgZ/UYP0jCIG0PXAjYeCSfwB9gGHAX83sr3HjvY8mjFP+NnALMB4YGt1KmAD8DDgFKCQMxzkrrmvpc4BTgdOA5pXU5c/ALKArcBBhZK8F7v6Qme0ALnD3oZV9CDP7JnADYTzvEuAAYHt1DoSZ9QMuBg6PRhcrAPLcfb6Z/RroE/XxHvMYsJxwrFoD/yQMK3p/NP8IwvHcD2gGPAz8h3Ci0xwYXJ36idQXurIXyY6fAZeYWccarLvQ3R+J+s1+mjBS1i/cfau7/wfYRghmMS+6+2vuvhX4MeFqe39CAF8UbavM3d8hjMz3jbh1/+7ub7r7TnffEl+JaBtDgWvcfYu7zyCchJyX4ue4ALjF3ad5MM/dP6nmsdgBtAD6m1kzd1/k7vMrW9DMOhFOai539y+ikchuJwz8ErPU3X8fHY/NhJOPnkDX6DO+Uc36idQLCvYiWeDuMwlXldfWYPXlce83R9tLLGsTN70kbr8bgTWEK/GewBHR7YB1ZraO0ArQubJ1K9EVWOPun8eVfQJ0S/Fz7A9UGphT5e7zgMsJLQQrzOwpM+uaZPGehKv1z+I+7/2Eq/iYxM97NWGc8almNsvMvlOb+opki4K9SPb8HPg/KgbHWDJbflxZfPCtiV1jZJtZG2BfwjjZS4BX3X2fuFcbd/9+3LpVjZS1FNjXomE8Iz2AT1Os1xJC0/2efEEVx8Pdn4xuFfQk1Pfm2KxK9rcV6BD3edu6+4D4zSVse5m7/5+7dwW+B9xrZvGtJiINgoK9SJZEV6VPA5fGla0kBMtzzSwvupJMJSBW5VQzG2pmzYFfAm+7+xJCy0JfMzvPzJpFr8PN7OAU678E+B9wk5m1NLNC4LuEnIBU/JGQqHhY9Ex+n/jkwTgzos+wr5l1JlzJA+GevZkdZ2YtgC2EVo3YsKDLgQIzaxLV9zPC/fffmllbM2tiZgeY2bBkFTSzb5pZ92hyLeFkQEO5SoOjYC+SXb8gJIrF+z/gKmA1MIAQUGvjSUIrwhrgMEJTPVHz+4mEe9ZLgWWEq+IW1dj22UBBtP5zwM/dfUIqK7r7M8C4qH6fA88TWh0SPQ68BywiBOv4jPgWhDHXV0X134+QhQ/wTPRztZm9E73/FiHRbjYheD8LdKmimocDb5vZRuAF4DJ3X5jK5xOpTzSevYiISI7Tlb2IiEiOU7AXERHJcQr2IiIiOU7BXkREJMcp2IuIiOQ4BXsREZEcp2AvIiKS4xTsRUREcpyCvYiISI77/zPuN/TuAvI0AAAAAElFTkSuQmCC",
       "text/plain": [
        "<Figure size 576x360 with 1 Axes>"
       ]
      },
      "metadata": {
       "needs_background": "light"
-     },
-     "output_type": "display_data"
+     }
     }
    ],
-   "source": [
-    "y = mean_rejection_data\n",
-    "x = y.index.values\n",
-    "\n",
-    "plt.rcParams[\"figure.figsize\"] = (8, 5)\n",
-    "plt.xlabel(\"Number of clusters\", fontsize=12)\n",
-    "plt.ylabel(\"Rejection rate\", fontsize=12)\n",
-    "plt.plot(x, y[\"uniform\"], label=\"Uniform Bootstrap\", color=\"blue\", marker=\"o\")\n",
-    "plt.plot(x, y[\"cluster\"], label=\"Cluster Bootstrap\", color=\"red\", marker=\"o\")\n",
-    "plt.legend()\n",
-    "plt.suptitle(\"Comparison of Rejection Rates\", fontsize=15)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "We can see that when the number of clusters is low, it is particularly important to use the cluster robust bootstrap, since rejection with the regular bootstrap is excessive. For a large number of clusters, clustering naturally becomes less important. "
-   ]
+   ],
+   "metadata": {}
   }
  ],
  "metadata": {
diff --git a/docs/source/explanations/inference/index.rst b/docs/source/explanations/inference/index.rst
index b2defa6e4..af4c6ee46 100644
--- a/docs/source/explanations/inference/index.rst
+++ b/docs/source/explanations/inference/index.rst
@@ -7,3 +7,4 @@ Inference
 
    bootstrap_ci
    bootstrap_montecarlo_comparison.ipynb
+   cluster_robust_likelihood_inference.rst
diff --git a/docs/source/how_to_guides/miscellaneous/how_to_generate_publication_quality_tables.ipynb b/docs/source/how_to_guides/miscellaneous/how_to_generate_publication_quality_tables.ipynb
index e5574b61c..2a73e0577 100644
--- a/docs/source/how_to_guides/miscellaneous/how_to_generate_publication_quality_tables.ipynb
+++ b/docs/source/how_to_guides/miscellaneous/how_to_generate_publication_quality_tables.ipynb
@@ -2,30 +2,28 @@
  "cells": [
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "# How to generate publication quality tables\n"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "estimagic helps you generate publication quality html and LaTex tables, given a list of estimation results."
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "## Set up"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 2,
    "source": [
     "import io\n",
     "import re\n",
@@ -38,25 +36,30 @@
     "from IPython.core.display import HTML, Latex\n",
     "\n",
     "import estimagic.visualization.estimation_table as et\n",
-    "from estimagic.config import TEST_DIR"
-   ]
+    "from estimagic.config import EXAMPLE_DIR"
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 4,
    "source": [
     "# Load dataset\n",
-    "df = pd.read_csv(TEST_DIR / \"visualization\" / \"diabetes.csv\", index_col=0)"
-   ]
+    "df = pd.read_csv(EXAMPLE_DIR / \"diabetes.csv\", index_col=0)"
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 3,
-   "metadata": {},
+   "source": [
+    "df.head()"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "<div>\n",
@@ -181,38 +184,33 @@
        "4 -0.002592 -0.031991 -0.046641   135.0  "
       ]
      },
-     "execution_count": 3,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 3
     }
    ],
-   "source": [
-    "df.head()"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 4,
-   "metadata": {},
-   "outputs": [],
    "source": [
     "# Fit regressions\n",
     "est = sm.OLS(endog=df[\"target\"], exog=sm.add_constant(df[df.columns[0:4]])).fit()\n",
     "est2 = sm.OLS(endog=df[\"target\"], exog=sm.add_constant(df[df.columns[0:6]])).fit()"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "The estimation results can be passed as `statsmodels` regression results, or as a tuple with attributes `params` (pandas DataFrame), with parameter values, standard errors and/or confidence intervals and p-values, and `info` (dict) with summary statistics of the model."
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 5,
-   "metadata": {},
-   "outputs": [],
    "source": [
     "# Extract `params` and `info`\n",
     "namedtuplee = namedtuple(\"namedtuplee\", \"params info\")\n",
@@ -224,21 +222,26 @@
     "# Remove redundant information\n",
     "del est3.info[\"df_model\"]\n",
     "del est3.info[\"df_resid\"]"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "The resulting dictionary contains all the information we need:"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 6,
-   "metadata": {},
+   "source": [
+    "est3[0]"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "<div>\n",
@@ -320,21 +323,21 @@
        "ABP    416.673772   4.245663e-09       69.494666  280.088446  553.259097"
       ]
      },
-     "execution_count": 6,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 6
     }
    ],
-   "source": [
-    "est3[0]"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 7,
-   "metadata": {},
+   "source": [
+    "est3[1]"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/plain": [
        "{'rsquared': 0.40026108237713975,\n",
@@ -346,20 +349,15 @@
        " 'n_obs': 442.0}"
       ]
      },
-     "execution_count": 7,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 7
     }
    ],
-   "source": [
-    "est3[1]"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 8,
-   "metadata": {},
-   "outputs": [],
    "source": [
     "# Make copy of estimation results\n",
     "est4 = {}\n",
@@ -369,35 +367,41 @@
     "est5 = {}\n",
     "est5[\"params\"] = deepcopy(est3.params)\n",
     "est5[\"info\"] = deepcopy(est3.info)"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "## Basics"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "Basic features include custom title and custom names for models, columns, index and parameters."
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "### Basic table, without title"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 9,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table([est, est2, est3, est4, est5], return_type=\"html\")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "<table border=\"1\" class=\"dataframe\">\n",
@@ -576,22 +580,28 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 9,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 9
     }
    ],
-   "source": [
-    "ex_html = et.estimation_table([est, est2, est3, est4, est5], return_type=\"html\")\n",
-    "HTML(ex_html)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 10,
-   "metadata": {},
+   "source": [
+    "ex_latex = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    return_type=\"latex\",\n",
+    "    left_decimals=4,\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
+    ")\n",
+    "Latex(ex_latex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{tabular}{lS[table-format =4.2]S[table-format =4.2]S[table-format =4.2]S[table-format =4.2]S[table-format =4.2]}\n",
@@ -627,35 +637,33 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 10,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 10
     }
    ],
-   "source": [
-    "ex_latex = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"latex\",\n",
-    "    left_decimals=4,\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    ")\n",
-    "Latex(ex_latex)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "### Basic table, with title"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 11,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\"caption\": \"This is a caption\"},\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -834,26 +842,29 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 11,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 11
     }
    ],
-   "source": [
-    "ex_html = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"html\",\n",
-    "    render_options={\"caption\": \"This is a caption\"},\n",
-    ")\n",
-    "HTML(ex_html)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 12,
-   "metadata": {},
+   "source": [
+    "ex_tex = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    left_decimals=4,\n",
+    "    return_type=\"latex\",\n",
+    "    render_options={\"caption\": \"This is a caption\"},\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
+    ")\n",
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -894,36 +905,34 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 12,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 12
     }
    ],
-   "source": [
-    "ex_tex = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    left_decimals=4,\n",
-    "    return_type=\"latex\",\n",
-    "    render_options={\"caption\": \"This is a caption\"},\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    ")\n",
-    "Latex(ex_tex)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "### Column names"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 13,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\"caption\": \"This is a caption\"},\n",
+    "    custom_col_names=list(\"abcde\"),\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -1102,27 +1111,30 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 13,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 13
     }
    ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
    "source": [
-    "ex_html = et.estimation_table(\n",
+    "ex_tex = et.estimation_table(\n",
     "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"html\",\n",
+    "    return_type=\"latex\",\n",
     "    render_options={\"caption\": \"This is a caption\"},\n",
+    "    left_decimals=4,\n",
     "    custom_col_names=list(\"abcde\"),\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
     ")\n",
-    "HTML(ex_html)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "metadata": {},
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -1163,37 +1175,34 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 14,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 14
     }
    ],
-   "source": [
-    "ex_tex = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"latex\",\n",
-    "    render_options={\"caption\": \"This is a caption\"},\n",
-    "    left_decimals=4,\n",
-    "    custom_col_names=list(\"abcde\"),\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    ")\n",
-    "Latex(ex_tex)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "Column names can be hidden by passing `show_col_names=False`:"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 15,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\"caption\": \"This is a caption\"},\n",
+    "    show_col_names=False,\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -1372,27 +1381,30 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 15,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 15
     }
    ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
    "source": [
-    "ex_html = et.estimation_table(\n",
+    "ex_tex = et.estimation_table(\n",
     "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"html\",\n",
+    "    return_type=\"latex\",\n",
     "    render_options={\"caption\": \"This is a caption\"},\n",
+    "    left_decimals=4,\n",
     "    show_col_names=False,\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
     ")\n",
-    "HTML(ex_html)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 16,
-   "metadata": {},
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -1433,46 +1445,44 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 16,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 16
     }
    ],
-   "source": [
-    "ex_tex = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"latex\",\n",
-    "    render_options={\"caption\": \"This is a caption\"},\n",
-    "    left_decimals=4,\n",
-    "    show_col_names=False,\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    ")\n",
-    "Latex(ex_tex)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "### Model names"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 17,
-   "metadata": {},
-   "outputs": [],
    "source": [
     "custom_mod_names = {\"M a\": [0], \"M b-d\": [1, 2, 3], \"M e\": [4]}"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 18,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\"caption\": \"This is a caption\"},\n",
+    "    custom_model_names=custom_mod_names,\n",
+    "    custom_col_names=list(\"abcde\"),\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -1657,28 +1667,31 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 18,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 18
     }
    ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
    "source": [
-    "ex_html = et.estimation_table(\n",
+    "ex_tex = et.estimation_table(\n",
     "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"html\",\n",
+    "    return_type=\"latex\",\n",
     "    render_options={\"caption\": \"This is a caption\"},\n",
+    "    left_decimals=4,\n",
     "    custom_model_names=custom_mod_names,\n",
     "    custom_col_names=list(\"abcde\"),\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
     ")\n",
-    "HTML(ex_html)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 19,
-   "metadata": {},
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -1724,45 +1737,41 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 19,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 19
     }
    ],
-   "source": [
-    "ex_tex = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"latex\",\n",
-    "    render_options={\"caption\": \"This is a caption\"},\n",
-    "    left_decimals=4,\n",
-    "    custom_model_names=custom_mod_names,\n",
-    "    custom_col_names=list(\"abcde\"),\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    ")\n",
-    "Latex(ex_tex)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "### Index name"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "By default, the index name is \"index\":"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 20,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\"caption\": \"This is a caption\", \"index_names\": True},\n",
+    "    custom_model_names=custom_mod_names,\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -1955,27 +1964,30 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 20,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 20
     }
    ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
    "source": [
-    "ex_html = et.estimation_table(\n",
+    "ex_tex = et.estimation_table(\n",
     "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"html\",\n",
+    "    return_type=\"latex\",\n",
     "    render_options={\"caption\": \"This is a caption\", \"index_names\": True},\n",
+    "    left_decimals=4,\n",
     "    custom_model_names=custom_mod_names,\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
     ")\n",
-    "HTML(ex_html)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 21,
-   "metadata": {},
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -2022,37 +2034,37 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 21,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 21
     }
    ],
-   "source": [
-    "ex_tex = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"latex\",\n",
-    "    render_options={\"caption\": \"This is a caption\", \"index_names\": True},\n",
-    "    left_decimals=4,\n",
-    "    custom_model_names=custom_mod_names,\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    ")\n",
-    "Latex(ex_tex)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "This can be customized by passing a different index name to `custom_index_names`:"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 22,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\n",
+    "        \"caption\": \"This is a caption\",\n",
+    "    },\n",
+    "    custom_index_names=[\"Variables\"],\n",
+    "    custom_model_names=custom_mod_names,\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -2245,30 +2257,33 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 22,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 22
     }
    ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
    "source": [
-    "ex_html = et.estimation_table(\n",
+    "ex_tex = et.estimation_table(\n",
     "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"html\",\n",
+    "    return_type=\"latex\",\n",
     "    render_options={\n",
     "        \"caption\": \"This is a caption\",\n",
     "    },\n",
     "    custom_index_names=[\"Variables\"],\n",
+    "    left_decimals=4,\n",
     "    custom_model_names=custom_mod_names,\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
     ")\n",
-    "HTML(ex_html)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 23,
-   "metadata": {},
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -2315,56 +2330,54 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 23,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 23
     }
    ],
-   "source": [
-    "ex_tex = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"latex\",\n",
-    "    render_options={\n",
-    "        \"caption\": \"This is a caption\",\n",
-    "    },\n",
-    "    custom_index_names=[\"Variables\"],\n",
-    "    left_decimals=4,\n",
-    "    custom_model_names=custom_mod_names,\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    ")\n",
-    "Latex(ex_tex)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "### Parameter names"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "Custom parameter names can be specified by passing a dictionary to `custom_param_names`:"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 24,
-   "metadata": {},
-   "outputs": [],
    "source": [
     "cust_par_names = {\"const\": \"Intercept\", \"Sex\": \"Gender\"}"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 25,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\n",
+    "        \"caption\": \"This is a caption\",\n",
+    "    },\n",
+    "    custom_index_names=[\"Variables\"],\n",
+    "    custom_model_names=custom_mod_names,\n",
+    "    custom_param_names=cust_par_names,\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -2557,31 +2570,34 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 25,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 25
     }
    ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
    "source": [
-    "ex_html = et.estimation_table(\n",
+    "ex_tex = et.estimation_table(\n",
     "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"html\",\n",
+    "    return_type=\"latex\",\n",
     "    render_options={\n",
     "        \"caption\": \"This is a caption\",\n",
     "    },\n",
     "    custom_index_names=[\"Variables\"],\n",
+    "    left_decimals=4,\n",
     "    custom_model_names=custom_mod_names,\n",
     "    custom_param_names=cust_par_names,\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
     ")\n",
-    "HTML(ex_html)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 26,
-   "metadata": {},
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -2628,48 +2644,46 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 26,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 26
     }
    ],
-   "source": [
-    "ex_tex = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"latex\",\n",
-    "    render_options={\n",
-    "        \"caption\": \"This is a caption\",\n",
-    "    },\n",
-    "    custom_index_names=[\"Variables\"],\n",
-    "    left_decimals=4,\n",
-    "    custom_model_names=custom_mod_names,\n",
-    "    custom_param_names=cust_par_names,\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    ")\n",
-    "Latex(ex_tex)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "## Advanced"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "### Confidence intervals"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 27,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\n",
+    "        \"caption\": \"This is a caption\",\n",
+    "    },\n",
+    "    custom_index_names=[\"Variables\"],\n",
+    "    custom_model_names=custom_mod_names,\n",
+    "    custom_param_names=cust_par_names,\n",
+    "    confidence_intervals=True,\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -2862,32 +2876,35 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 27,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 27
     }
    ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
    "source": [
-    "ex_html = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"html\",\n",
+    "ex_tex = et.estimation_table(\n",
+    "    [est, est2, est3, est4],\n",
+    "    return_type=\"latex\",\n",
     "    render_options={\n",
     "        \"caption\": \"This is a caption\",\n",
     "    },\n",
     "    custom_index_names=[\"Variables\"],\n",
-    "    custom_model_names=custom_mod_names,\n",
+    "    left_decimals=4,\n",
+    "    custom_model_names=None,\n",
     "    custom_param_names=cust_par_names,\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
     "    confidence_intervals=True,\n",
     ")\n",
-    "HTML(ex_html)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 28,
-   "metadata": {},
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -2929,42 +2946,37 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 28,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 28
     }
    ],
-   "source": [
-    "ex_tex = et.estimation_table(\n",
-    "    [est, est2, est3, est4],\n",
-    "    return_type=\"latex\",\n",
-    "    render_options={\n",
-    "        \"caption\": \"This is a caption\",\n",
-    "    },\n",
-    "    custom_index_names=[\"Variables\"],\n",
-    "    left_decimals=4,\n",
-    "    custom_model_names=None,\n",
-    "    custom_param_names=cust_par_names,\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    "    confidence_intervals=True,\n",
-    ")\n",
-    "Latex(ex_tex)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "Passing `confidence_intervals=False` prints standard errors. To hide both standard errors and confidence intervals you need to pass `show_inference=False`:"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 29,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\"caption\": \"This is a caption\"},\n",
+    "    custom_index_names=[\"Variables\"],\n",
+    "    custom_model_names=custom_mod_names,\n",
+    "    custom_param_names=cust_par_names,\n",
+    "    show_inference=False,\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -3101,30 +3113,35 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 29,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 29
     }
    ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
    "source": [
-    "ex_html = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"html\",\n",
-    "    render_options={\"caption\": \"This is a caption\"},\n",
+    "ex_tex = et.estimation_table(\n",
+    "    [est, est2, est3, est4],\n",
+    "    return_type=\"latex\",\n",
+    "    render_options={\n",
+    "        \"caption\": \"This is a caption\",\n",
+    "    },\n",
     "    custom_index_names=[\"Variables\"],\n",
-    "    custom_model_names=custom_mod_names,\n",
+    "    left_decimals=4,\n",
+    "    custom_model_names=None,\n",
     "    custom_param_names=cust_par_names,\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
     "    show_inference=False,\n",
     ")\n",
-    "HTML(ex_html)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 30,
-   "metadata": {},
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -3159,49 +3176,42 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 30,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 30
     }
    ],
-   "source": [
-    "ex_tex = et.estimation_table(\n",
-    "    [est, est2, est3, est4],\n",
-    "    return_type=\"latex\",\n",
-    "    render_options={\n",
-    "        \"caption\": \"This is a caption\",\n",
-    "    },\n",
-    "    custom_index_names=[\"Variables\"],\n",
-    "    left_decimals=4,\n",
-    "    custom_model_names=None,\n",
-    "    custom_param_names=cust_par_names,\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    "    show_inference=False,\n",
-    ")\n",
-    "Latex(ex_tex)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "### Footer"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "To avoid printint statistics, such as R-squared and number of observations, pass `show_footer=False`."
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 31,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\"caption\": \"This is a caption\"},\n",
+    "    custom_param_names=cust_par_names,\n",
+    "    show_footer=False,\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -3338,28 +3348,34 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 31,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 31
     }
    ],
-   "source": [
-    "ex_html = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"html\",\n",
-    "    render_options={\"caption\": \"This is a caption\"},\n",
-    "    custom_param_names=cust_par_names,\n",
-    "    show_footer=False,\n",
-    ")\n",
-    "HTML(ex_html)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 32,
-   "metadata": {},
+   "source": [
+    "ex_tex = et.estimation_table(\n",
+    "    [est, est2, est3, est4],\n",
+    "    return_type=\"latex\",\n",
+    "    render_options={\n",
+    "        \"caption\": \"This is a caption\",\n",
+    "    },\n",
+    "    left_decimals=4,\n",
+    "    custom_model_names=None,\n",
+    "    custom_param_names=cust_par_names,\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
+    "    show_footer=False,\n",
+    ")\n",
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -3394,41 +3410,38 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 32,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 32
     }
    ],
-   "source": [
-    "ex_tex = et.estimation_table(\n",
-    "    [est, est2, est3, est4],\n",
-    "    return_type=\"latex\",\n",
-    "    render_options={\n",
-    "        \"caption\": \"This is a caption\",\n",
-    "    },\n",
-    "    left_decimals=4,\n",
-    "    custom_model_names=None,\n",
-    "    custom_param_names=cust_par_names,\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    "    show_footer=False,\n",
-    ")\n",
-    "Latex(ex_tex)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
+   "metadata": {}
+  },
+  {
+   "cell_type": "markdown",
    "source": [
     "### Custom notes"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 33,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\"caption\": \"This is a caption\"},\n",
+    "    custom_param_names=cust_par_names,\n",
+    "    custom_notes=[\n",
+    "        \"This is the first note of some length\",\n",
+    "        \"This is the second note probably of larger length\",\n",
+    "    ],\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -3612,31 +3625,37 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 33,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 33
     }
    ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
    "source": [
-    "ex_html = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"html\",\n",
-    "    render_options={\"caption\": \"This is a caption\"},\n",
+    "ex_tex = et.estimation_table(\n",
+    "    [est, est2, est3, est4],\n",
+    "    return_type=\"latex\",\n",
+    "    render_options={\n",
+    "        \"caption\": \"This is a caption\",\n",
+    "    },\n",
+    "    left_decimals=4,\n",
+    "    custom_model_names=None,\n",
     "    custom_param_names=cust_par_names,\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
     "    custom_notes=[\n",
     "        \"This is the first note of some length\",\n",
     "        \"This is the second note probably of larger length\",\n",
     "    ],\n",
     ")\n",
-    "HTML(ex_html)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 34,
-   "metadata": {},
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -3681,44 +3700,39 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 34,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 34
     }
    ],
-   "source": [
-    "ex_tex = et.estimation_table(\n",
-    "    [est, est2, est3, est4],\n",
-    "    return_type=\"latex\",\n",
-    "    render_options={\n",
-    "        \"caption\": \"This is a caption\",\n",
-    "    },\n",
-    "    left_decimals=4,\n",
-    "    custom_model_names=None,\n",
-    "    custom_param_names=cust_par_names,\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    "    custom_notes=[\n",
-    "        \"This is the first note of some length\",\n",
-    "        \"This is the second note probably of larger length\",\n",
-    "    ],\n",
-    ")\n",
-    "Latex(ex_tex)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "### Custom names for summary statistics"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 35,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est, est2, est3, est4, est5],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\"caption\": \"This is a caption\"},\n",
+    "    custom_param_names=cust_par_names,\n",
+    "    custom_notes=[\n",
+    "        \"This is the first note of some length\",\n",
+    "        \"This is the second note probably of larger length\",\n",
+    "    ],\n",
+    "    stats_dict={\"R$^2$\": \"rsquared\", \"N. Obs\": \"n_obs\"},\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -3878,46 +3892,40 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 35,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 35
     }
    ],
-   "source": [
-    "ex_html = et.estimation_table(\n",
-    "    [est, est2, est3, est4, est5],\n",
-    "    return_type=\"html\",\n",
-    "    render_options={\"caption\": \"This is a caption\"},\n",
-    "    custom_param_names=cust_par_names,\n",
-    "    custom_notes=[\n",
-    "        \"This is the first note of some length\",\n",
-    "        \"This is the second note probably of larger length\",\n",
-    "    ],\n",
-    "    stats_dict={\"R$^2$\": \"rsquared\", \"N. Obs\": \"n_obs\"},\n",
-    ")\n",
-    "HTML(ex_html)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "## MultiIndex"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "### Set up"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 36,
-   "metadata": {},
+   "source": [
+    "# Convert `params` DataFrame to MultiIndex\n",
+    "df = et._extract_params_from_sm(est)\n",
+    "df.index = pd.MultiIndex.from_arrays(\n",
+    "    np.array([[\"Intercept\", \"Slope\", \"Slope\", \"Slope\", \"Slope\"], df.index.values])\n",
+    ")\n",
+    "df"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "<div>\n",
@@ -4009,36 +4017,26 @@
        "          ABP    553.259097  "
       ]
      },
-     "execution_count": 36,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 36
     }
    ],
-   "source": [
-    "# Convert `params` DataFrame to MultiIndex\n",
-    "df = et._extract_params_from_sm(est)\n",
-    "df.index = pd.MultiIndex.from_arrays(\n",
-    "    np.array([[\"Intercept\", \"Slope\", \"Slope\", \"Slope\", \"Slope\"], df.index.values])\n",
-    ")\n",
-    "df"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 37,
-   "metadata": {},
-   "outputs": [],
    "source": [
     "# Extract info and generate tuple of estimation results for `est1`\n",
     "info = et._extract_info_from_sm(est)\n",
     "est_mi = namedtuplee(params=df, info=info)"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 38,
-   "metadata": {},
-   "outputs": [],
    "source": [
     "# Repeat for `est2`\n",
     "df = et._extract_params_from_sm(est2)\n",
@@ -4052,21 +4050,38 @@
     ")\n",
     "info = et._extract_info_from_sm(est2)\n",
     "est_mi2 = namedtuplee(params=df, info=info)"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "### Basics"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 39,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est_mi, est_mi2],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\n",
+    "        \"caption\": \"This is a caption\",\n",
+    "    },\n",
+    "    custom_param_names=cust_par_names,\n",
+    "    custom_notes=[\n",
+    "        \"This is the first note of some length\",\n",
+    "        \"This is the second note probably of larger length\",\n",
+    "    ],\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -4199,33 +4214,37 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 39,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 39
     }
    ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
    "source": [
-    "ex_html = et.estimation_table(\n",
+    "ex_tex = et.estimation_table(\n",
     "    [est_mi, est_mi2],\n",
-    "    return_type=\"html\",\n",
+    "    return_type=\"latex\",\n",
     "    render_options={\n",
     "        \"caption\": \"This is a caption\",\n",
     "    },\n",
+    "    left_decimals=3,\n",
+    "    custom_model_names=None,\n",
     "    custom_param_names=cust_par_names,\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
     "    custom_notes=[\n",
     "        \"This is the first note of some length\",\n",
     "        \"This is the second note probably of larger length\",\n",
     "    ],\n",
     ")\n",
-    "HTML(ex_html)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 40,
-   "metadata": {},
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -4270,44 +4289,40 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 40,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 40
     }
    ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "markdown",
    "source": [
-    "ex_tex = et.estimation_table(\n",
+    "### Parameter names"
+   ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "source": [
+    "ex_html = et.estimation_table(\n",
     "    [est_mi, est_mi2],\n",
-    "    return_type=\"latex\",\n",
+    "    return_type=\"html\",\n",
     "    render_options={\n",
     "        \"caption\": \"This is a caption\",\n",
     "    },\n",
-    "    left_decimals=3,\n",
-    "    custom_model_names=None,\n",
-    "    custom_param_names=cust_par_names,\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
     "    custom_notes=[\n",
     "        \"This is the first note of some length\",\n",
     "        \"This is the second note probably of larger length\",\n",
     "    ],\n",
+    "    custom_param_names={\"Age\": \"Maturity\", \"Else\": \"Additionally\"},\n",
     ")\n",
-    "Latex(ex_tex)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### Parameter names"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 41,
-   "metadata": {},
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -4440,33 +4455,37 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 41,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 41
     }
    ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
    "source": [
-    "ex_html = et.estimation_table(\n",
+    "ex_tex = et.estimation_table(\n",
     "    [est_mi, est_mi2],\n",
-    "    return_type=\"html\",\n",
+    "    return_type=\"latex\",\n",
     "    render_options={\n",
     "        \"caption\": \"This is a caption\",\n",
     "    },\n",
+    "    left_decimals=3,\n",
+    "    custom_model_names=None,\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
     "    custom_notes=[\n",
     "        \"This is the first note of some length\",\n",
     "        \"This is the second note probably of larger length\",\n",
     "    ],\n",
     "    custom_param_names={\"Age\": \"Maturity\", \"Else\": \"Additionally\"},\n",
     ")\n",
-    "HTML(ex_html)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 42,
-   "metadata": {},
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -4511,43 +4530,22 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 42,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 42
     }
    ],
-   "source": [
-    "ex_tex = et.estimation_table(\n",
-    "    [est_mi, est_mi2],\n",
-    "    return_type=\"latex\",\n",
-    "    render_options={\n",
-    "        \"caption\": \"This is a caption\",\n",
-    "    },\n",
-    "    left_decimals=3,\n",
-    "    custom_model_names=None,\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    "    custom_notes=[\n",
-    "        \"This is the first note of some length\",\n",
-    "        \"This is the second note probably of larger length\",\n",
-    "    ],\n",
-    "    custom_param_names={\"Age\": \"Maturity\", \"Else\": \"Additionally\"},\n",
-    ")\n",
-    "Latex(ex_tex)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "### Index and model names"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 43,
-   "metadata": {},
-   "outputs": [],
    "source": [
     "stats_dict = {\n",
     "    \"Observations\": \"n_obs\",\n",
@@ -4557,14 +4555,34 @@
     "    \"F Statistic\": \"fvalue\",\n",
     "    \"show_dof\": True,\n",
     "}"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 44,
-   "metadata": {},
+   "source": [
+    "ex_html = et.estimation_table(\n",
+    "    [est_mi, est_mi2, est_mi],\n",
+    "    return_type=\"html\",\n",
+    "    render_options={\n",
+    "        \"caption\": \"This is a caption\",\n",
+    "    },\n",
+    "    custom_notes=[\n",
+    "        \"This is the first note of some length\",\n",
+    "        \"This is the second note probably of larger length\",\n",
+    "    ],\n",
+    "    custom_param_names={\"Age\": \"Maturity\", \"Else\": \"Additionally\"},\n",
+    "    custom_index_names=[\"Category\", \"Variable\"],\n",
+    "    custom_model_names={\"M1-2\": [0, 1], \"M3\": [2]},\n",
+    "    stats_dict=stats_dict,\n",
+    ")\n",
+    "HTML(ex_html)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/html": [
        "This is a caption<br><table border=\"1\" class=\"dataframe\">\n",
@@ -4730,36 +4748,39 @@
        "<IPython.core.display.HTML object>"
       ]
      },
-     "execution_count": 44,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 44
     }
    ],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
    "source": [
-    "ex_html = et.estimation_table(\n",
-    "    [est_mi, est_mi2, est_mi],\n",
-    "    return_type=\"html\",\n",
+    "ex_tex = et.estimation_table(\n",
+    "    [est_mi, est_mi2],\n",
+    "    return_type=\"latex\",\n",
     "    render_options={\n",
     "        \"caption\": \"This is a caption\",\n",
     "    },\n",
+    "    left_decimals=4,\n",
+    "    alignment_warning=False,\n",
+    "    siunitx_warning=False,\n",
     "    custom_notes=[\n",
     "        \"This is the first note of some length\",\n",
     "        \"This is the second note probably of larger length\",\n",
     "    ],\n",
     "    custom_param_names={\"Age\": \"Maturity\", \"Else\": \"Additionally\"},\n",
     "    custom_index_names=[\"Category\", \"Variable\"],\n",
-    "    custom_model_names={\"M1-2\": [0, 1], \"M3\": [2]},\n",
+    "    custom_model_names={\"M1\": [0], \"M2\": [1]},\n",
     "    stats_dict=stats_dict,\n",
     ")\n",
-    "HTML(ex_html)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 45,
-   "metadata": {},
+    "Latex(ex_tex)"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/latex": [
        "\\begin{table}\n",
@@ -4809,32 +4830,11 @@
        "<IPython.core.display.Latex object>"
       ]
      },
-     "execution_count": 45,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 45
     }
    ],
-   "source": [
-    "ex_tex = et.estimation_table(\n",
-    "    [est_mi, est_mi2],\n",
-    "    return_type=\"latex\",\n",
-    "    render_options={\n",
-    "        \"caption\": \"This is a caption\",\n",
-    "    },\n",
-    "    left_decimals=4,\n",
-    "    alignment_warning=False,\n",
-    "    siunitx_warning=False,\n",
-    "    custom_notes=[\n",
-    "        \"This is the first note of some length\",\n",
-    "        \"This is the second note probably of larger length\",\n",
-    "    ],\n",
-    "    custom_param_names={\"Age\": \"Maturity\", \"Else\": \"Additionally\"},\n",
-    "    custom_index_names=[\"Category\", \"Variable\"],\n",
-    "    custom_model_names={\"M1\": [0], \"M2\": [1]},\n",
-    "    stats_dict=stats_dict,\n",
-    ")\n",
-    "Latex(ex_tex)"
-   ]
+   "metadata": {}
   }
  ],
  "metadata": {
@@ -4843,9 +4843,8 @@
    "lastKernelId": null
   },
   "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
+   "name": "python3",
+   "display_name": "Python 3.8.12 64-bit ('estimagic': conda)"
   },
   "language_info": {
    "codemirror_mode": {
@@ -4857,7 +4856,10 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.7.8"
+   "version": "3.8.12"
+  },
+  "interpreter": {
+   "hash": "5cdb9867252288f10687117449de6ad870b49795ca695c868016dc0022895cce"
   }
  },
  "nbformat": 4,
diff --git a/docs/source/how_to_guides/optimization/how_to_use_logging.ipynb b/docs/source/how_to_guides/optimization/how_to_use_logging.ipynb
index ec051961f..1f1b824bf 100644
--- a/docs/source/how_to_guides/optimization/how_to_use_logging.ipynb
+++ b/docs/source/how_to_guides/optimization/how_to_use_logging.ipynb
@@ -2,7 +2,6 @@
  "cells": [
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "# How to use logging\n",
     "\n",
@@ -14,11 +13,11 @@
     "The sqlite database is also used to exchange data between the optimization and the dashboard.\n",
     "\n",
     "In addition to parameters and criterion values, we also save all arguments to a `maximize` or `minimize` in the database as well as other information in the database that can help to reproduce an optimization result."
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "## Turn logging on or off\n",
     "\n",
@@ -27,11 +26,11 @@
     "\n",
     "We encourage users to always use logging. However, it introduces a small overhead of about 5 milliseconds for each evaluation of the criterion function. If this is too much, you can turn logging off by specifying `logging=False`\n",
     "\n"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "## Reading the log\n",
     "\n",
@@ -41,55 +40,58 @@
     "- You want to visualize the fit of your model at a specific parameter vector in a way that is not yet supported in the dashboard. \n",
     "\n",
     "We provide a convenience function for this:"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {},
-   "outputs": [],
+   "execution_count": 2,
    "source": [
-    "from estimagic.config import TEST_DIR\n",
+    "from estimagic.config import EXAMPLE_DIR\n",
     "from estimagic.logging.read_log import read_optimization_iteration"
-   ]
+   ],
+   "outputs": [],
+   "metadata": {}
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
-   "metadata": {},
+   "execution_count": 3,
+   "source": [
+    "path = EXAMPLE_DIR / \"db1.db\"\n",
+    "info = read_optimization_iteration(path, 1)\n",
+    "info.keys()"
+   ],
    "outputs": [
     {
+     "output_type": "execute_result",
      "data": {
       "text/plain": [
        "dict_keys(['rowid', 'timestamp', 'exceptions', 'valid', 'hash', 'value', 'params'])"
       ]
      },
-     "execution_count": 20,
      "metadata": {},
-     "output_type": "execute_result"
+     "execution_count": 3
     }
    ],
-   "source": [
-    "path = TEST_DIR / \"dashboard\" / \"db1.db\"\n",
-    "info = read_optimization_iteration(path, 1)\n",
-    "info.keys()"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "The entries should be rather self explanatory. For more detailed information about the function, check out the docstring"
-   ]
+   ],
+   "metadata": {}
   },
   {
    "cell_type": "code",
    "execution_count": 21,
-   "metadata": {},
+   "source": [
+    "print(read_optimization_iteration.__doc__)"
+   ],
    "outputs": [
     {
-     "name": "stdout",
      "output_type": "stream",
+     "name": "stdout",
      "text": [
       "Get information about an optimization iteration.\n",
       "\n",
@@ -114,13 +116,10 @@
      ]
     }
    ],
-   "source": [
-    "print(read_optimization_iteration.__doc__)"
-   ]
+   "metadata": {}
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
    "source": [
     "## Customize the logging behaviour with the `log_options` argument\n",
     "\n",
@@ -130,14 +129,14 @@
     "\n",
     "- \"fast_logging\": A boolean that determines if \"unsafe\" settings are used to speed up write processes to the database. This should only be used for very short running criterion functions where the main purpose of the log is a real-time dashboard and it would not be catastrophic to get a corrupted database in case of a sudden system shutdown. If one evaluation of the criterion function (and gradient if applicable) takes more than 100 ms, the logging overhead is negligible.\n",
     "- \"if_exists\": (str) One of \"extend\", \"replace\", \"raise\"\n"
-   ]
+   ],
+   "metadata": {}
   }
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
+   "name": "python3",
+   "display_name": "Python 3.8.12 64-bit ('estimagic': conda)"
   },
   "language_info": {
    "codemirror_mode": {
@@ -149,7 +148,10 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.7.8"
+   "version": "3.8.12"
+  },
+  "interpreter": {
+   "hash": "5cdb9867252288f10687117449de6ad870b49795ca695c868016dc0022895cce"
   }
  },
  "nbformat": 4,
diff --git a/environment.yml b/environment.yml
index 6cb357579..870c9de70 100644
--- a/environment.yml
+++ b/environment.yml
@@ -8,6 +8,8 @@ channels:
 dependencies:
   - python=3.8
   - pip
+  - setuptools_scm
+  - toml
   - anaconda-client
   - bokeh>=1.3
   - ansi2html
diff --git a/estimagic/visualization/__init__.py b/estimagic/visualization/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/pyproject.toml b/pyproject.toml
index b55b318df..f27011fca 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -11,3 +11,11 @@ pyupgrade = 1
 [tool.nbqa.addopts]
 isort = ["--treat-comment-as-code", "# %%", "--profile=black"]
 pyupgrade = ["--py36-plus"]
+
+
+[build-system]
+requires = ["setuptools>=45", "wheel", "setuptools_scm[toml]>=6.0"]
+
+
+[tool.setuptools_scm]
+write_to = "src/estimagic/_version.py"
diff --git a/setup.cfg b/setup.cfg
index 630b8f440..8c973a394 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,12 +1,73 @@
-[bumpversion]
-current_version = 0.1.4
-parse = (?P<major>\d+)\.(?P<minor>\d+)(\.(?P<patch>\d+))(\-?((dev)?(?P<dev>\d+))?)
-serialize =
-	{major}.{minor}.{patch}dev{dev}
-	{major}.{minor}.{patch}
+[metadata]
+name = estimagic
+# version = 0.1.4
+description = Tools for the estimation of (structural) econometric models.
+long_description =
+            Estimagic is a Python package that helps to build high-quality and user
+            friendly implementations of (structural) econometric models.
 
-[bumpversion:file:setup.py]
+            It is designed with large structural models in mind. However, it is also
+            useful for any other estimator that numerically minimizes or maximizes a
+            criterion function (Extremum Estimator). Examples are maximum likelihood
+            estimation, generalized method of moments, method of simulated moments and
+            indirect inference.
+license = MIT
+classifiers =
+    License :: OSI Approved :: MIT License
+    Development Status :: 4 - Beta
+    Programming Language :: Python :: 3
+    Programming Language :: Python :: 3 :: Only
+    Programming Language :: Python :: 3.8
+    Programming Language :: Python :: 3.9
+    Operating System :: MacOS :: MacOS X
+    Operating System :: Microsoft :: Windows
+    Operating System :: POSIX
+    Topic :: Scientific/Engineering
+    Intended Audience :: Science/Research
+keywords =
+    econometrics
+    statistics
+    estimation
+    extremum estimation
+    optimization
+    inference
+    numerical differentiation
+    finite differences
+    richardson extrapolation
+    derivative free optimization
+    method of simulated moments
+    maximum likelihood
+url = https://github.com/OpenSourceEconomics/estimagic
+author = Janos Gabler
+author_email = janos.gabler@gmail.com
 
-[bumpversion:file:docs/source/conf.py]
+[options]
+packages = find:
+zip_safe = False
+package_dir = =src
+python_requires = >=3.8
+include_package_data = True
+install_requires =
+    click
+    cloudpickle
+    joblib
+    numpy>=1.16
+    pandas>=1.0
+    bokeh>=1.3
+    scipy
+    fuzzywuzzy
+    sqlalchemy>=1.3
+    seaborn
+    dill
 
-[bumpversion:file:estimagic/__init__.py]
+
+[options.packages.find]
+where = src
+
+[options.entry_points]
+console_scripts =
+    estimagic=estimagic.cli:cli
+
+[check-manifest]
+ignore =
+    src/estimagic/_version.py
diff --git a/setup.py b/setup.py
index 48f4314e7..7f1a1763c 100644
--- a/setup.py
+++ b/setup.py
@@ -1,32 +1,4 @@
-from setuptools import find_packages
 from setuptools import setup
 
-setup(
-    name="estimagic",
-    version="0.1.4",
-    description="Tools for the estimation of (structural) econometric models.",
-    long_description="""
-        Estimagic is a Python package that helps to build high-quality and user
-        friendly implementations of (structural) econometric models.
-
-        It is designed with large structural models in mind. However, it is also
-        useful for any other estimator that numerically minimizes or maximizes a
-        criterion function (Extremum Estimator). Examples are maximum likelihood
-        estimation, generalized method of moments, method of simulated moments and
-        indirect inference.""",
-    license="BSD",
-    classifiers=[
-        "Programming Language :: Python :: 3",
-        "License :: OSI Approved :: BSD License",
-        "Development Status :: 4 - Beta",
-    ],
-    keywords=["econometrics", "statistics", "extremum estimation", "optimization"],
-    url="https://github.com/OpenSourceEconomics/estimagic",
-    author="Janos Gabler",
-    author_email="janos.gabler@gmail.com",
-    packages=find_packages(exclude=["tests/*"]),
-    entry_points={"console_scripts": ["estimagic=estimagic.cli:cli"]},
-    zip_safe=False,
-    package_data={"estimagic": ["optimization/algo_dict.json"]},
-    include_package_data=True,
-)
+if __name__ == "__main__":
+    setup()
diff --git a/estimagic/__init__.py b/src/estimagic/__init__.py
similarity index 72%
rename from estimagic/__init__.py
rename to src/estimagic/__init__.py
index 1333db0ce..678f991a2 100644
--- a/estimagic/__init__.py
+++ b/src/estimagic/__init__.py
@@ -7,8 +7,12 @@
 from estimagic.optimization.optimize import maximize
 from estimagic.optimization.optimize import minimize
 
-
-__version__ = "0.1.4"
+try:
+    from ._version import version as __version__
+except ImportError:
+    # broken installation, we don't even try unknown only works because we do poor mans
+    # version compare
+    __version__ = "unknown"
 
 
 __all__ = [
@@ -20,4 +24,5 @@
     "estimate_msm",
     "estimate_ml",
     "get_moments_cov",
+    "__version__",
 ]
diff --git a/estimagic/batch_evaluators.py b/src/estimagic/batch_evaluators.py
similarity index 100%
rename from estimagic/batch_evaluators.py
rename to src/estimagic/batch_evaluators.py
diff --git a/estimagic/cli.py b/src/estimagic/cli.py
similarity index 99%
rename from estimagic/cli.py
rename to src/estimagic/cli.py
index 661f64d23..3cbb6c273 100644
--- a/estimagic/cli.py
+++ b/src/estimagic/cli.py
@@ -3,7 +3,6 @@
 from pathlib import Path
 
 import click
-
 from estimagic.dashboard.run_dashboard import run_dashboard
 
 CONTEXT_SETTINGS = {"help_option_names": ["-h", "--help"]}
diff --git a/estimagic/config.py b/src/estimagic/config.py
similarity index 97%
rename from estimagic/config.py
rename to src/estimagic/config.py
index 8e2fe5540..f13a5dfae 100644
--- a/estimagic/config.py
+++ b/src/estimagic/config.py
@@ -2,8 +2,6 @@
 
 DEFAULT_SEED = 5471
 
-TEST_DIR = Path(__file__).parent / "tests"
-
 DOCS_DIR = Path(__file__).parent.parent / "docs"
 
 EXAMPLE_DIR = Path(__file__).parent / "examples"
diff --git a/estimagic/dashboard/__init__.py b/src/estimagic/dashboard/__init__.py
similarity index 100%
rename from estimagic/dashboard/__init__.py
rename to src/estimagic/dashboard/__init__.py
diff --git a/estimagic/dashboard/create_short_database_names.py b/src/estimagic/dashboard/create_short_database_names.py
similarity index 100%
rename from estimagic/dashboard/create_short_database_names.py
rename to src/estimagic/dashboard/create_short_database_names.py
diff --git a/estimagic/dashboard/index.html b/src/estimagic/dashboard/index.html
similarity index 100%
rename from estimagic/dashboard/index.html
rename to src/estimagic/dashboard/index.html
diff --git a/estimagic/dashboard/master_app.py b/src/estimagic/dashboard/master_app.py
similarity index 100%
rename from estimagic/dashboard/master_app.py
rename to src/estimagic/dashboard/master_app.py
diff --git a/estimagic/dashboard/monitoring_app.py b/src/estimagic/dashboard/monitoring_app.py
similarity index 99%
rename from estimagic/dashboard/monitoring_app.py
rename to src/estimagic/dashboard/monitoring_app.py
index 935ca53c2..b501e7ee9 100644
--- a/estimagic/dashboard/monitoring_app.py
+++ b/src/estimagic/dashboard/monitoring_app.py
@@ -10,15 +10,14 @@
 from bokeh.models import Panel
 from bokeh.models import Tabs
 from bokeh.models import Toggle
-from jinja2 import Environment
-from jinja2 import FileSystemLoader
-
 from estimagic.dashboard.monitoring_callbacks import activation_callback
 from estimagic.dashboard.monitoring_callbacks import logscale_callback
 from estimagic.dashboard.plot_functions import plot_time_series
 from estimagic.logging.database_utilities import load_database
 from estimagic.logging.database_utilities import read_last_rows
 from estimagic.logging.read_log import read_start_params
+from jinja2 import Environment
+from jinja2 import FileSystemLoader
 
 
 def monitoring_app(
diff --git a/estimagic/dashboard/monitoring_callbacks.py b/src/estimagic/dashboard/monitoring_callbacks.py
similarity index 99%
rename from estimagic/dashboard/monitoring_callbacks.py
rename to src/estimagic/dashboard/monitoring_callbacks.py
index 2df821d95..2f629e4ca 100644
--- a/estimagic/dashboard/monitoring_callbacks.py
+++ b/src/estimagic/dashboard/monitoring_callbacks.py
@@ -2,7 +2,6 @@
 from functools import partial
 
 import numpy as np
-
 from estimagic.logging.database_utilities import read_new_rows
 from estimagic.logging.database_utilities import transpose_nested_list
 
diff --git a/estimagic/dashboard/plot_functions.py b/src/estimagic/dashboard/plot_functions.py
similarity index 99%
rename from estimagic/dashboard/plot_functions.py
rename to src/estimagic/dashboard/plot_functions.py
index 2c358fec2..859abe224 100644
--- a/estimagic/dashboard/plot_functions.py
+++ b/src/estimagic/dashboard/plot_functions.py
@@ -2,7 +2,6 @@
 from bokeh.models import HoverTool
 from bokeh.models import Legend
 from bokeh.plotting import figure
-
 from estimagic.config import GRID_VISIBLE
 from estimagic.config import LEGEND_LABEL_TEXT_FONT_SIZE
 from estimagic.config import LEGEND_SPACING
diff --git a/estimagic/dashboard/run_dashboard.py b/src/estimagic/dashboard/run_dashboard.py
similarity index 99%
rename from estimagic/dashboard/run_dashboard.py
rename to src/estimagic/dashboard/run_dashboard.py
index 0a3d67ca0..b1def74bd 100644
--- a/estimagic/dashboard/run_dashboard.py
+++ b/src/estimagic/dashboard/run_dashboard.py
@@ -8,7 +8,6 @@
 from bokeh.application.handlers.function import FunctionHandler
 from bokeh.command.util import report_server_init_errors
 from bokeh.server.server import Server
-
 from estimagic.dashboard.create_short_database_names import create_short_database_names
 from estimagic.dashboard.master_app import master_app
 from estimagic.dashboard.monitoring_app import monitoring_app
diff --git a/estimagic/dashboard/styles.css b/src/estimagic/dashboard/styles.css
similarity index 100%
rename from estimagic/dashboard/styles.css
rename to src/estimagic/dashboard/styles.css
diff --git a/estimagic/decorators.py b/src/estimagic/decorators.py
similarity index 99%
rename from estimagic/decorators.py
rename to src/estimagic/decorators.py
index 169d00938..a2b0d29ec 100644
--- a/estimagic/decorators.py
+++ b/src/estimagic/decorators.py
@@ -15,7 +15,6 @@
 
 import numpy as np
 import pandas as pd
-
 from estimagic.exceptions import get_traceback
 from estimagic.parameters.process_constraints import process_constraints
 from estimagic.parameters.reparametrize import reparametrize_from_internal
diff --git a/estimagic/differentiation/__init__.py b/src/estimagic/differentiation/__init__.py
similarity index 100%
rename from estimagic/differentiation/__init__.py
rename to src/estimagic/differentiation/__init__.py
diff --git a/estimagic/differentiation/derivatives.py b/src/estimagic/differentiation/derivatives.py
similarity index 99%
rename from estimagic/differentiation/derivatives.py
rename to src/estimagic/differentiation/derivatives.py
index 592d77fc3..ae3d7c6ea 100644
--- a/estimagic/differentiation/derivatives.py
+++ b/src/estimagic/differentiation/derivatives.py
@@ -5,7 +5,6 @@
 
 import numpy as np
 import pandas as pd
-
 from estimagic import batch_evaluators
 from estimagic.config import DEFAULT_N_CORES
 from estimagic.differentiation import finite_differences
diff --git a/estimagic/differentiation/finite_differences.py b/src/estimagic/differentiation/finite_differences.py
similarity index 100%
rename from estimagic/differentiation/finite_differences.py
rename to src/estimagic/differentiation/finite_differences.py
diff --git a/estimagic/differentiation/generate_steps.py b/src/estimagic/differentiation/generate_steps.py
similarity index 99%
rename from estimagic/differentiation/generate_steps.py
rename to src/estimagic/differentiation/generate_steps.py
index 1d80da076..f4b949ead 100644
--- a/estimagic/differentiation/generate_steps.py
+++ b/src/estimagic/differentiation/generate_steps.py
@@ -1,7 +1,6 @@
 import warnings
 
 import numpy as np
-
 from estimagic.utilities import namedtuple_from_kwargs
 
 
diff --git a/estimagic/differentiation/richardson_extrapolation.py b/src/estimagic/differentiation/richardson_extrapolation.py
similarity index 100%
rename from estimagic/differentiation/richardson_extrapolation.py
rename to src/estimagic/differentiation/richardson_extrapolation.py
diff --git a/estimagic/estimation/__init__.py b/src/estimagic/estimation/__init__.py
similarity index 100%
rename from estimagic/estimation/__init__.py
rename to src/estimagic/estimation/__init__.py
diff --git a/estimagic/estimation/estimate_ml.py b/src/estimagic/estimation/estimate_ml.py
similarity index 100%
rename from estimagic/estimation/estimate_ml.py
rename to src/estimagic/estimation/estimate_ml.py
diff --git a/estimagic/estimation/estimate_msm.py b/src/estimagic/estimation/estimate_msm.py
similarity index 99%
rename from estimagic/estimation/estimate_msm.py
rename to src/estimagic/estimation/estimate_msm.py
index aae4ce289..58f3c8f6b 100644
--- a/estimagic/estimation/estimate_msm.py
+++ b/src/estimagic/estimation/estimate_msm.py
@@ -4,7 +4,6 @@
 
 import numpy as np
 import pandas as pd
-
 from estimagic.estimation.msm_weighting import get_weighting_matrix
 from estimagic.inference.msm_covs import cov_optimal
 from estimagic.inference.msm_covs import cov_robust
diff --git a/estimagic/estimation/msm_weighting.py b/src/estimagic/estimation/msm_weighting.py
similarity index 99%
rename from estimagic/estimation/msm_weighting.py
rename to src/estimagic/estimation/msm_weighting.py
index 9a12912e9..33c60c3be 100644
--- a/estimagic/estimation/msm_weighting.py
+++ b/src/estimagic/estimation/msm_weighting.py
@@ -1,9 +1,8 @@
 import numpy as np
 import pandas as pd
-from scipy.linalg import block_diag
-
 from estimagic.inference.bootstrap import bootstrap
 from estimagic.utilities import robust_inverse
+from scipy.linalg import block_diag
 
 
 def get_moments_cov(data, calculate_moments, moment_kwargs=None, bootstrap_kwargs=None):
diff --git a/estimagic/examples/__init__.py b/src/estimagic/examples/__init__.py
similarity index 100%
rename from estimagic/examples/__init__.py
rename to src/estimagic/examples/__init__.py
diff --git a/estimagic/examples/criterion_functions.py b/src/estimagic/examples/criterion_functions.py
similarity index 100%
rename from estimagic/examples/criterion_functions.py
rename to src/estimagic/examples/criterion_functions.py
diff --git a/estimagic/tests/dashboard/db1.db b/src/estimagic/examples/db1.db
similarity index 100%
rename from estimagic/tests/dashboard/db1.db
rename to src/estimagic/examples/db1.db
diff --git a/estimagic/tests/dashboard/db2.db b/src/estimagic/examples/db2.db
similarity index 100%
rename from estimagic/tests/dashboard/db2.db
rename to src/estimagic/examples/db2.db
diff --git a/estimagic/tests/visualization/diabetes.csv b/src/estimagic/examples/diabetes.csv
similarity index 100%
rename from estimagic/tests/visualization/diabetes.csv
rename to src/estimagic/examples/diabetes.csv
diff --git a/estimagic/examples/exam_points.csv b/src/estimagic/examples/exam_points.csv
similarity index 100%
rename from estimagic/examples/exam_points.csv
rename to src/estimagic/examples/exam_points.csv
diff --git a/estimagic/examples/logit.py b/src/estimagic/examples/logit.py
similarity index 100%
rename from estimagic/examples/logit.py
rename to src/estimagic/examples/logit.py
diff --git a/estimagic/examples/numdiff_functions.py b/src/estimagic/examples/numdiff_functions.py
similarity index 100%
rename from estimagic/examples/numdiff_functions.py
rename to src/estimagic/examples/numdiff_functions.py
diff --git a/estimagic/tests/sensitivity/sensitivity_probit_example_data.csv b/src/estimagic/examples/sensitivity_probit_example_data.csv
similarity index 100%
rename from estimagic/tests/sensitivity/sensitivity_probit_example_data.csv
rename to src/estimagic/examples/sensitivity_probit_example_data.csv
diff --git a/estimagic/exceptions.py b/src/estimagic/exceptions.py
similarity index 100%
rename from estimagic/exceptions.py
rename to src/estimagic/exceptions.py
diff --git a/estimagic/inference/__init__.py b/src/estimagic/inference/__init__.py
similarity index 100%
rename from estimagic/inference/__init__.py
rename to src/estimagic/inference/__init__.py
diff --git a/estimagic/inference/bootstrap.py b/src/estimagic/inference/bootstrap.py
similarity index 99%
rename from estimagic/inference/bootstrap.py
rename to src/estimagic/inference/bootstrap.py
index 985feac99..69cfd8812 100644
--- a/estimagic/inference/bootstrap.py
+++ b/src/estimagic/inference/bootstrap.py
@@ -1,5 +1,4 @@
 import pandas as pd
-
 from estimagic.batch_evaluators import joblib_batch_evaluator
 from estimagic.inference.bootstrap_ci import compute_ci
 from estimagic.inference.bootstrap_helpers import check_inputs
diff --git a/estimagic/inference/bootstrap_ci.py b/src/estimagic/inference/bootstrap_ci.py
similarity index 99%
rename from estimagic/inference/bootstrap_ci.py
rename to src/estimagic/inference/bootstrap_ci.py
index c008a5fdc..6531a1924 100644
--- a/estimagic/inference/bootstrap_ci.py
+++ b/src/estimagic/inference/bootstrap_ci.py
@@ -1,11 +1,10 @@
 import numpy as np
 import pandas as pd
+from estimagic.inference.bootstrap_helpers import check_inputs
 from joblib import delayed
 from joblib import Parallel
 from scipy.stats import norm
 
-from estimagic.inference.bootstrap_helpers import check_inputs
-
 
 def compute_ci(data, outcome, estimates, ci_method="percentile", alpha=0.05, n_cores=1):
     """Compute confidence interval of bootstrap estimates. Parts of the code of the
diff --git a/estimagic/inference/bootstrap_helpers.py b/src/estimagic/inference/bootstrap_helpers.py
similarity index 100%
rename from estimagic/inference/bootstrap_helpers.py
rename to src/estimagic/inference/bootstrap_helpers.py
diff --git a/estimagic/inference/bootstrap_outcomes.py b/src/estimagic/inference/bootstrap_outcomes.py
similarity index 99%
rename from estimagic/inference/bootstrap_outcomes.py
rename to src/estimagic/inference/bootstrap_outcomes.py
index bd6fb6b75..53eee0148 100644
--- a/estimagic/inference/bootstrap_outcomes.py
+++ b/src/estimagic/inference/bootstrap_outcomes.py
@@ -1,7 +1,6 @@
 from functools import partial
 
 import pandas as pd
-
 from estimagic.batch_evaluators import joblib_batch_evaluator
 from estimagic.inference.bootstrap_helpers import check_inputs
 from estimagic.inference.bootstrap_samples import get_bootstrap_indices
diff --git a/estimagic/inference/bootstrap_samples.py b/src/estimagic/inference/bootstrap_samples.py
similarity index 100%
rename from estimagic/inference/bootstrap_samples.py
rename to src/estimagic/inference/bootstrap_samples.py
diff --git a/estimagic/inference/ml_covs.py b/src/estimagic/inference/ml_covs.py
similarity index 99%
rename from estimagic/inference/ml_covs.py
rename to src/estimagic/inference/ml_covs.py
index 15ab461dc..23299daa1 100644
--- a/estimagic/inference/ml_covs.py
+++ b/src/estimagic/inference/ml_covs.py
@@ -1,7 +1,6 @@
 """Functions for inferences in maximum likelihood models."""
 import numpy as np
 import pandas as pd
-
 from estimagic.exceptions import INVALID_INFERENCE_MSG
 from estimagic.inference.shared import process_pandas_arguments
 from estimagic.utilities import robust_inverse
diff --git a/estimagic/inference/msm_covs.py b/src/estimagic/inference/msm_covs.py
similarity index 99%
rename from estimagic/inference/msm_covs.py
rename to src/estimagic/inference/msm_covs.py
index e1cdc5bc2..fabf9bf40 100644
--- a/estimagic/inference/msm_covs.py
+++ b/src/estimagic/inference/msm_covs.py
@@ -1,5 +1,4 @@
 import pandas as pd
-
 from estimagic.exceptions import INVALID_INFERENCE_MSG
 from estimagic.inference.shared import process_pandas_arguments
 from estimagic.utilities import robust_inverse
diff --git a/estimagic/inference/shared.py b/src/estimagic/inference/shared.py
similarity index 99%
rename from estimagic/inference/shared.py
rename to src/estimagic/inference/shared.py
index 1fde110a4..b8762a5dc 100644
--- a/estimagic/inference/shared.py
+++ b/src/estimagic/inference/shared.py
@@ -4,7 +4,6 @@
 import numpy as np
 import pandas as pd
 import scipy
-
 from estimagic.decorators import numpy_interface
 from estimagic.differentiation.derivatives import first_derivative
 from estimagic.parameters.parameter_conversion import get_internal_bounds
diff --git a/estimagic/logging/__init__.py b/src/estimagic/logging/__init__.py
similarity index 100%
rename from estimagic/logging/__init__.py
rename to src/estimagic/logging/__init__.py
diff --git a/estimagic/logging/database_utilities.py b/src/estimagic/logging/database_utilities.py
similarity index 99%
rename from estimagic/logging/database_utilities.py
rename to src/estimagic/logging/database_utilities.py
index c24483c43..d60656242 100644
--- a/estimagic/logging/database_utilities.py
+++ b/src/estimagic/logging/database_utilities.py
@@ -16,6 +16,8 @@
 
 import cloudpickle
 import pandas as pd
+from estimagic.exceptions import get_traceback
+from estimagic.exceptions import TableExistsError
 from sqlalchemy import and_
 from sqlalchemy import BLOB
 from sqlalchemy import Boolean
@@ -30,9 +32,6 @@
 from sqlalchemy import Table
 from sqlalchemy.dialects.sqlite import DATETIME
 
-from estimagic.exceptions import get_traceback
-from estimagic.exceptions import TableExistsError
-
 
 def load_database(metadata=None, path=None, fast_logging=False):
     """Return a bound sqlalchemy.MetaData object for the database stored in ``path``.
diff --git a/estimagic/logging/read_log.py b/src/estimagic/logging/read_log.py
similarity index 99%
rename from estimagic/logging/read_log.py
rename to src/estimagic/logging/read_log.py
index b3f84e168..c8e0276ea 100644
--- a/estimagic/logging/read_log.py
+++ b/src/estimagic/logging/read_log.py
@@ -9,11 +9,10 @@
 """
 from pathlib import Path
 
-from sqlalchemy import MetaData
-
 from estimagic.logging.database_utilities import load_database
 from estimagic.logging.database_utilities import read_last_rows
 from estimagic.logging.database_utilities import read_specific_row
+from sqlalchemy import MetaData
 
 
 def read_optimization_iteration(path_or_database, iteration, include_internals=False):
diff --git a/estimagic/optimization/__init__.py b/src/estimagic/optimization/__init__.py
similarity index 100%
rename from estimagic/optimization/__init__.py
rename to src/estimagic/optimization/__init__.py
diff --git a/estimagic/optimization/algo_options.py b/src/estimagic/optimization/algo_options.py
similarity index 100%
rename from estimagic/optimization/algo_options.py
rename to src/estimagic/optimization/algo_options.py
diff --git a/estimagic/optimization/broadcast_arguments.py b/src/estimagic/optimization/broadcast_arguments.py
similarity index 100%
rename from estimagic/optimization/broadcast_arguments.py
rename to src/estimagic/optimization/broadcast_arguments.py
diff --git a/estimagic/optimization/check_arguments.py b/src/estimagic/optimization/check_arguments.py
similarity index 99%
rename from estimagic/optimization/check_arguments.py
rename to src/estimagic/optimization/check_arguments.py
index 699f964e4..40529dce9 100644
--- a/estimagic/optimization/check_arguments.py
+++ b/src/estimagic/optimization/check_arguments.py
@@ -3,7 +3,6 @@
 from pathlib import Path
 
 import pandas as pd
-
 from estimagic.shared.check_option_dicts import check_numdiff_options
 
 
diff --git a/estimagic/optimization/cyipopt_optimizers.py b/src/estimagic/optimization/cyipopt_optimizers.py
similarity index 100%
rename from estimagic/optimization/cyipopt_optimizers.py
rename to src/estimagic/optimization/cyipopt_optimizers.py
diff --git a/estimagic/optimization/internal_criterion_template.py b/src/estimagic/optimization/internal_criterion_template.py
similarity index 99%
rename from estimagic/optimization/internal_criterion_template.py
rename to src/estimagic/optimization/internal_criterion_template.py
index bb0edc742..831bf2d51 100644
--- a/estimagic/optimization/internal_criterion_template.py
+++ b/src/estimagic/optimization/internal_criterion_template.py
@@ -2,7 +2,6 @@
 import warnings
 
 import numpy as np
-
 from estimagic.differentiation.derivatives import first_derivative
 from estimagic.exceptions import get_traceback
 from estimagic.logging.database_utilities import append_row
diff --git a/estimagic/optimization/nag_optimizers.py b/src/estimagic/optimization/nag_optimizers.py
similarity index 99%
rename from estimagic/optimization/nag_optimizers.py
rename to src/estimagic/optimization/nag_optimizers.py
index 1184c8d0f..9f0d1130c 100644
--- a/estimagic/optimization/nag_optimizers.py
+++ b/src/estimagic/optimization/nag_optimizers.py
@@ -13,7 +13,6 @@
 from functools import partial
 
 import numpy as np
-
 from estimagic.config import IS_DFOLS_INSTALLED
 from estimagic.config import IS_PYBOBYQA_INSTALLED
 from estimagic.optimization.algo_options import CLIP_CRITERION_IF_OVERFLOWING
diff --git a/estimagic/optimization/nlopt_optimizers.py b/src/estimagic/optimization/nlopt_optimizers.py
similarity index 99%
rename from estimagic/optimization/nlopt_optimizers.py
rename to src/estimagic/optimization/nlopt_optimizers.py
index f7e639e21..e999c4df7 100644
--- a/estimagic/optimization/nlopt_optimizers.py
+++ b/src/estimagic/optimization/nlopt_optimizers.py
@@ -4,7 +4,6 @@
 
 """
 import numpy as np
-
 from estimagic.config import IS_NLOPT_INSTALLED
 from estimagic.optimization.algo_options import CONVERGENCE_ABSOLUTE_CRITERION_TOLERANCE
 from estimagic.optimization.algo_options import CONVERGENCE_ABSOLUTE_PARAMS_TOLERANCE
diff --git a/estimagic/optimization/optimize.py b/src/estimagic/optimization/optimize.py
similarity index 99%
rename from estimagic/optimization/optimize.py
rename to src/estimagic/optimization/optimize.py
index 5cf8bae7c..516c44112 100644
--- a/estimagic/optimization/optimize.py
+++ b/src/estimagic/optimization/optimize.py
@@ -3,9 +3,8 @@
 import warnings
 from pathlib import Path
 
-import numpy as np
-
 import estimagic.batch_evaluators as be
+import numpy as np
 from estimagic.config import CRITERION_PENALTY_CONSTANT
 from estimagic.config import CRITERION_PENALTY_SLOPE
 from estimagic.logging.database_utilities import append_row
diff --git a/estimagic/optimization/pygmo_optimizers.py b/src/estimagic/optimization/pygmo_optimizers.py
similarity index 99%
rename from estimagic/optimization/pygmo_optimizers.py
rename to src/estimagic/optimization/pygmo_optimizers.py
index cf2df43b0..ccf9a17d7 100644
--- a/estimagic/optimization/pygmo_optimizers.py
+++ b/src/estimagic/optimization/pygmo_optimizers.py
@@ -3,7 +3,6 @@
 import warnings
 
 import numpy as np
-
 from estimagic import batch_evaluators
 from estimagic.config import IS_PYGMO_INSTALLED
 from estimagic.optimization.algo_options import CONVERGENCE_RELATIVE_PARAMS_TOLERANCE
diff --git a/estimagic/optimization/scaling.py b/src/estimagic/optimization/scaling.py
similarity index 99%
rename from estimagic/optimization/scaling.py
rename to src/estimagic/optimization/scaling.py
index d3d26a366..8b8d58bdf 100644
--- a/estimagic/optimization/scaling.py
+++ b/src/estimagic/optimization/scaling.py
@@ -10,7 +10,6 @@
 
 """
 import numpy as np
-
 from estimagic.differentiation.derivatives import first_derivative
 from estimagic.parameters.parameter_conversion import get_internal_bounds
 from estimagic.parameters.parameter_conversion import get_reparametrize_functions
diff --git a/estimagic/optimization/scipy_optimizers.py b/src/estimagic/optimization/scipy_optimizers.py
similarity index 99%
rename from estimagic/optimization/scipy_optimizers.py
rename to src/estimagic/optimization/scipy_optimizers.py
index dd9a95ee6..f97c93c40 100644
--- a/estimagic/optimization/scipy_optimizers.py
+++ b/src/estimagic/optimization/scipy_optimizers.py
@@ -42,7 +42,6 @@
 
 import numpy as np
 import scipy
-
 from estimagic.optimization.algo_options import CONVERGENCE_ABSOLUTE_CRITERION_TOLERANCE
 from estimagic.optimization.algo_options import CONVERGENCE_ABSOLUTE_GRADIENT_TOLERANCE
 from estimagic.optimization.algo_options import CONVERGENCE_ABSOLUTE_PARAMS_TOLERANCE
diff --git a/estimagic/optimization/tao_optimizers.py b/src/estimagic/optimization/tao_optimizers.py
similarity index 99%
rename from estimagic/optimization/tao_optimizers.py
rename to src/estimagic/optimization/tao_optimizers.py
index 62c957c91..0ecb9176e 100644
--- a/estimagic/optimization/tao_optimizers.py
+++ b/src/estimagic/optimization/tao_optimizers.py
@@ -2,7 +2,6 @@
 import functools
 
 import numpy as np
-
 from estimagic.config import IS_PETSC4PY_INSTALLED
 from estimagic.optimization.algo_options import CONVERGENCE_ABSOLUTE_GRADIENT_TOLERANCE
 from estimagic.optimization.algo_options import CONVERGENCE_RELATIVE_GRADIENT_TOLERANCE
diff --git a/estimagic/parameters/__init__.py b/src/estimagic/parameters/__init__.py
similarity index 100%
rename from estimagic/parameters/__init__.py
rename to src/estimagic/parameters/__init__.py
diff --git a/estimagic/parameters/check_constraints.py b/src/estimagic/parameters/check_constraints.py
similarity index 99%
rename from estimagic/parameters/check_constraints.py
rename to src/estimagic/parameters/check_constraints.py
index 95ef39fbf..28edcf5f4 100644
--- a/estimagic/parameters/check_constraints.py
+++ b/src/estimagic/parameters/check_constraints.py
@@ -5,7 +5,6 @@
 import warnings
 
 import numpy as np
-
 from estimagic.utilities import cov_params_to_matrix
 from estimagic.utilities import sdcorr_params_to_matrix
 
diff --git a/estimagic/parameters/consolidate_constraints.py b/src/estimagic/parameters/consolidate_constraints.py
similarity index 99%
rename from estimagic/parameters/consolidate_constraints.py
rename to src/estimagic/parameters/consolidate_constraints.py
index 58271ee34..540018637 100644
--- a/estimagic/parameters/consolidate_constraints.py
+++ b/src/estimagic/parameters/consolidate_constraints.py
@@ -8,7 +8,6 @@
 """
 import numpy as np
 import pandas as pd
-
 from estimagic.utilities import number_of_triangular_elements_to_dimension
 
 
diff --git a/estimagic/parameters/kernel_transformations.py b/src/estimagic/parameters/kernel_transformations.py
similarity index 99%
rename from estimagic/parameters/kernel_transformations.py
rename to src/estimagic/parameters/kernel_transformations.py
index 61425c33c..093a2a1f1 100644
--- a/estimagic/parameters/kernel_transformations.py
+++ b/src/estimagic/parameters/kernel_transformations.py
@@ -29,7 +29,6 @@
 
 """
 import numpy as np
-
 from estimagic.utilities import chol_params_to_lower_triangular_matrix
 from estimagic.utilities import cov_matrix_to_sdcorr_params
 from estimagic.utilities import cov_params_to_matrix
diff --git a/estimagic/parameters/parameter_conversion.py b/src/estimagic/parameters/parameter_conversion.py
similarity index 100%
rename from estimagic/parameters/parameter_conversion.py
rename to src/estimagic/parameters/parameter_conversion.py
diff --git a/estimagic/parameters/parameter_preprocessing.py b/src/estimagic/parameters/parameter_preprocessing.py
similarity index 100%
rename from estimagic/parameters/parameter_preprocessing.py
rename to src/estimagic/parameters/parameter_preprocessing.py
diff --git a/estimagic/parameters/process_constraints.py b/src/estimagic/parameters/process_constraints.py
similarity index 99%
rename from estimagic/parameters/process_constraints.py
rename to src/estimagic/parameters/process_constraints.py
index efee2639a..32b40638a 100644
--- a/estimagic/parameters/process_constraints.py
+++ b/src/estimagic/parameters/process_constraints.py
@@ -32,7 +32,6 @@
 
 import numpy as np
 import pandas as pd
-
 from estimagic.parameters.check_constraints import check_constraints_are_satisfied
 from estimagic.parameters.check_constraints import check_fixes_and_bounds
 from estimagic.parameters.check_constraints import check_for_incompatible_overlaps
diff --git a/estimagic/parameters/reparametrize.py b/src/estimagic/parameters/reparametrize.py
similarity index 99%
rename from estimagic/parameters/reparametrize.py
rename to src/estimagic/parameters/reparametrize.py
index 31f528d99..f8558ae2d 100644
--- a/estimagic/parameters/reparametrize.py
+++ b/src/estimagic/parameters/reparametrize.py
@@ -34,11 +34,10 @@
 n_internal the length of the internal parameter vector.
 
 """
+import estimagic.parameters.kernel_transformations as kt
 import numpy as np
 import pandas as pd
 
-import estimagic.parameters.kernel_transformations as kt
-
 
 def reparametrize_to_internal(
     external,
diff --git a/estimagic/sensitivity/msm_sensitivity.py b/src/estimagic/sensitivity/msm_sensitivity.py
similarity index 99%
rename from estimagic/sensitivity/msm_sensitivity.py
rename to src/estimagic/sensitivity/msm_sensitivity.py
index 4204b70c2..8837e84c8 100644
--- a/estimagic/sensitivity/msm_sensitivity.py
+++ b/src/estimagic/sensitivity/msm_sensitivity.py
@@ -10,7 +10,6 @@
 """
 import numpy as np
 import pandas as pd
-
 from estimagic.estimation.msm_weighting import get_weighting_matrix
 from estimagic.exceptions import INVALID_SENSITIVITY_MSG
 from estimagic.inference.msm_covs import cov_optimal
diff --git a/estimagic/shared/check_option_dicts.py b/src/estimagic/shared/check_option_dicts.py
similarity index 100%
rename from estimagic/shared/check_option_dicts.py
rename to src/estimagic/shared/check_option_dicts.py
diff --git a/estimagic/utilities.py b/src/estimagic/utilities.py
similarity index 100%
rename from estimagic/utilities.py
rename to src/estimagic/utilities.py
diff --git a/estimagic/tests/__init__.py b/src/estimagic/visualization/__init__.py
similarity index 100%
rename from estimagic/tests/__init__.py
rename to src/estimagic/visualization/__init__.py
diff --git a/estimagic/visualization/colors.py b/src/estimagic/visualization/colors.py
similarity index 99%
rename from estimagic/visualization/colors.py
rename to src/estimagic/visualization/colors.py
index 7769c9b21..cf55f1346 100644
--- a/estimagic/visualization/colors.py
+++ b/src/estimagic/visualization/colors.py
@@ -1,5 +1,4 @@
 import numpy as np
-
 from estimagic.config import IS_MATPLOTLIB_INSTALLED
 
 if IS_MATPLOTLIB_INSTALLED:
diff --git a/estimagic/visualization/derivative_plot.py b/src/estimagic/visualization/derivative_plot.py
similarity index 100%
rename from estimagic/visualization/derivative_plot.py
rename to src/estimagic/visualization/derivative_plot.py
diff --git a/estimagic/visualization/estimation_table.py b/src/estimagic/visualization/estimation_table.py
similarity index 100%
rename from estimagic/visualization/estimation_table.py
rename to src/estimagic/visualization/estimation_table.py
diff --git a/estimagic/visualization/lollipop_plot.py b/src/estimagic/visualization/lollipop_plot.py
similarity index 99%
rename from estimagic/visualization/lollipop_plot.py
rename to src/estimagic/visualization/lollipop_plot.py
index 668e80abc..f86a6342d 100644
--- a/estimagic/visualization/lollipop_plot.py
+++ b/src/estimagic/visualization/lollipop_plot.py
@@ -1,6 +1,5 @@
 import pandas as pd
 import seaborn as sns
-
 from estimagic.visualization.colors import get_colors
 
 
diff --git a/estimagic/visualization/univariate_effects.py b/src/estimagic/visualization/univariate_effects.py
similarity index 99%
rename from estimagic/visualization/univariate_effects.py
rename to src/estimagic/visualization/univariate_effects.py
index 387f02f3b..c543800c5 100644
--- a/estimagic/visualization/univariate_effects.py
+++ b/src/estimagic/visualization/univariate_effects.py
@@ -1,7 +1,6 @@
 import numpy as np
 import pandas as pd
 import seaborn as sns
-
 from estimagic.visualization.colors import get_colors
 
 
diff --git a/tox.ini b/tox.ini
index 4b4f516b4..b6894138b 100644
--- a/tox.ini
+++ b/tox.ini
@@ -61,8 +61,9 @@ conda_deps =
     sphinx-panels
 commands =
     # Add W flag to builds so that warnings become errors.
-    sphinx-build -nT -b html -d {envtmpdir}/doctrees . {envtmpdir}/html
-    sphinx-build -nT -b linkcheck -d {envtmpdir}/doctrees . {envtmpdir}/linkcheck
+    sphinx-build -T -b html -d {envtmpdir}/doctrees . {envtmpdir}/html
+    sphinx-build -T -b linkcheck -d {envtmpdir}/doctrees . {envtmpdir}/linkcheck
+
 
 [doc8]
 ignore =


Test patch:
diff --git a/estimagic/tests/dashboard/__init__.py b/estimagic/tests/dashboard/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/estimagic/tests/differentiation/__init__.py b/estimagic/tests/differentiation/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/estimagic/tests/estimation/__init__.py b/estimagic/tests/estimation/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/estimagic/tests/examples/__init__.py b/estimagic/tests/examples/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/estimagic/tests/inference/__init__.py b/estimagic/tests/inference/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/estimagic/tests/logging/__init__.py b/estimagic/tests/logging/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/estimagic/tests/optimization/__init__.py b/estimagic/tests/optimization/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/estimagic/tests/parameters/__init__.py b/estimagic/tests/parameters/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/estimagic/tests/visualization/__init__.py b/estimagic/tests/visualization/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/estimagic/tests/conftest.py b/tests/conftest.py
similarity index 100%
rename from estimagic/tests/conftest.py
rename to tests/conftest.py
diff --git a/estimagic/tests/dashboard/test_create_short_database_names.py b/tests/dashboard/test_create_short_database_names.py
similarity index 100%
rename from estimagic/tests/dashboard/test_create_short_database_names.py
rename to tests/dashboard/test_create_short_database_names.py
diff --git a/estimagic/tests/dashboard/test_master_app.py b/tests/dashboard/test_master_app.py
similarity index 99%
rename from estimagic/tests/dashboard/test_master_app.py
rename to tests/dashboard/test_master_app.py
index c97de8c50..598f348a1 100644
--- a/estimagic/tests/dashboard/test_master_app.py
+++ b/tests/dashboard/test_master_app.py
@@ -1,9 +1,8 @@
 """Test the functions of the dashboards master_app.py."""
 from pathlib import Path
 
-from bokeh.document import Document
-
 import estimagic.dashboard.master_app as master_app
+from bokeh.document import Document
 
 
 def test_master_app():
diff --git a/estimagic/tests/dashboard/test_monitoring_app.py b/tests/dashboard/test_monitoring_app.py
similarity index 97%
rename from estimagic/tests/dashboard/test_monitoring_app.py
rename to tests/dashboard/test_monitoring_app.py
index db9fbb056..ffce612ad 100644
--- a/estimagic/tests/dashboard/test_monitoring_app.py
+++ b/tests/dashboard/test_monitoring_app.py
@@ -1,14 +1,12 @@
 """Test the functions of the monitoring app."""
-from pathlib import Path
-
+import estimagic.dashboard.monitoring_app as monitoring
 import numpy as np
 import pandas as pd
 import pandas.testing as pdt
 import pytest
 from bokeh.document import Document
 from bokeh.models import ColumnDataSource
-
-import estimagic.dashboard.monitoring_app as monitoring
+from estimagic.config import EXAMPLE_DIR
 from estimagic.optimization.optimize import minimize
 
 
@@ -16,8 +14,7 @@ def test_monitoring_app():
     """Integration test that no Error is raised when calling the monitoring app."""
     doc = Document()
     database_name = "test_db"
-    current_dir_path = Path(__file__).resolve().parent
-    db_path = current_dir_path / "db2.db"
+    db_path = EXAMPLE_DIR / "db2.db"
 
     needs_update = False
     if needs_update:
diff --git a/estimagic/tests/dashboard/test_monitoring_callbacks.py b/tests/dashboard/test_monitoring_callbacks.py
similarity index 99%
rename from estimagic/tests/dashboard/test_monitoring_callbacks.py
rename to tests/dashboard/test_monitoring_callbacks.py
index 1a820f37a..498281185 100644
--- a/estimagic/tests/dashboard/test_monitoring_callbacks.py
+++ b/tests/dashboard/test_monitoring_callbacks.py
@@ -2,7 +2,6 @@
 from bokeh.models import ColumnDataSource
 from bokeh.models import Toggle
 from bokeh.plotting import figure
-
 from estimagic.dashboard.monitoring_callbacks import _create_params_data_for_update
 from estimagic.dashboard.monitoring_callbacks import _reset_column_data_sources
 from estimagic.dashboard.monitoring_callbacks import _switch_to_linear_scale
diff --git a/estimagic/tests/dashboard/test_run_dashboard.py b/tests/dashboard/test_run_dashboard.py
similarity index 86%
rename from estimagic/tests/dashboard/test_run_dashboard.py
rename to tests/dashboard/test_run_dashboard.py
index e67df890b..ed0e488a1 100644
--- a/estimagic/tests/dashboard/test_run_dashboard.py
+++ b/tests/dashboard/test_run_dashboard.py
@@ -1,18 +1,15 @@
 """Test the functions to run the dashboard."""
-from pathlib import Path
-
 import pytest
 from click.testing import CliRunner
-
 from estimagic.cli import cli
+from estimagic.config import EXAMPLE_DIR
 from estimagic.dashboard.run_dashboard import _create_session_data
 from estimagic.dashboard.run_dashboard import _process_database_paths
 
 
 @pytest.fixture()
 def database_paths():
-    current_dir_path = Path(__file__).resolve().parent
-    database_paths = [current_dir_path / "db1.db", current_dir_path / "db2.db"]
+    database_paths = [EXAMPLE_DIR / "db1.db", EXAMPLE_DIR / "db2.db"]
     return database_paths
 
 
@@ -23,7 +20,7 @@ def database_name_to_path(database_paths):
 
 
 def test_process_dashboard_args_single_path():
-    single_path = Path(__file__).resolve().parent / "db1.db"
+    single_path = EXAMPLE_DIR / "db1.db"
     database_name_to_path = _process_database_paths(database_paths=single_path)
     assert database_name_to_path == {"db1": single_path}
 
@@ -76,7 +73,7 @@ def fake_run_dashboard(
         cli,
         [
             "dashboard",
-            str(Path(__file__).parent / "*.db"),
+            str(EXAMPLE_DIR / "*.db"),
             "--no-browser",
             "--port",
             "9999",
@@ -106,9 +103,9 @@ def fake_run_dashboard(
         cli,
         [
             "dashboard",
-            str(Path(__file__).parent / "*.db"),
-            str(Path(__file__).parent / "db1.db"),
-            str(Path(__file__).parent / "db2.db"),
+            str(EXAMPLE_DIR / "*.db"),
+            str(EXAMPLE_DIR / "db1.db"),
+            str(EXAMPLE_DIR / "db2.db"),
             "--stride",
             "10",
         ],
@@ -129,6 +126,6 @@ def fake_run_dashboard(
     monkeypatch.setattr("estimagic.cli.run_dashboard", fake_run_dashboard)
 
     runner = CliRunner()
-    result = runner.invoke(cli, ["dashboard", str(Path(__file__).parent)])
+    result = runner.invoke(cli, ["dashboard", str(EXAMPLE_DIR)])
 
     assert result.exit_code == 0
diff --git a/estimagic/tests/differentiation/binary_choice_inputs.pickle b/tests/differentiation/binary_choice_inputs.pickle
similarity index 100%
rename from estimagic/tests/differentiation/binary_choice_inputs.pickle
rename to tests/differentiation/binary_choice_inputs.pickle
diff --git a/estimagic/tests/differentiation/test_derivatives.py b/tests/differentiation/test_derivatives.py
similarity index 99%
rename from estimagic/tests/differentiation/test_derivatives.py
rename to tests/differentiation/test_derivatives.py
index f71b6d9c0..e142047e2 100644
--- a/estimagic/tests/differentiation/test_derivatives.py
+++ b/tests/differentiation/test_derivatives.py
@@ -4,10 +4,6 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-from pandas.testing import assert_frame_equal
-from scipy.optimize._numdiff import approx_derivative
-
 from estimagic.differentiation.derivatives import _consolidate_one_step_derivatives
 from estimagic.differentiation.derivatives import _convert_evaluation_data_to_frame
 from estimagic.differentiation.derivatives import (
@@ -21,6 +17,9 @@
 from estimagic.examples.numdiff_functions import logit_loglikeobs
 from estimagic.examples.numdiff_functions import logit_loglikeobs_jacobian
 from estimagic.utilities import namedtuple_from_kwargs
+from numpy.testing import assert_array_almost_equal as aaae
+from pandas.testing import assert_frame_equal
+from scipy.optimize._numdiff import approx_derivative
 
 
 @pytest.fixture
diff --git a/estimagic/tests/differentiation/test_finite_differences.py b/tests/differentiation/test_finite_differences.py
similarity index 99%
rename from estimagic/tests/differentiation/test_finite_differences.py
rename to tests/differentiation/test_finite_differences.py
index c455fc5f1..4ce24a8b7 100644
--- a/estimagic/tests/differentiation/test_finite_differences.py
+++ b/tests/differentiation/test_finite_differences.py
@@ -1,9 +1,8 @@
 import numpy as np
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.differentiation.finite_differences import jacobian
 from estimagic.utilities import namedtuple_from_kwargs
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 @pytest.fixture(scope="function")
diff --git a/estimagic/tests/differentiation/test_generate_steps.py b/tests/differentiation/test_generate_steps.py
similarity index 99%
rename from estimagic/tests/differentiation/test_generate_steps.py
rename to tests/differentiation/test_generate_steps.py
index d3a2b60f1..2e1a5b478 100644
--- a/estimagic/tests/differentiation/test_generate_steps.py
+++ b/tests/differentiation/test_generate_steps.py
@@ -1,12 +1,11 @@
 import numpy as np
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.differentiation.generate_steps import _calculate_or_validate_base_steps
 from estimagic.differentiation.generate_steps import _fillna
 from estimagic.differentiation.generate_steps import _rescale_to_accomodate_bounds
 from estimagic.differentiation.generate_steps import _set_unused_side_to_nan
 from estimagic.differentiation.generate_steps import generate_steps
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 def test_scalars_as_base_steps():
diff --git a/estimagic/tests/estimation/test_estimate_ml.py b/tests/estimation/test_estimate_ml.py
similarity index 99%
rename from estimagic/tests/estimation/test_estimate_ml.py
rename to tests/estimation/test_estimate_ml.py
index b5ae03371..ef451ad12 100644
--- a/estimagic/tests/estimation/test_estimate_ml.py
+++ b/tests/estimation/test_estimate_ml.py
@@ -1,13 +1,12 @@
 import itertools
 
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.estimation.estimate_ml import estimate_ml
 from estimagic.examples.logit import logit_derivative
 from estimagic.examples.logit import logit_hessian
 from estimagic.examples.logit import logit_loglike
 from estimagic.examples.logit import logit_loglike_and_derivative
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 test_cases = itertools.product(
diff --git a/estimagic/tests/estimation/test_estimate_msm.py b/tests/estimation/test_estimate_msm.py
similarity index 99%
rename from estimagic/tests/estimation/test_estimate_msm.py
rename to tests/estimation/test_estimate_msm.py
index 4b8f1a5c6..b50cb39d9 100644
--- a/estimagic/tests/estimation/test_estimate_msm.py
+++ b/tests/estimation/test_estimate_msm.py
@@ -5,11 +5,10 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.estimation.estimate_msm import estimate_msm
 from estimagic.shared.check_option_dicts import check_numdiff_options
 from estimagic.shared.check_option_dicts import check_optimization_options
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 def _sim_pd(params):
diff --git a/estimagic/tests/estimation/test_msm_weighting.py b/tests/estimation/test_msm_weighting.py
similarity index 99%
rename from estimagic/tests/estimation/test_msm_weighting.py
rename to tests/estimation/test_msm_weighting.py
index e572d0693..645fa5e48 100644
--- a/estimagic/tests/estimation/test_msm_weighting.py
+++ b/tests/estimation/test_msm_weighting.py
@@ -3,10 +3,9 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.estimation.msm_weighting import assemble_block_diagonal_matrix
 from estimagic.estimation.msm_weighting import get_weighting_matrix
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 @pytest.fixture
diff --git a/estimagic/tests/examples/test_criterion_functions.py b/tests/examples/test_criterion_functions.py
similarity index 99%
rename from estimagic/tests/examples/test_criterion_functions.py
rename to tests/examples/test_criterion_functions.py
index 45391d071..0c20da941 100644
--- a/estimagic/tests/examples/test_criterion_functions.py
+++ b/tests/examples/test_criterion_functions.py
@@ -1,9 +1,6 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_allclose
-from numpy.testing import assert_array_equal
-
 from estimagic.examples.criterion_functions import (
     rosenbrock_criterion_and_gradient,
 )
@@ -38,6 +35,8 @@
 from estimagic.examples.criterion_functions import (
     trid_scalar_criterion,
 )
+from numpy.testing import assert_allclose
+from numpy.testing import assert_array_equal
 
 
 # Fix input params to test every criterion function
diff --git a/estimagic/tests/examples/test_logit.py b/tests/examples/test_logit.py
similarity index 99%
rename from estimagic/tests/examples/test_logit.py
rename to tests/examples/test_logit.py
index 07a8546e9..2b7b0b941 100644
--- a/estimagic/tests/examples/test_logit.py
+++ b/tests/examples/test_logit.py
@@ -1,10 +1,9 @@
 """Tests for the logit example."""
 import numpy as np
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.examples.logit import logit_derivative
 from estimagic.examples.logit import logit_hessian
 from estimagic.examples.logit import logit_loglike
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 def test_logit_loglike(logit_inputs, logit_object):
diff --git a/estimagic/tests/inference/fixtures/logit_hessian.pickle b/tests/inference/fixtures/logit_hessian.pickle
similarity index 100%
rename from estimagic/tests/inference/fixtures/logit_hessian.pickle
rename to tests/inference/fixtures/logit_hessian.pickle
diff --git a/estimagic/tests/inference/fixtures/logit_hessian_matrix.pickle b/tests/inference/fixtures/logit_hessian_matrix.pickle
similarity index 100%
rename from estimagic/tests/inference/fixtures/logit_hessian_matrix.pickle
rename to tests/inference/fixtures/logit_hessian_matrix.pickle
diff --git a/estimagic/tests/inference/fixtures/logit_jacobian.pickle b/tests/inference/fixtures/logit_jacobian.pickle
similarity index 100%
rename from estimagic/tests/inference/fixtures/logit_jacobian.pickle
rename to tests/inference/fixtures/logit_jacobian.pickle
diff --git a/estimagic/tests/inference/fixtures/logit_jacobian_matrix.pickle b/tests/inference/fixtures/logit_jacobian_matrix.pickle
similarity index 100%
rename from estimagic/tests/inference/fixtures/logit_jacobian_matrix.pickle
rename to tests/inference/fixtures/logit_jacobian_matrix.pickle
diff --git a/estimagic/tests/inference/fixtures/logit_sandwich.pickle b/tests/inference/fixtures/logit_sandwich.pickle
similarity index 100%
rename from estimagic/tests/inference/fixtures/logit_sandwich.pickle
rename to tests/inference/fixtures/logit_sandwich.pickle
diff --git a/estimagic/tests/inference/fixtures/probit_hessian.pickle b/tests/inference/fixtures/probit_hessian.pickle
similarity index 100%
rename from estimagic/tests/inference/fixtures/probit_hessian.pickle
rename to tests/inference/fixtures/probit_hessian.pickle
diff --git a/estimagic/tests/inference/fixtures/probit_hessian_matrix.pickle b/tests/inference/fixtures/probit_hessian_matrix.pickle
similarity index 100%
rename from estimagic/tests/inference/fixtures/probit_hessian_matrix.pickle
rename to tests/inference/fixtures/probit_hessian_matrix.pickle
diff --git a/estimagic/tests/inference/fixtures/probit_jacobian.pickle b/tests/inference/fixtures/probit_jacobian.pickle
similarity index 100%
rename from estimagic/tests/inference/fixtures/probit_jacobian.pickle
rename to tests/inference/fixtures/probit_jacobian.pickle
diff --git a/estimagic/tests/inference/fixtures/probit_jacobian_matrix.pickle b/tests/inference/fixtures/probit_jacobian_matrix.pickle
similarity index 100%
rename from estimagic/tests/inference/fixtures/probit_jacobian_matrix.pickle
rename to tests/inference/fixtures/probit_jacobian_matrix.pickle
diff --git a/estimagic/tests/inference/fixtures/probit_sandwich.pickle b/tests/inference/fixtures/probit_sandwich.pickle
similarity index 100%
rename from estimagic/tests/inference/fixtures/probit_sandwich.pickle
rename to tests/inference/fixtures/probit_sandwich.pickle
diff --git a/estimagic/tests/inference/test_bootstrap.py b/tests/inference/test_bootstrap.py
similarity index 99%
rename from estimagic/tests/inference/test_bootstrap.py
rename to tests/inference/test_bootstrap.py
index efe47bb66..ddc0cd532 100644
--- a/estimagic/tests/inference/test_bootstrap.py
+++ b/tests/inference/test_bootstrap.py
@@ -1,9 +1,8 @@
 import numpy as np
 import pandas as pd
 import pytest
-from pandas.testing import assert_frame_equal as afe
-
 from estimagic.inference.bootstrap import bootstrap_from_outcomes
+from pandas.testing import assert_frame_equal as afe
 
 
 @pytest.fixture
diff --git a/estimagic/tests/inference/test_bootstrap_ci.py b/tests/inference/test_bootstrap_ci.py
similarity index 99%
rename from estimagic/tests/inference/test_bootstrap_ci.py
rename to tests/inference/test_bootstrap_ci.py
index 9db3abb09..6f57362a6 100644
--- a/estimagic/tests/inference/test_bootstrap_ci.py
+++ b/tests/inference/test_bootstrap_ci.py
@@ -1,11 +1,10 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.inference.bootstrap_ci import _jackknife
 from estimagic.inference.bootstrap_ci import compute_ci
 from estimagic.inference.bootstrap_helpers import check_inputs
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 @pytest.fixture
diff --git a/estimagic/tests/inference/test_bootstrap_outcomes.py b/tests/inference/test_bootstrap_outcomes.py
similarity index 99%
rename from estimagic/tests/inference/test_bootstrap_outcomes.py
rename to tests/inference/test_bootstrap_outcomes.py
index b02bb747c..f802c1e87 100644
--- a/estimagic/tests/inference/test_bootstrap_outcomes.py
+++ b/tests/inference/test_bootstrap_outcomes.py
@@ -3,13 +3,12 @@
 import numpy as np
 import pandas as pd
 import pytest
-from pandas.testing import assert_frame_equal as afe
-
 from estimagic.batch_evaluators import joblib_batch_evaluator
 from estimagic.inference.bootstrap_outcomes import (
     _get_bootstrap_outcomes_from_indices,
 )
 from estimagic.inference.bootstrap_outcomes import get_bootstrap_outcomes
+from pandas.testing import assert_frame_equal as afe
 
 
 @pytest.fixture
diff --git a/estimagic/tests/inference/test_bootstrap_samples.py b/tests/inference/test_bootstrap_samples.py
similarity index 99%
rename from estimagic/tests/inference/test_bootstrap_samples.py
rename to tests/inference/test_bootstrap_samples.py
index 375a8014b..45ef7ddd6 100644
--- a/estimagic/tests/inference/test_bootstrap_samples.py
+++ b/tests/inference/test_bootstrap_samples.py
@@ -1,13 +1,12 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_equal as aae
-from pandas.testing import assert_frame_equal as afe
-
 from estimagic.inference.bootstrap_samples import _convert_cluster_ids_to_indices
 from estimagic.inference.bootstrap_samples import _get_bootstrap_samples_from_indices
 from estimagic.inference.bootstrap_samples import get_bootstrap_indices
 from estimagic.inference.bootstrap_samples import get_bootstrap_samples
+from numpy.testing import assert_array_equal as aae
+from pandas.testing import assert_frame_equal as afe
 
 
 @pytest.fixture
diff --git a/estimagic/tests/inference/test_ml_covs.py b/tests/inference/test_ml_covs.py
similarity index 99%
rename from estimagic/tests/inference/test_ml_covs.py
rename to tests/inference/test_ml_covs.py
index e9cca8b03..e06feb9eb 100644
--- a/estimagic/tests/inference/test_ml_covs.py
+++ b/tests/inference/test_ml_covs.py
@@ -4,8 +4,6 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.inference import ml_covs
 from estimagic.inference.ml_covs import _clustering
 from estimagic.inference.ml_covs import _sandwich_step
@@ -15,6 +13,7 @@
 from estimagic.inference.ml_covs import cov_jacobian
 from estimagic.inference.ml_covs import cov_robust
 from estimagic.inference.ml_covs import cov_strata_robust
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 @pytest.fixture
diff --git a/estimagic/tests/inference/test_msm_covs.py b/tests/inference/test_msm_covs.py
similarity index 99%
rename from estimagic/tests/inference/test_msm_covs.py
rename to tests/inference/test_msm_covs.py
index e4c12042b..ec45a823e 100644
--- a/estimagic/tests/inference/test_msm_covs.py
+++ b/tests/inference/test_msm_covs.py
@@ -3,11 +3,10 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-from pandas.testing import assert_frame_equal
-
 from estimagic.inference.msm_covs import cov_optimal
 from estimagic.inference.msm_covs import cov_robust
+from numpy.testing import assert_array_almost_equal as aaae
+from pandas.testing import assert_frame_equal
 
 
 np.random.seed(1234)
diff --git a/estimagic/tests/inference/test_shared.py b/tests/inference/test_shared.py
similarity index 99%
rename from estimagic/tests/inference/test_shared.py
rename to tests/inference/test_shared.py
index be76a8d4b..adf2e263a 100644
--- a/estimagic/tests/inference/test_shared.py
+++ b/tests/inference/test_shared.py
@@ -1,7 +1,6 @@
 import numpy as np
 import pandas as pd
 import pytest
-
 from estimagic.inference.shared import process_pandas_arguments
 
 
diff --git a/estimagic/tests/logging/test_database_utilities.py b/tests/logging/test_database_utilities.py
similarity index 99%
rename from estimagic/tests/logging/test_database_utilities.py
rename to tests/logging/test_database_utilities.py
index 86dd1628a..eacd2cb69 100644
--- a/estimagic/tests/logging/test_database_utilities.py
+++ b/tests/logging/test_database_utilities.py
@@ -5,10 +5,6 @@
 import pandas as pd
 import pytest
 import sqlalchemy
-from numpy.testing import assert_array_equal
-from sqlalchemy import Float
-from sqlalchemy import PickleType
-
 from estimagic.logging.database_utilities import append_row
 from estimagic.logging.database_utilities import load_database
 from estimagic.logging.database_utilities import make_optimization_iteration_table
@@ -16,6 +12,9 @@
 from estimagic.logging.database_utilities import make_optimization_status_table
 from estimagic.logging.database_utilities import read_last_rows
 from estimagic.logging.database_utilities import read_new_rows
+from numpy.testing import assert_array_equal
+from sqlalchemy import Float
+from sqlalchemy import PickleType
 
 
 @pytest.fixture
diff --git a/estimagic/tests/logging/test_read_log.py b/tests/logging/test_read_log.py
similarity index 94%
rename from estimagic/tests/logging/test_read_log.py
rename to tests/logging/test_read_log.py
index cb168f940..318b903fa 100644
--- a/estimagic/tests/logging/test_read_log.py
+++ b/tests/logging/test_read_log.py
@@ -1,21 +1,18 @@
-from pathlib import Path
-
 import numpy as np
 import pandas as pd
 import pytest
-from pandas.testing import assert_frame_equal
-
+from estimagic.config import EXAMPLE_DIR
 from estimagic.logging.database_utilities import append_row
 from estimagic.logging.database_utilities import load_database
 from estimagic.logging.database_utilities import make_optimization_iteration_table
 from estimagic.logging.database_utilities import make_optimization_problem_table
 from estimagic.logging.read_log import read_optimization_iteration
 from estimagic.logging.read_log import read_start_params
+from pandas.testing import assert_frame_equal
 
 
 def test_read_start_params():
-    this_folder = Path(__file__).resolve().parent
-    db_path = this_folder.parent / "dashboard" / "db1.db"
+    db_path = EXAMPLE_DIR / "db1.db"
     res = read_start_params(path_or_database=db_path)
     assert isinstance(res, pd.DataFrame)
     assert "value" in res.columns
diff --git a/estimagic/tests/optimization/fixtures/reparametrize_fixtures.csv b/tests/optimization/fixtures/reparametrize_fixtures.csv
similarity index 100%
rename from estimagic/tests/optimization/fixtures/reparametrize_fixtures.csv
rename to tests/optimization/fixtures/reparametrize_fixtures.csv
diff --git a/estimagic/tests/optimization/test_broadcast_arguments.py b/tests/optimization/test_broadcast_arguments.py
similarity index 99%
rename from estimagic/tests/optimization/test_broadcast_arguments.py
rename to tests/optimization/test_broadcast_arguments.py
index 758675d8c..388f9d302 100644
--- a/estimagic/tests/optimization/test_broadcast_arguments.py
+++ b/tests/optimization/test_broadcast_arguments.py
@@ -1,7 +1,6 @@
 import numpy as np
 import pandas as pd
 import pytest
-
 from estimagic.optimization.broadcast_arguments import broadcast_arguments
 
 
diff --git a/estimagic/tests/optimization/test_criterion_versions.py b/tests/optimization/test_criterion_versions.py
similarity index 99%
rename from estimagic/tests/optimization/test_criterion_versions.py
rename to tests/optimization/test_criterion_versions.py
index 72d51bc1a..d73c57588 100644
--- a/estimagic/tests/optimization/test_criterion_versions.py
+++ b/tests/optimization/test_criterion_versions.py
@@ -9,13 +9,12 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.config import IS_DFOLS_INSTALLED
 from estimagic.examples.criterion_functions import sos_dict_criterion
 from estimagic.examples.criterion_functions import sos_dict_criterion_with_pd_objects
 from estimagic.examples.criterion_functions import sos_scalar_criterion
 from estimagic.optimization.optimize import minimize
+from numpy.testing import assert_array_almost_equal as aaae
 
 algorithms = ["scipy_lbfgsb", "scipy_neldermead"]
 if IS_DFOLS_INSTALLED:
diff --git a/estimagic/tests/optimization/test_derivative_versions.py b/tests/optimization/test_derivative_versions.py
similarity index 99%
rename from estimagic/tests/optimization/test_derivative_versions.py
rename to tests/optimization/test_derivative_versions.py
index 770d5d48a..9ebe0814b 100644
--- a/estimagic/tests/optimization/test_derivative_versions.py
+++ b/tests/optimization/test_derivative_versions.py
@@ -10,8 +10,6 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.decorators import switch_sign
 from estimagic.examples.criterion_functions import sos_criterion_and_gradient
 from estimagic.examples.criterion_functions import sos_criterion_and_jacobian
@@ -27,6 +25,7 @@
 from estimagic.examples.criterion_functions import sos_pandas_jacobian
 from estimagic.optimization.optimize import maximize
 from estimagic.optimization.optimize import minimize
+from numpy.testing import assert_array_almost_equal as aaae
 
 algorithms = ["scipy_lbfgsb", "scipy_ls_dogbox", "scipy_neldermead"]
 
diff --git a/estimagic/tests/optimization/test_internal_criterion_and_derivative_template.py b/tests/optimization/test_internal_criterion_and_derivative_template.py
similarity index 99%
rename from estimagic/tests/optimization/test_internal_criterion_and_derivative_template.py
rename to tests/optimization/test_internal_criterion_and_derivative_template.py
index edcd46df9..09bb39109 100644
--- a/estimagic/tests/optimization/test_internal_criterion_and_derivative_template.py
+++ b/tests/optimization/test_internal_criterion_and_derivative_template.py
@@ -4,8 +4,6 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.differentiation.derivatives import first_derivative
 from estimagic.examples.criterion_functions import sos_criterion_and_gradient
 from estimagic.examples.criterion_functions import sos_dict_criterion
@@ -29,6 +27,7 @@
     internal_criterion_and_derivative_template,
 )
 from estimagic.optimization.optimize import _fill_error_penalty_with_defaults
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 def no_second_call(func):
diff --git a/estimagic/tests/optimization/test_ipopt_options.py b/tests/optimization/test_ipopt_options.py
similarity index 99%
rename from estimagic/tests/optimization/test_ipopt_options.py
rename to tests/optimization/test_ipopt_options.py
index 533a391ab..7c573cc57 100644
--- a/estimagic/tests/optimization/test_ipopt_options.py
+++ b/tests/optimization/test_ipopt_options.py
@@ -1,10 +1,9 @@
 """Test the different options of ipopt."""
 import numpy as np
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.config import IS_CYIPOPT_INSTALLED
 from estimagic.optimization.cyipopt_optimizers import ipopt
+from numpy.testing import assert_array_almost_equal as aaae
 
 test_cases = [
     {},
diff --git a/estimagic/tests/optimization/test_many_algorithms.py b/tests/optimization/test_many_algorithms.py
similarity index 99%
rename from estimagic/tests/optimization/test_many_algorithms.py
rename to tests/optimization/test_many_algorithms.py
index ad03d7b2b..c192dc437 100644
--- a/estimagic/tests/optimization/test_many_algorithms.py
+++ b/tests/optimization/test_many_algorithms.py
@@ -10,12 +10,11 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.examples.criterion_functions import sos_dict_criterion
 from estimagic.optimization import AVAILABLE_ALGORITHMS
 from estimagic.optimization import GLOBAL_ALGORITHMS
 from estimagic.optimization.optimize import minimize
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 LOCAL_ALGORITHMS = {
diff --git a/estimagic/tests/optimization/test_nag_optimizers.py b/tests/optimization/test_nag_optimizers.py
similarity index 99%
rename from estimagic/tests/optimization/test_nag_optimizers.py
rename to tests/optimization/test_nag_optimizers.py
index d9d99bc33..5f9de0c6d 100644
--- a/estimagic/tests/optimization/test_nag_optimizers.py
+++ b/tests/optimization/test_nag_optimizers.py
@@ -1,5 +1,4 @@
 import pytest
-
 from estimagic.optimization.nag_optimizers import _build_options_dict
 from estimagic.optimization.nag_optimizers import _change_evals_per_point_interface
 from estimagic.optimization.nag_optimizers import _get_fast_start_method
diff --git a/estimagic/tests/optimization/test_optimization_helpers.py b/tests/optimization/test_optimization_helpers.py
similarity index 99%
rename from estimagic/tests/optimization/test_optimization_helpers.py
rename to tests/optimization/test_optimization_helpers.py
index 4509e6d30..0b58a2acb 100644
--- a/estimagic/tests/optimization/test_optimization_helpers.py
+++ b/tests/optimization/test_optimization_helpers.py
@@ -1,7 +1,6 @@
 """Test optimization helper functions."""
 import numpy as np
 import pytest
-
 from estimagic.optimization.pygmo_optimizers import _check_that_every_param_is_bounded
 from estimagic.optimization.pygmo_optimizers import _convert_str_to_int
 from estimagic.optimization.pygmo_optimizers import _determine_population_size
diff --git a/estimagic/tests/optimization/test_optimizations_with_scaling.py b/tests/optimization/test_optimizations_with_scaling.py
similarity index 99%
rename from estimagic/tests/optimization/test_optimizations_with_scaling.py
rename to tests/optimization/test_optimizations_with_scaling.py
index 5795dbf65..ceb367e63 100644
--- a/estimagic/tests/optimization/test_optimizations_with_scaling.py
+++ b/tests/optimization/test_optimizations_with_scaling.py
@@ -4,10 +4,9 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.config import IS_PYBOBYQA_INSTALLED
 from estimagic.optimization.optimize import minimize
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 ALGORITHMS = ["scipy_lbfgsb"]
diff --git a/estimagic/tests/optimization/test_optimize.py b/tests/optimization/test_optimize.py
similarity index 99%
rename from estimagic/tests/optimization/test_optimize.py
rename to tests/optimization/test_optimize.py
index 813ab0c42..ef2467879 100644
--- a/estimagic/tests/optimization/test_optimize.py
+++ b/tests/optimization/test_optimize.py
@@ -2,7 +2,6 @@
 import numpy as np
 import pandas as pd
 import pytest
-
 from estimagic.examples.criterion_functions import sos_scalar_criterion
 from estimagic.optimization.optimize import maximize
 from estimagic.optimization.optimize import minimize
diff --git a/estimagic/tests/optimization/test_parallel_optimizations.py b/tests/optimization/test_parallel_optimizations.py
similarity index 99%
rename from estimagic/tests/optimization/test_parallel_optimizations.py
rename to tests/optimization/test_parallel_optimizations.py
index f82a2ffa8..b1f30995e 100644
--- a/estimagic/tests/optimization/test_parallel_optimizations.py
+++ b/tests/optimization/test_parallel_optimizations.py
@@ -2,9 +2,8 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal
-
 from estimagic.optimization.optimize import minimize
+from numpy.testing import assert_array_almost_equal
 
 
 def rosen(x):
diff --git a/estimagic/tests/optimization/test_scaling.py b/tests/optimization/test_scaling.py
similarity index 99%
rename from estimagic/tests/optimization/test_scaling.py
rename to tests/optimization/test_scaling.py
index 31b87a3c9..55f01f109 100644
--- a/estimagic/tests/optimization/test_scaling.py
+++ b/tests/optimization/test_scaling.py
@@ -1,9 +1,8 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.optimization.scaling import calculate_scaling_factor_and_offset
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 @pytest.fixture
diff --git a/estimagic/tests/optimization/test_tao_optimizers.py b/tests/optimization/test_tao_optimizers.py
similarity index 99%
rename from estimagic/tests/optimization/test_tao_optimizers.py
rename to tests/optimization/test_tao_optimizers.py
index 3dc6a227e..50cd0f741 100644
--- a/estimagic/tests/optimization/test_tao_optimizers.py
+++ b/tests/optimization/test_tao_optimizers.py
@@ -4,7 +4,6 @@
 import numpy as np
 import pandas as pd
 import pytest
-
 from estimagic.config import IS_PETSC4PY_INSTALLED
 from estimagic.optimization.optimize import minimize
 
diff --git a/estimagic/tests/optimization/test_with_advanced_constraints.py b/tests/optimization/test_with_advanced_constraints.py
similarity index 99%
rename from estimagic/tests/optimization/test_with_advanced_constraints.py
rename to tests/optimization/test_with_advanced_constraints.py
index 0dbb6d8b3..28c8b8bf2 100644
--- a/estimagic/tests/optimization/test_with_advanced_constraints.py
+++ b/tests/optimization/test_with_advanced_constraints.py
@@ -10,11 +10,10 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.examples.criterion_functions import sos_gradient
 from estimagic.examples.criterion_functions import sos_scalar_criterion
 from estimagic.optimization.optimize import minimize
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 CONSTR_INFO = {
diff --git a/estimagic/tests/optimization/test_with_constraints.py b/tests/optimization/test_with_constraints.py
similarity index 99%
rename from estimagic/tests/optimization/test_with_constraints.py
rename to tests/optimization/test_with_constraints.py
index 1d5a935b8..10e4289f8 100644
--- a/estimagic/tests/optimization/test_with_constraints.py
+++ b/tests/optimization/test_with_constraints.py
@@ -9,8 +9,6 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.examples.criterion_functions import rosenbrock_dict_criterion
 from estimagic.examples.criterion_functions import rosenbrock_gradient
 from estimagic.examples.criterion_functions import (
@@ -24,6 +22,7 @@
 from estimagic.examples.criterion_functions import trid_gradient
 from estimagic.examples.criterion_functions import trid_scalar_criterion
 from estimagic.optimization.optimize import minimize
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 FUNC_INFO = {
diff --git a/estimagic/tests/optimization/test_with_logging.py b/tests/optimization/test_with_logging.py
similarity index 99%
rename from estimagic/tests/optimization/test_with_logging.py
rename to tests/optimization/test_with_logging.py
index 3a23a9b2c..d30d5550a 100644
--- a/estimagic/tests/optimization/test_with_logging.py
+++ b/tests/optimization/test_with_logging.py
@@ -11,12 +11,11 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.examples.criterion_functions import sos_dict_criterion
 from estimagic.examples.criterion_functions import sos_dict_derivative
 from estimagic.exceptions import TableExistsError
 from estimagic.optimization.optimize import minimize
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 algorithms = ["scipy_lbfgsb", "scipy_ls_dogbox"]
diff --git a/estimagic/tests/parameters/test_kernel_transformations.py b/tests/parameters/test_kernel_transformations.py
similarity index 99%
rename from estimagic/tests/parameters/test_kernel_transformations.py
rename to tests/parameters/test_kernel_transformations.py
index 6eec28536..668921601 100644
--- a/estimagic/tests/parameters/test_kernel_transformations.py
+++ b/tests/parameters/test_kernel_transformations.py
@@ -1,13 +1,12 @@
 from functools import partial
 from itertools import product
 
+import estimagic.parameters.kernel_transformations as kt
 import numpy as np
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
-import estimagic.parameters.kernel_transformations as kt
 from estimagic.differentiation.derivatives import first_derivative
 from estimagic.parameters.kernel_transformations import cov_matrix_to_sdcorr_params
+from numpy.testing import assert_array_almost_equal as aaae
 
 to_test = list(product(range(10, 30, 5), [1234, 5471]))
 
diff --git a/estimagic/tests/parameters/test_parameter_conversion.py b/tests/parameters/test_parameter_conversion.py
similarity index 99%
rename from estimagic/tests/parameters/test_parameter_conversion.py
rename to tests/parameters/test_parameter_conversion.py
index 8e3762498..556bd6e59 100644
--- a/estimagic/tests/parameters/test_parameter_conversion.py
+++ b/tests/parameters/test_parameter_conversion.py
@@ -1,9 +1,8 @@
 import numpy as np
 import pandas as pd
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.parameters.parameter_conversion import get_derivative_conversion_function
 from estimagic.parameters.parameter_conversion import get_reparametrize_functions
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 def test_get_parametrize_functions_with_back_and_forth_conversion():
diff --git a/estimagic/tests/parameters/test_process_constraints.py b/tests/parameters/test_process_constraints.py
similarity index 89%
rename from estimagic/tests/parameters/test_process_constraints.py
rename to tests/parameters/test_process_constraints.py
index 5c946b507..c03aef3bd 100644
--- a/estimagic/tests/parameters/test_process_constraints.py
+++ b/tests/parameters/test_process_constraints.py
@@ -2,14 +2,28 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.parameters.process_constraints import _process_selectors
 from estimagic.parameters.process_constraints import (
     _replace_pairwise_equality_by_equality,
 )
 from estimagic.parameters.process_constraints import process_constraints
-from estimagic.tests.parameters.test_reparametrize import reduce_params
+from numpy.testing import assert_array_almost_equal as aaae
+
+
+def reduce_params(params, constraints):
+    all_locs = []
+    for constr in constraints:
+        if "query" in constr:
+            all_locs = ["i", "j1", "j2"]
+        elif isinstance(constr["loc"], tuple):
+            all_locs.append(constr["loc"][0])
+        elif isinstance(constr["loc"], list):
+            all_locs.append(constr["loc"][0][0])
+        else:
+            all_locs.append(constr["loc"])
+    all_locs = sorted(set(all_locs))
+    return params.loc[all_locs].copy()
+
 
 constr1 = {"loc": 0, "type": "equality"}
 expected1 = {"index": [0, 1, 2]}
diff --git a/estimagic/tests/parameters/test_reparametrize.py b/tests/parameters/test_reparametrize.py
similarity index 99%
rename from estimagic/tests/parameters/test_reparametrize.py
rename to tests/parameters/test_reparametrize.py
index 2adc7d2b7..ef6ab9788 100644
--- a/estimagic/tests/parameters/test_reparametrize.py
+++ b/tests/parameters/test_reparametrize.py
@@ -4,8 +4,6 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.differentiation.derivatives import first_derivative
 from estimagic.parameters.parameter_conversion import get_derivative_conversion_function
 from estimagic.parameters.parameter_conversion import get_reparametrize_functions
@@ -18,6 +16,7 @@
 from estimagic.parameters.reparametrize import pre_replace_jacobian
 from estimagic.parameters.reparametrize import reparametrize_from_internal
 from estimagic.parameters.reparametrize import reparametrize_to_internal
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 to_test = list(
diff --git a/estimagic/tests/sensitivity/test_msm_sensitivity.py b/tests/sensitivity/test_msm_sensitivity.py
similarity index 97%
rename from estimagic/tests/sensitivity/test_msm_sensitivity.py
rename to tests/sensitivity/test_msm_sensitivity.py
index b07c12d0c..f1e9c656a 100644
--- a/estimagic/tests/sensitivity/test_msm_sensitivity.py
+++ b/tests/sensitivity/test_msm_sensitivity.py
@@ -1,10 +1,7 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-from scipy import stats
-
-from estimagic.config import TEST_DIR
+from estimagic.config import EXAMPLE_DIR
 from estimagic.differentiation.derivatives import first_derivative
 from estimagic.inference.msm_covs import cov_optimal
 from estimagic.sensitivity.msm_sensitivity import calculate_actual_sensitivity_to_noise
@@ -19,6 +16,8 @@
 )
 from estimagic.sensitivity.msm_sensitivity import calculate_sensitivity_to_bias
 from estimagic.sensitivity.msm_sensitivity import calculate_sensitivity_to_weighting
+from numpy.testing import assert_array_almost_equal as aaae
+from scipy import stats
 
 
 def simulate_aggregated_moments(params, x, y):
@@ -74,7 +73,7 @@ def params():
 
 @pytest.fixture
 def func_kwargs():
-    data = pd.read_csv(TEST_DIR / "sensitivity" / "sensitivity_probit_example_data.csv")
+    data = pd.read_csv(EXAMPLE_DIR / "sensitivity_probit_example_data.csv")
     y_data = data[["y"]]
     x_data = data[["intercept", "x1", "x2"]]
     func_kwargs = {"x": x_data, "y": y_data}
diff --git a/estimagic/tests/test_batch_evaluators.py b/tests/test_batch_evaluators.py
similarity index 99%
rename from estimagic/tests/test_batch_evaluators.py
rename to tests/test_batch_evaluators.py
index 1f3c7d8fa..ee69ea931 100644
--- a/estimagic/tests/test_batch_evaluators.py
+++ b/tests/test_batch_evaluators.py
@@ -2,7 +2,6 @@
 import warnings
 
 import pytest
-
 from estimagic.batch_evaluators import joblib_batch_evaluator
 
 
diff --git a/estimagic/tests/test_decorators.py b/tests/test_decorators.py
similarity index 99%
rename from estimagic/tests/test_decorators.py
rename to tests/test_decorators.py
index 262f1da7c..b5fadeb90 100644
--- a/estimagic/tests/test_decorators.py
+++ b/tests/test_decorators.py
@@ -1,12 +1,11 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-from pandas.testing import assert_frame_equal
-
 from estimagic.decorators import catch
 from estimagic.decorators import numpy_interface
 from estimagic.decorators import unpack
+from numpy.testing import assert_array_almost_equal as aaae
+from pandas.testing import assert_frame_equal
 
 
 def test_numpy_interface():
diff --git a/estimagic/tests/test_utilities.py b/tests/test_utilities.py
similarity index 99%
rename from estimagic/tests/test_utilities.py
rename to tests/test_utilities.py
index 0316ddbb8..31eef143d 100644
--- a/estimagic/tests/test_utilities.py
+++ b/tests/test_utilities.py
@@ -1,8 +1,6 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_almost_equal as aaae
-
 from estimagic.config import IS_CYIPOPT_INSTALLED
 from estimagic.config import IS_DFOLS_INSTALLED
 from estimagic.config import IS_PETSC4PY_INSTALLED
@@ -23,6 +21,7 @@
 from estimagic.utilities import sdcorr_params_to_matrix
 from estimagic.utilities import sdcorr_params_to_sds_and_corr
 from estimagic.utilities import sds_and_corr_to_cov
+from numpy.testing import assert_array_almost_equal as aaae
 
 
 def test_chol_params_to_lower_triangular_matrix():
diff --git a/estimagic/tests/visualization/combined_params_dataframe.csv b/tests/visualization/combined_params_dataframe.csv
similarity index 100%
rename from estimagic/tests/visualization/combined_params_dataframe.csv
rename to tests/visualization/combined_params_dataframe.csv
diff --git a/estimagic/tests/visualization/test_colors.py b/tests/visualization/test_colors.py
similarity index 99%
rename from estimagic/tests/visualization/test_colors.py
rename to tests/visualization/test_colors.py
index 02a03ce1e..206bc0cd6 100644
--- a/estimagic/tests/visualization/test_colors.py
+++ b/tests/visualization/test_colors.py
@@ -1,6 +1,5 @@
 """This only tests that we get the right number of colors, not the exact colors."""
 import pytest
-
 from estimagic.visualization.colors import get_colors
 
 
diff --git a/estimagic/tests/visualization/test_derivative_plot.py b/tests/visualization/test_derivative_plot.py
similarity index 99%
rename from estimagic/tests/visualization/test_derivative_plot.py
rename to tests/visualization/test_derivative_plot.py
index 2102fceda..3af7da050 100644
--- a/estimagic/tests/visualization/test_derivative_plot.py
+++ b/tests/visualization/test_derivative_plot.py
@@ -3,9 +3,6 @@
 import numpy as np
 import pandas as pd
 import pytest
-from numpy.testing import assert_array_equal
-from pandas.testing import assert_series_equal
-
 from estimagic.differentiation.derivatives import first_derivative
 from estimagic.visualization.derivative_plot import (
     _select_derivative_with_minimal_error,
@@ -14,6 +11,8 @@
     _select_eval_with_lowest_and_highest_step,
 )
 from estimagic.visualization.derivative_plot import derivative_plot
+from numpy.testing import assert_array_equal
+from pandas.testing import assert_series_equal
 
 
 def test__select_derivative_with_minimal_error():
diff --git a/estimagic/tests/visualization/test_estimation_table.py b/tests/visualization/test_estimation_table.py
similarity index 98%
rename from estimagic/tests/visualization/test_estimation_table.py
rename to tests/visualization/test_estimation_table.py
index b588b820b..4673b9cb1 100644
--- a/estimagic/tests/visualization/test_estimation_table.py
+++ b/tests/visualization/test_estimation_table.py
@@ -5,20 +5,19 @@
 import numpy as np
 import pandas as pd
 import statsmodels.api as sm
-from pandas.testing import assert_frame_equal as afe
-from pandas.testing import assert_series_equal as ase
-
-from estimagic.config import TEST_DIR
+from estimagic.config import EXAMPLE_DIR
 from estimagic.visualization.estimation_table import _convert_model_to_series
 from estimagic.visualization.estimation_table import _create_statistics_sr
 from estimagic.visualization.estimation_table import _process_body_df
 from estimagic.visualization.estimation_table import _process_model
 from estimagic.visualization.estimation_table import estimation_table
+from pandas.testing import assert_frame_equal as afe
+from pandas.testing import assert_series_equal as ase
 
 # test process_model for different model types
 NamedTup = namedtuple("NamedTup", "params info")
 
-fix_path = TEST_DIR / "visualization" / "diabetes.csv"
+fix_path = EXAMPLE_DIR / "diabetes.csv"
 
 df_ = pd.read_csv(fix_path, index_col=0)
 est = sm.OLS(endog=df_["target"], exog=sm.add_constant(df_[df_.columns[0:4]])).fit()
diff --git a/estimagic/tests/visualization/test_lollipop_plot.py b/tests/visualization/test_lollipop_plot.py
similarity index 99%
rename from estimagic/tests/visualization/test_lollipop_plot.py
rename to tests/visualization/test_lollipop_plot.py
index 295f6cb20..c6ec6a626 100644
--- a/estimagic/tests/visualization/test_lollipop_plot.py
+++ b/tests/visualization/test_lollipop_plot.py
@@ -1,6 +1,5 @@
 import numpy as np
 import pandas as pd
-
 from estimagic.visualization.lollipop_plot import lollipop_plot