Repository: zincware/MDSuite (language: python)

Issue:
metadata for experiments
**What feature would you like to see added?**
store metadata of any kind on experiments.
In the project, the values of the experiments should be accessible through the parameters of the experiments 

**Describe how this feature would improve the code**
Then I don't need to do that manually

**Describe how this feature would work/possible implementations**
no idea

**User story**
I run 100 simulations, varying 2 obscure parameters like packing fraction and flagellar unbundling rate.
I the want a plot of the Diffusion coefficient vs unbundling rate, with a different line color for each packing fraction.
To do that I would like tabulated data like

exp_id | pack_f | unbundle_rate | ... [all other metadata like time step, Temperature, vox volume etc] ... | msd
0        | 0.2    |   16.4  | [...] | 2e-8
1        | 0.2    |   16.8  | [...]  | 2.5e-8
2        | 0.1    |   16.4  | [...]  | 7e6
.
.
.



Discussion / hints:

Fix patch:
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 00000000..c55835a3
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,12 @@
+<!-- The issue that is fixed by this PR, if applicable: -->
+Fix #
+
+#### Summary of additions and changes
+
+* 
+
+#### How to test this pull request
+
+```
+
+```
diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml
new file mode 100644
index 00000000..e2421076
--- /dev/null
+++ b/.github/workflows/flake8.yml
@@ -0,0 +1,32 @@
+name: flake8 Test
+
+on:
+  push:
+  pull_request:
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        python-version: [ 3.9 ]
+
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up Python ${{ matrix.python-version }}
+        uses: actions/setup-python@v2
+        with:
+          python-version: ${{ matrix.python-version }}
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          python -m pip install flake8
+      - name: Lint with flake8
+        run: |
+          # stop the build if there are Python syntax errors or undefined names
+          flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
+      - name: Lint with flake8 (Full Output)
+        run: |
+          # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
+          flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml
new file mode 100644
index 00000000..6c1c82e9
--- /dev/null
+++ b/.github/workflows/python-package.yml
@@ -0,0 +1,40 @@
+# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
+
+name: pytest
+
+on:
+  push:
+    branches: [ main ]
+  pull_request:
+    branches: [ main ]
+
+jobs:
+  build:
+
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        python-version: [3.7, 3.8, 3.9]
+
+    steps:
+    - uses: actions/checkout@v2
+    - name: Set up Python ${{ matrix.python-version }}
+      uses: actions/setup-python@v2
+      with:
+        python-version: ${{ matrix.python-version }}
+    - name: Install dependencies
+      run: |
+        python -m pip install --upgrade pip
+        python -m pip install pytest
+        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+    - name: Install package
+      run: |
+        pip install .
+    - name: Pytest
+      run: |
+        pytest
+      env:
+        CUDA_VISIBLE_DEVICES: -1
+        TF_CPP_MIN_LOG_LEVEL: 3  # this might be really dumb, but we have to suppress libcudart error
\ No newline at end of file
diff --git a/README.md b/README.md
deleted file mode 100644
index 73954658..00000000
--- a/README.md
+++ /dev/null
@@ -1,51 +0,0 @@
-# Introduction
-MDSuite is a software designed specifically for the molecular dynamics community to enable fast, reliable, and simple 
-calculations from simulation data. 
-
-If you want to start learning about the code, you can check out the docs [here](https://mdsuite.readthedocs.io/en/latest/).
-
-**NOTE:** This README is designed for the release. Anything PyPi related is not yet functioning as the code is in
-development.
-
-## Installation
-There are several way to install MDSuite depending on what you would like from it. One can simply installing using 
-PyPi as **Not Currently available**
-```bash
-$ pip install mdsuite
-```
-If you would like to install it from source then you can clone the repository by running
-```bash
-$ git clone https://github.com/SamTov/MDSuite.git
-```
-Once you have cloned the repository, depending on whether you prefer conda or straight pip, you should follow the 
-instructions below.
-
-### Installation with pip
-```bash
-$ cd MDSuite
-$ pip install .
-``` 
-### Installation with conda
-```bash
-$ cd MDSuite
-$ conda create -n MDSuite python=3.8
-$ conda activate MDSuite
-$ pip install . 
-```
-
-## Documentation
-There is a live version of the documentation hosted [here](https://mdsuite.readthedocs.io/en/latest/).
-If you would prefer to have a local copy, it can be built using sphinx by following the instructions below.
-```bash
-$ cd MDSuite/docs
-$ make html
-$ cd build/html
-$ firefox index.html
-```
-
-## HINT
-
-Check out the mdsuite code through a jupyter notebook for a more user friendly experience. You can take full advantage 
-of the autocomplete features that are available for the calculators.
-
-![Alt Text](docs/source/images/test_einstein_record_3.gif)
diff --git a/README.rst b/README.rst
new file mode 100644
index 00000000..748fc58c
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,89 @@
+|madewithpython| |build| |docs| |license|
+
+Introduction
+------------
+
+MDSuite is a software designed specifically for the molecular dynamics community to enable fast, reliable, and simple 
+calculations from simulation data. 
+
+If you want to start learning about the code, you can check out the docs `here <https://mdsuite.readthedocs.io/en/latest/>`_.
+
+**NOTE:** This README is designed for the release. Anything PyPi related is not yet functioning as the code is in
+development.
+
+Installation
+============
+
+There are several way to install MDSuite depending on what you would like from it. One can simply installing using 
+PyPi as **Not Currently available**
+
+.. code-block:: bash
+
+   pip install mdsuite
+
+If you would like to install it from source then you can clone the repository by running
+
+.. code-block:: bash
+
+   git clone https://github.com/SamTov/MDSuite.git
+
+Once you have cloned the repository, depending on whether you prefer conda or straight pip, you should follow the 
+instructions below.
+
+Installation with pip
+*********************
+
+.. code-block:: bash
+
+   cd MDSuite
+   pip install .
+
+
+Installation with conda
+***********************
+
+.. code-block:: bash
+
+   cd MDSuite
+   conda create -n MDSuite python=3.8
+   conda activate MDSuite
+   pip install .
+
+Documentation
+=============
+
+There is a live version of the documentation hosted `here <https://mdsuite.readthedocs.io/en/latest/>`_.
+If you would prefer to have a local copy, it can be built using sphinx by following the instructions below.
+
+.. code-block:: bash
+
+   cd MDSuite/docs
+   make html
+   cd build/html
+   firefox index.html
+
+HINT
+====
+
+Check out the MDSuite code through a jupyter notebook for a more user friendly experience. You can take full advantage
+of the autocomplete features that are available for the calculators.
+
+.. image:: docs/source/images/test_einstein_record_3.gif
+    :width: 600
+
+.. badges
+
+.. |madewithpython| image:: https://img.shields.io/badge/Made%20With-Python-blue.svg?style=flat
+    :alt: Made with Python
+
+.. |build| image:: https://github.com/zincware/MDSuite/actions/workflows/python-package.yml/badge.svg
+    :alt: Build tests passing
+    :target: https://github.com/zincware/MDSuite/blob/readme_badges/
+
+.. |docs| image:: https://readthedocs.org/projects/mdsuite/badge/?version=latest&style=flat
+    :alt: Build tests passing
+    :target: https://mdsuite.readthedocs.io/en/latest/
+
+.. |license| image:: https://img.shields.io/badge/License-EPL-purple.svg?style=flat
+    :alt: Project license
+    :target: https://www.gnu.org/licenses/quick-guide-gplv3.en.html
\ No newline at end of file
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 7da06cdd..c0c7e6a9 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -1,13 +1,12 @@
-# If extensions (or modules to document with autodoc) are in another directory,
-# 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.
-#
+"""
+Conf file for the MDSuite docs.
+"""
 import os
 import sys
+import sphinx_rtd_theme
+
 sys.path.insert(0, os.path.abspath('.'))
 sys.path.insert(0, os.path.abspath('../../'))
-html_theme = 'sphinx_rtd_theme'
-import sphinx_rtd_theme
 html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
 
 # -- Experiment information -----------------------------------------------------
@@ -79,7 +78,7 @@
 html_theme = 'sphinx_rtd_theme'
 html_logo = 'images/MDSUITE.png'
 html_favicon = 'images/MDSUITE.png'
-html_theme_options={
+html_theme_options = {
         'logo_only': True,
         'display_version': False,
     }
@@ -149,9 +148,6 @@
      'Miscellaneous'),
 ]
 
-
-
-
 # Example configuration for intersphinx: refer to the Python standard library.
 intersphinx_mapping = {
     'python': ('https://docs.python.org/3/', None),
diff --git a/mdsuite/__init__.py b/mdsuite/__init__.py
index c42b110e..b70f45b1 100644
--- a/mdsuite/__init__.py
+++ b/mdsuite/__init__.py
@@ -6,22 +6,21 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python __init__ file
 """
 import logging
 import os
 import sys
-
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
-
-from .project import *  # Load the project class
+from .project import Project
 from .experiment.experiment import Experiment
 from .graph_modules import adjacency_matrix
 from .utils.report_computer_characteristics import Report
 
+__all__ = ['Project', 'Experiment', 'adjacency_matrix', 'Report']
+os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
+
+
 # there is a good chance, that the root logger is already defined so we have to make some changes to it!
 root = logging.getLogger()
 
diff --git a/mdsuite/calculators/__init__.py b/mdsuite/calculators/__init__.py
index 24a40366..0176d715 100644
--- a/mdsuite/calculators/__init__.py
+++ b/mdsuite/calculators/__init__.py
@@ -6,9 +6,6 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 __init__ module for the analysis directory
 """
-
diff --git a/mdsuite/calculators/angular_distribution_function.py b/mdsuite/calculators/angular_distribution_function.py
index 0796f9b1..9e96569a 100644
--- a/mdsuite/calculators/angular_distribution_function.py
+++ b/mdsuite/calculators/angular_distribution_function.py
@@ -7,23 +7,17 @@
 
 Copyright Contributors to the MDSuite Project.
 """
-
 from abc import ABC
-
 import logging
-
 import tensorflow as tf
 import itertools
 import numpy as np
 from tqdm import tqdm
-
 from mdsuite.calculators.calculator import Calculator
 from mdsuite.utils.neighbour_list import get_neighbour_list, get_triu_indicies, get_triplets
 from mdsuite.utils.linalg import get_angles
 import matplotlib.pyplot as plt
-
 from mdsuite.utils.meta_functions import join_path
-
 log = logging.getLogger(__name__)
 
 
diff --git a/mdsuite/calculators/calculator.py b/mdsuite/calculators/calculator.py
index cda5ac03..7ff7cc95 100644
--- a/mdsuite/calculators/calculator.py
+++ b/mdsuite/calculators/calculator.py
@@ -6,16 +6,15 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Parent class for different analysis
 
 Summary
 -------
 """
 import logging
-
+import numpy as np
+import os
 import abc
 import random
 import sys
@@ -25,16 +24,15 @@
 import tensorflow as tf
 import pandas as pd
 from scipy.optimize import curve_fit
-from mdsuite.utils.exceptions import *
-from mdsuite.utils.meta_functions import *
+from mdsuite.utils.exceptions import RangeExceeded
+from mdsuite.utils.meta_functions import join_path
 from mdsuite.memory_management.memory_manager import MemoryManager
 from mdsuite.database.data_manager import DataManager
 from mdsuite.database.simulation_database import Database
-from mdsuite.calculators.computations_dict import switcher_transformations
+from mdsuite.calculators.transformations_reference import switcher_transformations
 from mdsuite.database.properties_database import PropertiesDatabase
 from mdsuite.database.analysis_database import AnalysisDatabase
 from tqdm import tqdm
-
 from typing import Union
 
 log = logging.getLogger(__file__)
@@ -680,6 +678,9 @@ def perform_computation(self):
 
             self._apply_averaging_factor()
             self._post_operation_processes()
+            if self.plot:
+                plt.legend()
+                plt.show()
 
         elif self.experimental:
             data_path = [join_path(species, self.loaded_property) for species in self.experiment.species]
@@ -741,9 +742,10 @@ def run_analysis(self):
         self._run_dependency_check()
         if self.experimental:
             log.warning("\n ########## \n "
-                     "This is an experimental calculator. It is provided as it can still be used, however, it may not be"
-                     " memory safe or completely accurate. \n Please see the documentation for more information. \n "
-                     "#########")
+                        "This is an experimental calculator. It is provided as it can still be used, however, "
+                        "it may not be"
+                        " memory safe or completely accurate. \n Please see the documentation for more information. \n "
+                        "#########")
         if self.optimize:
             pass
         else:
diff --git a/mdsuite/calculators/computations_dict.py b/mdsuite/calculators/computations_dict.py
index 3d141d6d..4a6e55ae 100644
--- a/mdsuite/calculators/computations_dict.py
+++ b/mdsuite/calculators/computations_dict.py
@@ -6,41 +6,14 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Module to contain the structured dict for analysis.
 
 Summary
 -------
 """
-
-switcher_transformations = {
-    'Translational_Dipole_Moment': 'TranslationalDipoleMoment',
-    'Ionic_Current': 'IonicCurrent',
-    'Integrated_Heat_Current': 'IntegratedHeatCurrent',
-    'Thermal_Flux': 'ThermalFlux',
-    'Momentum_Flux': 'MomentumFlux',
-    'Kinaci_Heat_Current': 'KinaciIntegratedHeatCurrent'
-}
-
-dict_classes_db = {
-    'self_diffusion_coefficients': {'Einstein_Self_Diffusion_Coefficients': {},
-                               'Green_Kubo_Self_Diffusion': {}},
-    'distinct_diffusion_coefficients': {'Einstein_Distinct_Diffusion_Coefficients': {},
-                                        'Green_Kubo_Distinct_Diffusion_Coefficients': {}},
-    'ionic_conductivity': {},
-    'thermal_conductivity': {},
-    'coordination_numbers': {'Coordination_Numbers': {}},
-    'potential_of_mean_force_values': {'Potential_of_Mean_Force': {}},
-    'radial_distribution_function': {},
-    'kirkwood_buff_integral': {},
-    'structure_factor': {},
-    'viscosity': {}
-}
-
-from mdsuite.calculators.angular_distribution_function import AngularDistributionFunction
 from mdsuite.calculators.coordination_number_calculation import CoordinationNumbers
+from mdsuite.calculators.angular_distribution_function import AngularDistributionFunction
 from mdsuite.calculators.einstein_diffusion_coefficients import EinsteinDiffusionCoefficients
 from mdsuite.calculators.einstein_helfand_ionic_conductivity import EinsteinHelfandIonicConductivity
 from mdsuite.calculators.einstein_helfand_thermal_conductivity import EinsteinHelfandThermalConductivity
@@ -58,6 +31,21 @@
 from mdsuite.calculators.green_kubo_distinct_diffusion_coefficients import GreenKuboDistinctDiffusionCoefficients
 from mdsuite.calculators.einstein_distinct_diffusion_coefficients import EinsteinDistinctDiffusionCoefficients
 
+dict_classes_db = {
+    'self_diffusion_coefficients': {'Einstein_Self_Diffusion_Coefficients': {},
+                                    'Green_Kubo_Self_Diffusion': {}},
+    'distinct_diffusion_coefficients': {'Einstein_Distinct_Diffusion_Coefficients': {},
+                                        'Green_Kubo_Distinct_Diffusion_Coefficients': {}},
+    'ionic_conductivity': {},
+    'thermal_conductivity': {},
+    'coordination_numbers': {'Coordination_Numbers': {}},
+    'potential_of_mean_force_values': {'Potential_of_Mean_Force': {}},
+    'radial_distribution_function': {},
+    'kirkwood_buff_integral': {},
+    'structure_factor': {},
+    'viscosity': {}
+}
+
 dict_classes_computations = {
     'EinsteinDiffusionCoefficients': EinsteinDiffusionCoefficients,
     'EinsteinDistinctDiffusionCoefficients': EinsteinDistinctDiffusionCoefficients,
diff --git a/mdsuite/calculators/coordination_number_calculation.py b/mdsuite/calculators/coordination_number_calculation.py
index 18c08d53..2c7ee0eb 100644
--- a/mdsuite/calculators/coordination_number_calculation.py
+++ b/mdsuite/calculators/coordination_number_calculation.py
@@ -6,24 +6,19 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of the coordinated numbers
 
 Summary
 -------
 """
-
 import logging
-
 import os
 import numpy as np
 import matplotlib.pyplot as plt
 from scipy.signal import find_peaks
-
 from typing import Union
-from mdsuite.utils.exceptions import *
+from mdsuite.utils.exceptions import NotApplicableToAnalysis, CannotPerformThisAnalysis
 from mdsuite.calculators.calculator import Calculator
 from mdsuite.database.properties_database import PropertiesDatabase
 from mdsuite.database.database_scheme import SystemProperty
@@ -232,8 +227,8 @@ def _get_coordination_numbers(self):
         first_shell_error = np.std([self.integral_data[self.indices[0][0]],
                                     self.integral_data[self.indices[0][1]]]) / np.sqrt(2)
 
-        second_shell = np.mean([self.integral_data[self.indices[1][0]], self.integral_data[self.indices[1][1]]]) - \
-                       first_shell
+        second_shell = np.mean([self.integral_data[self.indices[1][0]],
+                                self.integral_data[self.indices[1][1]]]) - first_shell
         second_shell_error = np.std([self.integral_data[self.indices[1][0]],
                                      self.integral_data[self.indices[1][1]]]) / np.sqrt(2)
 
diff --git a/mdsuite/calculators/einstein_diffusion_coefficients.py b/mdsuite/calculators/einstein_diffusion_coefficients.py
index 27fb8255..6b330152 100644
--- a/mdsuite/calculators/einstein_diffusion_coefficients.py
+++ b/mdsuite/calculators/einstein_diffusion_coefficients.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of the einstein diffusion coefficients.
 
 Summary
@@ -18,7 +16,6 @@
 The methods in class can then be called by the Experiment.einstein_diffusion_coefficients method and all necessary
 calculations performed.
 """
-
 import logging
 import matplotlib.pyplot as plt
 import numpy as np
@@ -84,7 +81,7 @@ def __init__(self, experiment):
         self.molecules = None
         self.database_group = 'Diffusion_Coefficients'
         self.x_label = 'Time (s)'
-        self.y_label = 'MSD (m$^2$/s)'
+        self.y_label = 'MSD (m$^2$)'
         self.analysis_name = 'Einstein_Self_Diffusion_Coefficients'
         self.loop_condition = False
         self.optimize = None
@@ -212,7 +209,7 @@ def _post_operation_processes(self, species: str = None):
         if self.plot:
             plt.xlabel(rf'{self.x_label}')  # set the x label
             plt.ylabel(rf'{self.y_label}')  # set the y label
-            plt.plot(np.array(self.time) * self.experiment.units['time'], self.msd_array,
+            plt.plot(np.array(self.time) * self.experiment.units['time'], self.msd_array * self.experiment.units['time'],
                      label=fr"{species}: {result[0]: 0.3E} $\pm$ {result[1]: 0.3E}")
 
     def _optimized_calculation(self):
diff --git a/mdsuite/calculators/einstein_distinct_diffusion_coefficients.py b/mdsuite/calculators/einstein_distinct_diffusion_coefficients.py
index 5d55faa9..21b4001f 100644
--- a/mdsuite/calculators/einstein_distinct_diffusion_coefficients.py
+++ b/mdsuite/calculators/einstein_distinct_diffusion_coefficients.py
@@ -6,10 +6,9 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of the Green-Kubo diffusion coefficients.
+
 Summary
 -------
 This module contains the code for the Einstein diffusion coefficient class. This class is called by the
@@ -17,14 +16,12 @@
 The methods in class can then be called by the Experiment.green_kubo_diffusion_coefficients method and all necessary
 calculations performed.
 """
-
 from typing import Union
 import numpy as np
 import warnings
 from tqdm import tqdm
 import tensorflow as tf
 import itertools
-from scipy import signal
 import matplotlib.pyplot as plt
 from mdsuite.calculators.calculator import Calculator
 from mdsuite.utils.meta_functions import join_path
diff --git a/mdsuite/calculators/einstein_helfand_ionic_conductivity.py b/mdsuite/calculators/einstein_helfand_ionic_conductivity.py
index 8bacd0d8..0669240f 100644
--- a/mdsuite/calculators/einstein_helfand_ionic_conductivity.py
+++ b/mdsuite/calculators/einstein_helfand_ionic_conductivity.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of the Einstein-Helfand ionic conductivity.
 
 Summary
@@ -17,7 +15,6 @@
 Experiment.einstein_helfand_ionic_conductivity method. The methods in class can then be called by the
 Experiment.einstein_helfand_ionic_conductivity method and all necessary calculations performed.
 """
-
 import warnings
 import matplotlib.pyplot as plt
 import numpy as np
@@ -139,8 +136,7 @@ def _calculate_prefactor(self, species: str = None):
         numerator = (self.experiment.units['length'] ** 2) * (elementary_charge ** 2)
         denominator = 6 * self.experiment.units['time'] * (
                 self.experiment.volume * self.experiment.units['length'] ** 3) * \
-                      self.experiment.temperature * boltzmann_constant
-
+            self.experiment.temperature * boltzmann_constant
         self.prefactor = numerator / denominator
 
     def _apply_averaging_factor(self):
diff --git a/mdsuite/calculators/einstein_helfand_thermal_conductivity.py b/mdsuite/calculators/einstein_helfand_thermal_conductivity.py
index f6afa66c..81bdd897 100644
--- a/mdsuite/calculators/einstein_helfand_thermal_conductivity.py
+++ b/mdsuite/calculators/einstein_helfand_thermal_conductivity.py
@@ -6,22 +6,17 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of the conductivity.
 
 Summary
 -------
 """
-
 import warnings
-
 import matplotlib.pyplot as plt
 import numpy as np
 import tensorflow as tf
 from tqdm import tqdm
-
 from mdsuite.calculators.calculator import Calculator
 
 tqdm.monitor_interval = 0
@@ -195,5 +190,5 @@ def _post_operation_processes(self, species: str = None):
             self._update_properties_file(properties)
 
         if self.export:
-            self._export_data(name=self._build_table_name("System"), data=self._build_pandas_dataframe(self.time,
-                                                                                                      self.msd_array))
+            self._export_data(name=self._build_table_name("System"),
+                              data=self._build_pandas_dataframe(self.time, self.msd_array))
diff --git a/mdsuite/calculators/einstein_helfand_thermal_kinaci.py b/mdsuite/calculators/einstein_helfand_thermal_kinaci.py
index 99ff7505..8bf73384 100644
--- a/mdsuite/calculators/einstein_helfand_thermal_kinaci.py
+++ b/mdsuite/calculators/einstein_helfand_thermal_kinaci.py
@@ -6,17 +6,13 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of the conductivity.
 
 Summary
 -------
 """
-
 import warnings
-
 import matplotlib.pyplot as plt
 import numpy as np
 import tensorflow as tf
@@ -197,4 +193,4 @@ def _post_operation_processes(self, species: str = None):
 
         if self.export:
             self._export_data(name=self._build_table_name("System"), data=self._build_pandas_dataframe(self.time,
-                                                                                                      self.msd_array))
+                                                                                                       self.msd_array))
diff --git a/mdsuite/calculators/flux_viscosity.py b/mdsuite/calculators/flux_viscosity.py
index cfa509dc..cca0efcb 100644
--- a/mdsuite/calculators/flux_viscosity.py
+++ b/mdsuite/calculators/flux_viscosity.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of viscosity.
 
 Summary
@@ -19,8 +17,6 @@
 calculations performed.
 """
 import warnings
-
-# Python standard packages
 import matplotlib.pyplot as plt
 import numpy as np
 from tqdm import tqdm
@@ -138,7 +134,7 @@ def _calculate_prefactor(self, species: str = None):
         denominator = 3 * (self.data_range - 1) * self.experiment.temperature * self.experiment.units['boltzman']
 
         prefactor_units = self.experiment.units['pressure'] ** 2 * self.experiment.units['length'] ** 3 * \
-                          self.experiment.units['time'] / self.experiment.units['energy']
+            self.experiment.units['time'] / self.experiment.units['energy']
 
         self.prefactor = (numerator / denominator)*prefactor_units
 
@@ -209,4 +205,4 @@ def _post_operation_processes(self, species: str = None):
 
         if self.export:
             self._export_data(name=self._build_table_name("System"), data=self._build_pandas_dataframe(self.time,
-                                                                                                      self.jacf))
+                                                                                                       self.jacf))
diff --git a/mdsuite/calculators/green_kubo_distinct_diffusion_coefficients.py b/mdsuite/calculators/green_kubo_distinct_diffusion_coefficients.py
index e5ec04bf..c24f1998 100644
--- a/mdsuite/calculators/green_kubo_distinct_diffusion_coefficients.py
+++ b/mdsuite/calculators/green_kubo_distinct_diffusion_coefficients.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of the Green-Kubo diffusion coefficients.
 Summary
 -------
