diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000000000000000000000000000000000000..d202675ba9a917e0cd9db1c0fd569fc037c444cd
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Loic Hausammann		loic.hausammann@epfl.ch
+Yves Revaz   		yves.revaz@epfl.ch
diff --git a/COPYING b/COPYING
new file mode 120000
index 0000000000000000000000000000000000000000..88798ab60d0071429c816e50551d74789c45a51a
--- /dev/null
+++ b/COPYING
@@ -0,0 +1 @@
+/usr/share/automake-1.15/COPYING
\ No newline at end of file
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/INSTALL b/INSTALL
new file mode 120000
index 0000000000000000000000000000000000000000..ddcdb76b36bd0e6c66dda2e2a0b0f48bfffc7109
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1 @@
+/usr/share/automake-1.15/INSTALL
\ No newline at end of file
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..4daa85e84e708c56e89190d458e47d6af9f0edcb
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,22 @@
+# This file is part of SWIFT.
+# Copyright (c) 2012 pedro.gonnet@durham.ac.uk
+#               2015 matthieu.schaller@durham.ac.uk
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Automake stuff
+ACLOCAL_AMFLAGS = -I m4
+
+# Show the way...
+SUBDIRS = src
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/README b/README
new file mode 120000
index 0000000000000000000000000000000000000000..602d87dfd9405502dcd988b9dab5bb724dc4471d
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+Readme.md
\ No newline at end of file
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000000000000000000000000000000000000..f9353c57a215829c97255817266d01f20f2d2c5b
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,145 @@
+# This file is part of SWIFT.
+# Copyright (C) 2012 pedro.gonnet@durham.ac.uk.
+#               2016 p.w.draper@durham.ac.uk.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Init the project.
+AC_INIT([PySWIFTsim],[0.1.0],[https://gitlab.cosma.dur.ac.uk/swift/PySWIFTsim])
+
+swift_config_flags="$*"
+
+#  We want to stop when given unrecognised options. No subdirs so this is safe.
+enable_option_checking=${enable_option_checking:-fatal}
+if test -n "$ac_unrecognized_opts"; then
+    case $enable_option_checking in
+        no)
+        ;;
+        fatal)
+            { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2
+              { (exit 1); exit 1; }; }
+        ;;
+        *)
+            $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2
+        ;;
+    esac
+fi
+
+AC_COPYRIGHT
+AC_CONFIG_SRCDIR([src/wrapper.c])
+AC_CONFIG_AUX_DIR([.])
+AM_INIT_AUTOMAKE([subdir-objects])
+
+# Add local macro collection.
+AC_CONFIG_MACRO_DIR([m4])
+
+# Stop default CFLAGS from anyone except the environment.
+: ${CFLAGS=""}
+
+# Generate header file.
+AM_CONFIG_HEADER(config.h)
+
+# Find and test the compiler.
+AX_CHECK_ENABLE_DEBUG
+AC_PROG_CC
+AM_PROG_CC_C_O
+
+# Enable POSIX and platform extension preprocessor macros.
+AC_USE_SYSTEM_EXTENSIONS
+
+# Check for compiler version and vendor.
+AX_COMPILER_VENDOR
+AX_COMPILER_VERSION
+
+#  Restrict support.
+AC_C_RESTRICT
+
+
+# Add libtool support (now that CC is defined).
+LT_INIT
+
+# Need C99 and inline support.
+AC_PROG_CC_C99
+AC_C_INLINE
+
+# Need fortran for grackle and velociraptor
+AC_PROG_FC
+AC_FC_LIBRARY_LDFLAGS
+
+
+# Define HAVE_POSIX_MEMALIGN if it works.
+AX_FUNC_POSIX_MEMALIGN
+
+# Autoconf stuff.
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+AC_HEADER_STDC
+
+SWIFT_ADD_LIBRARIES
+
+SWIFT_ADD_SPECIAL_FLAGS
+
+# this one should be at the beginning
+# it overwrites all the required parameters
+SWIFT_ADD_SUBGRID_MODELS
+
+
+
+SWIFT_ADD_GRAVITY
+
+SWIFT_ADD_HYDRO
+
+SWIFT_ADD_STARS
+
+SWIFT_ADD_KERNEL
+
+SWIFT_ADD_DIMENSION
+
+SWIFT_ADD_EQUATION_OF_STATE
+
+SWIFT_ADD_CHEMISTRY
+
+SWIFT_ADD_COOLING
+
+SWIFT_ADD_RIEMANN
+
+SWIFT_ADD_TRACER
+
+PYSWIFT_ADD_PYTHON
+
+# Check for git, needed for revision stamps.
+AC_PATH_PROG([GIT_CMD], [git])
+AC_SUBST([GIT_CMD])
+
+# Make the documentation. Add conditional to handle disable option.
+DX_INIT_DOXYGEN(libswift,doc/Doxyfile,doc/)
+AM_CONDITIONAL([HAVE_DOXYGEN], [test "$ac_cv_path_ac_pt_DX_DOXYGEN" != ""])
+
+# Check if using EAGLE cooling
+AM_CONDITIONAL([HAVEEAGLECOOLING], [test $with_cooling = "EAGLE"])
+
+# Handle .in files.
+AC_CONFIG_FILES([Makefile src/Makefile])
+
+# Save the compilation options
+AC_DEFINE_UNQUOTED([PYSWIFT_CONFIG_FLAGS],["$swift_config_flags"],[Flags passed to configure])
+
+# Make sure the latest git revision string gets included, when we are
+# working in a checked out repository.
+test -d ${srcdir}/.git && touch ${srcdir}/src/version.c
+
+AC_DEFINE([PYSWIFT_PACKAGE_URL],["www.swiftsim.com"], [Package web pages])
+
+# Generate output.
+AC_OUTPUT
diff --git a/examples/cooling_rate/cooling.yml b/examples/cooling_rate/cooling.yml
index 0dd7d8b65ab0d4f54be66ce743182350b889b230..ba04594f9b4abd193f53f2438f299aec701e16d1 100644
--- a/examples/cooling_rate/cooling.yml
+++ b/examples/cooling_rate/cooling.yml
@@ -34,6 +34,17 @@ InitialConditions:
   file_name:  ./sedov.hdf5          # The file to read
   h_scaling:           3.33
 