@@ -17,7 +15,6 @@
 The methods in class can then be called by the Experiment.green_kubo_diffusion_coefficients method and all necessary
 calculations performed.
 """
-
 from typing import Union
 import numpy as np
 import warnings
@@ -189,10 +186,10 @@ def _calculate_prefactor(self, species: Union[str, tuple] = None):
 
         """
         if species[0] == species[1]:
-            atom_scale = len(self.experiment.species[species[0]]['indices'])*\
+            atom_scale = len(self.experiment.species[species[0]]['indices']) * \
                          (len(self.experiment.species[species[1]]['indices']) - 1)
         else:
-            atom_scale = len(self.experiment.species[species[0]]['indices'])*\
+            atom_scale = len(self.experiment.species[species[0]]['indices']) * \
                          len(self.experiment.species[species[1]]['indices'])
         numerator = self.experiment.units['length'] ** 2
         denominator = 3 * self.experiment.units['time'] * (self.data_range - 1) * atom_scale
diff --git a/mdsuite/calculators/green_kubo_ionic_conductivity.py b/mdsuite/calculators/green_kubo_ionic_conductivity.py
index 63e5d4a7..71ed73dc 100644
--- a/mdsuite/calculators/green_kubo_ionic_conductivity.py
+++ b/mdsuite/calculators/green_kubo_ionic_conductivity.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of the Green-Kubo ionic conductivity.
 
 Summary
@@ -17,7 +15,6 @@
 The methods in class can then be called by the Experiment.green_kubo_ionic_conductivity method and all necessary
 calculations performed.
 """
-
 import matplotlib.pyplot as plt
 import numpy as np
 import warnings
@@ -134,7 +131,7 @@ def _calculate_prefactor(self, species: str = None):
         # Calculate the prefactor
         numerator = (elementary_charge ** 2) * (self.experiment.units['length'] ** 2)
         denominator = 3 * boltzmann_constant * self.experiment.temperature * self.experiment.volume * \
-                      (self.experiment.units['length'] ** 3) * self.data_range * self.experiment.units['time']
+            (self.experiment.units['length'] ** 3) * self.data_range * self.experiment.units['time']
         self.prefactor = numerator / denominator
 
     def _apply_averaging_factor(self):
diff --git a/mdsuite/calculators/green_kubo_self_diffusion_coefficients.py b/mdsuite/calculators/green_kubo_self_diffusion_coefficients.py
index f00b6836..5a6bcdae 100644
--- a/mdsuite/calculators/green_kubo_self_diffusion_coefficients.py
+++ b/mdsuite/calculators/green_kubo_self_diffusion_coefficients.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of the Green-Kubo diffusion coefficients.
 Summary
 -------
@@ -17,7 +15,6 @@
 The methods in class can then be called by the Experiment.green_kubo_diffusion_coefficients method and all necessary
 calculations performed.
 """
-
 import matplotlib.pyplot as plt
 from scipy import signal
 import numpy as np
@@ -146,13 +143,13 @@ def _calculate_prefactor(self, species: str = None):
             # Calculate the prefactor
             numerator = self.experiment.units['length'] ** 2
             denominator = 3 * self.experiment.units['time'] * (self.data_range - 1) * \
-                          len(self.experiment.molecules[species]['indices'])
+                len(self.experiment.molecules[species]['indices'])
             self.prefactor = numerator / denominator
         else:
             # Calculate the prefactor
             numerator = self.experiment.units['length'] ** 2
             denominator = 3 * self.experiment.units['time'] * (self.data_range - 1) * \
-                          len(self.experiment.species[species]['indices'])
+                len(self.experiment.species[species]['indices'])
             self.prefactor = numerator / denominator
 
     def _apply_averaging_factor(self):
diff --git a/mdsuite/calculators/green_kubo_thermal_conductivity.py b/mdsuite/calculators/green_kubo_thermal_conductivity.py
index 0bef8ef8..e07c01bc 100644
--- a/mdsuite/calculators/green_kubo_thermal_conductivity.py
+++ b/mdsuite/calculators/green_kubo_thermal_conductivity.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of the Green-Kubo thermal conductivity.
 
 Summary
@@ -19,8 +17,6 @@
 calculations performed.
 """
 import warnings
-
-# Python standard packages
 import matplotlib.pyplot as plt
 import numpy as np
 import tensorflow as tf
@@ -132,7 +128,7 @@ def _calculate_prefactor(self, species: str = None):
         # prepare the prefactor for the integral
         numerator = 1
         denominator = 3 * (self.data_range - 1) * self.experiment.temperature ** 2 * self.experiment.units['boltzman'] \
-                      * self.experiment.volume  # we use Boltzmann constant in the units provided.
+            * self.experiment.volume  # we use Boltzmann constant in the units provided.
         prefactor_units = self.experiment.units['energy'] / self.experiment.units['length'] / self.experiment.units[
             'time']
 
@@ -196,4 +192,4 @@ def _post_operation_processes(self, species: str = None):
             self._update_properties_file(properties)
         if self.export:
             self._export_data(name=self._build_table_name("System"), data=self._build_pandas_dataframe(self.time,
-                                                                                                      self.jacf))
+                                                                                                       self.jacf))
diff --git a/mdsuite/calculators/green_kubo_viscosity.py b/mdsuite/calculators/green_kubo_viscosity.py
index c8f85906..451342b5 100644
--- a/mdsuite/calculators/green_kubo_viscosity.py
+++ b/mdsuite/calculators/green_kubo_viscosity.py
@@ -6,24 +6,19 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of the Green-Kubo viscosity.
 
 Summary
 This module contains the code for the Green-Kubo viscsity class. This class is called by the
 """
 import warnings
-
 import matplotlib.pyplot as plt
 import numpy as np
 import tensorflow as tf
 from tqdm import tqdm
 from scipy import signal
-
 from mdsuite.calculators.calculator import Calculator
-from mdsuite.utils.meta_functions import join_path
 
 # Set style preferences, turn off warning, and suppress the duplication of loading bars.
 tqdm.monitor_interval = 0
@@ -130,8 +125,7 @@ def _calculate_prefactor(self, species: str = None):
         denominator = 3 * (self.data_range - 1) * self.experiment.temperature * self.experiment.units[
             'boltzman'] * self.experiment.volume  # we use boltzman constant in the units provided.
         prefactor_units = self.experiment.units['pressure'] ** 2 * self.experiment.units['length'] ** 3 * \
-                          self.experiment.units[
-                              'time'] / self.experiment.units['energy']
+            self.experiment.units['time'] / self.experiment.units['energy']
 
         self.prefactor = (numerator / denominator) * prefactor_units
 
diff --git a/mdsuite/calculators/kirkwood_buff_integrals.py b/mdsuite/calculators/kirkwood_buff_integrals.py
index 5a507b29..d012f596 100644
--- a/mdsuite/calculators/kirkwood_buff_integrals.py
+++ b/mdsuite/calculators/kirkwood_buff_integrals.py
@@ -6,24 +6,19 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of the coordinated numbers
 """
-
 import logging
-
 import numpy as np
 import os
 import matplotlib.pyplot as plt
 from typing import Union
 from mdsuite.database.properties_database import PropertiesDatabase
 from mdsuite.database.database_scheme import SystemProperty
-
-# MDSuite imports
-from mdsuite.utils.exceptions import *
+from mdsuite.utils.exceptions import NotApplicableToAnalysis
 from mdsuite.calculators.calculator import Calculator
+from typing import Iterable
 
 log = logging.getLogger(__file__)
 
@@ -122,7 +117,7 @@ def _autocorrelation_time(self):
         """
         raise NotApplicableToAnalysis
 
-    def _get_rdf_data(self) -> list:
+    def _get_rdf_data(self) -> Iterable:
         """
         Fill the data_files list with filenames of the rdf tensor_values
         """
diff --git a/mdsuite/calculators/nernst_einstein_ionic_conductivity.py b/mdsuite/calculators/nernst_einstein_ionic_conductivity.py
index 9a85fc1d..3e2efc60 100644
--- a/mdsuite/calculators/nernst_einstein_ionic_conductivity.py
+++ b/mdsuite/calculators/nernst_einstein_ionic_conductivity.py
@@ -6,12 +6,10 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
-
-""" Calculate the Nernst-Einstein Conductivity of a system """
 
+Calculate the Nernst-Einstein Conductivity of a system
+"""
 import logging
-
 import sys
 import operator
 from typing import Union
@@ -128,7 +126,7 @@ def _nernst_einstein(self, diffusion_information: list):
         # evaluate the prefactor
         numerator = self.experiment.number_of_atoms * (elementary_charge ** 2)
         denominator = boltzmann_constant * self.experiment.temperature * \
-                      (self.experiment.volume * (self.experiment.units['length'] ** 3))
+            (self.experiment.volume * (self.experiment.units['length'] ** 3))
         prefactor = numerator / denominator
 
         conductivity = 0.0
@@ -165,7 +163,7 @@ def _corrected_nernst_einstein(self, self_diffusion_information: list, distinct_
         # evaluate the prefactor
         numerator = self.experiment.number_of_atoms * (elementary_charge ** 2)
         denominator = boltzmann_constant * self.experiment.temperature * \
-                      (self.experiment.volume * (self.experiment.units['length'] ** 3))
+            (self.experiment.volume * (self.experiment.units['length'] ** 3))
         prefactor = numerator / denominator
 
         conductivity = 0.0
@@ -184,10 +182,10 @@ def _corrected_nernst_einstein(self, self_diffusion_information: list, distinct_
             diffusion_uncertainty = item['uncertainty']
             constituents = item['Subject'].split("_")
             charge_term = self.experiment.species[constituents[0]]['charge'][0] * \
-                         self.experiment.species[constituents[1]]['charge'][0]
+                self.experiment.species[constituents[1]]['charge'][0]
             mass_fraction_term = (len(
                 self.experiment.species[constituents[0]]['indices']) / self.experiment.number_of_atoms) * \
-                                 (len(self.experiment.species[constituents[1]][
+                (len(self.experiment.species[constituents[1]][
                                           'indices']) / self.experiment.number_of_atoms)
             conductivity += diffusion_coefficient * charge_term * mass_fraction_term
             uncertainty += diffusion_uncertainty * charge_term * mass_fraction_term
@@ -206,7 +204,7 @@ def _run_nernst_einstein(self):
         if ne_table[0]:
             input_data = [self.experiment.export_property_data({'property': 'Diffusion_Coefficients',
                                                                 "analysis": "Green_Kubo_Self_Diffusion_Coefficients",
-                                                                "subjects": [species]})[0] for species in self.species]
+                                                                "subjects": [species[0] for species in self.species]})]
             data = self._nernst_einstein(input_data)
             properties = {"Property": self.database_group,
                           "Analysis": "Green_Kubo_Nernst_Einstein_Ionic_Conductivity",
@@ -219,7 +217,7 @@ def _run_nernst_einstein(self):
         if ne_table[1]:
             input_data = [self.experiment.export_property_data({'property': 'Diffusion_Coefficients',
                                                                 "analysis": "Einstein_Self_Diffusion_Coefficients",
-                                                                "subjects": [species]})[0] for species in self.species]
+                                                                "subjects": [species[0] for species in self.species]})]
             data = self._nernst_einstein(input_data)
 
             properties = {"Property": self.database_group,
@@ -250,8 +248,10 @@ def _run_corrected_nernst_einstein(self):
                                                                 "analysis": "Green_Kubo_Self_Diffusion_Coefficients",
                                                                 "subjects": [species]})[0] for species in self.species]
             input_distinct = [self.experiment.export_property_data({'property': 'Diffusion_Coefficients',
-                                                                "analysis": "Green_Kubo_Distinct_Diffusion_Coefficients",
-                                                                "subjects": [species]})[0] for species in self.species]
+                                                                    "analysis": "Green_Kubo_Distinct_Diffusion_"
+                                                                                "Coefficients",
+                                                                    "subjects": [species]})[0] for species in
+                              self.species]
             data = self._corrected_nernst_einstein(input_self, input_distinct)
 
             properties = {"Property": self.database_group,
@@ -267,8 +267,9 @@ def _run_corrected_nernst_einstein(self):
                                                                 "analysis": "Einstein_Self_Diffusion_Coefficients",
                                                                 "subjects": [species]})[0] for species in self.species]
             input_distinct = [self.experiment.export_property_data({'property': 'Diffusion_Coefficients',
-                                                                "analysis": "Einstein_Distinct_Diffusion_Coefficients",
-                                                                "subjects": [species]})[0] for species in self.species]
+                                                                    "analysis": "Einstein_Distinct_Diffusion_Coefficients",
+                                                                    "subjects": [species]})[0] for species in
+                              self.species]
             data = self._corrected_nernst_einstein(input_self, input_distinct)
 
             properties = {"Property": self.database_group,
diff --git a/mdsuite/calculators/potential_of_mean_force.py b/mdsuite/calculators/potential_of_mean_force.py
index 22b1c089..d5b47380 100644
--- a/mdsuite/calculators/potential_of_mean_force.py
+++ b/mdsuite/calculators/potential_of_mean_force.py
@@ -6,9 +6,8 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-""" Class for the calculation of the coordinated numbers
+Class for the calculation of the coordinated numbers
 
 Summary
 -------
@@ -26,17 +25,14 @@
         w^{(2)}(r) = -k_{B}Tln(g(r))
 """
 import logging
-
 import numpy as np
 import os
 from scipy.signal import find_peaks
 import matplotlib.pyplot as plt
 from typing import Union
-
 from mdsuite.database.properties_database import PropertiesDatabase
 from mdsuite.database.database_scheme import SystemProperty
-
-from mdsuite.utils.exceptions import *
+from mdsuite.utils.exceptions import NotApplicableToAnalysis
 from mdsuite.calculators.calculator import Calculator
 from mdsuite.utils.meta_functions import golden_section_search
 from mdsuite.utils.meta_functions import apply_savgol_filter
diff --git a/mdsuite/calculators/radial_distribution_function.py b/mdsuite/calculators/radial_distribution_function.py
index 37b4e2fc..840435a1 100644
--- a/mdsuite/calculators/radial_distribution_function.py
+++ b/mdsuite/calculators/radial_distribution_function.py
@@ -6,13 +6,9 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for the calculation of the radial distribution function.
 
-Author: Samuel Tovey, Fabian Zills
-
 Summary
 -------
 This module contains the code for the radial distribution function. This class is called by
@@ -22,20 +18,15 @@
 """
 import logging
 from abc import ABC
-
 import numpy as np
 import matplotlib.pyplot as plt
 import warnings
-
-# Import user packages
 from tqdm import tqdm
 import tensorflow as tf
 import itertools
 from mdsuite.utils.meta_functions import join_path
-
 from mdsuite.calculators.calculator import Calculator
 from mdsuite.utils.meta_functions import split_array
-
 from timeit import default_timer as timer
 
 # Set style preferences, turn off warning, and suppress the duplication of loading bars.
@@ -555,14 +546,14 @@ def _calculate_prefactor(self, species: str) -> float:
             ideal_correction = self._get_ideal_gas_probability()  # get the ideal gas value
             numerator = species_scale_factor
             denominator = self.number_of_configurations * rho * ideal_correction * \
-                          len(self.experiment.molecules[species_split[0]]['indices'])
+                len(self.experiment.molecules[species_split[0]]['indices'])
         else:
             # Density of all atoms / total volume
             rho = len(self.experiment.species[species_split[1]]['indices']) / self.experiment.volume
             ideal_correction = self._get_ideal_gas_probability()  # get the ideal gas value
             numerator = species_scale_factor
             denominator = self.number_of_configurations * rho * ideal_correction * \
-                          len(self.experiment.species[species_split[0]]['indices'])
+                len(self.experiment.species[species_split[0]]['indices'])
         prefactor = numerator / denominator
 
         return prefactor
@@ -619,7 +610,7 @@ def run_experimental_analysis(self):
             self.n_batches = self.override_n_batches
 
         if self.minibatch is None:
-            log.debug(f"Doing full batch RDF computations")
+            log.debug("Doing full batch RDF computations")
             if self.use_tf_function:
                 raise NotImplementedError('tf.function is only supported with minibatching')
             else:
diff --git a/mdsuite/calculators/structure_factor.py b/mdsuite/calculators/structure_factor.py
index 307c8ce2..1d01ee85 100644
--- a/mdsuite/calculators/structure_factor.py
+++ b/mdsuite/calculators/structure_factor.py
@@ -6,44 +6,39 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-""" Class for the calculation of the total structure factor for X-rays using the Faber-Ziman formalism"""
+Class for the calculation of the total structure factor for X-rays using the Faber-Ziman formalism
+ """
 import logging
-
 import numpy as np
 import os
 import pandas as pd
 from scipy.integrate import simps
 from scipy.integrate import cumtrapz
 import matplotlib.pyplot as plt
-
-plt.rcParams['figure.facecolor'] = 'white'
 from typing import Union
-
 from tqdm import tqdm
 
-# MDSuite imports
-from mdsuite.utils.exceptions import *
+from mdsuite.utils.exceptions import NotApplicableToAnalysis
 from mdsuite.calculators.calculator import Calculator
-
 from mdsuite import data as static_data
 from importlib.resources import open_text
-
 from mdsuite.database.properties_database import PropertiesDatabase
 from mdsuite.database.database_scheme import SystemProperty
+plt.rcParams['figure.facecolor'] = 'white'
 
 log = logging.getLogger(__file__)
 
 
 class StructureFactor(Calculator):
-    """ Class for the calculation of the total structure factor for X-ray scattering
-        using the Faber-Ziman partial structure factors. This analysis is valid for a magnitude of the X-ray
-        scattering vector Q < 25 * 1/Angstrom
-        Explicitly equations 9, 10 and 11 of the paper
-        'DFT Accurate Interatomic Potential for Molten NaCl from MachineLearning' from
-        Samuel Tovey, Anand Narayanan Krishnamoorthy, Ganesh Sivaraman, Jicheng Guo,
-        Chris Benmore,Andreas Heuer, and Christian Holm are implemented.
+    """
+    Class for the calculation of the total structure factor for X-ray scattering
+    using the Faber-Ziman partial structure factors. This analysis is valid for a magnitude of the X-ray
+    scattering vector Q < 25 * 1/Angstrom
+    Explicitly equations 9, 10 and 11 of the paper
+    'DFT Accurate Interatomic Potential for Molten NaCl from MachineLearning' from
+    Samuel Tovey, Anand Narayanan Krishnamoorthy, Ganesh Sivaraman, Jicheng Guo,
+    Chris Benmore,Andreas Heuer, and Christian Holm are implemented.
 
     Attributes
     ----------
diff --git a/mdsuite/calculators/transformations_reference.py b/mdsuite/calculators/transformations_reference.py
new file mode 100644
index 00000000..eb4cc1cd
--- /dev/null
+++ b/mdsuite/calculators/transformations_reference.py
@@ -0,0 +1,12 @@
+"""
+A string reference to transformations.
+"""
+
+switcher_transformations = {
+    'Translational_Dipole_Moment': 'TranslationalDipoleMoment',
+    'Ionic_Current': 'IonicCurrent',
+    'Integrated_Heat_Current': 'IntegratedHeatCurrent',
+    'Thermal_Flux': 'ThermalFlux',
+    'Momentum_Flux': 'MomentumFlux',
+    'Kinaci_Heat_Current': 'KinaciIntegratedHeatCurrent'
+}
diff --git a/mdsuite/data/__init__.py b/mdsuite/data/__init__.py
index 5a25718d..45b15aa7 100644
--- a/mdsuite/data/__init__.py
+++ b/mdsuite/data/__init__.py
@@ -6,4 +6,4 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
\ No newline at end of file
+"""
diff --git a/mdsuite/database/__init__.py b/mdsuite/database/__init__.py
index 5a25718d..45b15aa7 100644
--- a/mdsuite/database/__init__.py
+++ b/mdsuite/database/__init__.py
@@ -6,4 +6,4 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
\ No newline at end of file
+"""
diff --git a/mdsuite/database/analysis_database.py b/mdsuite/database/analysis_database.py
index df7dc1f9..327df822 100644
--- a/mdsuite/database/analysis_database.py
+++ b/mdsuite/database/analysis_database.py
@@ -6,17 +6,12 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python module for the Analysis database class.
 """
-
 import sqlalchemy as sql
 from sqlalchemy import select
 from sqlalchemy import column
-from sqlalchemy import table
-from sqlalchemy import delete
 from sqlalchemy import and_
 import pandas as pd
 
@@ -46,7 +41,7 @@ def build_database(self):
         -------
         Constructs a new database
         """
-        with self.engine.begin() as conn:
+        with self.engine.begin():  # as conn:
             print("Constructed new database")
 
     def _check_table_existence(self, parameters: dict):
diff --git a/mdsuite/database/data_manager.py b/mdsuite/database/data_manager.py
index bc093bc4..68da2d4a 100644
--- a/mdsuite/database/data_manager.py
+++ b/mdsuite/database/data_manager.py
@@ -6,18 +6,14 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python module for the tensor_values fetch class
 """
 import logging
-
 import sys
 import numpy as np
 import tensorflow as tf
 from tqdm import tqdm
-
 from mdsuite.database.simulation_database import Database
 
 log = logging.getLogger(__file__)
@@ -27,15 +23,15 @@ class DataManager:
     """
     Class for the MDS tensor_values fetcher
 
-    Due to the amount of tensor_values that needs to be collected and the possibility to optimize repeated loading, a separate
-    tensor_values fetching class is required. This class manages how tensor_values is loaded from the MDS database_path and optimizes
-    processes such as pre-loading and parallel reading.
+    Due to the amount of tensor_values that needs to be collected and the possibility to optimize repeated loading,
+    a separate tensor_values fetching class is required. This class manages how tensor_values is loaded from the MDS
+    database_path and optimizes processes such as pre-loading and parallel reading.
     """
 
     def __init__(self, database: Database = None, data_path: list = None, data_range: int = None,
                  n_batches: int = None, batch_size: int = None, ensemble_loop: int = None,
                  correlation_time: int = 1, remainder: int = None, atom_selection=np.s_[:],
-                 minibatch: bool = False, atom_batch_size : int = None, n_atom_batches: int = None,
+                 minibatch: bool = False, atom_batch_size: int = None, n_atom_batches: int = None,
                  atom_remainder: int = None, offset: int = 0):
         """
         Constructor for the DataManager class
@@ -165,6 +161,7 @@ def atom_generator(batch_number: int, batch_size: int, database: str, data_path:
             """
             database = Database(name=database)
             _atom_remainder = [1 if self.atom_remainder else 0][0]
+            start = 0
             for atom_batch in tqdm(range(self.n_atom_batches + _atom_remainder),
                                    total=self.n_atom_batches + _atom_remainder):
                 atom_start = atom_batch * self.atom_batch_size
@@ -206,6 +203,8 @@ def ensemble_generator(self, system: bool = False, dictionary: bool = False) ->
         ----------
         system : bool
                 If true, the system generator is returned.
+        dictionary : bool
+                If true, data is expected as a dictionary and returned as one.
 
         Returns
         -------
diff --git a/mdsuite/database/database_scheme.py b/mdsuite/database/database_scheme.py
index 0c7da26c..6db9eacf 100644
--- a/mdsuite/database/database_scheme.py
+++ b/mdsuite/database/database_scheme.py
@@ -1,4 +1,5 @@
-"""Definition of the Database objects
+"""
+Definition of the Database objects
 """
 from sqlalchemy.orm import declarative_base
 from sqlalchemy import Column, Integer, String, Float, ForeignKey
@@ -110,13 +111,21 @@ def __repr__(self):
 
 
 class Subject(Base):
-    """Class for the subjects associated with SystemProperty
+    """
+    Class for the subjects associated with SystemProperty
 
     Parameters
-    ----------
-    id: int, PK
-    subject: str
-        Name of the subject
+    ---------
+    id: int,
+        Primary key
+    subject: str,
+        name
+    system_property_id: int,
+        System property pk
+    system_property:
+        SQLAlchemy relation object
+
+
     """
     __tablename__ = "subjects"
     id = Column(Integer, primary_key=True)
diff --git a/mdsuite/database/properties_database.py b/mdsuite/database/properties_database.py
index 6c88f271..3f6eaf5d 100644
--- a/mdsuite/database/properties_database.py
+++ b/mdsuite/database/properties_database.py
@@ -6,19 +6,13 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python module for the properties database.
 """
-
 import logging
-
 import sqlalchemy as sa
-
 from sqlalchemy.orm import sessionmaker
 from sqlalchemy.orm.session import Session
-
 from .database_scheme import Base, SystemProperty, Data, Subject
 
 log = logging.getLogger(__file__)
@@ -59,7 +53,8 @@ def build_database(self):
         log.debug('Creating Database if not existing')
         self.Base.metadata.create_all(self.engine)
 
-    def _build_subject_query(self, subjects, query, ses):
+    @staticmethod
+    def _build_subject_query(subjects, query, ses):
         """Query the one->many subjects relationship
 
         Parameters
diff --git a/mdsuite/database/simulation_database.py b/mdsuite/database/simulation_database.py
index d11515d6..9062c853 100644
--- a/mdsuite/database/simulation_database.py
+++ b/mdsuite/database/simulation_database.py
@@ -6,16 +6,13 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for database_path objects and all of their operations
 """
-
 import h5py as hf
 import numpy as np
 from mdsuite.utils.meta_functions import join_path
-from mdsuite.utils.exceptions import *
+from mdsuite.utils.exceptions import DatabaseDoesNotExist
 import tensorflow as tf
 import time
 from typing import Union
@@ -83,6 +80,13 @@ def _update_indices(data: np.array, reference: np.array, batch_size: int, n_atom
         """
         Update the indices key of the structure dictionary if the tensor_values must be sorted.
 
+        Parameters
+        ----------
+        data : np.ndarray
+        reference : np.ndarray
+        batch_size : int
+        n_atoms : int
+
         Returns
         -------
 
@@ -194,7 +198,11 @@ def add_data(self, data: np.array, structure: dict, start_index: int, batch_size
                     database[item][start_index:stop_index, :] = data[structure[item]['indices']][
                         np.s_[:, structure[item]['columns'][0]:structure[item]['columns'][-1] + 1]].astype(float)
                 else:
-                    database[item][:, start_index:stop_index, :] = self._get_data(data, structure, item, batch_size, sort,
+                    database[item][:, start_index:stop_index, :] = self._get_data(data,
+                                                                                  structure,
+                                                                                  item,
+                                                                                  batch_size,
+                                                                                  sort,
                                                                                   n_atoms=n_atoms)
 
     def _get_data(self, data: np.array, structure: dict, item: str, batch_size: int, sort: bool = False,
@@ -387,8 +395,8 @@ def check_existence(self, path: str) -> bool:
         """
         with hf.File(self.name, 'r') as database_object:
             keys = []
-            database_object.visit(lambda item: keys.append(database_object[item].name) if type(database_object[item]) is
-                                                                                          hf.Dataset else None)
+            database_object.visit(lambda item: keys.append(database_object[item].name) if type(
+                database_object[item]) is hf.Dataset else None)
             path = f'/{path}'  # add the / to avoid name overlapping
 
             response = any(list(item.endswith(path) for item in keys))
diff --git a/mdsuite/experiment/__init__.py b/mdsuite/experiment/__init__.py
index 5a25718d..45b15aa7 100644
--- a/mdsuite/experiment/__init__.py
+++ b/mdsuite/experiment/__init__.py
@@ -6,4 +6,4 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
\ No newline at end of file
+"""
diff --git a/mdsuite/experiment/experiment.py b/mdsuite/experiment/experiment.py
index 399a4741..30b52571 100644
--- a/mdsuite/experiment/experiment.py
+++ b/mdsuite/experiment/experiment.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 The central experiment class fundamental to all analysis.
 
 Summary
@@ -16,32 +14,30 @@
 The experiment class is the main class involved in characterizing and analyzing a simulation.
 """
 import logging
-
 import json
 import os
 import pickle
 import sys
 from pathlib import Path
-
 import numpy as np
 import pubchempy as pcp
 import yaml
 from tqdm import tqdm
 import importlib.resources
-
 from datetime import datetime
-
 from mdsuite.calculators.computations_dict import dict_classes_computations, dict_classes_db
 from mdsuite.transformations.transformation_dict import transformations_dict
 from mdsuite.file_io.file_io_dict import dict_file_io
 from mdsuite.utils.units import units_dict
 from mdsuite.utils.meta_functions import join_path
-from mdsuite.utils.exceptions import *
+from mdsuite.utils.exceptions import ElementMassAssignedZero
 from mdsuite.database.simulation_database import Database
 from mdsuite.file_io.file_read import FileProcessor
 from mdsuite.database.properties_database import PropertiesDatabase
 from mdsuite.database.analysis_database import AnalysisDatabase
 
+log = logging.getLogger(__file__)
+
 
 class Experiment:
     """
@@ -134,9 +130,11 @@ def __init__(self, analysis_name, storage_path='./', time_step=1.0, temperature=
         # Run Computations
         self.run_computation = self.RunComputation(self)
 
-        self.log = None
         self._start_logging()
 
+        self._simulation_data: dict = {}
+        self.simulation_data_file = Path(self.storage_path) / self.analysis_name / "simulation_data.yaml"
+
     def _start_logging(self):
         logfile_name = datetime.now().replace(microsecond=0).isoformat().replace(':', '-') + ".log"
         logfile = os.path.join(self.logfile_path, logfile_name)
@@ -153,8 +151,7 @@ def _start_logging(self):
         # attaching the stdout handler to the configured logging
         root.addHandler(file_handler)
         # get the file specific logger to get information where the log was written!
-        self.log = logging.getLogger(__name__)
-        self.log.info(f"Created logfile {logfile_name} in experiment path {self.logfile_path}")
+        log.info(f"Created logfile {logfile_name} in experiment path {self.logfile_path}")
 
     def _create_internal_file_paths(self):
         """
@@ -212,10 +209,11 @@ class for later re-loading
         with open(filename, 'wb') as save_file:
             save_file.write(pickle.dumps(self.__dict__))  # write to file
 
-    def units_to_si(self, units_system):
+    @staticmethod
+    def units_to_si(units_system):
         """
         Returns a dictionary with equivalences from the unit experiment given by a string to SI.
-        Along with some constants in the unit experiment provided (boltzman, or other conversions).
+        Along with some constants in the unit experiment provided (boltzmann, or other conversions).
         Instead, the user may provide a dictionary. In that case, the dictionary will be used as the unit experiment.
 
 
@@ -227,15 +225,6 @@ def units_to_si(self, units_system):
         Returns
         -------
         conv_factor (float) -- conversion factor to pass to SI
-
-        Examples
-        --------
-        Pass from metal units of time (ps) to SI
-
-        >>> self.units_to_si('metal')
-        {'time': 1e-12, 'length': 1e-10, 'energy': 1.6022e-19}
-        >>> self.units_to_si({'time': 1e-12, 'length': 1e-10, 'energy': 1.6022e-19,
-        'NkTV2p':1.6021765e6, 'boltzman':8.617343e-5})
         """
 
         if isinstance(units_system, dict):
@@ -244,8 +233,8 @@ def units_to_si(self, units_system):
             try:
                 units = units_dict[units_system]()  # executes the function to return the appropriate dictionary.
             except KeyError:
-                print(f'The unit experiment provided is not implemented...')
-                print(f'The available systems are: ')
+                print('The unit experiment provided is not implemented...')
+                print('The available systems are: ')
                 [print(key) for key, _ in units_dict.items()]
                 sys.exit(-1)
         return units
@@ -260,8 +249,7 @@ def map_elements(self, mapping: dict = None):
         """
 
         if mapping is None:
-            # self.log("Must provide a mapping")
-            self.log.info("Must provide a mapping")
+            log.info("Must provide a mapping")
             return
 
         # rename keys in species dictionary
@@ -329,7 +317,7 @@ def perform_transformation(self, transformation_name, **kwargs):
             transformation = transformations_dict[transformation_name]
         except KeyError:
             print(f'{transformation_name} not found')
-            print(f'Available transformations are:')
+            print('Available transformations are:')
             [print(key) for key in transformations_dict.keys()]
             sys.exit(1)
 
@@ -340,9 +328,9 @@ def _build_model(self):
         """
         Build the 'experiment' for the analysis
 
-        A method to build the database_path in the hdf5 format. Within this method, several other are called to develop the
-        database_path skeleton, get configurations, and process and store the configurations. The method is accompanied
-        by a loading bar which should be customized to make it more interesting.
+        A method to build the database_path in the hdf5 format. Within this method, several other are called to develop
+        the database_path skeleton, get configurations, and process and store the configurations. The method is
+        accompanied by a loading bar which should be customized to make it more interesting.
         """
 
         # Create new analysis directory and change into it
@@ -372,7 +360,7 @@ def print_class_attributes(self):
         for item in vars(self).items():  # loop over class attributes
             attributes.append(item)  # append to the attributes array
         for tuple_attributes in attributes:  # Split the key and value terms
-            self.log.info(f"{tuple_attributes[0]}: {tuple_attributes[1]}")
+            log.info(f"{tuple_attributes[0]}: {tuple_attributes[1]}")
 
         return attributes
 
@@ -443,27 +431,26 @@ def _build_new_database(self, trajectory_reader: FileProcessor, trajectory_file:
         counter = 0  # instantiate counter
         structure = trajectory_reader.build_file_structure()  # build the file structure
 
-        f_object = open(trajectory_file, 'r')  # open the trajectory file
-        for _ in tqdm(range(batch_range), ncols=70):
-            database.add_data(data=trajectory_reader.read_configurations(self.batch_size, f_object, line_length),
-                              structure=structure,
-                              start_index=counter,
-                              batch_size=self.batch_size,
-                              flux=flux,
-                              n_atoms=self.number_of_atoms,
-                              sort=sort)
-            counter += self.batch_size
-
-        if remainder > 0:
-            structure = trajectory_reader.build_file_structure(batch_size=remainder)  # build the file structure
-            database.add_data(data=trajectory_reader.read_configurations(remainder, f_object, line_length),
-                              structure=structure,
-                              start_index=counter,
-                              batch_size=remainder,
-                              flux=flux,
-                              n_atoms=self.number_of_atoms,
-                              sort=sort)
-        f_object.close()
+        with open(trajectory_file, 'r') as f_object:
+            for _ in tqdm(range(batch_range), ncols=70):
+                database.add_data(data=trajectory_reader.read_configurations(self.batch_size, f_object, line_length),
+                                  structure=structure,
+                                  start_index=counter,
+                                  batch_size=self.batch_size,
+                                  flux=flux,
+                                  n_atoms=self.number_of_atoms,
+                                  sort=sort)
+                counter += self.batch_size
+
+            if remainder > 0:
+                structure = trajectory_reader.build_file_structure(batch_size=remainder)  # build the file structure
+                database.add_data(data=trajectory_reader.read_configurations(remainder, f_object, line_length),
+                                  structure=structure,
+                                  start_index=counter,
+                                  batch_size=remainder,
+                                  flux=flux,
+                                  n_atoms=self.number_of_atoms,
+                                  sort=sort)
 
         analysis_database = AnalysisDatabase(name=os.path.join(self.database_path, "analysis_database"))
         analysis_database.build_database()
@@ -515,7 +502,7 @@ def _load_trajectory_reader(self, file_format, trajectory_file, sort: bool = Fal
             class_file_io, file_type = dict_file_io[file_format]  # file type is per atoms or flux.
         except KeyError:
             print(f'{file_format} not found')
-            print(f'Available io formats are are:')
+            print('Available io formats are are:')
             [print(key) for key in dict_file_io.keys()]
             sys.exit(1)
         return class_file_io(self, file_path=trajectory_file, sort=sort), file_type
@@ -677,8 +664,7 @@ def results(self, result_dict: dict):
         with open(os.path.join(self.database_path, 'system_properties.yaml'), 'w') as pfw:
             yaml.dump(result_dict, pfw)
 
-    def write_xyz(self, dump_property: str = "Positions", species: list = None, atom_select: np.s_ = np.s_[:],
-                  time_slice: np.s_ = np.s_[:], name: str = 'dump.xyz'):
+    def write_xyz(self, dump_property: str = "Positions", species: list = None, name: str = 'dump.xyz'):
         """
         Write an xyz file from a database dataset
         """
@@ -752,7 +738,7 @@ def summarise(self):
         print("Database Information\n")
         print("---------------\n")
         print(f"Database Path: {self.database_path}/database.hdf5\n")
-        print(f"Database Size: {os.path.getsize(os.path.join(self.database_path, 'database.hdf5'))*1e-9: 6.3f}GB\n")
+        print(f"Database Size: {os.path.getsize(os.path.join(self.database_path, 'database.hdf5')) * 1e-9: 6.3f}GB\n")
         print(f"Data Groups: {database.get_database_summary()}\n")
         print("==================================================================================\n")
 
@@ -774,3 +760,51 @@ def export_property_data(self, parameters: dict):
         output = database.load_data(parameters)
 
         return output
+
+    @property
+    def simulation_data(self):
+        """
+        Load simulation data from internals.
+        If not available try to read them from file
+
+        Returns
+        -------
+        dict: A dictionary containing all simulation_data
+
+        """
+        if len(self._simulation_data) == 0:
+            try:
+                with open(self.simulation_data_file) as f:
+                    self._simulation_data = yaml.safe_load(f)
+            except FileNotFoundError:
+                log.debug(f"Could not find any data in from {self.simulation_data_file} or self._simulation_data. ")
+        return self._simulation_data
+
+    @simulation_data.setter
+    def simulation_data(self, value: dict):
+        """Update simulation data
+
+        Try to load the data from self.simulation_data_file, update the internals and update the yaml file.
+
+        Parameters
+        ----------
+        value: dict
+            A dictionary containing the (new) simulation data
+
+        Returns
+        -------
+        Updates the internal simulation_data
+
+        """
+        try:
+            with open(self.simulation_data_file) as f:
+                log.debug("Load simulation data from yaml file")
+                simulation_data = yaml.safe_load(f)
+        except FileNotFoundError:
+            simulation_data = {}
+        simulation_data.update(value)
+        log.debug("Updating yaml file")
+        self._simulation_data = simulation_data
+
+        with open(self.simulation_data_file, "w") as f:
+            yaml.safe_dump(simulation_data, f)
diff --git a/mdsuite/file_io/__init__.py b/mdsuite/file_io/__init__.py
index 0e6368a4..2ee23253 100644
--- a/mdsuite/file_io/__init__.py
+++ b/mdsuite/file_io/__init__.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python __init__ file for the file_io modules.
 """
 
diff --git a/mdsuite/file_io/extxyz_trajectory_reader.py b/mdsuite/file_io/extxyz_trajectory_reader.py
index c46f4b0a..43581fa4 100644
--- a/mdsuite/file_io/extxyz_trajectory_reader.py
+++ b/mdsuite/file_io/extxyz_trajectory_reader.py
@@ -6,19 +6,14 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Module for reading extxyz trajectory files
 
 Summary
 -------
 """
-
 from typing import Union, List, Dict, Tuple
-
 import numpy as np
-
 from mdsuite.file_io.trajectory_files import TrajectoryFile
 from mdsuite.utils.meta_functions import get_dimensionality
 from mdsuite.utils.meta_functions import line_counter
@@ -95,7 +90,8 @@ def _get_number_of_configurations(self, number_of_atoms: int):
 
         return int(number_of_lines / (number_of_atoms + self.header_lines))
 
-    def _get_time_value(self, data: list):
+    @staticmethod
+    def _get_time_value(data: list):
         """
         Extract the time value from the header.
 
@@ -143,7 +139,8 @@ def _get_time_information(self, number_of_atoms: int) -> Union[float, None]:
 
         return time
 
-    def _read_lattice(self, data: list) -> Union[list, None]:
+    @staticmethod
+    def _read_lattice(data: list) -> Union[list, None]:
         """
         Get the lattice information
         Parameters
@@ -169,14 +166,15 @@ def _read_lattice(self, data: list) -> Union[list, None]:
                     break
 
         if stop is not None:
-            lattice = data[start:stop+1]
+            lattice = data[start:stop + 1]
             lattice[0] = lattice[0].split('=')[1].replace('"', '')
             lattice[-1] = lattice[-1].replace('"', '')
             lattice = np.array(lattice).astype(float)
 
         return [lattice[0], lattice[4], lattice[8]]
 
-    def _get_property_summary(self, data: list) -> Tuple[int, Dict[str, List[int]]]:
+    @staticmethod
+    def _get_property_summary(data: list) -> Tuple[int, Dict[str, List[int]]]:
         """
         Get the property summary from the header data.
 
@@ -271,10 +269,10 @@ def process_trajectory_file(self, update_class: bool = True, rename_cols: dict =
                 Will map some observable to keys found in the dump file.
         update_class : bool
                 Boolean decision on whether or not to update the class. If yes, the full saved class instance will be
-                updated with new information. This is necessary on the first run of tensor_values addition to the database_path. After
-                this point, when new tensor_values is added, this is no longer required as other methods will take care of
-                updating the properties that change with new tensor_values. In fact, it will set the number of configurations to
-                only the new tensor_values, which will be wrong.
+                updated with new information. This is necessary on the first run of tensor_values addition to the
+                database_path. After this point, when new tensor_values is added, this is no longer required as other
+                methods will take care of updating the properties that change with new tensor_values. In fact, it will
+                set the number of configurations to only the new tensor_values, which will be wrong.
 
         Returns
         -------
@@ -305,5 +303,4 @@ def process_trajectory_file(self, update_class: bool = True, rename_cols: dict =
         else:
             self.experiment.batch_size = batch_size
 
-
         return self._build_architecture(species_summary, property_groups, number_of_configurations), line_length
diff --git a/mdsuite/file_io/file_io_dict.py b/mdsuite/file_io/file_io_dict.py
index 206d6ae8..c7749f67 100644
--- a/mdsuite/file_io/file_io_dict.py
+++ b/mdsuite/file_io/file_io_dict.py
@@ -6,15 +6,12 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Module to contain the structured dict for file io.
 
 Summary
 -------
 """
-
 from mdsuite.file_io.lammps_trajectory_files import LAMMPSTrajectoryFile
 from mdsuite.file_io.lammps_flux_files import LAMMPSFluxFile
 from mdsuite.file_io.extxyz_trajectory_reader import EXTXYZFileReader
diff --git a/mdsuite/file_io/file_read.py b/mdsuite/file_io/file_read.py
index d7bf956b..5d10e624 100644
--- a/mdsuite/file_io/file_read.py
+++ b/mdsuite/file_io/file_read.py
@@ -6,15 +6,12 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Parent class for file processing
 
 Summary
 -------
 """
-
 import abc
 from typing import TextIO
 
@@ -90,7 +87,7 @@ def read_configurations(self, number_of_configurations: int, file_object: TextIO
         return
 
     @staticmethod
-    def _extract_properties(database_correspondence_dict, column_dict_properties):
+    def _extract_properties(database_correspondence_dict: dict, column_dict_properties: dict):
         """
         Construct generalized property array
 
@@ -99,9 +96,8 @@ def _extract_properties(database_correspondence_dict, column_dict_properties):
 
         Parameters
         ----------
-        properties_dict : dict
-                A dictionary of all the available properties in the trajectory. This dictionary is built only from the
-                 LAMMPS symbols and therefore must be again processed to extract the useful information.
+        database_correspondence_dict : dict
+        column_dict_properties : dict
 
         Returns
         -------
@@ -109,7 +105,6 @@ def _extract_properties(database_correspondence_dict, column_dict_properties):
                 A dictionary of the keyword labelled properties in the trajectory. The  values of the dictionary keys
                 correspond to the array location of the specific piece of tensor_values in the set.
         """
-
         # for each property label (position, velocity,etc) in the lammps definition
         for property_label, property_names in database_correspondence_dict.items():
             # for each coordinate for a given property label (position: x, y, z), get idx and the name
@@ -118,7 +113,7 @@ def _extract_properties(database_correspondence_dict, column_dict_properties):
                     # we change the lammps_properties_dict replacing the string of the property name by the column name
                     database_correspondence_dict[property_label][idx] = column_dict_properties[property_name]
 
-        # trajectory_properties only needs the labels with the integer columns, then we one copy those
+        # trajectory_properties only need the labels with the integer columns, then we only copy those
         trajectory_properties = {}
         for property_label, properties_columns in database_correspondence_dict.items():
             if all([isinstance(property_column, int) for property_column in properties_columns]):
@@ -127,18 +122,21 @@ def _extract_properties(database_correspondence_dict, column_dict_properties):
         return trajectory_properties
 
     @staticmethod
-    def _get_column_properties(header_line, skip_words=0) -> dict:
+    def _get_column_properties(header_line: str, skip_words: int = 0) -> dict:
         """
         Given a line of text with the header, split it, enumerate and put in a dictionary.
         This is used to create the column - variable correspondance (see self._extract_properties)
 
         Parameters
         ----------
-                header_line: str
-                        Header line to split
+        header_line: str
+                Header line to split
+        skip_words : int
+                Skip words before reading.
         Returns
         -------
-                properties_summary : dict
+        properties_summary : dict
+                properties summary as a dictionary.
         """
         header_line = header_line[skip_words:]
         properties_summary = {variable: idx for idx, variable in enumerate(header_line)}
diff --git a/mdsuite/file_io/flux_files.py b/mdsuite/file_io/flux_files.py
index d92120e8..01ade995 100644
--- a/mdsuite/file_io/flux_files.py
+++ b/mdsuite/file_io/flux_files.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Module for reading lammps trajectory files
 
 Summary
@@ -16,15 +14,11 @@
 """
 import abc
 import os
-
 import h5py as hf
 import numpy as np
 from tqdm import tqdm
-
 from mdsuite.file_io.file_read import FileProcessor
-
-
-# from .file_io_dict import lammps_flux
+from typing import TextIO
 
 
 class FluxFile(FileProcessor, metaclass=abc.ABCMeta):
@@ -60,7 +54,8 @@ def build_database_skeleton(self):
         #                    libver='latest')
         axis_names = ('x', 'y', 'z', 'xy', 'xz', 'yz', 'yx', 'zx', 'zy')
 
-        with hf.File(os.path.join(self.experiment.database_path, 'database_path.hdf5'), 'w', libver='latest') as database:
+        with hf.File(os.path.join(self.experiment.database_path, 'database_path.hdf5'), 'w', libver='latest') as \
+                database:
             # Build the database_path structure
             database.create_group('1')
             for property_in, columns in self.experiment.property_groups.items():
@@ -102,7 +97,7 @@ def fill_database(self, counter=0):
                     skip_header = 1  # turn off the header skip
                     counter += len(batch_data)  # Update counter
 
-    def read_configurations(self, number_of_configurations, file_object, skip=False):
+    def read_configurations(self, number_of_configurations: int, file_object: TextIO, skip: bool = False):
         """
         Read in a number of configurations from a file file
 
@@ -110,8 +105,10 @@ def read_configurations(self, number_of_configurations, file_object, skip=False)
         ----------
         number_of_configurations : int
                 Number of configurations to be read in.
-        file_object : experiment
+        file_object : TextIO
                 File object to be read from.
+        skip : bool
+                If true, skip the header lines before reading.
 
         Returns
         -------
@@ -131,7 +128,7 @@ def read_configurations(self, number_of_configurations, file_object, skip=False)
 
         return np.array(configurations_data)
 
-    def process_configurations(self, data, database, counter):
+    def process_configurations(self, data: np.array, database: object, counter: int):
         """
         Process the available tensor_values
 
@@ -172,8 +169,6 @@ def _build_architecture(property_groups: dict, number_of_atoms: int,
 
         Parameters
         ----------
-        species_summary : dict
-                Species summary passed to the experiment class
         property_groups : dict
                 Property information passed to the experiment class
         number_of_atoms : int
@@ -189,4 +184,4 @@ def _build_architecture(property_groups: dict, number_of_atoms: int,
 
     @abc.abstractmethod
     def _get_line_length(self):
-        pass
\ No newline at end of file
+        pass
diff --git a/mdsuite/file_io/lammps_flux_files.py b/mdsuite/file_io/lammps_flux_files.py
index dcef9ca5..39619edb 100644
--- a/mdsuite/file_io/lammps_flux_files.py
+++ b/mdsuite/file_io/lammps_flux_files.py
@@ -6,20 +6,16 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Module for reading lammps trajectory files
 
 Summary
 -------
 """
-
 import numpy as np
-
 from mdsuite.file_io.flux_files import FluxFile
-# from .file_io_dict import lammps_flux
 from mdsuite.utils.meta_functions import optimize_batch_size, join_path
+import copy
 
 var_names = {
     "Temperature": ["temp"],
@@ -52,6 +48,7 @@ def __init__(self, obj, header_lines=9, file_path=None, sort: bool = False):
 
         super().__init__(obj, header_lines, file_path, sort=sort)  # fill the experiment class
         self.experiment.flux = True
+        self.time = None
 
     def _get_line_length(self):
         """
@@ -81,10 +78,10 @@ def process_trajectory_file(self, update_class=True, rename_cols=None):
                 Will map some observable to keys found in the dump file.
         update_class : bool
                 Boolean decision on whether or not to update the class. If yes, the full saved class instance will be
-                updated with new information. This is necessary on the first run of tensor_values addition to the database_path. After
-                this point, when new tensor_values is added, this is no longer required as other methods will take care of
-                updating the properties that change with new tensor_values. In fact, it will set the number of configurations to
-                only the new tensor_values, which will be wrong.
+                updated with new information. This is necessary on the first run of tensor_values addition to the
+                database_path. After this point, when new tensor_values is added, this is no longer required as
+                other methods will take care of updating the properties that change with new tensor_values. In fact,
+                it will set the number of configurations to only the new tensor_values, which will be wrong.
         """
 
         # user custom names for variables.
@@ -109,8 +106,7 @@ def process_trajectory_file(self, update_class=True, rename_cols=None):
 
         # Find properties available for analysis
         column_dict_properties = self._get_column_properties(header_line)
-        self.experiment.property_groups = self._extract_properties(var_names, column_dict_properties)
-
+        self.experiment.property_groups = self._extract_properties(copy.deepcopy(var_names), column_dict_properties)
 
         batch_size = optimize_batch_size(self.file_path, number_of_configurations)
 
diff --git a/mdsuite/file_io/lammps_trajectory_files.py b/mdsuite/file_io/lammps_trajectory_files.py
index ad7b8108..deefbeae 100644
--- a/mdsuite/file_io/lammps_trajectory_files.py
+++ b/mdsuite/file_io/lammps_trajectory_files.py
@@ -6,22 +6,19 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Module for reading lammps trajectory files
 
 Summary
 -------
 """
-
 import sys
-
 from mdsuite.file_io.trajectory_files import TrajectoryFile
-from mdsuite.utils.exceptions import *
+from mdsuite.utils.exceptions import NoElementInDump
 from mdsuite.utils.meta_functions import get_dimensionality
 from mdsuite.utils.meta_functions import line_counter
 from mdsuite.utils.meta_functions import optimize_batch_size
+import copy
 
 var_names = {
     "Positions": ['x', 'y', 'z'],
@@ -50,10 +47,8 @@ class LAMMPSTrajectoryFile(TrajectoryFile):
     ----------
     obj : object
             Experiment class instance to add to
-
     header_lines : int
             Number of header lines in the file format (lammps = 9)
-
     file_path : str
             Path to the trajectory file.
     """
@@ -156,7 +151,7 @@ def _get_species_information(self, number_of_atoms: int):
 
         column_dict_properties = self._get_column_properties(header[8], skip_words=2)  # get properties
 
-        property_groups = self._extract_properties(var_names, column_dict_properties)
+        property_groups = self._extract_properties(copy.deepcopy(var_names), column_dict_properties)
 
         box = [(float(header[5][1]) - float(header[5][0])),
                (float(header[6][1]) - float(header[6][0])),
@@ -191,10 +186,10 @@ def process_trajectory_file(self, update_class: bool = True, rename_cols: dict =
                 Will map some observable to keys found in the dump file.
         update_class : bool
                 Boolean decision on whether or not to update the class. If yes, the full saved class instance will be
-                updated with new information. This is necessary on the first run of tensor_values addition to the database_path. After
-                this point, when new tensor_values is added, this is no longer required as other methods will take care of
-                updating the properties that change with new tensor_values. In fact, it will set the number of configurations to
-                only the new tensor_values, which will be wrong.
+                updated with new information. This is necessary on the first run of tensor_values addition to the
+                database_path. After this point, when new tensor_values is added, this is no longer required as other
+                methods will take care of updating the properties that change with new tensor_values. In fact,
+                it will set the number of configurations to only the new tensor_values, which will be wrong.
 
         Returns
         -------
@@ -210,7 +205,6 @@ def process_trajectory_file(self, update_class: bool = True, rename_cols: dict =
         sample_rate = self._get_time_information(number_of_atoms)  # get the sample rate
         batch_size = optimize_batch_size(self.file_path, number_of_configurations)  # get the batch size
         species_summary, box, property_groups, line_length = self._get_species_information(number_of_atoms)
-
         if update_class:
             self.experiment.batch_size = batch_size
             self.experiment.dimensions = get_dimensionality(box)
@@ -226,4 +220,5 @@ def process_trajectory_file(self, update_class: bool = True, rename_cols: dict =
             self.experiment.batch_size = batch_size
             self.experiment.number_of_configurations += number_of_configurations
 
+        self.f_object.close()
         return self._build_architecture(species_summary, property_groups, number_of_configurations), line_length
diff --git a/mdsuite/file_io/trajectory_files.py b/mdsuite/file_io/trajectory_files.py
index dcfe8f82..ee55cae5 100644
--- a/mdsuite/file_io/trajectory_files.py
+++ b/mdsuite/file_io/trajectory_files.py
@@ -6,15 +6,12 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Parent class for file processing
 
 Summary
 -------
 """
-
 import abc
 from typing import TextIO
 import numpy as np
@@ -125,7 +122,8 @@ def build_file_structure(self, batch_size: int = None):
             if self.sort:
                 positions = np.array(self.experiment.species[item]['indices'])
             else:
-                positions = np.array([np.array(self.experiment.species[item]['indices']) + i * self.experiment.number_of_atoms -
+                positions = np.array([np.array(self.experiment.species[item]['indices']) + i *
+                                      self.experiment.number_of_atoms -
                                       self.header_lines for i in range(batch_size)]).flatten()
             length = len(self.experiment.species[item]['indices'])
             for observable in self.experiment.property_groups:
diff --git a/mdsuite/file_io/xtc_reader.py b/mdsuite/file_io/xtc_reader.py
index a1a65661..9e2011fe 100644
--- a/mdsuite/file_io/xtc_reader.py
+++ b/mdsuite/file_io/xtc_reader.py
@@ -6,9 +6,6 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python module to read xtc files for mdsuite
 """
-
diff --git a/mdsuite/graph_modules/__init__.py b/mdsuite/graph_modules/__init__.py
index db921f94..a0f9e1fc 100644
--- a/mdsuite/graph_modules/__init__.py
+++ b/mdsuite/graph_modules/__init__.py
@@ -6,8 +6,6 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Module for graph-based methods.
-"""
\ No newline at end of file
+"""
diff --git a/mdsuite/graph_modules/adjacency_matrix.py b/mdsuite/graph_modules/adjacency_matrix.py
index df085b97..1368186c 100644
--- a/mdsuite/graph_modules/adjacency_matrix.py
+++ b/mdsuite/graph_modules/adjacency_matrix.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Build the colour adjaceny matrix of a system.
 """
 
@@ -23,4 +21,3 @@ def __init__(self):
         Constructor for the adjacency matrix module.
         """
         pass
-
diff --git a/mdsuite/graph_modules/molecular_graph.py b/mdsuite/graph_modules/molecular_graph.py
index f38cd650..015dc5df 100644
--- a/mdsuite/graph_modules/molecular_graph.py
+++ b/mdsuite/graph_modules/molecular_graph.py
@@ -6,21 +6,18 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Module for the molecular graph module.
 """
-
 import os
 import numpy as np
 from pysmiles import read_smiles
 from mdsuite.utils.meta_functions import join_path
 from mdsuite.database.simulation_database import Database
 from tqdm import tqdm
-
 import tensorflow as tf
 
+
 class MolecularGraph:
     """
     Class for building and studying molecular graphs.
@@ -183,5 +180,4 @@ def reduce_graphs(adjacency_matrix: tf.Tensor):
         for item in del_list:
             molecules.pop(item)
 
-
         return molecules
diff --git a/mdsuite/memory_management/__init__.py b/mdsuite/memory_management/__init__.py
index 3dbe3e0d..a2de03f9 100644
--- a/mdsuite/memory_management/__init__.py
+++ b/mdsuite/memory_management/__init__.py
@@ -6,8 +6,6 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Constructor for the memory management directory
-"""
\ No newline at end of file
+"""
diff --git a/mdsuite/memory_management/memory_manager.py b/mdsuite/memory_management/memory_manager.py
index 181d2fe3..ff98640a 100644
--- a/mdsuite/memory_management/memory_manager.py
+++ b/mdsuite/memory_management/memory_manager.py
@@ -6,17 +6,14 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Class for memory management in MDSuite operations.
 """
-
 import logging
-
 from mdsuite.utils.meta_functions import get_machine_properties
 from mdsuite.database.simulation_database import Database
-from mdsuite.utils.scale_functions import *
+from mdsuite.utils.scale_functions import linear_scale_function, \
+    linearithmic_scale_function, polynomial_scale_function, quadratic_scale_function
 import numpy as np
 import sys
 from typing import Tuple
@@ -201,8 +198,7 @@ def _get_optimal_batch_size(self, naive_size):
         batch_size : int
                 An optimized batch size
         """
-        db_io_time = self.database.get_load_time()
-
+        # db_io_time = self.database.get_load_time()
         return naive_size
 
     def _compute_atomwise_minibatch(self, data_range: int):
@@ -224,7 +220,7 @@ def _compute_atomwise_minibatch(self, data_range: int):
         # This does not seem to be used anywhere?
         # per_configuration_memory = self.scale_function(per_configuration_memory, **self.scale_function_parameters)
         per_atom_memory = self.scale_function(per_atom_memory, **self.scale_function_parameters)
-        fractions = [1/2, 1/4, 1/8, 1/20, 1/100, 1/200, 0]
+        fractions = [1 / 2, 1 / 4, 1 / 8, 1 / 20, 1 / 100, 1 / 200, 0]
 
         for fraction in fractions:  # iterate over possible mini batch fractions to fit memory
             if fraction == 0:
diff --git a/mdsuite/plot_style/__init__.py b/mdsuite/plot_style/__init__.py
index 1bf2e3f0..f9582714 100644
--- a/mdsuite/plot_style/__init__.py
+++ b/mdsuite/plot_style/__init__.py
@@ -6,8 +6,6 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Constructor for the plot_style directory
-"""
\ No newline at end of file
+"""
diff --git a/mdsuite/plot_style/plot_style.py b/mdsuite/plot_style/plot_style.py
index 63cea94b..8c576ebf 100644
--- a/mdsuite/plot_style/plot_style.py
+++ b/mdsuite/plot_style/plot_style.py
@@ -11,7 +11,14 @@
 import matplotlib.pyplot as plt
 from matplotlib import checkdep_usetex
 
+
 def style():
+    """
+    Define the plot style.
+    Returns
+    -------
+    Sets a style.
+    """
     font_size = 36
     params = {
         'font.family': 'STIXGeneral',
@@ -58,20 +65,32 @@ def style():
         'axes.spines.right': False
         # 'figure.constrained_layout.use': True
     }
-    
-    usetex = checkdep_usetex(True) # check if latex is available
-    if not usetex: # if not, just set it to False, and do not use latex to print figures.
+
+    usetex = checkdep_usetex(True)  # check if latex is available
+    if not usetex:  # if not, just set it to False, and do not use latex to print figures.
         params['text.usetex'] = False
 
     return params
 
 
 def apply_style():
+    """
+    Apply the style to the kernel.
+    Returns
+    -------
+    Sets plotting styles for the kernel.
+    """
     params = style()
     plt.style.use(params)
 
 
 def get_markers():
+    """
+    Prepare a list of markers for use in the styling.
+    Returns
+    -------
+    Returns a list of markers.
+    """
     # list of markers
     return [".", "o", "v", "^", "<", ">", "1", "2", "3", "4", "8", "s", "p", "P", "*", "h", "H", "+", "x", "X", "D",
             "d", "|", "_", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
diff --git a/mdsuite/project.py b/mdsuite/project.py
index fa1bc9b5..0b588212 100644
--- a/mdsuite/project.py
+++ b/mdsuite/project.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Module for the Project class
 
 Summary
@@ -17,14 +15,11 @@
 mdsuite program. Within the project class include all of the method required to add a new experiment and
 compare the results of the analysis on that experiment.
 """
-
 import logging
-
 import os
 import pickle
 from datetime import datetime
 from pathlib import Path
-
 from typing import Union
 import shutil
 from mdsuite.experiment.experiment import Experiment
@@ -50,8 +45,8 @@ class Project:
             A short description of the project
 
     storage_path : str
-            Where to store the tensor_values and databases. This may not simply be the current directory if the databases are
-            expected to be quite large.
+            Where to store the tensor_values and databases. This may not simply be the current direcotry if the
+            databases are expected to be quite large.
 
     experiments : dict
             A dict of class objects. Class objects are instances of the experiment class for different
@@ -71,21 +66,20 @@ def __init__(self, name: str = "My_Project", storage_path: str = "./"):
         name : str
                 The name of the project.
         storage_path : str
-                Where to store the tensor_values and databases. This should be a place with sufficient storage space for the
-                full analysis.
+                Where to store the tensor_values and databases. This should be a place with sufficient storage space
+                for the full analysis.
         """
+        self.name = f"{name}_MDSuite_Project"
+        self.description = None
+        self.storage_path = storage_path
 
-        self.name = f"{name}_MDSuite_Project"  # the name of the project
-        self.description = None  # A short description of the project
-        self.storage_path = storage_path  # Tell me where to store this tensor_values
-
-        self.experiments = {}  # type: dict[str, Experiment]  #experiments added to this project
+        self.experiments = {}
 
         # Check for project directory, if none exist, create a new one
         test_dir = Path(f"{self.storage_path}/{self.name}")
         if test_dir.exists():
             print("Loading the class state")
-            self._load_class()  # load the class state
+            self._load_class()
 
             # load the class state for each experiment attached to the Project.
             for experiment in self.experiments.values():
@@ -94,8 +88,8 @@ def __init__(self, name: str = "My_Project", storage_path: str = "./"):
             # List the experiments available to the user
             self.__str__()
         else:
-            os.mkdir(f"{self.storage_path}/{self.name}")  # create a new directory for the project
-            self._save_class()  # Save the initial class state
+            os.mkdir(f"{self.storage_path}/{self.name}")
+            self._save_class()
 
     def __str__(self):
         return self.list_experiments()
@@ -167,7 +161,7 @@ def add_experiment(self, experiment: Union[str, dict] = None, timestep: float =
         ----------
         cluster_mode : bool
                 If true, cluster mode is parsed to the experiment class.
-        experiment_name : str
+        experiment : str
                 Name to use for the experiment class.
         timestep : float
                 Timestep used during the simulation.
@@ -275,7 +269,7 @@ def get_results(self, key_to_find):
                     result = float(result)
 
             if isinstance(result, list):
-                result = [float(res) for res in result] # convert results to floats
+                result = [float(res) for res in result]  # convert results to floats
             results[experiment_name] = result
 
         return results
@@ -326,7 +320,7 @@ def get_attribute(self, attribute):
 
         results = {}
         for experiment_name, experiment_class in self.experiments.items():
-            value_attr = experiment_class.__getattribute__(attribute)  # this is a dict with the results from the yaml file
+            value_attr = experiment_class.__getattribute__(attribute)
             results[experiment_name] = value_attr
 
         return results
diff --git a/mdsuite/project_methods/__init__.py b/mdsuite/project_methods/__init__.py
index 5a25718d..45b15aa7 100644
--- a/mdsuite/project_methods/__init__.py
+++ b/mdsuite/project_methods/__init__.py
@@ -6,4 +6,4 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
\ No newline at end of file
+"""
diff --git a/mdsuite/project_methods/compare_properties.py b/mdsuite/project_methods/compare_properties.py
index eeed973b..16dbd3c3 100644
--- a/mdsuite/project_methods/compare_properties.py
+++ b/mdsuite/project_methods/compare_properties.py
@@ -6,15 +6,14 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Methods for the project class to use
 
 Summary
 -------
 """
 
+
 class CompareProperties:
     """
     Methods used by the project class to compare physical properties of the experiments
@@ -29,4 +28,4 @@ def __init__(self):
         self.y_data_property = None
         self.y_data = None
 
-        raise NotImplementedError
\ No newline at end of file
+        raise NotImplementedError
diff --git a/mdsuite/transformations/__init__.py b/mdsuite/transformations/__init__.py
index 5a25718d..45b15aa7 100644
--- a/mdsuite/transformations/__init__.py
+++ b/mdsuite/transformations/__init__.py
@@ -6,4 +6,4 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
\ No newline at end of file
+"""
diff --git a/mdsuite/transformations/integrated_heat_current.py b/mdsuite/transformations/integrated_heat_current.py
index 25b337c3..f6035244 100644
--- a/mdsuite/transformations/integrated_heat_current.py
+++ b/mdsuite/transformations/integrated_heat_current.py
@@ -6,16 +6,12 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python module to calculate the integrated heat current in a experiment.
 """
-
 import numpy as np
 import tensorflow as tf
 from tqdm import tqdm
-
 from mdsuite.transformations.transformations import Transformations
 from mdsuite.utils.meta_functions import join_path
 
diff --git a/mdsuite/transformations/ionic_current.py b/mdsuite/transformations/ionic_current.py
index e4dc7a08..7b14b294 100644
--- a/mdsuite/transformations/ionic_current.py
+++ b/mdsuite/transformations/ionic_current.py
@@ -6,16 +6,12 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python module to calculate the ionic current in a experiment.
 """
-
 import numpy as np
 from tqdm import tqdm
 import tensorflow as tf
-
 from mdsuite.transformations.transformations import Transformations
 from mdsuite.utils.meta_functions import join_path
 
diff --git a/mdsuite/transformations/kinaci_integrated_heat_current.py b/mdsuite/transformations/kinaci_integrated_heat_current.py
index 62413fe8..8006b037 100644
--- a/mdsuite/transformations/kinaci_integrated_heat_current.py
+++ b/mdsuite/transformations/kinaci_integrated_heat_current.py
@@ -6,13 +6,9 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python module to calculate the Kinaci integrated heat current in a experiment.
 """
-import time
-
 import numpy as np
 import tensorflow as tf
 from tqdm import tqdm
diff --git a/mdsuite/transformations/map_molecules.py b/mdsuite/transformations/map_molecules.py
index a23b43fb..c9a85e22 100644
--- a/mdsuite/transformations/map_molecules.py
+++ b/mdsuite/transformations/map_molecules.py
@@ -6,17 +6,13 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Module for mapping atoms to molecules
 """
-
 import numpy as np
 import tensorflow as tf
 from tqdm import tqdm
 from typing import List
-
 from mdsuite.graph_modules.molecular_graph import MolecularGraph
 from mdsuite.transformations.transformations import Transformations
 from mdsuite.utils.meta_functions import join_path
diff --git a/mdsuite/transformations/momentum_flux.py b/mdsuite/transformations/momentum_flux.py
index 5fea19d0..7c3ebaa2 100644
--- a/mdsuite/transformations/momentum_flux.py
+++ b/mdsuite/transformations/momentum_flux.py
@@ -6,16 +6,12 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python module to calculate the momentum flux in an experiment.
 """
-
 import numpy as np
 import tensorflow as tf
 from tqdm import tqdm
-
 from mdsuite.transformations.transformations import Transformations
 from mdsuite.utils.meta_functions import join_path
 
@@ -120,8 +116,7 @@ def _compute_momentum_flux(self):
             data = self._transformation(x)
             self._save_coordinates(data, idx*self.batch_size, current_batch_size, data_structure)
 
-
-def run_transformation(self):
+    def run_transformation(self):
         """
         Run the ionic current transformation
         Returns
diff --git a/mdsuite/transformations/scale_coordinates.py b/mdsuite/transformations/scale_coordinates.py
index 0cb2c541..20c5f933 100644
--- a/mdsuite/transformations/scale_coordinates.py
+++ b/mdsuite/transformations/scale_coordinates.py
@@ -6,14 +6,11 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Scale a set of coordinates by a number or vector. This is most often used when a set of cordinates is printed in
 terms of a fraction of the box size and you need them to be extended. For unwrapping via printed indices, see the
 unwrap_via_indices transformation.
 """
-
 from mdsuite.transformations.transformations import Transformations
 from mdsuite.utils.meta_functions import join_path
 import sys
@@ -47,8 +44,6 @@ def __init__(self, experiment: object, species: list = None):
                 Experiment this transformation is attached to.
         species : list
                 Species on which this transformation should be applied.
-        box : list
-                Box vectors to multiply the indices by
         """
         super().__init__(experiment)
         self.species = species
diff --git a/mdsuite/transformations/thermal_flux.py b/mdsuite/transformations/thermal_flux.py
index 16a4603c..ed4918f2 100644
--- a/mdsuite/transformations/thermal_flux.py
+++ b/mdsuite/transformations/thermal_flux.py
@@ -6,16 +6,12 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python module to calculate the ionic current in a experiment.
 """
-
 import numpy as np
 import tensorflow as tf
 from tqdm import tqdm
-
 from mdsuite.transformations.transformations import Transformations
 from mdsuite.utils.meta_functions import join_path
 
@@ -88,14 +84,14 @@ def _transformation(self, data: tf.Tensor):
             ke_path = str.encode(join_path(species, 'KE'))
             pe_path = str.encode(join_path(species, 'PE'))
             phi_x = np.multiply(data[stress_path][:, :, 0], data[velocity_path][:, :, 0]) + \
-                    np.multiply(data[stress_path][:, :, 3], data[velocity_path][:, :, 1]) + \
-                    np.multiply(data[stress_path][:, :, 4], data[velocity_path][:, :, 2])
+                np.multiply(data[stress_path][:, :, 3], data[velocity_path][:, :, 1]) + \
+                np.multiply(data[stress_path][:, :, 4], data[velocity_path][:, :, 2])
             phi_y = np.multiply(data[stress_path][:, :, 3], data[velocity_path][:, :, 0]) + \
-                    np.multiply(data[stress_path][:, :, 1], data[velocity_path][:, :, 1]) + \
-                    np.multiply(data[stress_path][:, :, 5], data[velocity_path][:, :, 2])
+                np.multiply(data[stress_path][:, :, 1], data[velocity_path][:, :, 1]) + \
+                np.multiply(data[stress_path][:, :, 5], data[velocity_path][:, :, 2])
             phi_z = np.multiply(data[stress_path][:, :, 4], data[velocity_path][:, :, 0]) + \
-                    np.multiply(data[stress_path][:, :, 5], data[velocity_path][:, :, 1]) + \
-                    np.multiply(data[stress_path][:, :, 2], data[velocity_path][:, :, 2])
+                np.multiply(data[stress_path][:, :, 5], data[velocity_path][:, :, 1]) + \
+                np.multiply(data[stress_path][:, :, 2], data[velocity_path][:, :, 2])
 
             phi = np.dstack([phi_x, phi_y, phi_z])
 
@@ -165,7 +161,7 @@ def _compute_thermal_flux(self):
         for idx, x in tqdm(enumerate(data_set), ncols=70, desc="Thermal Flux", total=self.n_batches):
             current_batch_size = int(x[str.encode('data_size')])
             data = self._transformation(x)
-            self._save_coordinates(data, idx*self.batch_size, current_batch_size, data_structure)
+            self._save_coordinates(data, idx * self.batch_size, current_batch_size, data_structure)
 
     def run_transformation(self):
         """
diff --git a/mdsuite/transformations/transformation_dict.py b/mdsuite/transformations/transformation_dict.py
index 465af1b0..7bd87d6d 100644
--- a/mdsuite/transformations/transformation_dict.py
+++ b/mdsuite/transformations/transformation_dict.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 A dictionary of possible transformations in th MDSuite code.
 """
 
@@ -34,4 +32,4 @@
     'ThermalFlux': ThermalFlux,
     'MomentumFlux': MomentumFlux,
     'KinaciIntegratedHeatCurrent': KinaciIntegratedHeatCurrent
-}
\ No newline at end of file
+}
diff --git a/mdsuite/transformations/transformations.py b/mdsuite/transformations/transformations.py
index c8e3629a..16cc2442 100644
--- a/mdsuite/transformations/transformations.py
+++ b/mdsuite/transformations/transformations.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Parent class for MDSuite transformations
 """
 import time
@@ -70,6 +68,7 @@ def __init__(self, experiment: object):
         self.remainder: int
 
         self.dependency = None
+        self.scale_function = None
         self.offset = 0
 
         self.data_manager: DataManager
@@ -94,10 +93,7 @@ def _run_dataset_check(self, path: str):
     def _run_dependency_check(self):
         """
         Check that dependencies are fulfilled.
-        Parameters
-        ----------
-        path_list : list
-                A list of paths on which to check dependencies.
+
         Returns
         -------
         Calls a resolve method if dependencies are not met.
@@ -216,7 +212,6 @@ def _remainder_to_binary(self):
         binary_map : int
                 If remainder > 0, return 1, else,  return 0
         """
-        
         return int(self.remainder > 0)
 
     def _save_coordinates(self, data: Union[tf.Tensor, np.array], index: int, batch_size: int, data_structure: dict,
diff --git a/mdsuite/transformations/translational_dipole_moment.py b/mdsuite/transformations/translational_dipole_moment.py
index c02b66ee..019d0153 100644
--- a/mdsuite/transformations/translational_dipole_moment.py
+++ b/mdsuite/transformations/translational_dipole_moment.py
@@ -6,16 +6,12 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python module to calculate the translational dipole in a experiment.
 """
-
 import numpy as np
 from tqdm import tqdm
 import tensorflow as tf
-
 from mdsuite.transformations.transformations import Transformations
 from mdsuite.utils.meta_functions import join_path
 
diff --git a/mdsuite/transformations/unwrap_coordinates.py b/mdsuite/transformations/unwrap_coordinates.py
index eeec8560..2b1daff0 100644
--- a/mdsuite/transformations/unwrap_coordinates.py
+++ b/mdsuite/transformations/unwrap_coordinates.py
@@ -6,9 +6,7 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Atomic transformation to unwrap the simulation coordinates.
 
 Summary
@@ -18,11 +16,9 @@
 positions jumps of more than a half of the box are counted as a crossing of the boundary, to allow the particles to
 propagate on into space.
 """
-
 import numpy as np
 from tqdm import tqdm
 import tensorflow as tf
-
 from mdsuite.transformations.transformations import Transformations
 from mdsuite.utils.meta_functions import join_path
 
@@ -85,7 +81,8 @@ def _prepare_database_entry(self, species: str):
 
         return data_structure
 
-    def _calculate_difference_tensor(self, data: tf.Tensor):
+    @staticmethod
+    def _calculate_difference_tensor(data: tf.Tensor):
         """
         Calculate the amount particles move in each time step
 
diff --git a/mdsuite/transformations/unwrap_via_indices.py b/mdsuite/transformations/unwrap_via_indices.py
index 332c40fc..4030deac 100644
--- a/mdsuite/transformations/unwrap_via_indices.py
+++ b/mdsuite/transformations/unwrap_via_indices.py
@@ -6,20 +6,13 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Unwrap a set of coordinates based on dumped indices.
 """
-
 from mdsuite.transformations.transformations import Transformations
-from mdsuite.database.data_manager import DataManager
-from mdsuite.memory_management.memory_manager import MemoryManager
 from mdsuite.utils.meta_functions import join_path
-
 import sys
 import tensorflow as tf
-import time
 import numpy as np
 
 
@@ -33,8 +26,6 @@ class UnwrapViaIndices(Transformations):
             Experiment this transformation is attached to.
     species : list
             Species on which this transformation should be applied.
-    box : list
-            Box vectors to multiply the indices by
     scale_function : dict
             A dictionary referencing the memory/time scaling function of the transformation.
     """
@@ -49,8 +40,6 @@ def __init__(self, experiment: object, species: list = None):
                 Experiment this transformation is attached to.
         species : list
                 Species on which this transformation should be applied.
-        box : list
-                Box vectors to multiply the indices by
         """
         super().__init__(experiment)
         self.scale_function = {'linear': {'scale_factor': 2}}
diff --git a/mdsuite/transformations/wrap_coordinates.py b/mdsuite/transformations/wrap_coordinates.py
index 94cc974d..23d68d0b 100644
--- a/mdsuite/transformations/wrap_coordinates.py
+++ b/mdsuite/transformations/wrap_coordinates.py
@@ -6,22 +6,17 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Atomic transformation to wrap the simulation coordinates.
 
 Summary
 -------
 Sometimes, particularly in the study of molecules, it is necessary to wrap positions. This module will do that for you.
 """
-
 import numpy as np
 import os
 import tensorflow as tf
-
 from mdsuite.transformations.transformations import Transformations
-from mdsuite.database.simulation_database import Database
 from mdsuite.utils.meta_functions import join_path
 
 
@@ -55,6 +50,8 @@ class CoordinateWrapper(Transformations):
 
     mask : tf.tensor
             Mask to select and transform crossed tensor_values.
+    scale_function : dict
+            A dictionary referencing the memory/time scaling function of the transformation.
     """
 
     def __init__(self, experiment: object, species: list = None, center_box: bool = True):
@@ -69,8 +66,6 @@ def __init__(self, experiment: object, species: list = None, center_box: bool =
                 List of species to perform unwrapping on
         center_box : bool
                 If true, the box coordinates will be centered before the unwrapping occurs
-        scale_function : dict
-            A dictionary referencing the memory/time scaling function of the transformation.
         """
         super().__init__(experiment)
 
diff --git a/mdsuite/utils/__init__.py b/mdsuite/utils/__init__.py
index 8467b3fc..109c33a7 100644
--- a/mdsuite/utils/__init__.py
+++ b/mdsuite/utils/__init__.py
@@ -6,8 +6,6 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python __init__ file for the utils package
-"""
\ No newline at end of file
+"""
diff --git a/mdsuite/utils/constants.py b/mdsuite/utils/constants.py
index 0d64adfe..176f721e 100644
--- a/mdsuite/utils/constants.py
+++ b/mdsuite/utils/constants.py
@@ -15,4 +15,3 @@
 
 Collected by the author of the code.
 """
-
diff --git a/mdsuite/utils/exceptions.py b/mdsuite/utils/exceptions.py
index cababbdd..7bfeb195 100644
--- a/mdsuite/utils/exceptions.py
+++ b/mdsuite/utils/exceptions.py
@@ -52,9 +52,7 @@ class NoGPUInSystem(Exception):
     """
     Thrown during experiment analysis when GPUs are being searched for.
     """
-
-    def __init__(self):
-        Exception.__init__(self, "No GPUs detected, continuing without GPU support")
+    pass
 
 
 class DatasetExists(Exception):
diff --git a/mdsuite/utils/linalg.py b/mdsuite/utils/linalg.py
index 516899a5..7017add6 100644
--- a/mdsuite/utils/linalg.py
+++ b/mdsuite/utils/linalg.py
@@ -12,12 +12,15 @@
 
 
 def unit_vector(vector):
-    """ Returns the unit vector of the vector.  """
+    """
+    Returns the unit vector of the vector.
+    """
     return vector / tf.expand_dims(tf.norm(vector, axis=-1), -1)
 
 
 def angle_between(v1, v2, acos=True):
-    """ Returns the angle in radians between vectors 'v1' and 'v2'::
+    """
+    Returns the angle in radians between vectors 'v1' and 'v2'::
     """
     v1_u = unit_vector(v1)
     v2_u = unit_vector(v2)
@@ -30,7 +33,8 @@ def angle_between(v1, v2, acos=True):
 
 
 def get_angles(r_ij_mat, indices, acos=True):
-    """Compute the cosine angle for the given triples
+    """
+    Compute the cosine angle for the given triples
 
     Using :math theta = acos(r_ij * r_ik / (|r_ij| * |r_ik|))
 
diff --git a/mdsuite/utils/meta_functions.py b/mdsuite/utils/meta_functions.py
index 1c66bcff..bf32e07e 100644
--- a/mdsuite/utils/meta_functions.py
+++ b/mdsuite/utils/meta_functions.py
@@ -6,9 +6,9 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
+Meta Functions
+==============
 Module for the mdsuite meta functions
 
 Summary
@@ -74,11 +74,10 @@ def get_dimensionality(box: list) -> int:
 
     # Check if the x, y, or z entries are empty, i.e. 2 dimensions
     if box[0] == 0 or box[1] == 0 or box[2] == 0:
-        dimensions = 2
-
-    # Check if only one of the entries is non-zero, i.e. 1 dimension.
-    elif box[0] == 0 and box[1] == 0 or box[0] == 0 and box[2] == 0 or box[1] == 0 and box[2] == 0:
-        dimensions = 1
+        if box[0] == 0 and box[1] == 0 or box[0] == 0 and box[2] == 0 or box[1] == 0 and box[2] == 0:
+            dimensions = 1
+        else:
+            dimensions = 2
 
     # Other option is 3 dimensions.
     else:
@@ -108,7 +107,7 @@ def get_machine_properties() -> dict:
     try:
         total_gpu_devices = GPUtil.getGPUs()  # get information on all the gpu's
         for gpu in total_gpu_devices:
-            machine_properties['gpu'][gpu.id]= {}
+            machine_properties['gpu'][gpu.id] = {}
             machine_properties['gpu'][gpu.id]['name'] = gpu.name
             machine_properties['gpu'][gpu.id]['memory'] = gpu.memoryTotal
     except (NoGPUInSystem, ValueError):
@@ -135,10 +134,14 @@ def line_counter(filename: str) -> int:
             Number of lines in the file
     """
 
-    return sum(1 for _ in open(filename, 'rb'))
+    f = open(filename, 'rb')
+    num_lines = sum(1 for _ in f)
+    f.close()
+    return num_lines
 
 
-def optimize_batch_size(filepath: str, number_of_configurations: int) -> int:
+def optimize_batch_size(filepath: str, number_of_configurations: int,
+                        _file_size: int = None, _memory: int = None, test: bool = False) -> int:
     """
     Optimize the size of batches during initial processing
 
@@ -150,21 +153,29 @@ def optimize_batch_size(filepath: str, number_of_configurations: int) -> int:
     filepath : str
             Path to the file be read in. This is not opened during the process, it is simply needed to read the file
             size.
-
     number_of_configurations : int
             Number of configurations in the trajectory.
+    _file_size : int
+            Mock file size to use during tests.
+    _memory : int
+            Mock memory to use during tests.
+    test : bool
+            If true, mock variables are used.
 
     Returns
     -------
     batch size : int
             Number of configurations to load in each batch
     """
+    if test:
+        file_size = _file_size
+        database_memory = _memory
+    else:
+        computer_statistics = get_machine_properties()  # Get computer statistics
+        file_size = os.path.getsize(filepath)  # Get the size of the file
+        database_memory = 0.1 * computer_statistics['memory']  # We take 10% of the available memory
 
-    computer_statistics = get_machine_properties()  # Get computer statistics
-
-    file_size = os.path.getsize(filepath)  # Get the size of the file
     memory_per_configuration = file_size / number_of_configurations  # get the memory per configuration
-    database_memory = 0.1 * computer_statistics['memory']  # We take 50% of the available memory
     initial_batch_number = int(database_memory / (5 * memory_per_configuration))  # trivial batch allocation
 
     # The database_path generation expands memory ~5x
@@ -178,8 +189,8 @@ def linear_fitting_function(x: np.array, a: float, b: float) -> np.array:
     """
     Linear function for line fitting
 
-    In many cases, namely those involving an Einstein relation, a linear curve must be fit to some tensor_values. This function
-    is called by the scipy curve_fit module as the model to fit to.
+    In many cases, namely those involving an Einstein relation, a linear curve must be fit to some tensor_values.
+    This function is called by the scipy curve_fit module as the model to fit to.
 
     Parameters
     ----------
@@ -203,7 +214,8 @@ def simple_file_read(filename: str) -> list:
     Trivially read a file and load it into an array
 
     There are many occasions when a file simply must be read and dumped into a file. In these cases, we call this method
-    and dump tensor_values into an array. This is NOT memory safe, and should not be used for processing large trajectory files.
+    and dump tensor_values into an array. This is NOT memory safe, and should not be used for processing large
+    trajectory files.
 
     Parameters
     ----------
@@ -236,6 +248,11 @@ def timeit(f: Callable) -> Callable:
     Returns
     -------
     wrap : Callable
+            Method wrapper for timing the method.
+
+    Notes
+    -----
+    There is currently no test for this wrapper as there is no simple way of checking timing on a remote server.
     """
 
     @wraps(f)
@@ -253,7 +270,7 @@ def wrap(*args, **kw):
     return wrap
 
 
-def apply_savgol_filter(data: list, order: int = 2, window_length: int = 17) -> list:
+def apply_savgol_filter(data: list, order: int = 2, window_length: int = 17) -> np.ndarray:
     """
     Apply a savgol filter for function smoothing
 
@@ -262,6 +279,8 @@ def apply_savgol_filter(data: list, order: int = 2, window_length: int = 17) ->
 
     Parameters
     ----------
+    window_length : int
+            Window length to use in the filtering.
     data : list
             Array of tensor_values to be analysed.
     order : int
@@ -269,8 +288,13 @@ def apply_savgol_filter(data: list, order: int = 2, window_length: int = 17) ->
 
     Returns
     -------
-    filtered tensor_values : list
+    filtered tensor_values : np.ndarray
             Returns the filtered tensor_values directly from the scipy SavGol filter.
+
+    Notes
+    -----
+    There are no tests for this method as a test would simply be testing the scipy implementation which they have
+    done.
     """
 
     return savgol_filter(data, window_length, order)
@@ -362,9 +386,10 @@ def round_down(a: int, b: int) -> int:
     """
 
     remainder = 1  # initialize a remainder
+    a += 1
     while remainder != 0:
-        remainder = b % a
         a -= 1
+        remainder = b % a
 
     return a
 
@@ -383,13 +408,6 @@ def split_array(data: np.array, condition: np.array) -> list:
     -------
     split_array : list
             A list of split up arrays.
-
-    Examples
-    --------
-    >>> a = np.array([1, 2, 3, 10, 20, 30])
-    >>> split_array(a, a < 10)
-    >>> [np.array([1, 2, 3]), np.array([10, 20, 30])]
-
     """
 
     initial_split = [data[condition], data[~condition]]  # attempt to split the array
@@ -416,10 +434,10 @@ def find_item(obj, key):
     item: dict value.
         returns the value for the given key. Return type may change depending on the requested key
     """
-    if key in obj: return obj[key]
+    if key in obj:
+        return obj[key]
     for k, v in obj.items():
         if isinstance(v, dict):
             item = find_item(v, key)
             if item is not None:
                 return item
-
diff --git a/mdsuite/utils/neighbour_list.py b/mdsuite/utils/neighbour_list.py
index 2098a2cd..63d216e1 100644
--- a/mdsuite/utils/neighbour_list.py
+++ b/mdsuite/utils/neighbour_list.py
@@ -137,4 +137,4 @@ def get_triplets(full_r_ij: tf.Tensor, r_cut: float, n_atoms: int, n_batches=200
         k = tf.where(k >= n_atoms, k - n_atoms, k)
         triples.append(tf.stack([t, i, j, k], axis=1))
 
-    return tf.concat(triples, axis=0)
\ No newline at end of file
+    return tf.concat(triples, axis=0)
diff --git a/mdsuite/utils/report_computer_characteristics.py b/mdsuite/utils/report_computer_characteristics.py
index a78394d1..413d7367 100644
--- a/mdsuite/utils/report_computer_characteristics.py
+++ b/mdsuite/utils/report_computer_characteristics.py
@@ -7,19 +7,19 @@
 
 Copyright Contributors to the MDSuite Project.
 """
-
 from os import path
 from pathlib import Path
-
 import GPUtil
 import scooby
 import re
+from mdsuite.utils.exceptions import NoGPUInSystem
 
 
 class Report(scooby.Report):
-    """A class for custom scooby.Report."""
+    """
+    A class for custom scooby.Report."""
 
-    def __init__(self, additional=None, ncol=3, text_width=80, sort=False,
+    def __init__(self, additional: list = None, ncol: int = 3, text_width: int = 80, sort: bool = False,
                  gpu=True):
         """Generate a :class:`scooby.Report` instance.
 
@@ -27,17 +27,13 @@ def __init__(self, additional=None, ncol=3, text_width=80, sort=False,
         ----------
         additional : list(ModuleType), list(str)
             List of packages or package names to add to output information.
-
         ncol : int, optional
             Number of package-columns in html table; only has effect if
             ``mode='HTML'`` or ``mode='html'``. Defaults to 3.
-
         text_width : int, optional
             The text width for non-HTML display modes
-
         sort : bool, optional
             Alphabetically sort the packages
-
         gpu : bool
             Gather information about the GPU. Defaults to ``True`` but if
             experiencing renderinng issues, pass ``False`` to safely generate
@@ -77,7 +73,7 @@ def __init__(self, additional=None, ncol=3, text_width=80, sort=False,
                 list_gpus.append(('GPU ID', gpu_id))
                 list_gpus.append(('GPU Name', gpu_name))
                 list_gpus.append(('GPU Total Memory', gpu_total_memory))
-        except:
+        except NoGPUInSystem:
             list_gpus = [('GPU NAME', 'No Info Available')]
 
         scooby.Report.__init__(self, additional=additional, core=requirements,
diff --git a/mdsuite/utils/scale_functions.py b/mdsuite/utils/scale_functions.py
index 5dbeacb5..316c4b73 100644
--- a/mdsuite/utils/scale_functions.py
+++ b/mdsuite/utils/scale_functions.py
@@ -6,12 +6,9 @@
 SPDX-License-Identifier: EPL-2.0
 
 Copyright Contributors to the MDSuite Project.
-"""
 
-"""
 Python module for complexity/memory scaling functions
 """
-
 import numpy as np
 
 
diff --git a/setup.py b/setup.py
index 84371d1f..74c810e1 100644
--- a/setup.py
+++ b/setup.py
@@ -30,7 +30,7 @@ def run(self):
                     if not line.startswith('#')]
 
 
-with open("README.md", "r") as fh:
+with open("README.rst", "r") as fh:
     long_description = fh.read()
 
 setuptools.setup(
diff --git a/tutorials/.DS_Store b/tutorials/.DS_Store
deleted file mode 100644
index c3c78cf2..00000000
Binary files a/tutorials/.DS_Store and /dev/null differ
diff --git a/tutorials/README.md b/tutorials/README.md
deleted file mode 100644
index 81c8590f..00000000
--- a/tutorials/README.md
+++ /dev/null
@@ -1,1 +0,0 @@
-# Tutorials
diff --git a/tutorials/scripts/extxyz_loading_example.py b/tutorials/scripts/extxyz_loading_example.py
deleted file mode 100644
index 0642640c..00000000
--- a/tutorials/scripts/extxyz_loading_example.py
+++ /dev/null
@@ -1,25 +0,0 @@
-"""
-Read an xyz file
-"""
-
-import mdsuite as mds  # Import the mdsuite python package
-import shutil
-
-if __name__ == "__main__":
-
-    try:
-        shutil.rmtree('Argon')
-    except:
-        pass
-
-    Argon = mds.Experiment('Argon', storage_path='./', time_step=1.0, temperature=85, units='metal')
-
-    Argon.add_data(trajectory_file='/beegfs/work/fzills/work/FNET-Models/Ar85K/Ar85K_q_SOAP_r6l5n5_16x16_efe_b25_1e'
-                                   '-04_1000confs.extxyz',
-                   file_format='extxyz')
-    Argon.sample_rate = 10
-    Argon.run_visualization()
-    Argon.run_computation.RadialDistributionFunction(plot=True, number_of_configurations=500, start=1, stop=700)
-
-
-
diff --git a/tutorials/scripts/map_molecules.py b/tutorials/scripts/map_molecules.py
deleted file mode 100644
index 9f333525..00000000
--- a/tutorials/scripts/map_molecules.py
+++ /dev/null
@@ -1,40 +0,0 @@
-"""
-Example file for how to map atoms from a simulation to defined molecules.
-"""
-
-import sys
-sys.path.insert(1, "../../")
-
-import mdsuite as mds
-from mdsuite.transformations.map_molecules import MolecularMap
-import shutil
-
-def main():
-    """
-    Analyze the trajectory.
-    """
-    try:
-       shutil.rmtree('emim')
-    except:
-       pass
-    filename = "../data/trajectory_files/emim_f.dump"
-    emim = mds.Experiment(analysis_name='emim', time_step=1.0, units='real', temperature=303.15)
-    emim.add_data(trajectory_file=filename)
-    emim.species['N']['mass'] = 14.007
-    emim.species['C']['mass'] = 12.011
-    emim.species['H']['mass'] = 1.008
-    emim.species['F']['mass'] = 18.998
-    emim.run_computation.EinsteinHelfandIonicConductivity(plot=True, data_range=50)
-    #emim.run_computation.EinsteinDiffusionCoefficients(plot=True, data_range=50)
-    #emim.run_computation.GreenKuboIonicConductivity(plot=True, data_range=50)
-    #emim.perform_transformation("UnwrapCoordinates")
-    #mapper = MolecularMap(emim, molecules={'emim': {'smiles': 'CCN1C=C[N+](+C1)C', 'amount': 20}})
-    #mapper.run_transformation()
-    #emim.perform_transformation('WrapCoordinates', species=['emim'])
-    #emim.write_xyz(species=['emim'], name='emim', dump_property='Positions')
-    #emim.write_xyz(species=['C', 'H', 'N'], name='atomistic', dump_property='Positions')
-    #emim.export_data('self_diffusion', 'C_einstein')
-
-
-if __name__ == "__main__":
-    main()
diff --git a/tutorials/scripts/visualizer.py b/tutorials/scripts/visualizer.py
deleted file mode 100644
index 13741a3a..00000000
--- a/tutorials/scripts/visualizer.py
+++ /dev/null
@@ -1,41 +0,0 @@
-"""
-Tutorial Name: Visualizer
-
-Description: This script goes over how to use the MDSuite visualizer to look at your trajectories either for fun or
-for real interest in a specific phenomenon.
-"""
-
-import mdsuite as mds
-
-def main():
-    """
-    Boilerplate main function
-
-    Returns
-    -------
-    Nothing. Runs the example.
-    """
-    # Add project
-    Molten_NaCl = mds.Project(name="Molten_NaCl", storage_path="./")
-    # Project description (optional)
-    Molten_NaCl.add_description("Best project ever!")
-    # Add experiment to project
-    Molten_NaCl.add_experiment(experiment_name="NaCl_1400K",
-                               timestep=0.002,
-                               temperature=1400.0,
-                               units='metal')
-    # Create experiment object
-    NaCl_1400K = Molten_NaCl.experiments['NaCl_1400K']  # The nice way
-    # Add tensor_values to the experiment
-    NaCl_1400K.add_data(trajectory_file='../data/trajectory_files/NaCl_1400K.dump')
-    NaCl_1400K.perform_transformation('UnwrapCoordinates')
-    NaCl_1400K.run_visualization()  # run the visualizer
-
-
-if __name__ == "__main__":
-    """
-    Standard boilerplate
-    """
-    main()
-
-
diff --git a/tutorials/scripts/walkthrough.py b/tutorials/scripts/walkthrough.py
deleted file mode 100644
index 66dda559..00000000
--- a/tutorials/scripts/walkthrough.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import mdsuite as mds  # Import the mdsuite python package
-
-
-# Add project
-Molten_NaCl = mds.Project(name="Molten_NaCl", storage_path="./")  
-
-# Project description (optional)
-Molten_NaCl.add_description("Best project ever!")   
-
-# Add experiment to project
-Molten_NaCl.add_experiment(experiment_name="NaCl_1400K", 
-                           timestep=0.002, 
-                           temperature=1400.0, 
-                           units='metal')
-                           
-# Create experiment object
-NaCl_1400K = Molten_NaCl.experiments['NaCl_1400K']  # The nice way
-
-# Add tensor_values to the experiment
-NaCl_1400K.add_data(trajectory_file='../data/trajectory_files/NaCl_1400K.dump')
diff --git a/tutorials/simulation_scripts/in.argon b/tutorials/simulation_scripts/in.argon
deleted file mode 100644
index d2e9cdb8..00000000
--- a/tutorials/simulation_scripts/in.argon
+++ /dev/null
@@ -1,81 +0,0 @@
-# ################################## #
-# Liquid Argon at 85K NVT Simulation #
-# ################################## #
-
-#############################
-### Configure system type ###
-#############################
-
-units		metal
-boundary 	p p p
-atom_style	atomic
-
-################################
-### Define system parameters ###
-################################
-
-region		myRegion block 0.0 17.73096097 0.0 17.73096097 0.0 17.73096097
-create_box 	1 myRegion
-
-
-##############################################################
-### Read input file and assign types and elementary groups ###
-##############################################################
-
-read_dump 	Ar.xyz 0 x y z box no add yes format xyz
-set 		atom 1*108 type 1
-mass		1  39.948
-group		Ar type 1
-velocity	all create 85 174782
-
-########################################
-### Define forcefield for simulation ###
-########################################
-
-pair_style 	lj/cut 8.604747015385797
-pair_coeff      * * 0.01034 3.405 
-
-####################
-### Set Timestep ###
-####################
-
-timestep        0.002
-
-###########################################
-### Define thermostat or other ensemble ###
-###########################################
-
-fix             myThermostat all nvt temp 85 85 $(50*dt)
-
-#################################
-### Compute system parameters ###
-################################# 
-
-##########################
-#### Define dump files ###
-##########################
-
-<<<<<<< HEAD
-dump            myDump1 all custom 20 Ar_85K.dump id type element x y z vx vy vz fx fy fz
-dump_modify	myDump1 element Ar
-=======
-dump            myDump1 all custom 20 Ar_80K.dump id type element x y z vx vy vz fx fy fz
->>>>>>> d76b13e8cd30e1584e6e4051c33e9e2a5da49520
-dump_modify     myDump1 sort id
-dump_modify     myDump1 append yes
-
-log             log.Ar_85K append
-
-################################
-### Define restart file dump ###
-################################
-
-#restart		1000 Ar_1.restart Ar_2.restart
-
-#################################################################
-### Define thermo output for log dump and run the simulations ###
-#################################################################
-
-thermo          100
-thermo_style 	custom step time temp pe ke etotal press
-run             100000
diff --git a/tutorials/simulation_scripts/in.krypton b/tutorials/simulation_scripts/in.krypton
deleted file mode 100644
index ff696382..00000000
--- a/tutorials/simulation_scripts/in.krypton
+++ /dev/null
@@ -1,76 +0,0 @@
-# #################################### #
-# Liquid Krypton at 85K NVT Simulation #
-# #################################### #
-
-#############################
-### Configure system type ###
-#############################
-
-units		metal
-boundary 	p p p
-atom_style	atomic
-
-################################
-### Define system parameters ###
-################################
-
-region		myRegion block 0.0 18.40 0.0 18.40 0.0 18.40
-create_box 	1 myRegion
-
-
-##############################################################
-### Read input file and assign types and elementary groups ###
-##############################################################
-
-read_dump 	Kr.xyz 0 x y z box no add yes format xyz
-set 		atom 1*108 type 1
-mass		1  83.798
-velocity	all create 85 174782
-
-########################################
-### Define forcefield for simulation ###
-########################################
-
-pair_style 	lj/cut 8.604747015385797
-pair_coeff      * * 0.01436242 4.041 
-
-####################
-### Set Timestep ###
-####################
-
-timestep        0.002
-
-###########################################
-### Define thermostat or other ensemble ###
-###########################################
-
-fix             myThermostat all nvt temp 85 85 $(50*dt)
-
-#################################
-### Compute system parameters ###
-################################# 
-
-##########################
-#### Define dump files ###
-##########################
-
-dump            myDump1 all custom 20 Kr_85K.dump id type element x y z vx vy vz fx fy fz
-dump_modify	myDump1 element Kr
-dump_modify     myDump1 sort id
-dump_modify     myDump1 append yes
-
-log             log.Kr_85K append
-
-################################
-### Define restart file dump ###
-################################
-
-#restart		1000 Kr_1.restart Kr_2.restart
-
-#################################################################
-### Define thermo output for log dump and run the simulations ###
-#################################################################
-
-thermo          100
-thermo_style 	custom step time temp pe ke etotal press
-run             200000
diff --git a/tutorials/walkthrough_notebooks/.DS_Store b/tutorials/walkthrough_notebooks/.DS_Store
deleted file mode 100644
index b305b53a..00000000
Binary files a/tutorials/walkthrough_notebooks/.DS_Store and /dev/null differ
diff --git a/tutorials/walkthrough_notebooks/Liquid_Argon/argon_liquid.lammps b/tutorials/walkthrough_notebooks/Liquid_Argon/argon_liquid.lammps
deleted file mode 100644
index 3865b6c2..00000000
--- a/tutorials/walkthrough_notebooks/Liquid_Argon/argon_liquid.lammps
+++ /dev/null
@@ -1,92 +0,0 @@
-# Sample LAMMPS input script for thermal conductivity of solid Ar
-
-units       real
-variable    T equal 94.4
-variable    V equal vol
-variable    dt equal 2.0
-variable    p equal 200     # correlation length
-variable    s equal 10      # sample interval
-variable    d equal $p*$s   # dump interval
-
-variable    dens equal 1.374 # density
-variable    M_arg equal 39.948   # weight g/mol argon
-
-# convert from LAMMPS real units to SI
-
-variable    avgN equal 6.0221409e+23   # avogadro number
-variable    kB equal 1.3806504e-23    # [J/K] Boltzmann
-variable    kCal2J equal 4186.0/6.02214e23
-variable    A2m equal 1.0e-10
-variable    fs2s equal 1.0e-15
-variable    convert equal ${kCal2J}*${kCal2J}/${fs2s}/${A2m}
-
-# setup problem
-variable    repetitions equal 7 # number of blocks repetitions in each direction
-
-variable sidel equal (${M_arg}/${avgN}*4/${dens})^0.333333*1e+8
-
-dimension    3
-boundary     p p p
-lattice      fcc ${sidel} orient x 1 0 0 orient y 0 1 0 orient z 0 0 1
-region       box block 0 ${repetitions} 0 ${repetitions} 0 ${repetitions}
-create_box   1 box
-create_atoms 1 box
-mass         1 39.948
-pair_style   lj/cut 13.0
-pair_coeff   * * 0.2381 3.405
-timestep     ${dt}
-thermo       $d
-
-# equilibration and thermalization
-
-velocity     all create $T 102486 mom yes rot yes dist gaussian
-fix          NVT all nvt temp $T $T 10 drag 0.2
-run          100000
-
-# thermal conductivity calculation, switch to NVE if desired
-
-unfix       NVT
-fix         NVE all nve
-
-reset_timestep 0
-
-# Thermal
-compute      KE all ke/atom
-compute      PE all pe/atom
-compute      pe_total all pe
-compute      ke_total all ke
-compute      Stress all stress/atom NULL virial
-compute      flux_thermal all heat/flux KE PE Stress
-
-# viscosity
-variable     pxy equal pxy
-variable     pxz equal pxz
-variable     pyz equal pyz
-
-variable     Jx equal c_flux_thermal[1]/vol
-variable     Jy equal c_flux_thermal[2]/vol
-variable     Jz equal c_flux_thermal[3]/vol
-fix          JJ all ave/correlate $s $p $d &
-             c_flux_thermal[1] c_flux_thermal[2] c_flux_thermal[3] type auto file J0Jt.dat ave running
-fix          SS all ave/correlate $s $p $d &	
-             v_pxy v_pxz v_pyz type auto file S0St.dat ave running
-fix print_data all print 1 "$(step) $(time) $(temp) $(c_pe_total) $(c_ke_total) $(c_flux_thermal[1]) $(c_flux_thermal[2]) $(c_flux_thermal[3]) $(v_pxy) $(v_pxz) $(v_pyz)" file flux_1_cepstral.lmp_flux screen no
-variable     scale equal ${convert}/${kB}/$T/$T/$V*$s*${dt}
-variable     k11 equal trap(f_JJ[3])*${scale}
-variable     k22 equal trap(f_JJ[4])*${scale}
-variable     k33 equal trap(f_JJ[5])*${scale}
-
-# shell mkdir energy
-# dump energy all custom 400 energy/energy_dump.* id type x y z vx vy vz c_myKE c_myPE
-# dump the data required for G-K computations
-
-# NOT DUMPING POSITIONS NOW
-dump position all custom 1 gk_data.lmp_traj id type x y z vx vy vz c_KE c_PE c_Stress[1] c_Stress[2] c_Stress[3] c_Stress[4] c_Stress[5] c_Stress[6]
-
-thermo_style custom step temp press v_Jx v_Jy v_Jz v_k11 v_k22 v_k33
-# run          500000
-run          20000
-variable     k equal (v_k11+v_k22+v_k33)/3.0
-variable     ndens equal count(all)/vol
-print        "the volume of the box is: $V"
-print        "average conductivity: $k[W/mK] @ $T K, ${ndens} /A\^3"
diff --git a/tutorials/walkthrough_notebooks/Liquid_Argon/from_flux/add_header_flux_file.py b/tutorials/walkthrough_notebooks/Liquid_Argon/from_flux/add_header_flux_file.py
deleted file mode 100644
index 884fd8dc..00000000
--- a/tutorials/walkthrough_notebooks/Liquid_Argon/from_flux/add_header_flux_file.py
+++ /dev/null
@@ -1,123 +0,0 @@
-# This script is far from ideal...but it is only to give the structure.
-
-import re
-import os
-from shutil import copyfile
-import time
-
-
-def prepend(filename, data, bufsize=1<<15):
-    # adapted from https://stackoverflow.com/questions/5287762/how-to-insert-a-new-line-before-the-first-line-in-a-file-using-python/5290636#5290636
-    # backup the file
-    backupname = filename + os.extsep+'bak'
-    try: os.unlink(backupname) # remove previous backup if it exists
-    except OSError: pass
-    os.rename(filename, backupname)
-
-    # open input/output files,  note: outputfile's permissions lost
-    with open(backupname) as inputfile, open(filename, 'w') as outputfile:
-        # prepend
-        outputfile.write(data)
-        # copy the rest (remove the first line)
-        _ = inputfile.readline()
-        buf = inputfile.read(bufsize)
-        while buf:
-            outputfile.write(buf)
-            buf = inputfile.read(bufsize)
-
-    # remove backup on success
-    try: os.unlink(backupname)
-    except OSError: pass
-
-def find_match(lammpsfilename, match):
-    # find match in the line given a list of words as hint
-    with open(lammpsfilename,'r') as fp:
-        line_with_match = []
-        for line in fp:
-            if all(x in line for x in match):
-                return line
-
-def get_property(line_match):
-    # this takes the value of a dict (usually a string) and returns a value of the property.
-    # it is built this way to handle the possible errors.
-    try:
-        property_extracted = float(re.findall('\d*\.?\d+', line_match)[0])
-    except IndexError:
-        property_extracted = line_match.split()[1]
-    except TypeError:
-        property_extracted = None
-    return property_extracted
-
-
-def read_data(lammpsfilename):
-
-    # inputs to match (some variables and the line of headers)
-    things_to_match = {'density':           ['variable','Densi', 'equal'],
-                       'atom_side':         ['variable','atom_side', 'equal'],
-                       'dt':                ['variable', 'dt', 'equal'],
-                       'units':             ['units'],
-                       'molarMass':         ['variable', 'molarMass', 'equal'],
-                       'pair_style':        ['pair_style'],
-                       'timesteps_conduct': ["variable", 'timesteps_conductivity', 'equal'],
-                       'output_step':       ['variable','output_step', 'equal'],
-                       'temperature':       ['variable', 'T', 'equal'],
-                       'dt_production': ['variable', 'dt_production', 'equal'],
-                       'volume': ['the', 'volume', 'of', 'the', 'box', 'is:']
-                       }
-
-    line_fix_print_headers = "$(c_flux_thermal[1]) $(c_flux_thermal[2]) $(c_flux_thermal[3])"
-
-    # match the different properties required
-
-    matches = dict.fromkeys(things_to_match.keys())
-    properties_extracted = dict.fromkeys(things_to_match.keys())
-
-    for property, indicators in things_to_match.items():
-        matches[property] = find_match(lammpsfilename, indicators)
-        properties_extracted[property] = get_property(matches[property])
-        if properties_extracted[property] is None:
-            print(f'"{property}" not found, will be printed as "nan"')
-            properties_extracted[property] = -1
-
-    properties_extracted['num_atoms'] = properties_extracted["atom_side"]**3
-
-
-    # get the header line
-    line_header = find_match(lammpsfilename, line_fix_print_headers)
-    line_header = line_header.split(sep='"')[1].replace("$","").replace("(","").replace(")","")
-
-    text_to_replace = (f'# Fix print output for fix print_data\n'
-                       f'# {properties_extracted["pair_style"]} potential \n'
-                       f'# {properties_extracted["num_atoms"]} atoms, dens. {properties_extracted["density"]}g/cm^3 \n'
-                       f'# dt = {properties_extracted["dt"]}, {properties_extracted["timesteps_conduct"]} timesteps, output_step = every {properties_extracted["output_step"]} step \n'
-                       f'# Temperature = {properties_extracted["temperature"]} K, V = {properties_extracted["volume"]} A3 \n'
-                       f'# LAMMPS {properties_extracted["units"]} units \n'
-                       f'{line_header} \n')
-    return text_to_replace
-
-def check_header_existance(filename):
-    with open(filename,'r') as fp:
-        next(fp) # skip the first line
-        head = [next(fp) for x in range(2)]
-    if all([line.startswith("# ") for line in head]):
-        print('It seems the header already exists, I will not add it.')
-        return True
-    else:
-        return False
-
-def add_header(filename, lammpsfilename, keep_copy=True):
-
-    # Check if header already exists
-    header_exists = check_header_existance(filename=filename)
-
-    if not header_exists:
-        if keep_copy:
-            copyfile(filename, filename+'.backup')
-            print('back copy done')
-
-        text_to_replace = read_data(lammpsfilename)
-        prepend(filename, text_to_replace)
-        print("Job's Done! header replaced")
-
-if __name__=='__main__':
-    add_header('../flux_1.lmp_flux', '../argon.lammps')
\ No newline at end of file
diff --git a/tutorials/walkthrough_notebooks/Liquid_Argon/from_flux/step_by_step.py b/tutorials/walkthrough_notebooks/Liquid_Argon/from_flux/step_by_step.py
deleted file mode 100644
index d2718622..00000000
--- a/tutorials/walkthrough_notebooks/Liquid_Argon/from_flux/step_by_step.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import shutil
-
-from mdsuite.experiment.experiment import Experiment
-
-if __name__ == '__main__':
-
-    new_case = True
-
-    if new_case:
-        try:
-            shutil.rmtree('Argon_94')
-        except FileNotFoundError:
-            pass
-    argon = Experiment(analysis_name="Argon_94",
-                             storage_path=".",
-                             temperature=94.4,
-                             time_step=2,
-                             units='real')
-
-    argon.add_data(trajectory_file='../flux_1_cepstral.lmp_flux', file_format='lammps_flux', rename_cols={"Flux_Thermal":['flux[1]','flux[2]', "flux[3]"]})
-    argon.run_computation('GreenKuboThermalConductivityFlux', data_range=2500, plot=True, correlation_time=2)
-    argon.run_computation('GreenKuboViscosityFlux', data_range=2500, plot=True, correlation_time=2)
diff --git a/tutorials/walkthrough_notebooks/Liquid_Argon/from_traj/gk.py b/tutorials/walkthrough_notebooks/Liquid_Argon/from_traj/gk.py
deleted file mode 100644
index a829385d..00000000
--- a/tutorials/walkthrough_notebooks/Liquid_Argon/from_traj/gk.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import os
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
-import shutil
-
-import mdsuite as mds # Cool name for professionalism purposes
-
-try:
-    shutil.rmtree('Argon')
-except FileNotFoundError:
-    pass
-
-
-
-argon = mds.Experiment(analysis_name="Argon", time_step=2, temperature=94.4, units='real')
-
-argon.add_data(trajectory_file='../gk_data.lmp_traj')
-
-# argon.help_computations_args('EinsteinDiffusionCoefficients') # auxiliary function to help on the extra arguments
-# argon.run_computation('EinsteinDiffusionCoefficients', species=list(argon.species.keys()),data_range=50, plot=False, singular=True, distinct=False)
-#argon.run_computation('GreenKuboThermalConductivity', data_range=2500, plot=True, correlation_time=2)
-argon.run_computation('GreenKuboViscosity', data_range=2500, plot=True, correlation_time=2)
-
diff --git a/tutorials/walkthrough_notebooks/Liquid_Argon/from_traj/viscosity_gk.py b/tutorials/walkthrough_notebooks/Liquid_Argon/from_traj/viscosity_gk.py
deleted file mode 100644
index 954ea320..00000000
--- a/tutorials/walkthrough_notebooks/Liquid_Argon/from_traj/viscosity_gk.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import os
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
-import shutil
-
-import mdsuite as mds # Cool name for professionalism purposes
-
-try:
-    shutil.rmtree('Argon')
-except FileNotFoundError:
-    pass
-
-
-argon = mds.Experiment(analysis_name="Argon", time_step=2, temperature=94.4, units='real')
-
-
-argon.add_data(trajectory_file='../gk_data.lmp_traj')
-
-#argon.run_computation('GreenKuboThermalConductivity', data_range=19980, plot=True)
-argon.run_computation('GreenKuboViscosity', data_range=19980, plot=True)
-print(argon.results)
diff --git a/tutorials/walkthrough_notebooks/MDSuite_Binary_Salt_Walkthrough.ipynb b/tutorials/walkthrough_notebooks/MDSuite_Binary_Salt_Walkthrough.ipynb
deleted file mode 100644
index 0ee60c8b..00000000
--- a/tutorials/walkthrough_notebooks/MDSuite_Binary_Salt_Walkthrough.ipynb
+++ /dev/null
@@ -1,472 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# MDSuite Binary Salt Walkthrough\n",
-    "\n",
-    "In this tutorial, we will use the mdsuite post-processing\n",
-    "package to analyse a molten salt simulation. This should\n",
-    "give user the general idea of how to use the program as \n",
-    "well as showcase the features of the code"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### Step 0 - Import the package\n",
-    "\n",
-    "The absolute first thing we have to is import the package. We call this\n",
-    "step zero as it hardly counts as doing anything, but is at the same \n",
-    "time, the most essential part of the analysis..."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div id=\"glowscript\" class=\"glowscript\"></div>"
-      ],
-      "text/plain": [
-       "<IPython.core.display.HTML object>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    },
-    {
-     "data": {
-      "application/javascript": [
-       "if (typeof Jupyter !== \"undefined\") { window.__context = { glowscript_container: $(\"#glowscript\").removeAttr(\"id\")};}else{ element.textContent = ' ';}"
-      ],
-      "text/plain": [
-       "<IPython.core.display.Javascript object>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
-   "source": [
-    "import sys\n",
-    "sys.path.insert(1, \"/Users/samueltovey/work/Respositories/MDSuite\")\n",
-    "import mdsuite as mds  # Import the mdsuite python package\n",
-    "import shutil"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "try:\n",
-    "    shutil.rmtree(\"Molten_NaCl_MDSuite_Project\")\n",
-    "except:\n",
-    "    print(\"New experiment\")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### Step 1 - Create a new project\n",
-    "\n",
-    "The first real thing we have to do is create a project. This is where all \n",
-    "of your experiments will be kept in the future, so make it memorable"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "Molten_NaCl = mds.Project(name=\"Molten_NaCl\", storage_path=\"./\")  "
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### Step 1.5 - Give it a description\n",
-    "\n",
-    "Another great thing to do before you get into the analysis is to give\n",
-    "the project a short description. This can be done by calling the \n",
-    "add_description method and will be stored with the class state. It may \n",
-    "help the weary scientist who can't remember exactly why they have started\n",
-    "stuyding molten salts, but knew at the time there was a good reason... As \n",
-    "are the effects of Uranium poisening"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "Molten_NaCl.add_description(\"Best project ever!\")   "
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### Step 2 - Add an experiment\n",
-    "\n",
-    "With the technicalities out of the way, let's get into the meat, \n",
-    "or meat subsitute if that's your thing. We need to start adding\n",
-    "some data to this project. We structure this data in terms of \n",
-    "experiments, just as we would in any scientific project"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Creating a new experiment! How exciting!\n",
-      "** An experiment has been added titled NaCl_1400K **\n",
-      "2021-04-11 21:23:47,871 - mdsuite.experiment.experiment (INFO) - Created logfile 2021-04-11T21-23-47.log in experiment path /Users/samueltovey/work/Respositories/MDSuite/tutorials/walkthrough_notebooks/Molten_NaCl_MDSuite_Project/NaCl_1400K/logfiles\n"
-     ]
-    }
-   ],
-   "source": [
-    "Molten_NaCl.add_experiment(experiment_name=\"NaCl_1400K\", \n",
-    "                           timestep=0.002, \n",
-    "                           temperature=1400.0, \n",
-    "                           units='metal')"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### Step 2.5 - A closer look\n",
-    "\n",
-    "Yes it's a rip off of Seth Meyers but the phrase cannot be exclusive.\n",
-    "\n",
-    "What has actually just been achieved is that you have added an experiment\n",
-    "to your project. This instantiated a class called the Experiment class. Now, \n",
-    "you will want access to this class in order to perform analysis on that experiment.\n",
-    "First, let's look at where it has been stored, we do so by looking at the experiments\n",
-    "attribute of our Project class"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "{'NaCl_1400K': <mdsuite.experiment.experiment.Experiment at 0x1605c1d60>}"
-      ]
-     },
-     "execution_count": 6,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "Molten_NaCl.experiments"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "I know what you're thinking, this looks nothing like my 2 ns simulation of molten NaCl at 1400K in an NVT ensemble. You are correct, so instead of looking directly at guts of the program, why not purely focus on the shiny exterior and run the list_experiments method."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "'0.) NaCl_1400K'"
-      ]
-     },
-     "execution_count": 7,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "Molten_NaCl.list_experiments()  # List the available experiments"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "What can been seen here is an index number, and the name of the experiment. If you want to access the experiment, you need to select it from the project. There are three ways to do this so we will demonstrate them all, however, we recommend the first as it is easier to keep track of."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "'NaCl_1400K'"
-      ]
-     },
-     "execution_count": 8,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "NaCl_1400K = Molten_NaCl.experiments['NaCl_1400K']  # The nice way\n",
-    "NaCl_1400K.analysis_name"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "'NaCl_1400K'"
-      ]
-     },
-     "execution_count": 9,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "Molten_NaCl.experiments['NaCl_1400K'].analysis_name  # Maybe less code bu not as simple"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "'NaCl_1400K'"
-      ]
-     },
-     "execution_count": 10,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "experiment_list = list(Molten_NaCl.experiments)\n",
-    "NaCl_1400K = Molten_NaCl.experiments[experiment_list[0]]  # Can be useful if you want to iterate over experiments\n",
-    "NaCl_1400K.analysis_name"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "As we said, these ways all achieve the same goal, but each should be used under different circumstances. For performing analysis or reading the information of a specific experiment, we would recommend the first approach as it is easier to keep track of the experiment you are looking at. If you want to save code or are generating a summary, it may not be necessary to declare a variable referencing this class, so use the second method.If you want to run an analyis on several experiment, then you may wish to go for the third as it is easier to loop over, but we will get to that a bit later."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### Step 3 Adding Simulation Data\n",
-    "\n",
-    "So you have started your project up and you want to add some real trajectory data to it. We do this by accessing the experiment directly and performing calculations on it. The first thing you have to do is add some data. This is perfomed by the add_data method of the experiment class"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "NaCl_1400K = Molten_NaCl.experiments['NaCl_1400K']  # Get the experiment from the project"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "100%|███████████████████████████████████| 1/1 [00:00<00:00, 20.35it/s]\n"
-     ]
-    }
-   ],
-   "source": [
-    "NaCl_1400K.add_data(trajectory_file='../data/trajectory_files/NaCl_1400K.dump', sort=True)  # Add data to the experiment"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "190"
-      ]
-     },
-     "execution_count": 13,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "NaCl_1400K.number_of_configurations"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### Step 4: Performing Calculation\n",
-    "\n",
-    "Now that you have some data in one of the experiments, you can start performing analysis on it. Let's start with the einstein diffusion coefficints."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "NaCl_1400K.species['Na']['charge'] = [1]\n",
-    "NaCl_1400K.species['Cl']['charge'] = [-1]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 15,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "#NaCl_1400K.run_computation.NernstEinsteinIonicConductivity(corrected=True)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 16,
-   "metadata": {
-    "scrolled": false
-   },
-   "outputs": [
-    {
-     "ename": "TypeError",
-     "evalue": "__init__() got an unexpected keyword argument 'atom_selection'",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
-      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
-      "\u001b[0;32m<ipython-input-16-0ab658ed5df3>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mNaCl_1400K\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun_computation\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mEinsteinDistinctDiffusionCoefficients\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata_range\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m180\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0matom_selection\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m\"Na\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"Cl\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m6\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m8\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
-      "\u001b[0;32m~/work/Respositories/MDSuite/mdsuite/experiment/experiment.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m    360\u001b[0m                     \u001b[0mIntroduce\u001b[0m \u001b[0mcall\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    361\u001b[0m                     \"\"\"\n\u001b[0;32m--> 362\u001b[0;31m                     \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparent\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcompute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclass_compute\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    363\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    364\u001b[0m             \u001b[0;32mreturn\u001b[0m \u001b[0mFunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclass_compute\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;32m~/work/Respositories/MDSuite/mdsuite/experiment/experiment.py\u001b[0m in \u001b[0;36mcompute\u001b[0;34m(self, class_compute, **kwargs)\u001b[0m\n\u001b[1;32m    400\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    401\u001b[0m             \"\"\"\n\u001b[0;32m--> 402\u001b[0;31m             \u001b[0mobject_compute\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mclass_compute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparent\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    403\u001b[0m             \u001b[0mobject_compute\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun_analysis\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    404\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparent\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msave_class\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;31mTypeError\u001b[0m: __init__() got an unexpected keyword argument 'atom_selection'"
-     ]
-    }
-   ],
-   "source": [
-    "NaCl_1400K.run_computation.EinsteinDistinctDiffusionCoefficients(plot=True, data_range=180, atom_selection={\"Na\": [0, 1, 2], \"Cl\": [3, 6, 8]})"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "#NaCl_1400K.run_computation.EinsteinHelfandIonicConductivity(plot=True, data_range=13)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "NaCl_1400K.run_computation.GreenKuboDistinctDiffusionCoefficients(plot=True, data_range=150, atom_selection={\"Na\": [0, 1, 2], \"Cl\": [3, 6, 8]})"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "#NaCl_1400K.run_computation.GreenKuboIonicConductivity(plot=True, data_range=150)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "#NaCl_1400K.run_visualization()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "#NaCl_1400K.run_computation.RadialDistributionFunction(start=1, stop=150, number_of_configurations=100)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.8.8"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/tutorials/walkthrough_notebooks/NaCl_minicase/from_trajectory/check_db_sorted.py b/tutorials/walkthrough_notebooks/NaCl_minicase/from_trajectory/check_db_sorted.py
deleted file mode 100644
index 8eb734aa..00000000
--- a/tutorials/walkthrough_notebooks/NaCl_minicase/from_trajectory/check_db_sorted.py
+++ /dev/null
@@ -1,45 +0,0 @@
-import os
-
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
-import shutil
-import numpy as np
-import h5py as hf
-import matplotlib.pyplot as plt
-from plot_python_vki import  apply_style
-import mdsuite as mds  # Cool name for professionalism purposes
-
-case = 'NaCl_sorted'
-
-new_case = True
-
-if new_case:
-    try:
-        shutil.rmtree(case)
-    except FileNotFoundError:
-        pass
-
-argon = mds.Experiment(analysis_name=case, time_step=1, temperature=70.0, units='real')
-
-if new_case:
-    argon.add_data(trajectory_file='../gk_data_sorted.lmp_traj')
-
-argon.run_computation.EinsteinHelfandThermalConductivity(data_range=6, plot=True, correlation_time=1)
-
-plt.figure()
-apply_style()
-plt.style.use({"lines.markeredgewidth": 0, 'figure.figsize': [16, 9]})
-
-folder = case
-
-path = '1/Positions'
-with hf.File(f'{folder}/databases/database.hdf5', "r+") as database:
-    data = database[path][np.s_[:]]
-
-slice = np.s_[:, :, 1]
-
-sliced_x = data[slice]
-
-plt.plot(sliced_x[0:10].T, 'o')
-
-plt.savefig(f"{folder}/positions.png")
-plt.show()
diff --git a/tutorials/walkthrough_notebooks/NaCl_minicase/from_trajectory/check_db_unsorted.py b/tutorials/walkthrough_notebooks/NaCl_minicase/from_trajectory/check_db_unsorted.py
deleted file mode 100644
index e1e7d05b..00000000
--- a/tutorials/walkthrough_notebooks/NaCl_minicase/from_trajectory/check_db_unsorted.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import os
-
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
-import shutil
-import numpy as np
-import h5py as hf
-import matplotlib.pyplot as plt
-from plot_python_vki import  apply_style
-import mdsuite as mds  # Cool name for professionalism purposes
-
-case = 'NaCl_unsorted'
-
-new_case = True
-
-if new_case:
-    try:
-        shutil.rmtree(case)
-    except FileNotFoundError:
-        pass
-
-argon = mds.Experiment(analysis_name=case, time_step=1, temperature=70.0, units='real')
-
-if new_case:
-    argon.add_data(trajectory_file='../gk_data_unsorted.lmp_traj')#, sort=True)
-
-argon.run_computation.EinsteinHelfandThermalConductivity(data_range=6, plot=True, correlation_time=1)
-
-plt.figure()
-apply_style()
-plt.style.use({"lines.markeredgewidth": 0, 'figure.figsize': [16, 9]})
-
-folder = case
-
-path = '1/Positions'
-path = '1/Unwrapped_Positions'
-with hf.File(f'{folder}/databases/database.hdf5', "r+") as database:
-    data = database[path][np.s_[:]]
-
-slice = np.s_[:, :, 1]
-
-sliced_x = data[slice]
-
-plt.plot(sliced_x[0:10].T, 'o')
-
-plt.savefig(f"{folder}/positions.png")
-plt.show()
diff --git a/tutorials/walkthrough_notebooks/NaCl_minicase/in_sorted.eim b/tutorials/walkthrough_notebooks/NaCl_minicase/in_sorted.eim
deleted file mode 100644
index 93f9da79..00000000
--- a/tutorials/walkthrough_notebooks/NaCl_minicase/in_sorted.eim
+++ /dev/null
@@ -1,47 +0,0 @@
-# NaCl test problem for embedded atom method (EIM) potential
-
-units		metal
-atom_style      atomic
-
-boundary	p p p
-
-lattice         diamond 5.0
-read_data       data.eim
-
-pair_style      eim
-pair_coeff      * * Na Cl ffield.eim Na Cl 
-
-neighbor	0.3 bin
-neigh_modify	delay 0
-
-# Thermal
-compute      KE all ke/atom
-compute      PE all pe/atom
-compute      pe_total all pe
-compute      ke_total all ke
-compute      Stress all stress/atom NULL virial
-compute      flux_thermal all heat/flux KE PE Stress
-
-
-timestep        0.001
-thermo_style    custom step pe pxx pyy pzz temp
-thermo          50
-
-velocity        all create 1400.0 43454 dist gaussian mom yes
-fix             int all npt temp 1400.0 300.0 0.1 aniso 0.0 0.0 0.1
-
-# dump		id all atom 100 dump.eim
-
-# NOT DUMPING POSITIONS NOW
-dump position all custom 100 gk_data_sorted.lmp_traj id type x y z vx vy vz c_KE c_PE c_Stress[1] c_Stress[2] c_Stress[3] c_Stress[4] c_Stress[5] c_Stress[6]
-dump_modify position sort id
-
-#dump		2 all image 25 image.*.jpg element element &
-#		axes yes 0.8 0.02 view 60 -30
-#dump_modify	2 pad 3 element Na Cl
-
-#dump		3 all movie 25 movie.mpg element element &
-#		axes yes 0.8 0.02 view 60 -30
-#dump_modify	3 pad 3 element Na Cl
-
-run             5000
diff --git a/tutorials/walkthrough_notebooks/Noble_gases_project/compute_dt.py b/tutorials/walkthrough_notebooks/Noble_gases_project/compute_dt.py
deleted file mode 100644
index 0aa28629..00000000
--- a/tutorials/walkthrough_notebooks/Noble_gases_project/compute_dt.py
+++ /dev/null
@@ -1,50 +0,0 @@
-from math import ceil
-
-def compute_dt_all_gases():
-    # computes the delta t for all the gases in fs.
-
-    Mweight = {
-        "Argon": 39.948,
-        "Krypton": 83.8,
-        "Xenon": 131.29,
-        "CH4": 16.043
-    }
-
-    # sigma in Angstroms
-    sigma = {
-        "Argon": 3.3952,
-        "Krypton": 3.6274,
-        "Xenon": 3.9011,
-        "CH4": 3.7281
-    }
-
-    # epsilon divided by kb in K
-    eps_div_kb = {
-        "Argon": 116.79,
-        "Krypton": 162.58,
-        "Xenon": 277.55,
-        "CH4": 148.55
-    }
-
-    kb = 1.38064852 * 10 ** (-23)
-
-    #######
-
-    Na = 6.0221409e+23
-    eps = {k: v * kb for k, v in eps_div_kb.items()}
-    weight = {k: v / 1000 / Na for k, v in Mweight.items()}
-    sigma_SI = {k: v * 10 ** (-10) for k, v in Mweight.items()}
-
-    delta_t_SI = {}
-    for gas in eps.keys():
-        delta_t_SI[gas] = 0.001 / (((eps[gas] / weight[gas]) ** 0.5) / sigma_SI[gas])
-
-    delta_t_fs = {k: ceil(v * 10 ** 15) for k, v in delta_t_SI.items()}
-    return delta_t_fs
-
-
-def compute_dt_gas(gas_name):
-    # get the value for the specific gas, even though we recompute it, it is very cheap.
-
-    delta_t_fs = compute_dt_all_gases()
-    return delta_t_fs[gas_name]
\ No newline at end of file
diff --git a/tutorials/walkthrough_notebooks/Noble_gases_project/create_cases.py b/tutorials/walkthrough_notebooks/Noble_gases_project/create_cases.py
deleted file mode 100644
index 78125938..00000000
--- a/tutorials/walkthrough_notebooks/Noble_gases_project/create_cases.py
+++ /dev/null
@@ -1,93 +0,0 @@
-from math import ceil
-from pathlib import Path
-
-import pandas as pd
-
-from compute_dt import compute_dt_gas
-
-
-def replace_variable(old_values, new_values, template_file, output_file):
-    with open(output_file, "w") as myfile:
-        with open(template_file, "r") as f:
-            lines = f.readlines()
-            for line in lines:
-                # print str(line)
-                for old_value, new_value in zip(old_values, new_values):
-                    line = line.replace(f'{{{old_value}}}',
-                                        str(new_value))  # It will replace if line contain 'old_string' by '+new_string'
-                # print ret
-                myfile.write(line)
-
-
-########## Properties required
-Mweight = {
-    "Argon": 39.948,
-    "Xenon": 131.29,
-}
-eps_div_kb = {
-    "Argon": 116.79,
-    "Xenon": 227.55,
-}
-kb = 1.38064852 * 10 ** (-23)
-Na = 6.02214076 * 10 ** 23
-kCal2J = 4184
-eps = {k: v * kb * Na / kCal2J for k, v in eps_div_kb.items()}
-sigma = {
-    "Argon": 3.3952,
-    "Xenon": 3.9011,
-}
-
-densities = {
-    "Argon": [0.942, 1.375],
-    "Xenon": [2.243, 2.916],
-}
-
-temperatures = {
-    "Argon": [135.6, 92.97],
-    "Xenon": [229.0, 176.2],
-}
-
-timesteps = {
-    "Argon": 3,
-    "Xenon": 10,
-}
-
-##########
-# ACTUAL PROGRAM
-# CHOOSE THE GASES HERE
-
-gases = ('Argon', 'Xenon')
-
-template_file = Path('template_fluids.lammps')
-
-# iterate for every gas
-for gas in gases:
-
-    timestep = timesteps[gas]
-    eps_gas = eps[gas]
-    MW_gas = Mweight[gas]
-    sigma_gas = sigma[gas]
-    cutoff = 3 * sigma_gas
-
-    # iterate for every condition
-    for density, temperature in zip(densities[gas], temperatures[gas]):
-        # this is to make the folder names
-        dens_folder_name = str(density)
-        temperature_folder_name = str(temperature)
-        condition = f'{dens_folder_name}_gcm3_{temperature_folder_name}_K'
-        path = Path(f"./{gas}/{condition}")
-        path.mkdir(parents=True, exist_ok=True)
-
-        # replace the values in the template
-        # call it input.lammps
-        variables_to_replace = {'temperature': temperature,
-                                'density': density,
-                                "Mweight": MW_gas,
-                                "cut_off": cutoff,
-                                "epsilon": eps_gas,
-                                'sigma': sigma_gas,
-                                'timestep': timestep}
-
-        output_file = path / 'input.lammps'
-        replace_variable(variables_to_replace.keys(), variables_to_replace.values(),
-                         template_file=template_file, output_file=output_file)
diff --git a/tutorials/walkthrough_notebooks/Noble_gases_project/project.py b/tutorials/walkthrough_notebooks/Noble_gases_project/project.py
deleted file mode 100644
index 002b101e..00000000
--- a/tutorials/walkthrough_notebooks/Noble_gases_project/project.py
+++ /dev/null
@@ -1,106 +0,0 @@
-import shutil
-
-import matplotlib.pyplot as plt
-import numpy as np
-import pandas as pd
-
-import mdsuite as mds  # Import the mdsuite python package
-from mdsuite.plot_style.plot_style import apply_style
-
-apply_style()
-
-new_project = False
-if new_project:
-    try:
-        shutil.rmtree('Gases_MDSuite_Project')
-    except FileNotFoundError:
-        pass
-
-gases = mds.Project(name="Gases", storage_path="./")
-
-gases.add_description("Project to analyze and compare gases")
-
-gases.add_experiment(experiment="Argon_135",
-                     timestep=3,
-                     temperature=135.6,
-                     units='real')
-
-gases.add_experiment(experiment="Argon_93",
-                     timestep=3,
-                     temperature=92.97,
-                     units='real')
-
-gases.add_experiment(experiment="Xenon_229",
-                     timestep=3,
-                     temperature=229.0,
-                     units='real')
-
-gases.add_experiment(experiment="Xenon_176",
-                     timestep=3,
-                     temperature=176.2,
-                     units='real')
-
-print(gases)
-
-if new_project:
-    # you can access directly the experiment as an attribute
-    gases.Argon_93.add_data(trajectory_file='Argon/0.942_gcm3_135.6_K/gk_data.lmp_traj')
-    gases.Xenon_229.add_data(trajectory_file='Xenon/2.243_gcm3_229.0_K/gk_data.lmp_traj')
-    gases.Xenon_176.add_data(trajectory_file='Xenon/2.916_gcm3_176.2_K/gk_data.lmp_traj')
-    gases.Argon_135.add_data(trajectory_file='Argon/1.375_gcm3_92.97_K/gk_data.lmp_traj')
-
-# Then for each of them, we can run the conductivity computation
-if new_project:
-    for experiment_name, experiment_class in gases.experiments.items():
-        experiment_class.run_computation.GreenKuboThermalConductivity(data_range=500, plot=True, correlation_time=1)
-
-results = gases.Argon_93.results
-print(results)
-
-# get it for all the cases
-results_k = gases.get_results('green_kubo_thermal_conductivity')
-temperatures = gases.get_attribute('temperature')
-
-# put the results in a dataframe
-dict_results = pd.DataFrame.from_dict(results_k)
-dict_results = dict_results.append(temperatures, ignore_index=True)
-dict_results = dict_results.rename(index={0: 'k', 1: 'k_err', 2: 'temperature'})
-print(dict_results)
-
-# plot the results
-fig, ax = plt.subplots()
-
-dfs = {'argon': dict_results.iloc[:, 0:2], 'xenon': dict_results.iloc[:, 2:]}
-
-colors = ['C0', 'C1']
-
-for idx, (key, val) in enumerate(dfs.items()):
-    print(key)
-    temperature = val.loc['temperature', :].values
-    k = val.loc['k', :].values
-    k_err = val.loc['k_err', :].values
-    ax.errorbar(temperature, k, yerr=k_err, linestyle="--", marker='o', color=colors[idx])
-
-ref_data = {'argon': {93: 0.121, 135: 0.058}, 'xenon': {176: 0.075, 229: 0.0397}}
-
-for idx, (key, val) in enumerate(ref_data.items()):
-    temperature = []
-    k = []
-    for temp, conduct in val.items():
-        temperature.append(temp)
-        k.append(conduct)
-
-    ax.plot(temperature, k, linestyle="-", marker='s', color=colors[idx])
-
-ax.plot(np.nan, np.nan, linestyle="--", color='k', marker='o', label='Ref.')
-ax.plot(np.nan, np.nan, linestyle="-", color='k', marker='s', label='MDSuite')
-
-ax.plot(np.nan, np.nan, linestyle="-", color='C0', label='Argon')
-ax.plot(np.nan, np.nan, linestyle="-", color='C1', label='Xenon')
-
-ax.legend()
-
-ax.set_xlabel("Temperature, K")
-ax.set_ylabel("Thermal Conductivity, W/m/K")
-
-plt.show()
diff --git a/tutorials/walkthrough_notebooks/Noble_gases_project/run_cases.py b/tutorials/walkthrough_notebooks/Noble_gases_project/run_cases.py
deleted file mode 100644
index c0215fc5..00000000
--- a/tutorials/walkthrough_notebooks/Noble_gases_project/run_cases.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import os
-import subprocess
-import shlex
-from os.path import exists
-
-
-folders = ('Argon','Xenon')#, "CH4", "Krypton")#, 'Xenon_2', 'Argon_2', "CH4_2", "Krypton_2",)
-root_folder = os.getcwd()
-
-for folder in folders:
-    subfolders = os.listdir(f"{folder}")
-
-    # for each case to run
-    for subfolder in subfolders:
-        os.chdir(f'{folder}/{subfolder}')
-        if not exists('log.lammps'): # if it does not exist, we run the case.
-            print(f'Running case: {folder}/{subfolder}')
-            p = subprocess.Popen(shlex.split("mpirun -np 6 lmp_mpi -in input.lammps"), shell=False)
-            p.wait()
-        else:
-            print(f'Skipping case: {folder}/{subfolder}')
-        os.chdir(root_folder)
diff --git a/tutorials/walkthrough_notebooks/Noble_gases_project/template_fluids.lammps b/tutorials/walkthrough_notebooks/Noble_gases_project/template_fluids.lammps
deleted file mode 100644
index ba32d279..00000000
--- a/tutorials/walkthrough_notebooks/Noble_gases_project/template_fluids.lammps
+++ /dev/null
@@ -1,95 +0,0 @@
-# Sample LAMMPS input script for thermal conductivity of {gas}
-
-units       real # set units
-variable    T equal {temperature} # temperature
-variable    V equal vol
-variable    dt equal {timestep} # timestep
-variable    p equal 200     # correlation length
-variable    s equal 10      # sample interval
-variable    d equal $p*$s   # dump interval
-variable    timesteps equal 20000
-variable    eq_steps  equal 20000
-variable    output_step equal 2
-
-variable    dens equal {density} # density in g/cm3
-variable    M_arg equal {Mweight}   # weight g/mol argon
-
-# convert from LAMMPS real units to SI
-
-variable    avgN equal 6.0221409e+23   # avogadro number
-variable    kB equal 1.3806504e-23    # [J/K] Boltzmann
-variable    kCal2J equal 4186.0/6.02214e23
-variable    A2m equal 1.0e-10
-variable    fs2s equal 1.0e-15
-variable    convert equal ${kCal2J}*${kCal2J}/${fs2s}/${A2m}
-
-# setup problem
-variable    repetitions equal 6 # number of blocks repetitions in each direction
-
-variable sidel equal (${M_arg}/${avgN}*4/${dens})^0.333333*1e+8
-
-dimension    3
-boundary     p p p
-lattice      fcc ${sidel} orient x 1 0 0 orient y 0 1 0 orient z 0 0 1
-region       box block 0 ${repetitions} 0 ${repetitions} 0 ${repetitions}
-create_box   1 box
-create_atoms 1 box
-mass         1 {Mweight} 
-pair_style   lj/cut {cut_off}
-pair_coeff   * * {epsilon} {sigma}
-timestep     ${dt}
-thermo       $d
-
-# equilibration and thermalization
-
-velocity     all create $T 102486 mom yes rot yes dist gaussian
-fix          NVT all nvt temp $T $T 10 drag 0.2
-run          ${eq_steps}
-
-# thermal conductivity calculation, switch to NVE if desired
-
-unfix       NVT
-fix         NVE all nve
-
-reset_timestep 0
-
-# Thermal
-compute      KE all ke/atom
-compute      PE all pe/atom
-compute      pe_total all pe
-compute      ke_total all ke
-compute      Stress all stress/atom NULL virial
-compute      flux_thermal all heat/flux KE PE Stress
-
-# viscosity
-variable     pxy equal pxy
-variable     pxz equal pxz
-variable     pyz equal pyz
-
-variable     Jx equal c_flux_thermal[1]/vol
-variable     Jy equal c_flux_thermal[2]/vol
-variable     Jz equal c_flux_thermal[3]/vol
-fix          JJ all ave/correlate $s $p $d &
-             c_flux_thermal[1] c_flux_thermal[2] c_flux_thermal[3] type auto file J0Jt.dat ave running
-fix          SS all ave/correlate $s $p $d &	
-             v_pxy v_pxz v_pyz type auto file S0St.dat ave running
-fix print_data all print ${output_step} "$(step) $(time) $(temp) $(c_pe_total) $(c_ke_total) $(c_flux_thermal[1]) $(c_flux_thermal[2]) $(c_flux_thermal[3]) $(v_pxy) $(v_pxz) $(v_pyz)" file flux.lmp_flux screen no
-variable     scale equal ${convert}/${kB}/$T/$T/$V*$s*${dt}
-variable     k11 equal trap(f_JJ[3])*${scale}
-variable     k22 equal trap(f_JJ[4])*${scale}
-variable     k33 equal trap(f_JJ[5])*${scale}
-
-# shell mkdir energy
-# dump energy all custom 400 energy/energy_dump.* id type x y z vx vy vz c_myKE c_myPE
-# dump the data required for G-K computations
-
-# NOT DUMPING POSITIONS NOW
-dump position all custom ${output_step} gk_data.lmp_traj id type x y z vx vy vz c_KE c_PE c_Stress[1] c_Stress[2] c_Stress[3] c_Stress[4] c_Stress[5] c_Stress[6]
-
-thermo_style custom step temp press v_Jx v_Jy v_Jz v_k11 v_k22 v_k33
-# run          500000
-run          ${timesteps}
-variable     k equal (v_k11+v_k22+v_k33)/3.0
-variable     ndens equal count(all)/vol
-print        "the volume of the box is: $V"
-print        "average conductivity: $k[W/mK] @ $T K, ${ndens} /A\^3"
\ No newline at end of file
diff --git a/tutorials/walkthrough_notebooks/conductivity_thermal/argon.lammps b/tutorials/walkthrough_notebooks/conductivity_thermal/argon.lammps
deleted file mode 100644
index 30f00a85..00000000
--- a/tutorials/walkthrough_notebooks/conductivity_thermal/argon.lammps
+++ /dev/null
@@ -1,76 +0,0 @@
-# Sample LAMMPS input script for thermal conductivity of solid Ar
-
-units       real
-variable    T equal 70 # temperature
-variable    V equal vol
-variable    dt equal 1.0 # timestep
-variable    p equal 200     # correlation length
-variable    s equal 10      # sample interval
-variable    d equal $p*$s   # dump interval
-
-# convert from LAMMPS real units to SI
-
-variable    kB equal 1.3806504e-23    # [J/K] Boltzmann
-variable    kCal2J equal 4186.0/6.02214e23
-variable    A2m equal 1.0e-10
-variable    fs2s equal 1.0e-15
-variable    convert equal ${kCal2J}*${kCal2J}/${fs2s}/${A2m}
-
-# setup problem
-variable    repetitions equal 4 # number of blocks repetitions in each direction
-
-dimension    3
-boundary     p p p
-lattice      fcc 5.376 orient x 1 0 0 orient y 0 1 0 orient z 0 0 1
-region       box block 0 ${repetitions} 0 ${repetitions} 0 ${repetitions}
-create_box   1 box
-create_atoms 1 box
-mass         1 39.948
-pair_style   lj/cut 13.0
-pair_coeff   * * 0.2381 3.405
-timestep     ${dt}
-thermo       $d
-
-# equilibration and thermalization
-
-velocity     all create $T 102486 mom yes rot yes dist gaussian
-fix          NVT all nvt temp $T $T 10 drag 0.2
-run          400000
-
-# thermal conductivity calculation, switch to NVE if desired
-
-unfix       NVT
-fix         NVE all nve
-
-reset_timestep 0
-compute      KE all ke/atom
-compute      PE all pe/atom
-compute      pe_total all pe
-compute      ke_total all ke
-compute      Stress all stress/atom NULL virial
-compute      flux_thermal all heat/flux KE PE Stress
-variable     Jx equal c_flux_thermal[1]/vol
-variable     Jy equal c_flux_thermal[2]/vol
-variable     Jz equal c_flux_thermal[3]/vol
-fix          JJ all ave/correlate $s $p $d &
-             c_flux_thermal[1] c_flux_thermal[2] c_flux_thermal[3] type auto file J0Jt.dat ave running
-fix print_data all print 2 "$(step) $(time) $(temp) $(c_pe_total) $(c_ke_total) $(c_flux_thermal[1]) $(c_flux_thermal[2]) $(c_flux_thermal[3]) $(c_flux_thermal[4]) $(c_flux_thermal[5]) $(c_flux_thermal[6])" file flux_1.lmp_flux screen no
-variable     scale equal ${convert}/${kB}/$T/$T/$V*$s*${dt}
-variable     k11 equal trap(f_JJ[3])*${scale}
-variable     k22 equal trap(f_JJ[4])*${scale}
-variable     k33 equal trap(f_JJ[5])*${scale}
-
-# shell mkdir energy
-# dump energy all custom 400 energy/energy_dump.* id type x y z vx vy vz c_myKE c_myPE
-# dump the data required for G-K computations
-dump position all custom 5 gk_data.lmp_traj id type x y z vx vy vz fx fy fz c_KE c_PE c_Stress[1] c_Stress[2] c_Stress[3] c_Stress[4] c_Stress[5] c_Stress[6]
-dump_modify position sort id
-
-
-thermo_style custom step temp v_Jx v_Jy v_Jz v_k11 v_k22 v_k33
-# run          500000
-run          250000
-variable     k equal (v_k11+v_k22+v_k33)/3.0
-variable     ndens equal count(all)/vol
-print        "the volume of the box is: $V"
-print        "average conductivity: $k[W/mK] @ $T K, ${ndens} /A\^3"
\ No newline at end of file
diff --git a/tutorials/walkthrough_notebooks/conductivity_thermal/from_flux/add_header_flux_file.py b/tutorials/walkthrough_notebooks/conductivity_thermal/from_flux/add_header_flux_file.py
deleted file mode 100644
index c221a41c..00000000
--- a/tutorials/walkthrough_notebooks/conductivity_thermal/from_flux/add_header_flux_file.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# This script is far from ideal...but it is only to give the structure.
-
-import re
-import os
-from os.path import exists
-from shutil import copyfile
-import time
-
-
-def prepend(filename, data, bufsize=1<<15):
-    # adapted from https://stackoverflow.com/questions/5287762/how-to-insert-a-new-line-before-the-first-line-in-a-file-using-python/5290636#5290636
-    # backup the file
-    backupname = filename + os.extsep+'bak'
-    try: os.unlink(backupname) # remove previous backup if it exists
-    except OSError: pass
-    os.rename(filename, backupname)
-
-    # open input/output files,  note: outputfile's permissions lost
-    with open(backupname) as inputfile, open(filename, 'w') as outputfile:
-        # prepend
-        outputfile.write(data)
-        # copy the rest (remove the first line)
-        _ = inputfile.readline()
-        buf = inputfile.read(bufsize)
-        while buf:
-            outputfile.write(buf)
-            buf = inputfile.read(bufsize)
-
-    # remove backup on success
-    try: os.unlink(backupname)
-    except OSError: pass
-
-def find_match(lammpsfilename, match):
-    # find match in the line given a list of words as hint
-    with open(lammpsfilename,'r') as fp:
-        line_with_match = []
-        for line in fp:
-            if all(x in line for x in match):
-                line_with_match.append(line)
-    return line_with_match
-
-def get_property(line_match):
-    # this takes the value of a dict (usually a string) and returns a value of the property.
-    # it is built this way to handle the possible errors.
-    if line_match.startswith('pair_style'):
-        return line_match.split()[1]
-
-    try:
-        property_extracted = float(re.findall('\d*\.?\d+', line_match)[0])
-    except IndexError:
-        property_extracted = line_match.split()[1]
-    except TypeError:
-        property_extracted = None
-    return property_extracted
-
-
-def read_data(lammpsfilename):
-
-    # inputs to match (some variables and the line of headers)
-    things_to_match = {'density':           ['variable','densi', 'equal', '# density'],
-                       'atom_side':         ['variable','repetitions', 'equal'],
-                       'dt':                ['variable', 'dt', 'equal', '# timestep'],
-                       'units':             ['units', '# set units'],
-                       'molarMass':         ['variable', 'M_arg', 'equal'],
-                       'pair_style':        ['pair_style'],
-                       'timesteps': ["variable", 'timesteps', 'equal'],
-                       'output_step':       ['variable','output_step', 'equal'],
-                       'temperature':       ['variable', 'T', 'equal', '# temperature'],
-                       'volume': ['the', 'volume', 'of', 'the', 'box', 'is:']
-                       }
-
-    line_fix_print_headers = "$(c_flux_thermal[1]) $(c_flux_thermal[2]) $(c_flux_thermal[3])"
-
-    # match the different properties required
-
-    properties_extracted = dict.fromkeys(things_to_match.keys())
-
-    for property, indicators in things_to_match.items():
-        matches = find_match(lammpsfilename, indicators)
-        if not matches:
-            properties_extracted[property] = None
-        else:
-            if isinstance(matches, str):
-                properties_extracted[property] = get_property(matches)
-            elif isinstance(matches, list):
-                properties_extracted[property] = get_property(matches[-1])
-
-        if properties_extracted[property] is None:
-            print(f'"{property}" not found, will be printed as "nan"')
-            properties_extracted[property] = -1
-
-    properties_extracted['num_atoms'] = 4*properties_extracted["atom_side"]**3
-
-
-    # get the header line
-    line_header = find_match(lammpsfilename, line_fix_print_headers)[0]
-    line_header = line_header.split(sep='"')[1].replace("$","").replace("(","").replace(")","")
-
-    text_to_replace = (f'# Fix print output for fix print_data\n'
-                       f'# {properties_extracted["pair_style"]} potential \n'
-                       f'# {int(properties_extracted["num_atoms"])} atoms, dens. {properties_extracted["density"]}g/cm^3 \n'
-                       f'# dt = {properties_extracted["dt"]}, {properties_extracted["timesteps"]} timesteps, output_step = every {properties_extracted["output_step"]} step \n'
-                       f'# Temperature = {properties_extracted["temperature"]} K, V = {properties_extracted["volume"]} A3 \n'
-                       f'# LAMMPS {properties_extracted["units"]} units \n'
-                       f'{line_header} \n')
-    return text_to_replace
-
-def check_header_existance(filename):
-    with open(filename,'r') as fp:
-        next(fp) # skip the first line
-        head = [next(fp) for x in range(2)]
-    if all([line.startswith("# ") for line in head]):
-        print('It seems the header already exists, I will not add it.')
-        return True
-    else:
-        return False
-
-def add_header(filename, lammpsfilename, keep_copy=True):
-
-    # Check if header already exists
-    header_exists = check_header_existance(filename=filename)
-
-    if not header_exists:
-        if keep_copy:
-            copyfile(filename, filename+'.backup')
-            print('back copy done')
-
-        text_to_replace = read_data(lammpsfilename)
-        prepend(filename, text_to_replace)
-        print("Job's Done! header replaced")
-
-if __name__=='__main__':
-
-    add_header('../flux_1.lmp_flux', '../log.lammps')
-
-
diff --git a/tutorials/walkthrough_notebooks/conductivity_thermal/from_flux/step_by_step.py b/tutorials/walkthrough_notebooks/conductivity_thermal/from_flux/step_by_step.py
deleted file mode 100644
index 170400f4..00000000
--- a/tutorials/walkthrough_notebooks/conductivity_thermal/from_flux/step_by_step.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import shutil
-
-from mdsuite.experiment.experiment import Experiment
-
-if __name__ == '__main__':
-
-    new_case = True
-
-    if new_case:
-        try:
-            shutil.rmtree('Argon_70')
-        except FileNotFoundError:
-            pass
-
-    argon = Experiment(analysis_name="Argon_70",
-                       storage_path=".",
-                       temperature=70.0,
-                       time_step=1,
-                       units='real')
-
-    # the rename cols is only used to show here how it works, but in this case, the lammps file has the same column names...
-    if new_case:
-        argon.add_data(trajectory_file='../flux_1.lmp_flux', file_format='lammps_flux',
-                       rename_cols={'Thermal_Flux': ['c_flux_thermal[1]', 'c_flux_thermal[2]', 'c_flux_thermal[3]']})
-
-    argon.run_computation('GreenKuboThermalConductivity', data_range=2000, plot=True, correlation_time=4)
diff --git a/tutorials/walkthrough_notebooks/conductivity_thermal/from_trajectory/check_db.py b/tutorials/walkthrough_notebooks/conductivity_thermal/from_trajectory/check_db.py
deleted file mode 100644
index 36ae60b4..00000000
--- a/tutorials/walkthrough_notebooks/conductivity_thermal/from_trajectory/check_db.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import os
-import numpy as np
-import h5py as hf
-import matplotlib.pyplot as plt
-
-folder = 'Argon'
-
-path = '1/Unwrapped_Positions'
-with hf.File(f'{folder}/databases/database.hdf5', "r+") as database:
-    data = database[path][np.s_[:]]
-
-slice = np.s_[:, :,1]
-
-sliced_x = data[slice]
-
-plt.plot(sliced_x[0:10].T, 'o')
-
-plt.savefig(f"{folder}/positions.png")
-plt.show()
\ No newline at end of file
diff --git a/tutorials/walkthrough_notebooks/conductivity_thermal/from_trajectory/conductivity_eh.py b/tutorials/walkthrough_notebooks/conductivity_thermal/from_trajectory/conductivity_eh.py
deleted file mode 100644
index 9b4dcf2a..00000000
--- a/tutorials/walkthrough_notebooks/conductivity_thermal/from_trajectory/conductivity_eh.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import os
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
-import shutil
-
-import mdsuite as mds # Cool name for professionalism purposes
-
-new_case = False
-
-if new_case:
-    try:
-        shutil.rmtree('Argon')
-    except FileNotFoundError:
-        pass
-
-
-
-argon = mds.Experiment(analysis_name="Argon", time_step=1, temperature=70.0, units='real')
-
-if new_case:
-    argon.add_data(trajectory_file='../gk_data.lmp_traj')
-
-
-argon.run_computation.EinsteinHelfandThermalConductivity(data_range=4000, plot=True, correlation_time=3)
diff --git a/tutorials/walkthrough_notebooks/conductivity_thermal/from_trajectory/conductivity_gk.py b/tutorials/walkthrough_notebooks/conductivity_thermal/from_trajectory/conductivity_gk.py
deleted file mode 100644
index e4df06ee..00000000
--- a/tutorials/walkthrough_notebooks/conductivity_thermal/from_trajectory/conductivity_gk.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import os
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
-import shutil
-
-import mdsuite as mds # Cool name for professionalism purposes
-
-new_case = False
-
-if new_case:
-    try:
-        shutil.rmtree('Argon')
-    except FileNotFoundError:
-        pass
-
-
-
-argon = mds.Experiment(analysis_name="Argon", time_step=1, temperature=70.0, units='real')
-
-if new_case:
-    argon.add_data(trajectory_file='../gk_data.lmp_traj')
-
-
-argon.run_computation.GreenKuboThermalConductivity(data_range=4000, plot=True, correlation_time=3)
diff --git a/tutorials/walkthrough_notebooks/conductivity_thermal/from_trajectory/conductivity_kinaci.py b/tutorials/walkthrough_notebooks/conductivity_thermal/from_trajectory/conductivity_kinaci.py
deleted file mode 100644
index 7ad43ecb..00000000
--- a/tutorials/walkthrough_notebooks/conductivity_thermal/from_trajectory/conductivity_kinaci.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import os
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
-import shutil
-
-import mdsuite as mds # Cool name for professionalism purposes
-
-new_case = False
-
-if new_case:
-    try:
-        shutil.rmtree('Argon')
-    except FileNotFoundError:
-        pass
-
-
-
-argon = mds.Experiment(analysis_name="Argon", time_step=1, temperature=70.0, units='real')
-
-if new_case:
-    argon.add_data(trajectory_file='../gk_data.lmp_traj')
-
-
-argon.run_computation.EinsteinHelfandThermalKinaci(data_range=4000, plot=True, correlation_time=2)


Test patch:
diff --git a/CI/integration_tests/NaCl/test_nacl_liquid.py b/CI/integration_tests/NaCl/test_nacl_liquid.py
new file mode 100644
index 00000000..4ef156bd
--- /dev/null
+++ b/CI/integration_tests/NaCl/test_nacl_liquid.py
@@ -0,0 +1,203 @@
+"""
+Integration test with Liquid NaCl.
+
+Tests the following:
+* Project class function
+* Experiment class function
+* RDF calculator
+* Diffusion coefficients
+* Ionic Conductivity with and without charges.
+* Unwrapping with and without indices
+"""
+import mdsuite as mds
+import unittest
+import urllib.request
+import gzip
+import shutil
+import os
+import numpy as np
+import shutil
+
+
+class TestLiquidNaCl(unittest.TestCase):
+    """
+    Perform an integration test on liquid NaCl.
+    """
+
+    @classmethod
+    def setUpClass(cls) -> None:
+        """
+        set up the project class and experiments.
+
+        Returns
+        -------
+        Updates class attributes.
+        """
+        cls.project = mds.Project(name='molten_nacl_test')
+        time_step = 0.002
+        temperature = 1400.0
+        base_url = 'https://github.com/zincware/ExampleData/raw/main/'
+        cls.endpoints = ['NaCl_gk_i_q.lammpstraj',
+                         'NaCl_gk_ni_nq.lammpstraj',
+                         'NaCl_i_q.lammpstraj',
+                         'NaCl_ni_nq.lammpstraj']
+        for item in cls.endpoints:
+            filename, headers = urllib.request.urlretrieve(f'{base_url}{item}.gz', filename=f'{item}.gz')
+            with gzip.open(filename, 'rb') as f_in:
+                with open(item, 'wb') as f_out:
+                    shutil.copyfileobj(f_in, f_out)
+            cls.project.add_experiment(experiment=item[:-11],
+                                       timestep=time_step,
+                                       temperature=temperature,
+                                       units='metal')
+            cls.project.experiments[item[:-11]].add_data(item)
+            cls.project.experiments[item[:-11]].set_charge("Na", 1)
+            cls.project.experiments[item[:-11]].set_charge("Cl", -1)
+            os.remove(item)
+            os.remove(f'{item}.gz')
+
+    @classmethod
+    def tearDownClass(cls) -> None:
+        """
+        Remove files generated.
+        Returns
+        -------
+        Removes the project directory.
+        """
+        shutil.rmtree('molten_nacl_test_MDSuite_Project', ignore_errors=True)
+
+    def test_completion(self):
+        """
+        Test that the project is loaded.
+        Returns
+        -------
+        assert that all the experiments exist.
+        """
+        reference = [item[:-11] for item in self.endpoints]
+        comparison = list(self.project.experiments.keys())
+        assert np.array_equal(reference, comparison)
+
+    def test_einstein_diffusion_coefficients(self):
+        """
+        Test that einstein diffusion coefficients work as expected. This will include assessing how the unwrapping
+        works for both indices and from the MDSuite box-hopping implementation.
+
+        Returns
+        -------
+        Asserts the following:
+        * Self-diffusion coefficients match to expected value.
+        * Box-indices and box-hopping unwrapping methods yield the same value.
+        * All unwrapping, einstein computations, and fitting methods work together.
+        """
+        Na_ref = 1.46e-8
+        Cl_ref = 1.41e-8
+        reference_experiments = ['NaCl_i_q', 'NaCl_ni_nq']
+        for item in reference_experiments:
+            self.project.experiments[item].run_computation.EinsteinDiffusionCoefficients(plot=False,
+                                                                                         data_range=300,
+                                                                                         correlation_time=1,
+                                                                                         save=True)
+        dat_Na = self.project.get_properties({'analysis': 'Einstein_Self_Diffusion_Coefficients',
+                                              'subjects': ["Na"]})
+        dat_Cl = self.project.get_properties({'analysis': 'Einstein_Self_Diffusion_Coefficients',
+                                              'subjects': ["Cl"]})
+
+        Na_diff = [[dat_Na[item][0].data[0].x] for item in reference_experiments]
+        Cl_diff = [[dat_Cl[item][0].data[0].x] for item in reference_experiments]
+        np.testing.assert_almost_equal(Na_diff[0][0], Na_ref, 8)
+        np.testing.assert_almost_equal(Na_diff[1][0], Na_ref, 8)
+        np.testing.assert_almost_equal(Na_diff[0][0], Na_diff[1][0], 8)
+        np.testing.assert_almost_equal(Cl_diff[0][0], Cl_ref, 8)
+        np.testing.assert_almost_equal(Cl_diff[1][0], Cl_ref, 8)
+        np.testing.assert_almost_equal(Cl_diff[0][0], Cl_diff[1][0], 8)
+
+    def test_einstein_ionic_conductivity(self):
+        """
+        Test that Einstein-Helfand ionic conductivity work as expected. This will include assessing how the unwrapping
+        works for both indices and from the MDSuite box-hopping implementation. It will also ensure that the different
+        approaches for charge inclusion result in the same values.
+
+        Returns
+        -------
+        Asserts the following:
+        * Ionic conductivity values match to expected value.
+        * Box-indices and box-hopping unwrapping methods yield the same value.
+        * All unwrapping, einstein computations, and fitting methods work together.
+        """
+        reference_experiments = ['NaCl_i_q', 'NaCl_ni_nq']
+        ic_ref = 365.0
+        for item in reference_experiments:
+            self.project.experiments[item].run_computation.EinsteinHelfandIonicConductivity(plot=False,
+                                                                                            data_range=50,
+                                                                                            correlation_time=1,
+                                                                                            save=True)
+        dat = self.project.get_properties({'analysis': 'Einstein_Helfand_Ionic_Conductivity'})
+
+        ic = [[dat[item][0].data[0].x] for item in reference_experiments]
+        np.testing.assert_almost_equal(ic[0][0], ic[1][0], -1)
+        np.testing.assert_almost_equal(ic[0][0], ic_ref, -1)
+        np.testing.assert_almost_equal(ic[1][0], ic_ref, -1)
+
+    def test_green_kubo_diffusion_coefficients(self):
+        """
+        Test that green-kubo diffusion coefficients work as expected. This will include assessing how the unwrapping
+        works for both indices and from the MDSuite box-hopping implementation.
+
+        Returns
+        -------
+        Asserts the following:
+        * Self-diffusion coefficients match to expected value.
+        """
+        Na_ref = 1.78e-8
+        Cl_ref = 1.43e-8
+        reference_experiments = ['NaCl_gk_i_q', 'NaCl_gk_ni_nq']
+        for item in reference_experiments:
+            self.project.experiments[item].run_computation.GreenKuboDiffusionCoefficients(plot=False,
+                                                                                          data_range=300,
+                                                                                          correlation_time=1,
+                                                                                          save=True)
+        dat_Na = self.project.get_properties({'analysis': 'Green_Kubo_Self_Diffusion_Coefficients',
+                                              'subjects': ["Na"]})
+        dat_Cl = self.project.get_properties({'analysis': 'Green_Kubo_Self_Diffusion_Coefficients',
+                                              'subjects': ["Cl"]})
+        Na_diff = [[dat_Na[item][0].data[0].x] for item in reference_experiments]
+        Cl_diff = [[dat_Cl[item][0].data[0].x] for item in reference_experiments]
+        np.testing.assert_almost_equal(Na_diff[0][0], Na_ref, 8)
+        np.testing.assert_almost_equal(Na_diff[1][0], Na_ref, 8)
+        np.testing.assert_almost_equal(Na_diff[0][0], Na_diff[1][0], 8)
+        np.testing.assert_almost_equal(Cl_diff[0][0], Cl_ref, 8)
+        np.testing.assert_almost_equal(Cl_diff[1][0], Cl_ref, 8)
+        np.testing.assert_almost_equal(Cl_diff[0][0], Cl_diff[1][0], 8)
+
+    def test_green_kubo_ionic_conductivity(self):
+        """
+        Test that Green-Kubo ionic conductivity work as expected. This will include assessing how the unwrapping
+        works for both indices and from the MDSuite box-hopping implementation. It will also ensure that the different
+        approaches for charge inclusion result in the same values.
+
+        Returns
+        -------
+        Asserts the following:
+        * Ionic conductivity values match to expected value.
+        * All unwrapping, einstein computations, and fitting methods work together.
+        * Charge computation and matrix computation works the same.
+        """
+        reference_experiments = ['NaCl_gk_i_q', 'NaCl_gk_ni_nq']
+        ic_ref = 1067
+
+        for item in reference_experiments:
+            self.project.experiments[item].run_computation.GreenKuboIonicConductivity(plot=False,
+                                                                                      data_range=50,
+                                                                                      correlation_time=1,
+                                                                                      save=True)
+        dat = self.project.get_properties({'analysis': 'Green_Kubo_Ionic_Conductivity'})
+        ic = [[dat[item][0].data[0].x] for item in reference_experiments]
+        print(ic)
+        np.testing.assert_almost_equal(ic[0][0], ic[1][0], -1)
+        np.testing.assert_almost_equal(ic[0][0], ic_ref, -1)
+        np.testing.assert_almost_equal(ic[1][0], ic_ref, -1)
+
+
+if __name__ == '__main__':
+    unittest.main()
+    shutil.rmtree('molten_nacl_test_MDSuite_Project', ignore_errors=True)
diff --git a/CI/unit_tests/utils/test_meta_functions.py b/CI/unit_tests/utils/test_meta_functions.py
new file mode 100644
index 00000000..19740646
--- /dev/null
+++ b/CI/unit_tests/utils/test_meta_functions.py
@@ -0,0 +1,182 @@
+"""
+This program and the accompanying materials are made available under the terms of the
+Eclipse Public License v2.0 which accompanies this distribution, and is available at
+https://www.eclipse.org/legal/epl-v20.html
+SPDX-License-Identifier: EPL-2.0
+Copyright Contributors to the MDSuite Project.
+"""
+import unittest
+from mdsuite.utils.meta_functions import join_path, get_dimensionality, get_machine_properties, \
+    line_counter, optimize_batch_size, linear_fitting_function, simple_file_read, round_down, split_array, find_item
+import os
+import numpy as np
+
+
+class TestMetaFunction(unittest.TestCase):
+    """
+    A test class for the meta functions module.
+    """
+    def test_join_path(self):
+        """
+        Test the join_path method.
+
+        Returns
+        -------
+        assert that join_path('a', 'b') is 'a/b'
+        """
+        self.assertEqual(join_path('a', 'b'), 'a/b')
+
+    def test_get_dimensionality(self):
+        """
+        Test the get_dimensionality method.
+
+        Returns
+        -------
+        assert that for all choices of dimension array the correct dimension comes out.
+        """
+        one_d = [1, 0, 0]
+        two_d = [1, 1, 0]
+        three_d = [1, 1, 1]
+        self.assertEqual(get_dimensionality(one_d), 1)
+        self.assertEqual(get_dimensionality(two_d), 2)
+        self.assertEqual(get_dimensionality(three_d), 3)
+
+    def test_get_machine_properties(self):
+        """
+        Test the get_machine_properties method.
+
+        Returns
+        -------
+        This test will just run the method and check for a failure.
+        """
+        get_machine_properties()
+
+    def test_line_counter(self):
+        """
+        Test the line_counter method.
+
+        Returns
+        -------
+        Check that the correct number of lines is return for a test file.
+        """
+        data = [["ayy"], ["bee"], ["cee"], ["dee"]]
+        name = 'line_counter_test.txt'
+        with open(name, 'w') as f:
+            for item in data:
+                f.write(f"{item[0]}\n")
+        self.assertEqual(line_counter(name), 4)
+        os.remove(name)
+
+    def test_optimize_batch_size(self):
+        """
+        Test the optimize_batch_size method.
+
+        Returns
+        -------
+        assert the correct batch size is returned for several inputs.
+        """
+        # Assert that the batch number is the full trajectory.
+        number_of_configurations = 10
+        _file_size = 100
+        _memory = 1000000
+        self.assertEqual(optimize_batch_size('None', number_of_configurations, _file_size, _memory, test=True), 10)
+
+        # Assert that the batch number is the half the trajectory.
+        number_of_configurations = 10
+        _file_size = 100
+        _memory = 250
+        self.assertEqual(optimize_batch_size('None', number_of_configurations, _file_size, _memory, test=True), 5)
+
+    def test_linear_fitting_function(self):
+        """
+        Test the linear_fitting_function method.
+
+        Returns
+        -------
+        Assert the correction function values come out.
+        """
+        a = 5
+        b = 3
+        x = np.array([1, 2, 3, 4, 5])
+        reference = a*x + b
+        assert np.array_equal(linear_fitting_function(x, a, b), reference)
+
+    def test_simple_file_read(self):
+        """
+        Test the simple_file_read method.
+
+        Returns
+        -------
+        Assert that the arrays read in are as expected.
+        """
+        data = [["ayy"], ["bee"], ["cee"], ["dee"]]
+        name = 'line_counter_test.txt'
+        with open(name, 'w') as f:
+            for item in data:
+                f.write(f"{item[0]}\n")
+        np.array_equal(simple_file_read(name), data)
+        os.remove(name)
+
+    def test_golden_section_search(self):
+        """
+        Test the golden_section_search method.
+
+        Returns
+        -------
+        Asserts that the correct minimum is found.
+        """
+        def func(x: np.ndarray):
+            """
+            test function.
+            Parameters
+            ----------
+            x : np.ndarray
+
+            Returns
+            -------
+            x**2
+            """
+            return x**2
+        self.assertEqual(True, True)
+
+    def test_round_down(self):
+        """
+        Test the round_down method.
+
+        Returns
+        -------
+        Assert the correct rounding occurs.
+        """
+        b = 10
+        a = 9
+
+        self.assertEqual(round_down(a, b), 5)
+
+    def test_split_arrays(self):
+        """
+        Test the split_arrays method.
+
+        Returns
+        -------
+        assert that array splitting has been performed correctly.
+        """
+        a = np.array([1, 2, 3, 10, 20, 30])
+        assert np.array_equal(split_array(a, a < 10), [np.array([1, 2, 3]), np.array([10, 20, 30])])
+
+    def test_find_item(self):
+        """
+        Test the find item method.
+
+        Returns
+        -------
+        assert that a deep item is retrieved from a dictionary.
+        """
+        test_1 = {'a': 4}  # test the first if statement
+        test_2 = {'a': {'ae': {'aee': 1}}, 'b': {'be': {'bee': 4}}}  # test the case when the if statement fails.
+
+        self.assertEqual(find_item(test_1, 'a'), 4)
+        self.assertEqual(find_item(test_2, 'aee'), 1)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/package_tests/README.md b/package_tests/README.md
deleted file mode 100644
index 31d89f98..00000000
--- a/package_tests/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Package Tests
-
-Here you will find all the package tests for the MDSuite python package.
-
-### TODO
-* Add more tests
-* Separate tests into "hook" tests and manual tests. Hook tests being those that run before allowing a pull request 
diff --git a/package_tests/utils/meta_functions_tests.py b/package_tests/utils/meta_functions_tests.py
deleted file mode 100644
index 23137d2f..00000000
--- a/package_tests/utils/meta_functions_tests.py
+++ /dev/null
@@ -1,4 +0,0 @@
-"""
-unittests for the meta_functions module
-"""
-