+# Cosmological parameters
+Cosmology:
+  h:              0.6777        # Reduced Hubble constant
+  a_begin:        0.0078125     # Initial scale-factor of the simulation
+  a_end:          1.0           # Final scale factor of the simulation
+  Omega_m:        0.307         # Matter density parameter
+  Omega_lambda:   0.693         # Dark-energy density parameter
+  Omega_b:        0.0455        # Baryon density parameter
+  Omega_r:        0.            # (Optional) Radiation density parameter
+  w_0:            -1.0          # (Optional) Dark-energy equation-of-state parameter at z=0.
+  w_a:            0.            # (Optional) Dark-energy equation-of-state time evolution parameter.
 
 # Cooling with Grackle 2.0
 GrackleCooling:
diff --git a/examples/cooling_rate/plot_cooling.py b/examples/cooling_rate/plot_cooling.py
index 4471dea1043201c857e68f7f0b9cc91315da4583..a8096db72053d0b529449808a3685d769da2f87b 100644
--- a/examples/cooling_rate/plot_cooling.py
+++ b/examples/cooling_rate/plot_cooling.py
@@ -17,21 +17,31 @@ You should have received a copy of the GNU Lesser General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 
-from pyswiftsim import wrapper
+from libpyswiftsim import coolingRate
 
 from copy import deepcopy
 import numpy as np
 import matplotlib.pyplot as plt
-from astropy import units
+from astropy import units, constants
 from os.path import isfile
 from h5py import File
+import yaml
 
 plt.rc('text', usetex=True)
 
 # PARAMETERS
+# cosmology
+with_cosmo = 0
 
 # grackle primordial chemistry (for comparison)
-primordial_chemistry = 3
+primordial_chemistry = 0
+
+# grackle simulation
+grackle_simulation = 0
+grackle_simulation = "Simulation {}".format(grackle_simulation)
+
+# name of this simulation
+simulation_name = "Grackle"
 
 # reference data
 grackle_filename = "grackle.hdf5"
@@ -98,7 +108,7 @@ def get_fields(primordial_chemistry):
     return fields
 
 
-def generate_default_initial_condition(us, pconst):
+def generate_default_initial_condition(us):
     print("Generating default initial conditions")
     d = {}
     # generate grid
@@ -108,88 +118,50 @@ def generate_default_initial_condition(us, pconst):
     d["temperature"] = T
 
     # Deal with units
-    rho *= us.UnitLength_in_cgs**3 * pconst.const_proton_mass
+    m_p = constants.m_p.to("{} g".format(us["UnitLength_in_cgs"]))
+    rho *= us["UnitLength_in_cgs"]**3 * m_p
     d["density"] = rho
 
-    energy = pconst.const_boltzmann_k * T / us.UnitTemperature_in_cgs
-    energy /= (gamma - 1.) * pconst.const_proton_mass
+    unit_time = us["UnitLength_in_cgs"] / us["UnitVelocity_in_cgs"]
+    unit_energy = us["UnitMass_in_cgs"] * us["UnitLength_in_cgs"]**2
+    unit_energy /= unit_time**2
+    k_B = constants.k_B.to("{} J / {} K".format(
+        unit_energy, us["UnitTemp_in_cgs"]
+    ))
+    energy = k_B * T / us["UnitTemp_in_cgs"]
+    energy /= (gamma - 1.) * m_p
     d["energy"] = energy
 
-    dt = default_dt / us.UnitTime_in_cgs
+    dt = default_dt / unit_time
     d["time_step"] = dt
 
     return d
 
 
-def get_io_fields(cooling, chemistry, output):
-    a = 1. / (1. + cooling.redshift)
-    fields = {
-        "MetalCooling": cooling.with_metal_cooling,
-        "UVBackground": cooling.with_uv_background,
-        "SelfShieldingMethod": cooling.self_shielding_method,
-        "MetalMassFraction": chemistry.initial_metallicity,
-        "ScaleFactor": a,
-    }
-
-    if output:
-        fields.update({
-            "MaxIter": cooling.max_step,
-            "Tolerance": cooling.convergence_limit,
-        })
-    return fields
-
-
-def getSimulationIndice(data, cooling, chemistry, output):
-
-    fields = get_io_fields(cooling, chemistry, output)
-
-    ind = 0
-    for name in data:
-        test = True
-        d = data[name]
-        if "Params" in d:
-            tmp = d["Params"]
-            for key in fields.keys():
-                check = abs(tmp.attrs[key] - fields[key]) > \
-                        1e-3 * tmp.attrs[key]
-                if check:
-                    test = False
-                    break
-        if test:
-            break
-        ind += 1
-    if ind == len(data):
-        return -1
-    else:
-        return ind
-
-
-def read_grackle_data(filename, us, primordial_chemistry, cooling, chemistry):
+def read_grackle_data(filename, us):
     print("Reading initial conditions")
     f = File(filename, "r")
     data = f["PrimordialChemistry%i" % primordial_chemistry]
 
-    i = getSimulationIndice(data, cooling, chemistry, output=False)
-    if i < 0:
-        raise IOError("Unable to locate corresponding grackle simulation")
-    else:
-        tmp = list(data.keys())
-        data = data[tmp[i]]
+    data = data[grackle_simulation]
 
     # read units
     tmp = data["Units"].attrs
 
-    u_len = tmp["Length"] / us.UnitLength_in_cgs
-    u_den = tmp["Density"] * us.UnitLength_in_cgs**3 / us.UnitMass_in_cgs
-    u_time = tmp["Time"] / us.UnitTime_in_cgs
+    u_len = tmp["Length"] / float(us["UnitLength_in_cgs"])
+    u_den = tmp["Density"] * float(us["UnitLength_in_cgs"])**3
+    u_den /= float(us["UnitMass_in_cgs"])
+    u_time = float(us["UnitLength_in_cgs"]) / float(us["UnitVelocity_in_cgs"])
+    u_time = tmp["Time"] / u_time
 
     # read input
     tmp = data["Input"]
 
+    d = {}
     energy = tmp["Energy"][:] * u_len**2 / u_time**2
     d["energy"] = energy
 
-    T = tmp["Temperature"][:] / us.UnitTemperature_in_cgs
+    T = tmp["Temperature"][:] / float(us["UnitTemp_in_cgs"])
     d["temperature"] = T
 
     density = tmp["Density"][:] * u_den
@@ -215,32 +187,10 @@ def read_grackle_data(filename, us, primordial_chemistry, cooling, chemistry):
     return d
 
 
-def initialize_swift(filename):
-    print("Initialization of SWIFT")
-    d = {}
-
-    # parse swift params
-    params = wrapper.parserReadFile(filename)
-    d["params"] = params
-
-    # init units
-    us, pconst = wrapper.unitSystemInit(params)
-    d["us"] = us
-    d["pconst"] = pconst
-
-    # init cosmo
-    cosmo = wrapper.cosmologyInit(params, us, pconst)
-    d["cosmo"] = cosmo
-
-    # init cooling
-    cooling = wrapper.coolingInit(params, us, pconst)
-    d["cooling"] = cooling
-
-    # init chemistry
-    chemistry = wrapper.chemistryInit(params, us, pconst)
-    d["chemistry"] = chemistry
-
-    return d
+def getParser(filename):
+    with open(filename, "r") as stream:
+        stream = yaml.load(stream)
+        return stream
 
 
 def plot_solution(rate, data, us):
@@ -255,16 +205,19 @@ def plot_solution(rate, data, us):
         grackle_rate = data["rate"]
 
     # change units => cgs
-    rho *= us.UnitMass_in_cgs / us.UnitLength_in_cgs**3
+    u_m = float(us["UnitMass_in_cgs"])
+    u_l = float(us["UnitLength_in_cgs"])
+    u_t = float(us["UnitLength_in_cgs"]) / float(us["UnitVelocity_in_cgs"])
+    rho *= u_m / u_l**3
 
-    T *= us.UnitTemperature_in_cgs
+    T *= float(us["UnitTemp_in_cgs"])
 
-    energy *= us.UnitLength_in_cgs**2 / us.UnitTime_in_cgs**2
+    energy *= u_l**2 / u_t**2
 
-    rate *= us.UnitLength_in_cgs**2 / us.UnitTime_in_cgs**3
+    rate *= u_l**2 / u_t**3
 
     if ref:
-        grackle_rate *= us.UnitLength_in_cgs**2 / us.UnitTime_in_cgs**3
+        grackle_rate *= u_l**2 / u_t**3
 
     # lambda cooling
     lam = rate * rho
@@ -274,13 +227,10 @@ def plot_solution(rate, data, us):
 
     # do plot
     if N_rho == 1:
-        # save data
-        write_solution(T, rho, lam)
-
         # plot Lambda vs T
         plt.figure()
         plt.loglog(T, np.abs(lam),
-                   label="SWIFT, %s" % wrapper.configGetCooling())
+                   label="SWIFT")
         if ref:
             # plot reference
             plt.loglog(T, np.abs(grackle_lam),
@@ -334,81 +284,25 @@ def plot_solution(rate, data, us):
         plt.show()
 
 
-def write_solution(T, rho, lam):
-    f = File(swift_output_filename, "a")
-
-    # create data set for this cooling
-    data_name = wrapper.configGetCooling()
-
-    if data_name not in f:
-        print("Creating Dataset")
-        data = f.create_group(data_name)
-    else:
-        data = f[data_name]
-
-    i = getSimulationIndice(data, cooling, chemistry, output=True)
-    if i != -1:
-        print("Updating Simulation")
-        keys = list(data.keys())
-        data.pop(keys[i])
-
-    data = data.create_group("Simulation %i" % len(data))
-
-    tmp = data.create_group("Units")
-    tmp.attrs["UnitSystem"] = "cgs"
-
-    tmp = data.create_group("Params")
-    fields = get_io_fields(cooling, chemistry, output=True)
-    for key in fields.keys():
-        tmp.attrs[key] = fields[key]
-
-    # temperature
-    dset = data.create_dataset(
-        "Temperature", T.shape, dtype=T.dtype)
-    dset[:] = T
-
-    # density
-    dset = data.create_dataset(
-        "Density", rho.shape, dtype=rho.dtype)
-    dset[:] = rho
-
-    # cooling rate
-    dset = data.create_dataset(
-        "Lambda", lam.shape, dtype=lam.dtype)
-    dset[:] = lam
-
-    f.close()
-
-
 if __name__ == "__main__":
 
-    d = initialize_swift(filename)
-    pconst = d["pconst"]
-    us = d["us"]
-    params = d["params"]
-    cosmo = d["cosmo"]
-    cooling = d["cooling"]
-    chemistry = d["chemistry"]
+    parser = getParser(filename)
+    us = parser["InternalUnitSystem"]
 
     if isfile(grackle_filename) and N_rho == 1:
-        d = read_grackle_data(grackle_filename, us,
-                              primordial_chemistry, cooling,
-                              chemistry)
+        d = read_grackle_data(grackle_filename, us)
     else:
-        d = generate_default_initial_condition(us, pconst)
+        d = generate_default_initial_condition(us)
 
     # du / dt
     print("Computing cooling...")
     rate = np.zeros(d["density"].shape)
 
     if compute_equilibrium:
-        rate = wrapper.coolingRate(pconst, us,
-                                   cosmo,
-                                   cooling,
-                                   chemistry,
-                                   d["density"].astype(np.float32),
-                                   d["energy"].astype(np.float32),
-                                   d["time_step"])
+        rate = coolingRate(filename, with_cosmo,
+                           d["density"].astype(np.float32),
+                           d["energy"].astype(np.float32),
+                           d["time_step"])
     else:
         fields = get_fields(primordial_chemistry)
         N = len(fields)
@@ -416,13 +310,10 @@ if __name__ == "__main__":
         for i in range(N):
             frac[:, i] = d[fields[i]]
 
-        rate = wrapper.coolingRate(pconst, us,
-                                   cosmo,
-                                   cooling,
-                                   chemistry,
-                                   d["density"].astype(np.float32),
-                                   d["energy"].astype(np.float32),
-                                   d["time_step"],
-                                   frac.astype(np.float32))
+        rate = coolingRate(filename, with_cosmo,
+                           d["density"].astype(np.float32),
+                           d["energy"].astype(np.float32),
+                           d["time_step"],
+                           frac.astype(np.float32))
 
     plot_solution(rate, d, us)
diff --git a/src/Makefile.am b/src/Makefile.am
index 40c61f96f1dbd77e1caebebedd95ffbe8d61ac05..a77473fd9cf45fb642c0175a3d22490b9b7f9084 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,7 +15,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # Add the non-standard paths to the included library headers
-AM_CFLAGS = -I$(top_srcdir)/src $(HDF5_CPPFLAGS) $(GSL_INCS) $(FFTW_INCS) $(NUMA_INCS) $(GRACKLE_INCS) $(PYTHON_INCS)
+AM_CFLAGS = -I$(top_srcdir)/../src $(HDF5_CPPFLAGS) $(GSL_INCS) $(FFTW_INCS) $(NUMA_INCS) $(GRACKLE_INCS) $(PYTHON_INCS)
 
 # Assign a "safe" version number
 AM_LDFLAGS = $(HDF5_LDFLAGS) $(FFTW_LIBS) -version-info 0:0:0
diff --git a/src/cooling_wrapper.c b/src/cooling_wrapper.c
index 242dc7f76930d1bcafc734a0e4aff3830d73380b..8def5d2d1e23507a0edd4f438816df7a02aff522 100644
--- a/src/cooling_wrapper.c
+++ b/src/cooling_wrapper.c
@@ -16,53 +16,12 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  ******************************************************************************/
-#include "pyswiftsim_tools.h"
 #include "cooling_wrapper.h"
-#include <omp.h>
-
 
-/**
- * @brief Initialize the cooling
- *
- * args is expecting pyswiftsim classes in the following order:
- * SwiftParams, UnitSystem and PhysConst. 
- *
- * @param self calling object
- * @param args arguments
- * @return CoolingFunctionData
- */
-PyObject* pycooling_init(PyObject* self, PyObject* args) {
-  PyObject *pyparams;
-  PyObject *pyus;
-  PyObject *pypconst;
-
-  /* parse arguments */
-  if (!PyArg_ParseTuple(args, "OOO", &pyparams, &pyus, &pypconst))
-      return NULL;
-
-  struct swift_params *params = (struct swift_params*) pytools_construct(pyparams, class_swift_params);
-  if (params == NULL)
-    return NULL;
-
-  struct unit_system *us = (struct unit_system*) pytools_construct(pyus, class_unit_system);
-  if (us == NULL)
-    return NULL;
-  
-  struct phys_const *pconst = (struct phys_const*) pytools_construct(pypconst, class_phys_const);
-  if (pconst == NULL)
-    return NULL;
-
-
-  struct cooling_function_data cooling;
-
-  /* init cooling */
-  cooling_init_backend(params, us, pconst, &cooling);
-
-  /* construct python object */
-  PyObject *pycooling = pytools_return(&cooling, class_cooling_function_data);
+/* Local includes */
+#include "pyswiftsim_tools.h"
+#include "part_wrapper.h"
 
-  return pycooling;
-}
 
 /**
  * @brief Set the cooling element fractions
@@ -117,31 +76,20 @@ void pycooling_set_fractions(struct xpart *xp, PyArrayObject* frac, const int id
 PyObject* pycooling_rate(PyObject* self, PyObject* args) {
   import_array();
   
-  PyObject *pycooling;
-  PyObject *pyus;
-  PyObject *pycosmo;
-  PyObject *pypconst;
-  PyObject *pychemistry;
+
+  char *filename;
 
   PyArrayObject *rho;
   PyArrayObject *energy;
   PyArrayObject *fractions = NULL;
 
   float dt = 1e-3;
+  int with_cosmo = 0;
 
   /* parse argument */
-  if (!PyArg_ParseTuple(args,
-			"OOOOOOO|fO",
-			&pypconst,
-			&pyus,
-			&pycosmo,
-			&pycooling,
-			&pychemistry,
-			&rho,
-			&energy,
-			&dt,
-			&fractions
-			))
+  if (!PyArg_ParseTuple(
+        args, "siOO|fO", &filename, &with_cosmo,
+	&rho, &energy, &dt, &fractions))
     return NULL;
 
   /* check numpy array */
@@ -164,37 +112,41 @@ PyObject* pycooling_rate(PyObject* self, PyObject* args) {
 
   size_t N = PyArray_DIM(energy, 0);
 
-  /* transform PyObject to C struct */
 
-  struct cooling_function_data *cooling = (struct cooling_function_data*) pytools_construct(pycooling, class_cooling_function_data);
-  if (cooling == NULL)
-    return NULL;
+  /* Initialize everything */
+  struct swift_params params;
+  parser_read_file(filename, &params);
 
-  struct unit_system *us = (struct unit_system*) pytools_construct(pyus, class_unit_system);
-  if (us == NULL)
-    return NULL;
+  struct unit_system us;
+  units_init_from_params(&us, &params, "InternalUnitSystem");
 
-  struct phys_const *pconst = (struct phys_const*) pytools_construct(pypconst, class_phys_const);
-  if (pconst == NULL)
-    return NULL;
+  struct phys_const pconst;
+  phys_const_init(&us, &params, &pconst);
 
-  struct chemistry_global_data *chemistry = (struct chemistry_global_data*) pytools_construct(pychemistry, class_chemistry_global_data);
-  if (chemistry == NULL)
-    return NULL;
+  struct cooling_function_data cooling;
 
-  struct cosmology *cosmo = (struct cosmology*) pytools_construct(pycosmo, class_cosmology);
-  if (cosmo == NULL)
-    return NULL;
+  /* init cooling */
+  cooling_init_backend(&params, &us, &pconst, &cooling);
+
+  struct chemistry_global_data chemistry;
+  chemistry_init_backend(&params, &us, &pconst, &chemistry);
+
+  struct cosmology cosmo;
+
+  if (with_cosmo)
+    cosmology_init(&params, &us, &pconst, &cosmo);
+  else
+    cosmology_init_no_cosmo(&cosmo);
 
   struct part p;
   struct xpart xp;
 
+  pyswift_part_set_to_zero(&p, &xp);
+  hydro_first_init_part(&p, &xp);
+    
   /* return object */
   PyArrayObject *rate = (PyArrayObject *)PyArray_SimpleNew(PyArray_NDIM(energy), PyArray_DIMS(energy), NPY_FLOAT);
 
-  /* Release GIL */
-  Py_BEGIN_ALLOW_THREADS;
-  
   /* loop over all particles */
   for(size_t i = 0; i < N; i++)
     {
@@ -206,159 +158,22 @@ PyObject* pycooling_rate(PyObject* self, PyObject* args) {
       if (fractions != NULL)
 	pycooling_set_fractions(&xp, fractions, i);
       else
-	cooling_first_init_part(pconst, us, cosmo, cooling, &p, &xp);
+	cooling_first_init_part(&pconst, &us, &cosmo, &cooling, &p, &xp);
 
-      chemistry_first_init_part(pconst, us, cosmo, chemistry, &p, &xp);
+      chemistry_first_init_part(&pconst, &us, &cosmo, &chemistry, &p, &xp);
 	
       /* compute cooling rate */
 #ifdef COOLING_GRACKLE
       float *tmp = PyArray_GETPTR1(rate, i);
-      *tmp = cooling_new_energy(pconst, us, cosmo, cooling, &p, &xp, dt);
-      *tmp = *tmp - hydro_get_physical_internal_energy(&p, &xp, cosmo);
+      *tmp = cooling_new_energy(&pconst, &us, &cosmo, &cooling, &p, &xp, dt);
+      *tmp = *tmp - hydro_get_physical_internal_energy(&p, &xp, &cosmo);
       *tmp /= dt;
-      message("%g", *tmp);
 #else
       message("Not implemented");
       //*tmp = cooling_rate(pconst, us, cosmo, cooling, &p, &xp);
 #endif
     }
 
-  /* Acquire GIL */
-  Py_END_ALLOW_THREADS;
-
   return (PyObject *) rate;
   
 }
-
-
-/**
- * @brief Compute cooling
- *
- * args is expecting pyswiftsim classes in the following order: 
- * PhysConst, UnitSystem, Cosmology and CoolingFunctionData.
- * Then two numpy arrays (density and specific energy) and a
- * float for the time step
- *
- * @param self calling object
- * @param args arguments
- * @return New energy
- */
-PyObject* pycooling_do_cooling(PyObject* self, PyObject* args) {
-  import_array();
-  
-  PyObject *pycooling;
-  PyObject *pyus;
-  PyObject *pycosmo;
-  PyObject *pypconst;
-  PyObject *pychemistry;
-
-  PyArrayObject *rho;
-  PyArrayObject *energy;
-  PyArrayObject *fractions = NULL;
-
-  float dt = 1e-3;
-
-  /* parse argument */
-  if (!PyArg_ParseTuple(args,
-			"OOOOOOOf|O",
-			&pypconst,
-			&pyus,
-			&pycosmo,
-			&pycooling,
-			&pychemistry,
-			&rho,
-			&energy,
-			&dt,
-			&fractions
-			))
-    return NULL;
-
-  /* check numpy array */
-  if (pytools_check_array(energy, 1, NPY_FLOAT, "Energy") != SUCCESS)
-    return NULL;
-
-  if (pytools_check_array(rho, 1, NPY_FLOAT, "Density") != SUCCESS)
-    return NULL;
-
-  if (fractions != NULL &&
-      pytools_check_array(fractions, 2, NPY_FLOAT, "Fractions") != SUCCESS)
-    return NULL;
-
-  if (PyArray_DIM(energy, 0) != PyArray_DIM(rho, 0))
-    pyerror("Density and energy should have the same dimension");
-
-  if (fractions != NULL &&
-      PyArray_DIM(fractions, 0) != PyArray_DIM(rho,0))
-    pyerror("Fractions should have the same first dimension than the others");
-
-  size_t N = PyArray_DIM(energy, 0);
-
-  /* transform PyObject to C struct */
-
-  struct cooling_function_data *cooling = (struct cooling_function_data*) pytools_construct(pycooling, class_cooling_function_data);
-  if (cooling == NULL)
-    return NULL;
-
-  struct unit_system *us = (struct unit_system*) pytools_construct(pyus, class_unit_system);
-  if (us == NULL)
-    return NULL;
-
-  struct phys_const *pconst = (struct phys_const*) pytools_construct(pypconst, class_phys_const);
-  if (pconst == NULL)
-    return NULL;
-
-  struct chemistry_global_data *chemistry = (struct chemistry_global_data*) pytools_construct(pychemistry, class_chemistry_global_data);
-  if (chemistry == NULL)
-    return NULL;
-
-  struct cosmology *cosmo = (struct cosmology*) pytools_construct(pycosmo, class_cosmology);
-  if (cosmo == NULL)
-    return NULL;
-
-  struct part p;
-  struct xpart xp;
-
-#ifdef COOLING_GRACKLE
-  /* set grackle_data */
-  grackle_data = &cooling->chemistry;
-#endif
-
-  /* return object */
-  PyArrayObject *new_energy = (PyArrayObject *)PyArray_SimpleNew(PyArray_NDIM(energy), PyArray_DIMS(energy), NPY_FLOAT);
-
-  /* Release GIL */
-  Py_BEGIN_ALLOW_THREADS;
-  
-  /* loop over all particles */
-  for(size_t i = 0; i < N; i++)
-    {
-      /* set particle data */
-      p.rho = *(float*) PyArray_GETPTR1(rho, i);
-      float u = *(float*) PyArray_GETPTR1(energy, i);
-      p.entropy = gas_entropy_from_internal_energy(p.rho, u);
-
-      /* initialize fields */
-      //hydro_set_internal_energy_dt(&p, 0.);
-      
-      chemistry_first_init_part(pconst, us, cosmo, chemistry, &p, &xp);
-
-      if (fractions != NULL)
-	pycooling_set_fractions(&xp, fractions, i);
-      else
-	cooling_first_init_part(pconst, us, cosmo, cooling, &p, &xp);
-      
-      /* compute cooling */
-      cooling_cool_part(pconst, us, cosmo, NULL, cooling, &p, &xp, dt, dt);
-      message("Need to redo");
-
-      /* update energy */
-      float *tmp = PyArray_GETPTR1(new_energy, i);
-      *tmp = u + dt * hydro_get_physical_internal_energy_dt(&p, NULL);
-    }
-
-  /* Acquire GIL */
-  Py_END_ALLOW_THREADS;
-
-  return (PyObject *) new_energy;
-  
-}
diff --git a/src/cooling_wrapper.h b/src/cooling_wrapper.h
index e80cb1c38f7d97d2b00ac7161d8c98f9cbcaf578..a9eeeb4d6a5061637795536f76af71cc439c6747 100644
--- a/src/cooling_wrapper.h
+++ b/src/cooling_wrapper.h
@@ -21,11 +21,7 @@
 
 #include "pyswiftsim_tools.h"
 
-PyObject* pycooling_init(PyObject* self, PyObject* args);
-
 PyObject* pycooling_rate(PyObject* self, PyObject* args);
 
-PyObject* pycooling_do_cooling(PyObject* self, PyObject* args);
-
 #endif // __PYSWIFTSIM_COOLING_H__
 
diff --git a/src/part_wrapper.c b/src/part_wrapper.c
index 65ceec2618a250e4faeae64a9243179c83539fc0..d8cefd848401a1e5eedb5839e5f12188e2c7738c 100644
--- a/src/part_wrapper.c
+++ b/src/part_wrapper.c
@@ -22,34 +22,9 @@
 #include <stdlib.h>
 #include <string.h>
 
-PyObject* pypart_test_struct(PyObject *self, PyObject *args)
-{
-
-  size_t N = sizeof(struct part);
-
-  /* initialize particle */
-  struct part *p = malloc(N);
-  p->id = 0;
-  for(size_t k = 0; k < DIM; k++)
-    {
-      p->x[k] = 1. + k;
-      p->v[k] = 4. + k;
-      p->a_hydro[k] = 7. + k;
-    }
-
-  p->h = 10;
-  p->mass = 11.;
-  p->rho = 12.;
-  p->entropy = 13;
-  p->entropy_dt = 14;
-  
-  hydro_init_part(p, NULL);
-
-  /* create python object */
-  PyObject *object = pytools_return(p, class_part);
-
-  free(p);
-  
-  return object;
+void pyswift_part_set_to_zero(struct part *p, struct xpart *xp) {
+  p->v[0] = 0;
+  p->v[1] = 0;
+  p->v[2] = 0;
+  p->entropy = 0;
 }
-
diff --git a/src/part_wrapper.h b/src/part_wrapper.h
index 05a2fd8b4b57d1f8847a0fc4757e287cc00ae740..bdc3d52b5807871a4c0e656150686032917f17d8 100644
--- a/src/part_wrapper.h
+++ b/src/part_wrapper.h
@@ -20,16 +20,8 @@
 #define __PYSWIFTSIM_PART_H__
 
 #include <Python.h>
+#include "pyswiftsim_tools.h"
 
-/**
- * @brief Test function for the struct
- *
- * args is expecting no argument. 
- *
- * @param self calling object
- * @param args arguments
- * @return Part
- */
-PyObject* pypart_test_struct(PyObject *self, PyObject *args);
-
+void pyswift_part_set_to_zero(struct part *p, struct xpart *xp);
+  
 #endif // __PYSWIFTSIM_PART_H__
diff --git a/src/pyswiftsim.h b/src/pyswiftsim.h
new file mode 100644
index 0000000000000000000000000000000000000000..f215e81490bd56169a241e862d8ad6056c42cf38
--- /dev/null
+++ b/src/pyswiftsim.h
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * This file is part of PYSWIFTSIM.
+ * Copyright (c) 2018 loic hausammann (loic.hausammann@epfl.ch)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ******************************************************************************/
+#ifndef __PYSWIFTSIM_H__
+#define __PYSWIFTSIM_H__
+
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+
+#include <Python.h>
+#include <numpy/arrayobject.h>
+
+/* Assert is already defined in Python.h */
+#undef assert
+#include "swift.h"
+
+
+#endif // __PYSWIFTSIM_H__
diff --git a/src/pyswiftsim_tools.h b/src/pyswiftsim_tools.h
index ca2b0d03129c88da287f71e7ccb78342fb35c094..3cc461c5019251511dfc91d04b73da64d3b49d5b 100644
--- a/src/pyswiftsim_tools.h
+++ b/src/pyswiftsim_tools.h
@@ -19,14 +19,7 @@
 #ifndef __PYSWIFTSIM_TOOLS_H__
 #define __PYSWIFTSIM_TOOLS_H__
 
-#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
-
-#include <Python.h>
-#include <numpy/arrayobject.h>
-
-#undef assert
-#include "../config.h"
-#include "swift.h"
+#include "pyswiftsim.h"
 
 #define DIM 3
 #define STRING_SIZE 200
diff --git a/src/wrapper.c b/src/wrapper.c
index 2bc1f5f830bce9fd56773c3017f069394b0bae92..65dbad5592af49b1ca4900b3c99ad357edd56031 100644
--- a/src/wrapper.c
+++ b/src/wrapper.c
@@ -23,7 +23,6 @@
 #include "cosmology_wrapper.h"
 #include "chemistry_wrapper.h"
 #include "pyswiftsim_tools.h"
-#include "swift.h"
 
 #include <Python.h>
 #include <math.h>
@@ -40,9 +39,6 @@ static PyMethodDef wrapper_methods[] = {
   {"unitSystemInit", pyunit_system_init, METH_VARARGS,
    "Construct a unit_system object and return it."},
 
-  {"coolingInit", pycooling_init, METH_VARARGS,
-   "Initialize cooling."},
-
   {"chemistryInit", pychemistry_init, METH_VARARGS,
    "Initialize chemistry."},
 
@@ -70,26 +66,6 @@ static PyMethodDef wrapper_methods[] = {
    "\t Cooling rate\n"
   },
 
-  {"doCooling", pycooling_do_cooling, METH_VARARGS,
-   "Compute the cooling.\n\n"
-   "Parameters\n"
-   "----------\n\n"
-   "pyconst: swift physical constant\n"
-   "pyus: swift unit system\n"
-   "cooling: swift cooling structure\n"
-   "rho: np.array\n"
-   "\t Mass density in pyus units\n"
-   "energy: np.array\n"
-   "\t Internal energy in pyus units\n"
-   "dt: float\n"
-   "\t Time step in pyus units\n"
-   "fractions: np.array, optional\n"
-   "\t Fraction of each cooling element (including metals)\n"
-   "Returns\n"
-   "-------\n\n"
-   "new_energy: np.array\n"
-   "\t Energy of the particle after dt\n"
-  },
 
   {NULL, NULL, 0, NULL}        /* Sentinel */
 };